@@ -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