fix(sql-check): bound key probes and report directional coverage
Issue for this PR
Closes #1491
Stacked on feat/analyst-harness-dab-2026-10 (#1441)
Type of change
- Bug fix
- New feature
- Refactor / code improvement
- Documentation
What does this PR do?
The sql_check keys check gave misleading verdicts and was too slow on large warehouses. A key set that was a proper subset of the other side was reported as "unmatched keys found", integer keys produced spurious prefix/suffix findings, and large text key sets exceeded a 5s query deadline.
Root cause: the verdict required the exact match count to equal both distinct counts (so a complete left subset failed); the bidirectional substring predicate ran over all distinct key pairs with integers cast to text (nested-loop join, false positives such as 12 vs 123); and normalization functions were embedded in correlated predicates.
Before -> after:
- Subset: "unmatched keys found" -> "left coverage complete", with independent left/right coverage shares and counts. Empty sides report coverage as unavailable.
- Integer keys (including DuckDB unsigned/huge integers): spurious prefix/suffix and normalized matches -> text diagnostics skipped, reported as
n/a. - Large text key sets (7k left / 130k right, SQLite and DuckDB): >5s timeout -> under 1s. Normalized forms are materialized per distinct key, right-side forms grouped before equality joins, unmatched samples use anti-joins, and the prefix/suffix probe is bounded to 100 unmatched left and 100 right keys (disclosed in the output).
- Counts still cover all source keys; at most five unmatched values per side are returned.
Deferred / follow-ups (Codex review, both P2, not fixed here):
- DuckDB collated string keys (e.g. NOCASE/NOACCENT) can make join counts exceed one match per left key; per-left-key counting would harden this.
- DuckDB
BIGNUMis not in the integer-type allowlist. - Live PostgreSQL not exercised (sandbox could not start a server);
AS MATERIALIZEDneeds PostgreSQL 12+. - Prefix/suffix detection is intentionally sampled.
How did you verify your code works?
bun test test/altimate/tools/sql-check.test.ts: 76 pass, 0 fail (16 new tests; the large-set cases failed before the fix).bun test test/altimate/tools(24 files): 632 pass, 3 fail, 1 error. The failures are indatamate-list-integrationsandsample-setup(5s timeouts), unrelated to this change; they also fail in a clean detached worktree at the base (2 fail, 2 errors, flaky).bun test test/altimate/tryExecuteViaDbt.test.ts: 4 pass.bun run typecheckinpackages/opencode: 0 diagnostics.script/upstream/analyze.ts --markers --base feat/analyst-harness-dab-2026-10 --strict: pass. The changed files are undersrc/altimate/**and absent from the v1.4.0 baseline tag, so no markers are required.git diff --check: clean.- Independent Codex review: only two P2 findings (listed above).
Screenshots / recordings
N/A
Checklist
- I have tested my changes locally
- I have not included unrelated changes in this PR
š¤ Generated with Claude Code
[!NOTE]
Medium Risk
Changes diagnostic SQL and verdict semantics for a core analyst tool; behavior shifts (subset = success) could surprise existing callers, though scope is limited to the keys check path.
Overview
Fixes misleading keys verdicts and timeouts in sql_check by rewriting the keys SQL plan and tightening when text diagnostics run.
Verdict and reporting now treat complete left-side exact matches as left coverage complete (not failure when the right side is larger). Metadata adds left_coverage / right_coverage shares, a clearer verdict line, and empty-input coverage as n/a.
Integer keys (including DuckDB unsigned/huge integer types) skip trim/normalize/leading-zero and prefix/suffix probes so values like 12 vs 123 no longer produce false format findings; those metrics surface as n/a with an explicit skip message.
Performance and correctness materialize per-distinct-key normalization, aggregate right-side forms before joins (so collisions do not inflate match counts), use joins/anti-joins instead of correlated EXISTS scans, and cap the prefix/suffix probe to up to 100 unmatched left keys Ć 100 right keys (disclosed in output). Large-set tests expect completion within a 5s deadline on SQLite and DuckDB.
Tests add subset coverage, integer skip behavior, normalization collision counting, bounded prefix diagnostics, empty-side coverage, mixed-type SQLite behavior, DuckDB unsigned/hugeint coverage, and 7k/130k key performance cases.
Reviewed by Cursor Bugbot for commit 4711728471e967a03e3181e0ad7bc9a993330b75. Bugbot is set up for automated code reviews on this repo. Configure here.
Known follow-ups
- Prefix/suffix probe compares against a sampled 100-key right side (disclosed in the output); the keys query uses
AS MATERIALIZED, which needs PostgreSQL 12 or later; collation-aware exact coverage and BIGNUM key detection are not handled.