Skip to content

Commit d53febf

Browse files
Dandandanclaude
andcommitted
Use has_true() short-circuit in CASE WHEN evaluation
In multi-branch CASE expressions, later branches commonly match no rows. Using has_true() avoids a full popcount in these cases by short-circuiting on the first true value found. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 0670964 commit d53febf

1 file changed

Lines changed: 8 additions & 14 deletions

File tree

  • datafusion/physical-expr/src/expressions

datafusion/physical-expr/src/expressions/case.rs

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -793,17 +793,14 @@ impl CaseBody {
793793
}
794794
}?;
795795

796-
// `true_count` ignores `true` values where the validity bit is not set, so there's
797-
// no need to call `prep_null_mask_filter`.
798-
let when_true_count = when_value.true_count();
799-
800-
// If the 'when' predicate did not match any rows, continue to the next branch immediately
801-
if when_true_count == 0 {
796+
// If the 'when' predicate did not match any rows, continue to the next branch immediately.
797+
// `has_true` short-circuits on the first true value, avoiding a full popcount.
798+
if !when_value.has_true() {
802799
continue;
803800
}
804801

805802
// If the 'when' predicate matched all remaining rows, there is no need to filter
806-
if when_true_count == remainder_batch.num_rows() {
803+
if when_value.true_count() == remainder_batch.num_rows() {
807804
let then_expression = &self.when_then_expr[i].1;
808805
let then_value = then_expression.evaluate(&remainder_batch)?;
809806
result_builder.add_branch_result(&remainder_rows, then_value)?;
@@ -882,17 +879,14 @@ impl CaseBody {
882879
internal_datafusion_err!("WHEN expression did not return a BooleanArray")
883880
})?;
884881

885-
// `true_count` ignores `true` values where the validity bit is not set, so there's
886-
// no need to call `prep_null_mask_filter`.
887-
let when_true_count = when_value.true_count();
888-
889-
// If the 'when' predicate did not match any rows, continue to the next branch immediately
890-
if when_true_count == 0 {
882+
// If the 'when' predicate did not match any rows, continue to the next branch immediately.
883+
// `has_true` short-circuits on the first true value, avoiding a full popcount.
884+
if !when_value.has_true() {
891885
continue;
892886
}
893887

894888
// If the 'when' predicate matched all remaining rows, there is no need to filter
895-
if when_true_count == remainder_batch.num_rows() {
889+
if when_value.true_count() == remainder_batch.num_rows() {
896890
let then_expression = &self.when_then_expr[i].1;
897891
let then_value = then_expression.evaluate(&remainder_batch)?;
898892
result_builder.add_branch_result(&remainder_rows, then_value)?;

0 commit comments

Comments
 (0)