feat(sql): execute generated read queries without model round trips
Issue for this PR
Closes #1489
Type of change
- Bug fix
- New feature
- Refactor / code improvement
- Documentation
What does this PR do?
Stacked on feat/analyst-harness-dab-2026-10 (#1441).
Why. Reading across many tables (for example a table set built by a generator query) forced the model to receive the generated SQL, then retype it into sql_execute. For large warehouses the generated SQL is clipped in the preview or moved to a spill file, so the model had to recover and re-emit tens of thousands of characters, which is slow, costly and error-prone.
Root cause. sql_execute required literal query text; there was no way to say "run the SQL produced by this read". This is a missing capability, not a defect. The issue's other items are engine behavior or existing permission policy (DuckDB subquery/lateral/named-parameter limits and EXECUTE IMMEDIATE are engine-side; session settings and macros keep their write permission policy; preview clipping is intentional).
Before -> after. Before: the generated SQL had to pass through the conversation. After: sql_execute accepts query_from: { warehouse, sql }. The source SELECT must return exactly one row and one non-empty string column (not truncated, at most 1 MiB UTF-8). That string is validated as a single read-only SELECT and executed on the target warehouse, without being previewed or retyped. Only the final result is formatted.
- Exactly one of
query/query_fromis required;query_fromneeds an explicit target warehouse. - Strict-schema clients that send
query_from: nullor{warehouse:"", sql:""}(or an emptyquery) for the unused field are accepted; a half-filledquery_fromis rejected. - Source and generated reads are each permission-checked and routed independently. Generated writes, modifying CTEs, metadata commands and statement batches are rejected (including on scratch). PostgreSQL keeps read-only transactions; limits and deadlines are forwarded.
- Tool description documents DuckDB
query_table([...], true)and batching of at most 128 names perUNION ALL BY NAMEto stay within the default expression depth.
Deferred. No measured cost/token improvement (affected sessions unavailable offline); sql_materialize, table globs and remote workspace tools are not extended; the 1 MiB limit applies after retrieval and is not a driver-level transfer bound. Review follow-up (P2, not fixed): a source SELECT with duplicate output column aliases can collapse to one column in drivers that return keyed rows (e.g. SQLite), so the single-column check can be bypassed; the generated SQL is still validated as a read-only SELECT, so this is not a permission bypass.
How did you verify your code works?
bun test test/altimate/tools/sql-execute-query-from.test.ts: 51 pass, 0 fail (includes a real DuckDB aggregate over 1,024 synthetic tables with a compact request and no spill, and strict-schema placeholder cases).- All test files referencing
sql_execute(test/altimate/tools plus carry-forward, feature-discovery, precedence, scratch-sessions, sql-materialize, sql-validation, telemetry, warehouse-failure, session, skill and telemetry suites): 1138 pass, 11 fail. 4 failures are pre-existing, identical at the base (datamate_manager x2, a lintSqlResult large-cache test, one sample_setup test); the remaining sample_setup failures were 5s timeouts under load and pass in isolation (8 pass, 0 fail). bun run typecheck(packages/opencode): pass.git diff --check: pass.- Marker check:
sql-execute.tsdoes not exist in the last v1 baseline tag and lives undersrc/altimate/**, so no upstream markers are needed. - Independent Codex review: P1 (strict-schema callers could not represent an unused
query_from) fixed with regression tests; P2 above noted.
Screenshots / recordings
N/A (no UI change).
Checklist
- I have tested my changes locally
- I have not included unrelated changes in this PR
š¤ Generated with Claude Code
[!NOTE]
Medium Risk
Extends the SQL execution tool with a two-hop path and stricter read-only validation; changes are guarded by permissions and expanded function denylists but still touch warehouse execution behavior.
Overview
Adds query_from to sql_execute so a compact source SELECT can fetch generated SQL internally and run it on a target warehouse without copying megabytes of SQL through the model or tool preview.
The flow requires exactly one of query or query_from, an explicit target warehouse, and validates both the generator and the returned string as single read-only SELECTs (1 MiB cap, strict one-row/one-column scalar). Source and target each get permission prompts, workspace precedence, and PostgreSQL read_only where applicable; workspace redirects can include the generated SQL up to 40 KiB. readSql in sql-check is tightened to block more callable side effects (Unicode-escaped identifiers, Snowflake SYSTEM$*, PG session/backend/replication helpers). Docs and a large test suite cover placeholders, routing, and a 1k-table DuckDB aggregate.
Reviewed by Cursor Bugbot for commit 9c780d359c86ede1a68a307dd1c6a2bf230c0f0b. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by cubic
Adds a query_from option to sql_execute so the model no longer has to copy generated SQL through the conversation and re-emit it as a literal query. Closes #1489.
Previously, executing a read produced by a generator query forced the model to receive the SQL, then retype it into sql_execute; for large warehouses the SQL got clipped in the preview or moved to a spill file, making recovery slow and error-prone. Now query_from: { warehouse, sql } runs a source SELECT and executes its single SQL string result (up to 1 MiB UTF-8) as a read-only SELECT on the target warehouse. The source SQL and generated SQL are each permission-checked and routed independently; generated writes, modifying CTEs, metadata commands, statement batches, and PostgreSQL session, backend, advisory-lock, logical-slot, and system-control functions are rejected (including Unicode-escaped spellings, SYSTEM$ calls, and WAL replay controls). Only the final result is formatted, so the generated SQL never enters the preview or spill path.
- Requires exactly one of
queryorquery_from; accepts null or empty placeholders from strict-schema clients but rejects half-filledquery_from. - Source SELECT must return exactly one row and one non-empty string column without truncation; result is validated as a single read-only SELECT before execution.
- Preserves read-only transactions on PostgreSQL and forwards limits and deadlines to both reads.
- Workspace redirects carry the generated SQL so they can still be followed, but refuse redirects whose SQL exceeds 40 KiB; results are titled generically without exposing the SQL.
- Documents DuckDB
query_table([...], true)and batching of at most 128 table names perUNION ALL BY NAME.
Tests: a dedicated suite passes, including a real DuckDB aggregate over 1,024 synthetic tables with a compact request and no spill; all existing suites referencing sql_execute pass (11 failures, all pre-existing at the base).