ClickHouse / ClickHouse/ClickHouse
A column defined as ALIAS/DEFAULT/MATERIALIZED with a bare IN table expression is accepted at CREATE, then every read throws a Not-ready Set logical error and a mutation referencing it wedges permanently
- Dominant language
- C++
- Stars
- 49.9k
- Forks
- 9k
- Avg merge
- 21h 32m
- Merged PRs (30d)
- 515
Description
**Describe what's wrong**
A column definition whose expression is a bare `IN ` membership test — `flag UInt8 ALIAS p IN keys`, or the same with `DEFAULT`/`MATERIALIZED` — is accepted at CREATE time (a bare table identifier is not a subquery node, so the no-subqueries-in-column-defaults validation passes it), but every consumer of the definition then fails with a logical error at pure default settings, because the set for the expanded `in` is never scheduled for building:
```sql
CREATE TABLE keys (p UInt8) ENGINE = MergeTree ORDER BY p;
INSERT INTO keys VALUES (1);
CREATE TABLE t (p UInt8, x UInt64, flag UInt8 ALIAS p IN keys) ENGINE = MergeTree ORDER BY x;
INSERT INTO t (p, x) VALUES (1, 1), (2, 2);
SELECT p FROM t WHERE flag; -- Code: 49. DB::Exception: Not-ready Set is passed as the second
-- argument for function 'in' ... (LOGICAL_ERROR)
SELECT flag FROM t; -- same exception on a plain read of the column
```
The direct spelling `SELECT p FROM t WHERE p IN keys` works correctly, and the same queries return the correct result with `enable_analyzer = 0`.
Mutations referencing the column are accepted and then wedge permanently. On `MergeTree`, `ALTER TABLE t DELETE WHERE flag` with `mutations_sync = 1` throws `Code: 341 ... Exception happened during execution of mutation ... Not-ready Set is passed as the second argument for function 'in' ... (LOGICAL_ERROR)`. On `ReplicatedMergeTree` the mutation entry is committed, `is_done` stays 0, and `system.mutations.latest_fail_reason` shows the same logical error in a permanent retry loop until the mutation is killed manually. The `DEFAULT` variant fails on `INSERT` itself:
```sql
CREATE TABLE td (p UInt8, f UInt8 DEFAULT p IN keys) ENGINE = MergeTree ORDER BY p;
INSERT INTO td (p) VALUES (1), (2); -- same Not-ready Set logical error
```
One more consequence worth noting for the `ReplicatedMergeTree` case: before wedging, the mutation goes through partition pruning, and the block numbers recorded for it cover only the partitions matching the submission-time contents of `keys` (observed `block_numbers.partition_id = ['1']` on a table with partitions 1 and 2 and `keys` containing only 1). The `IN ` set is deferred state, so once the execution defect is fixed, this pruning also needs the deferred-set treatment that #117113 / PR #117272 give the same expression written directly in the predicate — otherwise rows in partitions matching only the execution-time set contents will silently escape the mutation.
**How to reproduce**
All statements above at pure default settings. Wrong on 24.8, 25.8, 26.8 (fiddle) and current master. 23.8 returns the correct result (`1`), and current versions return the correct result with `enable_analyzer = 0`, so this regressed when the analyzer became the default.
**Expected behavior**
Either the definition is rejected at CREATE time like the explicit-subquery form `ALIAS p IN (SELECT p FROM keys)` is, or the membership test is computed correctly everywhere the definition is consumed: `SELECT` returns the rows, and the mutation executes instead of being accepted and then failing forever.
Contributor guide
Assessment
This issue has not been assessed yet.