Skip to content

[bedtime-architecture] Deepen SQL parameter binding#125

Merged
mmkal merged 4 commits into
mainfrom
bedtime/2026-05-15-architecture
May 16, 2026
Merged

[bedtime-architecture] Deepen SQL parameter binding#125
mmkal merged 4 commits into
mainfrom
bedtime/2026-05-15-architecture

Conversation

@mmkal
Copy link
Copy Markdown
Collaborator

@mmkal mmkal commented May 15, 2026

Summary

Deepens runtime parameter binding into a driver-neutral Module behind the Adapter seam.

  • Adds packages/sqlfu/src/sql-params.ts for named SQL parameter scanning and driver bind-shape projection.
  • Moves D1, Durable Objects, Expo SQLite, Turso serverless, sqlite-wasm, and Postgres onto that Module.
  • Deletes the old sqlite-text named-param helper and the Postgres private ? to $N scanner, so Postgres named params now bind directly to $1, $2, etc. while preserving dollar-quoted SQL bodies.
  • Removes the old root export for rewriteNamedParamsToPositional; this was adapter plumbing, not product surface.

Design Choice

The grill-you pass challenged whether Postgres should keep its private scanner. The decision was to use one extended scanner for binding, including Postgres dollar-quoted strings, because two scanners over the same authored SQL were the source of the architectural wart.

Checks

Passed:

  • pnpm --filter sqlfu exec vitest run test/sql-params.test.ts test/adapters/pg.test.ts test/sqlite-text.test.ts
  • pnpm --filter sqlfu exec vitest run test/adapters/d1.test.ts test/adapters/durable-object.test.ts test/adapters/expo-sqlite.test.ts test/adapters/sqlite-wasm.test.ts
  • pnpm --filter sqlfu exec vitest run test/adapters/turso-remote.test.ts test/adapters/turso-database.test.ts
  • pnpm --filter sqlfu typecheck
  • pnpm --filter @sqlfu/ui build
  • pnpm --filter sqlfu exec vitest run test/resolve-sqlfu-ui.test.ts
  • git diff --check

Full pnpm --filter sqlfu test still fails test/import-surface.test.ts because the existing vendored TypeSQL bundle for sqlfu/analyze imports node:sqlite. That is outside this PR; the initial full run also needed @sqlfu/ui built before resolve-sqlfu-ui passed.

Replacement Compare Branches

Existing PR Replacement compare Strategy
#124 bedtime/2026-05-15-default-db-gitignore comparison clean merge
#123 bedtime/2026-05-15-pg-docs-followup comparison clean merge
#122 bedtime/2026-05-15-db-base-directory comparison clean merge
#121 bedtime/2026-05-15-improve-docs comparison clean merge
#120 bedtime/2026-05-15-landing-trace comparison clean merge
#119 bedtime/2026-05-15-cleanup-tasks comparison clean merge
#117 bedtime/2026-05-14-query-identity-manifest comparison clean merge
#114 bedtime/2026-05-14-generate-preflight comparison clean merge
#111 issue-110-sqlite3-parser-schemadiff comparison clean merge

Replacement checks: all replacement branches passed git diff --check; targeted tests/builds are recorded in tasks/architecture-2026-05-15.md.

Package size — packed 236.8 kB (+259 B, +0.1%)

Package size

main this PR Δ
packed 236.5 kB 236.8 kB +0.1%
unpacked 971.5 kB 974.5 kB +0.3%
files 181 183 +2

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).


Note

Medium Risk
Touches SQL parameter rewriting/binding used by multiple runtime adapters (including Postgres), so subtle placeholder-scanning edge cases could change query behavior. Added targeted unit tests for Postgres and the new binder to reduce regression risk.

Overview
Moves SQL placeholder scanning and parameter binding into a new driver-neutral sql-params.ts, supporting ?-style positional, Postgres $N placeholders, and sqlite-wasm’s prefixed named binds.

