dependabot[bot] opened a new pull request, #1091:
URL: https://github.com/apache/arrow-go/pull/1091

   Bumps [modernc.org/sqlite](https://gitlab.com/cznic/sqlite) from 1.54.0 to 
1.55.0.
   <details>
   <summary>Changelog</summary>
   <p><em>Sourced from <a 
href="https://gitlab.com/cznic/sqlite/blob/master/CHANGELOG.md";>modernc.org/sqlite's
 changelog</a>.</em></p>
   <blockquote>
   <h1>Changelog</h1>
   <ul>
   <li>
   <p>2026-08-03 v1.56.0:</p>
   <ul>
   <li>Re-vendor the transpiled SQLite sources, picking up 
<code>modernc.org/libsqlite3</code>'s fix for an upstream 
<strong>data-corruption bug in SQLite 3.53.3's journal rollback</strong>. The 
SQLite version is unchanged at <a 
href="https://sqlite.org/releaselog/3_53_3.html";>3.53.3</a>; what changes is 
that the amalgamation is now patched before it is transpiled. 3.53.3 reworked 
<code>readSuperJournal()</code> to return the super-journal name through a 
<code>char**</code> out-parameter, and <code>pager_playback()</code> now tests 
that pointer where it used to test <code>zSuper[0]</code>. A crash during the 
commit of a multi-database (ATTACH) transaction can leave the super-journal 
name and its checksum zeroed while the name length and the trailing magic 
survive; the checksum is a plain byte sum, so an all-zero name still validates 
and <code>readSuperJournal()</code> hands back a non-NULL pointer to an empty 
string. <code>pager_playback()</code> then calls <code>sqlite3OsAccess(pVfs
 , &quot;&quot;, SQLITE_ACCESS_EXISTS)</code>, gets ENOENT, and deletes the hot 
journal without playing it back — leaving the database corrupted. This is not a 
transpilation artifact: a plain gcc build of the stock 3.53.3 amalgamation 
fails on the same bytes while 3.53.2 recovers them, and it is what has been 
making upstream's own <code>test/crash.test</code> fail intermittently, in 
roughly 2% of runs, on every platform. The patch restores the pre-3.53.3 
behaviour of reporting a <code>(nul)</code> super-journal name and will be 
dropped once upstream ships its own fix. Every supported target carries it.</li>
   <li>Two targets change beyond that patch. On <code>linux/s390x</code> the 
regenerated transpile allocates C bit-fields MSB-first, as the big-endian 
platform ABI requires, rather than LSB-first; this comes from 
<code>modernc.org/cc/v4</code> v4.29.1 and touches bit-field accesses 
throughout the SQLite core, s390x being this module's only big-endian target. 
On <code>linux/riscv64</code> the transpile was regenerated on a host running 
GCC 11.4.0 where the previous one used GCC 13.3.0, which drops a handful of 
unexported compiler-predefined macro constants (the <code>__FLT16_*</code> 
family, <code>__DBL_IS_IEC_60559__</code> and friends) and changes the 
<code>COMPILER=gcc-13.3.0</code> entry <code>PRAGMA compile_options</code> 
reports to <code>COMPILER=gcc-11.4.0</code>; no SQLite code generation differs. 
Every other target's generated code is byte-identical to v1.55.0 apart from the 
journal-rollback patch above.</li>
   <li>Bump the pinned <code>modernc.org/libc</code> to v1.74.4, and the 
remaining dependencies to their current releases. v1.74.2 and v1.74.3 are 
retracted upstream — a <code>freeaddrinfo</code> lock leak that deadlocks name 
resolution — and v1.74.4 is the fix. As always, downstream modules must pin the 
exact <code>modernc.org/libc</code> version this module's <code>go.mod</code> 
pins (see [GitLab issue <a 
href="https://gitlab.com/cznic/sqlite/issues/177";>#177</a>](<a 
href="https://gitlab.com/cznic/sqlite/-/issues/177";>https://gitlab.com/cznic/sqlite/-/issues/177</a>)).</li>
   <li>Documentation sweep. <code>openbsd/amd64</code> and 
<code>openbsd/arm64</code> join the supported platforms table in the package 
documentation: both have been in the builder test matrix since January and are 
cross-built by <code>make build_all_targets</code>, but had never been listed. 
The <code>vfs</code> DSN query parameter — which names a VFS registered with 
SQLite, such as one returned by <code>vfs.New</code> — is now documented 
alongside the other DSN parameters on <code>Driver.Open</code>. The &quot;Debug 
and development versions&quot; section no longer describes a 
<code>GO_GENERATE</code> environment variable and a <code>go generate</code> 
that this repository has not had since <code>generator.go</code> moved to 
<code>modernc.org/libsqlite3</code>; it now points at that repository and 
<code>make vendor</code> instead, and the stale <code>//go:generate</code> 
directive naming the removed file is dropped with it. 
<code>modernc.org/sqlite/vec</code> and <code>modernc.o
 rg/sqlite/vfs</code> gained the package doc comments they were missing, so 
both finally carry a synopsis on pkg.go.dev. Documentation only; no behavior 
changes.</li>
   <li>Add <code>NewConnector</code>, returning a 
<code>database/sql/driver.Connector</code> for use with 
<code>sql.OpenDB</code>. It opens the same connections 
<code>sql.Open(&quot;sqlite&quot;, dsn)</code> does, from the same registered 
driver, so every function, collation, connection hook and virtual table module 
registered through this package applies to them. It exists for callers that 
need to interpose on the physical connections <code>database/sql</code> opens — 
tracing, metrics, connection-scoped setup — which <code>sql.Open</code> gives 
no access to: such a caller can embed the returned <code>Connector</code>, 
override <code>Connect</code>, and pass its own wrapper to 
<code>sql.OpenDB</code>. Previously the only way to reach the registered driver 
was the <code>db, _ := sql.Open(&quot;sqlite&quot;, &quot;&quot;); drv := 
db.Driver(); db.Close()</code> idiom, which works only because 
<code>sql.Open</code> does not connect and this driver does not implement 
<code>driver.Driv
 erContext</code>; and the only way to get a wrapper into a 
<code>*sql.DB</code> was <code>sql.Register</code>, which is process-global, 
panics on a name it has already seen, and cannot be undone, so a library had to 
invent a unique driver name per configuration. <code>sql.OpenDB</code> 
registers nothing. Constructing a <code>&amp;sqlite.Driver{}</code> is not an 
alternative — its fields are unexported, so it carries none of the 
registrations. <code>NewConnector</code> checks the DSN only as far as it can 
without opening a database — a query string that does not parse, and 
conflicting <code>vfs</code> parameters; everything else continues to be 
validated when the connection is opened, so an unknown parameter or an 
out-of-range value is reported by <code>Connect</code> rather than at 
construction. Nothing about the existing <code>sql.Open</code> path changes: 
<code>*Driver</code> deliberately still does not implement 
<code>driver.DriverContext</code>, so <code>sql.Open</code> rema
 ins lazy and DSN errors continue to surface where they always have. A runnable 
sample is in <code>examples/connector</code>. Resolves [GitLab issue <a 
href="https://gitlab.com/cznic/sqlite/issues/253";>#253</a>](<a 
href="https://gitlab.com/cznic/sqlite/-/issues/253";>https://gitlab.com/cznic/sqlite/-/issues/253</a>),
 thanks Alessandro Segala (<a 
href="https://github.com/ItalyPaleAle";><code>@​ItalyPaleAle</code></a>)!</li>
   <li>Document that a caller-constructed <code>sqlite.Driver</code> is not the 
driver this package registers as <code>&quot;sqlite&quot;</code>. Its fields 
are unexported, so it starts with no functions, collations or connection hooks 
and the only way to give it any is its own <code>RegisterConnectionHook</code> 
method; the package-level <code>Register*</code> functions always apply to the 
registered driver. Connections such a <code>Driver</code> opens therefore run 
without the package-level functions and collations — and because a registered 
function silently replaces a SQLite built-in of the same name, a 
<code>Driver</code> you construct can evaluate <code>upper(x)</code>, 
<code>date(x)</code> and the like differently from one opened through 
<code>sql.Open</code>. Virtual table modules are the one exception: they are 
held process-globally and reach every <code>Driver</code>. Constructing one 
remains supported for the private-hook pattern — a driver registered under a 
name of i
 ts own with <code>sql.Register</code> so its connection hooks apply only to 
its own connections — and is otherwise best avoided in favour of 
<code>sql.Open</code> or <code>NewConnector</code>. Documentation only; no 
behavior changes.</li>
   </ul>
   </li>
   <li>
   <p>2026-07-20 v1.55.0:</p>
   <ul>
   <li>Add <code>github.com/mattn/go-sqlite3</code>-compatible shorthand DSN 
query parameters to ease migration from that driver: 
<code>_busy_timeout</code>/<code>_timeout</code>, 
<code>_foreign_keys</code>/<code>_fk</code>, 
<code>_journal_mode</code>/<code>_journal</code>, 
<code>_synchronous</code>/<code>_sync</code>, 
<code>_auto_vacuum</code>/<code>_vacuum</code>, and <code>_query_only</code>, 
each setting the correspondingly named PRAGMA. Values are validated against the 
same set <code>mattn/go-sqlite3</code> accepts (case-insensitive) and an 
unrecognized value fails the connection with an error, so a typo such as 
<code>_synchronous=fu1l</code> or <code>_foreign_keys=yes_please</code> is 
reported rather than silently downgrading durability or dropping foreign-key 
enforcement. The keys are applied in a fixed order independent of their order 
in the DSN — <code>_busy_timeout</code> and <code>_auto_vacuum</code> before 
any <code>_pragma</code> values (<code>auto_vacuum</code> must b
 e set before the database is first written), the rest after, and 
<code>_query_only</code> last — and where a key and its alias are both supplied 
the alias wins, matching <code>mattn/go-sqlite3</code>; selection is by 
presence rather than by value, so supplying the alias empty 
(<code>_foreign_keys=on&amp;_fk=</code>) suppresses the PRAGMA rather than 
deferring to the primary key, again matching that driver. Behavior change to 
note: prior releases ignored these keys entirely, so a DSN carried over from a 
<code>mattn/go-sqlite3</code> setup changes in two ways. A recognized key that 
previously did nothing now takes effect — <code>_foreign_keys=on</code> begins 
enforcing constraints against data that may already violate them, 
<code>_journal_mode=wal</code> persistently converts the database file, and 
<code>_query_only=1</code> makes the connection read-only. And a value outside 
the accepted set now fails the connection with an error where the same DSN 
previously opened successfully 
 — for example a duration-style <code>_busy_timeout=5s</code> or 
<code>_timeout=5000ms</code>, neither of which is the integer that key 
requires. Review such DSNs before upgrading. <code>_pragma</code> is unchanged 
and no pre-existing parameter changes meaning, though see the following entry 
for a change in when all of them are validated.</li>
   <li>See [GitLab merge request <a 
href="https://gitlab.com/cznic/sqlite/issues/134";>#134</a>](<a 
href="https://gitlab.com/cznic/sqlite/-/merge_requests/134";>https://gitlab.com/cznic/sqlite/-/merge_requests/134</a>),
 thanks Toni Spets (<a 
href="https://github.com/beeper-hifi";><code>@​beeper-hifi</code></a>) and Ian 
Chechin!</li>
   <li>Validate every DSN query parameter before applying any of them. 
Parameters were previously checked as each was reached, so a DSN whose later 
parameter was rejected had already executed the PRAGMAs ahead of it. Because 
<code>PRAGMA journal_mode</code> and <code>PRAGMA auto_vacuum</code> are 
persistent changes to the database file, a DSN such as 
<code>file:x.db?_journal_mode=wal&amp;_synchronous=bogus</code> failed the 
connection and yet left <code>x.db</code> converted to WAL. A failed 
<code>Open</code> now leaves the database as it found it. This covers the 
pre-existing <code>_txlock</code>, <code>_timezone</code>, 
<code>_time_format</code>, <code>_time_integer_format</code>, 
<code>_inttotime</code> and <code>_texttotime</code> parameters as well as the 
shorthand keys above: all of them were validated only after the 
<code>_pragma</code> list had already run, so the same DSN shape — a valid 
<code>_pragma=journal_mode=wal</code> alongside a misspelled 
<code>_txlock</code> — 
 converted the file before reporting the error. Only the values accepted for 
each parameter are unchanged; a DSN that opened successfully before still 
opens, and one that failed still fails with the same error. 
<code>_pragma</code> remains the sole exception, since its values are executed 
verbatim and cannot be checked in advance: a malformed <code>_pragma</code> is 
still rejected by SQLite as it runs, after any earlier <code>_pragma</code> in 
the list has taken effect.</li>
   </ul>
   </li>
   <li>
   <p>2026-07-15 v1.54.0:</p>
   <ul>
   <li>Upgrade to <a href="https://sqlite.org/releaselog/3_53_3.html";>SQLite 
3.53.3</a>. This also bumps the pinned <code>modernc.org/libc</code> to 
v1.74.1; as always, downstream modules must pin the exact same 
<code>modernc.org/libc</code> version this module's <code>go.mod</code> pins 
(see [GitLab issue <a 
href="https://gitlab.com/cznic/sqlite/issues/177";>#177</a>](<a 
href="https://gitlab.com/cznic/sqlite/-/issues/177";>https://gitlab.com/cznic/sqlite/-/issues/177</a>)).</li>
   <li>Under the opt-in <code>_texttotime</code> DSN parameter, best-effort 
parse date-shaped TEXT values from columns SQLite reports with an empty 
declared type — aggregates and expressions over a date column 
(<code>MAX(d)</code>, <code>COALESCE(d, ...)</code>, <code>upper(d)</code>, 
<code>d || ''</code>), subqueries, and typeless real columns (<code>CREATE 
TABLE t(x)</code>) — into <code>time.Time</code>, instead of delivering them as 
a raw string that <code>Scan</code> cannot store into a 
<code>*time.Time</code>. The existing declared 
<code>DATE</code>/<code>DATETIME</code>/<code>TIME</code>/<code>TIMESTAMP</code>
 path is unchanged; this only adds the empty-decltype case. The conversion is 
strictly best-effort: a value that does not parse as a time falls through to 
the original string, so no <code>Scan</code> that worked before can newly fail. 
<code>ColumnTypeScanType</code> continues to report <code>string</code> for 
empty-decltype columns, since the declared type cannot prov
 e the column is temporal. Without <code>_texttotime</code> the behavior is 
byte-for-byte unchanged. Resolves [GitLab issue <a 
href="https://gitlab.com/cznic/sqlite/issues/248";>#248</a>](<a 
href="https://gitlab.com/cznic/sqlite/-/issues/248";>https://gitlab.com/cznic/sqlite/-/issues/248</a>).</li>
   <li>See [GitLab merge request <a 
href="https://gitlab.com/cznic/sqlite/issues/133";>#133</a>](<a 
href="https://gitlab.com/cznic/sqlite/-/merge_requests/133";>https://gitlab.com/cznic/sqlite/-/merge_requests/133</a>),
 thanks Ian Chechin!</li>
   </ul>
   </li>
   <li>
   <p>2026-06-21 v1.53.0:</p>
   <ul>
   <li>Add <strong>experimental</strong> <code>netbsd/amd64</code> support, 
resolving the long-standing build break in [GitLab issue <a 
href="https://gitlab.com/cznic/sqlite/issues/246";>#246</a>](<a 
href="https://gitlab.com/cznic/sqlite/-/issues/246";>https://gitlab.com/cznic/sqlite/-/issues/246</a>).
 This target is intentionally <strong>not yet listed among the supported 
platforms</strong> in the package documentation: the port had been broken for 
years and is only now revived, and there is as yet no real-world experience 
running it under production workloads. Green CI is not the same as 
battle-tested — so while the full test suite (including the <code>pcache</code> 
and <code>vec</code> packages and the <code>-race</code> concurrency test) 
passes on NetBSD 10.1 / Go 1.26.3, and the entire upstream toolchain 
(<code>libc</code>, <code>cc</code>, <code>ccgo</code>, <code>libz</code>, 
<code>libtcl8.6</code>, <code>libsqlite3</code>, <code>libsqlite_vec</code>) is 
green on the NetBSD CI
  builder, the target is offered for evaluation only. If you run NetBSD, please 
exercise it with your own workloads and report back via <a 
href="https://gitlab.com/cznic/sqlite/issues/246";>#246</a>; the intent is to 
promote it to a fully supported platform after a period of broader real-world 
testing (on the order of a month) elapses without surprises.</li>
   <li>Implementation notes: the previously shipped 
<code>lib/sqlite_netbsd_amd64.go</code> was a stale old-generator transpile 
that no longer compiled (the <code>mu.enter</code>/<code>mu.leave</code> break 
in <a href="https://gitlab.com/cznic/sqlite/issues/246";>#246</a>); it is 
replaced by a fresh new-generator transpile consistent with every other 
platform, and <code>modernc.org/sqlite/vec</code> (sqlite-vec) is vendored and 
auto-registers on netbsd. Correct operation requires the matching pinned 
<code>modernc.org/libc</code>, which carries two NetBSD-specific fixes found 
during this work: the <code>mmap(2)</code> <code>PAD</code>-argument ABI 
(without it, concurrent WAL access faults with SIGBUS in the WAL-index shared 
memory) and a working <code>abort(3)</code> (the prior stub left SQLite's 
crash-recovery <code>writecrash</code> test unable to terminate by signal). As 
usual, downstream modules must pin the exact <code>modernc.org/libc</code> 
version this module's <code>go.mod</co
 de> pins.</li>
   <li>See [GitLab merge request <a 
href="https://gitlab.com/cznic/sqlite/issues/82";>#82</a>](<a 
href="https://gitlab.com/cznic/sqlite/-/merge_requests/82";>https://gitlab.com/cznic/sqlite/-/merge_requests/82</a>),
 thanks Leonardo Taccari (<a 
href="https://github.com/iamleot";><code>@​iamleot</code></a>) and Thomas 
Klausner (@<em>wiz</em>)!</li>
   <li>Add <strong>experimental</strong> <code>freebsd/386</code> and 
<code>freebsd/arm</code> support. As with the <code>netbsd/amd64</code> target 
above, these two 32-bit FreeBSD ports are intentionally <strong>not yet listed 
among the supported platforms</strong> in the package documentation: 
<code>freebsd/386</code> previously shipped a stale, effectively untested 
SQLite 3.41 transpile, and <code>freebsd/arm</code> is entirely new, so neither 
has real-world production mileage yet. Both are now freshly transpiled at 
SQLite 3.53.2 consistent with every other platform, build cleanly, and pass the 
full test suite (core, WAL/concurrency, and the <code>vec</code> package) on 
the FreeBSD CI builders; they are offered for evaluation only. If you run 
32-bit FreeBSD, please exercise these targets with your own workloads and 
report back — the intent is to promote <code>freebsd/386</code>, 
<code>freebsd/arm</code>, and <code>netbsd/amd64</code> to fully supported 
platforms in a future rele
 ase cycle, once a period of broader real-world testing elapses without 
surprises.</li>
   <li>Implementation notes: correct operation on <code>freebsd/arm</code> 
requires the matching pinned <code>modernc.org/libc</code> (v1.73.4), which 
fixes the per-arch <code>mmap(2)</code> <code>off_t</code> encoding for 32-bit 
FreeBSD; without it the WAL shared-memory mapping faults with SIGBUS under 
concurrent access, the same class of bug found on the netbsd port. As usual, 
downstream modules must pin the exact <code>modernc.org/libc</code> version 
this module's <code>go.mod</code> pins.</li>
   <li>See [GitLab merge request <a 
href="https://gitlab.com/cznic/sqlite/issues/119";>#119</a>](<a 
href="https://gitlab.com/cznic/sqlite/-/merge_requests/119";>https://gitlab.com/cznic/sqlite/-/merge_requests/119</a>),
 thanks Olivier Cochard-Labbé (<a 
href="https://github.com/ocochard";><code>@​ocochard</code></a>)!</li>
   <li>Add a Go-facing wrapper for <code>SQLITE_CONFIG_PCACHE2</code>. 
<code>PageCache</code> is the factory and <code>Cache</code> the per-database 
instance, both idiomatic Go interfaces; <code>Page</code> exposes the raw 
<code>Buf</code> and <code>Extra</code> pointers that SQLite reads through the 
C pcache contract. <code>RegisterPageCache</code> and 
<code>MustRegisterPageCache</code> install the module process-globally before 
the first <code>sql.Open</code>; subsequent Open calls are gated through a 
one-shot <code>Xsqlite3_config(SQLITE_CONFIG_PCACHE2)</code> so a too-late 
Register returns <code>ErrPageCacheTooLate</code> rather than silently falling 
through to the built-in pcache1. The binding owns the 
<code>sqlite3_pcache_page</code> stub and re-consults the implementation on 
every Fetch, reusing the stub only when the returned <code>Page</code> value is 
unchanged, which keeps a bounded/evicting purgeable cache safe by 
construction.</li>
   <li>See [GitLab merge request <a 
href="https://gitlab.com/cznic/sqlite/issues/126";>#126</a>](<a 
href="https://gitlab.com/cznic/sqlite/-/merge_requests/126";>https://gitlab.com/cznic/sqlite/-/merge_requests/126</a>),
 thanks Ian Chechin!</li>
   <li>Add <code>modernc.org/sqlite/pcache</code>, the reference page-cache 
implementation that accompanies the <a 
href="https://gitlab.com/cznic/sqlite/issues/126";>#126</a> 
<code>SQLITE_CONFIG_PCACHE2</code> wrapper. <code>pcache.New</code> returns a 
<code>*Pool</code> satisfying the <code>PageCache</code> interface; register it 
once with <code>sqlite.MustRegisterPageCache(pcache.New())</code> and every 
connection opened afterwards draws its pages from it. Each 
<code>Pool.Create</code> mints a fresh per-database <code>Cache</code>: a 
bounded, LRU-evicting page store that honours the <code>PRAGMA 
cache_size</code> soft cap and releases the least-recently-unpinned page when 
it must make room. Page memory — the <code>Buf</code> and <code>Extra</code> 
buffers SQLite reads through — is allocated with 
<code>libc.Xmalloc</code>/<code>libc.Xcalloc</code> and therefore lives off the 
Go heap, which keeps SQLite's interior pointer arithmetic on the page extras 
from tripping the race detect
 or's checkptr enforcement. <code>Pool.Stats</code> reports aggregate lifetime 
counters (hits, misses, allocs, evictions, rekeys, truncates, caches) across 
every cache a Pool has created, so hit/miss/eviction behaviour is observable 
without instrumenting individual caches. Cross-connection page sharing is out 
of scope for now; each <code>Create</code> returns an independent per-database 
cache.</li>
   <li>Validated end-to-end against the <a 
href="https://gitlab.com/cznic/sqlite/issues/126";>#126</a> stress workload 
(<code>cache_size=16</code>, 4000 BLOB rows with DELETE and 
<code>incremental_vacuum</code>, <code>integrity_check</code> clean under 
<code>-race</code>) and benchmarked for the memory-utilization goal tracked in 
[GitLab issue <a href="https://gitlab.com/cznic/sqlite/issues/204";>#204</a>](<a 
href="https://gitlab.com/cznic/sqlite/-/issues/204";>https://gitlab.com/cznic/sqlite/-/issues/204</a>).</li>
   <li>See [GitLab merge request <a 
href="https://gitlab.com/cznic/sqlite/issues/127";>#127</a>](<a 
href="https://gitlab.com/cznic/sqlite/-/merge_requests/127";>https://gitlab.com/cznic/sqlite/-/merge_requests/127</a>),
 thanks Ian Chechin!</li>
   <li>Tighten the <code>modernc.org/sqlite/pcache</code> reference 
implementation per cznic's !127 review follow-ups. Adds 
<code>Stats.EasyRefusals</code>, a per-Pool counter for the cases where 
<code>FetchCreateEasy</code> returns nil at cap; SQLite reacts to a refusal by 
spilling dirty pages and retrying with <code>FetchCreateForce</code>, so the 
new field is a direct proxy for the I/O pressure the strict Easy contract 
imposes vs pcache1's recycle-without-spill behavior. 
<code>BenchmarkPoolEvictionChurn</code> was reworked to drive a 
rotating-residue DELETE (<code>k % 3 = i % 3</code>) and re-insert a matching 
batch each cycle so the spill pressure recurs and <code>easy-refusals/op</code> 
scales with <code>b.N</code> instead of capping at the seed's one-time 
first-cycle cost; both existing benchmarks now report 
<code>easy-refusals/op</code> alongside the page-allocs/evictions metrics. 
<code>Stats.Evictions</code> documentation was tightened to match the actual 
behavior (counts LRU
  eviction, <code>Unpin(discard=true)</code>, <code>Shrink</code> releases, and 
<code>Unpin(discard=false)</code> trimming back to target after a 
<code>FetchCreateForce</code> overcommit; bulk frees from 
<code>Truncate</code>, <code>Rekey</code> collisions, and <code>Destroy</code> 
are not counted). The <code>TestPoolRoundTripIntegrity</code> comment claiming 
the workload exercises <code>xRekey</code> ~15 times has been corrected; the 
SQL surface does not reliably emit xRekey here, and that codepath is covered by 
the unit tests instead.</li>
   <li>See [GitLab merge request <a 
href="https://gitlab.com/cznic/sqlite/issues/130";>#130</a>](<a 
href="https://gitlab.com/cznic/sqlite/-/merge_requests/130";>https://gitlab.com/cznic/sqlite/-/merge_requests/130</a>),
 thanks Ian Chechin!</li>
   <li>Make <code>modernc.org/sqlite/pcache</code> <code>-race</code>-clean 
under SQLite's <code>cache=shared</code> mode. The pool already runs correctly 
under shared-cache because every callback into a given <code>Cache</code> is 
serialised internally by SQLite's <code>sqlite3BtreeEnter</code> on the 
<code>BtShared</code> mutex; verified empirically with a lock-free in-flight 
probe (max-in-flight = 1 on the canonical two-connection workload, 4 on a 
positive control with goroutines hitting the cache directly). However the Go 
race detector does not recognise SQLite's libc mutex as a happens-before edge 
and reports false-positive races on <code>Fetch</code> vs <code>Unpin</code> 
reads/writes of the per-cache state, which surfaces as <code>DATA RACE</code> 
failures for any user who registers the pool and runs their suite under 
<code>-race</code>. A <code>sync.Mutex</code> on the <code>cache</code> type is 
now taken on every public method (<code>SetSize</code>, <code>PageCount</code>, 
<
 code>Fetch</code>, <code>Unpin</code>, <code>Rekey</code>, 
<code>Truncate</code>, <code>Destroy</code>, <code>Shrink</code>), always. On 
the common non-shared-cache path the lock is uncontended (one atomic CAS per 
Lock/Unlock pair, negligible next to the SQLite work it bookends); on the 
shared-cache path it just rubber-stamps the order SQLite's 
<code>BtShared</code> mutex already established. A new <code>e2e_test.go</code> 
<code>TestSharedCacheTwoConns_Integrity</code> drives two <code>sql.Conn</code> 
against the same <code>cache=shared</code> URI with concurrent writers and 
asserts <code>PRAGMA integrity_check = ok</code> under <code>-race</code>; 
passes cleanly with the lock, would surface the false-positive without it. 
Design notes live in <code>pcache/sharing.go</code>.</li>
   <li>See [GitLab merge request <a 
href="https://gitlab.com/cznic/sqlite/issues/131";>#131</a>](<a 
href="https://gitlab.com/cznic/sqlite/-/merge_requests/131";>https://gitlab.com/cznic/sqlite/-/merge_requests/131</a>),
 thanks Ian Chechin!</li>
   <li>Add a Go wrapper for <code>sqlite3_db_status</code>, the per-connection 
runtime counters (cache hit/miss/write/spill rates, schema and 
prepared-statement memory, lookaside usage, deferred foreign keys). 
<code>DBStatus</code> is an interface implemented by the driver connection and 
reached through the <code>database/sql</code> escape hatch 
<code>(*sql.Conn).Raw()</code>, mirroring the existing <code>FileControl</code> 
surface; <code>DBStatusOp</code> is a distinct typed enum of the 
<code>SQLITE_DBSTATUS_*</code> verbs so a counter from a different op family 
will not compile in its place. <code>Status(op, reset)</code> returns the 
<code>(current, high)</code> pair and optionally resets the counter. This also 
lets <code>modernc.org/sqlite/pcache</code> measure real I/O instead of the 
<code>EasyRefusals</code> proxy: the new <code>BenchmarkPoolSpillIO</code> 
reads the pager-level 
<code>SQLITE_DBSTATUS_CACHE_SPILL</code>/<code>_CACHE_WRITE</code> counters, 
which the pager maintains
  identically for pcache1 and the pool, making the pcache1-vs-pool comparison 
cznic raised on the !127 review a genuine apples-to-apples measurement. On the 
rotating-residue eviction-churn workload at <code>cache_size=16</code> the pool 
spills ~3.5x more than pcache1 (cache-spill/op 31.96 vs 8.96) for ~3% more page 
writes (cache-write/op 450 vs 436) at identical hit/miss, quantifying the I/O 
cost of the strict Easy contract that <code>EasyRefusals</code> only 
proxied.</li>
   <li>See [GitLab merge request <a 
href="https://gitlab.com/cznic/sqlite/issues/132";>#132</a>](<a 
href="https://gitlab.com/cznic/sqlite/-/merge_requests/132";>https://gitlab.com/cznic/sqlite/-/merge_requests/132</a>),
 thanks Ian Chechin!</li>
   <li>Add an opt-in <code>_dqs</code> DSN query parameter that disables 
SQLite's double-quoted string literal compatibility quirk on a per-connection 
basis. When <code>_dqs=0</code> (or any <code>strconv.ParseBool</code> false 
value) is supplied, the driver calls <code>sqlite3_db_config</code> with 
<code>SQLITE_DBCONFIG_DQS_DDL</code> and <code>SQLITE_DBCONFIG_DQS_DML</code> 
set to off before any statement is prepared, so a double-quoted identifier that 
fails to resolve raises a parse error instead of silently falling back to a 
string literal. Absence of the parameter, or <code>_dqs=1</code>, leaves 
SQLite's default behavior unchanged; existing DSNs continue to work 
byte-for-byte. Resolves [GitLab issue <a 
href="https://gitlab.com/cznic/sqlite/issues/61";>#61</a>](<a 
href="https://gitlab.com/cznic/sqlite/-/issues/61";>https://gitlab.com/cznic/sqlite/-/issues/61</a>).</li>
   <li>See [GitLab merge request <a 
href="https://gitlab.com/cznic/sqlite/issues/128";>#128</a>](<a 
href="https://gitlab.com/cznic/sqlite/-/merge_requests/128";>https://gitlab.com/cznic/sqlite/-/merge_requests/128</a>),
 thanks Ian Chechin!</li>
   <li>Add an opt-in <code>_error_rc</code> DSN query parameter for clearer 
error reporting on open-time failures. When <code>_error_rc=1</code> (or any 
<code>strconv.ParseBool</code> true value) is supplied, error strings 
synthesised from a <code>(rc, db)</code> pair only append 
<code>sqlite3_errmsg(db)</code> when <code>sqlite3_extended_errcode(db)</code> 
is consistent with the operation rc (full match first, primary code 
<code>&amp;0xff</code> as fallback). On mismatch the canonical 
<code>sqlite3_errstr(rc)</code> is used alone, so an open-time 
<code>SQLITE_CANTOPEN</code> no longer carries the temporary handle's stale 
&quot;out of memory&quot; errmsg. Absence of the parameter, or 
<code>_error_rc=0</code>, preserves the legacy &quot;errstr: errmsg&quot; form 
byte-for-byte; existing callers that parse error strings are unaffected. The 
driver's <code>*Error.Code()</code> returns the same SQLite result code in both 
modes. Parsed before <code>sqlite3_open_v2</code> so open-time errors
  are covered. Resolves [GitLab issue <a 
href="https://gitlab.com/cznic/sqlite/issues/230";>#230</a>](<a 
href="https://gitlab.com/cznic/sqlite/-/issues/230";>https://gitlab.com/cznic/sqlite/-/issues/230</a>).</li>
   <li>See [GitLab merge request <a 
href="https://gitlab.com/cznic/sqlite/issues/129";>#129</a>](<a 
href="https://gitlab.com/cznic/sqlite/-/merge_requests/129";>https://gitlab.com/cznic/sqlite/-/merge_requests/129</a>),
 thanks Ian Chechin!</li>
   </ul>
   </li>
   <li>
   <p>2026-06-06 v1.52.0:</p>
   <ul>
   <li>Upgrade to <a href="https://sqlite.org/releaselog/3_53_2.html";>SQLite 
3.53.2</a>.</li>
   <li>Add <code>Backup.Remaining</code> and <code>Backup.PageCount</code>, 
thin wrappers around the existing <code>sqlite3_backup_remaining</code> and 
<code>sqlite3_backup_pagecount</code> C symbols. Together they expose the 
per-<code>Step</code> progress counters that the underlying backup object 
already maintains, enabling progress reporting during online backups without 
dropping to <code>modernc.org/sqlite/lib</code> directly.</li>
   <li>See [GitLab merge request <a 
href="https://gitlab.com/cznic/sqlite/issues/122";>#122</a>](<a 
href="https://gitlab.com/cznic/sqlite/-/merge_requests/122";>https://gitlab.com/cznic/sqlite/-/merge_requests/122</a>),
 thanks Ian Chechin!</li>
   <li>Drop the redundant second copy in <code>(*conn).columnText</code>, the 
path that backs every <code>Rows.Scan</code> into a Go <code>string</code> for 
a TEXT column. The value's bytes are still copied once out of SQLite-owned 
memory into a fresh Go buffer; that buffer is then reinterpreted as the result 
string with <code>unsafe.String</code> rather than copied a second time by the 
implicit <code>string([]byte)</code> conversion. This removes one allocation 
per TEXT value per row and roughly halves the bytes allocated on that path; on 
the new <code>BenchmarkColumnTextScan</code> cases it is ~13–20% faster for 
payloads of 256 B and larger, with no measurable change for very short strings. 
Purely internal: no API or behavioral change, and the returned string never 
aliases SQLite's buffer.</li>
   <li>See [GitLab merge request <a 
href="https://gitlab.com/cznic/sqlite/issues/123";>#123</a>](<a 
href="https://gitlab.com/cznic/sqlite/-/merge_requests/123";>https://gitlab.com/cznic/sqlite/-/merge_requests/123</a>),
 thanks Ian Chechin!</li>
   <li>Cache each result column's declared type once per result set in 
<code>newRows</code> instead of recomputing it on every row. The TEXT branch of 
<code>Rows.Next</code> calls <code>ColumnTypeDatabaseTypeName</code> for every 
TEXT column on every row (independent of any DSN flag), which previously did a 
<code>libc.GoString</code> + <code>strings.ToUpper</code> each time; that 
lookup is now a single index into a cached, pre-uppercased 
<code>[]string</code>, and <code>ColumnTypeScanType</code> reads the same cache 
and drops its per-call <code>strings.ToLower</code>. The declared type is fixed 
for the lifetime of a prepared statement, so the C round-trip is paid once per 
column rather than once per column per row, removing exactly 1 alloc + 8 B per 
TEXT column per row from the <code>Next</code> hot path. The new 
<code>BenchmarkTextToTimeScan</code> cases show ~7% faster on a 1000-row 
DATETIME SELECT under <code>_texttotime=1</code>. Purely internal: 
<code>ColumnTypeDatabaseTypeName<
 /code> and <code>ColumnTypeScanType</code> return identical values, no API or 
behavioral change.</li>
   </ul>
   </li>
   </ul>
   <!-- raw HTML omitted -->
   </blockquote>
   <p>... (truncated)</p>
   </details>
   <details>
   <summary>Commits</summary>
   <ul>
   <li><a 
href="https://gitlab.com/cznic/sqlite/commit/cfb97341944de3bfa93dd4d7ef30bc921e924229";><code>cfb9734</code></a>
 CHANGELOG.md: document the DSN validation-order change</li>
   <li><a 
href="https://gitlab.com/cznic/sqlite/commit/0895392f927b5ebbd778751764ca25a73757f6ed";><code>0895392</code></a>
 sqlite: validate all DSN parameters before applying any of them</li>
   <li><a 
href="https://gitlab.com/cznic/sqlite/commit/63a57e475f6f0674c9cbc28b96a3c56d9342419c";><code>63a57e4</code></a>
 sqlite: select DSN shorthand aliases by presence, matching mattn (!134 
follow...</li>
   <li><a 
href="https://gitlab.com/cznic/sqlite/commit/d7210fc87cbdbd007f12564c221d9941cbe7e5be";><code>d7210fc</code></a>
 CHANGELOG.md: correct the !134 DSN shorthand-key entry</li>
   <li><a 
href="https://gitlab.com/cznic/sqlite/commit/b31f52124d296ead27daee9e457912139865073e";><code>b31f521</code></a>
 Merge branch 'dsn-compat-keys' into 'master'</li>
   <li><a 
href="https://gitlab.com/cznic/sqlite/commit/266b979e9d3b91e618c81d2462a367b06461fa55";><code>266b979</code></a>
 sqlite: validate mattn-compat DSN keys and fix auto_vacuum apply order</li>
   <li><a 
href="https://gitlab.com/cznic/sqlite/commit/97841221df58eb884ebe4784897345007c001e86";><code>9784122</code></a>
 sqlite: document mattn-compat DSN pragma keys and test them together</li>
   <li><a 
href="https://gitlab.com/cznic/sqlite/commit/5831f4bee87e259531f9cb941bb5a6cc550fd7da";><code>5831f4b</code></a>
 Support more underscore keys in DSN</li>
   <li>See full diff in <a 
href="https://gitlab.com/cznic/sqlite/compare/v1.54.0...v1.55.0";>compare 
view</a></li>
   </ul>
   </details>
   <br />
   
   <details>
   <summary>Most Recent Ignore Conditions Applied to This Pull Request</summary>
   
   | Dependency Name | Ignore Conditions |
   | --- | --- |
   | modernc.org/sqlite | [>= 1.34.a, < 1.35] |
   </details>
   
   
   [![Dependabot compatibility 
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=modernc.org/sqlite&package-manager=go_modules&previous-version=1.54.0&new-version=1.55.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
   
   Dependabot will resolve any conflicts with this PR as long as you don't 
alter it yourself. You can also trigger a rebase manually by commenting 
`@dependabot rebase`.
   
   [//]: # (dependabot-automerge-start)
   [//]: # (dependabot-automerge-end)
   
   ---
   
   <details>
   <summary>Dependabot commands and options</summary>
   <br />
   
   You can trigger Dependabot actions by commenting on this PR:
   - `@dependabot rebase` will rebase this PR
   - `@dependabot recreate` will recreate this PR, overwriting any edits that 
have been made to it
   - `@dependabot show <dependency name> ignore conditions` will show all of 
the ignore conditions of the specified dependency
   - `@dependabot ignore this major version` will close this PR and stop 
Dependabot creating any more for this major version (unless you reopen the PR 
or upgrade to it yourself)
   - `@dependabot ignore this minor version` will close this PR and stop 
Dependabot creating any more for this minor version (unless you reopen the PR 
or upgrade to it yourself)
   - `@dependabot ignore this dependency` will close this PR and stop 
Dependabot creating any more for this dependency (unless you reopen the PR or 
upgrade to it yourself)
   
   
   </details>


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to