Commits on Source 25

  • cznic's avatar
    add CLAUDE.md: guidance for Claude Code in this repo · 34d803d5
    cznic authored
    
    
    Documents the transpilation-based architecture (lib/, vec/, vfs/), the
    fragile modernc.org/libc version coupling, Makefile targets, debug build
    tags, the GitLab-canonical / GitHub-mirror workflow, and the singleton
    Driver registration model.
    
    Co-Authored-By: default avatarClaude Opus 4.7 (1M context) <noreply@anthropic.com>
    34d803d5
  • cznic's avatar
    git add -f .gitignore · be3fdc1e
    cznic authored
    be3fdc1e
  • Ian Chechin's avatar
    add FileControl.FileControlDataVersion wrapper for SQLITE_FCNTL_DATA_VERSION · 9fe88e9a
    Ian Chechin authored and cznic's avatar cznic committed
    Closes #219. Mirrors the existing FileControlPersistWAL pattern: takes
    the schema name, allocates a 4-byte slot via the TLS allocator,
    invokes Xsqlite3_file_control with the SQLITE_FCNTL_DATA_VERSION
    opcode, and returns the resulting uint32.
    
    The returned data version changes whenever the contents of the
    database file change, so the typical caller polls it to invalidate
    application-level caches.
    
    Adds a regression test that opens a fresh file-backed database,
    queries the version, performs a commit on the same connection,
    performs another commit from a separate connection, and asserts the
    version moves both times.
    9fe88e9a
  • cznic's avatar
    Merge branch 'feat/issue-219-fcntl-data-version' into 'master' · 09015fff
    cznic authored
    add FileControl.FileControlDataVersion wrapper for SQLITE_FCNTL_DATA_VERSION (#219)
    
    Closes #219
    
    See merge request !115
    09015fff
  • cznic's avatar
    CHANGELOG.md: document #115 · 569146e1
    cznic authored
    569146e1
  • Ian Chechin's avatar
    add Ian Chechin to AUTHORS and CONTRIBUTORS · 353bd70b
    Ian Chechin authored and cznic's avatar cznic committed
    Following the invitation in !115 review thread.
    353bd70b
  • cznic's avatar
    Merge branch 'chore/add-author-ian-chechin' into 'master' · f8e3a200
    cznic authored
    add Ian Chechin to AUTHORS and CONTRIBUTORS
    
    See merge request !118
    f8e3a200
  • Ian Chechin's avatar
    pool the []driver.Value slice in UDF and vtab callbacks · 9fdf8429
    Ian Chechin authored and cznic's avatar cznic committed
    The []driver.Value slice passed to user-defined-function scalar and
    aggregate callbacks, and to vtab Filter / Insert / Update, was
    allocated fresh on every invocation. For queries that fan out a UDF
    over many rows this is the dominant per-row allocation, identified
    as a hot spot in #226 with profile data showing ~13.5% of allocations
    attributed to functionArgs.
    
    The driver's contract on FunctionImpl.Scalar and
    AggregateFunction.Step / WindowInverse already states the argument
    values are not valid past the return of the user function, so the
    slice itself can be reused safely.
    
    Add a sync.Pool of *[]driver.Value and route the five existing call
    sites through acquireUDFArgs / releaseUDFArgs:
      - funcTrampoline       (scalar UDFs)
      - stepTrampoline       (aggregate Step)
      - inverseTrampoline    (aggregate WindowInverse)
      - vtabFilterTrampoline (vtab Filter)
      - vtabUpdateTrampoline (vtab Insert / Update)
    
    releaseUDFArgs zeroes each entry before returning the slice so any
    heap references held in the previous invocation can be reclaimed.
    
    Benchmark on 1000-row query with a 3-arg noop scalar UDF (Apple M3,
    Go 1.25, -benchtime 3s -count 3):
    
      name                old time/op     new time/op     delta
      UDFArgsAllocation-8 213000 ns/op    205000 ns/op    -4%
    
      name                old alloc/op    new alloc/op    delta
      UDFArgsAllocation-8 118331 B/op     70376 B/op      -40%
    
      name                old allocs/op   new allocs/op   delta
      UDFArgsAllocation-8 6754 allocs/op  5754 allocs/op  -15%
    
    The 1000 saved allocations per iteration match the expected savings:
    one slice header per UDF invocation, times 1000 invocations per query.
    
    Updates #226.
    9fdf8429
  • Ian Chechin's avatar
    vtab: document that Filter/Insert/Update arguments are not valid past return · 4b91273a
    Ian Chechin authored and cznic's avatar cznic committed
    After !114 pools the []driver.Value slice across UDF and vtab callbacks,
    vtab Cursor.Filter and Updater.Insert/Update share the same "not valid
    past return" contract as FunctionImpl.Scalar / AggregateFunction.Step /
    WindowInverse. Document it explicitly so vtab implementations don't
    silently retain references and corrupt later invocations.
    
    Per cznic review on !114.
    4b91273a
  • cznic's avatar
    Merge branch 'fix/issue-226-udfargs-pool' into 'master' · b8af3a22
    cznic authored
    pool the []driver.Value slice in UDF and vtab callbacks (#226)
    
    See merge request !114
    b8af3a22
  • cznic's avatar
    CHANGELOG.md: document #114 · be5154eb
    cznic authored
    
    
    Co-Authored-By: default avatarClaude Opus 4.7 <noreply@anthropic.com>
    be5154eb
  • Ian Chechin's avatar
    keep in-memory connections valid after a context-cancelled query · c1d418e0
    Ian Chechin authored and cznic's avatar cznic committed
    The fix for #198 made (*conn).usable() return false whenever
    sqlite3_is_interrupted reports the connection is interrupted, so
    database/sql discards the connection after a context-cancelled query.
    For file-backed databases that is fine, the data is on disk and a new
    connection re-opens the same database. For in-memory databases the
    connection IS the database, so dropping it loses the entire store -
    re-introducing the regression originally fixed by !74 (issue #196).
    
    Detect at open time whether the database is in-memory by checking the
    output of sqlite3_db_filename and cache the result on the conn.
    usable() short-circuits to true for those connections so the
    post-interrupt one stays in the pool. File-backed connections keep
    the existing behaviour - they are still reported unusable after an
    interrupt.
    
    Adds TestInMemoryDBSurvivesContextCancel with two subtests: one that
    exercises the regression (insert rows, run a pre-cancelled query,
    re-query and assert the rows are still there), and one that asserts
    the file-backed path is still discarded after an explicit
    sqlite3_interrupt.
    
    Closes #196.
    c1d418e0
  • Ian Chechin's avatar
    test issue #196: assert in-memory conn stays usable after interrupt · 1534aee9
    Ian Chechin authored and cznic's avatar cznic committed
    Per cznic's review on !116, the previous in-memory subtest used
    ExecContext with a pre-cancelled context, which short-circuits in
    stmt.exec before Xsqlite3_interrupt is ever called, so the table-still-
    present check passed even without the fix.
    
    Rewrite the subtest to obtain a *conn via db.Conn().Raw(), call
    sqlite3.Xsqlite3_interrupt directly, and assert c.usable() returns true
    (matches the file-backed subtest's shape). Retain the end-to-end
    QueryRow on the shared in-memory cache as a regression sanity check.
    Verified locally that the subtest fails when the c.inMemory short-
    circuit in (*conn).usable() is removed.
    1534aee9
  • cznic's avatar
    Merge branch 'fix/issue-196-inmemory-validator' into 'master' · 5e731534
    cznic authored
    keep in-memory connections valid after a context-cancelled query (#196)
    
    Closes #196
    
    See merge request !116
    5e731534
  • cznic's avatar
    CHANGELOG.md: document #116 · 0b223921
    cznic authored
    
    
    Co-Authored-By: default avatarClaude Opus 4.7 (1M context) <noreply@anthropic.com>
    0b223921
  • Ian Chechin's avatar
    add FunctionImpl.VolatileArgs opt-in for zero-copy TEXT/BLOB args · 905960c9
    Ian Chechin authored and cznic's avatar cznic committed
    Follow-up to !114 (#226). !114 pooled the []driver.Value slice header but
    explicitly left the per-row TEXT/BLOB body copies in place because a
    default-on zero-copy path would silently corrupt user code that retains
    an argument across rows -- undetectable by -race (UDF execution is
    sequential on one goroutine).
    
    This commit adds VolatileArgs bool to FunctionImpl as a strict opt-in.
    When true:
      - TEXT arguments are unsafe.String views into the SQLite-owned
        sqlite3_value_text buffer
      - BLOB arguments are unsafe.Slice views into the sqlite3_value_blob
        buffer
    When false (the default for all existing call sites), behavior is
    byte-for-byte identical to current master.
    
    Plumbing: the flag is captured at registration into small wrapper structs
    keyed in xFuncs.m / xAggregateFactories.m / xAggregateContext.m, so the
    hot path is one extra field read rather than a second map lookup. The
    five trampolines (funcTrampoline, stepTrampoline, inverseTrampoline,
    valueTrampoline, finalTrampoline) are updated for the new makeAggregate
    signature; only the three that materialise arguments forward the flag to
    functionArgs. Vtab Filter/Update are out of scope and pass false
    explicitly.
    
    Safety contract documented in detail on FunctionImpl.VolatileArgs:
    retention rule, deterministic-corruption failure mode invisible to -race,
    safe-copy idioms (strings.Clone / append([]byte(nil), ...)) for
    callbacks that must keep values across rows, and "when in doubt leave it
    off" guidance noting that the non-volatile path is already cheap after
    !114. Matching cross-references added to AggregateFunction.Step and
    WindowInverse docstrings.
    
    Benchmark (darwin/arm64 Apple M3, 3-arg noop UDF, 1000 rows of INTEGER +
    5-char TEXT + 3-byte BLOB):
    
      BenchmarkUDFArgsAllocation-8           208360 ns/op  70368 B/op  5754 allocs/op
      BenchmarkUDFArgsAllocationVolatile-8   182444 ns/op  62371 B/op  3754 allocs/op
    
    The 2000 fewer allocs/op match the 1000 BLOB + 1000 TEXT copies that
    unsafe.Slice / unsafe.String skip. The remaining 3754 allocs are
    upstream of the trampoline.
    
    Tests: TestVolatileArgsScalar exercises the scalar path with TEXT, BLOB,
    empty-string, and NULL-coerced-to-empty-BLOB rows. TestVolatileArgsAggregate
    exercises the Step trampoline path. Both callbacks demonstrate the
    required safe-copy pattern (strings.Clone + append([]byte(nil), ...)).
    Existing UDF + aggregate + vtab tests stay green under -race.
    
    API shape and "explicit opt-in" framing suggested by @cznic in the !114
    review thread.
    905960c9
  • Ian Chechin's avatar
    address review: empty-BLOB shape parity + re-entrancy note · 569614c5
    Ian Chechin authored
    Per @cznic on !120:
    
    1. The volatile branch of functionArgs returned []byte(nil) for empty
       BLOB args, while the non-volatile branch returned make([]byte, 0).
       A user comparing args[i] == nil would see different results depending
       on the flag, which is orthogonal to the volatility contract. Switch
       the volatile branch to make([]byte, 0) so the empty-BLOB shape is
       identical across both modes.
    
    2. Document the within-callback re-entrancy hazard in the VolatileArgs
       docstring: a nested Query/Exec on the same connection during a
       volatile-args callback can cause SQLite to reuse the underlying
       value buffers, so a volatile string/[]byte read before the nested
       call may alias different bytes after it returns. Rare in practice,
       but useful to spell out alongside the cross-row retention rule.
    
    TestVolatileArgsScalar and TestVolatileArgsAggregate stay green.
    569614c5
  • cznic's avatar
    Merge branch 'feat/volatile-args-opt-in' into 'master' · fac1cab2
    cznic authored
    add FunctionImpl.VolatileArgs opt-in for zero-copy TEXT/BLOB args (#226)
    
    See merge request !120
    fac1cab2
  • cznic's avatar
    CHANGELOG.md: document #120 · d808a8f1
    cznic authored
    
    
    Co-Authored-By: default avatarClaude Opus 4.7 (1M context) <noreply@anthropic.com>
    d808a8f1
  • cznic's avatar
  • Ian Chechin's avatar
    extend VolatileArgs opt-in to vtab Filter and Updater Insert/Update · 06e06d50
    Ian Chechin authored
    Follow-up to !120 (#226). !120 added the FunctionImpl.VolatileArgs
    opt-in for zero-copy TEXT/BLOB access on scalar and aggregate UDF
    callbacks but left vtab Filter/Update on the non-volatile path,
    flagged in the MR description as a candidate for a follow-up "if
    there's demand".
    
    This commit extends the same opt-in to:
      - Cursor.Filter (xFilter)
      - Updater.Insert / Updater.Update (xUpdate)
    
    The contract on those callbacks already says "the vals/cols slice and
    its entries are not valid past the return of this method;
    implementations must copy any value they wish to retain", so the API
    surface is unchanged for users who do not opt in; only the
    body-allocation strategy differs when opt-in is set.
    
    Opt-in is exposed as a new optional interface in package vtab:
    
        type VolatileArgsOpter interface {
            VolatileArgs() bool
        }
    
    A Module that implements it and returns true gets zero-copy TEXT/BLOB
    views for every Filter, Insert, and Upd...
    06e06d50
  • cznic's avatar
    Merge branch 'feat/vtab-volatile-args-opt-in' into 'master' · 0d384cb7
    cznic authored
    extend VolatileArgs opt-in to vtab Filter and Updater Insert/Update
    
    See merge request !121
    0d384cb7
  • cznic's avatar
    gofmt -l -s -w vtab/*.go · 827df98d
    cznic authored
    827df98d
  • cznic's avatar
    CHANGELOG.md: document #121 · 41e77be5
    cznic authored
    
    
    Co-Authored-By: default avatarClaude Opus 4.7 (1M context) <noreply@anthropic.com>
    41e77be5
  • cznic's avatar
    CHANGELOG.md: fix release tag · a5f439be
    cznic authored
    a5f439be
Loading
Loading