Skip to content

Commit 4e2f349

Browse files
committed
Merge pull request #1197 from Altinity/backports/25.8.12/89367
25.8.12 Backport of ClickHouse#89367: Crash in IN function where columns have different types and many columns are involved
1 parent e7db2db commit 4e2f349

File tree

4 files changed

+92
-8
lines changed

4 files changed

+92
-8
lines changed

src/Interpreters/sortBlock.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,10 @@ void checkSortedWithPermutation(const Block & block, const SortDescription & des
336336
void sortBlock(Block & block, const SortDescription & description, UInt64 limit, IColumn::PermutationSortStability stability)
337337
{
338338
IColumn::Permutation permutation;
339+
340+
#ifndef NDEBUG
341+
block.checkNumberOfRows();
342+
#endif
339343
getBlockSortPermutationImpl(block, description, stability, limit, permutation);
340344

341345
#ifndef NDEBUG

src/Storages/MergeTree/KeyCondition.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1422,6 +1422,9 @@ bool KeyCondition::tryPrepareSetIndex(
14221422

14231423
Columns transformed_set_columns = set_columns;
14241424

1425+
IColumn::Filter filter(transformed_set_columns.front()->size(), 1);
1426+
bool filter_used = false;
1427+
14251428
for (size_t indexes_mapping_index = 0; indexes_mapping_index < indexes_mapping_size; ++indexes_mapping_index)
14261429
{
14271430
const auto & key_column_type = data_types[indexes_mapping_index];
@@ -1493,32 +1496,39 @@ bool KeyCondition::tryPrepareSetIndex(
14931496
const NullMap & nullable_set_column_null_map = nullable_set_column_typed->getNullMapData();
14941497
size_t nullable_set_column_null_map_size = nullable_set_column_null_map.size();
14951498

1496-
IColumn::Filter filter(nullable_set_column_null_map_size);
1497-
14981499
if (set_column_null_map)
14991500
{
15001501
for (size_t i = 0; i < nullable_set_column_null_map_size; ++i)
15011502
{
15021503
if (nullable_set_column_null_map_size < set_column_null_map->size())
1503-
filter[i] = (*set_column_null_map)[i] || !nullable_set_column_null_map[i];
1504+
filter[i] &= (*set_column_null_map)[i] || !nullable_set_column_null_map[i];
15041505
else
1505-
filter[i] = !nullable_set_column_null_map[i];
1506+
filter[i] &= !nullable_set_column_null_map[i];
15061507
}
15071508

1508-
set_column = nullable_set_column_typed->filter(filter, 0);
1509+
set_column = nullable_set_column;
15091510
}
15101511
else
15111512
{
15121513
for (size_t i = 0; i < nullable_set_column_null_map_size; ++i)
1513-
filter[i] = !nullable_set_column_null_map[i];
1514+
filter[i] &= !nullable_set_column_null_map[i];
15141515

1515-
set_column = nullable_set_column_typed->getNestedColumn().filter(filter, 0);
1516+
set_column = nullable_set_column_typed->getNestedColumnPtr();
15161517
}
1518+
filter_used = true;
15171519

15181520
transformed_set_columns[set_element_index] = std::move(set_column);
15191521
}
15201522

1521-
set_columns = std::move(transformed_set_columns);
1523+
if (filter_used)
1524+
{
1525+
for (size_t set_element_index = 0; set_element_index < transformed_set_columns.size(); ++set_element_index)
1526+
set_columns[set_element_index] = transformed_set_columns[set_element_index]->filter(filter, 0);
1527+
}
1528+
else
1529+
{
1530+
set_columns = std::move(transformed_set_columns);
1531+
}
15221532

15231533
out.set_index = std::make_shared<MergeTreeSetIndex>(set_columns, std::move(indexes_mapping));
15241534

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
CreatingSets
2+
Expression
3+
Filter
4+
ReadFromMergeTree
5+
Indexes:
6+
PrimaryKey
7+
Keys:
8+
value
9+
Condition: (value in 5-element set)
10+
Parts: 1/1
11+
Granules: 1/1
12+
Search Algorithm: generic exclusion search
13+
Ranges: 1
14+
CreatingSets
15+
Expression
16+
Filter
17+
ReadFromMergeTree
18+
Indexes:
19+
PrimaryKey
20+
Keys:
21+
value
22+
Condition: (value in 0-element set)
23+
Parts: 0/1
24+
Granules: 0/1
25+
Search Algorithm: generic exclusion search
26+
Ranges: 0
27+
CreatingSets
28+
Expression
29+
Filter
30+
ReadFromMergeTree
31+
Indexes:
32+
PrimaryKey
33+
Keys:
34+
value
35+
Condition: (value in 5-element set)
36+
Parts: 1/1
37+
Granules: 1/1
38+
Search Algorithm: generic exclusion search
39+
Ranges: 1
40+
CreatingSets
41+
Expression
42+
Filter
43+
ReadFromMergeTree
44+
Indexes:
45+
PrimaryKey
46+
Keys:
47+
value
48+
Condition: (value in 0-element set)
49+
Parts: 0/1
50+
Granules: 0/1
51+
Search Algorithm: generic exclusion search
52+
Ranges: 0
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
-- Tags: no-parallel-replicas, no-random-merge-tree-settings
2+
-- followup to 02882_primary_key_index_in_function_different_types
3+
4+
DROP TABLE IF EXISTS test_table;
5+
CREATE TABLE test_table
6+
(
7+
id UInt64,
8+
value UInt64
9+
) ENGINE=MergeTree ORDER BY (id, value) SETTINGS index_granularity = 8192, index_granularity_bytes = '1Mi';
10+
11+
INSERT INTO test_table SELECT number, number FROM numbers(10);
12+
13+
EXPLAIN indexes = 1, description=0 SELECT id FROM test_table WHERE (id, value) IN (SELECT '5', number FROM numbers(5));
14+
EXPLAIN indexes = 1, description=0 SELECT id FROM test_table WHERE (id, value) IN (SELECT 'not a number', number FROM numbers(5));
15+
EXPLAIN indexes = 1, description=0 SELECT id FROM test_table WHERE (id, value) IN (SELECT 42, 'not a number' UNION ALL SELECT 5, toString(number) FROM numbers(5));
16+
EXPLAIN indexes = 1, description=0 SELECT id FROM test_table WHERE (id, value) IN (SELECT '42', 'not a number' UNION ALL SELECT 'not a number', '42' FROM numbers(5));
17+
18+
DROP TABLE test_table;

0 commit comments

Comments
 (0)