Skip to content

fix: CLI rename, coded errors, plan exit code and temporary test functions - #1149

Closed
kvlonge wants to merge 14 commits into
mainfrom
fix/cli-batch
Closed

kvlonge wants to merge 14 commits into
mainfrom
fix/cli-batch

Conversation

@kvlonge

@kvlonge kvlonge commented Oct 19, 2026

Copy link
Copy Markdown
Contributor

Why

Thirteen CLI tickets: sqb rename left MODEL() column declarations and audit conditions behind (CHI-640), several commands crashed with raw tracebacks instead of coded errors (CHI-501, 530, 534, 571, 596, 600), output glitches (CHI-533, 519), sqb plan exited 0 with errors (CHI-429), unit tests ran against stale built UDFs (CHI-555), and stale generated skill pages and a broken seed audit doc example went unnoticed (CHI-629, CHI-632).

Changes

  • sqb rename rewrites MODEL() column declarations and audit SQL arguments when they resolve to the renamed column; anything ambiguous is listed for manual editing.
  • Coded errors: unreadable --select-file (C114), non-interactive janitor (C503), unhashable macro dict keys, warehouse connection failures (C115), sqb diff missing relation/unknown key (X310/X311); source-only selections compile.
  • Plan tree bar and standalone audit rows fixed.
  • sqb plan exits 1 when the plan has errors, in text and --json (release note in the plan docs).
  • sqb test runs against session-temporary copies of the functions it calls and their callees (DuckDB, PostgreSQL, Snowflake, Databricks SQL); other adapters use the built function.
  • make check-docs-skill in check-ci; seed audit docs and error message fixed.

Verification

  • DuckDB E2E through the real CLI for every ticket and every review finding; offline rendering tests for Snowflake/Databricks/PostgreSQL.
  • make test (all failures caused by this branch fixed; two dev-profile timing tests unaffected), focused reruns, make check-ci, compiler differential (one intended golden).
  • Independent review plus one follow-up.

…h the column

A MODEL columns block without commas between entries hid every entry after the
first from sqb rename, so the model's own declaration was left for a hand edit
that the next run then refused because the project no longer compiled.
Column entries now split where the compiler splits them.

String arguments of attached audits are renamed only when the generic audit's
SQL definition splices them in as SQL (`@where_condition`), and only where they
reference the audited model: a subquery reading another model keeps that
model's column, and one reading the audited model is renamed too. Arguments
the audit quotes (`@'prefix'`), arguments of audits with no SQL definition,
unparseable ones and ones reading relations of unknown columns are listed for
a hand edit.

Refs: CHI-640
Reading a missing or unreadable selector file raised a raw FileNotFoundError
with a traceback from compile, plan and build. The read now fails with
error[C114] naming the file, in text and --json output.

Refs: CHI-501
With only declaration rules selected, model rule evaluation took the first
model unconditionally, so a source-only selection sliced an empty model list
and panicked. The model limit is now capped by the number of models.

Refs: CHI-530
Without --auto-approve, janitor prompted on a non-interactive stdin and ended
with an EOFError traceback. Like build confirmations, it now refuses before
prompting with error[C503] and tells the user to pass --auto-approve or run it
in a terminal.

Refs: CHI-534
A dict key such as [1] or (1, [2]) parsed, then failed with a raw TypeError
when the Python dict was built. The argument parser now rejects list and dict
keys, also inside tuple keys, with a located P001 error and help.

Refs: CHI-571
When the warehouse connection could not be opened, for example a DuckDB file
in a missing directory, build, seed, audit, test, plan, load, query and diff
printed the failed connection line and then the adapter's raw exception with
a traceback. Connection failures now raise error[C115] naming the adapter and
the reason, with help pointing at sqb debug. SQLBuild's own coded errors pass
through unchanged; a client library error that carries its own `code`, such as
a Google API error, is still reported as C115.

Refs: CHI-596
…errors

sqb diff with a --key column that does not exist, or with the relation
missing on either side, failed with a raw warehouse error and a traceback.
Key columns are now checked against both relations (X311), and a failed
schema read whose relation does not exist reports which side lacks it (X310).

Refs: CHI-600
Detail rows under every plan entry used a blank prefix, so the vertical bar
of a non-last entry broke under its cursor, bounds, reason and diff rows.
Detail and nested rows now carry the bar when their entry has a later
sibling.

Refs: CHI-533
Seed, source and end audits printed as 'audit not_null OK', without their
target, and a failing warn-severity audit still showed OK. Their rows now name
the target and column, as in 'not_null (customers.customer_id) PASS', and show
PASS, WARN, FAIL or INSUFFICIENT from the audit outcome. The partial semantic
checks notice also says '1 model' instead of '1 models'.

Refs: CHI-519
sqb plan always exited 0 and printed 'Plan complete with errors' when the
plan had error-severity findings that sqb build refuses, such as M114 name
claims, so CI could not gate on it. Text and --json plans now exit 1 and the
final line reads 'Plan failed with errors'; plans with only warnings still
exit 0. The plan docs record the change as a release note.

Refs: CHI-429
`sqb test` called the built warehouse function, so an edited UDF or table
function was tested at its last-built definition, and a never-built one
failed with "Run `sqb build` first". Before the tests run, SQLBuild now
creates a session-scoped copy of every function the selected tests call,
and of every function those call (the test plan now carries the transitive
closure), then points calls in the tests' SQL code at the copies; calls in
string literals and comments keep their text. No permanent DDL is issued.

The copy set is decided on the first test connection and recreated on every
other connection and on recovery reconnects; a connection that cannot create
it stops the run with error[T006] naming the function and connection.

Adapters opt in through the optional StrictAdapter method
`render_create_temporary_function`: DuckDB and MotherDuck use TEMP MACRO,
PostgreSQL uses pg_temp, Snowflake and Databricks use prefixed TEMPORARY
FUNCTIONs. BigQuery and SQL Server keep calling the built function. When no
copy can be created, tests fall back to the built function (a caller whose
callee has no copy too), and a missing one reports the reason with the build
hint.

Refs: CHI-555
The bundled skill reference pages under
src/sqlbuild/.agents/skills/sqlbuild/references/docs drifted from the
website docs and nothing caught it. `make check-docs-skill`, now part of
`make check-ci`, regenerates the pages in memory with the same generator
as `make skills` and fails, listing every changed, missing or retired
page, with `make skills` as the fix.

Refs: CHI-629
The seeds page attached `expression_is_true` without showing its
definition, and the definition people copy from the playground reads
`__ref("@model")`. An attached audit receives its owner kind's name
argument (`model`, `source` or `seed`) plus `relation`, so on a seed it
failed with a bare "missing argument 'model'". Passing the seed as
`model` would not help: `__ref` resolves only models.

The seeds page now shows a seed-compatible `@relation` definition and
explains the owner arguments, the audits page documents them, and the
missing-argument error names the argument the owner does receive and
points at @relation. A DuckDB E2E builds the documented example.

Refs: CHI-632
@kvlonge
kvlonge enabled auto-merge (squash) October 19, 2026 04:20
CHI-429 makes sqb plan exit 1 when the plan reports an error finding,
so the schema backfill case that plans an on_schema_change fail model
now expects that exit code.
@kvlonge

kvlonge commented Oct 19, 2026

Copy link
Copy Markdown
Contributor Author

Combined into #1152 (same adapter contract files; one CI run).

@kvlonge kvlonge closed this Oct 19, 2026
auto-merge was automatically disabled October 19, 2026 07:12

Pull request was closed

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