diff --git a/src/Interpreters/ExpressionActions.cpp b/src/Interpreters/ExpressionActions.cpp index 5cf235224b7..71b31a57f17 100644 --- a/src/Interpreters/ExpressionActions.cpp +++ b/src/Interpreters/ExpressionActions.cpp @@ -78,6 +78,9 @@ ExpressionActionsPtr ExpressionActions::clone() const void ExpressionActions::linearizeActions() { + /// This function does the topological sort or DAG and fills all the fields of ExpressionActions. + /// Algorithm traverses DAG starting from nodes without children. + /// For every node we support the number of created children, and if all children are created, put node into queue. struct Data { const Node * node = nullptr; @@ -102,6 +105,8 @@ void ExpressionActions::linearizeActions() reverse_index[&node] = id; } + /// There are independent queues for arrayJoin and other actions. + /// We delay creation of arrayJoin as long as we can, so that they will be executed closer to end. std::queue ready_nodes; std::queue ready_array_joins; @@ -120,6 +125,8 @@ void ExpressionActions::linearizeActions() ready_nodes.emplace(&node); } + /// Every argument will have fixed position in columns list. + /// If argument is removed, it's position may be reused by other action. std::stack free_positions; while (!ready_nodes.empty() || !ready_array_joins.empty()) @@ -128,12 +135,9 @@ void ExpressionActions::linearizeActions() const Node * node = stack.front(); stack.pop(); - Names argument_names; - for (const auto & child : node->children) - argument_names.emplace_back(child->result_name); - auto & cur = data[reverse_index[node]]; + /// Select position for action result. size_t free_position = num_columns; if (free_positions.empty()) ++num_columns; @@ -396,6 +400,8 @@ static void executeAction(const ExpressionActions::Action & action, ExecutionCon auto pos = execution_context.inputs_pos[action.arguments.front().pos]; if (pos < 0) { + /// Here we allow to skip input if it is not in block (in case it is not needed). + /// It may be unusual, but some code depend on such behaviour. if (action.arguments.front().needed_later) throw Exception(ErrorCodes::NOT_FOUND_COLUMN_IN_BLOCK, "Not found column {} in block", diff --git a/src/Interpreters/ExpressionJIT.h b/src/Interpreters/ExpressionJIT.h index 3c885aca72e..023599f98f0 100644 --- a/src/Interpreters/ExpressionJIT.h +++ b/src/Interpreters/ExpressionJIT.h @@ -31,6 +31,8 @@ class LLVMFunction : public IFunctionBaseImpl public: + /// LLVMFunction is a compiled part of ActionsDAG. + /// We store this part as independent DAG with minial required information to compile it. struct CompileNode { enum class NodeType @@ -51,6 +53,8 @@ public: std::vector arguments; }; + /// DAG is represented as list of nodes stored in in-order traverse order. + /// Expression (a + 1) + (b + 1) will be represented like chain: a, 1, a + 1, b, b + 1, (a + 1) + (b + 1). struct CompileDAG : public std::vector { std::string dump() const;