You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by sa...@apache.org on 2017/05/14 15:38:24 UTC
[1/3] lucene-solr:master: LUCENE-7821: The classic and flexible query
parsers, as well as Solr's 'lucene'/standard query parser,
should require ' TO ' in range queries,
and accept 'TO' as endpoints in range queries.
Repository: lucene-solr
Updated Branches:
refs/heads/branch_6_6 4b93c62d2 -> b172ceb14
refs/heads/branch_6x ee70e1e4c -> 8633f49dc
refs/heads/master 9fa04ecc9 -> e11bc0309
LUCENE-7821: The classic and flexible query parsers, as well as Solr's 'lucene'/standard query parser, should require ' TO ' in range queries, and accept 'TO' as endpoints in range queries.
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/e11bc030
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/e11bc030
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/e11bc030
Branch: refs/heads/master
Commit: e11bc030987b33faadf42f0b2fb21d521077f361
Parents: 9fa04ec
Author: Steve Rowe <sa...@apache.org>
Authored: Sun May 14 11:31:22 2017 -0400
Committer: Steve Rowe <sa...@apache.org>
Committed: Sun May 14 11:31:22 2017 -0400
----------------------------------------------------------------------
lucene/CHANGES.txt | 4 ++
.../lucene/queryparser/classic/QueryParser.java | 47 +++++++++---------
.../lucene/queryparser/classic/QueryParser.jj | 6 +--
.../standard/parser/StandardSyntaxParser.java | 43 ++++++++---------
.../standard/parser/StandardSyntaxParser.jj | 6 +--
.../queryparser/util/QueryParserTestBase.java | 51 ++++++++++++++++++++
solr/CHANGES.txt | 3 ++
.../org/apache/solr/parser/QueryParser.java | 47 +++++++++---------
.../java/org/apache/solr/parser/QueryParser.jj | 6 +--
.../org/apache/solr/search/TestRangeQuery.java | 42 ++++++++++++++++
10 files changed, 176 insertions(+), 79 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e11bc030/lucene/CHANGES.txt
----------------------------------------------------------------------
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index a57d67b..10c46cf 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -126,6 +126,10 @@ Bug Fixes
* LUCENE-5365, LUCENE-7818: Fix incorrect condition in queryparser's
QueryNodeOperation#logicalAnd(). (Olivier Binda, Amrit Sarkar,
AppChecker via Uwe Schindler)
+
+* LUCENE-7821: The classic and flexible query parsers, as well as Solr's
+ "lucene"/standard query parser, should require " TO " in range queries,
+ and accept "TO" as endpoints in range queries. (hossman, Steve Rowe)
Improvements
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e11bc030/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.java
index 5e5d57b..134ddfa 100644
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.java
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.java
@@ -490,19 +490,15 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
case RANGE_QUOTED:
goop1 = jj_consume_token(RANGE_QUOTED);
break;
+ case RANGE_TO:
+ goop1 = jj_consume_token(RANGE_TO);
+ break;
default:
jj_la1[16] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case RANGE_TO:
- jj_consume_token(RANGE_TO);
- break;
- default:
- jj_la1[17] = jj_gen;
- ;
- }
+ jj_consume_token(RANGE_TO);
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case RANGE_GOOP:
goop2 = jj_consume_token(RANGE_GOOP);
@@ -510,8 +506,11 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
case RANGE_QUOTED:
goop2 = jj_consume_token(RANGE_QUOTED);
break;
+ case RANGE_TO:
+ goop2 = jj_consume_token(RANGE_TO);
+ break;
default:
- jj_la1[18] = jj_gen;
+ jj_la1[17] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
@@ -524,7 +523,7 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
jj_consume_token(RANGEEX_END);
break;
default:
- jj_la1[19] = jj_gen;
+ jj_la1[18] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
@@ -534,7 +533,7 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
boost = jj_consume_token(NUMBER);
break;
default:
- jj_la1[20] = jj_gen;
+ jj_la1[19] = jj_gen;
;
}
boolean startOpen=false;
@@ -566,7 +565,7 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
fuzzy=true;
break;
default:
- jj_la1[21] = jj_gen;
+ jj_la1[20] = jj_gen;
;
}
break;
@@ -579,24 +578,24 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
boost = jj_consume_token(NUMBER);
break;
default:
- jj_la1[22] = jj_gen;
+ jj_la1[21] = jj_gen;
;
}
break;
default:
- jj_la1[23] = jj_gen;
+ jj_la1[22] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
break;
default:
- jj_la1[24] = jj_gen;
+ jj_la1[23] = jj_gen;
;
}
q = handleQuotedTerm(field, term, fuzzySlop);
break;
default:
- jj_la1[25] = jj_gen;
+ jj_la1[24] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
@@ -732,7 +731,7 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
private boolean jj_lookingAhead = false;
private boolean jj_semLA;
private int jj_gen;
- final private int[] jj_la1 = new int[26];
+ final private int[] jj_la1 = new int[25];
static private int[] jj_la1_0;
static private int[] jj_la1_1;
static {
@@ -740,10 +739,10 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
jj_la1_init_1();
}
private static void jj_la1_init_0() {
- jj_la1_0 = new int[] {0x300,0x300,0x1c00,0x1c00,0xfda7c00,0xfda7f00,0xfda7f00,0x120000,0x40000,0xfda6000,0x9d22000,0x200000,0x40000,0x240000,0x240000,0x6000000,0x80000000,0x10000000,0x80000000,0x60000000,0x40000,0x200000,0x40000,0x240000,0x240000,0xfda2000,};
+ jj_la1_0 = new int[] {0x300,0x300,0x1c00,0x1c00,0xfda7c00,0xfda7f00,0xfda7f00,0x120000,0x40000,0xfda6000,0x9d22000,0x200000,0x40000,0x240000,0x240000,0x6000000,0x90000000,0x90000000,0x60000000,0x40000,0x200000,0x40000,0x240000,0x240000,0xfda2000,};
}
private static void jj_la1_init_1() {
- jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,};
+ jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,};
}
final private JJCalls[] jj_2_rtns = new JJCalls[3];
private boolean jj_rescan = false;
@@ -755,7 +754,7 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 26; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 25; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -766,7 +765,7 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
jj_ntk = -1;
jj_lookingAhead = false;
jj_gen = 0;
- for (int i = 0; i < 26; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 25; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -776,7 +775,7 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 26; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 25; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -786,7 +785,7 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 26; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 25; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -903,7 +902,7 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
la1tokens[jj_kind] = true;
jj_kind = -1;
}
- for (int i = 0; i < 26; i++) {
+ for (int i = 0; i < 25; i++) {
if (jj_la1[i] == jj_gen) {
for (int j = 0; j < 32; j++) {
if ((jj_la1_0[i] & (1<<j)) != 0) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e11bc030/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.jj
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.jj b/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.jj
index 35cbe1a..2d280d1 100644
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.jj
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.jj
@@ -341,9 +341,9 @@ Query Term(String field) : {
{ q = handleBareTokenQuery(field, term, fuzzySlop, prefix, wildcard, fuzzy, regexp); }
| ( <RANGEIN_START> { startInc = true; } | <RANGEEX_START> )
- ( goop1=<RANGE_GOOP> | goop1=<RANGE_QUOTED> )
- [ <RANGE_TO> ]
- ( goop2=<RANGE_GOOP> | goop2=<RANGE_QUOTED> )
+ ( goop1=<RANGE_GOOP> | goop1=<RANGE_QUOTED> | goop1=<RANGE_TO> )
+ ( <RANGE_TO> )
+ ( goop2=<RANGE_GOOP> | goop2=<RANGE_QUOTED> | goop2=<RANGE_TO> )
( <RANGEIN_END> { endInc = true; } | <RANGEEX_END> )
[ <CARAT> boost=<NUMBER> ]
{
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e11bc030/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.java
index 8ba34a6..6008bcc 100644
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.java
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.java
@@ -577,19 +577,15 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
case RANGE_QUOTED:
goop1 = jj_consume_token(RANGE_QUOTED);
break;
+ case RANGE_TO:
+ goop1 = jj_consume_token(RANGE_TO);
+ break;
default:
jj_la1[18] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case RANGE_TO:
- jj_consume_token(RANGE_TO);
- break;
- default:
- jj_la1[19] = jj_gen;
- ;
- }
+ jj_consume_token(RANGE_TO);
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case RANGE_GOOP:
goop2 = jj_consume_token(RANGE_GOOP);
@@ -597,8 +593,11 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
case RANGE_QUOTED:
goop2 = jj_consume_token(RANGE_QUOTED);
break;
+ case RANGE_TO:
+ goop2 = jj_consume_token(RANGE_TO);
+ break;
default:
- jj_la1[20] = jj_gen;
+ jj_la1[19] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
@@ -611,7 +610,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
jj_consume_token(RANGEEX_END);
break;
default:
- jj_la1[21] = jj_gen;
+ jj_la1[20] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
@@ -621,7 +620,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
boost = jj_consume_token(NUMBER);
break;
default:
- jj_la1[22] = jj_gen;
+ jj_la1[21] = jj_gen;
;
}
if (goop1.kind == RANGE_QUOTED) {
@@ -645,7 +644,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
fuzzySlop = jj_consume_token(FUZZY_SLOP);
break;
default:
- jj_la1[23] = jj_gen;
+ jj_la1[22] = jj_gen;
;
}
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
@@ -654,7 +653,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
boost = jj_consume_token(NUMBER);
break;
default:
- jj_la1[24] = jj_gen;
+ jj_la1[23] = jj_gen;
;
}
int phraseSlop = 0;
@@ -672,7 +671,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
}
break;
default:
- jj_la1[25] = jj_gen;
+ jj_la1[24] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
@@ -831,7 +830,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
private Token jj_scanpos, jj_lastpos;
private int jj_la;
private int jj_gen;
- final private int[] jj_la1 = new int[26];
+ final private int[] jj_la1 = new int[25];
static private int[] jj_la1_0;
static private int[] jj_la1_1;
static {
@@ -839,10 +838,10 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
jj_la1_init_1();
}
private static void jj_la1_init_0() {
- jj_la1_0 = new int[] {0x1c00,0x1c00,0x1ec03c00,0x200,0x100,0x18000,0x1e0000,0x10c00000,0x1f8000,0x18000,0x200000,0x1ec02000,0x1ec02000,0x12800000,0x1000000,0x1000000,0x200000,0xc000000,0x0,0x20000000,0x0,0xc0000000,0x200000,0x1000000,0x200000,0x1ec00000,};
+ jj_la1_0 = new int[] {0x1c00,0x1c00,0x1ec03c00,0x200,0x100,0x18000,0x1e0000,0x10c00000,0x1f8000,0x18000,0x200000,0x1ec02000,0x1ec02000,0x12800000,0x1000000,0x1000000,0x200000,0xc000000,0x20000000,0x20000000,0xc0000000,0x200000,0x1000000,0x200000,0x1ec00000,};
}
private static void jj_la1_init_1() {
- jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x3,0x0,0x0,0x0,0x0,0x0,};
+ jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x3,0x0,0x0,0x0,0x0,0x0,};
}
final private JJCalls[] jj_2_rtns = new JJCalls[2];
private boolean jj_rescan = false;
@@ -854,7 +853,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 26; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 25; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -864,7 +863,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 26; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 25; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -874,7 +873,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 26; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 25; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -884,7 +883,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 26; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 25; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -1001,7 +1000,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
la1tokens[jj_kind] = true;
jj_kind = -1;
}
- for (int i = 0; i < 26; i++) {
+ for (int i = 0; i < 25; i++) {
if (jj_la1[i] == jj_gen) {
for (int j = 0; j < 32; j++) {
if ((jj_la1_0[i] & (1<<j)) != 0) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e11bc030/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.jj
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.jj b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.jj
index b53bab3..8803618 100644
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.jj
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.jj
@@ -445,9 +445,9 @@ QueryNode Term(CharSequence field) : {
}
}
| ( ( <RANGEIN_START> {startInc=true;} | <RANGEEX_START> )
- ( goop1=<RANGE_GOOP>|goop1=<RANGE_QUOTED> )
- [ <RANGE_TO> ]
- ( goop2=<RANGE_GOOP>|goop2=<RANGE_QUOTED> )
+ ( goop1=<RANGE_GOOP>|goop1=<RANGE_QUOTED>|goop1=<RANGE_TO> )
+ ( <RANGE_TO> )
+ ( goop2=<RANGE_GOOP>|goop2=<RANGE_QUOTED>|goop2=<RANGE_TO> )
( <RANGEIN_END> {endInc=true;} | <RANGEEX_END>))
[ <CARAT> boost=<NUMBER> ]
{
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e11bc030/lucene/queryparser/src/test/org/apache/lucene/queryparser/util/QueryParserTestBase.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/test/org/apache/lucene/queryparser/util/QueryParserTestBase.java b/lucene/queryparser/src/test/org/apache/lucene/queryparser/util/QueryParserTestBase.java
index 1b8ee96..b49f576 100644
--- a/lucene/queryparser/src/test/org/apache/lucene/queryparser/util/QueryParserTestBase.java
+++ b/lucene/queryparser/src/test/org/apache/lucene/queryparser/util/QueryParserTestBase.java
@@ -41,6 +41,7 @@ import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.queryparser.classic.QueryParserBase;
//import org.apache.lucene.queryparser.classic.QueryParserTokenManager;
+import org.apache.lucene.queryparser.classic.TestQueryParser;
import org.apache.lucene.queryparser.flexible.standard.CommonQueryParserConfiguration;
import org.apache.lucene.search.*;
import org.apache.lucene.search.BooleanClause.Occur;
@@ -594,6 +595,56 @@ public abstract class QueryParserTestBase extends LuceneTestCase {
assertQueryEquals("[\"*\" TO *]",null,"[\\* TO *]");
}
+ public void testRangeQueryEndpointTO() throws Exception {
+ Analyzer a = new MockAnalyzer(random());
+ assertQueryEquals("[to TO to]", a, "[to TO to]");
+ assertQueryEquals("[to TO TO]", a, "[to TO to]");
+ assertQueryEquals("[TO TO to]", a, "[to TO to]");
+ assertQueryEquals("[TO TO TO]", a, "[to TO to]");
+
+ assertQueryEquals("[\"TO\" TO \"TO\"]", a, "[to TO to]");
+ assertQueryEquals("[\"TO\" TO TO]", a, "[to TO to]");
+ assertQueryEquals("[TO TO \"TO\"]", a, "[to TO to]");
+
+ assertQueryEquals("[to TO xx]", a, "[to TO xx]");
+ assertQueryEquals("[\"TO\" TO xx]", a, "[to TO xx]");
+ assertQueryEquals("[TO TO xx]", a, "[to TO xx]");
+
+ assertQueryEquals("[xx TO to]", a, "[xx TO to]");
+ assertQueryEquals("[xx TO \"TO\"]", a, "[xx TO to]");
+ assertQueryEquals("[xx TO TO]", a, "[xx TO to]");
+ }
+
+ public void testRangeQueryRequiresTO() throws Exception {
+ Analyzer a = new MockAnalyzer(random());
+
+ assertQueryEquals("{A TO B}", a, "{a TO b}");
+ assertQueryEquals("[A TO B}", a, "[a TO b}");
+ assertQueryEquals("{A TO B]", a, "{a TO b]");
+ assertQueryEquals("[A TO B]", a, "[a TO b]");
+
+ // " TO " is required between range endpoints
+
+ Class<? extends Throwable> exceptionClass = this instanceof TestQueryParser
+ ? org.apache.lucene.queryparser.classic.ParseException.class
+ : org.apache.lucene.queryparser.flexible.standard.parser.ParseException.class;
+
+ expectThrows(exceptionClass, () -> getQuery("{A B}"));
+ expectThrows(exceptionClass, () -> getQuery("[A B}"));
+ expectThrows(exceptionClass, () -> getQuery("{A B]"));
+ expectThrows(exceptionClass, () -> getQuery("[A B]"));
+
+ expectThrows(exceptionClass, () -> getQuery("{TO B}"));
+ expectThrows(exceptionClass, () -> getQuery("[TO B}"));
+ expectThrows(exceptionClass, () -> getQuery("{TO B]"));
+ expectThrows(exceptionClass, () -> getQuery("[TO B]"));
+
+ expectThrows(exceptionClass, () -> getQuery("{A TO}"));
+ expectThrows(exceptionClass, () -> getQuery("[A TO}"));
+ expectThrows(exceptionClass, () -> getQuery("{A TO]"));
+ expectThrows(exceptionClass, () -> getQuery("[A TO]"));
+ }
+
private String escapeDateString(String s) {
if (s.indexOf(" ") > -1) {
return "\"" + s + "\"";
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e11bc030/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index c5c41c2..a3b5515 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -370,6 +370,9 @@ Bug Fixes
* SOLR-9527: Improve distribution of replicas when restoring a collection
(Hrishikesh Gadre, Stephen Lewis, Rohit, Varun Thacker)
+* LUCENE-7821: The classic and flexible query parsers, as well as Solr's
+ "lucene"/standard query parser, should require " TO " in range queries,
+ and accept "TO" as endpoints in range queries. (hossman, Steve Rowe)
Other Changes
----------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e11bc030/solr/core/src/java/org/apache/solr/parser/QueryParser.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/parser/QueryParser.java b/solr/core/src/java/org/apache/solr/parser/QueryParser.java
index 39ec673..42e982f 100644
--- a/solr/core/src/java/org/apache/solr/parser/QueryParser.java
+++ b/solr/core/src/java/org/apache/solr/parser/QueryParser.java
@@ -441,19 +441,15 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
case RANGE_QUOTED:
goop1 = jj_consume_token(RANGE_QUOTED);
break;
+ case RANGE_TO:
+ goop1 = jj_consume_token(RANGE_TO);
+ break;
default:
jj_la1[18] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case RANGE_TO:
- jj_consume_token(RANGE_TO);
- break;
- default:
- jj_la1[19] = jj_gen;
- ;
- }
+ jj_consume_token(RANGE_TO);
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case RANGE_GOOP:
goop2 = jj_consume_token(RANGE_GOOP);
@@ -461,8 +457,11 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
case RANGE_QUOTED:
goop2 = jj_consume_token(RANGE_QUOTED);
break;
+ case RANGE_TO:
+ goop2 = jj_consume_token(RANGE_TO);
+ break;
default:
- jj_la1[20] = jj_gen;
+ jj_la1[19] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
@@ -475,7 +474,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
jj_consume_token(RANGEEX_END);
break;
default:
- jj_la1[21] = jj_gen;
+ jj_la1[20] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
@@ -485,7 +484,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
boost = jj_consume_token(NUMBER);
break;
default:
- jj_la1[22] = jj_gen;
+ jj_la1[21] = jj_gen;
;
}
boolean startOpen=false;
@@ -519,7 +518,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
fuzzy=true;
break;
default:
- jj_la1[23] = jj_gen;
+ jj_la1[22] = jj_gen;
;
}
break;
@@ -532,24 +531,24 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
boost = jj_consume_token(NUMBER);
break;
default:
- jj_la1[24] = jj_gen;
+ jj_la1[23] = jj_gen;
;
}
break;
default:
- jj_la1[25] = jj_gen;
+ jj_la1[24] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
break;
default:
- jj_la1[26] = jj_gen;
+ jj_la1[25] = jj_gen;
;
}
q = handleQuotedTerm(getField(field), term, fuzzySlop);
break;
default:
- jj_la1[27] = jj_gen;
+ jj_la1[26] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
@@ -685,7 +684,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
private boolean jj_lookingAhead = false;
private boolean jj_semLA;
private int jj_gen;
- final private int[] jj_la1 = new int[28];
+ final private int[] jj_la1 = new int[27];
static private int[] jj_la1_0;
static private int[] jj_la1_1;
static {
@@ -693,10 +692,10 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
jj_la1_init_1();
}
private static void jj_la1_init_0() {
- jj_la1_0 = new int[] {0x6000,0x6000,0x38000,0x38000,0xfb4f8000,0xfb4fe000,0xfb4fe000,0x2400000,0x800000,0x800000,0x800000,0xfb4c0000,0x3a440000,0x4000000,0x800000,0x4800000,0x4800000,0xc0000000,0x0,0x0,0x0,0x0,0x800000,0x4000000,0x800000,0x4800000,0x4800000,0xfb440000,};
+ jj_la1_0 = new int[] {0x6000,0x6000,0x38000,0x38000,0xfb4f8000,0xfb4fe000,0xfb4fe000,0x2400000,0x800000,0x800000,0x800000,0xfb4c0000,0x3a440000,0x4000000,0x800000,0x4800000,0x4800000,0xc0000000,0x0,0x0,0x0,0x800000,0x4000000,0x800000,0x4800000,0x4800000,0xfb440000,};
}
private static void jj_la1_init_1() {
- jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x7,0x7,0x7,0x0,0x0,0x0,0x0,0x7,0x4,0x0,0x0,0x0,0x0,0x0,0xc0,0x8,0xc0,0x30,0x0,0x0,0x0,0x0,0x0,0x4,};
+ jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x7,0x7,0x7,0x0,0x0,0x0,0x0,0x7,0x4,0x0,0x0,0x0,0x0,0x0,0xc8,0xc8,0x30,0x0,0x0,0x0,0x0,0x0,0x4,};
}
final private JJCalls[] jj_2_rtns = new JJCalls[3];
private boolean jj_rescan = false;
@@ -708,7 +707,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 28; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 27; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -719,7 +718,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
jj_ntk = -1;
jj_lookingAhead = false;
jj_gen = 0;
- for (int i = 0; i < 28; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 27; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -729,7 +728,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 28; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 27; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -739,7 +738,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 28; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 27; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -856,7 +855,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
la1tokens[jj_kind] = true;
jj_kind = -1;
}
- for (int i = 0; i < 28; i++) {
+ for (int i = 0; i < 27; i++) {
if (jj_la1[i] == jj_gen) {
for (int j = 0; j < 32; j++) {
if ((jj_la1_0[i] & (1<<j)) != 0) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e11bc030/solr/core/src/java/org/apache/solr/parser/QueryParser.jj
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/parser/QueryParser.jj b/solr/core/src/java/org/apache/solr/parser/QueryParser.jj
index 1dfdfcb..58adcd9 100644
--- a/solr/core/src/java/org/apache/solr/parser/QueryParser.jj
+++ b/solr/core/src/java/org/apache/solr/parser/QueryParser.jj
@@ -282,9 +282,9 @@ Query Term(String field) throws SyntaxError : {
{ q = handleBareTokenQuery(getField(field), term, fuzzySlop, prefix, wildcard, fuzzy, regexp); }
| ( <RANGEIN_START> { startInc = true; } | <RANGEEX_START> )
- ( goop1=<RANGE_GOOP> | goop1=<RANGE_QUOTED> )
- [ <RANGE_TO> ]
- ( goop2=<RANGE_GOOP> | goop2=<RANGE_QUOTED> )
+ ( goop1=<RANGE_GOOP> | goop1=<RANGE_QUOTED> | goop1=<RANGE_TO> )
+ ( <RANGE_TO> )
+ ( goop2=<RANGE_GOOP> | goop2=<RANGE_QUOTED> | goop2=<RANGE_TO> )
( <RANGEIN_END> { endInc = true; } | <RANGEEX_END> )
[ <CARAT> boost=<NUMBER> ]
{
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e11bc030/solr/core/src/test/org/apache/solr/search/TestRangeQuery.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/search/TestRangeQuery.java b/solr/core/src/test/org/apache/solr/search/TestRangeQuery.java
index d2244b1..0ba716d 100644
--- a/solr/core/src/test/org/apache/solr/search/TestRangeQuery.java
+++ b/solr/core/src/test/org/apache/solr/search/TestRangeQuery.java
@@ -342,6 +342,48 @@ public class TestRangeQuery extends SolrTestCaseJ4 {
}
}
}
+
+ public void testRangeQueryEndpointTO() throws Exception {
+ assertEquals("[to TO to]", QParser.getParser("[to TO to]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[to TO to]", QParser.getParser("[to TO TO]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[to TO to]", QParser.getParser("[TO TO to]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[to TO to]", QParser.getParser("[TO TO TO]", req("df", "text")).getQuery().toString("text"));
+
+ assertEquals("[to TO to]", QParser.getParser("[\"TO\" TO \"TO\"]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[to TO to]", QParser.getParser("[\"TO\" TO TO]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[to TO to]", QParser.getParser("[TO TO \"TO\"]", req("df", "text")).getQuery().toString("text"));
+
+ assertEquals("[to TO xx]", QParser.getParser("[to TO xx]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[to TO xx]", QParser.getParser("[\"TO\" TO xx]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[to TO xx]", QParser.getParser("[TO TO xx]", req("df", "text")).getQuery().toString("text"));
+
+ assertEquals("[xx TO to]", QParser.getParser("[xx TO to]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[xx TO to]", QParser.getParser("[xx TO \"TO\"]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[xx TO to]", QParser.getParser("[xx TO TO]", req("df", "text")).getQuery().toString("text"));
+ }
+
+ public void testRangeQueryRequiresTO() throws Exception {
+ assertEquals("{a TO b}", QParser.getParser("{A TO B}", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[a TO b}", QParser.getParser("[A TO B}", req("df", "text")).getQuery().toString("text"));
+ assertEquals("{a TO b]", QParser.getParser("{A TO B]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[a TO b]", QParser.getParser("[A TO B]", req("df", "text")).getQuery().toString("text"));
+
+ // " TO " is required between range endpoints
+ expectThrows(SyntaxError.class, () -> QParser.getParser("{A B}", req("df", "text")).getQuery());
+ expectThrows(SyntaxError.class, () -> QParser.getParser("[A B}", req("df", "text")).getQuery());
+ expectThrows(SyntaxError.class, () -> QParser.getParser("{A B]", req("df", "text")).getQuery());
+ expectThrows(SyntaxError.class, () -> QParser.getParser("[A B]", req("df", "text")).getQuery());
+
+ expectThrows(SyntaxError.class, () -> QParser.getParser("{TO B}", req("df", "text")).getQuery());
+ expectThrows(SyntaxError.class, () -> QParser.getParser("[TO B}", req("df", "text")).getQuery());
+ expectThrows(SyntaxError.class, () -> QParser.getParser("{TO B]", req("df", "text")).getQuery());
+ expectThrows(SyntaxError.class, () -> QParser.getParser("[TO B]", req("df", "text")).getQuery());
+
+ expectThrows(SyntaxError.class, () -> QParser.getParser("{A TO}", req("df", "text")).getQuery());
+ expectThrows(SyntaxError.class, () -> QParser.getParser("[A TO}", req("df", "text")).getQuery());
+ expectThrows(SyntaxError.class, () -> QParser.getParser("{A TO]", req("df", "text")).getQuery());
+ expectThrows(SyntaxError.class, () -> QParser.getParser("[A TO]", req("df", "text")).getQuery());
+ }
static boolean sameDocs(String msg, DocSet a, DocSet b) {
DocIterator i = a.iterator();
[2/3] lucene-solr:branch_6x: LUCENE-7821: The classic and flexible
query parsers, as well as Solr's 'lucene'/standard query parser,
should require ' TO ' in range queries,
and accept 'TO' as endpoints in range queries.
Posted by sa...@apache.org.
LUCENE-7821: The classic and flexible query parsers, as well as Solr's 'lucene'/standard query parser, should require ' TO ' in range queries, and accept 'TO' as endpoints in range queries.
Conflicts:
solr/CHANGES.txt
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/8633f49d
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/8633f49d
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/8633f49d
Branch: refs/heads/branch_6x
Commit: 8633f49dcd1c0237fe0d6e65ea8cacd193950038
Parents: ee70e1e
Author: Steve Rowe <sa...@apache.org>
Authored: Sun May 14 11:31:22 2017 -0400
Committer: Steve Rowe <sa...@apache.org>
Committed: Sun May 14 11:36:52 2017 -0400
----------------------------------------------------------------------
lucene/CHANGES.txt | 4 ++
.../lucene/queryparser/classic/QueryParser.java | 47 +++++++++---------
.../lucene/queryparser/classic/QueryParser.jj | 6 +--
.../standard/parser/StandardSyntaxParser.java | 43 ++++++++---------
.../standard/parser/StandardSyntaxParser.jj | 6 +--
.../queryparser/util/QueryParserTestBase.java | 51 ++++++++++++++++++++
solr/CHANGES.txt | 4 ++
.../org/apache/solr/parser/QueryParser.java | 47 +++++++++---------
.../java/org/apache/solr/parser/QueryParser.jj | 6 +--
.../org/apache/solr/search/TestRangeQuery.java | 42 ++++++++++++++++
10 files changed, 177 insertions(+), 79 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8633f49d/lucene/CHANGES.txt
----------------------------------------------------------------------
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index bbb082e..fea75a0 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -37,6 +37,10 @@ Bug Fixes
* LUCENE-5365, LUCENE-7818: Fix incorrect condition in queryparser's
QueryNodeOperation#logicalAnd(). (Olivier Binda, Amrit Sarkar,
AppChecker via Uwe Schindler)
+
+* LUCENE-7821: The classic and flexible query parsers, as well as Solr's
+ "lucene"/standard query parser, should require " TO " in range queries,
+ and accept "TO" as endpoints in range queries. (hossman, Steve Rowe)
Improvements
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8633f49d/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.java
index 2410cb0..db6291a 100644
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.java
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.java
@@ -490,19 +490,15 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
case RANGE_QUOTED:
goop1 = jj_consume_token(RANGE_QUOTED);
break;
+ case RANGE_TO:
+ goop1 = jj_consume_token(RANGE_TO);
+ break;
default:
jj_la1[16] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case RANGE_TO:
- jj_consume_token(RANGE_TO);
- break;
- default:
- jj_la1[17] = jj_gen;
- ;
- }
+ jj_consume_token(RANGE_TO);
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case RANGE_GOOP:
goop2 = jj_consume_token(RANGE_GOOP);
@@ -510,8 +506,11 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
case RANGE_QUOTED:
goop2 = jj_consume_token(RANGE_QUOTED);
break;
+ case RANGE_TO:
+ goop2 = jj_consume_token(RANGE_TO);
+ break;
default:
- jj_la1[18] = jj_gen;
+ jj_la1[17] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
@@ -524,7 +523,7 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
jj_consume_token(RANGEEX_END);
break;
default:
- jj_la1[19] = jj_gen;
+ jj_la1[18] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
@@ -534,7 +533,7 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
boost = jj_consume_token(NUMBER);
break;
default:
- jj_la1[20] = jj_gen;
+ jj_la1[19] = jj_gen;
;
}
boolean startOpen=false;
@@ -566,7 +565,7 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
fuzzy=true;
break;
default:
- jj_la1[21] = jj_gen;
+ jj_la1[20] = jj_gen;
;
}
break;
@@ -579,24 +578,24 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
boost = jj_consume_token(NUMBER);
break;
default:
- jj_la1[22] = jj_gen;
+ jj_la1[21] = jj_gen;
;
}
break;
default:
- jj_la1[23] = jj_gen;
+ jj_la1[22] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
break;
default:
- jj_la1[24] = jj_gen;
+ jj_la1[23] = jj_gen;
;
}
q = handleQuotedTerm(field, term, fuzzySlop);
break;
default:
- jj_la1[25] = jj_gen;
+ jj_la1[24] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
@@ -732,7 +731,7 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
private boolean jj_lookingAhead = false;
private boolean jj_semLA;
private int jj_gen;
- final private int[] jj_la1 = new int[26];
+ final private int[] jj_la1 = new int[25];
static private int[] jj_la1_0;
static private int[] jj_la1_1;
static {
@@ -740,10 +739,10 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
jj_la1_init_1();
}
private static void jj_la1_init_0() {
- jj_la1_0 = new int[] {0x300,0x300,0x1c00,0x1c00,0xfda7c00,0xfda7f00,0xfda7f00,0x120000,0x40000,0xfda6000,0x9d22000,0x200000,0x40000,0x240000,0x240000,0x6000000,0x80000000,0x10000000,0x80000000,0x60000000,0x40000,0x200000,0x40000,0x240000,0x240000,0xfda2000,};
+ jj_la1_0 = new int[] {0x300,0x300,0x1c00,0x1c00,0xfda7c00,0xfda7f00,0xfda7f00,0x120000,0x40000,0xfda6000,0x9d22000,0x200000,0x40000,0x240000,0x240000,0x6000000,0x90000000,0x90000000,0x60000000,0x40000,0x200000,0x40000,0x240000,0x240000,0xfda2000,};
}
private static void jj_la1_init_1() {
- jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,};
+ jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,};
}
final private JJCalls[] jj_2_rtns = new JJCalls[3];
private boolean jj_rescan = false;
@@ -755,7 +754,7 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 26; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 25; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -766,7 +765,7 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
jj_ntk = -1;
jj_lookingAhead = false;
jj_gen = 0;
- for (int i = 0; i < 26; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 25; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -776,7 +775,7 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 26; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 25; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -786,7 +785,7 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 26; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 25; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -903,7 +902,7 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
la1tokens[jj_kind] = true;
jj_kind = -1;
}
- for (int i = 0; i < 26; i++) {
+ for (int i = 0; i < 25; i++) {
if (jj_la1[i] == jj_gen) {
for (int j = 0; j < 32; j++) {
if ((jj_la1_0[i] & (1<<j)) != 0) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8633f49d/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.jj
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.jj b/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.jj
index 970a055..13a6d75 100644
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.jj
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.jj
@@ -341,9 +341,9 @@ Query Term(String field) : {
{ q = handleBareTokenQuery(field, term, fuzzySlop, prefix, wildcard, fuzzy, regexp); }
| ( <RANGEIN_START> { startInc = true; } | <RANGEEX_START> )
- ( goop1=<RANGE_GOOP> | goop1=<RANGE_QUOTED> )
- [ <RANGE_TO> ]
- ( goop2=<RANGE_GOOP> | goop2=<RANGE_QUOTED> )
+ ( goop1=<RANGE_GOOP> | goop1=<RANGE_QUOTED> | goop1=<RANGE_TO> )
+ ( <RANGE_TO> )
+ ( goop2=<RANGE_GOOP> | goop2=<RANGE_QUOTED> | goop2=<RANGE_TO> )
( <RANGEIN_END> { endInc = true; } | <RANGEEX_END> )
[ <CARAT> boost=<NUMBER> ]
{
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8633f49d/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.java
index 8ba34a6..6008bcc 100644
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.java
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.java
@@ -577,19 +577,15 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
case RANGE_QUOTED:
goop1 = jj_consume_token(RANGE_QUOTED);
break;
+ case RANGE_TO:
+ goop1 = jj_consume_token(RANGE_TO);
+ break;
default:
jj_la1[18] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case RANGE_TO:
- jj_consume_token(RANGE_TO);
- break;
- default:
- jj_la1[19] = jj_gen;
- ;
- }
+ jj_consume_token(RANGE_TO);
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case RANGE_GOOP:
goop2 = jj_consume_token(RANGE_GOOP);
@@ -597,8 +593,11 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
case RANGE_QUOTED:
goop2 = jj_consume_token(RANGE_QUOTED);
break;
+ case RANGE_TO:
+ goop2 = jj_consume_token(RANGE_TO);
+ break;
default:
- jj_la1[20] = jj_gen;
+ jj_la1[19] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
@@ -611,7 +610,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
jj_consume_token(RANGEEX_END);
break;
default:
- jj_la1[21] = jj_gen;
+ jj_la1[20] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
@@ -621,7 +620,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
boost = jj_consume_token(NUMBER);
break;
default:
- jj_la1[22] = jj_gen;
+ jj_la1[21] = jj_gen;
;
}
if (goop1.kind == RANGE_QUOTED) {
@@ -645,7 +644,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
fuzzySlop = jj_consume_token(FUZZY_SLOP);
break;
default:
- jj_la1[23] = jj_gen;
+ jj_la1[22] = jj_gen;
;
}
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
@@ -654,7 +653,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
boost = jj_consume_token(NUMBER);
break;
default:
- jj_la1[24] = jj_gen;
+ jj_la1[23] = jj_gen;
;
}
int phraseSlop = 0;
@@ -672,7 +671,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
}
break;
default:
- jj_la1[25] = jj_gen;
+ jj_la1[24] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
@@ -831,7 +830,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
private Token jj_scanpos, jj_lastpos;
private int jj_la;
private int jj_gen;
- final private int[] jj_la1 = new int[26];
+ final private int[] jj_la1 = new int[25];
static private int[] jj_la1_0;
static private int[] jj_la1_1;
static {
@@ -839,10 +838,10 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
jj_la1_init_1();
}
private static void jj_la1_init_0() {
- jj_la1_0 = new int[] {0x1c00,0x1c00,0x1ec03c00,0x200,0x100,0x18000,0x1e0000,0x10c00000,0x1f8000,0x18000,0x200000,0x1ec02000,0x1ec02000,0x12800000,0x1000000,0x1000000,0x200000,0xc000000,0x0,0x20000000,0x0,0xc0000000,0x200000,0x1000000,0x200000,0x1ec00000,};
+ jj_la1_0 = new int[] {0x1c00,0x1c00,0x1ec03c00,0x200,0x100,0x18000,0x1e0000,0x10c00000,0x1f8000,0x18000,0x200000,0x1ec02000,0x1ec02000,0x12800000,0x1000000,0x1000000,0x200000,0xc000000,0x20000000,0x20000000,0xc0000000,0x200000,0x1000000,0x200000,0x1ec00000,};
}
private static void jj_la1_init_1() {
- jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x3,0x0,0x0,0x0,0x0,0x0,};
+ jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x3,0x0,0x0,0x0,0x0,0x0,};
}
final private JJCalls[] jj_2_rtns = new JJCalls[2];
private boolean jj_rescan = false;
@@ -854,7 +853,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 26; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 25; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -864,7 +863,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 26; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 25; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -874,7 +873,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 26; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 25; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -884,7 +883,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 26; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 25; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -1001,7 +1000,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
la1tokens[jj_kind] = true;
jj_kind = -1;
}
- for (int i = 0; i < 26; i++) {
+ for (int i = 0; i < 25; i++) {
if (jj_la1[i] == jj_gen) {
for (int j = 0; j < 32; j++) {
if ((jj_la1_0[i] & (1<<j)) != 0) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8633f49d/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.jj
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.jj b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.jj
index b53bab3..8803618 100644
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.jj
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.jj
@@ -445,9 +445,9 @@ QueryNode Term(CharSequence field) : {
}
}
| ( ( <RANGEIN_START> {startInc=true;} | <RANGEEX_START> )
- ( goop1=<RANGE_GOOP>|goop1=<RANGE_QUOTED> )
- [ <RANGE_TO> ]
- ( goop2=<RANGE_GOOP>|goop2=<RANGE_QUOTED> )
+ ( goop1=<RANGE_GOOP>|goop1=<RANGE_QUOTED>|goop1=<RANGE_TO> )
+ ( <RANGE_TO> )
+ ( goop2=<RANGE_GOOP>|goop2=<RANGE_QUOTED>|goop2=<RANGE_TO> )
( <RANGEIN_END> {endInc=true;} | <RANGEEX_END>))
[ <CARAT> boost=<NUMBER> ]
{
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8633f49d/lucene/queryparser/src/test/org/apache/lucene/queryparser/util/QueryParserTestBase.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/test/org/apache/lucene/queryparser/util/QueryParserTestBase.java b/lucene/queryparser/src/test/org/apache/lucene/queryparser/util/QueryParserTestBase.java
index bbececb..5ab8fb2 100644
--- a/lucene/queryparser/src/test/org/apache/lucene/queryparser/util/QueryParserTestBase.java
+++ b/lucene/queryparser/src/test/org/apache/lucene/queryparser/util/QueryParserTestBase.java
@@ -41,6 +41,7 @@ import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.queryparser.classic.QueryParserBase;
//import org.apache.lucene.queryparser.classic.QueryParserTokenManager;
+import org.apache.lucene.queryparser.classic.TestQueryParser;
import org.apache.lucene.queryparser.flexible.standard.CommonQueryParserConfiguration;
import org.apache.lucene.search.*;
import org.apache.lucene.search.BooleanClause.Occur;
@@ -619,6 +620,56 @@ public abstract class QueryParserTestBase extends LuceneTestCase {
assertQueryEquals("[\"*\" TO *]",null,"[\\* TO *]");
}
+ public void testRangeQueryEndpointTO() throws Exception {
+ Analyzer a = new MockAnalyzer(random());
+ assertQueryEquals("[to TO to]", a, "[to TO to]");
+ assertQueryEquals("[to TO TO]", a, "[to TO to]");
+ assertQueryEquals("[TO TO to]", a, "[to TO to]");
+ assertQueryEquals("[TO TO TO]", a, "[to TO to]");
+
+ assertQueryEquals("[\"TO\" TO \"TO\"]", a, "[to TO to]");
+ assertQueryEquals("[\"TO\" TO TO]", a, "[to TO to]");
+ assertQueryEquals("[TO TO \"TO\"]", a, "[to TO to]");
+
+ assertQueryEquals("[to TO xx]", a, "[to TO xx]");
+ assertQueryEquals("[\"TO\" TO xx]", a, "[to TO xx]");
+ assertQueryEquals("[TO TO xx]", a, "[to TO xx]");
+
+ assertQueryEquals("[xx TO to]", a, "[xx TO to]");
+ assertQueryEquals("[xx TO \"TO\"]", a, "[xx TO to]");
+ assertQueryEquals("[xx TO TO]", a, "[xx TO to]");
+ }
+
+ public void testRangeQueryRequiresTO() throws Exception {
+ Analyzer a = new MockAnalyzer(random());
+
+ assertQueryEquals("{A TO B}", a, "{a TO b}");
+ assertQueryEquals("[A TO B}", a, "[a TO b}");
+ assertQueryEquals("{A TO B]", a, "{a TO b]");
+ assertQueryEquals("[A TO B]", a, "[a TO b]");
+
+ // " TO " is required between range endpoints
+
+ Class<? extends Throwable> exceptionClass = this instanceof TestQueryParser
+ ? org.apache.lucene.queryparser.classic.ParseException.class
+ : org.apache.lucene.queryparser.flexible.standard.parser.ParseException.class;
+
+ expectThrows(exceptionClass, () -> getQuery("{A B}"));
+ expectThrows(exceptionClass, () -> getQuery("[A B}"));
+ expectThrows(exceptionClass, () -> getQuery("{A B]"));
+ expectThrows(exceptionClass, () -> getQuery("[A B]"));
+
+ expectThrows(exceptionClass, () -> getQuery("{TO B}"));
+ expectThrows(exceptionClass, () -> getQuery("[TO B}"));
+ expectThrows(exceptionClass, () -> getQuery("{TO B]"));
+ expectThrows(exceptionClass, () -> getQuery("[TO B]"));
+
+ expectThrows(exceptionClass, () -> getQuery("{A TO}"));
+ expectThrows(exceptionClass, () -> getQuery("[A TO}"));
+ expectThrows(exceptionClass, () -> getQuery("{A TO]"));
+ expectThrows(exceptionClass, () -> getQuery("[A TO]"));
+ }
+
private String escapeDateString(String s) {
if (s.indexOf(" ") > -1) {
return "\"" + s + "\"";
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8633f49d/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 28b9d89..918e927 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -257,6 +257,10 @@ Bug Fixes
* SOLR-9527: Improve distribution of replicas when restoring a collection
(Hrishikesh Gadre, Stephen Lewis, Rohit, Varun Thacker)
+* LUCENE-7821: The classic and flexible query parsers, as well as Solr's
+ "lucene"/standard query parser, should require " TO " in range queries,
+ and accept "TO" as endpoints in range queries. (hossman, Steve Rowe)
+
Other Changes
----------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8633f49d/solr/core/src/java/org/apache/solr/parser/QueryParser.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/parser/QueryParser.java b/solr/core/src/java/org/apache/solr/parser/QueryParser.java
index 2b64b88..7a21847 100644
--- a/solr/core/src/java/org/apache/solr/parser/QueryParser.java
+++ b/solr/core/src/java/org/apache/solr/parser/QueryParser.java
@@ -441,19 +441,15 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
case RANGE_QUOTED:
goop1 = jj_consume_token(RANGE_QUOTED);
break;
+ case RANGE_TO:
+ goop1 = jj_consume_token(RANGE_TO);
+ break;
default:
jj_la1[18] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case RANGE_TO:
- jj_consume_token(RANGE_TO);
- break;
- default:
- jj_la1[19] = jj_gen;
- ;
- }
+ jj_consume_token(RANGE_TO);
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case RANGE_GOOP:
goop2 = jj_consume_token(RANGE_GOOP);
@@ -461,8 +457,11 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
case RANGE_QUOTED:
goop2 = jj_consume_token(RANGE_QUOTED);
break;
+ case RANGE_TO:
+ goop2 = jj_consume_token(RANGE_TO);
+ break;
default:
- jj_la1[20] = jj_gen;
+ jj_la1[19] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
@@ -475,7 +474,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
jj_consume_token(RANGEEX_END);
break;
default:
- jj_la1[21] = jj_gen;
+ jj_la1[20] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
@@ -485,7 +484,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
boost = jj_consume_token(NUMBER);
break;
default:
- jj_la1[22] = jj_gen;
+ jj_la1[21] = jj_gen;
;
}
boolean startOpen=false;
@@ -519,7 +518,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
fuzzy=true;
break;
default:
- jj_la1[23] = jj_gen;
+ jj_la1[22] = jj_gen;
;
}
break;
@@ -532,24 +531,24 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
boost = jj_consume_token(NUMBER);
break;
default:
- jj_la1[24] = jj_gen;
+ jj_la1[23] = jj_gen;
;
}
break;
default:
- jj_la1[25] = jj_gen;
+ jj_la1[24] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
break;
default:
- jj_la1[26] = jj_gen;
+ jj_la1[25] = jj_gen;
;
}
q = handleQuotedTerm(getField(field), term, fuzzySlop);
break;
default:
- jj_la1[27] = jj_gen;
+ jj_la1[26] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
@@ -685,7 +684,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
private boolean jj_lookingAhead = false;
private boolean jj_semLA;
private int jj_gen;
- final private int[] jj_la1 = new int[28];
+ final private int[] jj_la1 = new int[27];
static private int[] jj_la1_0;
static private int[] jj_la1_1;
static {
@@ -693,10 +692,10 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
jj_la1_init_1();
}
private static void jj_la1_init_0() {
- jj_la1_0 = new int[] {0x6000,0x6000,0x38000,0x38000,0xfb4f8000,0xfb4fe000,0xfb4fe000,0x2400000,0x800000,0x800000,0x800000,0xfb4c0000,0x3a440000,0x4000000,0x800000,0x4800000,0x4800000,0xc0000000,0x0,0x0,0x0,0x0,0x800000,0x4000000,0x800000,0x4800000,0x4800000,0xfb440000,};
+ jj_la1_0 = new int[] {0x6000,0x6000,0x38000,0x38000,0xfb4f8000,0xfb4fe000,0xfb4fe000,0x2400000,0x800000,0x800000,0x800000,0xfb4c0000,0x3a440000,0x4000000,0x800000,0x4800000,0x4800000,0xc0000000,0x0,0x0,0x0,0x800000,0x4000000,0x800000,0x4800000,0x4800000,0xfb440000,};
}
private static void jj_la1_init_1() {
- jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x7,0x7,0x7,0x0,0x0,0x0,0x0,0x7,0x4,0x0,0x0,0x0,0x0,0x0,0xc0,0x8,0xc0,0x30,0x0,0x0,0x0,0x0,0x0,0x4,};
+ jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x7,0x7,0x7,0x0,0x0,0x0,0x0,0x7,0x4,0x0,0x0,0x0,0x0,0x0,0xc8,0xc8,0x30,0x0,0x0,0x0,0x0,0x0,0x4,};
}
final private JJCalls[] jj_2_rtns = new JJCalls[3];
private boolean jj_rescan = false;
@@ -708,7 +707,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 28; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 27; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -719,7 +718,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
jj_ntk = -1;
jj_lookingAhead = false;
jj_gen = 0;
- for (int i = 0; i < 28; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 27; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -729,7 +728,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 28; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 27; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -739,7 +738,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 28; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 27; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -856,7 +855,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
la1tokens[jj_kind] = true;
jj_kind = -1;
}
- for (int i = 0; i < 28; i++) {
+ for (int i = 0; i < 27; i++) {
if (jj_la1[i] == jj_gen) {
for (int j = 0; j < 32; j++) {
if ((jj_la1_0[i] & (1<<j)) != 0) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8633f49d/solr/core/src/java/org/apache/solr/parser/QueryParser.jj
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/parser/QueryParser.jj b/solr/core/src/java/org/apache/solr/parser/QueryParser.jj
index c07b28d..9198881 100644
--- a/solr/core/src/java/org/apache/solr/parser/QueryParser.jj
+++ b/solr/core/src/java/org/apache/solr/parser/QueryParser.jj
@@ -282,9 +282,9 @@ Query Term(String field) throws SyntaxError : {
{ q = handleBareTokenQuery(getField(field), term, fuzzySlop, prefix, wildcard, fuzzy, regexp); }
| ( <RANGEIN_START> { startInc = true; } | <RANGEEX_START> )
- ( goop1=<RANGE_GOOP> | goop1=<RANGE_QUOTED> )
- [ <RANGE_TO> ]
- ( goop2=<RANGE_GOOP> | goop2=<RANGE_QUOTED> )
+ ( goop1=<RANGE_GOOP> | goop1=<RANGE_QUOTED> | goop1=<RANGE_TO> )
+ ( <RANGE_TO> )
+ ( goop2=<RANGE_GOOP> | goop2=<RANGE_QUOTED> | goop2=<RANGE_TO> )
( <RANGEIN_END> { endInc = true; } | <RANGEEX_END> )
[ <CARAT> boost=<NUMBER> ]
{
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8633f49d/solr/core/src/test/org/apache/solr/search/TestRangeQuery.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/search/TestRangeQuery.java b/solr/core/src/test/org/apache/solr/search/TestRangeQuery.java
index d2244b1..0ba716d 100644
--- a/solr/core/src/test/org/apache/solr/search/TestRangeQuery.java
+++ b/solr/core/src/test/org/apache/solr/search/TestRangeQuery.java
@@ -342,6 +342,48 @@ public class TestRangeQuery extends SolrTestCaseJ4 {
}
}
}
+
+ public void testRangeQueryEndpointTO() throws Exception {
+ assertEquals("[to TO to]", QParser.getParser("[to TO to]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[to TO to]", QParser.getParser("[to TO TO]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[to TO to]", QParser.getParser("[TO TO to]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[to TO to]", QParser.getParser("[TO TO TO]", req("df", "text")).getQuery().toString("text"));
+
+ assertEquals("[to TO to]", QParser.getParser("[\"TO\" TO \"TO\"]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[to TO to]", QParser.getParser("[\"TO\" TO TO]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[to TO to]", QParser.getParser("[TO TO \"TO\"]", req("df", "text")).getQuery().toString("text"));
+
+ assertEquals("[to TO xx]", QParser.getParser("[to TO xx]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[to TO xx]", QParser.getParser("[\"TO\" TO xx]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[to TO xx]", QParser.getParser("[TO TO xx]", req("df", "text")).getQuery().toString("text"));
+
+ assertEquals("[xx TO to]", QParser.getParser("[xx TO to]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[xx TO to]", QParser.getParser("[xx TO \"TO\"]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[xx TO to]", QParser.getParser("[xx TO TO]", req("df", "text")).getQuery().toString("text"));
+ }
+
+ public void testRangeQueryRequiresTO() throws Exception {
+ assertEquals("{a TO b}", QParser.getParser("{A TO B}", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[a TO b}", QParser.getParser("[A TO B}", req("df", "text")).getQuery().toString("text"));
+ assertEquals("{a TO b]", QParser.getParser("{A TO B]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[a TO b]", QParser.getParser("[A TO B]", req("df", "text")).getQuery().toString("text"));
+
+ // " TO " is required between range endpoints
+ expectThrows(SyntaxError.class, () -> QParser.getParser("{A B}", req("df", "text")).getQuery());
+ expectThrows(SyntaxError.class, () -> QParser.getParser("[A B}", req("df", "text")).getQuery());
+ expectThrows(SyntaxError.class, () -> QParser.getParser("{A B]", req("df", "text")).getQuery());
+ expectThrows(SyntaxError.class, () -> QParser.getParser("[A B]", req("df", "text")).getQuery());
+
+ expectThrows(SyntaxError.class, () -> QParser.getParser("{TO B}", req("df", "text")).getQuery());
+ expectThrows(SyntaxError.class, () -> QParser.getParser("[TO B}", req("df", "text")).getQuery());
+ expectThrows(SyntaxError.class, () -> QParser.getParser("{TO B]", req("df", "text")).getQuery());
+ expectThrows(SyntaxError.class, () -> QParser.getParser("[TO B]", req("df", "text")).getQuery());
+
+ expectThrows(SyntaxError.class, () -> QParser.getParser("{A TO}", req("df", "text")).getQuery());
+ expectThrows(SyntaxError.class, () -> QParser.getParser("[A TO}", req("df", "text")).getQuery());
+ expectThrows(SyntaxError.class, () -> QParser.getParser("{A TO]", req("df", "text")).getQuery());
+ expectThrows(SyntaxError.class, () -> QParser.getParser("[A TO]", req("df", "text")).getQuery());
+ }
static boolean sameDocs(String msg, DocSet a, DocSet b) {
DocIterator i = a.iterator();
[3/3] lucene-solr:branch_6_6: LUCENE-7821: The classic and flexible
query parsers, as well as Solr's 'lucene'/standard query parser,
should require ' TO ' in range queries,
and accept 'TO' as endpoints in range queries.
Posted by sa...@apache.org.
LUCENE-7821: The classic and flexible query parsers, as well as Solr's 'lucene'/standard query parser, should require ' TO ' in range queries, and accept 'TO' as endpoints in range queries.
Conflicts:
solr/CHANGES.txt
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/b172ceb1
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/b172ceb1
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/b172ceb1
Branch: refs/heads/branch_6_6
Commit: b172ceb143955bf34a6b16ab3557bf98844ac427
Parents: 4b93c62
Author: Steve Rowe <sa...@apache.org>
Authored: Sun May 14 11:31:22 2017 -0400
Committer: Steve Rowe <sa...@apache.org>
Committed: Sun May 14 11:37:31 2017 -0400
----------------------------------------------------------------------
lucene/CHANGES.txt | 4 ++
.../lucene/queryparser/classic/QueryParser.java | 47 +++++++++---------
.../lucene/queryparser/classic/QueryParser.jj | 6 +--
.../standard/parser/StandardSyntaxParser.java | 43 ++++++++---------
.../standard/parser/StandardSyntaxParser.jj | 6 +--
.../queryparser/util/QueryParserTestBase.java | 51 ++++++++++++++++++++
solr/CHANGES.txt | 4 ++
.../org/apache/solr/parser/QueryParser.java | 47 +++++++++---------
.../java/org/apache/solr/parser/QueryParser.jj | 6 +--
.../org/apache/solr/search/TestRangeQuery.java | 42 ++++++++++++++++
10 files changed, 177 insertions(+), 79 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b172ceb1/lucene/CHANGES.txt
----------------------------------------------------------------------
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 7e7c5ac..8c021eb 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -34,6 +34,10 @@ Bug Fixes
* LUCENE-5365, LUCENE-7818: Fix incorrect condition in queryparser's
QueryNodeOperation#logicalAnd(). (Olivier Binda, Amrit Sarkar,
AppChecker via Uwe Schindler)
+
+* LUCENE-7821: The classic and flexible query parsers, as well as Solr's
+ "lucene"/standard query parser, should require " TO " in range queries,
+ and accept "TO" as endpoints in range queries. (hossman, Steve Rowe)
Improvements
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b172ceb1/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.java
index 2410cb0..db6291a 100644
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.java
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.java
@@ -490,19 +490,15 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
case RANGE_QUOTED:
goop1 = jj_consume_token(RANGE_QUOTED);
break;
+ case RANGE_TO:
+ goop1 = jj_consume_token(RANGE_TO);
+ break;
default:
jj_la1[16] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case RANGE_TO:
- jj_consume_token(RANGE_TO);
- break;
- default:
- jj_la1[17] = jj_gen;
- ;
- }
+ jj_consume_token(RANGE_TO);
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case RANGE_GOOP:
goop2 = jj_consume_token(RANGE_GOOP);
@@ -510,8 +506,11 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
case RANGE_QUOTED:
goop2 = jj_consume_token(RANGE_QUOTED);
break;
+ case RANGE_TO:
+ goop2 = jj_consume_token(RANGE_TO);
+ break;
default:
- jj_la1[18] = jj_gen;
+ jj_la1[17] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
@@ -524,7 +523,7 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
jj_consume_token(RANGEEX_END);
break;
default:
- jj_la1[19] = jj_gen;
+ jj_la1[18] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
@@ -534,7 +533,7 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
boost = jj_consume_token(NUMBER);
break;
default:
- jj_la1[20] = jj_gen;
+ jj_la1[19] = jj_gen;
;
}
boolean startOpen=false;
@@ -566,7 +565,7 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
fuzzy=true;
break;
default:
- jj_la1[21] = jj_gen;
+ jj_la1[20] = jj_gen;
;
}
break;
@@ -579,24 +578,24 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
boost = jj_consume_token(NUMBER);
break;
default:
- jj_la1[22] = jj_gen;
+ jj_la1[21] = jj_gen;
;
}
break;
default:
- jj_la1[23] = jj_gen;
+ jj_la1[22] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
break;
default:
- jj_la1[24] = jj_gen;
+ jj_la1[23] = jj_gen;
;
}
q = handleQuotedTerm(field, term, fuzzySlop);
break;
default:
- jj_la1[25] = jj_gen;
+ jj_la1[24] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
@@ -732,7 +731,7 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
private boolean jj_lookingAhead = false;
private boolean jj_semLA;
private int jj_gen;
- final private int[] jj_la1 = new int[26];
+ final private int[] jj_la1 = new int[25];
static private int[] jj_la1_0;
static private int[] jj_la1_1;
static {
@@ -740,10 +739,10 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
jj_la1_init_1();
}
private static void jj_la1_init_0() {
- jj_la1_0 = new int[] {0x300,0x300,0x1c00,0x1c00,0xfda7c00,0xfda7f00,0xfda7f00,0x120000,0x40000,0xfda6000,0x9d22000,0x200000,0x40000,0x240000,0x240000,0x6000000,0x80000000,0x10000000,0x80000000,0x60000000,0x40000,0x200000,0x40000,0x240000,0x240000,0xfda2000,};
+ jj_la1_0 = new int[] {0x300,0x300,0x1c00,0x1c00,0xfda7c00,0xfda7f00,0xfda7f00,0x120000,0x40000,0xfda6000,0x9d22000,0x200000,0x40000,0x240000,0x240000,0x6000000,0x90000000,0x90000000,0x60000000,0x40000,0x200000,0x40000,0x240000,0x240000,0xfda2000,};
}
private static void jj_la1_init_1() {
- jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,};
+ jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,};
}
final private JJCalls[] jj_2_rtns = new JJCalls[3];
private boolean jj_rescan = false;
@@ -755,7 +754,7 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 26; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 25; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -766,7 +765,7 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
jj_ntk = -1;
jj_lookingAhead = false;
jj_gen = 0;
- for (int i = 0; i < 26; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 25; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -776,7 +775,7 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 26; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 25; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -786,7 +785,7 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 26; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 25; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -903,7 +902,7 @@ public class QueryParser extends QueryParserBase implements QueryParserConstants
la1tokens[jj_kind] = true;
jj_kind = -1;
}
- for (int i = 0; i < 26; i++) {
+ for (int i = 0; i < 25; i++) {
if (jj_la1[i] == jj_gen) {
for (int j = 0; j < 32; j++) {
if ((jj_la1_0[i] & (1<<j)) != 0) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b172ceb1/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.jj
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.jj b/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.jj
index 970a055..13a6d75 100644
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.jj
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/classic/QueryParser.jj
@@ -341,9 +341,9 @@ Query Term(String field) : {
{ q = handleBareTokenQuery(field, term, fuzzySlop, prefix, wildcard, fuzzy, regexp); }
| ( <RANGEIN_START> { startInc = true; } | <RANGEEX_START> )
- ( goop1=<RANGE_GOOP> | goop1=<RANGE_QUOTED> )
- [ <RANGE_TO> ]
- ( goop2=<RANGE_GOOP> | goop2=<RANGE_QUOTED> )
+ ( goop1=<RANGE_GOOP> | goop1=<RANGE_QUOTED> | goop1=<RANGE_TO> )
+ ( <RANGE_TO> )
+ ( goop2=<RANGE_GOOP> | goop2=<RANGE_QUOTED> | goop2=<RANGE_TO> )
( <RANGEIN_END> { endInc = true; } | <RANGEEX_END> )
[ <CARAT> boost=<NUMBER> ]
{
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b172ceb1/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.java
index 8ba34a6..6008bcc 100644
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.java
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.java
@@ -577,19 +577,15 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
case RANGE_QUOTED:
goop1 = jj_consume_token(RANGE_QUOTED);
break;
+ case RANGE_TO:
+ goop1 = jj_consume_token(RANGE_TO);
+ break;
default:
jj_la1[18] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case RANGE_TO:
- jj_consume_token(RANGE_TO);
- break;
- default:
- jj_la1[19] = jj_gen;
- ;
- }
+ jj_consume_token(RANGE_TO);
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case RANGE_GOOP:
goop2 = jj_consume_token(RANGE_GOOP);
@@ -597,8 +593,11 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
case RANGE_QUOTED:
goop2 = jj_consume_token(RANGE_QUOTED);
break;
+ case RANGE_TO:
+ goop2 = jj_consume_token(RANGE_TO);
+ break;
default:
- jj_la1[20] = jj_gen;
+ jj_la1[19] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
@@ -611,7 +610,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
jj_consume_token(RANGEEX_END);
break;
default:
- jj_la1[21] = jj_gen;
+ jj_la1[20] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
@@ -621,7 +620,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
boost = jj_consume_token(NUMBER);
break;
default:
- jj_la1[22] = jj_gen;
+ jj_la1[21] = jj_gen;
;
}
if (goop1.kind == RANGE_QUOTED) {
@@ -645,7 +644,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
fuzzySlop = jj_consume_token(FUZZY_SLOP);
break;
default:
- jj_la1[23] = jj_gen;
+ jj_la1[22] = jj_gen;
;
}
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
@@ -654,7 +653,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
boost = jj_consume_token(NUMBER);
break;
default:
- jj_la1[24] = jj_gen;
+ jj_la1[23] = jj_gen;
;
}
int phraseSlop = 0;
@@ -672,7 +671,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
}
break;
default:
- jj_la1[25] = jj_gen;
+ jj_la1[24] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
@@ -831,7 +830,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
private Token jj_scanpos, jj_lastpos;
private int jj_la;
private int jj_gen;
- final private int[] jj_la1 = new int[26];
+ final private int[] jj_la1 = new int[25];
static private int[] jj_la1_0;
static private int[] jj_la1_1;
static {
@@ -839,10 +838,10 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
jj_la1_init_1();
}
private static void jj_la1_init_0() {
- jj_la1_0 = new int[] {0x1c00,0x1c00,0x1ec03c00,0x200,0x100,0x18000,0x1e0000,0x10c00000,0x1f8000,0x18000,0x200000,0x1ec02000,0x1ec02000,0x12800000,0x1000000,0x1000000,0x200000,0xc000000,0x0,0x20000000,0x0,0xc0000000,0x200000,0x1000000,0x200000,0x1ec00000,};
+ jj_la1_0 = new int[] {0x1c00,0x1c00,0x1ec03c00,0x200,0x100,0x18000,0x1e0000,0x10c00000,0x1f8000,0x18000,0x200000,0x1ec02000,0x1ec02000,0x12800000,0x1000000,0x1000000,0x200000,0xc000000,0x20000000,0x20000000,0xc0000000,0x200000,0x1000000,0x200000,0x1ec00000,};
}
private static void jj_la1_init_1() {
- jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x3,0x0,0x0,0x0,0x0,0x0,};
+ jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x3,0x0,0x0,0x0,0x0,0x0,};
}
final private JJCalls[] jj_2_rtns = new JJCalls[2];
private boolean jj_rescan = false;
@@ -854,7 +853,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 26; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 25; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -864,7 +863,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 26; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 25; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -874,7 +873,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 26; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 25; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -884,7 +883,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 26; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 25; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -1001,7 +1000,7 @@ public class StandardSyntaxParser implements SyntaxParser, StandardSyntaxParserC
la1tokens[jj_kind] = true;
jj_kind = -1;
}
- for (int i = 0; i < 26; i++) {
+ for (int i = 0; i < 25; i++) {
if (jj_la1[i] == jj_gen) {
for (int j = 0; j < 32; j++) {
if ((jj_la1_0[i] & (1<<j)) != 0) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b172ceb1/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.jj
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.jj b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.jj
index b53bab3..8803618 100644
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.jj
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.jj
@@ -445,9 +445,9 @@ QueryNode Term(CharSequence field) : {
}
}
| ( ( <RANGEIN_START> {startInc=true;} | <RANGEEX_START> )
- ( goop1=<RANGE_GOOP>|goop1=<RANGE_QUOTED> )
- [ <RANGE_TO> ]
- ( goop2=<RANGE_GOOP>|goop2=<RANGE_QUOTED> )
+ ( goop1=<RANGE_GOOP>|goop1=<RANGE_QUOTED>|goop1=<RANGE_TO> )
+ ( <RANGE_TO> )
+ ( goop2=<RANGE_GOOP>|goop2=<RANGE_QUOTED>|goop2=<RANGE_TO> )
( <RANGEIN_END> {endInc=true;} | <RANGEEX_END>))
[ <CARAT> boost=<NUMBER> ]
{
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b172ceb1/lucene/queryparser/src/test/org/apache/lucene/queryparser/util/QueryParserTestBase.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/test/org/apache/lucene/queryparser/util/QueryParserTestBase.java b/lucene/queryparser/src/test/org/apache/lucene/queryparser/util/QueryParserTestBase.java
index bbececb..5ab8fb2 100644
--- a/lucene/queryparser/src/test/org/apache/lucene/queryparser/util/QueryParserTestBase.java
+++ b/lucene/queryparser/src/test/org/apache/lucene/queryparser/util/QueryParserTestBase.java
@@ -41,6 +41,7 @@ import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.queryparser.classic.QueryParserBase;
//import org.apache.lucene.queryparser.classic.QueryParserTokenManager;
+import org.apache.lucene.queryparser.classic.TestQueryParser;
import org.apache.lucene.queryparser.flexible.standard.CommonQueryParserConfiguration;
import org.apache.lucene.search.*;
import org.apache.lucene.search.BooleanClause.Occur;
@@ -619,6 +620,56 @@ public abstract class QueryParserTestBase extends LuceneTestCase {
assertQueryEquals("[\"*\" TO *]",null,"[\\* TO *]");
}
+ public void testRangeQueryEndpointTO() throws Exception {
+ Analyzer a = new MockAnalyzer(random());
+ assertQueryEquals("[to TO to]", a, "[to TO to]");
+ assertQueryEquals("[to TO TO]", a, "[to TO to]");
+ assertQueryEquals("[TO TO to]", a, "[to TO to]");
+ assertQueryEquals("[TO TO TO]", a, "[to TO to]");
+
+ assertQueryEquals("[\"TO\" TO \"TO\"]", a, "[to TO to]");
+ assertQueryEquals("[\"TO\" TO TO]", a, "[to TO to]");
+ assertQueryEquals("[TO TO \"TO\"]", a, "[to TO to]");
+
+ assertQueryEquals("[to TO xx]", a, "[to TO xx]");
+ assertQueryEquals("[\"TO\" TO xx]", a, "[to TO xx]");
+ assertQueryEquals("[TO TO xx]", a, "[to TO xx]");
+
+ assertQueryEquals("[xx TO to]", a, "[xx TO to]");
+ assertQueryEquals("[xx TO \"TO\"]", a, "[xx TO to]");
+ assertQueryEquals("[xx TO TO]", a, "[xx TO to]");
+ }
+
+ public void testRangeQueryRequiresTO() throws Exception {
+ Analyzer a = new MockAnalyzer(random());
+
+ assertQueryEquals("{A TO B}", a, "{a TO b}");
+ assertQueryEquals("[A TO B}", a, "[a TO b}");
+ assertQueryEquals("{A TO B]", a, "{a TO b]");
+ assertQueryEquals("[A TO B]", a, "[a TO b]");
+
+ // " TO " is required between range endpoints
+
+ Class<? extends Throwable> exceptionClass = this instanceof TestQueryParser
+ ? org.apache.lucene.queryparser.classic.ParseException.class
+ : org.apache.lucene.queryparser.flexible.standard.parser.ParseException.class;
+
+ expectThrows(exceptionClass, () -> getQuery("{A B}"));
+ expectThrows(exceptionClass, () -> getQuery("[A B}"));
+ expectThrows(exceptionClass, () -> getQuery("{A B]"));
+ expectThrows(exceptionClass, () -> getQuery("[A B]"));
+
+ expectThrows(exceptionClass, () -> getQuery("{TO B}"));
+ expectThrows(exceptionClass, () -> getQuery("[TO B}"));
+ expectThrows(exceptionClass, () -> getQuery("{TO B]"));
+ expectThrows(exceptionClass, () -> getQuery("[TO B]"));
+
+ expectThrows(exceptionClass, () -> getQuery("{A TO}"));
+ expectThrows(exceptionClass, () -> getQuery("[A TO}"));
+ expectThrows(exceptionClass, () -> getQuery("{A TO]"));
+ expectThrows(exceptionClass, () -> getQuery("[A TO]"));
+ }
+
private String escapeDateString(String s) {
if (s.indexOf(" ") > -1) {
return "\"" + s + "\"";
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b172ceb1/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index dee3df5..d61a185 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -232,6 +232,10 @@ Bug Fixes
* SOLR-9527: Improve distribution of replicas when restoring a collection
(Hrishikesh Gadre, Stephen Lewis, Rohit, Varun Thacker)
+* LUCENE-7821: The classic and flexible query parsers, as well as Solr's
+ "lucene"/standard query parser, should require " TO " in range queries,
+ and accept "TO" as endpoints in range queries. (hossman, Steve Rowe)
+
Other Changes
----------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b172ceb1/solr/core/src/java/org/apache/solr/parser/QueryParser.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/parser/QueryParser.java b/solr/core/src/java/org/apache/solr/parser/QueryParser.java
index 2b64b88..7a21847 100644
--- a/solr/core/src/java/org/apache/solr/parser/QueryParser.java
+++ b/solr/core/src/java/org/apache/solr/parser/QueryParser.java
@@ -441,19 +441,15 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
case RANGE_QUOTED:
goop1 = jj_consume_token(RANGE_QUOTED);
break;
+ case RANGE_TO:
+ goop1 = jj_consume_token(RANGE_TO);
+ break;
default:
jj_la1[18] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case RANGE_TO:
- jj_consume_token(RANGE_TO);
- break;
- default:
- jj_la1[19] = jj_gen;
- ;
- }
+ jj_consume_token(RANGE_TO);
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case RANGE_GOOP:
goop2 = jj_consume_token(RANGE_GOOP);
@@ -461,8 +457,11 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
case RANGE_QUOTED:
goop2 = jj_consume_token(RANGE_QUOTED);
break;
+ case RANGE_TO:
+ goop2 = jj_consume_token(RANGE_TO);
+ break;
default:
- jj_la1[20] = jj_gen;
+ jj_la1[19] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
@@ -475,7 +474,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
jj_consume_token(RANGEEX_END);
break;
default:
- jj_la1[21] = jj_gen;
+ jj_la1[20] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
@@ -485,7 +484,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
boost = jj_consume_token(NUMBER);
break;
default:
- jj_la1[22] = jj_gen;
+ jj_la1[21] = jj_gen;
;
}
boolean startOpen=false;
@@ -519,7 +518,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
fuzzy=true;
break;
default:
- jj_la1[23] = jj_gen;
+ jj_la1[22] = jj_gen;
;
}
break;
@@ -532,24 +531,24 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
boost = jj_consume_token(NUMBER);
break;
default:
- jj_la1[24] = jj_gen;
+ jj_la1[23] = jj_gen;
;
}
break;
default:
- jj_la1[25] = jj_gen;
+ jj_la1[24] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
break;
default:
- jj_la1[26] = jj_gen;
+ jj_la1[25] = jj_gen;
;
}
q = handleQuotedTerm(getField(field), term, fuzzySlop);
break;
default:
- jj_la1[27] = jj_gen;
+ jj_la1[26] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
@@ -685,7 +684,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
private boolean jj_lookingAhead = false;
private boolean jj_semLA;
private int jj_gen;
- final private int[] jj_la1 = new int[28];
+ final private int[] jj_la1 = new int[27];
static private int[] jj_la1_0;
static private int[] jj_la1_1;
static {
@@ -693,10 +692,10 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
jj_la1_init_1();
}
private static void jj_la1_init_0() {
- jj_la1_0 = new int[] {0x6000,0x6000,0x38000,0x38000,0xfb4f8000,0xfb4fe000,0xfb4fe000,0x2400000,0x800000,0x800000,0x800000,0xfb4c0000,0x3a440000,0x4000000,0x800000,0x4800000,0x4800000,0xc0000000,0x0,0x0,0x0,0x0,0x800000,0x4000000,0x800000,0x4800000,0x4800000,0xfb440000,};
+ jj_la1_0 = new int[] {0x6000,0x6000,0x38000,0x38000,0xfb4f8000,0xfb4fe000,0xfb4fe000,0x2400000,0x800000,0x800000,0x800000,0xfb4c0000,0x3a440000,0x4000000,0x800000,0x4800000,0x4800000,0xc0000000,0x0,0x0,0x0,0x800000,0x4000000,0x800000,0x4800000,0x4800000,0xfb440000,};
}
private static void jj_la1_init_1() {
- jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x7,0x7,0x7,0x0,0x0,0x0,0x0,0x7,0x4,0x0,0x0,0x0,0x0,0x0,0xc0,0x8,0xc0,0x30,0x0,0x0,0x0,0x0,0x0,0x4,};
+ jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x7,0x7,0x7,0x0,0x0,0x0,0x0,0x7,0x4,0x0,0x0,0x0,0x0,0x0,0xc8,0xc8,0x30,0x0,0x0,0x0,0x0,0x0,0x4,};
}
final private JJCalls[] jj_2_rtns = new JJCalls[3];
private boolean jj_rescan = false;
@@ -708,7 +707,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 28; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 27; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -719,7 +718,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
jj_ntk = -1;
jj_lookingAhead = false;
jj_gen = 0;
- for (int i = 0; i < 28; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 27; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -729,7 +728,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 28; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 27; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -739,7 +738,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
token = new Token();
jj_ntk = -1;
jj_gen = 0;
- for (int i = 0; i < 28; i++) jj_la1[i] = -1;
+ for (int i = 0; i < 27; i++) jj_la1[i] = -1;
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
}
@@ -856,7 +855,7 @@ public class QueryParser extends SolrQueryParserBase implements QueryParserConst
la1tokens[jj_kind] = true;
jj_kind = -1;
}
- for (int i = 0; i < 28; i++) {
+ for (int i = 0; i < 27; i++) {
if (jj_la1[i] == jj_gen) {
for (int j = 0; j < 32; j++) {
if ((jj_la1_0[i] & (1<<j)) != 0) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b172ceb1/solr/core/src/java/org/apache/solr/parser/QueryParser.jj
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/parser/QueryParser.jj b/solr/core/src/java/org/apache/solr/parser/QueryParser.jj
index c07b28d..9198881 100644
--- a/solr/core/src/java/org/apache/solr/parser/QueryParser.jj
+++ b/solr/core/src/java/org/apache/solr/parser/QueryParser.jj
@@ -282,9 +282,9 @@ Query Term(String field) throws SyntaxError : {
{ q = handleBareTokenQuery(getField(field), term, fuzzySlop, prefix, wildcard, fuzzy, regexp); }
| ( <RANGEIN_START> { startInc = true; } | <RANGEEX_START> )
- ( goop1=<RANGE_GOOP> | goop1=<RANGE_QUOTED> )
- [ <RANGE_TO> ]
- ( goop2=<RANGE_GOOP> | goop2=<RANGE_QUOTED> )
+ ( goop1=<RANGE_GOOP> | goop1=<RANGE_QUOTED> | goop1=<RANGE_TO> )
+ ( <RANGE_TO> )
+ ( goop2=<RANGE_GOOP> | goop2=<RANGE_QUOTED> | goop2=<RANGE_TO> )
( <RANGEIN_END> { endInc = true; } | <RANGEEX_END> )
[ <CARAT> boost=<NUMBER> ]
{
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b172ceb1/solr/core/src/test/org/apache/solr/search/TestRangeQuery.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/search/TestRangeQuery.java b/solr/core/src/test/org/apache/solr/search/TestRangeQuery.java
index d2244b1..0ba716d 100644
--- a/solr/core/src/test/org/apache/solr/search/TestRangeQuery.java
+++ b/solr/core/src/test/org/apache/solr/search/TestRangeQuery.java
@@ -342,6 +342,48 @@ public class TestRangeQuery extends SolrTestCaseJ4 {
}
}
}
+
+ public void testRangeQueryEndpointTO() throws Exception {
+ assertEquals("[to TO to]", QParser.getParser("[to TO to]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[to TO to]", QParser.getParser("[to TO TO]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[to TO to]", QParser.getParser("[TO TO to]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[to TO to]", QParser.getParser("[TO TO TO]", req("df", "text")).getQuery().toString("text"));
+
+ assertEquals("[to TO to]", QParser.getParser("[\"TO\" TO \"TO\"]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[to TO to]", QParser.getParser("[\"TO\" TO TO]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[to TO to]", QParser.getParser("[TO TO \"TO\"]", req("df", "text")).getQuery().toString("text"));
+
+ assertEquals("[to TO xx]", QParser.getParser("[to TO xx]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[to TO xx]", QParser.getParser("[\"TO\" TO xx]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[to TO xx]", QParser.getParser("[TO TO xx]", req("df", "text")).getQuery().toString("text"));
+
+ assertEquals("[xx TO to]", QParser.getParser("[xx TO to]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[xx TO to]", QParser.getParser("[xx TO \"TO\"]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[xx TO to]", QParser.getParser("[xx TO TO]", req("df", "text")).getQuery().toString("text"));
+ }
+
+ public void testRangeQueryRequiresTO() throws Exception {
+ assertEquals("{a TO b}", QParser.getParser("{A TO B}", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[a TO b}", QParser.getParser("[A TO B}", req("df", "text")).getQuery().toString("text"));
+ assertEquals("{a TO b]", QParser.getParser("{A TO B]", req("df", "text")).getQuery().toString("text"));
+ assertEquals("[a TO b]", QParser.getParser("[A TO B]", req("df", "text")).getQuery().toString("text"));
+
+ // " TO " is required between range endpoints
+ expectThrows(SyntaxError.class, () -> QParser.getParser("{A B}", req("df", "text")).getQuery());
+ expectThrows(SyntaxError.class, () -> QParser.getParser("[A B}", req("df", "text")).getQuery());
+ expectThrows(SyntaxError.class, () -> QParser.getParser("{A B]", req("df", "text")).getQuery());
+ expectThrows(SyntaxError.class, () -> QParser.getParser("[A B]", req("df", "text")).getQuery());
+
+ expectThrows(SyntaxError.class, () -> QParser.getParser("{TO B}", req("df", "text")).getQuery());
+ expectThrows(SyntaxError.class, () -> QParser.getParser("[TO B}", req("df", "text")).getQuery());
+ expectThrows(SyntaxError.class, () -> QParser.getParser("{TO B]", req("df", "text")).getQuery());
+ expectThrows(SyntaxError.class, () -> QParser.getParser("[TO B]", req("df", "text")).getQuery());
+
+ expectThrows(SyntaxError.class, () -> QParser.getParser("{A TO}", req("df", "text")).getQuery());
+ expectThrows(SyntaxError.class, () -> QParser.getParser("[A TO}", req("df", "text")).getQuery());
+ expectThrows(SyntaxError.class, () -> QParser.getParser("{A TO]", req("df", "text")).getQuery());
+ expectThrows(SyntaxError.class, () -> QParser.getParser("[A TO]", req("df", "text")).getQuery());
+ }
static boolean sameDocs(String msg, DocSet a, DocSet b) {
DocIterator i = a.iterator();