aboutsummaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorCheng Hao <hao.cheng@intel.com>2014-07-25 01:30:22 -0700
committerMichael Armbrust <michael@databricks.com>2014-07-25 01:30:22 -0700
commit184aa1c6c0ddf26b703bcabf55397ade17497465 (patch)
tree10213ed590cd5b6d6a76dfe8b838466d8315c272 /sql
parenteb82abd8e3d25c912fa75201cf4f429aab8d73c7 (diff)
downloadspark-184aa1c6c0ddf26b703bcabf55397ade17497465.tar.gz
spark-184aa1c6c0ddf26b703bcabf55397ade17497465.tar.bz2
spark-184aa1c6c0ddf26b703bcabf55397ade17497465.zip
[SPARK-2665] [SQL] Add EqualNS & Unit Tests
Hive Supports the operator "<=>", which returns same result with EQUAL(=) operator for non-null operands, but returns TRUE if both are NULL, FALSE if one of the them is NULL. Author: Cheng Hao <hao.cheng@intel.com> Closes #1570 from chenghao-intel/equalns and squashes the following commits: 8d6c789 [Cheng Hao] Remove the test case orc_predicate_pushdown 5b2ca88 [Cheng Hao] Add cases into whitelist 8e66cdd [Cheng Hao] Rename the EqualNSTo ==> EqualNullSafe 7af4b0b [Cheng Hao] Add EqualNS & Unit Tests
Diffstat (limited to 'sql')
-rw-r--r--sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/HiveTypeCoercion.scala2
-rw-r--r--sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/dsl/package.scala1
-rw-r--r--sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/predicates.scala16
-rw-r--r--sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/optimizer/Optimizer.scala2
-rw-r--r--sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/ExpressionEvaluationSuite.scala10
-rw-r--r--sql/hive/compatibility/src/test/scala/org/apache/spark/sql/hive/execution/HiveCompatibilitySuite.scala7
-rw-r--r--sql/hive/src/main/scala/org/apache/spark/sql/hive/HiveContext.scala3
-rw-r--r--sql/hive/src/main/scala/org/apache/spark/sql/hive/HiveQl.scala1
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-0-869726b703f160eabdb7763700b53e601
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-1-5644ab44e5ba9f2941216b8d5dc33a990
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-10-b6de4e85dcc1d1949c7431d39fa1b9192
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-11-3aa243002a5363b84556736ef71613b10
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-12-3cc55b14e8256d2c51361b61986c291e4
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-13-69d94e229191e7b9b1a3e7eae46eb99312
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-14-cf9ff6ee72a701a8e2f3e7fb0667903c12
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-15-507d0fa6d7ce39e2d9921555cea6f8da13
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-16-1c714fc339304de4db630530e5d1ce9711
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-17-8a4b0dc781a28ad11a0db9805fe03aa811
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-18-10b2051e65cac50ee1ea1c138ec192c80
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-19-23ab7ac8229a53d391195be7ca0924290
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-2-793e288c9e0971f0bf3f37493f76dc70
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-20-d6fc260320c577eec9a5db0d4135d2240
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-21-a60dae725ffc543f805242611d99de4e0
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-22-24c80d0f9e3d72c48d947770fa1849850
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-23-3fe6ae20cab3417759dcc654a3a267460
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-24-2db30531137611e06fdba478ca7a84121
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-25-e58b2754e8d9c56a473557a549d0d2b91
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-26-64cabe5164130a94f387288f37b62d711
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-27-e8ed4a1b574a6ca70cbfb3f7b9980aa642
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-28-5a0c946cd7033857ca99e5fb800f852514
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-29-514043c2ddaf6ea8f16a764adc92d1cf42
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-3-ae378fc0f875a21884e58fa35a6d52cd0
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-30-fcbf92cb1b85ab01102fbbc6caba9a8842
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-31-1cb03e1106f79d14f22bc89d386cedcf42
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-32-6a0bf6127d4b042e67ae8ee15125fb8740
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-33-63157d43422fcedadba408537ccecd5c40
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-34-9265f806b71c03061f93f9fbc88aa22342
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-35-95815bafb81cccb8129c20d399a446fc42
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-36-c4762c60cc93236b7647ebd32a40ce5742
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-37-a87893adfc73c9cc63ceab200bb5624542
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-38-e3dfe0044b44c8a49414479521acf76242
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-39-9a7e1f373b9c02e632d6c7c550b908ec42
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-4-644c616d87ae426eb2f8c7163804518511
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-40-3c868718e4c120cb9a72ab7318c75be30
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-41-1f7d8737c3e2d74d5ad865535d7298119
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-5-1e393de94850e92b3b00536aacc9371f0
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-6-d66451815212e7d17744184e74c6b0a02
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-7-a3ad3cc301d9884898d3e6ab6c792d4c0
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-8-cc7527bcf746ab7e2cd9f28db0ead0ac29
-rw-r--r--sql/hive/src/test/resources/golden/join_nullsafe-9-88f6f40959b0d2faabd9d4b3cd8538090
-rw-r--r--sql/hive/src/test/resources/golden/udf_equal-0-36b6cdf7c5f68c91155569b1622f58761
-rw-r--r--sql/hive/src/test/resources/golden/udf_equal-1-2422b50b96502dde8b661acdfebd88922
-rw-r--r--sql/hive/src/test/resources/golden/udf_equal-2-e0faab0f5e736c24bcc5503aeac550531
-rw-r--r--sql/hive/src/test/resources/golden/udf_equal-3-39d8d6f197803de927f0af5409ec2f332
-rw-r--r--sql/hive/src/test/resources/golden/udf_equal-4-94ac2476006425e1b3bcddf29ad07b161
-rw-r--r--sql/hive/src/test/resources/golden/udf_equal-5-878650cf21e9360a07d204c8ffb0cde71
-rw-r--r--sql/hive/src/test/resources/golden/udf_equal-6-1635ef051fecdfc7891d9f5a9a3a545e1
-rw-r--r--sql/hive/src/test/resources/golden/udf_equal-7-78f1b96c199e307714fa1b804e5bae271
58 files changed, 683 insertions, 3 deletions
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/HiveTypeCoercion.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/HiveTypeCoercion.scala
index 9887856b9c..67a8ce9b88 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/HiveTypeCoercion.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/HiveTypeCoercion.scala
@@ -246,6 +246,8 @@ trait HiveTypeCoercion {
// No need to change other EqualTo operators as that actually makes sense for boolean types.
case e: EqualTo => e
+ // No need to change the EqualNullSafe operators, too
+ case e: EqualNullSafe => e
// Otherwise turn them to Byte types so that there exists and ordering.
case p: BinaryComparison
if p.left.dataType == BooleanType && p.right.dataType == BooleanType =>
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/dsl/package.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/dsl/package.scala
index 15c98efbca..5c8c810d91 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/dsl/package.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/dsl/package.scala
@@ -77,6 +77,7 @@ package object dsl {
def > (other: Expression) = GreaterThan(expr, other)
def >= (other: Expression) = GreaterThanOrEqual(expr, other)
def === (other: Expression) = EqualTo(expr, other)
+ def <=> (other: Expression) = EqualNullSafe(expr, other)
def !== (other: Expression) = Not(EqualTo(expr, other))
def in(list: Expression*) = In(expr, list)
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/predicates.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/predicates.scala
index b63406b94a..06b94a98d3 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/predicates.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/predicates.scala
@@ -153,6 +153,22 @@ case class EqualTo(left: Expression, right: Expression) extends BinaryComparison
}
}
+case class EqualNullSafe(left: Expression, right: Expression) extends BinaryComparison {
+ def symbol = "<=>"
+ override def nullable = false
+ override def eval(input: Row): Any = {
+ val l = left.eval(input)
+ val r = right.eval(input)
+ if (l == null && r == null) {
+ true
+ } else if (l == null || r == null) {
+ false
+ } else {
+ l == r
+ }
+ }
+}
+
case class LessThan(left: Expression, right: Expression) extends BinaryComparison {
def symbol = "<"
override def eval(input: Row): Any = c2(input, left, right, _.lt(_, _))
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/optimizer/Optimizer.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/optimizer/Optimizer.scala
index c65987b712..5f86d6047c 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/optimizer/Optimizer.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/optimizer/Optimizer.scala
@@ -153,6 +153,8 @@ object NullPropagation extends Rule[LogicalPlan] {
case e @ GetItem(Literal(null, _), _) => Literal(null, e.dataType)
case e @ GetItem(_, Literal(null, _)) => Literal(null, e.dataType)
case e @ GetField(Literal(null, _), _) => Literal(null, e.dataType)
+ case e @ EqualNullSafe(Literal(null, _), r) => IsNull(r)
+ case e @ EqualNullSafe(l, Literal(null, _)) => IsNull(l)
// For Coalesce, remove null literals.
case e @ Coalesce(children) =>
diff --git a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/ExpressionEvaluationSuite.scala b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/ExpressionEvaluationSuite.scala
index c3f5c26fdb..58f8c341e6 100644
--- a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/ExpressionEvaluationSuite.scala
+++ b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/ExpressionEvaluationSuite.scala
@@ -451,11 +451,13 @@ class ExpressionEvaluationSuite extends FunSuite {
}
test("BinaryComparison") {
- val row = new GenericRow(Array[Any](1, 2, 3, null))
+ val row = new GenericRow(Array[Any](1, 2, 3, null, 3, null))
val c1 = 'a.int.at(0)
val c2 = 'a.int.at(1)
val c3 = 'a.int.at(2)
val c4 = 'a.int.at(3)
+ val c5 = 'a.int.at(4)
+ val c6 = 'a.int.at(5)
checkEvaluation(LessThan(c1, c4), null, row)
checkEvaluation(LessThan(c1, c2), true, row)
@@ -469,6 +471,12 @@ class ExpressionEvaluationSuite extends FunSuite {
checkEvaluation(c1 >= c2, false, row)
checkEvaluation(c1 === c2, false, row)
checkEvaluation(c1 !== c2, true, row)
+ checkEvaluation(c4 <=> c1, false, row)
+ checkEvaluation(c1 <=> c4, false, row)
+ checkEvaluation(c4 <=> c6, true, row)
+ checkEvaluation(c3 <=> c5, true, row)
+ checkEvaluation(Literal(true) <=> Literal(null, BooleanType), false, row)
+ checkEvaluation(Literal(null, BooleanType) <=> Literal(true), false, row)
}
test("StringComparison") {
diff --git a/sql/hive/compatibility/src/test/scala/org/apache/spark/sql/hive/execution/HiveCompatibilitySuite.scala b/sql/hive/compatibility/src/test/scala/org/apache/spark/sql/hive/execution/HiveCompatibilitySuite.scala
index 8b451973a4..c69e93ba2b 100644
--- a/sql/hive/compatibility/src/test/scala/org/apache/spark/sql/hive/execution/HiveCompatibilitySuite.scala
+++ b/sql/hive/compatibility/src/test/scala/org/apache/spark/sql/hive/execution/HiveCompatibilitySuite.scala
@@ -196,7 +196,10 @@ class HiveCompatibilitySuite extends HiveQueryFileTest with BeforeAndAfter {
// Hive returns the results of describe as plain text. Comments with multiple lines
// introduce extra lines in the Hive results, which make the result comparison fail.
- "describe_comment_indent"
+ "describe_comment_indent",
+
+ // Limit clause without a ordering, which causes failure.
+ "orc_predicate_pushdown"
)
/**
@@ -503,6 +506,7 @@ class HiveCompatibilitySuite extends HiveQueryFileTest with BeforeAndAfter {
"join_hive_626",
"join_map_ppr",
"join_nulls",
+ "join_nullsafe",
"join_rc",
"join_reorder2",
"join_reorder3",
@@ -734,6 +738,7 @@ class HiveCompatibilitySuite extends HiveQueryFileTest with BeforeAndAfter {
"udf_double",
"udf_E",
"udf_elt",
+ "udf_equal",
"udf_exp",
"udf_field",
"udf_find_in_set",
diff --git a/sql/hive/src/main/scala/org/apache/spark/sql/hive/HiveContext.scala b/sql/hive/src/main/scala/org/apache/spark/sql/hive/HiveContext.scala
index 334462357e..201c85f3d5 100644
--- a/sql/hive/src/main/scala/org/apache/spark/sql/hive/HiveContext.scala
+++ b/sql/hive/src/main/scala/org/apache/spark/sql/hive/HiveContext.scala
@@ -253,7 +253,7 @@ class HiveContext(sc: SparkContext) extends SQLContext(sc) {
protected val primitiveTypes =
Seq(StringType, IntegerType, LongType, DoubleType, FloatType, BooleanType, ByteType,
- ShortType, DecimalType, TimestampType)
+ ShortType, DecimalType, TimestampType, BinaryType)
protected def toHiveString(a: (Any, DataType)): String = a match {
case (struct: Row, StructType(fields)) =>
@@ -269,6 +269,7 @@ class HiveContext(sc: SparkContext) extends SQLContext(sc) {
}.toSeq.sorted.mkString("{", ",", "}")
case (null, _) => "NULL"
case (t: Timestamp, TimestampType) => new TimestampWritable(t).toString
+ case (bin: Array[Byte], BinaryType) => new String(bin, "UTF-8")
case (other, tpe) if primitiveTypes contains tpe => other.toString
}
diff --git a/sql/hive/src/main/scala/org/apache/spark/sql/hive/HiveQl.scala b/sql/hive/src/main/scala/org/apache/spark/sql/hive/HiveQl.scala
index c4ca9f362a..4395874526 100644
--- a/sql/hive/src/main/scala/org/apache/spark/sql/hive/HiveQl.scala
+++ b/sql/hive/src/main/scala/org/apache/spark/sql/hive/HiveQl.scala
@@ -931,6 +931,7 @@ private[hive] object HiveQl {
/* Comparisons */
case Token("=", left :: right:: Nil) => EqualTo(nodeToExpr(left), nodeToExpr(right))
case Token("==", left :: right:: Nil) => EqualTo(nodeToExpr(left), nodeToExpr(right))
+ case Token("<=>", left :: right:: Nil) => EqualNullSafe(nodeToExpr(left), nodeToExpr(right))
case Token("!=", left :: right:: Nil) => Not(EqualTo(nodeToExpr(left), nodeToExpr(right)))
case Token("<>", left :: right:: Nil) => Not(EqualTo(nodeToExpr(left), nodeToExpr(right)))
case Token(">", left :: right:: Nil) => GreaterThan(nodeToExpr(left), nodeToExpr(right))
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-0-869726b703f160eabdb7763700b53e60 b/sql/hive/src/test/resources/golden/join_nullsafe-0-869726b703f160eabdb7763700b53e60
new file mode 100644
index 0000000000..573541ac97
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-0-869726b703f160eabdb7763700b53e60
@@ -0,0 +1 @@
+0
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-1-5644ab44e5ba9f2941216b8d5dc33a99 b/sql/hive/src/test/resources/golden/join_nullsafe-1-5644ab44e5ba9f2941216b8d5dc33a99
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-1-5644ab44e5ba9f2941216b8d5dc33a99
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-10-b6de4e85dcc1d1949c7431d39fa1b919 b/sql/hive/src/test/resources/golden/join_nullsafe-10-b6de4e85dcc1d1949c7431d39fa1b919
new file mode 100644
index 0000000000..31c409082c
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-10-b6de4e85dcc1d1949c7431d39fa1b919
@@ -0,0 +1,2 @@
+NULL 10 10 NULL NULL 10
+100 100 100 100 100 100
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-11-3aa243002a5363b84556736ef71613b1 b/sql/hive/src/test/resources/golden/join_nullsafe-11-3aa243002a5363b84556736ef71613b1
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-11-3aa243002a5363b84556736ef71613b1
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-12-3cc55b14e8256d2c51361b61986c291e b/sql/hive/src/test/resources/golden/join_nullsafe-12-3cc55b14e8256d2c51361b61986c291e
new file mode 100644
index 0000000000..9b77d13cba
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-12-3cc55b14e8256d2c51361b61986c291e
@@ -0,0 +1,4 @@
+NULL NULL NULL NULL NULL NULL
+NULL 10 10 NULL NULL 10
+10 NULL NULL 10 10 NULL
+100 100 100 100 100 100
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-13-69d94e229191e7b9b1a3e7eae46eb993 b/sql/hive/src/test/resources/golden/join_nullsafe-13-69d94e229191e7b9b1a3e7eae46eb993
new file mode 100644
index 0000000000..47c0709d39
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-13-69d94e229191e7b9b1a3e7eae46eb993
@@ -0,0 +1,12 @@
+NULL NULL NULL NULL
+NULL NULL 10 NULL
+NULL NULL 48 NULL
+NULL 10 NULL NULL
+NULL 10 10 NULL
+NULL 10 48 NULL
+NULL 35 NULL NULL
+NULL 35 10 NULL
+NULL 35 48 NULL
+10 NULL NULL 10
+48 NULL NULL NULL
+100 100 100 100
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-14-cf9ff6ee72a701a8e2f3e7fb0667903c b/sql/hive/src/test/resources/golden/join_nullsafe-14-cf9ff6ee72a701a8e2f3e7fb0667903c
new file mode 100644
index 0000000000..36ba48516b
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-14-cf9ff6ee72a701a8e2f3e7fb0667903c
@@ -0,0 +1,12 @@
+NULL NULL NULL NULL
+NULL NULL NULL 35
+NULL NULL 10 NULL
+NULL NULL 48 NULL
+NULL 10 NULL NULL
+NULL 10 10 NULL
+NULL 10 48 NULL
+NULL 35 NULL NULL
+NULL 35 10 NULL
+NULL 35 48 NULL
+10 NULL NULL 10
+100 100 100 100
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-15-507d0fa6d7ce39e2d9921555cea6f8da b/sql/hive/src/test/resources/golden/join_nullsafe-15-507d0fa6d7ce39e2d9921555cea6f8da
new file mode 100644
index 0000000000..fc1fd198cf
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-15-507d0fa6d7ce39e2d9921555cea6f8da
@@ -0,0 +1,13 @@
+NULL NULL NULL NULL
+NULL NULL NULL 35
+NULL NULL 10 NULL
+NULL NULL 48 NULL
+NULL 10 NULL NULL
+NULL 10 10 NULL
+NULL 10 48 NULL
+NULL 35 NULL NULL
+NULL 35 10 NULL
+NULL 35 48 NULL
+10 NULL NULL 10
+48 NULL NULL NULL
+100 100 100 100
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-16-1c714fc339304de4db630530e5d1ce97 b/sql/hive/src/test/resources/golden/join_nullsafe-16-1c714fc339304de4db630530e5d1ce97
new file mode 100644
index 0000000000..1cc70524f9
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-16-1c714fc339304de4db630530e5d1ce97
@@ -0,0 +1,11 @@
+NULL NULL NULL NULL
+NULL NULL 10 NULL
+NULL NULL 48 NULL
+NULL 10 NULL NULL
+NULL 10 10 NULL
+NULL 10 48 NULL
+NULL 35 NULL NULL
+NULL 35 10 NULL
+NULL 35 48 NULL
+10 NULL NULL 10
+100 100 100 100
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-17-8a4b0dc781a28ad11a0db9805fe03aa8 b/sql/hive/src/test/resources/golden/join_nullsafe-17-8a4b0dc781a28ad11a0db9805fe03aa8
new file mode 100644
index 0000000000..1cc70524f9
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-17-8a4b0dc781a28ad11a0db9805fe03aa8
@@ -0,0 +1,11 @@
+NULL NULL NULL NULL
+NULL NULL 10 NULL
+NULL NULL 48 NULL
+NULL 10 NULL NULL
+NULL 10 10 NULL
+NULL 10 48 NULL
+NULL 35 NULL NULL
+NULL 35 10 NULL
+NULL 35 48 NULL
+10 NULL NULL 10
+100 100 100 100
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-18-10b2051e65cac50ee1ea1c138ec192c8 b/sql/hive/src/test/resources/golden/join_nullsafe-18-10b2051e65cac50ee1ea1c138ec192c8
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-18-10b2051e65cac50ee1ea1c138ec192c8
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-19-23ab7ac8229a53d391195be7ca092429 b/sql/hive/src/test/resources/golden/join_nullsafe-19-23ab7ac8229a53d391195be7ca092429
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-19-23ab7ac8229a53d391195be7ca092429
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-2-793e288c9e0971f0bf3f37493f76dc7 b/sql/hive/src/test/resources/golden/join_nullsafe-2-793e288c9e0971f0bf3f37493f76dc7
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-2-793e288c9e0971f0bf3f37493f76dc7
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-20-d6fc260320c577eec9a5db0d4135d224 b/sql/hive/src/test/resources/golden/join_nullsafe-20-d6fc260320c577eec9a5db0d4135d224
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-20-d6fc260320c577eec9a5db0d4135d224
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-21-a60dae725ffc543f805242611d99de4e b/sql/hive/src/test/resources/golden/join_nullsafe-21-a60dae725ffc543f805242611d99de4e
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-21-a60dae725ffc543f805242611d99de4e
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-22-24c80d0f9e3d72c48d947770fa184985 b/sql/hive/src/test/resources/golden/join_nullsafe-22-24c80d0f9e3d72c48d947770fa184985
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-22-24c80d0f9e3d72c48d947770fa184985
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-23-3fe6ae20cab3417759dcc654a3a26746 b/sql/hive/src/test/resources/golden/join_nullsafe-23-3fe6ae20cab3417759dcc654a3a26746
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-23-3fe6ae20cab3417759dcc654a3a26746
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-24-2db30531137611e06fdba478ca7a8412 b/sql/hive/src/test/resources/golden/join_nullsafe-24-2db30531137611e06fdba478ca7a8412
new file mode 100644
index 0000000000..573541ac97
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-24-2db30531137611e06fdba478ca7a8412
@@ -0,0 +1 @@
+0
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-25-e58b2754e8d9c56a473557a549d0d2b9 b/sql/hive/src/test/resources/golden/join_nullsafe-25-e58b2754e8d9c56a473557a549d0d2b9
new file mode 100644
index 0000000000..573541ac97
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-25-e58b2754e8d9c56a473557a549d0d2b9
@@ -0,0 +1 @@
+0
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-26-64cabe5164130a94f387288f37b62d71 b/sql/hive/src/test/resources/golden/join_nullsafe-26-64cabe5164130a94f387288f37b62d71
new file mode 100644
index 0000000000..573541ac97
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-26-64cabe5164130a94f387288f37b62d71
@@ -0,0 +1 @@
+0
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-27-e8ed4a1b574a6ca70cbfb3f7b9980aa6 b/sql/hive/src/test/resources/golden/join_nullsafe-27-e8ed4a1b574a6ca70cbfb3f7b9980aa6
new file mode 100644
index 0000000000..6648229990
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-27-e8ed4a1b574a6ca70cbfb3f7b9980aa6
@@ -0,0 +1,42 @@
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL 10
+NULL NULL NULL 10
+NULL NULL NULL 35
+NULL NULL NULL 35
+NULL NULL NULL 110
+NULL NULL NULL 110
+NULL NULL NULL 135
+NULL NULL NULL 135
+NULL 10 NULL NULL
+NULL 10 NULL NULL
+NULL 10 NULL 10
+NULL 10 NULL 35
+NULL 10 NULL 110
+NULL 10 NULL 135
+NULL 35 NULL NULL
+NULL 35 NULL NULL
+NULL 35 NULL 10
+NULL 35 NULL 35
+NULL 35 NULL 110
+NULL 35 NULL 135
+NULL 110 NULL NULL
+NULL 110 NULL NULL
+NULL 110 NULL 10
+NULL 110 NULL 35
+NULL 110 NULL 110
+NULL 110 NULL 135
+NULL 135 NULL NULL
+NULL 135 NULL NULL
+NULL 135 NULL 10
+NULL 135 NULL 35
+NULL 135 NULL 110
+NULL 135 NULL 135
+10 NULL 10 NULL
+48 NULL 48 NULL
+100 100 100 100
+110 NULL 110 NULL
+148 NULL 148 NULL
+200 200 200 200
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-28-5a0c946cd7033857ca99e5fb800f8525 b/sql/hive/src/test/resources/golden/join_nullsafe-28-5a0c946cd7033857ca99e5fb800f8525
new file mode 100644
index 0000000000..2efbef0484
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-28-5a0c946cd7033857ca99e5fb800f8525
@@ -0,0 +1,14 @@
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL 10 NULL 10
+NULL 35 NULL 35
+NULL 110 NULL 110
+NULL 135 NULL 135
+10 NULL 10 NULL
+48 NULL 48 NULL
+100 100 100 100
+110 NULL 110 NULL
+148 NULL 148 NULL
+200 200 200 200
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-29-514043c2ddaf6ea8f16a764adc92d1cf b/sql/hive/src/test/resources/golden/join_nullsafe-29-514043c2ddaf6ea8f16a764adc92d1cf
new file mode 100644
index 0000000000..6648229990
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-29-514043c2ddaf6ea8f16a764adc92d1cf
@@ -0,0 +1,42 @@
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL 10
+NULL NULL NULL 10
+NULL NULL NULL 35
+NULL NULL NULL 35
+NULL NULL NULL 110
+NULL NULL NULL 110
+NULL NULL NULL 135
+NULL NULL NULL 135
+NULL 10 NULL NULL
+NULL 10 NULL NULL
+NULL 10 NULL 10
+NULL 10 NULL 35
+NULL 10 NULL 110
+NULL 10 NULL 135
+NULL 35 NULL NULL
+NULL 35 NULL NULL
+NULL 35 NULL 10
+NULL 35 NULL 35
+NULL 35 NULL 110
+NULL 35 NULL 135
+NULL 110 NULL NULL
+NULL 110 NULL NULL
+NULL 110 NULL 10
+NULL 110 NULL 35
+NULL 110 NULL 110
+NULL 110 NULL 135
+NULL 135 NULL NULL
+NULL 135 NULL NULL
+NULL 135 NULL 10
+NULL 135 NULL 35
+NULL 135 NULL 110
+NULL 135 NULL 135
+10 NULL 10 NULL
+48 NULL 48 NULL
+100 100 100 100
+110 NULL 110 NULL
+148 NULL 148 NULL
+200 200 200 200
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-3-ae378fc0f875a21884e58fa35a6d52cd b/sql/hive/src/test/resources/golden/join_nullsafe-3-ae378fc0f875a21884e58fa35a6d52cd
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-3-ae378fc0f875a21884e58fa35a6d52cd
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-30-fcbf92cb1b85ab01102fbbc6caba9a88 b/sql/hive/src/test/resources/golden/join_nullsafe-30-fcbf92cb1b85ab01102fbbc6caba9a88
new file mode 100644
index 0000000000..6648229990
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-30-fcbf92cb1b85ab01102fbbc6caba9a88
@@ -0,0 +1,42 @@
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL 10
+NULL NULL NULL 10
+NULL NULL NULL 35
+NULL NULL NULL 35
+NULL NULL NULL 110
+NULL NULL NULL 110
+NULL NULL NULL 135
+NULL NULL NULL 135
+NULL 10 NULL NULL
+NULL 10 NULL NULL
+NULL 10 NULL 10
+NULL 10 NULL 35
+NULL 10 NULL 110
+NULL 10 NULL 135
+NULL 35 NULL NULL
+NULL 35 NULL NULL
+NULL 35 NULL 10
+NULL 35 NULL 35
+NULL 35 NULL 110
+NULL 35 NULL 135
+NULL 110 NULL NULL
+NULL 110 NULL NULL
+NULL 110 NULL 10
+NULL 110 NULL 35
+NULL 110 NULL 110
+NULL 110 NULL 135
+NULL 135 NULL NULL
+NULL 135 NULL NULL
+NULL 135 NULL 10
+NULL 135 NULL 35
+NULL 135 NULL 110
+NULL 135 NULL 135
+10 NULL 10 NULL
+48 NULL 48 NULL
+100 100 100 100
+110 NULL 110 NULL
+148 NULL 148 NULL
+200 200 200 200
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-31-1cb03e1106f79d14f22bc89d386cedcf b/sql/hive/src/test/resources/golden/join_nullsafe-31-1cb03e1106f79d14f22bc89d386cedcf
new file mode 100644
index 0000000000..6648229990
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-31-1cb03e1106f79d14f22bc89d386cedcf
@@ -0,0 +1,42 @@
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL 10
+NULL NULL NULL 10
+NULL NULL NULL 35
+NULL NULL NULL 35
+NULL NULL NULL 110
+NULL NULL NULL 110
+NULL NULL NULL 135
+NULL NULL NULL 135
+NULL 10 NULL NULL
+NULL 10 NULL NULL
+NULL 10 NULL 10
+NULL 10 NULL 35
+NULL 10 NULL 110
+NULL 10 NULL 135
+NULL 35 NULL NULL
+NULL 35 NULL NULL
+NULL 35 NULL 10
+NULL 35 NULL 35
+NULL 35 NULL 110
+NULL 35 NULL 135
+NULL 110 NULL NULL
+NULL 110 NULL NULL
+NULL 110 NULL 10
+NULL 110 NULL 35
+NULL 110 NULL 110
+NULL 110 NULL 135
+NULL 135 NULL NULL
+NULL 135 NULL NULL
+NULL 135 NULL 10
+NULL 135 NULL 35
+NULL 135 NULL 110
+NULL 135 NULL 135
+10 NULL 10 NULL
+48 NULL 48 NULL
+100 100 100 100
+110 NULL 110 NULL
+148 NULL 148 NULL
+200 200 200 200
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-32-6a0bf6127d4b042e67ae8ee15125fb87 b/sql/hive/src/test/resources/golden/join_nullsafe-32-6a0bf6127d4b042e67ae8ee15125fb87
new file mode 100644
index 0000000000..ea001a222f
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-32-6a0bf6127d4b042e67ae8ee15125fb87
@@ -0,0 +1,40 @@
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL 10 NULL
+NULL NULL 10 NULL
+NULL NULL 48 NULL
+NULL NULL 48 NULL
+NULL NULL 110 NULL
+NULL NULL 110 NULL
+NULL NULL 148 NULL
+NULL NULL 148 NULL
+NULL 10 NULL NULL
+NULL 10 NULL NULL
+NULL 10 10 NULL
+NULL 10 48 NULL
+NULL 10 110 NULL
+NULL 10 148 NULL
+NULL 35 NULL NULL
+NULL 35 NULL NULL
+NULL 35 10 NULL
+NULL 35 48 NULL
+NULL 35 110 NULL
+NULL 35 148 NULL
+NULL 110 NULL NULL
+NULL 110 NULL NULL
+NULL 110 10 NULL
+NULL 110 48 NULL
+NULL 110 110 NULL
+NULL 110 148 NULL
+NULL 135 NULL NULL
+NULL 135 NULL NULL
+NULL 135 10 NULL
+NULL 135 48 NULL
+NULL 135 110 NULL
+NULL 135 148 NULL
+10 NULL NULL 10
+100 100 100 100
+110 NULL NULL 110
+200 200 200 200
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-33-63157d43422fcedadba408537ccecd5c b/sql/hive/src/test/resources/golden/join_nullsafe-33-63157d43422fcedadba408537ccecd5c
new file mode 100644
index 0000000000..ea001a222f
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-33-63157d43422fcedadba408537ccecd5c
@@ -0,0 +1,40 @@
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL 10 NULL
+NULL NULL 10 NULL
+NULL NULL 48 NULL
+NULL NULL 48 NULL
+NULL NULL 110 NULL
+NULL NULL 110 NULL
+NULL NULL 148 NULL
+NULL NULL 148 NULL
+NULL 10 NULL NULL
+NULL 10 NULL NULL
+NULL 10 10 NULL
+NULL 10 48 NULL
+NULL 10 110 NULL
+NULL 10 148 NULL
+NULL 35 NULL NULL
+NULL 35 NULL NULL
+NULL 35 10 NULL
+NULL 35 48 NULL
+NULL 35 110 NULL
+NULL 35 148 NULL
+NULL 110 NULL NULL
+NULL 110 NULL NULL
+NULL 110 10 NULL
+NULL 110 48 NULL
+NULL 110 110 NULL
+NULL 110 148 NULL
+NULL 135 NULL NULL
+NULL 135 NULL NULL
+NULL 135 10 NULL
+NULL 135 48 NULL
+NULL 135 110 NULL
+NULL 135 148 NULL
+10 NULL NULL 10
+100 100 100 100
+110 NULL NULL 110
+200 200 200 200
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-34-9265f806b71c03061f93f9fbc88aa223 b/sql/hive/src/test/resources/golden/join_nullsafe-34-9265f806b71c03061f93f9fbc88aa223
new file mode 100644
index 0000000000..1093bd89f6
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-34-9265f806b71c03061f93f9fbc88aa223
@@ -0,0 +1,42 @@
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL 10 NULL
+NULL NULL 10 NULL
+NULL NULL 48 NULL
+NULL NULL 48 NULL
+NULL NULL 110 NULL
+NULL NULL 110 NULL
+NULL NULL 148 NULL
+NULL NULL 148 NULL
+NULL 10 NULL NULL
+NULL 10 NULL NULL
+NULL 10 10 NULL
+NULL 10 48 NULL
+NULL 10 110 NULL
+NULL 10 148 NULL
+NULL 35 NULL NULL
+NULL 35 NULL NULL
+NULL 35 10 NULL
+NULL 35 48 NULL
+NULL 35 110 NULL
+NULL 35 148 NULL
+NULL 110 NULL NULL
+NULL 110 NULL NULL
+NULL 110 10 NULL
+NULL 110 48 NULL
+NULL 110 110 NULL
+NULL 110 148 NULL
+NULL 135 NULL NULL
+NULL 135 NULL NULL
+NULL 135 10 NULL
+NULL 135 48 NULL
+NULL 135 110 NULL
+NULL 135 148 NULL
+10 NULL NULL 10
+48 NULL NULL NULL
+100 100 100 100
+110 NULL NULL 110
+148 NULL NULL NULL
+200 200 200 200
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-35-95815bafb81cccb8129c20d399a446fc b/sql/hive/src/test/resources/golden/join_nullsafe-35-95815bafb81cccb8129c20d399a446fc
new file mode 100644
index 0000000000..9cf0036674
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-35-95815bafb81cccb8129c20d399a446fc
@@ -0,0 +1,42 @@
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL 35
+NULL NULL NULL 135
+NULL NULL 10 NULL
+NULL NULL 10 NULL
+NULL NULL 48 NULL
+NULL NULL 48 NULL
+NULL NULL 110 NULL
+NULL NULL 110 NULL
+NULL NULL 148 NULL
+NULL NULL 148 NULL
+NULL 10 NULL NULL
+NULL 10 NULL NULL
+NULL 10 10 NULL
+NULL 10 48 NULL
+NULL 10 110 NULL
+NULL 10 148 NULL
+NULL 35 NULL NULL
+NULL 35 NULL NULL
+NULL 35 10 NULL
+NULL 35 48 NULL
+NULL 35 110 NULL
+NULL 35 148 NULL
+NULL 110 NULL NULL
+NULL 110 NULL NULL
+NULL 110 10 NULL
+NULL 110 48 NULL
+NULL 110 110 NULL
+NULL 110 148 NULL
+NULL 135 NULL NULL
+NULL 135 NULL NULL
+NULL 135 10 NULL
+NULL 135 48 NULL
+NULL 135 110 NULL
+NULL 135 148 NULL
+10 NULL NULL 10
+100 100 100 100
+110 NULL NULL 110
+200 200 200 200
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-36-c4762c60cc93236b7647ebd32a40ce57 b/sql/hive/src/test/resources/golden/join_nullsafe-36-c4762c60cc93236b7647ebd32a40ce57
new file mode 100644
index 0000000000..77f6a8ddd7
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-36-c4762c60cc93236b7647ebd32a40ce57
@@ -0,0 +1,42 @@
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL 10 NULL
+NULL NULL 10 NULL
+NULL NULL 48 NULL
+NULL NULL 48 NULL
+NULL NULL 110 NULL
+NULL NULL 110 NULL
+NULL NULL 148 NULL
+NULL NULL 148 NULL
+NULL 10 NULL 10
+NULL 35 NULL 35
+NULL 110 NULL 110
+NULL 135 NULL 135
+10 NULL NULL NULL
+10 NULL NULL NULL
+10 NULL 10 NULL
+10 NULL 48 NULL
+10 NULL 110 NULL
+10 NULL 148 NULL
+48 NULL NULL NULL
+48 NULL NULL NULL
+48 NULL 10 NULL
+48 NULL 48 NULL
+48 NULL 110 NULL
+48 NULL 148 NULL
+100 100 100 100
+110 NULL NULL NULL
+110 NULL NULL NULL
+110 NULL 10 NULL
+110 NULL 48 NULL
+110 NULL 110 NULL
+110 NULL 148 NULL
+148 NULL NULL NULL
+148 NULL NULL NULL
+148 NULL 10 NULL
+148 NULL 48 NULL
+148 NULL 110 NULL
+148 NULL 148 NULL
+200 200 200 200
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-37-a87893adfc73c9cc63ceab200bb56245 b/sql/hive/src/test/resources/golden/join_nullsafe-37-a87893adfc73c9cc63ceab200bb56245
new file mode 100644
index 0000000000..77f6a8ddd7
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-37-a87893adfc73c9cc63ceab200bb56245
@@ -0,0 +1,42 @@
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL 10 NULL
+NULL NULL 10 NULL
+NULL NULL 48 NULL
+NULL NULL 48 NULL
+NULL NULL 110 NULL
+NULL NULL 110 NULL
+NULL NULL 148 NULL
+NULL NULL 148 NULL
+NULL 10 NULL 10
+NULL 35 NULL 35
+NULL 110 NULL 110
+NULL 135 NULL 135
+10 NULL NULL NULL
+10 NULL NULL NULL
+10 NULL 10 NULL
+10 NULL 48 NULL
+10 NULL 110 NULL
+10 NULL 148 NULL
+48 NULL NULL NULL
+48 NULL NULL NULL
+48 NULL 10 NULL
+48 NULL 48 NULL
+48 NULL 110 NULL
+48 NULL 148 NULL
+100 100 100 100
+110 NULL NULL NULL
+110 NULL NULL NULL
+110 NULL 10 NULL
+110 NULL 48 NULL
+110 NULL 110 NULL
+110 NULL 148 NULL
+148 NULL NULL NULL
+148 NULL NULL NULL
+148 NULL 10 NULL
+148 NULL 48 NULL
+148 NULL 110 NULL
+148 NULL 148 NULL
+200 200 200 200
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-38-e3dfe0044b44c8a49414479521acf762 b/sql/hive/src/test/resources/golden/join_nullsafe-38-e3dfe0044b44c8a49414479521acf762
new file mode 100644
index 0000000000..77f6a8ddd7
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-38-e3dfe0044b44c8a49414479521acf762
@@ -0,0 +1,42 @@
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL 10 NULL
+NULL NULL 10 NULL
+NULL NULL 48 NULL
+NULL NULL 48 NULL
+NULL NULL 110 NULL
+NULL NULL 110 NULL
+NULL NULL 148 NULL
+NULL NULL 148 NULL
+NULL 10 NULL 10
+NULL 35 NULL 35
+NULL 110 NULL 110
+NULL 135 NULL 135
+10 NULL NULL NULL
+10 NULL NULL NULL
+10 NULL 10 NULL
+10 NULL 48 NULL
+10 NULL 110 NULL
+10 NULL 148 NULL
+48 NULL NULL NULL
+48 NULL NULL NULL
+48 NULL 10 NULL
+48 NULL 48 NULL
+48 NULL 110 NULL
+48 NULL 148 NULL
+100 100 100 100
+110 NULL NULL NULL
+110 NULL NULL NULL
+110 NULL 10 NULL
+110 NULL 48 NULL
+110 NULL 110 NULL
+110 NULL 148 NULL
+148 NULL NULL NULL
+148 NULL NULL NULL
+148 NULL 10 NULL
+148 NULL 48 NULL
+148 NULL 110 NULL
+148 NULL 148 NULL
+200 200 200 200
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-39-9a7e1f373b9c02e632d6c7c550b908ec b/sql/hive/src/test/resources/golden/join_nullsafe-39-9a7e1f373b9c02e632d6c7c550b908ec
new file mode 100644
index 0000000000..77f6a8ddd7
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-39-9a7e1f373b9c02e632d6c7c550b908ec
@@ -0,0 +1,42 @@
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL NULL NULL
+NULL NULL 10 NULL
+NULL NULL 10 NULL
+NULL NULL 48 NULL
+NULL NULL 48 NULL
+NULL NULL 110 NULL
+NULL NULL 110 NULL
+NULL NULL 148 NULL
+NULL NULL 148 NULL
+NULL 10 NULL 10
+NULL 35 NULL 35
+NULL 110 NULL 110
+NULL 135 NULL 135
+10 NULL NULL NULL
+10 NULL NULL NULL
+10 NULL 10 NULL
+10 NULL 48 NULL
+10 NULL 110 NULL
+10 NULL 148 NULL
+48 NULL NULL NULL
+48 NULL NULL NULL
+48 NULL 10 NULL
+48 NULL 48 NULL
+48 NULL 110 NULL
+48 NULL 148 NULL
+100 100 100 100
+110 NULL NULL NULL
+110 NULL NULL NULL
+110 NULL 10 NULL
+110 NULL 48 NULL
+110 NULL 110 NULL
+110 NULL 148 NULL
+148 NULL NULL NULL
+148 NULL NULL NULL
+148 NULL 10 NULL
+148 NULL 48 NULL
+148 NULL 110 NULL
+148 NULL 148 NULL
+200 200 200 200
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-4-644c616d87ae426eb2f8c71638045185 b/sql/hive/src/test/resources/golden/join_nullsafe-4-644c616d87ae426eb2f8c71638045185
new file mode 100644
index 0000000000..1cc70524f9
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-4-644c616d87ae426eb2f8c71638045185
@@ -0,0 +1,11 @@
+NULL NULL NULL NULL
+NULL NULL 10 NULL
+NULL NULL 48 NULL
+NULL 10 NULL NULL
+NULL 10 10 NULL
+NULL 10 48 NULL
+NULL 35 NULL NULL
+NULL 35 10 NULL
+NULL 35 48 NULL
+10 NULL NULL 10
+100 100 100 100
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-40-3c868718e4c120cb9a72ab7318c75be3 b/sql/hive/src/test/resources/golden/join_nullsafe-40-3c868718e4c120cb9a72ab7318c75be3
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-40-3c868718e4c120cb9a72ab7318c75be3
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-41-1f7d8737c3e2d74d5ad865535d729811 b/sql/hive/src/test/resources/golden/join_nullsafe-41-1f7d8737c3e2d74d5ad865535d729811
new file mode 100644
index 0000000000..421049d6e5
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-41-1f7d8737c3e2d74d5ad865535d729811
@@ -0,0 +1,9 @@
+NULL NULL NULL NULL
+NULL NULL 10 NULL
+NULL NULL 48 NULL
+NULL 10 NULL NULL
+NULL 10 10 NULL
+NULL 10 48 NULL
+NULL 35 NULL NULL
+NULL 35 10 NULL
+NULL 35 48 NULL
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-5-1e393de94850e92b3b00536aacc9371f b/sql/hive/src/test/resources/golden/join_nullsafe-5-1e393de94850e92b3b00536aacc9371f
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-5-1e393de94850e92b3b00536aacc9371f
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-6-d66451815212e7d17744184e74c6b0a0 b/sql/hive/src/test/resources/golden/join_nullsafe-6-d66451815212e7d17744184e74c6b0a0
new file mode 100644
index 0000000000..aec3122cae
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-6-d66451815212e7d17744184e74c6b0a0
@@ -0,0 +1,2 @@
+10 NULL NULL 10 10 NULL
+100 100 100 100 100 100
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-7-a3ad3cc301d9884898d3e6ab6c792d4c b/sql/hive/src/test/resources/golden/join_nullsafe-7-a3ad3cc301d9884898d3e6ab6c792d4c
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-7-a3ad3cc301d9884898d3e6ab6c792d4c
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-8-cc7527bcf746ab7e2cd9f28db0ead0ac b/sql/hive/src/test/resources/golden/join_nullsafe-8-cc7527bcf746ab7e2cd9f28db0ead0ac
new file mode 100644
index 0000000000..30db79efa7
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-8-cc7527bcf746ab7e2cd9f28db0ead0ac
@@ -0,0 +1,29 @@
+NULL NULL NULL NULL NULL NULL
+NULL NULL NULL NULL NULL 10
+NULL NULL NULL NULL NULL 35
+NULL NULL 10 NULL NULL NULL
+NULL NULL 10 NULL NULL 10
+NULL NULL 10 NULL NULL 35
+NULL NULL 48 NULL NULL NULL
+NULL NULL 48 NULL NULL 10
+NULL NULL 48 NULL NULL 35
+NULL 10 NULL NULL NULL NULL
+NULL 10 NULL NULL NULL 10
+NULL 10 NULL NULL NULL 35
+NULL 10 10 NULL NULL NULL
+NULL 10 10 NULL NULL 10
+NULL 10 10 NULL NULL 35
+NULL 10 48 NULL NULL NULL
+NULL 10 48 NULL NULL 10
+NULL 10 48 NULL NULL 35
+NULL 35 NULL NULL NULL NULL
+NULL 35 NULL NULL NULL 10
+NULL 35 NULL NULL NULL 35
+NULL 35 10 NULL NULL NULL
+NULL 35 10 NULL NULL 10
+NULL 35 10 NULL NULL 35
+NULL 35 48 NULL NULL NULL
+NULL 35 48 NULL NULL 10
+NULL 35 48 NULL NULL 35
+10 NULL NULL 10 10 NULL
+100 100 100 100 100 100
diff --git a/sql/hive/src/test/resources/golden/join_nullsafe-9-88f6f40959b0d2faabd9d4b3cd853809 b/sql/hive/src/test/resources/golden/join_nullsafe-9-88f6f40959b0d2faabd9d4b3cd853809
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/join_nullsafe-9-88f6f40959b0d2faabd9d4b3cd853809
diff --git a/sql/hive/src/test/resources/golden/udf_equal-0-36b6cdf7c5f68c91155569b1622f5876 b/sql/hive/src/test/resources/golden/udf_equal-0-36b6cdf7c5f68c91155569b1622f5876
new file mode 100644
index 0000000000..9b9b6312a2
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/udf_equal-0-36b6cdf7c5f68c91155569b1622f5876
@@ -0,0 +1 @@
+a = b - Returns TRUE if a equals b and false otherwise
diff --git a/sql/hive/src/test/resources/golden/udf_equal-1-2422b50b96502dde8b661acdfebd8892 b/sql/hive/src/test/resources/golden/udf_equal-1-2422b50b96502dde8b661acdfebd8892
new file mode 100644
index 0000000000..30fdf50f62
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/udf_equal-1-2422b50b96502dde8b661acdfebd8892
@@ -0,0 +1,2 @@
+a = b - Returns TRUE if a equals b and false otherwise
+Synonyms: ==
diff --git a/sql/hive/src/test/resources/golden/udf_equal-2-e0faab0f5e736c24bcc5503aeac55053 b/sql/hive/src/test/resources/golden/udf_equal-2-e0faab0f5e736c24bcc5503aeac55053
new file mode 100644
index 0000000000..d6b4c86077
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/udf_equal-2-e0faab0f5e736c24bcc5503aeac55053
@@ -0,0 +1 @@
+a == b - Returns TRUE if a equals b and false otherwise
diff --git a/sql/hive/src/test/resources/golden/udf_equal-3-39d8d6f197803de927f0af5409ec2f33 b/sql/hive/src/test/resources/golden/udf_equal-3-39d8d6f197803de927f0af5409ec2f33
new file mode 100644
index 0000000000..71e55d6d63
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/udf_equal-3-39d8d6f197803de927f0af5409ec2f33
@@ -0,0 +1,2 @@
+a == b - Returns TRUE if a equals b and false otherwise
+Synonyms: =
diff --git a/sql/hive/src/test/resources/golden/udf_equal-4-94ac2476006425e1b3bcddf29ad07b16 b/sql/hive/src/test/resources/golden/udf_equal-4-94ac2476006425e1b3bcddf29ad07b16
new file mode 100644
index 0000000000..015c417bc6
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/udf_equal-4-94ac2476006425e1b3bcddf29ad07b16
@@ -0,0 +1 @@
+false false true true NULL NULL NULL NULL NULL
diff --git a/sql/hive/src/test/resources/golden/udf_equal-5-878650cf21e9360a07d204c8ffb0cde7 b/sql/hive/src/test/resources/golden/udf_equal-5-878650cf21e9360a07d204c8ffb0cde7
new file mode 100644
index 0000000000..aa7b4b51ed
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/udf_equal-5-878650cf21e9360a07d204c8ffb0cde7
@@ -0,0 +1 @@
+a <=> b - Returns same result with EQUAL(=) operator for non-null operands, but returns TRUE if both are NULL, FALSE if one of the them is NULL
diff --git a/sql/hive/src/test/resources/golden/udf_equal-6-1635ef051fecdfc7891d9f5a9a3a545e b/sql/hive/src/test/resources/golden/udf_equal-6-1635ef051fecdfc7891d9f5a9a3a545e
new file mode 100644
index 0000000000..aa7b4b51ed
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/udf_equal-6-1635ef051fecdfc7891d9f5a9a3a545e
@@ -0,0 +1 @@
+a <=> b - Returns same result with EQUAL(=) operator for non-null operands, but returns TRUE if both are NULL, FALSE if one of the them is NULL
diff --git a/sql/hive/src/test/resources/golden/udf_equal-7-78f1b96c199e307714fa1b804e5bae27 b/sql/hive/src/test/resources/golden/udf_equal-7-78f1b96c199e307714fa1b804e5bae27
new file mode 100644
index 0000000000..05292fb231
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/udf_equal-7-78f1b96c199e307714fa1b804e5bae27
@@ -0,0 +1 @@
+false false true true true false false false false