| 1 | #pragma once |
| 2 | |
| 3 | #include <Common/typeid_cast.h> |
| 4 | #include <Core/Block.h> |
| 5 | #include <Interpreters/InDepthNodeVisitor.h> |
| 6 | |
| 7 | namespace DB |
| 8 | { |
| 9 | |
| 10 | class Context; |
| 11 | class ASTSubquery; |
| 12 | class ASTFunction; |
| 13 | struct ASTTableExpression; |
| 14 | |
| 15 | /** Replace subqueries that return exactly one row |
| 16 | * ("scalar" subqueries) to the corresponding constants. |
| 17 | * |
| 18 | * If the subquery returns more than one column, it is replaced by a tuple of constants. |
| 19 | * |
| 20 | * Features |
| 21 | * |
| 22 | * A replacement occurs during query analysis, and not during the main runtime. |
| 23 | * This means that the progress indicator will not work during the execution of these requests, |
| 24 | * and also such queries can not be aborted. |
| 25 | * |
| 26 | * But the query result can be used for the index in the table. |
| 27 | * |
| 28 | * Scalar subqueries are executed on the request-initializer server. |
| 29 | * The request is sent to remote servers with already substituted constants. |
| 30 | */ |
| 31 | class ExecuteScalarSubqueriesMatcher |
| 32 | { |
| 33 | public: |
| 34 | using Visitor = InDepthNodeVisitor<ExecuteScalarSubqueriesMatcher, true>; |
| 35 | |
| 36 | struct Data |
| 37 | { |
| 38 | const Context & context; |
| 39 | size_t subquery_depth; |
| 40 | Scalars & scalars; |
| 41 | }; |
| 42 | |
| 43 | static bool needChildVisit(ASTPtr & node, const ASTPtr &); |
| 44 | static void visit(ASTPtr & ast, Data & data); |
| 45 | |
| 46 | private: |
| 47 | static void visit(const ASTSubquery & subquery, ASTPtr & ast, Data & data); |
| 48 | static void visit(const ASTFunction & func, ASTPtr & ast, Data & data); |
| 49 | }; |
| 50 | |
| 51 | using ExecuteScalarSubqueriesVisitor = ExecuteScalarSubqueriesMatcher::Visitor; |
| 52 | |
| 53 | } |
| 54 | |