feat(db): atomic update expressions — d.expr, d.increment, d.decrement (#1743)#2292
Merged
Conversation
…ypes #1743 Introduce column-relative SQL expressions for update operations. - DbExpr interface and isDbExpr() type guard in sql/expr.ts - d.expr(), d.increment(), d.decrement() on the d namespace - Widen $update and $update_input types to accept DbExpr - Re-export sql from main @vertz/db entry for single-import DX - Export DbExpr type and isDbExpr from both @vertz/db and @vertz/db/sql Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…yer #1743 - Export renumberParamsWithDialect() from tagged.ts for dialect-aware fragment composition (supports both $N and ? param styles) - buildUpdate: detect DbExpr values in SET clause, compose SqlFragment with correct param renumbering - buildInsert: detect DbExpr values in ON CONFLICT DO UPDATE SET clause for upsert expression support - Fix autoUpdate injection to not overwrite user-provided values/expressions in update(), updateMany(), and upsert() Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ypass (#1743) - SQLite dialect tests for DbExpr in buildUpdate and buildInsert - Type-level tests (.test-d.ts) for DbExpr in $update and $update_input - Unit tests for renumberParamsWithDialect() - Regression test for autoUpdate + DbExpr interaction - Fix: allow DbExpr through readOnly filter on autoUpdate columns Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add documentation for d.expr(), d.increment(), d.decrement() in the queries guide. Update sql import path to vertz/db. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ns (#1743) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This was referenced Apr 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds atomic column-level update expressions to
@vertz/db, enabling database-side operations without read-modify-write cycles.d.increment(n)/d.decrement(n)— atomic arithmetic on numeric columnsd.expr(col => sql\...`)** — arbitrary SQL expressions (e.g.LOWER(),COALESCE()`)update,updateMany,upsert, andON CONFLICT DO UPDATE SET$updateand$update_inputacceptInferColumnType<T> | DbExprPublic API Changes
New exports from
@vertz/dbDbExpr(type) — expression descriptor interfaceisDbExpr()— type guardsql— re-exported tagged template for use withd.expr()SqlFragment(type) — for advanced expression compositionNew methods on
dd.expr(col => sql\...`)` — general-purpose column expressiond.increment(n)— sugar ford.expr(col => sql\${col} + ${n}`)`d.decrement(n)— sugar ford.expr(col => sql\${col} - ${n}`)`Bug fix
autoUpdate()columns with user-providedDbExprwere silently overwritten by theNOW()sentinel becauseautoUpdate()setsisReadOnly: true, causing the readOnly filter to strip the expression before the autoUpdate guard could see it. Fixed by allowing DbExpr values through the readOnly filter on autoUpdate columns.Files changed
packages/db/src/sql/expr.ts— newDbExprtype andisDbExprguardpackages/db/src/d.ts—d.expr(),d.increment(),d.decrement()packages/db/src/sql/update.ts— DbExpr detection in SET clausepackages/db/src/sql/insert.ts— DbExpr in ON CONFLICT DO UPDATE SETpackages/db/src/sql/tagged.ts— exportedrenumberParamsWithDialect()packages/db/src/query/crud.ts— autoUpdate guard + readOnly bypass for DbExprpackages/db/src/schema/table.ts— widened$update/$update_inputtypespackages/db/src/index.ts— re-exportspackages/mint-docs/guides/db/queries.mdx— documentationTest plan
DbExpr,isDbExpr,d.expr(),d.increment(),d.decrement()buildUpdate(increment, decrement, expr, multi-param, mixed, now-override, constant)buildInsertON CONFLICT (increment, expr, mixed)renumberParamsWithDialect().test-d.ts) — positive and negative tests for DbExpr in$updateand$update_inputturbo run build typecheck test --filter='@vertz/db'passesCloses #1743
🤖 Generated with Claude Code