You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by kr...@apache.org on 2017/01/23 15:43:06 UTC

[28/39] lucene-solr:jira/solr-8593: SOLR-10011: Refactor PointField & TrieField to now have a common base class, NumericFieldType.

SOLR-10011: Refactor PointField & TrieField to now have a common base class, NumericFieldType.

  The TrieField.TrieTypes and PointField.PointTypes are now consolidated to NumericFieldType.NumberType. This
  refactoring also fixes a bug whereby PointFields were not using DocValues for range queries for
  indexed=false, docValues=true fields.


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/285a1013
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/285a1013
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/285a1013

Branch: refs/heads/jira/solr-8593
Commit: 285a1013ad04dd1cd5e5e41ffa93a87fe862c152
Parents: 49fa7b0
Author: Ishan Chattopadhyaya <is...@apache.org>
Authored: Sun Jan 22 04:27:11 2017 +0530
Committer: Ishan Chattopadhyaya <is...@apache.org>
Committed: Sun Jan 22 04:27:11 2017 +0530

----------------------------------------------------------------------
 solr/CHANGES.txt                                |   5 +
 .../apache/solr/schema/DoublePointField.java    |  11 +-
 .../org/apache/solr/schema/FloatPointField.java |  11 +-
 .../org/apache/solr/schema/IntPointField.java   |  10 +-
 .../org/apache/solr/schema/LongPointField.java  |  11 +-
 .../apache/solr/schema/NumericFieldType.java    | 151 ++++++++++++++++
 .../java/org/apache/solr/schema/PointField.java |  28 +--
 .../org/apache/solr/schema/TrieDateField.java   |   2 +-
 .../org/apache/solr/schema/TrieDoubleField.java |   2 +-
 .../java/org/apache/solr/schema/TrieField.java  | 179 +++----------------
 .../org/apache/solr/schema/TrieFloatField.java  |   2 +-
 .../org/apache/solr/schema/TrieIntField.java    |   2 +-
 .../org/apache/solr/schema/TrieLongField.java   |   2 +-
 .../apache/solr/search/SolrIndexSearcher.java   |   3 +-
 .../distributed/command/GroupConverter.java     |   2 +-
 .../solr/collection1/conf/schema-point.xml      |   4 +
 .../org/apache/solr/schema/TestPointFields.java |   8 +
 17 files changed, 239 insertions(+), 194 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 748125a..abd2983 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -80,6 +80,11 @@ Other Changes
 ----------------------
 * SOLR-8396: Add support for PointFields in Solr (Ishan Chattopadhyaya, Tom�s Fern�ndez L�bbe)
 
+* SOLR-10011: Refactor PointField & TrieField to now have a common base class, NumericFieldType. The
+  TrieField.TrieTypes and PointField.PointTypes are now consolidated to NumericFieldType.NumberType. This
+  refactoring also fixes a bug whereby PointFields were not using DocValues for range queries for
+  indexed=false, docValues=true fields.
+
 ==================  6.5.0 ==================
 
 Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release.

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/java/org/apache/solr/schema/DoublePointField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/DoublePointField.java b/solr/core/src/java/org/apache/solr/schema/DoublePointField.java
index c393dfe..b9a7311 100644
--- a/solr/core/src/java/org/apache/solr/schema/DoublePointField.java
+++ b/solr/core/src/java/org/apache/solr/schema/DoublePointField.java
@@ -45,6 +45,10 @@ public class DoublePointField extends PointField implements DoubleValueFieldType
 
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
+  public DoublePointField() {
+    type = NumberType.DOUBLE;
+  }
+
   @Override
   public Object toNativeType(Object val) {
     if (val == null) return null;
@@ -54,7 +58,7 @@ public class DoublePointField extends PointField implements DoubleValueFieldType
   }
 
   @Override
