This is an automated email from the ASF dual-hosted git repository.
dzamo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/drill.git
The following commit(s) were added to refs/heads/master by this push:
new d088f47 Drill 7955: Extend XOR bitwise functions to match AND and OR
(#2264)
d088f47 is described below
commit d088f471f1ce30edda84e34027f11322d8940961
Author: dzamo <[email protected]>
AuthorDate: Fri Jun 25 15:15:15 2021 +0200
Drill 7955: Extend XOR bitwise functions to match AND and OR (#2264)
* DRILL-7955: Add BIT_XOR aggregate function for bitwise XOR.
* DRILL-7955: Support all integer types for the scalar XOR (^) function.
* DRILL-7955: Add tests for BIT_XOR aggregate function.
* DRILL-7955: Replace tabs with spaces.
---
.../main/codegen/data/AggrBitwiseLogicalTypes.tdd | 19 ++++++++++++
exec/java-exec/src/main/codegen/data/MathFunc.tdd | 21 +++++++++----
.../templates/AggrBitwiseLogicalTypeFunctions.java | 8 +++++
.../src/main/codegen/templates/MathFunctions.java | 6 +++-
.../drill/exec/expr/fn/impl/BitFunctions.java | 19 ------------
.../exec/fn/impl/TestNewAggregateFunctions.java | 2 +-
.../drill/exec/fn/impl/TestNewMathFunctions.java | 17 +++++++----
.../test/resources/functions/testBitTwiddlers.json | 34 ++++++++++++++++++++++
.../resources/functions/test_logical_aggr.json | 11 ++++++-
.../src/test/resources/logical_aggr_input.json | 2 +-
10 files changed, 106 insertions(+), 33 deletions(-)
diff --git a/exec/java-exec/src/main/codegen/data/AggrBitwiseLogicalTypes.tdd
b/exec/java-exec/src/main/codegen/data/AggrBitwiseLogicalTypes.tdd
index 2ed875a..0c3cef3 100644
--- a/exec/java-exec/src/main/codegen/data/AggrBitwiseLogicalTypes.tdd
+++ b/exec/java-exec/src/main/codegen/data/AggrBitwiseLogicalTypes.tdd
@@ -55,6 +55,25 @@
{inputType: "UInt8", outputType: "NullableUInt8", maxval: "Long"},
{inputType: "NullableUInt8", outputType: "NullableUInt8", maxval: "Long"}
]
+ },
+ {className: "BitwiseXor", funcName: "bit_xor", aliasName: "", types: [
+ {inputType: "BigInt", outputType: "NullableBigInt", maxval: "Integer"},
+ {inputType: "NullableBigInt", outputType: "NullableBigInt", maxval:
"Integer"},
+ {inputType: "Int", outputType: "NullableInt", maxval: "Integer"},
+ {inputType: "NullableInt", outputType: "NullableInt", maxval: "Integer"},
+ {inputType: "SmallInt", outputType: "NullableSmallInt", maxval: "Byte",
extraCast: "short"},
+ {inputType: "NullableSmallInt", outputType: "NullableSmallInt", maxval:
"Byte", extraCast: "short"},
+ {inputType: "TinyInt", outputType: "NullableTinyInt", maxval: "Byte",
extraCast: "byte"},
+ {inputType: "NullableTinyInt", outputType: "NullableTinyInt", maxval:
"Byte", extraCast: "byte"},
+ {inputType: "UInt1", outputType: "NullableInt", maxval: "Byte"},
+ {inputType: "NullableUInt1", outputType: "NullableInt", maxval: "Byte"},
+ {inputType: "UInt2", outputType: "NullableInt", maxval: "Character"},
+ {inputType: "NullableUInt2", outputType: "NullableInt", maxval:
"Character"},
+ {inputType: "UInt4", outputType: "NullableInt", maxval: "Integer"},
+ {inputType: "NullableUInt4", outputType: "NullableInt", maxval:
"Integer"},
+ {inputType: "UInt8", outputType: "NullableUInt8", maxval: "Long"},
+ {inputType: "NullableUInt8", outputType: "NullableUInt8", maxval: "Long"}
+ ]
}
]
}
diff --git a/exec/java-exec/src/main/codegen/data/MathFunc.tdd
b/exec/java-exec/src/main/codegen/data/MathFunc.tdd
index 6f9e4ad..06f3ec8 100644
--- a/exec/java-exec/src/main/codegen/data/MathFunc.tdd
+++ b/exec/java-exec/src/main/codegen/data/MathFunc.tdd
@@ -112,7 +112,7 @@ unaryMathFunctions : [
}
],
binaryMathFunctions : [
- {className: "Div", funcName: "div", javaFunc : " / ", types: [
+ {className: "Div", funcName: "div", aliasName: "", javaFunc : " / ",
types: [
{input: "Int", outputType: "Int", castType: "int"},
{input: "BigInt", outputType: "BigInt", castType: "long"},
{input: "Float4", outputType: "Float4", castType: "float",
roundingRequired: "true"},
@@ -125,7 +125,7 @@ unaryMathFunctions : [
{input: "UInt8", outputType: "UInt8", castType: "long"}
]
},
- {className: "Mod", funcName: "mod", javaFunc : " % ", types: [
+ {className: "Mod", funcName: "mod", aliasName: "", javaFunc : " % ",
types: [
{input: "Int", outputType: "Int", castType: "int"},
{input: "BigInt", outputType: "BigInt", castType: "long"},
{input: "Float4", outputType: "Float4", castType: "float"},
@@ -138,7 +138,7 @@ unaryMathFunctions : [
{input: "UInt8", outputType: "UInt8", castType: "long"}
]
},
- {className: "LeftShift", funcName: "lshift", javaFunc: " << ", types: [
+ {className: "LeftShift", funcName: "lshift", aliasName: "", javaFunc: " <<
", types: [
{input: "Int", outputType: "Int", castType: "int"},
{input: "BigInt", outputType: "BigInt", castType: "long"},
{input: "SmallInt", outputType: "SmallInt", castType: "short"},
@@ -149,7 +149,18 @@ unaryMathFunctions : [
{input: "UInt8", outputType: "UInt8", castType: "long"}
]
},
- {className: "RightShift", funcName: "rshift", javaFunc: " >> ", types: [
+ {className: "RightShift", funcName: "rshift", aliasName: "", javaFunc: "
>> ", types: [
+ {input: "Int", outputType: "Int", castType: "int"},
+ {input: "BigInt", outputType: "BigInt", castType: "long"},
+ {input: "SmallInt", outputType: "SmallInt", castType: "short"},
+ {input: "TinyInt", outputType: "TinyInt", castType: "byte"},
+ {input: "UInt1", outputType: "UInt1", castType: "byte"},
+ {input: "UInt2", outputType: "UInt2", castType: "char"},
+ {input: "UInt4", outputType: "UInt4", castType: "int"},
+ {input: "UInt8", outputType: "UInt8", castType: "long"}
+ ]
+ },
+ {className: "Xor", funcName: "xor", aliasName: "^", javaFunc: " ^ ",
types: [
{input: "Int", outputType: "Int", castType: "int"},
{input: "BigInt", outputType: "BigInt", castType: "long"},
{input: "SmallInt", outputType: "SmallInt", castType: "short"},
@@ -423,4 +434,4 @@ trigoMathFunctions : [
]
}
]
-}
\ No newline at end of file
+}
diff --git
a/exec/java-exec/src/main/codegen/templates/AggrBitwiseLogicalTypeFunctions.java
b/exec/java-exec/src/main/codegen/templates/AggrBitwiseLogicalTypeFunctions.java
index 0fac22e..daf28c4 100644
---
a/exec/java-exec/src/main/codegen/templates/AggrBitwiseLogicalTypeFunctions.java
+++
b/exec/java-exec/src/main/codegen/templates/AggrBitwiseLogicalTypeFunctions.java
@@ -85,6 +85,8 @@ public static class ${type.inputType}${aggrtype.className}
implements DrillAggFu
inter.value = ${type.maxval}.MAX_VALUE;
<#elseif aggrtype.funcName == "bit_or">
inter.value = 0;
+ <#elseif aggrtype.funcName == "bit_xor">
+ inter.value = 0;
</#if>
}
@@ -102,6 +104,8 @@ public static class ${type.inputType}${aggrtype.className}
implements DrillAggFu
inter.value = <#if type.extraCast ??>(${type.extraCast})</#if>(inter.value
& in.value);
<#elseif aggrtype.funcName == "bit_or">
inter.value = <#if type.extraCast ??>(${type.extraCast})</#if>(inter.value
| in.value);
+ <#elseif aggrtype.funcName == "bit_xor">
+ inter.value = <#if type.extraCast ??>(${type.extraCast})</#if>(inter.value
^ in.value);
</#if>
<#if type.inputType?starts_with("Nullable")>
@@ -117,6 +121,8 @@ public static class ${type.inputType}${aggrtype.className}
implements DrillAggFu
out.value = inter.value;
<#elseif aggrtype.funcName == "bit_or">
out.value = inter.value;
+ <#elseif aggrtype.funcName == "bit_xor">
+ out.value = inter.value;
</#if>
} else {
out.isSet = 0;
@@ -130,6 +136,8 @@ public static class ${type.inputType}${aggrtype.className}
implements DrillAggFu
inter.value = ${type.maxval}.MAX_VALUE;
<#elseif aggrtype.funcName == "bit_or">
inter.value = 0;
+ <#elseif aggrtype.funcName == "bit_xor">
+ inter.value = 0;
</#if>
}
}
diff --git a/exec/java-exec/src/main/codegen/templates/MathFunctions.java
b/exec/java-exec/src/main/codegen/templates/MathFunctions.java
index a17865c..518a461 100644
--- a/exec/java-exec/src/main/codegen/templates/MathFunctions.java
+++ b/exec/java-exec/src/main/codegen/templates/MathFunctions.java
@@ -105,7 +105,11 @@ public class GMathFunctions{
<#list mathFunc.binaryMathFunctions as func>
<#list func.types as type>
+ <#if func.aliasName == "">
@FunctionTemplate(name = "${func.funcName}", scope = FunctionScope.SIMPLE,
nulls = NullHandling.NULL_IF_NULL)
+ <#else>
+ @FunctionTemplate(names = {"${func.funcName}", "${func.aliasName}"}, scope =
FunctionScope.SIMPLE, nulls = NullHandling.NULL_IF_NULL)
+ </#if>
public static class ${func.className}${type.input} implements
DrillSimpleFunc {
@Param ${type.input}Holder input1;
@@ -321,4 +325,4 @@ public class TrigoMathFunctions{
}
</#list>
</#list>
-}
\ No newline at end of file
+}
diff --git
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/BitFunctions.java
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/BitFunctions.java
index e0bcb91..66bb8b0 100644
---
a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/BitFunctions.java
+++
b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/BitFunctions.java
@@ -25,7 +25,6 @@ import
org.apache.drill.exec.expr.annotations.FunctionTemplate.NullHandling;
import org.apache.drill.exec.expr.annotations.Output;
import org.apache.drill.exec.expr.annotations.Param;
import org.apache.drill.exec.expr.holders.BitHolder;
-import org.apache.drill.exec.expr.holders.IntHolder;
/**
* Function templates for Bit/BOOLEAN functions other than comparison
@@ -71,22 +70,4 @@ public class BitFunctions {
}
}
-
- @FunctionTemplate(names = {FunctionNames.XOR, "^"},
- scope = FunctionScope.SIMPLE,
- nulls = NullHandling.NULL_IF_NULL)
- public static class IntXor implements DrillSimpleFunc {
-
- @Param IntHolder left;
- @Param IntHolder right;
- @Output IntHolder out;
-
- @Override
- public void setup() {}
-
- @Override
- public void eval() {
- out.value = left.value ^ right.value;
- }
- }
}
diff --git
a/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestNewAggregateFunctions.java
b/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestNewAggregateFunctions.java
index 5cf943b..52287af 100644
---
a/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestNewAggregateFunctions.java
+++
b/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestNewAggregateFunctions.java
@@ -83,7 +83,7 @@ public class TestNewAggregateFunctions extends
PopUnitTestBase {
public void testBitwiseAggrFuncs() throws Exception {
String physicalPlan = "/functions/test_logical_aggr.json";
String inputDataFile = "/logical_aggr_input.json";
- Object[] expected = {0L, 4L, 4L, 7L, -2L, 1L, true, false};
+ Object[] expected = {0L, 4L, 4L, 7L, -2L, 1L, 3L, 4L, 0L, true, false};
runTest(physicalPlan, inputDataFile, expected);
diff --git
a/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestNewMathFunctions.java
b/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestNewMathFunctions.java
index 720359c..e8340a1 100644
---
a/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestNewMathFunctions.java
+++
b/exec/java-exec/src/test/java/org/apache/drill/exec/fn/impl/TestNewMathFunctions.java
@@ -152,11 +152,18 @@ public class TestNewMathFunctions extends BaseTestQuery {
runTest(expected, "functions/testDivModTruncFunctions.json");
}
- @Test
- public void testIsNumeric() throws Throwable{
- final Object [] expected = new Object[] {1, 1, 1, 0};
- runTest(expected, "functions/testIsNumericFunction.json");
- }
+ @Test
+ public void testBitTwiddlers() throws Throwable {
+ final Object [] expected = new Object[] { 3072, 3, 14 };
+ // Note bitwise AND and OR do not have Drill function implementations
+ runTest(expected, "functions/testBitTwiddlers.json");
+ }
+
+ @Test
+ public void testIsNumeric() throws Throwable{
+ final Object [] expected = new Object[] {1, 1, 1, 0};
+ runTest(expected, "functions/testIsNumericFunction.json");
+ }
@Test
public void testLog10WithDouble() throws Throwable {
diff --git a/exec/java-exec/src/test/resources/functions/testBitTwiddlers.json
b/exec/java-exec/src/test/resources/functions/testBitTwiddlers.json
new file mode 100644
index 0000000..fa04e96
--- /dev/null
+++ b/exec/java-exec/src/test/resources/functions/testBitTwiddlers.json
@@ -0,0 +1,34 @@
+{
+ head : {
+ version : 1,
+ generator : {
+ type : "optiq",
+ info : "na"
+ },
+ type : "APACHE_DRILL_PHYSICAL"
+ },
+ graph:[
+ {
+ @id:1,
+ pop:"mock-sub-scan",
+ url: "http://apache.org",
+ entries:[
+ {records: 1, types: [
+ {name: "blue", type: "BIGINT", mode: "REQUIRED"}
+ ]}
+ ]
+ }, {
+ pop : "project",
+ @id : 2,
+ exprs : [
+ { ref : "ref1", expr : " lshift(3,10) "},
+ { ref : "ref2", expr : " rshift(3072, 10) "},
+ { ref : "ref3", expr : " xor(7, 9) " }
+ ],
+ child : 1
+ }, {
+ pop : "screen",
+ @id : 3,
+ child : 2
+ } ]
+}
diff --git a/exec/java-exec/src/test/resources/functions/test_logical_aggr.json
b/exec/java-exec/src/test/resources/functions/test_logical_aggr.json
index 6e071c5..fb942e9 100644
--- a/exec/java-exec/src/test/resources/functions/test_logical_aggr.json
+++ b/exec/java-exec/src/test/resources/functions/test_logical_aggr.json
@@ -62,9 +62,18 @@
"expr" : "bit_or(`D`) "
}, {
"ref" : "`EXPR$6`",
- "expr" : "bool_or(`C`) "
+ "expr" : "bit_xor(`A`) "
}, {
"ref" : "`EXPR$7`",
+ "expr" : "bit_xor(`B`) "
+ }, {
+ "ref" : "`EXPR$8`",
+ "expr" : "bit_xor(`D`) "
+ }, {
+ "ref" : "`EXPR$9`",
+ "expr" : "bool_or(`C`) "
+ }, {
+ "ref" : "`EXPR$10`",
"expr" : "bool_and(`C`) "
} ]
}, {
diff --git a/exec/java-exec/src/test/resources/logical_aggr_input.json
b/exec/java-exec/src/test/resources/logical_aggr_input.json
index d1d25be..ce11ef3 100644
--- a/exec/java-exec/src/test/resources/logical_aggr_input.json
+++ b/exec/java-exec/src/test/resources/logical_aggr_input.json
@@ -1,4 +1,4 @@
{"A" : 7, "B" : 2, "C" : true, "D" : 1}
{"A" : 4, "B" : -2, "C" : false, "D" : 0}
{"A" : 4, "B" : 4, "C" : false, "D" : 0}
-{"A" : 4, "B" : -4, "C" : true, "D" : 1}
\ No newline at end of file
+{"A" : 4, "B" : -4, "C" : true, "D" : 1}