Fix STID 1941-1bfa: reject query parameter substitution as function name#105839
Conversation
|
cc @evillique @george-larionov - could you review this? It is a parser-side fix for the chronic STID 1941-1bfa AST round-trip failure: rejects query parameter substitution as a function name ( |
|
@groeneai rebase on top of the fresh master |
… name The AST fuzzer rediscovered the chronic round-trip failure on PR ClickHouse#100412 and across multiple unrelated PRs (issue ClickHouse#104605). A query parameter substitution in a function-name position, such as `{F:Identifier}(args)` or `{db:Identifier}.tbl.fn(args)`, produced an `ASTFunction` with an empty `name` because `ASTIdentifier::name()` returns the unset `full_name` when `name_parts` contains parameter holes. `ASTFunction::formatImplWithoutAlias` then emitted just `(args)` (skipping the missing name), so re-parsing yielded a different AST (just the parenthesized expression). The round-trip check in `executeQueryImpl` raised `Inconsistent AST formatting: the original AST: (STID: 1941-1bfa)`, which aborts the server in debug builds. The fix rejects such an identifier as a function name at parse time in `getFunctionLayer` with a clear `SYNTAX_ERROR`. Parameter substitutions in column, table, and database positions are not affected. Minimal reproducer: SELECT {FUNC:Identifier}(-1) with `--param_FUNC=abs`. Pre-fix: server aborts with the `STID 1941-1bfa` exception. Post-fix: returns `Function name cannot be empty or a query parameter substitution (SYNTAX_ERROR)`. The new regression test covers the minimal single-part shape, the compound `COLUMNS` matcher shape that the AST fuzzer found on PR ClickHouse#100412, and the `DESCRIBE TABLE` wrapper variant. Sanity checks confirm legitimate parameter usages (column, table, database names) still work. Closes part of ClickHouse#104605 (the empty-function-name subvariant of `STID 1941-1bfa`). Related to PR ClickHouse#100412 (alexey-milovidov directive 2026-05-26T07:31:35Z).
15c715a to
5de9b39
Compare
|
@evillique rebased on current master in 5de9b39 (no conflicts). CI rerunning. |
|
Workflow [PR], commit [5de9b39] Summary: ✅
AI ReviewSummaryThis PR rejects query-parameter placeholders in function-name positions before they can create an empty-name PR Metadata
Final VerdictStatus: Minimum required action: update the changelog category, and adjust the changelog entry if keeping it under |
LLVM Coverage Report
Changed lines: Changed C/C++ lines covered by tests: 6/6 (100.00%) | Lost baseline coverage (was covered on master, now uncovered in this PR): 1 line(s) · Uncovered code |

The AST fuzzer keeps rediscovering the
Inconsistent AST formatting: the original AST: (STID: 1941-1bfa)round-trip failure across unrelated PRs (see #104605). One subvariant: a query parameter substitution placed in a function-name position, e.g.with
--param_FUNC=absaborts the server in debug builds.Root cause:
ParserCompoundIdentifieraccepts{p:Identifier}.tbl.fnas a 3-part identifier with a parameter hole in the first slot.getFunctionLayerthen callsgetIdentifierName(identifier), which returns the unsetASTIdentifier::full_name(empty whenname_partscontains parameter holes). The result is anASTFunctionwithname="".ASTFunction::formatImplWithoutAliasthen skips the name and emits just(args), so re-parsing yields a plain parenthesized expression. The round-trip tree-hash check inexecuteQueryImplraises theSTID 1941-1bfaexception.The fix rejects such an identifier as a function name at parse time in
getFunctionLayerwith a clearSYNTAX_ERROR. Parameter substitutions in column, table, and database positions are unaffected.Pre-fix on the AST fuzzer reproducer:
Post-fix:
The new regression test
04277_stid_1941_1bfa_param_subst_function_name.shcovers:{FUNC:Identifier}(-1){DB:Identifier}.test_table.COLUMNS(if(1, 1, id))that the fuzzer found on AST JSON serialization #100412DESCRIBE TABLE (...)wrapper used in the fuzzer outputIt also checks legitimate parameter usages (column / table / database names) still work and
COLUMNSmatcher unaffected.Related: requested by @alexey-milovidov on #100412 (2026-05-26T07:31:35Z,
STID 1941-1bfadirective). Issue #104605 tracks the umbrella.Pre-PR validation gate (the five questions) posted in a follow-up comment below.
Changelog category (leave one):
Changelog entry (a user-readable short description of the changes that goes into CHANGELOG.md):
Fix a server-aborting
LOGICAL_ERRORInconsistent AST formatting: the original AST: (STID: 1941-1bfa)raised by the AST round-trip check when a query parameter substitution was used in a function-name position, such as{F:Identifier}(args)or{db:Identifier}.tbl.fn(args). Such usages now fail at parse time with a clearSYNTAX_ERROR.Documentation entry for user-facing changes