feat(harness): tht sql preview --json + --offset for AGGrid paging (BE-2)
Add inject_limit_offset (tht/execute/limit.py) — pure subquery wrapper that applies LIMIT/OFFSET non-destructively without clobbering user-supplied LIMITs. Wire offset param into do_run (pre-processing when offset>0) and add --offset / --json flags to preview_cmd; JSON mode emits pristine stdout with columns, rows, execution_ms, truncated, limit, offset. 5 new tests (4 unit + 1 JSON-purity), 219/219 total passing (no regressions). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
"""Pure subquery LIMIT/OFFSET injection for paging (non-destructive).
|
||||
|
||||
Unlike `_inject_limit` (which uses AST rewriting and adds +1 for truncation detection),
|
||||
`inject_limit_offset` wraps the query as a subquery and applies LIMIT/OFFSET verbatim.
|
||||
This preserves any existing LIMIT that was part of the user's query (it becomes part
|
||||
of the inner subquery), and adds paging on top.
|
||||
"""
|
||||
|
||||
|
||||
def inject_limit_offset(sql: str, *, limit: int, offset: int = 0) -> str:
|
||||
"""Wrap query as subquery and apply LIMIT/OFFSET non-destructively.
|
||||
|
||||
The original query (including any user LIMIT) becomes the inner subquery,
|
||||
so no existing LIMIT clause is overwritten. OFFSET clause is omitted when
|
||||
offset == 0 to keep the SQL clean.
|
||||
"""
|
||||
inner = sql.strip().rstrip(";")
|
||||
clause = f"LIMIT {int(limit)}"
|
||||
if offset:
|
||||
clause += f" OFFSET {int(offset)}"
|
||||
return f"SELECT * FROM (\n{inner}\n) AS _tht_page {clause}"
|
||||
Reference in New Issue
Block a user