Skip to content

Commit f7be028

Browse files
authored
fix(query): to_string(DateColumn, format) should success if date = 9999-12-31 (#18321)
1 parent 4f7fbc4 commit f7be028

File tree

3 files changed

+40
-15
lines changed

3 files changed

+40
-15
lines changed

โ€Žsrc/query/expression/src/utils/date_helper.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -836,20 +836,28 @@ pub fn calc_date_to_timestamp(val: i32, tz: TimeZone) -> std::result::Result<i64
836836
let ts = (val as i64) * 24 * 3600 * MICROS_PER_SEC;
837837
let z = ts.to_timestamp(tz.clone());
838838

839+
let tomorrow = z.date().tomorrow();
840+
let yesterday = z.date().yesterday();
841+
842+
// If there were no yesterday or tomorrow, it might be the limit value.
843+
// e.g. 9999-12-31
844+
if tomorrow.is_err() || yesterday.is_err() {
845+
let tz_offset_micros = tz
846+
.to_timestamp(date(1970, 1, 1).at(0, 0, 0, 0))
847+
.unwrap()
848+
.as_microsecond();
849+
return Ok(ts + tz_offset_micros);
850+
}
851+
839852
// tomorrow midnight
840-
let tomorrow_date = z
841-
.date()
842-
.tomorrow()
843-
.map_err(|e| format!("Calc tomorrow midnight with error {}", e))?;
853+
let tomorrow_date = tomorrow.map_err(|e| format!("Calc tomorrow midnight with error {}", e))?;
844854

845855
let tomorrow_zoned = tomorrow_date.to_zoned(tz.clone()).unwrap_or(z.clone());
846856
let tomorrow_is_dst = tz.to_offset_info(tomorrow_zoned.timestamp()).dst().is_dst();
847857

848858
// yesterday midnight
849-
let yesterday_date = z
850-
.date()
851-
.yesterday()
852-
.map_err(|e| format!("Calc yesterday midnight with error {}", e))?;
859+
let yesterday_date =
860+
yesterday.map_err(|e| format!("Calc yesterday midnight with error {}", e))?;
853861
let yesterday_zoned = yesterday_date.to_zoned(tz.clone()).unwrap_or(z.clone());
854862
let yesterday_is_std = tz
855863
.to_offset_info(yesterday_zoned.timestamp())

โ€Žsrc/query/functions/src/scalars/timestamp/src/datetime.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -732,15 +732,10 @@ fn register_to_string(registry: &mut FunctionRegistry) {
732732
vectorize_with_builder_2_arg::<TimestampType, StringType, NullableType<StringType>>(
733733
|micros, format, output, ctx| {
734734
let ts = micros.to_timestamp(ctx.func_ctx.tz.clone());
735-
let format = if ctx.func_ctx.date_format_style == *"oracle" {
736-
pg_format_to_strftime(format)
737-
} else {
738-
format.to_string()
739-
};
740-
let format = replace_time_format(&format);
735+
let format = prepare_format_string(format, &ctx.func_ctx.date_format_style);
741736
let mut buf = String::new();
742737
let mut formatter = fmt::Formatter::new(&mut buf, FormattingOptions::new());
743-
if Display::fmt(&ts.strftime(format.as_ref()), &mut formatter).is_err() {
738+
if Display::fmt(&ts.strftime(&format), &mut formatter).is_err() {
744739
ctx.set_error(output.len(), format!("{format} is invalid time format"));
745740
output.builder.commit_row();
746741
output.validity.push(true);
@@ -2453,3 +2448,12 @@ where T: ToNumber<i32> {
24532448
}),
24542449
);
24552450
}
2451+
2452+
fn prepare_format_string(format: &str, date_format_style: &str) -> String {
2453+
let processed_format = if date_format_style == "oracle" {
2454+
pg_format_to_strftime(format)
2455+
} else {
2456+
format.to_string()
2457+
};
2458+
replace_time_format(&processed_format).to_string()
2459+
}

โ€Žtests/sqllogictests/suites/query/functions/02_0012_function_datetimes_tz.test

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,6 +1143,19 @@ select to_date('9999-12-31','%Y-%m-%d');
11431143
----
11441144
9999-12-31
11451145

1146+
statement ok
1147+
create or replace table t(c1 date);
1148+
1149+
statement ok
1150+
insert into t values('9999-12-31');
1151+
1152+
query T
1153+
select to_string(c1, '%Y'),c1 from t;
1154+
----
1155+
9999 9999-12-31
1156+
1157+
statement ok
1158+
drop table if exists t;
11461159

11471160
statement ok
11481161
set timezone='America/Los_Angeles';

0 commit comments

Comments
ย (0)