Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
ec34616
fix: compare naive timestamps with local ones and count sub-day DATED…
kvlonge Nov 6, 2026
9916e9e
evidence: naive and local timestamp comparisons, DATEADD of an LTZ, s…
kvlonge Nov 6, 2026
d1ca0bf
Merge remote-tracking branch 'origin/main' into fix/ntz-current-times…
kvlonge Nov 6, 2026
05d20a3
cases: compare a naive timestamp with a zoned one, as dbt's increment…
kvlonge Nov 6, 2026
19acc9b
evidence: record naive timestamps compared with zoned ones
kvlonge Nov 6, 2026
5d0a38f
Merge branch 'wip/d115-ntz-tz' of https://github.com/sqlstack-io/sqlq…
kvlonge Nov 6, 2026
d97c099
fix: compare naive timestamps with TIMESTAMP_TZ values as instants, a…
kvlonge Nov 6, 2026
fbc4331
fix: rely on timestamp_range where a zoned comparison widens to nanos…
kvlonge Nov 6, 2026
757ee76
cases: compare naive timestamps with zoned values past 2262 and in BE…
kvlonge Nov 6, 2026
a511a67
Merge remote-tracking branch 'origin/main' into fix/ntz-current-times…
kvlonge Nov 6, 2026
0cdfba3
evidence: record naive timestamps beside zoned values past 2262 and i…
kvlonge Nov 6, 2026
8c97747
Merge branch 'wip/d115-ntz-tz' of https://github.com/sqlstack-io/sqlq…
kvlonge Nov 6, 2026
31ac95e
style: sort the zoned-text generator's imports
kvlonge Nov 6, 2026
a91604e
coverage: re-record the translation baseline with instant comparisons…
kvlonge Nov 6, 2026
337b9b1
Merge main into the naive-timestamp comparisons with CURRENT_TIMESTAMP()
kvlonge Nov 7, 2026
849ada3
test: expect the nanosecond range when a naive timestamp is compared …
kvlonge Nov 7, 2026
b113010
corpus: record the clock filters and timestamp differences that now t…
kvlonge Nov 7, 2026
f2a03d9
Merge main into the naive-timestamp comparisons with CURRENT_TIMESTAMP()
kvlonge Nov 7, 2026
559fc80
test: pin the zone and nanosecond-range reliance of a naive-vs-local …
kvlonge Nov 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cases/generated/zoned_texts/column_comparisons.toml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ query = "SELECT z = '2024-01-01 00:00:00'::TIMESTAMP_NTZ AS r FROM input ORDER B
order = "ordered"
tags = ["null", "boundary"]
origin = "generated: zoned_texts@1"
expected_divergence = "timestamp_tz_submicro"

[[case]]
id = "timestamp_tz_column_gte_date"
Expand Down Expand Up @@ -233,6 +234,7 @@ query = "SELECT z = '2024-01-01 00:00:00'::TIMESTAMP_NTZ AS r FROM input ORDER B
order = "ordered"
tags = ["null", "boundary"]
origin = "generated: zoned_texts@1"
expected_divergence = "timestamp_tz_submicro"

[[case]]
id = "timestamp_ltz_column_gte_date"
Expand Down
87 changes: 87 additions & 0 deletions cases/temporal/naive_local_comparison.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# A TIMESTAMP_NTZ compared with a TIMESTAMP_LTZ (a column, CURRENT_TIMESTAMP() or DATEADD of it) in
# the UTC session, the incremental and freshness filters compiled models write.
category = "temporal"
construct = "node:lte"
session_profile = "utc-v1"

