diff --git a/dbms/src/DataStreams/ConvertingBlockInputStream.cpp b/dbms/src/DataStreams/ConvertingBlockInputStream.cpp index f1bf7ece9c3..644460b0153 100644 --- a/dbms/src/DataStreams/ConvertingBlockInputStream.cpp +++ b/dbms/src/DataStreams/ConvertingBlockInputStream.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -34,8 +35,9 @@ ConvertingBlockInputStream::ConvertingBlockInputStream( const Context & context_, const BlockInputStreamPtr & input, const Block & result_header, - MatchColumnsMode mode) - : context(context_), header(result_header), conversion(header.columns()) + MatchColumnsMode mode, + const ColumnDefaults & column_defaults_) + : context(context_), header(result_header), column_defaults(column_defaults_), conversion(header.columns()) { children.emplace_back(input); @@ -128,9 +130,12 @@ Block ConvertingBlockInputStream::readImpl() res_elem.column = std::move(converted); } - // erase any columns that need to be set to default value or expression + // replace missing columns with default value or expression if any if (!default_columns.empty()) + { res.erase(default_columns); + res = addMissingDefaults(res, header.getNamesAndTypesList(), column_defaults, context); + } return res; } diff --git a/dbms/src/DataStreams/ConvertingBlockInputStream.h b/dbms/src/DataStreams/ConvertingBlockInputStream.h index 89bbb3db378..515fce08c4b 100644 --- a/dbms/src/DataStreams/ConvertingBlockInputStream.h +++ b/dbms/src/DataStreams/ConvertingBlockInputStream.h @@ -2,6 +2,7 @@ #include #include +#include namespace DB @@ -37,7 +38,8 @@ public: const Context & context, const BlockInputStreamPtr & input, const Block & result_header, - MatchColumnsMode mode); + MatchColumnsMode mode, + const ColumnDefaults & column_defaults = {}); String getName() const override { return "Converting"; } Block getHeader() const override { return header; } @@ -47,6 +49,8 @@ private: const Context & context; Block header; + /// Only used in NameOrDefault mode + const ColumnDefaults column_defaults; /// How to construct result block. Position in source block, where to get each column. using Conversion = std::vector; diff --git a/dbms/src/DataStreams/PushingToViewsBlockOutputStream.cpp b/dbms/src/DataStreams/PushingToViewsBlockOutputStream.cpp index 7388f8b6904..8188a892df2 100644 --- a/dbms/src/DataStreams/PushingToViewsBlockOutputStream.cpp +++ b/dbms/src/DataStreams/PushingToViewsBlockOutputStream.cpp @@ -230,7 +230,16 @@ void PushingToViewsBlockOutputStream::process(const Block & block, size_t view_n /// and two-level aggregation is triggered). in = std::make_shared( in, context.getSettingsRef().min_insert_block_size_rows, context.getSettingsRef().min_insert_block_size_bytes); - in = std::make_shared(context, in, view.out->getHeader(), ConvertingBlockInputStream::MatchColumnsMode::NameOrDefault); + + auto view_table = context.getTable(view.table_id); + + if (auto * materialized_view = dynamic_cast(view_table.get())) + { + StoragePtr inner_table = materialized_view->getTargetTable(); + in = std::make_shared(context, in, view.out->getHeader(), ConvertingBlockInputStream::MatchColumnsMode::NameOrDefault, inner_table->getColumns().getDefaults()); + } + else + in = std::make_shared(context, in, view.out->getHeader(), ConvertingBlockInputStream::MatchColumnsMode::Name); } else in = std::make_shared(block); diff --git a/dbms/tests/queries/0_stateless/01023_materialized_view_query_context.sql b/dbms/tests/queries/0_stateless/01023_materialized_view_query_context.sql index 1a7f8c15678..d68d6df6ea3 100644 --- a/dbms/tests/queries/0_stateless/01023_materialized_view_query_context.sql +++ b/dbms/tests/queries/0_stateless/01023_materialized_view_query_context.sql @@ -1,5 +1,6 @@ -- Create dictionary, since dictGet*() uses DB::Context in executeImpl() -- (To cover scope of the Context in DB::PushingToViewsBlockOutputStream::process) +DROP TABLE IF EXISTS mv; DROP DATABASE IF EXISTS dict_in_01023; CREATE DATABASE dict_in_01023;