David Smiley created SOLR-18524:
-----------------------------------

             Summary: Honor q.op only as a local-param, not as a request param
                 Key: SOLR-18524
                 URL: https://issues.apache.org/jira/browse/SOLR-18524
             Project: Solr
          Issue Type: Improvement
          Components: query parsers
            Reporter: David Smiley


h3. What

{{q.op}} (default operator for the implicit operator between clauses) should be 
honored only when given as a local-param of the query it applies to, e.g. 
{{q={!q.op=AND}solr rocks}} or {{fq={!edismax q.op=AND qf=title}foo bar}}. A 
request-level {{q.op}} (including one set in a request handler's 
defaults/appends/invariants) should no longer be consulted by query parsers.

h3. Why

*1. A request-level q.op silently changes the meaning of every {{lucene}} query 
in the request, not just the user's.*
Parsers fetch it via {{QParser.getParam}}, which falls back from local params 
to request params. So a request-level {{q.op=AND}} reaches every query parsed 
in that request, not just {{q}}: each {{fq}}, {{facet.query}}, JSON Facet 
domain filters and queries, {{bq}}/{{boost}}, nested 
{{\{!parent\}}}/{{\{!join\}}} sub-queries, and so on. Readers include:
* {{LuceneQParser}} — 
{{lparser.setDefaultOperator(QueryParsing.parseOP(getParam(QueryParsing.OP)))}}
* {{ComplexPhraseQParserPlugin}} — same via {{getParam}}
* {{ExtendedDismaxQParser}} and {{SimpleQParserPlugin}} — 
{{SolrParams.wrapDefaults(localParams, params)}}
* {{SolrPluginUtils.parseMinShouldMatch}} — derives the {{mm}} default from it

Operators might set {{q.op=AND}} in solrconfig.xml to tune how *user* queries 
match. In practice this comes with a comment like the one in a config I 
maintain: {{<str name="q.op">AND</str><!-- affects filter queries too, 
unfortunately :-( -->}}. That "unfortunately" is the bug.

*2. Queries generated by programs need meanings that don't depend on context.*
Filters and other non-{{q}} queries are usually built by application code, not 
typed by users. The same reasoning was given for closing SOLR-15345 as Won't 
Fix: {{defType}} intentionally applies only to {{q}}. Yet today the meaning of 
a generated {{fq=a b}} depends on a parameter its author may not control and 
may not even know is set. Defensive client code has to avoid relying on the 
implicit operator everywhere: always spell out {{AND}}/{{OR}}, never emit bare 
SHOULD clauses, or wrap every query in {{\{!lucene q.op=OR\}}}. Equivalent 
query strings shouldn't need that care.

*3. It's inconsistent with {{defType}}.*
{{defType}} applies to {{q}} only, and {{q.op}} is closely related to it. A 
user who reasonably assumes they work the same way gets surprised.

*4. It keeps producing bugs that only show up in queries it was never meant 
for.*
* SOLR-12212: a parenthesized pure-NOT {{fq}} breaks under {{q.op=AND}}
* SOLR-17796: a tagged {{\{!collapse\}}} {{fq}} fails under {{q.op=AND}}
* SOLR-5161: distributed MoreLikeThis misbehaves under {{q.op=AND}}

All of these come from a request-level {{q.op}} reaching a query other than 
{{q}}.

*5. The scoped alternative already exists and is the clearer form.*
Local-params make the operator part of the query it governs: 
{{\{!q.op=AND\}…}}, {{\{!edismax q.op=AND …\}}}. A sub-query parser doesn't 
inherit its parent's local params, so it stays truly local — it neither leaks 
inward to nested queries nor outward to sibling ones.

h3. Proposal

* All request params starting with "q." (q dot) are _hoisted_ into local-params 
when parsing "q" specifically, but without the "q." prefix.  Actual/literal 
local-params take precedence.  Thus a request "q.op" becomes seen as an "op" 
local-param when "q" is parsed but not anywhere else.
* Query parsers read {{op}} from their local params only: {{LuceneQParser}}, 
{{ComplexPhraseQParserPlugin}}, {{ExtendedDismaxQParser}}, 
{{SimpleQParserPlugin}}, and the {{mm}} default in 
{{SolrPluginUtils.parseMinShouldMatch}}.  Gate this on luceneMatchVersion.
* Update the Ref Guide (standard, edismax, dismax, and simple parser pages; 
local-params page) and the major-version upgrade notes. Migration for a 
handler-level default: e.g. {{q=\{!q.op=AND v=$qq\}}} with the user's query in 
{{qq}}, or {{q.op}} in the local params the client already sends.

Perhaps "df" should be similar.  I'm in favor of that; separate issue.

🤖 This issue was drafted with AI assistance (Claude Code).



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to