Skip to content

Commit 7a4a24b

Browse files
committed
Add ResultState::Empty to defer creation of the indices array
1 parent dafea94 commit 7a4a24b

File tree

1 file changed

+35
-18
lines changed
  • datafusion/physical-expr/src/expressions

1 file changed

+35
-18
lines changed

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

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
// under the License.
1717

1818
use super::{Column, Literal};
19-
use crate::expressions::case::ResultState::{Complete, Partial};
19+
use crate::expressions::case::ResultState::{Complete, Empty, Partial};
2020
use crate::expressions::try_cast;
2121
use crate::PhysicalExpr;
2222
use arrow::array::*;
@@ -293,6 +293,10 @@ impl PartialResultIndex {
293293
Self { index: NONE_VALUE }
294294
}
295295

296+
fn zero() -> Self {
297+
Self { index: 0 }
298+
}
299+
296300
/// Creates a new partial result index.
297301
///
298302
/// If the provided value is greater than or equal to `u32::MAX`
@@ -335,10 +339,12 @@ impl Debug for PartialResultIndex {
335339
}
336340

337341
enum ResultState {
338-
/// The final result needs to be computed by merging the the data in `arrays`.
342+
/// The final result is an array containing only null values.
343+
Empty,
344+
/// The final result needs to be computed by merging the data in `arrays`.
339345
Partial {
340-
// A Vec of partial results that should be merged. `partial_result_indices` contains
341-
// indexes into this vec.
346+
// A `Vec` of partial results that should be merged.
347+
// `partial_result_indices` contains indexes into this vec.
342348
arrays: Vec<ArrayData>,
343349
// Indicates per result row from which array in `partial_results` a value should be taken.
344350
indices: Vec<PartialResultIndex>,
@@ -372,10 +378,7 @@ impl ResultBuilder {
372378
Self {
373379
data_type: data_type.clone(),
374380
row_count,
375-
state: Partial {
376-
arrays: vec![],
377-
indices: vec![PartialResultIndex::none(); row_count],
378-
},
381+
state: Empty,
379382
}
380383
}
381384

@@ -454,6 +457,20 @@ impl ResultBuilder {
454457
}
455458

456459
match &mut self.state {
460+
Empty => {
461+
let array_index = PartialResultIndex::zero();
462+
let mut indices = vec![PartialResultIndex::none(); self.row_count];
463+
for row_ix in row_indices.as_primitive::<UInt32Type>().values().iter() {
464+
indices[*row_ix as usize] = array_index;
465+
}
466+
467+
self.state = Partial {
468+
arrays: vec![row_values],
469+
indices,
470+
};
471+
472+
Ok(())
473+
}
457474
Partial { arrays, indices } => {
458475
let array_index = PartialResultIndex::try_new(arrays.len())?;
459476

@@ -485,27 +502,23 @@ impl ResultBuilder {
485502
/// without any merging overhead.
486503
fn set_complete_result(&mut self, value: ColumnarValue) -> Result<()> {
487504
match &self.state {
488-
Partial { arrays, .. } if !arrays.is_empty() => {
505+
Empty => {
506+
self.state = Complete(value);
507+
Ok(())
508+
}
509+
Partial { .. } => {
489510
internal_err!(
490511
"Cannot set a complete result when there are already partial results"
491512
)
492513
}
493514
Complete(_) => internal_err!("Complete result already set"),
494-
_ => {
495-
self.state = Complete(value);
496-
Ok(())
497-
}
498515
}
499516
}
500517

501518
/// Finishes building the result and returns the final array.
502519
fn finish(self) -> Result<ColumnarValue> {
503520
match self.state {
504-
Complete(v) => {
505-
// If we have a complete result, we can just return it.
506-
Ok(v)
507-
}
508-
Partial { arrays, .. } if arrays.is_empty() => {
521+
Empty => {
509522
// No complete result and no partial results.
510523
// This can happen for case expressions with no else branch where no rows
511524
// matched.
@@ -517,6 +530,10 @@ impl ResultBuilder {
517530
// Merge partial results into a single array.
518531
Ok(ColumnarValue::Array(merge(&arrays, &indices)?))
519532
}
533+
Complete(v) => {
534+
// If we have a complete result, we can just return it.
535+
Ok(v)
536+
}
520537
}
521538
}
522539
}

0 commit comments

Comments
 (0)