@@ -376,4 +376,48 @@ mod tests {
376376
377377 Ok ( ( ) )
378378 }
379+
380+ #[ test]
381+ fn test_not_of_not_and_not ( ) -> Result < ( ) > {
382+ let schema = test_schema ( ) ;
383+
384+ // NOT(NOT(a) AND NOT(b)) -> a OR b
385+ // This tests the combination of De Morgan's law and double negation elimination
386+ let not_a = Arc :: new ( NotExpr :: new ( col ( "a" , & schema) ?) ) ;
387+ let not_b = Arc :: new ( NotExpr :: new ( col ( "b" , & schema) ?) ) ;
388+ let and_expr = Arc :: new ( BinaryExpr :: new ( not_a, Operator :: And , not_b) ) ;
389+ let not_and: Arc < dyn PhysicalExpr > = Arc :: new ( NotExpr :: new ( and_expr) ) ;
390+
391+ let result = simplify_not_expr_recursive ( & not_and, & schema) ?;
392+ assert ! ( result. transformed, "Expression should be transformed" ) ;
393+
394+ // Verify the result is an OR expression
395+ if let Some ( or_binary) = result. data . as_any ( ) . downcast_ref :: < BinaryExpr > ( ) {
396+ assert_eq ! ( or_binary. op( ) , & Operator :: Or , "Top level should be OR" ) ;
397+
398+ // Verify left side is just 'a'
399+ assert ! (
400+ or_binary
401+ . left( )
402+ . as_any( )
403+ . downcast_ref:: <NotExpr >( )
404+ . is_none( ) ,
405+ "Left should be simplified to just 'a'"
406+ ) ;
407+
408+ // Verify right side is just 'b'
409+ assert ! (
410+ or_binary
411+ . right( )
412+ . as_any( )
413+ . downcast_ref:: <NotExpr >( )
414+ . is_none( ) ,
415+ "Right should be simplified to just 'b'"
416+ ) ;
417+ } else {
418+ panic ! ( "Expected binary OR expression result" ) ;
419+ }
420+
421+ Ok ( ( ) )
422+ }
379423}
0 commit comments