You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ds...@apache.org on 2021/05/09 04:59:56 UTC

[lucene-solr] branch branch_8x updated: SOLR-15156: [child childFilter='...:...'] no longer escapes (#2367)

This is an automated email from the ASF dual-hosted git repository.

dsmiley pushed a commit to branch branch_8x
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git


The following commit(s) were added to refs/heads/branch_8x by this push:
     new efac0ed  SOLR-15156: [child childFilter='...:...'] no longer escapes (#2367)
efac0ed is described below

commit efac0edee50ddd9beba765a86a4b591027cfdc60
Author: David Smiley <ds...@apache.org>
AuthorDate: Sun May 9 00:59:23 2021 -0400

    SOLR-15156: [child childFilter='...:...'] no longer escapes (#2367)
    
    The query escaping it did was inconsistent with all other places in Solr where a Lucene query may be provided.
    There was no escaping here prior to 8.0 either.
---
 solr/CHANGES.txt                                      |  3 +++
 .../transform/ChildDocTransformerFactory.java         | 12 ++++++------
 .../transform/TestChildDocTransformerHierarchy.java   | 19 +++++++++++++++++--
 solr/solr-ref-guide/src/solr-upgrade-notes.adoc       |  6 ++++++
 4 files changed, 32 insertions(+), 8 deletions(-)

diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index affca8b..d144204 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -54,6 +54,9 @@ Improvements
 
 * SOLR-15337: Avoid XPath in solrconfig.xml parsing (noble)
 
+* SOLR-15156: [child] doc transformer's childFilter param no longer applies query syntax escaping.
+  It was inconsistent with other Solr options.  It did this escaping since 8.0 but not prior.  (David Smiley)
+
 Optimizations
 ---------------------
 * SOLR-15079: Block Collapse - Faster collapse code when groups are co-located via Block Join style nested doc indexing.
diff --git a/solr/core/src/java/org/apache/solr/response/transform/ChildDocTransformerFactory.java b/solr/core/src/java/org/apache/solr/response/transform/ChildDocTransformerFactory.java
index 652a104..c35f398 100644
--- a/solr/core/src/java/org/apache/solr/response/transform/ChildDocTransformerFactory.java
+++ b/solr/core/src/java/org/apache/solr/response/transform/ChildDocTransformerFactory.java
@@ -145,24 +145,24 @@ public class ChildDocTransformerFactory extends TransformerFactory {
     try {
       return QParser.getParser(qstr, req).getQuery();
     } catch (SyntaxError syntaxError) {
-      throw new SolrException(ErrorCode.BAD_REQUEST, "Failed to parse '" + param + "' param.");
+      throw new SolrException(
+              ErrorCode.BAD_REQUEST,
+              "Failed to parse '" + param + "' param: " + syntaxError.getMessage(),
+              syntaxError);
     }
   }
 
-  // NOTE: THIS FEATURE IS PRESENTLY EXPERIMENTAL; WAIT TO SEE IT IN THE REF GUIDE.  FINAL SYNTAX IS TBD.
   protected static String processPathHierarchyQueryString(String queryString) {
     // if the filter includes a path string, build a lucene query string to match those specific child documents.
     // e.g. /toppings/ingredients/name_s:cocoa -> +_nest_path_:/toppings/ingredients +(name_s:cocoa)
     // ingredients/name_s:cocoa -> +_nest_path_:*/ingredients +(name_s:cocoa)
     int indexOfFirstColon = queryString.indexOf(':');
     if (indexOfFirstColon <= 0) {
-      return queryString;// give up
+      return queryString; // regular filter, not hierarchy based.
     }
     int indexOfLastPathSepChar = queryString.lastIndexOf(PATH_SEP_CHAR, indexOfFirstColon);
     if (indexOfLastPathSepChar < 0) {
-      // regular filter, not hierarchy based.
-      return ClientUtils.escapeQueryChars(queryString.substring(0, indexOfFirstColon))
-          + ":" + ClientUtils.escapeQueryChars(queryString.substring(indexOfFirstColon + 1));
+      return queryString; // regular filter, not hierarchy based.
     }
     final boolean isAbsolutePath = queryString.charAt(0) == PATH_SEP_CHAR;
     String path = ClientUtils.escapeQueryChars(queryString.substring(0, indexOfLastPathSepChar));
diff --git a/solr/core/src/test/org/apache/solr/response/transform/TestChildDocTransformerHierarchy.java b/solr/core/src/test/org/apache/solr/response/transform/TestChildDocTransformerHierarchy.java
index 02c1aca..f135523 100644
--- a/solr/core/src/test/org/apache/solr/response/transform/TestChildDocTransformerHierarchy.java
+++ b/solr/core/src/test/org/apache/solr/response/transform/TestChildDocTransformerHierarchy.java
@@ -76,6 +76,21 @@ public class TestChildDocTransformerHierarchy extends SolrTestCaseJ4 {
   }
 
   @Test
+  public void testNonTrivialChildFilter() throws Exception {
+    // just check we don't throw an exception. This used to throw before SOLR-15152
+    assertQ(
+            req(
+                    "q",
+                    "*:*",
+                    "sort",
+                    "id asc",
+                    "fl",
+                    "*, _nest_path_, [child childFilter='type_s:Regular OR type_s:Chocolate']",
+                    "fq",
+                    fqToExcludeNonTestedDocs));
+  }
+
+  @Test
   public void testParentFilterJSON() throws Exception {
     indexSampleData(numberOfDocsPerNestedTest);
     String[] tests = new String[] {
@@ -111,7 +126,7 @@ public class TestChildDocTransformerHierarchy extends SolrTestCaseJ4 {
   public void testParentFilterLimitJSON() throws Exception {
     indexSampleData(numberOfDocsPerNestedTest);
 
-    try(SolrQueryRequest req = req("q", "type_s:donut", "sort", "id asc", "fl", "id, type_s, toppings, _nest_path_, [child childFilter='_nest_path_:/toppings' limit=1]",
+    try(SolrQueryRequest req = req("q", "type_s:donut", "sort", "id asc", "fl", "id, type_s, toppings, _nest_path_, [child childFilter='{!field f=_nest_path_}/toppings' limit=1]",
         "fq", fqToExcludeNonTestedDocs)) {
       BasicResultContext res = (BasicResultContext) h.queryAndResponse("/select", req).getResponse();
       Iterator<SolrDocument> docsStreamer = res.getProcessedDocuments();
@@ -158,7 +173,7 @@ public class TestChildDocTransformerHierarchy extends SolrTestCaseJ4 {
     assertU(delQ("_nest_path_:\\/toppings"));
     assertU(commit());
 
-    try(SolrQueryRequest req = req("q", "type_s:donut", "sort", "id asc", "fl", "id, type_s, toppings, _nest_path_, [child childFilter='_nest_path_:/toppings' limit=1]",
+    try(SolrQueryRequest req = req("q", "type_s:donut", "sort", "id asc", "fl", "id, type_s, toppings, _nest_path_, [child childFilter='_nest_path_:\\\\/toppings' limit=1]",
         "fq", fqToExcludeNonTestedDocs)) {
       BasicResultContext res = (BasicResultContext) h.queryAndResponse("/select", req).getResponse();
       Iterator<SolrDocument> docsStreamer = res.getProcessedDocuments();
diff --git a/solr/solr-ref-guide/src/solr-upgrade-notes.adoc b/solr/solr-ref-guide/src/solr-upgrade-notes.adoc
index 28fd4bd..05ad698 100644
--- a/solr/solr-ref-guide/src/solr-upgrade-notes.adoc
+++ b/solr/solr-ref-guide/src/solr-upgrade-notes.adoc
@@ -45,6 +45,12 @@ When upgrading to 8.9.x users should be aware of the following major changes fro
 
 * When using EmbeddedSolrServer, it will no longer close CoreContainer instances that were passed to it.
 
+*Nested Docs*
+
+* Child Doc Transformer's `childFilter` param no longer applies query syntax
+escaping because it's inconsistent with the rest of Solr and was limiting.  This refers to `[child childFilter='field:value']`.
+There was no escaping here prior to 8.0 either.
+
 === Solr 8.8
 
 See the https://cwiki.apache.org/confluence/display/SOLR/ReleaseNote88[8.8 Release Notes^]