Index: modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/core/messages/QueryParserMessages.java =================================================================== --- modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/core/messages/QueryParserMessages.java (revision 1152425) +++ modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/core/messages/QueryParserMessages.java (working copy) @@ -54,5 +54,6 @@ public static String COULD_NOT_PARSE_NUMBER; public static String NUMBER_CLASS_NOT_SUPPORTED_BY_NUMERIC_RANGE_QUERY; public static String UNSUPPORTED_NUMERIC_DATA_TYPE; + public static String NUMERIC_CANNOT_BE_EMPTY; } Index: modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/builders/NumericRangeQueryNodeBuilder.java =================================================================== --- modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/builders/NumericRangeQueryNodeBuilder.java (revision 1152425) +++ modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/builders/NumericRangeQueryNodeBuilder.java (working copy) @@ -50,19 +50,8 @@ NumericQueryNode lowerNumericNode = numericRangeNode.getLowerBound(); NumericQueryNode upperNumericNode = numericRangeNode.getUpperBound(); - Number lowerNumber, upperNumber; - - if (lowerNumericNode != null) { - lowerNumber = lowerNumericNode.getValue(); - } else { - lowerNumber = null; - } - - if (upperNumericNode != null) { - upperNumber = upperNumericNode.getValue(); - } else { - upperNumber = null; - } + Number lowerNumber = lowerNumericNode.getValue(); + Number upperNumber = upperNumericNode.getValue(); NumericConfig numericConfig = numericRangeNode.getNumericConfig(); NumericField.DataType numberType = numericConfig.getType(); Index: modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/builders/TermRangeQueryNodeBuilder.java =================================================================== --- modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/builders/TermRangeQueryNodeBuilder.java (revision 1152425) +++ modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/builders/TermRangeQueryNodeBuilder.java (working copy) @@ -42,9 +42,18 @@ FieldQueryNode lower = rangeNode.getLowerBound(); String field = StringUtils.toString(rangeNode.getField()); + String lowerText = lower.getTextAsString(); + String upperText = upper.getTextAsString(); + + if (lowerText.length() == 0) { + lowerText = null; + } + + if (upperText.length() == 0) { + upperText = null; + } - TermRangeQuery rangeQuery = TermRangeQuery.newStringRange(field, lower - .getTextAsString(), upper.getTextAsString(), rangeNode + TermRangeQuery rangeQuery = TermRangeQuery.newStringRange(field, lowerText, upperText, rangeNode .isLowerInclusive(), rangeNode.isUpperInclusive()); MultiTermQuery.RewriteMethod method = (MultiTermQuery.RewriteMethod) queryNode Index: modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/nodes/AbstractRangeQueryNode.java =================================================================== --- modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/nodes/AbstractRangeQueryNode.java (revision 1152425) +++ modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/nodes/AbstractRangeQueryNode.java (working copy) @@ -204,4 +204,18 @@ } + @Override + public String toString() { + StringBuilder sb = new StringBuilder("<").append(getClass().getCanonicalName()); + sb.append(" lowerInclusive=").append(isLowerInclusive()); + sb.append(" upperInclusive=").append(isUpperInclusive()); + sb.append(">\n\t"); + sb.append(getUpperBound()).append("\n\t"); + sb.append(getLowerBound()).append("\n"); + sb.append("\n"); + + return sb.toString(); + + } + } Index: modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/JavaCharStream.java =================================================================== --- modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/JavaCharStream.java (revision 1152425) +++ modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/JavaCharStream.java (working copy) @@ -347,7 +347,7 @@ @Deprecated /** - * @deprecated (gen) + * @deprecated * @see #getEndColumn */ public int getColumn() { @@ -356,7 +356,7 @@ @Deprecated /** - * @deprecated (gen) + * @deprecated * @see #getEndLine */ public int getLine() { @@ -613,4 +613,4 @@ } } -/* JavaCC - OriginalChecksum=f19c73b8f7faf94cc4a581e7b2933cc6 (do not edit this line) */ +/* JavaCC - OriginalChecksum=7eecaeeaea1254b3e35fe8890a0127ce (do not edit this line) */ Index: modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/ParseException.java =================================================================== --- modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/ParseException.java (revision 1152425) +++ modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/ParseException.java (working copy) @@ -4,8 +4,8 @@ import org.apache.lucene.messages.Message; import org.apache.lucene.messages.MessageImpl; - import org.apache.lucene.queryparser.flexible.core.QueryNodeParseException; - import org.apache.lucene.queryparser.flexible.core.messages.QueryParserMessages; + import org.apache.lucene.queryparser.flexible.core.*; + import org.apache.lucene.queryparser.flexible.core.messages.*; /** * This exception is thrown when parse errors are encountered. @@ -56,7 +56,7 @@ /** Constructor with message. */ public ParseException(Message message) { super(message); - } + } /** * This variable determines which constructor was used to create @@ -193,4 +193,4 @@ } } -/* JavaCC - OriginalChecksum=38bce846fe6c8482993969f741c0323e (do not edit this line) */ +/* JavaCC - OriginalChecksum=0f25f4245374bbf9920c9a82efecadd2 (do not edit this line) */ Index: modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.java =================================================================== --- modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.java (revision 1152425) +++ modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.java (working copy) @@ -19,14 +19,10 @@ */ import java.io.StringReader; -import java.util.ArrayList; -import java.util.List; import java.util.Vector; import org.apache.lucene.messages.Message; import org.apache.lucene.messages.MessageImpl; -import org.apache.lucene.queryparser.flexible.core.QueryNodeError; -import org.apache.lucene.queryparser.flexible.core.QueryNodeException; import org.apache.lucene.queryparser.flexible.core.QueryNodeParseException; import org.apache.lucene.queryparser.flexible.core.messages.QueryParserMessages; import org.apache.lucene.queryparser.flexible.core.nodes.AndQueryNode; @@ -36,15 +32,12 @@ import org.apache.lucene.queryparser.flexible.core.nodes.FuzzyQueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.ModifierQueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.GroupQueryNode; -import org.apache.lucene.queryparser.flexible.core.nodes.OpaqueQueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.OrQueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.ParametricQueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.ParametricRangeQueryNode; import org.apache.lucene.queryparser.flexible.standard.nodes.RegexpQueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.SlopQueryNode; -import org.apache.lucene.queryparser.flexible.core.nodes.ProximityQueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode; -import org.apache.lucene.queryparser.flexible.core.nodes.QueryNodeImpl; import org.apache.lucene.queryparser.flexible.core.nodes.QuotedFieldQueryNode; import org.apache.lucene.queryparser.flexible.core.parser.SyntaxParser; @@ -59,7 +52,7 @@ public StandardSyntaxParser() { this(new StringReader("")); } - /** Parses a query string, returning a {@link org.apache.lucene.queryparser.flexible.core.nodes.QueryNode}. + /** Parses a query string, returning a {@link org.apache.lucene.queryParser.core.nodes.QueryNode}. * @param query the query string to be parsed. * @throws ParseException if the parsing fails */ @@ -315,43 +308,168 @@ final public QueryNode Clause(CharSequence field) throws ParseException { QueryNode q; - Token fieldToken=null, boost=null; + Token fieldToken=null, boost=null, operator=null, term=null; + ParametricQueryNode qLower, qUpper; + boolean group = false; - if (jj_2_1(2)) { + if (jj_2_2(3)) { fieldToken = jj_consume_token(TERM); - jj_consume_token(COLON); - field=EscapeQuerySyntaxImpl.discardEscapeChar(fieldToken.image); - } else { - ; - } - switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case QUOTED: - case TERM: - case REGEXPTERM: - case RANGEIN_START: - case RANGEEX_START: - case NUMBER: - q = Term(field); - break; - case LPAREN: - jj_consume_token(LPAREN); - q = Query(field); - jj_consume_token(RPAREN); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case CARAT: - jj_consume_token(CARAT); - boost = jj_consume_token(NUMBER); + case OP_COLON: + case OP_EQUAL: + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case OP_COLON: + jj_consume_token(OP_COLON); + break; + case OP_EQUAL: + jj_consume_token(OP_EQUAL); + break; + default: + jj_la1[7] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + field=EscapeQuerySyntaxImpl.discardEscapeChar(fieldToken.image); + q = Term(field); + break; + case OP_LESSTHAN: + case OP_LESSTHANEQ: + case OP_MORETHAN: + case OP_MORETHANEQ: + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case OP_LESSTHAN: + operator = jj_consume_token(OP_LESSTHAN); + break; + case OP_LESSTHANEQ: + operator = jj_consume_token(OP_LESSTHANEQ); + break; + case OP_MORETHAN: + operator = jj_consume_token(OP_MORETHAN); + break; + case OP_MORETHANEQ: + operator = jj_consume_token(OP_MORETHANEQ); + break; + default: + jj_la1[8] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + field=EscapeQuerySyntaxImpl.discardEscapeChar(fieldToken.image); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case TERM: + term = jj_consume_token(TERM); + break; + case QUOTED: + term = jj_consume_token(QUOTED); + break; + case NUMBER: + term = jj_consume_token(NUMBER); + break; + default: + jj_la1[9] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + if (term.kind == QUOTED) { + term.image = term.image.substring(1, term.image.length()-1); + } + switch (operator.kind) { + case OP_LESSTHAN: + qLower = new ParametricQueryNode(field, ParametricQueryNode.CompareOperator.GE, + "*", term.beginColumn, term.endColumn); + qUpper = new ParametricQueryNode(field, ParametricQueryNode.CompareOperator.LT, + EscapeQuerySyntaxImpl.discardEscapeChar(term.image), term.beginColumn, term.endColumn); + break; + case OP_LESSTHANEQ: + qLower = new ParametricQueryNode(field, ParametricQueryNode.CompareOperator.GE, + "*", term.beginColumn, term.endColumn); + qUpper = new ParametricQueryNode(field, ParametricQueryNode.CompareOperator.LE, + EscapeQuerySyntaxImpl.discardEscapeChar(term.image), term.beginColumn, term.endColumn); + break; + case OP_MORETHAN: + qLower = new ParametricQueryNode(field, ParametricQueryNode.CompareOperator.GT, + EscapeQuerySyntaxImpl.discardEscapeChar(term.image), term.beginColumn, term.endColumn); + qUpper = new ParametricQueryNode(field, ParametricQueryNode.CompareOperator.LE, + "*", term.beginColumn, term.endColumn); + break; + case OP_MORETHANEQ: + qLower = new ParametricQueryNode(field, ParametricQueryNode.CompareOperator.GE, + EscapeQuerySyntaxImpl.discardEscapeChar(term.image), term.beginColumn, term.endColumn); + qUpper = new ParametricQueryNode(field, ParametricQueryNode.CompareOperator.LE, + "*", term.beginColumn, term.endColumn); + break; + default: + {if (true) throw new Error("Unhandled case: operator="+operator.toString());} + } + q = new ParametricRangeQueryNode(qLower, qUpper); break; default: - jj_la1[7] = jj_gen; - ; + jj_la1[10] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); } + } else { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case LPAREN: + case QUOTED: + case TERM: + case REGEXPTERM: + case RANGEIN_START: + case RANGEEX_START: + case NUMBER: + if (jj_2_1(2)) { + fieldToken = jj_consume_token(TERM); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case OP_COLON: + jj_consume_token(OP_COLON); + break; + case OP_EQUAL: + jj_consume_token(OP_EQUAL); + break; + default: + jj_la1[11] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + field=EscapeQuerySyntaxImpl.discardEscapeChar(fieldToken.image); + } else { + ; + } + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case QUOTED: + case TERM: + case REGEXPTERM: + case RANGEIN_START: + case RANGEEX_START: + case NUMBER: + q = Term(field); + break; + case LPAREN: + jj_consume_token(LPAREN); + q = Query(field); + jj_consume_token(RPAREN); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case CARAT: + jj_consume_token(CARAT); + boost = jj_consume_token(NUMBER); + break; + default: + jj_la1[12] = jj_gen; + ; + } group=true; - break; - default: - jj_la1[8] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); + break; + default: + jj_la1[13] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + break; + default: + jj_la1[14] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } } if (boost != null) { float f = (float)1.0; @@ -376,6 +494,8 @@ Token term, boost=null, fuzzySlop=null, goop1, goop2; boolean fuzzy = false; boolean regexp = false; + boolean startInc=false; + boolean endInc=false; QueryNode q =null; ParametricQueryNode qLower, qUpper; float defaultMinSimilarity = org.apache.lucene.search.FuzzyQuery.defaultMinSimilarity; @@ -396,7 +516,7 @@ term = jj_consume_token(NUMBER); break; default: - jj_la1[9] = jj_gen; + jj_la1[15] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -406,7 +526,7 @@ fuzzy=true; break; default: - jj_la1[10] = jj_gen; + jj_la1[16] = jj_gen; ; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -419,12 +539,12 @@ fuzzy=true; break; default: - jj_la1[11] = jj_gen; + jj_la1[17] = jj_gen; ; } break; default: - jj_la1[12] = jj_gen; + jj_la1[18] = jj_gen; ; } if (fuzzy) { @@ -443,115 +563,84 @@ } break; case RANGEIN_START: - jj_consume_token(RANGEIN_START); + case RANGEEX_START: switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case RANGEIN_GOOP: - goop1 = jj_consume_token(RANGEIN_GOOP); + case RANGEIN_START: + jj_consume_token(RANGEIN_START); + startInc=true; break; - case RANGEIN_QUOTED: - goop1 = jj_consume_token(RANGEIN_QUOTED); + case RANGEEX_START: + jj_consume_token(RANGEEX_START); break; default: - jj_la1[13] = jj_gen; + jj_la1[19] = jj_gen; jj_consume_token(-1); throw new ParseException(); } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case RANGEIN_TO: - jj_consume_token(RANGEIN_TO); - break; - default: - jj_la1[14] = jj_gen; - ; - } - switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case RANGEIN_GOOP: - goop2 = jj_consume_token(RANGEIN_GOOP); + case RANGE_GOOP: + goop1 = jj_consume_token(RANGE_GOOP); break; - case RANGEIN_QUOTED: - goop2 = jj_consume_token(RANGEIN_QUOTED); + case RANGE_QUOTED: + goop1 = jj_consume_token(RANGE_QUOTED); break; default: - jj_la1[15] = jj_gen; + jj_la1[20] = jj_gen; jj_consume_token(-1); throw new ParseException(); } - jj_consume_token(RANGEIN_END); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case CARAT: - jj_consume_token(CARAT); - boost = jj_consume_token(NUMBER); + case RANGE_TO: + jj_consume_token(RANGE_TO); break; default: - jj_la1[16] = jj_gen; + jj_la1[21] = jj_gen; ; } - if (goop1.kind == RANGEIN_QUOTED) { - goop1.image = goop1.image.substring(1, goop1.image.length()-1); - } - if (goop2.kind == RANGEIN_QUOTED) { - goop2.image = goop2.image.substring(1, goop2.image.length()-1); - } - - qLower = new ParametricQueryNode(field, ParametricQueryNode.CompareOperator.GE, - EscapeQuerySyntaxImpl.discardEscapeChar(goop1.image), goop1.beginColumn, goop1.endColumn); - qUpper = new ParametricQueryNode(field, ParametricQueryNode.CompareOperator.LE, - EscapeQuerySyntaxImpl.discardEscapeChar(goop2.image), goop2.beginColumn, goop2.endColumn); - q = new ParametricRangeQueryNode(qLower, qUpper); - break; - case RANGEEX_START: - jj_consume_token(RANGEEX_START); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case RANGEEX_GOOP: - goop1 = jj_consume_token(RANGEEX_GOOP); + case RANGE_GOOP: + goop2 = jj_consume_token(RANGE_GOOP); break; - case RANGEEX_QUOTED: - goop1 = jj_consume_token(RANGEEX_QUOTED); + case RANGE_QUOTED: + goop2 = jj_consume_token(RANGE_QUOTED); break; default: - jj_la1[17] = jj_gen; + jj_la1[22] = jj_gen; jj_consume_token(-1); throw new ParseException(); } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case RANGEEX_TO: - jj_consume_token(RANGEEX_TO); + case RANGEIN_END: + jj_consume_token(RANGEIN_END); + endInc=true; break; - default: - jj_la1[18] = jj_gen; - ; - } - switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case RANGEEX_GOOP: - goop2 = jj_consume_token(RANGEEX_GOOP); - break; - case RANGEEX_QUOTED: - goop2 = jj_consume_token(RANGEEX_QUOTED); + case RANGEEX_END: + jj_consume_token(RANGEEX_END); break; default: - jj_la1[19] = jj_gen; + jj_la1[23] = jj_gen; jj_consume_token(-1); throw new ParseException(); } - jj_consume_token(RANGEEX_END); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case CARAT: jj_consume_token(CARAT); boost = jj_consume_token(NUMBER); break; default: - jj_la1[20] = jj_gen; + jj_la1[24] = jj_gen; ; } - if (goop1.kind == RANGEEX_QUOTED) { + if (goop1.kind == RANGE_QUOTED) { goop1.image = goop1.image.substring(1, goop1.image.length()-1); } - if (goop2.kind == RANGEEX_QUOTED) { + if (goop2.kind == RANGE_QUOTED) { goop2.image = goop2.image.substring(1, goop2.image.length()-1); } - qLower = new ParametricQueryNode(field, ParametricQueryNode.CompareOperator.GT, + + qLower = new ParametricQueryNode(field, startInc ? ParametricQueryNode.CompareOperator.GE : ParametricQueryNode.CompareOperator.GT, EscapeQuerySyntaxImpl.discardEscapeChar(goop1.image), goop1.beginColumn, goop1.endColumn); - qUpper = new ParametricQueryNode(field, ParametricQueryNode.CompareOperator.LT, + qUpper = new ParametricQueryNode(field, endInc ? ParametricQueryNode.CompareOperator.LE : ParametricQueryNode.CompareOperator.LT, EscapeQuerySyntaxImpl.discardEscapeChar(goop2.image), goop2.beginColumn, goop2.endColumn); q = new ParametricRangeQueryNode(qLower, qUpper); break; @@ -563,7 +652,7 @@ fuzzySlop = jj_consume_token(FUZZY_SLOP); break; default: - jj_la1[21] = jj_gen; + jj_la1[25] = jj_gen; ; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -572,7 +661,7 @@ boost = jj_consume_token(NUMBER); break; default: - jj_la1[22] = jj_gen; + jj_la1[26] = jj_gen; ; } int phraseSlop = 0; @@ -590,7 +679,7 @@ } break; default: - jj_la1[23] = jj_gen; + jj_la1[27] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -619,9 +708,123 @@ finally { jj_save(0, xla); } } + private boolean jj_2_2(int xla) { + jj_la = xla; jj_lastpos = jj_scanpos = token; + try { return !jj_3_2(); } + catch(LookaheadSuccess ls) { return true; } + finally { jj_save(1, xla); } + } + + private boolean jj_3R_4() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(15)) { + jj_scanpos = xsp; + if (jj_scan_token(16)) return true; + } + if (jj_3R_6()) return true; + return false; + } + + private boolean jj_3R_10() { + if (jj_scan_token(TERM)) return true; + return false; + } + + private boolean jj_3_2() { + if (jj_scan_token(TERM)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_4()) { + jj_scanpos = xsp; + if (jj_3R_5()) return true; + } + return false; + } + + private boolean jj_3R_12() { + if (jj_scan_token(RANGEIN_START)) return true; + return false; + } + + private boolean jj_3R_11() { + if (jj_scan_token(REGEXPTERM)) return true; + return false; + } + private boolean jj_3_1() { if (jj_scan_token(TERM)) return true; - if (jj_scan_token(COLON)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(15)) { + jj_scanpos = xsp; + if (jj_scan_token(16)) return true; + } + return false; + } + + private boolean jj_3R_8() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_12()) { + jj_scanpos = xsp; + if (jj_scan_token(27)) return true; + } + return false; + } + + private boolean jj_3R_7() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_10()) { + jj_scanpos = xsp; + if (jj_3R_11()) { + jj_scanpos = xsp; + if (jj_scan_token(28)) return true; + } + } + return false; + } + + private boolean jj_3R_9() { + if (jj_scan_token(QUOTED)) return true; + return false; + } + + private boolean jj_3R_6() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_7()) { + jj_scanpos = xsp; + if (jj_3R_8()) { + jj_scanpos = xsp; + if (jj_3R_9()) return true; + } + } + return false; + } + + private boolean jj_3R_5() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(17)) { + jj_scanpos = xsp; + if (jj_scan_token(18)) { + jj_scanpos = xsp; + if (jj_scan_token(19)) { + jj_scanpos = xsp; + if (jj_scan_token(20)) return true; + } + } + } + xsp = jj_scanpos; + if (jj_scan_token(23)) { + jj_scanpos = xsp; + if (jj_scan_token(22)) { + jj_scanpos = xsp; + if (jj_scan_token(28)) return true; + } + } return false; } @@ -636,15 +839,20 @@ private Token jj_scanpos, jj_lastpos; private int jj_la; private int jj_gen; - final private int[] jj_la1 = new int[24]; + final private int[] jj_la1 = new int[28]; static private int[] jj_la1_0; + static private int[] jj_la1_1; static { jj_la1_init_0(); + jj_la1_init_1(); } private static void jj_la1_init_0() { - jj_la1_0 = new int[] {0x300,0x300,0x1c00,0x1c00,0xf63c00,0x200,0x100,0x10000,0xf62000,0x940000,0x80000,0x80000,0x10000,0xc000000,0x1000000,0xc000000,0x10000,0xc0000000,0x10000000,0xc0000000,0x10000,0x80000,0x10000,0xf60000,}; + jj_la1_0 = new int[] {0x300,0x300,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,}; } - final private JJCalls[] jj_2_rtns = new JJCalls[1]; + 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,0x0,0x0,0x3,0x0,0x3,0x0,0x0,0x0,0x0,0x0,}; + } + final private JJCalls[] jj_2_rtns = new JJCalls[2]; private boolean jj_rescan = false; private int jj_gc = 0; @@ -659,7 +867,7 @@ token = new Token(); jj_ntk = -1; jj_gen = 0; - for (int i = 0; i < 24; i++) jj_la1[i] = -1; + for (int i = 0; i < 28; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } @@ -674,7 +882,7 @@ token = new Token(); jj_ntk = -1; jj_gen = 0; - for (int i = 0; i < 24; i++) jj_la1[i] = -1; + for (int i = 0; i < 28; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } @@ -685,7 +893,7 @@ token = new Token(); jj_ntk = -1; jj_gen = 0; - for (int i = 0; i < 24; i++) jj_la1[i] = -1; + for (int i = 0; i < 28; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } @@ -696,7 +904,7 @@ token = new Token(); jj_ntk = -1; jj_gen = 0; - for (int i = 0; i < 24; i++) jj_la1[i] = -1; + for (int i = 0; i < 28; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } @@ -706,7 +914,7 @@ token = new Token(); jj_ntk = -1; jj_gen = 0; - for (int i = 0; i < 24; i++) jj_la1[i] = -1; + for (int i = 0; i < 28; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } @@ -716,7 +924,7 @@ token = new Token(); jj_ntk = -1; jj_gen = 0; - for (int i = 0; i < 24; i++) jj_la1[i] = -1; + for (int i = 0; i < 28; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } @@ -794,7 +1002,7 @@ return (jj_ntk = jj_nt.kind); } - private java.util.List jj_expentries = new java.util.ArrayList(); + private java.util.List jj_expentries = new java.util.ArrayList(); private int[] jj_expentry; private int jj_kind = -1; private int[] jj_lasttokens = new int[100]; @@ -828,21 +1036,24 @@ /** Generate ParseException. */ public ParseException generateParseException() { jj_expentries.clear(); - boolean[] la1tokens = new boolean[32]; + boolean[] la1tokens = new boolean[34]; if (jj_kind >= 0) { la1tokens[jj_kind] = true; jj_kind = -1; } - for (int i = 0; i < 24; i++) { + for (int i = 0; i < 28; i++) { if (jj_la1[i] == jj_gen) { for (int j = 0; j < 32; j++) { if ((jj_la1_0[i] & (1< | <#_TERM_START_CHAR: ( ~[ " ", "\t", "\n", "\r", "\u3000", "+", "-", "!", "(", ")", ":", "^", - "[", "]", "\"", "{", "}", "~", "\\" ] + "<", ">", "=", "[", "]", "\"", "{", "}", "~", "\\" ] | <_ESCAPED_CHAR> ) > | <#_TERM_CHAR: ( <_TERM_START_CHAR> | <_ESCAPED_CHAR> | "-" | "+" ) > | <#_WHITESPACE: ( " " | "\t" | "\n" | "\r" | "\u3000") > | <#_QUOTED_CHAR: ( ~[ "\"", "\\" ] | <_ESCAPED_CHAR> ) > } - SKIP : { + SKIP : { < <_WHITESPACE>> } @@ -127,32 +120,31 @@ | | | -| +| +| +| " > +| =" > | : Boost | )* "\""> | (<_TERM_CHAR>)* > | )+ ( "." (<_NUM_CHAR>)+ )? )? > | -| : RangeIn -| : RangeEx +| : Range +| : Range } TOKEN : { )+ ( "." (<_NUM_CHAR>)+ )? > : DEFAULT } - TOKEN : { - + TOKEN : { + | : DEFAULT -| -| -} - - TOKEN : { - | : DEFAULT -| -| +| +| } // * Query ::= ( Clause )* @@ -335,22 +327,62 @@ QueryNode Clause(CharSequence field) : { QueryNode q; - Token fieldToken=null, boost=null; + Token fieldToken=null, boost=null, operator=null, term=null; + ParametricQueryNode qLower, qUpper; + boolean group = false; } { - [ +( + LOOKAHEAD(3) + fieldToken= ( + ( | ) {field=EscapeQuerySyntaxImpl.discardEscapeChar(fieldToken.image);} q=Term(field) + | ( operator= | operator= | operator= | operator= ) {field=EscapeQuerySyntaxImpl.discardEscapeChar(fieldToken.image);}( term= | term= | term= ) + { + if (term.kind == QUOTED) { + term.image = term.image.substring(1, term.image.length()-1); + } + switch (operator.kind) { + case OP_LESSTHAN: + qLower = new ParametricQueryNode(field, ParametricQueryNode.CompareOperator.GE, + "*", term.beginColumn, term.endColumn); + qUpper = new ParametricQueryNode(field, ParametricQueryNode.CompareOperator.LT, + EscapeQuerySyntaxImpl.discardEscapeChar(term.image), term.beginColumn, term.endColumn); + break; + case OP_LESSTHANEQ: + qLower = new ParametricQueryNode(field, ParametricQueryNode.CompareOperator.GE, + "*", term.beginColumn, term.endColumn); + qUpper = new ParametricQueryNode(field, ParametricQueryNode.CompareOperator.LE, + EscapeQuerySyntaxImpl.discardEscapeChar(term.image), term.beginColumn, term.endColumn); + break; + case OP_MORETHAN: + qLower = new ParametricQueryNode(field, ParametricQueryNode.CompareOperator.GT, + EscapeQuerySyntaxImpl.discardEscapeChar(term.image), term.beginColumn, term.endColumn); + qUpper = new ParametricQueryNode(field, ParametricQueryNode.CompareOperator.LE, + "*", term.beginColumn, term.endColumn); + break; + case OP_MORETHANEQ: + qLower = new ParametricQueryNode(field, ParametricQueryNode.CompareOperator.GE, + EscapeQuerySyntaxImpl.discardEscapeChar(term.image), term.beginColumn, term.endColumn); + qUpper = new ParametricQueryNode(field, ParametricQueryNode.CompareOperator.LE, + "*", term.beginColumn, term.endColumn); + break; + default: + throw new Error("Unhandled case: operator="+operator.toString()); + } + q = new ParametricRangeQueryNode(qLower, qUpper); + } + ) +| [ LOOKAHEAD(2) - ( - fieldToken= {field=EscapeQuerySyntaxImpl.discardEscapeChar(fieldToken.image);} - ) + fieldToken= + ( | ) {field=EscapeQuerySyntaxImpl.discardEscapeChar(fieldToken.image);} ] - ( q=Term(field) | q=Query(field) ( boost=)? {group=true;} - ) +) { if (boost != null) { float f = (float)1.0; @@ -376,6 +408,8 @@ Token term, boost=null, fuzzySlop=null, goop1, goop2; boolean fuzzy = false; boolean regexp = false; + boolean startInc=false; + boolean endInc=false; QueryNode q =null; ParametricQueryNode qLower, qUpper; float defaultMinSimilarity = org.apache.lucene.search.FuzzyQuery.defaultMinSimilarity; @@ -405,41 +439,26 @@ q = new RegexpQueryNode(field, term.image, term.beginColumn, term.endColumn-1); } } - | ( ( goop1=|goop1= ) - [ ] ( goop2=|goop2= ) - ) + | ( ( {startInc=true;} | ) + ( goop1=|goop1= ) + [ ] + ( goop2=|goop2= ) + ( {endInc=true;} | )) [ boost= ] { - if (goop1.kind == RANGEIN_QUOTED) { + if (goop1.kind == RANGE_QUOTED) { goop1.image = goop1.image.substring(1, goop1.image.length()-1); } - if (goop2.kind == RANGEIN_QUOTED) { + if (goop2.kind == RANGE_QUOTED) { goop2.image = goop2.image.substring(1, goop2.image.length()-1); } - qLower = new ParametricQueryNode(field, ParametricQueryNode.CompareOperator.GE, + qLower = new ParametricQueryNode(field, startInc ? ParametricQueryNode.CompareOperator.GE : ParametricQueryNode.CompareOperator.GT, EscapeQuerySyntaxImpl.discardEscapeChar(goop1.image), goop1.beginColumn, goop1.endColumn); - qUpper = new ParametricQueryNode(field, ParametricQueryNode.CompareOperator.LE, + qUpper = new ParametricQueryNode(field, endInc ? ParametricQueryNode.CompareOperator.LE : ParametricQueryNode.CompareOperator.LT, EscapeQuerySyntaxImpl.discardEscapeChar(goop2.image), goop2.beginColumn, goop2.endColumn); q = new ParametricRangeQueryNode(qLower, qUpper); } - | ( ( goop1=|goop1= ) - [ ] ( goop2=|goop2= ) - ) - [ boost= ] - { - if (goop1.kind == RANGEEX_QUOTED) { - goop1.image = goop1.image.substring(1, goop1.image.length()-1); - } - if (goop2.kind == RANGEEX_QUOTED) { - goop2.image = goop2.image.substring(1, goop2.image.length()-1); - } - qLower = new ParametricQueryNode(field, ParametricQueryNode.CompareOperator.GT, - EscapeQuerySyntaxImpl.discardEscapeChar(goop1.image), goop1.beginColumn, goop1.endColumn); - qUpper = new ParametricQueryNode(field, ParametricQueryNode.CompareOperator.LT, - EscapeQuerySyntaxImpl.discardEscapeChar(goop2.image), goop2.beginColumn, goop2.endColumn); - q = new ParametricRangeQueryNode(qLower, qUpper); - } | term= {q = new QuotedFieldQueryNode(field, EscapeQuerySyntaxImpl.discardEscapeChar(term.image.substring(1, term.image.length()-1)), term.beginColumn + 1, term.endColumn - 1);} [ fuzzySlop= ] [ boost= ] Index: modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParserConstants.java =================================================================== --- modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParserConstants.java (revision 1152425) +++ modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParserConstants.java (working copy) @@ -37,48 +37,50 @@ /** RegularExpression Id. */ int RPAREN = 14; /** RegularExpression Id. */ - int COLON = 15; + int OP_COLON = 15; + /** RegularExpression Id. */ + int OP_EQUAL = 16; + /** RegularExpression Id. */ + int OP_LESSTHAN = 17; /** RegularExpression Id. */ - int CARAT = 16; + int OP_LESSTHANEQ = 18; /** RegularExpression Id. */ - int QUOTED = 17; + int OP_MORETHAN = 19; /** RegularExpression Id. */ - int TERM = 18; + int OP_MORETHANEQ = 20; /** RegularExpression Id. */ - int FUZZY_SLOP = 19; + int CARAT = 21; /** RegularExpression Id. */ - int REGEXPTERM = 20; + int QUOTED = 22; /** RegularExpression Id. */ - int RANGEIN_START = 21; + int TERM = 23; /** RegularExpression Id. */ - int RANGEEX_START = 22; + int FUZZY_SLOP = 24; /** RegularExpression Id. */ - int NUMBER = 23; + int REGEXPTERM = 25; /** RegularExpression Id. */ - int RANGEIN_TO = 24; + int RANGEIN_START = 26; /** RegularExpression Id. */ - int RANGEIN_END = 25; + int RANGEEX_START = 27; /** RegularExpression Id. */ - int RANGEIN_QUOTED = 26; + int NUMBER = 28; /** RegularExpression Id. */ - int RANGEIN_GOOP = 27; + int RANGE_TO = 29; /** RegularExpression Id. */ - int RANGEEX_TO = 28; + int RANGEIN_END = 30; /** RegularExpression Id. */ - int RANGEEX_END = 29; + int RANGEEX_END = 31; /** RegularExpression Id. */ - int RANGEEX_QUOTED = 30; + int RANGE_QUOTED = 32; /** RegularExpression Id. */ - int RANGEEX_GOOP = 31; + int RANGE_GOOP = 33; /** Lexical state. */ int Boost = 0; /** Lexical state. */ - int RangeEx = 1; - /** Lexical state. */ - int RangeIn = 2; + int Range = 1; /** Lexical state. */ - int DEFAULT = 3; + int DEFAULT = 2; /** Literal token values. */ String[] tokenImage = { @@ -98,6 +100,11 @@ "\"(\"", "\")\"", "\":\"", + "\"=\"", + "\"<\"", + "\"<=\"", + "\">\"", + "\">=\"", "\"^\"", "", "", @@ -108,12 +115,9 @@ "", "\"TO\"", "\"]\"", - "", - "", - "\"TO\"", "\"}\"", - "", - "", + "", + "", }; } Index: modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParserTokenManager.java =================================================================== --- modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParserTokenManager.java (revision 1152425) +++ modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParserTokenManager.java (working copy) @@ -18,13 +18,9 @@ */ import java.io.StringReader; -import java.util.ArrayList; -import java.util.List; import java.util.Vector; import org.apache.lucene.messages.Message; import org.apache.lucene.messages.MessageImpl; -import org.apache.lucene.queryparser.flexible.core.QueryNodeError; -import org.apache.lucene.queryparser.flexible.core.QueryNodeException; import org.apache.lucene.queryparser.flexible.core.QueryNodeParseException; import org.apache.lucene.queryparser.flexible.core.messages.QueryParserMessages; import org.apache.lucene.queryparser.flexible.core.nodes.AndQueryNode; @@ -34,15 +30,12 @@ import org.apache.lucene.queryparser.flexible.core.nodes.FuzzyQueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.ModifierQueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.GroupQueryNode; -import org.apache.lucene.queryparser.flexible.core.nodes.OpaqueQueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.OrQueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.ParametricQueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.ParametricRangeQueryNode; import org.apache.lucene.queryparser.flexible.standard.nodes.RegexpQueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.SlopQueryNode; -import org.apache.lucene.queryparser.flexible.core.nodes.ProximityQueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode; -import org.apache.lucene.queryparser.flexible.core.nodes.QueryNodeImpl; import org.apache.lucene.queryparser.flexible.core.nodes.QuotedFieldQueryNode; import org.apache.lucene.queryparser.flexible.core.parser.SyntaxParser; @@ -54,7 +47,7 @@ public java.io.PrintStream debugStream = System.out; /** Set debug output. */ public void setDebugStream(java.io.PrintStream ds) { debugStream = ds; } -private final int jjStopStringLiteralDfa_3(int pos, long active0) +private final int jjStopStringLiteralDfa_2(int pos, long active0) { switch (pos) { @@ -62,9 +55,9 @@ return -1; } } -private final int jjStartNfa_3(int pos, long active0) +private final int jjStartNfa_2(int pos, long active0) { - return jjMoveNfa_3(jjStopStringLiteralDfa_3(pos, active0), pos + 1); + return jjMoveNfa_2(jjStopStringLiteralDfa_2(pos, active0), pos + 1); } private int jjStopAtPos(int pos, int kind) { @@ -72,7 +65,7 @@ jjmatchedPos = pos; return pos + 1; } -private int jjMoveStringLiteralDfa0_3() +private int jjMoveStringLiteralDfa0_2() { switch(curChar) { @@ -86,15 +79,43 @@ return jjStopAtPos(0, 12); case 58: return jjStopAtPos(0, 15); + case 60: + jjmatchedKind = 17; + return jjMoveStringLiteralDfa1_2(0x40000L); + case 61: + return jjStopAtPos(0, 16); + case 62: + jjmatchedKind = 19; + return jjMoveStringLiteralDfa1_2(0x100000L); case 91: - return jjStopAtPos(0, 21); + return jjStopAtPos(0, 26); case 94: - return jjStopAtPos(0, 16); + return jjStopAtPos(0, 21); case 123: - return jjStopAtPos(0, 22); + return jjStopAtPos(0, 27); + default : + return jjMoveNfa_2(0, 0); + } +} +private int jjMoveStringLiteralDfa1_2(long active0) +{ + try { curChar = input_stream.readChar(); } + catch(java.io.IOException e) { + jjStopStringLiteralDfa_2(0, active0); + return 1; + } + switch(curChar) + { + case 61: + if ((active0 & 0x40000L) != 0L) + return jjStopAtPos(1, 18); + else if ((active0 & 0x100000L) != 0L) + return jjStopAtPos(1, 20); + break; default : - return jjMoveNfa_3(0, 0); + break; } + return jjStartNfa_2(0, active0); } static final long[] jjbitVec0 = { 0x1L, 0x0L, 0x0L, 0x0L @@ -108,7 +129,7 @@ static final long[] jjbitVec4 = { 0xfffefffffffffffeL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL }; -private int jjMoveNfa_3(int startState, int curPos) +private int jjMoveNfa_2(int startState, int curPos) { int startsAt = 0; jjnewStateCnt = 33; @@ -127,10 +148,10 @@ switch(jjstateSet[--i]) { case 0: - if ((0xfbffd4f8ffffd9ffL & l) != 0L) + if ((0x8bffd4f8ffffd9ffL & l) != 0L) { - if (kind > 18) - kind = 18; + if (kind > 23) + kind = 23; jjCheckNAddTwoStates(20, 21); } else if ((0x100002600L & l) != 0L) @@ -174,33 +195,33 @@ jjCheckNAddStates(0, 2); break; case 18: - if (curChar == 34 && kind > 17) - kind = 17; + if (curChar == 34 && kind > 22) + kind = 22; break; case 19: - if ((0xfbffd4f8ffffd9ffL & l) == 0L) + if ((0x8bffd4f8ffffd9ffL & l) == 0L) break; - if (kind > 18) - kind = 18; + if (kind > 23) + kind = 23; jjCheckNAddTwoStates(20, 21); break; case 20: - if ((0xfbfffcf8ffffd9ffL & l) == 0L) + if ((0x8bfffcf8ffffd9ffL & l) == 0L) break; - if (kind > 18) - kind = 18; + if (kind > 23) + kind = 23; jjCheckNAddTwoStates(20, 21); break; case 22: - if (kind > 18) - kind = 18; + if (kind > 23) + kind = 23; jjCheckNAddTwoStates(20, 21); break; case 25: if ((0x3ff000000000000L & l) == 0L) break; - if (kind > 19) - kind = 19; + if (kind > 24) + kind = 24; jjAddStates(6, 7); break; case 26: @@ -210,8 +231,8 @@ case 27: if ((0x3ff000000000000L & l) == 0L) break; - if (kind > 19) - kind = 19; + if (kind > 24) + kind = 24; jjCheckNAdd(27); break; case 28: @@ -224,8 +245,8 @@ jjCheckNAddStates(3, 5); break; case 32: - if (curChar == 47 && kind > 20) - kind = 20; + if (curChar == 47 && kind > 25) + kind = 25; break; default : break; } @@ -241,14 +262,14 @@ case 0: if ((0x97ffffff87ffffffL & l) != 0L) { - if (kind > 18) - kind = 18; + if (kind > 23) + kind = 23; jjCheckNAddTwoStates(20, 21); } else if (curChar == 126) { - if (kind > 19) - kind = 19; + if (kind > 24) + kind = 24; jjstateSet[jjnewStateCnt++] = 25; } else if (curChar == 92) @@ -317,8 +338,8 @@ case 20: if ((0x97ffffff87ffffffL & l) == 0L) break; - if (kind > 18) - kind = 18; + if (kind > 23) + kind = 23; jjCheckNAddTwoStates(20, 21); break; case 21: @@ -326,8 +347,8 @@ jjCheckNAddTwoStates(22, 22); break; case 22: - if (kind > 18) - kind = 18; + if (kind > 23) + kind = 23; jjCheckNAddTwoStates(20, 21); break; case 23: @@ -337,8 +358,8 @@ case 24: if (curChar != 126) break; - if (kind > 19) - kind = 19; + if (kind > 24) + kind = 24; jjstateSet[jjnewStateCnt++] = 25; break; case 29: @@ -371,8 +392,8 @@ } if (jjCanMove_2(hiByte, i1, i2, l1, l2)) { - if (kind > 18) - kind = 18; + if (kind > 23) + kind = 23; jjCheckNAddTwoStates(20, 21); } break; @@ -385,15 +406,15 @@ case 20: if (!jjCanMove_2(hiByte, i1, i2, l1, l2)) break; - if (kind > 18) - kind = 18; + if (kind > 23) + kind = 23; jjCheckNAddTwoStates(20, 21); break; case 22: if (!jjCanMove_1(hiByte, i1, i2, l1, l2)) break; - if (kind > 18) - kind = 18; + if (kind > 23) + kind = 23; jjCheckNAddTwoStates(20, 21); break; case 29: @@ -417,201 +438,6 @@ catch(java.io.IOException e) { return curPos; } } } -private final int jjStopStringLiteralDfa_1(int pos, long active0) -{ - switch (pos) - { - case 0: - if ((active0 & 0x10000000L) != 0L) - { - jjmatchedKind = 31; - return 6; - } - return -1; - default : - return -1; - } -} -private final int jjStartNfa_1(int pos, long active0) -{ - return jjMoveNfa_1(jjStopStringLiteralDfa_1(pos, active0), pos + 1); -} -private int jjMoveStringLiteralDfa0_1() -{ - switch(curChar) - { - case 84: - return jjMoveStringLiteralDfa1_1(0x10000000L); - case 125: - return jjStopAtPos(0, 29); - default : - return jjMoveNfa_1(0, 0); - } -} -private int jjMoveStringLiteralDfa1_1(long active0) -{ - try { curChar = input_stream.readChar(); } - catch(java.io.IOException e) { - jjStopStringLiteralDfa_1(0, active0); - return 1; - } - switch(curChar) - { - case 79: - if ((active0 & 0x10000000L) != 0L) - return jjStartNfaWithStates_1(1, 28, 6); - break; - default : - break; - } - return jjStartNfa_1(0, active0); -} -private int jjStartNfaWithStates_1(int pos, int kind, int state) -{ - jjmatchedKind = kind; - jjmatchedPos = pos; - try { curChar = input_stream.readChar(); } - catch(java.io.IOException e) { return pos + 1; } - return jjMoveNfa_1(state, pos + 1); -} -private int jjMoveNfa_1(int startState, int curPos) -{ - int startsAt = 0; - jjnewStateCnt = 7; - int i = 1; - jjstateSet[0] = startState; - int kind = 0x7fffffff; - for (;;) - { - if (++jjround == 0x7fffffff) - ReInitRounds(); - if (curChar < 64) - { - long l = 1L << curChar; - do - { - switch(jjstateSet[--i]) - { - case 0: - if ((0xfffffffeffffffffL & l) != 0L) - { - if (kind > 31) - kind = 31; - jjCheckNAdd(6); - } - if ((0x100002600L & l) != 0L) - { - if (kind > 7) - kind = 7; - } - else if (curChar == 34) - jjCheckNAddTwoStates(2, 4); - break; - case 1: - if (curChar == 34) - jjCheckNAddTwoStates(2, 4); - break; - case 2: - if ((0xfffffffbffffffffL & l) != 0L) - jjCheckNAddStates(8, 10); - break; - case 3: - if (curChar == 34) - jjCheckNAddStates(8, 10); - break; - case 5: - if (curChar == 34 && kind > 30) - kind = 30; - break; - case 6: - if ((0xfffffffeffffffffL & l) == 0L) - break; - if (kind > 31) - kind = 31; - jjCheckNAdd(6); - break; - default : break; - } - } while(i != startsAt); - } - else if (curChar < 128) - { - long l = 1L << (curChar & 077); - do - { - switch(jjstateSet[--i]) - { - case 0: - case 6: - if ((0xdfffffffffffffffL & l) == 0L) - break; - if (kind > 31) - kind = 31; - jjCheckNAdd(6); - break; - case 2: - jjAddStates(8, 10); - break; - case 4: - if (curChar == 92) - jjstateSet[jjnewStateCnt++] = 3; - break; - default : break; - } - } while(i != startsAt); - } - else - { - int hiByte = (int)(curChar >> 8); - int i1 = hiByte >> 6; - long l1 = 1L << (hiByte & 077); - int i2 = (curChar & 0xff) >> 6; - long l2 = 1L << (curChar & 077); - do - { - switch(jjstateSet[--i]) - { - case 0: - if (jjCanMove_0(hiByte, i1, i2, l1, l2)) - { - if (kind > 7) - kind = 7; - } - if (jjCanMove_1(hiByte, i1, i2, l1, l2)) - { - if (kind > 31) - kind = 31; - jjCheckNAdd(6); - } - break; - case 2: - if (jjCanMove_1(hiByte, i1, i2, l1, l2)) - jjAddStates(8, 10); - break; - case 6: - if (!jjCanMove_1(hiByte, i1, i2, l1, l2)) - break; - if (kind > 31) - kind = 31; - jjCheckNAdd(6); - break; - default : break; - } - } while(i != startsAt); - } - if (kind != 0x7fffffff) - { - jjmatchedKind = kind; - jjmatchedPos = curPos; - kind = 0x7fffffff; - } - ++curPos; - if ((i = jjnewStateCnt) == (startsAt = 7 - (jjnewStateCnt = startsAt))) - return curPos; - try { curChar = input_stream.readChar(); } - catch(java.io.IOException e) { return curPos; } - } -} private int jjMoveStringLiteralDfa0_0() { return jjMoveNfa_0(0, 0); @@ -637,9 +463,9 @@ case 0: if ((0x3ff000000000000L & l) == 0L) break; - if (kind > 23) - kind = 23; - jjAddStates(11, 12); + if (kind > 28) + kind = 28; + jjAddStates(8, 9); break; case 1: if (curChar == 46) @@ -648,8 +474,8 @@ case 2: if ((0x3ff000000000000L & l) == 0L) break; - if (kind > 23) - kind = 23; + if (kind > 28) + kind = 28; jjCheckNAdd(2); break; default : break; @@ -695,14 +521,14 @@ catch(java.io.IOException e) { return curPos; } } } -private final int jjStopStringLiteralDfa_2(int pos, long active0) +private final int jjStopStringLiteralDfa_1(int pos, long active0) { switch (pos) { case 0: - if ((active0 & 0x1000000L) != 0L) + if ((active0 & 0x20000000L) != 0L) { - jjmatchedKind = 27; + jjmatchedKind = 33; return 6; } return -1; @@ -710,49 +536,51 @@ return -1; } } -private final int jjStartNfa_2(int pos, long active0) +private final int jjStartNfa_1(int pos, long active0) { - return jjMoveNfa_2(jjStopStringLiteralDfa_2(pos, active0), pos + 1); + return jjMoveNfa_1(jjStopStringLiteralDfa_1(pos, active0), pos + 1); } -private int jjMoveStringLiteralDfa0_2() +private int jjMoveStringLiteralDfa0_1() { switch(curChar) { case 84: - return jjMoveStringLiteralDfa1_2(0x1000000L); + return jjMoveStringLiteralDfa1_1(0x20000000L); case 93: - return jjStopAtPos(0, 25); + return jjStopAtPos(0, 30); + case 125: + return jjStopAtPos(0, 31); default : - return jjMoveNfa_2(0, 0); + return jjMoveNfa_1(0, 0); } } -private int jjMoveStringLiteralDfa1_2(long active0) +private int jjMoveStringLiteralDfa1_1(long active0) { try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { - jjStopStringLiteralDfa_2(0, active0); + jjStopStringLiteralDfa_1(0, active0); return 1; } switch(curChar) { case 79: - if ((active0 & 0x1000000L) != 0L) - return jjStartNfaWithStates_2(1, 24, 6); + if ((active0 & 0x20000000L) != 0L) + return jjStartNfaWithStates_1(1, 29, 6); break; default : break; } - return jjStartNfa_2(0, active0); + return jjStartNfa_1(0, active0); } -private int jjStartNfaWithStates_2(int pos, int kind, int state) +private int jjStartNfaWithStates_1(int pos, int kind, int state) { jjmatchedKind = kind; jjmatchedPos = pos; try { curChar = input_stream.readChar(); } catch(java.io.IOException e) { return pos + 1; } - return jjMoveNfa_2(state, pos + 1); + return jjMoveNfa_1(state, pos + 1); } -private int jjMoveNfa_2(int startState, int curPos) +private int jjMoveNfa_1(int startState, int curPos) { int startsAt = 0; jjnewStateCnt = 7; @@ -773,8 +601,8 @@ case 0: if ((0xfffffffeffffffffL & l) != 0L) { - if (kind > 27) - kind = 27; + if (kind > 33) + kind = 33; jjCheckNAdd(6); } if ((0x100002600L & l) != 0L) @@ -791,21 +619,21 @@ break; case 2: if ((0xfffffffbffffffffL & l) != 0L) - jjCheckNAddStates(8, 10); + jjCheckNAddStates(10, 12); break; case 3: if (curChar == 34) - jjCheckNAddStates(8, 10); + jjCheckNAddStates(10, 12); break; case 5: - if (curChar == 34 && kind > 26) - kind = 26; + if (curChar == 34 && kind > 32) + kind = 32; break; case 6: if ((0xfffffffeffffffffL & l) == 0L) break; - if (kind > 27) - kind = 27; + if (kind > 33) + kind = 33; jjCheckNAdd(6); break; default : break; @@ -821,14 +649,14 @@ { case 0: case 6: - if ((0xffffffffdfffffffL & l) == 0L) + if ((0xdfffffffdfffffffL & l) == 0L) break; - if (kind > 27) - kind = 27; + if (kind > 33) + kind = 33; jjCheckNAdd(6); break; case 2: - jjAddStates(8, 10); + jjAddStates(10, 12); break; case 4: if (curChar == 92) @@ -857,20 +685,20 @@ } if (jjCanMove_1(hiByte, i1, i2, l1, l2)) { - if (kind > 27) - kind = 27; + if (kind > 33) + kind = 33; jjCheckNAdd(6); } break; case 2: if (jjCanMove_1(hiByte, i1, i2, l1, l2)) - jjAddStates(8, 10); + jjAddStates(10, 12); break; case 6: if (!jjCanMove_1(hiByte, i1, i2, l1, l2)) break; - if (kind > 27) - kind = 27; + if (kind > 33) + kind = 33; jjCheckNAdd(6); break; default : break; @@ -891,7 +719,7 @@ } } static final int[] jjnextStates = { - 15, 16, 18, 29, 31, 32, 25, 26, 2, 4, 5, 0, 1, + 15, 16, 18, 29, 31, 32, 25, 26, 0, 1, 2, 4, 5, }; private static final boolean jjCanMove_0(int hiByte, int i1, int i2, long l1, long l2) { @@ -933,24 +761,23 @@ /** Token literal values. */ public static final String[] jjstrLiteralImages = { "", null, null, null, null, null, null, null, null, null, null, "\53", "\55", -"\50", "\51", "\72", "\136", null, null, null, null, "\133", "\173", null, -"\124\117", "\135", null, null, "\124\117", "\175", null, null, }; +"\50", "\51", "\72", "\75", "\74", "\74\75", "\76", "\76\75", "\136", null, null, +null, null, "\133", "\173", null, "\124\117", "\135", "\175", null, null, }; /** Lexer state names. */ public static final String[] lexStateNames = { "Boost", - "RangeEx", - "RangeIn", + "Range", "DEFAULT", }; /** Lex State array. */ public static final int[] jjnewLexState = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, 2, 1, 3, -1, - 3, -1, -1, -1, 3, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, + -1, 1, 1, 2, -1, 2, 2, -1, -1, }; static final long[] jjtoToken = { - 0xffffff01L, + 0x3ffffff01L, }; static final long[] jjtoSkip = { 0x80L, @@ -998,7 +825,7 @@ /** Switch to specified lex state. */ public void SwitchTo(int lexState) { - if (lexState >= 4 || lexState < 0) + if (lexState >= 3 || lexState < 0) throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE); else curLexState = lexState; @@ -1028,8 +855,8 @@ return t; } -int curLexState = 3; -int defaultLexState = 3; +int curLexState = 2; +int defaultLexState = 2; int jjnewStateCnt; int jjround; int jjmatchedPos; @@ -1072,11 +899,6 @@ jjmatchedPos = 0; curPos = jjMoveStringLiteralDfa0_2(); break; - case 3: - jjmatchedKind = 0x7fffffff; - jjmatchedPos = 0; - curPos = jjMoveStringLiteralDfa0_3(); - break; } if (jjmatchedKind != 0x7fffffff) { Index: modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/Token.java =================================================================== --- modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/Token.java (revision 1152425) +++ modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/Token.java (working copy) @@ -121,4 +121,4 @@ } } -/* JavaCC - OriginalChecksum=0aac6816ecd328eda2f38b9d09739ab6 (do not edit this line) */ +/* JavaCC - OriginalChecksum=e9c55091ec11152bcd3a300ddff5c73a (do not edit this line) */ Index: modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/TokenMgrError.java =================================================================== --- modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/TokenMgrError.java (revision 1152425) +++ modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/TokenMgrError.java (working copy) @@ -138,4 +138,4 @@ this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason); } } -/* JavaCC - OriginalChecksum=a75b5b61664a73631a032a6e44f4b38a (do not edit this line) */ +/* JavaCC - OriginalChecksum=76b513fd9c50f65248056bbeeff49277 (do not edit this line) */ Index: modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/LowercaseExpandedTermsQueryNodeProcessor.java =================================================================== --- modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/LowercaseExpandedTermsQueryNodeProcessor.java (revision 1152425) +++ modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/LowercaseExpandedTermsQueryNodeProcessor.java (working copy) @@ -67,7 +67,8 @@ || node instanceof ParametricQueryNode || node instanceof RegexpQueryNode) { TextableQueryNode txtNode = (TextableQueryNode) node; - txtNode.setText(UnescapedCharSequence.toLowerCase(txtNode.getText())); + CharSequence text = txtNode.getText(); + txtNode.setText(text != null ? UnescapedCharSequence.toLowerCase(text) : null); } return node; Index: modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/NumericQueryNodeProcessor.java =================================================================== --- modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/NumericQueryNodeProcessor.java (revision 1152425) +++ modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/NumericQueryNodeProcessor.java (working copy) @@ -29,6 +29,7 @@ import org.apache.lucene.queryparser.flexible.core.messages.QueryParserMessages; import org.apache.lucene.queryparser.flexible.core.nodes.FieldQueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.ParametricQueryNode; +import org.apache.lucene.queryparser.flexible.core.nodes.ParametricRangeQueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode; import org.apache.lucene.queryparser.flexible.core.processors.QueryNodeProcessorImpl; import org.apache.lucene.queryparser.flexible.standard.config.NumericConfig; @@ -69,7 +70,7 @@ protected QueryNode postProcessNode(QueryNode node) throws QueryNodeException { if (node instanceof FieldQueryNode - && !(node instanceof ParametricQueryNode)) { + && !(node.getParent() instanceof ParametricRangeQueryNode)) { QueryConfigHandler config = getQueryConfigHandler(); @@ -85,30 +86,38 @@ if (numericConfig != null) { NumberFormat numberFormat = numericConfig.getNumberFormat(); - Number number; + String text = fieldNode.getTextAsString(); + Number number = null; - try { - number = numberFormat.parse(fieldNode.getTextAsString()); + if (text.length() > 0) { + + try { + number = numberFormat.parse(text); + + } catch (ParseException e) { + throw new QueryNodeParseException(new MessageImpl( + QueryParserMessages.COULD_NOT_PARSE_NUMBER, fieldNode + .getTextAsString(), numberFormat.getClass() + .getCanonicalName()), e); + } + + switch (numericConfig.getType()) { + case LONG: + number = number.longValue(); + break; + case INT: + number = number.intValue(); + break; + case DOUBLE: + number = number.doubleValue(); + break; + case FLOAT: + number = number.floatValue(); + } - } catch (ParseException e) { + } else { throw new QueryNodeParseException(new MessageImpl( - QueryParserMessages.COULD_NOT_PARSE_NUMBER, fieldNode - .getTextAsString(), numberFormat.getClass() - .getCanonicalName()), e); - } - - switch (numericConfig.getType()) { - case LONG: - number = number.longValue(); - break; - case INT: - number = number.intValue(); - break; - case DOUBLE: - number = number.doubleValue(); - break; - case FLOAT: - number = number.floatValue(); + QueryParserMessages.NUMERIC_CANNOT_BE_EMPTY, fieldNode.getFieldAsString())); } NumericQueryNode lowerNode = new NumericQueryNode(fieldNode Index: modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/NumericRangeQueryNodeProcessor.java =================================================================== --- modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/NumericRangeQueryNodeProcessor.java (revision 1152425) +++ modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/NumericRangeQueryNodeProcessor.java (working copy) @@ -27,7 +27,6 @@ import org.apache.lucene.queryparser.flexible.core.config.FieldConfig; import org.apache.lucene.queryparser.flexible.core.config.QueryConfigHandler; import org.apache.lucene.queryparser.flexible.core.messages.QueryParserMessages; -import org.apache.lucene.queryparser.flexible.core.nodes.FieldQueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.ParametricQueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.ParametricRangeQueryNode; import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode; @@ -83,45 +82,55 @@ ParametricQueryNode lower = parametricRangeNode.getLowerBound(); ParametricQueryNode upper = parametricRangeNode.getUpperBound(); + String lowerText = lower.getTextAsString(); + String upperText = upper.getTextAsString(); NumberFormat numberFormat = numericConfig.getNumberFormat(); - Number lowerNumber, upperNumber; + Number lowerNumber = null, upperNumber = null; - try { - lowerNumber = numberFormat.parse(lower.getTextAsString()); + if (lowerText.length() > 0) { + + try { + lowerNumber = numberFormat.parse(lowerText); + + } catch (ParseException e) { + throw new QueryNodeParseException(new MessageImpl( + QueryParserMessages.COULD_NOT_PARSE_NUMBER, lower + .getTextAsString(), numberFormat.getClass() + .getCanonicalName()), e); + } - } catch (ParseException e) { - throw new QueryNodeParseException(new MessageImpl( - QueryParserMessages.COULD_NOT_PARSE_NUMBER, lower - .getTextAsString(), numberFormat.getClass() - .getCanonicalName()), e); } - try { - upperNumber = numberFormat.parse(upper.getTextAsString()); - - } catch (ParseException e) { - throw new QueryNodeParseException(new MessageImpl( - QueryParserMessages.COULD_NOT_PARSE_NUMBER, upper - .getTextAsString(), numberFormat.getClass() - .getCanonicalName()), e); + if (upperText.length() > 0) { + + try { + upperNumber = numberFormat.parse(upperText); + + } catch (ParseException e) { + throw new QueryNodeParseException(new MessageImpl( + QueryParserMessages.COULD_NOT_PARSE_NUMBER, upper + .getTextAsString(), numberFormat.getClass() + .getCanonicalName()), e); + } + } switch (numericConfig.getType()) { case LONG: - upperNumber = upperNumber.longValue(); - lowerNumber = lowerNumber.longValue(); + if (upperNumber != null) upperNumber = upperNumber.longValue(); + if (lowerNumber != null) lowerNumber = lowerNumber.longValue(); break; case INT: - upperNumber = upperNumber.intValue(); - lowerNumber = lowerNumber.intValue(); + if (upperNumber != null) upperNumber = upperNumber.intValue(); + if (lowerNumber != null) lowerNumber = lowerNumber.intValue(); break; case DOUBLE: - upperNumber = upperNumber.doubleValue(); - lowerNumber = lowerNumber.doubleValue(); + if (upperNumber != null) upperNumber = upperNumber.doubleValue(); + if (lowerNumber != null) lowerNumber = lowerNumber.doubleValue(); break; case FLOAT: - upperNumber = upperNumber.floatValue(); - lowerNumber = lowerNumber.floatValue(); + if (upperNumber != null) upperNumber = upperNumber.floatValue(); + if (lowerNumber != null) lowerNumber = lowerNumber.floatValue(); } NumericQueryNode lowerNode = new NumericQueryNode( @@ -129,8 +138,10 @@ NumericQueryNode upperNode = new NumericQueryNode( parametricRangeNode.getField(), upperNumber, numberFormat); - boolean upperInclusive = upper.getOperator() == CompareOperator.LE; - boolean lowerInclusive = lower.getOperator() == CompareOperator.GE; + boolean upperInclusive = upper == null + | upper.getOperator() == CompareOperator.LE; + boolean lowerInclusive = lower == null + | lower.getOperator() == CompareOperator.GE; return new NumericRangeQueryNode(lowerNode, upperNode, lowerInclusive, upperInclusive, numericConfig); Index: modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/OpenRangeQueryNodeProcessor.java =================================================================== --- modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/OpenRangeQueryNodeProcessor.java (revision 0) +++ modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/OpenRangeQueryNodeProcessor.java (revision 0) @@ -0,0 +1,61 @@ +package org.apache.lucene.queryparser.flexible.standard.processors; + +import java.util.List; + +import org.apache.lucene.queryparser.flexible.core.QueryNodeException; +import org.apache.lucene.queryparser.flexible.core.nodes.ParametricQueryNode; +import org.apache.lucene.queryparser.flexible.core.nodes.ParametricRangeQueryNode; +import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode; +import org.apache.lucene.queryparser.flexible.core.processors.QueryNodeProcessorImpl; +import org.apache.lucene.queryparser.flexible.core.util.UnescapedCharSequence; + +public class OpenRangeQueryNodeProcessor extends QueryNodeProcessorImpl { + + final public static String OPEN_RANGE_TOKEN = "*"; + + public OpenRangeQueryNodeProcessor() {} + + @Override + protected QueryNode postProcessNode(QueryNode node) throws QueryNodeException { + + if (node instanceof ParametricRangeQueryNode) { + ParametricRangeQueryNode rangeNode = (ParametricRangeQueryNode) node; + ParametricQueryNode lowerNode = (ParametricQueryNode) rangeNode.getLowerBound(); + ParametricQueryNode upperNode = (ParametricQueryNode) rangeNode.getUpperBound(); + CharSequence lowerText = lowerNode.getText(); + CharSequence upperText = upperNode.getText(); + + + if (OPEN_RANGE_TOKEN.equals(upperNode.getTextAsString()) + && (!(upperText instanceof UnescapedCharSequence) || !((UnescapedCharSequence) upperText) + .wasEscaped(0))) { + upperText = ""; + } + + if (OPEN_RANGE_TOKEN.equals(lowerNode.getTextAsString()) + && (!(lowerText instanceof UnescapedCharSequence) || !((UnescapedCharSequence) lowerText) + .wasEscaped(0))) { + lowerText = ""; + } + + lowerNode.setText(lowerText); + upperNode.setText(upperText); + + } + + return node; + + } + + @Override + protected QueryNode preProcessNode(QueryNode node) throws QueryNodeException { + return node; + } + + @Override + protected List setChildrenOrder(List children) + throws QueryNodeException { + return children; + } + +} Index: modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/ParametricRangeQueryNodeProcessor.java =================================================================== --- modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/ParametricRangeQueryNodeProcessor.java (revision 1152425) +++ modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/ParametricRangeQueryNodeProcessor.java (working copy) @@ -44,12 +44,13 @@ * value, it will only create the {@link TermRangeQueryNode} using the * non-parsed values.
*
- * If a {@link ConfigurationKeys#LOCALE} is defined in the {@link QueryConfigHandler} it - * will be used to parse the date, otherwise {@link Locale#getDefault()} will be - * used.
+ * If a {@link ConfigurationKeys#LOCALE} is defined in the + * {@link QueryConfigHandler} it will be used to parse the date, otherwise + * {@link Locale#getDefault()} will be used.
*
- * If a {@link ConfigurationKeys#DATE_RESOLUTION} is defined and the {@link Resolution} is - * not null it will also be used to parse the date value.
+ * If a {@link ConfigurationKeys#DATE_RESOLUTION} is defined and the + * {@link Resolution} is not null it will also be used to parse the + * date value.
*
* * @see ConfigurationKeys#DATE_RESOLUTION @@ -74,7 +75,7 @@ DateTools.Resolution dateRes = null; boolean inclusive = false; Locale locale = getQueryConfigHandler().get(ConfigurationKeys.LOCALE); - + if (locale == null) { locale = Locale.getDefault(); } @@ -95,9 +96,6 @@ if (upper.getOperator() == CompareOperator.LE) { inclusive = true; - - } else if (lower.getOperator() == CompareOperator.GE) { - inclusive = true; } String part1 = lower.getTextAsString(); @@ -106,33 +104,41 @@ try { DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale); df.setLenient(true); - Date d1 = df.parse(part1); - Date d2 = df.parse(part2); - if (inclusive) { - // The user can only specify the date, not the time, so make sure - // the time is set to the latest possible time of that date to really - // include all documents: - Calendar cal = Calendar.getInstance(locale); - cal.setTime(d2); - cal.set(Calendar.HOUR_OF_DAY, 23); - cal.set(Calendar.MINUTE, 59); - cal.set(Calendar.SECOND, 59); - cal.set(Calendar.MILLISECOND, 999); - d2 = cal.getTime(); + + if (part1.length() > 0) { + Date d1 = df.parse(part1); + part1 = DateTools.dateToString(d1, dateRes); + lower.setText(part1); + } + + if (part2.length() > 0) { + Date d2 = df.parse(part2); + if (inclusive) { + // The user can only specify the date, not the time, so make sure + // the time is set to the latest possible time of that date to + // really + // include all documents: + Calendar cal = Calendar.getInstance(locale); + cal.setTime(d2); + cal.set(Calendar.HOUR_OF_DAY, 23); + cal.set(Calendar.MINUTE, 59); + cal.set(Calendar.SECOND, 59); + cal.set(Calendar.MILLISECOND, 999); + d2 = cal.getTime(); + } + + part2 = DateTools.dateToString(d2, dateRes); + upper.setText(part2); + } - part1 = DateTools.dateToString(d1, dateRes); - part2 = DateTools.dateToString(d2, dateRes); } catch (Exception e) { // do nothing } - lower.setText(part1); - upper.setText(part2); - - return new TermRangeQueryNode(lower, upper, - lower.getOperator() == CompareOperator.GE, - upper.getOperator() == CompareOperator.LE); + return new TermRangeQueryNode(lower, upper, part1.length() == 0 + | lower.getOperator() == CompareOperator.GE, part2.length() == 0 + | upper.getOperator() == CompareOperator.LE); } Index: modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/StandardQueryNodeProcessorPipeline.java =================================================================== --- modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/StandardQueryNodeProcessorPipeline.java (revision 1152425) +++ modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/StandardQueryNodeProcessorPipeline.java (working copy) @@ -52,6 +52,7 @@ add(new MultiFieldQueryNodeProcessor()); add(new FuzzyQueryNodeProcessor()); add(new MatchAllDocsQueryNodeProcessor()); + add(new OpenRangeQueryNodeProcessor()); add(new NumericQueryNodeProcessor()); add(new NumericRangeQueryNodeProcessor()); add(new LowercaseExpandedTermsQueryNodeProcessor()); Index: modules/queryparser/src/java/org/apache/lucene/queryparser/surround/parser/CharStream.java =================================================================== --- modules/queryparser/src/java/org/apache/lucene/queryparser/surround/parser/CharStream.java (revision 1152425) +++ modules/queryparser/src/java/org/apache/lucene/queryparser/surround/parser/CharStream.java (working copy) @@ -28,14 +28,14 @@ /** * Returns the column position of the character last read. - * @deprecated (gen) + * @deprecated * @see #getEndColumn */ int getColumn(); /** * Returns the line number of the character last read. - * @deprecated (gen) + * @deprecated * @see #getEndLine */ int getLine(); @@ -109,4 +109,4 @@ void Done(); } -/* JavaCC - OriginalChecksum=872eafa2c180de2e08862f87f675b2dd (do not edit this line) */ +/* JavaCC - OriginalChecksum=def574f5a8956cf01b79ebe7bce95e74 (do not edit this line) */ Index: modules/queryparser/src/java/org/apache/lucene/queryparser/surround/parser/ParseException.java =================================================================== --- modules/queryparser/src/java/org/apache/lucene/queryparser/surround/parser/ParseException.java (revision 1152425) +++ modules/queryparser/src/java/org/apache/lucene/queryparser/surround/parser/ParseException.java (working copy) @@ -195,4 +195,4 @@ } } -/* JavaCC - OriginalChecksum=2a154532f17c98e29d1671b8413edb60 (do not edit this line) */ +/* JavaCC - OriginalChecksum=10f9a58db50336511327c43cc760ac21 (do not edit this line) */ Index: modules/queryparser/src/java/org/apache/lucene/queryparser/surround/parser/QueryParser.java =================================================================== --- modules/queryparser/src/java/org/apache/lucene/queryparser/surround/parser/QueryParser.java (revision 1152425) +++ modules/queryparser/src/java/org/apache/lucene/queryparser/surround/parser/QueryParser.java (working copy) @@ -624,7 +624,7 @@ return (jj_ntk = jj_nt.kind); } - private java.util.List jj_expentries = new java.util.ArrayList(); + private java.util.List jj_expentries = new java.util.ArrayList(); private int[] jj_expentry; private int jj_kind = -1; private int[] jj_lasttokens = new int[100]; @@ -684,7 +684,7 @@ jj_add_error_token(0, 0); int[][] exptokseq = new int[jj_expentries.size()][]; for (int i = 0; i < jj_expentries.size(); i++) { - exptokseq[i] = jj_expentries.get(i); + exptokseq[i] = (int[])jj_expentries.get(i); } return new ParseException(token, exptokseq, tokenImage); } Index: modules/queryparser/src/java/org/apache/lucene/queryparser/surround/parser/Token.java =================================================================== --- modules/queryparser/src/java/org/apache/lucene/queryparser/surround/parser/Token.java (revision 1152425) +++ modules/queryparser/src/java/org/apache/lucene/queryparser/surround/parser/Token.java (working copy) @@ -121,4 +121,4 @@ } } -/* JavaCC - OriginalChecksum=a1d2d2c0d7f5810183a1438fb4d51c1c (do not edit this line) */ +/* JavaCC - OriginalChecksum=072a7ad2709e5810f5c35fa113fa0c8b (do not edit this line) */ Index: modules/queryparser/src/java/org/apache/lucene/queryparser/surround/parser/TokenMgrError.java =================================================================== --- modules/queryparser/src/java/org/apache/lucene/queryparser/surround/parser/TokenMgrError.java (revision 1152425) +++ modules/queryparser/src/java/org/apache/lucene/queryparser/surround/parser/TokenMgrError.java (working copy) @@ -138,4 +138,4 @@ this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason); } } -/* JavaCC - OriginalChecksum=fecdd69c7d7b49407e441e312085db53 (do not edit this line) */ +/* JavaCC - OriginalChecksum=9cfe06f5ffcaac4b72c928c9ced2f5e7 (do not edit this line) */ Index: modules/queryparser/src/resources/org/apache/lucene/queryparser/flexible/core/messages/QueryParserMessages.properties =================================================================== --- modules/queryparser/src/resources/org/apache/lucene/queryparser/flexible/core/messages/QueryParserMessages.properties (revision 1152425) +++ modules/queryparser/src/resources/org/apache/lucene/queryparser/flexible/core/messages/QueryParserMessages.properties (working copy) @@ -55,3 +55,6 @@ #Apache Lucene Community UNSUPPORTED_NUMERIC_DATA_TYPE = Unsupported NumericField.DataType: {0} + +#Apache Lucene Community +NUMERIC_CANNOT_BE_EMPTY = Field "{0}" is numeric and cannot have an empty value. Index: modules/queryparser/src/test/org/apache/lucene/queryparser/classic/TestQueryParser.java =================================================================== --- modules/queryparser/src/test/org/apache/lucene/queryparser/classic/TestQueryParser.java (revision 1152425) +++ modules/queryparser/src/test/org/apache/lucene/queryparser/classic/TestQueryParser.java (working copy) @@ -547,6 +547,17 @@ qp.setMultiTermRewriteMethod(MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE); assertEquals(MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE,((TermRangeQuery)qp.parse("[ a TO z]")).getRewriteMethod()); + // test open ranges + assertQueryEquals("[ a TO * ]", null, "[a TO *]"); + assertQueryEquals("[ * TO z ]", null, "[* TO z]"); + assertQueryEquals("[ * TO * ]", null, "[* TO *]"); + + // mixing exclude and include bounds + assertQueryEquals("{ a TO z ]", null, "{a TO z]"); + assertQueryEquals("[ a TO z }", null, "[a TO z}"); + assertQueryEquals("{ a TO * ]", null, "{a TO *]"); + assertQueryEquals("[ * TO z }", null, "[* TO z}"); + assertQueryEquals("[ a TO z ]", null, "[a TO z]"); assertQueryEquals("{ a TO z}", null, "{a TO z}"); assertQueryEquals("{ a TO z }", null, "{a TO z}"); Index: modules/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestNumericQueryParser.java =================================================================== --- modules/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestNumericQueryParser.java (revision 1152425) +++ modules/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestNumericQueryParser.java (working copy) @@ -83,8 +83,10 @@ private static IndexReader reader = null; private static IndexSearcher searcher = null; - private static boolean checkDateFormatSanity(DateFormat dateFormat, long date) throws ParseException { - return date == dateFormat.parse(dateFormat.format(new Date(date))).getTime(); + private static boolean checkDateFormatSanity(DateFormat dateFormat, long date) + throws ParseException { + return date == dateFormat.parse(dateFormat.format(new Date(date))) + .getTime(); } @BeforeClass @@ -112,8 +114,8 @@ // assumes localized date pattern will have at least year, month, day, // hour, minute - dateFormat = (SimpleDateFormat) DateFormat - .getDateTimeInstance(DATE_STYLE, TIME_STYLE, LOCALE); + dateFormat = (SimpleDateFormat) DateFormat.getDateTimeInstance( + DATE_STYLE, TIME_STYLE, LOCALE); // not all date patterns includes era, full year, timezone and second, // so we add them here @@ -135,9 +137,8 @@ // only positive values randomDate = Math.abs(randomDate); } while (randomDate == 0L); - - dateFormatSanityCheckPass &= checkDateFormatSanity(dateFormat, - randomDate); + + dateFormatSanityCheckPass &= checkDateFormatSanity(dateFormat, randomDate); dateFormatSanityCheckPass &= checkDateFormatSanity(dateFormat, 0); @@ -152,7 +153,7 @@ NUMBER_FORMAT.setMinimumFractionDigits((random.nextInt() & 20) + 1); NUMBER_FORMAT.setMaximumIntegerDigits((random.nextInt() & 20) + 1); NUMBER_FORMAT.setMinimumIntegerDigits((random.nextInt() & 20) + 1); - + double randomDouble; long randomLong; int randomInt; @@ -167,8 +168,7 @@ while ((randomFloat = normalizeNumber(Math.abs(random.nextFloat())) .floatValue()) == 0.0f) ; - while ((randomInt = normalizeNumber(Math.abs(random.nextInt())) - .intValue()) == 0) + while ((randomInt = normalizeNumber(Math.abs(random.nextInt())).intValue()) == 0) ; randomNumberMap.put(NumericField.DataType.LONG.name(), randomLong); @@ -178,7 +178,7 @@ randomNumberMap.put(DATE_FIELD_NAME, randomDate); RANDOM_NUMBER_MAP = Collections.unmodifiableMap(randomNumberMap); - + directory = newDirectory(); RandomIndexWriter writer = new RandomIndexWriter(random, directory, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)) @@ -218,11 +218,15 @@ reader = writer.getReader(); searcher = newSearcher(reader); writer.close(); - + } private static Number getNumberType(NumberType numberType, String fieldName) { + if (numberType == null) { + return null; + } + switch (numberType) { case POSITIVE: @@ -253,6 +257,7 @@ default: return 0; + } } @@ -295,25 +300,25 @@ assertRangeQuery(NumberType.NEGATIVE, NumberType.NEGATIVE, true, true, 1); } - // @Test + @Test // test disabled since standard syntax parser does not work with inclusive and // exclusive at the same time -// public void testInclusiveLowerNumericRange() throws Exception { -// assertRangeQuery(NumberType.NEGATIVE, NumberType.ZERO, true, false, 1); -// assertRangeQuery(NumberType.ZERO, NumberType.POSITIVE, true, false, 1); -// assertRangeQuery(NumberType.NEGATIVE, NumberType.POSITIVE, true, false, 2); -// assertRangeQuery(NumberType.NEGATIVE, NumberType.NEGATIVE, true, false, 1); -// } + public void testInclusiveLowerNumericRange() throws Exception { + assertRangeQuery(NumberType.NEGATIVE, NumberType.ZERO, false, true, 1); + assertRangeQuery(NumberType.ZERO, NumberType.POSITIVE, false, true, 1); + assertRangeQuery(NumberType.NEGATIVE, NumberType.POSITIVE, false, true, 2); + assertRangeQuery(NumberType.NEGATIVE, NumberType.NEGATIVE, false, true, 0); + } - // @Test + @Test // test disabled since standard syntax parser does not work with inclusive and // exclusive at the same time -// public void testInclusiveUpperNumericRange() throws Exception { -// assertRangeQuery(NumberType.NEGATIVE, NumberType.ZERO, false, true, 1); -// assertRangeQuery(NumberType.ZERO, NumberType.POSITIVE, false, true, 1); -// assertRangeQuery(NumberType.NEGATIVE, NumberType.POSITIVE, false, true, 2); -// assertRangeQuery(NumberType.NEGATIVE, NumberType.NEGATIVE, false, true, 1); -// } + public void testInclusiveUpperNumericRange() throws Exception { + assertRangeQuery(NumberType.NEGATIVE, NumberType.ZERO, true, false, 1); + assertRangeQuery(NumberType.ZERO, NumberType.POSITIVE, true, false, 1); + assertRangeQuery(NumberType.NEGATIVE, NumberType.POSITIVE, true, false, 2); + assertRangeQuery(NumberType.NEGATIVE, NumberType.NEGATIVE, true, false, 0); + } @Test public void testExclusiveNumericRange() throws Exception { @@ -325,6 +330,43 @@ } @Test + public void testOpenRangeNumericQuery() throws Exception { + assertOpenRangeQuery(NumberType.ZERO, "<", 1); + assertOpenRangeQuery(NumberType.POSITIVE, "<", 2); + assertOpenRangeQuery(NumberType.NEGATIVE, "<", 0); + + assertOpenRangeQuery(NumberType.ZERO, "<=", 2); + assertOpenRangeQuery(NumberType.POSITIVE, "<=", 3); + assertOpenRangeQuery(NumberType.NEGATIVE, "<=", 1); + + assertOpenRangeQuery(NumberType.ZERO, ">", 1); + assertOpenRangeQuery(NumberType.POSITIVE, ">", 0); + assertOpenRangeQuery(NumberType.NEGATIVE, ">", 2); + + assertOpenRangeQuery(NumberType.ZERO, ">=", 2); + assertOpenRangeQuery(NumberType.POSITIVE, ">=", 1); + assertOpenRangeQuery(NumberType.NEGATIVE, ">=", 3); + + assertOpenRangeQuery(NumberType.NEGATIVE, "=", 1); + assertOpenRangeQuery(NumberType.ZERO, "=", 1); + assertOpenRangeQuery(NumberType.POSITIVE, "=", 1); + + assertRangeQuery(NumberType.NEGATIVE, null, true, true, 3); + assertRangeQuery(NumberType.NEGATIVE, null, false, true, 2); + assertRangeQuery(NumberType.POSITIVE, null, true, false, 1); + assertRangeQuery(NumberType.ZERO, null, false, false, 1); + + assertRangeQuery(null, NumberType.POSITIVE, true, true, 3); + assertRangeQuery(null, NumberType.POSITIVE, true, false, 2); + assertRangeQuery(null, NumberType.NEGATIVE, false, true, 1); + assertRangeQuery(null, NumberType.ZERO, false, false, 1); + + assertRangeQuery(null, null, false, false, 3); + assertRangeQuery(null, null, true, true, 3); + + } + + @Test public void testSimpleNumericQuery() throws Exception { assertSimpleQuery(NumberType.ZERO, 1); assertSimpleQuery(NumberType.POSITIVE, 1); @@ -332,7 +374,7 @@ } public void assertRangeQuery(NumberType lowerType, NumberType upperType, - boolean upperInclusive, boolean lowerInclusive, int expectedDocCount) + boolean lowerInclusive, boolean upperInclusive, int expectedDocCount) throws QueryNodeException, IOException { StringBuilder sb = new StringBuilder(); @@ -349,13 +391,28 @@ .append('"').append(upperInclusiveStr).append(' '); } - String lowerDateStr = ESCAPER.escape( - DATE_FORMAT.format(new Date(getNumberType(lowerType, DATE_FIELD_NAME) - .longValue())), LOCALE, EscapeQuerySyntax.Type.STRING).toString(); + Number lowerDateNumber = getNumberType(lowerType, DATE_FIELD_NAME); + Number upperDateNumber = getNumberType(upperType, DATE_FIELD_NAME); + String lowerDateStr; + String upperDateStr; - String upperDateStr = ESCAPER.escape( - DATE_FORMAT.format(new Date(getNumberType(upperType, DATE_FIELD_NAME) - .longValue())), LOCALE, EscapeQuerySyntax.Type.STRING).toString(); + if (lowerDateNumber != null) { + lowerDateStr = ESCAPER.escape( + DATE_FORMAT.format(new Date(lowerDateNumber.longValue())), LOCALE, + EscapeQuerySyntax.Type.STRING).toString(); + + } else { + lowerDateStr = "*"; + } + + if (upperDateNumber != null) { + upperDateStr = ESCAPER.escape( + DATE_FORMAT.format(new Date(upperDateNumber.longValue())), LOCALE, + EscapeQuerySyntax.Type.STRING).toString(); + + } else { + upperDateStr = "*"; + } sb.append("+").append(DATE_FIELD_NAME).append(':') .append(lowerInclusiveStr).append('"').append(lowerDateStr).append( @@ -366,6 +423,26 @@ } + public void assertOpenRangeQuery(NumberType boundType, String operator, int expectedDocCount) + throws QueryNodeException, IOException { + + StringBuilder sb = new StringBuilder(); + + for (NumericField.DataType type : NumericField.DataType.values()) { + String boundStr = numberToString(getNumberType(boundType, type.name())); + + sb.append("+").append(type.name()).append(operator).append('"').append(boundStr).append('"').append(' '); + } + + String boundDateStr = ESCAPER.escape( + DATE_FORMAT.format(new Date(getNumberType(boundType, DATE_FIELD_NAME) + .longValue())), LOCALE, EscapeQuerySyntax.Type.STRING).toString(); + + sb.append("+").append(DATE_FIELD_NAME).append(operator).append('"').append(boundDateStr).append('"'); + + testQuery(sb.toString(), expectedDocCount); + } + public void assertSimpleQuery(NumberType numberType, int expectedDocCount) throws QueryNodeException, IOException { StringBuilder sb = new StringBuilder(); @@ -401,12 +478,11 @@ if (VERBOSE) System.out.println(msg); assertEquals(msg, expectedDocCount, topDocs.totalHits); - } private static String numberToString(Number number) { - return ESCAPER.escape(NUMBER_FORMAT.format(number), LOCALE, - EscapeQuerySyntax.Type.STRING).toString(); + return number == null ? "*" : ESCAPER.escape(NUMBER_FORMAT.format(number), + LOCALE, EscapeQuerySyntax.Type.STRING).toString(); } private static Number normalizeNumber(Number number) throws ParseException { Index: modules/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestQPHelper.java =================================================================== --- modules/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestQPHelper.java (revision 1152425) +++ modules/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestQPHelper.java (working copy) @@ -407,6 +407,7 @@ } public void testSimple() throws Exception { + assertQueryEquals("field=a", null, "a"); assertQueryEquals("\"term germ\"~2", null, "\"term germ\"~2"); assertQueryEquals("term term term", null, "term term term"); assertQueryEquals("t�rm term term", new MockAnalyzer(random, MockTokenizer.WHITESPACE, false), @@ -630,6 +631,22 @@ qp.setMultiTermRewriteMethod(MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE); assertEquals(MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE,((TermRangeQuery)qp.parse("[ a TO z]", "field")).getRewriteMethod()); + // test open ranges + assertQueryEquals("[ a TO * ]", null, "[a TO *]"); + assertQueryEquals("[ * TO z ]", null, "[* TO z]"); + assertQueryEquals("[ * TO * ]", null, "[* TO *]"); + + assertQueryEquals("field>=a", null, "[a TO *]"); + assertQueryEquals("field>a", null, "{a TO *]"); + assertQueryEquals("field<=a", null, "[* TO a]"); + assertQueryEquals("field