Skip to content

Spike SQLite built-ins for parser dependency analysis#132

Closed
mmkal wants to merge 4 commits into
mainfrom
bedtime/2026-05-17-parser-spike
Closed

Spike SQLite built-ins for parser dependency analysis#132
mmkal wants to merge 4 commits into
mainfrom
bedtime/2026-05-17-parser-spike

Conversation

@mmkal
Copy link
Copy Markdown
Collaborator

@mmkal mmkal commented May 16, 2026

Summary

Runs the first bounded parser-task spike: check whether SQLite built-ins can narrow the need for a full SQL parser in schemadiff dependency analysis.

The result is executable evidence, not product integration. node:sqlite authorizer callbacks can report useful dependency facts for check constraints, partial indexes, views, triggers, and table-only reads, but DatabaseSync.setAuthorizer() only exists in Node v24.10.0+, so a future implementation needs a feature check/fallback or an explicit engine decision.

Findings

  • sqlite3_set_authorizer() is the useful built-in for semantic dependency facts.
  • StatementSync.columns() / sqlite3_column_origin_name() helps for result-column origins only, not where or other non-output dependencies.
  • explain / explain query plan is not a dependency API; the output is plan-oriented and unstable.
  • sqlite3_stmt_scanstatus() is performance telemetry, not semantic dependency analysis.

Checks

  • pnpm --dir packages/sqlfu exec vitest run test/schemadiff/sqlite-builtins-spike.test.ts passed
  • pnpm exec oxfmt --check packages/sqlfu/test/schemadiff/sqlite-builtins-spike.test.ts tasks/parser.md passed
  • git diff --check passed

Follow-up

Prototype an internal feature-gated authorizer-backed dependency probe before pulling in a parser. Keep parser adoption scoped to adapter-independent analysis, incomplete SQL fragments, and AST-level transformations that authorizer callbacks cannot cover.


Note

Low Risk
Adds a skipped-when-unsupported spec and task documentation only; no production code paths change. Risk is limited to potential CI/runtime variance due to reliance on node:sqlite APIs gated by Node version.

Overview
Documents the completed SQLite built-ins investigation in tasks/parser.md, including conclusions about which SQLite/Node APIs can (and cannot) support schema-body dependency analysis and what future integration decisions remain.

Adds an executable Vitest spec (sqlite-builtins-spike.test.ts) that probes node:sqlite’s DatabaseSync.setAuthorizer() behavior for dependency reporting across CHECK constraints, partial indexes, views, and triggers, and demonstrates that StatementSync.columns() and EXPLAIN QUERY PLAN don’t capture non-result-column dependencies. The spec is feature-gated and skips when setAuthorizer is unavailable.

Reviewed by Cursor Bugbot for commit 4dd92ee. Bugbot is set up for automated code reviews on this repo. Configure here.

Package size — packed 239.4 kB (no change)

Package size

main this PR Δ
packed 239.4 kB 239.4 kB 0
unpacked 991.8 kB 991.8 kB 0
files 185 185 0

dist/vendor/*.js bundles

main this PR Δ
vendor/sha256.js 4.3 kB 4.3 kB 0
vendor/sql-formatter/*.js 58.3 kB 58.3 kB 0
vendor/sqlfu-sqlite-parser/*.js 17.2 kB 17.2 kB 0
vendor/standard-schema/*.js 2.8 kB 2.8 kB 0
vendor/typesql/*.js 134.6 kB 134.6 kB 0

Measured with npm pack --dry-run --json on sqlfu (0.0.3-7 on main vs 0.0.3-7 on this PR).

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 16, 2026

Open in StackBlitz

npm i https://pkg.pr.new/sqlfu@132

commit: 4dd92ee

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 4dd92ee. Configure here.

(left, right) =>
sourceOrder(left).localeCompare(sourceOrder(right)) ||
left.relation.localeCompare(right.relation) ||
left.column.localeCompare(right.column) ||
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sort crashes on null column in localeCompare

Medium Severity

left.column.localeCompare(right.column) throws a TypeError when column is null. The Reference type explicitly declares column: string | null, and the authorizer produces null-column entries (line 159: column: column || null). The sourceOrder helper correctly handles nullable source with || '', but no equivalent null-safe handling exists for column in the sort comparator. If two references with the same source and relation but null columns need to be compared, this crashes at runtime.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 4dd92ee. Configure here.

});

test('column origin and explain query plan do not replace dependency analysis', () => {
using fixture = createAuthorizerFixture();
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test not skipped when setAuthorizer is unavailable

Medium Severity

The "column origin and explain query plan" test on line 114 uses test instead of authorizerTest, but calls createAuthorizerFixture() which unconditionally invokes database.setAuthorizer(...). On Node versions without setAuthorizer, the other tests are correctly skipped via authorizerTest, but this one will crash with a TypeError. The test's assertions only exercise statement.columns() and explain query plan, not the authorizer itself, so it appears unintentionally coupled to the authorizer API.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 4dd92ee. Configure here.

@mmkal mmkal marked this pull request as draft May 21, 2026 09:22
@mmkal mmkal closed this May 26, 2026
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