[[case]]
id = "ntz_beside_ltz_columns"
description = "Every comparison of a naive timestamp with a local-zone one, equal, a microsecond apart and across offsets."
columns = [{ name = "n", type = "TIMESTAMP_NTZ(9)" }, { name = "l", type = "TIMESTAMP_LTZ(9)" }]
rows = [
["'2024-06-01 10:00:00'", "'2024-06-01 10:00:00 +00:00'"],
["'2024-06-01 10:00:00'", "'2024-06-01 12:00:00 +02:00'"],
["'2024-06-01 10:00:00.000001'", "'2024-06-01 10:00:00 +00:00'"],
["'2024-06-01 09:59:59.999999'", "'2024-06-01 10:00:00 +00:00'"],
["'2024-06-01 10:00:00'", "'2024-06-01 05:00:00 -05:00'"],
["'1969-12-31 23:59:59.5'", "'1970-01-01 00:00:00 +00:00'"],
["NULL", "'2024-06-01 10:00:00 +00:00'"],
]
expression = "ARRAY_CONSTRUCT(n = l, n <> l, n < l, n <= l, n > l, n >= l, l < n)"
expected_divergence = "json_fidelity"
tags = ["null", "boundary"]

[[case]]
id = "ntz_millisecond_beside_ltz"
description = "A TIMESTAMP_NTZ(3) beside a TIMESTAMP_LTZ with microseconds compares at full precision."
columns = [{ name = "n", type = "TIMESTAMP_NTZ(3)" }, { name = "l", type = "TIMESTAMP_LTZ(9)" }]
rows = [
["'2024-06-01 10:00:00.123'", "'2024-06-01 10:00:00.123 +00:00'"],
["'2024-06-01 10:00:00.123'", "'2024-06-01 10:00:00.123001 +00:00'"],
["'2024-06-01 10:00:00.124'", "'2024-06-01 10:00:00.123999 +00:00'"],
]
expression = "ARRAY_CONSTRUCT(n = l, n < l, n > l)"
tags = ["boundary"]

[[case]]
id = "ntz_at_most_current_timestamp"
description = "A past naive timestamp is at most CURRENT_TIMESTAMP(); a far-future one is not."
columns = [{ name = "updated_at", type = "TIMESTAMP_NTZ(9)" }]
rows = [
["'2020-01-01 00:00:00'"],
["'2199-12-31 23:59:59'"],
["NULL"],
]
expression = "updated_at <= CURRENT_TIMESTAMP()"
tags = ["null"]

[[case]]
id = "ntz_after_dateadd_of_current_timestamp"
description = "The incremental filter updated_at >= DATEADD(day, -3, CURRENT_TIMESTAMP()) over past and future rows."
columns = [{ name = "updated_at", type = "TIMESTAMP_NTZ(9)" }]
rows = [
["'2020-01-01 00:00:00'"],
["'2199-12-31 23:59:59'"],
["NULL"],
]
expression = "updated_at >= DATEADD(day, -3, CURRENT_TIMESTAMP())"
tags = ["null"]

[[case]]
id = "dateadd_of_ltz_column"
description = "DATEADD of a local-zone column in DAY, HOUR, MONTH and MINUTE, compared with naive values."
columns = [{ name = "l", type = "TIMESTAMP_LTZ(9)" }]
rows = [
["'2024-01-31 23:30:00 +00:00'"],
["'2024-02-29 01:00:00 +05:30'"],
["'2024-03-31 00:00:00.000001 -08:00'"],
["NULL"],
]
expression = "ARRAY_CONSTRUCT(DATEADD(day, -3, l) = '2024-01-28 23:30:00'::TIMESTAMP_NTZ, TO_VARCHAR(DATEADD(hour, 5, l)::TIMESTAMP_NTZ), TO_VARCHAR(DATEADD(month, 1, l)::TIMESTAMP_NTZ), TO_VARCHAR(DATEADD(minute, -90, l)::TIMESTAMP_NTZ))"
expected_divergence = "json_fidelity"
tags = ["null", "boundary"]

