Skip to content

fix: type a DATE plus INTERVAL 'n' DAY as TIMESTAMP_NTZ(9) - #118

Merged
kvlonge merged 4 commits into
mainfrom
fix/date-interval-type
Nov 6, 2026
Merged

kvlonge merged 4 commits into
mainfrom
fix/date-interval-type

Conversation

@kvlonge

@kvlonge kvlonge commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Why

Snowflake types a DATE plus an interval differently depending on where the unit is written. d - INTERVAL '7 days', with the unit inside the quotes, stays a DATE (recorded in temporal/interval_arithmetic.toml). d + INTERVAL '3' DAY and INTERVAL '3' DAYS, with the unit after the quotes, give a TIMESTAMP_NTZ(9) at midnight (recorded in translation data-types-datetime.interval t003_plural). The second spelling converted as a DATE, which changes the column's type and how it compares downstream.

Changes

  • A DATE plus or minus INTERVAL 'n' DAY(S) with the unit after the quotes now gives TIMESTAMP_NTZ(9) at midnight plus the days, relying on timestamp_range, as for a timestamp operand. The quoted-unit spelling keeps a DATE.
  • The interval rule's conditions say so.

Verification

  • Tests that run the converted SQL on DuckDB: '2026-04-01'::DATE + INTERVAL '3' DAYS gives 2026-04-04 00:00:00.000 (it gave 2026-04-04 before the fix), and - INTERVAL '1' DAY across a leap day; the existing quoted-unit DATE case is unchanged.
  • No case or corpus file uses the unit-after spelling with a DATE, so no recorded result changes. The held-out t003_plural case can return with this.
  • make check-ci, make test-rust, make verify-recorded.

Snowflake keeps a DATE for INTERVAL '7 days', with the unit inside the
quotes, but gives a TIMESTAMP_NTZ(9) at midnight for INTERVAL '3' DAY,
with the unit after them. The second spelling converted as a DATE.

kvlonge commented Nov 6, 2026

Copy link
Copy Markdown
Contributor Author

D94 gate on 893cb9d (based on main 37e3767):

  • make check-ci: exit 0
  • make test-rust: passed, every suite exit 0
  • make verify-recorded: 11,779 cases, 7,761 passed, 1,031 diverged as expected, 2,951 refused, 0 pending, 0 unproven, 0 failed; 220 of 220 equivalences and rules verified. translation-results: 0 regressions, 0 other changes.
  • Hygiene scan: clean.

kvlonge added a commit that referenced this pull request Nov 6, 2026
INTERVAL 3 DAY parses as INTERVAL '3' DAY, but no recording shows how
Snowflake types it, so DATE or timestamp arithmetic with an unquoted
interval value now refuses.
With main merged, the conversion constants file reached 2,005 lines, over
the 2,000-line limit. The refusal reason now sits in intervals.rs like the
other interval refusals, and the keyword check reuses INTERVAL_KIND.

kvlonge commented Nov 6, 2026

Copy link
Copy Markdown
Contributor Author

Landing gate at 50e3efb (main 4b6278d merged):

  • make check-ci: exit 0
  • make test-rust: exit 0
  • make verify-recorded: 11,793 cases, 0 failed; nothing regressed against the translation baseline
  • Hygiene scan: clean

Merging main pushed conversion/constants.rs over the 2,000-line limit (2,005 lines). 50e3efb moves the unquoted-interval refusal reason inline in intervals.rs, where the other interval refusals already are, and reuses INTERVAL_KIND for the keyword check. Behaviour and message are unchanged. The audits (ee35e0a, 6dd5892) covered the behaviour.

@kvlonge
kvlonge merged commit 50e3efb into main Nov 6, 2026
1 check failed
@kvlonge
kvlonge deleted the fix/date-interval-type branch November 9, 2026 21:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant