@@ -94,11 +94,59 @@ object ConstantFolding extends Rule[LogicalPlan] {
9494 case q : LogicalPlan => q transformExpressionsDown {
9595 // Skip redundant folding of literals.
9696 case l : Literal => l
97+ case e @ If (Literal (v, _), trueValue, falseValue) => if (v == true ) trueValue else falseValue
98+ case e @ In (Literal (v, _), list) if (list.exists(c => c match {
99+ case Literal (candidate, _) if (candidate == v) => true
100+ case _ => false
101+ })) => Literal (true , BooleanType )
97102 case e if e.foldable => Literal (e.eval(null ), e.dataType)
98103 }
99104 }
100105}
101106
107+ /**
108+ * The expression may be constant value, due to one or more of its children expressions is null or
109+ * not null constantly, replaces [[catalyst.expressions.Expression Expressions ]] with equivalent
110+ * [[catalyst.expressions.Literal Literal ]] values if possible caused by that.
111+ */
112+ object NullPropagation extends Rule [LogicalPlan ] {
113+ def apply (plan : LogicalPlan ): LogicalPlan = plan transform {
114+ case q : LogicalPlan => q transformExpressionsUp {
115+ case l : Literal => l
116+ case e @ IsNull (Literal (null , _)) => Literal (true , BooleanType )
117+ case e @ IsNull (Literal (_, _)) => Literal (false , BooleanType )
118+ case e @ IsNull (c @ Rand ) => Literal (false , BooleanType )
119+ case e @ IsNotNull (Literal (null , _)) => Literal (false , BooleanType )
120+ case e @ IsNotNull (Literal (_, _)) => Literal (true , BooleanType )
121+ case e @ IsNotNull (c @ Rand ) => Literal (true , BooleanType )
122+ case e @ GetItem (Literal (null , _), _) => Literal (null , e.dataType)
123+ case e @ GetItem (_, Literal (null , _)) => Literal (null , e.dataType)
124+ case e @ GetField (Literal (null , _), _) => Literal (null , e.dataType)
125+ case e @ Coalesce (children) => {
126+ val newChildren = children.filter(c => c match {
127+ case Literal (null , _) => false
128+ case _ => true
129+ })
130+ if (newChildren.length == null ) {
131+ Literal (null , e.dataType)
132+ } else if (newChildren.length == children.length){
133+ e
134+ } else {
135+ Coalesce (newChildren)
136+ }
137+ }
138+ // TODO put exceptional cases(Unary & Binary Expression) before here.
139+ case e : UnaryExpression => e.child match {
140+ case Literal (null , _) => Literal (null , e.dataType)
141+ }
142+ case e : BinaryExpression => e.children match {
143+ case Literal (null , _) :: right :: Nil => Literal (null , e.dataType)
144+ case left :: Literal (null , _) :: Nil => Literal (null , e.dataType)
145+ }
146+ }
147+ }
148+ }
149+
102150/**
103151 * Simplifies boolean expressions where the answer can be determined without evaluating both sides.
104152 * Note that this rule can eliminate expressions that might otherwise have been evaluated and thus
0 commit comments