You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by cp...@apache.org on 2017/04/07 15:47:51 UTC

[14/24] lucene-solr:jira/solr-6203: SOLR-10425: Fix indexed="false" on numeric PointFields

SOLR-10425: Fix indexed="false" on numeric PointFields


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

Branch: refs/heads/jira/solr-6203
Commit: 6e5f6fab53b8c6f4acbebd51c346173829a3247a
Parents: e75a2e6
Author: Chris Hostetter <ho...@apache.org>
Authored: Thu Apr 6 12:07:41 2017 -0700
Committer: Chris Hostetter <ho...@apache.org>
Committed: Thu Apr 6 12:07:41 2017 -0700

----------------------------------------------------------------------
 solr/CHANGES.txt                                |   2 +
 .../org/apache/solr/schema/DatePointField.java  |   5 +-
 .../apache/solr/schema/DoublePointField.java    |   5 +-
 .../org/apache/solr/schema/FloatPointField.java |   5 +-
 .../org/apache/solr/schema/IntPointField.java   |   5 +-
 .../org/apache/solr/schema/LongPointField.java  |   5 +-
 .../java/org/apache/solr/schema/PointField.java |  53 +-
 .../solr/collection1/conf/schema-point.xml      |  34 +-
 .../org/apache/solr/schema/TestPointFields.java | 541 +++++++++++++++++--
 9 files changed, 590 insertions(+), 65 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/6e5f6fab/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index dcdf486..0bf2c54 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -225,6 +225,8 @@ Bug Fixes
   This fixes broken queries for ShingleFilter-containing query-time analyzers when request param sow=false.
   (Steve Rowe)
 
+* SOLR-10425: Fix indexed="false" on numeric PointFields (Tom�s Fern�ndez L�bbe, hossman)
+
 ==================  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/6e5f6fab/solr/core/src/java/org/apache/solr/schema/DatePointField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/DatePointField.java b/solr/core/src/java/org/apache/solr/schema/DatePointField.java
