Skip to content

Commit ffabb47

Browse files
KochetovNicolaizvonand
authored andcommitted
Merge pull request ClickHouse#89367 from ilejn/in_function_crash
Crash in IN function where columns have different types and many columns are involved
1 parent 1a76b25 commit ffabb47

File tree

4 files changed

+96
-8
lines changed

4 files changed

+96
-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
@@ -1420,6 +1420,9 @@ bool KeyCondition::tryPrepareSetIndex(
14201420

14211421
Columns transformed_set_columns = set_columns;
14221422

1423+
IColumn::Filter filter(transformed_set_columns.front()->size(), 1);
1424+
bool filter_used = false;
1425+
14231426
for (size_t indexes_mapping_index = 0; indexes_mapping_index < indexes_mapping_size; ++indexes_mapping_index)
14241427
{
14251428
const auto & key_column_type = data_types[indexes_mapping_index];
@@ -1491,32 +1494,39 @@ bool KeyCondition::tryPrepareSetIndex(
14911494
const NullMap & nullable_set_column_null_map = nullable_set_column_typed->getNullMapData();
14921495
size_t nullable_set_column_null_map_size = nullable_set_column_null_map.size();
14931496

1494-
IColumn::Filter filter(nullable_set_column_null_map_size);
1495-
14961497
if (set_column_null_map)
14971498
{
14981499
for (size_t i = 0; i < nullable_set_column_null_map_size; ++i)
14991500
{
15001501
if (nullable_set_column_null_map_size < set_column_null_map->size())
1501-
filter[i] = (*set_column_null_map)[i] || !nullable_set_column_null_map[i];
1502+
filter[i] &= (*set_column_null_map)[i] || !nullable_set_column_null_map[i];
15021503
else
1503-
filter[i] = !nullable_set_column_null_map[i];
1504+
filter[i] &= !nullable_set_column_null_map[i];
15041505
}
15051506

1506-
set_column = nullable_set_column_typed->filter(filter, 0);
1507+
set_column = nullable_set_column;
15071508
}
15081509
else
15091510
{
15101511
for (size_t i = 0; i < nullable_set_column_null_map_size; ++i)
1511-
filter[i] = !nullable_set_column_null_map[i];
1512+
filter[i] &= !nullable_set_column_null_map[i];
15121513

1513-
set_column = nullable_set_column_typed->getNestedColumn().filter(filter, 0);
1514+
set_column = nullable_set_column_typed->getNestedColumnPtr();
15141515
}
1516+
filter_used = true;
15151517

15161518
transformed_set_columns[set_element_index] = std::move(set_column);
15171519
}
15181520

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

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

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
CreatingSets
2+
Expression
3+
Filter
4+
ReadFromMergeTree
5+
Indexes:
6+
PrimaryKey
7+
Keys:
8+
id
9+
value
10+
Condition: ((id, value) in 5-element set)
11+
Parts: 1/1
12+
Granules: 1/1
13+
Search Algorithm: generic exclusion search
14+
Ranges: 1
15+
CreatingSets
16+
Expression
17+
Filter
18+
ReadFromMergeTree
19+
Indexes:
20+
PrimaryKey
21+
Keys:
22+
id
23+
value
24+
Condition: ((id, value) in 0-element set)
25+
Parts: 0/1
26+
Granules: 0/1
27+
Search Algorithm: generic exclusion search
28+
Ranges: 0
29+
CreatingSets
30+
Expression
31+
Filter
32+
ReadFromMergeTree
33+
Indexes:
34+
PrimaryKey
35+
Keys:
36+
id
37+
value
38+
Condition: ((id, value) in 5-element set)
39+
Parts: 1/1
40+
Granules: 1/1
41+
Search Algorithm: generic exclusion search
42+
Ranges: 1
43+
CreatingSets
44+
Expression
45+
Filter
46+
ReadFromMergeTree
47+
Indexes:
48+
PrimaryKey
49+
Keys:
50+
id
51+
value
52+
Condition: ((id, value) in 0-element set)
53+
Parts: 0/1
54+
Granules: 0/1
55+
Search Algorithm: generic exclusion search
56+
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)