-  public Query getRangeQuery(QParser parser, SchemaField field, String min, String max, boolean minInclusive,
+  public Query getPointRangeQuery(QParser parser, SchemaField field, String min, String max, boolean minInclusive,
       boolean maxInclusive) {
     double actualMin, actualMax;
     if (min == null) {
@@ -179,9 +183,4 @@ public class DoublePointField extends PointField implements DoubleValueFieldType
   protected StoredField getStoredField(SchemaField sf, Object value) {
     return new StoredField(sf.getName(), (Double) this.toNativeType(value));
   }
-
-  @Override
-  public PointTypes getType() {
-    return PointTypes.DOUBLE;
-  }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/java/org/apache/solr/schema/FloatPointField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/FloatPointField.java b/solr/core/src/java/org/apache/solr/schema/FloatPointField.java
index 766c6e9..7b866fc 100644
--- a/solr/core/src/java/org/apache/solr/schema/FloatPointField.java
+++ b/solr/core/src/java/org/apache/solr/schema/FloatPointField.java
@@ -45,6 +45,10 @@ public class FloatPointField extends PointField implements FloatValueFieldType {
 
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
+  public FloatPointField() {
+    type = NumberType.FLOAT;
+  }
+
   @Override
   public Object toNativeType(Object val) {
     if (val == null) return null;
@@ -54,7 +58,7 @@ public class FloatPointField extends PointField implements FloatValueFieldType {
   }
 
   @Override
-  public Query getRangeQuery(QParser parser, SchemaField field, String min, String max, boolean minInclusive,
+  public Query getPointRangeQuery(QParser parser, SchemaField field, String min, String max, boolean minInclusive,
       boolean maxInclusive) {
     float actualMin, actualMax;
     if (min == null) {
@@ -179,9 +183,4 @@ public class FloatPointField extends PointField implements FloatValueFieldType {
   protected StoredField getStoredField(SchemaField sf, Object value) {
     return new StoredField(sf.getName(), (Float) this.toNativeType(value));
   }
-  
-  @Override
-  public PointTypes getType() {
-    return PointTypes.FLOAT;
-  }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/java/org/apache/solr/schema/IntPointField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/IntPointField.java b/solr/core/src/java/org/apache/solr/schema/IntPointField.java
index 2271282..3e74241 100644
--- a/solr/core/src/java/org/apache/solr/schema/IntPointField.java
+++ b/solr/core/src/java/org/apache/solr/schema/IntPointField.java
@@ -44,6 +44,10 @@ public class IntPointField extends PointField implements IntValueFieldType {
 
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
+  public IntPointField() {
+    type = NumberType.INTEGER;
+  }
+
   @Override
   public Object toNativeType(Object val) {
     if (val == null) return null;
@@ -58,7 +62,7 @@ public class IntPointField extends PointField implements IntValueFieldType {
   }
 
   @Override
-  public Query getRangeQuery(QParser parser, SchemaField field, String min, String max, boolean minInclusive,
+  public Query getPointRangeQuery(QParser parser, SchemaField field, String min, String max, boolean minInclusive,
       boolean maxInclusive) {
     int actualMin, actualMax;
     if (min == null) {
@@ -179,8 +183,4 @@ public class IntPointField extends PointField implements IntValueFieldType {
     return new StoredField(sf.getName(), (Integer) this.toNativeType(value));
   }
 
-  @Override
-  public PointTypes getType() {
-    return PointTypes.INTEGER;
-  }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/java/org/apache/solr/schema/LongPointField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/LongPointField.java b/solr/core/src/java/org/apache/solr/schema/LongPointField.java
index f3fca3c..80f3cf7 100644
--- a/solr/core/src/java/org/apache/solr/schema/LongPointField.java
+++ b/solr/core/src/java/org/apache/solr/schema/LongPointField.java
@@ -44,6 +44,10 @@ public class LongPointField extends PointField implements LongValueFieldType {
 
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
+  public LongPointField() {
+    type = NumberType.LONG;
+  }
+
   @Override
   public Object toNativeType(Object val) {
     if (val == null) return null;
@@ -58,7 +62,7 @@ public class LongPointField extends PointField implements LongValueFieldType {
   }
 
   @Override
-  public Query getRangeQuery(QParser parser, SchemaField field, String min, String max, boolean minInclusive,
+  public Query getPointRangeQuery(QParser parser, SchemaField field, String min, String max, boolean minInclusive,
       boolean maxInclusive) {
     long actualMin, actualMax;
     if (min == null) {
@@ -178,9 +182,4 @@ public class LongPointField extends PointField implements LongValueFieldType {
   protected StoredField getStoredField(SchemaField sf, Object value) {
     return new StoredField(sf.getName(), (Long) this.toNativeType(value));
   }
-
-  @Override
-  public PointTypes getType() {
-    return PointTypes.LONG;
-  }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/java/org/apache/solr/schema/NumericFieldType.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/NumericFieldType.java b/solr/core/src/java/org/apache/solr/schema/NumericFieldType.java
new file mode 100644
index 0000000..404693d
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/schema/NumericFieldType.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.solr.schema;
+
+import org.apache.lucene.document.NumericDocValuesField;
+import org.apache.lucene.queries.function.ValueSource;
+import org.apache.lucene.search.MatchNoDocsQuery;
+import org.apache.lucene.search.Query;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.search.FunctionRangeQuery;
+import org.apache.solr.search.QParser;
+import org.apache.solr.search.function.ValueSourceRangeFilter;
+import org.apache.solr.util.DateMathParser;
+
+public abstract class NumericFieldType extends PrimitiveFieldType {
+
+  public static enum NumberType {
+    INTEGER,
+    LONG,
+    FLOAT,
+    DOUBLE,
+    DATE
+  }
+
+  protected NumberType type;
+
+  /**
+   * @return the type of this field
+   */
+  final public NumberType getType() {
+    return type;
+  }
+
+  private static long FLOAT_NEGATIVE_INFINITY_BITS = (long)Float.floatToIntBits(Float.NEGATIVE_INFINITY);
+  private static long DOUBLE_NEGATIVE_INFINITY_BITS = Double.doubleToLongBits(Double.NEGATIVE_INFINITY);
+  private static long FLOAT_POSITIVE_INFINITY_BITS = (long)Float.floatToIntBits(Float.POSITIVE_INFINITY);
+  private static long DOUBLE_POSITIVE_INFINITY_BITS = Double.doubleToLongBits(Double.POSITIVE_INFINITY);
+  private static long FLOAT_MINUS_ZERO_BITS = (long)Float.floatToIntBits(-0f);
+  private static long DOUBLE_MINUS_ZERO_BITS = Double.doubleToLongBits(-0d);
+  private static long FLOAT_ZERO_BITS = (long)Float.floatToIntBits(0f);
+  private static long DOUBLE_ZERO_BITS = Double.doubleToLongBits(0d);
+
+  protected Query getDocValuesRangeQuery(QParser parser, SchemaField field, String min, String max,
+      boolean minInclusive, boolean maxInclusive) {
+    assert field.hasDocValues() && !field.multiValued();
+    
+    switch (getType()) {
+      case INTEGER:
+        return numericDocValuesRangeQuery(field.getName(),
+              min == null ? null : (long) Integer.parseInt(min),
+              max == null ? null : (long) Integer.parseInt(max),
+              minInclusive, maxInclusive);
+      case FLOAT:
+        return getRangeQueryForFloatDoubleDocValues(field, min, max, minInclusive, maxInclusive);
+      case LONG:
+        return numericDocValuesRangeQuery(field.getName(),
+              min == null ? null : Long.parseLong(min),
+              max == null ? null : Long.parseLong(max),
+              minInclusive, maxInclusive);
+      case DOUBLE:
+        return getRangeQueryForFloatDoubleDocValues(field, min, max, minInclusive, maxInclusive);
+      case DATE:
+        return numericDocValuesRangeQuery(field.getName(),
+              min == null ? null : DateMathParser.parseMath(null, min).getTime(),
+              max == null ? null : DateMathParser.parseMath(null, max).getTime(),
+              minInclusive, maxInclusive);
+      default:
+        throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Unknown type for point field");
+    }
+  }
+  
+  protected Query getRangeQueryForFloatDoubleDocValues(SchemaField sf, String min, String max, boolean minInclusive, boolean maxInclusive) {
+    Query query;
+    String fieldName = sf.getName();
+
+    Number minVal = min == null ? null : getType() == NumberType.FLOAT ? Float.parseFloat(min): Double.parseDouble(min);
+    Number maxVal = max == null ? null : getType() == NumberType.FLOAT ? Float.parseFloat(max): Double.parseDouble(max);
+    
+    Long minBits = 
+        min == null ? null : getType() == NumberType.FLOAT ? (long) Float.floatToIntBits(minVal.floatValue()): Double.doubleToLongBits(minVal.doubleValue());
+    Long maxBits = 
+        max == null ? null : getType() == NumberType.FLOAT ? (long) Float.floatToIntBits(maxVal.floatValue()): Double.doubleToLongBits(maxVal.doubleValue());
+    
+    long negativeInfinityBits = getType() == NumberType.FLOAT ? FLOAT_NEGATIVE_INFINITY_BITS : DOUBLE_NEGATIVE_INFINITY_BITS;
+    long positiveInfinityBits = getType() == NumberType.FLOAT ? FLOAT_POSITIVE_INFINITY_BITS : DOUBLE_POSITIVE_INFINITY_BITS;
+    long minusZeroBits = getType() == NumberType.FLOAT ? FLOAT_MINUS_ZERO_BITS : DOUBLE_MINUS_ZERO_BITS;
+    long zeroBits = getType() == NumberType.FLOAT ? FLOAT_ZERO_BITS : DOUBLE_ZERO_BITS;
+    
+    // If min is negative (or -0d) and max is positive (or +0d), then issue a FunctionRangeQuery
+    if ((minVal == null || minVal.doubleValue() < 0d || minBits == minusZeroBits) && 
+        (maxVal == null || (maxVal.doubleValue() > 0d || maxBits == zeroBits))) {
+
+      ValueSource vs = getValueSource(sf, null);
+      query = new FunctionRangeQuery(new ValueSourceRangeFilter(vs, min, max, minInclusive, maxInclusive));
+
+    } else { // If both max and min are negative (or -0d), then issue range query with max and min reversed
+      if ((minVal == null || minVal.doubleValue() < 0d || minBits == minusZeroBits) &&
+          (maxVal != null && (maxVal.doubleValue() < 0d || maxBits == minusZeroBits))) {
+        query = numericDocValuesRangeQuery
+            (fieldName, maxBits, (min == null ? negativeInfinityBits : minBits), maxInclusive, minInclusive);
+      } else { // If both max and min are positive, then issue range query
+        query = numericDocValuesRangeQuery
+            (fieldName, minBits, (max == null ? positiveInfinityBits : maxBits), minInclusive, maxInclusive);
+      }
+    }
+    return query;
+  }
+  
+  public static Query numericDocValuesRangeQuery(
+      String field,
+      Number lowerValue, Number upperValue,
+      boolean lowerInclusive, boolean upperInclusive) {
+
+    long actualLowerValue = Long.MIN_VALUE;
+    if (lowerValue != null) {
+      actualLowerValue = lowerValue.longValue();
+      if (lowerInclusive == false) {
+        if (actualLowerValue == Long.MAX_VALUE) {
+          return new MatchNoDocsQuery();
+        }
+        ++actualLowerValue;
+      }
+    }
+
+    long actualUpperValue = Long.MAX_VALUE;
+    if (upperValue != null) {
+      actualUpperValue = upperValue.longValue();
+      if (upperInclusive == false) {
+        if (actualUpperValue == Long.MIN_VALUE) {
+          return new MatchNoDocsQuery();
+        }
+        --actualUpperValue;
+      }
+    }
+    return NumericDocValuesField.newRangeQuery(field, actualLowerValue, actualUpperValue);
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/java/org/apache/solr/schema/PointField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/PointField.java b/solr/core/src/java/org/apache/solr/schema/PointField.java
index a2dd8a8..9b1ed38 100644
--- a/solr/core/src/java/org/apache/solr/schema/PointField.java
+++ b/solr/core/src/java/org/apache/solr/schema/PointField.java
@@ -49,15 +49,7 @@ import org.slf4j.LoggerFactory;
  * {@code DocValues} are supported for single-value cases ({@code NumericDocValues}).
  * {@code FieldCache} is not supported for {@code PointField}s, so sorting, faceting, etc on these fields require the use of {@code docValues="true"} in the schema.
  */
-public abstract class PointField extends PrimitiveFieldType {
-  
-  public enum PointTypes {
-    INTEGER,
-    LONG,
-    FLOAT,
-    DOUBLE,
-    DATE
-  }
+public abstract class PointField extends NumericFieldType {
 
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
@@ -117,11 +109,6 @@ public abstract class PointField extends PrimitiveFieldType {
     return false;
   }
 
-  /**
-   * @return the type of this field
-   */
-  public abstract PointTypes getType();
-  
   @Override
   public abstract Query getSetQuery(QParser parser, SchemaField field, Collection<String> externalVals);
 
@@ -137,6 +124,19 @@ public abstract class PointField extends PrimitiveFieldType {
 
   protected abstract Query getExactQuery(SchemaField field, String externalVal);
 
+  public abstract Query getPointRangeQuery(QParser parser, SchemaField field, String min, String max, boolean minInclusive,
+      boolean maxInclusive);
+
+  @Override
+  public Query getRangeQuery(QParser parser, SchemaField field, String min, String max, boolean minInclusive,
+      boolean maxInclusive) {
+    if (!field.indexed() && field.hasDocValues() && !field.multiValued()) {
+      return getDocValuesRangeQuery(parser, field, min, max, minInclusive, maxInclusive);
+    } else {
+      return getPointRangeQuery(parser, field, min, max, minInclusive, maxInclusive);
+    }
+  }
+
   @Override
   public String storedToReadable(IndexableField f) {
     return toExternal(f);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/java/org/apache/solr/schema/TrieDateField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/TrieDateField.java b/solr/core/src/java/org/apache/solr/schema/TrieDateField.java
index 209c581..77980a7 100644
--- a/solr/core/src/java/org/apache/solr/schema/TrieDateField.java
+++ b/solr/core/src/java/org/apache/solr/schema/TrieDateField.java
@@ -84,7 +84,7 @@ import org.apache.solr.util.DateMathParser;
  */
 public class TrieDateField extends TrieField implements DateValueFieldType {
   {
-    this.type = TrieTypes.DATE;
+    this.type = NumberType.DATE;
   }
   
   @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/java/org/apache/solr/schema/TrieDoubleField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/TrieDoubleField.java b/solr/core/src/java/org/apache/solr/schema/TrieDoubleField.java
index 7faa38c..b610e6e 100644
--- a/solr/core/src/java/org/apache/solr/schema/TrieDoubleField.java
+++ b/solr/core/src/java/org/apache/solr/schema/TrieDoubleField.java
@@ -52,7 +52,7 @@ import org.apache.lucene.util.mutable.MutableValueDouble;
  */
 public class TrieDoubleField extends TrieField implements DoubleValueFieldType {
   {
-    type=TrieTypes.DOUBLE;
+    type = NumberType.DOUBLE;
   }
   
   @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/java/org/apache/solr/schema/TrieField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/TrieField.java b/solr/core/src/java/org/apache/solr/schema/TrieField.java
index 57dbeff..e470155 100644
--- a/solr/core/src/java/org/apache/solr/schema/TrieField.java
+++ b/solr/core/src/java/org/apache/solr/schema/TrieField.java
@@ -43,7 +43,6 @@ import org.apache.lucene.queries.function.valuesource.DoubleFieldSource;
 import org.apache.lucene.queries.function.valuesource.FloatFieldSource;
 import org.apache.lucene.queries.function.valuesource.IntFieldSource;
 import org.apache.lucene.queries.function.valuesource.LongFieldSource;
-import org.apache.lucene.search.MatchNoDocsQuery;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.SortField;
 import org.apache.lucene.search.SortedSetSelector;
@@ -56,9 +55,7 @@ import org.apache.lucene.util.mutable.MutableValueDate;
 import org.apache.lucene.util.mutable.MutableValueLong;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.response.TextResponseWriter;
-import org.apache.solr.search.FunctionRangeQuery;
 import org.apache.solr.search.QParser;
-import org.apache.solr.search.function.ValueSourceRangeFilter;
 import org.apache.solr.uninverting.UninvertingReader.Type;
 import org.apache.solr.util.DateMathParser;
 import org.slf4j.Logger;
@@ -84,12 +81,11 @@ import org.slf4j.LoggerFactory;
  * @see org.apache.lucene.legacy.LegacyNumericRangeQuery
  * @since solr 1.4
  */
-public class TrieField extends PrimitiveFieldType {
+public class TrieField extends NumericFieldType {
   public static final int DEFAULT_PRECISION_STEP = 8;
 
   protected int precisionStepArg = TrieField.DEFAULT_PRECISION_STEP;  // the one passed in or defaulted
   protected int precisionStep;     // normalized
-  protected TrieTypes type;
 
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
@@ -107,7 +103,7 @@ public class TrieField extends PrimitiveFieldType {
 
     if (t != null) {
       try {
-        type = TrieTypes.valueOf(t.toUpperCase(Locale.ROOT));
+        type = NumberType.valueOf(t.toUpperCase(Locale.ROOT));
       } catch (IllegalArgumentException e) {
         throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
                 "Invalid type specified in schema.xml for field: " + args.get("name"), e);
@@ -139,7 +135,7 @@ public class TrieField extends PrimitiveFieldType {
       }
 
       // normal stored case
-      return (type == TrieTypes.DATE) ? new Date(val.longValue()) : val;
+      return (type == NumberType.DATE) ? new Date(val.longValue()) : val;
     } else {
       // multi-valued numeric docValues currently use SortedSet on the indexed terms.
       BytesRef term = f.binaryValue();
@@ -340,13 +336,6 @@ public class TrieField extends PrimitiveFieldType {
     return precisionStepArg;
   }
 
-  /**
-   * @return the type of this field
-   */
-  public TrieTypes getType() {
-    return type;
-  }
-
   @Override
   public LegacyNumericType getNumericType() {
     switch (type) {
@@ -372,66 +361,41 @@ public class TrieField extends PrimitiveFieldType {
     }
     int ps = precisionStep;
     Query query;
-    final boolean matchOnly = field.hasDocValues() && !field.indexed();
+
+    if (field.hasDocValues() && !field.indexed()) {
+      return getDocValuesRangeQuery(parser, field, min, max, minInclusive, maxInclusive);
+    }
+
     switch (type) {
       case INTEGER:
-        if (matchOnly) {
-          query = numericDocValuesRangeQuery(field.getName(),
-                min == null ? null : Integer.parseInt(min),
-                max == null ? null : Integer.parseInt(max),
-                minInclusive, maxInclusive);
-        } else {
-          query = LegacyNumericRangeQuery.newIntRange(field.getName(), ps,
-              min == null ? null : Integer.parseInt(min),
-              max == null ? null : Integer.parseInt(max),
-              minInclusive, maxInclusive);
-        }
+        query = LegacyNumericRangeQuery.newIntRange(field.getName(), ps,
+            min == null ? null : Integer.parseInt(min),
+            max == null ? null : Integer.parseInt(max),
+            minInclusive, maxInclusive);
         break;
       case FLOAT:
-        if (matchOnly) {
-          return getRangeQueryForFloatDoubleDocValues(field, min, max, minInclusive, maxInclusive);
-        } else {
-          query = LegacyNumericRangeQuery.newFloatRange(field.getName(), ps,
-              min == null ? null : Float.parseFloat(min),
-              max == null ? null : Float.parseFloat(max),
-              minInclusive, maxInclusive);
-        }
+        query = LegacyNumericRangeQuery.newFloatRange(field.getName(), ps,
+            min == null ? null : Float.parseFloat(min),
+            max == null ? null : Float.parseFloat(max),
+            minInclusive, maxInclusive);
         break;
       case LONG:
-        if (matchOnly) {
-          query = numericDocValuesRangeQuery(field.getName(),
-                min == null ? null : Long.parseLong(min),
-                max == null ? null : Long.parseLong(max),
-                minInclusive, maxInclusive);
-        } else {
-          query = LegacyNumericRangeQuery.newLongRange(field.getName(), ps,
-              min == null ? null : Long.parseLong(min),
-              max == null ? null : Long.parseLong(max),
-              minInclusive, maxInclusive);
-        }
+        query = LegacyNumericRangeQuery.newLongRange(field.getName(), ps,
+            min == null ? null : Long.parseLong(min),
+            max == null ? null : Long.parseLong(max),
+            minInclusive, maxInclusive);
         break;
       case DOUBLE:
-        if (matchOnly) {
-          return getRangeQueryForFloatDoubleDocValues(field, min, max, minInclusive, maxInclusive);
-        } else {
-          query = LegacyNumericRangeQuery.newDoubleRange(field.getName(), ps,
-              min == null ? null : Double.parseDouble(min),
-              max == null ? null : Double.parseDouble(max),
-              minInclusive, maxInclusive);
-        }
+        query = LegacyNumericRangeQuery.newDoubleRange(field.getName(), ps,
+            min == null ? null : Double.parseDouble(min),
+            max == null ? null : Double.parseDouble(max),
+            minInclusive, maxInclusive);
         break;
       case DATE:
-        if (matchOnly) {
-          query = numericDocValuesRangeQuery(field.getName(),
-                min == null ? null : DateMathParser.parseMath(null, min).getTime(),
-                max == null ? null : DateMathParser.parseMath(null, max).getTime(),
-                minInclusive, maxInclusive);
-        } else {
-          query = LegacyNumericRangeQuery.newLongRange(field.getName(), ps,
-              min == null ? null : DateMathParser.parseMath(null, min).getTime(),
-              max == null ? null : DateMathParser.parseMath(null, max).getTime(),
-              minInclusive, maxInclusive);
-        }
+        query = LegacyNumericRangeQuery.newLongRange(field.getName(), ps,
+            min == null ? null : DateMathParser.parseMath(null, min).getTime(),
+            max == null ? null : DateMathParser.parseMath(null, max).getTime(),
+            minInclusive, maxInclusive);
         break;
       default:
         throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Unknown type for trie field");
@@ -440,81 +404,6 @@ public class TrieField extends PrimitiveFieldType {
     return query;
   }
 
-  private static Query numericDocValuesRangeQuery(
-      String field,
-      Number lowerValue, Number upperValue,
-      boolean lowerInclusive, boolean upperInclusive) {
-
-    long actualLowerValue = Long.MIN_VALUE;
-    if (lowerValue != null) {
-      actualLowerValue = lowerValue.longValue();
-      if (lowerInclusive == false) {
-        if (actualLowerValue == Long.MAX_VALUE) {
-          return new MatchNoDocsQuery();
-        }
-        ++actualLowerValue;
-      }
-    }
-
-    long actualUpperValue = Long.MAX_VALUE;
-    if (upperValue != null) {
-      actualUpperValue = upperValue.longValue();
-      if (upperInclusive == false) {
-        if (actualUpperValue == Long.MIN_VALUE) {
-          return new MatchNoDocsQuery();
-        }
-        --actualUpperValue;
-      }
-    }
-    return NumericDocValuesField.newRangeQuery(field, actualLowerValue, actualUpperValue);
-  }
-
-  private static long FLOAT_NEGATIVE_INFINITY_BITS = (long)Float.floatToIntBits(Float.NEGATIVE_INFINITY);
-  private static long DOUBLE_NEGATIVE_INFINITY_BITS = Double.doubleToLongBits(Double.NEGATIVE_INFINITY);
-  private static long FLOAT_POSITIVE_INFINITY_BITS = (long)Float.floatToIntBits(Float.POSITIVE_INFINITY);
-  private static long DOUBLE_POSITIVE_INFINITY_BITS = Double.doubleToLongBits(Double.POSITIVE_INFINITY);
-  private static long FLOAT_MINUS_ZERO_BITS = (long)Float.floatToIntBits(-0f);
-  private static long DOUBLE_MINUS_ZERO_BITS = Double.doubleToLongBits(-0d);
-  private static long FLOAT_ZERO_BITS = (long)Float.floatToIntBits(0f);
-  private static long DOUBLE_ZERO_BITS = Double.doubleToLongBits(0d);
-
-  private Query getRangeQueryForFloatDoubleDocValues(SchemaField sf, String min, String max, boolean minInclusive, boolean maxInclusive) {
-    Query query;
-    String fieldName = sf.getName();
-
-    Number minVal = min == null ? null : type == TrieTypes.FLOAT ? Float.parseFloat(min): Double.parseDouble(min);
-    Number maxVal = max == null ? null : type == TrieTypes.FLOAT ? Float.parseFloat(max): Double.parseDouble(max);
-    
-    Long minBits = 
-        min == null ? null : type == TrieTypes.FLOAT ? (long) Float.floatToIntBits(minVal.floatValue()): Double.doubleToLongBits(minVal.doubleValue());
-    Long maxBits = 
-        max == null ? null : type == TrieTypes.FLOAT ? (long) Float.floatToIntBits(maxVal.floatValue()): Double.doubleToLongBits(maxVal.doubleValue());
-    
-    long negativeInfinityBits = type == TrieTypes.FLOAT ? FLOAT_NEGATIVE_INFINITY_BITS : DOUBLE_NEGATIVE_INFINITY_BITS;
-    long positiveInfinityBits = type == TrieTypes.FLOAT ? FLOAT_POSITIVE_INFINITY_BITS : DOUBLE_POSITIVE_INFINITY_BITS;
-    long minusZeroBits = type == TrieTypes.FLOAT ? FLOAT_MINUS_ZERO_BITS : DOUBLE_MINUS_ZERO_BITS;
-    long zeroBits = type == TrieTypes.FLOAT ? FLOAT_ZERO_BITS : DOUBLE_ZERO_BITS;
-    
-    // If min is negative (or -0d) and max is positive (or +0d), then issue a FunctionRangeQuery
-    if ((minVal == null || minVal.doubleValue() < 0d || minBits == minusZeroBits) && 
-        (maxVal == null || (maxVal.doubleValue() > 0d || maxBits == zeroBits))) {
-
-      ValueSource vs = getValueSource(sf, null);
-      query = new FunctionRangeQuery(new ValueSourceRangeFilter(vs, min, max, minInclusive, maxInclusive));
-
-    } else { // If both max and min are negative (or -0d), then issue range query with max and min reversed
-      if ((minVal == null || minVal.doubleValue() < 0d || minBits == minusZeroBits) &&
-          (maxVal != null && (maxVal.doubleValue() < 0d || maxBits == minusZeroBits))) {
-        query = numericDocValuesRangeQuery
-            (fieldName, maxBits, (min == null ? negativeInfinityBits : minBits), maxInclusive, minInclusive);
-      } else { // If both max and min are positive, then issue range query
-        query = numericDocValuesRangeQuery
-            (fieldName, minBits, (max == null ? positiveInfinityBits : maxBits), minInclusive, maxInclusive);
-      }
-    }
-    return query;
-  }
-
   @Override
   public Query getFieldQuery(QParser parser, SchemaField field, String externalVal) {
     if (!field.indexed() && field.hasDocValues()) {
@@ -579,7 +468,7 @@ public class TrieField extends PrimitiveFieldType {
 
   @Override
   public String toExternal(IndexableField f) {
-    return (type == TrieTypes.DATE)
+    return (type == NumberType.DATE)
       ? ((Date) toObject(f)).toInstant().toString()
       : toObject(f).toString();
   }
@@ -792,15 +681,6 @@ public class TrieField extends PrimitiveFieldType {
     }
   }
 
-  public enum TrieTypes {
-    INTEGER,
-    LONG,
-    FLOAT,
-    DOUBLE,
-    DATE
-  }
-
-
   static final String INT_PREFIX = new String(new char[]{LegacyNumericUtils.SHIFT_START_INT});
   static final String LONG_PREFIX = new String(new char[]{LegacyNumericUtils.SHIFT_START_LONG});
 
@@ -863,7 +743,6 @@ class TrieDateFieldSource extends LongFieldSource {
   public long externalToLong(String extVal) {
     return DateMathParser.parseMath(null, extVal).getTime();
   }
-
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/java/org/apache/solr/schema/TrieFloatField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/TrieFloatField.java b/solr/core/src/java/org/apache/solr/schema/TrieFloatField.java
index 13b9141..b069810 100644
--- a/solr/core/src/java/org/apache/solr/schema/TrieFloatField.java
+++ b/solr/core/src/java/org/apache/solr/schema/TrieFloatField.java
@@ -52,7 +52,7 @@ import org.apache.lucene.util.mutable.MutableValueFloat;
  */
 public class TrieFloatField extends TrieField implements FloatValueFieldType {
   {
-    type=TrieTypes.FLOAT;
+    type = NumberType.FLOAT;
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/java/org/apache/solr/schema/TrieIntField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/TrieIntField.java b/solr/core/src/java/org/apache/solr/schema/TrieIntField.java
index d89dd0d..6d4d7cd 100644
--- a/solr/core/src/java/org/apache/solr/schema/TrieIntField.java
+++ b/solr/core/src/java/org/apache/solr/schema/TrieIntField.java
@@ -45,7 +45,7 @@ import org.apache.lucene.util.mutable.MutableValueInt;
  */
 public class TrieIntField extends TrieField implements IntValueFieldType {
   {
-    type=TrieTypes.INTEGER;
+    type = NumberType.INTEGER;
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/java/org/apache/solr/schema/TrieLongField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/TrieLongField.java b/solr/core/src/java/org/apache/solr/schema/TrieLongField.java
index c3a5440..a93d0ce 100644
--- a/solr/core/src/java/org/apache/solr/schema/TrieLongField.java
+++ b/solr/core/src/java/org/apache/solr/schema/TrieLongField.java
@@ -45,7 +45,7 @@ import org.apache.lucene.util.mutable.MutableValueLong;
  */
 public class TrieLongField extends TrieField implements LongValueFieldType {
   {
-    type=TrieTypes.LONG;
+    type = NumberType.LONG;
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
index 7c56311..3f7d511 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
@@ -98,6 +98,7 @@ import org.apache.solr.response.SolrQueryResponse;
 import org.apache.solr.schema.BoolField;
 import org.apache.solr.schema.EnumField;
 import org.apache.solr.schema.IndexSchema;
+import org.apache.solr.schema.NumericFieldType;
 import org.apache.solr.schema.PointField;
 import org.apache.solr.schema.SchemaField;
 import org.apache.solr.schema.TrieDateField;
@@ -823,7 +824,7 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
             }
             Object newVal = val;
             if (schemaField.getType().isPointField()) {
-              PointField.PointTypes type = ((PointField)schemaField.getType()).getType(); 
+              NumericFieldType.NumberType type = ((PointField)schemaField.getType()).getType(); 
               switch (type) {
                 case INTEGER:
                   newVal = val.intValue();

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/GroupConverter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/GroupConverter.java b/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/GroupConverter.java
index 2a5827d..a9849d5 100644
--- a/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/GroupConverter.java
+++ b/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/GroupConverter.java
@@ -70,7 +70,7 @@ class GroupConverter {
     for (SearchGroup<BytesRef> original : values) {
       SearchGroup<MutableValue> converted = new SearchGroup<MutableValue>();
       converted.sortValues = original.sortValues; // ?
-      TrieField.TrieTypes type = ((TrieField)fieldType).getType();
+      TrieField.NumberType type = ((TrieField)fieldType).getType();
       final MutableValue v;
       switch (type) {
         case INTEGER:

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/test-files/solr/collection1/conf/schema-point.xml
----------------------------------------------------------------------
diff --git a/solr/core/src/test-files/solr/collection1/conf/schema-point.xml b/solr/core/src/test-files/solr/collection1/conf/schema-point.xml
index ca37ff5..053d39b 100644
--- a/solr/core/src/test-files/solr/collection1/conf/schema-point.xml
+++ b/solr/core/src/test-files/solr/collection1/conf/schema-point.xml
@@ -79,6 +79,10 @@
    <dynamicField name="*_p_l_dv_ns"  type="plong"    indexed="true"  stored="false" docValues="true" useDocValuesAsStored="true"/>
    <dynamicField name="*_p_d_dv_ns"  type="pdouble"    indexed="true"  stored="false" docValues="true" useDocValuesAsStored="true"/>
    <dynamicField name="*_p_f_dv_ns"  type="pfloat"    indexed="true"  stored="false" docValues="true" useDocValuesAsStored="true"/>
+   <dynamicField name="*_p_i_ni_ns_dv" type="pint"    indexed="false"  stored="false" docValues="true" useDocValuesAsStored="true"/>
+   <dynamicField name="*_p_l_ni_ns_dv" type="plong"   indexed="false"  stored="false" docValues="true" useDocValuesAsStored="true"/>
+   <dynamicField name="*_p_d_ni_ns_dv" type="pdouble" indexed="false"  stored="false" docValues="true" useDocValuesAsStored="true"/>
+   <dynamicField name="*_p_f_ni_ns_dv" type="pfloat"  indexed="false"  stored="false" docValues="true" useDocValuesAsStored="true"/>
 
  </fields>
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/test/org/apache/solr/schema/TestPointFields.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/schema/TestPointFields.java b/solr/core/src/test/org/apache/solr/schema/TestPointFields.java
index 91a7b49..75d142d 100644
--- a/solr/core/src/test/org/apache/solr/schema/TestPointFields.java
+++ b/solr/core/src/test/org/apache/solr/schema/TestPointFields.java
@@ -59,6 +59,7 @@ public class TestPointFields extends SolrTestCaseJ4 {
     doTestIntPointFieldExactQuery("number_p_i", false);
     doTestIntPointFieldExactQuery("number_p_i_mv", false);
     doTestIntPointFieldExactQuery("number_p_i_ni_dv", false);
+    doTestIntPointFieldExactQuery("number_p_i_ni_ns_dv", false);
     // uncomment once MultiValued docValues are supported in PointFields
     //    doTestIntPointFieldExactQuery("number_p_i_ni_mv_dv", false);
   }
@@ -74,6 +75,7 @@ public class TestPointFields extends SolrTestCaseJ4 {
   @Test
   public void testIntPointFieldRangeQuery() throws Exception {
     doTestIntPointFieldRangeQuery("number_p_i", "int", false);
+    doTestIntPointFieldRangeQuery("number_p_i_ni_ns_dv", "int", false);
   }
   
   @Test
@@ -235,6 +237,7 @@ public class TestPointFields extends SolrTestCaseJ4 {
     doTestFloatPointFieldExactQuery("number_p_d");
     doTestFloatPointFieldExactQuery("number_p_d_mv");
     doTestFloatPointFieldExactQuery("number_p_d_ni_dv");
+    doTestFloatPointFieldExactQuery("number_p_d_ni_ns_dv");
     // TODO enable once MuultiValued docValues are supported with PointFields
 //    doTestFloatPointFieldExactQuery("number_p_d_ni_mv_dv");
   }
@@ -258,6 +261,7 @@ public class TestPointFields extends SolrTestCaseJ4 {
   @Test
   public void testDoublePointFieldRangeQuery() throws Exception {
     doTestFloatPointFieldRangeQuery("number_p_d", "double", true);
+    doTestFloatPointFieldRangeQuery("number_p_d_ni_ns_dv", "double", true);
   }
   
   @Test
@@ -457,6 +461,7 @@ public class TestPointFields extends SolrTestCaseJ4 {
     doTestFloatPointFieldExactQuery("number_p_f");
     doTestFloatPointFieldExactQuery("number_p_f_mv");
     doTestFloatPointFieldExactQuery("number_p_f_ni_dv");
+    doTestFloatPointFieldExactQuery("number_p_f_ni_ns_dv");
 //    doTestFloatPointFieldExactQuery("number_p_f_ni_mv_dv");
   }
   
@@ -479,6 +484,7 @@ public class TestPointFields extends SolrTestCaseJ4 {
   @Test
   public void testFloatPointFieldRangeQuery() throws Exception {
     doTestFloatPointFieldRangeQuery("number_p_f", "float", false);
+    doTestFloatPointFieldRangeQuery("number_p_f_ni_ns_dv", "float", false);
   }
   
   @Test
@@ -551,6 +557,7 @@ public class TestPointFields extends SolrTestCaseJ4 {
     doTestIntPointFieldExactQuery("number_p_l", true);
     doTestIntPointFieldExactQuery("number_p_l_mv", true);
     doTestIntPointFieldExactQuery("number_p_l_ni_dv", true);
+    doTestIntPointFieldExactQuery("number_p_l_ni_ns_dv", true);
 //    doTestIntPointFieldExactQuery("number_p_i_ni_mv_dv", true);
   }
   
@@ -565,6 +572,7 @@ public class TestPointFields extends SolrTestCaseJ4 {
   @Test
   public void testLongPointFieldRangeQuery() throws Exception {
     doTestIntPointFieldRangeQuery("number_p_l", "long", true);
+    doTestIntPointFieldRangeQuery("number_p_l_ni_ns_dv", "long", true);
   }
   
   @Test