Conversation
# Conflicts: # test/runtests.jl
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Aggregate callbacks currently serialize, copy, and deserialize the entire accumulator after every row. A callback that appends to a vector therefore does quadratic copying even though its own update is small. This change keeps one owned first-result snapshot per group, then roots later Julia values through the existing function registration. It removes the manually allocated native state buffer and releases roots before final/error callbacks can enter other SQL.
Compatibility: the first callback still receives the original
init, and its result is serialized/deserialized at the existing first boundary. Later intermediate objects are now kept by reference; their Serialization hooks no longer run per row, and references saved by a callback observe later mutations. SQL argument/result conversion and empty-input behavior are unchanged. The existing shared mutable-seed limitation remains documented: use an immutable seed and create fresh mutable state in the first step when groups need independent state.This branch builds on #362's shared database lifecycle lock. It adds no exports, dependencies, public mode, or separate lock. CI now runs for pull requests targeting any branch so this stack receives the same runtime, documentation, and native checks. Push triggers remain unchanged.
Validation:
Matched local in-memory measurements used three alternating-order pairs on each runtime, seven warmed samples per process, and independent result oracles. At 4,096 rows:
The fixed cost is about 44–45 extra Julia bytes per one-row group (holder plus periodic dictionary rehashing), and 336/352 extra bytes per registration. For 4,096 one-row groups, allocation rises 1.98%/1.37%; current timings ranged from 0.97× to 1.13× baseline speed. Four-row groups were 2.37×/2.64× faster with substantially fewer allocations. Empty queries retain their allocation counts; current empty scalar timing changed 0.822→0.874 µs, minimum 0.891→0.878 µs. First-query compilation allocation did not materially increase in the retained controls. An unrelated Julia process remained active, so these are bounded local measurements, not general throughput claims.
Native limitation: registered aggregate callbacks still do not pass safe trimming. The identical fixed-aggregate probe reports 54 verifier diagnostics on the base and 57 on this branch, involving dynamic callback/Serialization state. This is not an improvement to callback trimming. SQLite also still owns/allocates the native aggregate context; only the manually managed state buffer is removed.
Hosted validation: all seven runtime, documentation, and native checks are green at
b352ce6dc2325fec916bbf66557c86564e82eb5c.Co-authored by Codex