@@ -679,12 +679,31 @@ impl ExprSchemable for Expr {
679679 }
680680}
681681
682+ /// Represents the possible values for SQL's three valued logic.
683+ /// `Option<bool>` is not used for this since `None` is used to represent
684+ /// inconclusive answers already.
682685enum TriStateBool {
683686 True ,
684687 False ,
685688 Uncertain ,
686689}
687690
691+ impl TryFrom < & ScalarValue > for TriStateBool {
692+ type Error = DataFusionError ;
693+
694+ fn try_from ( value : & ScalarValue ) -> std:: result:: Result < Self , Self :: Error > {
695+ match value {
696+ ScalarValue :: Null => Ok ( TriStateBool :: Uncertain ) ,
697+ ScalarValue :: Boolean ( b) => Ok ( match b {
698+ None => TriStateBool :: Uncertain ,
699+ Some ( true ) => TriStateBool :: True ,
700+ Some ( false ) => TriStateBool :: False ,
701+ } ) ,
702+ _ => Self :: try_from ( & value. cast_to ( & DataType :: Boolean ) ?)
703+ }
704+ }
705+ }
706+
688707struct WhenThenConstEvaluator < ' a > {
689708 then_expr : & ' a Expr ,
690709 input_schema : & ' a dyn ExprSchema ,
@@ -696,7 +715,7 @@ impl WhenThenConstEvaluator<'_> {
696715 fn const_eval_predicate ( & self , predicate : & Expr ) -> Option < TriStateBool > {
697716 match predicate {
698717 // Literal null is equivalent to boolean uncertain
699- Expr :: Literal ( ScalarValue :: Null , _) => Some ( TriStateBool :: Uncertain ) ,
718+ Expr :: Literal ( scalar , _) => TriStateBool :: try_from ( scalar ) . ok ( ) ,
700719 Expr :: IsNotNull ( e) => {
701720 if let Ok ( false ) = e. nullable ( self . input_schema ) {
702721 // If `e` is not nullable, then `e IS NOT NULL` is always true
@@ -845,7 +864,7 @@ impl WhenThenConstEvaluator<'_> {
845864 }
846865 }
847866
848- /// Determines if the given expression is null.
867+ /// Determines if the given expression evaluates to null.
849868 ///
850869 /// This function returns:
851870 /// - `Some(true)` is `expr` is certainly null
@@ -1201,6 +1220,16 @@ mod tests {
12011220 assert_not_nullable ( & e, & nullable_schema) ;
12021221 assert_not_nullable ( & e, & not_nullable_schema) ;
12031222
1223+ // CASE WHEN 0 THEN x ELSE 0
1224+ let e = when ( lit ( 0 ) , col ( "x" ) ) . otherwise ( lit ( 0 ) ) ?;
1225+ assert_not_nullable ( & e, & nullable_schema) ;
1226+ assert_not_nullable ( & e, & not_nullable_schema) ;
1227+
1228+ // CASE WHEN 1 THEN x ELSE 0
1229+ let e = when ( lit ( 1 ) , col ( "x" ) ) . otherwise ( lit ( 0 ) ) ?;
1230+ assert_nullable ( & e, & nullable_schema) ;
1231+ assert_not_nullable ( & e, & not_nullable_schema) ;
1232+
12041233 Ok ( ( ) )
12051234 }
12061235
0 commit comments