mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
dbms: development.
This commit is contained in:
parent
e5d9895b57
commit
a3470586b9
@ -18,6 +18,7 @@ public:
|
|||||||
StringRange range;
|
StringRange range;
|
||||||
ASTs children;
|
ASTs children;
|
||||||
|
|
||||||
|
ASTExpressionList() {}
|
||||||
ASTExpressionList(StringRange range_) : range(range_) {}
|
ASTExpressionList(StringRange range_) : range(range_) {}
|
||||||
|
|
||||||
/** Получить кусок текста, откуда был получен этот элемент. */
|
/** Получить кусок текста, откуда был получен этот элемент. */
|
||||||
|
@ -18,6 +18,7 @@ public:
|
|||||||
/// параметры
|
/// параметры
|
||||||
ASTPtr arguments;
|
ASTPtr arguments;
|
||||||
|
|
||||||
|
ASTFunction() {}
|
||||||
ASTFunction(StringRange range_) : range(range_) {}
|
ASTFunction(StringRange range_) : range(range_) {}
|
||||||
|
|
||||||
/** Получить кусок текста, откуда был получен этот элемент. */
|
/** Получить кусок текста, откуда был получен этот элемент. */
|
||||||
|
@ -16,6 +16,7 @@ public:
|
|||||||
/// имя
|
/// имя
|
||||||
String name;
|
String name;
|
||||||
|
|
||||||
|
ASTIdentifier() {}
|
||||||
ASTIdentifier(StringRange range_, const String & name_) : range(range_), name(name_) {}
|
ASTIdentifier(StringRange range_, const String & name_) : range(range_), name(name_) {}
|
||||||
|
|
||||||
/** Получить кусок текста, откуда был получен этот элемент. */
|
/** Получить кусок текста, откуда был получен этот элемент. */
|
||||||
|
@ -17,6 +17,7 @@ public:
|
|||||||
/// значение
|
/// значение
|
||||||
Field value;
|
Field value;
|
||||||
|
|
||||||
|
ASTLiteral() {}
|
||||||
ASTLiteral(StringRange range_, const Field & value_) : range(range_), value(value_) {}
|
ASTLiteral(StringRange range_, const Field & value_) : range(range_), value(value_) {}
|
||||||
|
|
||||||
/** Получить кусок текста, откуда был получен этот элемент. */
|
/** Получить кусок текста, откуда был получен этот элемент. */
|
||||||
|
@ -16,6 +16,7 @@ public:
|
|||||||
StringRange range;
|
StringRange range;
|
||||||
ASTPtr select, from, where, group, having, order, limit;
|
ASTPtr select, from, where, group, having, order, limit;
|
||||||
|
|
||||||
|
ASTSelectQuery() {}
|
||||||
ASTSelectQuery(StringRange range_) : range(range_) {}
|
ASTSelectQuery(StringRange range_) : range(range_) {}
|
||||||
|
|
||||||
/** Получить кусок текста, откуда был получен этот элемент. */
|
/** Получить кусок текста, откуда был получен этот элемент. */
|
||||||
|
@ -12,14 +12,24 @@ namespace DB
|
|||||||
using Poco::SharedPtr;
|
using Poco::SharedPtr;
|
||||||
|
|
||||||
|
|
||||||
/** если прямо сейчас не s, то ошибка
|
/** Если прямо сейчас не s, то ошибка.
|
||||||
|
* Если word_boundary установлен в true, и последний символ строки - словарный (\w),
|
||||||
|
* то проверяется, что последующий символ строки не словарный.
|
||||||
*/
|
*/
|
||||||
class ParserString : public IParserBase
|
class ParserString : public IParserBase
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
String s;
|
String s;
|
||||||
|
bool word_boundary;
|
||||||
|
|
||||||
|
inline bool is_word(char c)
|
||||||
|
{
|
||||||
|
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || (c == '_');
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ParserString(const String & s_) : s(s_) {}
|
ParserString(const String & s_, bool word_boundary_ = false) : s(s_), word_boundary(word_boundary_) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
String getName() { return s; }
|
String getName() { return s; }
|
||||||
|
|
||||||
@ -29,6 +39,10 @@ protected:
|
|||||||
return false;
|
return false;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (word_boundary && s.size() && is_word(*s.rbegin())
|
||||||
|
&& pos + s.size() != end && is_word(pos[s.size()]))
|
||||||
|
return false;
|
||||||
|
|
||||||
pos += s.size();
|
pos += s.size();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -36,28 +50,6 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/** если сейчас словарный символ - то ошибка
|
|
||||||
* понимается только латиница
|
|
||||||
*/
|
|
||||||
class ParserNotWordCharOrEnd : public IParserBase
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
String getName() { return "non-word character"; }
|
|
||||||
|
|
||||||
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
|
|
||||||
{
|
|
||||||
if (pos == end)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if ((*pos >= 'a' && *pos <= 'z') || (*pos >= 'A' && *pos <= 'Z') || (*pos >= '0' && *pos <= '9') || *pos == '_')
|
|
||||||
return false;
|
|
||||||
|
|
||||||
++pos;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/** пробельные символы
|
/** пробельные символы
|
||||||
*/
|
*/
|
||||||
class ParserWhiteSpace : public IParserBase
|
class ParserWhiteSpace : public IParserBase
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef DBMS_PARSERS_EXPRESSIONLISTPARSERS_H
|
#ifndef DBMS_PARSERS_EXPRESSIONLISTPARSERS_H
|
||||||
#define DBMS_PARSERS_EXPRESSIONLISTPARSERS_H
|
#define DBMS_PARSERS_EXPRESSIONLISTPARSERS_H
|
||||||
|
|
||||||
#include <map>
|
#include <list>
|
||||||
|
|
||||||
#include <boost/assign/list_of.hpp>
|
#include <boost/assign/list_of.hpp>
|
||||||
|
|
||||||
@ -12,8 +12,10 @@
|
|||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
|
||||||
/** Оператор и соответствующая ему функция. Например, "+" -> "plus" */
|
/** Оператор и соответствующая ему функция. Например, "+" -> "plus"
|
||||||
typedef std::map<String, String> Operators_t;
|
* Не std::map, так как порядок парсинга операторов задаётся явно и может отличаться от алфавитного.
|
||||||
|
*/
|
||||||
|
typedef std::list<std::pair<String, String> > Operators_t;
|
||||||
|
|
||||||
|
|
||||||
/** Выражение с инфиксным бинарным лево-ассоциативным оператором.
|
/** Выражение с инфиксным бинарным лево-ассоциативным оператором.
|
||||||
|
@ -23,14 +23,12 @@ protected:
|
|||||||
ASTPtr select_expression_list;
|
ASTPtr select_expression_list;
|
||||||
|
|
||||||
ParserWhiteSpaceOrComments ws;
|
ParserWhiteSpaceOrComments ws;
|
||||||
ParserString s("SELECT");
|
ParserString s("SELECT", true);
|
||||||
ParserNotWordCharOrEnd nw;
|
|
||||||
ParserNotEmptyExpressionList exp_list;
|
ParserNotEmptyExpressionList exp_list;
|
||||||
|
|
||||||
ws.ignore(pos, end);
|
ws.ignore(pos, end);
|
||||||
|
|
||||||
if (!(s.ignore(pos, end, expected)
|
if (!s.ignore(pos, end, expected))
|
||||||
&& nw.check(pos, end, expected)))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ws.ignore(pos, end);
|
ws.ignore(pos, end);
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include <DB/Parsers/ExpressionElementParsers.h>
|
#include <DB/Parsers/ExpressionElementParsers.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
@ -118,13 +119,10 @@ bool ParserFunction::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expec
|
|||||||
ParserExpressionList contents;
|
ParserExpressionList contents;
|
||||||
ParserWhiteSpaceOrComments ws;
|
ParserWhiteSpaceOrComments ws;
|
||||||
|
|
||||||
ASTIdentifier * p_identifier = new ASTIdentifier(StringRange(begin, pos), "");
|
ASTPtr identifier = new ASTIdentifier;
|
||||||
ASTIdentifier & identifier = *p_identifier;
|
ASTPtr expr_list = new ASTExpressionList;
|
||||||
ASTPtr identifier_node = p_identifier;
|
|
||||||
|
|
||||||
ASTPtr expr_list_node = new ASTExpressionList(StringRange(begin, pos));
|
if (!id_parser.parse(pos, end, identifier, expected))
|
||||||
|
|
||||||
if (!id_parser.parse(pos, end, identifier_node, expected))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ws.ignore(pos, end);
|
ws.ignore(pos, end);
|
||||||
@ -133,15 +131,15 @@ bool ParserFunction::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expec
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
ws.ignore(pos, end);
|
ws.ignore(pos, end);
|
||||||
contents.parse(pos, end, expr_list_node, expected);
|
contents.parse(pos, end, expr_list, expected);
|
||||||
ws.ignore(pos, end);
|
ws.ignore(pos, end);
|
||||||
|
|
||||||
if (!close.ignore(pos, end, expected))
|
if (!close.ignore(pos, end, expected))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ASTFunction * function_node = new ASTFunction(StringRange(begin, pos));
|
ASTFunction * function_node = new ASTFunction(StringRange(begin, pos));
|
||||||
function_node->name = identifier.name;
|
function_node->name = dynamic_cast<ASTIdentifier &>(*identifier).name;
|
||||||
function_node->arguments = expr_list_node;
|
function_node->arguments = expr_list;
|
||||||
node = function_node;
|
node = function_node;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -150,7 +148,7 @@ bool ParserFunction::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expec
|
|||||||
bool ParserNull::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
|
bool ParserNull::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
|
||||||
{
|
{
|
||||||
Pos begin = pos;
|
Pos begin = pos;
|
||||||
ParserString nested_parser("NULL");
|
ParserString nested_parser("NULL", true);
|
||||||
if (nested_parser.parse(pos, end, node, expected))
|
if (nested_parser.parse(pos, end, node, expected))
|
||||||
{
|
{
|
||||||
node = new ASTLiteral(StringRange(StringRange(begin, pos)), Null());
|
node = new ASTLiteral(StringRange(StringRange(begin, pos)), Null());
|
||||||
@ -209,6 +207,8 @@ bool ParserStringLiteral::parseImpl(Pos & pos, Pos end, ASTPtr & node, String &
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
++pos;
|
||||||
|
|
||||||
while (pos != end)
|
while (pos != end)
|
||||||
{
|
{
|
||||||
size_t bytes = 0;
|
size_t bytes = 0;
|
||||||
|
@ -35,7 +35,7 @@ bool ParserLeftAssociativeBinaryOperatorList::parseImpl(Pos & pos, Pos end, ASTP
|
|||||||
Operators_t::const_iterator it;
|
Operators_t::const_iterator it;
|
||||||
for (it = operators.begin(); it != operators.end(); ++it)
|
for (it = operators.begin(); it != operators.end(); ++it)
|
||||||
{
|
{
|
||||||
ParserString op(it->first);
|
ParserString op(it->first, true);
|
||||||
if (op.ignore(pos, end, expected))
|
if (op.ignore(pos, end, expected))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -46,12 +46,12 @@ bool ParserLeftAssociativeBinaryOperatorList::parseImpl(Pos & pos, Pos end, ASTP
|
|||||||
ws.ignore(pos, end);
|
ws.ignore(pos, end);
|
||||||
|
|
||||||
/// функция, соответствующая оператору
|
/// функция, соответствующая оператору
|
||||||
ASTFunction * p_function = new ASTFunction(StringRange(pos, pos));
|
ASTFunction * p_function = new ASTFunction;
|
||||||
ASTFunction & function = *p_function;
|
ASTFunction & function = *p_function;
|
||||||
ASTPtr function_node = p_function;
|
ASTPtr function_node = p_function;
|
||||||
|
|
||||||
/// аргументы функции
|
/// аргументы функции
|
||||||
ASTExpressionList * p_exp_list = new ASTExpressionList(StringRange(pos, pos));
|
ASTExpressionList * p_exp_list = new ASTExpressionList;
|
||||||
ASTExpressionList & exp_list = *p_exp_list;
|
ASTExpressionList & exp_list = *p_exp_list;
|
||||||
ASTPtr exp_list_node = p_exp_list;
|
ASTPtr exp_list_node = p_exp_list;
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ bool ParserPrefixUnaryOperatorExpression::parseImpl(Pos & pos, Pos end, ASTPtr &
|
|||||||
Operators_t::const_iterator it;
|
Operators_t::const_iterator it;
|
||||||
for (it = operators.begin(); it != operators.end(); ++it)
|
for (it = operators.begin(); it != operators.end(); ++it)
|
||||||
{
|
{
|
||||||
ParserString op(it->first);
|
ParserString op(it->first, true);
|
||||||
if (op.ignore(pos, end, expected))
|
if (op.ignore(pos, end, expected))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -116,12 +116,12 @@ bool ParserPrefixUnaryOperatorExpression::parseImpl(Pos & pos, Pos end, ASTPtr &
|
|||||||
ws.ignore(pos, end);
|
ws.ignore(pos, end);
|
||||||
|
|
||||||
/// функция, соответствующая оператору
|
/// функция, соответствующая оператору
|
||||||
ASTFunction * p_function = new ASTFunction(StringRange(pos, pos));
|
ASTFunction * p_function = new ASTFunction;
|
||||||
ASTFunction & function = *p_function;
|
ASTFunction & function = *p_function;
|
||||||
ASTPtr function_node = p_function;
|
ASTPtr function_node = p_function;
|
||||||
|
|
||||||
/// аргументы функции
|
/// аргументы функции
|
||||||
ASTExpressionList * p_exp_list = new ASTExpressionList(StringRange(pos, pos));
|
ASTExpressionList * p_exp_list = new ASTExpressionList;
|
||||||
ASTExpressionList & exp_list = *p_exp_list;
|
ASTExpressionList & exp_list = *p_exp_list;
|
||||||
ASTPtr exp_list_node = p_exp_list;
|
ASTPtr exp_list_node = p_exp_list;
|
||||||
|
|
||||||
@ -157,7 +157,7 @@ bool ParserExpressionList::parseImpl(Pos & pos, Pos end, ASTPtr & node, String &
|
|||||||
ParserWhiteSpaceOrComments ws;
|
ParserWhiteSpaceOrComments ws;
|
||||||
ParserString comma(",");
|
ParserString comma(",");
|
||||||
|
|
||||||
ASTExpressionList * p_expr_list = new ASTExpressionList(StringRange(pos, pos));
|
ASTExpressionList * p_expr_list = new ASTExpressionList;
|
||||||
ASTExpressionList & expr_list = *p_expr_list;
|
ASTExpressionList & expr_list = *p_expr_list;
|
||||||
node = p_expr_list;
|
node = p_expr_list;
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ int main(int argc, char ** argv)
|
|||||||
{
|
{
|
||||||
DB::ParserSelectQuery parser;
|
DB::ParserSelectQuery parser;
|
||||||
DB::ASTPtr ast;
|
DB::ASTPtr ast;
|
||||||
std::string input = "SELECT 1, 2, 3";
|
std::string input = "SELECT f(x), 1, 2, 3, x, NULL, 'abc\\\\def\\'\\\\''";
|
||||||
std::string expected;
|
std::string expected;
|
||||||
|
|
||||||
const char * begin = input.data();
|
const char * begin = input.data();
|
||||||
|
Loading…
Reference in New Issue
Block a user