Fix INSERT SELECT incorrectly fills MATERIALIZED column based of Nullable column

Required columns of the default expression should not be converted to NULL,
since this map value to default and MATERIALIZED values will not work.

Consider the following structure:
- A Nullable(Int64)
- X Int64 materialized coalesce(A, -1)

With recursive_null_as_default=true you will get:

    _CAST(coalesce(A, -1), 'Int64') AS X, NULL AS A

And this will ignore default expression.

Fixes: #23524 (Cc: @kssenii)
Fixes: #29729 (Cc: @tavplubix)
Backport: 21.7+
This commit is contained in:
Azat Khuzhin 2021-10-14 21:02:26 +03:00
parent bc1662b9fe
commit a063097fdf
3 changed files with 27 additions and 1 deletions

View File

@ -61,7 +61,25 @@ void addDefaultRequiredExpressionsRecursively(
added_columns.emplace(required_column_name);
for (const auto & next_required_column_name : required_columns_names)
addDefaultRequiredExpressionsRecursively(block, next_required_column_name, required_column_type, columns, default_expr_list_accum, added_columns, null_as_default);
{
/// Required columns of the default expression should not be converted to NULL,
/// since this map value to default and MATERIALIZED values will not work.
///
/// Consider the following structure:
/// - A Nullable(Int64)
/// - X Int64 materialized coalesce(A, -1)
///
/// With recursive_null_as_default=true you will get:
///
/// _CAST(coalesce(A, -1), 'Int64') AS X, NULL AS A
///
/// And this will ignore default expression.
bool recursive_null_as_default = false;
addDefaultRequiredExpressionsRecursively(block,
next_required_column_name, required_column_type,
columns, default_expr_list_accum, added_columns,
recursive_null_as_default);
}
}
else if (columns.has(required_column_name))
{

View File

@ -0,0 +1,2 @@
1 42 42
1 42 42

View File

@ -0,0 +1,6 @@
-- Test from https://github.com/ClickHouse/ClickHouse/issues/29729
create table data_02053 (id Int64, A Nullable(Int64), X Int64 materialized coalesce(A, -1)) engine=MergeTree order by id;
insert into data_02053 values (1, 42);
-- Due to insert_null_as_default A became Null and X became -1
insert into data_02053 select 1, 42;
select *, X from data_02053 order by id;