2011-09-04 05:14:52 +00:00
|
|
|
|
#pragma once
|
2010-06-24 19:12:10 +00:00
|
|
|
|
|
2010-06-25 16:36:13 +00:00
|
|
|
|
#include <list>
|
2010-06-24 19:12:10 +00:00
|
|
|
|
|
|
|
|
|
#include <DB/Parsers/IParserBase.h>
|
|
|
|
|
#include <DB/Parsers/CommonParsers.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
|
{
|
|
|
|
|
|
2014-03-10 14:47:04 +00:00
|
|
|
|
/** Идущие подряд пары строк: оператор и соответствующая ему функция. Например, "+" -> "plus".
|
|
|
|
|
* Порядок парсинга операторов имеет значение.
|
2010-06-25 16:36:13 +00:00
|
|
|
|
*/
|
2016-05-28 10:35:44 +00:00
|
|
|
|
using Operators_t = const char **;
|
2010-06-24 19:12:10 +00:00
|
|
|
|
|
|
|
|
|
|
2011-08-18 18:48:00 +00:00
|
|
|
|
/** Список элементов, разделённых чем-либо. */
|
|
|
|
|
class ParserList : public IParserBase
|
|
|
|
|
{
|
|
|
|
|
public:
|
2014-03-10 14:47:04 +00:00
|
|
|
|
ParserList(ParserPtr && elem_parser_, ParserPtr && separator_parser_, bool allow_empty_ = true)
|
|
|
|
|
: elem_parser(std::move(elem_parser_)), separator_parser(std::move(separator_parser_)), allow_empty(allow_empty_)
|
2011-08-18 18:48:00 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
protected:
|
2014-03-10 12:25:37 +00:00
|
|
|
|
const char * getName() const { return "list of elements"; }
|
2015-04-11 03:10:23 +00:00
|
|
|
|
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
|
2011-08-18 18:48:00 +00:00
|
|
|
|
private:
|
|
|
|
|
ParserPtr elem_parser;
|
|
|
|
|
ParserPtr separator_parser;
|
|
|
|
|
bool allow_empty;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2010-06-24 19:12:10 +00:00
|
|
|
|
/** Выражение с инфиксным бинарным лево-ассоциативным оператором.
|
|
|
|
|
* Например, a + b - c + d.
|
|
|
|
|
*/
|
|
|
|
|
class ParserLeftAssociativeBinaryOperatorList : public IParserBase
|
|
|
|
|
{
|
|
|
|
|
private:
|
2010-06-24 19:37:23 +00:00
|
|
|
|
Operators_t operators;
|
2015-01-16 10:17:58 +00:00
|
|
|
|
ParserPtr first_elem_parser;
|
|
|
|
|
ParserPtr remaining_elem_parser;
|
2010-06-24 19:12:10 +00:00
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
/** operators_ - допустимые операторы и соответствующие им функции
|
|
|
|
|
*/
|
2015-01-16 10:17:58 +00:00
|
|
|
|
ParserLeftAssociativeBinaryOperatorList(Operators_t operators_, ParserPtr && first_elem_parser_)
|
|
|
|
|
: operators(operators_), first_elem_parser(std::move(first_elem_parser_))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ParserLeftAssociativeBinaryOperatorList(Operators_t operators_, ParserPtr && first_elem_parser_,
|
|
|
|
|
ParserPtr && remaining_elem_parser_)
|
|
|
|
|
: operators(operators_), first_elem_parser(std::move(first_elem_parser_)),
|
|
|
|
|
remaining_elem_parser(std::move(remaining_elem_parser_))
|
2010-06-24 19:12:10 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
2015-04-11 03:10:23 +00:00
|
|
|
|
|
2010-06-24 19:12:10 +00:00
|
|
|
|
protected:
|
2014-03-10 12:25:37 +00:00
|
|
|
|
const char * getName() const { return "list, delimited by binary operators"; }
|
2015-04-11 03:10:23 +00:00
|
|
|
|
|
|
|
|
|
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
|
2010-06-24 19:12:10 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2014-02-13 11:05:51 +00:00
|
|
|
|
/** Выражение с инфиксным оператором произвольной арности.
|
|
|
|
|
* Например, a AND b AND c AND d.
|
|
|
|
|
*/
|
|
|
|
|
class ParserVariableArityOperatorList : public IParserBase
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
ParserString infix_parser;
|
2014-03-10 14:47:04 +00:00
|
|
|
|
const char * function_name;
|
2014-02-13 11:05:51 +00:00
|
|
|
|
ParserPtr elem_parser;
|
|
|
|
|
|
|
|
|
|
public:
|
2014-03-10 14:47:04 +00:00
|
|
|
|
ParserVariableArityOperatorList(const char * infix_, const char * function_, ParserPtr && elem_parser_)
|
|
|
|
|
: infix_parser(infix_, true, true), function_name(function_), elem_parser(std::move(elem_parser_))
|
2014-02-13 11:05:51 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected:
|
2014-03-10 12:25:37 +00:00
|
|
|
|
const char * getName() const { return "list, delimited by operator of variable arity"; }
|
2014-02-13 11:05:51 +00:00
|
|
|
|
|
2015-04-11 03:10:23 +00:00
|
|
|
|
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
|
2014-02-13 11:05:51 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2010-06-24 19:12:10 +00:00
|
|
|
|
/** Выражение с префиксным унарным оператором.
|
|
|
|
|
* Например, NOT x.
|
|
|
|
|
*/
|
|
|
|
|
class ParserPrefixUnaryOperatorExpression : public IParserBase
|
|
|
|
|
{
|
|
|
|
|
private:
|
2010-06-24 19:37:23 +00:00
|
|
|
|
Operators_t operators;
|
2010-06-24 19:12:10 +00:00
|
|
|
|
ParserPtr elem_parser;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
/** operators_ - допустимые операторы и соответствующие им функции
|
|
|
|
|
*/
|
2014-03-10 14:47:04 +00:00
|
|
|
|
ParserPrefixUnaryOperatorExpression(Operators_t operators_, ParserPtr && elem_parser_)
|
|
|
|
|
: operators(operators_), elem_parser(std::move(elem_parser_))
|
2010-06-24 19:12:10 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
2015-04-11 03:10:23 +00:00
|
|
|
|
|
2010-06-24 19:12:10 +00:00
|
|
|
|
protected:
|
2014-03-10 12:25:37 +00:00
|
|
|
|
const char * getName() const { return "expression with prefix unary operator"; }
|
2015-04-11 03:10:23 +00:00
|
|
|
|
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
|
2010-06-24 19:12:10 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2015-11-07 23:18:39 +00:00
|
|
|
|
class ParserTupleElementExpression : public IParserBase
|
2010-06-24 19:12:10 +00:00
|
|
|
|
{
|
|
|
|
|
private:
|
2014-03-10 14:47:04 +00:00
|
|
|
|
static const char * operators[];
|
2015-01-16 10:17:58 +00:00
|
|
|
|
|
2010-06-24 19:12:10 +00:00
|
|
|
|
protected:
|
2015-11-07 23:18:39 +00:00
|
|
|
|
const char * getName() const { return "tuple element expression"; }
|
|
|
|
|
|
|
|
|
|
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ParserArrayElementExpression : public IParserBase
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
static const char * operators[];
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
const char * getName() const { return "array element expression"; }
|
2015-04-11 03:10:23 +00:00
|
|
|
|
|
|
|
|
|
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
|
2010-06-24 19:12:10 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ParserUnaryMinusExpression : public IParserBase
|
|
|
|
|
{
|
|
|
|
|
private:
|
2014-03-10 14:47:04 +00:00
|
|
|
|
static const char * operators[];
|
2015-11-07 23:18:39 +00:00
|
|
|
|
ParserPrefixUnaryOperatorExpression operator_parser {operators, ParserPtr(new ParserTupleElementExpression)};
|
2015-04-11 03:10:23 +00:00
|
|
|
|
|
2010-06-24 19:12:10 +00:00
|
|
|
|
protected:
|
2014-03-10 12:25:37 +00:00
|
|
|
|
const char * getName() const { return "unary minus expression"; }
|
2015-04-11 03:10:23 +00:00
|
|
|
|
|
|
|
|
|
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
|
2010-06-24 19:12:10 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ParserMultiplicativeExpression : public IParserBase
|
|
|
|
|
{
|
|
|
|
|
private:
|
2014-03-10 14:47:04 +00:00
|
|
|
|
static const char * operators[];
|
|
|
|
|
ParserLeftAssociativeBinaryOperatorList operator_parser {operators, ParserPtr(new ParserUnaryMinusExpression)};
|
|
|
|
|
|
2010-06-24 19:12:10 +00:00
|
|
|
|
protected:
|
2014-03-10 12:25:37 +00:00
|
|
|
|
const char * getName() const { return "multiplicative expression"; }
|
2015-04-11 03:10:23 +00:00
|
|
|
|
|
|
|
|
|
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
|
2010-06-24 19:12:10 +00:00
|
|
|
|
{
|
2015-04-11 03:10:23 +00:00
|
|
|
|
return operator_parser.parse(pos, end, node, max_parsed_pos, expected);
|
2010-06-24 19:12:10 +00:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ParserAdditiveExpression : public IParserBase
|
|
|
|
|
{
|
|
|
|
|
private:
|
2014-03-10 14:47:04 +00:00
|
|
|
|
static const char * operators[];
|
|
|
|
|
ParserLeftAssociativeBinaryOperatorList operator_parser {operators, ParserPtr(new ParserMultiplicativeExpression)};
|
2015-04-11 03:10:23 +00:00
|
|
|
|
|
2010-06-24 19:12:10 +00:00
|
|
|
|
protected:
|
2014-03-10 12:25:37 +00:00
|
|
|
|
const char * getName() const { return "additive expression"; }
|
2015-04-11 03:10:23 +00:00
|
|
|
|
|
|
|
|
|
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
|
2010-06-24 19:12:10 +00:00
|
|
|
|
{
|
2015-04-11 03:10:23 +00:00
|
|
|
|
return operator_parser.parse(pos, end, node, max_parsed_pos, expected);
|
2010-06-24 19:12:10 +00:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2016-04-03 01:15:53 +00:00
|
|
|
|
class ParserBetweenExpression : public IParserBase
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
ParserAdditiveExpression elem_parser;
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
const char * getName() const { return "BETWEEN expression"; }
|
|
|
|
|
|
|
|
|
|
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2010-06-24 19:12:10 +00:00
|
|
|
|
class ParserComparisonExpression : public IParserBase
|
|
|
|
|
{
|
|
|
|
|
private:
|
2014-03-10 14:47:04 +00:00
|
|
|
|
static const char * operators[];
|
2016-04-03 01:15:53 +00:00
|
|
|
|
ParserLeftAssociativeBinaryOperatorList operator_parser {operators, ParserPtr(new ParserBetweenExpression)};
|
2015-04-11 03:10:23 +00:00
|
|
|
|
|
2010-06-24 19:12:10 +00:00
|
|
|
|
protected:
|
2014-03-10 12:25:37 +00:00
|
|
|
|
const char * getName() const { return "comparison expression"; }
|
2015-04-11 03:10:23 +00:00
|
|
|
|
|
|
|
|
|
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
|
2010-06-24 19:12:10 +00:00
|
|
|
|
{
|
2015-04-11 03:10:23 +00:00
|
|
|
|
return operator_parser.parse(pos, end, node, max_parsed_pos, expected);
|
2010-06-24 19:12:10 +00:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ParserLogicalNotExpression : public IParserBase
|
|
|
|
|
{
|
|
|
|
|
private:
|
2014-03-10 14:47:04 +00:00
|
|
|
|
static const char * operators[];
|
|
|
|
|
ParserPrefixUnaryOperatorExpression operator_parser {operators, ParserPtr(new ParserComparisonExpression)};
|
|
|
|
|
|
2010-06-24 19:12:10 +00:00
|
|
|
|
protected:
|
2014-03-10 12:25:37 +00:00
|
|
|
|
const char * getName() const { return "logical-NOT expression"; }
|
2015-04-11 03:10:23 +00:00
|
|
|
|
|
|
|
|
|
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
|
2010-06-24 19:12:10 +00:00
|
|
|
|
{
|
2015-04-11 03:10:23 +00:00
|
|
|
|
return operator_parser.parse(pos, end, node, max_parsed_pos, expected);
|
2010-06-24 19:12:10 +00:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ParserLogicalAndExpression : public IParserBase
|
|
|
|
|
{
|
|
|
|
|
private:
|
2014-02-13 11:05:51 +00:00
|
|
|
|
ParserVariableArityOperatorList operator_parser;
|
2010-06-24 19:12:10 +00:00
|
|
|
|
public:
|
|
|
|
|
ParserLogicalAndExpression()
|
2014-03-10 14:47:04 +00:00
|
|
|
|
: operator_parser("AND", "and", ParserPtr(new ParserLogicalNotExpression))
|
2010-06-24 19:12:10 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
2015-04-11 03:10:23 +00:00
|
|
|
|
|
2010-06-24 19:12:10 +00:00
|
|
|
|
protected:
|
2014-03-10 12:25:37 +00:00
|
|
|
|
const char * getName() const { return "logical-AND expression"; }
|
2015-04-11 03:10:23 +00:00
|
|
|
|
|
|
|
|
|
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
|
2010-06-24 19:12:10 +00:00
|
|
|
|
{
|
2015-04-11 03:10:23 +00:00
|
|
|
|
return operator_parser.parse(pos, end, node, max_parsed_pos, expected);
|
2010-06-24 19:12:10 +00:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ParserLogicalOrExpression : public IParserBase
|
|
|
|
|
{
|
|
|
|
|
private:
|
2014-02-13 11:05:51 +00:00
|
|
|
|
ParserVariableArityOperatorList operator_parser;
|
2010-06-24 19:12:10 +00:00
|
|
|
|
public:
|
|
|
|
|
ParserLogicalOrExpression()
|
2014-03-10 14:47:04 +00:00
|
|
|
|
: operator_parser("OR", "or", ParserPtr(new ParserLogicalAndExpression))
|
2010-06-24 19:12:10 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
2015-04-11 03:10:23 +00:00
|
|
|
|
|
2010-06-24 19:12:10 +00:00
|
|
|
|
protected:
|
2014-03-10 12:25:37 +00:00
|
|
|
|
const char * getName() const { return "logical-OR expression"; }
|
2015-04-11 03:10:23 +00:00
|
|
|
|
|
|
|
|
|
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
|
2010-06-24 19:12:10 +00:00
|
|
|
|
{
|
2015-04-11 03:10:23 +00:00
|
|
|
|
return operator_parser.parse(pos, end, node, max_parsed_pos, expected);
|
2010-06-24 19:12:10 +00:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2012-09-23 06:16:42 +00:00
|
|
|
|
/** Выражение с тернарным оператором.
|
|
|
|
|
* Например, a = 1 ? b + 1 : c * 2.
|
|
|
|
|
*/
|
|
|
|
|
class ParserTernaryOperatorExpression : public IParserBase
|
|
|
|
|
{
|
|
|
|
|
private:
|
2014-03-10 14:47:04 +00:00
|
|
|
|
ParserLogicalOrExpression elem_parser;
|
2012-09-23 06:16:42 +00:00
|
|
|
|
|
|
|
|
|
protected:
|
2014-03-10 12:25:37 +00:00
|
|
|
|
const char * getName() const { return "expression with ternary operator"; }
|
2012-09-23 06:16:42 +00:00
|
|
|
|
|
2015-04-11 03:10:23 +00:00
|
|
|
|
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
|
2012-09-23 06:16:42 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2013-05-08 09:52:02 +00:00
|
|
|
|
class ParserLambdaExpression : public IParserBase
|
|
|
|
|
{
|
|
|
|
|
private:
|
2014-03-10 14:47:04 +00:00
|
|
|
|
ParserTernaryOperatorExpression elem_parser;
|
2015-04-11 03:10:23 +00:00
|
|
|
|
|
2013-05-08 09:52:02 +00:00
|
|
|
|
protected:
|
2014-03-10 12:25:37 +00:00
|
|
|
|
const char * getName() const { return "lambda expression"; }
|
2015-04-11 03:10:23 +00:00
|
|
|
|
|
|
|
|
|
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
|
2013-05-08 09:52:02 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2011-11-06 20:47:07 +00:00
|
|
|
|
class ParserExpressionWithOptionalAlias : public IParserBase
|
|
|
|
|
{
|
|
|
|
|
public:
|
2015-11-08 00:28:12 +00:00
|
|
|
|
ParserExpressionWithOptionalAlias(bool allow_alias_without_as_keyword);
|
2011-11-06 20:47:07 +00:00
|
|
|
|
protected:
|
|
|
|
|
ParserPtr impl;
|
|
|
|
|
|
2014-03-10 12:25:37 +00:00
|
|
|
|
const char * getName() const { return "expression with optional alias"; }
|
2015-04-11 03:10:23 +00:00
|
|
|
|
|
|
|
|
|
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
|
2011-11-06 20:47:07 +00:00
|
|
|
|
{
|
2015-04-11 03:10:23 +00:00
|
|
|
|
return impl->parse(pos, end, node, max_parsed_pos, expected);
|
2011-11-06 20:47:07 +00:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2015-12-24 17:14:10 +00:00
|
|
|
|
class ParserExpressionInCastExpression : public IParserBase
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
ParserExpressionInCastExpression(bool allow_alias_without_as_keyword);
|
|
|
|
|
protected:
|
|
|
|
|
ParserPtr impl;
|
|
|
|
|
|
|
|
|
|
const char * getName() const { return "expression in CAST expression"; }
|
|
|
|
|
|
|
|
|
|
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
|
|
|
|
|
{
|
|
|
|
|
return impl->parse(pos, end, node, max_parsed_pos, expected);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2011-11-06 20:47:07 +00:00
|
|
|
|
|
2010-06-24 19:12:10 +00:00
|
|
|
|
/** Список выражений, разделённых запятыми, возможно пустой. */
|
|
|
|
|
class ParserExpressionList : public IParserBase
|
|
|
|
|
{
|
2015-11-08 00:28:12 +00:00
|
|
|
|
public:
|
|
|
|
|
ParserExpressionList(bool allow_alias_without_as_keyword_)
|
|
|
|
|
: allow_alias_without_as_keyword(allow_alias_without_as_keyword_) {}
|
|
|
|
|
|
2010-06-24 19:12:10 +00:00
|
|
|
|
protected:
|
2015-11-08 00:28:12 +00:00
|
|
|
|
bool allow_alias_without_as_keyword;
|
|
|
|
|
|
2014-03-10 12:25:37 +00:00
|
|
|
|
const char * getName() const { return "list of expressions"; }
|
2015-04-11 03:10:23 +00:00
|
|
|
|
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
|
2010-06-24 19:12:10 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ParserNotEmptyExpressionList : public IParserBase
|
|
|
|
|
{
|
2015-11-08 00:28:12 +00:00
|
|
|
|
public:
|
|
|
|
|
ParserNotEmptyExpressionList(bool allow_alias_without_as_keyword)
|
|
|
|
|
: nested_parser(allow_alias_without_as_keyword) {}
|
2010-06-24 19:12:10 +00:00
|
|
|
|
private:
|
|
|
|
|
ParserExpressionList nested_parser;
|
|
|
|
|
protected:
|
2014-03-10 12:25:37 +00:00
|
|
|
|
const char * getName() const { return "not empty list of expressions"; }
|
2015-04-11 03:10:23 +00:00
|
|
|
|
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
|
2010-06-24 19:12:10 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2011-09-04 05:14:52 +00:00
|
|
|
|
class ParserOrderByExpressionList : public IParserBase
|
|
|
|
|
{
|
|
|
|
|
protected:
|
2014-03-10 12:25:37 +00:00
|
|
|
|
const char * getName() const { return "order by expression"; }
|
2015-04-11 03:10:23 +00:00
|
|
|
|
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected);
|
2011-09-04 05:14:52 +00:00
|
|
|
|
};
|
2010-06-24 19:12:10 +00:00
|
|
|
|
|
|
|
|
|
|
2011-09-04 05:14:52 +00:00
|
|
|
|
}
|