-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Add block/position convention to all distinct from operators #11983
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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.function.InvocationConvention.InvocationArgumentConvention.NULL_FLAG; | ||
| import static com.facebook.presto.spi.function.InvocationConvention.InvocationArgumentConvention.BLOCK_POSITION; | ||
| import static com.facebook.presto.spi.function.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,8 +44,8 @@ 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, | ||
| @TypeParameter("E") Type type, | ||
| convention = @Convention(arguments = {BLOCK_POSITION, BLOCK_POSITION}, result = FAIL_ON_NULL)) MethodHandle function, | ||
| @TypeParameter("array(E)") Type type, | ||
| @SqlType("array(E)") Block left, | ||
| @IsNull boolean leftNull, | ||
| @SqlType("array(E)") Block right, | ||
|
|
@@ -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)) { | ||
| if ((boolean) function.invokeExact( | ||
| left, | ||
|
||
| i, | ||
| right, | ||
| i)) { | ||
| return true; | ||
| } | ||
| } | ||
|
|
@@ -86,4 +76,27 @@ 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 elementIsDistinctFrom, | ||
| @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( | ||
| elementIsDistinctFrom, | ||
| type, | ||
| (Block) type.getObject(left, leftPosition), | ||
| left.isNull(leftPosition), | ||
| (Block) type.getObject(right, rightPosition), | ||
| right.isNull(rightPosition)); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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; | ||
|
|
@@ -391,15 +394,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 JsonDistinctFromOperator | ||
| { | ||
| 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); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,20 +14,23 @@ | |
| */ | ||
|
|
||
| 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.function.OperatorType.EQUAL; | ||
| import static com.facebook.presto.spi.function.OperatorType.HASH_CODE; | ||
| import static com.facebook.presto.spi.function.InvocationConvention.InvocationArgumentConvention.BLOCK_POSITION; | ||
| import static com.facebook.presto.spi.function.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; | ||
|
|
||
| @ScalarOperator(IS_DISTINCT_FROM) | ||
| public final class MapDistinctFromOperator | ||
|
|
@@ -38,14 +41,9 @@ private MapDistinctFromOperator() {} | |
| @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"}) | ||
| @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 +57,30 @@ 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.invokeExact(leftMapBlock, leftMapIndex, rightMapBlock, rightMapIndex)); | ||
| } | ||
|
|
||
| @TypeParameter("K") | ||
| @TypeParameter("V") | ||
| @SqlType(StandardTypes.BOOLEAN) | ||
| public static boolean isDistinctFrom( | ||
| @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( | ||
| valueDistinctFromFunction, | ||
| mapType, | ||
| (Block) mapType.getObject(left, leftPosition), | ||
| left.isNull(leftPosition), | ||
| (Block) mapType.getObject(right, rightPosition), | ||
| right.isNull(rightPosition)); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can be at the same time rename
functionto egelementIsDistinct?