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 1150626) +++ 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 1150671) +++ modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/builders/NumericRangeQueryNodeBuilder.java (working copy) @@ -50,20 +50,9 @@ NumericQueryNode lowerNumericNode = numericRangeNode.getLowerBound(); NumericQueryNode upperNumericNode = numericRangeNode.getUpperBound(); - Number lowerNumber, upperNumber; + Number lowerNumber = lowerNumericNode.getValue(); + Number upperNumber = upperNumericNode.getValue(); - if (lowerNumericNode != null) { - lowerNumber = lowerNumericNode.getValue(); - } else { - lowerNumber = null; - } - - if (upperNumericNode != null) { - upperNumber = upperNumericNode.getValue(); - } else { - upperNumber = null; - } - NumericConfig numericConfig = numericRangeNode.getNumericConfig(); NumericField.DataType numberType = numericConfig.getType(); String field = StringUtils.toString(numericRangeNode.getField()); 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 1150626) +++ 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(); - TermRangeQuery rangeQuery = TermRangeQuery.newStringRange(field, lower - .getTextAsString(), upper.getTextAsString(), rangeNode + if (lowerText.length() == 0) { + lowerText = null; + } + + if (upperText.length() == 0) { + upperText = null; + } + + 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 1150671) +++ 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 1150626) +++ 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 1150626) +++ 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 1150626) +++ 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 */ @@ -376,6 +369,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; @@ -443,13 +438,14 @@ } 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; @@ -457,101 +453,69 @@ throw new ParseException(); } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case RANGEIN_TO: - jj_consume_token(RANGEIN_TO); + case RANGE_GOOP: + goop1 = jj_consume_token(RANGE_GOOP); 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_QUOTED: + goop1 = jj_consume_token(RANGE_QUOTED); break; - case RANGEIN_QUOTED: - goop2 = jj_consume_token(RANGEIN_QUOTED); - break; default: - jj_la1[15] = jj_gen; + jj_la1[14] = 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[15] = 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[16] = 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); + case RANGEEX_END: + jj_consume_token(RANGEEX_END); break; - case RANGEEX_QUOTED: - goop2 = jj_consume_token(RANGEEX_QUOTED); - break; default: - jj_la1[19] = jj_gen; + jj_la1[17] = 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[18] = 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 +527,7 @@ fuzzySlop = jj_consume_token(FUZZY_SLOP); break; default: - jj_la1[21] = jj_gen; + jj_la1[19] = jj_gen; ; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -572,7 +536,7 @@ boost = jj_consume_token(NUMBER); break; default: - jj_la1[22] = jj_gen; + jj_la1[20] = jj_gen; ; } int phraseSlop = 0; @@ -590,7 +554,7 @@ } break; default: - jj_la1[23] = jj_gen; + jj_la1[21] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -636,13 +600,13 @@ 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[22]; static private int[] jj_la1_0; static { jj_la1_init_0(); } 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,0xf63c00,0x200,0x100,0x10000,0xf62000,0x940000,0x80000,0x80000,0x10000,0x600000,0x18000000,0x1000000,0x18000000,0x6000000,0x10000,0x80000,0x10000,0xf60000,}; } final private JJCalls[] jj_2_rtns = new JJCalls[1]; private boolean jj_rescan = false; @@ -659,7 +623,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 < 22; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } @@ -674,7 +638,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 < 22; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } @@ -685,7 +649,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 < 22; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } @@ -696,7 +660,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 < 22; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } @@ -706,7 +670,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 < 22; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } @@ -716,7 +680,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 < 22; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } @@ -794,7 +758,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,12 +792,12 @@ /** Generate ParseException. */ public ParseException generateParseException() { jj_expentries.clear(); - boolean[] la1tokens = new boolean[32]; + boolean[] la1tokens = new boolean[29]; if (jj_kind >= 0) { la1tokens[jj_kind] = true; jj_kind = -1; } - for (int i = 0; i < 24; i++) { + for (int i = 0; i < 22; i++) { if (jj_la1[i] == jj_gen) { for (int j = 0; j < 32; j++) { if ((jj_la1_0[i] & (1< ) > } - SKIP : { + SKIP : { < <_WHITESPACE>> } @@ -133,26 +126,20 @@ | (<_TERM_CHAR>)* > | )+ ( "." (<_NUM_CHAR>)+ )? )? > | -| : RangeIn -| : RangeEx +| : Range +| : Range } TOKEN : { )+ ( "." (<_NUM_CHAR>)+ )? > : DEFAULT } - TOKEN : { - + TOKEN : { + | : DEFAULT -| -| -} - - TOKEN : { - | : DEFAULT -| -| +| +| } // * Query ::= ( Clause )* @@ -376,6 +363,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 +394,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 1150626) +++ modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParserConstants.java (working copy) @@ -55,30 +55,22 @@ /** RegularExpression Id. */ int NUMBER = 23; /** RegularExpression Id. */ - int RANGEIN_TO = 24; + int RANGE_TO = 24; /** RegularExpression Id. */ int RANGEIN_END = 25; /** RegularExpression Id. */ - int RANGEIN_QUOTED = 26; + int RANGEEX_END = 26; /** RegularExpression Id. */ - int RANGEIN_GOOP = 27; + int RANGE_QUOTED = 27; /** RegularExpression Id. */ - int RANGEEX_TO = 28; - /** RegularExpression Id. */ - int RANGEEX_END = 29; - /** RegularExpression Id. */ - int RANGEEX_QUOTED = 30; - /** RegularExpression Id. */ - int RANGEEX_GOOP = 31; + int RANGE_GOOP = 28; /** Lexical state. */ int Boost = 0; /** Lexical state. */ - int RangeEx = 1; + int Range = 1; /** Lexical state. */ - int RangeIn = 2; - /** Lexical state. */ - int DEFAULT = 3; + int DEFAULT = 2; /** Literal token values. */ String[] tokenImage = { @@ -108,12 +100,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 1150626) +++ 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) { @@ -93,7 +86,7 @@ case 123: return jjStopAtPos(0, 22); default : - return jjMoveNfa_3(0, 0); + return jjMoveNfa_2(0, 0); } } static final long[] jjbitVec0 = { @@ -108,7 +101,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; @@ -417,201 +410,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); @@ -639,7 +437,7 @@ break; if (kind > 23) kind = 23; - jjAddStates(11, 12); + jjAddStates(8, 9); break; case 1: if (curChar == 46) @@ -695,14 +493,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) { - jjmatchedKind = 27; + jjmatchedKind = 28; return 6; } return -1; @@ -710,49 +508,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(0x1000000L); case 93: return jjStopAtPos(0, 25); + case 125: + return jjStopAtPos(0, 26); 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); + return jjStartNfaWithStates_1(1, 24, 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 +573,8 @@ case 0: if ((0xfffffffeffffffffL & l) != 0L) { - if (kind > 27) - kind = 27; + if (kind > 28) + kind = 28; jjCheckNAdd(6); } if ((0x100002600L & l) != 0L) @@ -791,21 +591,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 > 27) + kind = 27; break; case 6: if ((0xfffffffeffffffffL & l) == 0L) break; - if (kind > 27) - kind = 27; + if (kind > 28) + kind = 28; jjCheckNAdd(6); break; default : break; @@ -821,14 +621,14 @@ { case 0: case 6: - if ((0xffffffffdfffffffL & l) == 0L) + if ((0xdfffffffdfffffffL & l) == 0L) break; - if (kind > 27) - kind = 27; + if (kind > 28) + kind = 28; jjCheckNAdd(6); break; case 2: - jjAddStates(8, 10); + jjAddStates(10, 12); break; case 4: if (curChar == 92) @@ -857,20 +657,20 @@ } if (jjCanMove_1(hiByte, i1, i2, l1, l2)) { - if (kind > 27) - kind = 27; + if (kind > 28) + kind = 28; 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 > 28) + kind = 28; jjCheckNAdd(6); break; default : break; @@ -891,7 +691,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) { @@ -934,23 +734,22 @@ 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, }; +"\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, 0, -1, -1, -1, -1, 1, 1, 2, -1, + 2, 2, -1, -1, }; static final long[] jjtoToken = { - 0xffffff01L, + 0x1fffff01L, }; static final long[] jjtoSkip = { 0x80L, @@ -998,7 +797,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 +827,8 @@ return t; } -int curLexState = 3; -int defaultLexState = 3; +int curLexState = 2; +int defaultLexState = 2; int jjnewStateCnt; int jjround; int jjmatchedPos; @@ -1072,11 +871,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 1150626) +++ 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 1150626) +++ 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 1150626) +++ 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 1150671) +++ 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,32 +86,40 @@ 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) { - } catch (ParseException e) { + 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(); + } + + } else { throw new QueryNodeParseException(new MessageImpl( - QueryParserMessages.COULD_NOT_PARSE_NUMBER, fieldNode - .getTextAsString(), numberFormat.getClass() - .getCanonicalName()), e); + QueryParserMessages.NUMERIC_CANNOT_BE_EMPTY, fieldNode.getFieldAsString())); } - 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(); - } - NumericQueryNode lowerNode = new NumericQueryNode(fieldNode .getField(), number, numberFormat); NumericQueryNode upperNode = 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 1150671) +++ modules/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/NumericRangeQueryNodeProcessor.java (working copy) @@ -84,54 +84,81 @@ ParametricQueryNode upper = parametricRangeNode.getUpperBound(); NumberFormat numberFormat = numericConfig.getNumberFormat(); - Number lowerNumber, upperNumber; + Number lowerNumber = null; + Number upperNumber = null; + String lowerText = lower.getTextAsString(); + String upperText = upper.getTextAsString(); - try { - lowerNumber = numberFormat.parse(lower.getTextAsString()); + if (lowerText.length() > 0) { - } catch (ParseException e) { - throw new QueryNodeParseException(new MessageImpl( - QueryParserMessages.COULD_NOT_PARSE_NUMBER, lower - .getTextAsString(), numberFormat.getClass() - .getCanonicalName()), e); + try { + lowerNumber = numberFormat.parse(lowerText); + + } 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(); + upperNumber = upperNumber != null ? upperNumber.longValue() + : null; + lowerNumber = lowerNumber != null ? lowerNumber.longValue() + : null; break; case INT: - upperNumber = upperNumber.intValue(); - lowerNumber = lowerNumber.intValue(); + upperNumber = upperNumber != null ? upperNumber.intValue() + : null; + lowerNumber = lowerNumber != null ? lowerNumber.intValue() + : null; break; case DOUBLE: - upperNumber = upperNumber.doubleValue(); - lowerNumber = lowerNumber.doubleValue(); + upperNumber = upperNumber != null ? upperNumber.doubleValue() + : null; + lowerNumber = lowerNumber != null ? lowerNumber.doubleValue() + : null; break; case FLOAT: - upperNumber = upperNumber.floatValue(); - lowerNumber = lowerNumber.floatValue(); + upperNumber = upperNumber != null ? upperNumber.floatValue() + : null; + lowerNumber = lowerNumber != null ? lowerNumber.floatValue() + : null; + break; + default: + throw new QueryNodeException(new MessageImpl( + QueryParserMessages.UNSUPPORTED_NUMERIC_DATA_TYPE, + numericConfig.getType())); } NumericQueryNode lowerNode = new NumericQueryNode( parametricRangeNode.getField(), lowerNumber, numberFormat); - NumericQueryNode upperNode = new NumericQueryNode( - parametricRangeNode.getField(), upperNumber, numberFormat); - boolean upperInclusive = upper.getOperator() == CompareOperator.LE; - boolean lowerInclusive = lower.getOperator() == CompareOperator.GE; + NumericQueryNode upperNode = upper != null ? new NumericQueryNode( + parametricRangeNode.getField(), upperNumber, numberFormat) : null; + 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; + } + +} Property changes on: modules\queryparser\src\java\org\apache\lucene\queryparser\flexible\standard\processors\OpenRangeQueryNodeProcessor.java ___________________________________________________________________ Added: svn:keywords + Date Author Id Revision HeadURL Added: svn:eol-style + native 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 1150626) +++ 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,34 +104,42 @@ 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); } - part1 = DateTools.dateToString(d1, dateRes); - part2 = DateTools.dateToString(d2, dateRes); + 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); + + } + } catch (Exception e) { // do nothing } - lower.setText(part1); - upper.setText(part2); + return new TermRangeQueryNode(lower, upper, part1.length() == 0 + | lower.getOperator() == CompareOperator.GE, part2.length() == 0 + | upper.getOperator() == CompareOperator.LE); - return new TermRangeQueryNode(lower, upper, - lower.getOperator() == CompareOperator.GE, - upper.getOperator() == CompareOperator.LE); - } return node; 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 1150626) +++ 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/resources/org/apache/lucene/queryparser/flexible/core/messages/QueryParserMessages.properties =================================================================== --- modules/queryparser/src/resources/org/apache/lucene/queryparser/flexible/core/messages/QueryParserMessages.properties (revision 1150626) +++ 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 1150626) +++ 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 1150626) +++ 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,10 +137,9 @@ // only positive values randomDate = Math.abs(randomDate); } while (randomDate == 0L); - - dateFormatSanityCheckPass &= checkDateFormatSanity(dateFormat, - randomDate); + dateFormatSanityCheckPass &= checkDateFormatSanity(dateFormat, randomDate); + dateFormatSanityCheckPass &= checkDateFormatSanity(dateFormat, 0); dateFormatSanityCheckPass &= checkDateFormatSanity(dateFormat, @@ -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,42 @@ assertRangeQuery(NumberType.NEGATIVE, NumberType.NEGATIVE, true, true, 1); } - // @Test + @Test + public void testOpenNumericRange() throws Exception { + 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 // 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 { @@ -332,7 +354,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,14 +371,29 @@ .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( "\" TO \"").append(upperDateStr).append('"').append( @@ -405,8 +442,8 @@ } 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 1150626) +++ modules/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestQPHelper.java (working copy) @@ -630,6 +630,17 @@ 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 *]"); + + // 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}");