@@ -94,11 +94,59 @@ object ConstantFolding extends Rule[LogicalPlan] {
94
94
case q : LogicalPlan => q transformExpressionsDown {
95
95
// Skip redundant folding of literals.
96
96
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 )
97
102
case e if e.foldable => Literal (e.eval(null ), e.dataType)
98
103
}
99
104
}
100
105
}
101
106
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
+
102
150
/**
103
151
* Simplifies boolean expressions where the answer can be determined without evaluating both sides.
104
152
* Note that this rule can eliminate expressions that might otherwise have been evaluated and thus
0 commit comments