Skip to content

v0.1.1

Choose a tag to compare

@yogthos yogthos released this 11 Aug 17:41
· 16 commits to main since this release
cb4c4f3

Two fixes on the postgres side, both found while reviewing v0.1.0.

Affected rows are reported on postgres

execute!, update! and delete! now return the number of rows they affected, read from PQcmdTuples. execute! had always promised rows affected and sqlite had always delivered it, but postgres returned nil from all three, so anything branching on the count silently saw nothing. Commands that carry no count, DDL among them, give 0, which is what sqlite3_changes reports for those too.

If you are upgrading, this is the one outward change: a nil becomes a number, and postgres now matches what sqlite already did.

Placeholders are no longer miscounted

Rewriting JDBC ? placeholders to $N only skipped single-quoted literals, so a ? in a comment, a quoted identifier or a dollar-quoted body was rewritten and, worse, consumed a parameter number, shifting every later placeholder. Both triggers are ordinary things to write in a migration: a prose comment ending in a question mark, or a plpgsql body in dollar quotes.

before:  select /* ? */ ? as c   ->  select /* $1 */ $2 as c    ($2 with one parameter)
after:   select /* ? */ ? as c   ->  select /* ? */ $1 as c

The scanner now skips string literals, quoted identifiers, line and block comments including the nesting postgres allows, dollar-quoted bodies with or without a tag, and E escape strings. A $ inside an identifier is left alone, since postgres allows it there and a$b$c is one name rather than a dollar quote.

Placeholder rewriting is linear

It rebuilt the statement one character at a time, copying the accumulator on every character, so cost grew with the square of the length.

sql chars before after
500,000 19,343 ms 146 ms

Cost per character is now flat from 125KB through 2MB.

Changes

  • #8 Report affected rows on postgres, and rewrite placeholders in linear time