diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/Cast.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/Cast.java index a8dfe431749..29803964044 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/Cast.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/Cast.java @@ -6,9 +6,7 @@ package org.elasticsearch.xpack.sql.expression.function.scalar; import org.elasticsearch.xpack.sql.expression.Expression; -import org.elasticsearch.xpack.sql.expression.Expressions; -import org.elasticsearch.xpack.sql.expression.gen.pipeline.Pipe; -import org.elasticsearch.xpack.sql.expression.gen.pipeline.UnaryPipe; +import org.elasticsearch.xpack.sql.expression.gen.processor.Processor; import org.elasticsearch.xpack.sql.tree.Location; import org.elasticsearch.xpack.sql.tree.NodeInfo; import org.elasticsearch.xpack.sql.type.DataType; @@ -71,9 +69,8 @@ public class Cast extends UnaryScalarFunction { } @Override - protected Pipe makePipe() { - return new UnaryPipe(location(), this, Expressions.pipe(field()), - new CastProcessor(DataTypeConversion.conversionFor(from(), to()))); + protected Processor makeProcessor() { + return new CastProcessor(DataTypeConversion.conversionFor(from(), to())); } @Override diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/UnaryScalarFunction.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/UnaryScalarFunction.java index 54fe2e834db..1b639287a12 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/UnaryScalarFunction.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/UnaryScalarFunction.java @@ -6,6 +6,10 @@ package org.elasticsearch.xpack.sql.expression.function.scalar; import org.elasticsearch.xpack.sql.expression.Expression; +import org.elasticsearch.xpack.sql.expression.Expressions; +import org.elasticsearch.xpack.sql.expression.gen.pipeline.Pipe; +import org.elasticsearch.xpack.sql.expression.gen.pipeline.UnaryPipe; +import org.elasticsearch.xpack.sql.expression.gen.processor.Processor; import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate; import org.elasticsearch.xpack.sql.tree.Location; @@ -34,12 +38,20 @@ public abstract class UnaryScalarFunction extends ScalarFunction { } return replaceChild(newChildren.get(0)); } + protected abstract UnaryScalarFunction replaceChild(Expression newChild); public Expression field() { return field; } + @Override + public final Pipe makePipe() { + return new UnaryPipe(location(), this, Expressions.pipe(field()), makeProcessor()); + } + + protected abstract Processor makeProcessor(); + @Override public boolean foldable() { return field.foldable(); diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/datetime/DateTimeFunction.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/datetime/DateTimeFunction.java index fbb095f2f00..8d5a384b1f4 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/datetime/DateTimeFunction.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/datetime/DateTimeFunction.java @@ -6,11 +6,9 @@ package org.elasticsearch.xpack.sql.expression.function.scalar.datetime; import org.elasticsearch.xpack.sql.expression.Expression; -import org.elasticsearch.xpack.sql.expression.Expressions; import org.elasticsearch.xpack.sql.expression.FieldAttribute; import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DateTimeProcessor.DateTimeExtractor; -import org.elasticsearch.xpack.sql.expression.gen.pipeline.Pipe; -import org.elasticsearch.xpack.sql.expression.gen.pipeline.UnaryPipe; +import org.elasticsearch.xpack.sql.expression.gen.processor.Processor; import org.elasticsearch.xpack.sql.expression.gen.script.ParamsBuilder; import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate; import org.elasticsearch.xpack.sql.tree.Location; @@ -63,13 +61,13 @@ public abstract class DateTimeFunction extends BaseDateTimeFunction { */ protected abstract ChronoField chronoField(); - @Override - protected Pipe makePipe() { - return new UnaryPipe(location(), this, Expressions.pipe(field()), new DateTimeProcessor(extractor(), timeZone())); - } - protected abstract DateTimeExtractor extractor(); + @Override + protected Processor makeProcessor() { + return new DateTimeProcessor(extractor(), timeZone()); + } + @Override public DataType dataType() { return DataType.INTEGER; diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/datetime/NamedDateTimeFunction.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/datetime/NamedDateTimeFunction.java index ed43996fe8e..a8e6e02057a 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/datetime/NamedDateTimeFunction.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/datetime/NamedDateTimeFunction.java @@ -6,11 +6,9 @@ package org.elasticsearch.xpack.sql.expression.function.scalar.datetime; import org.elasticsearch.xpack.sql.expression.Expression; -import org.elasticsearch.xpack.sql.expression.Expressions; import org.elasticsearch.xpack.sql.expression.FieldAttribute; import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.NamedDateTimeProcessor.NameExtractor; -import org.elasticsearch.xpack.sql.expression.gen.pipeline.Pipe; -import org.elasticsearch.xpack.sql.expression.gen.pipeline.UnaryPipe; +import org.elasticsearch.xpack.sql.expression.gen.processor.Processor; import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate; import org.elasticsearch.xpack.sql.tree.Location; import org.elasticsearch.xpack.sql.type.DataType; @@ -51,8 +49,8 @@ abstract class NamedDateTimeFunction extends BaseDateTimeFunction { } @Override - protected final Pipe makePipe() { - return new UnaryPipe(location(), this, Expressions.pipe(field()), new NamedDateTimeProcessor(nameExtractor, timeZone())); + protected Processor makeProcessor() { + return new NamedDateTimeProcessor(nameExtractor, timeZone()); } @Override diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/datetime/Quarter.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/datetime/Quarter.java index c9a1d4ee721..51b9501c6eb 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/datetime/Quarter.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/datetime/Quarter.java @@ -7,10 +7,8 @@ package org.elasticsearch.xpack.sql.expression.function.scalar.datetime; import org.elasticsearch.xpack.sql.expression.Expression; -import org.elasticsearch.xpack.sql.expression.Expressions; import org.elasticsearch.xpack.sql.expression.FieldAttribute; -import org.elasticsearch.xpack.sql.expression.gen.pipeline.Pipe; -import org.elasticsearch.xpack.sql.expression.gen.pipeline.UnaryPipe; +import org.elasticsearch.xpack.sql.expression.gen.processor.Processor; import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate; import org.elasticsearch.xpack.sql.tree.Location; import org.elasticsearch.xpack.sql.tree.NodeInfo.NodeCtor2; @@ -53,8 +51,8 @@ public class Quarter extends BaseDateTimeFunction { } @Override - protected Pipe makePipe() { - return new UnaryPipe(location(), this, Expressions.pipe(field()), new QuarterProcessor(timeZone())); + protected Processor makeProcessor() { + return new QuarterProcessor(timeZone()); } @Override diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/math/MathFunction.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/math/MathFunction.java index 4b7ed1e7442..cd37e539bfc 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/math/MathFunction.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/math/MathFunction.java @@ -6,11 +6,9 @@ package org.elasticsearch.xpack.sql.expression.function.scalar.math; import org.elasticsearch.xpack.sql.expression.Expression; -import org.elasticsearch.xpack.sql.expression.Expressions; import org.elasticsearch.xpack.sql.expression.function.scalar.UnaryScalarFunction; import org.elasticsearch.xpack.sql.expression.function.scalar.math.MathProcessor.MathOperation; -import org.elasticsearch.xpack.sql.expression.gen.pipeline.Pipe; -import org.elasticsearch.xpack.sql.expression.gen.pipeline.UnaryPipe; +import org.elasticsearch.xpack.sql.expression.gen.processor.Processor; import org.elasticsearch.xpack.sql.tree.Location; import org.elasticsearch.xpack.sql.type.DataType; @@ -64,8 +62,8 @@ public abstract class MathFunction extends UnaryScalarFunction { } @Override - protected final Pipe makePipe() { - return new UnaryPipe(location(), this, Expressions.pipe(field()), new MathProcessor(operation())); + protected Processor makeProcessor() { + return new MathProcessor(operation()); } protected abstract MathOperation operation(); diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/string/UnaryStringFunction.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/string/UnaryStringFunction.java index d387fe7e4a1..af9bd05fd15 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/string/UnaryStringFunction.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/string/UnaryStringFunction.java @@ -6,12 +6,10 @@ package org.elasticsearch.xpack.sql.expression.function.scalar.string; import org.elasticsearch.xpack.sql.expression.Expression; -import org.elasticsearch.xpack.sql.expression.Expressions; import org.elasticsearch.xpack.sql.expression.FieldAttribute; import org.elasticsearch.xpack.sql.expression.function.scalar.UnaryScalarFunction; import org.elasticsearch.xpack.sql.expression.function.scalar.string.StringProcessor.StringOperation; -import org.elasticsearch.xpack.sql.expression.gen.pipeline.Pipe; -import org.elasticsearch.xpack.sql.expression.gen.pipeline.UnaryPipe; +import org.elasticsearch.xpack.sql.expression.gen.processor.Processor; import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate; import org.elasticsearch.xpack.sql.tree.Location; import org.elasticsearch.xpack.sql.util.StringUtils; @@ -49,8 +47,8 @@ public abstract class UnaryStringFunction extends UnaryScalarFunction { } @Override - protected final Pipe makePipe() { - return new UnaryPipe(location(), this, Expressions.pipe(field()), new StringProcessor(operation())); + protected Processor makeProcessor() { + return new StringProcessor(operation()); } protected abstract StringOperation operation(); diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/string/UnaryStringIntFunction.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/string/UnaryStringIntFunction.java index 613b37dd7e8..0753af03f14 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/string/UnaryStringIntFunction.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/string/UnaryStringIntFunction.java @@ -6,12 +6,10 @@ package org.elasticsearch.xpack.sql.expression.function.scalar.string; import org.elasticsearch.xpack.sql.expression.Expression; -import org.elasticsearch.xpack.sql.expression.Expressions; import org.elasticsearch.xpack.sql.expression.FieldAttribute; import org.elasticsearch.xpack.sql.expression.function.scalar.UnaryScalarFunction; import org.elasticsearch.xpack.sql.expression.function.scalar.string.StringProcessor.StringOperation; -import org.elasticsearch.xpack.sql.expression.gen.pipeline.Pipe; -import org.elasticsearch.xpack.sql.expression.gen.pipeline.UnaryPipe; +import org.elasticsearch.xpack.sql.expression.gen.processor.Processor; import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate; import org.elasticsearch.xpack.sql.tree.Location; @@ -51,8 +49,8 @@ public abstract class UnaryStringIntFunction extends UnaryScalarFunction { } @Override - protected final Pipe makePipe() { - return new UnaryPipe(location(), this, Expressions.pipe(field()), new StringProcessor(operation())); + protected Processor makeProcessor() { + return new StringProcessor(operation()); } protected abstract StringOperation operation(); @@ -72,6 +70,11 @@ public abstract class UnaryStringIntFunction extends UnaryScalarFunction { template)); } + @Override + public int hashCode() { + return Objects.hash(field()); + } + @Override public boolean equals(Object obj) { if (obj == null || obj.getClass() != getClass()) { @@ -80,9 +83,4 @@ public abstract class UnaryStringIntFunction extends UnaryScalarFunction { UnaryStringIntFunction other = (UnaryStringIntFunction) obj; return Objects.equals(other.field(), field()); } - - @Override - public int hashCode() { - return Objects.hash(field()); - } } \ No newline at end of file diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/whitelist/InternalSqlScriptUtils.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/whitelist/InternalSqlScriptUtils.java index c6f445c0590..9aabb3f10ec 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/whitelist/InternalSqlScriptUtils.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/whitelist/InternalSqlScriptUtils.java @@ -21,8 +21,11 @@ import org.elasticsearch.xpack.sql.expression.function.scalar.string.LocateFunct import org.elasticsearch.xpack.sql.expression.function.scalar.string.ReplaceFunctionProcessor; import org.elasticsearch.xpack.sql.expression.function.scalar.string.StringProcessor.StringOperation; import org.elasticsearch.xpack.sql.expression.function.scalar.string.SubstringFunctionProcessor; +import org.elasticsearch.xpack.sql.expression.predicate.IsNotNullProcessor; import org.elasticsearch.xpack.sql.expression.predicate.logical.BinaryLogicProcessor.BinaryLogicOperation; +import org.elasticsearch.xpack.sql.expression.predicate.logical.NotProcessor; import org.elasticsearch.xpack.sql.expression.predicate.operator.arithmetic.BinaryArithmeticProcessor.BinaryArithmeticOperation; +import org.elasticsearch.xpack.sql.expression.predicate.operator.arithmetic.UnaryArithmeticProcessor.UnaryArithmeticOperation; import org.elasticsearch.xpack.sql.expression.predicate.operator.comparison.BinaryComparisonProcessor.BinaryComparisonOperation; import org.elasticsearch.xpack.sql.expression.predicate.regex.RegexProcessor.RegexOperation; import org.elasticsearch.xpack.sql.util.StringUtils; @@ -102,6 +105,14 @@ public final class InternalSqlScriptUtils { return BinaryLogicOperation.OR.apply(left, right); } + public static Boolean not(Boolean expression) { + return NotProcessor.apply(expression); + } + + public static Boolean notNull(Object expression) { + return IsNotNullProcessor.apply(expression); + } + // // Regex // @@ -116,14 +127,6 @@ public final class InternalSqlScriptUtils { return BinaryArithmeticOperation.ADD.apply(left, right); } - public static Number sub(Number left, Number right) { - return BinaryArithmeticOperation.SUB.apply(left, right); - } - - public static Number mul(Number left, Number right) { - return BinaryArithmeticOperation.MUL.apply(left, right); - } - public static Number div(Number left, Number right) { return BinaryArithmeticOperation.DIV.apply(left, right); } @@ -132,6 +135,18 @@ public final class InternalSqlScriptUtils { return BinaryArithmeticOperation.MOD.apply(left, right); } + public static Number mul(Number left, Number right) { + return BinaryArithmeticOperation.MUL.apply(left, right); + } + + public static Number neg(Number value) { + return UnaryArithmeticOperation.NEGATE.apply(value); + } + + public static Number sub(Number left, Number right) { + return BinaryArithmeticOperation.SUB.apply(left, right); + } + public static Number round(Number v, Number s) { return BinaryMathOperation.ROUND.apply(v, s); } diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/gen/script/Scripts.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/gen/script/Scripts.java index 69ad3661dc5..f9e2588a9c0 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/gen/script/Scripts.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/gen/script/Scripts.java @@ -24,12 +24,16 @@ import static org.elasticsearch.xpack.sql.expression.gen.script.ParamsBuilder.pa public final class Scripts { + public static final String DOC_VALUE = "doc[{}].value"; + public static final String SQL_SCRIPTS = "{sql}"; + public static final String PARAM = "{}"; + private Scripts() {} private static final Map FORMATTING_PATTERNS = Collections.unmodifiableMap(Stream.of( - new SimpleEntry<>("doc[{}].value", "{sql}.docValue(doc,{})"), - new SimpleEntry<>("{sql}", InternalSqlScriptUtils.class.getSimpleName()), - new SimpleEntry<>("{}", "params.%s")) + new SimpleEntry<>(DOC_VALUE, SQL_SCRIPTS + ".docValue(doc,{})"), + new SimpleEntry<>(SQL_SCRIPTS, InternalSqlScriptUtils.class.getSimpleName()), + new SimpleEntry<>(PARAM, "params.%s")) .collect(toMap(e -> Pattern.compile(e.getKey(), Pattern.LITERAL), Map.Entry::getValue, (a, b) -> a, LinkedHashMap::new))); /** @@ -83,4 +87,4 @@ public final class Scripts { .build(), dataType); } -} +} \ No newline at end of file diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/IsNotNull.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/IsNotNull.java index cabca2aaf2d..bd3fd5bf081 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/IsNotNull.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/IsNotNull.java @@ -5,25 +5,24 @@ */ package org.elasticsearch.xpack.sql.expression.predicate; -import org.elasticsearch.xpack.sql.SqlIllegalArgumentException; import org.elasticsearch.xpack.sql.expression.Expression; -import org.elasticsearch.xpack.sql.expression.UnaryExpression; -import org.elasticsearch.xpack.sql.expression.gen.pipeline.Pipe; -import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate; +import org.elasticsearch.xpack.sql.expression.function.scalar.UnaryScalarFunction; +import org.elasticsearch.xpack.sql.expression.gen.processor.Processor; +import org.elasticsearch.xpack.sql.expression.gen.script.Scripts; import org.elasticsearch.xpack.sql.tree.Location; import org.elasticsearch.xpack.sql.tree.NodeInfo; import org.elasticsearch.xpack.sql.type.DataType; import org.elasticsearch.xpack.sql.type.DataTypes; -public class IsNotNull extends UnaryExpression { +public class IsNotNull extends UnaryScalarFunction { - public IsNotNull(Location location, Expression child) { - super(location, child); + public IsNotNull(Location location, Expression field) { + super(location, field); } @Override protected NodeInfo info() { - return NodeInfo.create(this, IsNotNull::new, child()); + return NodeInfo.create(this, IsNotNull::new, field()); } @Override @@ -33,17 +32,17 @@ public class IsNotNull extends UnaryExpression { @Override public Object fold() { - return child().fold() != null && !DataTypes.isNull(child().dataType()); + return field().fold() != null && !DataTypes.isNull(field().dataType()); } @Override - protected Pipe makePipe() { - throw new SqlIllegalArgumentException("Not supported yet"); + protected Processor makeProcessor() { + return IsNotNullProcessor.INSTANCE; } @Override - public ScriptTemplate asScript() { - throw new SqlIllegalArgumentException("Not supported yet"); + public String processScript(String script) { + return Scripts.formatTemplate(Scripts.SQL_SCRIPTS + ".notNull(" + script + ")"); } @Override @@ -55,9 +54,4 @@ public class IsNotNull extends UnaryExpression { public DataType dataType() { return DataType.BOOLEAN; } - - @Override - public String toString() { - return child().toString() + " IS NOT NULL"; - } -} +} \ No newline at end of file diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/IsNotNullProcessor.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/IsNotNullProcessor.java new file mode 100644 index 00000000000..b29ae263f39 --- /dev/null +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/IsNotNullProcessor.java @@ -0,0 +1,51 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.xpack.sql.expression.predicate; + +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.xpack.sql.expression.gen.processor.Processor; + +import java.io.IOException; + +public class IsNotNullProcessor implements Processor { + + static final IsNotNullProcessor INSTANCE = new IsNotNullProcessor(); + + public static final String NAME = "inn"; + + private IsNotNullProcessor() {} + + @Override + public String getWriteableName() { + return NAME; + } + + @Override + public void writeTo(StreamOutput out) throws IOException {} + + @Override + public Object process(Object input) { + return apply(input); + } + + public static Boolean apply(Object input) { + return input != null ? Boolean.TRUE : Boolean.FALSE; + } + + @Override + public int hashCode() { + return IsNotNullProcessor.class.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + return obj == null || getClass() != obj.getClass(); + } +} \ No newline at end of file diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/logical/BinaryLogicProcessor.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/logical/BinaryLogicProcessor.java index 7e3aef2b8c7..334a80b7d57 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/logical/BinaryLogicProcessor.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/logical/BinaryLogicProcessor.java @@ -26,7 +26,7 @@ public class BinaryLogicProcessor extends FunctionalBinaryProcessor { if (Boolean.TRUE.equals(l) || Boolean.TRUE.equals(r)) { @@ -35,7 +35,7 @@ public class BinaryLogicProcessor extends FunctionalBinaryProcessor process; diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/logical/Not.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/logical/Not.java index 48a307fa062..55115ffb4df 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/logical/Not.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/logical/Not.java @@ -5,19 +5,16 @@ */ package org.elasticsearch.xpack.sql.expression.predicate.logical; -import org.elasticsearch.xpack.sql.SqlIllegalArgumentException; import org.elasticsearch.xpack.sql.expression.Expression; import org.elasticsearch.xpack.sql.expression.Expressions; import org.elasticsearch.xpack.sql.expression.function.scalar.UnaryScalarFunction; -import org.elasticsearch.xpack.sql.expression.gen.pipeline.Pipe; -import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate; +import org.elasticsearch.xpack.sql.expression.gen.processor.Processor; +import org.elasticsearch.xpack.sql.expression.gen.script.Scripts; import org.elasticsearch.xpack.sql.expression.predicate.BinaryOperator.Negateable; import org.elasticsearch.xpack.sql.tree.Location; import org.elasticsearch.xpack.sql.tree.NodeInfo; import org.elasticsearch.xpack.sql.type.DataType; -import java.util.Objects; - public class Not extends UnaryScalarFunction { public Not(Location location, Expression child) { @@ -45,17 +42,17 @@ public class Not extends UnaryScalarFunction { @Override public Object fold() { - return Objects.equals(field().fold(), Boolean.TRUE) ? Boolean.FALSE : Boolean.TRUE; + return NotProcessor.INSTANCE.process(field().fold()); } @Override - protected Pipe makePipe() { - throw new SqlIllegalArgumentException("Not supported yet"); + protected Processor makeProcessor() { + return NotProcessor.INSTANCE; } @Override - public ScriptTemplate asScript() { - throw new SqlIllegalArgumentException("Not supported yet"); + public String processScript(String script) { + return Scripts.formatTemplate(Scripts.SQL_SCRIPTS + ".not(" + script + ")"); } @Override @@ -71,4 +68,4 @@ public class Not extends UnaryScalarFunction { public DataType dataType() { return DataType.BOOLEAN; } -} +} \ No newline at end of file diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/logical/NotProcessor.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/logical/NotProcessor.java new file mode 100644 index 00000000000..14425d35578 --- /dev/null +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/logical/NotProcessor.java @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +package org.elasticsearch.xpack.sql.expression.predicate.logical; + +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.xpack.sql.SqlIllegalArgumentException; +import org.elasticsearch.xpack.sql.expression.gen.processor.Processor; + +import java.io.IOException; + +public class NotProcessor implements Processor { + + static final NotProcessor INSTANCE = new NotProcessor(); + + public static final String NAME = "ln"; + + private NotProcessor() {} + + @Override + public String getWriteableName() { + return NAME; + } + + @Override + public void writeTo(StreamOutput out) throws IOException {} + + @Override + public Object process(Object input) { + return apply(input); + } + + public static Boolean apply(Object input) { + if (input == null) { + return null; + } + + if (!(input instanceof Boolean)) { + throw new SqlIllegalArgumentException("A boolean is required; received {}", input); + } + + return ((Boolean) input).booleanValue() ? Boolean.FALSE : Boolean.TRUE; + } + + @Override + public int hashCode() { + return NotProcessor.class.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + return obj == null || getClass() != obj.getClass(); + } +} \ No newline at end of file diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/operator/arithmetic/Neg.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/operator/arithmetic/Neg.java index c5758b787f0..47ea773f514 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/operator/arithmetic/Neg.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/operator/arithmetic/Neg.java @@ -9,9 +9,9 @@ import org.elasticsearch.xpack.sql.expression.Expression; import org.elasticsearch.xpack.sql.expression.Expressions; import org.elasticsearch.xpack.sql.expression.NamedExpression; import org.elasticsearch.xpack.sql.expression.function.scalar.UnaryScalarFunction; -import org.elasticsearch.xpack.sql.expression.gen.pipeline.Pipe; -import org.elasticsearch.xpack.sql.expression.gen.pipeline.UnaryPipe; +import org.elasticsearch.xpack.sql.expression.gen.processor.Processor; import org.elasticsearch.xpack.sql.expression.gen.script.ScriptWeaver; +import org.elasticsearch.xpack.sql.expression.gen.script.Scripts; import org.elasticsearch.xpack.sql.expression.predicate.operator.arithmetic.UnaryArithmeticProcessor.UnaryArithmeticOperation; import org.elasticsearch.xpack.sql.tree.Location; import org.elasticsearch.xpack.sql.tree.NodeInfo; @@ -57,12 +57,12 @@ public class Neg extends UnaryScalarFunction implements ScriptWeaver { } @Override - public String processScript(String template) { - return super.processScript("-" + template); + public String processScript(String script) { + return Scripts.formatTemplate(Scripts.SQL_SCRIPTS + ".neg(" + script + ")"); } @Override - protected Pipe makePipe() { - return new UnaryPipe(location(), this, Expressions.pipe(field()), new UnaryArithmeticProcessor(UnaryArithmeticOperation.NEGATE)); + protected Processor makeProcessor() { + return new UnaryArithmeticProcessor(UnaryArithmeticOperation.NEGATE); } -} +} \ No newline at end of file diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/planner/QueryTranslator.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/planner/QueryTranslator.java index 453660f07da..9fcd542ef63 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/planner/QueryTranslator.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/planner/QueryTranslator.java @@ -13,7 +13,6 @@ import org.elasticsearch.xpack.sql.expression.Expressions; import org.elasticsearch.xpack.sql.expression.FieldAttribute; import org.elasticsearch.xpack.sql.expression.Literal; import org.elasticsearch.xpack.sql.expression.NamedExpression; -import org.elasticsearch.xpack.sql.expression.UnaryExpression; import org.elasticsearch.xpack.sql.expression.function.Function; import org.elasticsearch.xpack.sql.expression.function.Functions; import org.elasticsearch.xpack.sql.expression.function.aggregate.AggregateFunction; @@ -354,11 +353,6 @@ final class QueryTranslator { return new BoolQuery(loc, false, left, right); } - static Query not(Query query) { - Check.isTrue(query != null, "Expressions is null"); - return new NotQuery(query.location(), query); - } - static String nameOf(Expression e) { if (e instanceof DateTimeFunction) { return nameOf(((DateTimeFunction) e).field()); @@ -484,20 +478,41 @@ final class QueryTranslator { @Override protected QueryTranslation asQuery(Not not, boolean onAggs) { - QueryTranslation translation = toQuery(not.field(), onAggs); - return new QueryTranslation(not(translation.query), translation.aggFilter); + Query query = null; + AggFilter aggFilter = null; + + if (onAggs) { + aggFilter = new AggFilter(not.id().toString(), not.asScript()); + } else { + query = new NotQuery(not.location(), toQuery(not.field(), false).query); + // query directly on the field + if (not.field() instanceof FieldAttribute) { + query = wrapIfNested(query, not.field()); + } + } + + return new QueryTranslation(query, aggFilter); } } - static class Nulls extends ExpressionTranslator { + static class Nulls extends ExpressionTranslator { @Override - protected QueryTranslation asQuery(UnaryExpression ue, boolean onAggs) { - // TODO: handle onAggs - missing bucket aggregation - if (ue instanceof IsNotNull) { - return new QueryTranslation(new ExistsQuery(ue.location(), nameOf(ue.child()))); + protected QueryTranslation asQuery(IsNotNull inn, boolean onAggs) { + Query query = null; + AggFilter aggFilter = null; + + if (onAggs) { + aggFilter = new AggFilter(inn.id().toString(), inn.asScript()); + } else { + query = new ExistsQuery(inn.location(), nameOf(inn.field())); + // query directly on the field + if (inn.field() instanceof NamedExpression) { + query = wrapIfNested(query, inn.field()); + } } - return null; + + return new QueryTranslation(query, aggFilter); } } diff --git a/x-pack/plugin/sql/src/main/resources/org/elasticsearch/xpack/sql/plugin/sql_whitelist.txt b/x-pack/plugin/sql/src/main/resources/org/elasticsearch/xpack/sql/plugin/sql_whitelist.txt index ea229940193..998dab84783 100644 --- a/x-pack/plugin/sql/src/main/resources/org/elasticsearch/xpack/sql/plugin/sql_whitelist.txt +++ b/x-pack/plugin/sql/src/main/resources/org/elasticsearch/xpack/sql/plugin/sql_whitelist.txt @@ -29,7 +29,9 @@ class org.elasticsearch.xpack.sql.expression.function.scalar.whitelist.InternalS # Logical # Boolean and(Boolean, Boolean) - Boolean or(Boolean, Boolean) + Boolean or(Boolean, Boolean) + Boolean not(Boolean) + Boolean notNull(Object) # # Regex @@ -43,6 +45,7 @@ class org.elasticsearch.xpack.sql.expression.function.scalar.whitelist.InternalS Number div(Number, Number) Number mod(Number, Number) Number mul(Number, Number) + Number neg(Number) Number sub(Number, Number) Number round(Number, Number) Number truncate(Number, Number) diff --git a/x-pack/qa/sql/src/main/resources/agg.sql-spec b/x-pack/qa/sql/src/main/resources/agg.sql-spec index dab4c386a55..2fafb75d69b 100644 --- a/x-pack/qa/sql/src/main/resources/agg.sql-spec +++ b/x-pack/qa/sql/src/main/resources/agg.sql-spec @@ -456,6 +456,13 @@ selectHireDateGroupByHireDate SELECT hire_date HD, COUNT(*) c FROM test_emp GROUP BY hire_date ORDER BY hire_date DESC; selectSalaryGroupBySalary SELECT salary, COUNT(*) c FROM test_emp GROUP BY salary ORDER BY salary DESC; +selectLangGroupByLangHavingCountIsNotNull +SELECT languages, COUNT(*) c FROM test_emp GROUP BY languages HAVING COUNT(*) IS NOT NULL ORDER BY languages DESC; +selectLangGroupByLangHavingNotEquality +SELECT languages, COUNT(*) c FROM test_emp GROUP BY languages HAVING NOT COUNT(*) = 1 ORDER BY languages DESC; +selectLangGroupByLangHavingDifferent +SELECT languages, COUNT(*) c FROM test_emp GROUP BY languages HAVING COUNT(*) <> 1 ORDER BY languages DESC; + // filter with IN aggMultiWithHavingUsingInAndNullHandling