On Sun, Sep 30, 2018 at 09:50:30AM +0100, James Aylett wrote:> Note that I'm using 1.4.7, and from your output I believe you're not > (the * in the query description I believe doesn't happen in those > situations any more).1.4.4 and later eliminate redundant 0 scaling factors, but this one isn't actually redundant:> > Query(((Tmail AND 0 * XSUBJECTnot at 1) AND_NOT (((Kspam OR Kdeleted) OR Kmuted) OR Kbad-address)))If it was on the right-hand side of AND_NOT it would be eliminated (because the right-hand side doesn't contribute any weight anyway). FWIW, I also couldn't reproduce this (I tried with quest and 1.4.7): $ quest -psubject:S -fdefault,boolean_any_case 'subject:"and"' Parsed Query: Query(Sand at 1) Cheers, Olly
Olly Betts <olly at survex.com> writes:> > FWIW, I also couldn't reproduce this (I tried with quest and 1.4.7): > > $ quest -psubject:S -fdefault,boolean_any_case 'subject:"and"' > Parsed Query: Query(Sand at 1) >Ah, OK, it must have something to do with the way that notmuch is using field processors. And I see now that the following code (from lib/regexp-fields.cc) is probably related (at least it explains subject:" not" works) if (str.find (' ') != std::string::npos) query_str = '"' + str + '"'; else query_str = str; return parser.parse_query (query_str, NOTMUCH_QUERY_PARSER_FLAGS, term_prefix); The motivation for not always triggering phrase processing is that it breaks/disables wildcards. In particular this change was to fix the query 'subject:foo*'. The difficulty here is that the field processor doesn't know if its string argument was originally quoted.
David Bremner <david at tethera.net> writes:> Olly Betts <olly at survex.com> writes: > >> >> FWIW, I also couldn't reproduce this (I tried with quest and 1.4.7): >> >> $ quest -psubject:S -fdefault,boolean_any_case 'subject:"and"' >> Parsed Query: Query(Sand at 1) >> > > Ah, OK, it must have something to do with the way that notmuch is using > field processors. And I see now that the following code (from > lib/regexp-fields.cc) is probably related (at least it explains > subject:" not" works) > > if (str.find (' ') != std::string::npos) > query_str = '"' + str + '"'; > else > query_str = str; > > return parser.parse_query (query_str, NOTMUCH_QUERY_PARSER_FLAGS, term_prefix);For the record, I have proposed a fix for notmuch (str is known to be non-empty there). This will phrase quote by default, unless the string looks like a wildcard query (without spaces). diff --git a/lib/regexp-fields.cc b/lib/regexp-fields.cc index 084bc8c0..52f30d82 100644 --- a/lib/regexp-fields.cc +++ b/lib/regexp-fields.cc @@ -194,7 +194,7 @@ RegexpFieldProcessor::operator() (const std::string & str) * phrase parsing, when possible */ std::string query_str; - if (str.find (' ') != std::string::npos) + if (*str.rbegin () != '*' || str.find (' ') != std::string::npos) query_str = '"' + str + '"'; else
On Sun, Sep 30, 2018 at 09:05:25AM -0300, David Bremner wrote:> if (str.find (' ') != std::string::npos) > query_str = '"' + str + '"'; > else > query_str = str; > > return parser.parse_query (query_str, NOTMUCH_QUERY_PARSER_FLAGS, term_prefix);I wouldn't recommend trying to generate strings to feed to QueryParser like this code seems to be doing. QueryParser aims to parse input from humans not machines. As well as the case where str is an operation name, the code above looks like it will mishandle cases where str contains a tab or double quotes. There are likely other problem cases too. Cheers, Olly