EqualNullSafe Predicate Expression¶
EqualNullSafe is a BinaryComparison predicate expression that represents the following high-level operators in a logical plan:
<=>SQL operatorColumn.<=>operator
Null Safeness¶
EqualNullSafe is safe for null values, i.e. is like EqualTo with the following "safeness":
trueif both operands arenullfalseif either operand isnull
Creating Instance¶
EqualNullSafe takes the following to be created:
- Left Expression
- Right Expression
EqualNullSafe is created when:
AstBuilderis requested to parse a comparison (for<=>operator) and withPredicateColumn.<=>operator is used- others
Interpreted Expression Evaluation¶
eval requests the left and right expressions to evaluate with the given InternalRow.
For all the two expressions evaluated to nulls, eval returns true.
For either expression evaluated to null, eval returns false.
Otherwise, eval uses ordering on the data type of the left expression.
Generating Java Source Code for Code-Generated Expression Evaluation¶
Expression
doGenCode(
ctx: CodegenContext,
ev: ExprCode): ExprCode
doGenCode is part of the Expression abstraction.
doGenCode requests the left and right expressions to generate a source code for expression evaluation.
doGenCode requests the given CodegenContext to generate code for equal expression.
In the end, doGenCode updates the given ExprCode to use the code to evaluate the expression.
import org.apache.spark.sql.catalyst.dsl.expressions._
val right = 'right
val left = 'left
val c = right <=> left
import org.apache.spark.sql.catalyst.expressions.EqualNullSafe
val e = c.expr.asInstanceOf[EqualNullSafe]
import org.apache.spark.sql.catalyst.expressions.codegen.CodegenContext
val ctx = new CodegenContext
// FIXME
scala> e.genCode(ctx)
org.apache.spark.sql.catalyst.analysis.UnresolvedException: Invalid call to dataType on unresolved object
at org.apache.spark.sql.catalyst.analysis.UnresolvedAttribute.dataType(unresolved.scala:227)
at org.apache.spark.sql.catalyst.expressions.Expression.$anonfun$genCode$3(Expression.scala:201)
at scala.Option.getOrElse(Option.scala:201)
at org.apache.spark.sql.catalyst.expressions.Expression.genCode(Expression.scala:196)
at org.apache.spark.sql.catalyst.expressions.EqualNullSafe.doGenCode(predicates.scala:1115)
at org.apache.spark.sql.catalyst.expressions.Expression.$anonfun$genCode$3(Expression.scala:201)
at scala.Option.getOrElse(Option.scala:201)
at org.apache.spark.sql.catalyst.expressions.Expression.genCode(Expression.scala:196)
... 42 elided
Symbol¶
symbol is <=>.
nullable¶
nullable is always false.
Catalyst DSL¶
Catalyst DSL defines <=> operator to create an EqualNullSafe expression.
import org.apache.spark.sql.catalyst.dsl.expressions._
val right = 'right
val left = 'left
val e = right <=> left
scala> e.explain(extended = true)
('right <=> 'left)
scala> println(e.expr.sql)
(`right` <=> `left`)
import org.apache.spark.sql.catalyst.expressions.EqualNullSafe
assert(e.expr.isInstanceOf[EqualNullSafe])