[[case]]
id = "datediff_subday_of_dates"
description = "DATEDIFF in HOUR, MINUTE and SECOND with a DATE operand, read as its midnight."
columns = [{ name = "d", type = "DATE" }, { name = "t", type = "TIMESTAMP_NTZ(9)" }]
rows = [
["'2024-06-01'", "'2024-06-01 10:30:00'"],
["'2024-06-01'", "'2024-05-31 23:59:59.999999999'"],
["'2024-02-28'", "'2024-03-01 00:00:00'"],
["'1969-12-31'", "'1970-01-01 00:00:01'"],
["NULL", "'2024-06-01 10:30:00'"],
]
expression = "ARRAY_CONSTRUCT(DATEDIFF(hour, d, t), DATEDIFF(minute, t, d), DATEDIFF(second, d, t), DATEDIFF(hour, d, '2024-06-03'::DATE))"
expected_divergence = "json_fidelity"
tags = ["null", "boundary"]
71 changes: 71 additions & 0 deletions cases/temporal/naive_zoned_comparison.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
category = "temporal"
construct = "node:lte"
session_profile = "utc-v1"

[[case]]
id = "ntz_beside_utc_tz"
description = "Every comparison of a naive timestamp with CONVERT_TIMEZONE('UTC', tz), equal, a microsecond apart and across source offsets."
columns = [{ name = "n", type = "TIMESTAMP_NTZ(9)" }, { name = "tz", type = "TIMESTAMP_TZ(9)" }]
rows = [
["'2024-06-01 10:00:00'", "'2024-06-01 10:00:00 +00:00'"],
["'2024-06-01 10:00:00'", "'2024-06-01 12:00:00 +02:00'"],
["'2024-06-01 10:00:00.000001'", "'2024-06-01 10:00:00 +00:00'"],
["'2024-06-01 09:59:59.999999'", "'2024-06-01 10:00:00 +00:00'"],
["'2024-06-01 10:00:00'", "'2024-06-01 05:00:00 -05:00'"],
["'1969-12-31 23:59:59.5'", "'1970-01-01 00:00:00 +00:00'"],
["NULL", "'2024-06-01 10:00:00 +00:00'"],
]
expression = "ARRAY_CONSTRUCT(n = CONVERT_TIMEZONE('UTC', tz), n <> CONVERT_TIMEZONE('UTC', tz), n < CONVERT_TIMEZONE('UTC', tz), n <= CONVERT_TIMEZONE('UTC', tz), n > CONVERT_TIMEZONE('UTC', tz), n >= CONVERT_TIMEZONE('UTC', tz), CONVERT_TIMEZONE('UTC', tz) < n)"
expected_divergence = "json_fidelity"
tags = ["null", "boundary"]

[[case]]
id = "ntz_beside_offset_tz_column"
description = "A naive timestamp compared with a TIMESTAMP_TZ column at a non-UTC offset, without CONVERT_TIMEZONE: whether Snowflake compares instants or wall times."
columns = [{ name = "n", type = "TIMESTAMP_NTZ(9)" }, { name = "tz", type = "TIMESTAMP_TZ(9)" }]
rows = [
["'2024-06-01 10:00:00'", "'2024-06-01 12:00:00 +02:00'"],
["'2024-06-01 12:00:00'", "'2024-06-01 12:00:00 +02:00'"],
["'2024-06-01 10:00:00'", "'2024-06-01 05:00:00 -05:00'"],
]
expression = "ARRAY_CONSTRUCT(n = tz, n < tz, n > tz)"
tags = ["boundary"]

[[case]]
id = "ntz_at_most_utc_current_timestamp"
description = "dbt's incremental upper bound: a past naive timestamp is at most CONVERT_TIMEZONE('UTC', CURRENT_TIMESTAMP()); a far-future one is not."
columns = [{ name = "updated_at", type = "TIMESTAMP_NTZ(9)" }]
rows = [
["'2020-01-01 00:00:00'"],
["'2199-12-31 23:59:59'"],
["NULL"],
]
expression = "updated_at <= CONVERT_TIMEZONE('UTC', CURRENT_TIMESTAMP())"
tags = ["null"]

