diff --git a/presto-main/src/main/java/com/facebook/presto/metadata/FunctionRegistry.java b/presto-main/src/main/java/com/facebook/presto/metadata/FunctionRegistry.java index 7760d014e8227..253e299c5d77d 100644 --- a/presto-main/src/main/java/com/facebook/presto/metadata/FunctionRegistry.java +++ b/presto-main/src/main/java/com/facebook/presto/metadata/FunctionRegistry.java @@ -482,27 +482,46 @@ public FunctionRegistry(TypeManager typeManager, BlockEncodingSerde blockEncodin .scalars(JsonFunctions.class) .scalars(ColorFunctions.class) .scalars(ColorOperators.class) + .scalar(ColorOperators.ColorIsDistinctFrom.class) .scalars(HyperLogLogFunctions.class) .scalars(UnknownOperators.class) + .scalar(UnknownOperators.UnknownIsDistinctFrom.class) .scalars(BooleanOperators.class) + .scalar(BooleanOperators.BooleanIsDistinctFrom.class) .scalars(BigintOperators.class) + .scalar(BigintOperators.BigIntIsDistinctFrom.class) .scalars(IntegerOperators.class) + .scalar(IntegerOperators.IntegerIsDistinctFrom.class) .scalars(SmallintOperators.class) + .scalar(SmallintOperators.SmallIntIsDistinctFrom.class) .scalars(TinyintOperators.class) + .scalar(TinyintOperators.TinyIntIsDistinctFrom.class) .scalars(DoubleOperators.class) + .scalar(DoubleOperators.DoubleIsDistinctFrom.class) .scalars(RealOperators.class) + .scalar(RealOperators.RealIsDistinctFrom.class) .scalars(VarcharOperators.class) + .scalar(VarcharOperators.VarcharIsDistinctFrom.class) .scalars(VarbinaryOperators.class) + .scalar(VarbinaryOperators.VarbinaryIsDistinctFrom.class) .scalars(DateOperators.class) + .scalar(DateOperators.DateIsDistinctFrom.class) .scalars(TimeOperators.class) + .scalar(TimeOperators.TimeIsDistinctFrom.class) .scalars(TimestampOperators.class) + .scalar(TimestampOperators.TimestampIsDistinctFrom.class) .scalars(IntervalDayTimeOperators.class) + .scalar(IntervalDayTimeOperators.IntervalDayTimeIsDistinctFrom.class) .scalars(IntervalYearMonthOperators.class) + .scalar(IntervalYearMonthOperators.IntervalYearMonthIsDistinctFrom.class) .scalars(TimeWithTimeZoneOperators.class) + .scalar(TimeWithTimeZoneOperators.TimeWithTimeZoneIsDistinctFrom.class) .scalars(TimestampWithTimeZoneOperators.class) + .scalar(TimestampWithTimeZoneOperators.TimestampWithTimeZoneIsDistinctFrom.class) .scalars(DateTimeOperators.class) .scalars(HyperLogLogOperators.class) .scalars(IpAddressOperators.class) + .scalar(IpAddressOperators.IpAddressIsDistinctFrom.class) .scalars(LikeFunctions.class) .scalars(ArrayFunctions.class) .scalars(HmacFunctions.class) @@ -512,10 +531,12 @@ public FunctionRegistry(TypeManager typeManager, BlockEncodingSerde blockEncodin .scalar(ArrayPositionFunction.class) .scalars(CombineHashFunction.class) .scalars(JsonOperators.class) + .scalar(JsonOperators.JsonIsDistinctFrom.class) .scalars(FailureFunction.class) .scalars(JoniRegexpCasts.class) .scalars(CharacterStringCasts.class) .scalars(CharOperators.class) + .scalar(CharOperators.CharIsDistinctFrom.class) .scalar(DecimalOperators.Negation.class) .scalar(DecimalOperators.HashCode.class) .scalar(DecimalOperators.Indeterminate.class) diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayDistinctFromOperator.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayDistinctFromOperator.java index c8df51d57794a..3bd2e00368567 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayDistinctFromOperator.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/ArrayDistinctFromOperator.java @@ -14,6 +14,8 @@ */ import com.facebook.presto.spi.block.Block; +import com.facebook.presto.spi.function.BlockIndex; +import com.facebook.presto.spi.function.BlockPosition; import com.facebook.presto.spi.function.Convention; import com.facebook.presto.spi.function.IsNull; import com.facebook.presto.spi.function.OperatorDependency; @@ -25,12 +27,10 @@ import java.lang.invoke.MethodHandle; -import static com.facebook.presto.spi.InvocationConvention.InvocationArgumentConvention.NULL_FLAG; +import static com.facebook.presto.spi.InvocationConvention.InvocationArgumentConvention.BLOCK_POSITION; import static com.facebook.presto.spi.InvocationConvention.InvocationReturnConvention.FAIL_ON_NULL; import static com.facebook.presto.spi.function.OperatorType.IS_DISTINCT_FROM; -import static com.facebook.presto.spi.type.TypeUtils.readNativeValue; import static com.facebook.presto.util.Failures.internalError; -import static com.google.common.base.Defaults.defaultValue; @ScalarOperator(IS_DISTINCT_FROM) public final class ArrayDistinctFromOperator @@ -44,7 +44,7 @@ public static boolean isDistinctFrom( operator = IS_DISTINCT_FROM, returnType = StandardTypes.BOOLEAN, argumentTypes = {"E", "E"}, - convention = @Convention(arguments = {NULL_FLAG, NULL_FLAG}, result = FAIL_ON_NULL)) MethodHandle function, + convention = @Convention(arguments = {BLOCK_POSITION, BLOCK_POSITION}, result = FAIL_ON_NULL)) MethodHandle function, @TypeParameter("E") Type type, @SqlType("array(E)") Block left, @IsNull boolean leftNull, @@ -61,22 +61,12 @@ public static boolean isDistinctFrom( return true; } for (int i = 0; i < left.getPositionCount(); i++) { - Object leftValue = readNativeValue(type, left, i); - boolean leftValueNull = leftValue == null; - if (leftValueNull) { - leftValue = defaultValue(type.getJavaType()); - } - Object rightValue = readNativeValue(type, right, i); - boolean rightValueNull = rightValue == null; - if (rightValueNull) { - rightValue = defaultValue(type.getJavaType()); - } try { if ((boolean) function.invoke( - leftValue, - leftValueNull, - rightValue, - rightValueNull)) { + left, + i, + right, + i)) { return true; } } @@ -86,4 +76,21 @@ public static boolean isDistinctFrom( } return false; } + + @TypeParameter("E") + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @OperatorDependency( + operator = IS_DISTINCT_FROM, + returnType = StandardTypes.BOOLEAN, + argumentTypes = {"E", "E"}, + convention = @Convention(arguments = {BLOCK_POSITION, BLOCK_POSITION}, result = FAIL_ON_NULL)) MethodHandle function, + @TypeParameter("array(E)") Type type, + @BlockPosition @SqlType(value = "array(E)", nativeContainerType = Block.class) Block left, + @BlockIndex int leftPosition, + @BlockPosition @SqlType(value = "array(E)", nativeContainerType = Block.class) Block right, + @BlockIndex int rightPosition) + { + return isDistinctFrom(function, type, (Block) type.getObject(left, leftPosition), left.isNull(leftPosition), (Block) type.getObject(right, rightPosition), right.isNull(rightPosition)); + } } diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/JsonOperators.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/JsonOperators.java index 850db1e190a5a..55ed3673532b5 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/JsonOperators.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/JsonOperators.java @@ -15,6 +15,9 @@ import com.facebook.presto.spi.ConnectorSession; import com.facebook.presto.spi.PrestoException; +import com.facebook.presto.spi.block.Block; +import com.facebook.presto.spi.function.BlockIndex; +import com.facebook.presto.spi.function.BlockPosition; import com.facebook.presto.spi.function.IsNull; import com.facebook.presto.spi.function.LiteralParameters; import com.facebook.presto.spi.function.ScalarOperator; @@ -389,15 +392,39 @@ public static boolean notEqual(@SqlType(JSON) Slice leftJson, @SqlType(JSON) Sli } @ScalarOperator(IS_DISTINCT_FROM) - @SqlType(BOOLEAN) - public static boolean isDistinctFrom(@SqlType(JSON) Slice leftJson, @IsNull boolean leftNull, @SqlType(JSON) Slice rightJson, @IsNull boolean rightNull) + public static class JsonIsDistinctFrom { - if (leftNull != rightNull) { - return true; + @SqlType(BOOLEAN) + public static boolean isDistinctFrom(@SqlType(JSON) Slice leftJson, @IsNull boolean leftNull, @SqlType(JSON) Slice rightJson, @IsNull boolean rightNull) + { + if (leftNull != rightNull) { + return true; + } + if (leftNull) { + return false; + } + return notEqual(leftJson, rightJson); } - if (leftNull) { - return false; + + @SqlType(BOOLEAN) + public static boolean isDistinctFrom( + @BlockPosition @SqlType(value = JSON, nativeContainerType = Slice.class) Block left, + @BlockIndex int leftPosition, + @BlockPosition @SqlType(value = JSON, nativeContainerType = Slice.class) Block right, + @BlockIndex int rightPosition) + { + if (left.isNull(leftPosition) != right.isNull(rightPosition)) { + return true; + } + if (left.isNull(leftPosition)) { + return false; + } + int leftLength = left.getSliceLength(leftPosition); + int rightLength = right.getSliceLength(rightPosition); + if (leftLength != rightLength) { + return true; + } + return !left.equals(leftPosition, 0, right, rightPosition, 0, leftLength); } - return notEqual(leftJson, rightJson); } } diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapDistinctFromOperator.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapDistinctFromOperator.java index 1174446d33afa..793323bd4eda3 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapDistinctFromOperator.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/MapDistinctFromOperator.java @@ -14,20 +14,25 @@ */ import com.facebook.presto.spi.block.Block; +import com.facebook.presto.spi.function.BlockIndex; +import com.facebook.presto.spi.function.BlockPosition; +import com.facebook.presto.spi.function.Convention; import com.facebook.presto.spi.function.IsNull; import com.facebook.presto.spi.function.OperatorDependency; import com.facebook.presto.spi.function.ScalarOperator; import com.facebook.presto.spi.function.SqlType; import com.facebook.presto.spi.function.TypeParameter; +import com.facebook.presto.spi.type.MapType; import com.facebook.presto.spi.type.StandardTypes; import com.facebook.presto.spi.type.Type; import java.lang.invoke.MethodHandle; +import static com.facebook.presto.spi.InvocationConvention.InvocationArgumentConvention.BLOCK_POSITION; +import static com.facebook.presto.spi.InvocationConvention.InvocationReturnConvention.FAIL_ON_NULL; import static com.facebook.presto.spi.function.OperatorType.EQUAL; import static com.facebook.presto.spi.function.OperatorType.HASH_CODE; import static com.facebook.presto.spi.function.OperatorType.IS_DISTINCT_FROM; -import static com.facebook.presto.spi.type.TypeUtils.readNativeValue; @ScalarOperator(IS_DISTINCT_FROM) public final class MapDistinctFromOperator @@ -42,10 +47,9 @@ public static boolean isDistinctFrom( MethodHandle keyEqualsFunction, @OperatorDependency(operator = HASH_CODE, returnType = StandardTypes.BIGINT, argumentTypes = {"K"}) MethodHandle keyHashcodeFunction, - @OperatorDependency(operator = IS_DISTINCT_FROM, returnType = StandardTypes.BOOLEAN, argumentTypes = {"V", "V"}) + @OperatorDependency(operator = IS_DISTINCT_FROM, returnType = StandardTypes.BOOLEAN, argumentTypes = {"V", "V"}, convention = @Convention(arguments = {BLOCK_POSITION, BLOCK_POSITION}, result = FAIL_ON_NULL)) MethodHandle valueDistinctFromFunction, - @TypeParameter("K") Type keyType, - @TypeParameter("V") Type valueType, + @TypeParameter("map(K, V)") Type mapType, @SqlType("map(K,V)") Block leftMapBlock, @IsNull boolean leftMapNull, @SqlType("map(K,V)") Block rightMapBlock, @@ -59,18 +63,28 @@ public static boolean isDistinctFrom( } // Note that we compare to NOT distinct here and so negate the result. return !MapGenericEquality.genericEqual( - keyType, + ((MapType) mapType).getKeyType(), leftMapBlock, rightMapBlock, - (leftMapIndex, rightMapIndex) -> { - Object leftValue = readNativeValue(valueType, leftMapBlock, leftMapIndex); - Object rightValue = readNativeValue(valueType, rightMapBlock, rightMapIndex); - boolean leftNull = leftValue == null; - boolean rightNull = rightValue == null; - if (leftNull || rightNull) { - return leftNull == rightNull; - } - return !(boolean) valueDistinctFromFunction.invoke(leftValue, leftNull, rightValue, rightNull); - }); + (leftMapIndex, rightMapIndex) -> !(boolean) valueDistinctFromFunction.invoke(leftMapBlock, leftMapIndex, rightMapBlock, rightMapIndex)); + } + + @TypeParameter("K") + @TypeParameter("V") + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @OperatorDependency(operator = EQUAL, returnType = StandardTypes.BOOLEAN, argumentTypes = {"K", "K"}) + MethodHandle keyEqualsFunction, + @OperatorDependency(operator = HASH_CODE, returnType = StandardTypes.BIGINT, argumentTypes = {"K"}) + MethodHandle keyHashcodeFunction, + @OperatorDependency(operator = IS_DISTINCT_FROM, returnType = StandardTypes.BOOLEAN, argumentTypes = {"V", "V"}, convention = @Convention(arguments = {BLOCK_POSITION, BLOCK_POSITION}, result = FAIL_ON_NULL)) + MethodHandle valueDistinctFromFunction, + @TypeParameter("map(K, V)") Type mapType, + @BlockPosition @SqlType(value = "map(K,V)", nativeContainerType = Block.class) Block left, + @BlockIndex int leftPosition, + @BlockPosition @SqlType(value = "map(K,V)", nativeContainerType = Block.class) Block right, + @BlockIndex int rightPosition) + { + return isDistinctFrom(keyEqualsFunction, keyHashcodeFunction, valueDistinctFromFunction, mapType, (Block) mapType.getObject(left, leftPosition), left.isNull(leftPosition), (Block) mapType.getObject(right, rightPosition), right.isNull(rightPosition)); } } diff --git a/presto-main/src/main/java/com/facebook/presto/operator/scalar/RowDistinctFromOperator.java b/presto-main/src/main/java/com/facebook/presto/operator/scalar/RowDistinctFromOperator.java index 6bf0895a9acda..85f60309f562c 100644 --- a/presto-main/src/main/java/com/facebook/presto/operator/scalar/RowDistinctFromOperator.java +++ b/presto-main/src/main/java/com/facebook/presto/operator/scalar/RowDistinctFromOperator.java @@ -18,6 +18,7 @@ import com.facebook.presto.metadata.FunctionRegistry; import com.facebook.presto.metadata.Signature; import com.facebook.presto.metadata.SqlOperator; +import com.facebook.presto.operator.scalar.ScalarFunctionImplementation.ScalarImplementationChoice; import com.facebook.presto.spi.InvocationConvention; import com.facebook.presto.spi.block.Block; import com.facebook.presto.spi.type.StandardTypes; @@ -31,6 +32,7 @@ import static com.facebook.presto.metadata.Signature.comparableWithVariadicBound; import static com.facebook.presto.operator.scalar.ScalarFunctionImplementation.ArgumentProperty.valueTypeArgumentProperty; +import static com.facebook.presto.operator.scalar.ScalarFunctionImplementation.NullConvention.BLOCK_AND_POSITION; import static com.facebook.presto.operator.scalar.ScalarFunctionImplementation.NullConvention.USE_NULL_FLAG; import static com.facebook.presto.spi.InvocationConvention.InvocationArgumentConvention.NULL_FLAG; import static com.facebook.presto.spi.function.OperatorType.IS_DISTINCT_FROM; @@ -45,6 +47,7 @@ public class RowDistinctFromOperator { public static final RowDistinctFromOperator ROW_DISTINCT_FROM = new RowDistinctFromOperator(); private static final MethodHandle METHOD_HANDLE = methodHandle(RowDistinctFromOperator.class, "isDistinctFrom", Type.class, List.class, Block.class, boolean.class, Block.class, boolean.class); + private static final MethodHandle METHOD_HANDLE_BLOCK_POSITION = methodHandle(RowDistinctFromOperator.class, "isDistinctFrom", Type.class, List.class, Block.class, int.class, Block.class, int.class); private RowDistinctFromOperator() { @@ -71,11 +74,17 @@ public ScalarFunctionImplementation specialize(BoundVariables boundVariables, in argumentMethods.add(functionInvoker.methodHandle()); } return new ScalarFunctionImplementation( - false, ImmutableList.of( - valueTypeArgumentProperty(USE_NULL_FLAG), - valueTypeArgumentProperty(USE_NULL_FLAG)), - METHOD_HANDLE.bindTo(type).bindTo(argumentMethods.build()), + new ScalarImplementationChoice( + false, + ImmutableList.of(valueTypeArgumentProperty(USE_NULL_FLAG), valueTypeArgumentProperty(USE_NULL_FLAG)), + METHOD_HANDLE.bindTo(type).bindTo(argumentMethods.build()), + Optional.empty()), + new ScalarImplementationChoice( + false, + ImmutableList.of(valueTypeArgumentProperty(BLOCK_AND_POSITION), valueTypeArgumentProperty(BLOCK_AND_POSITION)), + METHOD_HANDLE_BLOCK_POSITION.bindTo(type).bindTo(argumentMethods.build()), + Optional.empty())), isDeterministic()); } @@ -115,4 +124,9 @@ public static boolean isDistinctFrom(Type rowType, List argumentMe } return false; } + + public static boolean isDistinctFrom(Type rowType, List argumentMethods, Block leftRow, int leftPosition, Block rightRow, int rightPosition) + { + return isDistinctFrom(rowType, argumentMethods, (Block) rowType.getObject(leftRow, leftPosition), leftRow.isNull(leftPosition), (Block) rowType.getObject(rightRow, rightPosition), rightRow.isNull(rightPosition)); + } } diff --git a/presto-main/src/main/java/com/facebook/presto/type/BigintOperators.java b/presto-main/src/main/java/com/facebook/presto/type/BigintOperators.java index 63132870586fc..b002e88fe3533 100644 --- a/presto-main/src/main/java/com/facebook/presto/type/BigintOperators.java +++ b/presto-main/src/main/java/com/facebook/presto/type/BigintOperators.java @@ -14,6 +14,9 @@ package com.facebook.presto.type; import com.facebook.presto.spi.PrestoException; +import com.facebook.presto.spi.block.Block; +import com.facebook.presto.spi.function.BlockIndex; +import com.facebook.presto.spi.function.BlockPosition; import com.facebook.presto.spi.function.IsNull; import com.facebook.presto.spi.function.LiteralParameters; import com.facebook.presto.spi.function.ScalarOperator; @@ -47,6 +50,7 @@ import static com.facebook.presto.spi.function.OperatorType.SATURATED_FLOOR_CAST; import static com.facebook.presto.spi.function.OperatorType.SUBTRACT; import static com.facebook.presto.spi.function.OperatorType.XX_HASH_64; +import static com.facebook.presto.spi.type.BigintType.BIGINT; import static io.airlift.slice.Slices.utf8Slice; import static java.lang.Float.floatToRawIntBits; import static java.lang.Math.toIntExact; @@ -277,20 +281,39 @@ public static long hashCode(@SqlType(StandardTypes.BIGINT) long value) } @ScalarOperator(IS_DISTINCT_FROM) - @SqlType(StandardTypes.BOOLEAN) - public static boolean isDistinctFrom( - @SqlType(StandardTypes.BIGINT) long left, - @IsNull boolean leftNull, - @SqlType(StandardTypes.BIGINT) long right, - @IsNull boolean rightNull) + public static class BigIntIsDistinctFrom { - if (leftNull != rightNull) { - return true; + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @SqlType(StandardTypes.BIGINT) long left, + @IsNull boolean leftNull, + @SqlType(StandardTypes.BIGINT) long right, + @IsNull boolean rightNull) + { + if (leftNull != rightNull) { + return true; + } + if (leftNull) { + return false; + } + return notEqual(left, right); } - if (leftNull) { - return false; + + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @BlockPosition @SqlType(value = StandardTypes.BIGINT, nativeContainerType = long.class) Block left, + @BlockIndex int leftPosition, + @BlockPosition @SqlType(value = StandardTypes.BIGINT, nativeContainerType = long.class) Block right, + @BlockIndex int rightPosition) + { + if (left.isNull(leftPosition) != right.isNull(rightPosition)) { + return true; + } + if (left.isNull(leftPosition)) { + return false; + } + return !BIGINT.equalTo(left, leftPosition, right, rightPosition); } - return notEqual(left, right); } @ScalarOperator(XX_HASH_64) diff --git a/presto-main/src/main/java/com/facebook/presto/type/BooleanOperators.java b/presto-main/src/main/java/com/facebook/presto/type/BooleanOperators.java index 7f1dced74a8a0..99b46a8e444bd 100644 --- a/presto-main/src/main/java/com/facebook/presto/type/BooleanOperators.java +++ b/presto-main/src/main/java/com/facebook/presto/type/BooleanOperators.java @@ -13,6 +13,9 @@ */ package com.facebook.presto.type; +import com.facebook.presto.spi.block.Block; +import com.facebook.presto.spi.function.BlockIndex; +import com.facebook.presto.spi.function.BlockPosition; import com.facebook.presto.spi.function.IsNull; import com.facebook.presto.spi.function.LiteralParameters; import com.facebook.presto.spi.function.ScalarFunction; @@ -33,6 +36,7 @@ import static com.facebook.presto.spi.function.OperatorType.LESS_THAN; import static com.facebook.presto.spi.function.OperatorType.LESS_THAN_OR_EQUAL; import static com.facebook.presto.spi.function.OperatorType.NOT_EQUAL; +import static com.facebook.presto.spi.type.BooleanType.BOOLEAN; import static java.lang.Float.floatToRawIntBits; import static java.nio.charset.StandardCharsets.US_ASCII; @@ -166,19 +170,38 @@ public static boolean not(@SqlType(StandardTypes.BOOLEAN) boolean value) } @ScalarOperator(IS_DISTINCT_FROM) - @SqlType(StandardTypes.BOOLEAN) - public static boolean isDistinctFrom( - @SqlType(StandardTypes.BOOLEAN) boolean left, - @IsNull boolean leftNull, - @SqlType(StandardTypes.BOOLEAN) boolean right, - @IsNull boolean rightNull) - { - if (leftNull != rightNull) { - return true; + public static class BooleanIsDistinctFrom + { + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @SqlType(StandardTypes.BOOLEAN) boolean left, + @IsNull boolean leftNull, + @SqlType(StandardTypes.BOOLEAN) boolean right, + @IsNull boolean rightNull) + { + if (leftNull != rightNull) { + return true; + } + if (leftNull) { + return false; + } + return notEqual(left, right); } - if (leftNull) { - return false; + + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @BlockPosition @SqlType(value = StandardTypes.BOOLEAN, nativeContainerType = boolean.class) Block left, + @BlockIndex int leftPosition, + @BlockPosition @SqlType(value = StandardTypes.BOOLEAN, nativeContainerType = boolean.class) Block right, + @BlockIndex int rightPosition) + { + if (left.isNull(leftPosition) != right.isNull(rightPosition)) { + return true; + } + if (left.isNull(leftPosition)) { + return false; + } + return !BOOLEAN.equalTo(left, leftPosition, right, rightPosition); } - return notEqual(left, right); } } diff --git a/presto-main/src/main/java/com/facebook/presto/type/CharOperators.java b/presto-main/src/main/java/com/facebook/presto/type/CharOperators.java index 972e390beebd4..588c3d138377c 100644 --- a/presto-main/src/main/java/com/facebook/presto/type/CharOperators.java +++ b/presto-main/src/main/java/com/facebook/presto/type/CharOperators.java @@ -13,6 +13,9 @@ */ package com.facebook.presto.type; +import com.facebook.presto.spi.block.Block; +import com.facebook.presto.spi.function.BlockIndex; +import com.facebook.presto.spi.function.BlockPosition; import com.facebook.presto.spi.function.IsNull; import com.facebook.presto.spi.function.LiteralParameters; import com.facebook.presto.spi.function.ScalarOperator; @@ -110,22 +113,48 @@ public static long xxHash64(@SqlType("char(x)") Slice slice) return XxHash64.hash(slice); } - @LiteralParameters("x") @ScalarOperator(IS_DISTINCT_FROM) - @SqlType(StandardTypes.BOOLEAN) - public static boolean isDistinctFrom( - @SqlType("char(x)") Slice left, - @IsNull boolean leftNull, - @SqlType("char(x)") Slice right, - @IsNull boolean rightNull) + public static class CharIsDistinctFrom { - if (leftNull != rightNull) { - return true; + @LiteralParameters("x") + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @SqlType("char(x)") Slice left, + @IsNull boolean leftNull, + @SqlType("char(x)") Slice right, + @IsNull boolean rightNull) + { + if (leftNull != rightNull) { + return true; + } + if (leftNull) { + return false; + } + return notEqual(left, right); } - if (leftNull) { - return false; + + @LiteralParameters("x") + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @BlockPosition @SqlType(value = "char(x)", nativeContainerType = Slice.class) Block left, + @BlockIndex int leftPosition, + @BlockPosition @SqlType(value = "char(x)", nativeContainerType = Slice.class) Block right, + @BlockIndex int rightPosition) + { + if (left.isNull(leftPosition) != right.isNull(rightPosition)) { + return true; + } + if (left.isNull(leftPosition)) { + return false; + } + + int leftLength = left.getSliceLength(leftPosition); + int rightLength = right.getSliceLength(rightPosition); + if (leftLength != rightLength) { + return true; + } + return !left.equals(leftPosition, 0, right, rightPosition, 0, leftLength); } - return notEqual(left, right); } @LiteralParameters("x") diff --git a/presto-main/src/main/java/com/facebook/presto/type/ColorOperators.java b/presto-main/src/main/java/com/facebook/presto/type/ColorOperators.java index 042519eb991a2..92e569d37484c 100644 --- a/presto-main/src/main/java/com/facebook/presto/type/ColorOperators.java +++ b/presto-main/src/main/java/com/facebook/presto/type/ColorOperators.java @@ -13,6 +13,9 @@ */ package com.facebook.presto.type; +import com.facebook.presto.spi.block.Block; +import com.facebook.presto.spi.function.BlockIndex; +import com.facebook.presto.spi.function.BlockPosition; import com.facebook.presto.spi.function.IsNull; import com.facebook.presto.spi.function.ScalarOperator; import com.facebook.presto.spi.function.SqlType; @@ -23,6 +26,7 @@ import static com.facebook.presto.spi.function.OperatorType.INDETERMINATE; import static com.facebook.presto.spi.function.OperatorType.IS_DISTINCT_FROM; import static com.facebook.presto.spi.function.OperatorType.NOT_EQUAL; +import static com.facebook.presto.type.ColorType.COLOR; public final class ColorOperators { @@ -52,20 +56,39 @@ public static long hashCode(@SqlType(ColorType.NAME) long value) } @ScalarOperator(IS_DISTINCT_FROM) - @SqlType(StandardTypes.BOOLEAN) - public static boolean isDistinctFrom( - @SqlType(ColorType.NAME) long left, - @IsNull boolean leftNull, - @SqlType(ColorType.NAME) long right, - @IsNull boolean rightNull) + public static class ColorIsDistinctFrom { - if (leftNull != rightNull) { - return true; + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @SqlType(ColorType.NAME) long left, + @IsNull boolean leftNull, + @SqlType(ColorType.NAME) long right, + @IsNull boolean rightNull) + { + if (leftNull != rightNull) { + return true; + } + if (leftNull) { + return false; + } + return notEqual(left, right); } - if (leftNull) { - return false; + + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @BlockPosition @SqlType(value = ColorType.NAME, nativeContainerType = long.class) Block left, + @BlockIndex int leftPosition, + @BlockPosition @SqlType(value = ColorType.NAME, nativeContainerType = long.class) Block right, + @BlockIndex int rightPosition) + { + if (left.isNull(leftPosition) != right.isNull(rightPosition)) { + return true; + } + if (left.isNull(leftPosition)) { + return false; + } + return !COLOR.equalTo(left, leftPosition, right, rightPosition); } - return notEqual(left, right); } @ScalarOperator(INDETERMINATE) diff --git a/presto-main/src/main/java/com/facebook/presto/type/DateOperators.java b/presto-main/src/main/java/com/facebook/presto/type/DateOperators.java index ba296079d5507..8dc1374bca1ef 100644 --- a/presto-main/src/main/java/com/facebook/presto/type/DateOperators.java +++ b/presto-main/src/main/java/com/facebook/presto/type/DateOperators.java @@ -15,6 +15,9 @@ import com.facebook.presto.spi.ConnectorSession; import com.facebook.presto.spi.PrestoException; +import com.facebook.presto.spi.block.Block; +import com.facebook.presto.spi.function.BlockIndex; +import com.facebook.presto.spi.function.BlockPosition; import com.facebook.presto.spi.function.IsNull; import com.facebook.presto.spi.function.LiteralParameters; import com.facebook.presto.spi.function.ScalarFunction; @@ -42,6 +45,7 @@ import static com.facebook.presto.spi.function.OperatorType.NOT_EQUAL; import static com.facebook.presto.spi.function.OperatorType.XX_HASH_64; import static com.facebook.presto.spi.type.DateTimeEncoding.packDateTimeWithZone; +import static com.facebook.presto.spi.type.DateType.DATE; import static com.facebook.presto.util.DateTimeUtils.parseDate; import static com.facebook.presto.util.DateTimeUtils.printDate; import static com.facebook.presto.util.DateTimeZoneIndex.getChronology; @@ -163,20 +167,39 @@ public static long hashCode(@SqlType(StandardTypes.DATE) long value) } @ScalarOperator(IS_DISTINCT_FROM) - @SqlType(StandardTypes.BOOLEAN) - public static boolean isDistinctFrom( - @SqlType(StandardTypes.DATE) long left, - @IsNull boolean leftNull, - @SqlType(StandardTypes.DATE) long right, - @IsNull boolean rightNull) - { - if (leftNull != rightNull) { - return true; + public static class DateIsDistinctFrom + { + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @SqlType(StandardTypes.DATE) long left, + @IsNull boolean leftNull, + @SqlType(StandardTypes.DATE) long right, + @IsNull boolean rightNull) + { + if (leftNull != rightNull) { + return true; + } + if (leftNull) { + return false; + } + return notEqual(left, right); } - if (leftNull) { - return false; + + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @BlockPosition @SqlType(value = StandardTypes.DATE, nativeContainerType = long.class) Block left, + @BlockIndex int leftPosition, + @BlockPosition @SqlType(value = StandardTypes.DATE, nativeContainerType = long.class) Block right, + @BlockIndex int rightPosition) + { + if (left.isNull(leftPosition) != right.isNull(rightPosition)) { + return true; + } + if (left.isNull(leftPosition)) { + return false; + } + return !DATE.equalTo(left, leftPosition, right, rightPosition); } - return notEqual(left, right); } @ScalarOperator(INDETERMINATE) diff --git a/presto-main/src/main/java/com/facebook/presto/type/DoubleOperators.java b/presto-main/src/main/java/com/facebook/presto/type/DoubleOperators.java index 3223ae8bf881c..1a442b0cafdb5 100644 --- a/presto-main/src/main/java/com/facebook/presto/type/DoubleOperators.java +++ b/presto-main/src/main/java/com/facebook/presto/type/DoubleOperators.java @@ -15,6 +15,9 @@ import com.facebook.presto.operator.scalar.MathFunctions; import com.facebook.presto.spi.PrestoException; +import com.facebook.presto.spi.block.Block; +import com.facebook.presto.spi.function.BlockIndex; +import com.facebook.presto.spi.function.BlockPosition; import com.facebook.presto.spi.function.IsNull; import com.facebook.presto.spi.function.LiteralParameters; import com.facebook.presto.spi.function.ScalarOperator; @@ -49,6 +52,7 @@ import static com.facebook.presto.spi.function.OperatorType.SATURATED_FLOOR_CAST; import static com.facebook.presto.spi.function.OperatorType.SUBTRACT; import static com.facebook.presto.spi.function.OperatorType.XX_HASH_64; +import static com.facebook.presto.spi.type.DoubleType.DOUBLE; import static com.google.common.base.Preconditions.checkState; import static io.airlift.slice.Slices.utf8Slice; import static java.lang.Double.doubleToLongBits; @@ -315,23 +319,45 @@ private static long saturatedFloorCastToLong(double value, long minValue, double } @ScalarOperator(IS_DISTINCT_FROM) - @SqlType(StandardTypes.BOOLEAN) - public static boolean isDistinctFrom( - @SqlType(StandardTypes.DOUBLE) double left, - @IsNull boolean leftNull, - @SqlType(StandardTypes.DOUBLE) double right, - @IsNull boolean rightNull) + public static class DoubleIsDistinctFrom { - if (leftNull != rightNull) { - return true; - } - if (leftNull) { - return false; + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @SqlType(StandardTypes.DOUBLE) double left, + @IsNull boolean leftNull, + @SqlType(StandardTypes.DOUBLE) double right, + @IsNull boolean rightNull) + { + if (leftNull != rightNull) { + return true; + } + if (leftNull) { + return false; + } + if (Double.isNaN(left) && Double.isNaN(right)) { + return false; + } + return notEqual(left, right); } - if (Double.isNaN(left) && Double.isNaN(right)) { - return false; + + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @BlockPosition @SqlType(value = StandardTypes.DOUBLE, nativeContainerType = double.class) Block left, + @BlockIndex int leftPosition, + @BlockPosition @SqlType(value = StandardTypes.DOUBLE, nativeContainerType = double.class) Block right, + @BlockIndex int rightPosition) + { + if (left.isNull(leftPosition) != right.isNull(rightPosition)) { + return true; + } + if (left.isNull(leftPosition)) { + return false; + } + if (Double.isNaN(DOUBLE.getDouble(left, leftPosition)) && Double.isNaN(DOUBLE.getDouble(right, rightPosition))) { + return false; + } + return !DOUBLE.equalTo(left, leftPosition, right, rightPosition); } - return notEqual(left, right); } @ScalarOperator(XX_HASH_64) diff --git a/presto-main/src/main/java/com/facebook/presto/type/IntegerOperators.java b/presto-main/src/main/java/com/facebook/presto/type/IntegerOperators.java index da41e0a7c6232..716b321b6726a 100644 --- a/presto-main/src/main/java/com/facebook/presto/type/IntegerOperators.java +++ b/presto-main/src/main/java/com/facebook/presto/type/IntegerOperators.java @@ -14,6 +14,9 @@ package com.facebook.presto.type; import com.facebook.presto.spi.PrestoException; +import com.facebook.presto.spi.block.Block; +import com.facebook.presto.spi.function.BlockIndex; +import com.facebook.presto.spi.function.BlockPosition; import com.facebook.presto.spi.function.IsNull; import com.facebook.presto.spi.function.LiteralParameters; import com.facebook.presto.spi.function.ScalarOperator; @@ -46,6 +49,7 @@ import static com.facebook.presto.spi.function.OperatorType.SATURATED_FLOOR_CAST; import static com.facebook.presto.spi.function.OperatorType.SUBTRACT; import static com.facebook.presto.spi.function.OperatorType.XX_HASH_64; +import static com.facebook.presto.spi.type.IntegerType.INTEGER; import static io.airlift.slice.Slices.utf8Slice; import static java.lang.Float.floatToRawIntBits; import static java.lang.String.format; @@ -246,20 +250,39 @@ public static long hashCode(@SqlType(StandardTypes.INTEGER) long value) } @ScalarOperator(IS_DISTINCT_FROM) - @SqlType(StandardTypes.BOOLEAN) - public static boolean isDistinctFrom( - @SqlType(StandardTypes.INTEGER) long left, - @IsNull boolean leftNull, - @SqlType(StandardTypes.INTEGER) long right, - @IsNull boolean rightNull) + public static class IntegerIsDistinctFrom { - if (leftNull != rightNull) { - return true; + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @SqlType(StandardTypes.INTEGER) long left, + @IsNull boolean leftNull, + @SqlType(StandardTypes.INTEGER) long right, + @IsNull boolean rightNull) + { + if (leftNull != rightNull) { + return true; + } + if (leftNull) { + return false; + } + return notEqual(left, right); } - if (leftNull) { - return false; + + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @BlockPosition @SqlType(value = StandardTypes.INTEGER, nativeContainerType = long.class) Block left, + @BlockIndex int leftPosition, + @BlockPosition @SqlType(value = StandardTypes.INTEGER, nativeContainerType = long.class) Block right, + @BlockIndex int rightPosition) + { + if (left.isNull(leftPosition) != right.isNull(rightPosition)) { + return true; + } + if (left.isNull(leftPosition)) { + return false; + } + return !INTEGER.equalTo(left, leftPosition, right, rightPosition); } - return notEqual(left, right); } @ScalarOperator(SATURATED_FLOOR_CAST) diff --git a/presto-main/src/main/java/com/facebook/presto/type/IntervalDayTimeOperators.java b/presto-main/src/main/java/com/facebook/presto/type/IntervalDayTimeOperators.java index 4b6a27f9193d1..a98899be40e42 100644 --- a/presto-main/src/main/java/com/facebook/presto/type/IntervalDayTimeOperators.java +++ b/presto-main/src/main/java/com/facebook/presto/type/IntervalDayTimeOperators.java @@ -13,6 +13,9 @@ */ package com.facebook.presto.type; +import com.facebook.presto.spi.block.Block; +import com.facebook.presto.spi.function.BlockIndex; +import com.facebook.presto.spi.function.BlockPosition; import com.facebook.presto.spi.function.IsNull; import com.facebook.presto.spi.function.LiteralParameters; import com.facebook.presto.spi.function.ScalarOperator; @@ -38,6 +41,7 @@ import static com.facebook.presto.spi.function.OperatorType.NEGATION; import static com.facebook.presto.spi.function.OperatorType.NOT_EQUAL; import static com.facebook.presto.spi.function.OperatorType.SUBTRACT; +import static com.facebook.presto.type.IntervalDayTimeType.INTERVAL_DAY_TIME; import static io.airlift.slice.Slices.utf8Slice; public final class IntervalDayTimeOperators @@ -170,20 +174,39 @@ public static long hashCode(@SqlType(StandardTypes.INTERVAL_DAY_TO_SECOND) long } @ScalarOperator(IS_DISTINCT_FROM) - @SqlType(StandardTypes.BOOLEAN) - public static boolean isDistinctFrom( - @SqlType(StandardTypes.INTERVAL_DAY_TO_SECOND) long left, - @IsNull boolean leftNull, - @SqlType(StandardTypes.INTERVAL_DAY_TO_SECOND) long right, - @IsNull boolean rightNull) - { - if (leftNull != rightNull) { - return true; + public static class IntervalDayTimeIsDistinctFrom + { + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @SqlType(StandardTypes.INTERVAL_DAY_TO_SECOND) long left, + @IsNull boolean leftNull, + @SqlType(StandardTypes.INTERVAL_DAY_TO_SECOND) long right, + @IsNull boolean rightNull) + { + if (leftNull != rightNull) { + return true; + } + if (leftNull) { + return false; + } + return notEqual(left, right); } - if (leftNull) { - return false; + + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @BlockPosition @SqlType(value = StandardTypes.INTERVAL_DAY_TO_SECOND, nativeContainerType = long.class) Block left, + @BlockIndex int leftPosition, + @BlockPosition @SqlType(value = StandardTypes.INTERVAL_DAY_TO_SECOND, nativeContainerType = long.class) Block right, + @BlockIndex int rightPosition) + { + if (left.isNull(leftPosition) != right.isNull(rightPosition)) { + return true; + } + if (left.isNull(leftPosition)) { + return false; + } + return !INTERVAL_DAY_TIME.equalTo(left, leftPosition, right, rightPosition); } - return notEqual(left, right); } @ScalarOperator(INDETERMINATE) diff --git a/presto-main/src/main/java/com/facebook/presto/type/IntervalYearMonthOperators.java b/presto-main/src/main/java/com/facebook/presto/type/IntervalYearMonthOperators.java index d0d69cf61364a..c59d8143b966c 100644 --- a/presto-main/src/main/java/com/facebook/presto/type/IntervalYearMonthOperators.java +++ b/presto-main/src/main/java/com/facebook/presto/type/IntervalYearMonthOperators.java @@ -14,6 +14,9 @@ package com.facebook.presto.type; import com.facebook.presto.client.IntervalYearMonth; +import com.facebook.presto.spi.block.Block; +import com.facebook.presto.spi.function.BlockIndex; +import com.facebook.presto.spi.function.BlockPosition; import com.facebook.presto.spi.function.IsNull; import com.facebook.presto.spi.function.LiteralParameters; import com.facebook.presto.spi.function.ScalarOperator; @@ -38,6 +41,7 @@ import static com.facebook.presto.spi.function.OperatorType.NEGATION; import static com.facebook.presto.spi.function.OperatorType.NOT_EQUAL; import static com.facebook.presto.spi.function.OperatorType.SUBTRACT; +import static com.facebook.presto.type.IntervalYearMonthType.INTERVAL_YEAR_MONTH; import static io.airlift.slice.Slices.utf8Slice; import static java.lang.Math.toIntExact; @@ -171,20 +175,39 @@ public static long hashCode(@SqlType(StandardTypes.INTERVAL_YEAR_TO_MONTH) long } @ScalarOperator(IS_DISTINCT_FROM) - @SqlType(StandardTypes.BOOLEAN) - public static boolean isDistinctFrom( - @SqlType(StandardTypes.INTERVAL_YEAR_TO_MONTH) long left, - @IsNull boolean leftNull, - @SqlType(StandardTypes.INTERVAL_YEAR_TO_MONTH) long right, - @IsNull boolean rightNull) - { - if (leftNull != rightNull) { - return true; + public static class IntervalYearMonthIsDistinctFrom + { + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @SqlType(StandardTypes.INTERVAL_YEAR_TO_MONTH) long left, + @IsNull boolean leftNull, + @SqlType(StandardTypes.INTERVAL_YEAR_TO_MONTH) long right, + @IsNull boolean rightNull) + { + if (leftNull != rightNull) { + return true; + } + if (leftNull) { + return false; + } + return notEqual(left, right); } - if (leftNull) { - return false; + + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @BlockPosition @SqlType(value = StandardTypes.INTERVAL_YEAR_TO_MONTH, nativeContainerType = long.class) Block left, + @BlockIndex int leftPosition, + @BlockPosition @SqlType(value = StandardTypes.INTERVAL_YEAR_TO_MONTH, nativeContainerType = long.class) Block right, + @BlockIndex int rightPosition) + { + if (left.isNull(leftPosition) != right.isNull(rightPosition)) { + return true; + } + if (left.isNull(leftPosition)) { + return false; + } + return !INTERVAL_YEAR_MONTH.equalTo(left, leftPosition, right, rightPosition); } - return notEqual(left, right); } @ScalarOperator(INDETERMINATE) diff --git a/presto-main/src/main/java/com/facebook/presto/type/IpAddressOperators.java b/presto-main/src/main/java/com/facebook/presto/type/IpAddressOperators.java index 7fde450860777..4a12eef8fbcfc 100644 --- a/presto-main/src/main/java/com/facebook/presto/type/IpAddressOperators.java +++ b/presto-main/src/main/java/com/facebook/presto/type/IpAddressOperators.java @@ -14,6 +14,9 @@ package com.facebook.presto.type; import com.facebook.presto.spi.PrestoException; +import com.facebook.presto.spi.block.Block; +import com.facebook.presto.spi.function.BlockIndex; +import com.facebook.presto.spi.function.BlockPosition; import com.facebook.presto.spi.function.IsNull; import com.facebook.presto.spi.function.LiteralParameters; import com.facebook.presto.spi.function.ScalarOperator; @@ -40,6 +43,7 @@ import static com.facebook.presto.spi.function.OperatorType.LESS_THAN_OR_EQUAL; import static com.facebook.presto.spi.function.OperatorType.NOT_EQUAL; import static com.facebook.presto.spi.function.OperatorType.XX_HASH_64; +import static com.facebook.presto.type.IpAddressType.IPADDRESS; import static io.airlift.slice.Slices.utf8Slice; import static io.airlift.slice.Slices.wrappedBuffer; import static java.lang.System.arraycopy; @@ -183,19 +187,38 @@ public static Slice castFromIpAddressToVarbinary(@SqlType(StandardTypes.IPADDRES } @ScalarOperator(IS_DISTINCT_FROM) - @SqlType(StandardTypes.BOOLEAN) - public static boolean isDistinctFrom(@SqlType(StandardTypes.IPADDRESS) Slice left, - @IsNull boolean leftNull, - @SqlType(StandardTypes.IPADDRESS) Slice right, - @IsNull boolean rightNull) - { - if (leftNull != rightNull) { - return true; + public static class IpAddressIsDistinctFrom + { + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom(@SqlType(StandardTypes.IPADDRESS) Slice left, + @IsNull boolean leftNull, + @SqlType(StandardTypes.IPADDRESS) Slice right, + @IsNull boolean rightNull) + { + if (leftNull != rightNull) { + return true; + } + if (leftNull) { + return false; + } + return notEqual(left, right); } - if (leftNull) { - return false; + + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @BlockPosition @SqlType(value = StandardTypes.IPADDRESS, nativeContainerType = Slice.class) Block left, + @BlockIndex int leftPosition, + @BlockPosition @SqlType(value = StandardTypes.IPADDRESS, nativeContainerType = Slice.class) Block right, + @BlockIndex int rightPosition) + { + if (left.isNull(leftPosition) != right.isNull(rightPosition)) { + return true; + } + if (left.isNull(leftPosition)) { + return false; + } + return !IPADDRESS.equalTo(left, leftPosition, right, rightPosition); } - return notEqual(left, right); } @ScalarOperator(INDETERMINATE) diff --git a/presto-main/src/main/java/com/facebook/presto/type/RealOperators.java b/presto-main/src/main/java/com/facebook/presto/type/RealOperators.java index dc05445801701..8a761032bf2b6 100644 --- a/presto-main/src/main/java/com/facebook/presto/type/RealOperators.java +++ b/presto-main/src/main/java/com/facebook/presto/type/RealOperators.java @@ -15,6 +15,9 @@ import com.facebook.presto.operator.scalar.MathFunctions; import com.facebook.presto.spi.PrestoException; +import com.facebook.presto.spi.block.Block; +import com.facebook.presto.spi.function.BlockIndex; +import com.facebook.presto.spi.function.BlockPosition; import com.facebook.presto.spi.function.IsNull; import com.facebook.presto.spi.function.LiteralParameters; import com.facebook.presto.spi.function.ScalarOperator; @@ -47,6 +50,7 @@ import static com.facebook.presto.spi.function.OperatorType.SATURATED_FLOOR_CAST; import static com.facebook.presto.spi.function.OperatorType.SUBTRACT; import static com.facebook.presto.spi.function.OperatorType.XX_HASH_64; +import static com.facebook.presto.spi.type.RealType.REAL; import static io.airlift.slice.Slices.utf8Slice; import static java.lang.Float.floatToIntBits; import static java.lang.Float.floatToRawIntBits; @@ -241,25 +245,44 @@ public static boolean castToBoolean(@SqlType(StandardTypes.REAL) long value) } @ScalarOperator(IS_DISTINCT_FROM) - @SqlType(StandardTypes.BOOLEAN) - public static boolean isDistinctFrom( - @SqlType(StandardTypes.REAL) long left, - @IsNull boolean leftNull, - @SqlType(StandardTypes.REAL) long right, - @IsNull boolean rightNull) + public static class RealIsDistinctFrom { - if (leftNull != rightNull) { - return true; - } - if (leftNull) { - return false; + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @SqlType(StandardTypes.REAL) long left, + @IsNull boolean leftNull, + @SqlType(StandardTypes.REAL) long right, + @IsNull boolean rightNull) + { + if (leftNull != rightNull) { + return true; + } + if (leftNull) { + return false; + } + float leftFloat = intBitsToFloat((int) left); + float rightFloat = intBitsToFloat((int) right); + if (Float.isNaN(leftFloat) && Float.isNaN(rightFloat)) { + return false; + } + return notEqual(left, right); } - float leftFloat = intBitsToFloat((int) left); - float rightFloat = intBitsToFloat((int) right); - if (Float.isNaN(leftFloat) && Float.isNaN(rightFloat)) { - return false; + + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @BlockPosition @SqlType(value = StandardTypes.REAL, nativeContainerType = long.class) Block left, + @BlockIndex int leftPosition, + @BlockPosition @SqlType(value = StandardTypes.REAL, nativeContainerType = long.class) Block right, + @BlockIndex int rightPosition) + { + if (left.isNull(leftPosition) != right.isNull(rightPosition)) { + return true; + } + if (left.isNull(leftPosition)) { + return false; + } + return !REAL.equalTo(left, leftPosition, right, rightPosition); } - return notEqual(left, right); } @ScalarOperator(SATURATED_FLOOR_CAST) diff --git a/presto-main/src/main/java/com/facebook/presto/type/SmallintOperators.java b/presto-main/src/main/java/com/facebook/presto/type/SmallintOperators.java index 882653c20c5f6..0ea6e8d1b0318 100644 --- a/presto-main/src/main/java/com/facebook/presto/type/SmallintOperators.java +++ b/presto-main/src/main/java/com/facebook/presto/type/SmallintOperators.java @@ -14,6 +14,9 @@ package com.facebook.presto.type; import com.facebook.presto.spi.PrestoException; +import com.facebook.presto.spi.block.Block; +import com.facebook.presto.spi.function.BlockIndex; +import com.facebook.presto.spi.function.BlockPosition; import com.facebook.presto.spi.function.IsNull; import com.facebook.presto.spi.function.LiteralParameters; import com.facebook.presto.spi.function.ScalarOperator; @@ -46,6 +49,7 @@ import static com.facebook.presto.spi.function.OperatorType.SATURATED_FLOOR_CAST; import static com.facebook.presto.spi.function.OperatorType.SUBTRACT; import static com.facebook.presto.spi.function.OperatorType.XX_HASH_64; +import static com.facebook.presto.spi.type.SmallintType.SMALLINT; import static io.airlift.slice.Slices.utf8Slice; import static java.lang.Float.floatToRawIntBits; import static java.lang.String.format; @@ -241,20 +245,39 @@ public static long hashCode(@SqlType(StandardTypes.SMALLINT) long value) } @ScalarOperator(IS_DISTINCT_FROM) - @SqlType(StandardTypes.BOOLEAN) - public static boolean isDistinctFrom( - @SqlType(StandardTypes.SMALLINT) long left, - @IsNull boolean leftNull, - @SqlType(StandardTypes.SMALLINT) long right, - @IsNull boolean rightNull) + public static class SmallIntIsDistinctFrom { - if (leftNull != rightNull) { - return true; + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @SqlType(StandardTypes.SMALLINT) long left, + @IsNull boolean leftNull, + @SqlType(StandardTypes.SMALLINT) long right, + @IsNull boolean rightNull) + { + if (leftNull != rightNull) { + return true; + } + if (leftNull) { + return false; + } + return notEqual(left, right); } - if (leftNull) { - return false; + + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @BlockPosition @SqlType(value = StandardTypes.SMALLINT, nativeContainerType = long.class) Block left, + @BlockIndex int leftPosition, + @BlockPosition @SqlType(value = StandardTypes.SMALLINT, nativeContainerType = long.class) Block right, + @BlockIndex int rightPosition) + { + if (left.isNull(leftPosition) != right.isNull(rightPosition)) { + return true; + } + if (left.isNull(leftPosition)) { + return false; + } + return !SMALLINT.equalTo(left, leftPosition, right, rightPosition); } - return notEqual(left, right); } @ScalarOperator(SATURATED_FLOOR_CAST) diff --git a/presto-main/src/main/java/com/facebook/presto/type/TimeOperators.java b/presto-main/src/main/java/com/facebook/presto/type/TimeOperators.java index f5b53008bcae4..72b8a737b050b 100644 --- a/presto-main/src/main/java/com/facebook/presto/type/TimeOperators.java +++ b/presto-main/src/main/java/com/facebook/presto/type/TimeOperators.java @@ -15,6 +15,9 @@ import com.facebook.presto.spi.ConnectorSession; import com.facebook.presto.spi.PrestoException; +import com.facebook.presto.spi.block.Block; +import com.facebook.presto.spi.function.BlockIndex; +import com.facebook.presto.spi.function.BlockPosition; import com.facebook.presto.spi.function.IsNull; import com.facebook.presto.spi.function.LiteralParameters; import com.facebook.presto.spi.function.ScalarOperator; @@ -40,6 +43,7 @@ import static com.facebook.presto.spi.function.OperatorType.SUBTRACT; import static com.facebook.presto.spi.function.OperatorType.XX_HASH_64; import static com.facebook.presto.spi.type.DateTimeEncoding.packDateTimeWithZone; +import static com.facebook.presto.spi.type.TimeType.TIME; import static com.facebook.presto.util.DateTimeUtils.parseTimeWithoutTimeZone; import static com.facebook.presto.util.DateTimeUtils.printTimeWithoutTimeZone; import static com.facebook.presto.util.DateTimeZoneIndex.getChronology; @@ -186,20 +190,39 @@ public static long xxHash64(@SqlType(StandardTypes.TIME) long value) } @ScalarOperator(IS_DISTINCT_FROM) - @SqlType(StandardTypes.BOOLEAN) - public static boolean isDistinctFrom( - @SqlType(StandardTypes.TIME) long left, - @IsNull boolean leftNull, - @SqlType(StandardTypes.TIME) long right, - @IsNull boolean rightNull) - { - if (leftNull != rightNull) { - return true; + public static class TimeIsDistinctFrom + { + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @SqlType(StandardTypes.TIME) long left, + @IsNull boolean leftNull, + @SqlType(StandardTypes.TIME) long right, + @IsNull boolean rightNull) + { + if (leftNull != rightNull) { + return true; + } + if (leftNull) { + return false; + } + return notEqual(left, right); } - if (leftNull) { - return false; + + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @BlockPosition @SqlType(value = StandardTypes.TIME, nativeContainerType = long.class) Block left, + @BlockIndex int leftPosition, + @BlockPosition @SqlType(value = StandardTypes.TIME, nativeContainerType = long.class) Block right, + @BlockIndex int rightPosition) + { + if (left.isNull(leftPosition) != right.isNull(rightPosition)) { + return true; + } + if (left.isNull(leftPosition)) { + return false; + } + return !TIME.equalTo(left, leftPosition, right, rightPosition); } - return notEqual(left, right); } @ScalarOperator(INDETERMINATE) diff --git a/presto-main/src/main/java/com/facebook/presto/type/TimeWithTimeZoneOperators.java b/presto-main/src/main/java/com/facebook/presto/type/TimeWithTimeZoneOperators.java index 15b17ccde02d9..9e70bef27588f 100644 --- a/presto-main/src/main/java/com/facebook/presto/type/TimeWithTimeZoneOperators.java +++ b/presto-main/src/main/java/com/facebook/presto/type/TimeWithTimeZoneOperators.java @@ -14,6 +14,9 @@ package com.facebook.presto.type; import com.facebook.presto.spi.ConnectorSession; +import com.facebook.presto.spi.block.Block; +import com.facebook.presto.spi.function.BlockIndex; +import com.facebook.presto.spi.function.BlockPosition; import com.facebook.presto.spi.function.IsNull; import com.facebook.presto.spi.function.LiteralParameters; import com.facebook.presto.spi.function.ScalarOperator; @@ -43,6 +46,7 @@ import static com.facebook.presto.spi.function.OperatorType.XX_HASH_64; import static com.facebook.presto.spi.type.DateTimeEncoding.unpackMillisUtc; import static com.facebook.presto.spi.type.DateTimeEncoding.unpackZoneKey; +import static com.facebook.presto.spi.type.TimeWithTimeZoneType.TIME_WITH_TIME_ZONE; import static com.facebook.presto.util.DateTimeUtils.parseTimeWithTimeZone; import static com.facebook.presto.util.DateTimeUtils.printTimeWithTimeZone; import static com.facebook.presto.util.DateTimeZoneIndex.getChronology; @@ -177,20 +181,39 @@ public static long xxHash64(@SqlType(StandardTypes.TIME_WITH_TIME_ZONE) long val } @ScalarOperator(IS_DISTINCT_FROM) - @SqlType(StandardTypes.BOOLEAN) - public static boolean isDistinctFrom( - @SqlType(StandardTypes.TIME_WITH_TIME_ZONE) long left, - @IsNull boolean leftNull, - @SqlType(StandardTypes.TIME_WITH_TIME_ZONE) long right, - @IsNull boolean rightNull) - { - if (leftNull != rightNull) { - return true; + public static class TimeWithTimeZoneIsDistinctFrom + { + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @SqlType(StandardTypes.TIME_WITH_TIME_ZONE) long left, + @IsNull boolean leftNull, + @SqlType(StandardTypes.TIME_WITH_TIME_ZONE) long right, + @IsNull boolean rightNull) + { + if (leftNull != rightNull) { + return true; + } + if (leftNull) { + return false; + } + return notEqual(left, right); } - if (leftNull) { - return false; + + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @BlockPosition @SqlType(value = StandardTypes.TIME_WITH_TIME_ZONE, nativeContainerType = long.class) Block left, + @BlockIndex int leftPosition, + @BlockPosition @SqlType(value = StandardTypes.TIME_WITH_TIME_ZONE, nativeContainerType = long.class) Block right, + @BlockIndex int rightPosition) + { + if (left.isNull(leftPosition) && right.isNull(rightPosition)) { + return false; + } + if (left.isNull(leftPosition)) { + return false; + } + return !TIME_WITH_TIME_ZONE.equalTo(left, leftPosition, right, rightPosition); } - return notEqual(left, right); } @ScalarOperator(INDETERMINATE) diff --git a/presto-main/src/main/java/com/facebook/presto/type/TimestampOperators.java b/presto-main/src/main/java/com/facebook/presto/type/TimestampOperators.java index 2200677f25b6e..c2c78545a22dc 100644 --- a/presto-main/src/main/java/com/facebook/presto/type/TimestampOperators.java +++ b/presto-main/src/main/java/com/facebook/presto/type/TimestampOperators.java @@ -15,6 +15,9 @@ import com.facebook.presto.spi.ConnectorSession; import com.facebook.presto.spi.PrestoException; +import com.facebook.presto.spi.block.Block; +import com.facebook.presto.spi.function.BlockIndex; +import com.facebook.presto.spi.function.BlockPosition; import com.facebook.presto.spi.function.IsNull; import com.facebook.presto.spi.function.LiteralParameters; import com.facebook.presto.spi.function.ScalarFunction; @@ -43,6 +46,7 @@ import static com.facebook.presto.spi.function.OperatorType.SUBTRACT; import static com.facebook.presto.spi.function.OperatorType.XX_HASH_64; import static com.facebook.presto.spi.type.DateTimeEncoding.packDateTimeWithZone; +import static com.facebook.presto.spi.type.TimestampType.TIMESTAMP; import static com.facebook.presto.type.DateTimeOperators.modulo24Hour; import static com.facebook.presto.util.DateTimeUtils.parseTimestampWithoutTimeZone; import static com.facebook.presto.util.DateTimeUtils.printTimestampWithoutTimeZone; @@ -222,20 +226,39 @@ public static long hashCode(@SqlType(StandardTypes.TIMESTAMP) long value) } @ScalarOperator(IS_DISTINCT_FROM) - @SqlType(StandardTypes.BOOLEAN) - public static boolean isDistinctFrom( - @SqlType(StandardTypes.TIMESTAMP) long left, - @IsNull boolean leftNull, - @SqlType(StandardTypes.TIMESTAMP) long right, - @IsNull boolean rightNull) - { - if (leftNull != rightNull) { - return true; + public static class TimestampIsDistinctFrom + { + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @SqlType(StandardTypes.TIMESTAMP) long left, + @IsNull boolean leftNull, + @SqlType(StandardTypes.TIMESTAMP) long right, + @IsNull boolean rightNull) + { + if (leftNull != rightNull) { + return true; + } + if (leftNull) { + return false; + } + return notEqual(left, right); } - if (leftNull) { - return false; + + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @BlockPosition @SqlType(value = StandardTypes.TIMESTAMP, nativeContainerType = long.class) Block left, + @BlockIndex int leftPosition, + @BlockPosition @SqlType(value = StandardTypes.TIMESTAMP, nativeContainerType = long.class) Block right, + @BlockIndex int rightPosition) + { + if (left.isNull(leftPosition) != right.isNull(rightPosition)) { + return true; + } + if (left.isNull(leftPosition)) { + return false; + } + return !TIMESTAMP.equalTo(left, leftPosition, right, rightPosition); } - return notEqual(left, right); } @ScalarOperator(INDETERMINATE) diff --git a/presto-main/src/main/java/com/facebook/presto/type/TimestampWithTimeZoneOperators.java b/presto-main/src/main/java/com/facebook/presto/type/TimestampWithTimeZoneOperators.java index 6c7550f241f07..87773b5c0f9e3 100644 --- a/presto-main/src/main/java/com/facebook/presto/type/TimestampWithTimeZoneOperators.java +++ b/presto-main/src/main/java/com/facebook/presto/type/TimestampWithTimeZoneOperators.java @@ -15,6 +15,9 @@ import com.facebook.presto.spi.ConnectorSession; import com.facebook.presto.spi.PrestoException; +import com.facebook.presto.spi.block.Block; +import com.facebook.presto.spi.function.BlockIndex; +import com.facebook.presto.spi.function.BlockPosition; import com.facebook.presto.spi.function.IsNull; import com.facebook.presto.spi.function.LiteralParameters; import com.facebook.presto.spi.function.ScalarFunction; @@ -45,6 +48,7 @@ import static com.facebook.presto.spi.type.DateTimeEncoding.packDateTimeWithZone; import static com.facebook.presto.spi.type.DateTimeEncoding.unpackMillisUtc; import static com.facebook.presto.spi.type.DateTimeEncoding.unpackZoneKey; +import static com.facebook.presto.spi.type.TimestampWithTimeZoneType.TIMESTAMP_WITH_TIME_ZONE; import static com.facebook.presto.type.DateTimeOperators.modulo24Hour; import static com.facebook.presto.util.DateTimeUtils.parseTimestampWithTimeZone; import static com.facebook.presto.util.DateTimeUtils.printTimestampWithTimeZone; @@ -214,20 +218,39 @@ public static long xxHash64(@SqlType(StandardTypes.TIMESTAMP_WITH_TIME_ZONE) lon } @ScalarOperator(IS_DISTINCT_FROM) - @SqlType(StandardTypes.BOOLEAN) - public static boolean isDistinctFrom( - @SqlType(StandardTypes.TIMESTAMP_WITH_TIME_ZONE) long left, - @IsNull boolean leftNull, - @SqlType(StandardTypes.TIMESTAMP_WITH_TIME_ZONE) long right, - @IsNull boolean rightNull) - { - if (leftNull != rightNull) { - return true; + public static class TimestampWithTimeZoneIsDistinctFrom + { + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @SqlType(StandardTypes.TIMESTAMP_WITH_TIME_ZONE) long left, + @IsNull boolean leftNull, + @SqlType(StandardTypes.TIMESTAMP_WITH_TIME_ZONE) long right, + @IsNull boolean rightNull) + { + if (leftNull != rightNull) { + return true; + } + if (leftNull) { + return false; + } + return notEqual(left, right); } - if (leftNull) { - return false; + + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @BlockPosition @SqlType(value = StandardTypes.TIMESTAMP_WITH_TIME_ZONE, nativeContainerType = long.class) Block left, + @BlockIndex int leftPosition, + @BlockPosition @SqlType(value = StandardTypes.TIMESTAMP_WITH_TIME_ZONE, nativeContainerType = long.class) Block right, + @BlockIndex int rightPosition) + { + if (left.isNull(leftPosition) != right.isNull(rightPosition)) { + return true; + } + if (left.isNull(leftPosition)) { + return false; + } + return !TIMESTAMP_WITH_TIME_ZONE.equalTo(left, leftPosition, right, rightPosition); } - return notEqual(left, right); } @ScalarOperator(INDETERMINATE) diff --git a/presto-main/src/main/java/com/facebook/presto/type/TinyintOperators.java b/presto-main/src/main/java/com/facebook/presto/type/TinyintOperators.java index b2ac0d7cf082a..fa233eed5f2c8 100644 --- a/presto-main/src/main/java/com/facebook/presto/type/TinyintOperators.java +++ b/presto-main/src/main/java/com/facebook/presto/type/TinyintOperators.java @@ -14,6 +14,9 @@ package com.facebook.presto.type; import com.facebook.presto.spi.PrestoException; +import com.facebook.presto.spi.block.Block; +import com.facebook.presto.spi.function.BlockIndex; +import com.facebook.presto.spi.function.BlockPosition; import com.facebook.presto.spi.function.IsNull; import com.facebook.presto.spi.function.LiteralParameters; import com.facebook.presto.spi.function.ScalarOperator; @@ -44,6 +47,7 @@ import static com.facebook.presto.spi.function.OperatorType.NOT_EQUAL; import static com.facebook.presto.spi.function.OperatorType.SUBTRACT; import static com.facebook.presto.spi.function.OperatorType.XX_HASH_64; +import static com.facebook.presto.spi.type.TinyintType.TINYINT; import static io.airlift.slice.Slices.utf8Slice; import static java.lang.Float.floatToRawIntBits; import static java.lang.String.format; @@ -241,20 +245,39 @@ public static long xxHash64(@SqlType(StandardTypes.TINYINT) long value) } @ScalarOperator(IS_DISTINCT_FROM) - @SqlType(StandardTypes.BOOLEAN) - public static boolean isDistinctFrom( - @SqlType(StandardTypes.TINYINT) long left, - @IsNull boolean leftNull, - @SqlType(StandardTypes.TINYINT) long right, - @IsNull boolean rightNull) + public static class TinyIntIsDistinctFrom { - if (leftNull != rightNull) { - return true; + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @SqlType(StandardTypes.TINYINT) long left, + @IsNull boolean leftNull, + @SqlType(StandardTypes.TINYINT) long right, + @IsNull boolean rightNull) + { + if (leftNull != rightNull) { + return true; + } + if (leftNull) { + return false; + } + return notEqual(left, right); } - if (leftNull) { - return false; + + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @BlockPosition @SqlType(value = StandardTypes.TINYINT, nativeContainerType = long.class) Block left, + @BlockIndex int leftPosition, + @BlockPosition @SqlType(value = StandardTypes.TINYINT, nativeContainerType = long.class) Block right, + @BlockIndex int rightPosition) + { + if (left.isNull(leftPosition) != right.isNull(rightPosition)) { + return true; + } + if (left.isNull(leftPosition)) { + return false; + } + return !TINYINT.equalTo(left, leftPosition, right, rightPosition); } - return notEqual(left, right); } @ScalarOperator(INDETERMINATE) diff --git a/presto-main/src/main/java/com/facebook/presto/type/UnknownOperators.java b/presto-main/src/main/java/com/facebook/presto/type/UnknownOperators.java index 32241a65ad96e..b445c00a5367a 100644 --- a/presto-main/src/main/java/com/facebook/presto/type/UnknownOperators.java +++ b/presto-main/src/main/java/com/facebook/presto/type/UnknownOperators.java @@ -13,6 +13,9 @@ */ package com.facebook.presto.type; +import com.facebook.presto.spi.block.Block; +import com.facebook.presto.spi.function.BlockIndex; +import com.facebook.presto.spi.function.BlockPosition; import com.facebook.presto.spi.function.IsNull; import com.facebook.presto.spi.function.ScalarOperator; import com.facebook.presto.spi.function.SqlNullable; @@ -93,14 +96,27 @@ public static long hashCode(@SqlType("unknown") boolean value) } @ScalarOperator(IS_DISTINCT_FROM) - @SqlType(StandardTypes.BOOLEAN) - public static boolean isDistinctFrom( - @SqlType("unknown") boolean left, - @IsNull boolean leftNull, - @SqlType("unknown") boolean right, - @IsNull boolean rightNull) + public static class UnknownIsDistinctFrom { - return false; + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @SqlType("unknown") boolean left, + @IsNull boolean leftNull, + @SqlType("unknown") boolean right, + @IsNull boolean rightNull) + { + return false; + } + + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @BlockPosition @SqlType(value = "unknown", nativeContainerType = boolean.class) Block left, + @BlockIndex int leftPosition, + @BlockPosition @SqlType(value = "unknown", nativeContainerType = boolean.class) Block right, + @BlockIndex int rightNull) + { + return false; + } } @ScalarOperator(INDETERMINATE) diff --git a/presto-main/src/main/java/com/facebook/presto/type/VarbinaryOperators.java b/presto-main/src/main/java/com/facebook/presto/type/VarbinaryOperators.java index a89631fb045b6..c7cf0365501b5 100644 --- a/presto-main/src/main/java/com/facebook/presto/type/VarbinaryOperators.java +++ b/presto-main/src/main/java/com/facebook/presto/type/VarbinaryOperators.java @@ -13,6 +13,9 @@ */ package com.facebook.presto.type; +import com.facebook.presto.spi.block.Block; +import com.facebook.presto.spi.function.BlockIndex; +import com.facebook.presto.spi.function.BlockPosition; import com.facebook.presto.spi.function.IsNull; import com.facebook.presto.spi.function.ScalarOperator; import com.facebook.presto.spi.function.SqlType; @@ -98,20 +101,45 @@ public static long hashCode(@SqlType(StandardTypes.VARBINARY) Slice value) } @ScalarOperator(IS_DISTINCT_FROM) - @SqlType(StandardTypes.BOOLEAN) - public static boolean isDistinctFrom( - @SqlType(StandardTypes.VARBINARY) Slice left, - @IsNull boolean leftNull, - @SqlType(StandardTypes.VARBINARY) Slice right, - @IsNull boolean rightNull) + public static class VarbinaryIsDistinctFrom { - if (leftNull != rightNull) { - return true; + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @SqlType(StandardTypes.VARBINARY) Slice left, + @IsNull boolean leftNull, + @SqlType(StandardTypes.VARBINARY) Slice right, + @IsNull boolean rightNull) + { + if (leftNull != rightNull) { + return true; + } + if (leftNull) { + return false; + } + return notEqual(left, right); } - if (leftNull) { - return false; + + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @BlockPosition @SqlType(value = StandardTypes.VARBINARY, nativeContainerType = Slice.class) Block left, + @BlockIndex int leftPosition, + @BlockPosition @SqlType(value = StandardTypes.VARBINARY, nativeContainerType = Slice.class) Block right, + @BlockIndex int rightPosition) + { + if (left.isNull(leftPosition) != right.isNull(rightPosition)) { + return true; + } + if (left.isNull(leftPosition)) { + return false; + } + + int leftLength = left.getSliceLength(leftPosition); + int rightLength = right.getSliceLength(rightPosition); + if (leftLength != rightLength) { + return true; + } + return !left.equals(leftPosition, 0, right, rightPosition, 0, leftLength); } - return notEqual(left, right); } @ScalarOperator(XX_HASH_64) diff --git a/presto-main/src/main/java/com/facebook/presto/type/VarcharOperators.java b/presto-main/src/main/java/com/facebook/presto/type/VarcharOperators.java index e53eb6d12ba5f..703122076a596 100644 --- a/presto-main/src/main/java/com/facebook/presto/type/VarcharOperators.java +++ b/presto-main/src/main/java/com/facebook/presto/type/VarcharOperators.java @@ -14,6 +14,9 @@ package com.facebook.presto.type; import com.facebook.presto.spi.PrestoException; +import com.facebook.presto.spi.block.Block; +import com.facebook.presto.spi.function.BlockIndex; +import com.facebook.presto.spi.function.BlockPosition; import com.facebook.presto.spi.function.IsNull; import com.facebook.presto.spi.function.LiteralParameters; import com.facebook.presto.spi.function.ScalarOperator; @@ -235,22 +238,48 @@ public static long hashCode(@SqlType("varchar(x)") Slice value) return xxHash64(value); } - @LiteralParameters({"x", "y"}) @ScalarOperator(IS_DISTINCT_FROM) - @SqlType(StandardTypes.BOOLEAN) - public static boolean isDistinctFrom( - @SqlType("varchar(x)") Slice left, - @IsNull boolean leftNull, - @SqlType("varchar(y)") Slice right, - @IsNull boolean rightNull) + public static class VarcharIsDistinctFrom { - if (leftNull != rightNull) { - return true; + @LiteralParameters({"x", "y"}) + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @SqlType("varchar(x)") Slice left, + @IsNull boolean leftNull, + @SqlType("varchar(y)") Slice right, + @IsNull boolean rightNull) + { + if (leftNull != rightNull) { + return true; + } + if (leftNull) { + return false; + } + return notEqual(left, right); } - if (leftNull) { - return false; + + @LiteralParameters({"x", "y"}) + @SqlType(StandardTypes.BOOLEAN) + public static boolean isDistinctFrom( + @BlockPosition @SqlType(value = "varchar(x)", nativeContainerType = Slice.class) Block left, + @BlockIndex int leftPosition, + @BlockPosition @SqlType(value = "varchar(y)", nativeContainerType = Slice.class) Block right, + @BlockIndex int rightPosition) + { + if (left.isNull(leftPosition) != right.isNull(rightPosition)) { + return true; + } + if (left.isNull(leftPosition)) { + return false; + } + + int leftLength = left.getSliceLength(leftPosition); + int rightLength = right.getSliceLength(rightPosition); + if (leftLength != rightLength) { + return true; + } + return !left.equals(leftPosition, 0, right, rightPosition, 0, leftLength); } - return notEqual(left, right); } @LiteralParameters("x")