index 50f85e3..8e4a8a0 100644
--- a/solr/core/src/java/org/apache/solr/schema/DatePointField.java
+++ b/solr/core/src/java/org/apache/solr/schema/DatePointField.java
@@ -160,6 +160,9 @@ public class DatePointField extends PointField implements DateValueFieldType {
   @Override
   public Query getSetQuery(QParser parser, SchemaField field, Collection<String> externalVals) {
     assert externalVals.size() > 0;
+    if (!field.indexed()) {
+      return super.getSetQuery(parser, field, externalVals);
+    }
     long[] values = new long[externalVals.size()];
     int i = 0;
     for (String val:externalVals) {
@@ -222,8 +225,6 @@ public class DatePointField extends PointField implements DateValueFieldType {
 
   @Override
   public IndexableField createField(SchemaField field, Object value) {
-    if (!isFieldUsed(field)) return null;
-
     Date date = (value instanceof Date)
         ? ((Date)value)
         : DateMathParser.parseMath(null, value.toString());

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/6e5f6fab/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 6ae8349..24f4029 100644
--- a/solr/core/src/java/org/apache/solr/schema/DoublePointField.java
+++ b/solr/core/src/java/org/apache/solr/schema/DoublePointField.java
@@ -106,6 +106,9 @@ public class DoublePointField extends PointField implements DoubleValueFieldType
   @Override
   public Query getSetQuery(QParser parser, SchemaField field, Collection<String> externalVal) {
     assert externalVal.size() > 0;
+    if (!field.indexed()) {
+      return super.getSetQuery(parser, field, externalVal);
+    }
     double[] values = new double[externalVal.size()];
     int i = 0;
     for (String val:externalVal) {
@@ -167,8 +170,6 @@ public class DoublePointField extends PointField implements DoubleValueFieldType
 
   @Override
   public IndexableField createField(SchemaField field, Object value) {
-    if (!isFieldUsed(field)) return null;
-
     double doubleValue = (value instanceof Number) ? ((Number) value).doubleValue() : Double.parseDouble(value.toString());
     return new DoublePoint(field.getName(), doubleValue);
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/6e5f6fab/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 0f42cfd..46414ae 100644
--- a/solr/core/src/java/org/apache/solr/schema/FloatPointField.java
+++ b/solr/core/src/java/org/apache/solr/schema/FloatPointField.java
@@ -106,6 +106,9 @@ public class FloatPointField extends PointField implements FloatValueFieldType {
   @Override
   public Query getSetQuery(QParser parser, SchemaField field, Collection<String> externalVal) {
     assert externalVal.size() > 0;
+    if (!field.indexed()) {
+      return super.getSetQuery(parser, field, externalVal);
+    }
     float[] values = new float[externalVal.size()];
     int i = 0;
     for (String val:externalVal) {
@@ -167,8 +170,6 @@ public class FloatPointField extends PointField implements FloatValueFieldType {
 
   @Override
   public IndexableField createField(SchemaField field, Object value) {
-    if (!isFieldUsed(field)) return null;
-
     float floatValue = (value instanceof Number) ? ((Number) value).floatValue() : Float.parseFloat(value.toString());
     return new FloatPoint(field.getName(), floatValue);
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/6e5f6fab/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 5eaf7e0..66ac606 100644
--- a/solr/core/src/java/org/apache/solr/schema/IntPointField.java
+++ b/solr/core/src/java/org/apache/solr/schema/IntPointField.java
@@ -103,6 +103,9 @@ public class IntPointField extends PointField implements IntValueFieldType {
   @Override
   public Query getSetQuery(QParser parser, SchemaField field, Collection<String> externalVal) {
     assert externalVal.size() > 0;
+    if (!field.indexed()) {
+      return super.getSetQuery(parser, field, externalVal);
+    }
     int[] values = new int[externalVal.size()];
     int i = 0;
     for (String val:externalVal) {
@@ -159,8 +162,6 @@ public class IntPointField extends PointField implements IntValueFieldType {
 
   @Override
   public IndexableField createField(SchemaField field, Object value) {
-    if (!isFieldUsed(field)) return null;
-
     int intValue = (value instanceof Number) ? ((Number) value).intValue() : Integer.parseInt(value.toString());
     return new IntPoint(field.getName(), intValue);
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/6e5f6fab/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 e58fbcf..c3bc630 100644
--- a/solr/core/src/java/org/apache/solr/schema/LongPointField.java
+++ b/solr/core/src/java/org/apache/solr/schema/LongPointField.java
@@ -102,6 +102,9 @@ public class LongPointField extends PointField implements LongValueFieldType {
   @Override
   public Query getSetQuery(QParser parser, SchemaField field, Collection<String> externalVal) {
     assert externalVal.size() > 0;
+    if (!field.indexed()) {
+      return super.getSetQuery(parser, field, externalVal);
+    }
     long[] values = new long[externalVal.size()];
     int i = 0;
     for (String val:externalVal) {
@@ -164,8 +167,6 @@ public class LongPointField extends PointField implements LongValueFieldType {
 
   @Override
   public IndexableField createField(SchemaField field, Object value) {
-    if (!isFieldUsed(field)) return null;
-
     long longValue = (value instanceof Number) ? ((Number) value).longValue() : Long.parseLong(value.toString());
     return new LongPoint(field.getName(), longValue);
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/6e5f6fab/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 91d3eff..cad3c7e 100644
--- a/solr/core/src/java/org/apache/solr/schema/PointField.java
+++ b/solr/core/src/java/org/apache/solr/schema/PointField.java
@@ -21,6 +21,7 @@ import java.lang.invoke.MethodHandles;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Date;
 import java.util.List;
 
 import org.apache.lucene.document.NumericDocValuesField;
@@ -111,7 +112,9 @@ public abstract class PointField extends NumericFieldType {
   }
 
   @Override
-  public abstract Query getSetQuery(QParser parser, SchemaField field, Collection<String> externalVals);
+  public Query getSetQuery(QParser parser, SchemaField field, Collection<String> externalVals) {
+    return super.getSetQuery(parser, field, externalVals);
+  }
 
   @Override
   public Query getFieldQuery(QParser parser, SchemaField field, String externalVal) {
@@ -204,34 +207,48 @@ public abstract class PointField extends NumericFieldType {
 
   @Override
   public List<IndexableField> createFields(SchemaField sf, Object value) {
-    if (!(sf.hasDocValues() || sf.stored())) {
-      return Collections.singletonList(createField(sf, value));
+    if (!isFieldUsed(sf)) {
+      return Collections.emptyList();
+    }
+    List<IndexableField> fields = new ArrayList<>(3);
+    IndexableField field = null;
+    if (sf.indexed()) {
+      field = createField(sf, value);
+      fields.add(field);
     }
-    List<IndexableField> fields = new ArrayList<>();
-    final IndexableField field = createField(sf, value);
-    fields.add(field);
     
     if (sf.hasDocValues()) {
+      final Number numericValue;
+      if (field == null) {
+        final Object nativeTypeObject = toNativeType(value);
+        if (getNumberType() == NumberType.DATE) {
+          numericValue = ((Date)nativeTypeObject).getTime();
+        } else {
+          numericValue = (Number) nativeTypeObject;
+        }
+      } else {
+        numericValue = field.numericValue();
+      }
       final long bits;
       if (!sf.multiValued()) {
-        if (field.numericValue() instanceof Integer || field.numericValue() instanceof Long) {
-          bits = field.numericValue().longValue();
-        } else if (field.numericValue() instanceof Float) {
-          bits = Float.floatToIntBits(field.numericValue().floatValue());
+        if (numericValue instanceof Integer || numericValue instanceof Long) {
+          bits = numericValue.longValue();
+        } else if (numericValue instanceof Float) {
+          bits = Float.floatToIntBits(numericValue.floatValue());
         } else {
-          assert field.numericValue() instanceof Double;
-          bits = Double.doubleToLongBits(field.numericValue().doubleValue());
+          assert numericValue instanceof Double;
+          bits = Double.doubleToLongBits(numericValue.doubleValue());
         }
         fields.add(new NumericDocValuesField(sf.getName(), bits));
       } else {
         // MultiValued
-        if (field.numericValue() instanceof Integer || field.numericValue() instanceof Long) {
-          bits = field.numericValue().longValue();
-        } else if (field.numericValue() instanceof Float) {
-          bits = NumericUtils.floatToSortableInt(field.numericValue().floatValue());
+        if (numericValue instanceof Integer || numericValue instanceof Long) {
+          bits = numericValue.longValue();
+        } else if (numericValue instanceof Float) {
+          bits = NumericUtils.floatToSortableInt(numericValue.floatValue());
         } else {
-          assert field.numericValue() instanceof Double;
-          bits = NumericUtils.doubleToSortableLong(field.numericValue().doubleValue());
+          assert numericValue instanceof Double;
+          bits = NumericUtils.doubleToSortableLong(numericValue.doubleValue());
         }
         fields.add(new SortedNumericDocValuesField(sf.getName(), bits));
       }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/6e5f6fab/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 ed169a1..1a936a0 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
@@ -51,37 +51,69 @@
    <dynamicField name="*_p_i_dv"  type="pint"    indexed="true"  stored="true" docValues="true"/>
    <dynamicField name="*_p_i_mv"  type="pint"    indexed="true"  stored="true" multiValued="true"/>
    <dynamicField name="*_p_i_mv_dv"  type="pint"    indexed="true"  stored="true" docValues="true" multiValued="true"/>
+   <dynamicField name="*_p_i_ni"  type="pint"    indexed="false"  stored="true" docValues="false"/>
    <dynamicField name="*_p_i_ni_dv"  type="pint"    indexed="false"  stored="true" docValues="true"/>
+   <dynamicField name="*_p_i_ni_dv_ns"  type="pint"    indexed="false"  stored="false" docValues="true" useDocValuesAsStored="false"/>
+   <dynamicField name="*_p_i_ni_mv"  type="pint"    indexed="false"  stored="true" docValues="false" multiValued="true"/>
    <dynamicField name="*_p_i_ni_mv_dv"  type="pint"    indexed="false"  stored="true" docValues="true" multiValued="true"/>
+   <dynamicField name="*_p_i_ni_ns"  type="pint"    indexed="false"  stored="false" docValues="false" />
+   <dynamicField name="*_p_i_ni_ns_mv"  type="pint"    indexed="false"  stored="false" docValues="false" multiValued="true"/>
    
    <dynamicField name="*_p_l"  type="plong"    indexed="true"  stored="true"/>
    <dynamicField name="*_p_l_dv"  type="plong"    indexed="true"  stored="true" docValues="true"/>
    <dynamicField name="*_p_l_mv"  type="plong"    indexed="true"  stored="true" multiValued="true"/>
    <dynamicField name="*_p_l_mv_dv"  type="plong"    indexed="true"  stored="true" docValues="true" multiValued="true"/>
+   <dynamicField name="*_p_l_ni"  type="plong"    indexed="false"  stored="true" docValues="false"/>
    <dynamicField name="*_p_l_ni_dv"  type="plong"    indexed="false"  stored="true" docValues="true"/>
+   <dynamicField name="*_p_l_ni_dv_ns"  type="plong"    indexed="false"  stored="false" docValues="true" useDocValuesAsStored="false"/>
+   <dynamicField name="*_p_l_ni_mv"  type="plong"    indexed="false"  stored="true" docValues="false" multiValued="true"/>
    <dynamicField name="*_p_l_ni_mv_dv"  type="plong"    indexed="false"  stored="true" docValues="true" multiValued="true"/>
+   <dynamicField name="*_p_l_ni_ns"  type="plong"    indexed="false"  stored="false" docValues="false" />
+   <dynamicField name="*_p_l_ni_ns_mv"  type="plong"    indexed="false"  stored="false" docValues="false" multiValued="true"/>
    
    <dynamicField name="*_p_d"  type="pdouble"    indexed="true"  stored="true"/>
    <dynamicField name="*_p_d_dv"  type="pdouble"    indexed="true"  stored="true" docValues="true"/>
    <dynamicField name="*_p_d_mv"  type="pdouble"    indexed="true"  stored="true" multiValued="true"/>
    <dynamicField name="*_p_d_mv_dv"  type="pdouble"    indexed="true"  stored="true" docValues="true" multiValued="true"/>
+   <dynamicField name="*_p_d_ni"  type="pdouble"    indexed="false"  stored="true" docValues="false"/>
    <dynamicField name="*_p_d_ni_dv"  type="pdouble"    indexed="false"  stored="true" docValues="true"/>
+   <dynamicField name="*_p_d_ni_dv_ns"  type="pdouble"    indexed="false"  stored="false" docValues="true" useDocValuesAsStored="false"/>
+   <dynamicField name="*_p_d_ni_mv"  type="pdouble"    indexed="false"  stored="true" docValues="false" multiValued="true"/>
    <dynamicField name="*_p_d_ni_mv_dv"  type="pdouble"    indexed="false"  stored="true" docValues="true" multiValued="true"/>
+   <dynamicField name="*_p_d_ni_ns"  type="pdouble"    indexed="false"  stored="false" docValues="false"/>
+   <dynamicField name="*_p_d_ni_ns_mv"  type="pdouble"    indexed="false"  stored="false" docValues="false" multiValued="true"/>
    
    <dynamicField name="*_p_f"  type="pfloat"    indexed="true"  stored="true"/>
    <dynamicField name="*_p_f_dv"  type="pfloat"    indexed="true"  stored="true" docValues="true"/>
    <dynamicField name="*_p_f_mv"  type="pfloat"    indexed="true"  stored="true" multiValued="true"/>
    <dynamicField name="*_p_f_mv_dv"  type="pfloat"    indexed="true"  stored="true" docValues="true" multiValued="true"/>
+   <dynamicField name="*_p_f_ni"  type="pfloat"    indexed="false"  stored="true" docValues="false"/>
    <dynamicField name="*_p_f_ni_dv"  type="pfloat"    indexed="false"  stored="true" docValues="true"/>
+   <dynamicField name="*_p_f_ni_dv_ns"  type="pfloat"    indexed="false"  stored="false" docValues="true" useDocValuesAsStored="false"/>
+   <dynamicField name="*_p_f_ni_mv"  type="pfloat"    indexed="false"  stored="true" docValues="false" multiValued="true"/>
    <dynamicField name="*_p_f_ni_mv_dv"  type="pfloat"    indexed="false"  stored="true" docValues="true" multiValued="true"/>
+   <dynamicField name="*_p_f_ni_ns"  type="pfloat"    indexed="false"  stored="false" docValues="false"/>
+   <dynamicField name="*_p_f_ni_ns_mv"  type="pfloat"    indexed="false"  stored="false" docValues="false" multiValued="true"/>
 
    <dynamicField name="*_p_dt"  type="pdate"    indexed="true"  stored="true"/>
    <dynamicField name="*_p_dt_dv"  type="pdate"    indexed="true"  stored="true" docValues="true"/>
    <dynamicField name="*_p_dt_mv"  type="pdate"    indexed="true"  stored="true" multiValued="true"/>
    <dynamicField name="*_p_dt_mv_dv"  type="pdate"    indexed="true"  stored="true" docValues="true" multiValued="true"/>
+   <dynamicField name="*_p_dt_ni"  type="pdate"    indexed="false"  stored="true" docValues="false"/>
    <dynamicField name="*_p_dt_ni_dv"  type="pdate"    indexed="false"  stored="true" docValues="true"/>
+   <dynamicField name="*_p_dt_ni_dv_ns"  type="pdate"    indexed="false"  stored="false" docValues="true" useDocValuesAsStored="false"/>
+   <dynamicField name="*_p_dt_ni_mv"  type="pdate"    indexed="false"  stored="true" docValues="false" multiValued="true"/>
    <dynamicField name="*_p_dt_ni_mv_dv"  type="pdate"    indexed="false"  stored="true" docValues="true" multiValued="true"/>
-   
+   <dynamicField name="*_p_dt_ni_ns"  type="pdate"    indexed="false"  stored="false" docValues="false"/>
+   <dynamicField name="*_p_dt_ni_ns_mv"  type="pdate"    indexed="false"  stored="false" docValues="false" multiValued="true"/>
+
+
+   <!-- NOTE: https://issues.apache.org/jira/browse/SOLR-10438
+        
+        NOTE: because schema version=1.6, *all* DV fields default to useDocValuesAsStored="true"
+        
+        NOTE: we need to audit if this is breaking any assumptions elsewhere in the test code
+   -->
    <!-- return DV fields as  -->
    <dynamicField name="*_p_i_dv_ns"  type="pint"    indexed="true"  stored="false" docValues="true" useDocValuesAsStored="true"/>
    <dynamicField name="*_p_l_dv_ns"  type="plong"    indexed="true"  stored="false" docValues="true" useDocValuesAsStored="true"/>

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/6e5f6fab/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 36e8c10..de45844 100644
--- a/solr/core/src/test/org/apache/solr/schema/TestPointFields.java
+++ b/solr/core/src/test/org/apache/solr/schema/TestPointFields.java
@@ -16,22 +16,48 @@
  */
 package org.apache.solr.schema;
 
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
 import java.util.Locale;
 import java.util.Set;
 import java.util.TreeSet;
 
+import org.apache.lucene.document.Document;
+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.document.NumericDocValuesField;
+import org.apache.lucene.document.SortedNumericDocValuesField;
+import org.apache.lucene.document.StoredField;
+import org.apache.lucene.index.DocValues;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.IndexableField;
+import org.apache.lucene.index.LeafReader;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.index.PointValues;
+import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.search.IndexOrDocValuesQuery;
 import org.apache.lucene.search.PointRangeQuery;
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.common.SolrException;
+import org.apache.solr.common.SolrInputDocument;
+import org.apache.solr.schema.IndexSchema.DynamicField;
+import org.apache.solr.search.SolrIndexSearcher;
 import org.apache.solr.util.DateMathParser;
+import org.apache.solr.util.RefCounted;
 import org.junit.After;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
+import com.ibm.icu.text.SimpleDateFormat;
 
 /**
  * Tests for PointField functionality
@@ -57,17 +83,24 @@ public class TestPointFields extends SolrTestCaseJ4 {
   public void testIntPointFieldExactQuery() throws Exception {
     doTestIntPointFieldExactQuery("number_p_i", false);
     doTestIntPointFieldExactQuery("number_p_i_mv", false);
+    doTestIntPointFieldExactQuery("number_p_i_dv", false);
+    doTestIntPointFieldExactQuery("number_p_i_mv_dv", false);
     doTestIntPointFieldExactQuery("number_p_i_ni_dv", false);
     doTestIntPointFieldExactQuery("number_p_i_ni_ns_dv", false);
     doTestIntPointFieldExactQuery("number_p_i_ni_mv_dv", false);
   }
   
   @Test
+  public void testIntPointFieldNonSearchableExactQuery() throws Exception {
+    doTestIntPointFieldExactQuery("number_p_i_ni", false, false);
+    doTestIntPointFieldExactQuery("number_p_i_ni_ns", false, false);
+  }
+  
+  @Test
   public void testIntPointFieldReturn() throws Exception {
     testPointFieldReturn("number_p_i", "int", new String[]{"0", "-1", "2", "3", "43", "52", "-60", "74", "80", "99"});
-    clearIndex();
-    assertU(commit());
     testPointFieldReturn("number_p_i_dv_ns", "int", new String[]{"0", "-1", "2", "3", "43", "52", "-60", "74", "80", "99"});
+    testPointFieldReturn("number_p_i_ni", "int", new String[]{"0", "-1", "2", "3", "43", "52", "-60", "74", "80", "99"});
   }
   
   @Test
@@ -78,6 +111,13 @@ public class TestPointFields extends SolrTestCaseJ4 {
   }
   
   @Test
+  public void testIntPointFieldNonSearchableRangeQuery() throws Exception {
+    doTestPointFieldNonSearchableRangeQuery("number_p_i_ni", "42");
+    doTestPointFieldNonSearchableRangeQuery("number_p_i_ni_ns", "42");
+    doTestPointFieldNonSearchableRangeQuery("number_p_i_ni_ns_mv", "42", "666");
+  }
+  
+  @Test
   public void testIntPointFieldSort() throws Exception {
     doTestPointFieldSort("number_p_i", "number_p_i_dv", new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"});
   }
@@ -112,6 +152,12 @@ public class TestPointFields extends SolrTestCaseJ4 {
     testPointFieldMultiValuedExactQuery("number_p_i_mv", getSequentialStringArrayWithInts(20));
     testPointFieldMultiValuedExactQuery("number_p_i_ni_mv_dv", getSequentialStringArrayWithInts(20));
   }
+
+  @Test
+  public void testIntPointFieldMultiValuedNonSearchableExactQuery() throws Exception {
+    testPointFieldMultiValuedExactQuery("number_p_i_ni_mv", getSequentialStringArrayWithInts(20), false);
+    testPointFieldMultiValuedExactQuery("number_p_i_ni_ns_mv", getSequentialStringArrayWithInts(20), false);
+  }
   
   @Test
   public void testIntPointFieldMultiValuedReturn() throws Exception {
@@ -127,6 +173,12 @@ public class TestPointFields extends SolrTestCaseJ4 {
     testPointFieldMultiValuedRangeQuery("number_p_i_mv_dv", "int", getSequentialStringArrayWithInts(20));
   }
   
+  @Test
+  public void testIntPointFieldNotIndexed() throws Exception {
+    doTestFieldNotIndexed("number_p_i_ni", getSequentialStringArrayWithInts(10));
+    doTestFieldNotIndexed("number_p_i_ni_mv", getSequentialStringArrayWithInts(10));
+  }
+  
   //TODO MV SORT?
   @Test
   public void testIntPointFieldMultiValuedFacetField() throws Exception {
@@ -178,19 +230,24 @@ public class TestPointFields extends SolrTestCaseJ4 {
     doTestFloatPointFieldExactQuery("number_d");
     doTestFloatPointFieldExactQuery("number_p_d");
     doTestFloatPointFieldExactQuery("number_p_d_mv");
+    doTestFloatPointFieldExactQuery("number_p_d_dv");
+    doTestFloatPointFieldExactQuery("number_p_d_mv_dv");
     doTestFloatPointFieldExactQuery("number_p_d_ni_dv");
     doTestFloatPointFieldExactQuery("number_p_d_ni_ns_dv");
+    doTestFloatPointFieldExactQuery("number_p_d_ni_dv_ns");
     doTestFloatPointFieldExactQuery("number_p_d_ni_mv_dv");
   }
   
   @Test
+  public void testDoublePointFieldNonSearchableExactQuery() throws Exception {
+    doTestFloatPointFieldExactQuery("number_p_d_ni", false);
+    doTestFloatPointFieldExactQuery("number_p_d_ni_ns", false);
+  }
+ 
+  @Test
   public void testDoublePointFieldReturn() throws Exception {
     testPointFieldReturn("number_p_d", "double", new String[]{"0.0", "1.2", "2.5", "3.02", "0.43", "5.2", "6.01", "74.0", "80.0", "9.9"});
-    clearIndex();
-    assertU(commit());
     testPointFieldReturn("number_p_d_dv_ns", "double", new String[]{"0.0", "1.2", "2.5", "3.02", "0.43", "5.2", "6.01", "74.0", "80.0", "9.9"});
-    clearIndex();
-    assertU(commit());
     String[] arr = new String[atLeast(10)];
     for (int i = 0; i < arr.length; i++) {
       double rand = random().nextDouble() * 10;
@@ -207,6 +264,14 @@ public class TestPointFields extends SolrTestCaseJ4 {
   }
   
   @Test
+  public void testDoubleFieldNonSearchableRangeQuery() throws Exception {
+    doTestPointFieldNonSearchableRangeQuery("number_p_d_ni", "42.3");
+    doTestPointFieldNonSearchableRangeQuery("number_p_d_ni_ns", "42.3");
+    doTestPointFieldNonSearchableRangeQuery("number_p_d_ni_ns_mv", "42.3", "-66.6");
+  }
+  
+  
+  @Test
   public void testDoublePointFieldSort() throws Exception {
     String[] arr = getRandomStringArrayWithDoubles(10, true);
     doTestPointFieldSort("number_p_d", "number_p_d_dv", arr);
@@ -245,6 +310,12 @@ public class TestPointFields extends SolrTestCaseJ4 {
   }
   
   @Test
+  public void testDoublePointFieldMultiValuedNonSearchableExactQuery() throws Exception {
+    testPointFieldMultiValuedExactQuery("number_p_d_ni_mv", getRandomStringArrayWithDoubles(20, false), false);
+    testPointFieldMultiValuedExactQuery("number_p_d_ni_ns_mv", getRandomStringArrayWithDoubles(20, false), false);
+  }
+  
+  @Test
   public void testDoublePointFieldMultiValuedReturn() throws Exception {
     testPointFieldMultiValuedReturn("number_p_d_mv", "double", getSequentialStringArrayWithDoubles(20));
     testPointFieldMultiValuedReturn("number_p_d_ni_mv_dv", "double", getSequentialStringArrayWithDoubles(20));
@@ -295,6 +366,12 @@ public class TestPointFields extends SolrTestCaseJ4 {
     testMultiValuedFloatPointFieldsAtomicUpdates("number_p_d_dv_ns_mv", "double");
   }
   
+  @Test
+  public void testDoublePointFieldNotIndexed() throws Exception {
+    doTestFieldNotIndexed("number_p_d_ni", getSequentialStringArrayWithDoubles(10));
+    doTestFieldNotIndexed("number_p_d_ni_mv", getSequentialStringArrayWithDoubles(10));
+  }
+  
   
   private void doTestFloatPointFieldsAtomicUpdates(String field, String type) throws Exception {
     assertU(adoc(sdoc("id", "1", field, "1.1234")));
@@ -342,19 +419,24 @@ public class TestPointFields extends SolrTestCaseJ4 {
   public void testFloatPointFieldExactQuery() throws Exception {
     doTestFloatPointFieldExactQuery("number_p_f");
     doTestFloatPointFieldExactQuery("number_p_f_mv");
+    doTestFloatPointFieldExactQuery("number_p_f_dv");
+    doTestFloatPointFieldExactQuery("number_p_f_mv_dv");
     doTestFloatPointFieldExactQuery("number_p_f_ni_dv");
     doTestFloatPointFieldExactQuery("number_p_f_ni_ns_dv");
+    doTestFloatPointFieldExactQuery("number_p_f_ni_dv_ns");
     doTestFloatPointFieldExactQuery("number_p_f_ni_mv_dv");
   }
   
   @Test
+  public void testFloatPointFieldNonSearchableExactQuery() throws Exception {
+    doTestFloatPointFieldExactQuery("number_p_f_ni", false);
+    doTestFloatPointFieldExactQuery("number_p_f_ni_ns", false);
+  }
+  
+  @Test
   public void testFloatPointFieldReturn() throws Exception {
     testPointFieldReturn("number_p_f", "float", new String[]{"0.0", "-1.2", "2.5", "3.02", "0.43", "5.2", "6.01", "74.0", "80.0", "9.9"});
-    clearIndex();
-    assertU(commit());
     testPointFieldReturn("number_p_f_dv_ns", "float", new String[]{"0.0", "-1.2", "2.5", "3.02", "0.43", "5.2", "6.01", "74.0", "80.0", "9.9"});
-    clearIndex();
-    assertU(commit());
     String[] arr = new String[atLeast(10)];
     for (int i = 0; i < arr.length; i++) {
       float rand = random().nextFloat() * 10;
@@ -371,6 +453,13 @@ public class TestPointFields extends SolrTestCaseJ4 {
   }
   
   @Test
+  public void testFloatPointFieldNonSearchableRangeQuery() throws Exception {
+    doTestPointFieldNonSearchableRangeQuery("number_p_f_ni", "42.3");
+    doTestPointFieldNonSearchableRangeQuery("number_p_f_ni_ns", "42.3");
+    doTestPointFieldNonSearchableRangeQuery("number_p_f_ni_ns_mv", "42.3", "-66.6");
+  }
+  
+  @Test
   public void testFloatPointFieldSort() throws Exception {
     String[] arr = getRandomStringArrayWithFloats(10, true);
     doTestPointFieldSort("number_p_f", "number_p_f_dv", arr);
@@ -409,6 +498,12 @@ public class TestPointFields extends SolrTestCaseJ4 {
   }
   
   @Test
+  public void testFloatPointFieldMultiValuedNonSearchableExactQuery() throws Exception {
+    testPointFieldMultiValuedExactQuery("number_p_f_ni_mv", getRandomStringArrayWithFloats(20, false), false);
+    testPointFieldMultiValuedExactQuery("number_p_f_ni_ns_mv", getRandomStringArrayWithFloats(20, false), false);
+  }
+  
+  @Test
   public void testFloatPointFieldMultiValuedReturn() throws Exception {
     testPointFieldMultiValuedReturn("number_p_f_mv", "float", getSequentialStringArrayWithDoubles(20));
     testPointFieldMultiValuedReturn("number_p_f_ni_mv_dv", "float", getSequentialStringArrayWithDoubles(20));
@@ -467,22 +562,35 @@ public class TestPointFields extends SolrTestCaseJ4 {
     doTestSetQueries("number_p_f_ni_dv", getRandomStringArrayWithFloats(10, false), false);
   }
   
+  @Test
+  public void testFloatPointFieldNotIndexed() throws Exception {
+    doTestFieldNotIndexed("number_p_f_ni", getSequentialStringArrayWithDoubles(10));
+    doTestFieldNotIndexed("number_p_f_ni_mv", getSequentialStringArrayWithDoubles(10));
+  }
+  
   // Long
   
   @Test
   public void testLongPointFieldExactQuery() throws Exception {
     doTestIntPointFieldExactQuery("number_p_l", true);
     doTestIntPointFieldExactQuery("number_p_l_mv", true);
+    doTestIntPointFieldExactQuery("number_p_l_dv", true);
+    doTestIntPointFieldExactQuery("number_p_l_mv_dv", true);
     doTestIntPointFieldExactQuery("number_p_l_ni_dv", true);
     doTestIntPointFieldExactQuery("number_p_l_ni_ns_dv", true);
+    doTestIntPointFieldExactQuery("number_p_l_ni_dv_ns", true);
     doTestIntPointFieldExactQuery("number_p_l_ni_mv_dv", true);
   }
   
   @Test
+  public void testLongPointFieldNonSearchableExactQuery() throws Exception {
+    doTestIntPointFieldExactQuery("number_p_l_ni", true, false);
+    doTestIntPointFieldExactQuery("number_p_l_ni_ns", true, false);
+  }
+  
+  @Test
   public void testLongPointFieldReturn() throws Exception {
     testPointFieldReturn("number_p_l", "long", new String[]{"0", "-1", "2", "3", "43", "52", "-60", "74", "80", "99", String.valueOf(Long.MAX_VALUE)});
-    clearIndex();
-    assertU(commit());
     testPointFieldReturn("number_p_l_dv_ns", "long", new String[]{"0", "-1", "2", "3", "43", "52", "-60", "74", "80", "99", String.valueOf(Long.MAX_VALUE)});
   }
   
@@ -494,6 +602,13 @@ public class TestPointFields extends SolrTestCaseJ4 {
   }
   
   @Test
+  public void testLongPointFieldNonSearchableRangeQuery() throws Exception {
+    doTestPointFieldNonSearchableRangeQuery("number_p_l_ni", "3333333333");
+    doTestPointFieldNonSearchableRangeQuery("number_p_l_ni_ns", "3333333333");
+    doTestPointFieldNonSearchableRangeQuery("number_p_l_ni_ns_mv", "3333333333", "-4444444444");
+  }
+
+  @Test
   public void testLongPointFieldSort() throws Exception {
     doTestPointFieldSort("number_p_l", "number_p_l_dv", new String[]{String.valueOf(Integer.MIN_VALUE), 
         "1", "2", "3", "4", "5", "6", "7", 
@@ -533,6 +648,12 @@ public class TestPointFields extends SolrTestCaseJ4 {
   }
   
   @Test
+  public void testLongPointFieldMultiValuedNonSearchableExactQuery() throws Exception {
+    testPointFieldMultiValuedExactQuery("number_p_l_ni_mv", getSequentialStringArrayWithInts(20), false);
+    testPointFieldMultiValuedExactQuery("number_p_l_ni_ns_mv", getSequentialStringArrayWithInts(20), false);
+  }
+  
+  @Test
   public void testLongPointFieldMultiValuedReturn() throws Exception {
     testPointFieldMultiValuedReturn("number_p_l_mv", "long", getSequentialStringArrayWithInts(20));
     testPointFieldMultiValuedReturn("number_p_l_ni_mv_dv", "long", getSequentialStringArrayWithInts(20));
@@ -588,6 +709,12 @@ public class TestPointFields extends SolrTestCaseJ4 {
     doTestSetQueries("number_p_l_mv", getRandomStringArrayWithLongs(10, false), true);
     doTestSetQueries("number_p_l_ni_dv", getRandomStringArrayWithLongs(10, false), false);
   }
+  
+  @Test
+  public void testLongPointFieldNotIndexed() throws Exception {
+    doTestFieldNotIndexed("number_p_l_ni", getSequentialStringArrayWithInts(10));
+    doTestFieldNotIndexed("number_p_l_ni_mv", getSequentialStringArrayWithInts(10));
+  }
 
   // Date
 
@@ -595,18 +722,24 @@ public class TestPointFields extends SolrTestCaseJ4 {
   public void testDatePointFieldExactQuery() throws Exception {
     doTestDatePointFieldExactQuery("number_p_dt", "1995-12-31T23:59:59Z");
     doTestDatePointFieldExactQuery("number_p_dt_mv", "2015-12-31T23:59:59Z-1DAY");
+    doTestDatePointFieldExactQuery("number_p_dt_dv", "2000-12-31T23:59:59Z+3DAYS");
+    doTestDatePointFieldExactQuery("number_p_dt_mv_dv", "2000-12-31T23:59:59Z+3DAYS");
     doTestDatePointFieldExactQuery("number_p_dt_ni_dv", "2000-12-31T23:59:59Z+3DAYS");
     doTestDatePointFieldExactQuery("number_p_dt_ni_ns_dv", "1995-12-31T23:59:59Z-1MONTH");
     doTestDatePointFieldExactQuery("number_p_dt_ni_mv_dv", "1995-12-31T23:59:59Z+2MONTHS");
   }
+  @Test
+  public void testDatePointFieldNonSearchableExactQuery() throws Exception {
+    doTestDatePointFieldExactQuery("number_p_dt_ni", "1995-12-31T23:59:59Z", false);
+    doTestDatePointFieldExactQuery("number_p_dt_ni_ns", "1995-12-31T23:59:59Z", false);
+
+  }
 
   @Test
   public void testDatePointFieldReturn() throws Exception {
     testPointFieldReturn("number_p_dt", "date",
         new String[]{"1995-12-31T23:59:59Z", "1994-02-28T23:59:59Z",
             "2015-12-31T23:59:59Z", "2000-10-31T23:59:59Z", "1999-12-31T12:59:59Z"});
-    clearIndex();
-    assertU(commit());
     testPointFieldReturn("number_p_dt_dv_ns", "date",
         new String[]{"1995-12-31T23:59:59Z", "1994-02-28T23:59:59Z",
             "2015-12-31T23:59:59Z", "2000-10-31T23:59:59Z", "1999-12-31T12:59:59Z"});
@@ -617,6 +750,13 @@ public class TestPointFields extends SolrTestCaseJ4 {
     doTestDatePointFieldRangeQuery("number_p_dt");
     doTestDatePointFieldRangeQuery("number_p_dt_ni_ns_dv");
   }
+  
+  @Test
+  public void testDatePointFieldNonSearchableRangeQuery() throws Exception {
+    doTestPointFieldNonSearchableRangeQuery("number_p_dt_ni", "1995-12-31T23:59:59Z");
+    doTestPointFieldNonSearchableRangeQuery("number_p_dt_ni_ns", "1995-12-31T23:59:59Z");
+    doTestPointFieldNonSearchableRangeQuery("number_p_dt_ni_ns_mv", "1995-12-31T23:59:59Z", "2000-10-31T23:59:59Z");
+  }
 
   @Test
   public void testDatePointFieldSort() throws Exception {
@@ -654,6 +794,12 @@ public class TestPointFields extends SolrTestCaseJ4 {
   }
 
   @Test
+  public void testDatePointFieldMultiValuedNonSearchableExactQuery() throws Exception {
+    testPointFieldMultiValuedExactQuery("number_p_dt_ni_mv", getSequentialStringArrayWithDates(20), false);
+    testPointFieldMultiValuedExactQuery("number_p_dt_ni_ns_mv", getSequentialStringArrayWithDates(20), false);
+  }
+  
+  @Test
   public void testDatePointFieldMultiValuedReturn() throws Exception {
     testPointFieldMultiValuedReturn("number_p_dt_mv", "date", getSequentialStringArrayWithDates(20));
     testPointFieldMultiValuedReturn("number_p_dt_ni_mv_dv", "date", getSequentialStringArrayWithDates(20));
@@ -709,6 +855,13 @@ public class TestPointFields extends SolrTestCaseJ4 {
     doTestSetQueries("number_p_dt_ni_dv", getRandomStringArrayWithDates(10, false), false);
   }
   
+  
+  @Test
+  public void testDatePointFieldNotIndexed() throws Exception {
+    doTestFieldNotIndexed("number_p_dt_ni", getSequentialStringArrayWithDates(10));
+    doTestFieldNotIndexed("number_p_dt_ni_mv", getSequentialStringArrayWithDates(10));
+  }
+  
   @Test
   public void testIndexOrDocValuesQuery() throws Exception {
     String[] fieldTypeNames = new String[]{"_p_i", "_p_l", "_p_d", "_p_f"};
@@ -730,6 +883,30 @@ public class TestPointFields extends SolrTestCaseJ4 {
     }
   }
   
+  public void testInternals() throws IOException {
+    String[] types = new String[]{"i", "l", "f", "d"};
+    String[] suffixes = new String[]{"", "_dv", "_mv", "_mv_dv", "_ni", "_ni_dv", "_ni_dv_ns", "_ni_mv", "_ni_mv_dv", "_ni_ns", "_ni_ns_mv", "_dv_ns", "_ni_ns_dv", "_dv_ns_mv"};
+    Set<String> typesTested = new HashSet<>();
+    for (String type:types) {
+      for (String suffix:suffixes) {
+        doTestInternals("number_p_" + type + suffix, getSequentialStringArrayWithInts(10));
+        typesTested.add("*_p_" + type + suffix);
+      }
+    }
+    for (String suffix:suffixes) {
+      doTestInternals("number_p_dt" + suffix, getSequentialStringArrayWithDates(10));
+      typesTested.add("*_p_dt" + suffix);
+    }
+    
+    Set<String> typesToTest = new HashSet<>();
+    for (DynamicField dynField:h.getCore().getLatestSchema().getDynamicFields()) {
+      if (dynField.getPrototype().getType() instanceof PointField) {
+        typesToTest.add(dynField.getRegex());
+      }
+    }
+    assertEquals("Missing types in the test", typesTested, typesToTest);
+  }
+  
   // Helper methods
   
   private String[] getRandomStringArrayWithDoubles(int length, boolean sorted) {
@@ -870,24 +1047,61 @@ public class TestPointFields extends SolrTestCaseJ4 {
     return stringArr;
   }
   
-  private void doTestIntPointFieldExactQuery(String field, boolean testLong) throws Exception {
+  private void doTestFieldNotIndexed(String field, String[] values) throws IOException {
+    assert values.length == 10;
+    // test preconditions
+    SchemaField sf = h.getCore().getLatestSchema().getField(field);
+    assertFalse("Field should be indexed=false", sf.indexed());
+    assertFalse("Field should be docValues=false", sf.hasDocValues());
+    
+    for (int i=0; i < 10; i++) {
+      assertU(adoc("id", String.valueOf(i), field, values[i]));
+    }
+    assertU(commit());
+    assertQ(req("q", "*:*"), "//*[@numFound='10']");
+    assertQ("Can't search on index=false docValues=false field", req("q", field + ":[* TO *]"), "//*[@numFound='0']");
+    IndexReader ir;
+    RefCounted<SolrIndexSearcher> ref = null;
+    try {
+      ref = h.getCore().getSearcher();
+      ir = ref.get().getIndexReader();
+      assertEquals("Field " + field + " should have no point values", 0, PointValues.size(ir, field));
+    } finally {
+      ref.decref();
+    }
+  }
+  
+   
+  private void doTestIntPointFieldExactQuery(final String field, final boolean testLong) throws Exception {
+    doTestIntPointFieldExactQuery(field, testLong, true);
+  }
+
+  /**
+   * @param field the field to use for indexing and searching against
+   * @param testLong set to true if "field" is expected to support long values, false if only integers
+   * @param searchable set to true if searches against "field" should succeed, false if field is only stored and searches should always get numFound=0
+   */
+  private void doTestIntPointFieldExactQuery(final String field, final boolean testLong, final boolean searchable) throws Exception {
+    final String MATCH_ONE = "//*[@numFound='" + (searchable ? "1" : "0") + "']";
+    final String MATCH_TWO = "//*[@numFound='" + (searchable ? "2" : "0") + "']";
+
     for (int i=0; i < 10; i++) {
       assertU(adoc("id", String.valueOf(i), field, String.valueOf(i+1)));
     }
     assertU(commit());
     for (int i = 0; i < 10; i++) {
       assertQ(req("q", field + ":"+(i+1), "fl", "id, " + field), 
-          "//*[@numFound='1']");
+          MATCH_ONE);
     }
     
     for (int i = 0; i < 10; i++) {
-      assertQ(req("q", field + ":" + (i+1) + " OR " + field + ":" + ((i+1)%10 + 1)), "//*[@numFound='2']");
+      assertQ(req("debug", "true", "q", field + ":" + (i+1) + " OR " + field + ":" + ((i+1)%10 + 1)), MATCH_TWO);
     }
     
     assertU(adoc("id", String.valueOf(Integer.MAX_VALUE), field, String.valueOf(Integer.MAX_VALUE)));
     assertU(commit());
     assertQ(req("q", field + ":"+Integer.MAX_VALUE, "fl", "id, " + field), 
-        "//*[@numFound='1']");
+        MATCH_ONE);
     
     if (testLong) {
       for (long i = (long)Integer.MAX_VALUE; i < (long)Integer.MAX_VALUE + 10; i++) {
@@ -896,12 +1110,12 @@ public class TestPointFields extends SolrTestCaseJ4 {
       assertU(commit());
       for (long i = (long)Integer.MAX_VALUE; i < (long)Integer.MAX_VALUE + 10; i++) {
         assertQ(req("q", field + ":"+(i+1), "fl", "id, " + field), 
-            "//*[@numFound='1']");
+                MATCH_ONE);
       }
       assertU(adoc("id", String.valueOf(Long.MAX_VALUE), field, String.valueOf(Long.MAX_VALUE)));
       assertU(commit());
       assertQ(req("q", field + ":"+Long.MAX_VALUE, "fl", "id, " + field), 
-          "//*[@numFound='1']");
+              MATCH_ONE);
     }
     
     clearIndex();
@@ -937,6 +1151,21 @@ public class TestPointFields extends SolrTestCaseJ4 {
             "//doc/" + type + "[@name='" + field + "'][.='" + values[i] + "']");
       }
     }
+    clearIndex();
+    assertU(commit());
+  }
+
+  private void doTestPointFieldNonSearchableRangeQuery(String fieldName, String... values) throws Exception {
+    for (int i = 9; i >= 0; i--) {
+      SolrInputDocument doc = sdoc("id", String.valueOf(i));
+      for (String value : values) {
+        doc.addField(fieldName, value);
+      }
+      assertU(adoc(doc));
+    }
+    assertU(commit());
+    assertQ(req("q", fieldName + ":[* TO *]", "fl", "id, " + fieldName, "sort", "id asc"), 
+            "//*[@numFound='0']");
   }
 
   private void doTestIntPointFieldRangeQuery(String fieldName, String type, boolean testLong) throws Exception {
@@ -1185,8 +1414,23 @@ public class TestPointFields extends SolrTestCaseJ4 {
         req("q", "*:*", "fl", "id, " + field, "stats", "true", "stats.field", field), 
         SolrException.ErrorCode.BAD_REQUEST);
   }
-  
-  private void testPointFieldMultiValuedExactQuery(String fieldName, String[] numbers) throws Exception {
+
+
+  private void testPointFieldMultiValuedExactQuery(final String fieldName, final String[] numbers) throws Exception {
+    testPointFieldMultiValuedExactQuery(fieldName, numbers, true);
+  }
+
+  /**
+   * @param fieldName the field to use for indexing and searching against
+   * @param numbers list of 20 values to index in 10 docs (pairwise)
+   * @param searchable set to true if searches against "field" should succeed, false if field is only stored and searches should always get numFound=0
+   */
+  private void testPointFieldMultiValuedExactQuery(final String fieldName, final String[] numbers,
+                                                   final boolean searchable) throws Exception {
+    
+    final String MATCH_ONE = "//*[@numFound='" + (searchable ? "1" : "0") + "']";
+    final String MATCH_TWO = "//*[@numFound='" + (searchable ? "2" : "0") + "']";
+    
     assert numbers != null && numbers.length == 20;
     assertTrue(h.getCore().getLatestSchema().getField(fieldName).multiValued());
     assertTrue(h.getCore().getLatestSchema().getField(fieldName).getType() instanceof PointField);
@@ -1197,18 +1441,20 @@ public class TestPointFields extends SolrTestCaseJ4 {
     for (int i = 0; i < 20; i++) {
       if (h.getCore().getLatestSchema().getField(fieldName).getType() instanceof DatePointField) {
         assertQ(req("q", fieldName + ":\"" + numbers[i] + "\""),
-            "//*[@numFound='1']");
+                MATCH_ONE);
       } else {
         assertQ(req("q", fieldName + ":" + numbers[i].replace("-", "\\-")),
-            "//*[@numFound='1']");
+                MATCH_ONE);
       }
     }
     
     for (int i = 0; i < 20; i++) {
       if (h.getCore().getLatestSchema().getField(fieldName).getType() instanceof DatePointField) {
-        assertQ(req("q", fieldName + ":\"" + numbers[i] + "\"" + " OR " + fieldName + ":\"" + numbers[(i+1)%10]+"\""), "//*[@numFound='2']");
+        assertQ(req("q", fieldName + ":\"" + numbers[i] + "\"" + " OR " + fieldName + ":\"" + numbers[(i+1)%10]+"\""),
+                MATCH_TWO);
       } else {
-        assertQ(req("q", fieldName + ":" + numbers[i].replace("-", "\\-") + " OR " + fieldName + ":" + numbers[(i+1)%10].replace("-", "\\-")), "//*[@numFound='2']");
+        assertQ(req("q", fieldName + ":" + numbers[i].replace("-", "\\-") + " OR " + fieldName + ":" + numbers[(i+1)%10].replace("-", "\\-")),
+                MATCH_TWO);
       }
     }
   }
@@ -1248,7 +1494,7 @@ public class TestPointFields extends SolrTestCaseJ4 {
     }
     assertQ(req("q", "*:*", "fl", "id, " + fieldName, "sort","id asc"), expected);
   }
-  
+
   private void testPointFieldMultiValuedRangeQuery(String fieldName, String type, String[] numbers) throws Exception {
     assert numbers != null && numbers.length == 20;
     assertTrue(h.getCore().getLatestSchema().getField(fieldName).multiValued());
@@ -1605,20 +1851,32 @@ public class TestPointFields extends SolrTestCaseJ4 {
         "//result/doc[1]/" + type + "[@name='" + field + "'][.='3']");
   }
 
-  private void doTestFloatPointFieldExactQuery(String field) throws Exception {
+  
+  private void doTestFloatPointFieldExactQuery(final String field) throws Exception {
+    doTestFloatPointFieldExactQuery(field, true);
+  }
+  /**
+   * @param field the field to use for indexing and searching against
+   * @param searchable set to true if searches against "field" should succeed, false if field is only stored and searches should always get numFound=0
+   */
+  private void doTestFloatPointFieldExactQuery(String field, final boolean searchable) throws Exception {
+    final String MATCH_ONE = "//*[@numFound='" + (searchable ? "1" : "0") + "']";
+    final String MATCH_TWO = "//*[@numFound='" + (searchable ? "2" : "0") + "']";
+    
     for (int i=0; i < 10; i++) {
       assertU(adoc("id", String.valueOf(i), field, String.valueOf(i + "." + i)));
     }
     assertU(commit());
     for (int i = 0; i < 9; i++) {
       assertQ(req("q", field + ":"+(i+1) + "." + (i+1), "fl", "id, " + field), 
-          "//*[@numFound='1']");
+              MATCH_ONE);
     }
     
     for (int i = 0; i < 9; i++) {
       String num1 = (i+1) + "." + (i+1);
       String num2 = ((i+1)%9 + 1) + "." + ((i+1)%9 + 1);
-      assertQ(req("q", field + ":" + num1 + " OR " + field + ":" + num2), "//*[@numFound='2']");
+      assertQ(req("q", field + ":" + num1 + " OR " + field + ":" + num2),
+              MATCH_TWO);
     }
     
     clearIndex();
@@ -1628,7 +1886,7 @@ public class TestPointFields extends SolrTestCaseJ4 {
       assertU(adoc("id", "random_number ", field, String.valueOf(rand))); //always the same id to override
       assertU(commit());
       assertQ(req("q", field + ":" + rand, "fl", "id, " + field), 
-          "//*[@numFound='1']");
+              MATCH_ONE);
     }
     clearIndex();
     assertU(commit());
@@ -2008,8 +2266,20 @@ public class TestPointFields extends SolrTestCaseJ4 {
         "//lst[@name='facet_counts']/lst[@name='facet_ranges']/lst[@name='" + nonDocValuesField + "']/lst[@name='counts']/int[@name='-10'][.='0']");
   }
 
-
-  private void doTestDatePointFieldExactQuery(String field, String baseDate) throws Exception {
+  
+  private void doTestDatePointFieldExactQuery(final String field, final String baseDate) throws Exception {
+    doTestDatePointFieldExactQuery(field, baseDate, true);
+  }
+  
+  /**
+   * @param field the field to use for indexing and searching against
+   * @param baseDate basic value to use for indexing and searching
+   * @param searchable set to true if searches against "field" should succeed, false if field is only stored and searches should always get numFound=0
+   */
+  private void doTestDatePointFieldExactQuery(final String field, final String baseDate, final boolean searchable) throws Exception {
+    final String MATCH_ONE = "//*[@numFound='" + (searchable ? "1" : "0") + "']";
+    final String MATCH_TWO = "//*[@numFound='" + (searchable ? "2" : "0") + "']";
+    
     for (int i=0; i < 10; i++) {
       assertU(adoc("id", String.valueOf(i), field, String.format(Locale.ROOT, "%s+%dMINUTES", baseDate, i+1)));
     }
@@ -2017,20 +2287,21 @@ public class TestPointFields extends SolrTestCaseJ4 {
     for (int i = 0; i < 10; i++) {
       String date = String.format(Locale.ROOT, "%s+%dMINUTES", baseDate, i+1);
       assertQ(req("q", field + ":\""+date+"\"", "fl", "id, " + field),
-          "//*[@numFound='1']");
+              MATCH_ONE);
     }
 
     for (int i = 0; i < 10; i++) {
       String date1 = String.format(Locale.ROOT, "%s+%dMINUTES", baseDate, i+1);
       String date2 = String.format(Locale.ROOT, "%s+%dMINUTES", baseDate, ((i+1)%10 + 1));
       assertQ(req("q", field + ":\"" + date1 + "\""
-          + " OR " + field + ":\"" + date2 + "\""), "//*[@numFound='2']");
+                  + " OR " + field + ":\"" + date2 + "\""),
+              MATCH_TWO);
     }
 
     clearIndex();
     assertU(commit());
   }
-
+  
   private void doTestDatePointFieldRangeQuery(String fieldName) throws Exception {
     String baseDate = "1995-12-31T10:59:59Z";
     for (int i = 9; i >= 0; i--) {
@@ -2362,6 +2633,204 @@ public class TestPointFields extends SolrTestCaseJ4 {
         "count(//result/doc[1]/arr[@name='" + field + "']/" + type + ")=0");
 
   }
+  
+  private void doTestInternals(String field, String[] values) throws IOException {
+    assertTrue(h.getCore().getLatestSchema().getField(field).getType() instanceof PointField);
+    for (int i=0; i < 10; i++) {
+      assertU(adoc("id", String.valueOf(i), field, values[i]));
+    }
+    assertU(commit());
+    IndexReader ir;
+    RefCounted<SolrIndexSearcher> ref = null;
+    SchemaField sf = h.getCore().getLatestSchema().getField(field);
+    boolean ignoredField = !(sf.indexed() || sf.stored() || sf.hasDocValues());
+    try {
+      ref = h.getCore().getSearcher();
+      SolrIndexSearcher searcher = ref.get(); 
+      ir = searcher.getIndexReader();
+      if (sf.indexed()) {
+        assertEquals("Field " + field + " should have point values", 10, PointValues.size(ir, field));
+      } else {
+        assertEquals("Field " + field + " should have no point values", 0, PointValues.size(ir, field));
+      }
+      if (ignoredField) {
+        assertTrue("Field " + field + " should not have docValues",
+            DocValues.getSortedNumeric(searcher.getSlowAtomicReader(), field).nextDoc() == DocIdSetIterator.NO_MORE_DOCS);
+        assertTrue("Field " + field + " should not have docValues", 
+            DocValues.getNumeric(searcher.getSlowAtomicReader(), field).nextDoc() == DocIdSetIterator.NO_MORE_DOCS);
+        assertTrue("Field " + field + " should not have docValues", 
+            DocValues.getSorted(searcher.getSlowAtomicReader(), field).nextDoc() == DocIdSetIterator.NO_MORE_DOCS);
+        assertTrue("Field " + field + " should not have docValues", 
+            DocValues.getBinary(searcher.getSlowAtomicReader(), field).nextDoc() == DocIdSetIterator.NO_MORE_DOCS);
+      } else {
+        if (sf.hasDocValues()) {
+          if (sf.multiValued()) {
+            assertFalse("Field " + field + " should have docValues", 
+                DocValues.getSortedNumeric(searcher.getSlowAtomicReader(), field).nextDoc() == DocIdSetIterator.NO_MORE_DOCS);
+          } else {
+            assertFalse("Field " + field + " should have docValues", 
+                DocValues.getNumeric(searcher.getSlowAtomicReader(), field).nextDoc() == DocIdSetIterator.NO_MORE_DOCS);
+          }
+        } else {
+          expectThrows(IllegalStateException.class, ()->DocValues.getSortedNumeric(searcher.getSlowAtomicReader(), field));
+          expectThrows(IllegalStateException.class, ()->DocValues.getNumeric(searcher.getSlowAtomicReader(), field));
+        }
+        expectThrows(IllegalStateException.class, ()->DocValues.getSorted(searcher.getSlowAtomicReader(), field));
+        expectThrows(IllegalStateException.class, ()->DocValues.getBinary(searcher.getSlowAtomicReader(), field));
+      }
+      for (LeafReaderContext leave:ir.leaves()) {
+        LeafReader reader = leave.reader();
+        for (int i = 0; i < reader.numDocs(); i++) {
+          Document doc = reader.document(i, Collections.singleton(field));
+          if (sf.stored()) {
+            assertNotNull(doc.get(field));
+          } else {
+            assertNull(doc.get(field));
+          }
+        }
+      }
+    } finally {
+      ref.decref();
+    }
+  }
+
+  public void testNonReturnable() throws Exception {
+    
+    doTestNonReturnable("foo_p_i_ni_ns", "42");
+    doTestNonReturnable("foo_p_i_ni_ns_mv", "42", "666");
+
+    doTestNonReturnable("foo_p_l_ni_ns", "3333333333");
+    doTestNonReturnable("foo_p_l_ni_ns_mv", "3333333333", "-4444444444");
+
+    doTestNonReturnable("foo_p_f_ni_ns", "42.3");
+    doTestNonReturnable("foo_p_f_ni_ns_mv", "42.3", "-66.6");
+    
+    doTestNonReturnable("foo_p_d_ni_ns", "42.3");
+    doTestNonReturnable("foo_p_d_ni_ns_mv", "42.3", "-66.6");
+
+    doTestNonReturnable("foo_p_dt_ni_ns", "1995-12-31T23:59:59Z");
+    doTestNonReturnable("foo_p_dt_ni_ns_mv", "1995-12-31T23:59:59Z", "2000-12-31T23:59:59Z+3DAYS");
+
+  }
+
+  @AwaitsFix(bugUrl="https://issues.apache.org/jira/browse/SOLR-10437")
+  public void testNonReturnableDocValues() throws Exception {
+    // TODO: once SOLR-10437 is resolved, this test method can be folded into testNonReturnable()
+    
+    // these fields are stored=false, docValues=true, useDocValuesAsStored=false and yet they are
+    // still returned and failing this test.
+    
+    doTestNonReturnable("foo_p_i_ni_dv_ns", "42");
+    doTestNonReturnable("foo_p_l_ni_dv_ns", "3333333333");
+    doTestNonReturnable("foo_p_f_ni_dv_ns", "42.3");
+    doTestNonReturnable("foo_p_d_ni_dv_ns", "42.3");
+    doTestNonReturnable("foo_p_dt_ni_dv_ns", "1995-12-31T23:59:59Z");
+  }
+
+  public void doTestNonReturnable(final String fieldName, final String... values) throws Exception {
+    for (int i=0; i < 10; i++) {
+      SolrInputDocument doc = sdoc("id", String.valueOf(i));
+      for (String value : values) {
+        doc.addField(fieldName, value);
+      }
+      assertU(adoc(doc));
+    }
+    assertU(commit());
+    assertQ(req("q", "*:*", "rows", "100", "fl", "id," + fieldName), 
+            "//*[@numFound='10']",
+            "count(//doc)=10", // exactly 10 docs in response
+            "count(//doc/*)=10", // exactly 10 fields across all docs
+            "count(//doc/*[@name!='id'])=0"); // no field in any doc other then 'id'
+    clearIndex();
+    assertU(commit());
+  }
+
+  public void testWhiteboxCreateFields() throws Exception {
+    // TODO: we should have a "coverage" assert that we're looping over all the dynamic (point) fields in the schema
+    
+    String[] typeNames = new String[]{"i", "l", "f", "d", "dt"};
+    String[] suffixes = new String[]{"", "_dv", "_mv", "_mv_dv", "_ni", "_ni_dv", "_ni_dv_ns", "_ni_mv", "_ni_mv_dv", "_ni_ns", "_ni_ns_mv", "_dv_ns", "_ni_ns_dv", "_dv_ns_mv"};
+    Class<?>[] expectedClasses = new Class[]{IntPoint.class, LongPoint.class, FloatPoint.class, DoublePoint.class, LongPoint.class};
+    
+    Date dateToTest = new Date();
+    Object[][] values = new Object[][] {
+      {42, "42"},
+      {42, "42"},
+      {42.123, "42.123"},
+      {12345.6789, "12345.6789"},
+      {dateToTest, new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ROOT).format(dateToTest), "NOW"} // "NOW" won't be equal to the other dates
+    };
+    
+    Set<String> typesTested = new HashSet<>();
+    for (int i = 0; i < typeNames.length; i++) {
+      for (String suffix:suffixes) {
+        doWhiteboxCreateFields("whitebox_p_" + typeNames[i] + suffix, expectedClasses[i], values[i]);
+        typesTested.add("*_p_" + typeNames[i] + suffix);
+      }
+    }
+    Set<String> typesToTest = new HashSet<>();
+    for (DynamicField dynField:h.getCore().getLatestSchema().getDynamicFields()) {
+      if (dynField.getPrototype().getType() instanceof PointField) {
+        typesToTest.add(dynField.getRegex());
+      }
+    }
+    assertEquals("Missing types in the test", typesTested, typesToTest);
+  }
+  
+  /** 
+   * Calls {@link #callAndCheckCreateFields} on each of the specified values.
+   * This is a convinience method for testing the same fieldname with multiple inputs.
+   *
+   * @see #callAndCheckCreateFields
+   */
+  private void doWhiteboxCreateFields(final String fieldName, final Class<?> pointType, final Object... values) throws Exception {
+    
+    for (Object value : values) {
+      // ideally we should require that all input values be diff forms of the same logical value
+      // (ie '"42"' vs 'new Integer(42)') and assert that each produces an equivilent list of IndexableField objects
+      // but that doesn't seem to work -- appears not all IndexableField classes override Object.equals?
+      final List<IndexableField> result = callAndCheckCreateFields(fieldName, pointType, value);
+      assertNotNull(value + " => null", result);
+    }
+  }
+
+
+  /** 
+   * Calls {@link SchemaField#createFields} on the specified value for the specified field name, and asserts 
+   * that the results match the SchemaField propeties, with an additional check that the <code>pointType</code> 
+   * is included if and only if the SchemaField is "indexed" 
+   */
+  private List<IndexableField> callAndCheckCreateFields(final String fieldName, final Class<?> pointType, final Object value) throws Exception {
+    final SchemaField sf = h.getCore().getLatestSchema().getField(fieldName);
+    final List<IndexableField> results = sf.createFields(value);
+    final Set<IndexableField> resultSet = new LinkedHashSet<>(results);
+    assertEquals("duplicates found in results? " + results.toString(),
+                 results.size(), resultSet.size());
+
+    final Set<Class<?>> resultClasses = new HashSet<>();
+    for (IndexableField f : results) {
+      resultClasses.add(f.getClass());
+      
+      if (!sf.hasDocValues() ) {
+        assertFalse(f.toString(),
+                    (f instanceof NumericDocValuesField) ||
+                    (f instanceof SortedNumericDocValuesField));
+      }
+    }
+    assertEquals(fieldName + " stored? Result Fields: " + Arrays.toString(results.toArray()),
+                 sf.stored(), resultClasses.contains(StoredField.class));
+    assertEquals(fieldName + " indexed? Result Fields: " + Arrays.toString(results.toArray()),
+                 sf.indexed(), resultClasses.contains(pointType));
+    if (sf.multiValued()) {
+      assertEquals(fieldName + " docvalues? Result Fields: " + Arrays.toString(results.toArray()),
+                   sf.hasDocValues(), resultClasses.contains(SortedNumericDocValuesField.class));
+    } else {
+      assertEquals(fieldName + " docvalues? Result Fields: " + Arrays.toString(results.toArray()),
+                   sf.hasDocValues(), resultClasses.contains(NumericDocValuesField.class));
+    }
+
+    return results;
+  }
 
 
 }