Skip to content

Commit fbf7934

Browse files
authored
Support to unparse ScalarValue::TimestampNanosecond to String (#10984)
* support unparse TimestampNanosecond * cargo fmt * extract the duplicate code
1 parent e9f9a23 commit fbf7934

File tree

1 file changed

+44
-4
lines changed

1 file changed

+44
-4
lines changed

datafusion/sql/src/unparser/expr.rs

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@ use arrow::util::display::array_value_to_string;
1919
use core::fmt;
2020
use std::{fmt::Display, vec};
2121

22-
use arrow_array::{Date32Array, Date64Array};
22+
use arrow_array::{Date32Array, Date64Array, TimestampNanosecondArray};
2323
use arrow_schema::DataType;
2424
use sqlparser::ast::Value::SingleQuotedString;
2525
use sqlparser::ast::{
26-
self, Expr as AstExpr, Function, FunctionArg, Ident, Interval, UnaryOperator,
26+
self, Expr as AstExpr, Function, FunctionArg, Ident, Interval, TimezoneInfo,
27+
UnaryOperator,
2728
};
2829

2930
use datafusion_common::{
@@ -819,8 +820,36 @@ impl Unparser<'_> {
819820
ScalarValue::TimestampMicrosecond(None, _) => {
820821
Ok(ast::Expr::Value(ast::Value::Null))
821822
}
822-
ScalarValue::TimestampNanosecond(Some(_ts), _) => {
823-
not_impl_err!("Unsupported scalar: {v:?}")
823+
ScalarValue::TimestampNanosecond(Some(_ts), tz) => {
824+
let result = if let Some(tz) = tz {
825+
v.to_array()?
826+
.as_any()
827+
.downcast_ref::<TimestampNanosecondArray>()
828+
.ok_or(internal_datafusion_err!(
829+
"Unable to downcast to TimestampNanosecond from TimestampNanosecond scalar"
830+
))?
831+
.value_as_datetime_with_tz(0, tz.parse()?)
832+
.ok_or(internal_datafusion_err!(
833+
"Unable to convert TimestampNanosecond to DateTime"
834+
))?.to_string()
835+
} else {
836+
v.to_array()?
837+
.as_any()
838+
.downcast_ref::<TimestampNanosecondArray>()
839+
.ok_or(internal_datafusion_err!(
840+
"Unable to downcast to TimestampNanosecond from TimestampNanosecond scalar"
841+
))?
842+
.value_as_datetime(0)
843+
.ok_or(internal_datafusion_err!(
844+
"Unable to convert TimestampNanosecond to NaiveDateTime"
845+
))?.to_string()
846+
};
847+
Ok(ast::Expr::Cast {
848+
kind: ast::CastKind::Cast,
849+
expr: Box::new(ast::Expr::Value(SingleQuotedString(result))),
850+
data_type: ast::DataType::Timestamp(None, TimezoneInfo::None),
851+
format: None,
852+
})
824853
}
825854
ScalarValue::TimestampNanosecond(None, _) => {
826855
Ok(ast::Expr::Value(ast::Value::Null))
@@ -1151,6 +1180,17 @@ mod tests {
11511180
Expr::Literal(ScalarValue::Date32(Some(-1))),
11521181
r#"CAST('1969-12-31' AS DATE)"#,
11531182
),
1183+
(
1184+
Expr::Literal(ScalarValue::TimestampNanosecond(Some(10001), None)),
1185+
r#"CAST('1970-01-01 00:00:00.000010001' AS TIMESTAMP)"#,
1186+
),
1187+
(
1188+
Expr::Literal(ScalarValue::TimestampNanosecond(
1189+
Some(10001),
1190+
Some("+08:00".into()),
1191+
)),
1192+
r#"CAST('1970-01-01 08:00:00.000010001 +08:00' AS TIMESTAMP)"#,
1193+
),
11541194
(sum(col("a")), r#"sum(a)"#),
11551195
(
11561196
count_udaf()

0 commit comments

Comments
 (0)