diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 51f29cb6ada..e23c234fb71 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -67,6 +67,8 @@ New Features * SOLR-10358: New suspend-trigger and resume-trigger APIs for autoscaling. (shalin) +* SOLR-10356: Adds basic math Streaming Evaluators (Dennis Gove) + Bug Fixes ---------------------- * SOLR-9262: Connection and read timeouts are being ignored by UpdateShardHandler after SOLR-4509. 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 3ede7320f89..b508754b20a 100644 --- a/solr/core/src/java/org/apache/solr/handler/StreamHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/StreamHandler.java @@ -16,6 +16,9 @@ */ package org.apache.solr.handler; +import static org.apache.solr.common.params.CommonParams.ID; +import static org.apache.solr.common.params.CommonParams.SORT; + import java.io.IOException; import java.lang.invoke.MethodHandles; import java.util.ArrayList; @@ -33,27 +36,80 @@ import org.apache.solr.client.solrj.io.comp.StreamComparator; import org.apache.solr.client.solrj.io.eval.AbsoluteValueEvaluator; import org.apache.solr.client.solrj.io.eval.AddEvaluator; import org.apache.solr.client.solrj.io.eval.AndEvaluator; +import org.apache.solr.client.solrj.io.eval.ArcCosineEvaluator; +import org.apache.solr.client.solrj.io.eval.ArcSineEvaluator; +import org.apache.solr.client.solrj.io.eval.ArcTangentEvaluator; +import org.apache.solr.client.solrj.io.eval.CeilingEvaluator; +import org.apache.solr.client.solrj.io.eval.CoalesceEvaluator; +import org.apache.solr.client.solrj.io.eval.CosineEvaluator; +import org.apache.solr.client.solrj.io.eval.CubedRootEvaluator; import org.apache.solr.client.solrj.io.eval.DivideEvaluator; import org.apache.solr.client.solrj.io.eval.EqualsEvaluator; import org.apache.solr.client.solrj.io.eval.ExclusiveOrEvaluator; +import org.apache.solr.client.solrj.io.eval.FloorEvaluator; import org.apache.solr.client.solrj.io.eval.GreaterThanEqualToEvaluator; import org.apache.solr.client.solrj.io.eval.GreaterThanEvaluator; +import org.apache.solr.client.solrj.io.eval.HyperbolicCosineEvaluator; +import org.apache.solr.client.solrj.io.eval.HyperbolicSineEvaluator; +import org.apache.solr.client.solrj.io.eval.HyperbolicTangentEvaluator; import org.apache.solr.client.solrj.io.eval.IfThenElseEvaluator; import org.apache.solr.client.solrj.io.eval.LessThanEqualToEvaluator; import org.apache.solr.client.solrj.io.eval.LessThanEvaluator; +import org.apache.solr.client.solrj.io.eval.ModuloEvaluator; import org.apache.solr.client.solrj.io.eval.MultiplyEvaluator; import org.apache.solr.client.solrj.io.eval.NaturalLogEvaluator; import org.apache.solr.client.solrj.io.eval.NotEvaluator; import org.apache.solr.client.solrj.io.eval.OrEvaluator; +import org.apache.solr.client.solrj.io.eval.PowerEvaluator; import org.apache.solr.client.solrj.io.eval.RawValueEvaluator; +import org.apache.solr.client.solrj.io.eval.RoundEvaluator; +import org.apache.solr.client.solrj.io.eval.SineEvaluator; +import org.apache.solr.client.solrj.io.eval.SquareRootEvaluator; import org.apache.solr.client.solrj.io.eval.SubtractEvaluator; +import org.apache.solr.client.solrj.io.eval.TangentEvaluator; import org.apache.solr.client.solrj.io.graph.GatherNodesStream; import org.apache.solr.client.solrj.io.graph.ShortestPathStream; import org.apache.solr.client.solrj.io.ops.ConcatOperation; import org.apache.solr.client.solrj.io.ops.DistinctOperation; import org.apache.solr.client.solrj.io.ops.GroupOperation; import org.apache.solr.client.solrj.io.ops.ReplaceOperation; -import org.apache.solr.client.solrj.io.stream.*; +import org.apache.solr.client.solrj.io.stream.CartesianProductStream; +import org.apache.solr.client.solrj.io.stream.CloudSolrStream; +import org.apache.solr.client.solrj.io.stream.CommitStream; +import org.apache.solr.client.solrj.io.stream.ComplementStream; +import org.apache.solr.client.solrj.io.stream.DaemonStream; +import org.apache.solr.client.solrj.io.stream.ExceptionStream; +import org.apache.solr.client.solrj.io.stream.ExecutorStream; +import org.apache.solr.client.solrj.io.stream.FacetStream; +import org.apache.solr.client.solrj.io.stream.FeaturesSelectionStream; +import org.apache.solr.client.solrj.io.stream.FetchStream; +import org.apache.solr.client.solrj.io.stream.HashJoinStream; +import org.apache.solr.client.solrj.io.stream.HavingStream; +import org.apache.solr.client.solrj.io.stream.InnerJoinStream; +import org.apache.solr.client.solrj.io.stream.IntersectStream; +import org.apache.solr.client.solrj.io.stream.JDBCStream; +import org.apache.solr.client.solrj.io.stream.LeftOuterJoinStream; +import org.apache.solr.client.solrj.io.stream.MergeStream; +import org.apache.solr.client.solrj.io.stream.ModelStream; +import org.apache.solr.client.solrj.io.stream.NullStream; +import org.apache.solr.client.solrj.io.stream.OuterHashJoinStream; +import org.apache.solr.client.solrj.io.stream.ParallelStream; +import org.apache.solr.client.solrj.io.stream.PriorityStream; +import org.apache.solr.client.solrj.io.stream.RandomStream; +import org.apache.solr.client.solrj.io.stream.RankStream; +import org.apache.solr.client.solrj.io.stream.ReducerStream; +import org.apache.solr.client.solrj.io.stream.RollupStream; +import org.apache.solr.client.solrj.io.stream.ScoreNodesStream; +import org.apache.solr.client.solrj.io.stream.SelectStream; +import org.apache.solr.client.solrj.io.stream.SignificantTermsStream; +import org.apache.solr.client.solrj.io.stream.SortStream; +import org.apache.solr.client.solrj.io.stream.StatsStream; +import org.apache.solr.client.solrj.io.stream.StreamContext; +import org.apache.solr.client.solrj.io.stream.TextLogitStream; +import org.apache.solr.client.solrj.io.stream.TopicStream; +import org.apache.solr.client.solrj.io.stream.TupleStream; +import org.apache.solr.client.solrj.io.stream.UniqueStream; +import org.apache.solr.client.solrj.io.stream.UpdateStream; 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; @@ -80,9 +136,6 @@ import org.apache.solr.util.plugin.SolrCoreAware; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import static org.apache.solr.common.params.CommonParams.ID; -import static org.apache.solr.common.params.CommonParams.SORT; - public class StreamHandler extends RequestHandlerBase implements SolrCoreAware, PermissionNameProvider { static SolrClientCache clientCache = new SolrClientCache(); @@ -207,6 +260,24 @@ public class StreamHandler extends RequestHandlerBase implements SolrCoreAware, .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) + // Conditional Stream Evaluators .withFunctionName("if", IfThenElseEvaluator.class) .withFunctionName("analyze", AnalyzeEvaluator.class) diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArcCosineEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArcCosineEvaluator.java new file mode 100644 index 00000000000..0c8e383786a --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArcCosineEvaluator.java @@ -0,0 +1,60 @@ +/* + * 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.math.BigDecimal; +import java.util.List; +import java.util.Locale; + +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.stream.expr.StreamExpression; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; + +public class ArcCosineEvaluator extends NumberEvaluator { + protected static final long serialVersionUID = 1L; + + public ArcCosineEvaluator(StreamExpression expression, StreamFactory factory) throws IOException{ + super(expression, factory); + + if(1 != subEvaluators.size()){ + throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - expecting one value but found %d",expression,subEvaluators.size())); + } + } + + @Override + public Number evaluate(Tuple tuple) throws IOException { + + List results = evaluateAll(tuple); + + // we're still doing these checks because if we ever add an array-flatten evaluator, + // one found in the constructor could become != 1 + if(1 != results.size()){ + throw new IOException(String.format(Locale.ROOT,"%s(...) only works with a 1 value but %d were provided", constructingFactory.getFunctionName(getClass()), results.size())); + } + + if(null == results.get(0)){ + return null; + } + + return Math.acos(results.get(0).doubleValue()); + } + +} diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArcSineEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArcSineEvaluator.java new file mode 100644 index 00000000000..ed95165dfaa --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArcSineEvaluator.java @@ -0,0 +1,60 @@ +/* + * 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.math.BigDecimal; +import java.util.List; +import java.util.Locale; + +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.stream.expr.StreamExpression; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; + +public class ArcSineEvaluator extends NumberEvaluator { + protected static final long serialVersionUID = 1L; + + public ArcSineEvaluator(StreamExpression expression, StreamFactory factory) throws IOException{ + super(expression, factory); + + if(1 != subEvaluators.size()){ + throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - expecting one value but found %d",expression,subEvaluators.size())); + } + } + + @Override + public Number evaluate(Tuple tuple) throws IOException { + + List results = evaluateAll(tuple); + + // we're still doing these checks because if we ever add an array-flatten evaluator, + // one found in the constructor could become != 1 + if(1 != results.size()){ + throw new IOException(String.format(Locale.ROOT,"%s(...) only works with a 1 value but %d were provided", constructingFactory.getFunctionName(getClass()), results.size())); + } + + if(null == results.get(0)){ + return null; + } + + return Math.asin(results.get(0).doubleValue()); + } + +} diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArcTangentEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArcTangentEvaluator.java new file mode 100644 index 00000000000..9325b410ffb --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArcTangentEvaluator.java @@ -0,0 +1,60 @@ +/* + * 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.math.BigDecimal; +import java.util.List; +import java.util.Locale; + +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.stream.expr.StreamExpression; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; + +public class ArcTangentEvaluator extends NumberEvaluator { + protected static final long serialVersionUID = 1L; + + public ArcTangentEvaluator(StreamExpression expression, StreamFactory factory) throws IOException{ + super(expression, factory); + + if(1 != subEvaluators.size()){ + throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - expecting one value but found %d",expression,subEvaluators.size())); + } + } + + @Override + public Number evaluate(Tuple tuple) throws IOException { + + List results = evaluateAll(tuple); + + // we're still doing these checks because if we ever add an array-flatten evaluator, + // one found in the constructor could become != 1 + if(1 != results.size()){ + throw new IOException(String.format(Locale.ROOT,"%s(...) only works with a 1 value but %d were provided", constructingFactory.getFunctionName(getClass()), results.size())); + } + + if(null == results.get(0)){ + return null; + } + + return Math.atan(results.get(0).doubleValue()); + } + +} diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/BooleanEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/BooleanEvaluator.java index f02f1fac65e..908562f8220 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/BooleanEvaluator.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/BooleanEvaluator.java @@ -24,13 +24,11 @@ import java.util.ArrayList; import java.util.List; import org.apache.solr.client.solrj.io.Tuple; -import org.apache.solr.client.solrj.io.stream.StreamContext; import org.apache.solr.client.solrj.io.stream.expr.StreamExpression; import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; public abstract class BooleanEvaluator extends ComplexEvaluator { protected static final long serialVersionUID = 1L; - protected StreamContext streamContext; public BooleanEvaluator(StreamExpression expression, StreamFactory factory) throws IOException{ super(expression, factory); @@ -48,11 +46,6 @@ public abstract class BooleanEvaluator extends ComplexEvaluator { return results; } - public void setStreamContext(StreamContext streamContext) { - this.streamContext = streamContext; - } - - public interface Checker { default boolean isNullAllowed(){ return false; diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CeilingEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CeilingEvaluator.java new file mode 100644 index 00000000000..e2ccc8f1deb --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CeilingEvaluator.java @@ -0,0 +1,61 @@ +/* + * 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.math.BigDecimal; +import java.math.RoundingMode; +import java.util.List; +import java.util.Locale; + +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.stream.expr.StreamExpression; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; + +public class CeilingEvaluator extends NumberEvaluator { + protected static final long serialVersionUID = 1L; + + public CeilingEvaluator(StreamExpression expression, StreamFactory factory) throws IOException{ + super(expression, factory); + + if(1 != subEvaluators.size()){ + throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - expecting one value but found %d",expression,subEvaluators.size())); + } + } + + @Override + public Number evaluate(Tuple tuple) throws IOException { + + List results = evaluateAll(tuple); + + // we're still doing these checks because if we ever add an array-flatten evaluator, + // one found in the constructor could become != 1 + if(1 != results.size()){ + throw new IOException(String.format(Locale.ROOT,"%s(...) only works with a 1 value but %d were provided", constructingFactory.getFunctionName(getClass()), results.size())); + } + + if(null == results.get(0)){ + return null; + } + + return normalizeType(results.get(0).setScale(0, RoundingMode.CEILING)); + } + +} diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CoalesceEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CoalesceEvaluator.java new file mode 100644 index 00000000000..8a6eda40974 --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CoalesceEvaluator.java @@ -0,0 +1,52 @@ +/* + * 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.Locale; + +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.stream.expr.StreamExpression; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; + +public class CoalesceEvaluator extends ComplexEvaluator { + protected static final long serialVersionUID = 1L; + + public CoalesceEvaluator(StreamExpression expression, StreamFactory factory) throws IOException{ + super(expression, factory); + + if(subEvaluators.size() < 1){ + throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - expecting at least one value but found %d",expression,subEvaluators.size())); + } + } + + @Override + public Object evaluate(Tuple tuple) throws IOException { + + for(StreamEvaluator evaluator : subEvaluators){ + Object result = evaluator.evaluate(tuple); + if(null != result){ + return result; + } + } + + return null; + } +} 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 1e56d12bfcc..59a4653ef5e 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 @@ -22,6 +22,7 @@ import java.util.List; import java.util.Locale; import java.util.UUID; +import org.apache.solr.client.solrj.io.stream.StreamContext; 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.StreamExpression; @@ -31,6 +32,7 @@ import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; public abstract class ComplexEvaluator implements StreamEvaluator { protected static final long serialVersionUID = 1L; + protected StreamContext streamContext; protected UUID nodeId = UUID.randomUUID(); @@ -96,4 +98,8 @@ public abstract class ComplexEvaluator implements StreamEvaluator { .withImplementingClass(getClass().getName()) .withExpression(toExpression(factory).toString()); } + + public void setStreamContext(StreamContext context) { + this.streamContext = context; + } } diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ConditionalEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ConditionalEvaluator.java index 61265441f8d..025bfae7d98 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ConditionalEvaluator.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ConditionalEvaluator.java @@ -24,13 +24,11 @@ import java.util.ArrayList; import java.util.List; import org.apache.solr.client.solrj.io.Tuple; -import org.apache.solr.client.solrj.io.stream.StreamContext; import org.apache.solr.client.solrj.io.stream.expr.StreamExpression; import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; public abstract class ConditionalEvaluator extends ComplexEvaluator { protected static final long serialVersionUID = 1L; - protected StreamContext streamContext; public ConditionalEvaluator(StreamExpression expression, StreamFactory factory) throws IOException{ super(expression, factory); @@ -45,10 +43,6 @@ public abstract class ConditionalEvaluator extends ComplexEvaluator { return results; } - public void setStreamContext(StreamContext streamContext) { - this.streamContext = streamContext; - } - public interface Checker { default boolean isNullAllowed(){ return false; diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CosineEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CosineEvaluator.java new file mode 100644 index 00000000000..6adbb81f3cc --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CosineEvaluator.java @@ -0,0 +1,60 @@ +/* + * 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.math.BigDecimal; +import java.util.List; +import java.util.Locale; + +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.stream.expr.StreamExpression; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; + +public class CosineEvaluator extends NumberEvaluator { + protected static final long serialVersionUID = 1L; + + public CosineEvaluator(StreamExpression expression, StreamFactory factory) throws IOException{ + super(expression, factory); + + if(1 != subEvaluators.size()){ + throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - expecting one value but found %d",expression,subEvaluators.size())); + } + } + + @Override + public Number evaluate(Tuple tuple) throws IOException { + + List results = evaluateAll(tuple); + + // we're still doing these checks because if we ever add an array-flatten evaluator, + // one found in the constructor could become != 1 + if(1 != results.size()){ + throw new IOException(String.format(Locale.ROOT,"%s(...) only works with a 1 value but %d were provided", constructingFactory.getFunctionName(getClass()), results.size())); + } + + if(null == results.get(0)){ + return null; + } + + return Math.cos(results.get(0).doubleValue()); + } + +} diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CubedRootEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CubedRootEvaluator.java new file mode 100644 index 00000000000..4cd927789ad --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CubedRootEvaluator.java @@ -0,0 +1,60 @@ +/* + * 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.math.BigDecimal; +import java.util.List; +import java.util.Locale; + +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.stream.expr.StreamExpression; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; + +public class CubedRootEvaluator extends NumberEvaluator { + protected static final long serialVersionUID = 1L; + + public CubedRootEvaluator(StreamExpression expression, StreamFactory factory) throws IOException{ + super(expression, factory); + + if(1 != subEvaluators.size()){ + throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - expecting one value but found %d",expression,subEvaluators.size())); + } + } + + @Override + public Number evaluate(Tuple tuple) throws IOException { + + List results = evaluateAll(tuple); + + // we're still doing these checks because if we ever add an array-flatten evaluator, + // one found in the constructor could become != 1 + if(1 != results.size()){ + throw new IOException(String.format(Locale.ROOT,"%s(...) only works with a 1 value but %d were provided", constructingFactory.getFunctionName(getClass()), results.size())); + } + + if(null == results.get(0)){ + return null; + } + + return Math.cbrt(results.get(0).doubleValue()); + } + +} diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/FloorEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/FloorEvaluator.java new file mode 100644 index 00000000000..0191a8e4802 --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/FloorEvaluator.java @@ -0,0 +1,61 @@ +/* + * 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.math.BigDecimal; +import java.math.RoundingMode; +import java.util.List; +import java.util.Locale; + +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.stream.expr.StreamExpression; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; + +public class FloorEvaluator extends NumberEvaluator { + protected static final long serialVersionUID = 1L; + + public FloorEvaluator(StreamExpression expression, StreamFactory factory) throws IOException{ + super(expression, factory); + + if(1 != subEvaluators.size()){ + throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - expecting one value but found %d",expression,subEvaluators.size())); + } + } + + @Override + public Number evaluate(Tuple tuple) throws IOException { + + List results = evaluateAll(tuple); + + // we're still doing these checks because if we ever add an array-flatten evaluator, + // one found in the constructor could become != 1 + if(1 != results.size()){ + throw new IOException(String.format(Locale.ROOT,"%s(...) only works with a 1 value but %d were provided", constructingFactory.getFunctionName(getClass()), results.size())); + } + + if(null == results.get(0)){ + return null; + } + + return normalizeType(results.get(0).setScale(0, RoundingMode.FLOOR)); + } + +} diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/HyperbolicCosineEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/HyperbolicCosineEvaluator.java new file mode 100644 index 00000000000..4e973a4e789 --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/HyperbolicCosineEvaluator.java @@ -0,0 +1,60 @@ +/* + * 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.math.BigDecimal; +import java.util.List; +import java.util.Locale; + +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.stream.expr.StreamExpression; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; + +public class HyperbolicCosineEvaluator extends NumberEvaluator { + protected static final long serialVersionUID = 1L; + + public HyperbolicCosineEvaluator(StreamExpression expression, StreamFactory factory) throws IOException{ + super(expression, factory); + + if(1 != subEvaluators.size()){ + throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - expecting one value but found %d",expression,subEvaluators.size())); + } + } + + @Override + public Number evaluate(Tuple tuple) throws IOException { + + List results = evaluateAll(tuple); + + // we're still doing these checks because if we ever add an array-flatten evaluator, + // one found in the constructor could become != 1 + if(1 != results.size()){ + throw new IOException(String.format(Locale.ROOT,"%s(...) only works with a 1 value but %d were provided", constructingFactory.getFunctionName(getClass()), results.size())); + } + + if(null == results.get(0)){ + return null; + } + + return Math.cosh(results.get(0).doubleValue()); + } + +} diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/HyperbolicSineEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/HyperbolicSineEvaluator.java new file mode 100644 index 00000000000..5bf4a38c76c --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/HyperbolicSineEvaluator.java @@ -0,0 +1,60 @@ +/* + * 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.math.BigDecimal; +import java.util.List; +import java.util.Locale; + +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.stream.expr.StreamExpression; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; + +public class HyperbolicSineEvaluator extends NumberEvaluator { + protected static final long serialVersionUID = 1L; + + public HyperbolicSineEvaluator(StreamExpression expression, StreamFactory factory) throws IOException{ + super(expression, factory); + + if(1 != subEvaluators.size()){ + throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - expecting one value but found %d",expression,subEvaluators.size())); + } + } + + @Override + public Number evaluate(Tuple tuple) throws IOException { + + List results = evaluateAll(tuple); + + // we're still doing these checks because if we ever add an array-flatten evaluator, + // one found in the constructor could become != 1 + if(1 != results.size()){ + throw new IOException(String.format(Locale.ROOT,"%s(...) only works with a 1 value but %d were provided", constructingFactory.getFunctionName(getClass()), results.size())); + } + + if(null == results.get(0)){ + return null; + } + + return Math.sinh(results.get(0).doubleValue()); + } + +} diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/HyperbolicTangentEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/HyperbolicTangentEvaluator.java new file mode 100644 index 00000000000..89aacd19d23 --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/HyperbolicTangentEvaluator.java @@ -0,0 +1,60 @@ +/* + * 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.math.BigDecimal; +import java.util.List; +import java.util.Locale; + +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.stream.expr.StreamExpression; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; + +public class HyperbolicTangentEvaluator extends NumberEvaluator { + protected static final long serialVersionUID = 1L; + + public HyperbolicTangentEvaluator(StreamExpression expression, StreamFactory factory) throws IOException{ + super(expression, factory); + + if(1 != subEvaluators.size()){ + throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - expecting one value but found %d",expression,subEvaluators.size())); + } + } + + @Override + public Number evaluate(Tuple tuple) throws IOException { + + List results = evaluateAll(tuple); + + // we're still doing these checks because if we ever add an array-flatten evaluator, + // one found in the constructor could become != 1 + if(1 != results.size()){ + throw new IOException(String.format(Locale.ROOT,"%s(...) only works with a 1 value but %d were provided", constructingFactory.getFunctionName(getClass()), results.size())); + } + + if(null == results.get(0)){ + return null; + } + + return Math.tanh(results.get(0).doubleValue()); + } + +} diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ModuloEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ModuloEvaluator.java new file mode 100644 index 00000000000..928754b6360 --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ModuloEvaluator.java @@ -0,0 +1,78 @@ +/* + * 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.math.BigDecimal; +import java.math.MathContext; +import java.util.List; +import java.util.Locale; + +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.stream.expr.StreamExpression; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; + +public class ModuloEvaluator extends NumberEvaluator { + protected static final long serialVersionUID = 1L; + + public ModuloEvaluator(StreamExpression expression, StreamFactory factory) throws IOException{ + super(expression, factory); + + if(2 != subEvaluators.size()){ + throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - expecting two values but found %d",expression,subEvaluators.size())); + } + } + + @Override + public Number evaluate(Tuple tuple) throws IOException { + + List results = evaluateAll(tuple); + + // we're still doing these checks because if we ever add an array-flatten evaluator, + // two found in the constructor could become != 2 + if(2 != results.size()){ + String message = null; + if(1 == results.size()){ + message = String.format(Locale.ROOT,"%s(...) only works with a 2 values (numerator,denominator) but 1 was provided", constructingFactory.getFunctionName(getClass())); + } + else{ + message = String.format(Locale.ROOT,"%s(...) only works with a 2 values (numerator,denominator) but %d were provided", constructingFactory.getFunctionName(getClass()), results.size()); + } + throw new IOException(message); + } + + BigDecimal numerator = results.get(0); + BigDecimal denominator = results.get(1); + + if(null == numerator){ + throw new IOException(String.format(Locale.ROOT,"Unable to %s(...) with a null numerator", constructingFactory.getFunctionName(getClass()))); + } + + if(null == denominator){ + throw new IOException(String.format(Locale.ROOT,"Unable to %s(...) with a null denominator", constructingFactory.getFunctionName(getClass()))); + } + + if(0 == denominator.compareTo(BigDecimal.ZERO)){ + throw new IOException(String.format(Locale.ROOT,"Unable to %s(...) with a 0 denominator", constructingFactory.getFunctionName(getClass()))); + } + + return normalizeType(numerator.remainder(denominator, MathContext.DECIMAL64)); + } +} diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/NumberEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/NumberEvaluator.java index 283c7b196e8..f4491fd45ff 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/NumberEvaluator.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/NumberEvaluator.java @@ -26,13 +26,11 @@ import java.util.List; import java.util.Locale; import org.apache.solr.client.solrj.io.Tuple; -import org.apache.solr.client.solrj.io.stream.StreamContext; import org.apache.solr.client.solrj.io.stream.expr.StreamExpression; import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; public abstract class NumberEvaluator extends ComplexEvaluator { protected static final long serialVersionUID = 1L; - protected StreamContext streamContext; public NumberEvaluator(StreamExpression expression, StreamFactory factory) throws IOException{ super(expression, factory); @@ -40,10 +38,6 @@ public abstract class NumberEvaluator extends ComplexEvaluator { // restrict result to a Number public abstract Number evaluate(Tuple tuple) throws IOException; - - public void setStreamContext(StreamContext context) { - this.streamContext = context; - } public List evaluateAll(final Tuple tuple) throws IOException { // evaluate each and confirm they are all either null or numeric diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/PowerEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/PowerEvaluator.java new file mode 100644 index 00000000000..a8245b6e15e --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/PowerEvaluator.java @@ -0,0 +1,61 @@ +/* + * 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.math.BigDecimal; +import java.util.List; +import java.util.Locale; + +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.stream.expr.StreamExpression; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; + +public class PowerEvaluator extends NumberEvaluator { + protected static final long serialVersionUID = 1L; + + public PowerEvaluator(StreamExpression expression, StreamFactory factory) throws IOException{ + super(expression, factory); + + if(2 != subEvaluators.size()){ + throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - expecting exactly two values but found %d",expression,subEvaluators.size())); + } + } + + @Override + public Number evaluate(Tuple tuple) throws IOException { + + List results = evaluateAll(tuple); + + if(results.stream().anyMatch(item -> null == item)){ + return null; + } + + BigDecimal value = results.get(0); + BigDecimal exponent = results.get(1); + + double result = Math.pow(value.doubleValue(), exponent.doubleValue()); + if(Double.isNaN(result)){ + return result; + } + + return normalizeType(BigDecimal.valueOf(result)); + } +} diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RoundEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RoundEvaluator.java new file mode 100644 index 00000000000..a34cdf4037a --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RoundEvaluator.java @@ -0,0 +1,60 @@ +/* + * 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.math.BigDecimal; +import java.util.List; +import java.util.Locale; + +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.stream.expr.StreamExpression; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; + +public class RoundEvaluator extends NumberEvaluator { + protected static final long serialVersionUID = 1L; + + public RoundEvaluator(StreamExpression expression, StreamFactory factory) throws IOException{ + super(expression, factory); + + if(1 != subEvaluators.size()){ + throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - expecting one value but found %d",expression,subEvaluators.size())); + } + } + + @Override + public Number evaluate(Tuple tuple) throws IOException { + + List results = evaluateAll(tuple); + + // we're still doing these checks because if we ever add an array-flatten evaluator, + // one found in the constructor could become != 1 + if(1 != results.size()){ + throw new IOException(String.format(Locale.ROOT,"%s(...) only works with a 1 value but %d were provided", constructingFactory.getFunctionName(getClass()), results.size())); + } + + if(null == results.get(0)){ + return null; + } + + return Math.round(results.get(0).doubleValue()); + } + +} diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SineEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SineEvaluator.java new file mode 100644 index 00000000000..1e2fbb5a6bb --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SineEvaluator.java @@ -0,0 +1,60 @@ +/* + * 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.math.BigDecimal; +import java.util.List; +import java.util.Locale; + +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.stream.expr.StreamExpression; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; + +public class SineEvaluator extends NumberEvaluator { + protected static final long serialVersionUID = 1L; + + public SineEvaluator(StreamExpression expression, StreamFactory factory) throws IOException{ + super(expression, factory); + + if(1 != subEvaluators.size()){ + throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - expecting one value but found %d",expression,subEvaluators.size())); + } + } + + @Override + public Number evaluate(Tuple tuple) throws IOException { + + List results = evaluateAll(tuple); + + // we're still doing these checks because if we ever add an array-flatten evaluator, + // one found in the constructor could become != 1 + if(1 != results.size()){ + throw new IOException(String.format(Locale.ROOT,"%s(...) only works with a 1 value but %d were provided", constructingFactory.getFunctionName(getClass()), results.size())); + } + + if(null == results.get(0)){ + return null; + } + + return Math.sin(results.get(0).doubleValue()); + } + +} diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SquareRootEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SquareRootEvaluator.java new file mode 100644 index 00000000000..74b9d81989c --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SquareRootEvaluator.java @@ -0,0 +1,60 @@ +/* + * 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.math.BigDecimal; +import java.util.List; +import java.util.Locale; + +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.stream.expr.StreamExpression; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; + +public class SquareRootEvaluator extends NumberEvaluator { + protected static final long serialVersionUID = 1L; + + public SquareRootEvaluator(StreamExpression expression, StreamFactory factory) throws IOException{ + super(expression, factory); + + if(1 != subEvaluators.size()){ + throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - expecting one value but found %d",expression,subEvaluators.size())); + } + } + + @Override + public Number evaluate(Tuple tuple) throws IOException { + + List results = evaluateAll(tuple); + + // we're still doing these checks because if we ever add an array-flatten evaluator, + // one found in the constructor could become != 1 + if(1 != results.size()){ + throw new IOException(String.format(Locale.ROOT,"%s(...) only works with a 1 value but %d were provided", constructingFactory.getFunctionName(getClass()), results.size())); + } + + if(null == results.get(0)){ + return null; + } + + return Math.sqrt(results.get(0).doubleValue()); + } + +} diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/TangentEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/TangentEvaluator.java new file mode 100644 index 00000000000..d2a0476d1a2 --- /dev/null +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/TangentEvaluator.java @@ -0,0 +1,60 @@ +/* + * 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.math.BigDecimal; +import java.util.List; +import java.util.Locale; + +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.stream.expr.StreamExpression; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; + +public class TangentEvaluator extends NumberEvaluator { + protected static final long serialVersionUID = 1L; + + public TangentEvaluator(StreamExpression expression, StreamFactory factory) throws IOException{ + super(expression, factory); + + if(1 != subEvaluators.size()){ + throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - expecting one value but found %d",expression,subEvaluators.size())); + } + } + + @Override + public Number evaluate(Tuple tuple) throws IOException { + + List results = evaluateAll(tuple); + + // we're still doing these checks because if we ever add an array-flatten evaluator, + // one found in the constructor could become != 1 + if(1 != results.size()){ + throw new IOException(String.format(Locale.ROOT,"%s(...) only works with a 1 value but %d were provided", constructingFactory.getFunctionName(getClass()), results.size())); + } + + if(null == results.get(0)){ + return null; + } + + return Math.tan(results.get(0).doubleValue()); + } + +} diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ArcCosineEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ArcCosineEvaluatorTest.java new file mode 100644 index 00000000000..6a99a1cff0e --- /dev/null +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ArcCosineEvaluatorTest.java @@ -0,0 +1,91 @@ +/* + * 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.Map; + +import org.apache.lucene.util.LuceneTestCase; +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.eval.ArcCosineEvaluator; +import org.apache.solr.client.solrj.io.eval.StreamEvaluator; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; +import org.junit.Test; + +import junit.framework.Assert; + +public class ArcCosineEvaluatorTest extends LuceneTestCase { + + StreamFactory factory; + Map values; + + public ArcCosineEvaluatorTest() { + super(); + + factory = new StreamFactory() + .withFunctionName("acos", ArcCosineEvaluator.class); + values = new HashMap(); + } + + private void test(Double value) throws IOException{ + StreamEvaluator evaluator = factory.constructEvaluator("acos(a)"); + + values.clear(); + values.put("a", value); + Object result = evaluator.evaluate(new Tuple(values)); + + if(null == value){ + Assert.assertNull(result); + } + else{ + Assert.assertTrue(result instanceof Double); + Assert.assertEquals(Math.acos(value), result); + } + } + + @Test + public void oneField() throws Exception{ + test(90D); + test(45D); + test(12.4D); + test(-45D); + } + + @Test(expected = IOException.class) + public void noField() throws Exception{ + factory.constructEvaluator("acos()"); + } + + @Test(expected = IOException.class) + public void twoFields() throws Exception{ + factory.constructEvaluator("acos(a,b)"); + } + + @Test + public void noValue() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("acos(a)"); + + values.clear(); + Object result = evaluator.evaluate(new Tuple(values)); + assertNull(result); + } + @Test + public void nullValue() throws Exception{ + test(null); + } +} diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ArcSineEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ArcSineEvaluatorTest.java new file mode 100644 index 00000000000..79e934bda7c --- /dev/null +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ArcSineEvaluatorTest.java @@ -0,0 +1,91 @@ +/* + * 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.Map; + +import org.apache.lucene.util.LuceneTestCase; +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.eval.ArcSineEvaluator; +import org.apache.solr.client.solrj.io.eval.StreamEvaluator; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; +import org.junit.Test; + +import junit.framework.Assert; + +public class ArcSineEvaluatorTest extends LuceneTestCase { + + StreamFactory factory; + Map values; + + public ArcSineEvaluatorTest() { + super(); + + factory = new StreamFactory() + .withFunctionName("asin", ArcSineEvaluator.class); + values = new HashMap(); + } + + private void test(Double value) throws IOException{ + StreamEvaluator evaluator = factory.constructEvaluator("asin(a)"); + + values.clear(); + values.put("a", value); + Object result = evaluator.evaluate(new Tuple(values)); + + if(null == value){ + Assert.assertNull(result); + } + else{ + Assert.assertTrue(result instanceof Double); + Assert.assertEquals(Math.asin(value), result); + } + } + + @Test + public void oneField() throws Exception{ + test(90D); + test(45D); + test(12.4D); + test(-45D); + } + + @Test(expected = IOException.class) + public void noField() throws Exception{ + factory.constructEvaluator("asin()"); + } + + @Test(expected = IOException.class) + public void twoFields() throws Exception{ + factory.constructEvaluator("asin(a,b)"); + } + + @Test + public void noValue() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("asin(a)"); + + values.clear(); + Object result = evaluator.evaluate(new Tuple(values)); + assertNull(result); + } + @Test + public void nullValue() throws Exception{ + test(null); + } +} diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ArcTangentEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ArcTangentEvaluatorTest.java new file mode 100644 index 00000000000..7af225bd704 --- /dev/null +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ArcTangentEvaluatorTest.java @@ -0,0 +1,91 @@ +/* + * 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.Map; + +import org.apache.lucene.util.LuceneTestCase; +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.eval.ArcTangentEvaluator; +import org.apache.solr.client.solrj.io.eval.StreamEvaluator; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; +import org.junit.Test; + +import junit.framework.Assert; + +public class ArcTangentEvaluatorTest extends LuceneTestCase { + + StreamFactory factory; + Map values; + + public ArcTangentEvaluatorTest() { + super(); + + factory = new StreamFactory() + .withFunctionName("atan", ArcTangentEvaluator.class); + values = new HashMap(); + } + + private void test(Double value) throws IOException{ + StreamEvaluator evaluator = factory.constructEvaluator("atan(a)"); + + values.clear(); + values.put("a", value); + Object result = evaluator.evaluate(new Tuple(values)); + + if(null == value){ + Assert.assertNull(result); + } + else{ + Assert.assertTrue(result instanceof Double); + Assert.assertEquals(Math.atan(value), result); + } + } + + @Test + public void oneField() throws Exception{ + test(90D); + test(45D); + test(12.4D); + test(-45D); + } + + @Test(expected = IOException.class) + public void noField() throws Exception{ + factory.constructEvaluator("atan()"); + } + + @Test(expected = IOException.class) + public void twoFields() throws Exception{ + factory.constructEvaluator("atan(a,b)"); + } + + @Test + public void noValue() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("atan(a)"); + + values.clear(); + Object result = evaluator.evaluate(new Tuple(values)); + assertNull(result); + } + @Test + public void nullValue() throws Exception{ + test(null); + } +} diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/CeilingEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/CeilingEvaluatorTest.java new file mode 100644 index 00000000000..03395d2242e --- /dev/null +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/CeilingEvaluatorTest.java @@ -0,0 +1,96 @@ +/* + * 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.Map; + +import org.apache.lucene.util.LuceneTestCase; +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.eval.CeilingEvaluator; +import org.apache.solr.client.solrj.io.eval.StreamEvaluator; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; +import org.junit.Test; + +import junit.framework.Assert; + +public class CeilingEvaluatorTest extends LuceneTestCase { + + StreamFactory factory; + Map values; + + public CeilingEvaluatorTest() { + super(); + + factory = new StreamFactory() + .withFunctionName("ceil", CeilingEvaluator.class); + values = new HashMap(); + } + + @Test + public void ceilingOneField() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("ceil(a)"); + Object result; + + values.clear(); + values.put("a", 1); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertTrue(result instanceof Long); + Assert.assertEquals(1L, result); + + values.clear(); + values.put("a", 1.1); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertTrue(result instanceof Long); + Assert.assertEquals(2L, result); + + values.clear(); + values.put("a", -1.1); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertTrue(result instanceof Long); + Assert.assertEquals(-1L, result); + } + + @Test(expected = IOException.class) + public void ceilNoField() throws Exception{ + factory.constructEvaluator("ceil()"); + } + + @Test(expected = IOException.class) + public void ceilTwoFields() throws Exception{ + factory.constructEvaluator("ceil(a,b)"); + } + + @Test + public void ceilNoValue() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("ceil(a)"); + + values.clear(); + Object result = evaluator.evaluate(new Tuple(values)); + assertNull(result); + } + @Test + public void ceilNullValue() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("ceil(a)"); + + values.clear(); + values.put("a", null); + Object result = evaluator.evaluate(new Tuple(values)); + assertNull(result); + } +} diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/CoalesceEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/CoalesceEvaluatorTest.java new file mode 100644 index 00000000000..79f46e729d9 --- /dev/null +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/CoalesceEvaluatorTest.java @@ -0,0 +1,112 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for multitional 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.util.HashMap; +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.CoalesceEvaluator; +import org.apache.solr.client.solrj.io.eval.StreamEvaluator; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; +import org.junit.Test; + +import junit.framework.Assert; + +public class CoalesceEvaluatorTest extends LuceneTestCase { + + StreamFactory factory; + Map values; + + public CoalesceEvaluatorTest() { + super(); + + factory = new StreamFactory() + .withFunctionName("coalesce", CoalesceEvaluator.class); + values = new HashMap(); + } + + @Test + public void twoFieldsWithValues() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("coalesce(a,b)"); + Object result; + + values.clear(); + values.put("a", null); + values.put("b", 2); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertEquals(2, result); + + values.clear(); + values.put("a", 1.1); + values.put("b", null); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertEquals(1.1D, result); + + values.clear(); + values.put("a", "foo"); + values.put("b", 2.1); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertEquals("foo", result); + + values.clear(); + values.put("a", true); + values.put("b", 2.1); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertEquals(true, result); + + + values.clear(); + values.put("a", null); + values.put("b", false); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertEquals(false, result); + + values.clear(); + values.put("a", null); + values.put("b", null); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertNull(result); + } + + + @Test + public void twoFieldsWithMissingField() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("coalesce(a,b)"); + Object result; + + values.clear(); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertNull(result); + + } + + @Test + public void manyFieldsWithSubcoalesces() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("coalesce(a,b,coalesce(c,d))"); + Object result; + + values.clear(); + values.put("a", 1); + values.put("b", null); + values.put("c", null); + values.put("d", 4); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertEquals(1, result); + } +} diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/CosineEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/CosineEvaluatorTest.java new file mode 100644 index 00000000000..6bb69137340 --- /dev/null +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/CosineEvaluatorTest.java @@ -0,0 +1,91 @@ +/* + * 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.Map; + +import org.apache.lucene.util.LuceneTestCase; +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.eval.CosineEvaluator; +import org.apache.solr.client.solrj.io.eval.StreamEvaluator; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; +import org.junit.Test; + +import junit.framework.Assert; + +public class CosineEvaluatorTest extends LuceneTestCase { + + StreamFactory factory; + Map values; + + public CosineEvaluatorTest() { + super(); + + factory = new StreamFactory() + .withFunctionName("cos", CosineEvaluator.class); + values = new HashMap(); + } + + private void test(Double value) throws IOException{ + StreamEvaluator evaluator = factory.constructEvaluator("cos(a)"); + + values.clear(); + values.put("a", value); + Object result = evaluator.evaluate(new Tuple(values)); + + if(null == value){ + Assert.assertNull(result); + } + else{ + Assert.assertTrue(result instanceof Double); + Assert.assertEquals(Math.cos(value), result); + } + } + + @Test + public void oneField() throws Exception{ + test(90D); + test(45D); + test(12.4D); + test(-45D); + } + + @Test(expected = IOException.class) + public void noField() throws Exception{ + factory.constructEvaluator("cos()"); + } + + @Test(expected = IOException.class) + public void twoFields() throws Exception{ + factory.constructEvaluator("cos(a,b)"); + } + + @Test + public void noValue() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("cos(a)"); + + values.clear(); + Object result = evaluator.evaluate(new Tuple(values)); + assertNull(result); + } + @Test + public void nullValue() throws Exception{ + test(null); + } +} diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/CubedRootEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/CubedRootEvaluatorTest.java new file mode 100644 index 00000000000..0a7f3de8db9 --- /dev/null +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/CubedRootEvaluatorTest.java @@ -0,0 +1,91 @@ +/* + * 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.Map; + +import org.apache.lucene.util.LuceneTestCase; +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.eval.CubedRootEvaluator; +import org.apache.solr.client.solrj.io.eval.StreamEvaluator; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; +import org.junit.Test; + +import junit.framework.Assert; + +public class CubedRootEvaluatorTest extends LuceneTestCase { + + StreamFactory factory; + Map values; + + public CubedRootEvaluatorTest() { + super(); + + factory = new StreamFactory() + .withFunctionName("cbrt", CubedRootEvaluator.class); + values = new HashMap(); + } + + private void test(Double value) throws IOException{ + StreamEvaluator evaluator = factory.constructEvaluator("cbrt(a)"); + + values.clear(); + values.put("a", value); + Object result = evaluator.evaluate(new Tuple(values)); + + if(null == value){ + Assert.assertNull(result); + } + else{ + Assert.assertTrue(result instanceof Double); + Assert.assertEquals(Math.cbrt(value), result); + } + } + + @Test + public void oneField() throws Exception{ + test(90D); + test(45D); + test(12.4D); + test(-45D); + } + + @Test(expected = IOException.class) + public void noField() throws Exception{ + factory.constructEvaluator("cbrt()"); + } + + @Test(expected = IOException.class) + public void twoFields() throws Exception{ + factory.constructEvaluator("cbrt(a,b)"); + } + + @Test + public void noValue() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("cbrt(a)"); + + values.clear(); + Object result = evaluator.evaluate(new Tuple(values)); + assertNull(result); + } + @Test + public void nullValue() throws Exception{ + test(null); + } +} diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/FloorEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/FloorEvaluatorTest.java new file mode 100644 index 00000000000..0fbf16d909a --- /dev/null +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/FloorEvaluatorTest.java @@ -0,0 +1,96 @@ +/* + * 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.Map; + +import org.apache.lucene.util.LuceneTestCase; +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.eval.FloorEvaluator; +import org.apache.solr.client.solrj.io.eval.StreamEvaluator; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; +import org.junit.Test; + +import junit.framework.Assert; + +public class FloorEvaluatorTest extends LuceneTestCase { + + StreamFactory factory; + Map values; + + public FloorEvaluatorTest() { + super(); + + factory = new StreamFactory() + .withFunctionName("floor", FloorEvaluator.class); + values = new HashMap(); + } + + @Test + public void floorOneField() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("floor(a)"); + Object result; + + values.clear(); + values.put("a", 1); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertTrue(result instanceof Long); + Assert.assertEquals(1L, result); + + values.clear(); + values.put("a", 1.1); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertTrue(result instanceof Long); + Assert.assertEquals(1L, result); + + values.clear(); + values.put("a", -1.1); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertTrue(result instanceof Long); + Assert.assertEquals(-2L, result); + } + + @Test(expected = IOException.class) + public void floorNoField() throws Exception{ + factory.constructEvaluator("floor()"); + } + + @Test(expected = IOException.class) + public void floorTwoFields() throws Exception{ + factory.constructEvaluator("floor(a,b)"); + } + + @Test + public void floorNoValue() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("floor(a)"); + + values.clear(); + Object result = evaluator.evaluate(new Tuple(values)); + assertNull(result); + } + @Test + public void floorNullValue() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("floor(a)"); + + values.clear(); + values.put("a", null); + Object result = evaluator.evaluate(new Tuple(values)); + assertNull(result); + } +} diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/HyperbolicCosineEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/HyperbolicCosineEvaluatorTest.java new file mode 100644 index 00000000000..7847f30d846 --- /dev/null +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/HyperbolicCosineEvaluatorTest.java @@ -0,0 +1,91 @@ +/* + * 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.Map; + +import org.apache.lucene.util.LuceneTestCase; +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.eval.HyperbolicCosineEvaluator; +import org.apache.solr.client.solrj.io.eval.StreamEvaluator; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; +import org.junit.Test; + +import junit.framework.Assert; + +public class HyperbolicCosineEvaluatorTest extends LuceneTestCase { + + StreamFactory factory; + Map values; + + public HyperbolicCosineEvaluatorTest() { + super(); + + factory = new StreamFactory() + .withFunctionName("cosh", HyperbolicCosineEvaluator.class); + values = new HashMap(); + } + + private void test(Double value) throws IOException{ + StreamEvaluator evaluator = factory.constructEvaluator("cosh(a)"); + + values.clear(); + values.put("a", value); + Object result = evaluator.evaluate(new Tuple(values)); + + if(null == value){ + Assert.assertNull(result); + } + else{ + Assert.assertTrue(result instanceof Double); + Assert.assertEquals(Math.cosh(value), result); + } + } + + @Test + public void oneField() throws Exception{ + test(90D); + test(45D); + test(12.4D); + test(-45D); + } + + @Test(expected = IOException.class) + public void noField() throws Exception{ + factory.constructEvaluator("cosh()"); + } + + @Test(expected = IOException.class) + public void twoFields() throws Exception{ + factory.constructEvaluator("cosh(a,b)"); + } + + @Test + public void noValue() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("cosh(a)"); + + values.clear(); + Object result = evaluator.evaluate(new Tuple(values)); + assertNull(result); + } + @Test + public void nullValue() throws Exception{ + test(null); + } +} diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/HyperbolicSineEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/HyperbolicSineEvaluatorTest.java new file mode 100644 index 00000000000..22733cc9e1f --- /dev/null +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/HyperbolicSineEvaluatorTest.java @@ -0,0 +1,91 @@ +/* + * 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.Map; + +import org.apache.lucene.util.LuceneTestCase; +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.eval.HyperbolicSineEvaluator; +import org.apache.solr.client.solrj.io.eval.StreamEvaluator; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; +import org.junit.Test; + +import junit.framework.Assert; + +public class HyperbolicSineEvaluatorTest extends LuceneTestCase { + + StreamFactory factory; + Map values; + + public HyperbolicSineEvaluatorTest() { + super(); + + factory = new StreamFactory() + .withFunctionName("sinh", HyperbolicSineEvaluator.class); + values = new HashMap(); + } + + private void test(Double value) throws IOException{ + StreamEvaluator evaluator = factory.constructEvaluator("sinh(a)"); + + values.clear(); + values.put("a", value); + Object result = evaluator.evaluate(new Tuple(values)); + + if(null == value){ + Assert.assertNull(result); + } + else{ + Assert.assertTrue(result instanceof Double); + Assert.assertEquals(Math.sinh(value), result); + } + } + + @Test + public void oneField() throws Exception{ + test(90D); + test(45D); + test(12.4D); + test(-45D); + } + + @Test(expected = IOException.class) + public void noField() throws Exception{ + factory.constructEvaluator("sinh()"); + } + + @Test(expected = IOException.class) + public void twoFields() throws Exception{ + factory.constructEvaluator("sinh(a,b)"); + } + + @Test + public void noValue() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("sinh(a)"); + + values.clear(); + Object result = evaluator.evaluate(new Tuple(values)); + assertNull(result); + } + @Test + public void nullValue() throws Exception{ + test(null); + } +} diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/HyperbolicTangentEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/HyperbolicTangentEvaluatorTest.java new file mode 100644 index 00000000000..e526a086201 --- /dev/null +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/HyperbolicTangentEvaluatorTest.java @@ -0,0 +1,91 @@ +/* + * 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.Map; + +import org.apache.lucene.util.LuceneTestCase; +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.eval.HyperbolicTangentEvaluator; +import org.apache.solr.client.solrj.io.eval.StreamEvaluator; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; +import org.junit.Test; + +import junit.framework.Assert; + +public class HyperbolicTangentEvaluatorTest extends LuceneTestCase { + + StreamFactory factory; + Map values; + + public HyperbolicTangentEvaluatorTest() { + super(); + + factory = new StreamFactory() + .withFunctionName("tanh", HyperbolicTangentEvaluator.class); + values = new HashMap(); + } + + private void test(Double value) throws IOException{ + StreamEvaluator evaluator = factory.constructEvaluator("tanh(a)"); + + values.clear(); + values.put("a", value); + Object result = evaluator.evaluate(new Tuple(values)); + + if(null == value){ + Assert.assertNull(result); + } + else{ + Assert.assertTrue(result instanceof Double); + Assert.assertEquals(Math.tanh(value), result); + } + } + + @Test + public void oneField() throws Exception{ + test(90D); + test(45D); + test(12.4D); + test(-45D); + } + + @Test(expected = IOException.class) + public void noField() throws Exception{ + factory.constructEvaluator("tanh()"); + } + + @Test(expected = IOException.class) + public void twoFields() throws Exception{ + factory.constructEvaluator("tanh(a,b)"); + } + + @Test + public void noValue() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("tanh(a)"); + + values.clear(); + Object result = evaluator.evaluate(new Tuple(values)); + assertNull(result); + } + @Test + public void nullValue() throws Exception{ + test(null); + } +} diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ModuloEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ModuloEvaluatorTest.java new file mode 100644 index 00000000000..436763b931d --- /dev/null +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ModuloEvaluatorTest.java @@ -0,0 +1,164 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for multitional 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.Map; + +import org.apache.lucene.util.LuceneTestCase; +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.eval.ModuloEvaluator; +import org.apache.solr.client.solrj.io.eval.StreamEvaluator; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; +import org.junit.Test; + +import junit.framework.Assert; + +public class ModuloEvaluatorTest extends LuceneTestCase { + + StreamFactory factory; + Map values; + + public ModuloEvaluatorTest() { + super(); + + factory = new StreamFactory() + .withFunctionName("mod", ModuloEvaluator.class); + values = new HashMap(); + } + + @Test + public void modTwoFieldsWithValues() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("mod(a,b)"); + Object result; + + values.clear(); + values.put("a", 1); + values.put("b", 2); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertTrue(result instanceof Long); + Assert.assertEquals(Long.valueOf(1 % 2), result); + + values.clear(); + values.put("a", 1.1); + values.put("b", 2); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertTrue(result instanceof Double); + Assert.assertEquals(1.1 % 2, result); + + values.clear(); + values.put("a", 1.1); + values.put("b", 2.1); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertTrue(result instanceof Double); + Assert.assertEquals(1.1 % 2.1, result); + } + + @Test(expected = IOException.class) + public void modOneField() throws Exception{ + factory.constructEvaluator("mod(a)"); + } + + @Test(expected = IOException.class) + public void modTwoFieldWithNulls() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("mod(a,b)"); + + values.clear(); + evaluator.evaluate(new Tuple(values)); + } + + @Test(expected = IOException.class) + public void modTwoFieldsWithNullDenominator() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("mod(a,b)"); + + values.clear(); + values.put("a", 1); + evaluator.evaluate(new Tuple(values)); + } + + @Test(expected = IOException.class) + public void modTwoFieldsWithNullNumerator() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("mod(a,b)"); + + values.clear(); + values.put("b", 1); + evaluator.evaluate(new Tuple(values)); + } + + + @Test(expected = IOException.class) + public void modTwoFieldsWithMissingDenominator() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("mod(a,b)"); + + values.clear(); + values.put("a", 1); + evaluator.evaluate(new Tuple(values)); + } + + @Test(expected = IOException.class) + public void modTwoFieldsWithMissingNumerator() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("mod(a,b)"); + + values.clear(); + values.put("b", 1); + evaluator.evaluate(new Tuple(values)); + } + + + @Test(expected = IOException.class) + public void modManyFieldsWithValues() throws Exception{ + factory.constructEvaluator("mod(a,b,c,d)"); + } + + @Test + public void modManyFieldsWithSubmods() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("mod(a,mod(b,c))"); + Object result; + + values.clear(); + values.put("a", 1); + values.put("b", 2); + values.put("c", 9); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertTrue(result instanceof Long); + Assert.assertEquals(Long.valueOf(1 % (2 % 9)), result); + } + + @Test(expected = IOException.class) + public void modByZero() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("mod(a,b)"); + + values.clear(); + values.put("a", 1); + values.put("b", 0); + evaluator.evaluate(new Tuple(values)); + } + + @Test + public void modZeroByValue() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("mod(a,b)"); + Object result; + + values.clear(); + values.put("a", 0); + values.put("b", 2); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertTrue(result instanceof Long); + Assert.assertEquals(0L, result); + } +} diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/PowerEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/PowerEvaluatorTest.java new file mode 100644 index 00000000000..5efa7a4adf7 --- /dev/null +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/PowerEvaluatorTest.java @@ -0,0 +1,119 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for multitional 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.math.BigDecimal; +import java.util.HashMap; +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.PowerEvaluator; +import org.apache.solr.client.solrj.io.eval.StreamEvaluator; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; +import org.junit.Test; + +import junit.framework.Assert; + +public class PowerEvaluatorTest extends LuceneTestCase { + + StreamFactory factory; + Map values; + + public PowerEvaluatorTest() { + super(); + + factory = new StreamFactory() + .withFunctionName("pow", PowerEvaluator.class); + values = new HashMap(); + } + + @Test + public void powTwoFieldsWithValues() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("pow(a,b)"); + Object result; + + values.clear(); + values.put("a", 2); + values.put("b", 5); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertTrue(result instanceof Number); + Assert.assertEquals(BigDecimal.valueOf(Math.pow(2, 5)), BigDecimal.valueOf(result instanceof Long ? (long)result : (double)result)); + + values.clear(); + values.put("a", 1.1); + values.put("b", 2); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertTrue(result instanceof Number); + Assert.assertEquals(Math.pow(1.1, 2), result); + + values.clear(); + values.put("a", 1.1); + values.put("b", 2.1); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertTrue(result instanceof Number); + Assert.assertEquals(Math.pow(1.1, 2.1), result); + + values.clear(); + values.put("a", -1.1); + values.put("b", 2.1); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertTrue(Double.isNaN((double)result)); + + values.clear(); + values.put("a", 1.1); + values.put("b", -2.1); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertTrue(result instanceof Number); + Assert.assertEquals(Math.pow(1.1, -2.1), result); + + values.clear(); + values.put("a", -1.1); + values.put("b", -2.1); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertTrue(Double.isNaN((double)result)); + } + + @Test(expected = IOException.class) + public void powOneField() throws Exception{ + factory.constructEvaluator("pow(a)"); + } + + @Test + public void powTwoFieldWithNulls() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("pow(a,b)"); + + values.clear(); + Assert.assertNull(evaluator.evaluate(new Tuple(values))); + } + + @Test + public void powManyFieldsWithSubpows() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("pow(a,pow(b,c))"); + Object result; + + values.clear(); + values.put("a", 8); + values.put("b", 2); + values.put("c", 3); + result = evaluator.evaluate(new Tuple(values)); + Assert.assertTrue(result instanceof Number); + Assert.assertEquals(BigDecimal.valueOf(Math.pow(8, Math.pow(2, 3))), BigDecimal.valueOf(result instanceof Long ? (long)result : (double)result)); + } + +} diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/RoundEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/RoundEvaluatorTest.java new file mode 100644 index 00000000000..8851b3c621c --- /dev/null +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/RoundEvaluatorTest.java @@ -0,0 +1,95 @@ +/* + * 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.Map; + +import org.apache.lucene.util.LuceneTestCase; +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.eval.RoundEvaluator; +import org.apache.solr.client.solrj.io.eval.StreamEvaluator; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; +import org.junit.Test; + +import junit.framework.Assert; + +public class RoundEvaluatorTest extends LuceneTestCase { + + StreamFactory factory; + Map values; + + public RoundEvaluatorTest() { + super(); + + factory = new StreamFactory() + .withFunctionName("round", RoundEvaluator.class); + values = new HashMap(); + } + + private void test(Double value) throws IOException{ + StreamEvaluator evaluator = factory.constructEvaluator("round(a)"); + + values.clear(); + values.put("a", value); + Object result = evaluator.evaluate(new Tuple(values)); + + if(null == value){ + Assert.assertNull(result); + } + else{ + Assert.assertTrue(result instanceof Long); + Assert.assertEquals(Math.round(value), result); + } + } + + @Test + public void oneField() throws Exception{ + test(90D); + test(45.555555D); + test(12.4D); + test(-.4D); + test(-0D); + test(-0.0235D); + test(-12.44444446D); + test(-45.23D); + } + + @Test(expected = IOException.class) + public void noField() throws Exception{ + factory.constructEvaluator("round()"); + } + + @Test(expected = IOException.class) + public void twoFields() throws Exception{ + factory.constructEvaluator("round(a,b)"); + } + + @Test + public void noValue() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("round(a)"); + + values.clear(); + Object result = evaluator.evaluate(new Tuple(values)); + assertNull(result); + } + @Test + public void nullValue() throws Exception{ + test(null); + } +} diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/SineEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/SineEvaluatorTest.java new file mode 100644 index 00000000000..8f8a9eb9e88 --- /dev/null +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/SineEvaluatorTest.java @@ -0,0 +1,91 @@ +/* + * 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.Map; + +import org.apache.lucene.util.LuceneTestCase; +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.eval.SineEvaluator; +import org.apache.solr.client.solrj.io.eval.StreamEvaluator; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; +import org.junit.Test; + +import junit.framework.Assert; + +public class SineEvaluatorTest extends LuceneTestCase { + + StreamFactory factory; + Map values; + + public SineEvaluatorTest() { + super(); + + factory = new StreamFactory() + .withFunctionName("sin", SineEvaluator.class); + values = new HashMap(); + } + + private void test(Double value) throws IOException{ + StreamEvaluator evaluator = factory.constructEvaluator("sin(a)"); + + values.clear(); + values.put("a", value); + Object result = evaluator.evaluate(new Tuple(values)); + + if(null == value){ + Assert.assertNull(result); + } + else{ + Assert.assertTrue(result instanceof Double); + Assert.assertEquals(Math.sin(value), result); + } + } + + @Test + public void oneField() throws Exception{ + test(90D); + test(45D); + test(12.4D); + test(-45D); + } + + @Test(expected = IOException.class) + public void noField() throws Exception{ + factory.constructEvaluator("sin()"); + } + + @Test(expected = IOException.class) + public void twoFields() throws Exception{ + factory.constructEvaluator("sin(a,b)"); + } + + @Test + public void noValue() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("sin(a)"); + + values.clear(); + Object result = evaluator.evaluate(new Tuple(values)); + assertNull(result); + } + @Test + public void nullValue() throws Exception{ + test(null); + } +} diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/SquareRootEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/SquareRootEvaluatorTest.java new file mode 100644 index 00000000000..733a8f7701d --- /dev/null +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/SquareRootEvaluatorTest.java @@ -0,0 +1,91 @@ +/* + * 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.Map; + +import org.apache.lucene.util.LuceneTestCase; +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.eval.SquareRootEvaluator; +import org.apache.solr.client.solrj.io.eval.StreamEvaluator; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; +import org.junit.Test; + +import junit.framework.Assert; + +public class SquareRootEvaluatorTest extends LuceneTestCase { + + StreamFactory factory; + Map values; + + public SquareRootEvaluatorTest() { + super(); + + factory = new StreamFactory() + .withFunctionName("sqrt", SquareRootEvaluator.class); + values = new HashMap(); + } + + private void test(Double value) throws IOException{ + StreamEvaluator evaluator = factory.constructEvaluator("sqrt(a)"); + + values.clear(); + values.put("a", value); + Object result = evaluator.evaluate(new Tuple(values)); + + if(null == value){ + Assert.assertNull(result); + } + else{ + Assert.assertTrue(result instanceof Double); + Assert.assertEquals(Math.sqrt(value), result); + } + } + + @Test + public void oneField() throws Exception{ + test(90D); + test(45D); + test(12.4D); + test(-45D); + } + + @Test(expected = IOException.class) + public void noField() throws Exception{ + factory.constructEvaluator("sqrt()"); + } + + @Test(expected = IOException.class) + public void twoFields() throws Exception{ + factory.constructEvaluator("sqrt(a,b)"); + } + + @Test + public void noValue() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("sqrt(a)"); + + values.clear(); + Object result = evaluator.evaluate(new Tuple(values)); + assertNull(result); + } + @Test + public void nullValue() throws Exception{ + test(null); + } +} diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/TangentEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/TangentEvaluatorTest.java new file mode 100644 index 00000000000..ab0fbef09d3 --- /dev/null +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/TangentEvaluatorTest.java @@ -0,0 +1,91 @@ +/* + * 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.Map; + +import org.apache.lucene.util.LuceneTestCase; +import org.apache.solr.client.solrj.io.Tuple; +import org.apache.solr.client.solrj.io.eval.StreamEvaluator; +import org.apache.solr.client.solrj.io.eval.TangentEvaluator; +import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; +import org.junit.Test; + +import junit.framework.Assert; + +public class TangentEvaluatorTest extends LuceneTestCase { + + StreamFactory factory; + Map values; + + public TangentEvaluatorTest() { + super(); + + factory = new StreamFactory() + .withFunctionName("tan", TangentEvaluator.class); + values = new HashMap(); + } + + private void test(Double value) throws IOException{ + StreamEvaluator evaluator = factory.constructEvaluator("tan(a)"); + + values.clear(); + values.put("a", value); + Object result = evaluator.evaluate(new Tuple(values)); + + if(null == value){ + Assert.assertNull(result); + } + else{ + Assert.assertTrue(result instanceof Double); + Assert.assertEquals(Math.tan(value), result); + } + } + + @Test + public void oneField() throws Exception{ + test(90D); + test(45D); + test(12.4D); + test(-45D); + } + + @Test(expected = IOException.class) + public void noField() throws Exception{ + factory.constructEvaluator("tan()"); + } + + @Test(expected = IOException.class) + public void twoFields() throws Exception{ + factory.constructEvaluator("tan(a,b)"); + } + + @Test + public void noValue() throws Exception{ + StreamEvaluator evaluator = factory.constructEvaluator("tan(a)"); + + values.clear(); + Object result = evaluator.evaluate(new Tuple(values)); + assertNull(result); + } + @Test + public void nullValue() throws Exception{ + test(null); + } +}