#include #include #include #include #include #include #include #include namespace DB { static ITransformingStep::Traits getTraits(const ActionsDAGPtr & actions) { return ITransformingStep::Traits { { .preserves_distinct_columns = !actions->hasArrayJoin(), .returns_single_stream = false, .preserves_number_of_streams = true, .preserves_sorting = !actions->hasArrayJoin(), }, { .preserves_number_of_rows = !actions->hasArrayJoin(), } }; } ExpressionStep::ExpressionStep(const DataStream & input_stream_, ActionsDAGPtr actions_dag_) : ITransformingStep( input_stream_, ExpressionTransform::transformHeader(input_stream_.header, *actions_dag_), getTraits(actions_dag_)) , actions_dag(std::move(actions_dag_)) { /// Some columns may be removed by expression. updateDistinctColumns(output_stream->header, output_stream->distinct_columns); } void ExpressionStep::updateInputStream(DataStream input_stream, bool keep_header) { Block out_header = keep_header ? std::move(output_stream->header) : ExpressionTransform::transformHeader(input_stream.header, *actions_dag); output_stream = createOutputStream( input_stream, std::move(out_header), getDataStreamTraits()); input_streams.clear(); input_streams.emplace_back(std::move(input_stream)); } void ExpressionStep::transformPipeline(QueryPipelineBuilder & pipeline, const BuildQueryPipelineSettings & settings) { auto expression = std::make_shared(actions_dag, settings.getActionsSettings()); pipeline.addSimpleTransform([&](const Block & header) { return std::make_shared(header, expression); }); if (!blocksHaveEqualStructure(pipeline.getHeader(), output_stream->header)) { auto convert_actions_dag = ActionsDAG::makeConvertingActions( pipeline.getHeader().getColumnsWithTypeAndName(), output_stream->header.getColumnsWithTypeAndName(), ActionsDAG::MatchColumnsMode::Name); auto convert_actions = std::make_shared(convert_actions_dag, settings.getActionsSettings()); pipeline.addSimpleTransform([&](const Block & header) { return std::make_shared(header, convert_actions); }); } } void ExpressionStep::describeActions(FormatSettings & settings) const { String prefix(settings.offset, ' '); bool first = true; auto expression = std::make_shared(actions_dag); for (const auto & action : expression->getActions()) { settings.out << prefix << (first ? "Actions: " : " "); first = false; settings.out << action.toString() << '\n'; } settings.out << prefix << "Positions:"; for (const auto & pos : expression->getResultPositions()) settings.out << ' ' << pos; settings.out << '\n'; } void ExpressionStep::describeActions(JSONBuilder::JSONMap & map) const { auto expression = std::make_shared(actions_dag); map.add("Expression", expression->toTree()); } }