From fd2f24a603d908d049893f81ca5c0507a2ed980c Mon Sep 17 00:00:00 2001 From: TCeason Date: Sat, 18 Jan 2025 19:19:04 +0800 Subject: [PATCH] fix(query): unsupport format item should not return panic error --- .../src/scalars/timestamp/src/datetime.rs | 34 +++++++++++++------ .../functions/02_0012_function_datetimes.test | 6 ++++ 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/query/functions/src/scalars/timestamp/src/datetime.rs b/src/query/functions/src/scalars/timestamp/src/datetime.rs index 32ad99f1f273f..64aed47304475 100644 --- a/src/query/functions/src/scalars/timestamp/src/datetime.rs +++ b/src/query/functions/src/scalars/timestamp/src/datetime.rs @@ -15,6 +15,7 @@ use std::io::Write; use chrono::format::parse_and_remainder; +use chrono::format::Item; use chrono::format::Parsed; use chrono::format::StrftimeItems; use chrono::prelude::*; @@ -700,18 +701,29 @@ fn register_to_string(registry: &mut FunctionRegistry) { if format.is_empty() { output.push_null(); } else { - // Can't use `tz.timestamp_nanos(self.as_() * 1000)` directly, is may cause multiply with overflow. - let (mut secs, mut nanos) = - (micros / MICROS_PER_SEC, (micros % MICROS_PER_SEC) * 1_000); - if nanos < 0 { - secs -= 1; - nanos += 1_000_000_000; - } - let ts = ctx.func_ctx.tz.timestamp_opt(secs, nanos as u32).unwrap(); // https://github.com/BurntSushi/jiff/issues/155 - // ASCII is currently required in jiff crate - let res = ts.format(format).to_string(); - output.push(&res); + // Consider use jiff crate 0.1.24 version. + // let datetime = micros.to_timestamp(ctx.func_ctx.jiff_tz.clone()); + // match strtime::format(&datetime, format) { + // Ok(res) => output.push(&res), + // Err(e) => { ctx.set_error(output.len(), e.into());output.push_null() }, + // } + let items = StrftimeItems::new(format); + if items.clone().any(|item| matches!(item, Item::Error)) { + ctx.set_error(output.len(), "Invalid format string".to_string()); + output.push_null(); + } else { + // Can't use `tz.timestamp_nanos(self.as_() * 1000)` directly, is may cause multiply with overflow. + let (mut secs, mut nanos) = + (micros / MICROS_PER_SEC, (micros % MICROS_PER_SEC) * 1_000); + if nanos < 0 { + secs -= 1; + nanos += 1_000_000_000; + } + let ts = ctx.func_ctx.tz.timestamp_opt(secs, nanos as u32).unwrap(); + let res = ts.format(format).to_string(); + output.push(&res); + } } }, ), diff --git a/tests/sqllogictests/suites/query/functions/02_0012_function_datetimes.test b/tests/sqllogictests/suites/query/functions/02_0012_function_datetimes.test index e76537179a32b..ad7668efcedb0 100644 --- a/tests/sqllogictests/suites/query/functions/02_0012_function_datetimes.test +++ b/tests/sqllogictests/suites/query/functions/02_0012_function_datetimes.test @@ -1367,6 +1367,10 @@ select to_date('精彩的2022年,美丽的02month,激动の02d', '精彩的%Y ---- 2022-02-02 + +statement error 1006 +select date_format('2022-2-04T03:58:59', '%i'); + statement error 1006 select date_format('', ''); @@ -1486,3 +1490,5 @@ query T SELECT add_hours(to_timestamp(710455), 2147483647); ---- 1000-01-01 00:00:00.000000 + +