Merge pull request #13075 from ClickHouse/fix-11327

Fix 11327
This commit is contained in:
alexey-milovidov 2020-07-31 14:53:07 +03:00 committed by GitHub
commit 91156bef54
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 34 additions and 9 deletions

View File

@ -80,7 +80,7 @@ QueryPipeline createLocalStream(
pipeline.addSimpleTransform([&](const Block & source_header)
{
return std::make_shared<ConvertingTransform>(
source_header, header, ConvertingTransform::MatchColumnsMode::Name);
source_header, header, ConvertingTransform::MatchColumnsMode::Name, true);
});
/** Materialization is needed, since from remote servers the constants come materialized.

View File

@ -474,7 +474,7 @@ void InterpreterSelectQuery::buildQueryPlan(QueryPlan & query_plan)
/// We must guarantee that result structure is the same as in getSampleBlock()
if (!blocksHaveEqualStructure(query_plan.getCurrentDataStream().header, result_header))
{
auto converting = std::make_unique<ConvertingStep>(query_plan.getCurrentDataStream(), result_header);
auto converting = std::make_unique<ConvertingStep>(query_plan.getCurrentDataStream(), result_header, true);
query_plan.addStep(std::move(converting));
}
}

View File

@ -16,9 +16,10 @@ static ITransformingStep::DataStreamTraits getTraits()
};
}
ConvertingStep::ConvertingStep(const DataStream & input_stream_, Block result_header_)
ConvertingStep::ConvertingStep(const DataStream & input_stream_, Block result_header_, bool ignore_constant_values_)
: ITransformingStep(input_stream_, result_header_, getTraits())
, result_header(std::move(result_header_))
, ignore_constant_values(ignore_constant_values_)
{
updateDistinctColumns(output_stream->header, output_stream->distinct_columns);
}
@ -27,14 +28,14 @@ void ConvertingStep::transformPipeline(QueryPipeline & pipeline)
{
pipeline.addSimpleTransform([&](const Block & header)
{
return std::make_shared<ConvertingTransform>(header, result_header, ConvertingTransform::MatchColumnsMode::Name);
return std::make_shared<ConvertingTransform>(header, result_header, ConvertingTransform::MatchColumnsMode::Name, ignore_constant_values);
});
}
void ConvertingStep::describeActions(FormatSettings & settings) const
{
const auto & header = input_streams[0].header;
auto conversion = ConvertingTransform(header, result_header, ConvertingTransform::MatchColumnsMode::Name)
auto conversion = ConvertingTransform(header, result_header, ConvertingTransform::MatchColumnsMode::Name, ignore_constant_values)
.getConversion();
auto dump_description = [&](const ColumnWithTypeAndName & elem, bool is_const)

View File

@ -8,7 +8,7 @@ namespace DB
class ConvertingStep : public ITransformingStep
{
public:
ConvertingStep(const DataStream & input_stream_, Block result_header_);
ConvertingStep(const DataStream & input_stream_, Block result_header_, bool ignore_constant_values_ = false);
String getName() const override { return "Converting"; }
@ -18,6 +18,8 @@ public:
private:
Block result_header;
/// Do not check that constants are same. Use value from result_header.
bool ignore_constant_values;
};
}

View File

@ -35,9 +35,11 @@ static ColumnPtr castColumnWithDiagnostic(
ConvertingTransform::ConvertingTransform(
Block source_header_,
Block result_header_,
MatchColumnsMode mode_)
MatchColumnsMode mode_,
bool ignore_constant_values_)
: ISimpleTransform(std::move(source_header_), std::move(result_header_), false)
, conversion(getOutputPort().getHeader().columns())
, ignore_constant_values(ignore_constant_values_)
{
const auto & source = getInputPort().getHeader();
const auto & result = getOutputPort().getHeader();
@ -79,7 +81,7 @@ ConvertingTransform::ConvertingTransform(
{
if (const auto * src_const = typeid_cast<const ColumnConst *>(src_elem.column.get()))
{
if (res_const->getField() != src_const->getField())
if (!ignore_constant_values && res_const->getField() != src_const->getField())
throw Exception("Cannot convert column " + backQuoteIfNeed(res_elem.name) + " because "
"it is constant but values of constants are different in source and result",
ErrorCodes::ILLEGAL_COLUMN);
@ -115,6 +117,12 @@ void ConvertingTransform::transform(Chunk & chunk)
src_elem.column = src_columns[conversion[res_pos]];
auto res_elem = result.getByPosition(res_pos);
if (ignore_constant_values && isColumnConst(*res_elem.column))
{
res_columns.emplace_back(res_elem.column->cloneResized(num_rows));
continue;
}
ColumnPtr converted = castColumnWithDiagnostic(src_elem, res_elem);
if (!isColumnConst(*res_elem.column))

View File

@ -31,7 +31,8 @@ public:
ConvertingTransform(
Block source_header_,
Block result_header_,
MatchColumnsMode mode_);
MatchColumnsMode mode_,
bool ignore_constant_values_ = false); /// Do not check that constants are same. Use value from result_header.
String getName() const override { return "Converting"; }
@ -43,6 +44,11 @@ protected:
private:
/// How to construct result block. Position in source block, where to get each column.
ColumnNumbers conversion;
/// Do not check that constants are same. Use value from result_header.
/// This is needed in case run functions which are constatn in query scope,
/// but may return different result being executed remotely, like `now64()` or `randConstant()`.
/// In this case we replace constants from remote source to constatns from initiator.
bool ignore_constant_values;
};
}

View File

@ -0,0 +1,5 @@
1
1
1
1
1

View File

@ -0,0 +1,3 @@
select c >= 0 from (SELECT randConstant() as c FROM remote('127.0.0.{1,2}', numbers_mt(1)));
select c >= 0 from (SELECT randConstant() as c FROM remote('127.0.0.{3,2}', numbers_mt(1)));
select c >= 0 from (SELECT randConstant() as c FROM remote('127.0.0.1', numbers_mt(1)));