Skip to content

Commit 1e57ed1

Browse files
Format Date32 to string given timestamp specifiers
1 parent d20b6d1 commit 1e57ed1

File tree

1 file changed

+62
-2
lines changed

1 file changed

+62
-2
lines changed

datafusion/functions/src/datetime/to_char.rs

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use std::sync::Arc;
2020

2121
use arrow::array::cast::AsArray;
2222
use arrow::array::{new_null_array, Array, ArrayRef, StringArray};
23+
use arrow::compute::cast;
2324
use arrow::datatypes::DataType;
2425
use arrow::datatypes::DataType::{
2526
Date32, Date64, Duration, Time32, Time64, Timestamp, Utf8,
@@ -210,7 +211,7 @@ fn _to_char_scalar(
210211
// of the implementation in arrow-rs we need to convert it to an array
211212
let data_type = &expression.data_type();
212213
let is_scalar_expression = matches!(&expression, ColumnarValue::Scalar(_));
213-
let array = expression.into_array(1)?;
214+
let array = expression.clone().into_array(1)?;
214215

215216
if format.is_none() {
216217
if is_scalar_expression {
@@ -247,6 +248,10 @@ fn _to_char_scalar(
247248
))
248249
}
249250
} else {
251+
if data_type == &Date32 {
252+
return _to_char_scalar(expression.clone().cast_to(&Date64, None)?, format);
253+
}
254+
250255
exec_err!("{}", formatted.unwrap_err())
251256
}
252257
}
@@ -277,7 +282,25 @@ fn _to_char_array(args: &[ColumnarValue]) -> Result<ColumnarValue> {
277282
let result = formatter.value(idx).try_to_string();
278283
match result {
279284
Ok(value) => results.push(Some(value)),
280-
Err(e) => return exec_err!("{}", e),
285+
Err(e) => {
286+
if data_type == &Date32 {
287+
let format_options = match _build_format_options(&Date64, format) {
288+
Ok(value) => value,
289+
Err(value) => return value,
290+
};
291+
292+
let array = cast(arrays[0].as_ref(), &Date64)?;
293+
let formatter =
294+
ArrayFormatter::try_new(array.as_ref(), &format_options)?;
295+
let result = formatter.value(idx).try_to_string();
296+
match result {
297+
Ok(value) => results.push(Some(value)),
298+
Err(e) => return exec_err!("{}", e),
299+
}
300+
} else {
301+
return exec_err!("{}", e);
302+
}
303+
}
281304
}
282305
}
283306

@@ -328,6 +351,11 @@ mod tests {
328351
ScalarValue::Utf8(Some("%Y::%m::%d".to_string())),
329352
"2020::09::01".to_string(),
330353
),
354+
(
355+
ScalarValue::Date32(Some(18506)),
356+
ScalarValue::Utf8(Some("%Y::%m::%d %S::%M::%H %f".to_string())),
357+
"2020::09::01 00::00::00 000000000".to_string(),
358+
),
331359
(
332360
ScalarValue::Date64(Some(date.and_utc().timestamp_millis())),
333361
ScalarValue::Utf8(Some("%Y::%m::%d".to_string())),
@@ -407,6 +435,11 @@ mod tests {
407435
StringArray::from(vec!["%Y::%m::%d".to_string()]),
408436
"2020::09::01".to_string(),
409437
),
438+
(
439+
ScalarValue::Date32(Some(18506)),
440+
StringArray::from(vec!["%Y::%m::%d %S::%M::%H %f".to_string()]),
441+
"2020::09::01 00::00::00 000000000".to_string(),
442+
),
410443
(
411444
ScalarValue::Date64(Some(date.and_utc().timestamp_millis())),
412445
StringArray::from(vec!["%Y::%m::%d".to_string()]),
@@ -490,6 +523,14 @@ mod tests {
490523
ScalarValue::Utf8(Some("%Y::%m::%d".to_string())),
491524
StringArray::from(vec!["2020::09::01", "2020::09::02"]),
492525
),
526+
(
527+
Arc::new(Date32Array::from(vec![18506, 18507])) as ArrayRef,
528+
ScalarValue::Utf8(Some("%Y::%m::%d %S::%M::%H %f".to_string())),
529+
StringArray::from(vec![
530+
"2020::09::01 00::00::00 000000000",
531+
"2020::09::02 00::00::00 000000000",
532+
]),
533+
),
493534
(
494535
Arc::new(Date64Array::from(vec![
495536
date.and_utc().timestamp_millis(),
@@ -506,6 +547,25 @@ mod tests {
506547
StringArray::from(vec!["%Y::%m::%d", "%d::%m::%Y"]),
507548
StringArray::from(vec!["2020::09::01", "02::09::2020"]),
508549
),
550+
(
551+
Arc::new(Date32Array::from(vec![18506, 18507])) as ArrayRef,
552+
StringArray::from(vec![
553+
"%Y::%m::%d %S::%M::%H %f",
554+
"%Y::%m::%d %S::%M::%H %f",
555+
]),
556+
StringArray::from(vec![
557+
"2020::09::01 00::00::00 000000000",
558+
"2020::09::02 00::00::00 000000000",
559+
]),
560+
),
561+
(
562+
Arc::new(Date32Array::from(vec![18506, 18507])) as ArrayRef,
563+
StringArray::from(vec!["%Y::%m::%d", "%Y::%m::%d %S::%M::%H %f"]),
564+
StringArray::from(vec![
565+
"2020::09::01",
566+
"2020::09::02 00::00::00 000000000",
567+
]),
568+
),
509569
(
510570
Arc::new(Date64Array::from(vec![
511571
date.and_utc().timestamp_millis(),

0 commit comments

Comments
 (0)