Commits on Source 30

  • wsman's avatar
    sqlite: expose defensive mode DSN option · 9e955072
    wsman authored and cznic's avatar cznic committed
    9e955072
  • cznic's avatar
    sqlite: review follow-ups for the _defensive DSN option · 1fb71c49
    cznic authored
    Documentation, one new validation rule, and test coverage on top of wsman's
    GitHub PR #6. No change to what _defensive itself does.
    
    conn.go: the comment above the db_config calls had been generalized to
    "connection-level sqlite3_db_config options are applied before
    applyQueryParams because the SQLite contract requires
    sqlite3_db_config(SQLITE_DBCONFIG_DQS_*) to be set before any statement is
    prepared". That contract is DQS-specific and does not extend to DEFENSIVE,
    which may be toggled at any point in a connection's life; defensive goes
    first because the PRAGMAs that follow must run under the restriction, which
    is a choice, not an API requirement. Restore the DQS comment verbatim on the
    DQS call and give _defensive its own rationale.
    
    sqlite.go: reject _defensive=1 together with _journal_mode=OFF (or
    _journal=OFF). SQLite turns PRAGMA journal_mode=OFF into a no-op that still
    reports success under defensive mode, so the combination previously opened a
    connection in which neither parameter had been honoured and nothing was
    reported. The check sits in the validation phase from v1.55.0, before any
    statement executes, so a rejected DSN still cannot leave the database
    half-configured. _pragma stays the documented exception: _pragma
    =journal_mode(OFF) alongside _defensive=1 runs and is silently ignored by
    SQLite. Only DSNs using _defensive can be affected and that parameter is new,
    so no DSN that opened before changes behavior.
    
    driver.go: expand the _defensive documentation to the depth of its _dqs and
    _error_rc neighbours -- what the mode observably does (writable_schema=ON,
    journal_mode=OFF and schema_version=N become silent no-ops; shadow-table and
    sqlite_dbpage writes error; reads, ordinary virtual table use and VACUUM are
    unaffected), the new _journal_mode conflict, and the two limits the name
    invites callers to overlook: it is a hardening measure rather than a sandbox
    for hostile files (this build has neither SQLITE_TRUSTED_SCHEMA=0 nor
    SQLITE_DQS=0 and there is no authorizer), and it is a property of the
    connection, not of the database file.
    
    defensive_test.go: rename TestUnmodifiedBehaviorIsNotAnADEDefensiveControl,
    whose "ADE" is an acronym from the contributor's downstream and means nothing
    here, to TestDefensiveAbsentOrFalseIsBaseline, and TestUnprotectedPoolIsA
    NegativeControl to TestDefensiveOffPoolIsANegativeControl so every test in
    the file groups under the feature. Add TestDefensiveRejectsJournalModeOff for
    the new rule, TestDefensiveDSNForms for the file: URI shape -- which keeps its
    query string all the way into sqlite3_open_v2, so SQLite parses _defensive too
    and must ignore it -- plus :memory: and shared-cache memory URIs,
    TestDefensiveLeavesOrdinaryUseIntact for the other half of the contract
    (fts5 create/insert/MATCH, foreign keys, VACUUM, integrity_check and every
    other DSN parameter that could collide, with direct fts5 shadow-table and
    sqlite_dbpage writes refused), and TestDefensiveIsPerConnection to pin the
    documented scope. Also adopt the file's `package sqlite // import ...` form.
    
    CHANGELOG.md: document both the parameter and the new conflict rule.
    1fb71c49
  • cznic's avatar
    all_test: tolerate a cgo-less toolchain in the recursive -race check · 198be3c2
    cznic authored
    TestConcurrentGoroutines re-invokes itself under -race and treats anything
    the recursive run prints other than two known "cannot run here" messages as a
    failure. With CGO_ENABLED=0 the go tool refuses with "-race requires cgo;
    enable cgo by setting CGO_ENABLED=1", which matched neither, so the whole
    suite failed on an environment where the check simply cannot run -- and a
    CGo-free driver is a natural thing to build and test with cgo disabled.
    Accept that message alongside the existing two and skip, as the test already
    does for a toolchain without race support and for an unsupported VMA range.
    Nothing changes when cgo is available: the recursive -race run still executes
    and still has to pass.
    
    Found while reviewing GitHub PR #6, whose author hit it in a CGO_ENABLED=0
    lane; unrelated to that change.
    198be3c2
  • cznic's avatar
    GOVERNANCE.md: add Ian Chechin as maintainer · 69cd3ca1
    cznic authored
    Deln0r has had Maintainer rights on the GitLab project since 2026-06-09.
    The file has named only me since it was added in February and predates
    that grant.
    
    Split out of !135, where the hunk was proposed alongside a code change.
    69cd3ca1
  • cznic's avatar
    licensing: ship the sqlite-vec MIT notice, normalize the license names · 15ca5030
    cznic authored
    vec/ has carried the transpiled sqlite-vec sources since v1.47.0, but the
    module shipped only its own BSD-3-Clause LICENSE and the public-domain SQLite
    notice. sqlite-vec is Copyright (c) 2024 Alex Garcia and dual-licensed
    Apache-2.0 OR MIT; modernc.org/libsqlite_vec's generator elects MIT, whose
    terms require the copyright and permission notice to accompany substantial
    portions of the software. 2.8 MB of transpiled vec/ is a substantial portion.
    Attribution was never absent -- vec's package documentation names the
    extension, pins v0.1.9 and links upstream -- but the license text was.
    
    LICENSE-SQLITE_VEC: the notice, byte-identical to LICENSE-MIT in the upstream
    v0.1.9 archive and to the file libsqlite_vec extracts it into.
    
    vendor_libs/main.go: the omission was mechanical -- the tool copied the
    per-target transpiles and nothing else, so a plain cp of the notice would have
    survived only until the next `make vendor`. Copy it alongside the sources it
    belongs to, and treat a missing source as fatal: shipping the code without the
    notice is worse than not vendoring at all.
    
    SQLITE-LICENSE -> LICENSE-SQLITE, contents unchanged. This matches the new file
    beside it and the LICENSE-<upstream> convention the rest of the modernc.org
    repositories follow, but it is not only cosmetic. `go mod vendor` picks the
    metadata files it copies into a downstream vendor/ tree by matching each name
    against a fixed prefix list (cmd/go/internal/modcmd/vendor.go, metaPrefixes)
    that includes LICENSE, so a name merely ending in LICENSE was never propagated.
    Both notices now reach vendored builds, which is where the MIT terms on vec/
    keep applying. Direct links to the old path will break.
    
    vec/patches.go: a License section on the package documentation, so an importer
    of vec sees on pkg.go.dev that this package is under a different license from
    the rest of the module.
    
    Found by an SBOM audit of the published module.
    
    Co-Authored-By: default avatarClaude Opus 5 (1M context) <noreply@anthropic.com>
    15ca5030
  • cznic's avatar
    vendor_libs: handle a deduplicated libsqlite3/libsqlite_vec checkout · 50ee6dd1
    cznic authored
    The vendoring reads one full per-target file at a time from ../libsqlite3 and
    ../libsqlite_vec, which assumes those checkouts ship expanded. They do today,
    but either may adopt the deduplicated layout that modernc.org/wa2c already ships
    (modernc.org/builder's NW autogen; see NW_GENERALIZATION_HANDOFF.md there) — and
    then those per-target files hold only each target's residue, so vendoring them
    would silently drop most of the package.
    
    Detect it instead of remembering it later. srcDir applies undup's own rule
    (base.go or base_g_*.go present means folded) and:
    
      - returns an expanded checkout as is: no copy, no subprocess, exactly the path
        this tool has always taken;
      - copies a deduplicated one to a temp directory and expands it THERE, never in
        place — expanding the sibling would leave that checkout dirty and tempt a
        "restore" that discards whatever else is uncommitted in it. go.mod and go.sum
        travel with the copy because undup resolves each unaliased import's package
        name by running "go list" inside the directory it expands.
    
    The undup pin is passed in from the Makefile, so the repo keeps one version of
    record wherever undup is invoked, and expansion that leaves shared files behind
    is a hard error naming the pin — that is what a version too old for the layout
    looks like.
    
    Also adds -libsqlite3 / -libsqlite_vec flags so this can be exercised against
    scratch copies without touching the real checkouts.
    
    Verified both ways: output byte-identical to the previous binary on today's
    expanded checkouts (38/38 files); and from deduplicated copies of both siblings,
    a complete vendoring whose lib/ and vec/ build for linux/{amd64,s390x},
    darwin/arm64, windows/{amd64,386}, freebsd/386 and netbsd/amd64.
    
    Expect one-time textual churn whenever a sibling does flip: undup reconstructs
    declarations in its own order and recomputes imports, dropping ccgo's
    `var _ = math.Pi` and friends along with the imports they exist to keep. Same
    package, different bytes.
    
    Co-Authored-By: default avatarClaude Opus 5 (1M context) <noreply@anthropic.com>
    50ee6dd1
  • cznic's avatar
    all_test: drop a trailing space gofmt flags · 224fef61
    cznic authored
    TestDBPageVtab's comment about -DSQLITE_ENABLE_DBPAGE_VTAB carried a trailing
    space, which made all_test.go the one hand-written file in the tree that
    gofmt -l reports. Comment text only; nothing else changes.
    
    Noticed by Ian Chechin while preparing GitLab merge request #135, which does
    not touch this file.
    
    Co-Authored-By: default avatarClaude Opus 5 (1M context) <noreply@anthropic.com>
    224fef61
  • cznic's avatar
    all_test: make TestConnectionHook survive -count>1 · 15039fd3
    cznic authored
    The test registered its driver under the fixed name "sqlite_conn_hook_test".
    sql.Register panics on a name it has already seen and offers no way to undo a
    registration, so the second iteration of go test -count=2 took the whole test
    binary down with "sql: Register called twice for driver
    sqlite_conn_hook_test" -- not a failure of the code under test, and it hid
    whatever the remaining iterations would have found.
    
    Derive the name from an atomic counter instead, so each invocation registers
    its own driver, and close the sql.DB the test opens while here: it was leaked
    once per iteration.
    
    Nothing changes for a single run. Ian Chechin's driver_register_test.go in
    GitLab merge request #135 solves the same problem with a uniqueDriverName
    helper; the two can be folded together once that lands.
    
    Co-Authored-By: default avatarClaude Opus 5 (1M context) <noreply@anthropic.com>
    15039fd3
  • Ian Chechin's avatar
    sqlite: let a caller-constructed Driver register its own functions, collations and modules · 20e2e17e
    Ian Chechin authored
    Driver holds four categories of registration state but only connection
    hooks could be put on a constructed one. Functions and collations were
    reachable through the package-level API alone, and modules through the
    package-level driver only, so a constructed Driver was half-built: its
    modules field was written and read through the package-level instance,
    making it process-global state wearing a per-instance field.
    
    This is the additive half of #254, with one narrow, loud exception
    spelled out below:
    
      - registerFunction and registerCollation become methods on *Driver.
        The package-level RegisterFunction, RegisterScalarFunction,
        RegisterDeterministicScalarFunction and RegisterCollationUtf8 keep
        targeting the package-level driver, spelled explicitly now rather
        than by relying on the receiver named d shadowing the package
        variable of the same name. newDriver is renamed defaultDriver,
        since it read...
    20e2e17e
  • Ian Chechin's avatar
    9ed2aad5
  • cznic's avatar
    Merge branch 'driver-registration' into 'master' · 47d0960a
    cznic authored
    sqlite: let a caller-constructed Driver register its own functions, collations and modules
    
    See merge request !135
    47d0960a
  • cznic's avatar
    doc.go, CHANGELOG.md: promote freebsd/386, freebsd/arm and netbsd/amd64 · 6e86ac4a
    cznic authored
    All three shipped as experimental in v1.53.0 and were deliberately left out
    of the supported platforms table until they had accumulated some real-world
    exposure. That period has elapsed: they have been in the builder matrix and
    in build_all_targets since, they pass on this release's commit alongside the
    seventeen platforms already listed, and no open issue reports a defect in any
    of them. The table therefore listed seventeen entries while the module
    shipped, cross-built and tested twenty; it now lists all twenty.
    
    Also set the v1.57.0 CHANGELOG date to the release date, and drop a stale
    claim in lib/hooks_linux_arm64.go that this module is "stuck on libc@v1.55.3"
    -- go.mod has pinned v1.74.4 since v1.56.0. The comment now says what the
    run-time patch is actually for.
    6e86ac4a
  • cznic's avatar
    add Readme Headline · 93f0742e
    cznic authored
    93f0742e
  • cznic's avatar
    add Readme Headline... · bd9dcb65
    cznic authored
    bd9dcb65
  • Nathan Herring's avatar
  • cznic's avatar
    test: add Linux OFD lock regression tests · 9159fa5f
    cznic authored and Nathan Herring's avatar Nathan Herring committed
    9159fa5f
  • cznic's avatar
    update dependencies, make vendor · 3f99e260
    cznic authored
    3f99e260
  • cznic's avatar
    Merge branch 'ofd-lock-test' · 51d26771
    cznic authored
    51d26771
  • cznic's avatar
    sqlite: add the opt-in OFDLocking switch to Linux OFD locks · 5dcac5fb
    cznic authored
    The C side of #255 ships in the
    transpiled SQLite 3.53.4 sources: opt-in, off by default, process-wide,
    frozen at the process's first lock attempt, with a latched POSIX fallback
    on kernels that reject F_OFD_*. This adds the Go-facing half: OFDLocking
    switches the mode (overriding MODERNC_SQLITE_OFD_LOCK) and
    OFDLockingEnabled reports it, with ErrOFDLockingTooLate and
    ErrOFDLockingUnavailable mapping the gate's refusals. The scenario tests
    from merge request !136 now run in a re-executed child process with the
    mode really on (and the both-modes invariants also in the parent's
    inherited mode), TestOFDLockingSetter covers the Go call path end to end
    against /proc/locks, and the other platforms assert the switch reports
    itself unavailable.
    
    Co-Authored-By: default avatarClaude Fable 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01Qsot8zfLpqv4jHfpRgEq94
    5dcac5fb
  • cznic's avatar
  • cznic's avatar
    AUTHORS, CONTRIBUTORS: add Nathan Herring; CHANGELOG.md: credit him by name · 2f7234fc
    cznic authored
    Nathan Herring contributed the Linux OFD lock regression tests in merge
    request !136, part of the v1.58.0 OFD locking work, and asked to be listed
    as "Nathan Herring <nherring@google.com>" in
    #255 (comment 3791205112). Add that line
    to both AUTHORS and CONTRIBUTORS, in sort order, and replace the bare
    @technosloth handle in the v1.58.0 CHANGELOG thanks line with his name.
    
    Co-Authored-By: default avatarClaude Fable 5.1 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_019uwmKNHsMYPZgu32fAcTj6
    2f7234fc
  • cznic's avatar
    CHANGELOG.md: reconstruct the missing entries for v1.38.1 through v1.44.1 and v1.49.1 · 37e55e47
    cznic authored
    Twelve tagged releases had no entry. Each is rebuilt from the git history
    and the merge requests and issues it cites: v1.38.1, v1.38.2, v1.39.0,
    v1.40.0, v1.40.1, v1.41.0, v1.42.0 (retracted), v1.42.1, v1.42.2, v1.43.0,
    v1.44.1 and v1.49.1. A note under the heading marks them as reconstructed
    on 2026-09-05. Existing entries are untouched.
    
    Updates #129
    
    Co-Authored-By: default avatarClaude Fable 5.1 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_018WKdgGnpeHZjAiMLcGacYr
    37e55e47
  • cznic's avatar
    doc.go, README.md: point readers at CHANGELOG.md · 38af5817
    cznic authored
    The package documentation lost its changelog section when the release
    notes moved to CHANGELOG.md on 2026-01-18, and neither the package doc
    nor the README said where they went. Add a short pointer to both.
    
    Updates #129
    
    Co-Authored-By: default avatarClaude Fable 5.1 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_018WKdgGnpeHZjAiMLcGacYr
    38af5817
  • cznic's avatar
    sqlite: pool the FunctionContext handed to UDF and aggregate callbacks · e390a0ca
    cznic authored
    After the []driver.Value pooling of #226, the &FunctionContext{} passed to
    Scalar, Step, WindowInverse, WindowValue and Final was the last driver-side
    heap allocation per invocation: 16 bytes escaping to the heap on every call,
    about 12% of the allocations left in the #226 reproducer.
    
    Fold the context into the pooled per-call object next to the args slice, so
    one sync.Pool Get/Put serves both, and populate its tls and sqlite3_context
    fields per call so accessor methods can be added later without touching the
    trampolines. The vtab Filter and Update paths use the same object with a zero
    context. Document on FunctionContext and on the callbacks that, like the
    argument slice, the context is valid only for the duration of the call.
    
    BenchmarkUDFArgsAllocation: 5756 -> 4756 allocs/op, 70489 -> 54476 B/op;
    BenchmarkUDFArgsAllocationVolatile: 3756 -> 2756 allocs/op, 62481 -> 46464
    B/op; ns/op unchanged within noise. The #226 reproducer: 25.33M -> 22.35M
    allocs/op, 553 -> 505 MB/op.
    
    TestFunctionContextPerCall checks that every callback receives a populated
    context.
    
    Updates #226
    
    Co-Authored-By: default avatarClaude Fable 5.1 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_018WKdgGnpeHZjAiMLcGacYr
    e390a0ca
  • cznic's avatar
    Merge branch 'udf-call-pool' into 'master' · 51cbcbff
    cznic authored
    sqlite: pool the FunctionContext handed to UDF and aggregate callbacks
    
    See merge request !137
    51cbcbff
  • cznic's avatar
    doc.go: add a Performance section with measured driver-vs-C ratios · 59ec397b
    cznic authored
    Prompted by https://github.com/coderage-labs/spillway/issues/162, which
    attributed a 103 s query to this driver spilling a temp B-tree in Go. Running
    that workload here showed no spill (the LIMIT-bounded ephemeral b-tree path
    never touches a temp file) and a CPU cost of about 2x the same C build, the
    103 s being unbounded overlap of periodic polls.
    
    The section records what was measured: CPU time per query on linux/amd64
    against SQLite 3.53.4 compiled with our options, 2.0x/1.9x/1.3x with
    modernc.org/libc v1.75.7 and 3.0x/2.2x/1.6x with the transpiled musl mem*
    routines of earlier libc versions; that the ratios hold under concurrency;
    and the two practical consequences, indexing what ORDER BY/GROUP BY/WHERE
    use and bounding the database/sql pool.
    
    Co-Authored-By: default avatarClaude Fable 5.1 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01PmfDBCBKB4vdyiiG94dXK9
    59ec397b
  • Ian Chechin's avatar
    sqlite: pin the identity and the pooling of the FunctionContext in tests · d6d84a97
    Ian Chechin authored
    !137 hands user callbacks a pooled *FunctionContext. TestFunctionContextPerCall
    checks that the context is populated but not that it is the current
    invocation's: filling it only when zero and never clearing it on release
    passes that test while every later callback sees the first invocation's
    context, and the first accessor to dereference such a context faults in
    sqlite3_context_db_handle.
    
    TestFunctionContextIdentity catches that without dereferencing anything:
    two functions evaluated in one statement must see two different
    sqlite3_context values, and on each of two connections held at the same
    time (so that database/sql cannot hand out one physical connection twice)
    every callback's tls must be the connection's own, taken through Conn.Raw.
    It fails under the mutation above and passes on master.
    
    TestFunctionContextConcurrent runs the same function on eight connections
    held at once from their own goroutines, and TestFunctionContextNested runs
    a function whose body executes a statement invoking another function, so a
    second pooled object is acquired before the first is released; both are
    meant to run under the race detector, which nothing in the suite did for
    the pool before. Counters are atomics and the identity probe is behind a
    mutex, so the tests stay race-free if run in parallel.
    d6d84a97
  • cznic's avatar
    Merge branch 'udf-context-tests' into 'master' · 9ad02acf
    cznic authored
    sqlite: pin the identity and the pooling of the FunctionContext in tests
    
    See merge request !138
    9ad02acf
  • cznic's avatar
    update dependencies, make vendor · 35c446e7
    cznic authored
    Bump modernc.org/libc from v1.75.6 to v1.75.7 and re-vendor lib/ and vec/
    from modernc.org/libsqlite3 v1.14.5 and modernc.org/libsqlite_vec v0.5.0,
    both transpiled against it.
    
    lib/ comes out byte-identical: the 19 SQLite 3.53.4 transpiles did not
    change between libsqlite3 v1.14.4 and v1.14.5, only the libc they link
    against did. vec/ picks up the libsqlite_vec transpiles regenerated with
    cc v4.29.7 and ccgo v4.35.2: unreferenced macro constants added, dropped
    or re-evaluated (CHAR_MAX 255 -> 127 on linux/386, linux/amd64 and
    linux/loong64, CHAR_MIN dropped there), and one bounds check in
    _int8_vec_from_value on darwin spelled -128 and INT8_MAX instead of
    -127-1 and 127. sqlite-vec stays at v0.1.9. The rest of the vec/ diff is
    undup re-folding those constants between the shared files.
    
    make build_all_targets passes for all 20 targets; go test passes on
    linux/amd64, including the pooled FunctionContext and vec tests under the
    race detector.
    
    Co-Authored-By: Claude Fable 5.1...
    35c446e7
  • cznic's avatar
    CHANGELOG.md: document the libc v1.75.7 bump and the Performance section · c96a4e6c
    cznic authored
    Date the pending v1.59.0 section 2026-09-15 and add the two entries it was
    missing: the modernc.org/libc v1.75.7 bump with the re-vendored lib/ and
    vec/, and what the native libc routines do to the driver-vs-C CPU ratios;
    and the Performance section doc.go gained in 59ec397b.
    
    Co-Authored-By: default avatarClaude Fable 5.1 <noreply@anthropic.com>
    c96a4e6c
Loading
Loading