Skip to content

feat: name unaliased ROUND and current-time items as Snowflake receipts show - #122

Merged
kvlonge merged 11 commits into
mainfrom
feat/output-names-receipts
Nov 6, 2026
Merged

kvlonge merged 11 commits into
mainfrom
feat/output-names-receipts

Conversation

@kvlonge

@kvlonge kvlonge commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Why

The playground's first queries still refused with SQ0009: ROUND(total, 2) and CURRENT_DATE() without an alias. Main also had a binder bug: SELECT CURRENT_DATE() AS current_date converted to SQL DuckDB rejects, because DuckDB reads the alias as its own keyword. New receipts (cases/relational/unaliased_round_current.toml) record Snowflake's names for these items, plus DISTINCT aggregates, COALESCE, CAST and a spaced call.

Changes

  • An unaliased ROUND(col) or ROUND(col, n) takes its upper-cased text as its name, inner spaces kept, as recorded.
  • CURRENT_DATE, CURRENT_DATE() and CURRENT_TIMESTAMP() are named by their upper-cased text. Bare CURRENT_TIMESTAMP and CURRENT_DATE( ) still refuse.
  • The current-time calls emit current_date() and get_current_timestamp(), so an alias spelled as the keyword binds on DuckDB.
  • AVG(DISTINCT) of a NUMBER refuses outside a window. Snowflake types it with 3 more decimal places, not 6 (NUMBER(25,5) for NUMBER(10,2)), and no recording shows how it rounds. Before this, the conversion was typed wrongly.
  • The SQ0009 explanation lists the newly named shapes.

Verification

  • CLI tests check names on DuckDB for ROUND, the current-time items, SUM and MAX over DISTINCT, COALESCE, CAST and lower(g ). Another test runs the keyword-alias statement, and another checks that AVG(DISTINCT) of a NUMBER refuses.
  • The current-time receipt is typing evidence, since its values read the clock.
  • make check-ci, make test-rust, make verify-recorded: 11,786 cases, 0 failed. The translation baseline was re-recorded for the 7 new statements; nothing regressed.

Two playground shapes over input(n NUMBER(10,2)): ROUND with one and two arguments in mixed case and spacing,
and CURRENT_DATE(), CURRENT_DATE, CURRENT_TIMESTAMP() (values diverge under current_time; the names and types
are the receipt).
SUM, MAX and AVG over DISTINCT in one query, and COALESCE, CAST of text to INTEGER and lower(g ) in
another, since one select list cannot hold both without GROUP BY; each item as written, with a
no-rows twin for each.
Recorded from test/unaliased-round-current 5778f8d (3 cases, utc-v1, no failures). Snowflake
upper-cases the item text and keeps its spacing: ROUND(N, 1), ROUND(N), ROUND( N, 0 ),
CURRENT_DATE(), CURRENT_DATE, CURRENT_TIMESTAMP().
… expressions

Recorded from test/unaliased-round-current c0514f7 (4 cases, utc-v1, no failures): SUM(DISTINCT N),
MAX(DISTINCT N), AVG(DISTINCT N), COALESCE(N, 0, 1), COALESCE(1, 2), CAST(G AS INTEGER), LOWER(G ).
…ts show

ROUND of a column with an optional integer scale, CURRENT_DATE,
CURRENT_DATE() and CURRENT_TIMESTAMP() now take Snowflake's recorded
names. CURRENT_DATE and CURRENT_TIMESTAMP convert to DuckDB calls, so a
select item aliased as the keyword no longer captures them. The
recorded DISTINCT aggregate and row-expression names are pinned too.
Snowflake types AVG(DISTINCT n) of NUMBER(10,2) as NUMBER(25,5), three
more decimal places rather than six, and no recording shows how it rounds.
The current-time names case becomes typing evidence, since its values read
the clock.

kvlonge commented Nov 6, 2026

Copy link
Copy Markdown
Contributor Author

Gate at 3472c26 (merge base 37e3767, plus the evidence on evidence/unaliased-names 977b744):

  • make check-ci: exit 0
  • make test-rust: exit 0
  • make verify-recorded: 11,786 cases, 0 failed. The translation baseline was re-recorded in this branch for the 7 new statements; nothing regressed.
  • Hygiene scan: clean

It will merge main and re-gate in its landing slot, after #121.

kvlonge added a commit that referenced this pull request Nov 6, 2026
With main merged, the conversion constants file reached 2,005 lines, over
the 2,000-line limit. The names sit in output_names.rs as match literals,
as calls.rs writes them.

kvlonge commented Nov 6, 2026

Copy link
Copy Markdown
Contributor Author

Landing gate at cce77ac (main 596399e merged in):

  • make check-ci: exit 0
  • make test-rust: every suite passed (exit 0)
  • make verify-recorded: 11800 cases, 7780 passed, 1031 diverged as expected, 2952 refused, 37 typed, 0 pending, 0 unproven, 0 failed; 220 of 220 equivalences and rules verified. Translation baseline holds, 0 regressions.

Since the approved 3472c26:

  • 264c798 rewords the AVERAGE conditions: AVG(DISTINCT) of a NUMBER is refused, also over a window (audit note 1).
  • e8583f3 merges main.
  • cce77ac matches the ROUND and current-time names where they are read instead of adding constants. No behaviour change; it keeps conversion/constants.rs within the 2,000-line limit.

@kvlonge
kvlonge merged commit cce77ac into main Nov 6, 2026
1 check failed
kvlonge added a commit that referenced this pull request Nov 6, 2026
@kvlonge
kvlonge deleted the feat/output-names-receipts 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