Loading
Commits on Source 42
-
Tedla Brandsema authored
-
Tedla Brandsema authored
-
Ian Chechin authored
A tag push now starts a pipeline with one job, attest, on a GitLab-hosted runner. It first checks the job's ID token (push trigger, GitLab-hosted runner, this project, the tag, the commit) so that nothing is signed that verification would reject. It then checks that the tag names the commit and that vendor.json matches go.mod and the committed lib/ and vec/, downloads the module from gitlab.com and from proxy.golang.org with sum.golang.org, each into an empty scratch module and cache with none of the runner's Go or git settings, and writes provenance.json only if both downloads agree and the direct one came from that commit. cosign signs it keyless with the pipeline's GitLab identity; attestgen -verify checks the signature and the certificate claims cosign has no GitLab flags for (commit, ref, project ID, push trigger, GitLab-hosted runner); attestgen -publish stores the document and bundle in the generic package registry and links...
-
Ian Chechin authored
make vendor-check deletes every file vendor.json covers, runs the steps it shares with make vendor without the cross-builds, stamps again, and fails unless those files and vendor.json come out as committed. vendor.json may differ only in the Go release it records: the document carries both that and the Go that reproduced the files. The attest job clones the libsqlite3 and libsqlite_vec commits vendor.json names (attestgen -siblings) and runs it before observing or signing, so the stamp is something the pipeline reproduced rather than took on trust. make vendor runs the same commands as before; the shared ones are canned recipes now. The job's image is pinned by digest, since it holds the identity cosign signs with: golang:1.27.1, the toolchain vendor.json records.
-
Ian Chechin authored
-
Ian Chechin authored
# Conflicts: # CHANGELOG.md
-
Ian Chechin authored
-
cznic authored
conn.go, driver.go: add opt-in time format without monotonic readings (#259) Closes #259 See merge request !142 Co-Authored-By:
Claude Opus 5.5 <noreply@anthropic.com>
-
cznic authored
Merge request !142 adds a _time_format value, a new feature, so the pending section is a minor bump on v1.60.1. The number and the date are the maintainer's call at tag time, per HACKING.md. Co-Authored-By:
Claude Opus 5.5 <noreply@anthropic.com>
-
Ian Chechin authored
# Conflicts: # CHANGELOG.md
-
Ian Chechin authored
-
Ian Chechin authored
The direct download's origin is the repository URL as the go-import tag gives it. modernc.org's tag names https://gitlab.com/cznic/sqlite, but GitLab's own tag for a gitlab.com path adds .git, so -observe refused every project reached without a vanity path, such as a test project for rehearsing the job. Both forms name the same repository; anything else is still refused.
-
cznic authored
go mod download -json exits 1 with each failing module's error in its JSON object on stdout and nothing on stderr, so licgen reported only "exit status 1" after the full list of requested modules. Decode the output on failure and print one line per module error, then stderr if there is any, and the requested modules only when both are empty. Co-Authored-By:Claude Fable 5.1 <noreply@anthropic.com>
-
cznic authored
sqlite: expose connection authorizer Resolves #256 See merge request !139 Co-Authored-By:
Claude Fable 5.1 <noreply@anthropic.com>
-
cznic authored
Close removed the authorizer's map entry but left the three hook maps alone, so a closed connection that had registered a hook kept its entry, keyed by a handle value a later connection can reuse. Remove them before the handle is freed, as the authorizer does, and test it. Co-Authored-By:Claude Fable 5.1 <noreply@anthropic.com>
-
Ian Chechin authored
tx, conn: wait for a shared-cache lock in BeginTx, Commit and Rollback, and end such a wait with the context tx.exec ran BEGIN, COMMIT and ROLLBACK through sqlite3_exec, which skips the unlock-notify wait conn.step and conn.prepareV2 do on SQLITE_LOCKED_SHAREDCACHE, so with cache=shared BeginTx failed at once while ExecContext("BEGIN IMMEDIATE") waited. It now prepares and steps its statement like any other, and still reports a statement that ran as a success when the context is done just after, as before. The wait itself ignored the context. interrupt now wakes it, a context done before the wait began is caught through the call's Done channel that interruptOnDone records on the connection, and the woken call cancels its unlock-notify callback before freeing the mutex. Preparing a statement now watches the context as well. Updates #192. -
Ian Chechin authored
As suggested in the review of !143: the connection records the context of the call in progress, set and restored by interruptOnDone and newStmtContext, and retry watches it with context.AfterFunc only while it waits, returning ctx.Err() itself. A context done just before the wait returned "interrupted: not an error (9)" rather than its error, and every prepare with a cancellable context paid for a watcher goroutine; neither happens now. interrupt no longer wakes the wait. PrepareContext and BeginTx with a context already done return its error. COMMIT and ROLLBACK also wait while another connection holds the schema lock, since preparing them checks it; the CHANGELOG says so.
-
cznic authored
tx, conn: wait for a shared-cache lock in BeginTx, Commit and Rollback, and end such a wait with the context Updates #192 See merge request !143 Co-Authored-By:
Claude Opus 5.5 <noreply@anthropic.com>
-
Chris Gianelloni authored
Signed-off-by:Chris Gianelloni <wolf31o2@blinklabs.io>
-
cznic authored
fix: preserve cancellation before SQLite execution See https://github.com/modernc-org/sqlite/pull/9 Co-Authored-By:
Claude Opus 5.5 <noreply@anthropic.com>
-
cznic authored
The progress handler that keeps a cancellation in effect before a statement's first step looked its flag up in a map behind a lock all connections share, written twice per call and read on every callback, so connections running long statements in parallel contended for it: 37% slower than before with 24 goroutines. Give each connection its own flag, stored in a sync.Map on the connection's first call with a context and removed by Close, so the callback's lookup takes no lock; test that a cancellation does not carry over to the next call and that Close forgets the flag. See https://github.com/modernc-org/sqlite/pull/9 Co-Authored-By:
Claude Opus 5.5 <noreply@anthropic.com>
-
cznic authored
See https://github.com/modernc-org/sqlite/pull/9 Co-Authored-By:
Claude Opus 5.5 <noreply@anthropic.com>
-
cznic authored
lib/ is re-vendored from modernc.org/libsqlite3 v1.15.2 (SQLite 3.54.1, ccgo v4.37.0) and vec/ from modernc.org/libsqlite_vec v0.7.0; sqlite-vec stays v0.1.9. go.mod pins modernc.org/libc v1.79.0, golang.org/x/sys v0.49.0 and the current pprof; the indirect requirements follow libc. vendor.json is stamped with the two sibling commits under go1.27.2. Regenerate LICENSE-3RD-PARTY.md, SBOM.md, sbom.cdx.json and sbom.spdx.json, update the SQLite version in doc.go's platform table and in CLAUDE.md, and add the CHANGELOG bullet to the pending v1.61.0 section, re-dated to today. Co-Authored-By:Claude Fable 5.1 <noreply@anthropic.com>
-
cznic authored
SQLite's default busy callback, installed by PRAGMA busy_timeout, sleeps through its retry schedule and never looks at the interrupt flag, so a statement waiting for a lock kept waiting after its context was done and returned the context's error only when the timeout ran out: with busy_timeout 2000 a write with a 100 ms deadline took 2 s. At the start of each call with a context, replace that callback, when it is installed, with the driver's own copy of it: the same delays and the same bound, but the sleep ends and the handler gives up once the context of the call in progress is done. PRAGMA busy_timeout installs the default callback again whenever it runs, so the check repeats per call, at the cost of one pointer comparison when nothing changed. sqlite3_busy_handler clears the timeout the PRAGMA reports, so it is kept. A wait ended this way fails with SQLITE_BUSY inside SQLite; the handler sets the connection's canceled fla...
-
cznic authored
The v1.61.0 attest job failed its own verification. make vendor-check had stamped the working tree's vendor.json again with the image's go1.27.1; its diff check ignores that field, as intended, but attest -observe then read the working tree and recorded that copy, while attest -verify compares the document with the committed vendor.json the proxy serves, which records go1.27.2. The document is specified to carry the maintainer's stamp. -observe now reads vendor.json with git show from the commit the document names, and vendor-check checks the committed vendor.json out again on success, so the tree is left as committed. The attestgen tests commit vendor.json in their fixture and cover a tree stamped with another Go and a commit without the file. VERIFYING.md and the CHANGELOG record that v1.61.0 has no provenance document. Co-Authored-By:Claude Fable 5.1 <noreply@anthropic.com>
-
cznic authored
Commit ran COMMIT with context.Background, so a commit blocked by a reader's SHARED lock in rollback-journal mode waited the full busy_timeout whatever the context given to BeginTx said, and Rows.Next and Rows.Close stepped and finalized without any context: the step that finishes an autocommit INSERT ... RETURNING commits it, and so does finalizing or resetting such a statement after its first row, which is what Row.Scan does for QueryRowContext(ctx, "INSERT ... RETURNING id"). With busy_timeout 2000 each took 2 s past a 100 ms deadline. The transaction keeps the context BeginTx was given and Commit waits with it: database/sql documents that context as in use until the transaction is committed or rolled back, and rolls the transaction back itself when it ends before Commit; a wait ended this way fails the COMMIT, which Commit already answers with a ROLLBACK. The rows keep the query's context and Next and Close wait with it through a new conn.withWaitCtx, which sets the connection's waitCtx and the driver's busy handler for the duration of the step, finalize or reset, and reports a failure once the context is done as the context's error. Only the waits watch the context: a step or a commit that is not waiting for a lock is not interrupted, and a call whose context has no deadline or cancellation is unchanged. Rollback keeps running without a context, as database/sql calls it to clean up once the BeginTx context is done. Resolves #263, thanks SirLouen for the report and the reproducer. Co-Authored-By:
Claude Fable 5.1 <noreply@anthropic.com>
-
Ian Chechin authored
SQLite's VFS contract for a read that runs past the end of the file is the return code SQLITE_IOERR_SHORT_READ and a zeroed unread tail. The three read tests go through SQL, and none of them reaches that branch of vfsRead with an assertion on its result: all three pass when vfsRead returns SQLITE_IOERR_READ there, and when it leaves the tail as it was. TestVFSReadEOF now also calls vfsRead directly for 512 bytes of which the file holds the last 100, and checks the return code, the bytes read and the zeroed tail. Each of the two changes above makes it fail.
-
Ian Chechin authored
The draft of 21 September, brought up to v1.60.0 as the working sheet behind SECURITY.md's scope. Four surfaces: the connection string, the connection lifecycle, the page cache binding and the VFS bridge. Five positions, from who writes the DSN to another user of the same process. Each row names what is supplied, the code it reaches, what goes wrong if that code is wrong, and its status: fixed or documented with the commit, held with where the code keeps it, struck with the reason, out of scope by SECURITY.md, or open with what is missing. Three rows are new, the defects found next to the draft's rows: the interrupt on its own TLS, the vec import that rules out RegisterPageCache, and the 32-bit handle wrap. One row remains open: no fuzz target drives the page cache Truncate and Rekey paths. SECURITY.md and CLAUDE.md point to it.
-
Ian Chechin authored
vfsOpen set its out-flags to int32(os.O_RDONLY), which is 0, while SQLite reads them for SQLITE_OPEN_READONLY, so a database opened through a VFS made by New was writable as far as SQLite knew. vfsio has no xWrite, xTruncate or xSync. An UPDATE failed with SQLITE_NOMEM from the journal open; after PRAGMA journal_mode=OFF the same UPDATE went to the missing xWrite and the process panicked with a nil pointer dereference, from SQL text alone. The out-flags now carry SQLITE_OPEN_READONLY, and every write fails with SQLITE_READONLY. TestVFSWriteRefused runs UPDATE and DELETE with the journal on and off and checks the table afterwards; on the old flags it fails at the first UPDATE with SQLITE_NOMEM. The vfs tests pass under -race, and as GOARCH=386 and amd64 on linux.
-
Ian Chechin authored
-
Ian Chechin authored
-
Ian Chechin authored
Found after the sheet was drafted, in the same v1.60.0 code; fixed by merge request !145.
-
cznic authored
vfs: report files opened through vfs.New as read-only to SQLite CHANGELOG.md: credit the merge request and name the WAL close path the fix also covers. See merge request !145 Co-Authored-By:
Claude Fable 5.1 <noreply@anthropic.com>
-
cznic authored
THREAT-MODEL.md: the driver's threat model; assert the short read in TestVFSReadEOF CHANGELOG.md: credit the merge request. See merge request !146 Co-Authored-By:
Claude Fable 5.1 <noreply@anthropic.com>
-
cznic authored
The sqlite3_vfs that New registers wired the vfsDelete transpiled from vfs.c as its xDelete, a ccgo stub that printed "TODO vfsDelete:475:" and aborted the process, and whose code after the abort would have unlinked the path on the host file system, relative to the working directory. SQLite calls xDelete without consulting the read-only flag that vfsOpen reports since !145, to remove a journal it believes it no longer needs: when PRAGMA journal_mode leaves PERSIST or TRUNCATE, so from SQL text alone, and in hasHotJournal on the first read of a 0-byte database that has a -journal file next to it in the served file system. New now installs vfsDeleteReadOnly, which deletes nothing and fails with SQLITE_IOERR_DELETE; both callers tolerate the failure, so PRAGMA journal_mode reports the new mode and the empty database reads as empty. The io methods table also gets xWrite, xTruncate and xSync, which were nil: SQLite consults the read-only flag before every write path, so they are not expected to run, but a nil method is a crash and a method that fails is an error. xWrite and xTruncate answer SQLITE_READONLY, xSync SQLITE_OK. TestVFSDeleteRefused runs both xDelete callers against decoy files in the working directory and the served journal; TestVFSWALReadOnlyClose covers a path !145 also fixed, closing a WAL database shipped with its -wal file, which checkpointed through the missing xWrite. THREAT-MODEL.md gets the row and the WAL note, and two corrections: the shorthand keys validated before the apply phase include _synchronous and _query_only, and BenchmarkPoolEvictionChurn does reach Rekey through SQL. Found while reviewing !145. Co-Authored-By:
Claude Fable 5.1 <noreply@anthropic.com>
-
Roman authored
Since SQLite 3.54, whereLoopOutputAdjust marks a "col = ?" term of a join or an ORDER BY query as plan-sensitive: rebinding it to or from 0 or 1 should re-prepare the statement. The bind functions apply that rule per value, but sqlite3_clear_bindings expires the statement whenever such a parameter exists. The driver clears the bindings after every execution of a cached statement, so each execution parsed and planned it again, which doubles the cost of a simple join. Unbind each parameter with sqlite3_bind_null instead. It drops the references to the bound buffers just the same and expires the statement only when SQLite means it to. Every caller has already reset the statement, as bind_null requires. Add Roman Khafizianov to AUTHORS and CONTRIBUTORS. Fixes #264.
-
cznic authored
stmt.go, reprepare_test.go: stop re-preparing cached statements on each run CHANGELOG.md gets the entry with the credit. See merge request !147 Co-Authored-By:
Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LSAmjiAYJDMEs8WahbpBmN
-
cznic authored
!147 replaced sqlite3_clear_bindings, which since SQLite 3.54 expires any statement with a plan-sensitive parameter, with sqlite3_bind_null on every parameter after each execution of a cached statement. Two costs remained, measured on the reporter's program and on BenchmarkBindManyParameters: a parameter bound to 0 or 1 still re-prepared the statement on every run, because SQLite treats the change from the NULL the unbinding left to a small integer as a reason to plan again, and the unbinding itself cost about 40 ns per parameter and execution, 30 to 37 percent on a multi-row INSERT with thousands of parameters. bind now records, next to each C buffer it allocates for a text or blob argument, the index of the parameter it bound it to, and clearBindings unbinds only those. Integers, floats and NULLs stay bound: they hold no memory the driver owns, nothing in the driver reads a bound value, and bind refuses to run with an argument missing, so every step follows a full rebind. bind also unbinds what it bound when it fails midway, so no parameter points into a freed buffer. rows carries the list to Close. TestCachedStmtNotRepreparedSmallInt runs the statements of TestCachedStmtNotReprepared with 0 and 1; TestCachedStmtTextUnbound checks through sqlite3_expanded_sql that a text parameter reads NULL after every execution while an integer one keeps its value. Updates #264. Co-Authored-By:
Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LSAmjiAYJDMEs8WahbpBmN
-
cznic authored
The section header carries the release date. Co-Authored-By:
Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LSAmjiAYJDMEs8WahbpBmN