Closed ncruces closed 1 month ago
See #126.
sqlite3_trace_v2
is half done, and looking good enough for closure notification: it's called just before the connection being closed (which allows running PRAGMA optimize
on closure, etc).
Need to work on deduping the *sqlite.Stmt
pointers.
PS: There's an additional challenge. Statements we Exec
also get a "native" prepared statement, but those are "finalized" immediately after the Exec
ends. Deduping those (and the SQL string) to make them traceable, and avoid a bunch of memory churn is complicated; not sure it's feasible.
sqlite3_trace_v2 is half done, and looking good enough for closure notification: it's called just before the connection being closed (which allows running PRAGMA optimize on closure, etc).
Taking a bit of creative license with how trace is used works for me :smile:. The only thing I'm wondering is if people will take exception to it because trace sounds like something that has the potential for performance impact.
This is pretty much wrapped up now.
Documenting decisions.
I decided that only statements explicitly prepared from Go will be traced. This is unlike SQLite, but it is the only way to make pointer identity/equality work, as long as Go does not have weak references. Traces about statements that weren't prepared from Go are simply ignored (this means Exec
ed statements, but also statements executed by native virtual tables, like FTS5).
So far, I haven't exposed sqlite3_next_stmt
(I'd rather expose a Go 1.23 sequence of statements), nor sqlite3_sql
(I'd probably rather keep the Go string around than rematerialize it every time), nor sqlite3_expanded_sql
. Right now, TRACE_STMT
allocs a copy of the SQL string every time.
Until Go has some form of interning (for strings, and objects) or weak references, which both seem unlikely (package unique
is no replacement) this is unlikely to change. The only alternative I see is to make sqlite3.Stmt
a value, not a pointer, but that's bad too (because Close
clears the handle).
Will wrap these before the next release.
These should be easy:
sqlite3_db_cacheflush
sqlite3_db_status
sqlite3_value_frombind
sqlite3_table_column_metadata
sqlite3_trace_v2
raises interesting questions. It'd be a second "constructor" for*sqlite3.Stmt
, which raises the question of pointer identity. If we want two*sqlite3.Stmt
to be equal, we need to dedup them, which means storing a list of them in*sqlite3.Conn
(which incidentally SQLite also does). We'd also probably need identity, to make it easier to trace the start/row/end moments of a*sqlite3.Stmt
run.If we do this, we can also iterate over statements in a connection (replacing
sqlite3_next_stmt
), andsqlite3_sql
andsqlite3_expanded_sql
can also start to make sense.These are also done:
sqlite3_sql
sqlite3_expanded_sql
sqlite3_next_stmt
sqlite3_trace_v2