You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@drill.apache.org by me...@apache.org on 2015/04/03 22:04:00 UTC
drill git commit: DRILL-2244: Hash all numeric types as double
Repository: drill
Updated Branches:
refs/heads/master 30ad950e5 -> f215c4629
DRILL-2244: Hash all numeric types as double
Project: http://git-wip-us.apache.org/repos/asf/drill/repo
Commit: http://git-wip-us.apache.org/repos/asf/drill/commit/f215c462
Tree: http://git-wip-us.apache.org/repos/asf/drill/tree/f215c462
Diff: http://git-wip-us.apache.org/repos/asf/drill/diff/f215c462
Branch: refs/heads/master
Commit: f215c4629536df9e3990606b595b21c26cb6c86a
Parents: 30ad950
Author: Mehant Baid <me...@gmail.com>
Authored: Thu Apr 2 11:54:39 2015 -0700
Committer: Mehant Baid <me...@gmail.com>
Committed: Fri Apr 3 11:12:29 2015 -0700
----------------------------------------------------------------------
.../drill/exec/expr/fn/impl/Hash64AsDouble.java | 341 ++++++++++++++++++
.../exec/expr/fn/impl/Hash64Functions.java | 31 +-
.../expr/fn/impl/Hash64FunctionsWithSeed.java | 31 +-
.../expr/fn/impl/Hash64WithSeedAsDouble.java | 344 +++++++++++++++++++
.../physical/impl/common/ChainedHashTable.java | 31 +-
.../drill/exec/planner/physical/PrelUtil.java | 13 +-
.../drill/exec/resolver/TypeCastRules.java | 25 ++
.../org/apache/drill/TestFunctionsQuery.java | 25 ++
8 files changed, 808 insertions(+), 33 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/drill/blob/f215c462/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/Hash64AsDouble.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/Hash64AsDouble.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/Hash64AsDouble.java
new file mode 100644
index 0000000..b3e4cc1
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/Hash64AsDouble.java
@@ -0,0 +1,341 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.drill.exec.expr.fn.impl;
+
+import org.apache.drill.exec.expr.DrillSimpleFunc;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate;
+import org.apache.drill.exec.expr.annotations.Output;
+import org.apache.drill.exec.expr.annotations.Param;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionScope;
+import org.apache.drill.exec.expr.holders.BigIntHolder;
+import org.apache.drill.exec.expr.holders.Decimal18Holder;
+import org.apache.drill.exec.expr.holders.Decimal28SparseHolder;
+import org.apache.drill.exec.expr.holders.Decimal38SparseHolder;
+import org.apache.drill.exec.expr.holders.Decimal9Holder;
+import org.apache.drill.exec.expr.holders.Float4Holder;
+import org.apache.drill.exec.expr.holders.Float8Holder;
+import org.apache.drill.exec.expr.holders.IntHolder;
+import org.apache.drill.exec.expr.holders.NullableBigIntHolder;
+import org.apache.drill.exec.expr.holders.NullableDecimal18Holder;
+import org.apache.drill.exec.expr.holders.NullableDecimal28SparseHolder;
+import org.apache.drill.exec.expr.holders.NullableDecimal38SparseHolder;
+import org.apache.drill.exec.expr.holders.NullableDecimal9Holder;
+import org.apache.drill.exec.expr.holders.NullableFloat4Holder;
+import org.apache.drill.exec.expr.holders.NullableFloat8Holder;
+import org.apache.drill.exec.expr.holders.NullableIntHolder;
+
+/*
+ * Class contains hash64 function definitions for different data types.
+ *
+ * NOTE: These functions are used internally by Drill to perform hash distribution and in hash join. For
+ * numeric data types we would like to apply implicit casts in the join method however for this to work
+ * as expected we would need to hash the same value represented in different data types (int, bigint, float etc)
+ * to hash to the same node, this is why we cast all numeric values to double before performing the actual hash.
+ */
+public class Hash64AsDouble {
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ public static class NullableFloatHash implements DrillSimpleFunc {
+
+ @Param
+ NullableFloat4Holder in;
+ @Output
+ BigIntHolder out;
+
+ public void setup() {
+ }
+
+ public void eval() {
+ if (in.isSet == 0) {
+ out.value = 0;
+ } else {
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64((double) in.value, 0);
+ }
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ public static class FloatHash implements DrillSimpleFunc {
+
+ @Param
+ Float4Holder in;
+ @Output
+ BigIntHolder out;
+
+ public void setup() {
+ }
+
+ public void eval() {
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64((double) in.value, 0);
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ public static class NullableDoubleHash implements DrillSimpleFunc {
+
+ @Param
+ NullableFloat8Holder in;
+ @Output
+ BigIntHolder out;
+
+ public void setup() {
+ }
+
+ public void eval() {
+ if (in.isSet == 0) {
+ out.value = 0;
+ } else {
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64((double) in.value, 0);
+ }
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ public static class DoubleHash implements DrillSimpleFunc {
+
+ @Param
+ Float8Holder in;
+ @Output
+ BigIntHolder out;
+
+ public void setup() {
+ }
+
+ public void eval() {
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64(in.value, 0);
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ public static class NullableBigIntHash implements DrillSimpleFunc {
+
+ @Param
+ NullableBigIntHolder in;
+ @Output
+ BigIntHolder out;
+
+ public void setup() {
+ }
+
+ public void eval() {
+ if (in.isSet == 0) {
+ out.value = 0;
+ } else {
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64((double) in.value, 0);
+ }
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ public static class NullableIntHash implements DrillSimpleFunc {
+ @Param
+ NullableIntHolder in;
+ @Output
+ BigIntHolder out;
+
+ public void setup() {
+ }
+
+ public void eval() {
+ if (in.isSet == 0) {
+ out.value = 0;
+ } else {
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64((double) in.value, 0);
+ }
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ public static class HashBigInt implements DrillSimpleFunc {
+
+ @Param
+ BigIntHolder in;
+ @Output
+ BigIntHolder out;
+
+ public void setup() {
+ }
+
+ public void eval() {
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64((double) in.value, 0);
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ public static class IntHash implements DrillSimpleFunc {
+ @Param
+ IntHolder in;
+ @Output
+ BigIntHolder out;
+
+ public void setup() {
+ }
+
+ public void eval() {
+ // TODO: implement hash function for other types
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64((double) in.value, 0);
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ public static class Decimal9Hash implements DrillSimpleFunc {
+ @Param
+ Decimal9Holder in;
+ @Output
+ BigIntHolder out;
+
+ public void setup() {
+ }
+
+ public void eval() {
+ java.math.BigDecimal input = new java.math.BigDecimal(java.math.BigInteger.valueOf(in.value), in.scale);
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64(input.doubleValue(), 0);
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ public static class NullableDecimal9Hash implements DrillSimpleFunc {
+ @Param
+ NullableDecimal9Holder in;
+ @Output
+ BigIntHolder out;
+
+ public void setup() {
+ }
+
+ public void eval() {
+ if (in.isSet == 0) {
+ out.value = 0;
+ } else {
+ java.math.BigDecimal input = new java.math.BigDecimal(java.math.BigInteger.valueOf(in.value), in.scale);
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64(input.doubleValue(), 0);
+ }
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ public static class Decimal18Hash implements DrillSimpleFunc {
+ @Param
+ Decimal18Holder in;
+ @Output
+ BigIntHolder out;
+
+ public void setup() {
+ }
+
+ public void eval() {
+ java.math.BigDecimal input = new java.math.BigDecimal(java.math.BigInteger.valueOf(in.value), in.scale);
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64(input.doubleValue(), 0);
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ public static class NullableDecimal18Hash implements DrillSimpleFunc {
+ @Param
+ NullableDecimal18Holder in;
+ @Output
+ BigIntHolder out;
+
+ public void setup() {
+ }
+
+ public void eval() {
+ if (in.isSet == 0) {
+ out.value = 0;
+ } else {
+ java.math.BigDecimal input = new java.math.BigDecimal(java.math.BigInteger.valueOf(in.value), in.scale);
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64(input.doubleValue(), 0);
+ }
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ public static class Decimal28Hash implements DrillSimpleFunc {
+ @Param
+ Decimal28SparseHolder in;
+ @Output
+ BigIntHolder out;
+
+ public void setup() {
+ }
+
+ public void eval() {
+ java.math.BigDecimal input = org.apache.drill.exec.util.DecimalUtility.getBigDecimalFromSparse(in.buffer,
+ in.start, in.nDecimalDigits, in.scale);
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64(input.doubleValue(), 0);
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ public static class NullableDecimal28Hash implements DrillSimpleFunc {
+ @Param
+ NullableDecimal28SparseHolder in;
+ @Output
+ BigIntHolder out;
+
+ public void setup() {
+ }
+
+ public void eval() {
+ if (in.isSet == 0) {
+ out.value = 0;
+ } else {
+ java.math.BigDecimal input = org.apache.drill.exec.util.DecimalUtility.getBigDecimalFromSparse(in.buffer,
+ in.start, in.nDecimalDigits, in.scale);
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64(input.doubleValue(), 0);
+ }
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ public static class Decimal38Hash implements DrillSimpleFunc {
+ @Param
+ Decimal38SparseHolder in;
+ @Output
+ BigIntHolder out;
+
+ public void setup() {
+ }
+
+ public void eval() {
+ java.math.BigDecimal input = org.apache.drill.exec.util.DecimalUtility.getBigDecimalFromSparse(in.buffer,
+ in.start, in.nDecimalDigits, in.scale);
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64(input.doubleValue(), 0);
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ public static class NullableDecimal38Hash implements DrillSimpleFunc {
+ @Param
+ NullableDecimal38SparseHolder in;
+ @Output
+ BigIntHolder out;
+
+ public void setup() {
+ }
+
+ public void eval() {
+ if (in.isSet == 0) {
+ out.value = 0;
+ } else {
+ java.math.BigDecimal input = org.apache.drill.exec.util.DecimalUtility.getBigDecimalFromSparse(in.buffer,
+ in.start, in.nDecimalDigits, in.scale);
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64(input.doubleValue(), 0);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/drill/blob/f215c462/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/Hash64Functions.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/Hash64Functions.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/Hash64Functions.java
index 57154ed..3e390a4 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/Hash64Functions.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/Hash64Functions.java
@@ -53,6 +53,9 @@ import org.apache.drill.exec.expr.holders.Var16CharHolder;
import org.apache.drill.exec.expr.holders.VarBinaryHolder;
import org.apache.drill.exec.expr.holders.VarCharHolder;
+/*
+ * Class contains hash64 function definitions for different data types.
+ */
public class Hash64Functions {
@FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
public static class NullableFloatHash implements DrillSimpleFunc {
@@ -126,7 +129,7 @@ public class Hash64Functions {
}
}
- @FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ @FunctionTemplate(names = {"hash64", "hash64AsDouble"}, scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
public static class NullableVarBinaryHash implements DrillSimpleFunc {
@Param
@@ -146,7 +149,7 @@ public class Hash64Functions {
}
}
- @FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ @FunctionTemplate(names = {"hash64", "hash64AsDouble"}, scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
public static class NullableVarCharHash implements DrillSimpleFunc {
@Param
@@ -166,7 +169,7 @@ public class Hash64Functions {
}
}
- @FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ @FunctionTemplate(names = {"hash64", "hash64AsDouble"}, scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
public static class NullableVar16CharHash implements DrillSimpleFunc {
@Param
@@ -225,7 +228,7 @@ public class Hash64Functions {
}
}
- @FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ @FunctionTemplate(names = {"hash64", "hash64AsDouble"}, scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
public static class VarBinaryHash implements DrillSimpleFunc {
@Param
@@ -241,7 +244,7 @@ public class Hash64Functions {
}
}
- @FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ @FunctionTemplate(names = {"hash64", "hash64AsDouble"}, scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
public static class VarCharHash implements DrillSimpleFunc {
@Param
@@ -257,7 +260,7 @@ public class Hash64Functions {
}
}
- @FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ @FunctionTemplate(names = {"hash64", "hash64AsDouble"}, scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
public static class Var16CharHash implements DrillSimpleFunc {
@Param
@@ -305,7 +308,7 @@ public class Hash64Functions {
}
}
- @FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ @FunctionTemplate(names = {"hash64", "hash64AsDouble"}, scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
public static class DateHash implements DrillSimpleFunc {
@Param
DateHolder in;
@@ -320,7 +323,7 @@ public class Hash64Functions {
}
}
- @FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ @FunctionTemplate(names = {"hash64", "hash64AsDouble"}, scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
public static class NullableDateHash implements DrillSimpleFunc {
@Param
NullableDateHolder in;
@@ -339,7 +342,7 @@ public class Hash64Functions {
}
}
- @FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ @FunctionTemplate(names = {"hash64", "hash64AsDouble"}, scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
public static class TimeStampHash implements DrillSimpleFunc {
@Param
TimeStampHolder in;
@@ -354,7 +357,7 @@ public class Hash64Functions {
}
}
- @FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ @FunctionTemplate(names = {"hash64", "hash64AsDouble"}, scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
public static class NullableTimeStampHash implements DrillSimpleFunc {
@Param
NullableTimeStampHolder in;
@@ -373,7 +376,7 @@ public class Hash64Functions {
}
}
- @FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ @FunctionTemplate(names = {"hash64", "hash64AsDouble"}, scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
public static class TimeHash implements DrillSimpleFunc {
@Param
TimeHolder in;
@@ -388,7 +391,7 @@ public class Hash64Functions {
}
}
- @FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ @FunctionTemplate(names = {"hash64", "hash64AsDouble"}, scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
public static class NullableTimeHash implements DrillSimpleFunc {
@Param
NullableTimeHolder in;
@@ -547,7 +550,7 @@ public class Hash64Functions {
}
}
- @FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ @FunctionTemplate(names = {"hash64", "hash64AsDouble"}, scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
public static class NullableBitHash implements DrillSimpleFunc {
@Param
@@ -567,7 +570,7 @@ public class Hash64Functions {
}
}
- @FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ @FunctionTemplate(names = {"hash64", "hash64AsDouble"}, scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
public static class BitHash implements DrillSimpleFunc {
@Param
http://git-wip-us.apache.org/repos/asf/drill/blob/f215c462/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/Hash64FunctionsWithSeed.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/Hash64FunctionsWithSeed.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/Hash64FunctionsWithSeed.java
index b9ec956..3a1edd3 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/Hash64FunctionsWithSeed.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/Hash64FunctionsWithSeed.java
@@ -53,6 +53,9 @@ import org.apache.drill.exec.expr.holders.Var16CharHolder;
import org.apache.drill.exec.expr.holders.VarBinaryHolder;
import org.apache.drill.exec.expr.holders.VarCharHolder;
+/*
+ * Class contains hash64 function definitions for different data types.
+ */
public class Hash64FunctionsWithSeed {
@FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL )
public static class NullableFloatHash implements DrillSimpleFunc {
@@ -126,7 +129,7 @@ public class Hash64FunctionsWithSeed {
}
}
- @FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL )
+ @FunctionTemplate(names = {"hash64", "hash64AsDouble"}, scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL )
public static class NullableVarBinaryHash implements DrillSimpleFunc {
@Param NullableVarBinaryHolder in;
@@ -146,7 +149,7 @@ public class Hash64FunctionsWithSeed {
}
}
- @FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL )
+ @FunctionTemplate(names = {"hash64", "hash64AsDouble"}, scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL )
public static class NullableVarCharHash implements DrillSimpleFunc {
@Param NullableVarCharHolder in;
@@ -166,7 +169,7 @@ public class Hash64FunctionsWithSeed {
}
}
- @FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL )
+ @FunctionTemplate(names = {"hash64", "hash64AsDouble"}, scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL )
public static class NullableVar16CharHash implements DrillSimpleFunc {
@Param NullableVar16CharHolder in;
@@ -227,7 +230,7 @@ public class Hash64FunctionsWithSeed {
}
}
- @FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ @FunctionTemplate(names = {"hash64", "hash64AsDouble"}, scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
public static class VarBinaryHash implements DrillSimpleFunc {
@Param VarBinaryHolder in;
@@ -243,7 +246,7 @@ public class Hash64FunctionsWithSeed {
}
}
- @FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ @FunctionTemplate(names = {"hash64", "hash64AsDouble"}, scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
public static class VarCharHash implements DrillSimpleFunc {
@Param VarCharHolder in;
@@ -259,7 +262,7 @@ public class Hash64FunctionsWithSeed {
}
}
- @FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ @FunctionTemplate(names = {"hash64", "hash64AsDouble"}, scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
public static class Var16CharHash implements DrillSimpleFunc {
@Param Var16CharHolder in;
@@ -306,7 +309,7 @@ public class Hash64FunctionsWithSeed {
out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64(in.value, seed.value);
}
}
- @FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ @FunctionTemplate(names = {"hash64", "hash64AsDouble"}, scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
public static class DateHash implements DrillSimpleFunc {
@Param DateHolder in;
@Param BigIntHolder seed;
@@ -321,7 +324,7 @@ public class Hash64FunctionsWithSeed {
}
}
- @FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ @FunctionTemplate(names = {"hash64", "hash64AsDouble"}, scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
public static class NullableDateHash implements DrillSimpleFunc {
@Param NullableDateHolder in;
@Param BigIntHolder seed;
@@ -340,7 +343,7 @@ public class Hash64FunctionsWithSeed {
}
}
- @FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ @FunctionTemplate(names = {"hash64", "hash64AsDouble"}, scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
public static class TimeStampHash implements DrillSimpleFunc {
@Param TimeStampHolder in;
@Param BigIntHolder seed;
@@ -355,7 +358,7 @@ public class Hash64FunctionsWithSeed {
}
}
- @FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ @FunctionTemplate(names = {"hash64", "hash64AsDouble"}, scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
public static class NullableTimeStampHash implements DrillSimpleFunc {
@Param NullableTimeStampHolder in;
@Param BigIntHolder seed;
@@ -374,7 +377,7 @@ public class Hash64FunctionsWithSeed {
}
}
- @FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ @FunctionTemplate(names = {"hash64", "hash64AsDouble"}, scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
public static class TimeHash implements DrillSimpleFunc {
@Param TimeHolder in;
@Param BigIntHolder seed;
@@ -389,7 +392,7 @@ public class Hash64FunctionsWithSeed {
}
}
- @FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ @FunctionTemplate(names = {"hash64", "hash64AsDouble"}, scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
public static class NullableTimeHash implements DrillSimpleFunc {
@Param NullableTimeHolder in;
@Param BigIntHolder seed;
@@ -544,7 +547,7 @@ public class Hash64FunctionsWithSeed {
}
}
- @FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL )
+ @FunctionTemplate(names = {"hash64", "hash64AsDouble"}, scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL )
public static class NullableBitHash implements DrillSimpleFunc {
@Param NullableBitHolder in;
@@ -564,7 +567,7 @@ public class Hash64FunctionsWithSeed {
}
}
- @FunctionTemplate(name = "hash64", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL )
+ @FunctionTemplate(names = {"hash64", "hash64AsDouble"}, scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL )
public static class BitHash implements DrillSimpleFunc {
@Param BitHolder in;
http://git-wip-us.apache.org/repos/asf/drill/blob/f215c462/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/Hash64WithSeedAsDouble.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/Hash64WithSeedAsDouble.java b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/Hash64WithSeedAsDouble.java
new file mode 100644
index 0000000..0cbac1b
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/Hash64WithSeedAsDouble.java
@@ -0,0 +1,344 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.drill.exec.expr.fn.impl;
+
+import org.apache.drill.exec.expr.DrillSimpleFunc;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate;
+import org.apache.drill.exec.expr.annotations.Output;
+import org.apache.drill.exec.expr.annotations.Param;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate.FunctionScope;
+import org.apache.drill.exec.expr.holders.BigIntHolder;
+import org.apache.drill.exec.expr.holders.Decimal18Holder;
+import org.apache.drill.exec.expr.holders.Decimal28SparseHolder;
+import org.apache.drill.exec.expr.holders.Decimal38SparseHolder;
+import org.apache.drill.exec.expr.holders.Decimal9Holder;
+import org.apache.drill.exec.expr.holders.Float4Holder;
+import org.apache.drill.exec.expr.holders.Float8Holder;
+import org.apache.drill.exec.expr.holders.IntHolder;
+import org.apache.drill.exec.expr.holders.NullableBigIntHolder;
+import org.apache.drill.exec.expr.holders.NullableDecimal18Holder;
+import org.apache.drill.exec.expr.holders.NullableDecimal28SparseHolder;
+import org.apache.drill.exec.expr.holders.NullableDecimal38SparseHolder;
+import org.apache.drill.exec.expr.holders.NullableDecimal9Holder;
+import org.apache.drill.exec.expr.holders.NullableFloat4Holder;
+import org.apache.drill.exec.expr.holders.NullableFloat8Holder;
+import org.apache.drill.exec.expr.holders.NullableIntHolder;
+
+/*
+ * Class contains hash64 function definitions for different data types.
+ *
+ * NOTE: These functions are used internally by Drill to perform hash distribution and in hash join. For
+ * numeric data types we would like to apply implicit casts in the join method however for this to work
+ * as expected we would need to hash the same value represented in different data types (int, bigint, float etc)
+ * to hash to the same node, this is why we cast all numeric values to double before performing the actual hash.
+ */
+public class Hash64WithSeedAsDouble {
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL )
+ public static class NullableFloatHash implements DrillSimpleFunc {
+
+ @Param NullableFloat4Holder in;
+ @Param BigIntHolder seed;
+ @Output BigIntHolder out;
+
+
+ public void setup() {
+ }
+
+ public void eval() {
+ if (in.isSet == 0) {
+ out.value = 0;
+ } else {
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64((double) in.value, seed.value);
+ }
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL )
+ public static class FloatHash implements DrillSimpleFunc {
+
+ @Param Float4Holder in;
+ @Param BigIntHolder seed;
+ @Output BigIntHolder out;
+
+
+ public void setup() {
+ }
+
+ public void eval() {
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64((double) in.value, seed.value);
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL )
+ public static class NullableDoubleHash implements DrillSimpleFunc {
+
+ @Param NullableFloat8Holder in;
+ @Param BigIntHolder seed;
+ @Output BigIntHolder out;
+
+
+ public void setup() {
+ }
+
+ public void eval() {
+ if (in.isSet == 0) {
+ out.value = 0;
+ } else {
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64(in.value, seed.value);
+ }
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL )
+ public static class DoubleHash implements DrillSimpleFunc {
+
+ @Param Float8Holder in;
+ @Param BigIntHolder seed;
+ @Output BigIntHolder out;
+
+
+ public void setup() {
+ }
+
+ public void eval() {
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64(in.value, seed.value);
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ public static class NullableBigIntHash implements DrillSimpleFunc {
+
+ @Param NullableBigIntHolder in;
+ @Param BigIntHolder seed;
+ @Output BigIntHolder out;
+
+
+ public void setup() {
+ }
+
+ public void eval() {
+ if (in.isSet == 0) {
+ out.value = 0;
+ }
+ else {
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64((double) in.value, seed.value);
+ }
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ public static class NullableIntHash implements DrillSimpleFunc {
+ @Param NullableIntHolder in;
+ @Param BigIntHolder seed;
+ @Output BigIntHolder out;
+
+
+ public void setup() {
+ }
+
+ public void eval() {
+ if (in.isSet == 0) {
+ out.value = 0;
+ }
+ else {
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64((double) in.value, seed.value);
+ }
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ public static class HashBigInt implements DrillSimpleFunc {
+
+ @Param BigIntHolder in;
+ @Param BigIntHolder seed;
+ @Output BigIntHolder out;
+
+
+ public void setup() {
+ }
+
+ public void eval() {
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64((double) in.value, seed.value);
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ public static class IntHash implements DrillSimpleFunc {
+ @Param IntHolder in;
+ @Param BigIntHolder seed;
+ @Output BigIntHolder out;
+
+
+ public void setup() {
+ }
+
+ public void eval() {
+ // TODO: implement hash function for other types
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64((double) in.value, seed.value);
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ public static class Decimal9Hash implements DrillSimpleFunc {
+ @Param Decimal9Holder in;
+ @Param BigIntHolder seed;
+ @Output BigIntHolder out;
+
+
+ public void setup() {
+ }
+
+ public void eval() {
+ java.math.BigDecimal input = new java.math.BigDecimal(java.math.BigInteger.valueOf(in.value), in.scale);
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64(input.doubleValue(), seed.value);
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ public static class NullableDecimal9Hash implements DrillSimpleFunc {
+ @Param NullableDecimal9Holder in;
+ @Param BigIntHolder seed;
+ @Output BigIntHolder out;
+
+
+ public void setup() {
+ }
+
+ public void eval() {
+ if (in.isSet == 0) {
+ out.value = 0;
+ } else {
+ java.math.BigDecimal input = new java.math.BigDecimal(java.math.BigInteger.valueOf(in.value), in.scale);
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64(input.doubleValue(), seed.value);
+ }
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ public static class Decimal18Hash implements DrillSimpleFunc {
+ @Param Decimal18Holder in;
+ @Param BigIntHolder seed;
+ @Output BigIntHolder out;
+
+
+ public void setup() {
+ }
+
+ public void eval() {
+ java.math.BigDecimal input = new java.math.BigDecimal(java.math.BigInteger.valueOf(in.value), in.scale);
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64(input.doubleValue(), seed.value);
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ public static class NullableDecimal18Hash implements DrillSimpleFunc {
+ @Param NullableDecimal18Holder in;
+ @Param BigIntHolder seed;
+ @Output BigIntHolder out;
+
+
+ public void setup() {
+ }
+
+ public void eval() {
+ if (in.isSet == 0) {
+ out.value = 0;
+ } else {
+ java.math.BigDecimal input = new java.math.BigDecimal(java.math.BigInteger.valueOf(in.value), in.scale);
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64(input.doubleValue(), seed.value);
+ }
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ public static class Decimal28Hash implements DrillSimpleFunc {
+ @Param Decimal28SparseHolder in;
+ @Param BigIntHolder seed;
+ @Output BigIntHolder out;
+
+
+ public void setup() {
+ }
+
+ public void eval() {
+ java.math.BigDecimal input = org.apache.drill.exec.util.DecimalUtility.getBigDecimalFromSparse(in.buffer,
+ in.start, in.nDecimalDigits, in.scale);
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64(input.doubleValue(), 0);
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ public static class NullableDecimal28Hash implements DrillSimpleFunc {
+ @Param NullableDecimal28SparseHolder in;
+ @Param BigIntHolder seed;
+ @Output BigIntHolder out;
+
+
+ public void setup() {
+ }
+
+ public void eval() {
+ if (in.isSet == 0) {
+ out.value = 0;
+ } else {
+ java.math.BigDecimal input = org.apache.drill.exec.util.DecimalUtility.getBigDecimalFromSparse(in.buffer,
+ in.start, in.nDecimalDigits, in.scale);
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64(input.doubleValue(), 0);
+ }
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ public static class Decimal38Hash implements DrillSimpleFunc {
+ @Param Decimal38SparseHolder in;
+ @Param BigIntHolder seed;
+ @Output BigIntHolder out;
+
+
+ public void setup() {
+ }
+
+ public void eval() {
+ java.math.BigDecimal input = org.apache.drill.exec.util.DecimalUtility.getBigDecimalFromSparse(in.buffer,
+ in.start, in.nDecimalDigits, in.scale);
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64(input.doubleValue(), 0);
+ }
+ }
+
+ @FunctionTemplate(name = "hash64AsDouble", scope = FunctionScope.SIMPLE, nulls = FunctionTemplate.NullHandling.INTERNAL)
+ public static class NullableDecimal38Hash implements DrillSimpleFunc {
+ @Param NullableDecimal38SparseHolder in;
+ @Param BigIntHolder seed;
+ @Output BigIntHolder out;
+
+
+ public void setup() {
+ }
+
+ public void eval() {
+ if (in.isSet == 0) {
+ out.value = 0;
+ } else {
+ java.math.BigDecimal input = org.apache.drill.exec.util.DecimalUtility.getBigDecimalFromSparse(in.buffer,
+ in.start, in.nDecimalDigits, in.scale);
+ out.value = org.apache.drill.exec.expr.fn.impl.XXHash.hash64(input.doubleValue(), 0);
+ }
+ }
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/drill/blob/f215c462/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/common/ChainedHashTable.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/common/ChainedHashTable.java b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/common/ChainedHashTable.java
index 84a2956..9df67d8 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/common/ChainedHashTable.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/common/ChainedHashTable.java
@@ -309,6 +309,14 @@ public class ChainedHashTable {
MinorType probeType = probeExpr.getMajorType().getMinorType();
if (buildType != probeType) {
+
+ // currently we only support implicit casts if the input types are numeric or varchar/varbinary
+ if (!allowImplicitCast(buildType, probeType)) {
+ throw new DrillRuntimeException(String.format("Hash join only supports implicit casts between " +
+ "1. Numeric data\n 2. Varchar, Varbinary data " +
+ "Build type: %s, Probe type: %s. Add explicit casts to avoid this error", buildType, probeType));
+ }
+
// We need to add a cast to one of the expressions
List<MinorType> types = new LinkedList<>();
types.add(buildType);
@@ -349,11 +357,32 @@ public class ChainedHashTable {
return;
}
- LogicalExpression hashExpression = PrelUtil.getHashExpression(Arrays.asList(keyExprs));
+ /*
+ * We use the same logic to generate run time code for the hash function both for hash join and hash
+ * aggregate. For join we need to hash everything as double (both for distribution and for comparison) but
+ * for aggregation we can avoid the penalty of casting to double
+ */
+ LogicalExpression hashExpression = PrelUtil.getHashExpression(Arrays.asList(keyExprs),
+ incomingProbe != null ? true : false);
final LogicalExpression materializedExpr = ExpressionTreeMaterializer.materializeAndCheckErrors(hashExpression, batch, context.getFunctionRegistry());
HoldingContainer hash = cg.addExpr(materializedExpr);
cg.getEvalBlock()._return(hash.getValue());
}
+
+ private boolean allowImplicitCast(MinorType input1, MinorType input2) {
+ // allow implicit cast if both the input types are numeric
+ if (TypeCastRules.isNumericType(input1) && TypeCastRules.isNumericType(input2)) {
+ return true;
+ }
+
+ // allow implicit cast if both the input types are varbinary/ varchar
+ if ((input1 == MinorType.VARCHAR || input1 == MinorType.VARBINARY) &&
+ (input2 == MinorType.VARCHAR || input2 == MinorType.VARBINARY)) {
+ return true;
+ }
+
+ return false;
+ }
}
http://git-wip-us.apache.org/repos/asf/drill/blob/f215c462/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/PrelUtil.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/PrelUtil.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/PrelUtil.java
index f7c144f..44afd68 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/PrelUtil.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/PrelUtil.java
@@ -68,6 +68,8 @@ import com.google.common.collect.Sets;
public class PrelUtil {
public static final String HASH_EXPR_NAME = "E_X_P_R_H_A_S_H_F_I_E_L_D";
+ private static final String HASH64_FUNCTION_NAME = "hash64";
+ private static final String HASH64_DOUBLE_FUNCTION_NAME = "hash64AsDouble";
public static List<Ordering> getOrdering(RelCollation collation, RelDataType rowType) {
List<Ordering> orderExpr = Lists.newArrayList();
@@ -85,12 +87,13 @@ public class PrelUtil {
/*
* Return a hash expression : (int) hash(field1, hash(field2, hash(field3, 0)));
*/
- public static LogicalExpression getHashExpression(List<LogicalExpression> fields){
+ public static LogicalExpression getHashExpression(List<LogicalExpression> fields, boolean hashAsDouble){
assert fields.size() > 0;
- FunctionCall func = new FunctionCall("hash64", ImmutableList.of(fields.get(0)), ExpressionPosition.UNKNOWN);
+ String functionName = hashAsDouble ? HASH64_DOUBLE_FUNCTION_NAME : HASH64_FUNCTION_NAME;
+ FunctionCall func = new FunctionCall(functionName, ImmutableList.of(fields.get(0)), ExpressionPosition.UNKNOWN);
for (int i = 1; i<fields.size(); i++) {
- func = new FunctionCall("hash64", ImmutableList.of(fields.get(i), func), ExpressionPosition.UNKNOWN);
+ func = new FunctionCall(functionName, ImmutableList.of(fields.get(i), func), ExpressionPosition.UNKNOWN);
}
return new CastExpression(func, Types.required(MinorType.INT), ExpressionPosition.UNKNOWN);
@@ -111,7 +114,9 @@ public class PrelUtil {
for(int i =0; i < fields.size(); i++){
expressions.add(new FieldReference(childFields.get(fields.get(i).getFieldId()), ExpressionPosition.UNKNOWN));
}
- return getHashExpression(expressions);
+
+ // for distribution always hash as double
+ return getHashExpression(expressions, true);
}
public static Iterator<Prel> iter(RelNode... nodes) {
http://git-wip-us.apache.org/repos/asf/drill/blob/f215c462/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/TypeCastRules.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/TypeCastRules.java b/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/TypeCastRules.java
index d8652f2..92302e0 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/TypeCastRules.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/resolver/TypeCastRules.java
@@ -938,4 +938,29 @@ public class TypeCastRules {
return cost;
}
+ /*
+ * Simple helper function to determine if input type is numeric
+ */
+ public static boolean isNumericType(MinorType inputType) {
+ switch (inputType) {
+ case TINYINT:
+ case SMALLINT:
+ case INT:
+ case BIGINT:
+ case UINT1:
+ case UINT2:
+ case UINT4:
+ case UINT8:
+ case DECIMAL9:
+ case DECIMAL18:
+ case DECIMAL28SPARSE:
+ case DECIMAL38SPARSE:
+ case FLOAT4:
+ case FLOAT8:
+ return true;
+ default:
+ return false;
+ }
+ }
+
}
http://git-wip-us.apache.org/repos/asf/drill/blob/f215c462/exec/java-exec/src/test/java/org/apache/drill/TestFunctionsQuery.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/test/java/org/apache/drill/TestFunctionsQuery.java b/exec/java-exec/src/test/java/org/apache/drill/TestFunctionsQuery.java
index f1005ab..476370d 100644
--- a/exec/java-exec/src/test/java/org/apache/drill/TestFunctionsQuery.java
+++ b/exec/java-exec/src/test/java/org/apache/drill/TestFunctionsQuery.java
@@ -709,4 +709,29 @@ public class TestFunctionsQuery extends BaseTestQuery {
.baselineValues(new BigDecimal("1.00000"))
.go();
}
+
+ /*
+ * We may apply implicit casts in Hash Join while dealing with different numeric data types
+ * For this to work we need to distribute the data based on a common key, below method
+ * makes sure the hash value for different numeric types is the same for the same key
+ */
+ @Test
+ public void testHash64() throws Exception {
+ String query = "select " +
+ "hash64AsDouble(cast(employee_id as int)) = hash64AsDouble(cast(employee_id as bigint)) col1, " +
+ "hash64AsDouble(cast(employee_id as bigint)) = hash64AsDouble(cast(employee_id as float)) col2, " +
+ "hash64AsDouble(cast(employee_id as float)) = hash64AsDouble(cast(employee_id as double)) col3, " +
+ "hash64AsDouble(cast(employee_id as double)) = hash64AsDouble(cast(employee_id as decimal(9, 0))) col4, " +
+ "hash64AsDouble(cast(employee_id as decimal(9, 0))) = hash64AsDouble(cast(employee_id as decimal(18, 0))) col5, " +
+ "hash64AsDouble(cast(employee_id as decimal(18, 0))) = hash64AsDouble(cast(employee_id as decimal(28, 0))) col6, " +
+ "hash64AsDouble(cast(employee_id as decimal(28, 0))) = hash64AsDouble(cast(employee_id as decimal(38, 0))) col7 " +
+ "from cp.`employee.json` where employee_id = 1";
+
+ testBuilder()
+ .sqlQuery(query)
+ .unOrdered()
+ .baselineColumns("col1", "col2", "col3", "col4", "col5", "col6", "col7")
+ .baselineValues(true, true, true, true, true, true, true)
+ .go();
+ }
}