Skip to content

Commit a5d9226

Browse files
committed
bendsql todo
1 parent 846d8d3 commit a5d9226

54 files changed

Lines changed: 1335 additions & 881 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Cargo.lock

Lines changed: 8 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/common/io/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ borsh = { workspace = true }
1313
byteorder = { workspace = true }
1414
bytes = { workspace = true }
1515
chrono = { workspace = true }
16+
chrono-tz = { workspace = true }
1617
databend-common-base = { workspace = true }
1718
databend-common-exception = { workspace = true }
1819
databend-common-timezone = { workspace = true }

src/common/io/src/cursor_ext/cursor_read_datetime_ext.rs

Lines changed: 27 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ use chrono::Datelike;
1919
use chrono::NaiveDate;
2020
use chrono::NaiveDateTime;
2121
use chrono::Timelike;
22+
use chrono_tz::Tz;
2223
use databend_common_exception::ErrorCode;
2324
use databend_common_exception::Result;
2425
use databend_common_exception::ToErrorCode;
25-
use databend_common_timezone::Tz;
2626
use databend_common_timezone::fast_utc_from_local;
2727

2828
use crate::cursor_ext::cursor_read_bytes_ext::ReadBytesExt;
@@ -65,7 +65,23 @@ fn days_from_epoch(date: &NaiveDate) -> i32 {
6565
.num_days() as i32
6666
}
6767

68-
fn local_to_micros(tz: &Tz, local: &NaiveDateTime, micro: u32) -> Option<i64> {
68+
fn local_to_micros_checked(
69+
tz: &Tz,
70+
local: &NaiveDateTime,
71+
micro: u32,
72+
provided_offset: Option<i32>,
73+
) -> Result<i64> {
74+
// Explicit offsets are independent of the session timezone and its DST gaps.
75+
if let Some(offset) = provided_offset {
76+
return local
77+
.and_utc()
78+
.timestamp()
79+
.checked_sub(i64::from(offset))
80+
.and_then(|seconds| seconds.checked_mul(MICROS_PER_SEC))
81+
.and_then(|micros| micros.checked_add(i64::from(micro)))
82+
.ok_or_else(|| ErrorCode::BadBytes("Datetime offset adjustment overflowed"));
83+
}
84+
6985
fast_utc_from_local(
7086
tz,
7187
local.year(),
@@ -76,28 +92,14 @@ fn local_to_micros(tz: &Tz, local: &NaiveDateTime, micro: u32) -> Option<i64> {
7692
local.second() as u8,
7793
micro,
7894
)
79-
}
80-
81-
fn local_to_micros_checked(tz: &Tz, local: &NaiveDateTime, micro: u32) -> Result<i64> {
82-
local_to_micros(tz, local, micro).ok_or_else(|| {
95+
.ok_or_else(|| {
8396
ErrorCode::BadBytes(format!(
8497
"Invalid local datetime {} for timezone {tz}",
8598
local.format("%Y-%m-%d %H:%M:%S")
8699
))
87100
})
88101
}
89102

90-
/// Explicit offsets are independent of the session timezone and its DST gaps.
91-
fn micros_with_offset(local: &NaiveDateTime, micro: u32, offset: i32) -> Result<i64> {
92-
local
93-
.and_utc()
94-
.timestamp()
95-
.checked_sub(i64::from(offset))
96-
.and_then(|seconds| seconds.checked_mul(MICROS_PER_SEC))
97-
.and_then(|micros| micros.checked_add(i64::from(micro)))
98-
.ok_or_else(|| ErrorCode::BadBytes("Datetime offset adjustment overflowed"))
99-
}
100-
101103
fn try_read_standard_timestamp<T: AsRef<[u8]>>(
102104
cursor: &mut Cursor<T>,
103105
tz: &Tz,
@@ -183,11 +185,7 @@ fn build_best_effort_result(
183185
))
184186
})?;
185187

186-
let micros = if let Some(offset) = provided_offset {
187-
micros_with_offset(&local, micro, offset)?
188-
} else {
189-
local_to_micros_checked(tz, &local, micro)?
190-
};
188+
let micros = local_to_micros_checked(tz, &local, micro, provided_offset)?;
191189
Ok(DateTimeResType::Datetime(micros))
192190
}
193191

@@ -306,15 +304,14 @@ where T: AsRef<[u8]>
306304
v = "1970-01-01";
307305
}
308306

309-
let d = NaiveDate::parse_from_str(v, "%Y-%m-%d").map_err_to_code(
310-
ErrorCode::BadBytes,
311-
|| {
307+
let d = v
308+
.parse::<NaiveDate>()
309+
.map_err_to_code(ErrorCode::BadBytes, || {
312310
format!(
313311
"Date Parsing Error: The value '{}' could not be parsed into a valid Date",
314312
v
315313
)
316-
},
317-
)?;
314+
})?;
318315
check_input_year(d.year())?;
319316

320317
buf.clear();
@@ -325,7 +322,7 @@ where T: AsRef<[u8]>
325322
}
326323
let midnight = d.and_hms_opt(0, 0, 0).expect("midnight is valid");
327324
return Ok(DateTimeResType::Datetime(local_to_micros_checked(
328-
tz, &midnight, 0,
325+
tz, &midnight, 0, None,
329326
)?));
330327
}
331328

