Browse Source

(refactor) Extract Empty/Script/Missing ValuesSource behavior to an interface (#48320)

This is a pure code rearrangement refactor.  Logic for what specific ValuesSource instance to use for a given type (e.g. script or field) moved out of ValuesSourceConfig and into CoreValuesSourceType (previously just ValueSourceType; we extract an interface for future extensibility).  ValueSourceConfig still selects which case to use, and then the ValuesSourceType instance knows how to construct the ValuesSource for that case.
Mark Tozzi 5 years ago
parent
commit
6cccf3d827
42 changed files with 558 additions and 403 deletions
  1. 3 3
      modules/aggs-matrix-stats/src/main/java/org/elasticsearch/search/aggregations/matrix/stats/MatrixStatsAggregationBuilder.java
  2. 7 7
      modules/aggs-matrix-stats/src/main/java/org/elasticsearch/search/aggregations/support/ArrayValuesSourceAggregationBuilder.java
  3. 4 4
      modules/aggs-matrix-stats/src/main/java/org/elasticsearch/search/aggregations/support/ArrayValuesSourceParser.java
  4. 4 4
      modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/ChildrenAggregationBuilder.java
  5. 4 4
      modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/ParentAggregationBuilder.java
  6. 3 3
      server/src/main/java/org/elasticsearch/search/aggregations/bucket/geogrid/GeoGridAggregationBuilder.java
  7. 3 3
      server/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/AutoDateHistogramAggregationBuilder.java
  8. 4 3
      server/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/DateHistogramAggregationBuilder.java
  9. 4 3
      server/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/HistogramAggregationBuilder.java
  10. 3 3
      server/src/main/java/org/elasticsearch/search/aggregations/bucket/missing/MissingAggregationBuilder.java
  11. 2 1
      server/src/main/java/org/elasticsearch/search/aggregations/bucket/range/InternalGeoDistance.java
  12. 2 1
      server/src/main/java/org/elasticsearch/search/aggregations/bucket/range/InternalRange.java
  13. 3 3
      server/src/main/java/org/elasticsearch/search/aggregations/bucket/range/IpRangeAggregationBuilder.java
  14. 3 3
      server/src/main/java/org/elasticsearch/search/aggregations/bucket/sampler/DiversifiedAggregationBuilder.java
  15. 3 3
      server/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTermsAggregationBuilder.java
  16. 3 3
      server/src/main/java/org/elasticsearch/search/aggregations/bucket/terms/RareTermsAggregationBuilder.java
  17. 3 3
      server/src/main/java/org/elasticsearch/search/aggregations/bucket/terms/TermsAggregationBuilder.java
  18. 3 3
      server/src/main/java/org/elasticsearch/search/aggregations/metrics/AvgAggregationBuilder.java
  19. 3 3
      server/src/main/java/org/elasticsearch/search/aggregations/metrics/CardinalityAggregationBuilder.java
  20. 3 3
      server/src/main/java/org/elasticsearch/search/aggregations/metrics/ExtendedStatsAggregationBuilder.java
  21. 3 3
      server/src/main/java/org/elasticsearch/search/aggregations/metrics/GeoBoundsAggregationBuilder.java
  22. 3 3
      server/src/main/java/org/elasticsearch/search/aggregations/metrics/GeoCentroidAggregationBuilder.java
  23. 3 3
      server/src/main/java/org/elasticsearch/search/aggregations/metrics/MaxAggregationBuilder.java
  24. 3 3
      server/src/main/java/org/elasticsearch/search/aggregations/metrics/MedianAbsoluteDeviationAggregationBuilder.java
  25. 3 3
      server/src/main/java/org/elasticsearch/search/aggregations/metrics/MinAggregationBuilder.java
  26. 3 3
      server/src/main/java/org/elasticsearch/search/aggregations/metrics/PercentileRanksAggregationBuilder.java
  27. 3 3
      server/src/main/java/org/elasticsearch/search/aggregations/metrics/PercentilesAggregationBuilder.java
  28. 3 3
      server/src/main/java/org/elasticsearch/search/aggregations/metrics/StatsAggregationBuilder.java
  29. 3 3
      server/src/main/java/org/elasticsearch/search/aggregations/metrics/SumAggregationBuilder.java
  30. 3 3
      server/src/main/java/org/elasticsearch/search/aggregations/metrics/ValueCountAggregationBuilder.java
  31. 218 0
      server/src/main/java/org/elasticsearch/search/aggregations/support/CoreValuesSourceType.java
  32. 10 10
      server/src/main/java/org/elasticsearch/search/aggregations/support/ValueType.java
  33. 74 62
      server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSource.java
  34. 4 4
      server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceAggregationBuilder.java
  35. 2 2
      server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceAggregatorFactory.java
  36. 25 125
      server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceConfig.java
  37. 46 26
      server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceType.java
  38. 74 0
      server/src/test/java/org/elasticsearch/search/aggregations/support/CoreValuesSourceTypeTests.java
  39. 0 73
      server/src/test/java/org/elasticsearch/search/aggregations/support/ValuesSourceTypeTests.java
  40. 3 3
      x-pack/plugin/analytics/src/main/java/org/elasticsearch/xpack/analytics/stringstats/StringStatsAggregationBuilder.java
  41. 3 3
      x-pack/plugin/analytics/src/test/java/org/elasticsearch/xpack/analytics/cumulativecardinality/CumulativeCardinalityAggregatorTests.java
  42. 2 2
      x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/transform/transforms/MockDeprecatedAggregationBuilder.java

+ 3 - 3
modules/aggs-matrix-stats/src/main/java/org/elasticsearch/search/aggregations/matrix/stats/MatrixStatsAggregationBuilder.java

@@ -28,11 +28,11 @@ import org.elasticsearch.search.aggregations.AggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
 import org.elasticsearch.search.aggregations.support.ArrayValuesSourceAggregationBuilder;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 import org.elasticsearch.search.aggregations.support.ValueType;
 import org.elasticsearch.search.aggregations.support.ValuesSource;
 import org.elasticsearch.search.aggregations.support.ValuesSource.Numeric;
 import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
-import org.elasticsearch.search.aggregations.support.ValuesSourceType;
 
 import java.io.IOException;
 import java.util.Map;
@@ -44,7 +44,7 @@ public class MatrixStatsAggregationBuilder
     private MultiValueMode multiValueMode = MultiValueMode.AVG;
 
     public MatrixStatsAggregationBuilder(String name) {
-        super(name, ValuesSourceType.NUMERIC, ValueType.NUMERIC);
+        super(name, CoreValuesSourceType.NUMERIC, ValueType.NUMERIC);
     }
 
     protected MatrixStatsAggregationBuilder(MatrixStatsAggregationBuilder clone,
@@ -62,7 +62,7 @@ public class MatrixStatsAggregationBuilder
      * Read from a stream.
      */
     public MatrixStatsAggregationBuilder(StreamInput in) throws IOException {
-        super(in, ValuesSourceType.NUMERIC, ValueType.NUMERIC);
+        super(in, CoreValuesSourceType.NUMERIC, ValueType.NUMERIC);
     }
 
     @Override

+ 7 - 7
modules/aggs-matrix-stats/src/main/java/org/elasticsearch/search/aggregations/support/ArrayValuesSourceAggregationBuilder.java

@@ -266,16 +266,16 @@ public abstract class ArrayValuesSourceAggregationBuilder<VS extends ValuesSourc
 
         if (field == null) {
             if (script == null) {
-                ValuesSourceConfig<VS> config = new ValuesSourceConfig<>(ValuesSourceType.ANY);
+                ValuesSourceConfig<VS> config = new ValuesSourceConfig<>(CoreValuesSourceType.ANY);
                 return config.format(resolveFormat(null, valueType));
             }
             ValuesSourceType valuesSourceType = valueType != null ? valueType.getValuesSourceType() : this.valuesSourceType;
-            if (valuesSourceType == null || valuesSourceType == ValuesSourceType.ANY) {
+            if (valuesSourceType == null || valuesSourceType == CoreValuesSourceType.ANY) {
                 // the specific value source type is undefined, but for scripts,
                 // we need to have a specific value source
                 // type to know how to handle the script values, so we fallback
                 // on Bytes
-                valuesSourceType = ValuesSourceType.BYTES;
+                valuesSourceType = CoreValuesSourceType.BYTES;
             }
             ValuesSourceConfig<VS> config = new ValuesSourceConfig<>(valuesSourceType);
             config.missing(missingMap.get(field));
@@ -294,13 +294,13 @@ public abstract class ArrayValuesSourceAggregationBuilder<VS extends ValuesSourc
         IndexFieldData<?> indexFieldData = queryShardContext.getForField(fieldType);
 
         ValuesSourceConfig<VS> config;
-        if (valuesSourceType == ValuesSourceType.ANY) {
+        if (valuesSourceType == CoreValuesSourceType.ANY) {
             if (indexFieldData instanceof IndexNumericFieldData) {
-                config = new ValuesSourceConfig<>(ValuesSourceType.NUMERIC);
+                config = new ValuesSourceConfig<>(CoreValuesSourceType.NUMERIC);
             } else if (indexFieldData instanceof IndexGeoPointFieldData) {
-                config = new ValuesSourceConfig<>(ValuesSourceType.GEOPOINT);
+                config = new ValuesSourceConfig<>(CoreValuesSourceType.GEOPOINT);
             } else {
-                config = new ValuesSourceConfig<>(ValuesSourceType.BYTES);
+                config = new ValuesSourceConfig<>(CoreValuesSourceType.BYTES);
             }
         } else {
             config = new ValuesSourceConfig<>(valuesSourceType);

+ 4 - 4
modules/aggs-matrix-stats/src/main/java/org/elasticsearch/search/aggregations/support/ArrayValuesSourceParser.java

@@ -38,28 +38,28 @@ public abstract class ArrayValuesSourceParser<VS extends ValuesSource> implement
     public abstract static class AnyValuesSourceParser extends ArrayValuesSourceParser<ValuesSource> {
 
         protected AnyValuesSourceParser(boolean formattable) {
-            super(formattable, ValuesSourceType.ANY, null);
+            super(formattable, CoreValuesSourceType.ANY, null);
         }
     }
 
     public abstract static class NumericValuesSourceParser extends ArrayValuesSourceParser<ValuesSource.Numeric> {
 
         protected NumericValuesSourceParser(boolean formattable) {
-            super(formattable, ValuesSourceType.NUMERIC, ValueType.NUMERIC);
+            super(formattable, CoreValuesSourceType.NUMERIC, ValueType.NUMERIC);
         }
     }
 
     public abstract static class BytesValuesSourceParser extends ArrayValuesSourceParser<ValuesSource.Bytes> {
 
         protected BytesValuesSourceParser(boolean formattable) {
-            super(formattable, ValuesSourceType.BYTES, ValueType.STRING);
+            super(formattable, CoreValuesSourceType.BYTES, ValueType.STRING);
         }
     }
 
     public abstract static class GeoPointValuesSourceParser extends ArrayValuesSourceParser<ValuesSource.GeoPoint> {
 
         protected GeoPointValuesSourceParser(boolean formattable) {
-            super(formattable, ValuesSourceType.GEOPOINT, ValueType.GEOPOINT);
+            super(formattable, CoreValuesSourceType.GEOPOINT, ValueType.GEOPOINT);
         }
     }
 

+ 4 - 4
modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/ChildrenAggregationBuilder.java

@@ -33,13 +33,13 @@ import org.elasticsearch.join.mapper.ParentJoinFieldMapper;
 import org.elasticsearch.search.aggregations.AggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 import org.elasticsearch.search.aggregations.support.FieldContext;
 import org.elasticsearch.search.aggregations.support.ValueType;
 import org.elasticsearch.search.aggregations.support.ValuesSource.Bytes.WithOrdinals;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory;
 import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
-import org.elasticsearch.search.aggregations.support.ValuesSourceType;
 
 import java.io.IOException;
 import java.util.Map;
@@ -61,7 +61,7 @@ public class ChildrenAggregationBuilder
      *            the type of children documents
      */
     public ChildrenAggregationBuilder(String name, String childType) {
-        super(name, ValuesSourceType.BYTES, ValueType.STRING);
+        super(name, CoreValuesSourceType.BYTES, ValueType.STRING);
         if (childType == null) {
             throw new IllegalArgumentException("[childType] must not be null: [" + name + "]");
         }
@@ -85,7 +85,7 @@ public class ChildrenAggregationBuilder
      * Read from a stream.
      */
     public ChildrenAggregationBuilder(StreamInput in) throws IOException {
-        super(in, ValuesSourceType.BYTES, ValueType.STRING);
+        super(in, CoreValuesSourceType.BYTES, ValueType.STRING);
         childType = in.readString();
     }
 
@@ -105,7 +105,7 @@ public class ChildrenAggregationBuilder
 
     @Override
     protected ValuesSourceConfig<WithOrdinals> resolveConfig(QueryShardContext queryShardContext) {
-        ValuesSourceConfig<WithOrdinals> config = new ValuesSourceConfig<>(ValuesSourceType.BYTES);
+        ValuesSourceConfig<WithOrdinals> config = new ValuesSourceConfig<>(CoreValuesSourceType.BYTES);
         joinFieldResolveConfig(queryShardContext, config);
         return config;
     }

+ 4 - 4
modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/ParentAggregationBuilder.java

@@ -33,13 +33,13 @@ import org.elasticsearch.join.mapper.ParentJoinFieldMapper;
 import org.elasticsearch.search.aggregations.AggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 import org.elasticsearch.search.aggregations.support.FieldContext;
 import org.elasticsearch.search.aggregations.support.ValueType;
 import org.elasticsearch.search.aggregations.support.ValuesSource.Bytes.WithOrdinals;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory;
 import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
-import org.elasticsearch.search.aggregations.support.ValuesSourceType;
 
 import java.io.IOException;
 import java.util.Map;
@@ -61,7 +61,7 @@ public class ParentAggregationBuilder
      *            the type of children documents
      */
     public ParentAggregationBuilder(String name, String childType) {
-        super(name, ValuesSourceType.BYTES, ValueType.STRING);
+        super(name, CoreValuesSourceType.BYTES, ValueType.STRING);
         if (childType == null) {
             throw new IllegalArgumentException("[childType] must not be null: [" + name + "]");
         }
@@ -85,7 +85,7 @@ public class ParentAggregationBuilder
      * Read from a stream.
      */
     public ParentAggregationBuilder(StreamInput in) throws IOException {
-        super(in, ValuesSourceType.BYTES, ValueType.STRING);
+        super(in, CoreValuesSourceType.BYTES, ValueType.STRING);
         childType = in.readString();
     }
 
@@ -105,7 +105,7 @@ public class ParentAggregationBuilder
 
     @Override
     protected ValuesSourceConfig<WithOrdinals> resolveConfig(QueryShardContext queryShardContext) {
-        ValuesSourceConfig<WithOrdinals> config = new ValuesSourceConfig<>(ValuesSourceType.BYTES);
+        ValuesSourceConfig<WithOrdinals> config = new ValuesSourceConfig<>(CoreValuesSourceType.BYTES);
         joinFieldResolveConfig(queryShardContext, config);
         return config;
     }

+ 3 - 3
server/src/main/java/org/elasticsearch/search/aggregations/bucket/geogrid/GeoGridAggregationBuilder.java

@@ -31,13 +31,13 @@ import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
 import org.elasticsearch.search.aggregations.bucket.BucketUtils;
 import org.elasticsearch.search.aggregations.bucket.MultiBucketAggregationBuilder;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 import org.elasticsearch.search.aggregations.support.ValueType;
 import org.elasticsearch.search.aggregations.support.ValuesSource;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory;
 import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
 import org.elasticsearch.search.aggregations.support.ValuesSourceParserHelper;
-import org.elasticsearch.search.aggregations.support.ValuesSourceType;
 
 import java.io.IOException;
 import java.util.Map;
@@ -70,7 +70,7 @@ public abstract class GeoGridAggregationBuilder extends ValuesSourceAggregationB
     }
 
     public GeoGridAggregationBuilder(String name) {
-        super(name, ValuesSourceType.GEOPOINT, ValueType.GEOPOINT);
+        super(name, CoreValuesSourceType.GEOPOINT, ValueType.GEOPOINT);
     }
 
     protected GeoGridAggregationBuilder(GeoGridAggregationBuilder clone, Builder factoriesBuilder, Map<String, Object> metaData) {
@@ -85,7 +85,7 @@ public abstract class GeoGridAggregationBuilder extends ValuesSourceAggregationB
      * Read from a stream.
      */
     public GeoGridAggregationBuilder(StreamInput in) throws IOException {
-        super(in, ValuesSourceType.GEOPOINT, ValueType.GEOPOINT);
+        super(in, CoreValuesSourceType.GEOPOINT, ValueType.GEOPOINT);
         precision = in.readVInt();
         requiredSize = in.readVInt();
         shardSize = in.readVInt();

+ 3 - 3
server/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/AutoDateHistogramAggregationBuilder.java

@@ -34,6 +34,7 @@ import org.elasticsearch.search.aggregations.AggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
 import org.elasticsearch.search.aggregations.MultiBucketConsumerService;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 import org.elasticsearch.search.aggregations.support.ValueType;
 import org.elasticsearch.search.aggregations.support.ValuesSource;
 import org.elasticsearch.search.aggregations.support.ValuesSource.Numeric;
@@ -41,7 +42,6 @@ import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuil
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory;
 import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
 import org.elasticsearch.search.aggregations.support.ValuesSourceParserHelper;
-import org.elasticsearch.search.aggregations.support.ValuesSourceType;
 
 import java.io.IOException;
 import java.time.ZoneId;
@@ -134,12 +134,12 @@ public class AutoDateHistogramAggregationBuilder
 
     /** Create a new builder with the given name. */
     public AutoDateHistogramAggregationBuilder(String name) {
-        super(name, ValuesSourceType.NUMERIC, ValueType.DATE);
+        super(name, CoreValuesSourceType.NUMERIC, ValueType.DATE);
     }
 
     /** Read from a stream, for internal use only. */
     public AutoDateHistogramAggregationBuilder(StreamInput in) throws IOException {
-        super(in, ValuesSourceType.NUMERIC, ValueType.DATE);
+        super(in, CoreValuesSourceType.NUMERIC, ValueType.DATE);
         numBuckets = in.readVInt();
         if (in.getVersion().onOrAfter(Version.V_7_3_0)) {
             minimumIntervalExpression = in.readOptionalString();

+ 4 - 3
server/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/DateHistogramAggregationBuilder.java

@@ -45,6 +45,7 @@ import org.elasticsearch.search.aggregations.BucketOrder;
 import org.elasticsearch.search.aggregations.InternalOrder;
 import org.elasticsearch.search.aggregations.InternalOrder.CompoundOrder;
 import org.elasticsearch.search.aggregations.bucket.MultiBucketAggregationBuilder;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 import org.elasticsearch.search.aggregations.support.ValueType;
 import org.elasticsearch.search.aggregations.support.ValuesSource;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder;
@@ -130,7 +131,7 @@ public class DateHistogramAggregationBuilder extends ValuesSourceAggregationBuil
 
     /** Create a new builder with the given name. */
     public DateHistogramAggregationBuilder(String name) {
-        super(name, ValuesSourceType.ANY, ValueType.DATE);
+        super(name, CoreValuesSourceType.ANY, ValueType.DATE);
     }
 
     protected DateHistogramAggregationBuilder(DateHistogramAggregationBuilder clone,
@@ -151,7 +152,7 @@ public class DateHistogramAggregationBuilder extends ValuesSourceAggregationBuil
 
     /** Read from a stream, for internal use only. */
     public DateHistogramAggregationBuilder(StreamInput in) throws IOException {
-        super(in, ValuesSourceType.ANY, ValueType.DATE);
+        super(in, CoreValuesSourceType.ANY, ValueType.DATE);
         order = InternalOrder.Streams.readHistogramOrder(in);
         keyed = in.readBoolean();
         minDocCount = in.readVLong();
@@ -163,7 +164,7 @@ public class DateHistogramAggregationBuilder extends ValuesSourceAggregationBuil
     @Override
     protected ValuesSourceType resolveScriptAny(Script script) {
         // TODO: No idea how we'd support Range scripts here.
-        return ValuesSourceType.NUMERIC;
+        return CoreValuesSourceType.NUMERIC;
     }
 
 

+ 4 - 3
server/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/HistogramAggregationBuilder.java

@@ -34,6 +34,7 @@ import org.elasticsearch.search.aggregations.BucketOrder;
 import org.elasticsearch.search.aggregations.InternalOrder;
 import org.elasticsearch.search.aggregations.InternalOrder.CompoundOrder;
 import org.elasticsearch.search.aggregations.bucket.MultiBucketAggregationBuilder;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 import org.elasticsearch.search.aggregations.support.ValueType;
 import org.elasticsearch.search.aggregations.support.ValuesSource;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder;
@@ -99,12 +100,12 @@ public class HistogramAggregationBuilder extends ValuesSourceAggregationBuilder<
     @Override
     protected ValuesSourceType resolveScriptAny(Script script) {
         // TODO: No idea how we'd support Range scripts here.
-        return ValuesSourceType.NUMERIC;
+        return CoreValuesSourceType.NUMERIC;
     }
 
     /** Create a new builder with the given name. */
     public HistogramAggregationBuilder(String name) {
-        super(name, ValuesSourceType.ANY, ValueType.NUMERIC);
+        super(name, CoreValuesSourceType.ANY, ValueType.NUMERIC);
     }
 
     protected HistogramAggregationBuilder(HistogramAggregationBuilder clone, Builder factoriesBuilder, Map<String, Object> metaData) {
@@ -125,7 +126,7 @@ public class HistogramAggregationBuilder extends ValuesSourceAggregationBuilder<
 
     /** Read from a stream, for internal use only. */
     public HistogramAggregationBuilder(StreamInput in) throws IOException {
-        super(in, ValuesSourceType.ANY, ValueType.NUMERIC);
+        super(in, CoreValuesSourceType.ANY, ValueType.NUMERIC);
         order = InternalOrder.Streams.readHistogramOrder(in);
         keyed = in.readBoolean();
         minDocCount = in.readVLong();

+ 3 - 3
server/src/main/java/org/elasticsearch/search/aggregations/bucket/missing/MissingAggregationBuilder.java

@@ -29,13 +29,13 @@ import org.elasticsearch.index.query.QueryShardContext;
 import org.elasticsearch.search.aggregations.AggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 import org.elasticsearch.search.aggregations.support.ValueType;
 import org.elasticsearch.search.aggregations.support.ValuesSource;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory;
 import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
 import org.elasticsearch.search.aggregations.support.ValuesSourceParserHelper;
-import org.elasticsearch.search.aggregations.support.ValuesSourceType;
 
 import java.io.IOException;
 import java.util.Map;
@@ -54,7 +54,7 @@ public class MissingAggregationBuilder extends ValuesSourceAggregationBuilder<Va
     }
 
     public MissingAggregationBuilder(String name, ValueType targetValueType) {
-        super(name, ValuesSourceType.ANY, targetValueType);
+        super(name, CoreValuesSourceType.ANY, targetValueType);
     }
 
     protected MissingAggregationBuilder(MissingAggregationBuilder clone, Builder factoriesBuilder, Map<String, Object> metaData) {
@@ -70,7 +70,7 @@ public class MissingAggregationBuilder extends ValuesSourceAggregationBuilder<Va
      * Read from a stream.
      */
     public MissingAggregationBuilder(StreamInput in) throws IOException {
-        super(in, ValuesSourceType.ANY);
+        super(in, CoreValuesSourceType.ANY);
     }
 
     @Override

+ 2 - 1
server/src/main/java/org/elasticsearch/search/aggregations/bucket/range/InternalGeoDistance.java

@@ -23,6 +23,7 @@ import org.elasticsearch.search.DocValueFormat;
 import org.elasticsearch.search.aggregations.InternalAggregation;
 import org.elasticsearch.search.aggregations.InternalAggregations;
 import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 import org.elasticsearch.search.aggregations.support.ValueType;
 import org.elasticsearch.search.aggregations.support.ValuesSourceType;
 
@@ -56,7 +57,7 @@ public class InternalGeoDistance extends InternalRange<InternalGeoDistance.Bucke
     public static class Factory extends InternalRange.Factory<InternalGeoDistance.Bucket, InternalGeoDistance> {
         @Override
         public ValuesSourceType getValueSourceType() {
-            return ValuesSourceType.GEOPOINT;
+            return CoreValuesSourceType.GEOPOINT;
         }
 
         @Override

+ 2 - 1
server/src/main/java/org/elasticsearch/search/aggregations/bucket/range/InternalRange.java

@@ -27,6 +27,7 @@ import org.elasticsearch.search.aggregations.InternalAggregation;
 import org.elasticsearch.search.aggregations.InternalAggregations;
 import org.elasticsearch.search.aggregations.InternalMultiBucketAggregation;
 import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 import org.elasticsearch.search.aggregations.support.ValueType;
 import org.elasticsearch.search.aggregations.support.ValuesSourceType;
 
@@ -188,7 +189,7 @@ public class InternalRange<B extends InternalRange.Bucket, R extends InternalRan
 
     public static class Factory<B extends Bucket, R extends InternalRange<B, R>> {
         public ValuesSourceType getValueSourceType() {
-            return ValuesSourceType.NUMERIC;
+            return CoreValuesSourceType.NUMERIC;
         }
 
         public ValueType getValueType() {

+ 3 - 3
server/src/main/java/org/elasticsearch/search/aggregations/bucket/range/IpRangeAggregationBuilder.java

@@ -36,13 +36,13 @@ import org.elasticsearch.script.Script;
 import org.elasticsearch.search.aggregations.AggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 import org.elasticsearch.search.aggregations.support.ValueType;
 import org.elasticsearch.search.aggregations.support.ValuesSource;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory;
 import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
 import org.elasticsearch.search.aggregations.support.ValuesSourceParserHelper;
-import org.elasticsearch.search.aggregations.support.ValuesSourceType;
 
 import java.io.IOException;
 import java.net.InetAddress;
@@ -220,7 +220,7 @@ public final class IpRangeAggregationBuilder
     private List<Range> ranges = new ArrayList<>();
 
     public IpRangeAggregationBuilder(String name) {
-        super(name, ValuesSourceType.BYTES, ValueType.IP);
+        super(name, CoreValuesSourceType.BYTES, ValueType.IP);
     }
 
     protected IpRangeAggregationBuilder(IpRangeAggregationBuilder clone, Builder factoriesBuilder, Map<String, Object> metaData) {
@@ -337,7 +337,7 @@ public final class IpRangeAggregationBuilder
     }
 
     public IpRangeAggregationBuilder(StreamInput in) throws IOException {
-        super(in, ValuesSourceType.BYTES, ValueType.IP);
+        super(in, CoreValuesSourceType.BYTES, ValueType.IP);
         final int numRanges = in.readVInt();
         for (int i = 0; i < numRanges; ++i) {
             addRange(new Range(in));

+ 3 - 3
server/src/main/java/org/elasticsearch/search/aggregations/bucket/sampler/DiversifiedAggregationBuilder.java

@@ -28,12 +28,12 @@ import org.elasticsearch.index.query.QueryShardContext;
 import org.elasticsearch.search.aggregations.AggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 import org.elasticsearch.search.aggregations.support.ValuesSource;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory;
 import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
 import org.elasticsearch.search.aggregations.support.ValuesSourceParserHelper;
-import org.elasticsearch.search.aggregations.support.ValuesSourceType;
 
 import java.io.IOException;
 import java.util.Map;
@@ -62,7 +62,7 @@ public class DiversifiedAggregationBuilder extends ValuesSourceAggregationBuilde
     private String executionHint = null;
 
     public DiversifiedAggregationBuilder(String name) {
-        super(name, ValuesSourceType.ANY, null);
+        super(name, CoreValuesSourceType.ANY, null);
     }
 
     protected DiversifiedAggregationBuilder(DiversifiedAggregationBuilder clone, Builder factoriesBuilder, Map<String, Object> metaData) {
@@ -81,7 +81,7 @@ public class DiversifiedAggregationBuilder extends ValuesSourceAggregationBuilde
      * Read from a stream.
      */
     public DiversifiedAggregationBuilder(StreamInput in) throws IOException {
-        super(in, ValuesSourceType.ANY, null);
+        super(in, CoreValuesSourceType.ANY, null);
         shardSize = in.readVInt();
         maxDocsPerValue = in.readVInt();
         executionHint = in.readOptionalString();

+ 3 - 3
server/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTermsAggregationBuilder.java

@@ -46,7 +46,7 @@ import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuil
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory;
 import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
 import org.elasticsearch.search.aggregations.support.ValuesSourceParserHelper;
-import org.elasticsearch.search.aggregations.support.ValuesSourceType;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 
 import java.io.IOException;
 import java.util.Map;
@@ -116,14 +116,14 @@ public class SignificantTermsAggregationBuilder extends ValuesSourceAggregationB
     private SignificanceHeuristic significanceHeuristic = DEFAULT_SIGNIFICANCE_HEURISTIC;
 
     public SignificantTermsAggregationBuilder(String name, ValueType valueType) {
-        super(name, ValuesSourceType.ANY, valueType);
+        super(name, CoreValuesSourceType.ANY, valueType);
     }
 
     /**
      * Read from a Stream.
      */
     public SignificantTermsAggregationBuilder(StreamInput in) throws IOException {
-        super(in, ValuesSourceType.ANY);
+        super(in, CoreValuesSourceType.ANY);
         bucketCountThresholds = new BucketCountThresholds(in);
         executionHint = in.readOptionalString();
         filterBuilder = in.readOptionalNamedWriteable(QueryBuilder.class);

+ 3 - 3
server/src/main/java/org/elasticsearch/search/aggregations/bucket/terms/RareTermsAggregationBuilder.java

@@ -29,13 +29,13 @@ import org.elasticsearch.index.query.QueryShardContext;
 import org.elasticsearch.search.aggregations.AggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 import org.elasticsearch.search.aggregations.support.ValueType;
 import org.elasticsearch.search.aggregations.support.ValuesSource;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory;
 import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
 import org.elasticsearch.search.aggregations.support.ValuesSourceParserHelper;
-import org.elasticsearch.search.aggregations.support.ValuesSourceType;
 
 import java.io.IOException;
 import java.util.Map;
@@ -72,7 +72,7 @@ public class RareTermsAggregationBuilder extends ValuesSourceAggregationBuilder<
     private double precision = 0.001;
 
     public RareTermsAggregationBuilder(String name, ValueType valueType) {
-        super(name, ValuesSourceType.ANY, valueType);
+        super(name, CoreValuesSourceType.ANY, valueType);
     }
 
     private RareTermsAggregationBuilder(RareTermsAggregationBuilder clone, Builder factoriesBuilder, Map<String, Object> metaData) {
@@ -89,7 +89,7 @@ public class RareTermsAggregationBuilder extends ValuesSourceAggregationBuilder<
      * Read from a stream.
      */
     public RareTermsAggregationBuilder(StreamInput in) throws IOException {
-        super(in, ValuesSourceType.ANY);
+        super(in, CoreValuesSourceType.ANY);
         includeExclude = in.readOptionalWriteable(IncludeExclude::new);
         maxDocCount = in.readVInt();
     }

+ 3 - 3
server/src/main/java/org/elasticsearch/search/aggregations/bucket/terms/TermsAggregationBuilder.java

@@ -36,13 +36,13 @@ import org.elasticsearch.search.aggregations.InternalOrder;
 import org.elasticsearch.search.aggregations.InternalOrder.CompoundOrder;
 import org.elasticsearch.search.aggregations.bucket.MultiBucketAggregationBuilder;
 import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregator.BucketCountThresholds;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 import org.elasticsearch.search.aggregations.support.ValueType;
 import org.elasticsearch.search.aggregations.support.ValuesSource;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory;
 import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
 import org.elasticsearch.search.aggregations.support.ValuesSourceParserHelper;
-import org.elasticsearch.search.aggregations.support.ValuesSourceType;
 
 import java.io.IOException;
 import java.util.List;
@@ -109,7 +109,7 @@ public class TermsAggregationBuilder extends ValuesSourceAggregationBuilder<Valu
     private boolean showTermDocCountError = false;
 
     public TermsAggregationBuilder(String name, ValueType valueType) {
-        super(name, ValuesSourceType.ANY, valueType);
+        super(name, CoreValuesSourceType.ANY, valueType);
     }
 
     protected TermsAggregationBuilder(TermsAggregationBuilder clone, Builder factoriesBuilder, Map<String, Object> metaData) {
@@ -131,7 +131,7 @@ public class TermsAggregationBuilder extends ValuesSourceAggregationBuilder<Valu
      * Read from a stream.
      */
     public TermsAggregationBuilder(StreamInput in) throws IOException {
-        super(in, ValuesSourceType.ANY);
+        super(in, CoreValuesSourceType.ANY);
         bucketCountThresholds = new BucketCountThresholds(in);
         collectMode = in.readOptionalWriteable(SubAggCollectionMode::readFromStream);
         executionHint = in.readOptionalString();

+ 3 - 3
server/src/main/java/org/elasticsearch/search/aggregations/metrics/AvgAggregationBuilder.java

@@ -34,7 +34,7 @@ import org.elasticsearch.search.aggregations.support.ValuesSource.Numeric;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder;
 import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
 import org.elasticsearch.search.aggregations.support.ValuesSourceParserHelper;
-import org.elasticsearch.search.aggregations.support.ValuesSourceType;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 
 import java.io.IOException;
 import java.util.Map;
@@ -53,7 +53,7 @@ public class AvgAggregationBuilder extends ValuesSourceAggregationBuilder.LeafOn
     }
 
     public AvgAggregationBuilder(String name) {
-        super(name, ValuesSourceType.NUMERIC, ValueType.NUMERIC);
+        super(name, CoreValuesSourceType.NUMERIC, ValueType.NUMERIC);
     }
 
     public AvgAggregationBuilder(AvgAggregationBuilder clone, Builder factoriesBuilder, Map<String, Object> metaData) {
@@ -64,7 +64,7 @@ public class AvgAggregationBuilder extends ValuesSourceAggregationBuilder.LeafOn
      * Read from a stream.
      */
     public AvgAggregationBuilder(StreamInput in) throws IOException {
-        super(in, ValuesSourceType.NUMERIC, ValueType.NUMERIC);
+        super(in, CoreValuesSourceType.NUMERIC, ValueType.NUMERIC);
     }
 
     @Override

+ 3 - 3
server/src/main/java/org/elasticsearch/search/aggregations/metrics/CardinalityAggregationBuilder.java

@@ -30,12 +30,12 @@ import org.elasticsearch.index.query.QueryShardContext;
 import org.elasticsearch.search.aggregations.AggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 import org.elasticsearch.search.aggregations.support.ValueType;
 import org.elasticsearch.search.aggregations.support.ValuesSource;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder;
 import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
 import org.elasticsearch.search.aggregations.support.ValuesSourceParserHelper;
-import org.elasticsearch.search.aggregations.support.ValuesSourceType;
 
 import java.io.IOException;
 import java.util.Map;
@@ -64,7 +64,7 @@ public final class CardinalityAggregationBuilder
     private Long precisionThreshold = null;
 
     public CardinalityAggregationBuilder(String name, ValueType targetValueType) {
-        super(name, ValuesSourceType.ANY, targetValueType);
+        super(name, CoreValuesSourceType.ANY, targetValueType);
     }
 
     public CardinalityAggregationBuilder(CardinalityAggregationBuilder clone, Builder factoriesBuilder, Map<String, Object> metaData) {
@@ -76,7 +76,7 @@ public final class CardinalityAggregationBuilder
      * Read from a stream.
      */
     public CardinalityAggregationBuilder(StreamInput in) throws IOException {
-        super(in, ValuesSourceType.ANY);
+        super(in, CoreValuesSourceType.ANY);
         if (in.readBoolean()) {
             precisionThreshold = in.readLong();
         }

+ 3 - 3
server/src/main/java/org/elasticsearch/search/aggregations/metrics/ExtendedStatsAggregationBuilder.java

@@ -28,13 +28,13 @@ import org.elasticsearch.index.query.QueryShardContext;
 import org.elasticsearch.search.aggregations.AggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 import org.elasticsearch.search.aggregations.support.ValueType;
 import org.elasticsearch.search.aggregations.support.ValuesSource;
 import org.elasticsearch.search.aggregations.support.ValuesSource.Numeric;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder;
 import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
 import org.elasticsearch.search.aggregations.support.ValuesSourceParserHelper;
-import org.elasticsearch.search.aggregations.support.ValuesSourceType;
 
 import java.io.IOException;
 import java.util.Map;
@@ -58,7 +58,7 @@ public class ExtendedStatsAggregationBuilder
     private double sigma = 2.0;
 
     public ExtendedStatsAggregationBuilder(String name) {
-        super(name, ValuesSourceType.NUMERIC, ValueType.NUMERIC);
+        super(name, CoreValuesSourceType.NUMERIC, ValueType.NUMERIC);
     }
 
     protected ExtendedStatsAggregationBuilder(ExtendedStatsAggregationBuilder clone,
@@ -76,7 +76,7 @@ public class ExtendedStatsAggregationBuilder
      * Read from a stream.
      */
     public ExtendedStatsAggregationBuilder(StreamInput in) throws IOException {
-        super(in, ValuesSourceType.NUMERIC, ValueType.NUMERIC);
+        super(in, CoreValuesSourceType.NUMERIC, ValueType.NUMERIC);
         sigma = in.readDouble();
     }
 

+ 3 - 3
server/src/main/java/org/elasticsearch/search/aggregations/metrics/GeoBoundsAggregationBuilder.java

@@ -33,7 +33,7 @@ import org.elasticsearch.search.aggregations.support.ValuesSource;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder;
 import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
 import org.elasticsearch.search.aggregations.support.ValuesSourceParserHelper;
-import org.elasticsearch.search.aggregations.support.ValuesSourceType;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 
 import java.io.IOException;
 import java.util.Map;
@@ -56,7 +56,7 @@ public class GeoBoundsAggregationBuilder extends ValuesSourceAggregationBuilder<
     private boolean wrapLongitude = true;
 
     public GeoBoundsAggregationBuilder(String name) {
-        super(name, ValuesSourceType.GEOPOINT, ValueType.GEOPOINT);
+        super(name, CoreValuesSourceType.GEOPOINT, ValueType.GEOPOINT);
     }
 
     protected GeoBoundsAggregationBuilder(GeoBoundsAggregationBuilder clone, Builder factoriesBuilder, Map<String, Object> metaData) {
@@ -73,7 +73,7 @@ public class GeoBoundsAggregationBuilder extends ValuesSourceAggregationBuilder<
      * Read from a stream.
      */
     public GeoBoundsAggregationBuilder(StreamInput in) throws IOException {
-        super(in, ValuesSourceType.GEOPOINT, ValueType.GEOPOINT);
+        super(in, CoreValuesSourceType.GEOPOINT, ValueType.GEOPOINT);
         wrapLongitude = in.readBoolean();
     }
 

+ 3 - 3
server/src/main/java/org/elasticsearch/search/aggregations/metrics/GeoCentroidAggregationBuilder.java

@@ -28,12 +28,12 @@ import org.elasticsearch.index.query.QueryShardContext;
 import org.elasticsearch.search.aggregations.AggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 import org.elasticsearch.search.aggregations.support.ValueType;
 import org.elasticsearch.search.aggregations.support.ValuesSource;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder;
 import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
 import org.elasticsearch.search.aggregations.support.ValuesSourceParserHelper;
-import org.elasticsearch.search.aggregations.support.ValuesSourceType;
 
 import java.io.IOException;
 import java.util.Map;
@@ -53,7 +53,7 @@ public class GeoCentroidAggregationBuilder
     }
 
     public GeoCentroidAggregationBuilder(String name) {
-        super(name, ValuesSourceType.GEOPOINT, ValueType.GEOPOINT);
+        super(name, CoreValuesSourceType.GEOPOINT, ValueType.GEOPOINT);
     }
 
     protected GeoCentroidAggregationBuilder(GeoCentroidAggregationBuilder clone, Builder factoriesBuilder, Map<String, Object> metaData) {
@@ -69,7 +69,7 @@ public class GeoCentroidAggregationBuilder
      * Read from a stream.
      */
     public GeoCentroidAggregationBuilder(StreamInput in) throws IOException {
-        super(in, ValuesSourceType.GEOPOINT, ValueType.GEOPOINT);
+        super(in, CoreValuesSourceType.GEOPOINT, ValueType.GEOPOINT);
     }
 
     @Override

+ 3 - 3
server/src/main/java/org/elasticsearch/search/aggregations/metrics/MaxAggregationBuilder.java

@@ -28,13 +28,13 @@ import org.elasticsearch.index.query.QueryShardContext;
 import org.elasticsearch.search.aggregations.AggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 import org.elasticsearch.search.aggregations.support.ValueType;
 import org.elasticsearch.search.aggregations.support.ValuesSource;
 import org.elasticsearch.search.aggregations.support.ValuesSource.Numeric;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder;
 import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
 import org.elasticsearch.search.aggregations.support.ValuesSourceParserHelper;
-import org.elasticsearch.search.aggregations.support.ValuesSourceType;
 
 import java.io.IOException;
 import java.util.Map;
@@ -53,7 +53,7 @@ public class MaxAggregationBuilder extends ValuesSourceAggregationBuilder.LeafOn
     }
 
     public MaxAggregationBuilder(String name) {
-        super(name, ValuesSourceType.NUMERIC, ValueType.NUMERIC);
+        super(name, CoreValuesSourceType.NUMERIC, ValueType.NUMERIC);
     }
 
     protected MaxAggregationBuilder(MaxAggregationBuilder clone, Builder factoriesBuilder, Map<String, Object> metaData) {
@@ -69,7 +69,7 @@ public class MaxAggregationBuilder extends ValuesSourceAggregationBuilder.LeafOn
      * Read from a stream.
      */
     public MaxAggregationBuilder(StreamInput in) throws IOException {
-        super(in, ValuesSourceType.NUMERIC, ValueType.NUMERIC);
+        super(in, CoreValuesSourceType.NUMERIC, ValueType.NUMERIC);
     }
 
     @Override

+ 3 - 3
server/src/main/java/org/elasticsearch/search/aggregations/metrics/MedianAbsoluteDeviationAggregationBuilder.java

@@ -29,13 +29,13 @@ import org.elasticsearch.index.query.QueryShardContext;
 import org.elasticsearch.search.aggregations.AggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 import org.elasticsearch.search.aggregations.support.ValueType;
 import org.elasticsearch.search.aggregations.support.ValuesSource;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder.LeafOnly;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory;
 import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
 import org.elasticsearch.search.aggregations.support.ValuesSourceParserHelper;
-import org.elasticsearch.search.aggregations.support.ValuesSourceType;
 
 import java.io.IOException;
 import java.util.Map;
@@ -62,11 +62,11 @@ public class MedianAbsoluteDeviationAggregationBuilder extends LeafOnly<ValuesSo
     private double compression = 1000d;
 
     public MedianAbsoluteDeviationAggregationBuilder(String name) {
-        super(name, ValuesSourceType.NUMERIC, ValueType.NUMERIC);
+        super(name, CoreValuesSourceType.NUMERIC, ValueType.NUMERIC);
     }
 
     public MedianAbsoluteDeviationAggregationBuilder(StreamInput in) throws IOException {
-        super(in, ValuesSourceType.NUMERIC, ValueType.NUMERIC);
+        super(in, CoreValuesSourceType.NUMERIC, ValueType.NUMERIC);
         compression = in.readDouble();
     }
 

+ 3 - 3
server/src/main/java/org/elasticsearch/search/aggregations/metrics/MinAggregationBuilder.java

@@ -28,13 +28,13 @@ import org.elasticsearch.index.query.QueryShardContext;
 import org.elasticsearch.search.aggregations.AggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 import org.elasticsearch.search.aggregations.support.ValueType;
 import org.elasticsearch.search.aggregations.support.ValuesSource;
 import org.elasticsearch.search.aggregations.support.ValuesSource.Numeric;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder;
 import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
 import org.elasticsearch.search.aggregations.support.ValuesSourceParserHelper;
-import org.elasticsearch.search.aggregations.support.ValuesSourceType;
 
 import java.io.IOException;
 import java.util.Map;
@@ -53,7 +53,7 @@ public class MinAggregationBuilder extends ValuesSourceAggregationBuilder.LeafOn
     }
 
     public MinAggregationBuilder(String name) {
-        super(name, ValuesSourceType.NUMERIC, ValueType.NUMERIC);
+        super(name, CoreValuesSourceType.NUMERIC, ValueType.NUMERIC);
     }
 
     protected MinAggregationBuilder(MinAggregationBuilder clone, Builder factoriesBuilder, Map<String, Object> metaData) {
@@ -69,7 +69,7 @@ public class MinAggregationBuilder extends ValuesSourceAggregationBuilder.LeafOn
      * Read from a stream.
      */
     public MinAggregationBuilder(StreamInput in) throws IOException {
-        super(in, ValuesSourceType.NUMERIC, ValueType.NUMERIC);
+        super(in, CoreValuesSourceType.NUMERIC, ValueType.NUMERIC);
     }
 
     @Override

+ 3 - 3
server/src/main/java/org/elasticsearch/search/aggregations/metrics/PercentileRanksAggregationBuilder.java

@@ -30,6 +30,7 @@ import org.elasticsearch.index.query.QueryShardContext;
 import org.elasticsearch.search.aggregations.AggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 import org.elasticsearch.search.aggregations.support.ValueType;
 import org.elasticsearch.search.aggregations.support.ValuesSource;
 import org.elasticsearch.search.aggregations.support.ValuesSource.Numeric;
@@ -37,7 +38,6 @@ import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuil
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory;
 import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
 import org.elasticsearch.search.aggregations.support.ValuesSourceParserHelper;
-import org.elasticsearch.search.aggregations.support.ValuesSourceType;
 
 import java.io.IOException;
 import java.util.Arrays;
@@ -115,7 +115,7 @@ public class PercentileRanksAggregationBuilder extends LeafOnly<ValuesSource.Num
     }
 
     public PercentileRanksAggregationBuilder(String name, double[] values) {
-        super(name, ValuesSourceType.NUMERIC, ValueType.NUMERIC);
+        super(name, CoreValuesSourceType.NUMERIC, ValueType.NUMERIC);
         if (values == null) {
             throw new IllegalArgumentException("[values] must not be null: [" + name + "]");
         }
@@ -147,7 +147,7 @@ public class PercentileRanksAggregationBuilder extends LeafOnly<ValuesSource.Num
      * Read from a stream.
      */
     public PercentileRanksAggregationBuilder(StreamInput in) throws IOException {
-        super(in, ValuesSourceType.NUMERIC, ValueType.NUMERIC);
+        super(in, CoreValuesSourceType.NUMERIC, ValueType.NUMERIC);
         values = in.readDoubleArray();
         keyed = in.readBoolean();
         numberOfSignificantValueDigits = in.readVInt();

+ 3 - 3
server/src/main/java/org/elasticsearch/search/aggregations/metrics/PercentilesAggregationBuilder.java

@@ -29,6 +29,7 @@ import org.elasticsearch.index.query.QueryShardContext;
 import org.elasticsearch.search.aggregations.AggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 import org.elasticsearch.search.aggregations.support.ValueType;
 import org.elasticsearch.search.aggregations.support.ValuesSource;
 import org.elasticsearch.search.aggregations.support.ValuesSource.Numeric;
@@ -36,7 +37,6 @@ import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuil
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory;
 import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
 import org.elasticsearch.search.aggregations.support.ValuesSourceParserHelper;
-import org.elasticsearch.search.aggregations.support.ValuesSourceType;
 
 import java.io.IOException;
 import java.util.Arrays;
@@ -132,7 +132,7 @@ public class PercentilesAggregationBuilder extends LeafOnly<ValuesSource.Numeric
     private boolean keyed = true;
 
     public PercentilesAggregationBuilder(String name) {
-        super(name, ValuesSourceType.NUMERIC, ValueType.NUMERIC);
+        super(name, CoreValuesSourceType.NUMERIC, ValueType.NUMERIC);
     }
 
     protected PercentilesAggregationBuilder(PercentilesAggregationBuilder clone,
@@ -154,7 +154,7 @@ public class PercentilesAggregationBuilder extends LeafOnly<ValuesSource.Numeric
      * Read from a stream.
      */
     public PercentilesAggregationBuilder(StreamInput in) throws IOException {
-        super(in, ValuesSourceType.NUMERIC, ValueType.NUMERIC);
+        super(in, CoreValuesSourceType.NUMERIC, ValueType.NUMERIC);
         percents = in.readDoubleArray();
         keyed = in.readBoolean();
         numberOfSignificantValueDigits = in.readVInt();

+ 3 - 3
server/src/main/java/org/elasticsearch/search/aggregations/metrics/StatsAggregationBuilder.java

@@ -34,7 +34,7 @@ import org.elasticsearch.search.aggregations.support.ValuesSource.Numeric;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder;
 import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
 import org.elasticsearch.search.aggregations.support.ValuesSourceParserHelper;
-import org.elasticsearch.search.aggregations.support.ValuesSourceType;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 
 import java.io.IOException;
 import java.util.Map;
@@ -53,7 +53,7 @@ public class StatsAggregationBuilder extends ValuesSourceAggregationBuilder.Leaf
     }
 
     public StatsAggregationBuilder(String name) {
-        super(name, ValuesSourceType.NUMERIC, ValueType.NUMERIC);
+        super(name, CoreValuesSourceType.NUMERIC, ValueType.NUMERIC);
     }
 
     protected StatsAggregationBuilder(StatsAggregationBuilder clone,
@@ -70,7 +70,7 @@ public class StatsAggregationBuilder extends ValuesSourceAggregationBuilder.Leaf
      * Read from a stream.
      */
     public StatsAggregationBuilder(StreamInput in) throws IOException {
-        super(in, ValuesSourceType.NUMERIC, ValueType.NUMERIC);
+        super(in, CoreValuesSourceType.NUMERIC, ValueType.NUMERIC);
     }
 
     @Override

+ 3 - 3
server/src/main/java/org/elasticsearch/search/aggregations/metrics/SumAggregationBuilder.java

@@ -28,13 +28,13 @@ import org.elasticsearch.index.query.QueryShardContext;
 import org.elasticsearch.search.aggregations.AggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 import org.elasticsearch.search.aggregations.support.ValueType;
 import org.elasticsearch.search.aggregations.support.ValuesSource;
 import org.elasticsearch.search.aggregations.support.ValuesSource.Numeric;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder;
 import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
 import org.elasticsearch.search.aggregations.support.ValuesSourceParserHelper;
-import org.elasticsearch.search.aggregations.support.ValuesSourceType;
 
 import java.io.IOException;
 import java.util.Map;
@@ -53,7 +53,7 @@ public class SumAggregationBuilder extends ValuesSourceAggregationBuilder.LeafOn
     }
 
     public SumAggregationBuilder(String name) {
-        super(name, ValuesSourceType.NUMERIC, ValueType.NUMERIC);
+        super(name, CoreValuesSourceType.NUMERIC, ValueType.NUMERIC);
     }
 
     protected SumAggregationBuilder(SumAggregationBuilder clone, Builder factoriesBuilder, Map<String, Object> metaData) {
@@ -69,7 +69,7 @@ public class SumAggregationBuilder extends ValuesSourceAggregationBuilder.LeafOn
      * Read from a stream.
      */
     public SumAggregationBuilder(StreamInput in) throws IOException {
-        super(in, ValuesSourceType.NUMERIC, ValueType.NUMERIC);
+        super(in, CoreValuesSourceType.NUMERIC, ValueType.NUMERIC);
     }
 
     @Override

+ 3 - 3
server/src/main/java/org/elasticsearch/search/aggregations/metrics/ValueCountAggregationBuilder.java

@@ -29,12 +29,12 @@ import org.elasticsearch.index.query.QueryShardContext;
 import org.elasticsearch.search.aggregations.AggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 import org.elasticsearch.search.aggregations.support.ValueType;
 import org.elasticsearch.search.aggregations.support.ValuesSource;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder;
 import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
 import org.elasticsearch.search.aggregations.support.ValuesSourceParserHelper;
-import org.elasticsearch.search.aggregations.support.ValuesSourceType;
 
 import java.io.IOException;
 import java.util.Map;
@@ -53,7 +53,7 @@ public class ValueCountAggregationBuilder extends ValuesSourceAggregationBuilder
     }
 
     public ValueCountAggregationBuilder(String name, ValueType targetValueType) {
-        super(name, ValuesSourceType.ANY, targetValueType);
+        super(name, CoreValuesSourceType.ANY, targetValueType);
     }
 
     protected ValueCountAggregationBuilder(ValueCountAggregationBuilder clone,
@@ -70,7 +70,7 @@ public class ValueCountAggregationBuilder extends ValuesSourceAggregationBuilder
      * Read from a stream.
      */
     public ValueCountAggregationBuilder(StreamInput in) throws IOException {
-        super(in, ValuesSourceType.ANY);
+        super(in, CoreValuesSourceType.ANY);
     }
 
     @Override

+ 218 - 0
server/src/main/java/org/elasticsearch/search/aggregations/support/CoreValuesSourceType.java

@@ -0,0 +1,218 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch 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.elasticsearch.search.aggregations.support;
+
+import org.apache.lucene.util.BytesRef;
+import org.elasticsearch.common.geo.GeoPoint;
+import org.elasticsearch.common.io.stream.StreamInput;
+import org.elasticsearch.common.io.stream.StreamOutput;
+import org.elasticsearch.common.io.stream.Writeable;
+import org.elasticsearch.index.fielddata.IndexFieldData;
+import org.elasticsearch.index.fielddata.IndexGeoPointFieldData;
+import org.elasticsearch.index.fielddata.IndexNumericFieldData;
+import org.elasticsearch.index.fielddata.IndexOrdinalsFieldData;
+import org.elasticsearch.index.mapper.MappedFieldType;
+import org.elasticsearch.index.mapper.RangeFieldMapper;
+import org.elasticsearch.script.AggregationScript;
+import org.elasticsearch.search.DocValueFormat;
+import org.elasticsearch.search.aggregations.AggregationExecutionException;
+
+import java.io.IOException;
+import java.util.Locale;
+import java.util.function.LongSupplier;
+
+/**
+ * {@link CoreValuesSourceType} holds the {@link ValuesSourceType} implementations for the core aggregations package.
+ */
+public enum CoreValuesSourceType implements Writeable, ValuesSourceType {
+    ANY {
+        // ANY still has a lot of special handling in ValuesSourceConfig, and as such doesn't adhere to this interface yet
+        @Override
+        public ValuesSource getEmpty() {
+            // TODO: Implement this or get rid of ANY
+            throw new UnsupportedOperationException("CoreValuesSourceType.ANY is still a special case");
+        }
+
+        @Override
+        public ValuesSource getScript(AggregationScript.LeafFactory script, ValueType scriptValueType) {
+            // TODO: Implement this or get rid of ANY
+            throw new UnsupportedOperationException("CoreValuesSourceType.ANY is still a special case");
+        }
+
+        @Override
+        public ValuesSource getField(FieldContext fieldContext, AggregationScript.LeafFactory script) {
+            // TODO: Implement this or get rid of ANY
+            throw new UnsupportedOperationException("CoreValuesSourceType.ANY is still a special case");
+        }
+
+        @Override
+        public ValuesSource replaceMissing(ValuesSource valuesSource, Object rawMissing, DocValueFormat docValueFormat, LongSupplier now) {
+            return BYTES.replaceMissing(valuesSource, rawMissing, docValueFormat, now);
+        }
+    },
+    NUMERIC {
+        @Override
+        public ValuesSource getEmpty() {
+            return ValuesSource.Numeric.EMPTY;
+        }
+
+        @Override
+        public ValuesSource getScript(AggregationScript.LeafFactory script, ValueType scriptValueType) {
+            return new ValuesSource.Numeric.Script(script, scriptValueType);
+        }
+
+        @Override
+        public ValuesSource getField(FieldContext fieldContext, AggregationScript.LeafFactory script) {
+
+            if ((fieldContext.indexFieldData() instanceof IndexNumericFieldData) == false) {
+                // TODO: Is this the correct exception type here?
+                throw new IllegalArgumentException("Expected numeric type on field [" + fieldContext.field() +
+                    "], but got [" + fieldContext.fieldType().typeName() + "]");
+            }
+
+            ValuesSource.Numeric dataSource = new ValuesSource.Numeric.FieldData((IndexNumericFieldData)fieldContext.indexFieldData());
+            if (script != null) {
+                // Value script case
+                dataSource = new ValuesSource.Numeric.WithScript(dataSource, script);
+            }
+            return dataSource;
+        }
+
+        @Override
+        public ValuesSource replaceMissing(ValuesSource valuesSource, Object rawMissing, DocValueFormat docValueFormat, LongSupplier now) {
+            Number missing = docValueFormat.parseDouble(rawMissing.toString(), false, now);
+            return MissingValues.replaceMissing((ValuesSource.Numeric) valuesSource, missing);
+        }
+    },
+    BYTES {
+        @Override
+        public ValuesSource getEmpty() {
+            return ValuesSource.Bytes.WithOrdinals.EMPTY;
+        }
+
+        @Override
+        public ValuesSource getScript(AggregationScript.LeafFactory script, ValueType scriptValueType) {
+            return new ValuesSource.Bytes.Script(script);
+        }
+
+        @Override
+        public ValuesSource getField(FieldContext fieldContext, AggregationScript.LeafFactory script) {
+            final IndexFieldData<?> indexFieldData = fieldContext.indexFieldData();
+            ValuesSource dataSource;
+            if (indexFieldData instanceof IndexOrdinalsFieldData) {
+                dataSource = new ValuesSource.Bytes.WithOrdinals.FieldData((IndexOrdinalsFieldData) indexFieldData);
+            } else {
+                dataSource = new ValuesSource.Bytes.FieldData(indexFieldData);
+            }
+            if (script != null) {
+                // Again, what's the difference between WithScript and Script?
+                dataSource = new ValuesSource.Bytes.WithScript(dataSource, script);
+            }
+            return dataSource;
+        }
+
+        @Override
+        public ValuesSource replaceMissing(ValuesSource valuesSource, Object rawMissing, DocValueFormat docValueFormat, LongSupplier now) {
+            final BytesRef missing = docValueFormat.parseBytesRef(rawMissing.toString());
+            if (valuesSource instanceof ValuesSource.Bytes.WithOrdinals) {
+                return MissingValues.replaceMissing((ValuesSource.Bytes.WithOrdinals) valuesSource, missing);
+            } else {
+                return MissingValues.replaceMissing((ValuesSource.Bytes) valuesSource, missing);
+            }
+        }
+    },
+    GEOPOINT {
+        @Override
+        public ValuesSource getEmpty() {
+            return ValuesSource.GeoPoint.EMPTY;
+        }
+
+        @Override
+        public ValuesSource getScript(AggregationScript.LeafFactory script, ValueType scriptValueType) {
+            throw new AggregationExecutionException("value source of type [" + this.value() + "] is not supported by scripts");
+        }
+
+        @Override
+        public ValuesSource getField(FieldContext fieldContext, AggregationScript.LeafFactory script) {
+            if (!(fieldContext.indexFieldData() instanceof IndexGeoPointFieldData)) {
+                // TODO: Is this the correct exception type here?
+                throw new IllegalArgumentException("Expected geo_point type on field [" + fieldContext.field() +
+                    "], but got [" + fieldContext.fieldType().typeName() + "]");
+            }
+
+            return new ValuesSource.GeoPoint.Fielddata((IndexGeoPointFieldData) fieldContext.indexFieldData());
+        }
+
+        @Override
+        public ValuesSource replaceMissing(ValuesSource valuesSource, Object rawMissing, DocValueFormat docValueFormat, LongSupplier now) {
+            // TODO: also support the structured formats of geo points
+            final GeoPoint missing = new GeoPoint(rawMissing.toString());
+            return MissingValues.replaceMissing((ValuesSource.GeoPoint) valuesSource, missing);
+        }
+    },
+    RANGE {
+        @Override
+        public ValuesSource getEmpty() {
+            // TODO: Is this the correct exception type here?
+            throw new IllegalArgumentException("Can't deal with unmapped ValuesSource type " + this.value());
+        }
+
+        @Override
+        public ValuesSource getScript(AggregationScript.LeafFactory script, ValueType scriptValueType) {
+            throw new AggregationExecutionException("value source of type [" + this.value() + "] is not supported by scripts");
+        }
+
+        @Override
+        public ValuesSource getField(FieldContext fieldContext, AggregationScript.LeafFactory script) {
+            MappedFieldType fieldType = fieldContext.fieldType();
+
+            if (fieldType instanceof RangeFieldMapper.RangeFieldType == false) {
+                // TODO: Is this the correct exception type here?
+                throw new IllegalStateException("Asked for range ValuesSource, but field is of type " + fieldType.name());
+            }
+            RangeFieldMapper.RangeFieldType rangeFieldType = (RangeFieldMapper.RangeFieldType)fieldType;
+            return new ValuesSource.Range(fieldContext.indexFieldData(), rangeFieldType.rangeType());
+        }
+
+        @Override
+        public ValuesSource replaceMissing(ValuesSource valuesSource, Object rawMissing, DocValueFormat docValueFormat, LongSupplier now) {
+            throw new IllegalArgumentException("Can't apply missing values on a " + valuesSource.getClass());
+        }
+    };
+
+    public static ValuesSourceType fromString(String name) {
+        return valueOf(name.trim().toUpperCase(Locale.ROOT));
+    }
+
+    public static ValuesSourceType fromStream(StreamInput in) throws IOException {
+        return in.readEnum(CoreValuesSourceType.class);
+    }
+
+    @Override
+    public void writeTo(StreamOutput out) throws IOException {
+        CoreValuesSourceType state = this;
+        out.writeEnum(state);
+    }
+
+    public String value() {
+        return name().toLowerCase(Locale.ROOT);
+    }
+
+}

+ 10 - 10
server/src/main/java/org/elasticsearch/search/aggregations/support/ValueType.java

@@ -35,22 +35,22 @@ import java.time.ZoneOffset;
 
 public enum ValueType implements Writeable {
 
-    STRING((byte) 1, "string", "string", ValuesSourceType.BYTES,
+    STRING((byte) 1, "string", "string", CoreValuesSourceType.BYTES,
             IndexFieldData.class, DocValueFormat.RAW),
     LONG((byte) 2, "byte|short|integer|long", "long",
-                    ValuesSourceType.NUMERIC,
+                    CoreValuesSourceType.NUMERIC,
             IndexNumericFieldData.class, DocValueFormat.RAW),
-    DOUBLE((byte) 3, "float|double", "double", ValuesSourceType.NUMERIC, IndexNumericFieldData.class, DocValueFormat.RAW),
-    NUMBER((byte) 4, "number", "number", ValuesSourceType.NUMERIC, IndexNumericFieldData.class, DocValueFormat.RAW),
-    DATE((byte) 5, "date", "date", ValuesSourceType.NUMERIC, IndexNumericFieldData.class,
+    DOUBLE((byte) 3, "float|double", "double", CoreValuesSourceType.NUMERIC, IndexNumericFieldData.class, DocValueFormat.RAW),
+    NUMBER((byte) 4, "number", "number", CoreValuesSourceType.NUMERIC, IndexNumericFieldData.class, DocValueFormat.RAW),
+    DATE((byte) 5, "date", "date", CoreValuesSourceType.NUMERIC, IndexNumericFieldData.class,
             new DocValueFormat.DateTime(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER, ZoneOffset.UTC,
                 DateFieldMapper.Resolution.MILLISECONDS)),
-    IP((byte) 6, "ip", "ip", ValuesSourceType.BYTES, IndexFieldData.class, DocValueFormat.IP),
+    IP((byte) 6, "ip", "ip", CoreValuesSourceType.BYTES, IndexFieldData.class, DocValueFormat.IP),
     // TODO: what is the difference between "number" and "numeric"?
-    NUMERIC((byte) 7, "numeric", "numeric", ValuesSourceType.NUMERIC, IndexNumericFieldData.class, DocValueFormat.RAW),
-    GEOPOINT((byte) 8, "geo_point", "geo_point", ValuesSourceType.GEOPOINT, IndexGeoPointFieldData.class, DocValueFormat.GEOHASH),
-    BOOLEAN((byte) 9, "boolean", "boolean", ValuesSourceType.NUMERIC, IndexNumericFieldData.class, DocValueFormat.BOOLEAN),
-    RANGE((byte) 10, "range", "range", ValuesSourceType.RANGE, BinaryDVIndexFieldData.class, DocValueFormat.RAW);
+    NUMERIC((byte) 7, "numeric", "numeric", CoreValuesSourceType.NUMERIC, IndexNumericFieldData.class, DocValueFormat.RAW),
+    GEOPOINT((byte) 8, "geo_point", "geo_point", CoreValuesSourceType.GEOPOINT, IndexGeoPointFieldData.class, DocValueFormat.GEOHASH),
+    BOOLEAN((byte) 9, "boolean", "boolean", CoreValuesSourceType.NUMERIC, IndexNumericFieldData.class, DocValueFormat.BOOLEAN),
+    RANGE((byte) 10, "range", "range", CoreValuesSourceType.RANGE, BinaryDVIndexFieldData.class, DocValueFormat.RAW);
 
     final String description;
     final ValuesSourceType valuesSourceType;

+ 74 - 62
server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSource.java

@@ -44,7 +44,7 @@ import org.elasticsearch.index.fielddata.SortingBinaryDocValues;
 import org.elasticsearch.index.fielddata.SortingNumericDoubleValues;
 import org.elasticsearch.index.mapper.RangeType;
 import org.elasticsearch.script.AggregationScript;
-import org.elasticsearch.search.aggregations.support.ValuesSource.WithScript.BytesValues;
+import org.elasticsearch.search.aggregations.support.ValuesSource.Bytes.WithScript.BytesValues;
 import org.elasticsearch.search.aggregations.support.values.ScriptBytesValues;
 import org.elasticsearch.search.aggregations.support.values.ScriptDoubleValues;
 import org.elasticsearch.search.aggregations.support.values.ScriptLongValues;
@@ -219,6 +219,9 @@ public abstract class ValuesSource {
 
         }
 
+        /**
+         * {@link ValuesSource} implementation for stand alone scripts returning a Bytes value
+         */
         public static class Script extends Bytes {
 
             private final AggregationScript.LeafFactory script;
@@ -237,6 +240,69 @@ public abstract class ValuesSource {
                 return script.needs_score();
             }
         }
+
+        // No need to implement ReaderContextAware here, the delegate already takes care of updating data structures
+        /**
+         * {@link ValuesSource} subclass for Bytes fields with a Value Script applied
+         */
+        public static class WithScript extends Bytes {
+
+            private final ValuesSource delegate;
+            private final AggregationScript.LeafFactory script;
+
+            public WithScript(ValuesSource delegate, AggregationScript.LeafFactory script) {
+                this.delegate = delegate;
+                this.script = script;
+            }
+
+            @Override
+            public boolean needsScores() {
+                return script.needs_score();
+            }
+
+            @Override
+            public SortedBinaryDocValues bytesValues(LeafReaderContext context) throws IOException {
+                return new BytesValues(delegate.bytesValues(context), script.newInstance(context));
+            }
+
+            static class BytesValues extends SortingBinaryDocValues implements ScorerAware {
+
+                private final SortedBinaryDocValues bytesValues;
+                private final AggregationScript script;
+
+                BytesValues(SortedBinaryDocValues bytesValues, AggregationScript script) {
+                    this.bytesValues = bytesValues;
+                    this.script = script;
+                }
+
+                @Override
+                public void setScorer(Scorable scorer) {
+                    script.setScorer(scorer);
+                }
+
+                @Override
+                public boolean advanceExact(int doc) throws IOException {
+                    if (bytesValues.advanceExact(doc)) {
+                        count = bytesValues.docValueCount();
+                        grow();
+                        script.setDocument(doc);
+                        for (int i = 0; i < count; ++i) {
+                            final BytesRef value = bytesValues.nextValue();
+                            script.setNextAggregationValue(value.utf8ToString());
+                            Object run = script.execute();
+                            CollectionUtils.ensureNoSelfReferences(run, "ValuesSource.BytesValues script");
+                            values[i].copyChars(run.toString());
+                        }
+                        sort();
+                        return true;
+                    } else {
+                        count = 0;
+                        grow();
+                        return false;
+                    }
+                }
+            }
+        }
     }
 
     public abstract static class Numeric extends ValuesSource {
@@ -285,6 +351,9 @@ public abstract class ValuesSource {
             }
         }
 
+        /**
+         * {@link ValuesSource} subclass for Numeric fields with a Value Script applied
+         */
         public static class WithScript extends Numeric {
 
             private final Numeric delegate;
@@ -307,7 +376,7 @@ public abstract class ValuesSource {
 
             @Override
             public SortedBinaryDocValues bytesValues(LeafReaderContext context) throws IOException {
-                return new ValuesSource.WithScript.BytesValues(delegate.bytesValues(context), script.newInstance(context));
+                return new Bytes.WithScript.BytesValues(delegate.bytesValues(context), script.newInstance(context));
             }
 
             @Override
@@ -412,6 +481,9 @@ public abstract class ValuesSource {
             }
         }
 
+        /**
+         * {@link ValuesSource} implementation for stand alone scripts returning a Numeric value
+         */
         public static class Script extends Numeric {
             private final AggregationScript.LeafFactory script;
             private final ValueType scriptValueType;
@@ -449,66 +521,6 @@ public abstract class ValuesSource {
 
     }
 
-    // No need to implement ReaderContextAware here, the delegate already takes care of updating data structures
-    public static class WithScript extends Bytes {
-
-        private final ValuesSource delegate;
-        private final AggregationScript.LeafFactory script;
-
-        public WithScript(ValuesSource delegate, AggregationScript.LeafFactory script) {
-            this.delegate = delegate;
-            this.script = script;
-        }
-
-        @Override
-        public boolean needsScores() {
-            return script.needs_score();
-        }
-
-        @Override
-        public SortedBinaryDocValues bytesValues(LeafReaderContext context) throws IOException {
-            return new BytesValues(delegate.bytesValues(context), script.newInstance(context));
-        }
-
-        static class BytesValues extends SortingBinaryDocValues implements ScorerAware {
-
-            private final SortedBinaryDocValues bytesValues;
-            private final AggregationScript script;
-
-            BytesValues(SortedBinaryDocValues bytesValues, AggregationScript script) {
-                this.bytesValues = bytesValues;
-                this.script = script;
-            }
-
-            @Override
-            public void setScorer(Scorable scorer) {
-                script.setScorer(scorer);
-            }
-
-            @Override
-            public boolean advanceExact(int doc) throws IOException {
-                if (bytesValues.advanceExact(doc)) {
-                    count = bytesValues.docValueCount();
-                    grow();
-                    script.setDocument(doc);
-                    for (int i = 0; i < count; ++i) {
-                        final BytesRef value = bytesValues.nextValue();
-                        script.setNextAggregationValue(value.utf8ToString());
-                        Object run = script.execute();
-                        CollectionUtils.ensureNoSelfReferences(run, "ValuesSource.BytesValues script");
-                        values[i].copyChars(run.toString());
-                    }
-                    sort();
-                    return true;
-                } else {
-                    count = 0;
-                    grow();
-                    return false;
-                }
-            }
-        }
-    }
-
     public abstract static class GeoPoint extends ValuesSource {
 
         public static final GeoPoint EMPTY = new GeoPoint() {

+ 4 - 4
server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceAggregationBuilder.java

@@ -315,14 +315,14 @@ public abstract class ValuesSourceAggregationBuilder<VS extends ValuesSource, AB
     }
 
     /**
-     * Provide a hook for aggregations to have finer grained control of the ValuesSourceType for script values.  This will only be called if
-     * the user did not supply a type hint for the script.  The script object is provided for reference.
+     * Provide a hook for aggregations to have finer grained control of the CoreValuesSourceType for script values.  This will only be
+     * called if the user did not supply a type hint for the script.  The script object is provided for reference.
      *
      * @param script - The user supplied script
-     * @return The ValuesSourceType we expect this script to yield.
+     * @return The CoreValuesSourceType we expect this script to yield.
      */
     protected ValuesSourceType resolveScriptAny(Script script) {
-        return ValuesSourceType.BYTES;
+        return CoreValuesSourceType.BYTES;
     }
 
     /**

+ 2 - 2
server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceAggregatorFactory.java

@@ -53,8 +53,8 @@ public abstract class ValuesSourceAggregatorFactory<VS extends ValuesSource> ext
     /**
      * This method provides a hook for aggregations that need finer grained control over the ValuesSource selected when the user supplies a
      * missing value and there is no mapped field to infer the type from.  This will only be called for aggregations that specify the
-     * ValuesSourceType.ANY in their constructors (On the builder class).  The user supplied object is passed as a parameter, so its type
-     * may be inspected as needed.
+     * CoreValuesSourceType.ANY in their constructors (On the builder class).  The user supplied object is passed as a parameter, so its
+     * type * may be inspected as needed.
      *
      * Generally, only the type of the returned ValuesSource is used, so returning the EMPTY instance of the chosen type is recommended.
      *

+ 25 - 125
server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceConfig.java

@@ -18,14 +18,11 @@
  */
 package org.elasticsearch.search.aggregations.support;
 
-import org.apache.lucene.util.BytesRef;
 import org.elasticsearch.common.Nullable;
-import org.elasticsearch.common.geo.GeoPoint;
 import org.elasticsearch.common.time.DateFormatter;
 import org.elasticsearch.index.fielddata.IndexFieldData;
 import org.elasticsearch.index.fielddata.IndexGeoPointFieldData;
 import org.elasticsearch.index.fielddata.IndexNumericFieldData;
-import org.elasticsearch.index.fielddata.IndexOrdinalsFieldData;
 import org.elasticsearch.index.mapper.DateFieldMapper;
 import org.elasticsearch.index.mapper.MappedFieldType;
 import org.elasticsearch.index.mapper.RangeFieldMapper;
@@ -33,7 +30,6 @@ import org.elasticsearch.index.query.QueryShardContext;
 import org.elasticsearch.script.AggregationScript;
 import org.elasticsearch.script.Script;
 import org.elasticsearch.search.DocValueFormat;
-import org.elasticsearch.search.aggregations.AggregationExecutionException;
 
 import java.time.ZoneId;
 import java.time.ZoneOffset;
@@ -55,7 +51,7 @@ public class ValuesSourceConfig<VS extends ValuesSource> {
         Object missing,
         ZoneId timeZone,
         String format) {
-        return resolve(context, valueType, field, script, missing, timeZone, format, s -> ValuesSourceType.BYTES);
+        return resolve(context, valueType, field, script, missing, timeZone, format, s -> CoreValuesSourceType.BYTES);
     }
 
     /**
@@ -73,12 +69,12 @@ public class ValuesSourceConfig<VS extends ValuesSource> {
 
         if (field == null) {
             if (script == null) {
-                ValuesSourceConfig<VS> config = new ValuesSourceConfig<>(ValuesSourceType.ANY);
+                ValuesSourceConfig<VS> config = new ValuesSourceConfig<>(CoreValuesSourceType.ANY);
                 config.format(resolveFormat(null, valueType, timeZone));
                 return config;
             }
-            ValuesSourceType valuesSourceType = valueType != null ? valueType.getValuesSourceType() : ValuesSourceType.ANY;
-            if (valuesSourceType == ValuesSourceType.ANY) {
+            ValuesSourceType valuesSourceType = valueType != null ? valueType.getValuesSourceType() : CoreValuesSourceType.ANY;
+            if (valuesSourceType == CoreValuesSourceType.ANY) {
                 // the specific value source type is undefined, but for scripts,
                 // we need to have a specific value source
                 // type to know how to handle the script values, so we fallback
@@ -96,7 +92,7 @@ public class ValuesSourceConfig<VS extends ValuesSource> {
 
         MappedFieldType fieldType = context.fieldMapper(field);
         if (fieldType == null) {
-            ValuesSourceType valuesSourceType = valueType != null ? valueType.getValuesSourceType() : ValuesSourceType.ANY;
+            ValuesSourceType valuesSourceType = valueType != null ? valueType.getValuesSourceType() : CoreValuesSourceType.ANY;
             ValuesSourceConfig<VS> config = new ValuesSourceConfig<>(valuesSourceType);
             config.missing(missing);
             config.timezone(timeZone);
@@ -113,14 +109,14 @@ public class ValuesSourceConfig<VS extends ValuesSource> {
 
         ValuesSourceConfig<VS> config;
         if (indexFieldData instanceof IndexNumericFieldData) {
-            config = new ValuesSourceConfig<>(ValuesSourceType.NUMERIC);
+            config = new ValuesSourceConfig<>(CoreValuesSourceType.NUMERIC);
         } else if (indexFieldData instanceof IndexGeoPointFieldData) {
-            config = new ValuesSourceConfig<>(ValuesSourceType.GEOPOINT);
+            config = new ValuesSourceConfig<>(CoreValuesSourceType.GEOPOINT);
         } else if (fieldType instanceof RangeFieldMapper.RangeFieldType) {
-            config = new ValuesSourceConfig<>(ValuesSourceType.RANGE);
+            config = new ValuesSourceConfig<>(CoreValuesSourceType.RANGE);
         } else {
             if (valueType == null) {
-                config = new ValuesSourceConfig<>(ValuesSourceType.BYTES);
+                config = new ValuesSourceConfig<>(CoreValuesSourceType.BYTES);
             } else {
                 config = new ValuesSourceConfig<>(valueType.getValuesSourceType());
             }
@@ -262,126 +258,30 @@ public class ValuesSourceConfig<VS extends ValuesSource> {
             if (missing() == null) {
                 // otherwise we will have values because of the missing value
                 vs = null;
-            } else if (valueSourceType() == ValuesSourceType.NUMERIC) {
-                vs = (VS) ValuesSource.Numeric.EMPTY;
-            } else if (valueSourceType() == ValuesSourceType.GEOPOINT) {
-                vs = (VS) ValuesSource.GeoPoint.EMPTY;
-            } else if (valueSourceType() == ValuesSourceType.BYTES) {
-                vs = (VS) ValuesSource.Bytes.WithOrdinals.EMPTY;
-            } else if (valueSourceType() == ValuesSourceType.ANY) {
+            } else if (valueSourceType() == CoreValuesSourceType.ANY) {
+                // TODO: Clean up special cases around CoreValuesSourceType.ANY
                 vs = (VS) resolveMissingAny.apply(missing());
             } else {
-                throw new IllegalArgumentException("Can't deal with unmapped ValuesSource type " + valueSourceType());
+                vs = (VS) valueSourceType().getEmpty();
             }
         } else {
-            vs = originalValuesSource();
-        }
-
-        if (missing() == null) {
-            return vs;
-        }
-
-        if (vs instanceof ValuesSource.Bytes) {
-            final BytesRef missing = format.parseBytesRef(missing().toString());
-            if (vs instanceof ValuesSource.Bytes.WithOrdinals) {
-                return (VS) MissingValues.replaceMissing((ValuesSource.Bytes.WithOrdinals) vs, missing);
+            if (fieldContext() == null) {
+                vs = (VS) valueSourceType().getScript(script(), scriptValueType());
             } else {
-                return (VS) MissingValues.replaceMissing((ValuesSource.Bytes) vs, missing);
+                if (valueSourceType() == CoreValuesSourceType.ANY) {
+                    // TODO: Clean up special cases around CoreValuesSourceType.ANY
+                    // falling back to bytes values
+                    vs = (VS) CoreValuesSourceType.BYTES.getField(fieldContext(), script());
+                } else {
+                    // TODO: Better docs for Scripts vs Scripted Fields
+                    vs = (VS) valueSourceType().getField(fieldContext(), script());
+                }
             }
-        } else if (vs instanceof ValuesSource.Numeric) {
-            Number missing = format.parseDouble(missing().toString(), false, context::nowInMillis);
-            return (VS) MissingValues.replaceMissing((ValuesSource.Numeric) vs, missing);
-        } else if (vs instanceof ValuesSource.GeoPoint) {
-            // TODO: also support the structured formats of geo points
-            final GeoPoint missing = new GeoPoint(missing().toString());
-            return (VS) MissingValues.replaceMissing((ValuesSource.GeoPoint) vs, missing);
-        } else {
-            // Should not happen
-            throw new IllegalArgumentException("Can't apply missing values on a " + vs.getClass());
-        }
-    }
-
-    /**
-     * Return the original values source, before we apply `missing`.
-     */
-    private VS originalValuesSource() {
-        if (fieldContext() == null) {
-            if (valueSourceType() == ValuesSourceType.NUMERIC) {
-                return (VS) numericScript();
-            }
-            if (valueSourceType() == ValuesSourceType.BYTES) {
-                return (VS) bytesScript();
-            }
-            throw new AggregationExecutionException("value source of type [" + valueSourceType().name()
-                    + "] is not supported by scripts");
-        }
-
-        if (valueSourceType() == ValuesSourceType.NUMERIC) {
-            return (VS) numericField();
-        }
-        if (valueSourceType() == ValuesSourceType.GEOPOINT) {
-            return (VS) geoPointField();
-        }
-        if (valueSourceType() == ValuesSourceType.RANGE) {
-            return (VS) rangeField();
-        }
-        // falling back to bytes values
-        return (VS) bytesField();
-    }
-
-    private ValuesSource.Numeric numericScript() {
-        return new ValuesSource.Numeric.Script(script(), scriptValueType());
-    }
-
-    private ValuesSource.Numeric numericField() {
-
-        if (!(fieldContext().indexFieldData() instanceof IndexNumericFieldData)) {
-            throw new IllegalArgumentException("Expected numeric type on field [" + fieldContext().field() +
-                    "], but got [" + fieldContext().fieldType().typeName() + "]");
         }
 
-        ValuesSource.Numeric dataSource = new ValuesSource.Numeric.FieldData((IndexNumericFieldData)fieldContext().indexFieldData());
-        if (script() != null) {
-            dataSource = new ValuesSource.Numeric.WithScript(dataSource, script());
-        }
-        return dataSource;
-    }
-
-    private ValuesSource bytesField() {
-        final IndexFieldData<?> indexFieldData = fieldContext().indexFieldData();
-        ValuesSource dataSource;
-        if (indexFieldData instanceof IndexOrdinalsFieldData) {
-            dataSource = new ValuesSource.Bytes.WithOrdinals.FieldData((IndexOrdinalsFieldData) indexFieldData);
-        } else {
-            dataSource = new ValuesSource.Bytes.FieldData(indexFieldData);
-        }
-        if (script() != null) {
-            dataSource = new ValuesSource.WithScript(dataSource, script());
-        }
-        return dataSource;
-    }
-
-    private ValuesSource.Bytes bytesScript() {
-        return new ValuesSource.Bytes.Script(script());
-    }
-
-    private ValuesSource.GeoPoint geoPointField() {
-
-        if (!(fieldContext().indexFieldData() instanceof IndexGeoPointFieldData)) {
-            throw new IllegalArgumentException("Expected geo_point type on field [" + fieldContext().field() +
-                    "], but got [" + fieldContext().fieldType().typeName() + "]");
-        }
-
-        return new ValuesSource.GeoPoint.Fielddata((IndexGeoPointFieldData) fieldContext().indexFieldData());
-    }
-
-    private ValuesSource rangeField() {
-        MappedFieldType fieldType = fieldContext.fieldType();
-
-        if (fieldType instanceof RangeFieldMapper.RangeFieldType == false) {
-            throw new IllegalStateException("Asked for range ValuesSource, but field is of type " + fieldType.name());
+        if (missing() == null) {
+            return vs;
         }
-        RangeFieldMapper.RangeFieldType rangeFieldType = (RangeFieldMapper.RangeFieldType)fieldType;
-        return new ValuesSource.Range(fieldContext().indexFieldData(), rangeFieldType.rangeType());
+        return (VS) valueSourceType().replaceMissing(vs, missing, format, context::nowInMillis);
     }
 }

+ 46 - 26
server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceType.java

@@ -19,35 +19,55 @@
 
 package org.elasticsearch.search.aggregations.support;
 
-import org.elasticsearch.common.io.stream.StreamInput;
-import org.elasticsearch.common.io.stream.StreamOutput;
-import org.elasticsearch.common.io.stream.Writeable;
+import org.elasticsearch.script.AggregationScript;
+import org.elasticsearch.search.DocValueFormat;
 
-import java.io.IOException;
-import java.util.Locale;
+import java.util.function.LongSupplier;
 
-public enum ValuesSourceType implements Writeable {
-    ANY,
-    NUMERIC,
-    BYTES,
-    GEOPOINT,
-    RANGE;
-
-    public static ValuesSourceType fromString(String name) {
-        return valueOf(name.trim().toUpperCase(Locale.ROOT));
-    }
+/**
+ * ValuesSourceType wraps the creation of specific per-source instances each {@link ValuesSource} needs to provide.  Every top-level
+ * subclass of {@link ValuesSource} should have a corresponding implementation of this interface.  In general, new data types seeking
+ * aggregation support should create a top level {@link ValuesSource}, then implement this to return wrappers for the specific sources of
+ * values.
+ */
+public interface ValuesSourceType {
+    /**
+     * Called when an aggregation is operating over a known empty set (usually because the field isn't specified), this method allows for
+     * returning a no-op implementation.  All {@link ValuesSource}s should implement this method.
+     * @return - Empty specialization of the base {@link ValuesSource}
+     */
+    ValuesSource getEmpty();
 
-    public static ValuesSourceType fromStream(StreamInput in) throws IOException {
-        return in.readEnum(ValuesSourceType.class);
-    }
+    /**
+     * Returns the type-specific sub class for a script data source.  {@link ValuesSource}s that do not support scripts should throw
+     * {@link org.elasticsearch.search.aggregations.AggregationExecutionException}.  Note that this method is called when a script is
+     * operating without an underlying field.  Scripts operating over fields are handled by the script argument to getField below.
+     *
+     * @param script - The script being wrapped
+     * @param scriptValueType - The expected output type of the script
+     * @return - Script specialization of the base {@link ValuesSource}
+     */
+    ValuesSource getScript(AggregationScript.LeafFactory script, ValueType scriptValueType);
 
-    @Override
-    public void writeTo(StreamOutput out) throws IOException {
-        ValuesSourceType state = this;
-        out.writeEnum(state);
-    }
+    /**
+     * Return a {@link ValuesSource} wrapping a field for the given type.  All {@link ValuesSource}s must implement this method.
+     *
+     * @param fieldContext - The field being wrapped
+     * @param script - Optional script that might be applied over the field
+     * @return - Field specialization of the base {@link ValuesSource}
+     */
+    ValuesSource getField(FieldContext fieldContext, AggregationScript.LeafFactory script);
 
-    public String value() {
-        return name().toLowerCase(Locale.ROOT);
-    }
+    /**
+     * Apply the given missing value to an already-constructed {@link ValuesSource}.  Types which do not support missing values should throw
+     * {@link org.elasticsearch.search.aggregations.AggregationExecutionException}
+     *
+     * @param valuesSource - The original {@link ValuesSource}
+     * @param rawMissing - The missing value we got from the parser, typically a string or number
+     * @param docValueFormat - The format to use for further parsing the user supplied value, e.g. a date format
+     * @param now - Used in conjunction with the formatter, should return the current time in milliseconds
+     * @return - Wrapper over the provided {@link ValuesSource} to apply the given missing value
+     */
+    ValuesSource replaceMissing(ValuesSource valuesSource, Object rawMissing, DocValueFormat docValueFormat,
+                                LongSupplier now);
 }

+ 74 - 0
server/src/test/java/org/elasticsearch/search/aggregations/support/CoreValuesSourceTypeTests.java

@@ -0,0 +1,74 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch 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.elasticsearch.search.aggregations.support;
+
+import org.elasticsearch.common.io.stream.AbstractWriteableEnumTestCase;
+
+import java.io.IOException;
+
+import static org.hamcrest.Matchers.equalTo;
+
+public class CoreValuesSourceTypeTests extends AbstractWriteableEnumTestCase {
+
+    public CoreValuesSourceTypeTests() {
+        super(CoreValuesSourceType::fromStream);
+    }
+
+    @Override
+    public void testValidOrdinals() {
+        assertThat(CoreValuesSourceType.ANY.ordinal(), equalTo(0));
+        assertThat(CoreValuesSourceType.NUMERIC.ordinal(), equalTo(1));
+        assertThat(CoreValuesSourceType.BYTES.ordinal(), equalTo(2));
+        assertThat(CoreValuesSourceType.GEOPOINT.ordinal(), equalTo(3));
+        assertThat(CoreValuesSourceType.RANGE.ordinal(), equalTo(4));
+    }
+
+    @Override
+    public void testFromString() {
+        assertThat(CoreValuesSourceType.fromString("any"), equalTo(CoreValuesSourceType.ANY));
+        assertThat(CoreValuesSourceType.fromString("numeric"), equalTo(CoreValuesSourceType.NUMERIC));
+        assertThat(CoreValuesSourceType.fromString("bytes"), equalTo(CoreValuesSourceType.BYTES));
+        assertThat(CoreValuesSourceType.fromString("geopoint"), equalTo(CoreValuesSourceType.GEOPOINT));
+        assertThat(CoreValuesSourceType.fromString("range"), equalTo(CoreValuesSourceType.RANGE));
+        IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
+            () -> CoreValuesSourceType.fromString("does_not_exist"));
+        assertThat(e.getMessage(),
+            equalTo("No enum constant org.elasticsearch.search.aggregations.support.CoreValuesSourceType.DOES_NOT_EXIST"));
+        expectThrows(NullPointerException.class, () -> CoreValuesSourceType.fromString(null));
+    }
+
+    @Override
+    public void testReadFrom() throws IOException {
+        assertReadFromStream(0, CoreValuesSourceType.ANY);
+        assertReadFromStream(1, CoreValuesSourceType.NUMERIC);
+        assertReadFromStream(2, CoreValuesSourceType.BYTES);
+        assertReadFromStream(3, CoreValuesSourceType.GEOPOINT);
+        assertReadFromStream(4, CoreValuesSourceType.RANGE);
+    }
+
+    @Override
+    public void testWriteTo() throws IOException {
+        assertWriteToStream(CoreValuesSourceType.ANY, 0);
+        assertWriteToStream(CoreValuesSourceType.NUMERIC, 1);
+        assertWriteToStream(CoreValuesSourceType.BYTES, 2);
+        assertWriteToStream(CoreValuesSourceType.GEOPOINT, 3);
+        assertWriteToStream(CoreValuesSourceType.RANGE, 4);
+    }
+}

+ 0 - 73
server/src/test/java/org/elasticsearch/search/aggregations/support/ValuesSourceTypeTests.java

@@ -1,73 +0,0 @@
-/*
- * Licensed to Elasticsearch under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch 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.elasticsearch.search.aggregations.support;
-
-import org.elasticsearch.common.io.stream.AbstractWriteableEnumTestCase;
-
-import java.io.IOException;
-
-import static org.hamcrest.Matchers.equalTo;
-
-public class ValuesSourceTypeTests extends AbstractWriteableEnumTestCase {
-
-    public ValuesSourceTypeTests() {
-        super(ValuesSourceType::fromStream);
-    }
-
-    @Override
-    public void testValidOrdinals() {
-        assertThat(ValuesSourceType.ANY.ordinal(), equalTo(0));
-        assertThat(ValuesSourceType.NUMERIC.ordinal(), equalTo(1));
-        assertThat(ValuesSourceType.BYTES.ordinal(), equalTo(2));
-        assertThat(ValuesSourceType.GEOPOINT.ordinal(), equalTo(3));
-        assertThat(ValuesSourceType.RANGE.ordinal(), equalTo(4));
-    }
-
-    @Override
-    public void testFromString() {
-        assertThat(ValuesSourceType.fromString("any"), equalTo(ValuesSourceType.ANY));
-        assertThat(ValuesSourceType.fromString("numeric"), equalTo(ValuesSourceType.NUMERIC));
-        assertThat(ValuesSourceType.fromString("bytes"), equalTo(ValuesSourceType.BYTES));
-        assertThat(ValuesSourceType.fromString("geopoint"), equalTo(ValuesSourceType.GEOPOINT));
-        assertThat(ValuesSourceType.fromString("range"), equalTo(ValuesSourceType.RANGE));
-        IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> ValuesSourceType.fromString("does_not_exist"));
-        assertThat(e.getMessage(),
-            equalTo("No enum constant org.elasticsearch.search.aggregations.support.ValuesSourceType.DOES_NOT_EXIST"));
-        expectThrows(NullPointerException.class, () -> ValuesSourceType.fromString(null));
-    }
-
-    @Override
-    public void testReadFrom() throws IOException {
-        assertReadFromStream(0, ValuesSourceType.ANY);
-        assertReadFromStream(1, ValuesSourceType.NUMERIC);
-        assertReadFromStream(2, ValuesSourceType.BYTES);
-        assertReadFromStream(3, ValuesSourceType.GEOPOINT);
-        assertReadFromStream(4, ValuesSourceType.RANGE);
-    }
-
-    @Override
-    public void testWriteTo() throws IOException {
-        assertWriteToStream(ValuesSourceType.ANY, 0);
-        assertWriteToStream(ValuesSourceType.NUMERIC, 1);
-        assertWriteToStream(ValuesSourceType.BYTES, 2);
-        assertWriteToStream(ValuesSourceType.GEOPOINT, 3);
-        assertWriteToStream(ValuesSourceType.RANGE, 4);
-    }
-}

+ 3 - 3
x-pack/plugin/analytics/src/main/java/org/elasticsearch/xpack/analytics/stringstats/StringStatsAggregationBuilder.java

@@ -15,12 +15,12 @@ import org.elasticsearch.index.query.QueryShardContext;
 import org.elasticsearch.search.aggregations.AggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 import org.elasticsearch.search.aggregations.support.ValueType;
 import org.elasticsearch.search.aggregations.support.ValuesSource;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder;
 import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
 import org.elasticsearch.search.aggregations.support.ValuesSourceParserHelper;
-import org.elasticsearch.search.aggregations.support.ValuesSourceType;
 
 import java.io.IOException;
 import java.util.Map;
@@ -46,7 +46,7 @@ public class StringStatsAggregationBuilder extends ValuesSourceAggregationBuilde
     }
 
     public StringStatsAggregationBuilder(String name) {
-        super(name, ValuesSourceType.BYTES, ValueType.STRING);
+        super(name, CoreValuesSourceType.BYTES, ValueType.STRING);
     }
 
     public StringStatsAggregationBuilder(StringStatsAggregationBuilder clone,
@@ -58,7 +58,7 @@ public class StringStatsAggregationBuilder extends ValuesSourceAggregationBuilde
 
     /** Read from a stream. */
     public StringStatsAggregationBuilder(StreamInput in) throws IOException {
-        super(in, ValuesSourceType.BYTES, ValueType.STRING);
+        super(in, CoreValuesSourceType.BYTES, ValueType.STRING);
         this.showDistribution = in.readBoolean();
     }
 

+ 3 - 3
x-pack/plugin/analytics/src/test/java/org/elasticsearch/xpack/analytics/cumulativecardinality/CumulativeCardinalityAggregatorTests.java

@@ -40,10 +40,10 @@ import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
 import org.elasticsearch.search.aggregations.bucket.histogram.HistogramAggregatorFactory;
 import org.elasticsearch.search.aggregations.metrics.CardinalityAggregationBuilder;
 import org.elasticsearch.search.aggregations.metrics.SumAggregationBuilder;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 import org.elasticsearch.search.aggregations.support.ValueType;
 import org.elasticsearch.search.aggregations.support.ValuesSource;
 import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
-import org.elasticsearch.search.aggregations.support.ValuesSourceType;
 import org.elasticsearch.xpack.analytics.StubAggregatorFactory;
 
 import java.io.IOException;
@@ -116,7 +116,7 @@ public class CumulativeCardinalityAggregatorTests extends AggregatorTestCase {
     }
 
     public void testParentValidations() throws IOException {
-        ValuesSourceConfig<ValuesSource> valuesSource = new ValuesSourceConfig<>(ValuesSourceType.NUMERIC);
+        ValuesSourceConfig<ValuesSource> valuesSource = new ValuesSourceConfig<>(CoreValuesSourceType.NUMERIC);
 
         // Histogram
         Set<PipelineAggregationBuilder> aggBuilders = new HashSet<>();
@@ -139,7 +139,7 @@ public class CumulativeCardinalityAggregatorTests extends AggregatorTestCase {
         builder.validate(parent, Collections.emptySet(), aggBuilders);
 
         // Auto Date Histogram
-        ValuesSourceConfig<ValuesSource.Numeric> numericVS = new ValuesSourceConfig<>(ValuesSourceType.NUMERIC);
+        ValuesSourceConfig<ValuesSource.Numeric> numericVS = new ValuesSourceConfig<>(CoreValuesSourceType.NUMERIC);
         aggBuilders.clear();
         aggBuilders.add(new CumulativeCardinalityPipelineAggregationBuilder("cumulative_card", "sum"));
         AutoDateHistogramAggregationBuilder.RoundingInfo[] roundings = new AutoDateHistogramAggregationBuilder.RoundingInfo[1];

+ 2 - 2
x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/transform/transforms/MockDeprecatedAggregationBuilder.java

@@ -16,12 +16,12 @@ import org.elasticsearch.index.query.QueryShardContext;
 import org.elasticsearch.search.aggregations.AggregationBuilder;
 import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
 import org.elasticsearch.search.aggregations.AggregatorFactory;
+import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 import org.elasticsearch.search.aggregations.support.ValueType;
 import org.elasticsearch.search.aggregations.support.ValuesSource;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder;
 import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory;
 import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
-import org.elasticsearch.search.aggregations.support.ValuesSourceType;
 
 import java.io.IOException;
 import java.util.Map;
@@ -45,7 +45,7 @@ public class MockDeprecatedAggregationBuilder extends ValuesSourceAggregationBui
     }
 
     public MockDeprecatedAggregationBuilder() {
-        super(NAME, ValuesSourceType.NUMERIC, ValueType.NUMERIC);
+        super(NAME, CoreValuesSourceType.NUMERIC, ValueType.NUMERIC);
     }
 
     /**