1#pragma once
2
3#include <Interpreters/InDepthNodeVisitor.h>
4
5namespace DB
6{
7
8class ASTSelectQuery;
9class 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 ...'
14class JoinToSubqueryTransformMatcher
15{
16public:
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
26private:
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
48using JoinToSubqueryTransformVisitor = InDepthNodeVisitor<JoinToSubqueryTransformMatcher, true>;
49
50}
51