1 | #pragma once |
2 | |
3 | #include <Interpreters/InDepthNodeVisitor.h> |
4 | |
5 | namespace DB |
6 | { |
7 | |
8 | class ASTSelectQuery; |
9 | class Context; |
10 | |
11 | /// AST transformer. It replaces multiple joins to (subselect + join) track. |
12 | /// 'select * from t1 join t2 on ... join t3 on ... join t4 on ...' would be rewriten with |
13 | /// 'select * from (select * from t1 join t2 on ...) join t3 on ...) join t4 on ...' |
14 | class JoinToSubqueryTransformMatcher |
15 | { |
16 | public: |
17 | struct Data |
18 | { |
19 | const Context & context; |
20 | bool done = false; |
21 | }; |
22 | |
23 | static bool needChildVisit(ASTPtr &, const ASTPtr &) { return true; } |
24 | static void visit(ASTPtr & ast, Data & data); |
25 | |
26 | private: |
27 | /// - combines two source TablesInSelectQueryElement into resulting one (Subquery) |
28 | /// - adds table hidings to ASTSelectQuery.with_expression_list |
29 | /// |
30 | /// TablesInSelectQueryElement [result] |
31 | /// TableExpression |
32 | /// Subquery (alias __join1) |
33 | /// SelectWithUnionQuery |
34 | /// ExpressionList |
35 | /// SelectQuery |
36 | /// ExpressionList |
37 | /// Asterisk |
38 | /// TablesInSelectQuery |
39 | /// TablesInSelectQueryElement [source1] |
40 | /// TablesInSelectQueryElement [source2] |
41 | /// |
42 | static void visit(ASTSelectQuery & select, ASTPtr & ast, Data & data); |
43 | |
44 | /// @return combined TablesInSelectQueryElement or nullptr if cannot rewrite |
45 | static ASTPtr replaceJoin(ASTPtr left, ASTPtr right); |
46 | }; |
47 | |
48 | using JoinToSubqueryTransformVisitor = InDepthNodeVisitor<JoinToSubqueryTransformMatcher, true>; |
49 | |
50 | } |
51 | |