diff --git a/src/Interpreters/ActionsDAG.cpp b/src/Interpreters/ActionsDAG.cpp index fd5efc4f75c..b917b2ccb70 100644 --- a/src/Interpreters/ActionsDAG.cpp +++ b/src/Interpreters/ActionsDAG.cpp @@ -292,6 +292,33 @@ std::string ActionsDAG::dumpNames() const return out.str(); } +void ActionsDAG::removeUnusedActions(const NameSet & required_names) +{ + NodeRawConstPtrs required_nodes; + required_nodes.reserve(required_names.size()); + + NameSet added; + for (const auto & node : index) + { + if (required_names.count(node->result_name) && added.count(node->result_name) == 0) + { + required_nodes.push_back(node); + added.insert(node->result_name); + } + } + + if (added.size() < required_names.size()) + { + for (const auto & name : required_names) + if (added.count(name) == 0) + throw Exception(ErrorCodes::UNKNOWN_IDENTIFIER, + "Unknown column: {}, there are only columns {}", name, dumpNames()); + } + + index.swap(required_nodes); + removeUnusedActions(); +} + void ActionsDAG::removeUnusedActions(const Names & required_names) { NodeRawConstPtrs required_nodes; @@ -717,18 +744,21 @@ bool ActionsDAG::trivial() const } void ActionsDAG::addMaterializingOutputActions() +{ + for (auto & node : index) + node = &materializeNode(*node); +} + +const ActionsDAG::Node & ActionsDAG::materializeNode(const Node & node) { FunctionOverloadResolverPtr func_builder_materialize = std::make_shared( std::make_unique( std::make_shared())); - for (auto & node : index) - { - auto & name = node->result_name; - node = &addFunction(func_builder_materialize, {node}, {}); - node = &addAlias(*node, name); - } + const auto & name = node.result_name; + const auto * func = &addFunction(func_builder_materialize, {&node}, {}); + return addAlias(*func, name); } ActionsDAGPtr ActionsDAG::makeConvertingActions( diff --git a/src/Interpreters/ActionsDAG.h b/src/Interpreters/ActionsDAG.h index 735fb301366..c86bcac7705 100644 --- a/src/Interpreters/ActionsDAG.h +++ b/src/Interpreters/ActionsDAG.h @@ -233,6 +233,7 @@ public: bool projectedOutput() const { return projected_output; } void removeUnusedActions(const Names & required_names); + void removeUnusedActions(const NameSet & required_names); bool hasArrayJoin() const; bool hasStatefulFunctions() const; @@ -258,6 +259,8 @@ public: /// Also add aliases so the result names remain unchanged. void addMaterializingOutputActions(); + const Node & materializeNode(const Node & node); + enum class MatchColumnsMode { /// Require same number of columns in source and result. Match columns by corresponding positions, regardless to names. diff --git a/src/Interpreters/addMissingDefaults.cpp b/src/Interpreters/addMissingDefaults.cpp index f2e02f66506..bb444103d8e 100644 --- a/src/Interpreters/addMissingDefaults.cpp +++ b/src/Interpreters/addMissingDefaults.cpp @@ -75,7 +75,8 @@ ActionsDAGPtr addMissingDefaults( * it can be full (or the interpreter may decide that it is constant everywhere). */ auto new_column = column.type->createColumnConstWithDefaultValue(0); - index.push_back(&actions->addColumn({std::move(new_column), column.type, column.name})); + const auto * col = &actions->addColumn({std::move(new_column), column.type, column.name}); + index.push_back(&actions->materializeNode(*col)); } /// Computes explicitly specified values by default and materialized columns.