Skip to content

Commit 6c1d328

Browse files
authored
fix: fix NotEq case in anticipation of non-literals (#1260)
The code as written fails when the "other" [min, max] interval has size greater than 1. Call the left-hand-side's interval: `[lmin, lmax]` and the right-hand-side's interval: `[rmin, rmax]`. The current expression is: (lmin == rmin) && (rmin == lmax) || (lmin == rmax) && (rmax == lmax) By transitivity, in either conjunction, lmin == lmax. That means the column has a single known value: lmin (equivalently: lmax). If the right-hand-side is only ever literals or expressions thereof, its interval is always `[x, x]`. In that case, this expression is tantamount to: is the column constant and equal to `x`? If the right-hand-side is either another column or some non-deterministic expression, the interval could be, for example: `[10, 11]`. If the column is known to be the constant value `10` (i.e. its min and max are 10), we cannot prune this chunk! The rows where the right-hand-side is 11 would satisfy the inequality. I'm also open to: `(lmin == lmax) && (lmin == rmin)` with a comment indicating that, because we only have literals, rmin is necessarily equal to rmax and thus rmin _is_ the, known, right-hand-side value.
1 parent 04af8e4 commit 6c1d328

File tree

1 file changed

+25
-27
lines changed

1 file changed

+25
-27
lines changed

vortex-serde/src/layouts/pruning.rs

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -200,23 +200,28 @@ impl<'a> PruningPredicateRewriter<'a> {
200200
let replaced_max = self.rewrite_other_exp(Stat::Max);
201201
let replaced_min = self.rewrite_other_exp(Stat::Min);
202202

203-
// In case of other_exp is literal both sides of AND will be the same expression
203+
let column_value_is_single_known_value = Arc::new(BinaryExpr::new(
204+
min_col.clone(),
205+
Operator::Eq,
206+
max_col.clone(),
207+
));
208+
let column_value = min_col;
209+
210+
let other_value_is_single_known_value = Arc::new(BinaryExpr::new(
211+
replaced_min.clone(),
212+
Operator::Eq,
213+
replaced_max.clone(),
214+
));
215+
let other_value = replaced_min;
216+
204217
Some(Arc::new(BinaryExpr::new(
205218
Arc::new(BinaryExpr::new(
206-
Arc::new(BinaryExpr::new(
207-
min_col.clone(),
208-
Operator::Eq,
209-
replaced_min.clone(),
210-
)),
211-
Operator::And,
212-
Arc::new(BinaryExpr::new(replaced_min, Operator::Eq, max_col.clone())),
213-
)),
214-
Operator::Or,
215-
Arc::new(BinaryExpr::new(
216-
Arc::new(BinaryExpr::new(min_col, Operator::Eq, replaced_max.clone())),
219+
column_value_is_single_known_value,
217220
Operator::And,
218-
Arc::new(BinaryExpr::new(replaced_max, Operator::Eq, max_col)),
221+
other_value_is_single_known_value,
219222
)),
223+
Operator::And,
224+
Arc::new(BinaryExpr::new(column_value, Operator::Eq, other_value)),
220225
)))
221226
}
222227
Operator::Gt | Operator::Gte => {
@@ -394,30 +399,23 @@ mod tests {
394399
Arc::new(BinaryExpr::new(
395400
Arc::new(Column::new(stat_column_name(&column, Stat::Min))),
396401
Operator::Eq,
397-
Arc::new(Column::new(stat_column_name(&other_col, Stat::Min))),
402+
Arc::new(Column::new(stat_column_name(&column, Stat::Max))),
398403
)),
399404
Operator::And,
400405
Arc::new(BinaryExpr::new(
401406
Arc::new(Column::new(stat_column_name(&other_col, Stat::Min))),
402407
Operator::Eq,
403-
Arc::new(Column::new(stat_column_name(&column, Stat::Max))),
408+
Arc::new(Column::new(stat_column_name(&other_col, Stat::Max))),
404409
)),
405410
)),
406-
Operator::Or,
411+
Operator::And,
407412
Arc::new(BinaryExpr::new(
408-
Arc::new(BinaryExpr::new(
409-
Arc::new(Column::new(stat_column_name(&column, Stat::Min))),
410-
Operator::Eq,
411-
Arc::new(Column::new(stat_column_name(&other_col, Stat::Max))),
412-
)),
413-
Operator::And,
414-
Arc::new(BinaryExpr::new(
415-
Arc::new(Column::new(stat_column_name(&other_col, Stat::Max))),
416-
Operator::Eq,
417-
Arc::new(Column::new(stat_column_name(&column, Stat::Max))),
418-
)),
413+
Arc::new(Column::new(stat_column_name(&column, Stat::Min))),
414+
Operator::Eq,
415+
Arc::new(Column::new(stat_column_name(&other_col, Stat::Min))),
419416
)),
420417
));
418+
421419
assert_eq!(*converted, *expected_expr.as_any());
422420
}
423421

0 commit comments

Comments
 (0)