[[case]]
id = "ntz_beside_zoned_past_nanosecond_range"
description = "A naive TIMESTAMP_NTZ(9) compared with TIMESTAMP_TZ and TIMESTAMP_LTZ sentinels past 2262, which DuckDB cannot widen to nanoseconds."
columns = [{ name = "n", type = "TIMESTAMP_NTZ(9)" }, { name = "tz", type = "TIMESTAMP_TZ(9)" }, { name = "l", type = "TIMESTAMP_LTZ(9)" }]
rows = [
["'2024-06-01 10:00:00'", "'9999-12-31 00:00:00 +00:00'", "'9999-12-31 00:00:00 +00:00'"],
["'2024-06-01 10:00:00'", "'2300-01-01 12:00:00 +02:00'", "'2300-01-01 12:00:00 +00:00'"],
["'2024-06-01 10:00:00'", "'2024-06-01 12:00:00 +02:00'", "'2024-06-01 10:00:00 +00:00'"],
]
expression = "ARRAY_CONSTRUCT(n < tz, n = tz, n < l, n >= l)"
expected_divergence = "timestamp_range"
tags = ["boundary"]

[[case]]
id = "ntz_between_zoned_bounds"
description = "A naive timestamp BETWEEN a TIMESTAMP_TZ and a TIMESTAMP_LTZ bound, and a zoned value BETWEEN naive bounds."
columns = [{ name = "n", type = "TIMESTAMP_NTZ(9)" }, { name = "tz", type = "TIMESTAMP_TZ(9)" }, { name = "l", type = "TIMESTAMP_LTZ(9)" }]
rows = [
["'2024-06-01 10:00:00'", "'2024-06-01 11:00:00 +02:00'", "'2024-06-01 11:00:00 +00:00'"],
["'2024-06-01 10:00:00'", "'2024-06-01 12:00:00 +02:00'", "'2024-06-01 10:00:00 +00:00'"],
["'2024-06-01 10:00:00'", "'2024-06-01 13:00:00 +02:00'", "'2024-06-01 09:00:00 +00:00'"],
["NULL", "'2024-06-01 10:00:00 +00:00'", "'2024-06-01 10:00:00 +00:00'"],
]
query = "SELECT n BETWEEN tz AND l AS a, tz BETWEEN n AND '2024-06-01 10:30:00'::TIMESTAMP_NTZ AS b FROM input ORDER BY ordinal"
order = "ordered"
tags = ["null", "boundary"]
25 changes: 15 additions & 10 deletions corpora/basics/queries.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14565,29 +14565,34 @@ expect_repository = "refused SQ0003 node:gte at 42..87"
[[query]]
category = "last_days"
sql = '''SELECT order_id FROM orders WHERE ordered_at >= DATEADD(day, -30, CURRENT_TIMESTAMP())'''
expect = "refused SQ0003 fn:DATEADD at 48..86"
expect_repository = "refused SQ0003 fn:DATEADD at 48..86"
expect = "refused SQ0008 fn:DATEADD at 48..86"
expect_repository = "translated"
result_repository = "0 rows e3b0c44298fc1c14"

[[query]]
category = "last_days"
sql = '''select /* c */ order_id from "ORDERS" where ordered_at >= dateadd(day, -30, current_timestamp())'''
expect = "refused SQ0003 fn:DATEADD at 58..96"
expect_repository = "refused SQ0003 fn:DATEADD at 58..96"
expect = "refused SQ0008 fn:DATEADD at 58..96"
expect_repository = "translated"
result_repository = "0 rows e3b0c44298fc1c14"

[[query]]
category = "last_days"
sql = '''SELECT /* c */ ORDER_ID FROM ORDERS WHERE ORDERED_AT >= DATEADD(DAY, -30, CURRENT_TIMESTAMP())'''
expect = "refused SQ0003 fn:DATEADD at 60..98"
expect_repository = "refused SQ0003 fn:DATEADD at 60..98"
expect = "refused SQ0008 fn:DATEADD at 60..98"
expect_repository = "translated"
result_repository = "0 rows e3b0c44298fc1c14"

