1#include <Parsers/ASTIdentifier.h>
2#include <Parsers/ASTSelectWithUnionQuery.h>
3#include <Parsers/ASTInsertQuery.h>
4
5#include <Parsers/CommonParsers.h>
6#include <Parsers/ExpressionElementParsers.h>
7#include <Parsers/ExpressionListParsers.h>
8#include <Parsers/ParserSelectWithUnionQuery.h>
9#include <Parsers/ParserInsertQuery.h>
10#include <Parsers/ParserSetQuery.h>
11#include <Common/typeid_cast.h>
12
13
14namespace DB
15{
16
17namespace ErrorCodes
18{
19 extern const int SYNTAX_ERROR;
20}
21
22
23bool ParserInsertQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
24{
25 ParserKeyword s_insert_into("INSERT INTO");
26 ParserKeyword s_table("TABLE");
27 ParserKeyword s_function("FUNCTION");
28 ParserToken s_dot(TokenType::Dot);
29 ParserKeyword s_values("VALUES");
30 ParserKeyword s_format("FORMAT");
31 ParserKeyword s_settings("SETTINGS");
32 ParserKeyword s_select("SELECT");
33 ParserKeyword s_with("WITH");
34 ParserToken s_lparen(TokenType::OpeningRoundBracket);
35 ParserToken s_rparen(TokenType::ClosingRoundBracket);
36 ParserIdentifier name_p;
37 ParserList columns_p(std::make_unique<ParserCompoundIdentifier>(), std::make_unique<ParserToken>(TokenType::Comma), false);
38 ParserFunction table_function_p{false};
39
40 ASTPtr database;
41 ASTPtr table;
42 ASTPtr columns;
43 ASTPtr format;
44 ASTPtr select;
45 ASTPtr table_function;
46 ASTPtr settings_ast;
47 /// Insertion data
48 const char * data = nullptr;
49
50 if (!s_insert_into.ignore(pos, expected))
51 return false;
52
53 s_table.ignore(pos, expected);
54
55 if (s_function.ignore(pos, expected))
56 {
57 if (!table_function_p.parse(pos, table_function, expected))
58 return false;
59 }
60 else
61 {
62 if (!name_p.parse(pos, table, expected))
63 return false;
64
65 if (s_dot.ignore(pos, expected))
66 {
67 database = table;
68 if (!name_p.parse(pos, table, expected))
69 return false;
70 }
71 }
72
73 /// Is there a list of columns
74 if (s_lparen.ignore(pos, expected))
75 {
76 if (!columns_p.parse(pos, columns, expected))
77 return false;
78
79 if (!s_rparen.ignore(pos, expected))
80 return false;
81 }
82
83 Pos before_select = pos;
84
85 /// VALUES or FORMAT or SELECT
86 if (s_values.ignore(pos, expected))
87 {
88 data = pos->begin;
89 }
90 else if (s_format.ignore(pos, expected))
91 {
92 if (!name_p.parse(pos, format, expected))
93 return false;
94 }
95 else if (s_select.ignore(pos, expected) || s_with.ignore(pos,expected))
96 {
97 pos = before_select;
98 ParserSelectWithUnionQuery select_p;
99 select_p.parse(pos, select, expected);
100
101 /// FORMAT section is expected if we have input() in SELECT part
102 if (s_format.ignore(pos, expected) && !name_p.parse(pos, format, expected))
103 return false;
104 }
105 else
106 {
107 return false;
108 }
109
110 if (s_settings.ignore(pos, expected))
111 {
112 ParserSetQuery parser_settings(true);
113 if (!parser_settings.parse(pos, settings_ast, expected))
114 return false;
115 }
116
117 if (format)
118 {
119 Pos last_token = pos;
120 --last_token;
121 data = last_token->end;
122
123 if (data < end && *data == ';')
124 throw Exception("You have excessive ';' symbol before data for INSERT.\n"
125 "Example:\n\n"
126 "INSERT INTO t (x, y) FORMAT TabSeparated\n"
127 ";\tHello\n"
128 "2\tWorld\n"
129 "\n"
130 "Note that there is no ';' just after format name, "
131 "you need to put at least one whitespace symbol before the data.", ErrorCodes::SYNTAX_ERROR);
132
133 while (data < end && (*data == ' ' || *data == '\t' || *data == '\f'))
134 ++data;
135
136 /// Data starts after the first newline, if there is one, or after all the whitespace characters, otherwise.
137
138 if (data < end && *data == '\r')
139 ++data;
140
141 if (data < end && *data == '\n')
142 ++data;
143 }
144
145 auto query = std::make_shared<ASTInsertQuery>();
146 node = query;
147
148 if (table_function)
149 {
150 query->table_function = table_function;
151 }
152 else
153 {
154 tryGetIdentifierNameInto(database, query->database);
155 tryGetIdentifierNameInto(table, query->table);
156 }
157
158 tryGetIdentifierNameInto(format, query->format);
159
160 query->columns = columns;
161 query->select = select;
162 query->settings_ast = settings_ast;
163 query->data = data != end ? data : nullptr;
164 query->end = end;
165
166 if (columns)
167 query->children.push_back(columns);
168 if (select)
169 query->children.push_back(select);
170 if (settings_ast)
171 query->children.push_back(settings_ast);
172
173 return true;
174}
175
176
177}
178