Fix block structure mismatch for nullable LowCardinality column with default expression.

This commit is contained in:
Nikolai Kochetov 2023-03-13 17:57:07 +00:00
parent fa6fd10e1b
commit 650427614f
3 changed files with 13 additions and 1 deletions

View File

@ -61,11 +61,17 @@ void addDefaultRequiredExpressionsRecursively(
RequiredSourceColumnsVisitor::Data columns_context; RequiredSourceColumnsVisitor::Data columns_context;
RequiredSourceColumnsVisitor(columns_context).visit(column_default_expr); RequiredSourceColumnsVisitor(columns_context).visit(column_default_expr);
NameSet required_columns_names = columns_context.requiredColumns(); NameSet required_columns_names = columns_context.requiredColumns();
auto required_type = std::make_shared<ASTLiteral>(columns.get(required_column_name).type->getName());
auto expr = makeASTFunction("_CAST", column_default_expr, std::make_shared<ASTLiteral>(columns.get(required_column_name).type->getName())); auto expr = makeASTFunction("_CAST", column_default_expr, required_type);
if (is_column_in_query && convert_null_to_default) if (is_column_in_query && convert_null_to_default)
{
expr = makeASTFunction("ifNull", std::make_shared<ASTIdentifier>(required_column_name), std::move(expr)); expr = makeASTFunction("ifNull", std::make_shared<ASTIdentifier>(required_column_name), std::move(expr));
/// ifNull does not respect LowCardinality.
/// It may be fixed later or re-implemented properly for identical types.
expr = makeASTFunction("_CAST", std::move(expr), required_type);
}
default_expr_list_accum->children.emplace_back(setAlias(expr, required_column_name)); default_expr_list_accum->children.emplace_back(setAlias(expr, required_column_name));
added_columns.emplace(required_column_name); added_columns.emplace(required_column_name);

View File

@ -0,0 +1,6 @@
drop table if exists test_null_as_default__fuzz_46;
SET allow_suspicious_low_cardinality_types = 1;
CREATE TABLE test_null_as_default__fuzz_46 (a Nullable(DateTime64(3)), b LowCardinality(Float32) DEFAULT a + 1000) ENGINE = Memory;
INSERT INTO test_null_as_default__fuzz_46 SELECT 1, NULL UNION ALL SELECT 2, NULL;
drop table test_null_as_default__fuzz_46;