Skip to content

Commit 43c2fe2

Browse files
committed
Avoid calling interleave in simple cases
1 parent 132757e commit 43c2fe2

File tree

1 file changed

+20
-4
lines changed
  • datafusion/physical-expr/src/expressions

1 file changed

+20
-4
lines changed

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

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -208,10 +208,26 @@ impl InterleaveBuilder {
208208
Ok(())
209209
}
210210

211-
fn finish(self) -> Result<ColumnarValue> {
212-
let array_refs = self.arrays.iter().map(|a| a.as_ref()).collect::<Vec<_>>();
213-
let interleaved_result = interleave(&array_refs, &self.indices)?;
214-
Ok(ColumnarValue::Array(interleaved_result))
211+
fn finish(mut self) -> Result<ColumnarValue> {
212+
if self.arrays.len() == 1 {
213+
// The first array is always a single null value.
214+
if self.indices.len() == 1 {
215+
// If there's only a single row, reuse the array
216+
Ok(ColumnarValue::Array(self.arrays.remove(0)))
217+
} else {
218+
// Otherwise make a new null array with the correct type and length
219+
Ok(ColumnarValue::Array(new_null_array(self.arrays[0].data_type(), self.indices.len())))
220+
}
221+
} else if self.arrays.len() == 2 && !self.indices.iter().any(|(array_ix, _)| *array_ix == 0) && self.arrays[1].len() == self.indices.len() {
222+
// There's only a single non-null array and no references to the null array.
223+
// We can take a shortcut and return the non-null array directly.
224+
Ok(ColumnarValue::Array(self.arrays.remove(1)))
225+
} else {
226+
// Interleave arrays
227+
let array_refs = self.arrays.iter().map(|a| a.as_ref()).collect::<Vec<_>>();
228+
let interleaved_result = interleave(&array_refs, &self.indices)?;
229+
Ok(ColumnarValue::Array(interleaved_result))
230+
}
215231
}
216232
}
217233

0 commit comments

Comments
 (0)