fix: preserve SETTINGS clause in PrepareBatch after column list#1923
fix: preserve SETTINGS clause in PrepareBatch after column list#1923polyglotAI-bot wants to merge 2 commits into
Conversation
extractNormalizedInsertQueryAndColumns normalized the INSERT query with a regex that stopped after the optional column list, so a SETTINGS clause placed after the columns (e.g. "INSERT INTO t (a, b) SETTINGS async_insert=1") was silently dropped from the query sent to the server. In the no-column-list form it instead leaked into the extracted table name, breaking the HTTP DESCRIBE TABLE path. Capture a trailing SETTINGS clause and preserve it in the normalized query, stripping it before the table name and columns are extracted. The clause is recognized only when the SETTINGS keyword is followed by a "name = value" assignment, so a table or column merely named "settings" is not misparsed. Fixes: #1919
🤖 Claude reviewFixes #1919: The implementation is correct and the regex is appropriately conservative — the Test coverage is strong:
Blind spots:
Verdict: ✅ Approve Inline comments are attached to the relevant lines. This summary updates in place on re-review. |
There was a problem hiding this comment.
Pull request overview
Fixes a PrepareBatch INSERT normalization bug where an inline SETTINGS ... clause (especially after a column list) could be dropped or misparsed, affecting both native and HTTP batch paths.
Changes:
- Extend INSERT normalization to detect and preserve a trailing
SETTINGS name=value...clause while preventing it from leaking into the extracted table name/columns. - Expand unit coverage for INSERT normalization around
SETTINGSplacement/casing/FORMAT interactions and “settings” identifier contrast cases. - Add an end-to-end regression test (native + HTTP) asserting inline
SETTINGSreaches the server (unknown setting must error).
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
batch.go |
Captures and re-injects a trailing SETTINGS clause into the normalized INSERT query. |
batch_test.go |
Adds table-driven unit cases covering SETTINGS after column lists (and related contrasts). |
tests/issues/1919_test.go |
Adds an integration regression test for issue #1919 across native and HTTP protocols. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…atch A trailing `;` statement terminator on the inline SETTINGS form (e.g. `INSERT INTO t (a, b) SETTINGS async_insert=1;`) was folded into the captured settings clause by the lazy `.+?`, producing a malformed normalized query `... SETTINGS async_insert=1; FORMAT Native` that the server rejects with a syntax error. Match trailing terminators and whitespace with `[\s;]*$` outside the capture group so they are dropped, mirroring how the no-SETTINGS path already strips a trailing `;`. A `;` inside a quoted setting value is preserved (only end-of-query terminators are consumed). Addresses review feedback on #1919.
Description
Fixes #1919.
PrepareBatchnormalizes the INSERT query throughextractNormalizedInsertQueryAndColumns(batch.go). The normalization regex capturesINSERT INTO <table>[(columns)]and stops there, so aSETTINGS ...clause placed after the column list — e.g.INSERT INTO t (a, b) SETTINGS async_insert=1— was silently dropped from the query sent to the server. In the no-column-list form (INSERT INTO t SETTINGS async_insert=1) the settings text instead leaked into the extracted table name, which breaks the HTTP path'sDESCRIBE TABLE <tableName>.The fix captures a trailing
SETTINGSclause and preserves it in the normalized query, stripping it from the query before the table name and columns are extracted so it no longer leaks into either. The clause is recognized only when theSETTINGSkeyword is followed by an actualname = valueassignment, so a table or column merely namedsettingsis not misparsed as a settings clause.Changes
batch.go: addextractInsertSettingsMatchand capture/re-inject theSETTINGSclause inextractNormalizedInsertQueryAndColumns; build the normalized query asINSERT INTO <table>[(cols)] [SETTINGS ...] FORMAT Native.batch_test.go: extend the table-drivenTestExtractNormalizedInsertQueryAndColumnswith cases forSETTINGSafter the column list (incl. trailingVALUES, multiple settings, no column list, lowercase keyword, explicitFORMAT) plus contrast cases proving a table/column namedsettingsis left untouched.tests/issues/1919_test.go: end-to-end regression test over native and HTTP — a valid inlineSETTINGSclause round-trips, and an unknown setting must surface as an error (proving the clause actually reaches the server instead of being dropped).Test
go test -run TestExtractNormalizedInsertQueryAndColumns .andTest1919both fail onmainand pass on this branch. The unit cases assert the exact normalized query / table name / columns;Test1919inserts with a validSETTINGSclause after the column list and then asserts an unknown setting produces an error on both protocols (before the fix the setting was dropped and no error was raised). Existing root-package tests andTestBatch*integration tests still pass with no changes to existing tests.Pre-PR validation gate
main, pass here)SETTINGSclause)AGENTS.md/CONTRIBUTING.md(regression test intests/issues/NNNN_test.go,t.Cleanupfor connections, table-driven cases,gofmtclean)CHANGELOG.mdedit —CONTRIBUTING.mdstates it is generated automatically during release