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

Open
#117,276 0 comments 0 reactions 0 assignees View on GitHub
comp-mutations comp-query-analyzer minor potential bug
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.