Skip to content

ast.setLimit / ast.setOffset silently no-op on set-operation nodes (UNION/INTERSECT/EXCEPT) #236

@ujaval403

Description

@ujaval403

SDK version: 0.5.3 · Dialect: DuckDB

Summary

ast.setLimit / ast.setOffset silently return the node unchanged when the statement is a set operation (UNION / INTERSECT / EXCEPT). No error, no change — the caller can't tell it didn't work.

Repro (node, @polyglot-sql/sdk@0.5.3)

import { init, parse, generate, Dialect, ast } from '@polyglot-sql/sdk';

await init();
const D = Dialect.DuckDB;

const union = parse('SELECT id FROM a UNION ALL SELECT id FROM b', D).ast[0];
console.log(generate([ast.setLimit(union, 5)], D).sql[0]);
// → "SELECT id FROM a UNION ALL SELECT id FROM b"      (no LIMIT)
console.log(generate([ast.setOffset(union, 10)], D).sql[0]);
// → "SELECT id FROM a UNION ALL SELECT id FROM b"      (no OFFSET)

// control — plain SELECT works:
const sel = parse('SELECT id FROM a', D).ast[0];
console.log(generate([ast.setLimit(sel, 5)], D).sql[0]);
// → "SELECT id FROM a LIMIT 5"

A set-operation node does carry its own limit/offset fields (a trailing … UNION ALL … LIMIT 3 parses onto the set-op node, stored as a bare literal expression rather than SELECT's Limit { this } wrapper) — the setters just don't handle that shape.

Expected

setLimit/setOffset should set the set-operation node's own limit/offset (the SQL-standard meaning: applied after the arms combine). Failing that, throwing/returning an error beats the silent no-op.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions