mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-20 08:40:50 +00:00
dbms: better diagnostics on syntax error [#METR-15933].
This commit is contained in:
parent
62ff76c572
commit
9ec393df61
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
15
dbms/include/DB/Parsers/parseQuery.h
Normal file
15
dbms/include/DB/Parsers/parseQuery.h
Normal 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);
|
||||||
|
|
||||||
|
}
|
@ -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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
28
dbms/include/DB/Storages/ColumnsDescription.h
Normal file
28
dbms/include/DB/Storages/ColumnsDescription.h
Normal 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);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
|
@ -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>();
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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";
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
97
dbms/src/Parsers/parseQuery.cpp
Normal file
97
dbms/src/Parsers/parseQuery.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
119
dbms/src/Storages/ColumnsDescription.cpp
Normal file
119
dbms/src/Storages/ColumnsDescription.cpp
Normal 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>;
|
||||||
|
|
||||||
|
}
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user