You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ho...@apache.org on 2020/08/22 00:32:48 UTC
[lucene-solr] 01/02: Demonstrate equivilence of more compact syntax
w/o param refs (that requires careful escaping of nest path '/' chars)
This is an automated email from the ASF dual-hosted git repository.
hossman pushed a commit to branch jira/SOLR-14383
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git
commit 0e026d6357a53e7e32cdc0b5f413a74931202e0d
Author: Chris Hostetter <ho...@apache.org>
AuthorDate: Fri Aug 21 10:44:14 2020 -0700
Demonstrate equivilence of more compact syntax w/o param refs (that requires careful escaping of nest path '/' chars)
---
.../test-files/solr/collection1/conf/schema15.xml | 2 +
.../org/apache/solr/search/QueryEqualityTest.java | 65 ++++++++++++++++------
.../solr/update/TestNestedUpdateProcessor.java | 61 +++++++++++++++-----
3 files changed, 98 insertions(+), 30 deletions(-)
diff --git a/solr/core/src/test-files/solr/collection1/conf/schema15.xml b/solr/core/src/test-files/solr/collection1/conf/schema15.xml
index c2a8bbb..b585df5 100644
--- a/solr/core/src/test-files/solr/collection1/conf/schema15.xml
+++ b/solr/core/src/test-files/solr/collection1/conf/schema15.xml
@@ -560,6 +560,8 @@
<field name="_version_" type="long" indexed="false" stored="false" docValues="true"/>
<!-- points to the root document of a block of nested documents -->
<field name="_root_" type="string" indexed="true" stored="true"/>
+ <!-- for nested documents (relationship tracking) -->
+ <field name="_nest_path_" type="_nest_path_" /><fieldType name="_nest_path_" class="solr.NestPathField" />
<field name="multi_int_with_docvals" type="tint" multiValued="true" docValues="true" indexed="false"/>
diff --git a/solr/core/src/test/org/apache/solr/search/QueryEqualityTest.java b/solr/core/src/test/org/apache/solr/search/QueryEqualityTest.java
index 419619d..1d65406 100644
--- a/solr/core/src/test/org/apache/solr/search/QueryEqualityTest.java
+++ b/solr/core/src/test/org/apache/solr/search/QueryEqualityTest.java
@@ -523,25 +523,56 @@ public class QueryEqualityTest extends SolrTestCaseJ4 {
assertQueryEquals(null, "{!parent which='+*:* -foo_s:parent'}",
"{!child of=foo_s:parent}");
- final SolrQueryRequest req = req(
- "fq","bar_s:baz","fq","{!tag=fqban}bar_s:ban",
- "ffq","bar_s:baz","ffq","{!tag=ffqban}bar_s:ban");
- try {
- assertQueryEquals("filters", req,
- "{!parent which=foo_s:parent param=$fq}foo_s:bar",
- "{!parent which=foo_s:parent param=$ffq}foo_s:bar" // differently named params
- );
- assertQueryEquals("filters", req,
- "{!parent which=foo_s:parent param=$fq excludeTags=fqban}foo_s:bar",
- "{!parent which=foo_s:parent param=$ffq excludeTags=ffqban}foo_s:bar" // differently named params
- );
+ try (SolrQueryRequest req = req("fq","bar_s:baz","fq","{!tag=fqban}bar_s:ban",
+ "ffq","bar_s:baz","ffq","{!tag=ffqban}bar_s:ban")) {
+ assertQueryEquals("filters", req,
+ "{!parent which=foo_s:parent param=$fq}foo_s:bar",
+ "{!parent which=foo_s:parent param=$ffq}foo_s:bar" // differently named params
+ );
+ assertQueryEquals("filters", req,
+ "{!parent which=foo_s:parent param=$fq excludeTags=fqban}foo_s:bar",
+ "{!parent which=foo_s:parent param=$ffq excludeTags=ffqban}foo_s:bar" // differently named params
+ );
+
+ QueryUtils.checkUnequal(// parent filter is not an equal to child
+ QParser.getParser("{!child of=foo_s:parent}", req).getQuery(),
+ QParser.getParser("{!parent which=foo_s:parent}", req).getQuery());
+ }
- QueryUtils.checkUnequal(// parent filter is not an equal to child
- QParser.getParser("{!child of=foo_s:parent}", req).getQuery(),
- QParser.getParser("{!parent which=foo_s:parent}", req).getQuery());
+ // sanity check multiple ways of specifing _nest_path_ prefixes
+ final String parent_path = "/aa/bb";
+ try (SolrQueryRequest req = req("parent_filt", "(*:* -{!prefix f='_nest_path_' v='"+parent_path+"/'})",
+ "child_q", "(+foo +{!prefix f='_nest_path_' v='"+parent_path+"/'})",
+ "parent_q", "(+bar +{!field f='_nest_path_' v='"+parent_path+"'})")) {
+
+ assertQueryEquals("parent", req,
+
+ // using local params to refer to other query params using 'prefix' parser...
+ "{!parent which=$parent_filt v=$child_q}",
+
+ // using 'inline' prefix query syntax...
+ //
+ // '/' has to be escaped other wise it will be treated as a regex query...
+ // ...and when used inside the 'which' param it has to be escaped *AGAIN* because of
+ // the "quoted" localparam evaluation layer...
+ // (and of course '\' escaping is the java syntax as well, we have to double it)
+ "{!parent which='*:* -_nest_path_:"+(parent_path + "/").replace("/","\\\\/") +"*'}"
+ + "(+foo +_nest_path_:" + (parent_path + "/").replace("/", "\\/") + "*)");
+
+ assertQueryEquals("child", req,
+
+ // using local params to refer to other query params using 'prefix' parser...
+ "{!child of=$parent_filt v=$parent_q}",
+
+ // using 'inline' prefix query syntax...
+ //
+ // '/' has to be escaped other wise it will be treated as a regex query...
+ // ...and when used inside the 'which' param it has to be escaped *AGAIN* because of
+ // the "quoted" localparam evaluation layer...
+ // (and of course '\' escaping is the java syntax as well, we have to double it)
+ "{!child of='*:* -_nest_path_:"+(parent_path + "/").replace("/","\\\\/") +"*'}"
+ + "(+bar +_nest_path_:" + parent_path.replace("/", "\\/") + ")");
- } finally {
- req.close();
}
}
diff --git a/solr/core/src/test/org/apache/solr/update/TestNestedUpdateProcessor.java b/solr/core/src/test/org/apache/solr/update/TestNestedUpdateProcessor.java
index 83305a8..a3844ad 100644
--- a/solr/core/src/test/org/apache/solr/update/TestNestedUpdateProcessor.java
+++ b/solr/core/src/test/org/apache/solr/update/TestNestedUpdateProcessor.java
@@ -450,15 +450,32 @@ public class TestNestedUpdateProcessor extends SolrTestCaseJ4 {
*/
private SolrParams parentQueryMaker(String parent_path, String inner_child_query) {
assertValidPathSytax(parent_path);
-
+ final boolean verbose = random().nextBoolean();
+
if (parent_path.equals("/")) {
- return params("q", "{!parent which=$parent_filt v=$child_q}",
- "parent_filt", "(*:* -_nest_path_:*)",
- "child_q", "(+" + inner_child_query + " +_nest_path_:*)");
+ if (verbose) {
+ return params("q", "{!parent which=$parent_filt v=$child_q}",
+ "parent_filt", "(*:* -_nest_path_:*)",
+ "child_q", "(+" + inner_child_query + " +_nest_path_:*)");
+ } else {
+ return params("q", "{!parent which='(*:* -_nest_path_:*)'}(+" + inner_child_query + " +_nest_path_:*)");
+ }
} // else...
- return params("q", "{!parent which=$parent_filt v=$child_q})",
- "parent_filt", "(*:* -{!prefix f='_nest_path_' v='"+parent_path+"/'})",
- "child_q", "(+" + inner_child_query + " +{!prefix f='_nest_path_' v='"+parent_path+"/'})");
+
+ if (verbose) {
+ final String path = parent_path + "/";
+ return params("q", "{!parent which=$parent_filt v=$child_q}",
+ "parent_filt", "(*:* -{!prefix f='_nest_path_' v='"+path+"'})",
+ "child_q", "(+" + inner_child_query + " +{!prefix f='_nest_path_' v='"+path+"'})");
+ } else {
+ // '/' has to be escaped other wise it will be treated as a regex query...
+ // (and of course '\' escaping is the java syntax as well, we have to double it)
+ final String path = (parent_path + "/").replace("/", "\\/");
+ // ...and when used inside the 'which' param it has to be escaped *AGAIN* because of
+ // the "quoted" localparam evaluation layer...
+ return params("q", "{!parent which='(*:* -_nest_path_:" + path.replace("\\/","\\\\/") + "*)'}"
+ + "(+" + inner_child_query + " +_nest_path_:" + path + "*)");
+ }
}
/**
@@ -503,14 +520,32 @@ public class TestNestedUpdateProcessor extends SolrTestCaseJ4 {
*/
private SolrParams childQueryMaker(String parent_path, String inner_parent_query) {
assertValidPathSytax(parent_path);
+ final boolean verbose = random().nextBoolean();
+
if (parent_path.equals("/")) {
- return params("q", "{!child of=$parent_filt v=$parent_q})",
- "parent_filt", "(*:* -_nest_path_:*)",
- "parent_q", "(+" + inner_parent_query + " -_nest_path_:*)");
+ if (verbose) {
+ return params("q", "{!child of=$parent_filt v=$parent_q})",
+ "parent_filt", "(*:* -_nest_path_:*)",
+ "parent_q", "(+" + inner_parent_query + " -_nest_path_:*)");
+ } else {
+ return params("q", "{!child of='(*:* -_nest_path_:*)'}(+" + inner_parent_query + " -_nest_path_:*)");
+ }
} // else...
- return params("q", "{!child of=$parent_filt v=$parent_q})",
- "parent_filt", "(*:* -{!prefix f='_nest_path_' v='"+parent_path+"/'})",
- "parent_q", "(+" + inner_parent_query + " +{!field f='_nest_path_' v='"+parent_path+"'})");
+
+ if (verbose) {
+ return params("q", "{!child of=$parent_filt v=$parent_q})",
+ "parent_filt", "(*:* -{!prefix f='_nest_path_' v='"+parent_path+"/'})",
+ "parent_q", "(+" + inner_parent_query + " +{!field f='_nest_path_' v='"+parent_path+"'})");
+ } else {
+ // '/' has to be escaped other wise it will be treated as a regex query...
+ // (and of course '\' escaping is the java syntax as well, we have to double it)
+ final String exact_path = parent_path.replace("/", "\\/");
+ // ...and when used inside the 'which' param it has to be escaped *AGAIN* because of
+ // the "quoted" localparam evaluation layer...
+ final String prefix_path = (parent_path + "/").replace("/","\\\\/");
+ return params("q", "{!child of='(*:* -_nest_path_:"+prefix_path+"*)'}"
+ + "(+" + inner_parent_query + " +_nest_path_:" + exact_path + ")");
+ }
}
private void assertValidPathSytax(String path) {