From 2206491277c44fc7f3b0ba42779c999627dfdc19 Mon Sep 17 00:00:00 2001 From: Marios Trivyzas Date: Mon, 8 Apr 2019 16:43:36 +0200 Subject: [PATCH] SQL: Refactor args verification of In & conditionals (#40916) Move verification of arguments for Conditional functions and IN from `Verifier` to the `resolveType()` method of the functions. (cherry picked from commit 241644aac57baee1eb128b993ee410c7d08172a5) --- .../xpack/sql/analysis/analyzer/Verifier.java | 53 ----- .../expression/function/FunctionRegistry.java | 48 ++--- .../ArbitraryConditionalFunction.java | 9 - .../conditional/ConditionalFunction.java | 30 +++ .../predicate/conditional/NullIf.java | 6 - .../predicate/operator/comparison/In.java | 18 +- .../xpack/sql/type/DataTypes.java | 11 + .../xpack/sql/util/StringUtils.java | 24 ++- .../analyzer/VerifierErrorMessagesTests.java | 67 +----- .../function/FunctionRegistryTests.java | 6 +- .../xpack/sql/optimizer/OptimizerTests.java | 193 +++++++++--------- 11 files changed, 212 insertions(+), 253 deletions(-) diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/analysis/analyzer/Verifier.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/analysis/analyzer/Verifier.java index bade2d44c8a..db84a444f57 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/analysis/analyzer/Verifier.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/analysis/analyzer/Verifier.java @@ -26,8 +26,6 @@ import org.elasticsearch.xpack.sql.expression.function.aggregate.TopHits; import org.elasticsearch.xpack.sql.expression.function.grouping.GroupingFunction; import org.elasticsearch.xpack.sql.expression.function.grouping.GroupingFunctionAttribute; import org.elasticsearch.xpack.sql.expression.function.scalar.ScalarFunction; -import org.elasticsearch.xpack.sql.expression.predicate.conditional.ConditionalFunction; -import org.elasticsearch.xpack.sql.expression.predicate.operator.comparison.In; import org.elasticsearch.xpack.sql.plan.logical.Aggregate; import org.elasticsearch.xpack.sql.plan.logical.Distinct; import org.elasticsearch.xpack.sql.plan.logical.Filter; @@ -228,9 +226,6 @@ public final class Verifier { Set localFailures = new LinkedHashSet<>(); - validateInExpression(p, localFailures); - validateConditional(p, localFailures); - checkGroupingFunctionInGroupBy(p, localFailures); checkFilterOnAggs(p, localFailures); checkFilterOnGrouping(p, localFailures); @@ -724,52 +719,4 @@ public final class Verifier { fail(nested.get(0), "HAVING isn't (yet) compatible with nested fields " + new AttributeSet(nested).names())); } } - - private static void validateInExpression(LogicalPlan p, Set localFailures) { - p.forEachExpressions(e -> - e.forEachUp((In in) -> { - DataType dt = in.value().dataType(); - for (Expression value : in.list()) { - if (areTypesCompatible(dt, value.dataType()) == false) { - localFailures.add(fail(value, "expected data type [{}], value provided is of type [{}]", - dt.typeName, value.dataType().typeName)); - return; - } - } - }, - In.class)); - } - - private static void validateConditional(LogicalPlan p, Set localFailures) { - p.forEachExpressions(e -> - e.forEachUp((ConditionalFunction cf) -> { - DataType dt = DataType.NULL; - - for (Expression child : cf.children()) { - if (dt == DataType.NULL) { - if (Expressions.isNull(child) == false) { - dt = child.dataType(); - } - } else { - if (areTypesCompatible(dt, child.dataType()) == false) { - localFailures.add(fail(child, "expected data type [{}], value provided is of type [{}]", - dt.typeName, child.dataType().typeName)); - return; - } - } - } - }, - ConditionalFunction.class)); - } - - private static boolean areTypesCompatible(DataType left, DataType right) { - if (left == right) { - return true; - } else { - return - (left == DataType.NULL || right == DataType.NULL) || - (left.isString() && right.isString()) || - (left.isNumeric() && right.isNumeric()); - } - } } diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/FunctionRegistry.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/FunctionRegistry.java index 1e22be34661..a29b19e4128 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/FunctionRegistry.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/FunctionRegistry.java @@ -262,7 +262,7 @@ public class FunctionRegistry { for (String alias : f.aliases()) { Object old = batchMap.put(alias, f); if (old != null || defs.containsKey(alias)) { - throw new IllegalArgumentException("alias [" + alias + "] is used by " + throw new SqlIllegalArgumentException("alias [" + alias + "] is used by " + "[" + (old != null ? old : defs.get(alias).name()) + "] and [" + f.name() + "]"); } aliases.put(alias, f.name()); @@ -321,10 +321,10 @@ public class FunctionRegistry { java.util.function.Function ctorRef, String... names) { FunctionBuilder builder = (source, children, distinct, cfg) -> { if (false == children.isEmpty()) { - throw new IllegalArgumentException("expects no arguments"); + throw new SqlIllegalArgumentException("expects no arguments"); } if (distinct) { - throw new IllegalArgumentException("does not support DISTINCT yet it was specified"); + throw new SqlIllegalArgumentException("does not support DISTINCT yet it was specified"); } return ctorRef.apply(source); }; @@ -341,10 +341,10 @@ public class FunctionRegistry { ConfigurationAwareFunctionBuilder ctorRef, String... names) { FunctionBuilder builder = (source, children, distinct, cfg) -> { if (false == children.isEmpty()) { - throw new IllegalArgumentException("expects no arguments"); + throw new SqlIllegalArgumentException("expects no arguments"); } if (distinct) { - throw new IllegalArgumentException("does not support DISTINCT yet it was specified"); + throw new SqlIllegalArgumentException("does not support DISTINCT yet it was specified"); } return ctorRef.build(source, cfg); }; @@ -365,10 +365,10 @@ public class FunctionRegistry { UnaryConfigurationAwareFunctionBuilder ctorRef, String... names) { FunctionBuilder builder = (source, children, distinct, cfg) -> { if (children.size() > 1) { - throw new IllegalArgumentException("expects exactly one argument"); + throw new SqlIllegalArgumentException("expects exactly one argument"); } if (distinct) { - throw new IllegalArgumentException("does not support DISTINCT yet it was specified"); + throw new SqlIllegalArgumentException("does not support DISTINCT yet it was specified"); } Expression ex = children.size() == 1 ? children.get(0) : null; return ctorRef.build(source, ex, cfg); @@ -390,10 +390,10 @@ public class FunctionRegistry { BiFunction ctorRef, String... names) { FunctionBuilder builder = (source, children, distinct, cfg) -> { if (children.size() != 1) { - throw new IllegalArgumentException("expects exactly one argument"); + throw new SqlIllegalArgumentException("expects exactly one argument"); } if (distinct) { - throw new IllegalArgumentException("does not support DISTINCT yet it was specified"); + throw new SqlIllegalArgumentException("does not support DISTINCT yet it was specified"); } return ctorRef.apply(source, children.get(0)); }; @@ -409,7 +409,7 @@ public class FunctionRegistry { MultiFunctionBuilder ctorRef, String... names) { FunctionBuilder builder = (source, children, distinct, cfg) -> { if (distinct) { - throw new IllegalArgumentException("does not support DISTINCT yet it was specified"); + throw new SqlIllegalArgumentException("does not support DISTINCT yet it was specified"); } return ctorRef.build(source, children); }; @@ -429,7 +429,7 @@ public class FunctionRegistry { DistinctAwareUnaryFunctionBuilder ctorRef, String... names) { FunctionBuilder builder = (source, children, distinct, cfg) -> { if (children.size() != 1) { - throw new IllegalArgumentException("expects exactly one argument"); + throw new SqlIllegalArgumentException("expects exactly one argument"); } return ctorRef.build(source, children.get(0), distinct); }; @@ -449,10 +449,10 @@ public class FunctionRegistry { DatetimeUnaryFunctionBuilder ctorRef, String... names) { FunctionBuilder builder = (source, children, distinct, cfg) -> { if (children.size() != 1) { - throw new IllegalArgumentException("expects exactly one argument"); + throw new SqlIllegalArgumentException("expects exactly one argument"); } if (distinct) { - throw new IllegalArgumentException("does not support DISTINCT yet it was specified"); + throw new SqlIllegalArgumentException("does not support DISTINCT yet it was specified"); } return ctorRef.build(source, children.get(0), cfg.zoneId()); }; @@ -471,10 +471,10 @@ public class FunctionRegistry { static FunctionDefinition def(Class function, DatetimeBinaryFunctionBuilder ctorRef, String... names) { FunctionBuilder builder = (source, children, distinct, cfg) -> { if (children.size() != 2) { - throw new IllegalArgumentException("expects exactly two arguments"); + throw new SqlIllegalArgumentException("expects exactly two arguments"); } if (distinct) { - throw new IllegalArgumentException("does not support DISTINCT yet it was specified"); + throw new SqlIllegalArgumentException("does not support DISTINCT yet it was specified"); } return ctorRef.build(source, children.get(0), children.get(1), cfg.zoneId()); }; @@ -496,13 +496,13 @@ public class FunctionRegistry { boolean isBinaryOptionalParamFunction = function.isAssignableFrom(Round.class) || function.isAssignableFrom(Truncate.class) || TopHits.class.isAssignableFrom(function); if (isBinaryOptionalParamFunction && (children.size() > 2 || children.size() < 1)) { - throw new IllegalArgumentException("expects one or two arguments"); + throw new SqlIllegalArgumentException("expects one or two arguments"); } else if (!isBinaryOptionalParamFunction && children.size() != 2) { - throw new IllegalArgumentException("expects exactly two arguments"); + throw new SqlIllegalArgumentException("expects exactly two arguments"); } if (distinct) { - throw new IllegalArgumentException("does not support DISTINCT yet it was specified"); + throw new SqlIllegalArgumentException("does not support DISTINCT yet it was specified"); } return ctorRef.build(source, children.get(0), children.size() == 2 ? children.get(1) : null); }; @@ -527,7 +527,7 @@ public class FunctionRegistry { FunctionDefinition.Builder realBuilder = (uf, distinct, cfg) -> { try { return builder.build(uf.source(), uf.children(), distinct, cfg); - } catch (IllegalArgumentException e) { + } catch (SqlIllegalArgumentException e) { throw new ParsingException(uf.source(), "error building [" + primaryName + "]: " + e.getMessage(), e); } }; @@ -544,12 +544,12 @@ public class FunctionRegistry { FunctionBuilder builder = (source, children, distinct, cfg) -> { boolean isLocateFunction = function.isAssignableFrom(Locate.class); if (isLocateFunction && (children.size() > 3 || children.size() < 2)) { - throw new IllegalArgumentException("expects two or three arguments"); + throw new SqlIllegalArgumentException("expects two or three arguments"); } else if (!isLocateFunction && children.size() != 3) { - throw new IllegalArgumentException("expects exactly three arguments"); + throw new SqlIllegalArgumentException("expects exactly three arguments"); } if (distinct) { - throw new IllegalArgumentException("does not support DISTINCT yet it was specified"); + throw new SqlIllegalArgumentException("does not support DISTINCT yet it was specified"); } return ctorRef.build(source, children.get(0), children.get(1), children.size() == 3 ? children.get(2) : null); }; @@ -565,10 +565,10 @@ public class FunctionRegistry { FourParametersFunctionBuilder ctorRef, String... names) { FunctionBuilder builder = (source, children, distinct, cfg) -> { if (children.size() != 4) { - throw new IllegalArgumentException("expects exactly four arguments"); + throw new SqlIllegalArgumentException("expects exactly four arguments"); } if (distinct) { - throw new IllegalArgumentException("does not support DISTINCT yet it was specified"); + throw new SqlIllegalArgumentException("does not support DISTINCT yet it was specified"); } return ctorRef.build(source, children.get(0), children.get(1), children.get(2), children.get(3)); }; diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/ArbitraryConditionalFunction.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/ArbitraryConditionalFunction.java index ecc5835d1aa..b2bea979acd 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/ArbitraryConditionalFunction.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/ArbitraryConditionalFunction.java @@ -13,7 +13,6 @@ import org.elasticsearch.xpack.sql.expression.gen.script.ParamsBuilder; import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate; import org.elasticsearch.xpack.sql.expression.predicate.conditional.ConditionalProcessor.ConditionalOperation; import org.elasticsearch.xpack.sql.tree.Source; -import org.elasticsearch.xpack.sql.type.DataTypeConversion; import java.util.ArrayList; import java.util.List; @@ -33,14 +32,6 @@ public abstract class ArbitraryConditionalFunction extends ConditionalFunction { this.operation = operation; } - @Override - protected TypeResolution resolveType() { - for (Expression e : children()) { - dataType = DataTypeConversion.commonType(dataType, e.dataType()); - } - return TypeResolution.TYPE_RESOLVED; - } - @Override protected Pipe makePipe() { return new ConditionalPipe(source(), this, Expressions.pipe(children()), operation); diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/ConditionalFunction.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/ConditionalFunction.java index 13b765e941c..3de85185e8a 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/ConditionalFunction.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/ConditionalFunction.java @@ -12,9 +12,14 @@ import org.elasticsearch.xpack.sql.expression.Nullability; import org.elasticsearch.xpack.sql.expression.function.scalar.ScalarFunction; import org.elasticsearch.xpack.sql.tree.Source; import org.elasticsearch.xpack.sql.type.DataType; +import org.elasticsearch.xpack.sql.type.DataTypeConversion; import java.util.List; +import static org.elasticsearch.common.logging.LoggerMessageFormat.format; +import static org.elasticsearch.xpack.sql.type.DataTypes.areTypesCompatible; +import static org.elasticsearch.xpack.sql.util.StringUtils.ordinal; + /** * Base class for conditional predicates. */ @@ -36,6 +41,31 @@ public abstract class ConditionalFunction extends ScalarFunction { return Expressions.foldable(children()); } + @Override + protected TypeResolution resolveType() { + DataType dt = DataType.NULL; + + for (int i = 0; i < children().size(); i++) { + Expression child = children().get(i); + if (dt == DataType.NULL) { + if (Expressions.isNull(child) == false) { + dt = child.dataType(); + } + } else { + if (areTypesCompatible(dt, child.dataType()) == false) { + return new TypeResolution(format(null, "{} argument of [{}] must be [{}], found value [{}] type [{}]", + ordinal(i + 1), + sourceText(), + dt.typeName, + Expressions.name(child), + child.dataType().typeName)); + } + } + dataType = DataTypeConversion.commonType(dataType, child.dataType()); + } + return TypeResolution.TYPE_RESOLVED; + } + @Override public Nullability nullable() { return Nullability.UNKNOWN; diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/NullIf.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/NullIf.java index dac5add1792..50692edb40e 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/NullIf.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/NullIf.java @@ -39,12 +39,6 @@ public class NullIf extends ConditionalFunction { return new NullIf(source(), newChildren.get(0), newChildren.get(1)); } - @Override - protected TypeResolution resolveType() { - dataType = children().get(0).dataType(); - return TypeResolution.TYPE_RESOLVED; - } - @Override public Object fold() { return NullIfProcessor.apply(children().get(0).fold(), children().get(1).fold()); diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/operator/comparison/In.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/operator/comparison/In.java index e687c9ac1ba..342407c21b3 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/operator/comparison/In.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/operator/comparison/In.java @@ -26,6 +26,8 @@ import java.util.stream.Collectors; import static org.elasticsearch.common.logging.LoggerMessageFormat.format; import static org.elasticsearch.xpack.sql.expression.gen.script.ParamsBuilder.paramsBuilder; +import static org.elasticsearch.xpack.sql.type.DataTypes.areTypesCompatible; +import static org.elasticsearch.xpack.sql.util.StringUtils.ordinal; public class In extends ScalarFunction { @@ -109,7 +111,7 @@ public class In extends ScalarFunction { @Override protected TypeResolution resolveType() { TypeResolution resolution = TypeResolutions.isExact(value, functionName(), Expressions.ParamOrdinal.DEFAULT); - if (resolution != TypeResolution.TYPE_RESOLVED) { + if (resolution.unresolved()) { return resolution; } @@ -120,6 +122,20 @@ public class In extends ScalarFunction { name())); } } + + DataType dt = value.dataType(); + for (int i = 0; i < list.size(); i++) { + Expression listValue = list.get(i); + if (areTypesCompatible(dt, listValue.dataType()) == false) { + return new TypeResolution(format(null, "{} argument of [{}] must be [{}], found value [{}] type [{}]", + ordinal(i + 1), + sourceText(), + dt.typeName, + Expressions.name(listValue), + listValue.dataType().typeName)); + } + } + return super.resolveType(); } diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/type/DataTypes.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/type/DataTypes.java index c74f6397452..dcd6a1b35a1 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/type/DataTypes.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/type/DataTypes.java @@ -230,4 +230,15 @@ public final class DataTypes { } return t.displaySize; } + + public static boolean areTypesCompatible(DataType left, DataType right) { + if (left == right) { + return true; + } else { + return + (left == DataType.NULL || right == DataType.NULL) || + (left.isString() && right.isString()) || + (left.isNumeric() && right.isNumeric()); + } + } } diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/util/StringUtils.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/util/StringUtils.java index 10066e77649..d2e8d3badf6 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/util/StringUtils.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/util/StringUtils.java @@ -23,12 +23,16 @@ import java.util.Locale; import static java.util.stream.Collectors.toList; -public abstract class StringUtils { +public final class StringUtils { + + private StringUtils() {} public static final String EMPTY = ""; public static final String NEW_LINE = "\n"; public static final String SQL_WILDCARD = "%"; + private static final String[] INTEGER_ORDINALS = new String[] { "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th" }; + //CamelCase to camel_case public static String camelCaseToUnderscore(String string) { if (!Strings.hasText(string)) { @@ -86,10 +90,6 @@ public abstract class StringUtils { return sb.toString(); } - public static String nullAsEmpty(String string) { - return string == null ? EMPTY : string; - } - // % -> .* // _ -> . // escape character - can be 0 (in which case every regex gets escaped) or @@ -297,4 +297,16 @@ public abstract class StringUtils { throw new SqlIllegalArgumentException("Cannot parse number [{}]", string); } } -} \ No newline at end of file + + public static String ordinal(int i) { + switch (i % 100) { + case 11: + case 12: + case 13: + return i + "th"; + default: + return i + INTEGER_ORDINALS[i % 10]; + + } + } +} diff --git a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/analysis/analyzer/VerifierErrorMessagesTests.java b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/analysis/analyzer/VerifierErrorMessagesTests.java index 3b1e8da318f..c2310aa331e 100644 --- a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/analysis/analyzer/VerifierErrorMessagesTests.java +++ b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/analysis/analyzer/VerifierErrorMessagesTests.java @@ -420,46 +420,16 @@ public class VerifierErrorMessagesTests extends ESTestCase { error("SELECT int FROM test GROUP BY int HAVING 2 < ABS(int)")); } - public void testInWithDifferentDataTypes_SelectClause() { - assertEquals("1:17: expected data type [integer], value provided is of type [keyword]", + public void testInWithDifferentDataTypes() { + assertEquals("1:8: 2nd argument of [1 IN (2, '3', 4)] must be [integer], found value ['3'] type [keyword]", error("SELECT 1 IN (2, '3', 4)")); } - public void testInNestedWithDifferentDataTypes_SelectClause() { - assertEquals("1:27: expected data type [integer], value provided is of type [keyword]", - error("SELECT 1 = 1 OR 1 IN (2, '3', 4)")); - } - - public void testInWithDifferentDataTypesFromLeftValue_SelectClause() { - assertEquals("1:14: expected data type [integer], value provided is of type [keyword]", + public void testInWithDifferentDataTypesFromLeftValue() { + assertEquals("1:8: 1st argument of [1 IN ('foo', 'bar')] must be [integer], found value ['foo'] type [keyword]", error("SELECT 1 IN ('foo', 'bar')")); } - public void testInNestedWithDifferentDataTypesFromLeftValue_SelectClause() { - assertEquals("1:29: expected data type [keyword], value provided is of type [integer]", - error("SELECT 1 = 1 OR 'foo' IN (2, 3)")); - } - - public void testInWithDifferentDataTypes_WhereClause() { - assertEquals("1:52: expected data type [keyword], value provided is of type [integer]", - error("SELECT * FROM test WHERE keyword IN ('foo', 'bar', 4)")); - } - - public void testInNestedWithDifferentDataTypes_WhereClause() { - assertEquals("1:63: expected data type [keyword], value provided is of type [integer]", - error("SELECT * FROM test WHERE int = 1 OR keyword IN ('foo', 'bar', 2)")); - } - - public void testInWithDifferentDataTypesFromLeftValue_WhereClause() { - assertEquals("1:38: expected data type [keyword], value provided is of type [integer]", - error("SELECT * FROM test WHERE keyword IN (1, 2)")); - } - - public void testInNestedWithDifferentDataTypesFromLeftValue_WhereClause() { - assertEquals("1:49: expected data type [keyword], value provided is of type [integer]", - error("SELECT * FROM test WHERE int = 1 OR keyword IN (1, 2)")); - } - public void testInWithFieldInListOfValues() { assertEquals("1:26: Comparisons against variables are not (currently) supported; offender [int] in [int IN (1, int)]", error("SELECT * FROM test WHERE int IN (1, int)")); @@ -615,32 +585,17 @@ public class VerifierErrorMessagesTests extends ESTestCase { incompatibleError("SELECT languages FROM \"*\" ORDER BY SIGN(ABS(emp_no))")); } - public void testConditionalWithDifferentDataTypes_SelectClause() { + public void testConditionalWithDifferentDataTypes() { @SuppressWarnings("unchecked") String function = randomFrom(IfNull.class, NullIf.class).getSimpleName(); - assertEquals("1:" + (22 + function.length()) + - ": expected data type [integer], value provided is of type [keyword]", - error("SELECT 1 = 1 OR " + function + "(3, '4') > 1")); + assertEquals("1:17: 2nd argument of [" + function + "(3, '4')] must be [integer], found value ['4'] type [keyword]", + error("SELECT 1 = 1 OR " + function + "(3, '4') > 1")); @SuppressWarnings("unchecked") - String arbirtraryArgsfunction = randomFrom(Coalesce.class, Greatest.class, Least.class).getSimpleName(); - assertEquals("1:" + (34 + arbirtraryArgsfunction.length()) + - ": expected data type [integer], value provided is of type [keyword]", - error("SELECT 1 = 1 OR " + arbirtraryArgsfunction + "(null, null, 3, '4') > 1")); - } - - public void testConditionalWithDifferentDataTypes_WhereClause() { - @SuppressWarnings("unchecked") - String function = randomFrom(IfNull.class, NullIf.class).getSimpleName(); - assertEquals("1:" + (34 + function.length()) + - ": expected data type [keyword], value provided is of type [integer]", - error("SELECT * FROM test WHERE " + function + "('foo', 4) > 1")); - - @SuppressWarnings("unchecked") - String arbirtraryArgsfunction = randomFrom(Coalesce.class, Greatest.class, Least.class).getSimpleName(); - assertEquals("1:" + (46 + arbirtraryArgsfunction.length()) + - ": expected data type [keyword], value provided is of type [integer]", - error("SELECT * FROM test WHERE " + arbirtraryArgsfunction + "(null, null, 'foo', 4) > 1")); + String arbirtraryArgsFunction = randomFrom(Coalesce.class, Greatest.class, Least.class).getSimpleName(); + assertEquals("1:17: 3rd argument of [" + arbirtraryArgsFunction + "(null, 3, '4')] must be [integer], " + + "found value ['4'] type [keyword]", + error("SELECT 1 = 1 OR " + arbirtraryArgsFunction + "(null, 3, '4') > 1")); } public void testAggsInWhere() { diff --git a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/expression/function/FunctionRegistryTests.java b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/expression/function/FunctionRegistryTests.java index a810dac501e..56767d7e319 100644 --- a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/expression/function/FunctionRegistryTests.java +++ b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/expression/function/FunctionRegistryTests.java @@ -165,13 +165,13 @@ public class FunctionRegistryTests extends ESTestCase { public void testAliasNameIsTheSameAsAFunctionName() { FunctionRegistry r = new FunctionRegistry(def(DummyFunction.class, DummyFunction::new, "DUMMY_FUNCTION", "ALIAS")); - IllegalArgumentException iae = expectThrows(IllegalArgumentException.class, () -> + SqlIllegalArgumentException iae = expectThrows(SqlIllegalArgumentException.class, () -> r.addToMap(def(DummyFunction2.class, DummyFunction2::new, "DUMMY_FUNCTION2", "DUMMY_FUNCTION"))); assertEquals("alias [DUMMY_FUNCTION] is used by [DUMMY_FUNCTION] and [DUMMY_FUNCTION2]", iae.getMessage()); } public void testDuplicateAliasInTwoDifferentFunctionsFromTheSameBatch() { - IllegalArgumentException iae = expectThrows(IllegalArgumentException.class, () -> + SqlIllegalArgumentException iae = expectThrows(SqlIllegalArgumentException.class, () -> new FunctionRegistry(def(DummyFunction.class, DummyFunction::new, "DUMMY_FUNCTION", "ALIAS"), def(DummyFunction2.class, DummyFunction2::new, "DUMMY_FUNCTION2", "ALIAS"))); assertEquals("alias [ALIAS] is used by [DUMMY_FUNCTION(ALIAS)] and [DUMMY_FUNCTION2]", iae.getMessage()); @@ -179,7 +179,7 @@ public class FunctionRegistryTests extends ESTestCase { public void testDuplicateAliasInTwoDifferentFunctionsFromTwoDifferentBatches() { FunctionRegistry r = new FunctionRegistry(def(DummyFunction.class, DummyFunction::new, "DUMMY_FUNCTION", "ALIAS")); - IllegalArgumentException iae = expectThrows(IllegalArgumentException.class, () -> + SqlIllegalArgumentException iae = expectThrows(SqlIllegalArgumentException.class, () -> r.addToMap(def(DummyFunction2.class, DummyFunction2::new, "DUMMY_FUNCTION2", "ALIAS"))); assertEquals("alias [ALIAS] is used by [DUMMY_FUNCTION] and [DUMMY_FUNCTION2]", iae.getMessage()); } diff --git a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/optimizer/OptimizerTests.java b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/optimizer/OptimizerTests.java index 8e4c9c7dd59..a23d88b5956 100644 --- a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/optimizer/OptimizerTests.java +++ b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/optimizer/OptimizerTests.java @@ -108,7 +108,10 @@ import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static java.util.Collections.emptyMap; import static java.util.Collections.singletonList; +import static org.elasticsearch.xpack.sql.expression.Literal.FALSE; import static org.elasticsearch.xpack.sql.expression.Literal.NULL; +import static org.elasticsearch.xpack.sql.expression.Literal.TRUE; +import static org.elasticsearch.xpack.sql.expression.Literal.of; import static org.elasticsearch.xpack.sql.tree.Source.EMPTY; import static org.elasticsearch.xpack.sql.util.DateUtils.UTC; import static org.hamcrest.Matchers.contains; @@ -174,7 +177,7 @@ public class OptimizerTests extends ESTestCase { } private static Literal L(Object value) { - return Literal.of(EMPTY, value); + return of(EMPTY, value); } private static FieldAttribute getFieldAttribute() { @@ -190,8 +193,8 @@ public class OptimizerTests extends ESTestCase { } public void testDuplicateFunctions() { - AggregateFunction f1 = new Count(EMPTY, Literal.TRUE, false); - AggregateFunction f2 = new Count(EMPTY, Literal.TRUE, false); + AggregateFunction f1 = new Count(EMPTY, TRUE, false); + AggregateFunction f2 = new Count(EMPTY, TRUE, false); assertTrue(f1.functionEquals(f2)); @@ -284,34 +287,34 @@ public class OptimizerTests extends ESTestCase { } public void testConstantFoldingBinaryComparison() { - assertEquals(Literal.FALSE, new ConstantFolding().rule(new GreaterThan(EMPTY, TWO, THREE)).canonical()); - assertEquals(Literal.FALSE, new ConstantFolding().rule(new GreaterThanOrEqual(EMPTY, TWO, THREE)).canonical()); - assertEquals(Literal.FALSE, new ConstantFolding().rule(new Equals(EMPTY, TWO, THREE)).canonical()); - assertEquals(Literal.FALSE, new ConstantFolding().rule(new NullEquals(EMPTY, TWO, THREE)).canonical()); - assertEquals(Literal.FALSE, new ConstantFolding().rule(new NullEquals(EMPTY, TWO, NULL)).canonical()); - assertEquals(Literal.TRUE, new ConstantFolding().rule(new NotEquals(EMPTY, TWO, THREE)).canonical()); - assertEquals(Literal.TRUE, new ConstantFolding().rule(new LessThanOrEqual(EMPTY, TWO, THREE)).canonical()); - assertEquals(Literal.TRUE, new ConstantFolding().rule(new LessThan(EMPTY, TWO, THREE)).canonical()); + assertEquals(FALSE, new ConstantFolding().rule(new GreaterThan(EMPTY, TWO, THREE)).canonical()); + assertEquals(FALSE, new ConstantFolding().rule(new GreaterThanOrEqual(EMPTY, TWO, THREE)).canonical()); + assertEquals(FALSE, new ConstantFolding().rule(new Equals(EMPTY, TWO, THREE)).canonical()); + assertEquals(FALSE, new ConstantFolding().rule(new NullEquals(EMPTY, TWO, THREE)).canonical()); + assertEquals(FALSE, new ConstantFolding().rule(new NullEquals(EMPTY, TWO, NULL)).canonical()); + assertEquals(TRUE, new ConstantFolding().rule(new NotEquals(EMPTY, TWO, THREE)).canonical()); + assertEquals(TRUE, new ConstantFolding().rule(new LessThanOrEqual(EMPTY, TWO, THREE)).canonical()); + assertEquals(TRUE, new ConstantFolding().rule(new LessThan(EMPTY, TWO, THREE)).canonical()); } public void testConstantFoldingBinaryLogic() { - assertEquals(Literal.FALSE, - new ConstantFolding().rule(new And(EMPTY, new GreaterThan(EMPTY, TWO, THREE), Literal.TRUE)).canonical()); - assertEquals(Literal.TRUE, - new ConstantFolding().rule(new Or(EMPTY, new GreaterThanOrEqual(EMPTY, TWO, THREE), Literal.TRUE)).canonical()); + assertEquals(FALSE, + new ConstantFolding().rule(new And(EMPTY, new GreaterThan(EMPTY, TWO, THREE), TRUE)).canonical()); + assertEquals(TRUE, + new ConstantFolding().rule(new Or(EMPTY, new GreaterThanOrEqual(EMPTY, TWO, THREE), TRUE)).canonical()); } public void testConstantFoldingBinaryLogic_WithNullHandling() { - assertEquals(NULL, new ConstantFolding().rule(new And(EMPTY, NULL, Literal.TRUE)).canonical()); - assertEquals(NULL, new ConstantFolding().rule(new And(EMPTY, Literal.TRUE, NULL)).canonical()); - assertEquals(Literal.FALSE, new ConstantFolding().rule(new And(EMPTY, NULL, Literal.FALSE)).canonical()); - assertEquals(Literal.FALSE, new ConstantFolding().rule(new And(EMPTY, Literal.FALSE, NULL)).canonical()); + assertEquals(NULL, new ConstantFolding().rule(new And(EMPTY, NULL, TRUE)).canonical()); + assertEquals(NULL, new ConstantFolding().rule(new And(EMPTY, TRUE, NULL)).canonical()); + assertEquals(FALSE, new ConstantFolding().rule(new And(EMPTY, NULL, FALSE)).canonical()); + assertEquals(FALSE, new ConstantFolding().rule(new And(EMPTY, FALSE, NULL)).canonical()); assertEquals(NULL, new ConstantFolding().rule(new And(EMPTY, NULL, NULL)).canonical()); - assertEquals(Literal.TRUE, new ConstantFolding().rule(new Or(EMPTY, NULL, Literal.TRUE)).canonical()); - assertEquals(Literal.TRUE, new ConstantFolding().rule(new Or(EMPTY, Literal.TRUE, NULL)).canonical()); - assertEquals(NULL, new ConstantFolding().rule(new Or(EMPTY, NULL, Literal.FALSE)).canonical()); - assertEquals(NULL, new ConstantFolding().rule(new Or(EMPTY, Literal.FALSE, NULL)).canonical()); + assertEquals(TRUE, new ConstantFolding().rule(new Or(EMPTY, NULL, TRUE)).canonical()); + assertEquals(TRUE, new ConstantFolding().rule(new Or(EMPTY, TRUE, NULL)).canonical()); + assertEquals(NULL, new ConstantFolding().rule(new Or(EMPTY, NULL, FALSE)).canonical()); + assertEquals(NULL, new ConstantFolding().rule(new Or(EMPTY, FALSE, NULL)).canonical()); assertEquals(NULL, new ConstantFolding().rule(new Or(EMPTY, NULL, NULL)).canonical()); } @@ -321,25 +324,25 @@ public class OptimizerTests extends ESTestCase { } public void testConstantIsNotNull() { - assertEquals(Literal.FALSE, new ConstantFolding().rule(new IsNotNull(EMPTY, L(null)))); - assertEquals(Literal.TRUE, new ConstantFolding().rule(new IsNotNull(EMPTY, FIVE))); + assertEquals(FALSE, new ConstantFolding().rule(new IsNotNull(EMPTY, L(null)))); + assertEquals(TRUE, new ConstantFolding().rule(new IsNotNull(EMPTY, FIVE))); } public void testConstantNot() { - assertEquals(Literal.FALSE, new ConstantFolding().rule(new Not(EMPTY, Literal.TRUE))); - assertEquals(Literal.TRUE, new ConstantFolding().rule(new Not(EMPTY, Literal.FALSE))); + assertEquals(FALSE, new ConstantFolding().rule(new Not(EMPTY, TRUE))); + assertEquals(TRUE, new ConstantFolding().rule(new Not(EMPTY, FALSE))); } public void testConstantFoldingLikes() { - assertEquals(Literal.TRUE, - new ConstantFolding().rule(new Like(EMPTY, Literal.of(EMPTY, "test_emp"), new LikePattern("test%", (char) 0))) + assertEquals(TRUE, + new ConstantFolding().rule(new Like(EMPTY, of(EMPTY, "test_emp"), new LikePattern("test%", (char) 0))) .canonical()); - assertEquals(Literal.TRUE, - new ConstantFolding().rule(new RLike(EMPTY, Literal.of(EMPTY, "test_emp"), "test.emp")).canonical()); + assertEquals(TRUE, + new ConstantFolding().rule(new RLike(EMPTY, of(EMPTY, "test_emp"), "test.emp")).canonical()); } public void testConstantFoldingDatetime() { - Expression cast = new Cast(EMPTY, Literal.of(EMPTY, "2018-01-19T10:23:27Z"), DataType.DATETIME); + Expression cast = new Cast(EMPTY, of(EMPTY, "2018-01-19T10:23:27Z"), DataType.DATETIME); assertEquals(2018, foldFunction(new Year(EMPTY, cast, UTC))); assertEquals(1, foldFunction(new MonthOfYear(EMPTY, cast, UTC))); assertEquals(19, foldFunction(new DayOfMonth(EMPTY, cast, UTC))); @@ -407,44 +410,44 @@ public class OptimizerTests extends ESTestCase { public void testNullFoldingIsNull() { FoldNull foldNull = new FoldNull(); - assertEquals(true, foldNull.rule(new IsNull(EMPTY, Literal.NULL)).fold()); - assertEquals(false, foldNull.rule(new IsNull(EMPTY, Literal.TRUE)).fold()); + assertEquals(true, foldNull.rule(new IsNull(EMPTY, NULL)).fold()); + assertEquals(false, foldNull.rule(new IsNull(EMPTY, TRUE)).fold()); } public void testNullFoldingIsNotNull() { FoldNull foldNull = new FoldNull(); - assertEquals(true, foldNull.rule(new IsNotNull(EMPTY, Literal.TRUE)).fold()); - assertEquals(false, foldNull.rule(new IsNotNull(EMPTY, Literal.NULL)).fold()); + assertEquals(true, foldNull.rule(new IsNotNull(EMPTY, TRUE)).fold()); + assertEquals(false, foldNull.rule(new IsNotNull(EMPTY, NULL)).fold()); } public void testGenericNullableExpression() { FoldNull rule = new FoldNull(); // date-time - assertNullLiteral(rule.rule(new DayName(EMPTY, Literal.NULL, randomZone()))); + assertNullLiteral(rule.rule(new DayName(EMPTY, NULL, randomZone()))); // math function - assertNullLiteral(rule.rule(new Cos(EMPTY, Literal.NULL))); + assertNullLiteral(rule.rule(new Cos(EMPTY, NULL))); // string function - assertNullLiteral(rule.rule(new Ascii(EMPTY, Literal.NULL))); - assertNullLiteral(rule.rule(new Repeat(EMPTY, getFieldAttribute(), Literal.NULL))); + assertNullLiteral(rule.rule(new Ascii(EMPTY, NULL))); + assertNullLiteral(rule.rule(new Repeat(EMPTY, getFieldAttribute(), NULL))); // arithmetic - assertNullLiteral(rule.rule(new Add(EMPTY, getFieldAttribute(), Literal.NULL))); + assertNullLiteral(rule.rule(new Add(EMPTY, getFieldAttribute(), NULL))); // comparison - assertNullLiteral(rule.rule(new GreaterThan(EMPTY, getFieldAttribute(), Literal.NULL))); + assertNullLiteral(rule.rule(new GreaterThan(EMPTY, getFieldAttribute(), NULL))); // regex - assertNullLiteral(rule.rule(new RLike(EMPTY, Literal.NULL, "123"))); + assertNullLiteral(rule.rule(new RLike(EMPTY, NULL, "123"))); } public void testNullFoldingDoesNotApplyOnLogicalExpressions() { FoldNull rule = new FoldNull(); - Or or = new Or(EMPTY, Literal.NULL, Literal.TRUE); + Or or = new Or(EMPTY, NULL, TRUE); assertEquals(or, rule.rule(or)); - or = new Or(EMPTY, Literal.NULL, Literal.NULL); + or = new Or(EMPTY, NULL, NULL); assertEquals(or, rule.rule(or)); - And and = new And(EMPTY, Literal.NULL, Literal.TRUE); + And and = new And(EMPTY, NULL, TRUE); assertEquals(and, rule.rule(and)); - and = new And(EMPTY, Literal.NULL, Literal.NULL); + and = new And(EMPTY, NULL, NULL); assertEquals(and, rule.rule(and)); } @@ -455,11 +458,11 @@ public class OptimizerTests extends ESTestCase { Class clazz = (Class) randomFrom(IfNull.class, NullIf.class); Constructor ctor = clazz.getConstructor(Source.class, Expression.class, Expression.class); - ConditionalFunction conditionalFunction = ctor.newInstance(EMPTY, Literal.NULL, ONE); + ConditionalFunction conditionalFunction = ctor.newInstance(EMPTY, NULL, ONE); assertEquals(conditionalFunction, rule.rule(conditionalFunction)); - conditionalFunction = ctor.newInstance(EMPTY, ONE, Literal.NULL); + conditionalFunction = ctor.newInstance(EMPTY, ONE, NULL); assertEquals(conditionalFunction, rule.rule(conditionalFunction)); - conditionalFunction = ctor.newInstance(EMPTY, Literal.NULL, Literal.NULL); + conditionalFunction = ctor.newInstance(EMPTY, NULL, NULL); assertEquals(conditionalFunction, rule.rule(conditionalFunction)); } @@ -470,14 +473,14 @@ public class OptimizerTests extends ESTestCase { Class clazz = (Class) randomFrom(Coalesce.class, Greatest.class, Least.class); Constructor ctor = clazz.getConstructor(Source.class, List.class); - ArbitraryConditionalFunction conditionalFunction = ctor.newInstance(EMPTY, Arrays.asList(Literal.NULL, ONE, TWO)); + ArbitraryConditionalFunction conditionalFunction = ctor.newInstance(EMPTY, Arrays.asList(NULL, ONE, TWO)); assertEquals(conditionalFunction, rule.rule(conditionalFunction)); - conditionalFunction = ctor.newInstance(EMPTY, Arrays.asList(Literal.NULL, NULL, NULL)); + conditionalFunction = ctor.newInstance(EMPTY, Arrays.asList(NULL, NULL, NULL)); assertEquals(conditionalFunction, rule.rule(conditionalFunction)); } public void testSimplifyCoalesceNulls() { - Expression e = new SimplifyConditional().rule(new Coalesce(EMPTY, asList(Literal.NULL, Literal.NULL))); + Expression e = new SimplifyConditional().rule(new Coalesce(EMPTY, asList(NULL, NULL))); assertEquals(Coalesce.class, e.getClass()); assertEquals(0, e.children().size()); } @@ -491,51 +494,51 @@ public class OptimizerTests extends ESTestCase { public void testSimplifyCoalesceRandomNullsWithValue() { Expression e = new SimplifyConditional().rule(new Coalesce(EMPTY, CollectionUtils.combine( - CollectionUtils.combine(randomListOfNulls(), Literal.TRUE, Literal.FALSE, Literal.TRUE), + CollectionUtils.combine(randomListOfNulls(), TRUE, FALSE, TRUE), randomListOfNulls()))); assertEquals(1, e.children().size()); - assertEquals(Literal.TRUE, e.children().get(0)); + assertEquals(TRUE, e.children().get(0)); } private List randomListOfNulls() { - return asList(randomArray(1, 10, Literal[]::new, () -> Literal.NULL)); + return asList(randomArray(1, 10, Literal[]::new, () -> NULL)); } public void testSimplifyCoalesceFirstLiteral() { Expression e = new SimplifyConditional() .rule(new Coalesce(EMPTY, - Arrays.asList(Literal.NULL, Literal.TRUE, Literal.FALSE, new Abs(EMPTY, getFieldAttribute())))); + Arrays.asList(NULL, TRUE, FALSE, new Abs(EMPTY, getFieldAttribute())))); assertEquals(Coalesce.class, e.getClass()); assertEquals(1, e.children().size()); - assertEquals(Literal.TRUE, e.children().get(0)); + assertEquals(TRUE, e.children().get(0)); } public void testSimplifyIfNullNulls() { - Expression e = new SimplifyConditional().rule(new IfNull(EMPTY, Literal.NULL, Literal.NULL)); + Expression e = new SimplifyConditional().rule(new IfNull(EMPTY, NULL, NULL)); assertEquals(IfNull.class, e.getClass()); assertEquals(0, e.children().size()); } public void testSimplifyIfNullWithNullAndValue() { - Expression e = new SimplifyConditional().rule(new IfNull(EMPTY, Literal.NULL, ONE)); + Expression e = new SimplifyConditional().rule(new IfNull(EMPTY, NULL, ONE)); assertEquals(IfNull.class, e.getClass()); assertEquals(1, e.children().size()); assertEquals(ONE, e.children().get(0)); - e = new SimplifyConditional().rule(new IfNull(EMPTY, ONE, Literal.NULL)); + e = new SimplifyConditional().rule(new IfNull(EMPTY, ONE, NULL)); assertEquals(IfNull.class, e.getClass()); assertEquals(1, e.children().size()); assertEquals(ONE, e.children().get(0)); } public void testFoldNullNotAppliedOnNullIf() { - Expression orig = new NullIf(EMPTY, ONE, Literal.NULL); + Expression orig = new NullIf(EMPTY, ONE, NULL); Expression f = new FoldNull().rule(orig); assertEquals(orig, f); } public void testSimplifyGreatestNulls() { - Expression e = new SimplifyConditional().rule(new Greatest(EMPTY, asList(Literal.NULL, Literal.NULL))); + Expression e = new SimplifyConditional().rule(new Greatest(EMPTY, asList(NULL, NULL))); assertEquals(Greatest.class, e.getClass()); assertEquals(0, e.children().size()); } @@ -556,7 +559,7 @@ public class OptimizerTests extends ESTestCase { } public void testSimplifyLeastNulls() { - Expression e = new SimplifyConditional().rule(new Least(EMPTY, asList(Literal.NULL, Literal.NULL))); + Expression e = new SimplifyConditional().rule(new Least(EMPTY, asList(NULL, NULL))); assertEquals(Least.class, e.getClass()); assertEquals(0, e.children().size()); } @@ -578,9 +581,9 @@ public class OptimizerTests extends ESTestCase { public void testConcatFoldingIsNotNull() { FoldNull foldNull = new FoldNull(); - assertEquals(1, foldNull.rule(new Concat(EMPTY, Literal.NULL, ONE)).fold()); - assertEquals(1, foldNull.rule(new Concat(EMPTY, ONE, Literal.NULL)).fold()); - assertEquals(StringUtils.EMPTY, foldNull.rule(new Concat(EMPTY, Literal.NULL, Literal.NULL)).fold()); + assertEquals(1, foldNull.rule(new Concat(EMPTY, NULL, ONE)).fold()); + assertEquals(1, foldNull.rule(new Concat(EMPTY, ONE, NULL)).fold()); + assertEquals(StringUtils.EMPTY, foldNull.rule(new Concat(EMPTY, NULL, NULL)).fold()); } // @@ -593,15 +596,15 @@ public class OptimizerTests extends ESTestCase { } public void testBinaryComparisonSimplification() { - assertEquals(Literal.TRUE, new BinaryComparisonSimplification().rule(new Equals(EMPTY, FIVE, FIVE))); - assertEquals(Literal.TRUE, new BinaryComparisonSimplification().rule(new NullEquals(EMPTY, FIVE, FIVE))); - assertEquals(Literal.TRUE, new BinaryComparisonSimplification().rule(new NullEquals(EMPTY, NULL, NULL))); - assertEquals(Literal.FALSE, new BinaryComparisonSimplification().rule(new NotEquals(EMPTY, FIVE, FIVE))); - assertEquals(Literal.TRUE, new BinaryComparisonSimplification().rule(new GreaterThanOrEqual(EMPTY, FIVE, FIVE))); - assertEquals(Literal.TRUE, new BinaryComparisonSimplification().rule(new LessThanOrEqual(EMPTY, FIVE, FIVE))); + assertEquals(TRUE, new BinaryComparisonSimplification().rule(new Equals(EMPTY, FIVE, FIVE))); + assertEquals(TRUE, new BinaryComparisonSimplification().rule(new NullEquals(EMPTY, FIVE, FIVE))); + assertEquals(TRUE, new BinaryComparisonSimplification().rule(new NullEquals(EMPTY, NULL, NULL))); + assertEquals(FALSE, new BinaryComparisonSimplification().rule(new NotEquals(EMPTY, FIVE, FIVE))); + assertEquals(TRUE, new BinaryComparisonSimplification().rule(new GreaterThanOrEqual(EMPTY, FIVE, FIVE))); + assertEquals(TRUE, new BinaryComparisonSimplification().rule(new LessThanOrEqual(EMPTY, FIVE, FIVE))); - assertEquals(Literal.FALSE, new BinaryComparisonSimplification().rule(new GreaterThan(EMPTY, FIVE, FIVE))); - assertEquals(Literal.FALSE, new BinaryComparisonSimplification().rule(new LessThan(EMPTY, FIVE, FIVE))); + assertEquals(FALSE, new BinaryComparisonSimplification().rule(new GreaterThan(EMPTY, FIVE, FIVE))); + assertEquals(FALSE, new BinaryComparisonSimplification().rule(new LessThan(EMPTY, FIVE, FIVE))); } public void testNullEqualsWithNullLiteralBecomesIsNull() { @@ -648,25 +651,25 @@ public class OptimizerTests extends ESTestCase { public void testBoolSimplifyOr() { BooleanSimplification simplification = new BooleanSimplification(); - assertEquals(Literal.TRUE, simplification.rule(new Or(EMPTY, Literal.TRUE, Literal.TRUE))); - assertEquals(Literal.TRUE, simplification.rule(new Or(EMPTY, Literal.TRUE, DUMMY_EXPRESSION))); - assertEquals(Literal.TRUE, simplification.rule(new Or(EMPTY, DUMMY_EXPRESSION, Literal.TRUE))); + assertEquals(TRUE, simplification.rule(new Or(EMPTY, TRUE, TRUE))); + assertEquals(TRUE, simplification.rule(new Or(EMPTY, TRUE, DUMMY_EXPRESSION))); + assertEquals(TRUE, simplification.rule(new Or(EMPTY, DUMMY_EXPRESSION, TRUE))); - assertEquals(Literal.FALSE, simplification.rule(new Or(EMPTY, Literal.FALSE, Literal.FALSE))); - assertEquals(DUMMY_EXPRESSION, simplification.rule(new Or(EMPTY, Literal.FALSE, DUMMY_EXPRESSION))); - assertEquals(DUMMY_EXPRESSION, simplification.rule(new Or(EMPTY, DUMMY_EXPRESSION, Literal.FALSE))); + assertEquals(FALSE, simplification.rule(new Or(EMPTY, FALSE, FALSE))); + assertEquals(DUMMY_EXPRESSION, simplification.rule(new Or(EMPTY, FALSE, DUMMY_EXPRESSION))); + assertEquals(DUMMY_EXPRESSION, simplification.rule(new Or(EMPTY, DUMMY_EXPRESSION, FALSE))); } public void testBoolSimplifyAnd() { BooleanSimplification simplification = new BooleanSimplification(); - assertEquals(Literal.TRUE, simplification.rule(new And(EMPTY, Literal.TRUE, Literal.TRUE))); - assertEquals(DUMMY_EXPRESSION, simplification.rule(new And(EMPTY, Literal.TRUE, DUMMY_EXPRESSION))); - assertEquals(DUMMY_EXPRESSION, simplification.rule(new And(EMPTY, DUMMY_EXPRESSION, Literal.TRUE))); + assertEquals(TRUE, simplification.rule(new And(EMPTY, TRUE, TRUE))); + assertEquals(DUMMY_EXPRESSION, simplification.rule(new And(EMPTY, TRUE, DUMMY_EXPRESSION))); + assertEquals(DUMMY_EXPRESSION, simplification.rule(new And(EMPTY, DUMMY_EXPRESSION, TRUE))); - assertEquals(Literal.FALSE, simplification.rule(new And(EMPTY, Literal.FALSE, Literal.FALSE))); - assertEquals(Literal.FALSE, simplification.rule(new And(EMPTY, Literal.FALSE, DUMMY_EXPRESSION))); - assertEquals(Literal.FALSE, simplification.rule(new And(EMPTY, DUMMY_EXPRESSION, Literal.FALSE))); + assertEquals(FALSE, simplification.rule(new And(EMPTY, FALSE, FALSE))); + assertEquals(FALSE, simplification.rule(new And(EMPTY, FALSE, DUMMY_EXPRESSION))); + assertEquals(FALSE, simplification.rule(new And(EMPTY, DUMMY_EXPRESSION, FALSE))); } public void testBoolCommonFactorExtraction() { @@ -710,7 +713,7 @@ public class OptimizerTests extends ESTestCase { public void testCombineBinaryComparisonsNotComparable() { FieldAttribute fa = getFieldAttribute(); LessThanOrEqual lte = new LessThanOrEqual(EMPTY, fa, SIX); - LessThan lt = new LessThan(EMPTY, fa, Literal.FALSE); + LessThan lt = new LessThan(EMPTY, fa, FALSE); CombineBinaryComparisons rule = new CombineBinaryComparisons(); And and = new And(EMPTY, lte, lt); @@ -790,7 +793,7 @@ public class OptimizerTests extends ESTestCase { CombineBinaryComparisons rule = new CombineBinaryComparisons(); // TRUE AND a != 5 AND 4 < a <= 7 - Expression exp = rule.rule(new And(EMPTY, gte, new And(EMPTY, Literal.TRUE, new And(EMPTY, gt, new And(EMPTY, ne, lte))))); + Expression exp = rule.rule(new And(EMPTY, gte, new And(EMPTY, TRUE, new And(EMPTY, gt, new And(EMPTY, ne, lte))))); assertEquals(And.class, exp.getClass()); And and = ((And) exp); assertEquals(Range.class, and.right().getClass()); @@ -943,7 +946,7 @@ public class OptimizerTests extends ESTestCase { FieldAttribute fa = getFieldAttribute(); GreaterThan gt1 = new GreaterThan(EMPTY, fa, ONE); - GreaterThan gt2 = new GreaterThan(EMPTY, fa, Literal.FALSE); + GreaterThan gt2 = new GreaterThan(EMPTY, fa, FALSE); Or or = new Or(EMPTY, gt1, gt2); @@ -1056,7 +1059,7 @@ public class OptimizerTests extends ESTestCase { FieldAttribute fa = getFieldAttribute(); Range r1 = new Range(EMPTY, fa, TWO, false, THREE, false); - Range r2 = new Range(EMPTY, fa, ONE, false, Literal.FALSE, false); + Range r2 = new Range(EMPTY, fa, ONE, false, FALSE, false); Or or = new Or(EMPTY, r1, r2); @@ -1194,7 +1197,7 @@ public class OptimizerTests extends ESTestCase { PropagateEquals rule = new PropagateEquals(); Expression exp = rule.rule(new And(EMPTY, eq1, eq2)); - assertEquals(Literal.FALSE, rule.rule(exp)); + assertEquals(FALSE, rule.rule(exp)); } // a <=> 1 AND a <=> 2 -> FALSE @@ -1205,7 +1208,7 @@ public class OptimizerTests extends ESTestCase { PropagateEquals rule = new PropagateEquals(); Expression exp = rule.rule(new And(EMPTY, eq1, eq2)); - assertEquals(Literal.FALSE, rule.rule(exp)); + assertEquals(FALSE, rule.rule(exp)); } // 1 < a < 10 AND a == 10 -> FALSE @@ -1216,7 +1219,7 @@ public class OptimizerTests extends ESTestCase { PropagateEquals rule = new PropagateEquals(); Expression exp = rule.rule(new And(EMPTY, eq1, r)); - assertEquals(Literal.FALSE, rule.rule(exp)); + assertEquals(FALSE, rule.rule(exp)); } // 1 < a < 10 AND a <=> 10 -> FALSE @@ -1227,7 +1230,7 @@ public class OptimizerTests extends ESTestCase { PropagateEquals rule = new PropagateEquals(); Expression exp = rule.rule(new And(EMPTY, eq1, r)); - assertEquals(Literal.FALSE, rule.rule(exp)); + assertEquals(FALSE, rule.rule(exp)); } public void testTranslateMinToFirst() {