Fix logical error "Inconsistent AST formatting" on a function name containing query parameters#106635
Conversation
20d1f1b to
c02a6b4
Compare
LLVM Coverage Report
Changed lines: Changed C/C++ lines covered by tests: 11/11 (100.00%) | Lost baseline coverage: none · Uncovered code |
|
@groeneai Investigate the test failure and provide a fix. |
|
@nikitamikhaylov investigated. The AST fuzzer hit on Failure: Failing query (full stack in the CI report): SELECT DISTINCT toNullable('2')
GROUP BY toString(
isZeroOrNull(toUInt64OrDefault(9223372036854775807)),
multiIf(
arrayReverseSort(isZeroOrNull, [])[toNullable(65535)],
arrayReverseSort(['00:00:00.000000000'], isZeroOrNull(-9223372036854775808), (SELECT toString(NULL))),
'2020-02-29'
),
NULL
) LIMIT -2147483647The query uses no query parameters and no function-name parsing tricks. The crash site is cond_is_true = !cond_is_null && checkAndGetColumn<ColumnUInt8>(*data_column).getBool(0);The condition column is Cross-PR + master history (CIDB, 180d): the same crash signature (
PR #104591 is purely a setting-handling change; it has zero code path overlap with This PR's diff is parser-only ( Recommendation: treat this AST fuzzer hit as a flaky/chronic finding on this PR's CI, unblock the merge, and track the underlying I will open a separate fix PR for the session: cron:clickhouse-ci-task-worker:20260607-131300 |
|
@groeneai We will wait for you fixing the problem first. |
cfdb589
`FunctionIf::executeForConstAndNullableCondition` aborted with
`Bad cast from type DB::ColumnNothing to DB::ColumnVector<char8_t>`
when the condition column constant-folded to
`ColumnConst(ColumnNullable(ColumnNothing))`, e.g.
SELECT if(arraySort(x -> x, [])[toNullable(1)], 1, 2);
Two interacting issues:
1. `ColumnConst::onlyNull` was `data->isNullAt(0)`, which for
`ColumnNullable(ColumnNothing)` reads `null_map[0]`. Whenever that
byte happens to be `0`, `onlyNull` returned `false` even though no
representable value exists. `ColumnNullable::onlyNull` already
handles this by checking `nested_column->isDummy`, so `ColumnConst`
was inconsistent.
2. `executeForConstAndNullableCondition` then unconditionally
overwrote `cond_is_null` with the inner `Nullable`'s `null_map[0]`,
discarding the correct outer-column value, and proceeded to
`checkAndGetColumn<ColumnUInt8>` on the inner `ColumnNothing`
triggering the bad cast.
This patch:
- Makes `ColumnConst::onlyNull` delegate to `data->onlyNull` so all
callers see `Const(Nullable(Nothing))` and `Const(ColumnNothing)` as
only-null. This matches `ColumnNullable::onlyNull`.
- Tightens the `if.cpp` branch so the inner `null_map[0]` is OR'd into
`cond_is_null` instead of replacing it, and gates the
`getBool`/`checkAndGetColumn<ColumnUInt8>` reads on
`!cond_is_null`.
Surfaced by AST fuzzer STID 1499-483b on PR ClickHouse#106635 (arm_asan_ubsan)
and earlier STID 1499-35af on PR ClickHouse#104591 (amd_debug, 2026-05-13).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Changelog category (leave one):
Changelog entry (a user-readable short description of the changes that goes into CHANGELOG.md):
Fix logical error "Inconsistent AST formatting" on a function name containing query parameters
Closes #106358
Version info
26.6.1.474