You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by rm...@apache.org on 2016/03/10 03:04:58 UTC
[1/3] lucene-solr git commit: LUCENE-7089,
LUCENE-7075: add points to flexible queryparser to replace legacy
numerics support
Repository: lucene-solr
Updated Branches:
refs/heads/master f24810bdf -> 89cc676f2
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestNumericQueryParser.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestNumericQueryParser.java b/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestNumericQueryParser.java
deleted file mode 100644
index c29573b..0000000
--- a/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestNumericQueryParser.java
+++ /dev/null
@@ -1,535 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.queryparser.flexible.standard;
-
-import java.io.IOException;
-import java.text.DateFormat;
-import java.text.NumberFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Random;
-import java.util.TimeZone;
-
-import org.apache.lucene.analysis.Analyzer;
-import org.apache.lucene.analysis.MockAnalyzer;
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.LegacyDoubleField;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.document.FieldType.LegacyNumericType;
-import org.apache.lucene.document.FieldType;
-import org.apache.lucene.document.LegacyFloatField;
-import org.apache.lucene.document.LegacyIntField;
-import org.apache.lucene.document.LegacyLongField;
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.RandomIndexWriter;
-import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
-import org.apache.lucene.queryparser.flexible.core.parser.EscapeQuerySyntax;
-import org.apache.lucene.queryparser.flexible.standard.config.NumberDateFormat;
-import org.apache.lucene.queryparser.flexible.standard.config.NumericConfig;
-import org.apache.lucene.queryparser.flexible.standard.parser.EscapeQuerySyntaxImpl;
-import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.TopDocs;
-import org.apache.lucene.store.Directory;
-import org.apache.lucene.util.LuceneTestCase;
-import org.apache.lucene.util.TestUtil;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-public class TestNumericQueryParser extends LuceneTestCase {
-
- private static enum NumberType {
- NEGATIVE, ZERO, POSITIVE;
- }
-
- final private static int[] DATE_STYLES = {DateFormat.FULL, DateFormat.LONG,
- DateFormat.MEDIUM, DateFormat.SHORT};
-
- final private static int PRECISION_STEP = 8;
- final private static String FIELD_NAME = "field";
- private static Locale LOCALE;
- private static TimeZone TIMEZONE;
- private static Map<String,Number> RANDOM_NUMBER_MAP;
- private static EscapeQuerySyntax ESCAPER = new EscapeQuerySyntaxImpl();
- final private static String DATE_FIELD_NAME = "date";
- private static int DATE_STYLE;
- private static int TIME_STYLE;
-
- private static Analyzer ANALYZER;
-
- private static NumberFormat NUMBER_FORMAT;
-
- private static StandardQueryParser qp;
-
- private static NumberDateFormat DATE_FORMAT;
-
- private static Directory directory = null;
- private static IndexReader reader = null;
- private static IndexSearcher searcher = null;
-
- private static boolean checkDateFormatSanity(DateFormat dateFormat, long date) {
- try {
- return date == dateFormat.parse(dateFormat.format(new Date(date)))
- .getTime();
- } catch (ParseException e) {
- return false;
- }
- }
-
- @BeforeClass
- public static void beforeClass() throws Exception {
- ANALYZER = new MockAnalyzer(random());
-
- qp = new StandardQueryParser(ANALYZER);
-
- final HashMap<String,Number> randomNumberMap = new HashMap<>();
-
- SimpleDateFormat dateFormat;
- long randomDate;
- boolean dateFormatSanityCheckPass;
- int count = 0;
- do {
- if (count > 100) {
- fail("This test has problems to find a sane random DateFormat/NumberFormat. Stopped trying after 100 iterations.");
- }
-
- dateFormatSanityCheckPass = true;
- LOCALE = randomLocale(random());
- TIMEZONE = randomTimeZone(random());
- DATE_STYLE = randomDateStyle(random());
- TIME_STYLE = randomDateStyle(random());
-
- // assumes localized date pattern will have at least year, month, day,
- // hour, minute
- 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
- dateFormat.applyPattern(dateFormat.toPattern() + " G s Z yyyy");
- dateFormat.setTimeZone(TIMEZONE);
-
- DATE_FORMAT = new NumberDateFormat(dateFormat);
-
- do {
- randomDate = random().nextLong();
-
- // prune date value so it doesn't pass in insane values to some
- // calendars.
- randomDate = randomDate % 3400000000000l;
-
- // truncate to second
- randomDate = (randomDate / 1000L) * 1000L;
-
- // only positive values
- randomDate = Math.abs(randomDate);
- } while (randomDate == 0L);
-
- dateFormatSanityCheckPass &= checkDateFormatSanity(dateFormat, randomDate);
-
- dateFormatSanityCheckPass &= checkDateFormatSanity(dateFormat, 0);
-
- dateFormatSanityCheckPass &= checkDateFormatSanity(dateFormat,
- -randomDate);
-
- count++;
- } while (!dateFormatSanityCheckPass);
-
- NUMBER_FORMAT = NumberFormat.getNumberInstance(LOCALE);
- NUMBER_FORMAT.setMaximumFractionDigits((random().nextInt() & 20) + 1);
- 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;
- float randomFloat;
-
- while ((randomLong = normalizeNumber(Math.abs(random().nextLong()))
- .longValue()) == 0L)
- ;
- while ((randomDouble = normalizeNumber(Math.abs(random().nextDouble()))
- .doubleValue()) == 0.0)
- ;
- while ((randomFloat = normalizeNumber(Math.abs(random().nextFloat()))
- .floatValue()) == 0.0f)
- ;
- while ((randomInt = normalizeNumber(Math.abs(random().nextInt())).intValue()) == 0)
- ;
-
- randomNumberMap.put(LegacyNumericType.LONG.name(), randomLong);
- randomNumberMap.put(FieldType.LegacyNumericType.INT.name(), randomInt);
- randomNumberMap.put(LegacyNumericType.FLOAT.name(), randomFloat);
- randomNumberMap.put(LegacyNumericType.DOUBLE.name(), randomDouble);
- randomNumberMap.put(DATE_FIELD_NAME, randomDate);
-
- RANDOM_NUMBER_MAP = Collections.unmodifiableMap(randomNumberMap);
-
- directory = newDirectory();
- RandomIndexWriter writer = new RandomIndexWriter(random(), directory,
- newIndexWriterConfig(new MockAnalyzer(random()))
- .setMaxBufferedDocs(TestUtil.nextInt(random(), 50, 1000))
- .setMergePolicy(newLogMergePolicy()));
-
- Document doc = new Document();
- HashMap<String,NumericConfig> numericConfigMap = new HashMap<>();
- HashMap<String,Field> numericFieldMap = new HashMap<>();
- qp.setNumericConfigMap(numericConfigMap);
-
- for (LegacyNumericType type : LegacyNumericType.values()) {
- numericConfigMap.put(type.name(), new NumericConfig(PRECISION_STEP,
- NUMBER_FORMAT, type));
-
- FieldType ft = new FieldType(LegacyIntField.TYPE_NOT_STORED);
- ft.setNumericType(type);
- ft.setStored(true);
- ft.setNumericPrecisionStep(PRECISION_STEP);
- ft.freeze();
- final Field field;
-
- switch(type) {
- case INT:
- field = new LegacyIntField(type.name(), 0, ft);
- break;
- case FLOAT:
- field = new LegacyFloatField(type.name(), 0.0f, ft);
- break;
- case LONG:
- field = new LegacyLongField(type.name(), 0l, ft);
- break;
- case DOUBLE:
- field = new LegacyDoubleField(type.name(), 0.0, ft);
- break;
- default:
- fail();
- field = null;
- }
- numericFieldMap.put(type.name(), field);
- doc.add(field);
- }
-
- numericConfigMap.put(DATE_FIELD_NAME, new NumericConfig(PRECISION_STEP,
- DATE_FORMAT, LegacyNumericType.LONG));
- FieldType ft = new FieldType(LegacyLongField.TYPE_NOT_STORED);
- ft.setStored(true);
- ft.setNumericPrecisionStep(PRECISION_STEP);
- LegacyLongField dateField = new LegacyLongField(DATE_FIELD_NAME, 0l, ft);
- numericFieldMap.put(DATE_FIELD_NAME, dateField);
- doc.add(dateField);
-
- for (NumberType numberType : NumberType.values()) {
- setFieldValues(numberType, numericFieldMap);
- if (VERBOSE) System.out.println("Indexing document: " + doc);
- writer.addDocument(doc);
- }
-
- 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:
- return RANDOM_NUMBER_MAP.get(fieldName);
-
- case NEGATIVE:
- Number number = RANDOM_NUMBER_MAP.get(fieldName);
-
- if (LegacyNumericType.LONG.name().equals(fieldName)
- || DATE_FIELD_NAME.equals(fieldName)) {
- number = -number.longValue();
-
- } else if (FieldType.LegacyNumericType.DOUBLE.name().equals(fieldName)) {
- number = -number.doubleValue();
-
- } else if (FieldType.LegacyNumericType.FLOAT.name().equals(fieldName)) {
- number = -number.floatValue();
-
- } else if (LegacyNumericType.INT.name().equals(fieldName)) {
- number = -number.intValue();
-
- } else {
- throw new IllegalArgumentException("field name not found: "
- + fieldName);
- }
-
- return number;
-
- default:
- return 0;
-
- }
-
- }
-
- private static void setFieldValues(NumberType numberType,
- HashMap<String,Field> numericFieldMap) {
-
- Number number = getNumberType(numberType, LegacyNumericType.DOUBLE
- .name());
- numericFieldMap.get(LegacyNumericType.DOUBLE.name()).setDoubleValue(
- number.doubleValue());
-
- number = getNumberType(numberType, FieldType.LegacyNumericType.INT.name());
- numericFieldMap.get(FieldType.LegacyNumericType.INT.name()).setIntValue(
- number.intValue());
-
- number = getNumberType(numberType, LegacyNumericType.LONG.name());
- numericFieldMap.get(FieldType.LegacyNumericType.LONG.name()).setLongValue(
- number.longValue());
-
- number = getNumberType(numberType, FieldType.LegacyNumericType.FLOAT.name());
- numericFieldMap.get(FieldType.LegacyNumericType.FLOAT.name()).setFloatValue(
- number.floatValue());
-
- number = getNumberType(numberType, DATE_FIELD_NAME);
- numericFieldMap.get(DATE_FIELD_NAME).setLongValue(number.longValue());
- }
-
- private static int randomDateStyle(Random random) {
- return DATE_STYLES[random.nextInt(DATE_STYLES.length)];
- }
-
- @Test
- public void testInclusiveNumericRange() throws Exception {
- assertRangeQuery(NumberType.ZERO, NumberType.ZERO, true, true, 1);
- assertRangeQuery(NumberType.ZERO, NumberType.POSITIVE, true, true, 2);
- assertRangeQuery(NumberType.NEGATIVE, NumberType.ZERO, true, true, 2);
- assertRangeQuery(NumberType.NEGATIVE, NumberType.POSITIVE, true, true, 3);
- assertRangeQuery(NumberType.NEGATIVE, NumberType.NEGATIVE, true, true, 1);
- }
-
- @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, 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 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, 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 {
- assertRangeQuery(NumberType.ZERO, NumberType.ZERO, false, false, 0);
- assertRangeQuery(NumberType.ZERO, NumberType.POSITIVE, false, false, 0);
- assertRangeQuery(NumberType.NEGATIVE, NumberType.ZERO, false, false, 0);
- assertRangeQuery(NumberType.NEGATIVE, NumberType.POSITIVE, false, false, 1);
- assertRangeQuery(NumberType.NEGATIVE, NumberType.NEGATIVE, false, false, 0);
- }
-
- @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);
- assertSimpleQuery(NumberType.NEGATIVE, 1);
- }
-
- public void assertRangeQuery(NumberType lowerType, NumberType upperType,
- boolean lowerInclusive, boolean upperInclusive, int expectedDocCount)
- throws QueryNodeException, IOException {
-
- StringBuilder sb = new StringBuilder();
-
- String lowerInclusiveStr = (lowerInclusive ? "[" : "{");
- String upperInclusiveStr = (upperInclusive ? "]" : "}");
-
- for (LegacyNumericType type : LegacyNumericType.values()) {
- String lowerStr = numberToString(getNumberType(lowerType, type.name()));
- String upperStr = numberToString(getNumberType(upperType, type.name()));
-
- sb.append("+").append(type.name()).append(':').append(lowerInclusiveStr)
- .append('"').append(lowerStr).append("\" TO \"").append(upperStr)
- .append('"').append(upperInclusiveStr).append(' ');
- }
-
- Number lowerDateNumber = getNumberType(lowerType, DATE_FIELD_NAME);
- Number upperDateNumber = getNumberType(upperType, DATE_FIELD_NAME);
- String lowerDateStr;
- String upperDateStr;
-
- 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(
- upperInclusiveStr);
-
- testQuery(sb.toString(), expectedDocCount);
-
- }
-
- public void assertOpenRangeQuery(NumberType boundType, String operator, int expectedDocCount)
- throws QueryNodeException, IOException {
-
- StringBuilder sb = new StringBuilder();
-
- for (LegacyNumericType type : FieldType.LegacyNumericType.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();
-
- for (LegacyNumericType type : LegacyNumericType.values()) {
- String numberStr = numberToString(getNumberType(numberType, type.name()));
- sb.append('+').append(type.name()).append(":\"").append(numberStr)
- .append("\" ");
- }
-
- String dateStr = ESCAPER.escape(
- DATE_FORMAT.format(new Date(getNumberType(numberType, DATE_FIELD_NAME)
- .longValue())), LOCALE, EscapeQuerySyntax.Type.STRING).toString();
-
- sb.append('+').append(DATE_FIELD_NAME).append(":\"").append(dateStr)
- .append('"');
-
- testQuery(sb.toString(), expectedDocCount);
-
- }
-
- private void testQuery(String queryStr, int expectedDocCount)
- throws QueryNodeException, IOException {
- if (VERBOSE) System.out.println("Parsing: " + queryStr);
-
- Query query = qp.parse(queryStr, FIELD_NAME);
- if (VERBOSE) System.out.println("Querying: " + query);
- TopDocs topDocs = searcher.search(query, 1000);
-
- String msg = "Query <" + queryStr + "> retrieved " + topDocs.totalHits
- + " document(s), " + expectedDocCount + " document(s) expected.";
-
- if (VERBOSE) System.out.println(msg);
-
- assertEquals(msg, expectedDocCount, topDocs.totalHits);
- }
-
- private static String numberToString(Number number) {
- return number == null ? "*" : ESCAPER.escape(NUMBER_FORMAT.format(number),
- LOCALE, EscapeQuerySyntax.Type.STRING).toString();
- }
-
- private static Number normalizeNumber(Number number) throws ParseException {
- return NUMBER_FORMAT.parse(NUMBER_FORMAT.format(number));
- }
-
- @AfterClass
- public static void afterClass() throws Exception {
- searcher = null;
- reader.close();
- reader = null;
- directory.close();
- directory = null;
- qp = null;
- LOCALE = null;
- TIMEZONE = null;
- NUMBER_FORMAT = null;
- DATE_FORMAT = null;
- ESCAPER = null;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestPointQueryParser.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestPointQueryParser.java b/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestPointQueryParser.java
new file mode 100644
index 0000000..323b0ff
--- /dev/null
+++ b/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestPointQueryParser.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.queryparser.flexible.standard;
+
+import java.text.NumberFormat;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.lucene.document.DoublePoint;
+import org.apache.lucene.document.FloatPoint;
+import org.apache.lucene.document.IntPoint;
+import org.apache.lucene.document.LongPoint;
+import org.apache.lucene.queryparser.flexible.standard.config.PointsConfig;
+import org.apache.lucene.util.LuceneTestCase;
+
+/** Simple test for point field integration into the flexible QP */
+public class TestPointQueryParser extends LuceneTestCase {
+
+ public void testIntegers() throws Exception {
+ StandardQueryParser parser = new StandardQueryParser();
+ Map<String,PointsConfig> pointsConfig = new HashMap<>();
+ pointsConfig.put("intField", new PointsConfig(NumberFormat.getIntegerInstance(Locale.ROOT), Integer.class));
+ parser.setPointsConfigMap(pointsConfig);
+
+ assertEquals(IntPoint.newRangeQuery("intField", 1, 3),
+ parser.parse("intField:[1 TO 3]", "body"));
+ assertEquals(IntPoint.newRangeQuery("intField", 1, 1),
+ parser.parse("intField:1", "body"));
+ }
+
+ public void testLongs() throws Exception {
+ StandardQueryParser parser = new StandardQueryParser();
+ Map<String,PointsConfig> pointsConfig = new HashMap<>();
+ pointsConfig.put("longField", new PointsConfig(NumberFormat.getIntegerInstance(Locale.ROOT), Long.class));
+ parser.setPointsConfigMap(pointsConfig);
+
+ assertEquals(LongPoint.newRangeQuery("longField", 1, 3),
+ parser.parse("longField:[1 TO 3]", "body"));
+ assertEquals(LongPoint.newRangeQuery("longField", 1, 1),
+ parser.parse("longField:1", "body"));
+ }
+
+ public void testFloats() throws Exception {
+ StandardQueryParser parser = new StandardQueryParser();
+ Map<String,PointsConfig> pointsConfig = new HashMap<>();
+ pointsConfig.put("floatField", new PointsConfig(NumberFormat.getNumberInstance(Locale.ROOT), Float.class));
+ parser.setPointsConfigMap(pointsConfig);
+
+ assertEquals(FloatPoint.newRangeQuery("floatField", 1.5F, 3.6F),
+ parser.parse("floatField:[1.5 TO 3.6]", "body"));
+ assertEquals(FloatPoint.newRangeQuery("floatField", 1.5F, 1.5F),
+ parser.parse("floatField:1.5", "body"));
+ }
+
+ public void testDoubles() throws Exception {
+ StandardQueryParser parser = new StandardQueryParser();
+ Map<String,PointsConfig> pointsConfig = new HashMap<>();
+ pointsConfig.put("doubleField", new PointsConfig(NumberFormat.getNumberInstance(Locale.ROOT), Double.class));
+ parser.setPointsConfigMap(pointsConfig);
+
+ assertEquals(DoublePoint.newRangeQuery("doubleField", 1.5D, 3.6D),
+ parser.parse("doubleField:[1.5 TO 3.6]", "body"));
+ assertEquals(DoublePoint.newRangeQuery("floatField", 1.5D, 1.5D),
+ parser.parse("doubleField:1.5", "body"));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/tools/junit4/cached-timehints.txt
----------------------------------------------------------------------
diff --git a/lucene/tools/junit4/cached-timehints.txt b/lucene/tools/junit4/cached-timehints.txt
index 9c8b22a..f2b8974 100644
--- a/lucene/tools/junit4/cached-timehints.txt
+++ b/lucene/tools/junit4/cached-timehints.txt
@@ -548,7 +548,7 @@ org.apache.lucene.queryparser.flexible.spans.TestSpanQueryParser=711,339,113,55,
org.apache.lucene.queryparser.flexible.spans.TestSpanQueryParserSimpleSample=51,644,92,32,129,60,21
org.apache.lucene.queryparser.flexible.standard.TestMultiAnalyzerQPHelper=44,84,87,34,260,35,229
org.apache.lucene.queryparser.flexible.standard.TestMultiFieldQPHelper=1152,1779,1888,384,179,1665,445
-org.apache.lucene.queryparser.flexible.standard.TestNumericQueryParser=344,496,451,1373,733,1420,367
+org.apache.lucene.queryparser.flexible.standard.TestLegacyNumericQueryParser=344,496,451,1373,733,1420,367
org.apache.lucene.queryparser.flexible.standard.TestQPHelper=287,676,989,2137,860,586,612
org.apache.lucene.queryparser.flexible.standard.TestStandardQP=1643,430,2182,2193,600,1506,741
org.apache.lucene.queryparser.surround.query.SrndQueryTest=1062,92,92,212,65,95,113
[3/3] lucene-solr git commit: LUCENE-7089,
LUCENE-7075: add points to flexible queryparser to replace legacy
numerics support
Posted by rm...@apache.org.
LUCENE-7089, LUCENE-7075: add points to flexible queryparser to replace legacy numerics support
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/89cc676f
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/89cc676f
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/89cc676f
Branch: refs/heads/master
Commit: 89cc676f2bf560091bd24db544faa16946654164
Parents: f24810b
Author: Robert Muir <rm...@apache.org>
Authored: Wed Mar 9 21:05:26 2016 -0500
Committer: Robert Muir <rm...@apache.org>
Committed: Wed Mar 9 21:06:41 2016 -0500
----------------------------------------------------------------------
.../flexible/core/nodes/package-info.java | 4 +-
.../flexible/standard/StandardQueryParser.java | 29 +-
.../LegacyNumericRangeQueryNodeBuilder.java | 93 ++++
.../builders/NumericRangeQueryNodeBuilder.java | 91 ----
.../builders/PointRangeQueryNodeBuilder.java | 137 +++++
.../builders/StandardQueryTreeBuilder.java | 12 +-
.../standard/config/LegacyNumericConfig.java | 166 ++++++
.../LegacyNumericFieldConfigListener.java | 75 +++
.../flexible/standard/config/NumericConfig.java | 164 ------
.../config/NumericFieldConfigListener.java | 73 ---
.../flexible/standard/config/PointsConfig.java | 124 +++++
.../standard/config/PointsConfigListener.java | 65 +++
.../config/StandardQueryConfigHandler.java | 39 +-
.../standard/nodes/LegacyNumericQueryNode.java | 153 ++++++
.../nodes/LegacyNumericRangeQueryNode.java | 153 ++++++
.../standard/nodes/NumericQueryNode.java | 151 ------
.../standard/nodes/NumericRangeQueryNode.java | 151 ------
.../flexible/standard/nodes/PointQueryNode.java | 151 ++++++
.../standard/nodes/PointRangeQueryNode.java | 124 +++++
.../LegacyNumericQueryNodeProcessor.java | 154 ++++++
.../LegacyNumericRangeQueryNodeProcessor.java | 170 ++++++
.../processors/NumericQueryNodeProcessor.java | 152 ------
.../NumericRangeQueryNodeProcessor.java | 168 ------
.../processors/PointQueryNodeProcessor.java | 136 +++++
.../PointRangeQueryNodeProcessor.java | 148 +++++
.../StandardQueryNodeProcessorPipeline.java | 6 +-
.../standard/TestLegacyNumericQueryParser.java | 535 +++++++++++++++++++
.../standard/TestNumericQueryParser.java | 535 -------------------
.../flexible/standard/TestPointQueryParser.java | 82 +++
lucene/tools/junit4/cached-timehints.txt | 2 +-
30 files changed, 2535 insertions(+), 1508 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/core/nodes/package-info.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/core/nodes/package-info.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/core/nodes/package-info.java
index c9d55ea..23c72a1 100644
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/core/nodes/package-info.java
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/core/nodes/package-info.java
@@ -52,14 +52,14 @@
* <li>FuzzyQueryNode - fuzzy node</li>
* <li>TermRangeQueryNode - used for parametric field:[low_value TO high_value]</li>
* <li>ProximityQueryNode - used for proximity search</li>
- * <li>NumericRangeQueryNode - used for numeric range search</li>
+ * <li>LegacyNumericRangeQueryNode - used for numeric range search</li>
* <li>TokenizedPhraseQueryNode - used by tokenizers/lemmatizers/analyzers for phrases/autophrases</li>
* </ul>
* <p>
* Leaf Nodes:
* <ul>
* <li>FieldQueryNode - field/value node</li>
- * <li>NumericQueryNode - used for numeric search</li>
+ * <li>LegacyNumericQueryNode - used for numeric search</li>
* <li>PathQueryNode - {@link org.apache.lucene.queryparser.flexible.core.nodes.QueryNode} object used with path-like queries</li>
* <li>OpaqueQueryNode - Used as for part of the query that can be parsed by other parsers. schema/value</li>
* <li>PrefixWildcardQueryNode - non-phrase wildcard query</li>
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/StandardQueryParser.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/StandardQueryParser.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/StandardQueryParser.java
index ada65a4..2774cf0 100644
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/StandardQueryParser.java
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/StandardQueryParser.java
@@ -29,7 +29,8 @@ import org.apache.lucene.queryparser.flexible.core.QueryParserHelper;
import org.apache.lucene.queryparser.flexible.core.config.QueryConfigHandler;
import org.apache.lucene.queryparser.flexible.standard.builders.StandardQueryTreeBuilder;
import org.apache.lucene.queryparser.flexible.standard.config.FuzzyConfig;
-import org.apache.lucene.queryparser.flexible.standard.config.NumericConfig;
+import org.apache.lucene.queryparser.flexible.standard.config.LegacyNumericConfig;
+import org.apache.lucene.queryparser.flexible.standard.config.PointsConfig;
import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler;
import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler.ConfigurationKeys;
import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler.Operator;
@@ -322,12 +323,30 @@ public class StandardQueryParser extends QueryParserHelper implements CommonQuer
}
- public void setNumericConfigMap(Map<String,NumericConfig> numericConfigMap) {
- getQueryConfigHandler().set(ConfigurationKeys.NUMERIC_CONFIG_MAP, numericConfigMap);
+ /**
+ * Sets field configuration for legacy numeric fields
+ * @deprecated Index with points instead and use {@link #setPointsConfigMap(Map)}
+ */
+ @Deprecated
+ public void setLegacyNumericConfigMap(Map<String,LegacyNumericConfig> legacyNumericConfigMap) {
+ getQueryConfigHandler().set(ConfigurationKeys.LEGACY_NUMERIC_CONFIG_MAP, legacyNumericConfigMap);
+ }
+
+ /**
+ * Gets field configuration for legacy numeric fields
+ * @deprecated Index with points instead and use {@link #getPointsConfigMap()}
+ */
+ @Deprecated
+ public Map<String,LegacyNumericConfig> getLegacyNumericConfigMap() {
+ return getQueryConfigHandler().get(ConfigurationKeys.LEGACY_NUMERIC_CONFIG_MAP);
+ }
+
+ public void setPointsConfigMap(Map<String,PointsConfig> pointsConfigMap) {
+ getQueryConfigHandler().set(ConfigurationKeys.POINTS_CONFIG_MAP, pointsConfigMap);
}
- public Map<String,NumericConfig> getNumericConfigMap() {
- return getQueryConfigHandler().get(ConfigurationKeys.NUMERIC_CONFIG_MAP);
+ public Map<String,PointsConfig> getPointsConfigMap() {
+ return getQueryConfigHandler().get(ConfigurationKeys.POINTS_CONFIG_MAP);
}
/**
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/builders/LegacyNumericRangeQueryNodeBuilder.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/builders/LegacyNumericRangeQueryNodeBuilder.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/builders/LegacyNumericRangeQueryNodeBuilder.java
new file mode 100644
index 0000000..8ae7d5e
--- /dev/null
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/builders/LegacyNumericRangeQueryNodeBuilder.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.queryparser.flexible.standard.builders;
+
+import org.apache.lucene.document.FieldType;
+import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
+import org.apache.lucene.queryparser.flexible.core.messages.QueryParserMessages;
+import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode;
+import org.apache.lucene.queryparser.flexible.core.util.StringUtils;
+import org.apache.lucene.queryparser.flexible.messages.MessageImpl;
+import org.apache.lucene.queryparser.flexible.standard.config.LegacyNumericConfig;
+import org.apache.lucene.queryparser.flexible.standard.nodes.LegacyNumericQueryNode;
+import org.apache.lucene.queryparser.flexible.standard.nodes.LegacyNumericRangeQueryNode;
+import org.apache.lucene.search.LegacyNumericRangeQuery;
+
+/**
+ * Builds {@link org.apache.lucene.search.LegacyNumericRangeQuery}s out of {@link LegacyNumericRangeQueryNode}s.
+ *
+ * @see org.apache.lucene.search.LegacyNumericRangeQuery
+ * @see LegacyNumericRangeQueryNode
+ * @deprecated Index with points and use {@link PointRangeQueryNodeBuilder} instead.
+ */
+@Deprecated
+public class LegacyNumericRangeQueryNodeBuilder implements StandardQueryBuilder {
+
+ /**
+ * Constructs a {@link LegacyNumericRangeQueryNodeBuilder} object.
+ */
+ public LegacyNumericRangeQueryNodeBuilder() {
+ // empty constructor
+ }
+
+ @Override
+ public LegacyNumericRangeQuery<? extends Number> build(QueryNode queryNode)
+ throws QueryNodeException {
+ LegacyNumericRangeQueryNode numericRangeNode = (LegacyNumericRangeQueryNode) queryNode;
+
+ LegacyNumericQueryNode lowerNumericNode = numericRangeNode.getLowerBound();
+ LegacyNumericQueryNode upperNumericNode = numericRangeNode.getUpperBound();
+
+ Number lowerNumber = lowerNumericNode.getValue();
+ Number upperNumber = upperNumericNode.getValue();
+
+ LegacyNumericConfig numericConfig = numericRangeNode.getNumericConfig();
+ FieldType.LegacyNumericType numberType = numericConfig.getType();
+ String field = StringUtils.toString(numericRangeNode.getField());
+ boolean minInclusive = numericRangeNode.isLowerInclusive();
+ boolean maxInclusive = numericRangeNode.isUpperInclusive();
+ int precisionStep = numericConfig.getPrecisionStep();
+
+ switch (numberType) {
+
+ case LONG:
+ return LegacyNumericRangeQuery.newLongRange(field, precisionStep,
+ (Long) lowerNumber, (Long) upperNumber, minInclusive, maxInclusive);
+
+ case INT:
+ return LegacyNumericRangeQuery.newIntRange(field, precisionStep,
+ (Integer) lowerNumber, (Integer) upperNumber, minInclusive,
+ maxInclusive);
+
+ case FLOAT:
+ return LegacyNumericRangeQuery.newFloatRange(field, precisionStep,
+ (Float) lowerNumber, (Float) upperNumber, minInclusive,
+ maxInclusive);
+
+ case DOUBLE:
+ return LegacyNumericRangeQuery.newDoubleRange(field, precisionStep,
+ (Double) lowerNumber, (Double) upperNumber, minInclusive,
+ maxInclusive);
+
+ default :
+ throw new QueryNodeException(new MessageImpl(
+ QueryParserMessages.UNSUPPORTED_NUMERIC_DATA_TYPE, numberType));
+
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/builders/NumericRangeQueryNodeBuilder.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/builders/NumericRangeQueryNodeBuilder.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/builders/NumericRangeQueryNodeBuilder.java
deleted file mode 100644
index 6c8790f..0000000
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/builders/NumericRangeQueryNodeBuilder.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.queryparser.flexible.standard.builders;
-
-import org.apache.lucene.document.FieldType;
-import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
-import org.apache.lucene.queryparser.flexible.core.messages.QueryParserMessages;
-import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode;
-import org.apache.lucene.queryparser.flexible.core.util.StringUtils;
-import org.apache.lucene.queryparser.flexible.messages.MessageImpl;
-import org.apache.lucene.queryparser.flexible.standard.config.NumericConfig;
-import org.apache.lucene.queryparser.flexible.standard.nodes.NumericQueryNode;
-import org.apache.lucene.queryparser.flexible.standard.nodes.NumericRangeQueryNode;
-import org.apache.lucene.search.LegacyNumericRangeQuery;
-
-/**
- * Builds {@link org.apache.lucene.search.LegacyNumericRangeQuery}s out of {@link NumericRangeQueryNode}s.
- *
- * @see org.apache.lucene.search.LegacyNumericRangeQuery
- * @see NumericRangeQueryNode
- */
-public class NumericRangeQueryNodeBuilder implements StandardQueryBuilder {
-
- /**
- * Constructs a {@link NumericRangeQueryNodeBuilder} object.
- */
- public NumericRangeQueryNodeBuilder() {
- // empty constructor
- }
-
- @Override
- public LegacyNumericRangeQuery<? extends Number> build(QueryNode queryNode)
- throws QueryNodeException {
- NumericRangeQueryNode numericRangeNode = (NumericRangeQueryNode) queryNode;
-
- NumericQueryNode lowerNumericNode = numericRangeNode.getLowerBound();
- NumericQueryNode upperNumericNode = numericRangeNode.getUpperBound();
-
- Number lowerNumber = lowerNumericNode.getValue();
- Number upperNumber = upperNumericNode.getValue();
-
- NumericConfig numericConfig = numericRangeNode.getNumericConfig();
- FieldType.LegacyNumericType numberType = numericConfig.getType();
- String field = StringUtils.toString(numericRangeNode.getField());
- boolean minInclusive = numericRangeNode.isLowerInclusive();
- boolean maxInclusive = numericRangeNode.isUpperInclusive();
- int precisionStep = numericConfig.getPrecisionStep();
-
- switch (numberType) {
-
- case LONG:
- return LegacyNumericRangeQuery.newLongRange(field, precisionStep,
- (Long) lowerNumber, (Long) upperNumber, minInclusive, maxInclusive);
-
- case INT:
- return LegacyNumericRangeQuery.newIntRange(field, precisionStep,
- (Integer) lowerNumber, (Integer) upperNumber, minInclusive,
- maxInclusive);
-
- case FLOAT:
- return LegacyNumericRangeQuery.newFloatRange(field, precisionStep,
- (Float) lowerNumber, (Float) upperNumber, minInclusive,
- maxInclusive);
-
- case DOUBLE:
- return LegacyNumericRangeQuery.newDoubleRange(field, precisionStep,
- (Double) lowerNumber, (Double) upperNumber, minInclusive,
- maxInclusive);
-
- default :
- throw new QueryNodeException(new MessageImpl(
- QueryParserMessages.UNSUPPORTED_NUMERIC_DATA_TYPE, numberType));
-
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/builders/PointRangeQueryNodeBuilder.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/builders/PointRangeQueryNodeBuilder.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/builders/PointRangeQueryNodeBuilder.java
new file mode 100644
index 0000000..0cce4bf
--- /dev/null
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/builders/PointRangeQueryNodeBuilder.java
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.queryparser.flexible.standard.builders;
+
+import org.apache.lucene.document.DoublePoint;
+import org.apache.lucene.document.FloatPoint;
+import org.apache.lucene.document.IntPoint;
+import org.apache.lucene.document.LongPoint;
+import org.apache.lucene.index.PointValues;
+import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
+import org.apache.lucene.queryparser.flexible.core.messages.QueryParserMessages;
+import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode;
+import org.apache.lucene.queryparser.flexible.core.util.StringUtils;
+import org.apache.lucene.queryparser.flexible.messages.MessageImpl;
+import org.apache.lucene.queryparser.flexible.standard.config.PointsConfig;
+import org.apache.lucene.queryparser.flexible.standard.nodes.PointQueryNode;
+import org.apache.lucene.queryparser.flexible.standard.nodes.PointRangeQueryNode;
+import org.apache.lucene.search.Query;
+
+/**
+ * Builds {@link PointValues} range queries out of {@link PointRangeQueryNode}s.
+ *
+ * @see PointRangeQueryNode
+ */
+public class PointRangeQueryNodeBuilder implements StandardQueryBuilder {
+
+ /**
+ * Constructs a {@link PointRangeQueryNodeBuilder} object.
+ */
+ public PointRangeQueryNodeBuilder() {
+ // empty constructor
+ }
+
+ @Override
+ public Query build(QueryNode queryNode) throws QueryNodeException {
+ PointRangeQueryNode numericRangeNode = (PointRangeQueryNode) queryNode;
+
+ PointQueryNode lowerNumericNode = numericRangeNode.getLowerBound();
+ PointQueryNode upperNumericNode = numericRangeNode.getUpperBound();
+
+ Number lowerNumber = lowerNumericNode.getValue();
+ Number upperNumber = upperNumericNode.getValue();
+
+ PointsConfig pointsConfig = numericRangeNode.getPointsConfig();
+ Class<? extends Number> numberType = pointsConfig.getType();
+ String field = StringUtils.toString(numericRangeNode.getField());
+ boolean minInclusive = numericRangeNode.isLowerInclusive();
+ boolean maxInclusive = numericRangeNode.isUpperInclusive();
+
+ // TODO: push down cleaning up of crazy nulls and inclusive/exclusive elsewhere
+ if (Integer.class.equals(numberType)) {
+ Integer lower = (Integer) lowerNumber;
+ if (lower == null) {
+ lower = Integer.MIN_VALUE;
+ }
+ if (minInclusive == false) {
+ lower = lower + 1;
+ }
+
+ Integer upper = (Integer) upperNumber;
+ if (upper == null) {
+ upper = Integer.MAX_VALUE;
+ }
+ if (maxInclusive == false) {
+ upper = upper - 1;
+ }
+ return IntPoint.newRangeQuery(field, lower, upper);
+ } else if (Long.class.equals(numberType)) {
+ Long lower = (Long) lowerNumber;
+ if (lower == null) {
+ lower = Long.MIN_VALUE;
+ }
+ if (minInclusive == false) {
+ lower = lower + 1;
+ }
+
+ Long upper = (Long) upperNumber;
+ if (upper == null) {
+ upper = Long.MAX_VALUE;
+ }
+ if (maxInclusive == false) {
+ upper = upper - 1;
+ }
+ return LongPoint.newRangeQuery(field, lower, upper);
+ } else if (Float.class.equals(numberType)) {
+ Float lower = (Float) lowerNumber;
+ if (lower == null) {
+ lower = Float.NEGATIVE_INFINITY;
+ }
+ if (minInclusive == false) {
+ lower = Math.nextUp(lower);
+ }
+
+ Float upper = (Float) upperNumber;
+ if (upper == null) {
+ upper = Float.POSITIVE_INFINITY;
+ }
+ if (maxInclusive == false) {
+ upper = Math.nextDown(upper);
+ }
+ return FloatPoint.newRangeQuery(field, lower, upper);
+ } else if (Double.class.equals(numberType)) {
+ Double lower = (Double) lowerNumber;
+ if (lower == null) {
+ lower = Double.NEGATIVE_INFINITY;
+ }
+ if (minInclusive == false) {
+ lower = Math.nextUp(lower);
+ }
+
+ Double upper = (Double) upperNumber;
+ if (upper == null) {
+ upper = Double.POSITIVE_INFINITY;
+ }
+ if (maxInclusive == false) {
+ upper = Math.nextDown(upper);
+ }
+ return DoublePoint.newRangeQuery(field, lower, upper);
+ } else {
+ throw new QueryNodeException(new MessageImpl(QueryParserMessages.UNSUPPORTED_NUMERIC_DATA_TYPE, numberType));
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/builders/StandardQueryTreeBuilder.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/builders/StandardQueryTreeBuilder.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/builders/StandardQueryTreeBuilder.java
index 2d7c643..360f6a7 100644
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/builders/StandardQueryTreeBuilder.java
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/builders/StandardQueryTreeBuilder.java
@@ -30,8 +30,10 @@ import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode;
import org.apache.lucene.queryparser.flexible.core.nodes.SlopQueryNode;
import org.apache.lucene.queryparser.flexible.core.nodes.TokenizedPhraseQueryNode;
import org.apache.lucene.queryparser.flexible.standard.nodes.MultiPhraseQueryNode;
-import org.apache.lucene.queryparser.flexible.standard.nodes.NumericQueryNode;
-import org.apache.lucene.queryparser.flexible.standard.nodes.NumericRangeQueryNode;
+import org.apache.lucene.queryparser.flexible.standard.nodes.PointQueryNode;
+import org.apache.lucene.queryparser.flexible.standard.nodes.PointRangeQueryNode;
+import org.apache.lucene.queryparser.flexible.standard.nodes.LegacyNumericQueryNode;
+import org.apache.lucene.queryparser.flexible.standard.nodes.LegacyNumericRangeQueryNode;
import org.apache.lucene.queryparser.flexible.standard.nodes.PrefixWildcardQueryNode;
import org.apache.lucene.queryparser.flexible.standard.nodes.TermRangeQueryNode;
import org.apache.lucene.queryparser.flexible.standard.nodes.RegexpQueryNode;
@@ -57,8 +59,10 @@ public class StandardQueryTreeBuilder extends QueryTreeBuilder implements
setBuilder(FieldQueryNode.class, new FieldQueryNodeBuilder());
setBuilder(BooleanQueryNode.class, new BooleanQueryNodeBuilder());
setBuilder(FuzzyQueryNode.class, new FuzzyQueryNodeBuilder());
- setBuilder(NumericQueryNode.class, new DummyQueryNodeBuilder());
- setBuilder(NumericRangeQueryNode.class, new NumericRangeQueryNodeBuilder());
+ setBuilder(LegacyNumericQueryNode.class, new DummyQueryNodeBuilder());
+ setBuilder(LegacyNumericRangeQueryNode.class, new LegacyNumericRangeQueryNodeBuilder());
+ setBuilder(PointQueryNode.class, new DummyQueryNodeBuilder());
+ setBuilder(PointRangeQueryNode.class, new PointRangeQueryNodeBuilder());
setBuilder(BoostQueryNode.class, new BoostQueryNodeBuilder());
setBuilder(ModifierQueryNode.class, new ModifierQueryNodeBuilder());
setBuilder(WildcardQueryNode.class, new WildcardQueryNodeBuilder());
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/config/LegacyNumericConfig.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/config/LegacyNumericConfig.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/config/LegacyNumericConfig.java
new file mode 100644
index 0000000..985f55a
--- /dev/null
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/config/LegacyNumericConfig.java
@@ -0,0 +1,166 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.queryparser.flexible.standard.config;
+
+import java.text.NumberFormat;
+import java.util.Objects;
+
+import org.apache.lucene.document.FieldType;
+import org.apache.lucene.document.FieldType.LegacyNumericType;
+
+/**
+ * This class holds the configuration used to parse numeric queries and create
+ * {@link org.apache.lucene.search.LegacyNumericRangeQuery}s.
+ *
+ * @see org.apache.lucene.search.LegacyNumericRangeQuery
+ * @see NumberFormat
+ * @deprecated Index with Points instead and use {@link PointsConfig}
+ */
+@Deprecated
+public class LegacyNumericConfig {
+
+ private int precisionStep;
+
+ private NumberFormat format;
+
+ private FieldType.LegacyNumericType type;
+
+ /**
+ * Constructs a {@link LegacyNumericConfig} object.
+ *
+ * @param precisionStep
+ * the precision used to index the numeric values
+ * @param format
+ * the {@link NumberFormat} used to parse a {@link String} to
+ * {@link Number}
+ * @param type
+ * the numeric type used to index the numeric values
+ *
+ * @see LegacyNumericConfig#setPrecisionStep(int)
+ * @see LegacyNumericConfig#setNumberFormat(NumberFormat)
+ * @see #setType(org.apache.lucene.document.FieldType.LegacyNumericType)
+ */
+ public LegacyNumericConfig(int precisionStep, NumberFormat format,
+ LegacyNumericType type) {
+ setPrecisionStep(precisionStep);
+ setNumberFormat(format);
+ setType(type);
+
+ }
+
+ /**
+ * Returns the precision used to index the numeric values
+ *
+ * @return the precision used to index the numeric values
+ *
+ * @see org.apache.lucene.search.LegacyNumericRangeQuery#getPrecisionStep()
+ */
+ public int getPrecisionStep() {
+ return precisionStep;
+ }
+
+ /**
+ * Sets the precision used to index the numeric values
+ *
+ * @param precisionStep
+ * the precision used to index the numeric values
+ *
+ * @see org.apache.lucene.search.LegacyNumericRangeQuery#getPrecisionStep()
+ */
+ public void setPrecisionStep(int precisionStep) {
+ this.precisionStep = precisionStep;
+ }
+
+ /**
+ * Returns the {@link NumberFormat} used to parse a {@link String} to
+ * {@link Number}
+ *
+ * @return the {@link NumberFormat} used to parse a {@link String} to
+ * {@link Number}
+ */
+ public NumberFormat getNumberFormat() {
+ return format;
+ }
+
+ /**
+ * Returns the numeric type used to index the numeric values
+ *
+ * @return the numeric type used to index the numeric values
+ */
+ public LegacyNumericType getType() {
+ return type;
+ }
+
+ /**
+ * Sets the numeric type used to index the numeric values
+ *
+ * @param type the numeric type used to index the numeric values
+ */
+ public void setType(LegacyNumericType type) {
+
+ if (type == null) {
+ throw new IllegalArgumentException("type cannot be null!");
+ }
+
+ this.type = type;
+
+ }
+
+ /**
+ * Sets the {@link NumberFormat} used to parse a {@link String} to
+ * {@link Number}
+ *
+ * @param format
+ * the {@link NumberFormat} used to parse a {@link String} to
+ * {@link Number}, cannot be <code>null</code>
+ */
+ public void setNumberFormat(NumberFormat format) {
+
+ if (format == null) {
+ throw new IllegalArgumentException("format cannot be null!");
+ }
+
+ this.format = format;
+
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+
+ if (obj == this) return true;
+
+ if (obj instanceof LegacyNumericConfig) {
+ LegacyNumericConfig other = (LegacyNumericConfig) obj;
+
+ if (this.precisionStep == other.precisionStep
+ && this.type == other.type
+ && (this.format == other.format || (this.format.equals(other.format)))) {
+ return true;
+ }
+
+ }
+
+ return false;
+
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(precisionStep, type, format);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/config/LegacyNumericFieldConfigListener.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/config/LegacyNumericFieldConfigListener.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/config/LegacyNumericFieldConfigListener.java
new file mode 100644
index 0000000..f2d3124
--- /dev/null
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/config/LegacyNumericFieldConfigListener.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.queryparser.flexible.standard.config;
+
+import java.util.Map;
+
+import org.apache.lucene.queryparser.flexible.core.config.FieldConfig;
+import org.apache.lucene.queryparser.flexible.core.config.FieldConfigListener;
+import org.apache.lucene.queryparser.flexible.core.config.QueryConfigHandler;
+import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler.ConfigurationKeys;
+
+/**
+ * This listener is used to listen to {@link FieldConfig} requests in
+ * {@link QueryConfigHandler} and add {@link ConfigurationKeys#LEGACY_NUMERIC_CONFIG}
+ * based on the {@link ConfigurationKeys#LEGACY_NUMERIC_CONFIG_MAP} set in the
+ * {@link QueryConfigHandler}.
+ *
+ * @see LegacyNumericConfig
+ * @see QueryConfigHandler
+ * @see ConfigurationKeys#LEGACY_NUMERIC_CONFIG
+ * @see ConfigurationKeys#LEGACY_NUMERIC_CONFIG_MAP
+ * @deprecated Index with Points instead and use {@link PointsConfigListener}
+ */
+@Deprecated
+public class LegacyNumericFieldConfigListener implements FieldConfigListener {
+
+ final private QueryConfigHandler config;
+
+ /**
+ * Constructs a {@link LegacyNumericFieldConfigListener} object using the given {@link QueryConfigHandler}.
+ *
+ * @param config the {@link QueryConfigHandler} it will listen too
+ */
+ public LegacyNumericFieldConfigListener(QueryConfigHandler config) {
+
+ if (config == null) {
+ throw new IllegalArgumentException("config cannot be null!");
+ }
+
+ this.config = config;
+
+ }
+
+ @Override
+ public void buildFieldConfig(FieldConfig fieldConfig) {
+ Map<String,LegacyNumericConfig> numericConfigMap = config
+ .get(ConfigurationKeys.LEGACY_NUMERIC_CONFIG_MAP);
+
+ if (numericConfigMap != null) {
+ LegacyNumericConfig numericConfig = numericConfigMap
+ .get(fieldConfig.getField());
+
+ if (numericConfig != null) {
+ fieldConfig.set(ConfigurationKeys.LEGACY_NUMERIC_CONFIG, numericConfig);
+ }
+
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/config/NumericConfig.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/config/NumericConfig.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/config/NumericConfig.java
deleted file mode 100644
index c457a4e..0000000
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/config/NumericConfig.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.queryparser.flexible.standard.config;
-
-import java.text.NumberFormat;
-import java.util.Objects;
-
-import org.apache.lucene.document.FieldType;
-import org.apache.lucene.document.FieldType.LegacyNumericType;
-
-/**
- * This class holds the configuration used to parse numeric queries and create
- * {@link org.apache.lucene.search.LegacyNumericRangeQuery}s.
- *
- * @see org.apache.lucene.search.LegacyNumericRangeQuery
- * @see NumberFormat
- */
-public class NumericConfig {
-
- private int precisionStep;
-
- private NumberFormat format;
-
- private FieldType.LegacyNumericType type;
-
- /**
- * Constructs a {@link NumericConfig} object.
- *
- * @param precisionStep
- * the precision used to index the numeric values
- * @param format
- * the {@link NumberFormat} used to parse a {@link String} to
- * {@link Number}
- * @param type
- * the numeric type used to index the numeric values
- *
- * @see NumericConfig#setPrecisionStep(int)
- * @see NumericConfig#setNumberFormat(NumberFormat)
- * @see #setType(org.apache.lucene.document.FieldType.LegacyNumericType)
- */
- public NumericConfig(int precisionStep, NumberFormat format,
- LegacyNumericType type) {
- setPrecisionStep(precisionStep);
- setNumberFormat(format);
- setType(type);
-
- }
-
- /**
- * Returns the precision used to index the numeric values
- *
- * @return the precision used to index the numeric values
- *
- * @see org.apache.lucene.search.LegacyNumericRangeQuery#getPrecisionStep()
- */
- public int getPrecisionStep() {
- return precisionStep;
- }
-
- /**
- * Sets the precision used to index the numeric values
- *
- * @param precisionStep
- * the precision used to index the numeric values
- *
- * @see org.apache.lucene.search.LegacyNumericRangeQuery#getPrecisionStep()
- */
- public void setPrecisionStep(int precisionStep) {
- this.precisionStep = precisionStep;
- }
-
- /**
- * Returns the {@link NumberFormat} used to parse a {@link String} to
- * {@link Number}
- *
- * @return the {@link NumberFormat} used to parse a {@link String} to
- * {@link Number}
- */
- public NumberFormat getNumberFormat() {
- return format;
- }
-
- /**
- * Returns the numeric type used to index the numeric values
- *
- * @return the numeric type used to index the numeric values
- */
- public LegacyNumericType getType() {
- return type;
- }
-
- /**
- * Sets the numeric type used to index the numeric values
- *
- * @param type the numeric type used to index the numeric values
- */
- public void setType(LegacyNumericType type) {
-
- if (type == null) {
- throw new IllegalArgumentException("type cannot be null!");
- }
-
- this.type = type;
-
- }
-
- /**
- * Sets the {@link NumberFormat} used to parse a {@link String} to
- * {@link Number}
- *
- * @param format
- * the {@link NumberFormat} used to parse a {@link String} to
- * {@link Number}, cannot be <code>null</code>
- */
- public void setNumberFormat(NumberFormat format) {
-
- if (format == null) {
- throw new IllegalArgumentException("format cannot be null!");
- }
-
- this.format = format;
-
- }
-
- @Override
- public boolean equals(Object obj) {
-
- if (obj == this) return true;
-
- if (obj instanceof NumericConfig) {
- NumericConfig other = (NumericConfig) obj;
-
- if (this.precisionStep == other.precisionStep
- && this.type == other.type
- && (this.format == other.format || (this.format.equals(other.format)))) {
- return true;
- }
-
- }
-
- return false;
-
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(precisionStep, type, format);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/config/NumericFieldConfigListener.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/config/NumericFieldConfigListener.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/config/NumericFieldConfigListener.java
deleted file mode 100644
index c28cf2c..0000000
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/config/NumericFieldConfigListener.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.queryparser.flexible.standard.config;
-
-import java.util.Map;
-
-import org.apache.lucene.queryparser.flexible.core.config.FieldConfig;
-import org.apache.lucene.queryparser.flexible.core.config.FieldConfigListener;
-import org.apache.lucene.queryparser.flexible.core.config.QueryConfigHandler;
-import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler.ConfigurationKeys;
-
-/**
- * This listener is used to listen to {@link FieldConfig} requests in
- * {@link QueryConfigHandler} and add {@link ConfigurationKeys#NUMERIC_CONFIG}
- * based on the {@link ConfigurationKeys#NUMERIC_CONFIG_MAP} set in the
- * {@link QueryConfigHandler}.
- *
- * @see NumericConfig
- * @see QueryConfigHandler
- * @see ConfigurationKeys#NUMERIC_CONFIG
- * @see ConfigurationKeys#NUMERIC_CONFIG_MAP
- */
-public class NumericFieldConfigListener implements FieldConfigListener {
-
- final private QueryConfigHandler config;
-
- /**
- * Construcs a {@link NumericFieldConfigListener} object using the given {@link QueryConfigHandler}.
- *
- * @param config the {@link QueryConfigHandler} it will listen too
- */
- public NumericFieldConfigListener(QueryConfigHandler config) {
-
- if (config == null) {
- throw new IllegalArgumentException("config cannot be null!");
- }
-
- this.config = config;
-
- }
-
- @Override
- public void buildFieldConfig(FieldConfig fieldConfig) {
- Map<String,NumericConfig> numericConfigMap = config
- .get(ConfigurationKeys.NUMERIC_CONFIG_MAP);
-
- if (numericConfigMap != null) {
- NumericConfig numericConfig = numericConfigMap
- .get(fieldConfig.getField());
-
- if (numericConfig != null) {
- fieldConfig.set(ConfigurationKeys.NUMERIC_CONFIG, numericConfig);
- }
-
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/config/PointsConfig.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/config/PointsConfig.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/config/PointsConfig.java
new file mode 100644
index 0000000..db59b48
--- /dev/null
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/config/PointsConfig.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.queryparser.flexible.standard.config;
+
+import java.text.NumberFormat;
+
+import org.apache.lucene.index.PointValues;
+
+/**
+ * This class holds the configuration used to parse numeric queries and create
+ * {@link PointValues} queries.
+ *
+ * @see PointValues
+ * @see NumberFormat
+ */
+public class PointsConfig {
+
+ private NumberFormat format;
+
+ private Class<? extends Number> type;
+
+ /**
+ * Constructs a {@link PointsConfig} object.
+ *
+ * @param format
+ * the {@link NumberFormat} used to parse a {@link String} to
+ * {@link Number}
+ * @param type
+ * the numeric type used to index the numeric values
+ *
+ * @see PointsConfig#setNumberFormat(NumberFormat)
+ */
+ public PointsConfig(NumberFormat format, Class<? extends Number> type) {
+ setNumberFormat(format);
+ setType(type);
+ }
+
+ /**
+ * Returns the {@link NumberFormat} used to parse a {@link String} to
+ * {@link Number}
+ *
+ * @return the {@link NumberFormat} used to parse a {@link String} to
+ * {@link Number}
+ */
+ public NumberFormat getNumberFormat() {
+ return format;
+ }
+
+ /**
+ * Returns the numeric type used to index the numeric values
+ *
+ * @return the numeric type used to index the numeric values
+ */
+ public Class<? extends Number> getType() {
+ return type;
+ }
+
+ /**
+ * Sets the numeric type used to index the numeric values
+ *
+ * @param type the numeric type used to index the numeric values
+ */
+ public void setType(Class<? extends Number> type) {
+ if (type == null) {
+ throw new IllegalArgumentException("type cannot be null!");
+ }
+ if (Integer.class.equals(type) == false &&
+ Long.class.equals(type) == false &&
+ Float.class.equals(type) == false &&
+ Double.class.equals(type) == false) {
+ throw new IllegalArgumentException("unsupported numeric type: " + type);
+ }
+ this.type = type;
+ }
+
+ /**
+ * Sets the {@link NumberFormat} used to parse a {@link String} to
+ * {@link Number}
+ *
+ * @param format
+ * the {@link NumberFormat} used to parse a {@link String} to
+ * {@link Number}, cannot be <code>null</code>
+ */
+ public void setNumberFormat(NumberFormat format) {
+ if (format == null) {
+ throw new IllegalArgumentException("format cannot be null!");
+ }
+ this.format = format;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + format.hashCode();
+ result = prime * result + type.hashCode();
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (obj == null) return false;
+ if (getClass() != obj.getClass()) return false;
+ PointsConfig other = (PointsConfig) obj;
+ if (!format.equals(other.format)) return false;
+ if (!type.equals(other.type)) return false;
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/config/PointsConfigListener.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/config/PointsConfigListener.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/config/PointsConfigListener.java
new file mode 100644
index 0000000..9efbbb7
--- /dev/null
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/config/PointsConfigListener.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.queryparser.flexible.standard.config;
+
+import java.util.Map;
+
+import org.apache.lucene.queryparser.flexible.core.config.FieldConfig;
+import org.apache.lucene.queryparser.flexible.core.config.FieldConfigListener;
+import org.apache.lucene.queryparser.flexible.core.config.QueryConfigHandler;
+import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler.ConfigurationKeys;
+
+/**
+ * This listener is used to listen to {@link FieldConfig} requests in
+ * {@link QueryConfigHandler} and add {@link ConfigurationKeys#POINTS_CONFIG}
+ * based on the {@link ConfigurationKeys#POINTS_CONFIG_MAP} set in the
+ * {@link QueryConfigHandler}.
+ *
+ * @see PointsConfig
+ * @see QueryConfigHandler
+ * @see ConfigurationKeys#POINTS_CONFIG
+ * @see ConfigurationKeys#POINTS_CONFIG_MAP
+ */
+public class PointsConfigListener implements FieldConfigListener {
+
+ final private QueryConfigHandler config;
+
+ /**
+ * Constructs a {@link PointsConfigListener} object using the given {@link QueryConfigHandler}.
+ *
+ * @param config the {@link QueryConfigHandler} it will listen too
+ */
+ public PointsConfigListener(QueryConfigHandler config) {
+ if (config == null) {
+ throw new IllegalArgumentException("config cannot be null!");
+ }
+ this.config = config;
+ }
+
+ @Override
+ public void buildFieldConfig(FieldConfig fieldConfig) {
+ Map<String,PointsConfig> pointsConfigMap = config.get(ConfigurationKeys.POINTS_CONFIG_MAP);
+
+ if (pointsConfigMap != null) {
+ PointsConfig pointsConfig = pointsConfigMap.get(fieldConfig.getField());
+
+ if (pointsConfig != null) {
+ fieldConfig.set(ConfigurationKeys.POINTS_CONFIG, pointsConfig);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/config/StandardQueryConfigHandler.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/config/StandardQueryConfigHandler.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/config/StandardQueryConfigHandler.java
index 77bd7bb..bba95ee 100644
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/config/StandardQueryConfigHandler.java
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/config/StandardQueryConfigHandler.java
@@ -167,21 +167,41 @@ public class StandardQueryConfigHandler extends QueryConfigHandler {
final public static ConfigurationKey<Float> BOOST = ConfigurationKey.newInstance();
/**
- * Key used to set a field to its {@link NumericConfig}.
+ * Key used to set a field to its {@link LegacyNumericConfig}.
*
- * @see StandardQueryParser#setNumericConfigMap(Map)
- * @see StandardQueryParser#getNumericConfigMap()
+ * @see StandardQueryParser#setLegacyNumericConfigMap(Map)
+ * @see StandardQueryParser#getLegacyNumericConfigMap()
+ * @deprecated Index with Points instead and use {@link #POINTS_CONFIG}
*/
- final public static ConfigurationKey<NumericConfig> NUMERIC_CONFIG = ConfigurationKey.newInstance();
+ @Deprecated
+ final public static ConfigurationKey<LegacyNumericConfig> LEGACY_NUMERIC_CONFIG = ConfigurationKey.newInstance();
/**
- * Key used to set the {@link NumericConfig} in {@link FieldConfig} for numeric fields.
+ * Key used to set the {@link LegacyNumericConfig} in {@link FieldConfig} for numeric fields.
*
- * @see StandardQueryParser#setNumericConfigMap(Map)
- * @see StandardQueryParser#getNumericConfigMap()
+ * @see StandardQueryParser#setLegacyNumericConfigMap(Map)
+ * @see StandardQueryParser#getLegacyNumericConfigMap()
+ * @deprecated Index with Points instead and use {@link #POINTS_CONFIG_MAP}
*/
- final public static ConfigurationKey<Map<String,NumericConfig>> NUMERIC_CONFIG_MAP = ConfigurationKey.newInstance();
+ @Deprecated
+ final public static ConfigurationKey<Map<String,LegacyNumericConfig>> LEGACY_NUMERIC_CONFIG_MAP = ConfigurationKey.newInstance();
+ /**
+ * Key used to set a field to its {@link PointsConfig}.
+ *
+ * @see StandardQueryParser#setLegacyNumericConfigMap(Map)
+ * @see StandardQueryParser#getLegacyNumericConfigMap()
+ */
+ final public static ConfigurationKey<PointsConfig> POINTS_CONFIG = ConfigurationKey.newInstance();
+
+ /**
+ * Key used to set the {@link PointsConfig} in {@link FieldConfig} for point fields.
+ *
+ * @see StandardQueryParser#setLegacyNumericConfigMap(Map)
+ * @see StandardQueryParser#getLegacyNumericConfigMap()
+ */
+ final public static ConfigurationKey<Map<String,PointsConfig>> POINTS_CONFIG_MAP = ConfigurationKey.newInstance();
+
}
/**
@@ -195,7 +215,8 @@ public class StandardQueryConfigHandler extends QueryConfigHandler {
// Add listener that will build the FieldConfig.
addFieldConfigListener(new FieldBoostMapFCListener(this));
addFieldConfigListener(new FieldDateResolutionFCListener(this));
- addFieldConfigListener(new NumericFieldConfigListener(this));
+ addFieldConfigListener(new LegacyNumericFieldConfigListener(this));
+ addFieldConfigListener(new PointsConfigListener(this));
// Default Values
set(ConfigurationKeys.ALLOW_LEADING_WILDCARD, false); // default in 2.9
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/nodes/LegacyNumericQueryNode.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/nodes/LegacyNumericQueryNode.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/nodes/LegacyNumericQueryNode.java
new file mode 100644
index 0000000..b644d8a
--- /dev/null
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/nodes/LegacyNumericQueryNode.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.queryparser.flexible.standard.nodes;
+
+import java.text.NumberFormat;
+import java.util.Locale;
+
+import org.apache.lucene.queryparser.flexible.core.nodes.FieldQueryNode;
+import org.apache.lucene.queryparser.flexible.core.nodes.FieldValuePairQueryNode;
+import org.apache.lucene.queryparser.flexible.core.nodes.QueryNodeImpl;
+import org.apache.lucene.queryparser.flexible.core.parser.EscapeQuerySyntax;
+import org.apache.lucene.queryparser.flexible.core.parser.EscapeQuerySyntax.Type;
+import org.apache.lucene.queryparser.flexible.standard.config.LegacyNumericConfig;
+
+/**
+ * This query node represents a field query that holds a numeric value. It is
+ * similar to {@link FieldQueryNode}, however the {@link #getValue()} returns a
+ * {@link Number}.
+ *
+ * @see LegacyNumericConfig
+ * @deprecated Index with Points instead and use {@link PointQueryNode} instead.
+ */
+@Deprecated
+public class LegacyNumericQueryNode extends QueryNodeImpl implements
+ FieldValuePairQueryNode<Number> {
+
+ private NumberFormat numberFormat;
+
+ private CharSequence field;
+
+ private Number value;
+
+ /**
+ * Creates a {@link LegacyNumericQueryNode} object using the given field,
+ * {@link Number} value and {@link NumberFormat} used to convert the value to
+ * {@link String}.
+ *
+ * @param field the field associated with this query node
+ * @param value the value hold by this node
+ * @param numberFormat the {@link NumberFormat} used to convert the value to {@link String}
+ */
+ public LegacyNumericQueryNode(CharSequence field, Number value,
+ NumberFormat numberFormat) {
+
+ super();
+
+ setNumberFormat(numberFormat);
+ setField(field);
+ setValue(value);
+
+ }
+
+ /**
+ * Returns the field associated with this node.
+ *
+ * @return the field associated with this node
+ */
+ @Override
+ public CharSequence getField() {
+ return this.field;
+ }
+
+ /**
+ * Sets the field associated with this node.
+ *
+ * @param fieldName the field associated with this node
+ */
+ @Override
+ public void setField(CharSequence fieldName) {
+ this.field = fieldName;
+ }
+
+ /**
+ * This method is used to get the value converted to {@link String} and
+ * escaped using the given {@link EscapeQuerySyntax}.
+ *
+ * @param escaper the {@link EscapeQuerySyntax} used to escape the value {@link String}
+ *
+ * @return the value converte to {@link String} and escaped
+ */
+ protected CharSequence getTermEscaped(EscapeQuerySyntax escaper) {
+ return escaper.escape(numberFormat.format(this.value),
+ Locale.ROOT, Type.NORMAL);
+ }
+
+ @Override
+ public CharSequence toQueryString(EscapeQuerySyntax escapeSyntaxParser) {
+ if (isDefaultField(this.field)) {
+ return getTermEscaped(escapeSyntaxParser);
+ } else {
+ return this.field + ":" + getTermEscaped(escapeSyntaxParser);
+ }
+ }
+
+ /**
+ * Sets the {@link NumberFormat} used to convert the value to {@link String}.
+ *
+ * @param format the {@link NumberFormat} used to convert the value to {@link String}
+ */
+ public void setNumberFormat(NumberFormat format) {
+ this.numberFormat = format;
+ }
+
+ /**
+ * Returns the {@link NumberFormat} used to convert the value to {@link String}.
+ *
+ * @return the {@link NumberFormat} used to convert the value to {@link String}
+ */
+ public NumberFormat getNumberFormat() {
+ return this.numberFormat;
+ }
+
+ /**
+ * Returns the numeric value as {@link Number}.
+ *
+ * @return the numeric value
+ */
+ @Override
+ public Number getValue() {
+ return value;
+ }
+
+ /**
+ * Sets the numeric value.
+ *
+ * @param value the numeric value
+ */
+ @Override
+ public void setValue(Number value) {
+ this.value = value;
+ }
+
+ @Override
+ public String toString() {
+ return "<numeric field='" + this.field + "' number='"
+ + numberFormat.format(value) + "'/>";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/nodes/LegacyNumericRangeQueryNode.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/nodes/LegacyNumericRangeQueryNode.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/nodes/LegacyNumericRangeQueryNode.java
new file mode 100644
index 0000000..088ab98
--- /dev/null
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/nodes/LegacyNumericRangeQueryNode.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.queryparser.flexible.standard.nodes;
+
+import org.apache.lucene.document.FieldType;
+import org.apache.lucene.document.FieldType.LegacyNumericType;
+import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
+import org.apache.lucene.queryparser.flexible.core.messages.QueryParserMessages;
+import org.apache.lucene.queryparser.flexible.messages.MessageImpl;
+import org.apache.lucene.queryparser.flexible.standard.config.LegacyNumericConfig;
+
+/**
+ * This query node represents a range query composed by {@link LegacyNumericQueryNode}
+ * bounds, which means the bound values are {@link Number}s.
+ *
+ * @see LegacyNumericQueryNode
+ * @see AbstractRangeQueryNode
+ * @deprecated Index with Points instead and use {@link PointRangeQueryNode} instead.
+ */
+@Deprecated
+public class LegacyNumericRangeQueryNode extends
+ AbstractRangeQueryNode<LegacyNumericQueryNode> {
+
+ public LegacyNumericConfig numericConfig;
+
+ /**
+ * Constructs a {@link LegacyNumericRangeQueryNode} object using the given
+ * {@link LegacyNumericQueryNode} as its bounds and {@link LegacyNumericConfig}.
+ *
+ * @param lower the lower bound
+ * @param upper the upper bound
+ * @param lowerInclusive <code>true</code> if the lower bound is inclusive, otherwise, <code>false</code>
+ * @param upperInclusive <code>true</code> if the upper bound is inclusive, otherwise, <code>false</code>
+ * @param numericConfig the {@link LegacyNumericConfig} that represents associated with the upper and lower bounds
+ *
+ * @see #setBounds(LegacyNumericQueryNode, LegacyNumericQueryNode, boolean, boolean, LegacyNumericConfig)
+ */
+ public LegacyNumericRangeQueryNode(LegacyNumericQueryNode lower, LegacyNumericQueryNode upper,
+ boolean lowerInclusive, boolean upperInclusive, LegacyNumericConfig numericConfig) throws QueryNodeException {
+ setBounds(lower, upper, lowerInclusive, upperInclusive, numericConfig);
+ }
+
+ private static LegacyNumericType getNumericDataType(Number number) throws QueryNodeException {
+
+ if (number instanceof Long) {
+ return FieldType.LegacyNumericType.LONG;
+ } else if (number instanceof Integer) {
+ return FieldType.LegacyNumericType.INT;
+ } else if (number instanceof Double) {
+ return LegacyNumericType.DOUBLE;
+ } else if (number instanceof Float) {
+ return FieldType.LegacyNumericType.FLOAT;
+ } else {
+ throw new QueryNodeException(
+ new MessageImpl(
+ QueryParserMessages.NUMBER_CLASS_NOT_SUPPORTED_BY_NUMERIC_RANGE_QUERY,
+ number.getClass()));
+ }
+
+ }
+
+ /**
+ * Sets the upper and lower bounds of this range query node and the
+ * {@link LegacyNumericConfig} associated with these bounds.
+ *
+ * @param lower the lower bound
+ * @param upper the upper bound
+ * @param lowerInclusive <code>true</code> if the lower bound is inclusive, otherwise, <code>false</code>
+ * @param upperInclusive <code>true</code> if the upper bound is inclusive, otherwise, <code>false</code>
+ * @param numericConfig the {@link LegacyNumericConfig} that represents associated with the upper and lower bounds
+ *
+ */
+ public void setBounds(LegacyNumericQueryNode lower, LegacyNumericQueryNode upper,
+ boolean lowerInclusive, boolean upperInclusive, LegacyNumericConfig numericConfig) throws QueryNodeException {
+
+ if (numericConfig == null) {
+ throw new IllegalArgumentException("numericConfig cannot be null!");
+ }
+
+ LegacyNumericType lowerNumberType, upperNumberType;
+
+ if (lower != null && lower.getValue() != null) {
+ lowerNumberType = getNumericDataType(lower.getValue());
+ } else {
+ lowerNumberType = null;
+ }
+
+ if (upper != null && upper.getValue() != null) {
+ upperNumberType = getNumericDataType(upper.getValue());
+ } else {
+ upperNumberType = null;
+ }
+
+ if (lowerNumberType != null
+ && !lowerNumberType.equals(numericConfig.getType())) {
+ throw new IllegalArgumentException(
+ "lower value's type should be the same as numericConfig type: "
+ + lowerNumberType + " != " + numericConfig.getType());
+ }
+
+ if (upperNumberType != null
+ && !upperNumberType.equals(numericConfig.getType())) {
+ throw new IllegalArgumentException(
+ "upper value's type should be the same as numericConfig type: "
+ + upperNumberType + " != " + numericConfig.getType());
+ }
+
+ super.setBounds(lower, upper, lowerInclusive, upperInclusive);
+ this.numericConfig = numericConfig;
+
+ }
+
+ /**
+ * Returns the {@link LegacyNumericConfig} associated with the lower and upper bounds.
+ *
+ * @return the {@link LegacyNumericConfig} associated with the lower and upper bounds
+ */
+ public LegacyNumericConfig getNumericConfig() {
+ return this.numericConfig;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("<numericRange lowerInclusive='");
+
+ sb.append(isLowerInclusive()).append("' upperInclusive='").append(
+ isUpperInclusive()).append(
+ "' precisionStep='" + numericConfig.getPrecisionStep()).append(
+ "' type='" + numericConfig.getType()).append("'>\n");
+
+ sb.append(getLowerBound()).append('\n');
+ sb.append(getUpperBound()).append('\n');
+ sb.append("</numericRange>");
+
+ return sb.toString();
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/nodes/NumericQueryNode.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/nodes/NumericQueryNode.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/nodes/NumericQueryNode.java
deleted file mode 100644
index 7509a39..0000000
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/nodes/NumericQueryNode.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.queryparser.flexible.standard.nodes;
-
-import java.text.NumberFormat;
-import java.util.Locale;
-
-import org.apache.lucene.queryparser.flexible.core.nodes.FieldQueryNode;
-import org.apache.lucene.queryparser.flexible.core.nodes.FieldValuePairQueryNode;
-import org.apache.lucene.queryparser.flexible.core.nodes.QueryNodeImpl;
-import org.apache.lucene.queryparser.flexible.core.parser.EscapeQuerySyntax;
-import org.apache.lucene.queryparser.flexible.core.parser.EscapeQuerySyntax.Type;
-import org.apache.lucene.queryparser.flexible.standard.config.NumericConfig;
-
-/**
- * This query node represents a field query that holds a numeric value. It is
- * similar to {@link FieldQueryNode}, however the {@link #getValue()} returns a
- * {@link Number}.
- *
- * @see NumericConfig
- */
-public class NumericQueryNode extends QueryNodeImpl implements
- FieldValuePairQueryNode<Number> {
-
- private NumberFormat numberFormat;
-
- private CharSequence field;
-
- private Number value;
-
- /**
- * Creates a {@link NumericQueryNode} object using the given field,
- * {@link Number} value and {@link NumberFormat} used to convert the value to
- * {@link String}.
- *
- * @param field the field associated with this query node
- * @param value the value hold by this node
- * @param numberFormat the {@link NumberFormat} used to convert the value to {@link String}
- */
- public NumericQueryNode(CharSequence field, Number value,
- NumberFormat numberFormat) {
-
- super();
-
- setNumberFormat(numberFormat);
- setField(field);
- setValue(value);
-
- }
-
- /**
- * Returns the field associated with this node.
- *
- * @return the field associated with this node
- */
- @Override
- public CharSequence getField() {
- return this.field;
- }
-
- /**
- * Sets the field associated with this node.
- *
- * @param fieldName the field associated with this node
- */
- @Override
- public void setField(CharSequence fieldName) {
- this.field = fieldName;
- }
-
- /**
- * This method is used to get the value converted to {@link String} and
- * escaped using the given {@link EscapeQuerySyntax}.
- *
- * @param escaper the {@link EscapeQuerySyntax} used to escape the value {@link String}
- *
- * @return the value converte to {@link String} and escaped
- */
- protected CharSequence getTermEscaped(EscapeQuerySyntax escaper) {
- return escaper.escape(numberFormat.format(this.value),
- Locale.ROOT, Type.NORMAL);
- }
-
- @Override
- public CharSequence toQueryString(EscapeQuerySyntax escapeSyntaxParser) {
- if (isDefaultField(this.field)) {
- return getTermEscaped(escapeSyntaxParser);
- } else {
- return this.field + ":" + getTermEscaped(escapeSyntaxParser);
- }
- }
-
- /**
- * Sets the {@link NumberFormat} used to convert the value to {@link String}.
- *
- * @param format the {@link NumberFormat} used to convert the value to {@link String}
- */
- public void setNumberFormat(NumberFormat format) {
- this.numberFormat = format;
- }
-
- /**
- * Returns the {@link NumberFormat} used to convert the value to {@link String}.
- *
- * @return the {@link NumberFormat} used to convert the value to {@link String}
- */
- public NumberFormat getNumberFormat() {
- return this.numberFormat;
- }
-
- /**
- * Returns the numeric value as {@link Number}.
- *
- * @return the numeric value
- */
- @Override
- public Number getValue() {
- return value;
- }
-
- /**
- * Sets the numeric value.
- *
- * @param value the numeric value
- */
- @Override
- public void setValue(Number value) {
- this.value = value;
- }
-
- @Override
- public String toString() {
- return "<numeric field='" + this.field + "' number='"
- + numberFormat.format(value) + "'/>";
- }
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/nodes/NumericRangeQueryNode.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/nodes/NumericRangeQueryNode.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/nodes/NumericRangeQueryNode.java
deleted file mode 100644
index c132aa1..0000000
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/nodes/NumericRangeQueryNode.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.queryparser.flexible.standard.nodes;
-
-import org.apache.lucene.document.FieldType;
-import org.apache.lucene.document.FieldType.LegacyNumericType;
-import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
-import org.apache.lucene.queryparser.flexible.core.messages.QueryParserMessages;
-import org.apache.lucene.queryparser.flexible.messages.MessageImpl;
-import org.apache.lucene.queryparser.flexible.standard.config.NumericConfig;
-
-/**
- * This query node represents a range query composed by {@link NumericQueryNode}
- * bounds, which means the bound values are {@link Number}s.
- *
- * @see NumericQueryNode
- * @see AbstractRangeQueryNode
- */
-public class NumericRangeQueryNode extends
- AbstractRangeQueryNode<NumericQueryNode> {
-
- public NumericConfig numericConfig;
-
- /**
- * Constructs a {@link NumericRangeQueryNode} object using the given
- * {@link NumericQueryNode} as its bounds and {@link NumericConfig}.
- *
- * @param lower the lower bound
- * @param upper the upper bound
- * @param lowerInclusive <code>true</code> if the lower bound is inclusive, otherwise, <code>false</code>
- * @param upperInclusive <code>true</code> if the upper bound is inclusive, otherwise, <code>false</code>
- * @param numericConfig the {@link NumericConfig} that represents associated with the upper and lower bounds
- *
- * @see #setBounds(NumericQueryNode, NumericQueryNode, boolean, boolean, NumericConfig)
- */
- public NumericRangeQueryNode(NumericQueryNode lower, NumericQueryNode upper,
- boolean lowerInclusive, boolean upperInclusive, NumericConfig numericConfig) throws QueryNodeException {
- setBounds(lower, upper, lowerInclusive, upperInclusive, numericConfig);
- }
-
- private static LegacyNumericType getNumericDataType(Number number) throws QueryNodeException {
-
- if (number instanceof Long) {
- return FieldType.LegacyNumericType.LONG;
- } else if (number instanceof Integer) {
- return FieldType.LegacyNumericType.INT;
- } else if (number instanceof Double) {
- return LegacyNumericType.DOUBLE;
- } else if (number instanceof Float) {
- return FieldType.LegacyNumericType.FLOAT;
- } else {
- throw new QueryNodeException(
- new MessageImpl(
- QueryParserMessages.NUMBER_CLASS_NOT_SUPPORTED_BY_NUMERIC_RANGE_QUERY,
- number.getClass()));
- }
-
- }
-
- /**
- * Sets the upper and lower bounds of this range query node and the
- * {@link NumericConfig} associated with these bounds.
- *
- * @param lower the lower bound
- * @param upper the upper bound
- * @param lowerInclusive <code>true</code> if the lower bound is inclusive, otherwise, <code>false</code>
- * @param upperInclusive <code>true</code> if the upper bound is inclusive, otherwise, <code>false</code>
- * @param numericConfig the {@link NumericConfig} that represents associated with the upper and lower bounds
- *
- */
- public void setBounds(NumericQueryNode lower, NumericQueryNode upper,
- boolean lowerInclusive, boolean upperInclusive, NumericConfig numericConfig) throws QueryNodeException {
-
- if (numericConfig == null) {
- throw new IllegalArgumentException("numericConfig cannot be null!");
- }
-
- LegacyNumericType lowerNumberType, upperNumberType;
-
- if (lower != null && lower.getValue() != null) {
- lowerNumberType = getNumericDataType(lower.getValue());
- } else {
- lowerNumberType = null;
- }
-
- if (upper != null && upper.getValue() != null) {
- upperNumberType = getNumericDataType(upper.getValue());
- } else {
- upperNumberType = null;
- }
-
- if (lowerNumberType != null
- && !lowerNumberType.equals(numericConfig.getType())) {
- throw new IllegalArgumentException(
- "lower value's type should be the same as numericConfig type: "
- + lowerNumberType + " != " + numericConfig.getType());
- }
-
- if (upperNumberType != null
- && !upperNumberType.equals(numericConfig.getType())) {
- throw new IllegalArgumentException(
- "upper value's type should be the same as numericConfig type: "
- + upperNumberType + " != " + numericConfig.getType());
- }
-
- super.setBounds(lower, upper, lowerInclusive, upperInclusive);
- this.numericConfig = numericConfig;
-
- }
-
- /**
- * Returns the {@link NumericConfig} associated with the lower and upper bounds.
- *
- * @return the {@link NumericConfig} associated with the lower and upper bounds
- */
- public NumericConfig getNumericConfig() {
- return this.numericConfig;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder("<numericRange lowerInclusive='");
-
- sb.append(isLowerInclusive()).append("' upperInclusive='").append(
- isUpperInclusive()).append(
- "' precisionStep='" + numericConfig.getPrecisionStep()).append(
- "' type='" + numericConfig.getType()).append("'>\n");
-
- sb.append(getLowerBound()).append('\n');
- sb.append(getUpperBound()).append('\n');
- sb.append("</numericRange>");
-
- return sb.toString();
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/nodes/PointQueryNode.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/nodes/PointQueryNode.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/nodes/PointQueryNode.java
new file mode 100644
index 0000000..6d4cba7
--- /dev/null
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/nodes/PointQueryNode.java
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.queryparser.flexible.standard.nodes;
+
+import java.text.NumberFormat;
+import java.util.Locale;
+
+import org.apache.lucene.queryparser.flexible.core.nodes.FieldQueryNode;
+import org.apache.lucene.queryparser.flexible.core.nodes.FieldValuePairQueryNode;
+import org.apache.lucene.queryparser.flexible.core.nodes.QueryNodeImpl;
+import org.apache.lucene.queryparser.flexible.core.parser.EscapeQuerySyntax;
+import org.apache.lucene.queryparser.flexible.core.parser.EscapeQuerySyntax.Type;
+import org.apache.lucene.queryparser.flexible.standard.config.PointsConfig;
+
+/**
+ * This query node represents a field query that holds a point value. It is
+ * similar to {@link FieldQueryNode}, however the {@link #getValue()} returns a
+ * {@link Number}.
+ *
+ * @see PointsConfig
+ */
+public class PointQueryNode extends QueryNodeImpl implements
+ FieldValuePairQueryNode<Number> {
+
+ private NumberFormat numberFormat;
+
+ private CharSequence field;
+
+ private Number value;
+
+ /**
+ * Creates a {@link PointQueryNode} object using the given field,
+ * {@link Number} value and {@link NumberFormat} used to convert the value to
+ * {@link String}.
+ *
+ * @param field the field associated with this query node
+ * @param value the value hold by this node
+ * @param numberFormat the {@link NumberFormat} used to convert the value to {@link String}
+ */
+ public PointQueryNode(CharSequence field, Number value,
+ NumberFormat numberFormat) {
+
+ super();
+
+ setNumberFormat(numberFormat);
+ setField(field);
+ setValue(value);
+
+ }
+
+ /**
+ * Returns the field associated with this node.
+ *
+ * @return the field associated with this node
+ */
+ @Override
+ public CharSequence getField() {
+ return this.field;
+ }
+
+ /**
+ * Sets the field associated with this node.
+ *
+ * @param fieldName the field associated with this node
+ */
+ @Override
+ public void setField(CharSequence fieldName) {
+ this.field = fieldName;
+ }
+
+ /**
+ * This method is used to get the value converted to {@link String} and
+ * escaped using the given {@link EscapeQuerySyntax}.
+ *
+ * @param escaper the {@link EscapeQuerySyntax} used to escape the value {@link String}
+ *
+ * @return the value converte to {@link String} and escaped
+ */
+ protected CharSequence getTermEscaped(EscapeQuerySyntax escaper) {
+ return escaper.escape(numberFormat.format(this.value),
+ Locale.ROOT, Type.NORMAL);
+ }
+
+ @Override
+ public CharSequence toQueryString(EscapeQuerySyntax escapeSyntaxParser) {
+ if (isDefaultField(this.field)) {
+ return getTermEscaped(escapeSyntaxParser);
+ } else {
+ return this.field + ":" + getTermEscaped(escapeSyntaxParser);
+ }
+ }
+
+ /**
+ * Sets the {@link NumberFormat} used to convert the value to {@link String}.
+ *
+ * @param format the {@link NumberFormat} used to convert the value to {@link String}
+ */
+ public void setNumberFormat(NumberFormat format) {
+ this.numberFormat = format;
+ }
+
+ /**
+ * Returns the {@link NumberFormat} used to convert the value to {@link String}.
+ *
+ * @return the {@link NumberFormat} used to convert the value to {@link String}
+ */
+ public NumberFormat getNumberFormat() {
+ return this.numberFormat;
+ }
+
+ /**
+ * Returns the numeric value as {@link Number}.
+ *
+ * @return the numeric value
+ */
+ @Override
+ public Number getValue() {
+ return value;
+ }
+
+ /**
+ * Sets the numeric value.
+ *
+ * @param value the numeric value
+ */
+ @Override
+ public void setValue(Number value) {
+ this.value = value;
+ }
+
+ @Override
+ public String toString() {
+ return "<numeric field='" + this.field + "' number='"
+ + numberFormat.format(value) + "'/>";
+ }
+
+}
[2/3] lucene-solr git commit: LUCENE-7089,
LUCENE-7075: add points to flexible queryparser to replace legacy
numerics support
Posted by rm...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/nodes/PointRangeQueryNode.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/nodes/PointRangeQueryNode.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/nodes/PointRangeQueryNode.java
new file mode 100644
index 0000000..cb838fc
--- /dev/null
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/nodes/PointRangeQueryNode.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.queryparser.flexible.standard.nodes;
+
+import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
+import org.apache.lucene.queryparser.flexible.standard.config.PointsConfig;
+
+/**
+ * This query node represents a range query composed by {@link PointQueryNode}
+ * bounds, which means the bound values are {@link Number}s.
+ *
+ * @see PointQueryNode
+ * @see AbstractRangeQueryNode
+ */
+public class PointRangeQueryNode extends AbstractRangeQueryNode<PointQueryNode> {
+
+ public PointsConfig numericConfig;
+
+ /**
+ * Constructs a {@link PointRangeQueryNode} object using the given
+ * {@link PointQueryNode} as its bounds and {@link PointsConfig}.
+ *
+ * @param lower the lower bound
+ * @param upper the upper bound
+ * @param lowerInclusive <code>true</code> if the lower bound is inclusive, otherwise, <code>false</code>
+ * @param upperInclusive <code>true</code> if the upper bound is inclusive, otherwise, <code>false</code>
+ * @param numericConfig the {@link PointsConfig} that represents associated with the upper and lower bounds
+ *
+ * @see #setBounds(PointQueryNode, PointQueryNode, boolean, boolean, PointsConfig)
+ */
+ public PointRangeQueryNode(PointQueryNode lower, PointQueryNode upper,
+ boolean lowerInclusive, boolean upperInclusive, PointsConfig numericConfig) throws QueryNodeException {
+ setBounds(lower, upper, lowerInclusive, upperInclusive, numericConfig);
+ }
+
+ /**
+ * Sets the upper and lower bounds of this range query node and the
+ * {@link PointsConfig} associated with these bounds.
+ *
+ * @param lower the lower bound
+ * @param upper the upper bound
+ * @param lowerInclusive <code>true</code> if the lower bound is inclusive, otherwise, <code>false</code>
+ * @param upperInclusive <code>true</code> if the upper bound is inclusive, otherwise, <code>false</code>
+ * @param pointsConfig the {@link PointsConfig} that represents associated with the upper and lower bounds
+ *
+ */
+ public void setBounds(PointQueryNode lower, PointQueryNode upper,
+ boolean lowerInclusive, boolean upperInclusive, PointsConfig pointsConfig) throws QueryNodeException {
+
+ if (pointsConfig == null) {
+ throw new IllegalArgumentException("pointsConfig cannot be null!");
+ }
+
+ Class<? extends Number> lowerNumberType, upperNumberType;
+
+ if (lower != null && lower.getValue() != null) {
+ lowerNumberType = lower.getValue().getClass();
+ } else {
+ lowerNumberType = null;
+ }
+
+ if (upper != null && upper.getValue() != null) {
+ upperNumberType = upper.getValue().getClass();
+ } else {
+ upperNumberType = null;
+ }
+
+ if (lowerNumberType != null
+ && !lowerNumberType.equals(pointsConfig.getType())) {
+ throw new IllegalArgumentException(
+ "lower value's type should be the same as numericConfig type: "
+ + lowerNumberType + " != " + pointsConfig.getType());
+ }
+
+ if (upperNumberType != null
+ && !upperNumberType.equals(pointsConfig.getType())) {
+ throw new IllegalArgumentException(
+ "upper value's type should be the same as numericConfig type: "
+ + upperNumberType + " != " + pointsConfig.getType());
+ }
+
+ super.setBounds(lower, upper, lowerInclusive, upperInclusive);
+ this.numericConfig = pointsConfig;
+ }
+
+ /**
+ * Returns the {@link PointsConfig} associated with the lower and upper bounds.
+ *
+ * @return the {@link PointsConfig} associated with the lower and upper bounds
+ */
+ public PointsConfig getPointsConfig() {
+ return this.numericConfig;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("<pointRange lowerInclusive='");
+ sb.append(isLowerInclusive());
+ sb.append("' upperInclusive='");
+ sb.append(isUpperInclusive());
+ sb.append("' type='");
+ sb.append(numericConfig.getType().getSimpleName());
+ sb.append("'>\n");
+ sb.append(getLowerBound()).append('\n');
+ sb.append(getUpperBound()).append('\n');
+ sb.append("</pointRange>");
+ return sb.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/LegacyNumericQueryNodeProcessor.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/LegacyNumericQueryNodeProcessor.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/LegacyNumericQueryNodeProcessor.java
new file mode 100644
index 0000000..8b71824
--- /dev/null
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/LegacyNumericQueryNodeProcessor.java
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.queryparser.flexible.standard.processors;
+
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.util.List;
+
+import org.apache.lucene.queryparser.flexible.messages.MessageImpl;
+import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
+import org.apache.lucene.queryparser.flexible.core.QueryNodeParseException;
+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.QueryNode;
+import org.apache.lucene.queryparser.flexible.core.nodes.RangeQueryNode;
+import org.apache.lucene.queryparser.flexible.core.processors.QueryNodeProcessorImpl;
+import org.apache.lucene.queryparser.flexible.standard.config.LegacyNumericConfig;
+import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler.ConfigurationKeys;
+import org.apache.lucene.queryparser.flexible.standard.nodes.LegacyNumericQueryNode;
+import org.apache.lucene.queryparser.flexible.standard.nodes.LegacyNumericRangeQueryNode;
+
+/**
+ * This processor is used to convert {@link FieldQueryNode}s to
+ * {@link LegacyNumericRangeQueryNode}s. It looks for
+ * {@link ConfigurationKeys#LEGACY_NUMERIC_CONFIG} set in the {@link FieldConfig} of
+ * every {@link FieldQueryNode} found. If
+ * {@link ConfigurationKeys#LEGACY_NUMERIC_CONFIG} is found, it considers that
+ * {@link FieldQueryNode} to be a numeric query and convert it to
+ * {@link LegacyNumericRangeQueryNode} with upper and lower inclusive and lower and
+ * upper equals to the value represented by the {@link FieldQueryNode} converted
+ * to {@link Number}. It means that <b>field:1</b> is converted to <b>field:[1
+ * TO 1]</b>. <br>
+ * <br>
+ * Note that {@link FieldQueryNode}s children of a
+ * {@link RangeQueryNode} are ignored.
+ *
+ * @see ConfigurationKeys#LEGACY_NUMERIC_CONFIG
+ * @see FieldQueryNode
+ * @see LegacyNumericConfig
+ * @see LegacyNumericQueryNode
+ * @deprecated Index with points and use {@link PointQueryNodeProcessor} instead.
+ */
+@Deprecated
+public class LegacyNumericQueryNodeProcessor extends QueryNodeProcessorImpl {
+
+ /**
+ * Constructs a {@link LegacyNumericQueryNodeProcessor} object.
+ */
+ public LegacyNumericQueryNodeProcessor() {
+ // empty constructor
+ }
+
+ @Override
+ protected QueryNode postProcessNode(QueryNode node) throws QueryNodeException {
+
+ if (node instanceof FieldQueryNode
+ && !(node.getParent() instanceof RangeQueryNode)) {
+
+ QueryConfigHandler config = getQueryConfigHandler();
+
+ if (config != null) {
+ FieldQueryNode fieldNode = (FieldQueryNode) node;
+ FieldConfig fieldConfig = config.getFieldConfig(fieldNode
+ .getFieldAsString());
+
+ if (fieldConfig != null) {
+ LegacyNumericConfig numericConfig = fieldConfig
+ .get(ConfigurationKeys.LEGACY_NUMERIC_CONFIG);
+
+ if (numericConfig != null) {
+
+ NumberFormat numberFormat = numericConfig.getNumberFormat();
+ String text = fieldNode.getTextAsString();
+ Number number = null;
+
+ 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();
+ }
+
+ } else {
+ throw new QueryNodeParseException(new MessageImpl(
+ QueryParserMessages.NUMERIC_CANNOT_BE_EMPTY, fieldNode.getFieldAsString()));
+ }
+
+ LegacyNumericQueryNode lowerNode = new LegacyNumericQueryNode(fieldNode
+ .getField(), number, numberFormat);
+ LegacyNumericQueryNode upperNode = new LegacyNumericQueryNode(fieldNode
+ .getField(), number, numberFormat);
+
+ return new LegacyNumericRangeQueryNode(lowerNode, upperNode, true, true,
+ numericConfig);
+
+ }
+
+ }
+
+ }
+
+ }
+
+ return node;
+
+ }
+
+ @Override
+ protected QueryNode preProcessNode(QueryNode node) throws QueryNodeException {
+ return node;
+ }
+
+ @Override
+ protected List<QueryNode> setChildrenOrder(List<QueryNode> children)
+ throws QueryNodeException {
+ return children;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/LegacyNumericRangeQueryNodeProcessor.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/LegacyNumericRangeQueryNodeProcessor.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/LegacyNumericRangeQueryNodeProcessor.java
new file mode 100644
index 0000000..5a54b7b
--- /dev/null
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/LegacyNumericRangeQueryNodeProcessor.java
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.queryparser.flexible.standard.processors;
+
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.util.List;
+
+import org.apache.lucene.queryparser.flexible.messages.MessageImpl;
+import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
+import org.apache.lucene.queryparser.flexible.core.QueryNodeParseException;
+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.QueryNode;
+import org.apache.lucene.queryparser.flexible.core.processors.QueryNodeProcessorImpl;
+import org.apache.lucene.queryparser.flexible.core.util.StringUtils;
+import org.apache.lucene.queryparser.flexible.standard.config.LegacyNumericConfig;
+import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler.ConfigurationKeys;
+import org.apache.lucene.queryparser.flexible.standard.nodes.LegacyNumericQueryNode;
+import org.apache.lucene.queryparser.flexible.standard.nodes.LegacyNumericRangeQueryNode;
+import org.apache.lucene.queryparser.flexible.standard.nodes.TermRangeQueryNode;
+
+/**
+ * This processor is used to convert {@link TermRangeQueryNode}s to
+ * {@link LegacyNumericRangeQueryNode}s. It looks for
+ * {@link ConfigurationKeys#LEGACY_NUMERIC_CONFIG} set in the {@link FieldConfig} of
+ * every {@link TermRangeQueryNode} found. If
+ * {@link ConfigurationKeys#LEGACY_NUMERIC_CONFIG} is found, it considers that
+ * {@link TermRangeQueryNode} to be a numeric range query and convert it to
+ * {@link LegacyNumericRangeQueryNode}.
+ *
+ * @see ConfigurationKeys#LEGACY_NUMERIC_CONFIG
+ * @see TermRangeQueryNode
+ * @see LegacyNumericConfig
+ * @see LegacyNumericRangeQueryNode
+ * @deprecated Index with points and use {@link PointRangeQueryNodeProcessor} instead.
+ */
+@Deprecated
+public class LegacyNumericRangeQueryNodeProcessor extends QueryNodeProcessorImpl {
+
+ /**
+ * Constructs an empty {@link LegacyNumericRangeQueryNode} object.
+ */
+ public LegacyNumericRangeQueryNodeProcessor() {
+ // empty constructor
+ }
+
+ @Override
+ protected QueryNode postProcessNode(QueryNode node) throws QueryNodeException {
+
+ if (node instanceof TermRangeQueryNode) {
+ QueryConfigHandler config = getQueryConfigHandler();
+
+ if (config != null) {
+ TermRangeQueryNode termRangeNode = (TermRangeQueryNode) node;
+ FieldConfig fieldConfig = config.getFieldConfig(StringUtils
+ .toString(termRangeNode.getField()));
+
+ if (fieldConfig != null) {
+
+ LegacyNumericConfig numericConfig = fieldConfig
+ .get(ConfigurationKeys.LEGACY_NUMERIC_CONFIG);
+
+ if (numericConfig != null) {
+
+ FieldQueryNode lower = termRangeNode.getLowerBound();
+ FieldQueryNode upper = termRangeNode.getUpperBound();
+
+ String lowerText = lower.getTextAsString();
+ String upperText = upper.getTextAsString();
+ NumberFormat numberFormat = numericConfig.getNumberFormat();
+ Number lowerNumber = null, upperNumber = null;
+
+ 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);
+ }
+
+ }
+
+ 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:
+ if (upperNumber != null) upperNumber = upperNumber.longValue();
+ if (lowerNumber != null) lowerNumber = lowerNumber.longValue();
+ break;
+ case INT:
+ if (upperNumber != null) upperNumber = upperNumber.intValue();
+ if (lowerNumber != null) lowerNumber = lowerNumber.intValue();
+ break;
+ case DOUBLE:
+ if (upperNumber != null) upperNumber = upperNumber.doubleValue();
+ if (lowerNumber != null) lowerNumber = lowerNumber.doubleValue();
+ break;
+ case FLOAT:
+ if (upperNumber != null) upperNumber = upperNumber.floatValue();
+ if (lowerNumber != null) lowerNumber = lowerNumber.floatValue();
+ }
+
+ LegacyNumericQueryNode lowerNode = new LegacyNumericQueryNode(
+ termRangeNode.getField(), lowerNumber, numberFormat);
+ LegacyNumericQueryNode upperNode = new LegacyNumericQueryNode(
+ termRangeNode.getField(), upperNumber, numberFormat);
+
+ boolean lowerInclusive = termRangeNode.isLowerInclusive();
+ boolean upperInclusive = termRangeNode.isUpperInclusive();
+
+ return new LegacyNumericRangeQueryNode(lowerNode, upperNode,
+ lowerInclusive, upperInclusive, numericConfig);
+
+ }
+
+ }
+
+ }
+
+ }
+
+ return node;
+
+ }
+
+ @Override
+ protected QueryNode preProcessNode(QueryNode node) throws QueryNodeException {
+ return node;
+ }
+
+ @Override
+ protected List<QueryNode> setChildrenOrder(List<QueryNode> children)
+ throws QueryNodeException {
+ return children;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/NumericQueryNodeProcessor.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/NumericQueryNodeProcessor.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/NumericQueryNodeProcessor.java
deleted file mode 100644
index 10bd6ba..0000000
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/NumericQueryNodeProcessor.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.queryparser.flexible.standard.processors;
-
-import java.text.NumberFormat;
-import java.text.ParseException;
-import java.util.List;
-
-import org.apache.lucene.queryparser.flexible.messages.MessageImpl;
-import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
-import org.apache.lucene.queryparser.flexible.core.QueryNodeParseException;
-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.QueryNode;
-import org.apache.lucene.queryparser.flexible.core.nodes.RangeQueryNode;
-import org.apache.lucene.queryparser.flexible.core.processors.QueryNodeProcessorImpl;
-import org.apache.lucene.queryparser.flexible.standard.config.NumericConfig;
-import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler.ConfigurationKeys;
-import org.apache.lucene.queryparser.flexible.standard.nodes.NumericQueryNode;
-import org.apache.lucene.queryparser.flexible.standard.nodes.NumericRangeQueryNode;
-
-/**
- * This processor is used to convert {@link FieldQueryNode}s to
- * {@link NumericRangeQueryNode}s. It looks for
- * {@link ConfigurationKeys#NUMERIC_CONFIG} set in the {@link FieldConfig} of
- * every {@link FieldQueryNode} found. If
- * {@link ConfigurationKeys#NUMERIC_CONFIG} is found, it considers that
- * {@link FieldQueryNode} to be a numeric query and convert it to
- * {@link NumericRangeQueryNode} with upper and lower inclusive and lower and
- * upper equals to the value represented by the {@link FieldQueryNode} converted
- * to {@link Number}. It means that <b>field:1</b> is converted to <b>field:[1
- * TO 1]</b>. <br>
- * <br>
- * Note that {@link FieldQueryNode}s children of a
- * {@link RangeQueryNode} are ignored.
- *
- * @see ConfigurationKeys#NUMERIC_CONFIG
- * @see FieldQueryNode
- * @see NumericConfig
- * @see NumericQueryNode
- */
-public class NumericQueryNodeProcessor extends QueryNodeProcessorImpl {
-
- /**
- * Constructs a {@link NumericQueryNodeProcessor} object.
- */
- public NumericQueryNodeProcessor() {
- // empty constructor
- }
-
- @Override
- protected QueryNode postProcessNode(QueryNode node) throws QueryNodeException {
-
- if (node instanceof FieldQueryNode
- && !(node.getParent() instanceof RangeQueryNode)) {
-
- QueryConfigHandler config = getQueryConfigHandler();
-
- if (config != null) {
- FieldQueryNode fieldNode = (FieldQueryNode) node;
- FieldConfig fieldConfig = config.getFieldConfig(fieldNode
- .getFieldAsString());
-
- if (fieldConfig != null) {
- NumericConfig numericConfig = fieldConfig
- .get(ConfigurationKeys.NUMERIC_CONFIG);
-
- if (numericConfig != null) {
-
- NumberFormat numberFormat = numericConfig.getNumberFormat();
- String text = fieldNode.getTextAsString();
- Number number = null;
-
- 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();
- }
-
- } else {
- throw new QueryNodeParseException(new MessageImpl(
- QueryParserMessages.NUMERIC_CANNOT_BE_EMPTY, fieldNode.getFieldAsString()));
- }
-
- NumericQueryNode lowerNode = new NumericQueryNode(fieldNode
- .getField(), number, numberFormat);
- NumericQueryNode upperNode = new NumericQueryNode(fieldNode
- .getField(), number, numberFormat);
-
- return new NumericRangeQueryNode(lowerNode, upperNode, true, true,
- numericConfig);
-
- }
-
- }
-
- }
-
- }
-
- return node;
-
- }
-
- @Override
- protected QueryNode preProcessNode(QueryNode node) throws QueryNodeException {
- return node;
- }
-
- @Override
- protected List<QueryNode> setChildrenOrder(List<QueryNode> children)
- throws QueryNodeException {
- return children;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/NumericRangeQueryNodeProcessor.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/NumericRangeQueryNodeProcessor.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/NumericRangeQueryNodeProcessor.java
deleted file mode 100644
index bbe5284..0000000
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/NumericRangeQueryNodeProcessor.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.queryparser.flexible.standard.processors;
-
-import java.text.NumberFormat;
-import java.text.ParseException;
-import java.util.List;
-
-import org.apache.lucene.queryparser.flexible.messages.MessageImpl;
-import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
-import org.apache.lucene.queryparser.flexible.core.QueryNodeParseException;
-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.QueryNode;
-import org.apache.lucene.queryparser.flexible.core.processors.QueryNodeProcessorImpl;
-import org.apache.lucene.queryparser.flexible.core.util.StringUtils;
-import org.apache.lucene.queryparser.flexible.standard.config.NumericConfig;
-import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler.ConfigurationKeys;
-import org.apache.lucene.queryparser.flexible.standard.nodes.NumericQueryNode;
-import org.apache.lucene.queryparser.flexible.standard.nodes.NumericRangeQueryNode;
-import org.apache.lucene.queryparser.flexible.standard.nodes.TermRangeQueryNode;
-
-/**
- * This processor is used to convert {@link TermRangeQueryNode}s to
- * {@link NumericRangeQueryNode}s. It looks for
- * {@link ConfigurationKeys#NUMERIC_CONFIG} set in the {@link FieldConfig} of
- * every {@link TermRangeQueryNode} found. If
- * {@link ConfigurationKeys#NUMERIC_CONFIG} is found, it considers that
- * {@link TermRangeQueryNode} to be a numeric range query and convert it to
- * {@link NumericRangeQueryNode}.
- *
- * @see ConfigurationKeys#NUMERIC_CONFIG
- * @see TermRangeQueryNode
- * @see NumericConfig
- * @see NumericRangeQueryNode
- */
-public class NumericRangeQueryNodeProcessor extends QueryNodeProcessorImpl {
-
- /**
- * Constructs an empty {@link NumericRangeQueryNode} object.
- */
- public NumericRangeQueryNodeProcessor() {
- // empty constructor
- }
-
- @Override
- protected QueryNode postProcessNode(QueryNode node) throws QueryNodeException {
-
- if (node instanceof TermRangeQueryNode) {
- QueryConfigHandler config = getQueryConfigHandler();
-
- if (config != null) {
- TermRangeQueryNode termRangeNode = (TermRangeQueryNode) node;
- FieldConfig fieldConfig = config.getFieldConfig(StringUtils
- .toString(termRangeNode.getField()));
-
- if (fieldConfig != null) {
-
- NumericConfig numericConfig = fieldConfig
- .get(ConfigurationKeys.NUMERIC_CONFIG);
-
- if (numericConfig != null) {
-
- FieldQueryNode lower = termRangeNode.getLowerBound();
- FieldQueryNode upper = termRangeNode.getUpperBound();
-
- String lowerText = lower.getTextAsString();
- String upperText = upper.getTextAsString();
- NumberFormat numberFormat = numericConfig.getNumberFormat();
- Number lowerNumber = null, upperNumber = null;
-
- 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);
- }
-
- }
-
- 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:
- if (upperNumber != null) upperNumber = upperNumber.longValue();
- if (lowerNumber != null) lowerNumber = lowerNumber.longValue();
- break;
- case INT:
- if (upperNumber != null) upperNumber = upperNumber.intValue();
- if (lowerNumber != null) lowerNumber = lowerNumber.intValue();
- break;
- case DOUBLE:
- if (upperNumber != null) upperNumber = upperNumber.doubleValue();
- if (lowerNumber != null) lowerNumber = lowerNumber.doubleValue();
- break;
- case FLOAT:
- if (upperNumber != null) upperNumber = upperNumber.floatValue();
- if (lowerNumber != null) lowerNumber = lowerNumber.floatValue();
- }
-
- NumericQueryNode lowerNode = new NumericQueryNode(
- termRangeNode.getField(), lowerNumber, numberFormat);
- NumericQueryNode upperNode = new NumericQueryNode(
- termRangeNode.getField(), upperNumber, numberFormat);
-
- boolean lowerInclusive = termRangeNode.isLowerInclusive();
- boolean upperInclusive = termRangeNode.isUpperInclusive();
-
- return new NumericRangeQueryNode(lowerNode, upperNode,
- lowerInclusive, upperInclusive, numericConfig);
-
- }
-
- }
-
- }
-
- }
-
- return node;
-
- }
-
- @Override
- protected QueryNode preProcessNode(QueryNode node) throws QueryNodeException {
- return node;
- }
-
- @Override
- protected List<QueryNode> setChildrenOrder(List<QueryNode> children)
- throws QueryNodeException {
- return children;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/PointQueryNodeProcessor.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/PointQueryNodeProcessor.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/PointQueryNodeProcessor.java
new file mode 100644
index 0000000..81a8449
--- /dev/null
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/PointQueryNodeProcessor.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.queryparser.flexible.standard.processors;
+
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.util.List;
+
+import org.apache.lucene.queryparser.flexible.messages.MessageImpl;
+import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
+import org.apache.lucene.queryparser.flexible.core.QueryNodeParseException;
+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.QueryNode;
+import org.apache.lucene.queryparser.flexible.core.nodes.RangeQueryNode;
+import org.apache.lucene.queryparser.flexible.core.processors.QueryNodeProcessorImpl;
+import org.apache.lucene.queryparser.flexible.standard.config.PointsConfig;
+import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler.ConfigurationKeys;
+import org.apache.lucene.queryparser.flexible.standard.nodes.PointQueryNode;
+import org.apache.lucene.queryparser.flexible.standard.nodes.PointRangeQueryNode;
+
+/**
+ * This processor is used to convert {@link FieldQueryNode}s to
+ * {@link PointRangeQueryNode}s. It looks for
+ * {@link ConfigurationKeys#POINTS_CONFIG} set in the {@link FieldConfig} of
+ * every {@link FieldQueryNode} found. If
+ * {@link ConfigurationKeys#POINTS_CONFIG} is found, it considers that
+ * {@link FieldQueryNode} to be a numeric query and convert it to
+ * {@link PointRangeQueryNode} with upper and lower inclusive and lower and
+ * upper equals to the value represented by the {@link FieldQueryNode} converted
+ * to {@link Number}. It means that <b>field:1</b> is converted to <b>field:[1
+ * TO 1]</b>. <br>
+ * <br>
+ * Note that {@link FieldQueryNode}s children of a
+ * {@link RangeQueryNode} are ignored.
+ *
+ * @see ConfigurationKeys#POINTS_CONFIG
+ * @see FieldQueryNode
+ * @see PointsConfig
+ * @see PointQueryNode
+ */
+public class PointQueryNodeProcessor extends QueryNodeProcessorImpl {
+
+ /**
+ * Constructs a {@link PointQueryNodeProcessor} object.
+ */
+ public PointQueryNodeProcessor() {
+ // empty constructor
+ }
+
+ @Override
+ protected QueryNode postProcessNode(QueryNode node) throws QueryNodeException {
+
+ if (node instanceof FieldQueryNode
+ && !(node.getParent() instanceof RangeQueryNode)) {
+
+ QueryConfigHandler config = getQueryConfigHandler();
+
+ if (config != null) {
+ FieldQueryNode fieldNode = (FieldQueryNode) node;
+ FieldConfig fieldConfig = config.getFieldConfig(fieldNode
+ .getFieldAsString());
+
+ if (fieldConfig != null) {
+ PointsConfig numericConfig = fieldConfig.get(ConfigurationKeys.POINTS_CONFIG);
+
+ if (numericConfig != null) {
+
+ NumberFormat numberFormat = numericConfig.getNumberFormat();
+ String text = fieldNode.getTextAsString();
+ Number number = null;
+
+ 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);
+ }
+
+ if (Integer.class.equals(numericConfig.getType())) {
+ number = number.intValue();
+ } else if (Long.class.equals(numericConfig.getType())) {
+ number = number.longValue();
+ } else if (Double.class.equals(numericConfig.getType())) {
+ number = number.doubleValue();
+ } else if (Float.class.equals(numericConfig.getType())) {
+ number = number.floatValue();
+ }
+
+ } else {
+ throw new QueryNodeParseException(new MessageImpl(
+ QueryParserMessages.NUMERIC_CANNOT_BE_EMPTY, fieldNode.getFieldAsString()));
+ }
+
+ PointQueryNode lowerNode = new PointQueryNode(fieldNode.getField(), number, numberFormat);
+ PointQueryNode upperNode = new PointQueryNode(fieldNode.getField(), number, numberFormat);
+
+ return new PointRangeQueryNode(lowerNode, upperNode, true, true, numericConfig);
+ }
+ }
+ }
+ }
+ return node;
+ }
+
+ @Override
+ protected QueryNode preProcessNode(QueryNode node) throws QueryNodeException {
+ return node;
+ }
+
+ @Override
+ protected List<QueryNode> setChildrenOrder(List<QueryNode> children) throws QueryNodeException {
+ return children;
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/PointRangeQueryNodeProcessor.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/PointRangeQueryNodeProcessor.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/PointRangeQueryNodeProcessor.java
new file mode 100644
index 0000000..2ffc437
--- /dev/null
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/PointRangeQueryNodeProcessor.java
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.queryparser.flexible.standard.processors;
+
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.util.List;
+
+import org.apache.lucene.queryparser.flexible.messages.MessageImpl;
+import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
+import org.apache.lucene.queryparser.flexible.core.QueryNodeParseException;
+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.QueryNode;
+import org.apache.lucene.queryparser.flexible.core.processors.QueryNodeProcessorImpl;
+import org.apache.lucene.queryparser.flexible.core.util.StringUtils;
+import org.apache.lucene.queryparser.flexible.standard.config.PointsConfig;
+import org.apache.lucene.queryparser.flexible.standard.config.StandardQueryConfigHandler.ConfigurationKeys;
+import org.apache.lucene.queryparser.flexible.standard.nodes.PointQueryNode;
+import org.apache.lucene.queryparser.flexible.standard.nodes.PointRangeQueryNode;
+import org.apache.lucene.queryparser.flexible.standard.nodes.TermRangeQueryNode;
+
+/**
+ * This processor is used to convert {@link TermRangeQueryNode}s to
+ * {@link PointRangeQueryNode}s. It looks for
+ * {@link ConfigurationKeys#POINTS_CONFIG} set in the {@link FieldConfig} of
+ * every {@link TermRangeQueryNode} found. If
+ * {@link ConfigurationKeys#POINTS_CONFIG} is found, it considers that
+ * {@link TermRangeQueryNode} to be a numeric range query and convert it to
+ * {@link PointRangeQueryNode}.
+ *
+ * @see ConfigurationKeys#POINTS_CONFIG
+ * @see TermRangeQueryNode
+ * @see PointsConfig
+ * @see PointRangeQueryNode
+ */
+public class PointRangeQueryNodeProcessor extends QueryNodeProcessorImpl {
+
+ /**
+ * Constructs an empty {@link PointRangeQueryNodeProcessor} object.
+ */
+ public PointRangeQueryNodeProcessor() {
+ // empty constructor
+ }
+
+ @Override
+ protected QueryNode postProcessNode(QueryNode node) throws QueryNodeException {
+
+ if (node instanceof TermRangeQueryNode) {
+ QueryConfigHandler config = getQueryConfigHandler();
+
+ if (config != null) {
+ TermRangeQueryNode termRangeNode = (TermRangeQueryNode) node;
+ FieldConfig fieldConfig = config.getFieldConfig(StringUtils.toString(termRangeNode.getField()));
+
+ if (fieldConfig != null) {
+ PointsConfig numericConfig = fieldConfig.get(ConfigurationKeys.POINTS_CONFIG);
+
+ if (numericConfig != null) {
+ FieldQueryNode lower = termRangeNode.getLowerBound();
+ FieldQueryNode upper = termRangeNode.getUpperBound();
+
+ String lowerText = lower.getTextAsString();
+ String upperText = upper.getTextAsString();
+ NumberFormat numberFormat = numericConfig.getNumberFormat();
+ Number lowerNumber = null, upperNumber = null;
+
+ 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);
+ }
+
+ }
+
+ 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);
+ }
+ }
+
+ if (Integer.class.equals(numericConfig.getType())) {
+ if (upperNumber != null) upperNumber = upperNumber.intValue();
+ if (lowerNumber != null) lowerNumber = lowerNumber.intValue();
+ } else if (Long.class.equals(numericConfig.getType())) {
+ if (upperNumber != null) upperNumber = upperNumber.longValue();
+ if (lowerNumber != null) lowerNumber = lowerNumber.longValue();
+ } else if (Double.class.equals(numericConfig.getType())) {
+ if (upperNumber != null) upperNumber = upperNumber.doubleValue();
+ if (lowerNumber != null) lowerNumber = lowerNumber.doubleValue();
+ } else if (Float.class.equals(numericConfig.getType())) {
+ if (upperNumber != null) upperNumber = upperNumber.floatValue();
+ if (lowerNumber != null) lowerNumber = lowerNumber.floatValue();
+ }
+
+ PointQueryNode lowerNode = new PointQueryNode(termRangeNode.getField(), lowerNumber, numberFormat);
+ PointQueryNode upperNode = new PointQueryNode(termRangeNode.getField(), upperNumber, numberFormat);
+
+ boolean lowerInclusive = termRangeNode.isLowerInclusive();
+ boolean upperInclusive = termRangeNode.isUpperInclusive();
+
+ return new PointRangeQueryNode(lowerNode, upperNode, lowerInclusive, upperInclusive, numericConfig);
+ }
+ }
+ }
+ }
+ return node;
+ }
+
+ @Override
+ protected QueryNode preProcessNode(QueryNode node) throws QueryNodeException {
+ return node;
+ }
+
+ @Override
+ protected List<QueryNode> setChildrenOrder(List<QueryNode> children) throws QueryNodeException {
+ return children;
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/StandardQueryNodeProcessorPipeline.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/StandardQueryNodeProcessorPipeline.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/StandardQueryNodeProcessorPipeline.java
index 06f38c2..6e4a394 100644
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/StandardQueryNodeProcessorPipeline.java
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/flexible/standard/processors/StandardQueryNodeProcessorPipeline.java
@@ -55,8 +55,10 @@ public class StandardQueryNodeProcessorPipeline extends
add(new FuzzyQueryNodeProcessor());
add(new MatchAllDocsQueryNodeProcessor());
add(new OpenRangeQueryNodeProcessor());
- add(new NumericQueryNodeProcessor());
- add(new NumericRangeQueryNodeProcessor());
+ add(new LegacyNumericQueryNodeProcessor());
+ add(new LegacyNumericRangeQueryNodeProcessor());
+ add(new PointQueryNodeProcessor());
+ add(new PointRangeQueryNodeProcessor());
add(new LowercaseExpandedTermsQueryNodeProcessor());
add(new TermRangeQueryNodeProcessor());
add(new AllowLeadingWildcardProcessor());
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/89cc676f/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestLegacyNumericQueryParser.java
----------------------------------------------------------------------
diff --git a/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestLegacyNumericQueryParser.java b/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestLegacyNumericQueryParser.java
new file mode 100644
index 0000000..c6ab7f5
--- /dev/null
+++ b/lucene/queryparser/src/test/org/apache/lucene/queryparser/flexible/standard/TestLegacyNumericQueryParser.java
@@ -0,0 +1,535 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.queryparser.flexible.standard;
+
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Random;
+import java.util.TimeZone;
+
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.LegacyDoubleField;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.FieldType.LegacyNumericType;
+import org.apache.lucene.document.FieldType;
+import org.apache.lucene.document.LegacyFloatField;
+import org.apache.lucene.document.LegacyIntField;
+import org.apache.lucene.document.LegacyLongField;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.RandomIndexWriter;
+import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
+import org.apache.lucene.queryparser.flexible.core.parser.EscapeQuerySyntax;
+import org.apache.lucene.queryparser.flexible.standard.config.NumberDateFormat;
+import org.apache.lucene.queryparser.flexible.standard.config.LegacyNumericConfig;
+import org.apache.lucene.queryparser.flexible.standard.parser.EscapeQuerySyntaxImpl;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.TopDocs;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.TestUtil;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class TestLegacyNumericQueryParser extends LuceneTestCase {
+
+ private static enum NumberType {
+ NEGATIVE, ZERO, POSITIVE;
+ }
+
+ final private static int[] DATE_STYLES = {DateFormat.FULL, DateFormat.LONG,
+ DateFormat.MEDIUM, DateFormat.SHORT};
+
+ final private static int PRECISION_STEP = 8;
+ final private static String FIELD_NAME = "field";
+ private static Locale LOCALE;
+ private static TimeZone TIMEZONE;
+ private static Map<String,Number> RANDOM_NUMBER_MAP;
+ private static EscapeQuerySyntax ESCAPER = new EscapeQuerySyntaxImpl();
+ final private static String DATE_FIELD_NAME = "date";
+ private static int DATE_STYLE;
+ private static int TIME_STYLE;
+
+ private static Analyzer ANALYZER;
+
+ private static NumberFormat NUMBER_FORMAT;
+
+ private static StandardQueryParser qp;
+
+ private static NumberDateFormat DATE_FORMAT;
+
+ private static Directory directory = null;
+ private static IndexReader reader = null;
+ private static IndexSearcher searcher = null;
+
+ private static boolean checkDateFormatSanity(DateFormat dateFormat, long date) {
+ try {
+ return date == dateFormat.parse(dateFormat.format(new Date(date)))
+ .getTime();
+ } catch (ParseException e) {
+ return false;
+ }
+ }
+
+ @BeforeClass
+ public static void beforeClass() throws Exception {
+ ANALYZER = new MockAnalyzer(random());
+
+ qp = new StandardQueryParser(ANALYZER);
+
+ final HashMap<String,Number> randomNumberMap = new HashMap<>();
+
+ SimpleDateFormat dateFormat;
+ long randomDate;
+ boolean dateFormatSanityCheckPass;
+ int count = 0;
+ do {
+ if (count > 100) {
+ fail("This test has problems to find a sane random DateFormat/NumberFormat. Stopped trying after 100 iterations.");
+ }
+
+ dateFormatSanityCheckPass = true;
+ LOCALE = randomLocale(random());
+ TIMEZONE = randomTimeZone(random());
+ DATE_STYLE = randomDateStyle(random());
+ TIME_STYLE = randomDateStyle(random());
+
+ // assumes localized date pattern will have at least year, month, day,
+ // hour, minute
+ 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
+ dateFormat.applyPattern(dateFormat.toPattern() + " G s Z yyyy");
+ dateFormat.setTimeZone(TIMEZONE);
+
+ DATE_FORMAT = new NumberDateFormat(dateFormat);
+
+ do {
+ randomDate = random().nextLong();
+
+ // prune date value so it doesn't pass in insane values to some
+ // calendars.
+ randomDate = randomDate % 3400000000000l;
+
+ // truncate to second
+ randomDate = (randomDate / 1000L) * 1000L;
+
+ // only positive values
+ randomDate = Math.abs(randomDate);
+ } while (randomDate == 0L);
+
+ dateFormatSanityCheckPass &= checkDateFormatSanity(dateFormat, randomDate);
+
+ dateFormatSanityCheckPass &= checkDateFormatSanity(dateFormat, 0);
+
+ dateFormatSanityCheckPass &= checkDateFormatSanity(dateFormat,
+ -randomDate);
+
+ count++;
+ } while (!dateFormatSanityCheckPass);
+
+ NUMBER_FORMAT = NumberFormat.getNumberInstance(LOCALE);
+ NUMBER_FORMAT.setMaximumFractionDigits((random().nextInt() & 20) + 1);
+ 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;
+ float randomFloat;
+
+ while ((randomLong = normalizeNumber(Math.abs(random().nextLong()))
+ .longValue()) == 0L)
+ ;
+ while ((randomDouble = normalizeNumber(Math.abs(random().nextDouble()))
+ .doubleValue()) == 0.0)
+ ;
+ while ((randomFloat = normalizeNumber(Math.abs(random().nextFloat()))
+ .floatValue()) == 0.0f)
+ ;
+ while ((randomInt = normalizeNumber(Math.abs(random().nextInt())).intValue()) == 0)
+ ;
+
+ randomNumberMap.put(LegacyNumericType.LONG.name(), randomLong);
+ randomNumberMap.put(FieldType.LegacyNumericType.INT.name(), randomInt);
+ randomNumberMap.put(LegacyNumericType.FLOAT.name(), randomFloat);
+ randomNumberMap.put(LegacyNumericType.DOUBLE.name(), randomDouble);
+ randomNumberMap.put(DATE_FIELD_NAME, randomDate);
+
+ RANDOM_NUMBER_MAP = Collections.unmodifiableMap(randomNumberMap);
+
+ directory = newDirectory();
+ RandomIndexWriter writer = new RandomIndexWriter(random(), directory,
+ newIndexWriterConfig(new MockAnalyzer(random()))
+ .setMaxBufferedDocs(TestUtil.nextInt(random(), 50, 1000))
+ .setMergePolicy(newLogMergePolicy()));
+
+ Document doc = new Document();
+ HashMap<String,LegacyNumericConfig> numericConfigMap = new HashMap<>();
+ HashMap<String,Field> numericFieldMap = new HashMap<>();
+ qp.setLegacyNumericConfigMap(numericConfigMap);
+
+ for (LegacyNumericType type : LegacyNumericType.values()) {
+ numericConfigMap.put(type.name(), new LegacyNumericConfig(PRECISION_STEP,
+ NUMBER_FORMAT, type));
+
+ FieldType ft = new FieldType(LegacyIntField.TYPE_NOT_STORED);
+ ft.setNumericType(type);
+ ft.setStored(true);
+ ft.setNumericPrecisionStep(PRECISION_STEP);
+ ft.freeze();
+ final Field field;
+
+ switch(type) {
+ case INT:
+ field = new LegacyIntField(type.name(), 0, ft);
+ break;
+ case FLOAT:
+ field = new LegacyFloatField(type.name(), 0.0f, ft);
+ break;
+ case LONG:
+ field = new LegacyLongField(type.name(), 0l, ft);
+ break;
+ case DOUBLE:
+ field = new LegacyDoubleField(type.name(), 0.0, ft);
+ break;
+ default:
+ fail();
+ field = null;
+ }
+ numericFieldMap.put(type.name(), field);
+ doc.add(field);
+ }
+
+ numericConfigMap.put(DATE_FIELD_NAME, new LegacyNumericConfig(PRECISION_STEP,
+ DATE_FORMAT, LegacyNumericType.LONG));
+ FieldType ft = new FieldType(LegacyLongField.TYPE_NOT_STORED);
+ ft.setStored(true);
+ ft.setNumericPrecisionStep(PRECISION_STEP);
+ LegacyLongField dateField = new LegacyLongField(DATE_FIELD_NAME, 0l, ft);
+ numericFieldMap.put(DATE_FIELD_NAME, dateField);
+ doc.add(dateField);
+
+ for (NumberType numberType : NumberType.values()) {
+ setFieldValues(numberType, numericFieldMap);
+ if (VERBOSE) System.out.println("Indexing document: " + doc);
+ writer.addDocument(doc);
+ }
+
+ 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:
+ return RANDOM_NUMBER_MAP.get(fieldName);
+
+ case NEGATIVE:
+ Number number = RANDOM_NUMBER_MAP.get(fieldName);
+
+ if (LegacyNumericType.LONG.name().equals(fieldName)
+ || DATE_FIELD_NAME.equals(fieldName)) {
+ number = -number.longValue();
+
+ } else if (FieldType.LegacyNumericType.DOUBLE.name().equals(fieldName)) {
+ number = -number.doubleValue();
+
+ } else if (FieldType.LegacyNumericType.FLOAT.name().equals(fieldName)) {
+ number = -number.floatValue();
+
+ } else if (LegacyNumericType.INT.name().equals(fieldName)) {
+ number = -number.intValue();
+
+ } else {
+ throw new IllegalArgumentException("field name not found: "
+ + fieldName);
+ }
+
+ return number;
+
+ default:
+ return 0;
+
+ }
+
+ }
+
+ private static void setFieldValues(NumberType numberType,
+ HashMap<String,Field> numericFieldMap) {
+
+ Number number = getNumberType(numberType, LegacyNumericType.DOUBLE
+ .name());
+ numericFieldMap.get(LegacyNumericType.DOUBLE.name()).setDoubleValue(
+ number.doubleValue());
+
+ number = getNumberType(numberType, FieldType.LegacyNumericType.INT.name());
+ numericFieldMap.get(FieldType.LegacyNumericType.INT.name()).setIntValue(
+ number.intValue());
+
+ number = getNumberType(numberType, LegacyNumericType.LONG.name());
+ numericFieldMap.get(FieldType.LegacyNumericType.LONG.name()).setLongValue(
+ number.longValue());
+
+ number = getNumberType(numberType, FieldType.LegacyNumericType.FLOAT.name());
+ numericFieldMap.get(FieldType.LegacyNumericType.FLOAT.name()).setFloatValue(
+ number.floatValue());
+
+ number = getNumberType(numberType, DATE_FIELD_NAME);
+ numericFieldMap.get(DATE_FIELD_NAME).setLongValue(number.longValue());
+ }
+
+ private static int randomDateStyle(Random random) {
+ return DATE_STYLES[random.nextInt(DATE_STYLES.length)];
+ }
+
+ @Test
+ public void testInclusiveNumericRange() throws Exception {
+ assertRangeQuery(NumberType.ZERO, NumberType.ZERO, true, true, 1);
+ assertRangeQuery(NumberType.ZERO, NumberType.POSITIVE, true, true, 2);
+ assertRangeQuery(NumberType.NEGATIVE, NumberType.ZERO, true, true, 2);
+ assertRangeQuery(NumberType.NEGATIVE, NumberType.POSITIVE, true, true, 3);
+ assertRangeQuery(NumberType.NEGATIVE, NumberType.NEGATIVE, true, true, 1);
+ }
+
+ @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, 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 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, 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 {
+ assertRangeQuery(NumberType.ZERO, NumberType.ZERO, false, false, 0);
+ assertRangeQuery(NumberType.ZERO, NumberType.POSITIVE, false, false, 0);
+ assertRangeQuery(NumberType.NEGATIVE, NumberType.ZERO, false, false, 0);
+ assertRangeQuery(NumberType.NEGATIVE, NumberType.POSITIVE, false, false, 1);
+ assertRangeQuery(NumberType.NEGATIVE, NumberType.NEGATIVE, false, false, 0);
+ }
+
+ @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);
+ assertSimpleQuery(NumberType.NEGATIVE, 1);
+ }
+
+ public void assertRangeQuery(NumberType lowerType, NumberType upperType,
+ boolean lowerInclusive, boolean upperInclusive, int expectedDocCount)
+ throws QueryNodeException, IOException {
+
+ StringBuilder sb = new StringBuilder();
+
+ String lowerInclusiveStr = (lowerInclusive ? "[" : "{");
+ String upperInclusiveStr = (upperInclusive ? "]" : "}");
+
+ for (LegacyNumericType type : LegacyNumericType.values()) {
+ String lowerStr = numberToString(getNumberType(lowerType, type.name()));
+ String upperStr = numberToString(getNumberType(upperType, type.name()));
+
+ sb.append("+").append(type.name()).append(':').append(lowerInclusiveStr)
+ .append('"').append(lowerStr).append("\" TO \"").append(upperStr)
+ .append('"').append(upperInclusiveStr).append(' ');
+ }
+
+ Number lowerDateNumber = getNumberType(lowerType, DATE_FIELD_NAME);
+ Number upperDateNumber = getNumberType(upperType, DATE_FIELD_NAME);
+ String lowerDateStr;
+ String upperDateStr;
+
+ 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(
+ upperInclusiveStr);
+
+ testQuery(sb.toString(), expectedDocCount);
+
+ }
+
+ public void assertOpenRangeQuery(NumberType boundType, String operator, int expectedDocCount)
+ throws QueryNodeException, IOException {
+
+ StringBuilder sb = new StringBuilder();
+
+ for (LegacyNumericType type : FieldType.LegacyNumericType.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();
+
+ for (LegacyNumericType type : LegacyNumericType.values()) {
+ String numberStr = numberToString(getNumberType(numberType, type.name()));
+ sb.append('+').append(type.name()).append(":\"").append(numberStr)
+ .append("\" ");
+ }
+
+ String dateStr = ESCAPER.escape(
+ DATE_FORMAT.format(new Date(getNumberType(numberType, DATE_FIELD_NAME)
+ .longValue())), LOCALE, EscapeQuerySyntax.Type.STRING).toString();
+
+ sb.append('+').append(DATE_FIELD_NAME).append(":\"").append(dateStr)
+ .append('"');
+
+ testQuery(sb.toString(), expectedDocCount);
+
+ }
+
+ private void testQuery(String queryStr, int expectedDocCount)
+ throws QueryNodeException, IOException {
+ if (VERBOSE) System.out.println("Parsing: " + queryStr);
+
+ Query query = qp.parse(queryStr, FIELD_NAME);
+ if (VERBOSE) System.out.println("Querying: " + query);
+ TopDocs topDocs = searcher.search(query, 1000);
+
+ String msg = "Query <" + queryStr + "> retrieved " + topDocs.totalHits
+ + " document(s), " + expectedDocCount + " document(s) expected.";
+
+ if (VERBOSE) System.out.println(msg);
+
+ assertEquals(msg, expectedDocCount, topDocs.totalHits);
+ }
+
+ private static String numberToString(Number number) {
+ return number == null ? "*" : ESCAPER.escape(NUMBER_FORMAT.format(number),
+ LOCALE, EscapeQuerySyntax.Type.STRING).toString();
+ }
+
+ private static Number normalizeNumber(Number number) throws ParseException {
+ return NUMBER_FORMAT.parse(NUMBER_FORMAT.format(number));
+ }
+
+ @AfterClass
+ public static void afterClass() throws Exception {
+ searcher = null;
+ reader.close();
+ reader = null;
+ directory.close();
+ directory = null;
+ qp = null;
+ LOCALE = null;
+ TIMEZONE = null;
+ NUMBER_FORMAT = null;
+ DATE_FORMAT = null;
+ ESCAPER = null;
+ }
+
+}