Skip to content

feat(analysis): accept write values that bind no placeholder - #56

Merged
omer-cengel merged 2 commits into
masterfrom
feature/non-binding-write-values
Oct 1, 2026
Merged

omer-cengel merged 2 commits into
masterfrom
feature/non-binding-write-values

Conversation

@omer-cengel

Copy link
Copy Markdown
Member

Summary

Common write idioms such as updated_at = now(), version = version + 1, DEFAULT, literals, and NULL were rejected because every INSERT value and UPDATE assignment had to be a placeholder. They are now accepted as written: a value that binds no placeholder contributes no generated parameter and reaches the database unchanged, while the placeholders beside it keep their existing numbering and binding order.

Changes

  • INSERT ... VALUES accepts, for each column, either a placeholder or an expression that binds none; the expression's target column must exist in the table, but its type does not need a Java mapping because nothing binds it.
  • UPDATE ... SET accepts the same per assignment; assignment placeholders still bind before WHERE placeholders, for both $N and :name queries.
  • A column-list assignment such as SET (name, active) = ('a', TRUE) now fails with UPDATE assignments must set one column at a time.
  • A placeholder nested inside a write value, such as $2 || 'x' or COALESCE($2, bio), is rejected as a placeholder in an unsupported location.
  • Analyzer tests cover interleaved $N and named placeholders, returning inserts, mixed UPDATE assignments, writes without any placeholder, unmapped-type target columns, unknown target columns, and the rejections; a PostgreSQL integration test generates, compiles, and runs an :exec insert, a returning named insert, and an :exec update using DEFAULT, a literal, NULL, now(), and code + 1.
  • The query documentation describes the accepted values, an example with its generated signature and binding order, and the updated rejections.

Scope and non-goals

  • Placeholders inside expressions or casts remain rejected.
  • ON CONFLICT, multi-row VALUES, and INSERT ... SELECT are unchanged and remain rejected.
  • Column references inside a non-binding expression are not resolved; the expression is passed to the database as written.
  • SQL parameter compilation, Java generation, and the runtime are unchanged.

@omer-cengel
omer-cengel merged commit b21b9ad into master Oct 1, 2026
6 checks passed
@omer-cengel
omer-cengel deleted the feature/non-binding-write-values branch October 1, 2026 15:49
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