Commits on Source 42

  • Tedla Brandsema's avatar
    sqlite: expose connection authorizer · 68e698ce
    Tedla Brandsema authored
    68e698ce
  • Tedla Brandsema's avatar
    f0f3429a
  • Ian Chechin's avatar
    attestgen, .gitlab-ci.yml: sign a provenance document for each release tag · 3c60ac53
    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...
    3c60ac53
  • Ian Chechin's avatar
    Makefile, .gitlab-ci.yml: vendor again from the stamped commits before signing · c330a018
    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.
    c330a018
  • Ian Chechin's avatar
    CHANGELOG.md: link merge request !141 · d0b73e03
    Ian Chechin authored
    d0b73e03
  • Ian Chechin's avatar
    Merge remote-tracking branch 'origin/master' into tag-attestation · aa8b1437
    Ian Chechin authored
    # Conflicts:
    #	CHANGELOG.md
    aa8b1437
  • Ian Chechin's avatar
  • r27153733's avatar
    conn.go, driver.go: omit monotonic readings from stored times · a343f6cb
    r27153733 authored
    Keep the legacy wall-clock layout while removing process-local state that cannot survive scanning. A scanned timestamp must match its stored value when rebound in UPDATE and DELETE predicates. Preserve explicit formats and reads of legacy strings.
    
    Fixes #259.
    a343f6cb
  • r27153733's avatar
    conn.go, driver.go: add opt-in time format without monotonic readings · c68e5b25
    r27153733 authored
    Preserve the default time.String output for compatibility. Add string_no_monotonic through the existing layout map and verify default, SQL round-trip, timezone and integer-format behavior. Refs #259.
    c68e5b25
  • cznic's avatar
    Merge branch 'codex/time-monotonic-roundtrip' into 'master' · 85e46b56
    cznic authored
    conn.go, driver.go: add opt-in time format without monotonic readings (#259)
    
    Closes #259
    See merge request !142
    
    Co-Authored-By: default avatarClaude Opus 5.5 <noreply@anthropic.com>
    85e46b56
  • cznic's avatar
    CHANGELOG.md: _time_format=string_no_monotonic; open v1.61.0 · 5204a676
    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: default avatarClaude Opus 5.5 <noreply@anthropic.com>
    5204a676
  • Ian Chechin's avatar
    Merge remote-tracking branch 'origin/master' into tag-attestation · 2a69777f
    Ian Chechin authored
    # Conflicts:
    #	CHANGELOG.md
    2a69777f
  • Ian Chechin's avatar
  • Ian Chechin's avatar
    attestgen: accept the repository URL with .git · 3fcaebad
    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.
    3fcaebad
  • cznic's avatar
    Merge branch 'tag-attestation' into 'master' · 24ace412
    cznic authored
    attestgen, .gitlab-ci.yml: sign a provenance document for each release tag
    
    See merge request !141
    24ace412
  • cznic's avatar
    licensegen: name the module and the error when go mod download fails · 51ddb0b4
    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: default avatarClaude Fable 5.1 <noreply@anthropic.com>
    51ddb0b4
  • cznic's avatar
    Merge branch 'authorizer-api' into 'master' · a4099dee
    cznic authored
    sqlite: expose connection authorizer
    
    Resolves #256
    
    See merge request !139
    
    Co-Authored-By: default avatarClaude Fable 5.1 <noreply@anthropic.com>
    a4099dee
  • cznic's avatar
    conn: forget the pre-update, commit and rollback hooks on Close · 0fc3f90d
    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: default avatarClaude Fable 5.1 <noreply@anthropic.com>
    0fc3f90d
  • Ian Chechin's avatar
    tx, conn: wait for a shared-cache lock in BeginTx, Commit and Rollback, and... · 5856ee87
    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.
    5856ee87
  • Ian Chechin's avatar
    conn: watch the context only while waiting for a shared-cache lock · 75b4e62f
    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.
    75b4e62f
  • cznic's avatar
    Merge branch 'tx-shared-cache-wait' into 'master' · fd378191
    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: default avatarClaude Opus 5.5 <noreply@anthropic.com>
    fd378191
  • Chris Gianelloni's avatar
  • cznic's avatar
    Merge GitHub pull request #9 'fix/context-cancellation' · 4926b7ac
    cznic authored
    fix: preserve cancellation before SQLite execution
    
    See https://github.com/modernc-org/sqlite/pull/9
    
    Co-Authored-By: default avatarClaude Opus 5.5 <noreply@anthropic.com>
    4926b7ac
  • cznic's avatar
    sqlite, conn: keep one cancellation flag per connection · 4eacffe8
    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: default avatarClaude Opus 5.5 <noreply@anthropic.com>
    4eacffe8
  • cznic's avatar
  • cznic's avatar
    update dependencies, make vendor: SQLite 3.54.1, libc v1.79.0 · 44ae8d4c
    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: default avatarClaude Fable 5.1 <noreply@anthropic.com>
    44ae8d4c
  • cznic's avatar
    sqlite, conn, stmt, tx: end a busy_timeout wait when the call's context is done · 4df1ebea
    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...
    4df1ebea
  • cznic's avatar
    attestgen, Makefile, .gitlab-ci.yml: copy vendor.json into the document from the tagged commit · 9a8718ed
    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: default avatarClaude Fable 5.1 <noreply@anthropic.com>
    9a8718ed
  • cznic's avatar
    tx, rows, conn: end the lock waits of Commit, Rows.Next and Rows.Close with the context · b1712029
    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: default avatarClaude Fable 5.1 <noreply@anthropic.com>
    b1712029
  • Ian Chechin's avatar
    vfs/all_test.go: assert the short read itself in TestVFSReadEOF · 16dcd1fd
    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.
    16dcd1fd
  • Ian Chechin's avatar
    THREAT-MODEL.md: the threat model, row by row with its status · 32349542
    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.
    32349542
  • Ian Chechin's avatar
    vfs/patches.go: report the file read-only to SQLite · cf5e7c3a
    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.
    cf5e7c3a
  • Ian Chechin's avatar
  • Ian Chechin's avatar
    CHANGELOG.md: the vfs.New write panic · 67055eb8
    Ian Chechin authored
    67055eb8
  • Ian Chechin's avatar
    THREAT-MODEL.md: a row for the vfs.New write panic · 0ea9fb8e
    Ian Chechin authored
    Found after the sheet was drafted, in the same v1.60.0 code; fixed by merge request !145.
    0ea9fb8e
  • cznic's avatar
    Merge branch 'vfs-readonly-open' into 'master' · 56d80777
    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: default avatarClaude Fable 5.1 <noreply@anthropic.com>
    56d80777
  • cznic's avatar
    Merge branch 'threat-model' into 'master' · 78c3b0ca
    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: default avatarClaude Fable 5.1 <noreply@anthropic.com>
    78c3b0ca
  • cznic's avatar
    vfs: implement xDelete and the write methods SQLite could still reach · 683b7278
    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: default avatarClaude Fable 5.1 <noreply@anthropic.com>
    683b7278
  • Roman's avatar
    stmt.go, reprepare_test.go, AUTHORS, CONTRIBUTORS: stop re-preparing cached statements on each run · 0afd2c84
    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.
    0afd2c84
  • cznic's avatar
    Merge branch 'clear-bindings-reprepare' into 'master' · 519e1d2a
    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: default avatarClaude Fable 5.1 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01LSAmjiAYJDMEs8WahbpBmN
    519e1d2a
  • cznic's avatar
    conn.go, stmt.go, rows.go: unbind only the parameters that point into the driver's buffers · e6990422
    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: default avatarClaude Fable 5.1 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01LSAmjiAYJDMEs8WahbpBmN
    e6990422
  • cznic's avatar
    CHANGELOG.md: v1.61.1 · 014351f1
    cznic authored
    The section header carries the release date.
    
    Co-Authored-By: default avatarClaude Fable 5.1 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01LSAmjiAYJDMEs8WahbpBmN
    014351f1
Loading
Loading