[[query]]
category = "last_days"
sql = '''select order_id from orders where ordered_at >= DATEADD(day, -30, CURRENT_TIMESTAMP())'''
expect = "refused SQ0003 fn:DATEADD at 48..86"
expect_repository = "refused SQ0003 fn:DATEADD at 48..86"
expect = "refused SQ0008 fn:DATEADD at 48..86"
expect_repository = "translated"
result_repository = "0 rows e3b0c44298fc1c14"

[[query]]
category = "last_days"
sql = '''SeLect ordEr_Id FrOM "ORDERS" wHERe oRDeRed_at >= DAteAdD(DAY, -30, cURrENt_tImEsTamP())'''
expect = "refused SQ0003 fn:DATEADD at 54..92"
expect_repository = "refused SQ0003 fn:DATEADD at 54..92"
expect = "refused SQ0008 fn:DATEADD at 54..92"
expect_repository = "translated"
result_repository = "0 rows e3b0c44298fc1c14"
18 changes: 9 additions & 9 deletions corpora/everyday-models/queries.toml
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,8 @@ sql = '''select
_loaded_at
from raw_orders
where _loaded_at >= dateadd(day, -3, current_timestamp())'''
expect = "refused SQ0003 fn:DATEADD at 152..189"
expect_repository = "refused SQ0003 fn:DATEADD at 152..189"
expect = "refused SQ0008 fn:DATEADD at 152..189"
expect_repository = "translated"

[[query]]
category = "dbt_staging"
Expand Down Expand Up @@ -4066,8 +4066,8 @@ category = "dbt_tests"
sql = '''select max(updated_at) as max_updated_at
from stg_orders
having max(updated_at) < dateadd(hour, -24, current_timestamp())'''
expect = "refused SQ0003 fn:DATEADD at 82..121"
expect_repository = "refused SQ0003 fn:DATEADD at 82..121"
expect = "refused SQ0008 fn:DATEADD at 82..121"
expect_repository = "translated"

[[query]]
category = "dbt_tests"
Expand Down Expand Up @@ -4704,8 +4704,8 @@ sql = '''select *
from stg_orders
where updated_at > (select max(updated_at) from fct_orders)
and updated_at <= current_timestamp()'''
expect = "refused SQ0003 node:lte at 91..124"
expect_repository = "refused SQ0003 node:lte at 91..124"
expect = "refused SQ0008 node:lte at 91..124"
expect_repository = "translated"

[[query]]
category = "dbt_incremental"
Expand Down Expand Up @@ -4797,8 +4797,8 @@ expect_repository = "translated"
category = "dates"
sql = '''select order_id, timestampdiff(hour, order_date, updated_at) as hours_to_update
from stg_orders'''
expect = "refused SQ0003 fn:TIMESTAMPDIFF at 17..60"
expect_repository = "refused SQ0003 fn:TIMESTAMPDIFF at 17..60"
expect = "translated"
expect_repository = "translated"

[[query]]
category = "strings"
Expand Down Expand Up @@ -6091,7 +6091,7 @@ sql = '''select * from analytics.dbt_dev.fct_orders
where updated_at > (select max(updated_at) from analytics.dbt_dev.inc_event_time)
and updated_at <= convert_timezone('UTC', current_timestamp())'''
expect = "refused SQ0008 fn:CONVERT_TIMEZONE at 145..189"
expect_repository = "refused SQ0003 node:lte at 131..189"
expect_repository = "translated"

[[query]]
category = "dbt_incremental"
Expand Down
4 changes: 2 additions & 2 deletions corpora/everyday/queries.toml
Original file line number Diff line number Diff line change
Expand Up @@ -1506,8 +1506,8 @@ expect_repository = "refused SQ0003 node:gte at 34..79"
[[query]]
category = "dates"
sql = '''SELECT order_id FROM orders WHERE ordered_at >= DATEADD(day, -30, CURRENT_TIMESTAMP())'''
expect = "refused SQ0003 fn:DATEADD at 48..86"
expect_repository = "refused SQ0003 fn:DATEADD at 48..86"
expect = "refused SQ0008 fn:DATEADD at 48..86"
expect_repository = "translated"

[[query]]
category = "dates"
Expand Down
Loading
Loading