Skip to content

Commit 25675b2

Browse files
committed
Fix potential crash caused by concurrent mutation of underlying const PREWHERE columns
The issue was that in MergeTreeReadTask we may have column that has other references, usually it is a constant column that created during analysis (that is not a constant anymore where we call shrink, i.e. after `materialize()`), and we do not need to mutate such column anyway. v2: move code from MergeTreeSplitPrewhereIntoReadSteps.cpp::addClonedDAGToDAG() into MergeTreeReadTask
1 parent 7d2b4ca commit 25675b2

File tree

3 files changed

+18
-1
lines changed

3 files changed

+18
-1
lines changed

src/Storages/MergeTree/MergeTreeReadTask.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,12 @@ MergeTreeReadTask::BlockAndProgress MergeTreeReadTask::read()
351351
if (read_result.num_rows != 0)
352352
{
353353
for (const auto & column : read_result.columns)
354-
column->assumeMutableRef().shrinkToFit();
354+
{
355+
/// We may have columns that has other references, usually it is a constant column that has been created during analysis
356+
/// (that will not be const here anymore, i.e. after materialize()), and we do not need to shrink it anyway.
357+
if (column->use_count() == 1)
358+
column->assumeMutableRef().shrinkToFit();
359+
}
355360
block = sample_block.cloneWithColumns(read_result.columns);
356361
}
357362

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
1
2+
2
3+
3
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
DROP TABLE IF EXISTS const_node;
2+
CREATE TABLE const_node (`v` Nullable(UInt8)) ENGINE = MergeTree ORDER BY tuple();
3+
SYSTEM STOP MERGES const_node;
4+
INSERT INTO const_node VALUES (1);
5+
INSERT INTO const_node VALUES (2);
6+
INSERT INTO const_node VALUES (3);
7+
-- Here we have condition with a constant "materialize(255)", for which convertToFullColumnIfConst() will return underlying column w/o copying,
8+
-- and later shrinkToFit() will be called from multiple threads on this column, and leads to UB
9+
SELECT v FROM const_node PREWHERE and(materialize(255), *) ORDER BY v;

0 commit comments

Comments
 (0)