Updates D1, Durable Objects, Expo SQLite, Turso serverless, sqlite-wasm, and the Postgres adapter to use the shared binder; Postgres drops its custom ?$N conversion and now binds named params directly while preserving dollar-quoted strings, casts, and JSON ? operators.

Removes the adapter-plumbing export rewriteNamedParamsToPositional (and its tests) from sqlite-text.ts/root index.ts, and adds new unit tests covering the shared binder plus Postgres binding behavior.

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

Review Follow-up

Independent review found two Postgres scanner gaps after the first push: :param::type casts and JSONB ? / ?| / ?& operators. Both are fixed in 8780812 with regression tests in test/sql-params.test.ts and test/adapters/pg.test.ts. Replacement compare branches were refreshed by merging the updated architecture head and all replacement branches still pass git diff --check.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 15, 2026

Open in StackBlitz

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

commit: 8780812

@mmkal mmkal changed the title Nightly architecture improvement 2026-05-15 [bedtime-architecture] Deepen SQL parameter binding May 15, 2026
@mmkal mmkal merged commit 8db045b into main May 16, 2026
8 checks passed
mmkal added a commit that referenced this pull request May 21, 2026
## Summary

Runs the 2026-05-17 evergreen task cleanup pass.

- Files the completed nightly architecture task from merged PR #125 into
`tasks/complete/2026-05-16-architecture-2026-05-15.md`
- Updates `tasks/cleanup-tasks.md` with the pass status, PR/task survey,
removed local worktrees, and skipped candidates
- Removes clean local worktree checkouts for merged or stale compare
branches while preserving local/remote branches

## Task filing

Moved:

- `tasks/architecture-2026-05-15.md` ->
`tasks/complete/2026-05-16-architecture-2026-05-15.md`

Left open intentionally:

- Evergreen logs: `tasks/cleanup-tasks.md`, `tasks/improve-docs.md`
- Broad or deferred follow-up tasks touched by recent PRs:
`tasks/landing-demo-maintainability.md`, `tasks/pg.md`
- Open PR task files, including `tasks/ui-relations.md` while PR #128
remains open

## Local worktree cleanup

Removed clean local checkouts only:

- `bedtime-2026-05-14-generate-preflight`
- `bedtime-2026-05-14-query-identity-manifest`
- `bedtime-2026-05-15-architecture`
- `bedtime-2026-05-15-cleanup-tasks`
- `bedtime-2026-05-15-db-base-directory`
- `bedtime-2026-05-15-default-db-gitignore`
- `bedtime-2026-05-15-improve-docs`
- `bedtime-2026-05-15-landing-trace`
- `bedtime-2026-05-15-pg-docs-followup`
- `compat-existing-tools`
- `query-identity-refresh-pr-114`

Left dirty, ahead, active, ambiguous, or out-of-scope worktrees in place
and recorded the reason in the task log.

## Verification

- `gh pr list --state open --limit 50 --json
number,title,headRefName,baseRefName,isDraft,updatedAt,url`
- `gh pr list --state merged --limit 30 --json
number,title,headRefName,baseRefName,mergedAt,url`
- `gh pr list --state closed --limit 30 --json
number,title,headRefName,baseRefName,closedAt,url`
- `gh pr view` for PRs #120 through #129
- `find tasks -maxdepth 2 -type f | sort`
- `git worktree list --porcelain`
- `git status --short`
- `git diff --check`

<!-- package-size:start -->
<details>
<summary>Package size — packed 239.4 kB (no change)</summary>

## 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)._

</details>
<!-- package-size:end -->

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk: documentation-only changes that move a task file to `done`
status and append cleanup notes; no runtime or build logic is modified.
> 
> **Overview**
> Records the **2026-05-17 cleanup pass** in `tasks/cleanup-tasks.md`,
including what was inspected, which worktrees were removed, and which
candidates were intentionally left in place.
> 
> Files the merged nightly architecture task into
`tasks/complete/2026-05-16-architecture-2026-05-15.md` and updates its
frontmatter/status summary to reflect **done/merged in PR #125**.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
c3d0672. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
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