This commit has broken StreamExpressionTest.testArraySort

On Sun, Jun 18, 2017 at 9:24 PM,  <[email protected]> wrote:
> SOLR-10882: ArrayEvaluator now works with all types and allows sorts (deleted 
> ArraySortEvaluator)
>
>
> Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
> Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/113459a8
> Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/113459a8
> Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/113459a8
>
> Branch: refs/heads/master
> Commit: 113459a840e8ca3482ebd36a76dda551fac885ec
> Parents: 5fca6a4
> Author: Dennis Gove <[email protected]>
> Authored: Thu Jun 15 22:10:37 2017 -0400
> Committer: Dennis Gove <[email protected]>
> Committed: Sun Jun 18 11:50:58 2017 -0400
>
> ----------------------------------------------------------------------
>  .../org/apache/solr/handler/StreamHandler.java  | 479 +++++++++----------
>  .../client/solrj/io/eval/ArrayEvaluator.java    |  48 +-
>  .../solrj/io/eval/ArraySortEvaluator.java       |  77 ---
>  .../client/solrj/io/eval/ComplexEvaluator.java  |  18 +-
>  .../io/stream/eval/ArrayEvaluatorTest.java      | 155 ++++++
>  5 files changed, 452 insertions(+), 325 deletions(-)
> ----------------------------------------------------------------------
>
>
> http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/113459a8/solr/core/src/java/org/apache/solr/handler/StreamHandler.java
> ----------------------------------------------------------------------
> diff --git a/solr/core/src/java/org/apache/solr/handler/StreamHandler.java 
> b/solr/core/src/java/org/apache/solr/handler/StreamHandler.java
> index 7889bf7..4616204 100644
> --- a/solr/core/src/java/org/apache/solr/handler/StreamHandler.java
> +++ b/solr/core/src/java/org/apache/solr/handler/StreamHandler.java
> @@ -77,7 +77,7 @@ public class StreamHandler extends RequestHandlerBase 
> implements SolrCoreAware,
>    private StreamFactory streamFactory = new StreamFactory();
>    private static final Logger logger = 
> LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
>    private String coreName;
> -  private Map<String, DaemonStream> daemons = 
> Collections.synchronizedMap(new HashMap());
> +  private Map<String,DaemonStream> daemons = Collections.synchronizedMap(new 
> HashMap());
>
>    @Override
>    public PermissionNameProvider.Name getPermissionName(AuthorizationContext 
> request) {
> @@ -89,202 +89,202 @@ public class StreamHandler extends RequestHandlerBase 
> implements SolrCoreAware,
>    }
>
>    public void inform(SolrCore core) {
> -
> -    /* The stream factory will always contain the zkUrl for the given 
> collection
> -     * Adds default streams with their corresponding function names. These
> -     * defaults can be overridden or added to in the solrConfig in the stream
> -     * RequestHandler def. Example config override
> -     *  <lst name="streamFunctions">
> -     *    <str 
> name="group">org.apache.solr.client.solrj.io.stream.ReducerStream</str>
> -     *    <str 
> name="count">org.apache.solr.client.solrj.io.stream.RecordCountStream</str>
> -     *  </lst>
> -     * */
> +
> +    /*
> +     * The stream factory will always contain the zkUrl for the given 
> collection Adds default streams with their
> +     * corresponding function names. These defaults can be overridden or 
> added to in the solrConfig in the stream
> +     * RequestHandler def. Example config override
> +     * <lst name="streamFunctions">
> +     *  <str 
> name="group">org.apache.solr.client.solrj.io.stream.ReducerStream</str>
> +     *  <str 
> name="count">org.apache.solr.client.solrj.io.stream.RecordCountStream</str>
> +     * </lst>
> +     */
>
>      String defaultCollection;
>      String defaultZkhost;
>      CoreContainer coreContainer = core.getCoreContainer();
>      this.coreName = core.getName();
>
> -    if(coreContainer.isZooKeeperAware()) {
> +    if (coreContainer.isZooKeeperAware()) {
>        defaultCollection = core.getCoreDescriptor().getCollectionName();
>        defaultZkhost = 
> core.getCoreContainer().getZkController().getZkServerAddress();
>        streamFactory.withCollectionZkHost(defaultCollection, defaultZkhost);
>        streamFactory.withDefaultZkHost(defaultZkhost);
>        modelCache = new ModelCache(250,
> -                                  defaultZkhost,
> -                                  clientCache);
> -    }
> -
> -     streamFactory
> -       // source streams
> -      .withFunctionName("search", CloudSolrStream.class)
> -      .withFunctionName("facet", FacetStream.class)
> -      .withFunctionName("update", UpdateStream.class)
> -      .withFunctionName("jdbc", JDBCStream.class)
> -      .withFunctionName("topic", TopicStream.class)
> -      .withFunctionName("commit", CommitStream.class)
> -      .withFunctionName("random", RandomStream.class)
> -      .withFunctionName("knn", KnnStream.class)
> -
> -      // decorator streams
> -      .withFunctionName("merge", MergeStream.class)
> -      .withFunctionName("unique", UniqueStream.class)
> -      .withFunctionName("top", RankStream.class)
> -      .withFunctionName("group", GroupOperation.class)
> -      .withFunctionName("reduce", ReducerStream.class)
> -      .withFunctionName("parallel", ParallelStream.class)
> -      .withFunctionName("rollup", RollupStream.class)
> -      .withFunctionName("stats", StatsStream.class)
> -      .withFunctionName("innerJoin", InnerJoinStream.class)
> -      .withFunctionName("leftOuterJoin", LeftOuterJoinStream.class)
> -      .withFunctionName("hashJoin", HashJoinStream.class)
> -      .withFunctionName("outerHashJoin", OuterHashJoinStream.class)
> -      .withFunctionName("intersect", IntersectStream.class)
> -      .withFunctionName("complement", ComplementStream.class)
> -      .withFunctionName(SORT, SortStream.class)
> -      .withFunctionName("train", TextLogitStream.class)
> -      .withFunctionName("features", FeaturesSelectionStream.class)
> -      .withFunctionName("daemon", DaemonStream.class)
> -      .withFunctionName("shortestPath", ShortestPathStream.class)
> -      .withFunctionName("gatherNodes", GatherNodesStream.class)
> -      .withFunctionName("nodes", GatherNodesStream.class)
> -      .withFunctionName("select", SelectStream.class)
> -      .withFunctionName("shortestPath", ShortestPathStream.class)
> -      .withFunctionName("gatherNodes", GatherNodesStream.class)
> -      .withFunctionName("nodes", GatherNodesStream.class)
> -      .withFunctionName("scoreNodes", ScoreNodesStream.class)
> -      .withFunctionName("model", ModelStream.class)
> -      .withFunctionName("classify", ClassifyStream.class)
> -      .withFunctionName("fetch", FetchStream.class)
> -      .withFunctionName("executor", ExecutorStream.class)
> -      .withFunctionName("null", NullStream.class)
> -      .withFunctionName("priority", PriorityStream.class)
> -         .withFunctionName("significantTerms", SignificantTermsStream.class)
> -      .withFunctionName("cartesianProduct", CartesianProductStream.class)
> -         .withFunctionName("shuffle", ShuffleStream.class)
> -         .withFunctionName("calc", CalculatorStream.class)
> -      .withFunctionName("eval",EvalStream.class)
> -      .withFunctionName("echo", EchoStream.class)
> -      .withFunctionName("cell", CellStream.class)
> -      .withFunctionName("list", ListStream.class)
> -      .withFunctionName("let", LetStream.class)
> -      .withFunctionName("get", GetStream.class)
> -      .withFunctionName("timeseries", TimeSeriesStream.class)
> -      .withFunctionName("tuple", TupStream.class)
> -      .withFunctionName("sql", SqlStream.class)
> -      .withFunctionName("col", ColumnEvaluator.class)
> -      .withFunctionName("predict", PredictEvaluator.class)
> -      .withFunctionName("regress", RegressionEvaluator.class)
> -      .withFunctionName("cov", CovarianceEvaluator.class)
> -      .withFunctionName("conv", ConvolutionEvaluator.class)
> -      .withFunctionName("normalize", NormalizeEvaluator.class)
> -      .withFunctionName("rev", ReverseEvaluator.class)
> -      .withFunctionName("length", LengthEvaluator.class)
> -      .withFunctionName("rank", RankEvaluator.class)
> -      .withFunctionName("scale", ScaleEvaluator.class)
> -      .withFunctionName("distance", DistanceEvaluator.class)
> -      .withFunctionName("copyOf", CopyOfEvaluator.class)
> -      .withFunctionName("copyOfRange", CopyOfRangeEvaluator.class)
> -      .withFunctionName("percentile", PercentileEvaluator.class)
> -      .withFunctionName("empiricalDistribution", 
> EmpiricalDistributionEvaluator.class)
> -      .withFunctionName("cumulativeProbability", 
> CumulativeProbabilityEvaluator.class)
> -      .withFunctionName("describe", DescribeEvaluator.class)
> -      .withFunctionName("finddelay", FindDelayEvaluator.class)
> -      .withFunctionName("sequence", SequenceEvaluator.class)
> -      .withFunctionName("array", ArrayEvaluator.class)
> -      .withFunctionName("hist", HistogramEvaluator.class)
> -      .withFunctionName("anova", AnovaEvaluator.class)
> -      .withFunctionName("movingAvg", MovingAverageEvaluator.class)
> -      .withFunctionName("arraySort", ArraySortEvaluator.class)
> -
> -      // metrics
> -         .withFunctionName("min", MinMetric.class)
> -      .withFunctionName("max", MaxMetric.class)
> -      .withFunctionName("avg", MeanMetric.class)
> -      .withFunctionName("sum", SumMetric.class)
> -      .withFunctionName("count", CountMetric.class)
> -
> -      // tuple manipulation operations
> -         .withFunctionName("replace", ReplaceOperation.class)
> -      .withFunctionName("concat", ConcatOperation.class)
> -
> -      // stream reduction operations
> -         .withFunctionName("group", GroupOperation.class)
> -      .withFunctionName("distinct", DistinctOperation.class)
> -      .withFunctionName("having", HavingStream.class)
> -
> -      // Stream Evaluators
> -         .withFunctionName("val", RawValueEvaluator.class)
> -
> -      // Boolean Stream Evaluators
> -         .withFunctionName("and", AndEvaluator.class)
> -      .withFunctionName("eor", ExclusiveOrEvaluator.class)
> -      .withFunctionName("eq", EqualsEvaluator.class)
> -      .withFunctionName("gt", GreaterThanEvaluator.class)
> -      .withFunctionName("gteq", GreaterThanEqualToEvaluator.class)
> -      .withFunctionName("lt", LessThanEvaluator.class)
> -      .withFunctionName("lteq", LessThanEqualToEvaluator.class)
> -      .withFunctionName("not", NotEvaluator.class)
> -         .withFunctionName("or", OrEvaluator.class)
> -
> -      // Date Time Evaluators
> -         .withFunctionName(TemporalEvaluatorYear.FUNCTION_NAME, 
> TemporalEvaluatorYear.class)
> -      .withFunctionName(TemporalEvaluatorMonth.FUNCTION_NAME, 
> TemporalEvaluatorMonth.class)
> -      .withFunctionName(TemporalEvaluatorDay.FUNCTION_NAME, 
> TemporalEvaluatorDay.class)
> -      .withFunctionName(TemporalEvaluatorDayOfYear.FUNCTION_NAME, 
> TemporalEvaluatorDayOfYear.class)
> -         .withFunctionName(TemporalEvaluatorHour.FUNCTION_NAME, 
> TemporalEvaluatorHour.class)
> -      .withFunctionName(TemporalEvaluatorMinute.FUNCTION_NAME, 
> TemporalEvaluatorMinute.class)
> -         .withFunctionName(TemporalEvaluatorSecond.FUNCTION_NAME, 
> TemporalEvaluatorSecond.class)
> -      .withFunctionName(TemporalEvaluatorEpoch.FUNCTION_NAME, 
> TemporalEvaluatorEpoch.class)
> -      .withFunctionName(TemporalEvaluatorWeek.FUNCTION_NAME, 
> TemporalEvaluatorWeek.class)
> -         .withFunctionName(TemporalEvaluatorQuarter.FUNCTION_NAME, 
> TemporalEvaluatorQuarter.class)
> -         .withFunctionName(TemporalEvaluatorDayOfQuarter.FUNCTION_NAME, 
> TemporalEvaluatorDayOfQuarter.class)
> -
> -      // Number Stream Evaluators
> -         .withFunctionName("abs", AbsoluteValueEvaluator.class)
> -      .withFunctionName("add", AddEvaluator.class)
> -      .withFunctionName("div", DivideEvaluator.class)
> -      .withFunctionName("mult", MultiplyEvaluator.class)
> -      .withFunctionName("sub", SubtractEvaluator.class)
> -      .withFunctionName("log", NaturalLogEvaluator.class)
> -      .withFunctionName("pow", PowerEvaluator.class)
> -      .withFunctionName("mod", ModuloEvaluator.class)
> -         .withFunctionName("ceil", CeilingEvaluator.class)
> -      .withFunctionName("floor", FloorEvaluator.class)
> -      .withFunctionName("sin", SineEvaluator.class)
> -      .withFunctionName("asin", ArcSineEvaluator.class)
> -      .withFunctionName("sinh", HyperbolicSineEvaluator.class)
> -      .withFunctionName("cos", CosineEvaluator.class)
> -      .withFunctionName("acos", ArcCosineEvaluator.class)
> -      .withFunctionName("cosh", HyperbolicCosineEvaluator.class)
> -      .withFunctionName("tan", TangentEvaluator.class)
> -      .withFunctionName("atan", ArcTangentEvaluator.class)
> -      .withFunctionName("tanh", HyperbolicTangentEvaluator.class)
> -         .withFunctionName("round", RoundEvaluator.class)
> -      .withFunctionName("sqrt", SquareRootEvaluator.class)
> -      .withFunctionName("cbrt", CubedRootEvaluator.class)
> -      .withFunctionName("coalesce", CoalesceEvaluator.class)
> -      .withFunctionName("uuid", UuidEvaluator.class)
> -      .withFunctionName("corr", CorrelationEvaluator.class)
> -
> -
> -      // Conditional Stream Evaluators
> -         .withFunctionName("if", IfThenElseEvaluator.class)
> -         .withFunctionName("analyze", AnalyzeEvaluator.class)
> -         .withFunctionName("convert", ConversionEvaluator.class)
> -      ;
> -
> -     // This pulls all the overrides and additions from the config
> -     List<PluginInfo> pluginInfos = 
> core.getSolrConfig().getPluginInfos(Expressible.class.getName());
> -     for (PluginInfo pluginInfo : pluginInfos) {
> -       Class<? extends Expressible> clazz = 
> core.getMemClassLoader().findClass(pluginInfo.className, Expressible.class);
> -       streamFactory.withFunctionName(pluginInfo.name, clazz);
> -     }
> +          defaultZkhost,
> +          clientCache);
> +    }
> +
> +    streamFactory
> +        // source streams
> +        .withFunctionName("search", CloudSolrStream.class)
> +        .withFunctionName("facet", FacetStream.class)
> +        .withFunctionName("update", UpdateStream.class)
> +        .withFunctionName("jdbc", JDBCStream.class)
> +        .withFunctionName("topic", TopicStream.class)
> +        .withFunctionName("commit", CommitStream.class)
> +        .withFunctionName("random", RandomStream.class)
> +        .withFunctionName("knn", KnnStream.class)
> +
> +        // decorator streams
> +        .withFunctionName("merge", MergeStream.class)
> +        .withFunctionName("unique", UniqueStream.class)
> +        .withFunctionName("top", RankStream.class)
> +        .withFunctionName("group", GroupOperation.class)
> +        .withFunctionName("reduce", ReducerStream.class)
> +        .withFunctionName("parallel", ParallelStream.class)
> +        .withFunctionName("rollup", RollupStream.class)
> +        .withFunctionName("stats", StatsStream.class)
> +        .withFunctionName("innerJoin", InnerJoinStream.class)
> +        .withFunctionName("leftOuterJoin", LeftOuterJoinStream.class)
> +        .withFunctionName("hashJoin", HashJoinStream.class)
> +        .withFunctionName("outerHashJoin", OuterHashJoinStream.class)
> +        .withFunctionName("intersect", IntersectStream.class)
> +        .withFunctionName("complement", ComplementStream.class)
> +        .withFunctionName(SORT, SortStream.class)
> +        .withFunctionName("train", TextLogitStream.class)
> +        .withFunctionName("features", FeaturesSelectionStream.class)
> +        .withFunctionName("daemon", DaemonStream.class)
> +        .withFunctionName("shortestPath", ShortestPathStream.class)
> +        .withFunctionName("gatherNodes", GatherNodesStream.class)
> +        .withFunctionName("nodes", GatherNodesStream.class)
> +        .withFunctionName("select", SelectStream.class)
> +        .withFunctionName("shortestPath", ShortestPathStream.class)
> +        .withFunctionName("gatherNodes", GatherNodesStream.class)
> +        .withFunctionName("nodes", GatherNodesStream.class)
> +        .withFunctionName("scoreNodes", ScoreNodesStream.class)
> +        .withFunctionName("model", ModelStream.class)
> +        .withFunctionName("classify", ClassifyStream.class)
> +        .withFunctionName("fetch", FetchStream.class)
> +        .withFunctionName("executor", ExecutorStream.class)
> +        .withFunctionName("null", NullStream.class)
> +        .withFunctionName("priority", PriorityStream.class)
> +        .withFunctionName("significantTerms", SignificantTermsStream.class)
> +        .withFunctionName("cartesianProduct", CartesianProductStream.class)
> +        .withFunctionName("shuffle", ShuffleStream.class)
> +        .withFunctionName("calc", CalculatorStream.class)
> +        .withFunctionName("eval", EvalStream.class)
> +        .withFunctionName("echo", EchoStream.class)
> +        .withFunctionName("cell", CellStream.class)
> +        .withFunctionName("list", ListStream.class)
> +        .withFunctionName("let", LetStream.class)
> +        .withFunctionName("get", GetStream.class)
> +        .withFunctionName("timeseries", TimeSeriesStream.class)
> +        .withFunctionName("tuple", TupStream.class)
> +        .withFunctionName("sql", SqlStream.class)
> +
> +        // metrics
> +        .withFunctionName("min", MinMetric.class)
> +        .withFunctionName("max", MaxMetric.class)
> +        .withFunctionName("avg", MeanMetric.class)
> +        .withFunctionName("sum", SumMetric.class)
> +        .withFunctionName("count", CountMetric.class)
> +
> +        // tuple manipulation operations
> +        .withFunctionName("replace", ReplaceOperation.class)
> +        .withFunctionName("concat", ConcatOperation.class)
> +
> +        // stream reduction operations
> +        .withFunctionName("group", GroupOperation.class)
> +        .withFunctionName("distinct", DistinctOperation.class)
> +        .withFunctionName("having", HavingStream.class)
> +
> +        // Stream Evaluators
> +        .withFunctionName("val", RawValueEvaluator.class)
> +
> +        // New Evaluators
> +        .withFunctionName("anova", AnovaEvaluator.class)
> +        .withFunctionName("array", ArrayEvaluator.class)
> +        .withFunctionName("col", ColumnEvaluator.class)
> +        .withFunctionName("conv", ConvolutionEvaluator.class)
> +        .withFunctionName("copyOf", CopyOfEvaluator.class)
> +        .withFunctionName("copyOfRange", CopyOfRangeEvaluator.class)
> +        .withFunctionName("cov", CovarianceEvaluator.class)
> +        .withFunctionName("cumulativeProbability", 
> CumulativeProbabilityEvaluator.class)
> +        .withFunctionName("describe", DescribeEvaluator.class)
> +        .withFunctionName("distance", DistanceEvaluator.class)
> +        .withFunctionName("empiricalDistribution", 
> EmpiricalDistributionEvaluator.class)
> +        .withFunctionName("finddelay", FindDelayEvaluator.class)
> +        .withFunctionName("hist", HistogramEvaluator.class)
> +        .withFunctionName("length", LengthEvaluator.class)
> +        .withFunctionName("movingAvg", MovingAverageEvaluator.class)
> +        .withFunctionName("normalize", NormalizeEvaluator.class)
> +        .withFunctionName("percentile", PercentileEvaluator.class)
> +        .withFunctionName("predict", PredictEvaluator.class)
> +        .withFunctionName("rank", RankEvaluator.class)
> +        .withFunctionName("regress", RegressionEvaluator.class)
> +        .withFunctionName("rev", ReverseEvaluator.class)
> +        .withFunctionName("scale", ScaleEvaluator.class)
> +        .withFunctionName("sequence", SequenceEvaluator.class)
> +
>
> +        // Boolean Stream Evaluators
> +        .withFunctionName("and", AndEvaluator.class)
> +        .withFunctionName("eor", ExclusiveOrEvaluator.class)
> +        .withFunctionName("eq", EqualsEvaluator.class)
> +        .withFunctionName("gt", GreaterThanEvaluator.class)
> +        .withFunctionName("gteq", GreaterThanEqualToEvaluator.class)
> +        .withFunctionName("lt", LessThanEvaluator.class)
> +        .withFunctionName("lteq", LessThanEqualToEvaluator.class)
> +        .withFunctionName("not", NotEvaluator.class)
> +        .withFunctionName("or", OrEvaluator.class)
> +
> +        // Date Time Evaluators
> +        .withFunctionName(TemporalEvaluatorYear.FUNCTION_NAME, 
> TemporalEvaluatorYear.class)
> +        .withFunctionName(TemporalEvaluatorMonth.FUNCTION_NAME, 
> TemporalEvaluatorMonth.class)
> +        .withFunctionName(TemporalEvaluatorDay.FUNCTION_NAME, 
> TemporalEvaluatorDay.class)
> +        .withFunctionName(TemporalEvaluatorDayOfYear.FUNCTION_NAME, 
> TemporalEvaluatorDayOfYear.class)
> +        .withFunctionName(TemporalEvaluatorHour.FUNCTION_NAME, 
> TemporalEvaluatorHour.class)
> +        .withFunctionName(TemporalEvaluatorMinute.FUNCTION_NAME, 
> TemporalEvaluatorMinute.class)
> +        .withFunctionName(TemporalEvaluatorSecond.FUNCTION_NAME, 
> TemporalEvaluatorSecond.class)
> +        .withFunctionName(TemporalEvaluatorEpoch.FUNCTION_NAME, 
> TemporalEvaluatorEpoch.class)
> +        .withFunctionName(TemporalEvaluatorWeek.FUNCTION_NAME, 
> TemporalEvaluatorWeek.class)
> +        .withFunctionName(TemporalEvaluatorQuarter.FUNCTION_NAME, 
> TemporalEvaluatorQuarter.class)
> +        .withFunctionName(TemporalEvaluatorDayOfQuarter.FUNCTION_NAME, 
> TemporalEvaluatorDayOfQuarter.class)
> +
> +        // Number Stream Evaluators
> +        .withFunctionName("abs", AbsoluteValueEvaluator.class)
> +        .withFunctionName("add", AddEvaluator.class)
> +        .withFunctionName("div", DivideEvaluator.class)
> +        .withFunctionName("mult", MultiplyEvaluator.class)
> +        .withFunctionName("sub", SubtractEvaluator.class)
> +        .withFunctionName("log", NaturalLogEvaluator.class)
> +        .withFunctionName("pow", PowerEvaluator.class)
> +        .withFunctionName("mod", ModuloEvaluator.class)
> +        .withFunctionName("ceil", CeilingEvaluator.class)
> +        .withFunctionName("floor", FloorEvaluator.class)
> +        .withFunctionName("sin", SineEvaluator.class)
> +        .withFunctionName("asin", ArcSineEvaluator.class)
> +        .withFunctionName("sinh", HyperbolicSineEvaluator.class)
> +        .withFunctionName("cos", CosineEvaluator.class)
> +        .withFunctionName("acos", ArcCosineEvaluator.class)
> +        .withFunctionName("cosh", HyperbolicCosineEvaluator.class)
> +        .withFunctionName("tan", TangentEvaluator.class)
> +        .withFunctionName("atan", ArcTangentEvaluator.class)
> +        .withFunctionName("tanh", HyperbolicTangentEvaluator.class)
> +        .withFunctionName("round", RoundEvaluator.class)
> +        .withFunctionName("sqrt", SquareRootEvaluator.class)
> +        .withFunctionName("cbrt", CubedRootEvaluator.class)
> +        .withFunctionName("coalesce", CoalesceEvaluator.class)
> +        .withFunctionName("uuid", UuidEvaluator.class)
> +        .withFunctionName("corr", CorrelationEvaluator.class)
> +
> +        // Conditional Stream Evaluators
> +        .withFunctionName("if", IfThenElseEvaluator.class)
> +        .withFunctionName("analyze", AnalyzeEvaluator.class)
> +        .withFunctionName("convert", ConversionEvaluator.class);
> +
> +    // This pulls all the overrides and additions from the config
> +    List<PluginInfo> pluginInfos = 
> core.getSolrConfig().getPluginInfos(Expressible.class.getName());
> +    for (PluginInfo pluginInfo : pluginInfos) {
> +      Class<? extends Expressible> clazz = 
> core.getMemClassLoader().findClass(pluginInfo.className, Expressible.class);
> +      streamFactory.withFunctionName(pluginInfo.name, clazz);
> +    }
> +
>      core.addCloseHook(new CloseHook() {
>        @Override
>        public void preClose(SolrCore core) {
> -        //To change body of implemented methods use File | Settings | File 
> Templates.
> +        // To change body of implemented methods use File | Settings | File 
> Templates.
>        }
>
>        @Override
> @@ -299,7 +299,7 @@ public class StreamHandler extends RequestHandlerBase 
> implements SolrCoreAware,
>      params = adjustParams(params);
>      req.setParams(params);
>
> -    if(params.get("action") != null) {
> +    if (params.get("action") != null) {
>        handleAdmin(req, rsp, params);
>        return;
>      }
> @@ -308,7 +308,7 @@ public class StreamHandler extends RequestHandlerBase 
> implements SolrCoreAware,
>
>      try {
>        StreamExpression streamExpression = 
> StreamExpressionParser.parse(params.get("expr"));
> -      if(this.streamFactory.isEvaluator(streamExpression)) {
> +      if (this.streamFactory.isEvaluator(streamExpression)) {
>          StreamExpression tupleExpression = new StreamExpression("tuple");
>          tupleExpression.addParameter(new 
> StreamExpressionNamedParameter("return-value", streamExpression));
>          tupleStream = this.streamFactory.constructStream(tupleExpression);
> @@ -316,7 +316,8 @@ public class StreamHandler extends RequestHandlerBase 
> implements SolrCoreAware,
>          tupleStream = this.streamFactory.constructStream(streamExpression);
>        }
>      } catch (Exception e) {
> -      //Catch exceptions that occur while the stream is being created. This 
> will include streaming expression parse rules.
> +      // Catch exceptions that occur while the stream is being created. This 
> will include streaming expression parse
> +      // rules.
>        SolrException.log(logger, e);
>        rsp.add("result-set", new DummyErrorStream(e));
>
> @@ -334,21 +335,21 @@ public class StreamHandler extends RequestHandlerBase 
> implements SolrCoreAware,
>      context.put("core", this.coreName);
>      context.put("solr-core", req.getCore());
>      tupleStream.setStreamContext(context);
> -
> +
>      // if asking for explanation then go get it
> -    if(params.getBool("explain", false)){
> +    if (params.getBool("explain", false)) {
>        rsp.add("explanation", tupleStream.toExplanation(this.streamFactory));
>      }
> -
> -    if(tupleStream instanceof DaemonStream) {
> -      DaemonStream daemonStream = (DaemonStream)tupleStream;
> -      if(daemons.containsKey(daemonStream.getId())) {
> +
> +    if (tupleStream instanceof DaemonStream) {
> +      DaemonStream daemonStream = (DaemonStream) tupleStream;
> +      if (daemons.containsKey(daemonStream.getId())) {
>          daemons.remove(daemonStream.getId()).close();
>        }
>        daemonStream.setDaemons(daemons);
> -      daemonStream.open();  //This will start the deamonStream
> +      daemonStream.open(); // This will start the deamonStream
>        daemons.put(daemonStream.getId(), daemonStream);
> -      rsp.add("result-set", new 
> DaemonResponseStream("Deamon:"+daemonStream.getId()+" started on "+coreName));
> +      rsp.add("result-set", new DaemonResponseStream("Deamon:" + 
> daemonStream.getId() + " started on " + coreName));
>      } else {
>        rsp.add("result-set", new TimerStream(new 
> ExceptionStream(tupleStream)));
>      }
> @@ -356,10 +357,10 @@ public class StreamHandler extends RequestHandlerBase 
> implements SolrCoreAware,
>
>    private void handleAdmin(SolrQueryRequest req, SolrQueryResponse rsp, 
> SolrParams params) {
>      String action = params.get("action");
> -    if("stop".equalsIgnoreCase(action)) {
> +    if ("stop".equalsIgnoreCase(action)) {
>        String id = params.get(ID);
>        DaemonStream d = daemons.get(id);
> -      if(d != null) {
> +      if (d != null) {
>          d.close();
>          rsp.add("result-set", new DaemonResponseStream("Deamon:" + id + " 
> stopped on " + coreName));
>        } else {
> @@ -400,50 +401,46 @@ public class StreamHandler extends RequestHandlerBase 
> implements SolrCoreAware,
>      return null;
>    }
>
> -
>    public static class DummyErrorStream extends TupleStream {
>      private Exception e;
>
>      public DummyErrorStream(Exception e) {
>        this.e = e;
>      }
> +
>      public StreamComparator getStreamSort() {
>        return null;
>      }
>
> -    public void close() {
> -    }
> +    public void close() {}
>
> -    public void open() {
> -    }
> +    public void open() {}
>
> -    public void setStreamContext(StreamContext context) {
> -    }
> +    public void setStreamContext(StreamContext context) {}
>
>      public List<TupleStream> children() {
>        return null;
>      }
> -
> +
>      @Override
>      public Explanation toExplanation(StreamFactory factory) throws 
> IOException {
>
>        return new StreamExplanation(getStreamNodeId().toString())
> -        .withFunctionName("error")
> -        .withImplementingClass(this.getClass().getName())
> -        .withExpressionType(ExpressionType.STREAM_DECORATOR)
> -        .withExpression("--non-expressible--");
> +          .withFunctionName("error")
> +          .withImplementingClass(this.getClass().getName())
> +          .withExpressionType(ExpressionType.STREAM_DECORATOR)
> +          .withExpression("--non-expressible--");
>      }
>
>      public Tuple read() {
>        String msg = e.getMessage();
>
>        Throwable t = e.getCause();
> -      while(t != null) {
> +      while (t != null) {
>          msg = t.getMessage();
>          t = t.getCause();
>        }
>
> -
>        Map m = new HashMap();
>        m.put("EOF", true);
>        m.put("EXCEPTION", msg);
> @@ -457,18 +454,16 @@ public class StreamHandler extends RequestHandlerBase 
> implements SolrCoreAware,
>      public DaemonCollectionStream(Collection<DaemonStream> col) {
>        this.it = col.iterator();
>      }
> +
>      public StreamComparator getStreamSort() {
>        return null;
>      }
>
> -    public void close() {
> -    }
> +    public void close() {}
>
> -    public void open() {
> -    }
> +    public void open() {}
>
> -    public void setStreamContext(StreamContext context) {
> -    }
> +    public void setStreamContext(StreamContext context) {}
>
>      public List<TupleStream> children() {
>        return null;
> @@ -478,14 +473,14 @@ public class StreamHandler extends RequestHandlerBase 
> implements SolrCoreAware,
>      public Explanation toExplanation(StreamFactory factory) throws 
> IOException {
>
>        return new StreamExplanation(getStreamNodeId().toString())
> -        .withFunctionName("daemon-collection")
> -        .withImplementingClass(this.getClass().getName())
> -        .withExpressionType(ExpressionType.STREAM_DECORATOR)
> -        .withExpression("--non-expressible--");
> +          .withFunctionName("daemon-collection")
> +          .withImplementingClass(this.getClass().getName())
> +          .withExpressionType(ExpressionType.STREAM_DECORATOR)
> +          .withExpression("--non-expressible--");
>      }
> -
> +
>      public Tuple read() {
> -      if(it.hasNext()) {
> +      if (it.hasNext()) {
>          return it.next().getInfo();
>        } else {
>          Map m = new HashMap();
> @@ -502,18 +497,16 @@ public class StreamHandler extends RequestHandlerBase 
> implements SolrCoreAware,
>      public DaemonResponseStream(String message) {
>        this.message = message;
>      }
> +
>      public StreamComparator getStreamSort() {
>        return null;
>      }
>
> -    public void close() {
> -    }
> +    public void close() {}
>
> -    public void open() {
> -    }
> +    public void open() {}
>
> -    public void setStreamContext(StreamContext context) {
> -    }
> +    public void setStreamContext(StreamContext context) {}
>
>      public List<TupleStream> children() {
>        return null;
> @@ -523,10 +516,10 @@ public class StreamHandler extends RequestHandlerBase 
> implements SolrCoreAware,
>      public Explanation toExplanation(StreamFactory factory) throws 
> IOException {
>
>        return new StreamExplanation(getStreamNodeId().toString())
> -        .withFunctionName("daemon-response")
> -        .withImplementingClass(this.getClass().getName())
> -        .withExpressionType(ExpressionType.STREAM_DECORATOR)
> -        .withExpression("--non-expressible--");
> +          .withFunctionName("daemon-response")
> +          .withImplementingClass(this.getClass().getName())
> +          .withExpressionType(ExpressionType.STREAM_DECORATOR)
> +          .withExpression("--non-expressible--");
>      }
>
>      public Tuple read() {
> @@ -537,7 +530,7 @@ public class StreamHandler extends RequestHandlerBase 
> implements SolrCoreAware,
>        } else {
>          sendEOF = true;
>          Map m = new HashMap();
> -        m.put("DaemonOp",message);
> +        m.put("DaemonOp", message);
>          return new Tuple(m);
>        }
>      }
> @@ -577,15 +570,15 @@ public class StreamHandler extends RequestHandlerBase 
> implements SolrCoreAware,
>      public Explanation toExplanation(StreamFactory factory) throws 
> IOException {
>
>        return new StreamExplanation(getStreamNodeId().toString())
> -        .withFunctionName("timer")
> -        .withImplementingClass(this.getClass().getName())
> -        .withExpressionType(ExpressionType.STREAM_DECORATOR)
> -        .withExpression("--non-expressible--");
> +          .withFunctionName("timer")
> +          .withImplementingClass(this.getClass().getName())
> +          .withExpressionType(ExpressionType.STREAM_DECORATOR)
> +          .withExpression("--non-expressible--");
>      }
>
>      public Tuple read() throws IOException {
>        Tuple tuple = this.tupleStream.read();
> -      if(tuple.EOF) {
> +      if (tuple.EOF) {
>          long totalTime = (System.nanoTime() - begin) / 1000000;
>          tuple.fields.put("RESPONSE_TIME", totalTime);
>        }
> @@ -593,25 +586,25 @@ public class StreamHandler extends RequestHandlerBase 
> implements SolrCoreAware,
>      }
>    }
>
> -  private Map<String, List<String>> getCollectionShards(SolrParams params) {
> +  private Map<String,List<String>> getCollectionShards(SolrParams params) {
>
> -    Map<String, List<String>> collectionShards = new HashMap();
> +    Map<String,List<String>> collectionShards = new HashMap();
>      Iterator<String> paramsIt = params.getParameterNamesIterator();
> -    while(paramsIt.hasNext()) {
> +    while (paramsIt.hasNext()) {
>        String param = paramsIt.next();
> -      if(param.indexOf(".shards") > -1) {
> +      if (param.indexOf(".shards") > -1) {
>          String collection = param.split("\\.")[0];
>          String shardString = params.get(param);
>          String[] shards = shardString.split(",");
>          List<String> shardList = new ArrayList();
> -        for(String shard : shards) {
> +        for (String shard : shards) {
>            shardList.add(shard);
>          }
>          collectionShards.put(collection, shardList);
>        }
>      }
>
> -    if(collectionShards.size() > 0) {
> +    if (collectionShards.size() > 0) {
>        return collectionShards;
>      } else {
>        return null;
>
> http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/113459a8/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArrayEvaluator.java
> ----------------------------------------------------------------------
> diff --git 
> a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArrayEvaluator.java
>  
> b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArrayEvaluator.java
> index ed45ee9..065335b 100644
> --- 
> a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArrayEvaluator.java
> +++ 
> b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArrayEvaluator.java
> @@ -18,30 +18,72 @@ package org.apache.solr.client.solrj.io.eval;
>
>  import java.io.IOException;
>  import java.util.ArrayList;
> +import java.util.Comparator;
>  import java.util.List;
> +import java.util.Locale;
> +import java.util.stream.Collectors;
>
>  import org.apache.solr.client.solrj.io.Tuple;
>  import org.apache.solr.client.solrj.io.stream.expr.Explanation;
>  import 
> org.apache.solr.client.solrj.io.stream.expr.Explanation.ExpressionType;
>  import org.apache.solr.client.solrj.io.stream.expr.Expressible;
>  import org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
> +import 
> org.apache.solr.client.solrj.io.stream.expr.StreamExpressionNamedParameter;
>  import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionParameter;
> +import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionValue;
>  import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
>
> +import com.google.common.collect.Lists;
> +
>  public class ArrayEvaluator extends ComplexEvaluator implements Expressible {
>
>    private static final long serialVersionUID = 1;
> -
> +  private String sortOrder;
> +
>    public ArrayEvaluator(StreamExpression expression, StreamFactory factory) 
> throws IOException {
> -    super(expression, factory);
> +    super(expression, factory, Lists.newArrayList("sort"));
> +
> +    sortOrder = extractSortOrder(expression, factory);
> +  }
> +
> +  private String extractSortOrder(StreamExpression expression, StreamFactory 
> factory) throws IOException{
> +    StreamExpressionNamedParameter sortParam = 
> factory.getNamedOperand(expression, "sort");
> +    if(null == sortParam){
> +      return null; // this is ok
> +    }
> +
> +    if(sortParam.getParameter() instanceof StreamExpressionValue){
> +      String sortOrder = 
> ((StreamExpressionValue)sortParam.getParameter()).getValue().trim().toLowerCase(Locale.ROOT);
> +      if("asc".equals(sortOrder) || "desc".equals(sortOrder)){
> +        return sortOrder;
> +      }
> +    }
> +
> +    throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - 
> invalid 'sort' parameter - expecting either 'asc' or 'desc'", expression));
>    }
>
>    public List<Object> evaluate(Tuple tuple) throws IOException {
>      List<Object> list = new ArrayList<>();
>      for(StreamEvaluator subEvaluator : subEvaluators) {
> -      Object value = (Number)subEvaluator.evaluate(tuple);
> +      Object value = subEvaluator.evaluate(tuple);
> +
> +      // if we want sorting but the evaluated value is not comparable then 
> we have an error
> +      if(null != sortOrder && !(value instanceof Comparable<?>)){
> +        String message = String.format(Locale.ROOT,"Failed to evaluate to a 
> comparable object - evaluator '%s' resulted in type '%s' and value '%s'",
> +            subEvaluator.toExpression(constructingFactory),
> +            value.getClass().getName(),
> +            value.toString());
> +        throw new IOException(message);
> +      }
> +
>        list.add(value);
>      }
> +
> +    if(null != sortOrder){
> +      // Because of the type checking above we know that the value is at 
> least Comparable
> +      Comparator<Comparable> comparator = "asc".equals(sortOrder) ? 
> (left,right) -> left.compareTo(right) : (left,right) -> right.compareTo(left);
> +      list = list.stream().map(value -> 
> (Comparable<Object>)value).sorted(comparator).collect(Collectors.toList());
> +    }
>
>      return list;
>    }
>
> http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/113459a8/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArraySortEvaluator.java
> ----------------------------------------------------------------------
> diff --git 
> a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArraySortEvaluator.java
>  
> b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArraySortEvaluator.java
> deleted file mode 100644
> index dabc615..0000000
> --- 
> a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArraySortEvaluator.java
> +++ /dev/null
> @@ -1,77 +0,0 @@
> -/*
> - * Licensed to the Apache Software Foundation (ASF) under one or more
> - * contributor license agreements.  See the NOTICE file distributed with
> - * this work for additional information regarding copyright ownership.
> - * The ASF licenses this file to You under the Apache License, Version 2.0
> - * (the "License"); you may not use this file except in compliance with
> - * the License.  You may obtain a copy of the License at
> - *
> - *     http://www.apache.org/licenses/LICENSE-2.0
> - *
> - * Unless required by applicable law or agreed to in writing, software
> - * distributed under the License is distributed on an "AS IS" BASIS,
> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> - * See the License for the specific language governing permissions and
> - * limitations under the License.
> - */
> -package org.apache.solr.client.solrj.io.eval;
> -
> -import java.io.IOException;
> -import java.util.ArrayList;
> -import java.util.Collections;
> -import java.util.Comparator;
> -import java.util.List;
> -
> -import org.apache.solr.client.solrj.io.Tuple;
> -import org.apache.solr.client.solrj.io.stream.expr.Explanation;
> -import 
> org.apache.solr.client.solrj.io.stream.expr.Explanation.ExpressionType;
> -import org.apache.solr.client.solrj.io.stream.expr.Expressible;
> -import org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
> -import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionParameter;
> -import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
> -
> -public class ArraySortEvaluator extends ComplexEvaluator implements 
> Expressible {
> -
> -  private static final long serialVersionUID = 1;
> -
> -  public ArraySortEvaluator(StreamExpression expression, StreamFactory 
> factory) throws IOException {
> -    super(expression, factory);
> -  }
> -
> -  public List<Number> evaluate(Tuple tuple) throws IOException {
> -
> -    if(subEvaluators.size() != 1) {
> -      throw new IOException("Array sort evaluator expects 1 parameters 
> found: "+subEvaluators.size());
> -    }
> -
> -    StreamEvaluator colEval1 = subEvaluators.get(0);
> -
> -    List<Number> numbers1 = (List<Number>)colEval1.evaluate(tuple);
> -    List<Number> numbers2 = new ArrayList();
> -    numbers2.addAll(numbers1);
> -    Collections.sort(numbers2, new Comparator<Number>() {
> -      @Override
> -      public int compare(Number o1, Number o2) {
> -        Double d1 = o1.doubleValue();
> -        Double d2 = o2.doubleValue();
> -        return d1.compareTo(d2);
> -      }
> -    });
> -    return numbers2;
> -  }
> -
> -  @Override
> -  public StreamExpressionParameter toExpression(StreamFactory factory) 
> throws IOException {
> -    StreamExpression expression = new 
> StreamExpression(factory.getFunctionName(getClass()));
> -    return expression;
> -  }
> -
> -  @Override
> -  public Explanation toExplanation(StreamFactory factory) throws IOException 
> {
> -    return new Explanation(nodeId.toString())
> -        .withExpressionType(ExpressionType.EVALUATOR)
> -        .withFunctionName(factory.getFunctionName(getClass()))
> -        .withImplementingClass(getClass().getName())
> -        .withExpression(toExpression(factory).toString());
> -  }
> -}
> \ No newline at end of file
>
> http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/113459a8/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ComplexEvaluator.java
> ----------------------------------------------------------------------
> diff --git 
> a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ComplexEvaluator.java
>  
> b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ComplexEvaluator.java
> index ea4c88c..ca1f0de 100644
> --- 
> a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ComplexEvaluator.java
> +++ 
> b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ComplexEvaluator.java
> @@ -20,7 +20,9 @@ import java.io.IOException;
>  import java.util.ArrayList;
>  import java.util.List;
>  import java.util.Locale;
> +import java.util.Set;
>  import java.util.UUID;
> +import java.util.stream.Collectors;
>
>  import org.apache.solr.client.solrj.io.stream.StreamContext;
>  import org.apache.solr.client.solrj.io.stream.expr.Explanation;
> @@ -40,6 +42,10 @@ public abstract class ComplexEvaluator implements 
> StreamEvaluator {
>    protected List<StreamEvaluator> subEvaluators = new 
> ArrayList<StreamEvaluator>();
>
>    public ComplexEvaluator(StreamExpression expression, StreamFactory 
> factory) throws IOException{
> +    this(expression, factory, new ArrayList<>());
> +  }
> +
> +  public ComplexEvaluator(StreamExpression expression, StreamFactory 
> factory, List<String> ignoredNamedParameters) throws IOException{
>      constructingFactory = factory;
>
>      // We have to do this because order of the parameters matter
> @@ -75,8 +81,16 @@ public abstract class ComplexEvaluator implements 
> StreamEvaluator {
>        }
>      }
>
> -    if(expression.getParameters().size() != subEvaluators.size()){
> -      throw new IOException(String.format(Locale.ROOT,"Invalid expression %s 
> - unknown operands found - expecting only StreamEvaluators or field names", 
> expression));
> +    Set<String> namedParameters = 
> factory.getNamedOperands(expression).stream().map(param -> 
> param.getName()).collect(Collectors.toSet());
> +    long ignorableCount = ignoredNamedParameters.stream().filter(name -> 
> namedParameters.contains(name)).count();
> +
> +    if(0 != expression.getParameters().size() - subEvaluators.size() - 
> ignorableCount){
> +      if(namedParameters.isEmpty()){
> +        throw new IOException(String.format(Locale.ROOT,"Invalid expression 
> %s - unknown operands found - expecting only StreamEvaluators or field 
> names", expression));
> +      }
> +      else{
> +        throw new IOException(String.format(Locale.ROOT,"Invalid expression 
> %s - unknown operands found - expecting only StreamEvaluators, field names, 
> or named parameters [%s]", expression, 
> namedParameters.stream().collect(Collectors.joining(","))));
> +      }
>      }
>    }
>
>
> http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/113459a8/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ArrayEvaluatorTest.java
> ----------------------------------------------------------------------
> diff --git 
> a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ArrayEvaluatorTest.java
>  
> b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ArrayEvaluatorTest.java
> new file mode 100644
> index 0000000..36e5e78
> --- /dev/null
> +++ 
> b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ArrayEvaluatorTest.java
> @@ -0,0 +1,155 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements.  See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You under the Apache License, Version 2.0
> + * (the "License"); you may not use this file except in compliance with
> + * the License.  You may obtain a copy of the License at
> + *
> + *     http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +package org.apache.solr.client.solrj.io.stream.eval;
> +
> +import java.io.IOException;
> +import java.util.HashMap;
> +import java.util.List;
> +import java.util.Map;
> +
> +import org.apache.lucene.util.LuceneTestCase;
> +import org.apache.solr.client.solrj.io.Tuple;
> +import org.apache.solr.client.solrj.io.eval.ArrayEvaluator;
> +import org.apache.solr.client.solrj.io.eval.StreamEvaluator;
> +import org.apache.solr.client.solrj.io.stream.StreamContext;
> +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
> +import org.junit.Test;
> +
> +import junit.framework.Assert;
> +
> +public class ArrayEvaluatorTest extends LuceneTestCase {
> +
> +  StreamFactory factory;
> +  Map<String, Object> values;
> +
> +  public ArrayEvaluatorTest() {
> +    super();
> +
> +    factory = new StreamFactory()
> +      .withFunctionName("array", ArrayEvaluator.class);
> +    values = new HashMap<String,Object>();
> +  }
> +
> +  @Test
> +  public void arrayLongSortAscTest() throws IOException{
> +    StreamEvaluator evaluator = factory.constructEvaluator("array(a,b,c, 
> sort=asc)");
> +    StreamContext context = new StreamContext();
> +    evaluator.setStreamContext(context);
> +    Object result;
> +
> +    values.put("a", 1L);
> +    values.put("b", 3L);
> +    values.put("c", 2L);
> +
> +    result = evaluator.evaluate(new Tuple(values));
> +
> +    Assert.assertTrue(result instanceof List<?>);
> +
> +    Assert.assertEquals(3, ((List<?>)result).size());
> +    Assert.assertEquals(1L, ((List<?>)result).get(0));
> +    Assert.assertEquals(2L, ((List<?>)result).get(1));
> +    Assert.assertEquals(3L, ((List<?>)result).get(2));
> +  }
> +
> +  @Test
> +  public void arrayLongSortDescTest() throws IOException{
> +    StreamEvaluator evaluator = factory.constructEvaluator("array(a,b,c, 
> sort=desc)");
> +    StreamContext context = new StreamContext();
> +    evaluator.setStreamContext(context);
> +    Object result;
> +
> +    values.put("a", 1L);
> +    values.put("b", 3L);
> +    values.put("c", 2L);
> +
> +    result = evaluator.evaluate(new Tuple(values));
> +
> +    Assert.assertTrue(result instanceof List<?>);
> +
> +    Assert.assertEquals(3, ((List<?>)result).size());
> +    Assert.assertEquals(3L, ((List<?>)result).get(0));
> +    Assert.assertEquals(2L, ((List<?>)result).get(1));
> +    Assert.assertEquals(1L, ((List<?>)result).get(2));
> +  }
> +
> +  @Test
> +  public void arrayStringSortAscTest() throws IOException{
> +    StreamEvaluator evaluator = factory.constructEvaluator("array(a,b,c, 
> sort=asc)");
> +    StreamContext context = new StreamContext();
> +    evaluator.setStreamContext(context);
> +    Object result;
> +
> +    values.put("a", "a");
> +    values.put("b", "c");
> +    values.put("c", "b");
> +
> +    result = evaluator.evaluate(new Tuple(values));
> +
> +    Assert.assertTrue(result instanceof List<?>);
> +
> +    Assert.assertEquals(3, ((List<?>)result).size());
> +    Assert.assertEquals("a", ((List<?>)result).get(0));
> +    Assert.assertEquals("b", ((List<?>)result).get(1));
> +    Assert.assertEquals("c", ((List<?>)result).get(2));
> +  }
> +
> +  @Test
> +  public void arrayStringSortDescTest() throws IOException{
> +    StreamEvaluator evaluator = factory.constructEvaluator("array(a,b,c, 
> sort=desc)");
> +    StreamContext context = new StreamContext();
> +    evaluator.setStreamContext(context);
> +    Object result;
> +
> +    values.put("a", "a");
> +    values.put("b", "c");
> +    values.put("c", "b");
> +
> +    result = evaluator.evaluate(new Tuple(values));
> +
> +    Assert.assertTrue(result instanceof List<?>);
> +
> +    Assert.assertEquals(3, ((List<?>)result).size());
> +    Assert.assertEquals("c", ((List<?>)result).get(0));
> +    Assert.assertEquals("b", ((List<?>)result).get(1));
> +    Assert.assertEquals("a", ((List<?>)result).get(2));
> +  }
> +
> +  @Test
> +  public void arrayStringUnsortedTest() throws IOException{
> +    StreamEvaluator evaluator = factory.constructEvaluator("array(a,b,c)");
> +    StreamContext context = new StreamContext();
> +    evaluator.setStreamContext(context);
> +    Object result;
> +
> +    values.put("a", "a");
> +    values.put("b", "c");
> +    values.put("c", "b");
> +
> +    result = evaluator.evaluate(new Tuple(values));
> +
> +    Assert.assertTrue(result instanceof List<?>);
> +
> +    Assert.assertEquals(3, ((List<?>)result).size());
> +    Assert.assertEquals("a", ((List<?>)result).get(0));
> +    Assert.assertEquals("c", ((List<?>)result).get(1));
> +    Assert.assertEquals("b", ((List<?>)result).get(2));
> +  }
> +
> +
> +
> +
> +}
>



-- 
Regards,
Shalin Shekhar Mangar.

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to