@@ -360,7 +357,7 @@ where T: AsRef<[u8]>
360357
return Ok(DateTimeResType::Date(days_from_epoch(&d)));
361358
}
362359
return Ok(DateTimeResType::Datetime(local_to_micros_checked(
363-
tz, &local, 0,
360+
tz, &local, 0, None,
364361
)?));
365362
}
366363

@@ -402,11 +399,7 @@ where T: AsRef<[u8]>
402399
return Ok(DateTimeResType::Date(days_from_epoch(&d)));
403400
}
404401

405-
let micros = if let Some(offset) = explicit_offset {
406-
micros_with_offset(&local, micro, offset)?
407-
} else {
408-
local_to_micros_checked(tz, &local, micro)?
409-
};
402+
let micros = local_to_micros_checked(tz, &local, micro, explicit_offset)?;
410403
Ok(DateTimeResType::Datetime(micros))
411404
}
412405
}

src/common/io/src/format_settings.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ use std::borrow::Cow;
1616

1717
use base64::Engine as _;
1818
use base64::engine::general_purpose;
19+
use chrono_tz::Tz;
1920
use databend_common_exception::ErrorCode;
20-
use databend_common_timezone::Tz;
2121

2222
use crate::GeometryDataType;
2323

src/common/io/tests/it/cursor_ext/read_datetime_ext.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
use std::io::Cursor;
1616

1717
use chrono::NaiveDate;
18+
use chrono_tz::Tz;
1819
use databend_common_io::cursor_ext::*;
19-
use databend_common_timezone::Tz;
2020
use databend_common_timezone::local_datetime_at;
2121

2222
/// Render microseconds as a local datetime in `tz`, for comparison against the

src/common/timezone/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use chrono::Offset;
2727
use chrono::TimeDelta;
2828
use chrono::TimeZone as _;
2929
use chrono::Utc;
30-
pub use chrono_tz::Tz;
30+
use chrono_tz::Tz;
3131
pub use civil::DateTimeComponents;
3232
pub use lut::components_from_timestamp;
3333
pub use lut::fast_utc_from_local;

src/common/timezone/src/resolve.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
use chrono::LocalResult;
1818
use chrono::NaiveDateTime;
1919
use chrono::Offset;
20-
use chrono::TimeZone as _;
20+
use chrono::TimeZone;
2121
use chrono_tz::GapInfo;
2222
use chrono_tz::Tz;
2323

@@ -100,10 +100,7 @@ fn resolve_named(
100100
}
101101
}
102102

103-
fn resolved<Tz: chrono::TimeZone>(
104-
unix_seconds: i64,
105-
value: &chrono::DateTime<Tz>,
106-
) -> ResolvedLocalTime {
103+
fn resolved<Tz: TimeZone>(unix_seconds: i64, value: &chrono::DateTime<Tz>) -> ResolvedLocalTime {
107104
ResolvedLocalTime {
108105
unix_seconds,
109106
offset_seconds: value.offset().fix().local_minus_utc(),

src/query/expression/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ base64 = { workspace = true }
2020
borsh = { workspace = true }
2121
bumpalo = { workspace = true }
2222
chrono = { workspace = true }
23+
chrono-tz = { workspace = true }
2324
comfy-table = { workspace = true }
2425
databend-common-ast = { workspace = true }
2526
databend-common-base = { workspace = true }

src/query/expression/src/function.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,14 @@ use std::sync::Arc;
2424

2525
use chrono::DateTime;
2626
use chrono::Utc;
27+
use chrono_tz::Tz;
2728
use databend_common_ast::Span;
2829
use databend_common_column::bitmap::Bitmap;
2930
use databend_common_column::bitmap::MutableBitmap;
3031
use databend_common_exception::ErrorCode;
3132
use databend_common_exception::Result;
3233
use databend_common_io::GeometryDataType;
3334
use databend_common_io::prelude::BinaryDisplayFormat;
34-
use databend_common_timezone::Tz;
3535
use enum_as_inner::EnumAsInner;
3636
use itertools::Itertools;
3737
use serde::Deserialize;

src/query/expression/src/types/date.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ use std::io::Cursor;
1717

1818
use chrono::NaiveDate;
1919
use chrono::TimeDelta;
20+
use chrono_tz::Tz;
2021
use databend_common_column::buffer::Buffer;
2122
use databend_common_exception::ErrorCode;
2223
use databend_common_io::cursor_ext::BufferReadDateTimeExt;
2324
use databend_common_io::cursor_ext::ReadBytesExt;
2425
pub use databend_common_io::datetime::check_input_year;
25-
use databend_common_timezone::Tz;
2626
use num_traits::AsPrimitive;
2727

2828
use super::ArgType;
@@ -55,6 +55,16 @@ pub fn date_from_days(days: impl AsPrimitive<i64>) -> NaiveDate {
5555
.expect("date day count is inside the chrono civil range")
5656
}
5757

58+
/// Preserve the legacy conversion policy: either bound overflow maps to DATE_MIN.
59+
#[inline]
60+
pub fn clamp_date(days: i64) -> i32 {
61+
if (DATE_MIN as i64..=DATE_MAX as i64).contains(&days) {
62+
days as i32
63+
} else {
64+
DATE_MIN
65+
}
66+
}
67+
5868
/// Validate the SQL DATE range without silently changing the value.
5969
#[inline]
6070
pub fn check_date(days: i64) -> Result<i32, String> {

0 commit comments

Comments
 (0)