Skip to content

Read a bare LIMIT or OFFSET as an alias, and help split long set-operation chains (D186) - #90

Closed
kvlonge wants to merge 3 commits into
fix/d150-v3from
fix/limit-union
Closed

kvlonge wants to merge 3 commits into
fix/d150-v3from
fix/limit-union

Conversation

@kvlonge

@kvlonge kvlonge commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #89 (D186). It is based on #89's branch fix/d150-v3, so the diff shows only these two commits. Once #89 lands, I'll rebase this PR onto main, retarget it to main, re-derive the corpus rates and gate it.

Commits

  1. A bare Snowflake LIMIT or OFFSET is an alias, as Snowflake reads it (import 163, wip/syntax-evidence 462b572).
    • SELECT 1 LIMIT names its column LIMIT.
    • In FROM t LIMIT, LIMIT names the table, so LIMIT.a reads its column.
    • A bare LIMIT is an alias when ;, ), WHERE, ORDER BY, another LIMIT or the end of input follows it.
    • A bare OFFSET is an alias when ;, ) or the end of input follows it.
    • LIMIT OFFSET 1 stays a syntax error (1003). LIMIT with a row count, and LIMIT NULL, keep their row-limit meaning.
  2. SQ0105's help for a long set-operation chain.
    • A flat UNION ALL chain of 513 or more branches is still refused with SQ0105. The depth limit stays because convert recurses once per branch and overflows its stack at 513 branches.
    • When the statement holds more than 250 set operators, the help now says to put at most 250 branches in each common table expression and combine them with the same operator. Other deep statements keep the general help.
    • An iterative convert for long chains is on the product lane's list.

Evidence

  • The parse verdict changes for none of the 56,748 receipted statements.
  • The everyday corpus query SELECT order_id FROM orders LIMIT moves from refused SQ0003 to translated, with the alias quoted as "LIMIT". The translation rates move to 288 of 436 (strict) and 357 of 436 (repository).
  • 1,000 UNION ALL branches, split into four CTEs of 250 as the new help says, pass both check and convert.
  • The test suites, clippy, fensu (0 faults) and the hygiene scan pass.

Snowflake reads a LIMIT with no row count after it as an alias of the item
before it (import 163): SELECT 1 LIMIT names its column LIMIT, FROM t LIMIT
names the table, which LIMIT.a then reads, and LIMIT before WHERE, ORDER
BY, a second LIMIT, ) or ; is an alias too. A bare OFFSET before ), ; or
the end is the same. LIMIT OFFSET 1 stays a syntax error (1003), so OFFSET
does not end an alias LIMIT. LIMIT with a count, LIMIT NULL and other bare
LIMITs keep their row-limit reading. No receipted statement changes
verdict; the everyday corpus query SELECT order_id FROM orders LIMIT now
translates, with the alias quoted as "LIMIT".
A flat chain of 513 or more UNION ALL branches is refused with SQ0105, and
its help said to move nested parts into common table expressions, which
does not fit a flat chain. Counting the chain as one level is not safe:
convert overflows its stack on 513 branches (it recurses per branch), so
the depth limit stays. When the statement holds more than 250 set
operators, SQ0105's help now says to put at most 250 branches in each
common table expression and combine them with the same operator; 1,000
branches split that way check and convert. Other deep statements keep the
general help.

kvlonge commented Nov 8, 2026

Copy link
Copy Markdown
Contributor Author

Closing: SQLQuack lands through local-gate trains, not PR merges (D94), so open PRs only add clutter (D628/D630). The branch is kept. Any work here that isn't on main yet is tracked by the train owner and lands through a train.

@kvlonge kvlonge closed this Nov 8, 2026
@kvlonge
kvlonge deleted the fix/limit-union 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