-
Notifications
You must be signed in to change notification settings - Fork 0
⚡ Bolt: Optimize row scanning and query execution allocations #95
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -975,11 +975,10 @@ func (q *SelectQuery) compileExists() (compiledQuery, error) { | |
| } | ||
|
|
||
| func wrapExistsCompiled(compiled compiledQuery) (compiledQuery, error) { | ||
| existsQuery := compiledQuery{ | ||
| sql: "SELECT EXISTS(" + compiled.sql + ")", | ||
| argPlan: make([]compiledArg, len(compiled.argPlan)), | ||
| hasNames: compiled.hasNames, | ||
| } | ||
| copy(existsQuery.argPlan, compiled.argPlan) | ||
| return existsQuery, nil | ||
| // NOTE: This shallow copies the input compiledQuery and wraps the SQL. | ||
| // The argPlan and args slices are shared with the original. This is safe | ||
| // because compileExists (the only caller) does not use the original after | ||
| // this call. | ||
| compiled.sql = "SELECT EXISTS(" + compiled.sql + ")" | ||
| return compiled, nil | ||
|
Comment on lines
977
to
+983
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The previous Prompt To Fix With AIThis is a comment left during a code review.
Path: pkg/rain/query_select.go
Line: 977-979
Comment:
**Silent slice aliasing after removing explicit argPlan copy**
The previous `wrapExistsCompiled` made an explicit deep copy of `argPlan` so that the returned `compiledQuery` had no shared mutable state with its source. The new code mutates and returns a value-type copy, meaning `argPlan` and `args` are still backed by the same arrays as the `compiled` passed in. In the one call site (`compileExists`), `compiled` is a local that immediately goes out of scope, so there is no live aliasing today. But the function signature accepts any `compiledQuery` by value, and a future caller that retains the original `compiled` alongside the returned exists-variant would silently share mutable slice state between the two. A comment documenting the ownership assumption (caller must not use the original after this call) would prevent a subtle future regression.
How can I resolve this? If you propose a fix, please make it concise. |
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
literalArgs()and the!q.hasNamesbranch ofbind()now returnq.argsdirectly instead of a fresh copy. ForPreparedSelectQuery, thecompiledQueryis stored permanently and reused across many calls — every invocation ofScan,Count, orExistsreceives the same backing array. Today all call sites only read the slice (cache-key hashing, variadic spread toQueryContext), so concurrent reads are safe. However, a future change that modifies the returned slice (e.g., appending a tenant ID or an extra bound value) before passing it to the driver would silently corrupt the prepared query'sargsfor every subsequent call, because the original never creates a defensive copy anymore. The previous code always returned an independent slice, which kept this footgun impossible.Prompt To Fix With AI
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!