# 4 - change "Re: " normalization, avoid circular Reference ghosts
# 5 - subject_path drops trailing '.'
# 6 - preserve References: order in document data
- # 7 - remove references and inreplyto terms
+ # 7 - remove references and inreplyto terms (restored in 15 (v2.0))
# 8 - remove redundant/unneeded document data
# 9 - disable Message-ID compression (SHA-1)
# 10 - optimize doc for NNTP overviews
# * "lid:" and "l:" for List-Id searches
#
# v1.6.0 adds BYTES, UID and THREADID values
+ # v2.0.0 re-adds "references:"
SCHEMA_VERSION => 15,
# we may have up to 8 FDs per shard (depends on Xapian *shrug*)
my %bool_pfx_external = (
mid => 'Q', # Message-ID (full/exact), this is mostly uniQue
lid => 'G', # newsGroup (or similar entity), just inside <>
+ references => 'XRF',
%PATCH_BOOL_COMMON
);
$doc->add_boolean_term('O'.$ekey) if ($ekey // '.') ne '.';
msg_iter($eml, \&index_xapian, [ $self, $doc ]);
index_ids($self, $doc, $eml, $mids);
+ for (@{$smsg->parse_references($eml, $mids)}) {
+ $doc->add_boolean_term('XRF'.$_)
+ }
# by default, we maintain compatibility with v1.5.0 and earlier
# by writing to docdata.glass, users who never expect to downgrade can
if (!$self->{-skip_docdata}) {
# WWW doesn't need {to} or {cc}, only NNTP
$smsg->{to} = $smsg->{cc} = '';
- $smsg->parse_references($eml, $mids);
- my $data = $smsg->to_doc_data;
- $doc->set_data($data);
+ $doc->set_data($smsg->to_doc_data);
}
my $xtra = defined $ekey ? $self->{"-extra\t$ekey"} : undef;
$xtra //= $self->{-extra};
Xapian::Query qry;
if (str.at(0) != '{') { // thread:$MSGID (no `{'/`}' encasement)
- qry = Xapian::Query("Q" + str);
+ qry = Xapian::Query(Xapian::Query::OP_OR,
+ Xapian::Query("Q" + str),
+ Xapian::Query("XRF" + str));
} else if (str.size() <= 1 || str.at(str.size() - 1) != '}') {
throw Xapian::QueryParserError("missing } in '" + str + "'");
} else { // thread:"{hello world}"
my $second = $res->[0];
isnt($first, $second, "offset returned different result from limit");
+
+ for my $f (qw(references)) {
+ $res = $query->($f . ':root@s');
+ @res = filter_mids($res);
+ is_deeply \@res, [ 'last@s' ],
+ "got expected results for $f: match";
+ diag explain(\@res);
+ $res = $query->($f . ':root');
+ is scalar(@$res), 0, "no partial mid match";
+ }
}
# ghost vivication
}
};
-my $thr = create_inbox 'thr', indexlevel => 'medium', version => 2,
+my $thr = create_inbox 'thr-ref+', indexlevel => 'medium', version => 2,
tmpdir => "$tmp/thr", sub {
my ($im) = @_;
my $common = <<EOM;
scalar(@art),
'expected matches for thread:"{ SUBQUERY }"';
+ @art = $retrieve->('thread:ghost-root@example');
+ is scalar(@art), 6,
+ 'expected number of results for thread:GHOST-MSGID';
+ is scalar(grep { $_->{references} =~ /ghost-root/ } @art),
+ scalar(@art),
+ 'thread:MSGID works on ghosts';
+
my $nr = $ENV{TEST_LEAK_NR} or skip 'TEST_LEAK_NR unset', 1;
$ENV{VALGRIND} or diag
"W: `VALGRIND=' unset w/ TEST_LEAK_NR (using -fsanitize?)";