|
17 | 17 |
|
18 | 18 | use std::sync::Arc; |
19 | 19 |
|
20 | | -use arrow::array::builder::PrimitiveBuilder; |
21 | 20 | use arrow::array::cast::AsArray; |
22 | 21 | use arrow::array::types::Int32Type; |
23 | 22 | use arrow::array::{Array, PrimitiveArray}; |
| 23 | +use arrow::buffer::NullBuffer; |
24 | 24 | use arrow::datatypes::DataType::Time32; |
25 | 25 | use arrow::datatypes::{DataType, Time32SecondType, TimeUnit}; |
26 | 26 | use chrono::prelude::*; |
@@ -142,24 +142,31 @@ impl ScalarUDFImpl for MakeTimeFunc { |
142 | 142 | let minutes = minutes.as_primitive::<Int32Type>(); |
143 | 143 | let seconds = seconds.as_primitive::<Int32Type>(); |
144 | 144 |
|
145 | | - let mut builder: PrimitiveBuilder<Time32SecondType> = |
146 | | - PrimitiveArray::builder(len); |
| 145 | + let nulls = NullBuffer::union( |
| 146 | + NullBuffer::union(hours.nulls(), minutes.nulls()).as_ref(), |
| 147 | + seconds.nulls(), |
| 148 | + ); |
147 | 149 |
|
| 150 | + let mut values = Vec::with_capacity(len); |
148 | 151 | for i in 0..len { |
149 | | - // match postgresql behaviour which returns null for any null input |
150 | | - if hours.is_null(i) || minutes.is_null(i) || seconds.is_null(i) { |
151 | | - builder.append_null(); |
| 152 | + // Match Postgres behaviour which returns null for any null input |
| 153 | + if nulls.as_ref().is_some_and(|n| n.is_null(i)) { |
| 154 | + values.push(0); |
152 | 155 | } else { |
153 | 156 | make_time_inner( |
154 | 157 | hours.value(i), |
155 | 158 | minutes.value(i), |
156 | 159 | seconds.value(i), |
157 | | - |seconds: i32| builder.append_value(seconds), |
| 160 | + |seconds: i32| values.push(seconds), |
158 | 161 | )?; |
159 | 162 | } |
160 | 163 | } |
161 | 164 |
|
162 | | - Ok(ColumnarValue::Array(Arc::new(builder.finish()))) |
| 165 | + Ok(ColumnarValue::Array(Arc::new(PrimitiveArray::< |
| 166 | + Time32SecondType, |
| 167 | + >::new( |
| 168 | + values.into(), nulls |
| 169 | + )))) |
163 | 170 | } |
164 | 171 | } |
165 | 172 | } |
|
0 commit comments