Skip to content

Commit 8a650b7

Browse files
committed
fix(cubesql): Support to_timestamp(epoch) pg function, fix #8901
1 parent 7723838 commit 8a650b7

File tree

2 files changed

+35
-5
lines changed

2 files changed

+35
-5
lines changed

rust/cubesql/cubesql/src/compile/rewrite/rules/filters.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ use chrono::{
3939
use cubeclient::models::V1CubeMeta;
4040
use datafusion::{
4141
arrow::{
42-
array::{Date32Array, Date64Array, TimestampNanosecondArray},
42+
array::{Date32Array, Date64Array, TimestampNanosecondArray, TimestampSecondArray},
4343
datatypes::{DataType, IntervalDayTimeType},
4444
},
4545
logical_plan::{Column, Expr, Operator},
@@ -2804,6 +2804,7 @@ impl FilterRules {
28042804
vec![Decimal::new(*value).to_string(*scale)]
28052805
}
28062806
ScalarValue::TimestampNanosecond(_, _)
2807+
| ScalarValue::TimestampSecond(_, _)
28072808
| ScalarValue::Date32(_)
28082809
| ScalarValue::Date64(_) => {
28092810
if let Some(timestamp) =
@@ -3561,6 +3562,7 @@ impl FilterRules {
35613562
Decimal::new(*value).to_string(*scale)
35623563
}
35633564
ScalarValue::TimestampNanosecond(_, _)
3565+
| ScalarValue::TimestampSecond(_, _)
35643566
| ScalarValue::Date32(_)
35653567
| ScalarValue::Date64(_) => {
35663568
if let Some(timestamp) = Self::scalar_to_native_datetime(literal) {
@@ -3576,13 +3578,16 @@ impl FilterRules {
35763578
fn scalar_to_native_datetime(literal: &ScalarValue) -> Option<NaiveDateTime> {
35773579
match literal {
35783580
ScalarValue::TimestampNanosecond(_, _)
3581+
| ScalarValue::TimestampSecond(_, _)
35793582
| ScalarValue::Date32(_)
35803583
| ScalarValue::Date64(_) => {
35813584
let array = literal.to_array();
35823585
let timestamp = if let Some(array) =
35833586
array.as_any().downcast_ref::<TimestampNanosecondArray>()
35843587
{
35853588
array.value_as_datetime(0)
3589+
} else if let Some(array) = array.as_any().downcast_ref::<TimestampSecondArray>() {
3590+
array.value_as_datetime(0)
35863591
} else if let Some(array) = array.as_any().downcast_ref::<Date32Array>() {
35873592
array.value_as_datetime(0)
35883593
} else if let Some(array) = array.as_any().downcast_ref::<Date64Array>() {

rust/cubesql/cubesql/src/sql/statement.rs

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -940,11 +940,36 @@ impl ToTimestampReplacer {
940940
}
941941

942942
impl<'ast> Visitor<'ast, ConnectionError> for ToTimestampReplacer {
943-
fn visit_identifier(&mut self, identifier: &mut Ident) -> Result<(), ConnectionError> {
944-
if identifier.value.to_lowercase() == "to_timestamp" {
945-
identifier.value = "str_to_date".to_string()
946-
};
943+
fn visit_function(&mut self, fun: &mut Function) -> Result<(), ConnectionError> {
944+
if fun.name.to_string().to_lowercase() == "to_timestamp" {
945+
if fun.args.len() == 1
946+
&& matches!(
947+
&fun.args[0],
948+
FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(Value::Number(_, _))))
949+
)
950+
{
951+
fun.name = ObjectName(vec![Ident {
952+
value: "to_timestamp_seconds".to_string(),
953+
quote_style: None,
954+
}]);
955+
} else {
956+
fun.name = ObjectName(vec![Ident {
957+
value: "str_to_date".to_string(),
958+
quote_style: None,
959+
}]);
960+
}
961+
}
947962

963+
// Continue visiting function arguments
964+
self.visit_function_args(&mut fun.args)?;
965+
if let Some(over) = &mut fun.over {
966+
for res in over.partition_by.iter_mut() {
967+
self.visit_expr(res)?;
968+
}
969+
for order_expr in over.order_by.iter_mut() {
970+
self.visit_expr(&mut order_expr.expr)?;
971+
}
972+
}
948973
Ok(())
949974
}
950975
}

0 commit comments

Comments
 (0)