dbms: better diagnostics on syntax error [#METR-15933].

This commit is contained in:
Alexey Milovidov 2015-04-11 06:10:23 +03:00
parent 62ff76c572
commit 9ec393df61
59 changed files with 835 additions and 783 deletions

View File

@ -27,15 +27,15 @@ private:
{ {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || (c == '_'); return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || (c == '_');
} }
public: public:
ParserString(const char * s_, bool word_boundary_ = false, bool case_insensitive_ = false) ParserString(const char * s_, bool word_boundary_ = false, bool case_insensitive_ = false)
: s(s_), s_size(strlen(s)), word_boundary(word_boundary_), case_insensitive(case_insensitive_) {} : s(s_), s_size(strlen(s)), word_boundary(word_boundary_), case_insensitive(case_insensitive_) {}
protected: protected:
const char * getName() const { return s; } const char * getName() const { return s; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
if (static_cast<ssize_t>(s_size) > end - pos || (case_insensitive ? strncasecmp : strncmp)(pos, s, s_size)) if (static_cast<ssize_t>(s_size) > end - pos || (case_insensitive ? strncasecmp : strncmp)(pos, s, s_size))
return false; return false;
@ -44,14 +44,14 @@ protected:
if (word_boundary && s_size && is_word(s[s_size - 1]) if (word_boundary && s_size && is_word(s[s_size - 1])
&& pos + s_size != end && is_word(pos[s_size])) && pos + s_size != end && is_word(pos[s_size]))
return false; return false;
pos += s_size; pos += s_size;
return true; return true;
} }
} }
}; };
/** пробельные символы /** пробельные символы
*/ */
class ParserWhiteSpace : public IParserBase class ParserWhiteSpace : public IParserBase
@ -61,10 +61,10 @@ public:
protected: protected:
bool allow_newlines; bool allow_newlines;
const char * getName() const { return "white space"; } const char * getName() const { return "white space"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
Pos begin = pos; Pos begin = pos;
while (pos < end && (*pos == ' ' || *pos == '\t' || (allow_newlines && *pos == '\n') || *pos == '\r' || *pos == '\f')) while (pos < end && (*pos == ' ' || *pos == '\t' || (allow_newlines && *pos == '\n') || *pos == '\r' || *pos == '\f'))
@ -80,7 +80,7 @@ class ParserCStyleComment : public IParserBase
protected: protected:
const char * getName() const { return "C-style comment"; } const char * getName() const { return "C-style comment"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
if (end - pos >= 4 && pos[0] == '/' && pos[1] == '*') if (end - pos >= 4 && pos[0] == '/' && pos[1] == '*')
{ {
@ -110,7 +110,7 @@ class ParserSQLStyleComment : public IParserBase
protected: protected:
const char * getName() const { return "SQL-style comment"; } const char * getName() const { return "SQL-style comment"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
if (end - pos >= 2 && pos[0] == '-' && pos[1] == '-') if (end - pos >= 2 && pos[0] == '-' && pos[1] == '-')
{ {
@ -135,13 +135,13 @@ class ParserComment : public IParserBase
protected: protected:
const char * getName() const { return "comment"; } const char * getName() const { return "comment"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
ParserCStyleComment p1; ParserCStyleComment p1;
ParserSQLStyleComment p2; ParserSQLStyleComment p2;
return p1.ignore(pos, end, expected) return p1.ignore(pos, end, max_parsed_pos, expected)
|| p2.ignore(pos, end, expected); || p2.ignore(pos, end, max_parsed_pos, expected);
} }
}; };
@ -150,19 +150,19 @@ class ParserWhiteSpaceOrComments : public IParserBase
{ {
public: public:
ParserWhiteSpaceOrComments(bool allow_newlines_outside_comments_ = true) : allow_newlines_outside_comments(allow_newlines_outside_comments_) {} ParserWhiteSpaceOrComments(bool allow_newlines_outside_comments_ = true) : allow_newlines_outside_comments(allow_newlines_outside_comments_) {}
protected: protected:
bool allow_newlines_outside_comments; bool allow_newlines_outside_comments;
const char * getName() const { return "white space or comments"; } const char * getName() const { return "white space or comments"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
ParserWhiteSpace p1(allow_newlines_outside_comments); ParserWhiteSpace p1(allow_newlines_outside_comments);
ParserComment p2; ParserComment p2;
bool res = false; bool res = false;
while (p1.ignore(pos, end, expected) || p2.ignore(pos, end, expected)) while (p1.ignore(pos, end, max_parsed_pos, expected) || p2.ignore(pos, end, max_parsed_pos, expected))
res = true; res = true;
return res; return res;
} }

View File

@ -11,7 +11,7 @@ class ParserArray : public IParserBase
{ {
protected: protected:
const char * getName() const { return "array"; } const char * getName() const { return "array"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
@ -23,7 +23,7 @@ class ParserParenthesisExpression : public IParserBase
{ {
protected: protected:
const char * getName() const { return "parenthesized expression"; } const char * getName() const { return "parenthesized expression"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
@ -33,7 +33,7 @@ class ParserSubquery : public IParserBase
{ {
protected: protected:
const char * getName() const { return "SELECT subquery"; } const char * getName() const { return "SELECT subquery"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
@ -43,7 +43,7 @@ class ParserIdentifier : public IParserBase
{ {
protected: protected:
const char * getName() const { return "identifier"; } const char * getName() const { return "identifier"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
@ -53,7 +53,7 @@ class ParserCompoundIdentifier : public IParserBase
{ {
protected: protected:
const char * getName() const { return "compound identifier"; } const char * getName() const { return "compound identifier"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
@ -66,7 +66,7 @@ class ParserFunction : public IParserBase
{ {
protected: protected:
const char * getName() const { return "function"; } const char * getName() const { return "function"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
@ -76,7 +76,7 @@ class ParserNull : public IParserBase
{ {
protected: protected:
const char * getName() const { return "NULL"; } const char * getName() const { return "NULL"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
@ -86,7 +86,7 @@ class ParserNumber : public IParserBase
{ {
protected: protected:
const char * getName() const { return "number"; } const char * getName() const { return "number"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
@ -96,7 +96,7 @@ class ParserStringLiteral : public IParserBase
{ {
protected: protected:
const char * getName() const { return "string literal"; } const char * getName() const { return "string literal"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
@ -106,7 +106,7 @@ class ParserLiteral : public IParserBase
{ {
protected: protected:
const char * getName() const { return "literal"; } const char * getName() const { return "literal"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
@ -116,7 +116,7 @@ class ParserAlias : public IParserBase
{ {
protected: protected:
const char * getName() const { return "alias"; } const char * getName() const { return "alias"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
@ -126,7 +126,7 @@ class ParserExpressionElement : public IParserBase
{ {
protected: protected:
const char * getName() const { return "element of expression"; } const char * getName() const { return "element of expression"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
@ -138,9 +138,9 @@ public:
ParserWithOptionalAlias(ParserPtr && elem_parser_) : elem_parser(std::move(elem_parser_)) {} ParserWithOptionalAlias(ParserPtr && elem_parser_) : elem_parser(std::move(elem_parser_)) {}
protected: protected:
ParserPtr elem_parser; ParserPtr elem_parser;
const char * getName() const { return "element of expression with optional alias"; } const char * getName() const { return "element of expression with optional alias"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
@ -151,7 +151,7 @@ class ParserOrderByElement : public IParserBase
{ {
protected: protected:
const char * getName() const { return "element of ORDER BY expression"; } const char * getName() const { return "element of ORDER BY expression"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };

View File

@ -25,7 +25,7 @@ public:
} }
protected: protected:
const char * getName() const { return "list of elements"; } const char * getName() const { return "list of elements"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
private: private:
ParserPtr elem_parser; ParserPtr elem_parser;
ParserPtr separator_parser; ParserPtr separator_parser;
@ -57,11 +57,11 @@ public:
remaining_elem_parser(std::move(remaining_elem_parser_)) remaining_elem_parser(std::move(remaining_elem_parser_))
{ {
} }
protected: protected:
const char * getName() const { return "list, delimited by binary operators"; } const char * getName() const { return "list, delimited by binary operators"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
@ -84,7 +84,7 @@ public:
protected: protected:
const char * getName() const { return "list, delimited by operator of variable arity"; } const char * getName() const { return "list, delimited by operator of variable arity"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
@ -104,10 +104,10 @@ public:
: operators(operators_), elem_parser(std::move(elem_parser_)) : operators(operators_), elem_parser(std::move(elem_parser_))
{ {
} }
protected: protected:
const char * getName() const { return "expression with prefix unary operator"; } const char * getName() const { return "expression with prefix unary operator"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
@ -118,8 +118,8 @@ private:
protected: protected:
const char * getName() const { return "access expression"; } const char * getName() const { return "access expression"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
@ -128,11 +128,11 @@ class ParserUnaryMinusExpression : public IParserBase
private: private:
static const char * operators[]; static const char * operators[];
ParserPrefixUnaryOperatorExpression operator_parser {operators, ParserPtr(new ParserAccessExpression)}; ParserPrefixUnaryOperatorExpression operator_parser {operators, ParserPtr(new ParserAccessExpression)};
protected: protected:
const char * getName() const { return "unary minus expression"; } const char * getName() const { return "unary minus expression"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
@ -144,10 +144,10 @@ private:
protected: protected:
const char * getName() const { return "multiplicative expression"; } const char * getName() const { return "multiplicative expression"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
return operator_parser.parse(pos, end, node, expected); return operator_parser.parse(pos, end, node, max_parsed_pos, expected);
} }
}; };
@ -157,13 +157,13 @@ class ParserAdditiveExpression : public IParserBase
private: private:
static const char * operators[]; static const char * operators[];
ParserLeftAssociativeBinaryOperatorList operator_parser {operators, ParserPtr(new ParserMultiplicativeExpression)}; ParserLeftAssociativeBinaryOperatorList operator_parser {operators, ParserPtr(new ParserMultiplicativeExpression)};
protected: protected:
const char * getName() const { return "additive expression"; } const char * getName() const { return "additive expression"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
return operator_parser.parse(pos, end, node, expected); return operator_parser.parse(pos, end, node, max_parsed_pos, expected);
} }
}; };
@ -173,13 +173,13 @@ class ParserComparisonExpression : public IParserBase
private: private:
static const char * operators[]; static const char * operators[];
ParserLeftAssociativeBinaryOperatorList operator_parser {operators, ParserPtr(new ParserAdditiveExpression)}; ParserLeftAssociativeBinaryOperatorList operator_parser {operators, ParserPtr(new ParserAdditiveExpression)};
protected: protected:
const char * getName() const { return "comparison expression"; } const char * getName() const { return "comparison expression"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
return operator_parser.parse(pos, end, node, expected); return operator_parser.parse(pos, end, node, max_parsed_pos, expected);
} }
}; };
@ -192,10 +192,10 @@ private:
protected: protected:
const char * getName() const { return "logical-NOT expression"; } const char * getName() const { return "logical-NOT expression"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
return operator_parser.parse(pos, end, node, expected); return operator_parser.parse(pos, end, node, max_parsed_pos, expected);
} }
}; };
@ -209,13 +209,13 @@ public:
: operator_parser("AND", "and", ParserPtr(new ParserLogicalNotExpression)) : operator_parser("AND", "and", ParserPtr(new ParserLogicalNotExpression))
{ {
} }
protected: protected:
const char * getName() const { return "logical-AND expression"; } const char * getName() const { return "logical-AND expression"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
return operator_parser.parse(pos, end, node, expected); return operator_parser.parse(pos, end, node, max_parsed_pos, expected);
} }
}; };
@ -229,13 +229,13 @@ public:
: operator_parser("OR", "or", ParserPtr(new ParserLogicalAndExpression)) : operator_parser("OR", "or", ParserPtr(new ParserLogicalAndExpression))
{ {
} }
protected: protected:
const char * getName() const { return "logical-OR expression"; } const char * getName() const { return "logical-OR expression"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
return operator_parser.parse(pos, end, node, expected); return operator_parser.parse(pos, end, node, max_parsed_pos, expected);
} }
}; };
@ -251,7 +251,7 @@ private:
protected: protected:
const char * getName() const { return "expression with ternary operator"; } const char * getName() const { return "expression with ternary operator"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
@ -259,11 +259,11 @@ class ParserLambdaExpression : public IParserBase
{ {
private: private:
ParserTernaryOperatorExpression elem_parser; ParserTernaryOperatorExpression elem_parser;
protected: protected:
const char * getName() const { return "lambda expression"; } const char * getName() const { return "lambda expression"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
@ -275,10 +275,10 @@ protected:
ParserPtr impl; ParserPtr impl;
const char * getName() const { return "expression with optional alias"; } const char * getName() const { return "expression with optional alias"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
return impl->parse(pos, end, node, expected); return impl->parse(pos, end, node, max_parsed_pos, expected);
} }
}; };
@ -288,7 +288,7 @@ class ParserExpressionList : public IParserBase
{ {
protected: protected:
const char * getName() const { return "list of expressions"; } const char * getName() const { return "list of expressions"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
@ -298,7 +298,7 @@ private:
ParserExpressionList nested_parser; ParserExpressionList nested_parser;
protected: protected:
const char * getName() const { return "not empty list of expressions"; } const char * getName() const { return "not empty list of expressions"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
@ -306,7 +306,7 @@ class ParserOrderByExpressionList : public IParserBase
{ {
protected: protected:
const char * getName() const { return "order by expression"; } const char * getName() const { return "order by expression"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };

View File

@ -13,7 +13,7 @@ namespace DB
using Poco::SharedPtr; using Poco::SharedPtr;
typedef const char * Expected; using Expected = const char *;
/** Интерфейс для классов-парсеров /** Интерфейс для классов-парсеров
@ -21,7 +21,7 @@ typedef const char * Expected;
class IParser class IParser
{ {
public: public:
typedef const char * Pos; using Pos = const char *;
/** Получить текст о том, что парсит этот парсер. */ /** Получить текст о том, что парсит этот парсер. */
virtual const char * getName() const = 0; virtual const char * getName() const = 0;
@ -34,27 +34,28 @@ public:
* или что парсит этот парсер, если парсинг был успешным. * или что парсит этот парсер, если парсинг был успешным.
* Строка, в которую входит диапазон [begin, end) может быть не 0-terminated. * Строка, в которую входит диапазон [begin, end) может быть не 0-terminated.
*/ */
virtual bool parse(Pos & pos, Pos end, ASTPtr & node, Expected & expected) = 0; virtual bool parse(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected) = 0;
bool ignore(Pos & pos, Pos end, Expected & expected) bool ignore(Pos & pos, Pos end, Pos & max_parsed_pos, Expected & expected)
{ {
ASTPtr ignore_node; ASTPtr ignore_node;
return parse(pos, end, ignore_node, expected); return parse(pos, end, ignore_node, max_parsed_pos, expected);
} }
bool ignore(Pos & pos, Pos end) bool ignore(Pos & pos, Pos end)
{ {
Pos max_parsed_pos = pos;
Expected expected; Expected expected;
return ignore(pos, end, expected); return ignore(pos, end, max_parsed_pos, expected);
} }
/** То же самое, но не двигать позицию и не записывать результат в node. /** То же самое, но не двигать позицию и не записывать результат в node.
*/ */
bool check(Pos & pos, Pos end, Expected & expected) bool check(Pos & pos, Pos end, Pos & max_parsed_pos, Expected & expected)
{ {
Pos begin = pos; Pos begin = pos;
ASTPtr node; ASTPtr node;
if (!parse(pos, end, node, expected)) if (!parse(pos, end, node, max_parsed_pos, expected))
{ {
pos = begin; pos = begin;
return false; return false;
@ -66,62 +67,6 @@ public:
virtual ~IParser() {} virtual ~IParser() {}
}; };
typedef std::unique_ptr<IParser> ParserPtr; using ParserPtr = std::unique_ptr<IParser>;
/** Из позиции в (возможно многострочном) запросе получить номер строки и номер столбца в строке.
* Используется в сообщении об ошибках.
*/
inline std::pair<size_t, size_t> getLineAndCol(IParser::Pos begin, IParser::Pos pos)
{
size_t line = 0;
IParser::Pos nl;
while (nullptr != (nl = reinterpret_cast<IParser::Pos>(memchr(begin, '\n', pos - begin))))
{
++line;
begin = nl + 1;
}
/// Нумеруются с единицы.
return { line + 1, pos - begin + 1 };
}
/** Получить сообщение о синтаксической ошибке.
*/
inline std::string getSyntaxErrorMessage(
bool parse_res, /// false, если не удалось распарсить; true, если удалось, но не до конца строки или точки с запятой.
IParser::Pos begin,
IParser::Pos end,
IParser::Pos pos,
Expected expected,
const std::string & description = "")
{
std::stringstream message;
message << "Syntax error";
if (!description.empty())
message << " (" << description << ")";
message << ": failed at position " << (pos - begin + 1);
/// Если запрос многострочный.
IParser::Pos nl = reinterpret_cast<IParser::Pos>(memchr(begin, '\n', end - begin));
if (nullptr != nl && nl + 1 != end)
{
size_t line = 0;
size_t col = 0;
std::tie(line, col) = getLineAndCol(begin, pos);
message << " (line " << line << ", col " << col << ")";
}
message << ": " << std::string(pos, std::min(SHOW_CHARS_ON_SYNTAX_ERROR, end - pos))
<< ", expected " << (parse_res ? "end of query" : expected) << ".";
return message.str();
}
} }

View File

@ -16,10 +16,18 @@ namespace DB
class IParserBase : public IParser class IParserBase : public IParser
{ {
public: public:
bool parse(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool parse(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
expected = getName(); Pos new_max_parsed_pos = pos;
bool res = parseImpl(pos, end, node, expected); Expected new_expected = getName();
bool res = parseImpl(pos, end, node, new_max_parsed_pos, new_expected);
if (new_max_parsed_pos > max_parsed_pos)
{
max_parsed_pos = new_max_parsed_pos;
expected = new_expected;
}
if (!res) if (!res)
node = nullptr; node = nullptr;
@ -30,7 +38,7 @@ public:
return res; return res;
} }
protected: protected:
virtual bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) = 0; virtual bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected) = 0;
}; };
} }

View File

@ -18,7 +18,7 @@ class ParserAlterQuery : public IParserBase
{ {
protected: protected:
const char * getName() const { return "ALTER query"; } const char * getName() const { return "ALTER query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
} }

View File

@ -11,7 +11,7 @@ class ParserCheckQuery : public IParserBase
{ {
protected: protected:
const char * getName() const { return "ALTER query"; } const char * getName() const { return "ALTER query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
} }

View File

@ -19,7 +19,7 @@ class ParserNestedTable : public IParserBase
{ {
protected: protected:
const char * getName() const { return "nested table"; } const char * getName() const { return "nested table"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
@ -33,7 +33,7 @@ class ParserIdentifierWithParameters : public IParserBase
{ {
protected: protected:
const char * getName() const { return "identifier with parameters"; } const char * getName() const { return "identifier with parameters"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
@ -44,7 +44,7 @@ class ParserIdentifierWithOptionalParameters : public IParserBase
{ {
protected: protected:
const char * getName() const { return "identifier with optional parameters"; } const char * getName() const { return "identifier with optional parameters"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
@ -53,7 +53,7 @@ class IParserNameTypePair : public IParserBase
{ {
protected: protected:
const char * getName() const { return "name and type pair"; } const char * getName() const { return "name and type pair"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
/** Имя и тип через пробел. Например, URL String. */ /** Имя и тип через пробел. Например, URL String. */
@ -62,7 +62,7 @@ typedef IParserNameTypePair<ParserIdentifier> ParserNameTypePair;
typedef IParserNameTypePair<ParserCompoundIdentifier> ParserCompoundNameTypePair; typedef IParserNameTypePair<ParserCompoundIdentifier> ParserCompoundNameTypePair;
template <class NameParser> template <class NameParser>
bool IParserNameTypePair<NameParser>::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool IParserNameTypePair<NameParser>::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
NameParser name_parser; NameParser name_parser;
ParserIdentifierWithOptionalParameters type_parser; ParserIdentifierWithOptionalParameters type_parser;
@ -71,9 +71,9 @@ bool IParserNameTypePair<NameParser>::parseImpl(Pos & pos, Pos end, ASTPtr & nod
Pos begin = pos; Pos begin = pos;
ASTPtr name, type; ASTPtr name, type;
if (name_parser.parse(pos, end, name, expected) if (name_parser.parse(pos, end, name, max_parsed_pos, expected)
&& ws_parser.ignore(pos, end, expected) && ws_parser.ignore(pos, end, max_parsed_pos, expected)
&& type_parser.parse(pos, end, type, expected)) && type_parser.parse(pos, end, type, max_parsed_pos, expected))
{ {
ASTNameTypePair * name_type_pair = new ASTNameTypePair(StringRange(begin, pos)); ASTNameTypePair * name_type_pair = new ASTNameTypePair(StringRange(begin, pos));
node = name_type_pair; node = name_type_pair;
@ -92,7 +92,7 @@ class ParserNameTypePairList : public IParserBase
{ {
protected: protected:
const char * getName() const { return "name and type pair list"; } const char * getName() const { return "name and type pair list"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
@ -101,14 +101,14 @@ class IParserColumnDeclaration : public IParserBase
{ {
protected: protected:
const char * getName() const { return "column declaration"; } const char * getName() const { return "column declaration"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
typedef IParserColumnDeclaration<ParserIdentifier> ParserColumnDeclaration; typedef IParserColumnDeclaration<ParserIdentifier> ParserColumnDeclaration;
typedef IParserColumnDeclaration<ParserCompoundIdentifier> ParserCompoundColumnDeclaration; typedef IParserColumnDeclaration<ParserCompoundIdentifier> ParserCompoundColumnDeclaration;
template <class NameParser> template <class NameParser>
bool IParserColumnDeclaration<NameParser>::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool IParserColumnDeclaration<NameParser>::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
NameParser name_parser; NameParser name_parser;
ParserIdentifierWithOptionalParameters type_parser; ParserIdentifierWithOptionalParameters type_parser;
@ -126,21 +126,22 @@ bool IParserColumnDeclaration<NameParser>::parseImpl(Pos & pos, Pos end, ASTPtr
/// mandatory column name /// mandatory column name
ASTPtr name; ASTPtr name;
if (!name_parser.parse(pos, end, name, expected)) if (!name_parser.parse(pos, end, name, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end, expected); ws.ignore(pos, end, max_parsed_pos, expected);
/** column name should be followed by type name if it /** column name should be followed by type name if it
* is not immediately followed by {DEFAULT, MATERIALIZED, ALIAS} */ * is not immediately followed by {DEFAULT, MATERIALIZED, ALIAS}
*/
ASTPtr type; ASTPtr type;
const auto fallback_pos = pos; const auto fallback_pos = pos;
if (!s_default.check(pos, end, expected) && if (!s_default.check(pos, end, expected, max_parsed_pos) &&
!s_materialized.check(pos, end, expected) && !s_materialized.check(pos, end, expected, max_parsed_pos) &&
!s_alias.check(pos, end, expected)) !s_alias.check(pos, end, expected, max_parsed_pos))
{ {
if (type_parser.parse(pos, end, type, expected)) if (type_parser.parse(pos, end, type, max_parsed_pos, expected))
ws.ignore(pos, end, expected); ws.ignore(pos, end, max_parsed_pos, expected);
} }
else else
pos = fallback_pos; pos = fallback_pos;
@ -149,16 +150,16 @@ bool IParserColumnDeclaration<NameParser>::parseImpl(Pos & pos, Pos end, ASTPtr
String default_specifier; String default_specifier;
ASTPtr default_expression; ASTPtr default_expression;
const auto pos_before_specifier = pos; const auto pos_before_specifier = pos;
if (s_default.ignore(pos, end, expected) || if (s_default.ignore(pos, end, max_parsed_pos, expected) ||
s_materialized.ignore(pos, end, expected) || s_materialized.ignore(pos, end, max_parsed_pos, expected) ||
s_alias.ignore(pos, end, expected)) s_alias.ignore(pos, end, max_parsed_pos, expected))
{ {
default_specifier = Poco::toUpper(std::string{pos_before_specifier, pos}); default_specifier = Poco::toUpper(std::string{pos_before_specifier, pos});
/// should be followed by an expression /// should be followed by an expression
ws.ignore(pos, end, expected); ws.ignore(pos, end, max_parsed_pos, expected);
if (!expr_parser.parse(pos, end, default_expression, expected)) if (!expr_parser.parse(pos, end, default_expression, max_parsed_pos, expected))
return reset_pos_and_return(); return reset_pos_and_return();
} }
else if (!type) else if (!type)
@ -187,7 +188,7 @@ class ParserColumnDeclarationList : public IParserBase
{ {
protected: protected:
const char * getName() const { return "column declaration list"; } const char * getName() const { return "column declaration list"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
@ -196,7 +197,7 @@ class ParserEngine : public IParserBase
{ {
protected: protected:
const char * getName() const { return "ENGINE"; } const char * getName() const { return "ENGINE"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
@ -224,7 +225,7 @@ class ParserCreateQuery : public IParserBase
{ {
protected: protected:
const char * getName() const { return "CREATE TABLE or ATTACH TABLE query"; } const char * getName() const { return "CREATE TABLE or ATTACH TABLE query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
} }

View File

@ -17,7 +17,7 @@ class ParserDropQuery : public IParserBase
{ {
protected: protected:
const char * getName() const { return "DROP query"; } const char * getName() const { return "DROP query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
} }

View File

@ -26,7 +26,7 @@ class ParserInsertQuery : public IParserBase
{ {
protected: protected:
const char * getName() const { return "INSERT query"; } const char * getName() const { return "INSERT query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
} }

View File

@ -11,7 +11,7 @@ class ParserJoin : public IParserBase
{ {
protected: protected:
const char * getName() const { return "JOIN"; } const char * getName() const { return "JOIN"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
} }

View File

@ -13,7 +13,7 @@ class ParserOptimizeQuery : public IParserBase
{ {
protected: protected:
const char * getName() const { return "OPTIMIZE query"; } const char * getName() const { return "OPTIMIZE query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
} }

View File

@ -11,7 +11,7 @@ class ParserQuery : public IParserBase
{ {
protected: protected:
const char * getName() const { return "Query"; } const char * getName() const { return "Query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
} }

View File

@ -15,7 +15,7 @@ class ParserRenameQuery : public IParserBase
{ {
protected: protected:
const char * getName() const { return "RENAME query"; } const char * getName() const { return "RENAME query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
} }

View File

@ -11,7 +11,7 @@ class ParserSelectQuery : public IParserBase
{ {
protected: protected:
const char * getName() const { return "SELECT query"; } const char * getName() const { return "SELECT query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
} }

View File

@ -14,7 +14,7 @@ class ParserSetQuery : public IParserBase
{ {
protected: protected:
const char * getName() const { return "SET query"; } const char * getName() const { return "SET query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
} }

View File

@ -17,7 +17,7 @@ class ParserShowProcesslistQuery : public IParserBase
protected: protected:
const char * getName() const { return "SHOW PROCESSLIST query"; } const char * getName() const { return "SHOW PROCESSLIST query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
Pos begin = pos; Pos begin = pos;
@ -30,23 +30,23 @@ protected:
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_show.ignore(pos, end, expected)) if (!s_show.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_processlist.ignore(pos, end, expected)) if (!s_processlist.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_format.ignore(pos, end, expected)) if (s_format.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
ParserIdentifier format_p; ParserIdentifier format_p;
if (!format_p.parse(pos, end, format, expected)) if (!format_p.parse(pos, end, format, max_parsed_pos, expected))
return false; return false;
typeid_cast<ASTIdentifier &>(*format).kind = ASTIdentifier::Format; typeid_cast<ASTIdentifier &>(*format).kind = ASTIdentifier::Format;

View File

@ -15,7 +15,7 @@ class ParserShowTablesQuery : public IParserBase
{ {
protected: protected:
const char * getName() const { return "SHOW TABLES|DATABASES query"; } const char * getName() const { return "SHOW TABLES|DATABASES query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
} }

View File

@ -13,7 +13,7 @@ class ParserTablePropertiesQuery : public IParserBase
{ {
protected: protected:
const char * getName() const { return "EXISTS, SHOW CREATE or DESCRIBE query"; } const char * getName() const { return "EXISTS, SHOW CREATE or DESCRIBE query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected); bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
}; };
} }

View File

@ -16,7 +16,7 @@ class ParserUseQuery : public IParserBase
{ {
protected: protected:
const char * getName() const { return "USE query"; } const char * getName() const { return "USE query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
Pos begin = pos; Pos begin = pos;
@ -28,12 +28,12 @@ protected:
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_use.ignore(pos, end, expected)) if (!s_use.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!name_p.parse(pos, end, database, expected)) if (!name_p.parse(pos, end, database, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);

View File

@ -0,0 +1,15 @@
#pragma once
#include <DB/Parsers/IParser.h>
namespace DB
{
/// Распарсить запрос или записать сообщение об ошибке в out_error_message.
ASTPtr tryParseQuery(IParser & parser, IParser::Pos begin, IParser::Pos end, std::string & out_error_message, const std::string & description);
/// Распарсить запрос или кинуть исключение с сообщением об ошибке.
ASTPtr parseQuery(IParser & parser, IParser::Pos begin, IParser::Pos end, const std::string & description);
}

View File

@ -1,21 +1,22 @@
#pragma once #pragma once
#include <DB/Parsers/IAST.h>
#include <DB/Parsers/queryToString.h> #include <DB/Parsers/queryToString.h>
#include <DB/Parsers/ExpressionListParsers.h>
#include <DB/IO/WriteBufferFromString.h>
#include <unordered_map> #include <unordered_map>
namespace DB namespace DB
{ {
enum struct ColumnDefaultType
{ enum class ColumnDefaultType
Default, {
Materialized, Default,
Alias Materialized,
}; Alias
};
} }
namespace std namespace std
{ {
template<> struct hash<DB::ColumnDefaultType> template<> struct hash<DB::ColumnDefaultType>
@ -27,152 +28,51 @@ namespace std
}; };
} }
namespace DB namespace DB
{ {
inline ColumnDefaultType columnDefaultTypeFromString(const String & str)
{
static const std::unordered_map<String, ColumnDefaultType> map{
{ "DEFAULT", ColumnDefaultType::Default },
{ "MATERIALIZED", ColumnDefaultType::Materialized },
{ "ALIAS", ColumnDefaultType::Alias }
};
const auto it = map.find(str);
return it != std::end(map) ? it->second : throw Exception{"Unknown column default specifier: " + str};
}
inline String toString(const ColumnDefaultType type) inline ColumnDefaultType columnDefaultTypeFromString(const String & str)
{ {
static const std::unordered_map<ColumnDefaultType, String> map{ static const std::unordered_map<String, ColumnDefaultType> map{
{ ColumnDefaultType::Default, "DEFAULT" }, { "DEFAULT", ColumnDefaultType::Default },
{ ColumnDefaultType::Materialized, "MATERIALIZED" }, { "MATERIALIZED", ColumnDefaultType::Materialized },
{ ColumnDefaultType::Alias, "ALIAS" } { "ALIAS", ColumnDefaultType::Alias }
};
const auto it = map.find(type);
return it != std::end(map) ? it->second : throw Exception{"Invalid ColumnDefaultType"};
}
struct ColumnDefault
{
ColumnDefaultType type;
ASTPtr expression;
}; };
inline bool operator==(const ColumnDefault & lhs, const ColumnDefault & rhs) const auto it = map.find(str);
{ return it != std::end(map) ? it->second : throw Exception{"Unknown column default specifier: " + str};
return lhs.type == rhs.type && queryToString(lhs.expression) == queryToString(rhs.expression); }
}
using ColumnDefaults = std::unordered_map<String, ColumnDefault>; inline String toString(const ColumnDefaultType type)
{
template <bool store> static const std::unordered_map<ColumnDefaultType, String> map{
struct ColumnsDescription { ColumnDefaultType::Default, "DEFAULT" },
{ { ColumnDefaultType::Materialized, "MATERIALIZED" },
template <typename T> using by_value_or_cref = typename std::conditional<store, T, const T &>::type; { ColumnDefaultType::Alias, "ALIAS" }
by_value_or_cref<NamesAndTypesList> columns; };
by_value_or_cref<NamesAndTypesList> materialized;
by_value_or_cref<NamesAndTypesList> alias; const auto it = map.find(type);
by_value_or_cref<ColumnDefaults> defaults; return it != std::end(map) ? it->second : throw Exception{"Invalid ColumnDefaultType"};
}
String toString() const
{
String s; struct ColumnDefault
WriteBufferFromString buf{s}; {
ColumnDefaultType type;
writeString("columns format version: 1\n", buf); ASTPtr expression;
writeText(columns.size() + materialized.size() + alias.size(), buf); };
writeString(" columns:\n", buf);
const auto write_columns = [this, &buf] (const NamesAndTypesList & columns) { inline bool operator==(const ColumnDefault & lhs, const ColumnDefault & rhs)
for (const auto & column : columns) {
{ return lhs.type == rhs.type && queryToString(lhs.expression) == queryToString(rhs.expression);
const auto it = defaults.find(column.name); }
writeBackQuotedString(column.name, buf);
writeChar(' ', buf); using ColumnDefaults = std::unordered_map<String, ColumnDefault>;
writeString(column.type->getName(), buf);
if (it == std::end(defaults))
{
writeChar('\n', buf);
continue;
}
else
writeChar('\t', buf);
writeString(DB::toString(it->second.type), buf);
writeChar('\t', buf);
writeString(queryToString(it->second.expression), buf);
writeChar('\n', buf);
}
};
write_columns(columns);
write_columns(materialized);
write_columns(alias);
return s;
}
static ColumnsDescription parse(const String & str, const DataTypeFactory & data_type_factory)
{
ReadBufferFromString buf{str};
assertString("columns format version: 1\n", buf);
size_t count{};
readText(count, buf);
assertString(" columns:\n", buf);
ParserTernaryOperatorExpression expr_parser;
ColumnsDescription result{};
for (size_t i = 0; i < count; ++i)
{
String column_name;
readBackQuotedString(column_name, buf);
assertString(" ", buf);
String type_name;
readString(type_name, buf);
auto type = data_type_factory.get(type_name);
if (*buf.position() == '\n')
{
assertString("\n", buf);
result.columns.emplace_back(column_name, std::move(type));
continue;
}
assertString("\t", buf);
String default_type_str;
readString(default_type_str, buf);
const auto default_type = columnDefaultTypeFromString(default_type_str);
assertString("\t", buf);
String default_expr_str;
readText(default_expr_str, buf);
assertString("\n", buf);
ASTPtr default_expr;
Expected expected{};
auto begin = default_expr_str.data();
const auto end = begin + default_expr_str.size();
if (!expr_parser.parse(begin, end, default_expr, expected))
throw Exception{"Could not parse default expression", DB::ErrorCodes::CANNOT_PARSE_TEXT};
if (ColumnDefaultType::Default == default_type)
result.columns.emplace_back(column_name, std::move(type));
else if (ColumnDefaultType::Materialized == default_type)
result.materialized.emplace_back(column_name, std::move(type));
else if (ColumnDefaultType::Alias == default_type)
result.alias.emplace_back(column_name, std::move(type));
result.defaults.emplace(column_name, ColumnDefault{default_type, default_expr});
}
assertEOF(buf);
return result;
}
};
} }

View File

@ -0,0 +1,28 @@
#pragma once
#include <DB/Storages/ColumnDefault.h>
#include <DB/Core/NamesAndTypes.h>
namespace DB
{
template <bool store>
struct ColumnsDescription
{
template <typename T>
using by_value_or_cref = typename std::conditional<store, T, const T &>::type;
by_value_or_cref<NamesAndTypesList> columns;
by_value_or_cref<NamesAndTypesList> materialized;
by_value_or_cref<NamesAndTypesList> alias;
by_value_or_cref<ColumnDefaults> defaults;
String toString() const;
static ColumnsDescription parse(const String & str, const DataTypeFactory & data_type_factory);
};
}

View File

@ -49,6 +49,7 @@
#include <DB/Parsers/ASTQueryWithOutput.h> #include <DB/Parsers/ASTQueryWithOutput.h>
#include <DB/Parsers/ASTIdentifier.h> #include <DB/Parsers/ASTIdentifier.h>
#include <DB/Parsers/formatAST.h> #include <DB/Parsers/formatAST.h>
#include <DB/Parsers/parseQuery.h>
#include <DB/Interpreters/Context.h> #include <DB/Interpreters/Context.h>
@ -635,28 +636,24 @@ private:
} }
ASTPtr parseQuery(Expected & pos, const char * end) ASTPtr parseQuery(IParser::Pos & pos, const char * end)
{ {
ParserQuery parser; ParserQuery parser;
Expected expected = "";
const char * begin = pos;
ASTPtr res; ASTPtr res;
bool parse_res = parser.parse(pos, end, res, expected);
/// Распарсенный запрос должен заканчиваться на конец входных данных или на точку с запятой. if (is_interactive)
if (!parse_res || (pos != end && *pos != ';'))
{ {
std::string message = getSyntaxErrorMessage(parse_res, begin, end, pos, expected); String message;
res = tryParseQuery(parser, pos, end, message, "");
if (is_interactive) if (!res)
{
std::cerr << message << std::endl << std::endl; std::cerr << message << std::endl << std::endl;
else return nullptr;
throw Exception(message, ErrorCodes::SYNTAX_ERROR); }
return nullptr;
} }
else
res = DB::parseQuery(parser, pos, end, "");
if (is_interactive) if (is_interactive)
{ {

View File

@ -40,7 +40,7 @@ int main(int argc, char ** argv)
const char * end = begin + input.size(); const char * end = begin + input.size();
const char * pos = begin; const char * pos = begin;
if (!parser.parse(pos, end, ast, expected)) if (!parser.parse(pos, end, ast, max_parsed_pos, expected))
{ {
std::cout << "Failed at position " << (pos - begin) << ": " std::cout << "Failed at position " << (pos - begin) << ": "
<< mysqlxx::quote << input.substr(pos - begin, 10) << mysqlxx::quote << input.substr(pos - begin, 10)

View File

@ -42,7 +42,7 @@ int main(int argc, char ** argv)
const char * end = begin + input.size(); const char * end = begin + input.size();
const char * pos = begin; const char * pos = begin;
if (!parser.parse(pos, end, ast, expected)) if (!parser.parse(pos, end, ast, max_parsed_pos, expected))
{ {
std::cout << "Failed at position " << (pos - begin) << ": " std::cout << "Failed at position " << (pos - begin) << ": "
<< mysqlxx::quote << input.substr(pos - begin, 10) << mysqlxx::quote << input.substr(pos - begin, 10)

View File

@ -108,7 +108,7 @@ int main(int argc, char ** argv)
const char * end = begin + input.size(); const char * end = begin + input.size();
const char * pos = begin; const char * pos = begin;
if (!parser.parse(pos, end, ast, expected)) if (!parser.parse(pos, end, ast, max_parsed_pos, expected))
{ {
std::cout << "Failed at position " << (pos - begin) << ": " std::cout << "Failed at position " << (pos - begin) << ": "
<< mysqlxx::quote << input.substr(pos - begin, 10) << mysqlxx::quote << input.substr(pos - begin, 10)

View File

@ -59,7 +59,7 @@ int main(int argc, char ** argv)
const char * end = begin + input.size(); const char * end = begin + input.size();
const char * pos = begin; const char * pos = begin;
if (!parser.parse(pos, end, ast, expected)) if (!parser.parse(pos, end, ast, max_parsed_pos, expected))
{ {
std::cout << "Failed at position " << (pos - begin) << ": " std::cout << "Failed at position " << (pos - begin) << ": "
<< mysqlxx::quote << input.substr(pos - begin, 10) << mysqlxx::quote << input.substr(pos - begin, 10)

View File

@ -112,7 +112,7 @@ int main(int argc, char ** argv)
const char * end = begin + input.size(); const char * end = begin + input.size();
const char * pos = begin; const char * pos = begin;
if (!parser.parse(pos, end, ast, expected)) if (!parser.parse(pos, end, ast, max_parsed_pos, expected))
{ {
std::cout << "Failed at position " << (pos - begin) << ": " std::cout << "Failed at position " << (pos - begin) << ": "
<< mysqlxx::quote << input.substr(pos - begin, 10) << mysqlxx::quote << input.substr(pos - begin, 10)

View File

@ -73,8 +73,9 @@ DataTypePtr DataTypeFactory::get(const String & name) const
Expected expected = ""; Expected expected = "";
IParser::Pos pos = parameters.data(); IParser::Pos pos = parameters.data();
IParser::Pos end = pos + parameters.size(); IParser::Pos end = pos + parameters.size();
IParser::Pos max_parsed_pos = pos;
if (!(args_parser.parse(pos, end, args_ast, expected) && pos == end)) if (!(args_parser.parse(pos, end, args_ast, max_parsed_pos, expected) && pos == end))
throw Exception("Cannot parse parameters for data type " + name, ErrorCodes::SYNTAX_ERROR); throw Exception("Cannot parse parameters for data type " + name, ErrorCodes::SYNTAX_ERROR);
ASTExpressionList & args_list = typeid_cast<ASTExpressionList &>(*args_ast); ASTExpressionList & args_list = typeid_cast<ASTExpressionList &>(*args_ast);
@ -124,8 +125,9 @@ DataTypePtr DataTypeFactory::get(const String & name) const
Expected expected = ""; Expected expected = "";
IParser::Pos pos = parameters.data(); IParser::Pos pos = parameters.data();
IParser::Pos end = pos + parameters.size(); IParser::Pos end = pos + parameters.size();
IParser::Pos max_parsed_pos = pos;
if (!(columns_p.parse(pos, end, columns_ast, expected) && pos == end)) if (!(columns_p.parse(pos, end, columns_ast, max_parsed_pos, expected) && pos == end))
throw Exception("Cannot parse parameters for data type " + name, ErrorCodes::SYNTAX_ERROR); throw Exception("Cannot parse parameters for data type " + name, ErrorCodes::SYNTAX_ERROR);
NamesAndTypesListPtr columns = new NamesAndTypesList; NamesAndTypesListPtr columns = new NamesAndTypesList;
@ -153,8 +155,9 @@ DataTypePtr DataTypeFactory::get(const String & name) const
Expected expected = ""; Expected expected = "";
IParser::Pos pos = parameters.data(); IParser::Pos pos = parameters.data();
IParser::Pos end = pos + parameters.size(); IParser::Pos end = pos + parameters.size();
IParser::Pos max_parsed_pos = pos;
if (!(columns_p.parse(pos, end, columns_ast, expected) && pos == end)) if (!(columns_p.parse(pos, end, columns_ast, max_parsed_pos, expected) && pos == end))
throw Exception("Cannot parse parameters for data type " + name, ErrorCodes::SYNTAX_ERROR); throw Exception("Cannot parse parameters for data type " + name, ErrorCodes::SYNTAX_ERROR);
DataTypes elems; DataTypes elems;

View File

@ -7,6 +7,7 @@
#include <DB/IO/copyData.h> #include <DB/IO/copyData.h>
#include <DB/Parsers/ASTCreateQuery.h> #include <DB/Parsers/ASTCreateQuery.h>
#include <DB/Parsers/ParserCreateQuery.h> #include <DB/Parsers/ParserCreateQuery.h>
#include <DB/Parsers/parseQuery.h>
#include <DB/Interpreters/Context.h> #include <DB/Interpreters/Context.h>
#include <DB/Client/ConnectionPoolWithFailover.h> #include <DB/Client/ConnectionPoolWithFailover.h>
@ -356,19 +357,8 @@ ASTPtr Context::getCreateQuery(const String & database_name, const String & tabl
copyData(in, out); copyData(in, out);
} }
const char * begin = query->data();
const char * end = begin + query->size();
const char * pos = begin;
ParserCreateQuery parser; ParserCreateQuery parser;
ASTPtr ast; ASTPtr ast = parseQuery(parser, query->data(), query->data() + query->size(), "in file " + metadata_path);
Expected expected = "";
bool parse_res = parser.parse(pos, end, ast, expected);
/// Распарсенный запрос должен заканчиваться на конец входных данных или на точку с запятой.
if (!parse_res || (pos != end && *pos != ';'))
throw Exception(getSyntaxErrorMessage(parse_res, begin, end, pos, expected, "in file " + metadata_path),
DB::ErrorCodes::SYNTAX_ERROR);
ASTCreateQuery & ast_create_query = typeid_cast<ASTCreateQuery &>(*ast); ASTCreateQuery & ast_create_query = typeid_cast<ASTCreateQuery &>(*ast);
ast_create_query.attach = false; ast_create_query.attach = false;

View File

@ -11,6 +11,7 @@
#include <DB/IO/copyData.h> #include <DB/IO/copyData.h>
#include <DB/Common/escapeForFileName.h> #include <DB/Common/escapeForFileName.h>
#include <DB/Parsers/formatAST.h> #include <DB/Parsers/formatAST.h>
#include <DB/Parsers/parseQuery.h>
#include <Poco/FileStream.h> #include <Poco/FileStream.h>
@ -179,19 +180,8 @@ void InterpreterAlterQuery::updateMetadata(
copyData(in, out); copyData(in, out);
} }
const char * begin = query->data();
const char * end = begin + query->size();
const char * pos = begin;
ParserCreateQuery parser; ParserCreateQuery parser;
ASTPtr ast; ASTPtr ast = parseQuery(parser, query->data(), query->data() + query->size(), "in file " + metadata_path);
Expected expected = "";
bool parse_res = parser.parse(pos, end, ast, expected);
/// Распарсенный запрос должен заканчиваться на конец входных данных или на точку с запятой.
if (!parse_res || (pos != end && *pos != ';'))
throw Exception(getSyntaxErrorMessage(parse_res, begin, end, pos, expected, "in file " + metadata_path),
DB::ErrorCodes::SYNTAX_ERROR);
ast->query_string = query; ast->query_string = query;

View File

@ -410,7 +410,8 @@ ASTPtr InterpreterCreateQuery::formatColumns(const NamesAndTypesList & columns)
ParserIdentifierWithOptionalParameters storage_p; ParserIdentifierWithOptionalParameters storage_p;
Expected expected{""}; Expected expected{""};
if (!storage_p.parse(pos, end, column_declaration->type, expected)) IParser::Pos max_parsed_pos = pos;
if (!storage_p.parse(pos, end, column_declaration->type, max_parsed_pos, expected))
throw Exception("Cannot parse data type.", ErrorCodes::SYNTAX_ERROR); throw Exception("Cannot parse data type.", ErrorCodes::SYNTAX_ERROR);
column_declaration->type->query_string = type_name; column_declaration->type->query_string = type_name;
@ -444,7 +445,8 @@ ASTPtr InterpreterCreateQuery::formatColumns(NamesAndTypesList columns,
ParserIdentifierWithOptionalParameters storage_p; ParserIdentifierWithOptionalParameters storage_p;
Expected expected{""}; Expected expected{""};
if (!storage_p.parse(pos, end, column_declaration->type, expected)) IParser::Pos max_parsed_pos = pos;
if (!storage_p.parse(pos, end, column_declaration->type, max_parsed_pos, expected))
throw Exception("Cannot parse data type.", ErrorCodes::SYNTAX_ERROR); throw Exception("Cannot parse data type.", ErrorCodes::SYNTAX_ERROR);
column_declaration->type->query_string = type_name; column_declaration->type->query_string = type_name;

View File

@ -11,6 +11,7 @@
#include <DB/Parsers/ASTCreateQuery.h> #include <DB/Parsers/ASTCreateQuery.h>
#include <DB/Parsers/ParserCreateQuery.h> #include <DB/Parsers/ParserCreateQuery.h>
#include <DB/Parsers/formatAST.h> #include <DB/Parsers/formatAST.h>
#include <DB/Parsers/parseQuery.h>
#include <DB/Interpreters/InterpreterRenameQuery.h> #include <DB/Interpreters/InterpreterRenameQuery.h>
@ -126,16 +127,7 @@ void InterpreterRenameQuery::execute()
} }
ParserCreateQuery parser; ParserCreateQuery parser;
const char * pos = create_query.data(); ASTPtr ast = parseQuery(parser, create_query.data(), create_query.data() + create_query.size(), "in file " + elem.from_metadata_path);
const char * end = pos + create_query.size();
ASTPtr ast;
Expected expected = "";
bool parse_res = parser.parse(pos, end, ast, expected);
/// Распарсенный запрос должен заканчиваться на конец входных данных или на точку с запятой.
if (!parse_res || (pos != end && *pos != ';'))
throw Exception(getSyntaxErrorMessage(parse_res, create_query.data(), end, pos, expected, "in file " + elem.from_metadata_path),
ErrorCodes::SYNTAX_ERROR);
typeid_cast<ASTCreateQuery &>(*ast).table = elem.to_table_name; typeid_cast<ASTCreateQuery &>(*ast).table = elem.to_table_name;

View File

@ -5,6 +5,7 @@
#include <DB/DataStreams/BlockIO.h> #include <DB/DataStreams/BlockIO.h>
#include <DB/Parsers/ASTInsertQuery.h> #include <DB/Parsers/ASTInsertQuery.h>
#include <DB/Parsers/ASTShowProcesslistQuery.h> #include <DB/Parsers/ASTShowProcesslistQuery.h>
#include <DB/Parsers/parseQuery.h>
#include <DB/Interpreters/executeQuery.h> #include <DB/Interpreters/executeQuery.h>
@ -32,8 +33,6 @@ void executeQuery(
ProfileEvents::increment(ProfileEvents::Query); ProfileEvents::increment(ProfileEvents::Query);
ParserQuery parser; ParserQuery parser;
ASTPtr ast;
Expected expected = "";
PODArray<char> parse_buf; PODArray<char> parse_buf;
const char * begin; const char * begin;
@ -61,21 +60,10 @@ void executeQuery(
end = begin + parse_buf.size(); end = begin + parse_buf.size();
} }
const char * pos = begin; ASTPtr ast = parseQuery(parser, begin, end, "");
bool parse_res = parser.parse(pos, end, ast, expected);
if (pos == begin && (end == begin || *pos == ';'))
throw Exception("Empty query", ErrorCodes::EMPTY_QUERY);
/// Распарсенный запрос должен заканчиваться на конец входных данных или на точку с запятой.
if (!parse_res || (pos != end && *pos != ';'))
throw Exception(getSyntaxErrorMessage(parse_res, begin, end, pos, expected),
ErrorCodes::SYNTAX_ERROR);
/// Засунем запрос в строку. Она выводится в лог и в processlist. Если запрос INSERT, то не будем включать данные для вставки. /// Засунем запрос в строку. Она выводится в лог и в processlist. Если запрос INSERT, то не будем включать данные для вставки.
auto insert = typeid_cast<const ASTInsertQuery *>(&*ast); size_t query_size = ast->range.second - ast->range.first;
size_t query_size = (insert && insert->data) ? (insert->data - begin) : (pos - begin);
if (query_size > max_query_size) if (query_size > max_query_size)
throw Exception("Query is too large (" + toString(query_size) + ")." throw Exception("Query is too large (" + toString(query_size) + ")."
@ -132,22 +120,7 @@ BlockIO executeQuery(
ProfileEvents::increment(ProfileEvents::Query); ProfileEvents::increment(ProfileEvents::Query);
ParserQuery parser; ParserQuery parser;
ASTPtr ast; ASTPtr ast = parseQuery(parser, query.data(), query.data() + query.size(), "");
Expected expected = "";
const char * begin = query.data();
const char * end = begin + query.size();
const char * pos = begin;
bool parse_res = parser.parse(pos, end, ast, expected);
if (pos == begin && (end == begin || *pos == ';'))
throw Exception("Empty query", ErrorCodes::EMPTY_QUERY);
/// Распарсенный запрос должен заканчиваться на конец входных данных или на точку с запятой.
if (!parse_res || (pos != end && *pos != ';'))
throw Exception(getSyntaxErrorMessage(parse_res, begin, end, pos, expected),
ErrorCodes::SYNTAX_ERROR);
/// Проверка ограничений. /// Проверка ограничений.
checkLimits(*ast, context.getSettingsRef().limits); checkLimits(*ast, context.getSettingsRef().limits);

View File

@ -5,6 +5,7 @@
#include <DB/Parsers/ParserCreateQuery.h> #include <DB/Parsers/ParserCreateQuery.h>
#include <DB/Parsers/ASTCreateQuery.h> #include <DB/Parsers/ASTCreateQuery.h>
#include <DB/Parsers/parseQuery.h>
#include <DB/Interpreters/InterpreterCreateQuery.h> #include <DB/Interpreters/InterpreterCreateQuery.h>
#include <DB/Interpreters/loadMetadata.h> #include <DB/Interpreters/loadMetadata.h>
@ -22,19 +23,8 @@ namespace DB
static void executeCreateQuery(const String & query, Context & context, const String & database, const String & file_name) static void executeCreateQuery(const String & query, Context & context, const String & database, const String & file_name)
{ {
const char * begin = query.data();
const char * end = begin + query.size();
const char * pos = begin;
ParserCreateQuery parser; ParserCreateQuery parser;
ASTPtr ast; ASTPtr ast = parseQuery(parser, query.data(), query.data() + query.size(), "in file " + file_name);
Expected expected = "";
bool parse_res = parser.parse(pos, end, ast, expected);
/// Распарсенный запрос должен заканчиваться на конец входных данных или на точку с запятой.
if (!parse_res || (pos != end && *pos != ';'))
throw Exception(getSyntaxErrorMessage(parse_res, begin, end, pos, expected, "in file " + file_name),
DB::ErrorCodes::SYNTAX_ERROR);
ASTCreateQuery & ast_create_query = typeid_cast<ASTCreateQuery &>(*ast); ASTCreateQuery & ast_create_query = typeid_cast<ASTCreateQuery &>(*ast);
ast_create_query.attach = true; ast_create_query.attach = true;

View File

@ -79,7 +79,7 @@ int main(int argc, char ** argv)
const char * end = begin + input.size(); const char * end = begin + input.size();
const char * pos = begin; const char * pos = begin;
if (parser.parse(pos, end, ast, expected)) if (parser.parse(pos, end, ast, max_parsed_pos, expected))
{ {
std::cout << "Success." << std::endl; std::cout << "Success." << std::endl;
formatAST(*ast, std::cout); formatAST(*ast, std::cout);

View File

@ -45,7 +45,7 @@ int main(int argc, char ** argv)
const char * end = begin + input.size(); const char * end = begin + input.size();
const char * pos = begin; const char * pos = begin;
if (parser.parse(pos, end, ast, expected)) if (parser.parse(pos, end, ast, max_parsed_pos, expected))
{ {
std::cout << "Success." << std::endl; std::cout << "Success." << std::endl;
formatAST(*ast, std::cout); formatAST(*ast, std::cout);

View File

@ -233,7 +233,7 @@ bool parse(DB::ASTPtr & ast, const std::string & query)
const char * end = &query[0] + query.size(); const char * end = &query[0] + query.size();
DB::Expected expected = ""; DB::Expected expected = "";
return parser.parse(pos, end, ast, expected); return parser.parse(pos, end, ast, max_parsed_pos, expected);
} }
bool equals(const DB::ASTPtr & lhs, const DB::ASTPtr & rhs) bool equals(const DB::ASTPtr & lhs, const DB::ASTPtr & rhs)

View File

@ -24,7 +24,7 @@ namespace DB
{ {
bool ParserArray::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserArray::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
Pos begin = pos; Pos begin = pos;
ASTPtr contents_node; ASTPtr contents_node;
@ -32,15 +32,15 @@ bool ParserArray::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expect
ParserExpressionList contents; ParserExpressionList contents;
ParserWhiteSpaceOrComments ws; ParserWhiteSpaceOrComments ws;
if (!open.ignore(pos, end, expected)) if (!open.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!contents.parse(pos, end, contents_node, expected)) if (!contents.parse(pos, end, contents_node, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!close.ignore(pos, end, expected)) if (!close.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ASTFunction * function_node = new ASTFunction(StringRange(begin, pos)); ASTFunction * function_node = new ASTFunction(StringRange(begin, pos));
@ -53,7 +53,7 @@ bool ParserArray::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expect
} }
bool ParserParenthesisExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserParenthesisExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
Pos begin = pos; Pos begin = pos;
ASTPtr contents_node; ASTPtr contents_node;
@ -61,15 +61,15 @@ bool ParserParenthesisExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, E
ParserExpressionList contents; ParserExpressionList contents;
ParserWhiteSpaceOrComments ws; ParserWhiteSpaceOrComments ws;
if (!open.ignore(pos, end, expected)) if (!open.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!contents.parse(pos, end, contents_node, expected)) if (!contents.parse(pos, end, contents_node, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!close.ignore(pos, end, expected)) if (!close.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ASTExpressionList & expr_list = typeid_cast<ASTExpressionList &>(*contents_node); ASTExpressionList & expr_list = typeid_cast<ASTExpressionList &>(*contents_node);
@ -98,7 +98,7 @@ bool ParserParenthesisExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, E
} }
bool ParserSubquery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserSubquery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
Pos begin = pos; Pos begin = pos;
ASTPtr select_node; ASTPtr select_node;
@ -106,15 +106,15 @@ bool ParserSubquery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & exp
ParserSelectQuery select; ParserSelectQuery select;
ParserWhiteSpaceOrComments ws; ParserWhiteSpaceOrComments ws;
if (!open.ignore(pos, end, expected)) if (!open.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!select.parse(pos, end, select_node, expected)) if (!select.parse(pos, end, select_node, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!close.ignore(pos, end, expected)) if (!close.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
node = new ASTSubquery(StringRange(begin, pos)); node = new ASTSubquery(StringRange(begin, pos));
@ -123,7 +123,7 @@ bool ParserSubquery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & exp
} }
bool ParserIdentifier::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserIdentifier::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
Pos begin = pos; Pos begin = pos;
@ -161,7 +161,7 @@ bool ParserIdentifier::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & e
} }
bool ParserCompoundIdentifier::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserCompoundIdentifier::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
Pos begin = pos; Pos begin = pos;
@ -206,7 +206,7 @@ bool ParserCompoundIdentifier::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expe
} }
bool ParserFunction::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserFunction::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
Pos begin = pos; Pos begin = pos;
@ -219,22 +219,22 @@ bool ParserFunction::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & exp
ASTPtr expr_list_args; ASTPtr expr_list_args;
ASTPtr expr_list_params; ASTPtr expr_list_params;
if (!id_parser.parse(pos, end, identifier, expected)) if (!id_parser.parse(pos, end, identifier, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!open.ignore(pos, end, expected)) if (!open.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
Pos contents_begin = pos; Pos contents_begin = pos;
if (!contents.parse(pos, end, expr_list_args, expected)) if (!contents.parse(pos, end, expr_list_args, max_parsed_pos, expected))
return false; return false;
Pos contents_end = pos; Pos contents_end = pos;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!close.ignore(pos, end, expected)) if (!close.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
/** Проверка на распространённый случай ошибки - часто из-за сложности квотирования аргументов командной строки, /** Проверка на распространённый случай ошибки - часто из-за сложности квотирования аргументов командной строки,
@ -261,17 +261,17 @@ bool ParserFunction::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & exp
} }
/// У параметрической агрегатной функции - два списка (параметры и аргументы) в круглых скобках. Пример: quantile(0.9)(x). /// У параметрической агрегатной функции - два списка (параметры и аргументы) в круглых скобках. Пример: quantile(0.9)(x).
if (open.ignore(pos, end, expected)) if (open.ignore(pos, end, max_parsed_pos, expected))
{ {
expr_list_params = expr_list_args; expr_list_params = expr_list_args;
expr_list_args = nullptr; expr_list_args = nullptr;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!contents.parse(pos, end, expr_list_args, expected)) if (!contents.parse(pos, end, expr_list_args, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!close.ignore(pos, end, expected)) if (!close.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
} }
@ -292,11 +292,11 @@ bool ParserFunction::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & exp
} }
bool ParserNull::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserNull::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
Pos begin = pos; Pos begin = pos;
ParserString nested_parser("NULL", true); ParserString nested_parser("NULL", true);
if (nested_parser.parse(pos, end, node, expected)) if (nested_parser.parse(pos, end, node, max_parsed_pos, expected))
{ {
node = new ASTLiteral(StringRange(StringRange(begin, pos)), Null()); node = new ASTLiteral(StringRange(StringRange(begin, pos)), Null());
return true; return true;
@ -306,7 +306,7 @@ bool ParserNull::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expecte
} }
bool ParserNumber::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserNumber::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
Field res; Field res;
@ -357,7 +357,7 @@ bool ParserNumber::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expec
} }
bool ParserStringLiteral::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserStringLiteral::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
Pos begin = pos; Pos begin = pos;
String s; String s;
@ -405,7 +405,7 @@ bool ParserStringLiteral::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected
} }
bool ParserLiteral::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserLiteral::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
Pos begin = pos; Pos begin = pos;
@ -413,15 +413,15 @@ bool ParserLiteral::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expe
ParserNumber num_p; ParserNumber num_p;
ParserStringLiteral str_p; ParserStringLiteral str_p;
if (null_p.parse(pos, end, node, expected)) if (null_p.parse(pos, end, node, max_parsed_pos, expected))
return true; return true;
pos = begin; pos = begin;
if (num_p.parse(pos, end, node, expected)) if (num_p.parse(pos, end, node, max_parsed_pos, expected))
return true; return true;
pos = begin; pos = begin;
if (str_p.parse(pos, end, node, expected)) if (str_p.parse(pos, end, node, max_parsed_pos, expected))
return true; return true;
pos = begin; pos = begin;
@ -430,25 +430,25 @@ bool ParserLiteral::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expe
} }
bool ParserAlias::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserAlias::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
ParserWhiteSpaceOrComments ws; ParserWhiteSpaceOrComments ws;
ParserString s_as("AS", true, true); ParserString s_as("AS", true, true);
ParserIdentifier id_p; ParserIdentifier id_p;
if (!s_as.parse(pos, end, node, expected)) if (!s_as.parse(pos, end, node, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!id_p.parse(pos, end, node, expected)) if (!id_p.parse(pos, end, node, max_parsed_pos, expected))
return false; return false;
return true; return true;
} }
bool ParserExpressionElement::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserExpressionElement::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
Pos begin = pos; Pos begin = pos;
@ -460,31 +460,31 @@ bool ParserExpressionElement::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expec
ParserCompoundIdentifier id_p; ParserCompoundIdentifier id_p;
ParserString asterisk_p("*"); ParserString asterisk_p("*");
if (subquery_p.parse(pos, end, node, expected)) if (subquery_p.parse(pos, end, node, max_parsed_pos, expected))
return true; return true;
pos = begin; pos = begin;
if (paren_p.parse(pos, end, node, expected)) if (paren_p.parse(pos, end, node, max_parsed_pos, expected))
return true; return true;
pos = begin; pos = begin;
if (array_p.parse(pos, end, node, expected)) if (array_p.parse(pos, end, node, max_parsed_pos, expected))
return true; return true;
pos = begin; pos = begin;
if (lit_p.parse(pos, end, node, expected)) if (lit_p.parse(pos, end, node, max_parsed_pos, expected))
return true; return true;
pos = begin; pos = begin;
if (fun_p.parse(pos, end, node, expected)) if (fun_p.parse(pos, end, node, max_parsed_pos, expected))
return true; return true;
pos = begin; pos = begin;
if (id_p.parse(pos, end, node, expected)) if (id_p.parse(pos, end, node, max_parsed_pos, expected))
return true; return true;
pos = begin; pos = begin;
if (asterisk_p.parse(pos, end, node, expected)) if (asterisk_p.parse(pos, end, node, max_parsed_pos, expected))
{ {
node = new ASTAsterisk(StringRange(begin, pos)); node = new ASTAsterisk(StringRange(begin, pos));
return true; return true;
@ -496,18 +496,18 @@ bool ParserExpressionElement::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expec
} }
bool ParserWithOptionalAlias::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserWithOptionalAlias::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
ParserWhiteSpaceOrComments ws; ParserWhiteSpaceOrComments ws;
ParserAlias alias_p; ParserAlias alias_p;
if (!elem_parser->parse(pos, end, node, expected)) if (!elem_parser->parse(pos, end, node, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
ASTPtr alias_node; ASTPtr alias_node;
if (alias_p.parse(pos, end, alias_node, expected)) if (alias_p.parse(pos, end, alias_node, max_parsed_pos, expected))
{ {
String alias_name = typeid_cast<ASTIdentifier &>(*alias_node).name; String alias_name = typeid_cast<ASTIdentifier &>(*alias_node).name;
@ -528,7 +528,7 @@ bool ParserWithOptionalAlias::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expec
} }
bool ParserOrderByElement::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserOrderByElement::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
Pos begin = pos; Pos begin = pos;
@ -542,7 +542,7 @@ bool ParserOrderByElement::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected
ParserStringLiteral collate_locale_parser; ParserStringLiteral collate_locale_parser;
ASTPtr expr_elem; ASTPtr expr_elem;
if (!elem_p.parse(pos, end, expr_elem, expected)) if (!elem_p.parse(pos, end, expr_elem, max_parsed_pos, expected))
return false; return false;
int direction = 1; int direction = 1;
@ -561,7 +561,7 @@ bool ParserOrderByElement::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected
ws.ignore(pos, end); ws.ignore(pos, end);
ASTPtr locale_node; ASTPtr locale_node;
if (!collate_locale_parser.parse(pos, end, locale_node, expected)) if (!collate_locale_parser.parse(pos, end, locale_node, max_parsed_pos, expected))
return false; return false;
const String & locale = typeid_cast<const ASTLiteral &>(*locale_node).value.safeGet<String>(); const String & locale = typeid_cast<const ASTLiteral &>(*locale_node).value.safeGet<String>();

View File

@ -67,7 +67,7 @@ const char * ParserAccessExpression::operators[] =
bool ParserList::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserList::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
bool first = true; bool first = true;
ParserWhiteSpaceOrComments ws; ParserWhiteSpaceOrComments ws;
@ -80,7 +80,7 @@ bool ParserList::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expecte
if (first) if (first)
{ {
ASTPtr elem; ASTPtr elem;
if (!elem_parser->parse(pos, end, elem, expected)) if (!elem_parser->parse(pos, end, elem, max_parsed_pos, expected))
break; break;
list->children.push_back(elem); list->children.push_back(elem);
@ -89,12 +89,12 @@ bool ParserList::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expecte
else else
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (!separator_parser->ignore(pos, end, expected)) if (!separator_parser->ignore(pos, end, max_parsed_pos, expected))
break; break;
ws.ignore(pos, end); ws.ignore(pos, end);
ASTPtr elem; ASTPtr elem;
if (!elem_parser->parse(pos, end, elem, expected)) if (!elem_parser->parse(pos, end, elem, max_parsed_pos, expected))
return false; return false;
list->children.push_back(elem); list->children.push_back(elem);
@ -108,7 +108,7 @@ bool ParserList::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expecte
} }
bool ParserLeftAssociativeBinaryOperatorList::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserLeftAssociativeBinaryOperatorList::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
bool first = true; bool first = true;
ParserWhiteSpaceOrComments ws; ParserWhiteSpaceOrComments ws;
@ -118,7 +118,7 @@ bool ParserLeftAssociativeBinaryOperatorList::parseImpl(Pos & pos, Pos end, ASTP
if (first) if (first)
{ {
ASTPtr elem; ASTPtr elem;
if (!first_elem_parser->parse(pos, end, elem, expected)) if (!first_elem_parser->parse(pos, end, elem, max_parsed_pos, expected))
return false; return false;
node = elem; node = elem;
@ -135,7 +135,7 @@ bool ParserLeftAssociativeBinaryOperatorList::parseImpl(Pos & pos, Pos end, ASTP
for (it = operators; *it; it += 2) for (it = operators; *it; it += 2)
{ {
ParserString op(it[0], true, true); ParserString op(it[0], true, true);
if (op.ignore(pos, end, expected)) if (op.ignore(pos, end, max_parsed_pos, expected))
break; break;
} }
@ -155,7 +155,7 @@ bool ParserLeftAssociativeBinaryOperatorList::parseImpl(Pos & pos, Pos end, ASTP
ASTPtr exp_list_node = p_exp_list; ASTPtr exp_list_node = p_exp_list;
ASTPtr elem; ASTPtr elem;
if (!(remaining_elem_parser ? remaining_elem_parser : first_elem_parser)->parse(pos, end, elem, expected)) if (!(remaining_elem_parser ? remaining_elem_parser : first_elem_parser)->parse(pos, end, elem, max_parsed_pos, expected))
return false; return false;
/// первым аргументом функции будет предыдущий элемент, вторым - следующий /// первым аргументом функции будет предыдущий элемент, вторым - следующий
@ -178,7 +178,7 @@ bool ParserLeftAssociativeBinaryOperatorList::parseImpl(Pos & pos, Pos end, ASTP
ParserString rest_p("]"); ParserString rest_p("]");
ws.ignore(pos, end); ws.ignore(pos, end);
if (!rest_p.ignore(pos, end, expected)) if (!rest_p.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
} }
@ -189,21 +189,21 @@ bool ParserLeftAssociativeBinaryOperatorList::parseImpl(Pos & pos, Pos end, ASTP
return true; return true;
} }
bool ParserVariableArityOperatorList::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserVariableArityOperatorList::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
ParserWhiteSpaceOrComments ws; ParserWhiteSpaceOrComments ws;
Pos begin = pos; Pos begin = pos;
ASTPtr arguments; ASTPtr arguments;
if (!elem_parser->parse(pos, end, node, expected)) if (!elem_parser->parse(pos, end, node, max_parsed_pos, expected))
return false; return false;
while (true) while (true)
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (!infix_parser.ignore(pos, end, expected)) if (!infix_parser.ignore(pos, end, max_parsed_pos, expected))
break; break;
ws.ignore(pos, end); ws.ignore(pos, end);
@ -215,7 +215,7 @@ bool ParserVariableArityOperatorList::parseImpl(Pos & pos, Pos end, ASTPtr & nod
} }
ASTPtr elem; ASTPtr elem;
if (!elem_parser->parse(pos, end, elem, expected)) if (!elem_parser->parse(pos, end, elem, max_parsed_pos, expected))
return false; return false;
arguments->children.push_back(elem); arguments->children.push_back(elem);
@ -227,7 +227,7 @@ bool ParserVariableArityOperatorList::parseImpl(Pos & pos, Pos end, ASTPtr & nod
return true; return true;
} }
bool ParserTernaryOperatorExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserTernaryOperatorExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
ParserWhiteSpaceOrComments ws; ParserWhiteSpaceOrComments ws;
ParserString symbol1("?"); ParserString symbol1("?");
@ -239,28 +239,28 @@ bool ParserTernaryOperatorExpression::parseImpl(Pos & pos, Pos end, ASTPtr & nod
Pos begin = pos; Pos begin = pos;
if (!elem_parser.parse(pos, end, elem_cond, expected)) if (!elem_parser.parse(pos, end, elem_cond, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!symbol1.ignore(pos, end, expected)) if (!symbol1.ignore(pos, end, max_parsed_pos, expected))
node = elem_cond; node = elem_cond;
else else
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (!elem_parser.parse(pos, end, elem_then, expected)) if (!elem_parser.parse(pos, end, elem_then, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!symbol2.ignore(pos, end, expected)) if (!symbol2.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!elem_parser.parse(pos, end, elem_else, expected)) if (!elem_parser.parse(pos, end, elem_else, max_parsed_pos, expected))
return false; return false;
/// функция, соответствующая оператору /// функция, соответствующая оператору
@ -292,7 +292,7 @@ bool ParserTernaryOperatorExpression::parseImpl(Pos & pos, Pos end, ASTPtr & nod
} }
bool ParserLambdaExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserLambdaExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
ParserWhiteSpaceOrComments ws; ParserWhiteSpaceOrComments ws;
ParserString arrow("->"); ParserString arrow("->");
@ -308,28 +308,28 @@ bool ParserLambdaExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expect
bool was_open = false; bool was_open = false;
if (open.ignore(pos, end, expected)) if (open.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end, expected); ws.ignore(pos, end, max_parsed_pos, expected);
was_open = true; was_open = true;
} }
if (!ParserList(ParserPtr(new ParserIdentifier), ParserPtr(new ParserString(","))).parse(pos, end, inner_arguments, expected)) if (!ParserList(ParserPtr(new ParserIdentifier), ParserPtr(new ParserString(","))).parse(pos, end, inner_arguments, max_parsed_pos, expected))
break; break;
ws.ignore(pos, end, expected); ws.ignore(pos, end, max_parsed_pos, expected);
if (was_open) if (was_open)
{ {
if (!close.ignore(pos, end, expected)) if (!close.ignore(pos, end, max_parsed_pos, expected))
break; break;
ws.ignore(pos, end, expected); ws.ignore(pos, end, max_parsed_pos, expected);
} }
if (!arrow.ignore(pos, end, expected)) if (!arrow.ignore(pos, end, max_parsed_pos, expected))
break; break;
ws.ignore(pos, end, expected); ws.ignore(pos, end, max_parsed_pos, expected);
if (!elem_parser.parse(pos, end, expression, expected)) if (!elem_parser.parse(pos, end, expression, max_parsed_pos, expected))
{ {
pos = begin; pos = begin;
return false; return false;
@ -358,11 +358,11 @@ bool ParserLambdaExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expect
while (false); while (false);
pos = begin; pos = begin;
return elem_parser.parse(pos, end, node, expected); return elem_parser.parse(pos, end, node, max_parsed_pos, expected);
} }
bool ParserPrefixUnaryOperatorExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserPrefixUnaryOperatorExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
ParserWhiteSpaceOrComments ws; ParserWhiteSpaceOrComments ws;
@ -372,14 +372,14 @@ bool ParserPrefixUnaryOperatorExpression::parseImpl(Pos & pos, Pos end, ASTPtr &
for (it = operators; *it; it += 2) for (it = operators; *it; it += 2)
{ {
ParserString op(it[0], true, true); ParserString op(it[0], true, true);
if (op.ignore(pos, end, expected)) if (op.ignore(pos, end, max_parsed_pos, expected))
break; break;
} }
ws.ignore(pos, end); ws.ignore(pos, end);
ASTPtr elem; ASTPtr elem;
if (!elem_parser->parse(pos, end, elem, expected)) if (!elem_parser->parse(pos, end, elem, max_parsed_pos, expected))
return false; return false;
if (!*it) if (!*it)
@ -413,7 +413,7 @@ bool ParserPrefixUnaryOperatorExpression::parseImpl(Pos & pos, Pos end, ASTPtr &
} }
bool ParserUnaryMinusExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserUnaryMinusExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
/// В качестве исключения, отрицательные числа должны парситься, как литералы, а не как применение оператора. /// В качестве исключения, отрицательные числа должны парситься, как литералы, а не как применение оператора.
@ -422,23 +422,23 @@ bool ParserUnaryMinusExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, Ex
ParserLiteral lit_p; ParserLiteral lit_p;
Pos begin = pos; Pos begin = pos;
if (lit_p.parse(pos, end, node, expected)) if (lit_p.parse(pos, end, node, max_parsed_pos, expected))
return true; return true;
pos = begin; pos = begin;
} }
return operator_parser.parse(pos, end, node, expected); return operator_parser.parse(pos, end, node, max_parsed_pos, expected);
} }
bool ParserAccessExpression::parseImpl(Pos &pos, Pos end, ASTPtr &node, Expected &expected) bool ParserAccessExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected &expected)
{ {
return ParserLeftAssociativeBinaryOperatorList{ return ParserLeftAssociativeBinaryOperatorList{
operators, operators,
ParserPtr(new ParserExpressionElement), ParserPtr(new ParserExpressionElement),
ParserPtr(new ParserExpressionWithOptionalAlias) ParserPtr(new ParserExpressionWithOptionalAlias)
}.parse(pos, end, node, expected); }.parse(pos, end, node, max_parsed_pos, expected);
} }
@ -448,22 +448,22 @@ ParserExpressionWithOptionalAlias::ParserExpressionWithOptionalAlias()
} }
bool ParserExpressionList::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserExpressionList::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
return ParserList(ParserPtr(new ParserExpressionWithOptionalAlias), ParserPtr(new ParserString(","))).parse(pos, end, node, expected); return ParserList(ParserPtr(new ParserExpressionWithOptionalAlias), ParserPtr(new ParserString(","))).parse(pos, end, node, max_parsed_pos, expected);
} }
bool ParserNotEmptyExpressionList::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserNotEmptyExpressionList::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
return nested_parser.parse(pos, end, node, expected) return nested_parser.parse(pos, end, node, max_parsed_pos, expected)
&& !typeid_cast<ASTExpressionList &>(*node).children.empty(); && !typeid_cast<ASTExpressionList &>(*node).children.empty();
} }
bool ParserOrderByExpressionList::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserOrderByExpressionList::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
return ParserList(ParserPtr(new ParserOrderByElement), ParserPtr(new ParserString(",")), false).parse(pos, end, node, expected); return ParserList(ParserPtr(new ParserOrderByElement), ParserPtr(new ParserString(",")), false).parse(pos, end, node, max_parsed_pos, expected);
} }

View File

@ -9,7 +9,7 @@
namespace DB namespace DB
{ {
bool ParserAlterQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserAlterQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
Pos begin = pos; Pos begin = pos;
@ -50,22 +50,22 @@ bool ParserAlterQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & e
ASTPtr query_ptr = query; ASTPtr query_ptr = query;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_alter.ignore(pos, end, expected)) if (!s_alter.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_table.ignore(pos, end, expected)) if (!s_table.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!table_parser.parse(pos, end, database, expected)) if (!table_parser.parse(pos, end, database, max_parsed_pos, expected))
return false; return false;
/// Parse [db].name /// Parse [db].name
if (s_dot.ignore(pos, end)) if (s_dot.ignore(pos, end))
{ {
if (!table_parser.parse(pos, end, table, expected)) if (!table_parser.parse(pos, end, table, max_parsed_pos, expected))
return false; return false;
query->table = typeid_cast<ASTIdentifier &>(*table).name; query->table = typeid_cast<ASTIdentifier &>(*table).name;
@ -83,44 +83,44 @@ bool ParserAlterQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & e
ASTAlterQuery::Parameters params; ASTAlterQuery::Parameters params;
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_add.ignore(pos, end, expected)) if (s_add.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_column.ignore(pos, end, expected)) if (!s_column.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
parser_col_decl.parse(pos, end, params.col_decl, expected); parser_col_decl.parse(pos, end, params.col_decl, max_parsed_pos, expected);
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_after.ignore(pos, end, expected)) if (s_after.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if(!parser_name.parse(pos, end, params.column, expected)) if(!parser_name.parse(pos, end, params.column, max_parsed_pos, expected))
return false; return false;
} }
params.type = ASTAlterQuery::ADD_COLUMN; params.type = ASTAlterQuery::ADD_COLUMN;
} }
else if (s_drop.ignore(pos, end, expected)) else if (s_drop.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_partition.ignore(pos, end, expected)) if (s_partition.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (!parser_literal.parse(pos, end, params.partition, expected)) if (!parser_literal.parse(pos, end, params.partition, max_parsed_pos, expected))
return false; return false;
params.type = ASTAlterQuery::DROP_PARTITION; params.type = ASTAlterQuery::DROP_PARTITION;
} }
else if (s_column.ignore(pos, end, expected)) else if (s_column.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (!parser_name.parse(pos, end, params.column, expected)) if (!parser_name.parse(pos, end, params.column, max_parsed_pos, expected))
return false; return false;
params.type = ASTAlterQuery::DROP_COLUMN; params.type = ASTAlterQuery::DROP_COLUMN;
@ -129,93 +129,93 @@ bool ParserAlterQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & e
else else
return false; return false;
} }
else if (s_detach.ignore(pos, end, expected)) else if (s_detach.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_partition.ignore(pos, end, expected)) if (!s_partition.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!parser_literal.parse(pos, end, params.partition, expected)) if (!parser_literal.parse(pos, end, params.partition, max_parsed_pos, expected))
return false; return false;
params.type = ASTAlterQuery::DROP_PARTITION; params.type = ASTAlterQuery::DROP_PARTITION;
params.detach = true; params.detach = true;
} }
else if (s_attach.ignore(pos, end, expected)) else if (s_attach.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_unreplicated.ignore(pos, end, expected)) if (s_unreplicated.ignore(pos, end, max_parsed_pos, expected))
{ {
params.unreplicated = true; params.unreplicated = true;
ws.ignore(pos, end); ws.ignore(pos, end);
} }
if (s_part.ignore(pos, end, expected)) if (s_part.ignore(pos, end, max_parsed_pos, expected))
params.part = true; params.part = true;
else if (!s_partition.ignore(pos, end, expected)) else if (!s_partition.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!parser_literal.parse(pos, end, params.partition, expected)) if (!parser_literal.parse(pos, end, params.partition, max_parsed_pos, expected))
return false; return false;
params.type = ASTAlterQuery::ATTACH_PARTITION; params.type = ASTAlterQuery::ATTACH_PARTITION;
} }
else if (s_fetch.ignore(pos, end, expected)) else if (s_fetch.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_partition.ignore(pos, end, expected)) if (!s_partition.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!parser_literal.parse(pos, end, params.partition, expected)) if (!parser_literal.parse(pos, end, params.partition, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_from.ignore(pos, end, expected)) if (!s_from.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
ASTPtr ast_from; ASTPtr ast_from;
if (!parser_string_literal.parse(pos, end, ast_from, expected)) if (!parser_string_literal.parse(pos, end, ast_from, max_parsed_pos, expected))
return false; return false;
params.from = typeid_cast<const ASTLiteral &>(*ast_from).value.get<const String &>(); params.from = typeid_cast<const ASTLiteral &>(*ast_from).value.get<const String &>();
params.type = ASTAlterQuery::FETCH_PARTITION; params.type = ASTAlterQuery::FETCH_PARTITION;
} }
else if (s_freeze.ignore(pos, end, expected)) else if (s_freeze.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_partition.ignore(pos, end, expected)) if (!s_partition.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!parser_literal.parse(pos, end, params.partition, expected)) if (!parser_literal.parse(pos, end, params.partition, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
params.type = ASTAlterQuery::FREEZE_PARTITION; params.type = ASTAlterQuery::FREEZE_PARTITION;
} }
else if (s_modify.ignore(pos, end, expected)) else if (s_modify.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_column.ignore(pos, end, expected)) if (!s_column.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!parser_col_decl.parse(pos, end, params.col_decl, expected)) if (!parser_col_decl.parse(pos, end, params.col_decl, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
@ -227,7 +227,7 @@ bool ParserAlterQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & e
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_comma.ignore(pos, end, expected)) if (!s_comma.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
parsing_finished = true; parsing_finished = true;

View File

@ -6,7 +6,7 @@
using namespace DB; using namespace DB;
bool ParserCheckQuery::parseImpl(IParser::Pos& pos, IParser::Pos end, ASTPtr& node, Expected& expected) bool ParserCheckQuery::parseImpl(IParser::Pos & pos, IParser::Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
ParserWhiteSpaceOrComments ws; ParserWhiteSpaceOrComments ws;
ParserString s_check("CHECK", true, true); ParserString s_check("CHECK", true, true);
@ -22,19 +22,19 @@ bool ParserCheckQuery::parseImpl(IParser::Pos& pos, IParser::Pos end, ASTPtr& no
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_check.ignore(pos, end, expected)) if (!s_check.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
s_table.ignore(pos, end, expected); s_table.ignore(pos, end, max_parsed_pos, expected);
ws.ignore(pos, end); ws.ignore(pos, end);
if (!table_parser.parse(pos, end, database, expected)) if (!table_parser.parse(pos, end, database, max_parsed_pos, expected))
return false; return false;
if (s_dot.ignore(pos, end)) if (s_dot.ignore(pos, end))
{ {
if (!table_parser.parse(pos, end, table, expected)) if (!table_parser.parse(pos, end, table, max_parsed_pos, expected))
return false; return false;
query->database = typeid_cast<ASTIdentifier &>(*database).name; query->database = typeid_cast<ASTIdentifier &>(*database).name;

View File

@ -10,7 +10,7 @@
namespace DB namespace DB
{ {
bool ParserNestedTable::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserNestedTable::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
ParserWhiteSpaceOrComments ws; ParserWhiteSpaceOrComments ws;
ParserString open("("); ParserString open("(");
@ -24,7 +24,7 @@ bool ParserNestedTable::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected &
Pos begin = pos; Pos begin = pos;
/// Пока name == 'Nested', возможно потом появятся альтернативные вложенные структуры данных /// Пока name == 'Nested', возможно потом появятся альтернативные вложенные структуры данных
if (!name_p.parse(pos, end, name, expected)) if (!name_p.parse(pos, end, name, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
@ -34,7 +34,7 @@ bool ParserNestedTable::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected &
ws.ignore(pos, end); ws.ignore(pos, end);
if (!columns_p.parse(pos, end, columns, expected)) if (!columns_p.parse(pos, end, columns, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
@ -52,18 +52,18 @@ bool ParserNestedTable::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected &
} }
bool ParserIdentifierWithParameters::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserIdentifierWithParameters::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
Pos begin = pos; Pos begin = pos;
ParserFunction function_or_array; ParserFunction function_or_array;
if (function_or_array.parse(pos, end, node, expected)) if (function_or_array.parse(pos, end, node, max_parsed_pos, expected))
return true; return true;
pos = begin; pos = begin;
ParserNestedTable nested; ParserNestedTable nested;
if (nested.parse(pos, end, node, expected)) if (nested.parse(pos, end, node, max_parsed_pos, expected))
return true; return true;
pos = begin; pos = begin;
@ -72,21 +72,21 @@ bool ParserIdentifierWithParameters::parseImpl(Pos & pos, Pos end, ASTPtr & node
} }
bool ParserIdentifierWithOptionalParameters::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserIdentifierWithOptionalParameters::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
ParserIdentifier non_parametric; ParserIdentifier non_parametric;
ParserIdentifierWithParameters parametric; ParserIdentifierWithParameters parametric;
Pos begin = pos; Pos begin = pos;
if (parametric.parse(pos, end, node, expected)) if (parametric.parse(pos, end, node, max_parsed_pos, expected))
{ {
return true; return true;
} }
pos = begin; pos = begin;
ASTPtr ident; ASTPtr ident;
if (non_parametric.parse(pos, end, ident, expected)) if (non_parametric.parse(pos, end, ident, max_parsed_pos, expected))
{ {
ASTFunction * func = new ASTFunction(StringRange(begin, pos)); ASTFunction * func = new ASTFunction(StringRange(begin, pos));
node = func; node = func;
@ -98,18 +98,18 @@ bool ParserIdentifierWithOptionalParameters::parseImpl(Pos & pos, Pos end, ASTPt
return false; return false;
} }
bool ParserNameTypePairList::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserNameTypePairList::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
return ParserList(ParserPtr(new ParserNameTypePair), ParserPtr(new ParserString(",")), false).parse(pos, end, node, expected); return ParserList(ParserPtr(new ParserNameTypePair), ParserPtr(new ParserString(",")), false).parse(pos, end, node, max_parsed_pos, expected);
} }
bool ParserColumnDeclarationList::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserColumnDeclarationList::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
return ParserList{ParserPtr{new ParserColumnDeclaration}, ParserPtr{new ParserString{","}}, false}.parse(pos, end, node, expected); return ParserList{ParserPtr{new ParserColumnDeclaration}, ParserPtr{new ParserString{","}}, false}.parse(pos, end, node, max_parsed_pos, expected);
} }
bool ParserEngine::parseImpl(Pos & pos, Pos end, ASTPtr & storage, Expected & expected) bool ParserEngine::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
ParserWhiteSpaceOrComments ws; ParserWhiteSpaceOrComments ws;
ParserString s_engine("ENGINE", true, true); ParserString s_engine("ENGINE", true, true);
@ -118,16 +118,16 @@ bool ParserEngine::parseImpl(Pos & pos, Pos end, ASTPtr & storage, Expected & ex
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_engine.ignore(pos, end, expected)) if (s_engine.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_eq.ignore(pos, end, expected)) if (!s_eq.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!storage_p.parse(pos, end, storage, expected)) if (!storage_p.parse(pos, end, node, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
@ -137,7 +137,7 @@ bool ParserEngine::parseImpl(Pos & pos, Pos end, ASTPtr & storage, Expected & ex
} }
bool ParserCreateQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserCreateQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
Pos begin = pos; Pos begin = pos;
@ -179,9 +179,9 @@ bool ParserCreateQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected &
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_create.ignore(pos, end, expected)) if (!s_create.ignore(pos, end, max_parsed_pos, expected))
{ {
if (s_attach.ignore(pos, end, expected)) if (s_attach.ignore(pos, end, max_parsed_pos, expected))
attach = true; attach = true;
else else
return false; return false;
@ -189,116 +189,116 @@ bool ParserCreateQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected &
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_temporary.ignore(pos, end, expected)) if (s_temporary.ignore(pos, end, max_parsed_pos, expected))
{ {
is_temporary = true; is_temporary = true;
ws.ignore(pos, end); ws.ignore(pos, end);
} }
if (s_database.ignore(pos, end, expected)) if (s_database.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_if.ignore(pos, end, expected) if (s_if.ignore(pos, end, max_parsed_pos, expected)
&& ws.ignore(pos, end) && ws.ignore(pos, end)
&& s_not.ignore(pos, end, expected) && s_not.ignore(pos, end, max_parsed_pos, expected)
&& ws.ignore(pos, end) && ws.ignore(pos, end)
&& s_exists.ignore(pos, end, expected) && s_exists.ignore(pos, end, max_parsed_pos, expected)
&& ws.ignore(pos, end)) && ws.ignore(pos, end))
if_not_exists = true; if_not_exists = true;
if (!name_p.parse(pos, end, database, expected)) if (!name_p.parse(pos, end, database, max_parsed_pos, expected))
return false; return false;
} }
else if (s_table.ignore(pos, end, expected)) else if (s_table.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_if.ignore(pos, end, expected) if (s_if.ignore(pos, end, max_parsed_pos, expected)
&& ws.ignore(pos, end) && ws.ignore(pos, end)
&& s_not.ignore(pos, end, expected) && s_not.ignore(pos, end, max_parsed_pos, expected)
&& ws.ignore(pos, end) && ws.ignore(pos, end)
&& s_exists.ignore(pos, end, expected) && s_exists.ignore(pos, end, max_parsed_pos, expected)
&& ws.ignore(pos, end)) && ws.ignore(pos, end))
if_not_exists = true; if_not_exists = true;
if (!name_p.parse(pos, end, table, expected)) if (!name_p.parse(pos, end, table, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_dot.ignore(pos, end, expected)) if (s_dot.ignore(pos, end, max_parsed_pos, expected))
{ {
database = table; database = table;
if (!name_p.parse(pos, end, table, expected)) if (!name_p.parse(pos, end, table, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
} }
/// Список столбцов /// Список столбцов
if (s_lparen.ignore(pos, end, expected)) if (s_lparen.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (!columns_p.parse(pos, end, columns, expected)) if (!columns_p.parse(pos, end, columns, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_rparen.ignore(pos, end, expected)) if (!s_rparen.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!engine_p.parse(pos, end, storage, expected)) if (!engine_p.parse(pos, end, storage, max_parsed_pos, expected))
return false; return false;
/// Для engine VIEW необходимо так же считать запрос AS SELECT /// Для engine VIEW необходимо так же считать запрос AS SELECT
if (storage && (typeid_cast<ASTFunction &>(*storage).name == "View" if (storage && (typeid_cast<ASTFunction &>(*storage).name == "View"
|| typeid_cast<ASTFunction &>(*storage).name == "MaterializedView")) || typeid_cast<ASTFunction &>(*storage).name == "MaterializedView"))
{ {
if (!s_as.ignore(pos, end, expected)) if (!s_as.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
Pos before_select = pos; Pos before_select = pos;
if (!s_select.ignore(pos, end, expected)) if (!s_select.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
pos = before_select; pos = before_select;
ParserSelectQuery select_p; ParserSelectQuery select_p;
select_p.parse(pos, end, select, expected); select_p.parse(pos, end, select, max_parsed_pos, expected);
} }
} }
else else
{ {
engine_p.parse(pos, end, storage, expected); engine_p.parse(pos, end, storage, max_parsed_pos, expected);
if (!s_as.ignore(pos, end, expected)) if (!s_as.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
/// AS SELECT ... /// AS SELECT ...
Pos before_select = pos; Pos before_select = pos;
if (s_select.ignore(pos, end, expected)) if (s_select.ignore(pos, end, max_parsed_pos, expected))
{ {
pos = before_select; pos = before_select;
ParserSelectQuery select_p; ParserSelectQuery select_p;
select_p.parse(pos, end, select, expected); select_p.parse(pos, end, select, max_parsed_pos, expected);
} }
else else
{ {
/// AS [db.]table /// AS [db.]table
if (!name_p.parse(pos, end, as_table, expected)) if (!name_p.parse(pos, end, as_table, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_dot.ignore(pos, end, expected)) if (s_dot.ignore(pos, end, max_parsed_pos, expected))
{ {
as_database = as_table; as_database = as_table;
if (!name_p.parse(pos, end, as_table, expected)) if (!name_p.parse(pos, end, as_table, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
@ -307,76 +307,76 @@ bool ParserCreateQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected &
ws.ignore(pos, end); ws.ignore(pos, end);
/// Опционально - может быть указана ENGINE. /// Опционально - может быть указана ENGINE.
engine_p.parse(pos, end, storage, expected); engine_p.parse(pos, end, storage, max_parsed_pos, expected);
} }
} }
} }
else else
{ {
/// VIEW or MATERIALIZED VIEW /// VIEW or MATERIALIZED VIEW
if (s_materialized.ignore(pos, end, expected) && ws.ignore(pos, end, expected)) if (s_materialized.ignore(pos, end, max_parsed_pos, expected) && ws.ignore(pos, end, max_parsed_pos, expected))
is_materialized_view = true; is_materialized_view = true;
else else
is_view = true; is_view = true;
if (!s_view.ignore(pos, end, expected) || !ws.ignore(pos, end, expected)) if (!s_view.ignore(pos, end, max_parsed_pos, expected) || !ws.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
if (s_if.ignore(pos, end, expected) if (s_if.ignore(pos, end, max_parsed_pos, expected)
&& ws.ignore(pos, end) && ws.ignore(pos, end)
&& s_not.ignore(pos, end, expected) && s_not.ignore(pos, end, max_parsed_pos, expected)
&& ws.ignore(pos, end) && ws.ignore(pos, end)
&& s_exists.ignore(pos, end, expected) && s_exists.ignore(pos, end, max_parsed_pos, expected)
&& ws.ignore(pos, end)) && ws.ignore(pos, end))
if_not_exists = true; if_not_exists = true;
if (!name_p.parse(pos, end, table, expected)) if (!name_p.parse(pos, end, table, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_dot.ignore(pos, end, expected)) if (s_dot.ignore(pos, end, max_parsed_pos, expected))
{ {
database = table; database = table;
if (!name_p.parse(pos, end, table, expected)) if (!name_p.parse(pos, end, table, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
} }
/// Опционально - может быть указан список столбцов. Он должен полностью соответствовать SELECT-у. /// Опционально - может быть указан список столбцов. Он должен полностью соответствовать SELECT-у.
if (s_lparen.ignore(pos, end, expected)) if (s_lparen.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (!columns_p.parse(pos, end, columns, expected)) if (!columns_p.parse(pos, end, columns, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_rparen.ignore(pos, end, expected)) if (!s_rparen.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
} }
/// Опционально - может быть указана внутренняя ENGINE для MATERIALIZED VIEW /// Опционально - может быть указана внутренняя ENGINE для MATERIALIZED VIEW
engine_p.parse(pos, end, inner_storage, expected); engine_p.parse(pos, end, inner_storage, max_parsed_pos, expected);
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_populate.ignore(pos, end, expected)) if (s_populate.ignore(pos, end, max_parsed_pos, expected))
is_populate = true; is_populate = true;
ws.ignore(pos, end); ws.ignore(pos, end);
/// AS SELECT ... /// AS SELECT ...
if (!s_as.ignore(pos, end, expected)) if (!s_as.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
Pos before_select = pos; Pos before_select = pos;
if (!s_select.ignore(pos, end, expected)) if (!s_select.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
pos = before_select; pos = before_select;
ParserSelectQuery select_p; ParserSelectQuery select_p;
select_p.parse(pos, end, select, expected); select_p.parse(pos, end, select, max_parsed_pos, expected);
} }
ws.ignore(pos, end); ws.ignore(pos, end);

View File

@ -9,7 +9,7 @@ namespace DB
{ {
bool ParserDropQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserDropQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
Pos begin = pos; Pos begin = pos;
@ -30,9 +30,9 @@ bool ParserDropQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & ex
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_drop.ignore(pos, end, expected)) if (!s_drop.ignore(pos, end, max_parsed_pos, expected))
{ {
if (s_detach.ignore(pos, end, expected)) if (s_detach.ignore(pos, end, max_parsed_pos, expected))
detach = true; detach = true;
else else
return false; return false;
@ -40,41 +40,41 @@ bool ParserDropQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & ex
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_database.ignore(pos, end, expected)) if (s_database.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_if.ignore(pos, end, expected) if (s_if.ignore(pos, end, max_parsed_pos, expected)
&& ws.ignore(pos, end) && ws.ignore(pos, end)
&& s_exists.ignore(pos, end, expected) && s_exists.ignore(pos, end, max_parsed_pos, expected)
&& ws.ignore(pos, end)) && ws.ignore(pos, end))
if_exists = true; if_exists = true;
if (!name_p.parse(pos, end, database, expected)) if (!name_p.parse(pos, end, database, max_parsed_pos, expected))
return false; return false;
} }
else else
{ {
if (!s_table.ignore(pos, end, expected)) if (!s_table.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_if.ignore(pos, end, expected) if (s_if.ignore(pos, end, max_parsed_pos, expected)
&& ws.ignore(pos, end) && ws.ignore(pos, end)
&& s_exists.ignore(pos, end, expected) && s_exists.ignore(pos, end, max_parsed_pos, expected)
&& ws.ignore(pos, end)) && ws.ignore(pos, end))
if_exists = true; if_exists = true;
if (!name_p.parse(pos, end, table, expected)) if (!name_p.parse(pos, end, table, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_dot.ignore(pos, end, expected)) if (s_dot.ignore(pos, end, max_parsed_pos, expected))
{ {
database = table; database = table;
if (!name_p.parse(pos, end, table, expected)) if (!name_p.parse(pos, end, table, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);

View File

@ -14,7 +14,7 @@ namespace DB
{ {
bool ParserInsertQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserInsertQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
Pos begin = pos; Pos begin = pos;
@ -45,22 +45,22 @@ bool ParserInsertQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected &
ws.ignore(pos, end); ws.ignore(pos, end);
/// INSERT INTO /// INSERT INTO
if (!s_insert.ignore(pos, end, expected) if (!s_insert.ignore(pos, end, max_parsed_pos, expected)
|| !ws.ignore(pos, end) || !ws.ignore(pos, end)
|| !s_into.ignore(pos, end, expected)) || !s_into.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!name_p.parse(pos, end, table, expected)) if (!name_p.parse(pos, end, table, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_dot.ignore(pos, end, expected)) if (s_dot.ignore(pos, end, max_parsed_pos, expected))
{ {
database = table; database = table;
if (!name_p.parse(pos, end, table, expected)) if (!name_p.parse(pos, end, table, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
@ -68,24 +68,24 @@ bool ParserInsertQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected &
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_id.ignore(pos, end, expected)) if (s_id.ignore(pos, end, max_parsed_pos, expected))
{ {
if (!s_eq.ignore(pos, end, expected)) if (!s_eq.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
if (!id_p.parse(pos, end, id, expected)) if (!id_p.parse(pos, end, id, max_parsed_pos, expected))
return false; return false;
} }
ws.ignore(pos, end); ws.ignore(pos, end);
/// Есть ли список столбцов /// Есть ли список столбцов
if (s_lparen.ignore(pos, end, expected)) if (s_lparen.ignore(pos, end, max_parsed_pos, expected))
{ {
if (!columns_p.parse(pos, end, columns, expected)) if (!columns_p.parse(pos, end, columns, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_rparen.ignore(pos, end, expected)) if (!s_rparen.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
} }
@ -94,17 +94,17 @@ bool ParserInsertQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected &
Pos before_select = pos; Pos before_select = pos;
/// VALUES или FORMAT или SELECT /// VALUES или FORMAT или SELECT
if (s_values.ignore(pos, end, expected)) if (s_values.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
data = pos; data = pos;
pos = end; pos = end;
} }
else if (s_format.ignore(pos, end, expected)) else if (s_format.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (!name_p.parse(pos, end, format, expected)) if (!name_p.parse(pos, end, format, max_parsed_pos, expected))
return false; return false;
/// Данные начинаются после первого перевода строки, если такой есть, или после всех пробельных символов, иначе. /// Данные начинаются после первого перевода строки, если такой есть, или после всех пробельных символов, иначе.
@ -126,11 +126,11 @@ bool ParserInsertQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected &
data = pos; data = pos;
pos = end; pos = end;
} }
else if (s_select.ignore(pos, end, expected)) else if (s_select.ignore(pos, end, max_parsed_pos, expected))
{ {
pos = before_select; pos = before_select;
ParserSelectQuery select_p; ParserSelectQuery select_p;
select_p.parse(pos, end, select, expected); select_p.parse(pos, end, select, max_parsed_pos, expected);
} }
else else
{ {

View File

@ -9,7 +9,7 @@ namespace DB
{ {
bool ParserJoin::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserJoin::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
Pos begin = pos; Pos begin = pos;
@ -62,13 +62,13 @@ bool ParserJoin::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expecte
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_join.ignore(pos, end, expected)) if (!s_join.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!identifier.parse(pos, end, join->table, expected) if (!identifier.parse(pos, end, join->table, max_parsed_pos, expected)
&& !subquery.parse(pos, end, join->table, expected)) && !subquery.parse(pos, end, join->table, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
@ -77,12 +77,12 @@ bool ParserJoin::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expecte
ParserAlias().ignore(pos, end); ParserAlias().ignore(pos, end);
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_using.ignore(pos, end, expected)) if (!s_using.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!exp_list.parse(pos, end, join->using_expr_list, expected)) if (!exp_list.parse(pos, end, join->using_expr_list, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);

View File

@ -9,7 +9,7 @@ namespace DB
{ {
bool ParserOptimizeQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserOptimizeQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
Pos begin = pos; Pos begin = pos;
@ -24,25 +24,25 @@ bool ParserOptimizeQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_optimize.ignore(pos, end, expected)) if (!s_optimize.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_table.ignore(pos, end, expected)) if (!s_table.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!name_p.parse(pos, end, table, expected)) if (!name_p.parse(pos, end, table, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_dot.ignore(pos, end, expected)) if (s_dot.ignore(pos, end, max_parsed_pos, expected))
{ {
database = table; database = table;
if (!name_p.parse(pos, end, table, expected)) if (!name_p.parse(pos, end, table, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);

View File

@ -20,7 +20,7 @@ namespace DB
{ {
bool ParserQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
ParserShowTablesQuery show_tables_p; ParserShowTablesQuery show_tables_p;
ParserSelectQuery select_p; ParserSelectQuery select_p;
@ -37,20 +37,20 @@ bool ParserQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expect
ParserCheckQuery check_p; ParserCheckQuery check_p;
// ParserMultiQuery multi_p; // ParserMultiQuery multi_p;
bool res = show_tables_p.parse(pos, end, node, expected) bool res = show_tables_p.parse(pos, end, node, max_parsed_pos, expected)
|| select_p.parse(pos, end, node, expected) || select_p.parse(pos, end, node, max_parsed_pos, expected)
|| insert_p.parse(pos, end, node, expected) || insert_p.parse(pos, end, node, max_parsed_pos, expected)
|| create_p.parse(pos, end, node, expected) || create_p.parse(pos, end, node, max_parsed_pos, expected)
|| rename_p.parse(pos, end, node, expected) || rename_p.parse(pos, end, node, max_parsed_pos, expected)
|| drop_p.parse(pos, end, node, expected) || drop_p.parse(pos, end, node, max_parsed_pos, expected)
|| alter_p.parse(pos, end, node, expected) || alter_p.parse(pos, end, node, max_parsed_pos, expected)
|| use_p.parse(pos, end, node, expected) || use_p.parse(pos, end, node, max_parsed_pos, expected)
|| set_p.parse(pos, end, node, expected) || set_p.parse(pos, end, node, max_parsed_pos, expected)
|| optimize_p.parse(pos, end, node, expected) || optimize_p.parse(pos, end, node, max_parsed_pos, expected)
|| table_p.parse(pos, end, node, expected) || table_p.parse(pos, end, node, max_parsed_pos, expected)
|| show_processlist_p.parse(pos, end, node, expected) || show_processlist_p.parse(pos, end, node, max_parsed_pos, expected)
|| check_p.parse(pos, end, node, expected); || check_p.parse(pos, end, node, max_parsed_pos, expected);
/* || multi_p.parse(pos, end, node, expected)*/; /* || multi_p.parse(pos, end, node, max_parsed_pos, expected)*/;
if (!res) if (!res)
expected = "One of: SHOW TABLES, SHOW DATABASES, SHOW CREATE TABLE, SELECT, INSERT, CREATE, ATTACH, RENAME, DROP, DETACH, USE, SET, OPTIMIZE, EXISTS, DESCRIBE, DESC, ALTER, SHOW PROCESSLIST, CHECK, opening curly brace"; expected = "One of: SHOW TABLES, SHOW DATABASES, SHOW CREATE TABLE, SELECT, INSERT, CREATE, ATTACH, RENAME, DROP, DETACH, USE, SET, OPTIMIZE, EXISTS, DESCRIBE, DESC, ALTER, SHOW PROCESSLIST, CHECK, opening curly brace";

View File

@ -10,7 +10,8 @@ namespace DB
/// Парсит database.table или table. /// Парсит database.table или table.
static bool parseDatabaseAndTable(ASTRenameQuery::Table & db_and_table, IParser::Pos & pos, IParser::Pos end, Expected & expected) static bool parseDatabaseAndTable(
ASTRenameQuery::Table & db_and_table, IParser::Pos & pos, IParser::Pos end, IParser::Pos & max_parsed_pos, Expected & expected)
{ {
ParserIdentifier name_p; ParserIdentifier name_p;
ParserWhiteSpaceOrComments ws; ParserWhiteSpaceOrComments ws;
@ -21,15 +22,15 @@ static bool parseDatabaseAndTable(ASTRenameQuery::Table & db_and_table, IParser:
ws.ignore(pos, end); ws.ignore(pos, end);
if (!name_p.parse(pos, end, table, expected)) if (!name_p.parse(pos, end, table, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_dot.ignore(pos, end, expected)) if (s_dot.ignore(pos, end, max_parsed_pos, expected))
{ {
database = table; database = table;
if (!name_p.parse(pos, end, table, expected)) if (!name_p.parse(pos, end, table, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
@ -42,7 +43,7 @@ static bool parseDatabaseAndTable(ASTRenameQuery::Table & db_and_table, IParser:
} }
bool ParserRenameQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserRenameQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
Pos begin = pos; Pos begin = pos;
@ -54,12 +55,12 @@ bool ParserRenameQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected &
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_rename.ignore(pos, end, expected)) if (!s_rename.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_table.ignore(pos, end, expected)) if (!s_table.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ASTRenameQuery::Elements elements; ASTRenameQuery::Elements elements;
@ -75,9 +76,9 @@ bool ParserRenameQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected &
elements.push_back(ASTRenameQuery::Element()); elements.push_back(ASTRenameQuery::Element());
if (!parseDatabaseAndTable(elements.back().from, pos, end, expected) if (!parseDatabaseAndTable(elements.back().from, pos, end, max_parsed_pos, expected)
|| !s_to.ignore(pos, end) || !s_to.ignore(pos, end)
|| !parseDatabaseAndTable(elements.back().to, pos, end, expected)) || !parseDatabaseAndTable(elements.back().to, pos, end, max_parsed_pos, expected))
return false; return false;
} }

View File

@ -12,7 +12,7 @@ namespace DB
{ {
bool ParserSelectQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserSelectQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
Pos begin = pos; Pos begin = pos;
@ -50,25 +50,25 @@ bool ParserSelectQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected &
/// SELECT [DISTINCT] expr list /// SELECT [DISTINCT] expr list
{ {
if (!s_select.ignore(pos, end, expected)) if (!s_select.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_distinct.ignore(pos, end, expected)) if (s_distinct.ignore(pos, end, max_parsed_pos, expected))
{ {
select_query->distinct = true; select_query->distinct = true;
ws.ignore(pos, end); ws.ignore(pos, end);
} }
if (!exp_list.parse(pos, end, select_query->select_expression_list, expected)) if (!exp_list.parse(pos, end, select_query->select_expression_list, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
} }
/// FROM database.table или FROM table или FROM (subquery) или FROM tableFunction /// FROM database.table или FROM table или FROM (subquery) или FROM tableFunction
if (s_from.ignore(pos, end, expected)) if (s_from.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
@ -79,28 +79,28 @@ bool ParserSelectQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected &
ParserFunction table_function; ParserFunction table_function;
Pos before = pos; Pos before = pos;
if (s_lparen.ignore(pos, end, expected)) if (s_lparen.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
ParserSelectQuery select_p; ParserSelectQuery select_p;
if (!select_p.parse(pos, end, select_query->table, expected)) if (!select_p.parse(pos, end, select_query->table, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_rparen.ignore(pos, end, expected)) if (!s_rparen.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
} }
else if (ident.parse(pos, end, select_query->table, expected)) else if (ident.parse(pos, end, select_query->table, max_parsed_pos, expected))
{ {
/// Если сразу после identifier идет скобка, значит это должна быть табличная функция /// Если сразу после identifier идет скобка, значит это должна быть табличная функция
if (s_lparen.ignore(pos, end, expected)) if (s_lparen.ignore(pos, end, max_parsed_pos, expected))
{ {
pos = before; pos = before;
if (!table_function.parse(pos, end, select_query->table, expected)) if (!table_function.parse(pos, end, select_query->table, max_parsed_pos, expected))
return false; return false;
if (select_query->table) if (select_query->table)
typeid_cast<ASTFunction &>(*select_query->table).kind = ASTFunction::TABLE_FUNCTION; typeid_cast<ASTFunction &>(*select_query->table).kind = ASTFunction::TABLE_FUNCTION;
@ -109,10 +109,10 @@ bool ParserSelectQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected &
else else
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_dot.ignore(pos, end, expected)) if (s_dot.ignore(pos, end, max_parsed_pos, expected))
{ {
select_query->database = select_query->table; select_query->database = select_query->table;
if (!ident.parse(pos, end, select_query->table, expected)) if (!ident.parse(pos, end, select_query->table, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
@ -138,7 +138,7 @@ bool ParserSelectQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected &
{ {
/// FINAL /// FINAL
if (!select_query->final if (!select_query->final
&& s_final.ignore(pos, end, expected)) && s_final.ignore(pos, end, max_parsed_pos, expected))
{ {
select_query->final = true; select_query->final = true;
@ -147,13 +147,13 @@ bool ParserSelectQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected &
/// SAMPLE number /// SAMPLE number
if (!select_query->sample_size if (!select_query->sample_size
&& s_sample.ignore(pos, end, expected)) && s_sample.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
ParserNumber num; ParserNumber num;
if (!num.parse(pos, end, select_query->sample_size, expected)) if (!num.parse(pos, end, select_query->sample_size, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
@ -166,67 +166,67 @@ bool ParserSelectQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected &
return false; return false;
/// ARRAY JOIN expr list /// ARRAY JOIN expr list
if (s_array.ignore(pos, end, expected)) if (s_array.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_join.ignore(pos, end, expected)) if (!s_join.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!exp_list.parse(pos, end, select_query->array_join_expression_list, expected)) if (!exp_list.parse(pos, end, select_query->array_join_expression_list, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
} }
/// [GLOBAL] ANY|ALL INNER|LEFT JOIN (subquery) USING (tuple) /// [GLOBAL] ANY|ALL INNER|LEFT JOIN (subquery) USING (tuple)
join.parse(pos, end, select_query->join, expected); join.parse(pos, end, select_query->join, max_parsed_pos, expected);
if (!parse_final_and_sample()) if (!parse_final_and_sample())
return false; return false;
/// PREWHERE expr /// PREWHERE expr
if (s_prewhere.ignore(pos, end, expected)) if (s_prewhere.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (!exp_elem.parse(pos, end, select_query->prewhere_expression, expected)) if (!exp_elem.parse(pos, end, select_query->prewhere_expression, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
} }
/// WHERE expr /// WHERE expr
if (s_where.ignore(pos, end, expected)) if (s_where.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (!exp_elem.parse(pos, end, select_query->where_expression, expected)) if (!exp_elem.parse(pos, end, select_query->where_expression, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
} }
/// GROUP BY expr list /// GROUP BY expr list
if (s_group.ignore(pos, end, expected)) if (s_group.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_by.ignore(pos, end, expected)) if (!s_by.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
if (!exp_list.parse(pos, end, select_query->group_expression_list, expected)) if (!exp_list.parse(pos, end, select_query->group_expression_list, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
} }
/// WITH TOTALS /// WITH TOTALS
if (s_with.ignore(pos, end, expected)) if (s_with.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_totals.ignore(pos, end, expected)) if (!s_totals.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
select_query->group_by_with_totals = true; select_query->group_by_with_totals = true;
@ -235,46 +235,46 @@ bool ParserSelectQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected &
} }
/// HAVING expr /// HAVING expr
if (s_having.ignore(pos, end, expected)) if (s_having.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (!exp_elem.parse(pos, end, select_query->having_expression, expected)) if (!exp_elem.parse(pos, end, select_query->having_expression, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
} }
/// ORDER BY expr ASC|DESC COLLATE 'locale' list /// ORDER BY expr ASC|DESC COLLATE 'locale' list
if (s_order.ignore(pos, end, expected)) if (s_order.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_by.ignore(pos, end, expected)) if (!s_by.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
if (!order_list.parse(pos, end, select_query->order_expression_list, expected)) if (!order_list.parse(pos, end, select_query->order_expression_list, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
} }
/// LIMIT length или LIMIT offset, length /// LIMIT length или LIMIT offset, length
if (s_limit.ignore(pos, end, expected)) if (s_limit.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
ParserString s_comma(","); ParserString s_comma(",");
ParserNumber num; ParserNumber num;
if (!num.parse(pos, end, select_query->limit_length, expected)) if (!num.parse(pos, end, select_query->limit_length, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_comma.ignore(pos, end, expected)) if (s_comma.ignore(pos, end, max_parsed_pos, expected))
{ {
select_query->limit_offset = select_query->limit_length; select_query->limit_offset = select_query->limit_length;
if (!num.parse(pos, end, select_query->limit_length, expected)) if (!num.parse(pos, end, select_query->limit_length, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
@ -282,13 +282,13 @@ bool ParserSelectQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected &
} }
/// FORMAT format_name /// FORMAT format_name
if (s_format.ignore(pos, end, expected)) if (s_format.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
ParserIdentifier format_p; ParserIdentifier format_p;
if (!format_p.parse(pos, end, select_query->format, expected)) if (!format_p.parse(pos, end, select_query->format, max_parsed_pos, expected))
return false; return false;
typeid_cast<ASTIdentifier &>(*select_query->format).kind = ASTIdentifier::Format; typeid_cast<ASTIdentifier &>(*select_query->format).kind = ASTIdentifier::Format;
@ -296,14 +296,14 @@ bool ParserSelectQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected &
} }
// UNION ALL select query // UNION ALL select query
if (s_union.ignore(pos, end, expected)) if (s_union.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_all.ignore(pos, end, expected)) if (s_all.ignore(pos, end, max_parsed_pos, expected))
{ {
ParserSelectQuery select_p; ParserSelectQuery select_p;
if (!select_p.parse(pos, end, select_query->next_union_all, expected)) if (!select_p.parse(pos, end, select_query->next_union_all, max_parsed_pos, expected))
return false; return false;
} }
else else

View File

@ -11,7 +11,7 @@ namespace DB
/// Парсит name = value. /// Парсит name = value.
static bool parseNameValuePair(ASTSetQuery::Change & change, IParser::Pos & pos, IParser::Pos end, Expected & expected) static bool parseNameValuePair(ASTSetQuery::Change & change, IParser::Pos & pos, IParser::Pos end, IParser::Pos & max_parsed_pos, Expected & expected)
{ {
ParserIdentifier name_p; ParserIdentifier name_p;
ParserLiteral value_p; ParserLiteral value_p;
@ -23,17 +23,17 @@ static bool parseNameValuePair(ASTSetQuery::Change & change, IParser::Pos & pos,
ws.ignore(pos, end); ws.ignore(pos, end);
if (!name_p.parse(pos, end, name, expected)) if (!name_p.parse(pos, end, name, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_eq.ignore(pos, end, expected)) if (!s_eq.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (!value_p.parse(pos, end, value, expected)) if (!value_p.parse(pos, end, value, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
@ -45,7 +45,7 @@ static bool parseNameValuePair(ASTSetQuery::Change & change, IParser::Pos & pos,
} }
bool ParserSetQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserSetQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
Pos begin = pos; Pos begin = pos;
@ -56,12 +56,12 @@ bool ParserSetQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & exp
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_set.ignore(pos, end, expected)) if (!s_set.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
bool global = s_global.ignore(pos, end, expected); bool global = s_global.ignore(pos, end, max_parsed_pos, expected);
ASTSetQuery::Changes changes; ASTSetQuery::Changes changes;
@ -76,7 +76,7 @@ bool ParserSetQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & exp
changes.push_back(ASTSetQuery::Change()); changes.push_back(ASTSetQuery::Change());
if (!parseNameValuePair(changes.back(), pos, end, expected)) if (!parseNameValuePair(changes.back(), pos, end, max_parsed_pos, expected))
return false; return false;
} }

View File

@ -11,7 +11,7 @@ namespace DB
{ {
bool ParserShowTablesQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserShowTablesQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
Pos begin = pos; Pos begin = pos;
@ -35,7 +35,7 @@ bool ParserShowTablesQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expecte
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_show.ignore(pos, end, expected)) if (!s_show.ignore(pos, end, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
@ -44,32 +44,32 @@ bool ParserShowTablesQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expecte
{ {
query->databases = true; query->databases = true;
} }
else if (s_tables.ignore(pos, end, expected)) else if (s_tables.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_from.ignore(pos, end, expected)) if (s_from.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (!name_p.parse(pos, end, database, expected)) if (!name_p.parse(pos, end, database, max_parsed_pos, expected))
return false; return false;
} }
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_not.ignore(pos, end, expected)) if (s_not.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
query->not_like = true; query->not_like = true;
} }
if (s_like.ignore(pos, end, expected)) if (s_like.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (!like_p.parse(pos, end, like, expected)) if (!like_p.parse(pos, end, like, max_parsed_pos, expected))
return false; return false;
} }
else if (query->not_like) else if (query->not_like)
@ -83,13 +83,13 @@ bool ParserShowTablesQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expecte
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_format.ignore(pos, end, expected)) if (s_format.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
ParserIdentifier format_p; ParserIdentifier format_p;
if (!format_p.parse(pos, end, format, expected)) if (!format_p.parse(pos, end, format, max_parsed_pos, expected))
return false; return false;
typeid_cast<ASTIdentifier &>(*format).kind = ASTIdentifier::Format; typeid_cast<ASTIdentifier &>(*format).kind = ASTIdentifier::Format;

View File

@ -9,7 +9,7 @@ namespace DB
{ {
bool ParserTablePropertiesQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Expected & expected) bool ParserTablePropertiesQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{ {
Pos begin = pos; Pos begin = pos;
@ -31,19 +31,19 @@ bool ParserTablePropertiesQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Ex
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_exists.ignore(pos, end, expected)) if (s_exists.ignore(pos, end, max_parsed_pos, expected))
{ {
query_ptr = new ASTExistsQuery; query_ptr = new ASTExistsQuery;
} }
else if (s_describe.ignore(pos, end, expected) || s_desc.ignore(pos, end, expected)) else if (s_describe.ignore(pos, end, max_parsed_pos, expected) || s_desc.ignore(pos, end, max_parsed_pos, expected))
{ {
query_ptr = new ASTDescribeQuery; query_ptr = new ASTDescribeQuery;
} }
else if (s_show.ignore(pos, end, expected)) else if (s_show.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
if (!s_create.ignore(pos, end, expected)) if (!s_create.ignore(pos, end, max_parsed_pos, expected))
{ {
pos = begin; pos = begin;
return false; return false;
@ -59,19 +59,19 @@ bool ParserTablePropertiesQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Ex
ws.ignore(pos, end); ws.ignore(pos, end);
s_table.ignore(pos, end, expected); s_table.ignore(pos, end, max_parsed_pos, expected);
ws.ignore(pos, end); ws.ignore(pos, end);
if (!name_p.parse(pos, end, table, expected)) if (!name_p.parse(pos, end, table, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_dot.ignore(pos, end, expected)) if (s_dot.ignore(pos, end, max_parsed_pos, expected))
{ {
database = table; database = table;
if (!name_p.parse(pos, end, table, expected)) if (!name_p.parse(pos, end, table, max_parsed_pos, expected))
return false; return false;
ws.ignore(pos, end); ws.ignore(pos, end);
@ -79,13 +79,13 @@ bool ParserTablePropertiesQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Ex
ws.ignore(pos, end); ws.ignore(pos, end);
if (s_format.ignore(pos, end, expected)) if (s_format.ignore(pos, end, max_parsed_pos, expected))
{ {
ws.ignore(pos, end); ws.ignore(pos, end);
ParserIdentifier format_p; ParserIdentifier format_p;
if (!format_p.parse(pos, end, format, expected)) if (!format_p.parse(pos, end, format, max_parsed_pos, expected))
return false; return false;
typeid_cast<ASTIdentifier &>(*format).kind = ASTIdentifier::Format; typeid_cast<ASTIdentifier &>(*format).kind = ASTIdentifier::Format;

View File

@ -0,0 +1,97 @@
#include <DB/Parsers/parseQuery.h>
namespace DB
{
/** Из позиции в (возможно многострочном) запросе получить номер строки и номер столбца в строке.
* Используется в сообщении об ошибках.
*/
static inline std::pair<size_t, size_t> getLineAndCol(IParser::Pos begin, IParser::Pos pos)
{
size_t line = 0;
IParser::Pos nl;
while (nullptr != (nl = reinterpret_cast<IParser::Pos>(memchr(begin, '\n', pos - begin))))
{
++line;
begin = nl + 1;
}
/// Нумеруются с единицы.
return { line + 1, pos - begin + 1 };
}
static std::string getSyntaxErrorMessage(
IParser::Pos begin,
IParser::Pos end,
IParser::Pos max_parsed_pos,
Expected expected,
const std::string & description)
{
std::stringstream message;
message << "Syntax error";
if (!description.empty())
message << " (" << description << ")";
message << ": failed at position " << (max_parsed_pos - begin + 1);
/// Если запрос многострочный.
IParser::Pos nl = reinterpret_cast<IParser::Pos>(memchr(begin, '\n', end - begin));
if (nullptr != nl && nl + 1 != end)
{
size_t line = 0;
size_t col = 0;
std::tie(line, col) = getLineAndCol(begin, max_parsed_pos);
message << " (line " << line << ", col " << col << ")";
}
message << ": " << std::string(max_parsed_pos, std::min(SHOW_CHARS_ON_SYNTAX_ERROR, end - max_parsed_pos))
<< ", expected " << expected << ".";
return message.str();
}
ASTPtr tryParseQuery(IParser & parser, IParser::Pos begin, IParser::Pos end, std::string & out_error_message, const std::string & description)
{
if (begin == end || *begin == ';')
{
out_error_message = "Empty query";
return nullptr;
}
Expected expected = "";
IParser::Pos pos = begin;
IParser::Pos max_parsed_pos = pos;
ASTPtr res;
bool parse_res = parser.parse(pos, end, res, max_parsed_pos, expected);
/// Распарсенный запрос должен заканчиваться на конец входных данных или на точку с запятой.
if (!parse_res || (pos != end && *pos != ';'))
{
out_error_message = getSyntaxErrorMessage(begin, end, max_parsed_pos, expected, description);
return nullptr;
}
return res;
}
ASTPtr parseQuery(IParser & parser, IParser::Pos begin, IParser::Pos end, const std::string & description)
{
std::string error_message;
ASTPtr res = tryParseQuery(parser, begin, end, error_message, description);
if (res)
return res;
throw Exception(error_message, ErrorCodes::SYNTAX_ERROR);
}
}

View File

@ -20,7 +20,7 @@ int main(int argc, char ** argv)
const char * end = begin + input.size(); const char * end = begin + input.size();
const char * pos = begin; const char * pos = begin;
if (parser.parse(pos, end, ast, expected)) if (parser.parse(pos, end, ast, max_parsed_pos, expected))
{ {
std::cout << "Success." << std::endl; std::cout << "Success." << std::endl;
formatAST(*ast, std::cout); formatAST(*ast, std::cout);

View File

@ -27,7 +27,7 @@ int main(int argc, char ** argv)
const char * end = begin + input.size(); const char * end = begin + input.size();
const char * pos = begin; const char * pos = begin;
if (parser.parse(pos, end, ast, expected)) if (parser.parse(pos, end, ast, max_parsed_pos, expected))
{ {
std::cout << "Success." << std::endl; std::cout << "Success." << std::endl;
formatAST(*ast, std::cerr); formatAST(*ast, std::cerr);

View File

@ -0,0 +1,119 @@
#include <DB/Parsers/ExpressionListParsers.h>
#include <DB/IO/WriteBufferFromString.h>
#include <DB/Storages/ColumnsDescription.h>
namespace DB
{
template <bool store>
String ColumnsDescription<store>::toString() const
{
String s;
WriteBufferFromString buf{s};
writeString("columns format version: 1\n", buf);
writeText(columns.size() + materialized.size() + alias.size(), buf);
writeString(" columns:\n", buf);
const auto write_columns = [this, &buf] (const NamesAndTypesList & columns)
{
for (const auto & column : columns)
{
const auto it = defaults.find(column.name);
writeBackQuotedString(column.name, buf);
writeChar(' ', buf);
writeString(column.type->getName(), buf);
if (it == std::end(defaults))
{
writeChar('\n', buf);
continue;
}
else
writeChar('\t', buf);
writeString(DB::toString(it->second.type), buf);
writeChar('\t', buf);
writeString(queryToString(it->second.expression), buf);
writeChar('\n', buf);
}
};
write_columns(columns);
write_columns(materialized);
write_columns(alias);
return s;
}
template <>
ColumnsDescription<true> ColumnsDescription<true>::parse(const String & str, const DataTypeFactory & data_type_factory)
{
ReadBufferFromString buf{str};
assertString("columns format version: 1\n", buf);
size_t count{};
readText(count, buf);
assertString(" columns:\n", buf);
ParserTernaryOperatorExpression expr_parser;
ColumnsDescription<true> result{};
for (size_t i = 0; i < count; ++i)
{
String column_name;
readBackQuotedString(column_name, buf);
assertString(" ", buf);
String type_name;
readString(type_name, buf);
auto type = data_type_factory.get(type_name);
if (*buf.position() == '\n')
{
assertString("\n", buf);
result.columns.emplace_back(column_name, std::move(type));
continue;
}
assertString("\t", buf);
String default_type_str;
readString(default_type_str, buf);
const auto default_type = columnDefaultTypeFromString(default_type_str);
assertString("\t", buf);
String default_expr_str;
readText(default_expr_str, buf);
assertString("\n", buf);
ASTPtr default_expr;
Expected expected{};
auto begin = default_expr_str.data();
const auto end = begin + default_expr_str.size();
const char * max_parsed_pos = begin;
if (!expr_parser.parse(begin, end, default_expr, max_parsed_pos, expected))
throw Exception{"Could not parse default expression", DB::ErrorCodes::CANNOT_PARSE_TEXT};
if (ColumnDefaultType::Default == default_type)
result.columns.emplace_back(column_name, std::move(type));
else if (ColumnDefaultType::Materialized == default_type)
result.materialized.emplace_back(column_name, std::move(type));
else if (ColumnDefaultType::Alias == default_type)
result.alias.emplace_back(column_name, std::move(type));
result.defaults.emplace(column_name, ColumnDefault{default_type, default_expr});
}
assertEOF(buf);
return result;
}
template struct ColumnsDescription<false>;
template struct ColumnsDescription<true>;
}

View File

@ -1,4 +1,5 @@
#include <statdaemons/ext/range.hpp> #include <statdaemons/ext/range.hpp>
#include <DB/Storages/ColumnsDescription.h>
#include <DB/Storages/StorageReplicatedMergeTree.h> #include <DB/Storages/StorageReplicatedMergeTree.h>
#include <DB/Storages/MergeTree/ReplicatedMergeTreeBlockOutputStream.h> #include <DB/Storages/MergeTree/ReplicatedMergeTreeBlockOutputStream.h>
#include <DB/Storages/MergeTree/ReplicatedMergeTreePartsExchange.h> #include <DB/Storages/MergeTree/ReplicatedMergeTreePartsExchange.h>