Repository navigation
fix(r2dbc): bound batch resource normalization - #12935
gh-worker-dd-mergequeue-cf854d[bot] merged 4 commits into
Conversation
A Batch reaches beforeQuery once with all its statements. The listener joined them into one string and normalized it on the thread executing the query (usually an I/O event loop). SQLNormalizer's cost grows quadratically with input size, so a batch of thousands of distinct INSERTs with inlined values kept the event loop busy for tens of seconds. Build a batch's resource from its first 10 statements only, as their distinct normalized forms; a batch of same-template statements now gets that one template as its resource. Batch entries use DBQueryInfo.ofStatement so distinct inlined-literal statements don't churn the prepared-statement cache. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e13a030e67
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
More details
The ten-statement cap is applied before batch normalization, so normalization work no longer grows with the number of batch entries. Single-statement resource naming remains unchanged.
🤖 Bits Code Review · Commit e13a030
🟢 Java Benchmark SLOs — All performance SLOs passed
PR vs. master results
Commit: Load and DaCapo benchmarks can be triggered manually in the GitLab pipeline. Results will appear in the Benchmarking Platform UI after completion. |
…cache The first statement of a batch still went through DBQueryInfo's shared prepared-statement cache. With changing inlined values each batch added a new key, which can evict reusable templates. Use ofStatement for all batch entries; single statements keep the cache. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Keep the normalized forms as UTF8BytesString instead of converting each to a String; UTF8BytesString compares by content, so deduplication is unchanged, and String.join accepts CharSequences. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
/merge |

What
Bounds the work R2DBC does to name a
Batchspan. The resource is now built from the batch's first 10 statements, as their distinct normalized forms, instead of normalizing all statements joined together.Why
Fixes #12932. A
BatchreachesTraceProxyExecutionListener.beforeQueryonce with all its statements, on the thread executing the query (usually an I/O event loop). The listener joined them with"; "and normalized the result.SQLNormalizer.normalizecopies the rest of the buffer for each literal it replaces, so its cost grows quadratically with input size. A batch of thousands of distinctINSERTs with inlined values kept the event loop busy for tens of seconds.Measured with
SQLNormalizer.normalizeon joined batches of ~280-characterINSERTstatements:After this change a batch costs at most 10 single-statement normalizations (~16 µs each), whatever its size.
Behavior change
INSERT INTO t (id, name) VALUES (?, ?). Before, the resource was every normalized statement joined together.;, taken from the first 10 statements.DBQueryInfo.ofStatement, so statements with distinct inlined literals don't fill the prepared-statement cache.Testing
R2dbcInstrumentationTest:INSERTresource. This test fails on master, where the resource is the whole joined batch.INSERT/UPDATE/DELETEbatch lists the distinct templates in order.check,muzzle,latestDepTest: all pass.SQLNormalizeritself is still quadratic on very large inputs, which also affects JDBC. That is left for a separate change.🤖 Generated with Claude Code