File tree Expand file tree Collapse file tree 2 files changed +12
-12
lines changed
datafusion/physical-expr/src/expression_analyzer Expand file tree Collapse file tree 2 files changed +12
-12
lines changed Original file line number Diff line number Diff line change @@ -210,20 +210,12 @@ impl ExpressionAnalyzer for DefaultExpressionAnalyzer {
210210 return AnalysisResult :: Computed ( 1 ) ;
211211 }
212212
213- // BinaryExpr: for arithmetic with a literal operand, treat as injective
214- // (preserves NDV). This is an approximation: col * 0 or col % 1 are
215- // technically not injective, but the common case (col + 1, col * 2, etc.) is
213+ // BinaryExpr: addition/subtraction with a literal is always injective
214+ // TODO: support more injective operators (e.g. multiply by non-zero)
216215 if let Some ( binary) = expr. as_any ( ) . downcast_ref :: < BinaryExpr > ( ) {
217- let is_arithmetic = matches ! (
218- binary. op( ) ,
219- Operator :: Plus
220- | Operator :: Minus
221- | Operator :: Multiply
222- | Operator :: Divide
223- | Operator :: Modulo
224- ) ;
216+ let is_injective = matches ! ( binary. op( ) , Operator :: Plus | Operator :: Minus ) ;
225217
226- if is_arithmetic {
218+ if is_injective {
227219 // If one side is a literal, the operation is injective on the other side
228220 let left_is_literal = binary. left ( ) . as_any ( ) . is :: < Literal > ( ) ;
229221 let right_is_literal = binary. right ( ) . as_any ( ) . is :: < Literal > ( ) ;
Original file line number Diff line number Diff line change @@ -73,6 +73,14 @@ fn test_arithmetic_ndv() {
7373 ) ) as Arc < dyn PhysicalExpr > ;
7474 assert_eq ! ( registry. get_distinct_count( & plus, & stats) , Some ( 100 ) ) ;
7575
76+ // col - 1: injective, preserves NDV
77+ let minus = Arc :: new ( BinaryExpr :: new (
78+ Arc :: clone ( & col) ,
79+ Operator :: Minus ,
80+ Arc :: clone ( & lit) ,
81+ ) ) as Arc < dyn PhysicalExpr > ;
82+ assert_eq ! ( registry. get_distinct_count( & minus, & stats) , Some ( 100 ) ) ;
83+
7684 // 1 + col: also injective (literal on left)
7785 let plus_rev =
7886 Arc :: new ( BinaryExpr :: new ( lit, Operator :: Plus , col) ) as Arc < dyn PhysicalExpr > ;
You can’t perform that action at this time.
0 commit comments