Skip to content

Commit

Permalink
First attempt to fix issue ClickHouse#7878
Browse files Browse the repository at this point in the history
  • Loading branch information
Vitaliy Zakaznikov authored and filimonov committed Feb 4, 2020
1 parent 619fc2e commit 8bbd883
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 4 deletions.
25 changes: 23 additions & 2 deletions dbms/src/DataStreams/ConvertingBlockInputStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <Common/assert_cast.h>
#include <Common/quoteString.h>
#include <Parsers/IAST.h>

#include <iostream>

namespace DB
{
Expand Down Expand Up @@ -65,8 +65,20 @@ ConvertingBlockInputStream::ConvertingBlockInputStream(
throw Exception("Cannot find column " + backQuote(res_elem.name) + " in source stream",
ErrorCodes::THERE_IS_NO_COLUMN);
break;

case MatchColumnsMode::NameOrDefault:
if (input_header.has(res_elem.name))
conversion[result_col_num] = input_header.getPositionByName(res_elem.name);
else {
std::cerr << "column " << result_col_num << " will be set to default\n";
conversion[result_col_num] = USE_DEFAULT;
}
break;
}

if (conversion[result_col_num] == USE_DEFAULT)
continue;

const auto & src_elem = input_header.getByPosition(conversion[result_col_num]);

/// Check constants.
Expand Down Expand Up @@ -100,9 +112,18 @@ Block ConvertingBlockInputStream::readImpl()
Block res = header.cloneEmpty();
for (size_t res_pos = 0, size = conversion.size(); res_pos < size; ++res_pos)
{
const auto & src_elem = src.getByPosition(conversion[res_pos]);
auto & res_elem = res.getByPosition(res_pos);

if (conversion[res_pos] == USE_DEFAULT)
{
// Create a column with default values
auto column_with_defaults = res_elem.type->createColumn()->cloneResized(src.rows());
res_elem.column = std::move(column_with_defaults);
continue;
}

const auto & src_elem = src.getByPosition(conversion[res_pos]);

ColumnPtr converted = castColumnWithDiagnostic(src_elem, res_elem, context);

if (isColumnConst(*src_elem.column) && !isColumnConst(*res_elem.column))
Expand Down
5 changes: 4 additions & 1 deletion dbms/src/DataStreams/ConvertingBlockInputStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ class ConvertingBlockInputStream : public IBlockInputStream
/// Require same number of columns in source and result. Match columns by corresponding positions, regardless to names.
Position,
/// Find columns in source by their names. Allow excessive columns in source.
Name
Name,
/// Find columns in source by their names if present else use the default. Allow excessive columns in source.
NameOrDefault
};

ConvertingBlockInputStream(
Expand All @@ -48,6 +50,7 @@ class ConvertingBlockInputStream : public IBlockInputStream

/// How to construct result block. Position in source block, where to get each column.
using Conversion = std::vector<size_t>;
const size_t USE_DEFAULT = static_cast<size_t>(-1);
Conversion conversion;
};

Expand Down
2 changes: 1 addition & 1 deletion dbms/src/DataStreams/PushingToViewsBlockOutputStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ void PushingToViewsBlockOutputStream::process(const Block & block, size_t view_n
/// and two-level aggregation is triggered).
in = std::make_shared<SquashingBlockInputStream>(
in, context.getSettingsRef().min_insert_block_size_rows, context.getSettingsRef().min_insert_block_size_bytes);
in = std::make_shared<ConvertingBlockInputStream>(context, in, view.out->getHeader(), ConvertingBlockInputStream::MatchColumnsMode::Name);
in = std::make_shared<ConvertingBlockInputStream>(context, in, view.out->getHeader(), ConvertingBlockInputStream::MatchColumnsMode::NameOrDefault);
}
else
in = std::make_shared<OneBlockInputStream>(block);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
1
1
2
3
1 0
1 0
2 0
3 0
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
DROP TABLE IF EXISTS mv_source;
DROP TABLE IF EXISTS mv_target;

CREATE TABLE mv_source (`a` UInt64) ENGINE = MergeTree ORDER BY tuple();
CREATE TABLE mv_target (`a` UInt64) ENGINE = MergeTree ORDER BY tuple();

CREATE MATERIALIZED VIEW mv TO mv_target AS SELECT * FROM mv_source;

INSERT INTO mv_source VALUES (1);

ALTER TABLE mv_target ADD COLUMN b UInt8;
INSERT INTO mv_source VALUES (1),(2),(3);

SELECT * FROM mv ORDER BY a;
SELECT * FROM mv_target ORDER BY a;

0 comments on commit 8bbd883

Please sign in to comment.