Skip to content

Commit

Permalink
Support to unparse ScalarValue::TimestampNanosecond to String (apac…
Browse files Browse the repository at this point in the history
…he#10984)

* support unparse TimestampNanosecond

* cargo fmt

* extract the duplicate code
  • Loading branch information
goldmedal authored and findepi committed Jul 16, 2024
1 parent a024655 commit 60c5b23
Showing 1 changed file with 44 additions and 4 deletions.
48 changes: 44 additions & 4 deletions datafusion/sql/src/unparser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ use arrow::util::display::array_value_to_string;
use core::fmt;
use std::{fmt::Display, vec};

use arrow_array::{Date32Array, Date64Array};
use arrow_array::{Date32Array, Date64Array, TimestampNanosecondArray};
use arrow_schema::DataType;
use sqlparser::ast::Value::SingleQuotedString;
use sqlparser::ast::{
self, Expr as AstExpr, Function, FunctionArg, Ident, Interval, UnaryOperator,
self, Expr as AstExpr, Function, FunctionArg, Ident, Interval, TimezoneInfo,
UnaryOperator,
};

use datafusion_common::{
Expand Down Expand Up @@ -819,8 +820,36 @@ impl Unparser<'_> {
ScalarValue::TimestampMicrosecond(None, _) => {
Ok(ast::Expr::Value(ast::Value::Null))
}
ScalarValue::TimestampNanosecond(Some(_ts), _) => {
not_impl_err!("Unsupported scalar: {v:?}")
ScalarValue::TimestampNanosecond(Some(_ts), tz) => {
let result = if let Some(tz) = tz {
v.to_array()?
.as_any()
.downcast_ref::<TimestampNanosecondArray>()
.ok_or(internal_datafusion_err!(
"Unable to downcast to TimestampNanosecond from TimestampNanosecond scalar"
))?
.value_as_datetime_with_tz(0, tz.parse()?)
.ok_or(internal_datafusion_err!(
"Unable to convert TimestampNanosecond to DateTime"
))?.to_string()
} else {
v.to_array()?
.as_any()
.downcast_ref::<TimestampNanosecondArray>()
.ok_or(internal_datafusion_err!(
"Unable to downcast to TimestampNanosecond from TimestampNanosecond scalar"
))?
.value_as_datetime(0)
.ok_or(internal_datafusion_err!(
"Unable to convert TimestampNanosecond to NaiveDateTime"
))?.to_string()
};
Ok(ast::Expr::Cast {
kind: ast::CastKind::Cast,
expr: Box::new(ast::Expr::Value(SingleQuotedString(result))),
data_type: ast::DataType::Timestamp(None, TimezoneInfo::None),
format: None,
})
}
ScalarValue::TimestampNanosecond(None, _) => {
Ok(ast::Expr::Value(ast::Value::Null))
Expand Down Expand Up @@ -1151,6 +1180,17 @@ mod tests {
Expr::Literal(ScalarValue::Date32(Some(-1))),
r#"CAST('1969-12-31' AS DATE)"#,
),
(
Expr::Literal(ScalarValue::TimestampNanosecond(Some(10001), None)),
r#"CAST('1970-01-01 00:00:00.000010001' AS TIMESTAMP)"#,
),
(
Expr::Literal(ScalarValue::TimestampNanosecond(
Some(10001),
Some("+08:00".into()),
)),
r#"CAST('1970-01-01 08:00:00.000010001 +08:00' AS TIMESTAMP)"#,
),
(sum(col("a")), r#"sum(a)"#),
(
count_udaf()
Expand Down

0 comments on commit 60c5b23

Please sign in to comment.