Fix STID 1941-1bfa: stop mutating call-syntax arrayElement on kql_array_sort_*#106691
Fix STID 1941-1bfa: stop mutating call-syntax arrayElement on kql_array_sort_*#106691groeneai wants to merge 1 commit into
Conversation
…ay_sort_* The bracket subscript on kql_array_sort_asc/desc was implemented in the operator-folding code by an in-place rename of a sibling arrayElement operand to tupleElement. The rewrite also fired against arrayElement nodes built via call syntax (arrayElement(kql_array_sort_*(...), i)), which destroyed the user-built shape and broke the format/parse/format round-trip check executed in debug builds. The original AST stored arrayElement(arrayElement(kql_array_sort_*, i), j) because the inner was constructed by call syntax (is_operator=false). Formatting wrote arrayElement(kql_array_sort_*, i)[j], and the re-parse of that string went through this same code path and renamed the inner to tupleElement. The resulting AST had a different tree hash than the original and executeQueryImpl raised LOGICAL_ERROR 'Inconsistent AST formatting (STID: 1941-1bfa)' across many BuzzHouse runs (issue ClickHouse#105396). Restrict the inner rewrite to siblings whose is_operator flag is set. Operator-syntax kql_array_sort_*(...)[i][j] still folds to arrayElement(tupleElement(kql, i), j), but call-syntax shapes are kept verbatim and survive the round-trip; the type checker reports the semantic mismatch instead of an internal LOGICAL_ERROR. Closes: ClickHouse#105396 Reproducer (debug build): SELECT 1 WHERE (arrayElement(kql_array_sort_asc([(1, 2)]), 1)[2]).1 = 1 Pre-fix raises LOGICAL_ERROR 'Inconsistent AST formatting (STID: 1941-1bfa)'. Post-fix raises ILLEGAL_TYPE_OF_ARGUMENT (the round-trip check passes; the call-syntax arrayElement applied to a Tuple is correctly rejected by type analysis). Latest CI report: https://s3.amazonaws.com/clickhouse-test-reports/json.html?PR=91164&sha=1102a6dbcb0f2cd3788e5c04bbdc1b1a78b76121&name_0=PR&name_1=BuzzHouse%20%28amd_debug%29 Related: ClickHouse#91164 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
cc @evillique @alexey-milovidov — could you review this? It fixes the chronic STID 1941-1bfa AST round-trip failure where the kql_array_sort subscript hack in ParserExpression in-place renamed an existing call-syntax |
|
Workflow [PR], commit [b76c782] Summary: ❌
AI ReviewSummaryThis PR narrows the Final VerdictStatus: ✅ Approve |
LLVM Coverage Report
Changed lines: Changed C/C++ lines covered by tests: 11/11 (100.00%) | Lost baseline coverage (was covered on master, now uncovered in this PR): 1 line(s) · Uncovered code |
CI Ledger — covered SHA: b76c782CI fully finished. Two job-level failures; neither is PR-caused. Both surface chronic trunk issues with existing tracking.
All other 141 checks pass (Style, Fast, Builds, all FT shards, all stress, IT, Unit, Bugfix validation, Upgrade, Compatibility, Smoke). cron:our-pr-ci-monitor:20260608-033000 |

The bracket subscript on
kql_array_sort_asc/kql_array_sort_descwas implemented by an in-place rename of a siblingarrayElementoperand totupleElementinside the operator-folding code inParserExpression. The rewrite also fired againstarrayElementnodes built via call syntax (arrayElement(kql_array_sort_*(...), i)), which destroyed the user-built AST and broke the format/parse/format round-trip check executed in debug builds.The original AST stored
arrayElement(arrayElement(kql_array_sort_*, i), j)because the inner was constructed by call syntax (is_operator = false). Formatting wrotearrayElement(kql_array_sort_*, i)[j], and the re-parse of that string went through the same code path and renamed the inner totupleElement. The resulting AST had a different tree hash than the original andexecuteQueryImplraisedLOGICAL_ERRORInconsistent AST formatting (STID: 1941-1bfa)across many BuzzHouse runs.The fix restricts the inner rewrite to siblings whose
is_operatorflag is set. Operator-syntaxkql_array_sort_*(...)[i][j]still folds toarrayElement(tupleElement(kql, i), j). Call-syntax shapes are kept verbatim and survive the round-trip; the type checker reports the semantic mismatch instead of an internalLOGICAL_ERROR.Reproducer (debug build):
Pre-fix raises
LOGICAL_ERRORInconsistent AST formatting (STID: 1941-1bfa). Post-fix raisesILLEGAL_TYPE_OF_ARGUMENT(the round-trip check passes; the call-syntaxarrayElementapplied to a Tuple is correctly rejected by type analysis).Closes: #105396
Related: #91164
Latest CI report: https://s3.amazonaws.com/clickhouse-test-reports/json.html?PR=91164&sha=1102a6dbcb0f2cd3788e5c04bbdc1b1a78b76121&name_0=PR&name_1=BuzzHouse%20%28amd_debug%29
Changelog category (leave one):
Changelog entry (a user-readable short description of the changes that goes into CHANGELOG.md):
Fix a server-side
LOGICAL_ERRORInconsistent AST formatting: ... (STID: 1941-1bfa)raised by the AST round-trip check in debug builds when anarrayElement(kql_array_sort_asc(...), i)orarrayElement(kql_array_sort_desc(...), i)was constructed via call syntax and a further[j]was applied. The parser no longer destructively renames a call-syntax siblingarrayElement, preserving the user-supplied shape across format/parse/format.Documentation entry for user-facing changes