1#pragma once
2
3#include <Parsers/IAST.h>
4
5
6namespace DB
7{
8
9/** List of zero, single or multiple JOIN-ed tables or subqueries in SELECT query, with ARRAY JOINs and SAMPLE, FINAL modifiers.
10 *
11 * Table expression is:
12 * [database_name.]table_name
13 * or
14 * table_function(params)
15 * or
16 * (subquery)
17 *
18 * Optionally with alias (correlation name):
19 * [AS] alias
20 *
21 * Table may contain FINAL and SAMPLE modifiers:
22 * FINAL
23 * SAMPLE 1 / 10
24 * SAMPLE 0.1
25 * SAMPLE 1000000
26 *
27 * Table expressions may be combined with JOINs of following kinds:
28 * [GLOBAL] [ANY|ALL|ASOF|SEMI] [INNER|LEFT|RIGHT|FULL] [OUTER] JOIN table_expr
29 * CROSS JOIN
30 * , (comma)
31 *
32 * In all kinds except cross and comma, there are join condition in one of following forms:
33 * USING (a, b c)
34 * USING a, b, c
35 * ON expr...
36 *
37 * Also, tables may be ARRAY JOIN-ed with one or more arrays or nested columns:
38 * [LEFT|INNER|] ARRAY JOIN name [AS alias], ...
39 */
40
41
42/// Table expression, optionally with alias.
43struct ASTTableExpression : public IAST
44{
45 /// One of fields is non-nullptr.
46 ASTPtr database_and_table_name;
47 ASTPtr table_function;
48 ASTPtr subquery;
49
50 /// Modifiers
51 bool final = false;
52 ASTPtr sample_size;
53 ASTPtr sample_offset;
54
55 using IAST::IAST;
56 String getID(char) const override { return "TableExpression"; }
57 ASTPtr clone() const override;
58 void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override;
59};
60
61
62/// How to JOIN another table.
63struct ASTTableJoin : public IAST
64{
65 /// Algorithm for distributed query processing.
66 enum class Locality
67 {
68 Unspecified,
69 Local, /// Perform JOIN, using only data available on same servers (co-located data).
70 Global /// Collect and merge data from remote servers, and broadcast it to each server.
71 };
72
73 /// Allows more optimal JOIN for typical cases.
74 enum class Strictness
75 {
76 Unspecified,
77 RightAny, /// Old ANY JOIN. If there are many suitable rows in right table, use any from them to join.
78 Any, /// Semi Join with any value from filtering table. For LEFT JOIN with Any and RightAny are the same.
79 All, /// If there are many suitable rows to join, use all of them and replicate rows of "left" table (usual semantic of JOIN).
80 Asof, /// For the last JOIN column, pick the latest value
81 Semi, /// LEFT or RIGHT. SEMI LEFT JOIN filters left table by values exists in right table. SEMI RIGHT - otherwise.
82 Anti, /// LEFT or RIGHT. Same as SEMI JOIN but filter values that are NOT exists in other table.
83 };
84
85 /// Join method.
86 enum class Kind
87 {
88 Inner, /// Leave only rows that was JOINed.
89 Left, /// If in "right" table there is no corresponding rows, use default values instead.
90 Right,
91 Full,
92 Cross, /// Direct product. Strictness and condition doesn't matter.
93 Comma /// Same as direct product. Intended to be converted to INNER JOIN with conditions from WHERE.
94 };
95
96 Locality locality = Locality::Unspecified;
97 Strictness strictness = Strictness::Unspecified;
98 Kind kind = Kind::Inner;
99
100 /// Condition. One of fields is non-nullptr.
101 ASTPtr using_expression_list;
102 ASTPtr on_expression;
103
104 using IAST::IAST;
105 String getID(char) const override { return "TableJoin"; }
106 ASTPtr clone() const override;
107
108 void formatImplBeforeTable(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const;
109 void formatImplAfterTable(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const;
110 void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override;
111};
112
113inline bool isLeft(ASTTableJoin::Kind kind) { return kind == ASTTableJoin::Kind::Left; }
114inline bool isRight(ASTTableJoin::Kind kind) { return kind == ASTTableJoin::Kind::Right; }
115inline bool isInner(ASTTableJoin::Kind kind) { return kind == ASTTableJoin::Kind::Inner; }
116inline bool isFull(ASTTableJoin::Kind kind) { return kind == ASTTableJoin::Kind::Full; }
117inline bool isCross(ASTTableJoin::Kind kind) { return kind == ASTTableJoin::Kind::Cross; }
118inline bool isComma(ASTTableJoin::Kind kind) { return kind == ASTTableJoin::Kind::Comma; }
119inline bool isRightOrFull(ASTTableJoin::Kind kind) { return kind == ASTTableJoin::Kind::Right || kind == ASTTableJoin::Kind::Full; }
120inline bool isLeftOrFull(ASTTableJoin::Kind kind) { return kind == ASTTableJoin::Kind::Left || kind == ASTTableJoin::Kind::Full; }
121inline bool isInnerOrRight(ASTTableJoin::Kind kind) { return kind == ASTTableJoin::Kind::Inner || kind == ASTTableJoin::Kind::Right; }
122
123
124/// Specification of ARRAY JOIN.
125struct ASTArrayJoin : public IAST
126{
127 enum class Kind
128 {
129 Inner, /// If array is empty, row will not present (default).
130 Left, /// If array is empty, leave row with default values instead of array elements.
131 };
132
133 Kind kind = Kind::Inner;
134
135 /// List of array or nested names to JOIN, possible with aliases.
136 ASTPtr expression_list;
137
138 using IAST::IAST;
139 String getID(char) const override { return "ArrayJoin"; }
140 ASTPtr clone() const override;
141 void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override;
142};
143
144
145/// Element of list.
146struct ASTTablesInSelectQueryElement : public IAST
147{
148 /** For first element of list, either table_expression or array_join element could be non-nullptr.
149 * For former elements, either table_join and table_expression are both non-nullptr, or array_join is non-nullptr.
150 */
151 ASTPtr table_join; /// How to JOIN a table, if table_expression is non-nullptr.
152 ASTPtr table_expression; /// Table.
153 ASTPtr array_join; /// Arrays to JOIN.
154
155 using IAST::IAST;
156 String getID(char) const override { return "TablesInSelectQueryElement"; }
157 ASTPtr clone() const override;
158 void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override;
159};
160
161
162/// The list. Elements are in 'children' field.
163struct ASTTablesInSelectQuery : public IAST
164{
165 using IAST::IAST;
166 String getID(char) const override { return "TablesInSelectQuery"; }
167 ASTPtr clone() const override;
168 void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override;
169};
170
171}
172