This commit is contained in:
Michael Kolupaev 2014-03-17 22:27:43 +04:00
commit 0faca75b37
80 changed files with 1143 additions and 559 deletions

View File

@ -452,41 +452,32 @@ private:
for (size_t i = 0; i < col_size; ++i)
{
// std::cerr << "i: " << i << std::endl;
/// Насколько размножить массив.
size_t size_to_replicate = replicate_offsets[i] - prev_replicate_offset;
// std::cerr << "size_to_replicate: " << size_to_replicate << std::endl;
/// Количество строк в массиве.
size_t value_size = cur_offsets[i] - prev_cur_offset;
// std::cerr << "value_size: " << value_size << std::endl;
size_t sum_chars_size = 0;
for (size_t j = 0; j < size_to_replicate; ++j)
{
// std::cerr << "j: " << j << std::endl;
current_res_offset += value_size;
res_offsets.push_back(current_res_offset);
// std::cerr << "current_res_offset: " << current_res_offset << std::endl;
sum_chars_size = 0;
size_t prev_cur_string_offset_local = prev_cur_string_offset;
for (size_t k = 0; k < value_size; ++k)
{
// std::cerr << "k: " << k << std::endl;
/// Размер одной строки.
size_t chars_size = cur_string_offsets[k + prev_cur_offset] - prev_cur_string_offset_local;
// std::cerr << "chars_size: " << chars_size << std::endl;
current_res_string_offset += chars_size;
res_string_offsets.push_back(current_res_string_offset);
// std::cerr << "current_res_string_offset: " << current_res_string_offset << std::endl;
/// Копирование символов одной строки.
res_chars.resize(res_chars.size() + chars_size);
memcpy(&res_chars[res_chars.size() - chars_size], &cur_chars[prev_cur_string_offset_local], chars_size);
// std::cerr << "copied: " << mysqlxx::escape << std::string(reinterpret_cast<const char *>(&cur_chars[prev_cur_string_offset_local]), chars_size) << std::endl;
sum_chars_size += chars_size;
prev_cur_string_offset_local += chars_size;

View File

@ -16,6 +16,9 @@ class ColumnSet : public IColumnDummy
public:
ColumnSet(size_t s_, SetPtr data_) : IColumnDummy(s_), data(data_) {}
/// Столбец не константный. Иначе столбец будет использоваться в вычислениях в ExpressionActions::prepare, когда множество из подзапроса ещё не готово.
bool isConst() const { return false; }
std::string getName() const { return "ColumnSet"; }
ColumnPtr cloneDummy(size_t s_) const { return new ColumnSet(s_, data); }

View File

@ -18,7 +18,7 @@ public:
virtual ColumnPtr cloneDummy(size_t s_) const = 0;
ColumnPtr cloneResized(size_t s_) const { return cloneDummy(s_); }
bool isConst() { return true; }
bool isConst() const { return true; }
size_t size() const { return s; }
void insertDefault() { ++s; }
size_t byteSize() const { return 0; }

View File

@ -85,10 +85,9 @@ public:
removeOverflow();
}
void getStats(size_t & out_hits, size_t & out_misses) const volatile
void getStats(size_t & out_hits, size_t & out_misses) const
{
Poco::ScopedLock<Poco::FastMutex> lock(mutex);
/// Синхронизация не нужна.
out_hits = hits;
out_misses = misses;
}
@ -135,7 +134,7 @@ private:
size_t current_size = 0;
const size_t max_size;
Poco::FastMutex mutex;
mutable Poco::FastMutex mutex;
size_t hits = 0;
size_t misses = 0;

View File

@ -10,7 +10,6 @@
#include <DB/Parsers/ASTLiteral.h>
#include <DB/Parsers/ASTSelectQuery.h>
#include <DB/Storages/StoragePtr.h>
#include <DB/Interpreters/InterpreterSelectQuery.h>
#include <DB/Columns/ColumnString.h>
namespace DB

View File

@ -73,7 +73,7 @@ namespace Protocol
inline const char * toString(UInt64 packet)
{
static const char * data[] = { "Hello", "Data", "Exception", "Progress", "Pong", "EndOfStream", "ProfileInfo", "Totals", "Extremes" };
return packet >= 0 && packet < 9
return packet < 9
? data[packet]
: "Unknown packet";
}
@ -97,7 +97,7 @@ namespace Protocol
inline const char * toString(UInt64 packet)
{
static const char * data[] = { "Hello", "Query", "Data", "Cancel", "Ping" };
return packet >= 0 && packet < 5
return packet < 5
? data[packet]
: "Unknown packet";
}

View File

@ -20,7 +20,7 @@ namespace QueryProcessingStage
inline const char * toString(UInt64 stage)
{
static const char * data[] = { "FetchColumns", "WithMergeableState", "Complete" };
return stage >= 0 && stage < 3
return stage < 3
? data[stage]
: "Unknown stage";
}

View File

@ -18,7 +18,7 @@ using Poco::SharedPtr;
* Функция принимает количество строк в последнем блоке, количество байт в последнем блоке.
* Следует иметь ввиду, что колбэк может вызываться из разных потоков.
*/
typedef boost::function<void(size_t, size_t)> ProgressCallback;
typedef std::function<void(size_t, size_t)> ProgressCallback;
/** Интерфейс потока для чтения данных по блокам из БД.

View File

@ -23,11 +23,9 @@ public:
std::string getName() const;
static std::string concatenateNestedName(const std::string & nested_table_name, const std::string & nested_field_name);
static std::pair<std::string, std::string> splitNestedName(const std::string & nested_name);
static bool isNestedName(const std::string & nested_name);
/// Возвращает префикс имени до первой точки '.'. Или имя без изменений, если точки нет.
static std::string extractNestedTableName(const std::string & nested_name);
/// Возвращает суффикс имени до первой точки справа '.'. Или имя без изменений, если точки нет.
/// Возвращает суффикс имени после первой точки справа '.'. Или имя без изменений, если точки нет.
static std::string extractNestedColumnName(const std::string & nested_name);
DataTypePtr clone() const

View File

@ -20,12 +20,12 @@ namespace DB
*/
struct Memory : boost::noncopyable
{
size_t m_capacity;
size_t m_size;
char * m_data;
size_t alignment;
size_t m_capacity = 0;
size_t m_size = 0;
char * m_data = nullptr;
size_t alignment = 0;
Memory() : m_capacity(0), m_size(0), m_data(NULL), alignment(0) {}
Memory() {}
/// Если alignment != 0, то будет выделяться память, выровненная на alignment.
Memory(size_t size_, size_t alignment_ = 0) : m_capacity(size_), m_size(m_capacity), alignment(alignment_)
@ -38,6 +38,21 @@ struct Memory : boost::noncopyable
dealloc();
}
Memory(Memory && rhs)
{
*this = std::move(rhs);
}
Memory & operator=(Memory && rhs)
{
std::swap(m_capacity, rhs.m_capacity);
std::swap(m_size, rhs.m_size);
std::swap(m_data, rhs.m_data);
std::swap(alignment, rhs.alignment);
return *this;
}
size_t size() const { return m_size; }
const char & operator[](size_t i) const { return m_data[i]; }
char & operator[](size_t i) { return m_data[i]; }

View File

@ -51,7 +51,7 @@ public:
session.setPort(port);
/// устанавливаем таймаут
session.setTimeout(Poco::Timespan(timeout_ || DEFAULT_REMOTE_READ_BUFFER_TIMEOUT, 0));
session.setTimeout(Poco::Timespan(timeout_ ? timeout_ : DEFAULT_REMOTE_READ_BUFFER_TIMEOUT, 0));
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, uri.str());
Poco::Net::HTTPResponse response;
@ -100,7 +100,7 @@ public:
Poco::Net::HTTPClientSession session;
session.setHost(host);
session.setPort(port);
session.setTimeout(Poco::Timespan(timeout_ || DEFAULT_REMOTE_READ_BUFFER_TIMEOUT, 0));
session.setTimeout(Poco::Timespan(timeout_ ? timeout_ : DEFAULT_REMOTE_READ_BUFFER_TIMEOUT, 0));
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, uri.str());
Poco::Net::HTTPResponse response;

View File

@ -417,7 +417,9 @@ public:
size_degree = new_size <= 1
? GrowthTraits::INITIAL_SIZE_DEGREE
: std::max(GrowthTraits::INITIAL_SIZE_DEGREE, static_cast<int>(log2(new_size - 1)) + 2);
: ((GrowthTraits::INITIAL_SIZE_DEGREE > static_cast<int>(log2(new_size - 1)) + 2)
? GrowthTraits::INITIAL_SIZE_DEGREE
: (static_cast<int>(log2(new_size - 1)) + 2));
alloc();
@ -436,7 +438,9 @@ public:
size_t new_size_degree = new_size <= 1
? GrowthTraits::INITIAL_SIZE_DEGREE
: std::max(GrowthTraits::INITIAL_SIZE_DEGREE, static_cast<int>(log2(new_size - 1)) + 2);
: ((GrowthTraits::INITIAL_SIZE_DEGREE > static_cast<int>(log2(new_size - 1)) + 2)
? GrowthTraits::INITIAL_SIZE_DEGREE
: (static_cast<int>(log2(new_size - 1)) + 2));
if (new_size_degree > size_degree)
resize(new_size_degree);

View File

@ -65,7 +65,7 @@ private:
void executeTotalsAndHaving( BlockInputStreams & streams, bool has_having, ExpressionActionsPtr expression,
bool overflow_row);
void executeHaving( BlockInputStreams & streams, ExpressionActionsPtr expression);
void executeOuterExpression( BlockInputStreams & streams, ExpressionActionsPtr expression);
void executeExpression( BlockInputStreams & streams, ExpressionActionsPtr expression);
void executeOrder( BlockInputStreams & streams);
void executePreLimit( BlockInputStreams & streams);
void executeUnion( BlockInputStreams & streams);

View File

@ -86,7 +86,6 @@ private:
Sizes key_sizes;
UInt128Hash hash_func_128;
StringRefHash hash_func_string;
/// Для более точного контроля max_rows_to_group_by.

View File

@ -18,7 +18,8 @@ using Poco::SharedPtr;
class ParserString : public IParserBase
{
private:
String s;
const char * s;
size_t s_size;
bool word_boundary;
bool case_insensitive;
@ -28,23 +29,23 @@ private:
}
public:
ParserString(const String & s_, bool word_boundary_ = false, bool case_insensitive_ = false)
: s(s_), word_boundary(word_boundary_), case_insensitive(case_insensitive_) {}
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_) {}
protected:
String getName() { return s; }
const char * getName() const { return s; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
if (static_cast<ssize_t>(s.size()) > end - pos || (case_insensitive ? strncasecmp : strncmp)(pos, s.data(), s.size()))
if (static_cast<ssize_t>(s_size) > end - pos || (case_insensitive ? strncasecmp : strncmp)(pos, s, s_size))
return false;
else
{
if (word_boundary && s.size() && is_word(*s.rbegin())
&& pos + s.size() != end && is_word(pos[s.size()]))
if (word_boundary && s_size && is_word(s[s_size - 1])
&& pos + s_size != end && is_word(pos[s_size]))
return false;
pos += s.size();
pos += s_size;
return true;
}
}
@ -61,9 +62,9 @@ public:
protected:
bool allow_newlines;
String getName() { return "white space"; }
const char * getName() const { return "white space"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
Pos begin = pos;
while (*pos == ' ' || *pos == '\t' || (allow_newlines && *pos == '\n') || *pos == '\r' || *pos == '\f')
@ -77,9 +78,9 @@ protected:
class ParserCStyleComment : public IParserBase
{
protected:
String getName() { return "C-style comment"; }
const char * getName() const { return "C-style comment"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
if (end - pos >= 4 && pos[0] == '/' && pos[1] == '*')
{
@ -107,9 +108,9 @@ protected:
class ParserSQLStyleComment : public IParserBase
{
protected:
String getName() { return "SQL-style comment"; }
const char * getName() const { return "SQL-style comment"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
if (end - pos >= 2 && pos[0] == '-' && pos[1] == '-')
{
@ -132,9 +133,9 @@ protected:
class ParserComment : public IParserBase
{
protected:
String getName() { return "comment"; }
const char * getName() const { return "comment"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
ParserCStyleComment p1;
ParserSQLStyleComment p2;
@ -153,9 +154,9 @@ public:
protected:
bool allow_newlines_outside_comments;
String getName() { return "white space or comments"; }
const char * getName() const { return "white space or comments"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
ParserWhiteSpace p1(allow_newlines_outside_comments);
ParserComment p2;

View File

@ -10,8 +10,8 @@ namespace DB
class ParserArray : public IParserBase
{
protected:
String getName() { return "array"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "array"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
@ -22,8 +22,8 @@ protected:
class ParserParenthesisExpression : public IParserBase
{
protected:
String getName() { return "expression in parenthesis"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "expression in parenthesis"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
@ -32,8 +32,8 @@ protected:
class ParserSubquery : public IParserBase
{
protected:
String getName() { return "SELECT subquery"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "SELECT subquery"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
@ -42,8 +42,8 @@ protected:
class ParserIdentifier : public IParserBase
{
protected:
String getName() { return "identifier"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "identifier"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
@ -52,8 +52,8 @@ protected:
class ParserCompoundIdentifier : public IParserBase
{
protected:
String getName() { return "compound identifier"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "compound identifier"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
@ -65,8 +65,8 @@ protected:
class ParserFunction : public IParserBase
{
protected:
String getName() { return "function"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "function"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
@ -75,8 +75,8 @@ protected:
class ParserNull : public IParserBase
{
protected:
String getName() { return "NULL"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "NULL"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
@ -85,8 +85,8 @@ protected:
class ParserNumber : public IParserBase
{
protected:
String getName() { return "number"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "number"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
@ -95,8 +95,8 @@ protected:
class ParserStringLiteral : public IParserBase
{
protected:
String getName() { return "string literal"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "string literal"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
@ -105,8 +105,8 @@ protected:
class ParserLiteral : public IParserBase
{
protected:
String getName() { return "literal"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "literal"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
@ -115,8 +115,8 @@ protected:
class ParserAlias : public IParserBase
{
protected:
String getName() { return "alias"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "alias"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
@ -125,8 +125,8 @@ protected:
class ParserExpressionElement : public IParserBase
{
protected:
String getName() { return "element of expression"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "element of expression"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
@ -135,12 +135,12 @@ protected:
class ParserWithOptionalAlias : public IParserBase
{
public:
ParserWithOptionalAlias(ParserPtr elem_parser_) : elem_parser(elem_parser_) {}
ParserWithOptionalAlias(ParserPtr && elem_parser_) : elem_parser(std::move(elem_parser_)) {}
protected:
ParserPtr elem_parser;
String getName() { return "element of expression with optional alias"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "element of expression with optional alias"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
@ -150,8 +150,8 @@ protected:
class ParserOrderByElement : public IParserBase
{
protected:
String getName() { return "element of ORDER BY expression"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "element of ORDER BY expression"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};

View File

@ -2,8 +2,6 @@
#include <list>
#include <boost/assign/list_of.hpp>
#include <DB/Parsers/IParserBase.h>
#include <DB/Parsers/CommonParsers.h>
@ -11,23 +9,23 @@
namespace DB
{
/** Оператор и соответствующая ему функция. Например, "+" -> "plus"
* Не std::map, так как порядок парсинга операторов задаётся явно и может отличаться от алфавитного.
/** Идущие подряд пары строк: оператор и соответствующая ему функция. Например, "+" -> "plus".
* Порядок парсинга операторов имеет значение.
*/
typedef std::list<std::pair<String, String> > Operators_t;
typedef const char ** Operators_t;
/** Список элементов, разделённых чем-либо. */
class ParserList : public IParserBase
{
public:
ParserList(ParserPtr elem_parser_, ParserPtr separator_parser_, bool allow_empty_ = true)
: elem_parser(elem_parser_), separator_parser(separator_parser_), allow_empty(allow_empty_)
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_)
{
}
protected:
String getName() { return "list of elements (" + elem_parser->getName() + ")"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "list of elements"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
private:
ParserPtr elem_parser;
ParserPtr separator_parser;
@ -47,15 +45,15 @@ private:
public:
/** operators_ - допустимые операторы и соответствующие им функции
*/
ParserLeftAssociativeBinaryOperatorList(const Operators_t & operators_, ParserPtr elem_parser_)
: operators(operators_), elem_parser(elem_parser_)
ParserLeftAssociativeBinaryOperatorList(Operators_t operators_, ParserPtr && elem_parser_)
: operators(operators_), elem_parser(std::move(elem_parser_))
{
}
protected:
String getName() { return "list, delimited by binary operators"; }
const char * getName() const { return "list, delimited by binary operators"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
@ -66,19 +64,19 @@ class ParserVariableArityOperatorList : public IParserBase
{
private:
ParserString infix_parser;
String function_name;
const char * function_name;
ParserPtr elem_parser;
public:
ParserVariableArityOperatorList(const String & infix_, const String & function_, ParserPtr elem_parser_)
: infix_parser(infix_, true, true), function_name(function_), elem_parser(elem_parser_)
ParserVariableArityOperatorList(const char * infix_, const char * function_, ParserPtr && elem_parser_)
: infix_parser(infix_, true, true), function_name(function_), elem_parser(std::move(elem_parser_))
{
}
protected:
String getName() { 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, String & expected);
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
@ -94,29 +92,29 @@ private:
public:
/** operators_ - допустимые операторы и соответствующие им функции
*/
ParserPrefixUnaryOperatorExpression(const Operators_t & operators_, ParserPtr elem_parser_)
: operators(operators_), elem_parser(elem_parser_)
ParserPrefixUnaryOperatorExpression(Operators_t operators_, ParserPtr && elem_parser_)
: operators(operators_), elem_parser(std::move(elem_parser_))
{
}
protected:
String getName() { return "expression with prefix unary operator"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "expression with prefix unary operator"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
class ParserAccessExpression : public IParserBase
{
private:
ParserPtr elem_parser;
static const char * operators[];
ParserLeftAssociativeBinaryOperatorList operator_parser;
public:
ParserAccessExpression();
protected:
String getName() { return "access expression"; }
const char * getName() const { return "access expression"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
return operator_parser.parse(pos, end, node, expected);
}
@ -126,42 +124,26 @@ protected:
class ParserUnaryMinusExpression : public IParserBase
{
private:
ParserPtr elem_parser;
ParserPrefixUnaryOperatorExpression operator_parser;
public:
ParserUnaryMinusExpression()
: elem_parser(new ParserAccessExpression),
operator_parser(boost::assign::map_list_of("-", "negate"), elem_parser)
{
}
static const char * operators[];
ParserPrefixUnaryOperatorExpression operator_parser {operators, ParserPtr(new ParserAccessExpression)};
protected:
String getName() { return "unary minus expression"; }
const char * getName() const { return "unary minus expression"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
class ParserMultiplicativeExpression : public IParserBase
{
private:
ParserPtr elem_parser;
ParserLeftAssociativeBinaryOperatorList operator_parser;
public:
ParserMultiplicativeExpression()
: elem_parser(new ParserUnaryMinusExpression),
operator_parser(boost::assign::map_list_of
("*", "multiply")
("/", "divide")
("%", "modulo"),
elem_parser)
{
}
static const char * operators[];
ParserLeftAssociativeBinaryOperatorList operator_parser {operators, ParserPtr(new ParserUnaryMinusExpression)};
protected:
String getName() { return "multiplicative expression"; }
const char * getName() const { return "multiplicative expression"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
return operator_parser.parse(pos, end, node, expected);
}
@ -171,22 +153,13 @@ protected:
class ParserAdditiveExpression : public IParserBase
{
private:
ParserPtr elem_parser;
ParserLeftAssociativeBinaryOperatorList operator_parser;
public:
ParserAdditiveExpression()
: elem_parser(new ParserMultiplicativeExpression),
operator_parser(boost::assign::map_list_of
("+", "plus")
("-", "minus"),
elem_parser)
{
}
static const char * operators[];
ParserLeftAssociativeBinaryOperatorList operator_parser {operators, ParserPtr(new ParserMultiplicativeExpression)};
protected:
String getName() { return "additive expression"; }
const char * getName() const { return "additive expression"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
return operator_parser.parse(pos, end, node, expected);
}
@ -196,32 +169,13 @@ protected:
class ParserComparisonExpression : public IParserBase
{
private:
ParserPtr elem_parser;
ParserLeftAssociativeBinaryOperatorList operator_parser;
public:
ParserComparisonExpression()
: elem_parser(new ParserAdditiveExpression),
operator_parser(boost::assign::map_list_of
("==", "equals")
("!=", "notEquals")
("<>", "notEquals")
("<=", "lessOrEquals")
(">=", "greaterOrEquals")
("<", "less")
(">", "greater")
("=", "equals")
("LIKE", "like")
("NOT LIKE", "notLike")
("IN", "in")
("NOT IN", "notIn"),
elem_parser)
{
}
static const char * operators[];
ParserLeftAssociativeBinaryOperatorList operator_parser {operators, ParserPtr(new ParserAdditiveExpression)};
protected:
String getName() { return "comparison expression"; }
const char * getName() const { return "comparison expression"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
return operator_parser.parse(pos, end, node, expected);
}
@ -231,19 +185,13 @@ protected:
class ParserLogicalNotExpression : public IParserBase
{
private:
ParserPtr elem_parser;
ParserPrefixUnaryOperatorExpression operator_parser;
public:
ParserLogicalNotExpression()
: elem_parser(new ParserComparisonExpression),
operator_parser(boost::assign::map_list_of("NOT", "not"), elem_parser)
{
}
static const char * operators[];
ParserPrefixUnaryOperatorExpression operator_parser {operators, ParserPtr(new ParserComparisonExpression)};
protected:
String getName() { return "logical-NOT expression"; }
const char * getName() const { return "logical-NOT expression"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
return operator_parser.parse(pos, end, node, expected);
}
@ -253,19 +201,17 @@ protected:
class ParserLogicalAndExpression : public IParserBase
{
private:
ParserPtr elem_parser;
ParserVariableArityOperatorList operator_parser;
public:
ParserLogicalAndExpression()
: elem_parser(new ParserLogicalNotExpression),
operator_parser("AND", "and", elem_parser)
: operator_parser("AND", "and", ParserPtr(new ParserLogicalNotExpression))
{
}
protected:
String getName() { return "logical-AND expression"; }
const char * getName() const { return "logical-AND expression"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
return operator_parser.parse(pos, end, node, expected);
}
@ -275,19 +221,17 @@ protected:
class ParserLogicalOrExpression : public IParserBase
{
private:
ParserPtr elem_parser;
ParserVariableArityOperatorList operator_parser;
public:
ParserLogicalOrExpression()
: elem_parser(new ParserLogicalAndExpression),
operator_parser("OR", "or", elem_parser)
: operator_parser("OR", "or", ParserPtr(new ParserLogicalAndExpression))
{
}
protected:
String getName() { return "logical-OR expression"; }
const char * getName() const { return "logical-OR expression"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
return operator_parser.parse(pos, end, node, expected);
}
@ -300,36 +244,24 @@ protected:
class ParserTernaryOperatorExpression : public IParserBase
{
private:
ParserPtr elem_parser;
public:
ParserTernaryOperatorExpression()
: elem_parser(new ParserLogicalOrExpression)
{
}
ParserLogicalOrExpression elem_parser;
protected:
String getName() { return "expression with ternary operator"; }
const char * getName() const { return "expression with ternary operator"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
class ParserLambdaExpression : public IParserBase
{
private:
ParserPtr elem_parser;
public:
ParserLambdaExpression()
: elem_parser(new ParserTernaryOperatorExpression)
{
}
ParserTernaryOperatorExpression elem_parser;
protected:
String getName() { return "lambda expression"; }
const char * getName() const { return "lambda expression"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
@ -340,9 +272,9 @@ public:
protected:
ParserPtr impl;
String getName() { return "expression with optional alias"; }
const char * getName() const { return "expression with optional alias"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
return impl->parse(pos, end, node, expected);
}
@ -353,8 +285,8 @@ protected:
class ParserExpressionList : public IParserBase
{
protected:
String getName() { return "list of expressions"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "list of expressions"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
@ -363,16 +295,16 @@ class ParserNotEmptyExpressionList : public IParserBase
private:
ParserExpressionList nested_parser;
protected:
String getName() { return "not empty list of expressions"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "not empty list of expressions"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
class ParserOrderByExpressionList : public IParserBase
{
protected:
String getName() { return "order by expression"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "order by expression"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};

View File

@ -1,8 +1,7 @@
#ifndef DBMS_PARSERS_IPARSER_H
#define DBMS_PARSERS_IPARSER_H
#pragma once
#include <list>
#include <Poco/SharedPtr.h>
#include <memory>
#include <DB/Core/Types.h>
#include <DB/Parsers/IAST.h>
@ -22,7 +21,7 @@ public:
typedef const char * Pos;
/** Получить текст о том, что парсит этот парсер. */
virtual String getName() = 0;
virtual const char * getName() const = 0;
/** Распарсить кусок текста с позиции pos, но не дальше конца строки (end - позиция после конца строки),
* переместить указатель pos на максимальное место, до которого удалось распарсить,
@ -32,9 +31,9 @@ public:
* или что парсит этот парсер, если парсинг был успешным.
* Везде предполагается, что строка, в которую входит диапазон [begin, end) 0-terminated.
*/
virtual bool parse(Pos & pos, Pos end, ASTPtr & node, String & expected) = 0;
virtual bool parse(Pos & pos, Pos end, ASTPtr & node, const char *& expected) = 0;
bool ignore(Pos & pos, Pos end, String & expected)
bool ignore(Pos & pos, Pos end, const char *& expected)
{
ASTPtr ignore_node;
return parse(pos, end, ignore_node, expected);
@ -42,13 +41,13 @@ public:
bool ignore(Pos & pos, Pos end)
{
String expected;
const char * expected;
return ignore(pos, end, expected);
}
/** То же самое, но не двигать позицию и не записывать результат в node.
*/
bool check(Pos & pos, Pos end, String & expected)
bool check(Pos & pos, Pos end, const char *& expected)
{
Pos begin = pos;
ASTPtr node;
@ -64,8 +63,6 @@ public:
virtual ~IParser() {}
};
typedef SharedPtr<IParser> ParserPtr;
typedef std::unique_ptr<IParser> ParserPtr;
}
#endif

View File

@ -1,5 +1,4 @@
#ifndef DBMS_PARSERS_IPARSERBASE_H
#define DBMS_PARSERS_IPARSERBASE_H
#pragma once
#include <list>
#include <Poco/SharedPtr.h>
@ -17,16 +16,14 @@ namespace DB
class IParserBase : public IParser
{
public:
bool parse(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool parse(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
expected = getName();
bool res = parseImpl(pos, end, node, expected);
return res;
}
protected:
virtual bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected) = 0;
virtual bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected) = 0;
};
}
#endif

View File

@ -13,8 +13,8 @@ namespace DB
class ParserAlterQuery : public IParserBase
{
protected:
String getName() { return "ALTER query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "ALTER query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
}

View File

@ -12,8 +12,8 @@ namespace DB
class ParserNestedTable : public IParserBase
{
protected:
String getName() { return "nested table"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "nested table"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
@ -26,8 +26,8 @@ protected:
class ParserIdentifierWithParameters : public IParserBase
{
protected:
String getName() { return "identifier with parameters"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "identifier with parameters"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
@ -37,8 +37,8 @@ protected:
class ParserIdentifierWithOptionalParameters : public IParserBase
{
protected:
String getName() { return "identifier with optional parameters"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "identifier with optional parameters"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
@ -46,8 +46,8 @@ protected:
class ParserNameTypePair : public IParserBase
{
protected:
String getName() { return "name and type pair"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "name and type pair"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
@ -55,8 +55,8 @@ protected:
class ParserNameTypePairList : public IParserBase
{
protected:
String getName() { return "name and type pair list"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "name and type pair list"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
@ -64,8 +64,8 @@ protected:
class ParserEngine : public IParserBase
{
protected:
String getName() { return "ENGINE"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "ENGINE"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
@ -89,8 +89,8 @@ protected:
class ParserCreateQuery : public IParserBase
{
protected:
String getName() { return "CREATE TABLE or ATTACH TABLE query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "CREATE TABLE or ATTACH TABLE query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
}

View File

@ -16,8 +16,8 @@ namespace DB
class ParserDropQuery : public IParserBase
{
protected:
String getName() { return "DROP query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "DROP query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
}

View File

@ -25,8 +25,8 @@ namespace DB
class ParserInsertQuery : public IParserBase
{
protected:
String getName() { return "INSERT query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "INSERT query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
}

View File

@ -12,8 +12,8 @@ namespace DB
class ParserOptimizeQuery : public IParserBase
{
protected:
String getName() { return "OPTIMIZE query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "OPTIMIZE query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
}

View File

@ -10,8 +10,8 @@ namespace DB
class ParserQuery : public IParserBase
{
protected:
String getName() { return "Query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "Query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
}

View File

@ -14,8 +14,8 @@ namespace DB
class ParserRenameQuery : public IParserBase
{
protected:
String getName() { return "RENAME query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "RENAME query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
}

View File

@ -10,8 +10,8 @@ namespace DB
class ParserSelectQuery : public IParserBase
{
protected:
String getName() { return "SELECT query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "SELECT query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
}

View File

@ -13,8 +13,8 @@ namespace DB
class ParserSetQuery : public IParserBase
{
protected:
String getName() { return "SET query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "SET query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
}

View File

@ -15,9 +15,9 @@ namespace DB
class ParserShowProcesslistQuery : public IParserBase
{
protected:
String getName() { return "SHOW PROCESSLIST query"; }
const char * getName() const { return "SHOW PROCESSLIST query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
Pos begin = pos;

View File

@ -14,8 +14,8 @@ namespace DB
class ParserShowTablesQuery : public IParserBase
{
protected:
String getName() { return "SHOW TABLES|DATABASES query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
const char * getName() const { return "SHOW TABLES|DATABASES query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected);
};
}

View File

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

View File

@ -15,8 +15,8 @@ namespace DB
class ParserUseQuery : public IParserBase
{
protected:
String getName() { return "USE query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
const char * getName() const { return "USE query"; }
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
Pos begin = pos;

View File

@ -31,31 +31,35 @@ namespace DB
/** Берёт синтаксическое дерево и превращает его обратно в текст.
* В случае запроса INSERT, данные будут отсутствовать.
*/
void formatAST(const IAST & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false);
void formatAST(const IAST & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false, bool need_parens = false);
void formatAST(const ASTSelectQuery & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false);
void formatAST(const ASTCreateQuery & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false);
void formatAST(const ASTDropQuery & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false);
void formatAST(const ASTInsertQuery & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false);
void formatAST(const ASTRenameQuery & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false);
void formatAST(const ASTShowTablesQuery & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false);
void formatAST(const ASTUseQuery & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false);
void formatAST(const ASTSetQuery & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false);
void formatAST(const ASTOptimizeQuery & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false);
void formatAST(const ASTExistsQuery & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false);
void formatAST(const ASTDescribeQuery & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false);
void formatAST(const ASTShowCreateQuery & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false);
void formatAST(const ASTExpressionList & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false);
void formatAST(const ASTFunction & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false);
void formatAST(const ASTIdentifier & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false);
void formatAST(const ASTLiteral & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false);
void formatAST(const ASTNameTypePair & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false);
void formatAST(const ASTAsterisk & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false);
void formatAST(const ASTOrderByElement & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false);
void formatAST(const ASTSubquery & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false);
void formatAST(const ASTQueryWithTableAndOutput & ast, std::string name, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false);
void formatAST(const ASTAlterQuery & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false);
void formatAST(const ASTShowProcesslistQuery & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false);
void formatAST(const ASTSelectQuery & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false, bool need_parens = false);
void formatAST(const ASTCreateQuery & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false, bool need_parens = false);
void formatAST(const ASTDropQuery & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false, bool need_parens = false);
void formatAST(const ASTInsertQuery & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false, bool need_parens = false);
void formatAST(const ASTRenameQuery & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false, bool need_parens = false);
void formatAST(const ASTShowTablesQuery & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false, bool need_parens = false);
void formatAST(const ASTUseQuery & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false, bool need_parens = false);
void formatAST(const ASTSetQuery & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false, bool need_parens = false);
void formatAST(const ASTOptimizeQuery & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false, bool need_parens = false);
void formatAST(const ASTExistsQuery & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false, bool need_parens = false);
void formatAST(const ASTDescribeQuery & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false, bool need_parens = false);
void formatAST(const ASTShowCreateQuery & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false, bool need_parens = false);
void formatAST(const ASTExpressionList & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false, bool need_parens = false);
void formatAST(const ASTFunction & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false, bool need_parens = false);
void formatAST(const ASTIdentifier & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false, bool need_parens = false);
void formatAST(const ASTLiteral & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false, bool need_parens = false);
void formatAST(const ASTNameTypePair & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false, bool need_parens = false);
void formatAST(const ASTAsterisk & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false, bool need_parens = false);
void formatAST(const ASTOrderByElement & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false, bool need_parens = false);
void formatAST(const ASTSubquery & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false, bool need_parens = false);
void formatAST(const ASTAlterQuery & ast, std::ostream & s, size_t indent = 0, bool hilite = true, bool one_line = false, bool need_parens = false);
void formatAST(const ASTQueryWithTableAndOutput & ast, std::string name, std::ostream & s,
size_t indent = 0, bool hilite = true, bool one_line = false, bool need_parens = false);
void formatAST(const ASTShowProcesslistQuery & ast, std::ostream & s,
size_t indent = 0, bool hilite = true, bool one_line = false, bool need_parens = false);
String formatColumnsForCreateQuery(NamesAndTypesList & columns);

View File

@ -20,7 +20,7 @@ public:
size_t block_size_, const Names & column_names_,
MergeTreeData & storage_, const MergeTreeData::DataPartPtr & owned_data_part_,
const MarkRanges & mark_ranges_, StoragePtr owned_storage, bool use_uncompressed_cache_,
ExpressionActionsPtr prewhere_actions_, String prewhere_column_)
ExpressionActionsPtr prewhere_actions_, String prewhere_column_, bool take_read_lock)
: IProfilingBlockInputStream(owned_storage),
path(path_), block_size(block_size_), column_names(column_names_),
storage(storage_), owned_data_part(owned_data_part_),

View File

@ -25,7 +25,6 @@ public:
const String & remote_database_, /// БД на удалённых серверах.
const String & remote_table_, /// Имя таблицы на удалённых серверах.
const String & cluster_name,
const DataTypeFactory & data_type_factory_,
Context & context_,
const String & sign_column_name_ = "");
@ -35,7 +34,6 @@ public:
const String & remote_database_, /// БД на удалённых серверах.
const String & remote_table_, /// Имя таблицы на удалённых серверах.
SharedPtr<Cluster> & owned_cluster_,
const DataTypeFactory & data_type_factory_,
Context & context_,
const String & sign_column_name_ = "");
@ -75,7 +73,6 @@ private:
const String & remote_database_,
const String & remote_table_,
Cluster & cluster_,
const DataTypeFactory & data_type_factory_,
const Context & context_,
const String & sign_column_name_ = "");
@ -86,7 +83,6 @@ private:
NamesAndTypesListPtr columns;
String remote_database;
String remote_table;
const DataTypeFactory & data_type_factory;
String sign_column_name;
/// Имя виртуального столбца, куда записывается имя хоста (Например "_host").

View File

@ -62,7 +62,7 @@ public:
SharedPtr<Cluster> cluster = new Cluster(context.getSettings(), context.getDataTypeFactory(), names, username, password);
return StorageDistributed::create(getName(), chooseColumns(*cluster, remote_database, remote_table, context),
remote_database, remote_table, cluster, context.getDataTypeFactory(), context);
remote_database, remote_table, cluster, context);
}
private:

View File

@ -0,0 +1,313 @@
#define DBMS_CLIENT 1 /// Используется в Context.h
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <signal.h>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <Poco/File.h>
#include <Poco/SharedPtr.h>
#include <Poco/Util/Application.h>
#include <statdaemons/Stopwatch.h>
#include <statdaemons/threadpool.hpp>
#include <stats/ReservoirSampler.h>
#include <boost/program_options.hpp>
#include <DB/Common/ConcurrentBoundedQueue.h>
#include <DB/Core/Exception.h>
#include <DB/Core/Types.h>
#include <DB/IO/ReadBufferFromFileDescriptor.h>
#include <DB/IO/WriteBufferFromFileDescriptor.h>
#include <DB/IO/WriteBufferFromString.h>
#include <DB/IO/ReadHelpers.h>
#include <DB/IO/WriteHelpers.h>
#include <DB/IO/copyData.h>
#include <DB/DataStreams/RemoteBlockInputStream.h>
#include <DB/Parsers/ParserQuery.h>
#include <DB/Parsers/formatAST.h>
#include <DB/Interpreters/Context.h>
#include <DB/Client/Connection.h>
#include "InterruptListener.h"
/** Инструмент для измерения производительности ClickHouse
* при выполнении запросов с фиксированным количеством одновременных запросов.
*/
namespace DB
{
class Benchmark
{
public:
Benchmark(unsigned concurrency_,
const String & host_, UInt16 port_, const String & default_database_,
const String & user_, const String & password_)
: concurrency(concurrency_), queue(concurrency), pool(concurrency),
connections(concurrency, host_, port_, default_database_, user_, password_, data_type_factory)
{
std::cerr << std::fixed << std::setprecision(3);
readQueries();
run();
report();
}
private:
typedef std::string Query;
unsigned concurrency;
typedef std::vector<Query> Queries;
Queries queries;
typedef ConcurrentBoundedQueue<Query> Queue;
Queue queue;
boost::threadpool::pool pool;
DataTypeFactory data_type_factory;
ConnectionPool connections;
Stopwatch total_watch;
size_t total_queries = 0;
size_t total_rows = 0;
size_t total_bytes = 0;
ReservoirSampler<double> sampler {1 << 16};
Poco::FastMutex mutex;
void readQueries()
{
ReadBufferFromFileDescriptor in(STDIN_FILENO);
while (!in.eof())
{
std::string query;
readText(query, in);
assertString("\n", in);
if (!query.empty())
queries.emplace_back(query);
}
if (queries.empty())
throw Exception("Empty list of queries.");
std::cerr << "Loaded " << queries.size() << " queries." << std::endl;
}
void run()
{
for (size_t i = 0; i < concurrency; ++i)
pool.schedule(std::bind(&Benchmark::thread, this, connections.get()));
InterruptListener interrupt_listener;
total_watch.restart();
Stopwatch watch;
/// В цикле, кладём все запросы в очередь.
for (size_t i = 0; !interrupt_listener.check(); ++i)
{
if (i >= queries.size())
i = 0;
queue.push(queries[i]);
if (watch.elapsedSeconds() > 1)
{
report();
watch.restart();
}
}
/// Попросим потоки завершиться.
for (size_t i = 0; i < concurrency; ++i)
queue.push("");
pool.wait();
}
void thread(ConnectionPool::Entry connection)
{
try
{
/// В этих потоках не будем принимать сигнал INT.
sigset_t sig_set;
if (sigemptyset(&sig_set)
|| sigaddset(&sig_set, SIGINT)
|| pthread_sigmask(SIG_BLOCK, &sig_set, NULL))
throwFromErrno("Cannot block signal.", ErrorCodes::CANNOT_BLOCK_SIGNAL);
Query query;
while (true)
{
queue.pop(query);
/// Пустой запрос обозначает конец работы.
if (query.empty())
break;
execute(connection, query);
}
}
catch (const Exception & e)
{
std::string text = e.displayText();
std::cerr << "Code: " << e.code() << ". " << text << std::endl << std::endl;
/// Если есть стек-трейс на сервере, то не будем писать стек-трейс на клиенте.
if (std::string::npos == text.find("Stack trace"))
std::cerr << "Stack trace:" << std::endl
<< e.getStackTrace().toString();
throw;
}
catch (const Poco::Exception & e)
{
std::cerr << "Poco::Exception: " << e.displayText() << std::endl;
throw;
}
catch (const std::exception & e)
{
std::cerr << "std::exception: " << e.what() << std::endl;
throw;
}
catch (...)
{
std::cerr << "Unknown exception" << std::endl;
throw;
}
}
void execute(ConnectionPool::Entry & connection, Query & query)
{
Stopwatch watch;
RemoteBlockInputStream stream(*connection, query, nullptr);
size_t rows = 0;
size_t bytes = 0;
stream.setProgressCallback([&](size_t rows_inc , size_t bytes_inc) { rows += rows_inc; bytes += bytes_inc; });
stream.readPrefix();
while (Block block = stream.read())
;
stream.readSuffix();
addTiming(watch.elapsedSeconds(), rows, bytes);
}
void addTiming(double seconds, size_t rows, size_t bytes)
{
Poco::ScopedLock<Poco::FastMutex> lock(mutex);
++total_queries;
total_rows += rows;
total_bytes += bytes;
sampler.insert(seconds);
}
void report()
{
Poco::ScopedLock<Poco::FastMutex> lock(mutex);
std::cerr
<< std::endl
<< "QPS: " << (total_queries / total_watch.elapsedSeconds()) << ", "
<< "RPS: " << (total_rows / total_watch.elapsedSeconds()) << ", "
<< "MiB/s: " << (total_bytes / total_watch.elapsedSeconds() / 1048576) << "."
<< std::endl;
for (double level = 0; level < 1; level += 0.1)
std::cerr << int(level * 100) << "%\t" << sampler.quantileInterpolated(level) << " sec." << std::endl;
}
};
}
int main(int argc, char ** argv)
{
using namespace DB;
try
{
boost::program_options::options_description desc("Allowed options");
desc.add_options()
("help", "produce help message")
("concurrency,c", boost::program_options::value<unsigned>()->default_value(1), "number of parallel queries")
("host,h", boost::program_options::value<std::string>()->default_value("localhost"), "")
("port", boost::program_options::value<UInt16>()->default_value(9000), "")
("user", boost::program_options::value<std::string>()->default_value("default"), "")
("password", boost::program_options::value<std::string>()->default_value(""), "")
("database", boost::program_options::value<std::string>()->default_value("default"), "")
;
boost::program_options::variables_map options;
boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), options);
if (options.count("help"))
{
std::cout << "Usage: " << argv[0] << " [options] < queries.txt" << std::endl;
std::cout << desc << std::endl;
return 1;
}
Benchmark benchmark(
options["concurrency"].as<unsigned>(),
options["host"].as<std::string>(),
options["port"].as<UInt16>(),
options["database"].as<std::string>(),
options["user"].as<std::string>(),
options["password"].as<std::string>());
}
catch (const Exception & e)
{
std::string text = e.displayText();
std::cerr << "Code: " << e.code() << ". " << text << std::endl << std::endl;
/// Если есть стек-трейс на сервере, то не будем писать стек-трейс на клиенте.
if (std::string::npos == text.find("Stack trace"))
std::cerr << "Stack trace:" << std::endl
<< e.getStackTrace().toString();
return e.code();
}
catch (const Poco::Exception & e)
{
std::cerr << "Poco::Exception: " << e.displayText() << std::endl;
return ErrorCodes::POCO_EXCEPTION;
}
catch (const std::exception & e)
{
std::cerr << "std::exception: " << e.what() << std::endl;
return ErrorCodes::STD_EXCEPTION;
}
catch (...)
{
std::cerr << "Unknown exception" << std::endl;
return ErrorCodes::UNKNOWN_EXCEPTION;
}
}

View File

@ -44,6 +44,8 @@
#include <DB/Client/Connection.h>
#include "InterruptListener.h"
/** Клиент командной строки СУБД ClickHouse.
*/
@ -55,75 +57,6 @@ namespace DB
using Poco::SharedPtr;
/** Пока существует объект этого класса - блокирует сигнал INT, при этом позволяет узнать, не пришёл ли он.
* Это нужно, чтобы можно было прервать выполнение запроса с помощью Ctrl+C.
* В один момент времени используйте только один экземпляр этого класса.
* Если метод check вернул true (пришёл сигнал), то следующие вызовы будут ждать следующий сигнал.
*/
class InterruptListener
{
private:
bool active;
sigset_t sig_set;
public:
InterruptListener() : active(false)
{
if (sigemptyset(&sig_set)
|| sigaddset(&sig_set, SIGINT))
throwFromErrno("Cannot manipulate with signal set.", ErrorCodes::CANNOT_MANIPULATE_SIGSET);
block();
}
~InterruptListener()
{
unblock();
}
bool check()
{
if (!active)
return false;
timespec timeout = { 0, 0 };
if (-1 == sigtimedwait(&sig_set, NULL, &timeout))
{
if (errno == EAGAIN)
return false;
else
throwFromErrno("Cannot poll signal (sigtimedwait).", ErrorCodes::CANNOT_WAIT_FOR_SIGNAL);
}
return true;
}
void block()
{
if (!active)
{
if (pthread_sigmask(SIG_BLOCK, &sig_set, NULL))
throwFromErrno("Cannot block signal.", ErrorCodes::CANNOT_BLOCK_SIGNAL);
active = true;
}
}
/// Можно прекратить блокировать сигнал раньше, чем в деструкторе.
void unblock()
{
if (active)
{
if (pthread_sigmask(SIG_UNBLOCK, &sig_set, NULL))
throwFromErrno("Cannot unblock signal.", ErrorCodes::CANNOT_UNBLOCK_SIGNAL);
active = false;
}
}
};
class Client : public Poco::Util::Application
{
public:
@ -528,7 +461,7 @@ private:
bool parseQuery()
{
ParserQuery parser;
std::string expected;
const char * expected = "";
const char * begin = query.data();
const char * end = begin + query.size();

View File

@ -0,0 +1,79 @@
#pragma once
#include <signal.h>
#include <DB/Core/Exception.h>
#include <DB/Core/ErrorCodes.h>
namespace DB
{
/** Пока существует объект этого класса - блокирует сигнал INT, при этом позволяет узнать, не пришёл ли он.
* Это нужно, чтобы можно было прервать выполнение запроса с помощью Ctrl+C.
* В один момент времени используйте только один экземпляр этого класса.
* Если метод check вернул true (пришёл сигнал), то следующие вызовы будут ждать следующий сигнал.
*/
class InterruptListener
{
private:
bool active;
sigset_t sig_set;
public:
InterruptListener() : active(false)
{
if (sigemptyset(&sig_set)
|| sigaddset(&sig_set, SIGINT))
throwFromErrno("Cannot manipulate with signal set.", ErrorCodes::CANNOT_MANIPULATE_SIGSET);
block();
}
~InterruptListener()
{
unblock();
}
bool check()
{
if (!active)
return false;
timespec timeout = { 0, 0 };
if (-1 == sigtimedwait(&sig_set, NULL, &timeout))
{
if (errno == EAGAIN)
return false;
else
throwFromErrno("Cannot poll signal (sigtimedwait).", ErrorCodes::CANNOT_WAIT_FOR_SIGNAL);
}
return true;
}
void block()
{
if (!active)
{
if (pthread_sigmask(SIG_BLOCK, &sig_set, NULL))
throwFromErrno("Cannot block signal.", ErrorCodes::CANNOT_BLOCK_SIGNAL);
active = true;
}
}
/// Можно прекратить блокировать сигнал раньше, чем в деструкторе.
void unblock()
{
if (active)
{
if (pthread_sigmask(SIG_UNBLOCK, &sig_set, NULL))
throwFromErrno("Cannot unblock signal.", ErrorCodes::CANNOT_UNBLOCK_SIGNAL);
active = false;
}
}
};
}

View File

@ -32,7 +32,7 @@ int main(int argc, char ** argv)
DB::ParserSelectQuery parser;
DB::ASTPtr ast;
std::string input = "SELECT number, number / 3, number * number";
std::string expected;
const char * expected = "";
const char * begin = input.data();
const char * end = begin + input.size();

View File

@ -34,7 +34,7 @@ int main(int argc, char ** argv)
DB::ParserSelectQuery parser;
DB::ASTPtr ast;
std::string input = "SELECT number, number % 3 == 1";
std::string expected;
const char * expected = "";
const char * begin = input.data();
const char * end = begin + input.size();

View File

@ -105,7 +105,7 @@ int main(int argc, char ** argv)
DB::ParserSelectQuery parser;
DB::ASTPtr ast;
std::string input = "SELECT UniqID, URL, CounterID, IsLink WHERE URL = 'http://mail.yandex.ru/neo2/#inbox'";
std::string expected;
const char * expected = "";
const char * begin = input.data();
const char * end = begin + input.size();

View File

@ -51,7 +51,7 @@ int main(int argc, char ** argv)
DB::ParserSelectQuery parser;
DB::ASTPtr ast;
std::string input = "SELECT number, number % 10000000 == 1";
std::string expected;
const char * expected = "";
const char * begin = input.data();
const char * end = begin + input.size();

View File

@ -107,7 +107,7 @@ int main(int argc, char ** argv)
DB::ParserSelectQuery parser;
DB::ASTPtr ast;
std::string input = "SELECT UniqID, URL, CounterID, IsLink";
std::string expected;
const char * expected = "";
const char * begin = input.data();
const char * end = begin + input.size();

View File

@ -74,7 +74,7 @@ DataTypePtr DataTypeFactory::get(const String & name) const
ParserExpressionList args_parser;
ASTPtr args_ast;
String expected;
const char * expected = "";
IParser::Pos pos = parameters.data();
IParser::Pos end = pos + parameters.size();
@ -101,7 +101,7 @@ DataTypePtr DataTypeFactory::get(const String & name) const
{
ParserNameTypePairList columns_p;
ASTPtr columns_ast;
String expected;
const char * expected = "";
IParser::Pos pos = parameters.data();
IParser::Pos end = pos + parameters.size();
@ -130,7 +130,7 @@ DataTypePtr DataTypeFactory::get(const String & name) const
{
ParserExpressionList columns_p;
ASTPtr columns_ast;
String expected;
const char * expected = "";
IParser::Pos pos = parameters.data();
IParser::Pos end = pos + parameters.size();

View File

@ -14,8 +14,6 @@
#include <DB/DataTypes/DataTypeArray.h>
#include <Poco/StringTokenizer.h>
namespace DB
{
@ -33,31 +31,17 @@ std::string DataTypeNested::concatenateNestedName(const std::string & nested_tab
}
std::pair<std::string, std::string> DataTypeNested::splitNestedName(const std::string & nested_name)
{
Poco::StringTokenizer tokenizer(nested_name, ".");
return std::make_pair(tokenizer[0], tokenizer[1]);
}
bool DataTypeNested::isNestedName(const std::string & nested_name)
{
Poco::StringTokenizer tokenizer(nested_name, ".");
return tokenizer.count() == 2 && tokenizer[0] != "" && tokenizer[1] != "";
}
std::string DataTypeNested::extractNestedTableName(const std::string & nested_name)
{
Poco::StringTokenizer tokenizer(nested_name, ".");
return tokenizer[0];
const char * pos = strchr(nested_name.data(), '.');
return pos == nullptr ? nested_name : nested_name.substr(0, pos - nested_name.data());
}
std::string DataTypeNested::extractNestedColumnName(const std::string & nested_name)
{
Poco::StringTokenizer tokenizer(nested_name, ".");
return tokenizer[tokenizer.count() - 1];
const char * pos = strrchr(nested_name.data(), '.');
return pos == nullptr ? nested_name : nested_name.substr(pos - nested_name.data() + 1);
}

View File

@ -26,7 +26,7 @@ void WriteBufferFromPocoSocket::nextImpl()
}
catch (const Poco::Net::NetException & e)
{
throw Exception(e.displayText() + "while writing to socket (" + peer_address.toString() + ")", ErrorCodes::NETWORK_ERROR);
throw Exception(e.displayText() + " while writing to socket (" + peer_address.toString() + ")", ErrorCodes::NETWORK_ERROR);
}
catch (const Poco::TimeoutException & e)
{
@ -34,7 +34,7 @@ void WriteBufferFromPocoSocket::nextImpl()
}
catch (const Poco::IOException & e)
{
throw Exception(e.displayText(), "while reading from socket (" + peer_address.toString() + ")", ErrorCodes::NETWORK_ERROR);
throw Exception(e.displayText(), " while reading from socket (" + peer_address.toString() + ")", ErrorCodes::NETWORK_ERROR);
}
if (res < 0)

View File

@ -17,7 +17,9 @@
#include <statdaemons/Stopwatch.h>
const UInt32 decimal_table[10000] =
#if 0
static const UInt32 decimal_table[10000] =
{
0x30303030,0x31303030,0x32303030,0x33303030,0x34303030,0x35303030,0x36303030,0x37303030,0x38303030,0x39303030,
0x30313030,0x31313030,0x32313030,0x33313030,0x34313030,0x35313030,0x36313030,0x37313030,0x38313030,0x39313030,
@ -1022,7 +1024,7 @@ const UInt32 decimal_table[10000] =
};
const UInt8 length_table[10000] =
static const UInt8 length_table[10000] =
{
3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
@ -1095,7 +1097,6 @@ void writeUIntTextTable(T x, DB::WriteBuffer & buf)
buf.write(data.chars + length_table[x], len - length_table[x]);
}
template <typename T>
void writeIntTextTable(T x, DB::WriteBuffer & buf)
{
@ -1127,6 +1128,8 @@ void writeIntTextTable(T x, DB::WriteBuffer & buf)
writeUIntTextTable(static_cast<typename boost::make_unsigned<T>::type>(x), buf);
}
#endif
UInt64 rdtsc()
{

View File

@ -284,7 +284,7 @@ ASTPtr Context::getCreateQuery(const String & database_name, const String & tabl
ParserCreateQuery parser;
ASTPtr ast;
String expected;
const char * expected = "";
bool parse_res = parser.parse(pos, end, ast, expected);
/// Распарсенный запрос должен заканчиваться на конец входных данных или на точку с запятой.

View File

@ -1229,9 +1229,7 @@ Sets ExpressionAnalyzer::getSetsWithSubqueries()
{
Sets res;
for (auto & s : sets_with_subqueries)
{
res.push_back(s.second);
}
return res;
}

View File

@ -137,7 +137,7 @@ StoragePtr InterpreterCreateQuery::execute(bool assume_metadata_exists)
StringPtr type_name = new String(it->second->getName());
ParserIdentifierWithOptionalParameters storage_p;
String expected;
const char * expected = "";
const char * pos = type_name->data();
const char * end = pos + type_name->size();

View File

@ -72,7 +72,7 @@ void InterpreterRenameQuery::execute()
const char * pos = create_query.data();
const char * end = pos + create_query.size();
ASTPtr ast;
String expected;
const char * expected = "";
bool parse_res = parser.parse(pos, end, ast, expected);
/// Распарсенный запрос должен заканчиваться на конец входных данных или на точку с запятой.

View File

@ -210,6 +210,7 @@ BlockInputStreamPtr InterpreterSelectQuery::execute()
bool has_having = false;
bool has_order_by = !query.order_expression_list.isNull();
ExpressionActionsPtr array_join;
ExpressionActionsPtr before_where;
ExpressionActionsPtr before_aggregation;
ExpressionActionsPtr before_having;
@ -225,7 +226,8 @@ BlockInputStreamPtr InterpreterSelectQuery::execute()
if (from_stage < QueryProcessingStage::WithMergeableState
&& to_stage >= QueryProcessingStage::WithMergeableState)
{
query_analyzer->appendArrayJoin(chain);
if (query_analyzer->appendArrayJoin(chain))
array_join = chain.getLastActions();
if (query_analyzer->appendWhere(chain))
{
@ -312,6 +314,16 @@ BlockInputStreamPtr InterpreterSelectQuery::execute()
if (need_aggregate)
executeAggregation(streams, before_aggregation, aggregate_overflow_row, aggregate_final);
if (array_join && !has_where && !need_aggregate && to_stage == QueryProcessingStage::WithMergeableState)
{
/** Если есть ARRAY JOIN, его действие сначала старается оказаться в
* before_where, before_aggregation или before_order_and_select.
* Если ни одного из них нет, array_join нужно выполнить отдельно.
*/
executeExpression(streams, array_join);
}
/** Оптимизация - при распределённой обработке запроса,
* если не указаны DISTINCT, GROUP, HAVING, ORDER, но указан LIMIT,
* то выполним предварительный LIMIT на удалёном сервере.
@ -339,7 +351,7 @@ BlockInputStreamPtr InterpreterSelectQuery::execute()
executeHaving(streams, before_having);
}
executeOuterExpression(streams, before_order_and_select);
executeExpression(streams, before_order_and_select);
if (has_order_by)
executeOrder(streams);
@ -433,11 +445,31 @@ QueryProcessingStage::Enum InterpreterSelectQuery::executeFetchColumns(BlockInpu
Names required_columns = query_analyzer->getRequiredColumns();
if (table_function_storage)
table = table_function_storage; /// Если в запросе была указана табличная функция, данные читаем из нее.
{
/// Если в запросе была указана табличная функция, данные читаем из нее.
table = table_function_storage;
}
else if (!query.table || !dynamic_cast<ASTSelectQuery *>(&*query.table))
{
/// Запрос из обычной таблицы или без секции FROM.
table = getTable();
}
else if (dynamic_cast<ASTSelectQuery *>(&*query.table))
interpreter_subquery = new InterpreterSelectQuery(query.table, context, required_columns, QueryProcessingStage::Complete, subquery_depth + 1);
{
/** Для подзапроса не действуют ограничения на максимальный размер результата.
* Так как результат поздапроса - ещё не результат всего запроса.
*/
Context subquery_context = context;
Settings subquery_settings = context.getSettings();
subquery_settings.limits.max_result_rows = 0;
subquery_settings.limits.max_result_bytes = 0;
/// Вычисление extremes не имеет смысла и не нужно (если его делать, то в результате всего запроса могут взяться extremes подзапроса).
subquery_settings.extremes = 0;
subquery_context.setSettings(subquery_settings);
interpreter_subquery = new InterpreterSelectQuery(
query.table, subquery_context, required_columns, QueryProcessingStage::Complete, subquery_depth + 1);
}
/// если в настройках установлен default_sample != 1, то все запросы выполняем с сэмплингом
/// если таблица не поддерживает сэмплинг получим исключение
@ -647,7 +679,7 @@ void InterpreterSelectQuery::executeTotalsAndHaving(BlockInputStreams & streams,
}
void InterpreterSelectQuery::executeOuterExpression(BlockInputStreams & streams, ExpressionActionsPtr expression)
void InterpreterSelectQuery::executeExpression(BlockInputStreams & streams, ExpressionActionsPtr expression)
{
bool is_async = settings.asynchronous && streams.size() <= settings.max_threads;
for (BlockInputStreams::iterator it = streams.begin(); it != streams.end(); ++it)

View File

@ -31,7 +31,7 @@ void executeQuery(
ParserQuery parser;
ASTPtr ast;
std::string expected;
const char * expected = "";
std::vector<char> parse_buf;
const char * begin;
@ -122,7 +122,7 @@ BlockIO executeQuery(
ParserQuery parser;
ASTPtr ast;
std::string expected;
const char * expected = "";
const char * begin = query.data();
const char * end = begin + query.size();

View File

@ -28,7 +28,7 @@ static void executeCreateQuery(const String & query, Context & context, const St
ParserCreateQuery parser;
ASTPtr ast;
String expected;
const char * expected = "";
bool parse_res = parser.parse(pos, end, ast, expected);
/// Распарсенный запрос должен заканчиваться на конец входных данных или на точку с запятой.

View File

@ -73,7 +73,7 @@ int main(int argc, char ** argv)
"DontCountHits UInt8,\n"
"WithHash UInt8\n"
") ENGINE = Log";
std::string expected;
const char * expected = "";
const char * begin = input.data();
const char * end = begin + input.size();

View File

@ -37,7 +37,7 @@ int main(int argc, char ** argv)
"s1 <= 'abc', s1 <= s2, s1 >= 'abc', s1 >= s2, "
"*/"
"s1 < s2 AND x % 3 < x % 5";
std::string expected;
const char * expected = "";
const char * begin = input.data();
const char * end = begin + input.size();

View File

@ -29,13 +29,13 @@ int main(int argc, char ** argv)
}
ASTPtr root;
ParserPtr parsers[] = {new ParserSelectQuery, new ParserExpressionList};
ParserPtr parsers[] = {ParserPtr(new ParserSelectQuery), ParserPtr(new ParserExpressionList)};
for (size_t i = 0; i < sizeof(parsers)/sizeof(parsers[0]); ++i)
{
IParser & parser = *parsers[i];
const char * pos = argv[1];
const char * end = argv[1] + strlen(argv[1]);
std::string expected;
const char * expected = "";
if (parser.parse(pos ,end, root, expected))
break;
else

View File

@ -24,7 +24,7 @@ namespace DB
{
bool ParserArray::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserArray::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
Pos begin = pos;
ASTPtr contents_node;
@ -52,7 +52,7 @@ bool ParserArray::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected
}
bool ParserParenthesisExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserParenthesisExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
Pos begin = pos;
ASTPtr contents_node;
@ -96,7 +96,7 @@ bool ParserParenthesisExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, S
}
bool ParserSubquery::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserSubquery::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
Pos begin = pos;
ASTPtr select_node;
@ -120,7 +120,7 @@ bool ParserSubquery::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expec
}
bool ParserIdentifier::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserIdentifier::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
Pos begin = pos;
@ -154,7 +154,7 @@ bool ParserIdentifier::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & exp
}
bool ParserCompoundIdentifier::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserCompoundIdentifier::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
Pos begin = pos;
@ -199,7 +199,7 @@ bool ParserCompoundIdentifier::parseImpl(Pos & pos, Pos end, ASTPtr & node, Stri
}
bool ParserFunction::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserFunction::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
Pos begin = pos;
@ -258,7 +258,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, const char *& expected)
{
Pos begin = pos;
ParserString nested_parser("NULL", true);
@ -272,7 +272,7 @@ bool ParserNull::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
}
bool ParserNumber::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserNumber::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
Field res;
@ -312,7 +312,7 @@ bool ParserNumber::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expecte
}
bool ParserStringLiteral::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserStringLiteral::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
Pos begin = pos;
String s;
@ -360,7 +360,7 @@ bool ParserStringLiteral::parseImpl(Pos & pos, Pos end, ASTPtr & node, String &
}
bool ParserLiteral::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserLiteral::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
Pos begin = pos;
@ -385,7 +385,7 @@ bool ParserLiteral::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expect
}
bool ParserAlias::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserAlias::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
ParserWhiteSpaceOrComments ws;
ParserString s_as("AS", true, true);
@ -403,7 +403,7 @@ bool ParserAlias::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected
}
bool ParserExpressionElement::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserExpressionElement::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
Pos begin = pos;
@ -451,7 +451,7 @@ bool ParserExpressionElement::parseImpl(Pos & pos, Pos end, ASTPtr & node, Strin
}
bool ParserWithOptionalAlias::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserWithOptionalAlias::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
ParserWhiteSpaceOrComments ws;
ParserAlias alias_p;
@ -483,7 +483,7 @@ bool ParserWithOptionalAlias::parseImpl(Pos & pos, Pos end, ASTPtr & node, Strin
}
bool ParserOrderByElement::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserOrderByElement::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
Pos begin = pos;

View File

@ -12,7 +12,60 @@ namespace DB
{
bool ParserList::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
const char * ParserMultiplicativeExpression::operators[] =
{
"*", "multiply",
"/", "divide",
"%", "modulo",
nullptr
};
const char * ParserUnaryMinusExpression::operators[] =
{
"-", "negate",
nullptr
};
const char * ParserAdditiveExpression::operators[] =
{
"+", "plus",
"-", "minus",
nullptr
};
const char * ParserComparisonExpression::operators[] =
{
"==", "equals",
"!=", "notEquals",
"<>", "notEquals",
"<=", "lessOrEquals",
">=", "greaterOrEquals",
"<", "less",
">", "greater",
"=", "equals",
"LIKE", "like",
"NOT LIKE", "notLike",
"IN", "in",
"NOT IN", "notIn",
nullptr
};
const char * ParserLogicalNotExpression::operators[] =
{
"NOT", "not",
nullptr
};
const char * ParserAccessExpression::operators[] =
{
".", "tupleElement",
"[", "arrayElement",
nullptr
};
bool ParserList::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
bool first = true;
ParserWhiteSpaceOrComments ws;
@ -54,7 +107,7 @@ bool ParserList::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
}
bool ParserLeftAssociativeBinaryOperatorList::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserLeftAssociativeBinaryOperatorList::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
bool first = true;
ParserWhiteSpaceOrComments ws;
@ -75,15 +128,16 @@ bool ParserLeftAssociativeBinaryOperatorList::parseImpl(Pos & pos, Pos end, ASTP
/// пробуем найти какой-нибудь из допустимых операторов
Pos begin = pos;
Operators_t::const_iterator it;
for (it = operators.begin(); it != operators.end(); ++it)
const char ** it;
for (it = operators; *it; it += 2)
{
ParserString op(it->first, true, true);
ParserString op(it[0], true, true);
if (op.ignore(pos, end, expected))
break;
}
if (it == operators.end())
if (!*it)
break;
ws.ignore(pos, end);
@ -105,7 +159,7 @@ bool ParserLeftAssociativeBinaryOperatorList::parseImpl(Pos & pos, Pos end, ASTP
/// первым аргументом функции будет предыдущий элемент, вторым - следующий
function.range.first = begin;
function.range.second = pos;
function.name = it->second;
function.name = it[1];
function.arguments = exp_list_node;
function.children.push_back(exp_list_node);
@ -117,7 +171,7 @@ bool ParserLeftAssociativeBinaryOperatorList::parseImpl(Pos & pos, Pos end, ASTP
/** специальное исключение для оператора доступа к элементу массива x[y], который
* содержит инфиксную часть '[' и суффиксную ']' (задаётся в виде '[')
*/
if (it->first == "[")
if (0 == strcmp(it[0], "["))
{
ParserString rest_p("]");
@ -135,7 +189,7 @@ bool ParserLeftAssociativeBinaryOperatorList::parseImpl(Pos & pos, Pos end, ASTP
return true;
}
bool ParserVariableArityOperatorList::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserVariableArityOperatorList::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
ParserWhiteSpaceOrComments ws;
@ -179,7 +233,7 @@ bool ParserVariableArityOperatorList::parseImpl(Pos & pos, Pos end, ASTPtr & nod
return true;
}
bool ParserTernaryOperatorExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserTernaryOperatorExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
ParserWhiteSpaceOrComments ws;
ParserString symbol1("?");
@ -191,7 +245,7 @@ bool ParserTernaryOperatorExpression::parseImpl(Pos & pos, Pos end, ASTPtr & nod
Pos begin = pos;
if (!elem_parser->parse(pos, end, elem_cond, expected))
if (!elem_parser.parse(pos, end, elem_cond, expected))
return false;
ws.ignore(pos, end);
@ -202,7 +256,7 @@ bool ParserTernaryOperatorExpression::parseImpl(Pos & pos, Pos end, ASTPtr & nod
{
ws.ignore(pos, end);
if (!elem_parser->parse(pos, end, elem_then, expected))
if (!elem_parser.parse(pos, end, elem_then, expected))
return false;
ws.ignore(pos, end);
@ -212,7 +266,7 @@ bool ParserTernaryOperatorExpression::parseImpl(Pos & pos, Pos end, ASTPtr & nod
ws.ignore(pos, end);
if (!elem_parser->parse(pos, end, elem_else, expected))
if (!elem_parser.parse(pos, end, elem_else, expected))
return false;
/// функция, соответствующая оператору
@ -244,7 +298,7 @@ bool ParserTernaryOperatorExpression::parseImpl(Pos & pos, Pos end, ASTPtr & nod
}
bool ParserLambdaExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserLambdaExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
ParserWhiteSpaceOrComments ws;
ParserString arrow("->");
@ -266,7 +320,7 @@ bool ParserLambdaExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, String
was_open = true;
}
if (!ParserList(new ParserIdentifier, new ParserString(",")).parse(pos, end, inner_arguments, expected))
if (!ParserList(ParserPtr(new ParserIdentifier), ParserPtr(new ParserString(","))).parse(pos, end, inner_arguments, expected))
break;
ws.ignore(pos, end, expected);
@ -281,7 +335,7 @@ bool ParserLambdaExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, String
break;
ws.ignore(pos, end, expected);
if (!elem_parser->parse(pos, end, expression, expected))
if (!elem_parser.parse(pos, end, expression, expected))
{
pos = begin;
return false;
@ -310,20 +364,20 @@ bool ParserLambdaExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, String
while (false);
pos = begin;
return elem_parser->parse(pos, end, node, expected);
return elem_parser.parse(pos, end, node, expected);
}
bool ParserPrefixUnaryOperatorExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserPrefixUnaryOperatorExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
ParserWhiteSpaceOrComments ws;
/// пробуем найти какой-нибудь из допустимых операторов
Pos begin = pos;
Operators_t::const_iterator it;
for (it = operators.begin(); it != operators.end(); ++it)
const char ** it;
for (it = operators; *it; it += 2)
{
ParserString op(it->first, true, true);
ParserString op(it[0], true, true);
if (op.ignore(pos, end, expected))
break;
}
@ -334,7 +388,7 @@ bool ParserPrefixUnaryOperatorExpression::parseImpl(Pos & pos, Pos end, ASTPtr &
if (!elem_parser->parse(pos, end, elem, expected))
return false;
if (it == operators.end())
if (!*it)
node = elem;
else
{
@ -350,7 +404,7 @@ bool ParserPrefixUnaryOperatorExpression::parseImpl(Pos & pos, Pos end, ASTPtr &
function.range.first = begin;
function.range.second = pos;
function.name = it->second;
function.name = it[1];
function.arguments = exp_list_node;
function.children.push_back(exp_list_node);
@ -365,7 +419,7 @@ bool ParserPrefixUnaryOperatorExpression::parseImpl(Pos & pos, Pos end, ASTPtr &
}
bool ParserUnaryMinusExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserUnaryMinusExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
/// В качестве исключения, отрицательные числа должны парситься, как литералы, а не как применение оператора.
@ -385,37 +439,35 @@ bool ParserUnaryMinusExpression::parseImpl(Pos & pos, Pos end, ASTPtr & node, St
ParserAccessExpression::ParserAccessExpression()
: elem_parser(new ParserExpressionElement),
operator_parser(boost::assign::map_list_of
(".", "tupleElement")
("[", "arrayElement"),
elem_parser)
: operator_parser(
operators,
ParserPtr(new ParserExpressionElement))
{
}
ParserExpressionWithOptionalAlias::ParserExpressionWithOptionalAlias()
: impl(new ParserWithOptionalAlias(new ParserLambdaExpression))
: impl(new ParserWithOptionalAlias(ParserPtr(new ParserLambdaExpression)))
{
}
bool ParserExpressionList::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserExpressionList::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
return ParserList(new ParserExpressionWithOptionalAlias, new ParserString(",")).parse(pos, end, node, expected);
return ParserList(ParserPtr(new ParserExpressionWithOptionalAlias), ParserPtr(new ParserString(","))).parse(pos, end, node, expected);
}
bool ParserNotEmptyExpressionList::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserNotEmptyExpressionList::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
return nested_parser.parse(pos, end, node, expected)
&& !dynamic_cast<ASTExpressionList &>(*node).children.empty();
}
bool ParserOrderByExpressionList::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserOrderByExpressionList::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
return ParserList(new ParserOrderByElement, new ParserString(","), false).parse(pos, end, node, expected);
return ParserList(ParserPtr(new ParserOrderByElement), ParserPtr(new ParserString(",")), false).parse(pos, end, node, expected);
}

View File

@ -10,7 +10,7 @@
namespace DB
{
bool ParserAlterQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserAlterQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
Pos begin = pos;

View File

@ -13,7 +13,7 @@
namespace DB
{
bool ParserNestedTable::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserNestedTable::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
ParserWhiteSpaceOrComments ws;
ParserString open("(");
@ -55,7 +55,7 @@ bool ParserNestedTable::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & ex
}
bool ParserIdentifierWithParameters::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserIdentifierWithParameters::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
Pos begin = pos;
@ -75,7 +75,7 @@ bool ParserIdentifierWithParameters::parseImpl(Pos & pos, Pos end, ASTPtr & node
}
bool ParserIdentifierWithOptionalParameters::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserIdentifierWithOptionalParameters::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
ParserIdentifier non_parametric;
ParserIdentifierWithParameters parametric;
@ -102,7 +102,7 @@ bool ParserIdentifierWithOptionalParameters::parseImpl(Pos & pos, Pos end, ASTPt
}
bool ParserNameTypePair::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserNameTypePair::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
ParserIdentifier name_parser;
ParserIdentifierWithOptionalParameters type_parser;
@ -128,13 +128,13 @@ bool ParserNameTypePair::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & e
}
bool ParserNameTypePairList::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserNameTypePairList::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
return ParserList(new ParserNameTypePair, new ParserString(","), false).parse(pos, end, node, expected);
return ParserList(ParserPtr(new ParserNameTypePair), ParserPtr(new ParserString(",")), false).parse(pos, end, node, expected);
}
bool ParserEngine::parseImpl(Pos & pos, Pos end, ASTPtr & storage, String & expected)
bool ParserEngine::parseImpl(Pos & pos, Pos end, ASTPtr & storage, const char *& expected)
{
ParserWhiteSpaceOrComments ws;
ParserString s_engine("ENGINE", true, true);
@ -162,7 +162,7 @@ bool ParserEngine::parseImpl(Pos & pos, Pos end, ASTPtr & storage, String & expe
}
bool ParserCreateQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserCreateQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
Pos begin = pos;

View File

@ -9,7 +9,7 @@ namespace DB
{
bool ParserDropQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserDropQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
Pos begin = pos;

View File

@ -13,7 +13,7 @@ namespace DB
{
bool ParserInsertQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserInsertQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
Pos begin = pos;
@ -27,7 +27,7 @@ bool ParserInsertQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & ex
ParserString s_lparen("(");
ParserString s_rparen(")");
ParserIdentifier name_p;
ParserList columns_p(new ParserIdentifier, new ParserString(","), false);
ParserList columns_p(ParserPtr(new ParserIdentifier), ParserPtr(new ParserString(",")), false);
ASTPtr database;
ASTPtr table;

View File

@ -9,7 +9,7 @@ namespace DB
{
bool ParserOptimizeQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserOptimizeQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
Pos begin = pos;

View File

@ -18,7 +18,7 @@ namespace DB
{
bool ParserQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
ParserShowTablesQuery show_tables_p;
ParserSelectQuery select_p;

View File

@ -10,7 +10,7 @@ namespace DB
/// Парсит database.table или table.
static bool parseDatabaseAndTable(ASTRenameQuery::Table & db_and_table, IParser::Pos & pos, IParser::Pos end, String & expected)
static bool parseDatabaseAndTable(ASTRenameQuery::Table & db_and_table, IParser::Pos & pos, IParser::Pos end, const char *& expected)
{
ParserIdentifier name_p;
ParserWhiteSpaceOrComments ws;
@ -42,7 +42,7 @@ static bool parseDatabaseAndTable(ASTRenameQuery::Table & db_and_table, IParser:
}
bool ParserRenameQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserRenameQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
Pos begin = pos;

View File

@ -12,7 +12,7 @@ namespace DB
{
bool ParserSelectQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserSelectQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
Pos begin = pos;

View File

@ -11,7 +11,7 @@ namespace DB
/// Парсит name = value.
static bool parseNameValuePair(ASTSetQuery::Change & change, IParser::Pos & pos, IParser::Pos end, String & expected)
static bool parseNameValuePair(ASTSetQuery::Change & change, IParser::Pos & pos, IParser::Pos end, const char *& expected)
{
ParserIdentifier name_p;
ParserLiteral value_p;
@ -45,7 +45,7 @@ static bool parseNameValuePair(ASTSetQuery::Change & change, IParser::Pos & pos,
}
bool ParserSetQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserSetQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
Pos begin = pos;

View File

@ -11,7 +11,7 @@ namespace DB
{
bool ParserShowTablesQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserShowTablesQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
Pos begin = pos;

View File

@ -9,7 +9,7 @@ namespace DB
{
bool ParserTablePropertiesQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
bool ParserTablePropertiesQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, const char *& expected)
{
Pos begin = pos;

View File

@ -22,6 +22,7 @@ namespace DB
static const char * hilite_keyword = "\033[1;37m";
static const char * hilite_identifier = "\033[0;36m";
static const char * hilite_function = "\033[0;33m";
static const char * hilite_operator = "\033[1;33m";
static const char * hilite_alias = "\033[0;32m";
static const char * hilite_none = "\033[0m";
@ -38,12 +39,12 @@ String backQuoteIfNeed(const String & x)
}
void formatAST(const IAST & ast, std::ostream & s, size_t indent, bool hilite, bool one_line)
void formatAST(const IAST & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
{
#define DISPATCH(NAME) \
else if (const AST ## NAME * concrete = dynamic_cast<const AST ## NAME *>(&ast)) \
formatAST(*concrete, s, indent, hilite, one_line);
formatAST(*concrete, s, indent, hilite, one_line, need_parens);
if (false) {}
DISPATCH(SelectQuery)
@ -76,7 +77,37 @@ void formatAST(const IAST & ast, std::ostream & s, size_t indent, bool hilite, b
}
void formatAST(const ASTSelectQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line)
void formatAST(const ASTExpressionList & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
{
for (ASTs::const_iterator it = ast.children.begin(); it != ast.children.end(); ++it)
{
if (it != ast.children.begin())
s << ", ";
formatAST(**it, s, indent, hilite, one_line, need_parens);
}
}
/** Вывести список выражений в секциях запроса SELECT - по одному выражению на строку.
*/
static void formatExpressionListMultiline(const ASTExpressionList & ast, std::ostream & s, size_t indent, bool hilite)
{
std::string indent_str = "\n" + std::string(4 * (indent + 1), ' ');
for (ASTs::const_iterator it = ast.children.begin(); it != ast.children.end(); ++it)
{
if (it != ast.children.begin())
s << ", ";
if (ast.children.size() > 1)
s << indent_str;
formatAST(**it, s, indent + 1, hilite, false);
}
}
void formatAST(const ASTSelectQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
{
std::string nl_or_nothing = one_line ? "" : "\n";
@ -84,7 +115,9 @@ void formatAST(const ASTSelectQuery & ast, std::ostream & s, size_t indent, bo
std::string nl_or_ws = one_line ? " " : "\n";
s << (hilite ? hilite_keyword : "") << indent_str << "SELECT " << (ast.distinct ? "DISTINCT " : "") << (hilite ? hilite_none : "");
formatAST(*ast.select_expression_list, s, indent, hilite, one_line);
one_line
? formatAST(*ast.select_expression_list, s, indent, hilite, one_line)
: formatExpressionListMultiline(dynamic_cast<const ASTExpressionList &>(*ast.select_expression_list), s, indent, hilite);
if (ast.table)
{
@ -116,7 +149,9 @@ void formatAST(const ASTSelectQuery & ast, std::ostream & s, size_t indent, bo
if (ast.array_join_expression_list)
{
s << (hilite ? hilite_keyword : "") << nl_or_ws << indent_str << "ARRAY JOIN " << (hilite ? hilite_none : "");
formatAST(*ast.array_join_expression_list, s, indent, hilite, one_line);
one_line
? formatAST(*ast.array_join_expression_list, s, indent, hilite, one_line)
: formatExpressionListMultiline(dynamic_cast<const ASTExpressionList &>(*ast.array_join_expression_list), s, indent, hilite);
}
if (ast.final)
@ -133,7 +168,9 @@ void formatAST(const ASTSelectQuery & ast, std::ostream & s, size_t indent, bo
if (ast.prewhere_expression)
{
s << (hilite ? hilite_keyword : "") << nl_or_ws << indent_str << "PREWHERE " << (hilite ? hilite_none : "");
formatAST(*ast.prewhere_expression, s, indent, hilite, one_line);
one_line
? formatAST(*ast.prewhere_expression, s, indent, hilite, one_line)
: formatExpressionListMultiline(dynamic_cast<const ASTExpressionList &>(*ast.prewhere_expression), s, indent, hilite);
}
if (ast.where_expression)
@ -145,10 +182,12 @@ void formatAST(const ASTSelectQuery & ast, std::ostream & s, size_t indent, bo
if (ast.group_expression_list)
{
s << (hilite ? hilite_keyword : "") << nl_or_ws << indent_str << "GROUP BY " << (hilite ? hilite_none : "");
formatAST(*ast.group_expression_list, s, indent, hilite, one_line);
one_line
? formatAST(*ast.group_expression_list, s, indent, hilite, one_line)
: formatExpressionListMultiline(dynamic_cast<const ASTExpressionList &>(*ast.group_expression_list), s, indent, hilite);
if (ast.group_by_with_totals)
s << (hilite ? hilite_keyword : "") << " WITH TOTALS" << (hilite ? hilite_none : "");
s << (hilite ? hilite_keyword : "") << nl_or_ws << indent_str << (one_line ? "" : " ") << "WITH TOTALS" << (hilite ? hilite_none : "");
}
if (ast.having_expression)
@ -160,7 +199,9 @@ void formatAST(const ASTSelectQuery & ast, std::ostream & s, size_t indent, bo
if (ast.order_expression_list)
{
s << (hilite ? hilite_keyword : "") << nl_or_ws << indent_str << "ORDER BY " << (hilite ? hilite_none : "");
formatAST(*ast.order_expression_list, s, indent, hilite, one_line);
one_line
? formatAST(*ast.order_expression_list, s, indent, hilite, one_line)
: formatExpressionListMultiline(dynamic_cast<const ASTExpressionList &>(*ast.order_expression_list), s, indent, hilite);
}
if (ast.limit_length)
@ -181,16 +222,17 @@ void formatAST(const ASTSelectQuery & ast, std::ostream & s, size_t indent, bo
}
}
void formatAST(const ASTSubquery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line)
void formatAST(const ASTSubquery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
{
std::string indent_str = one_line ? "" : std::string(4 * indent, ' ');
std::string nl_or_nothing = one_line ? "" : "\n";
s << nl_or_nothing << "(" << nl_or_nothing;
s << nl_or_nothing << indent_str << "(" << nl_or_nothing;
formatAST(*ast.children[0], s, indent + 1, hilite, one_line);
s << nl_or_nothing << ")";
s << nl_or_nothing << indent_str << ")";
}
void formatAST(const ASTCreateQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line)
void formatAST(const ASTCreateQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
{
std::string nl_or_ws = one_line ? " " : "\n";
@ -249,7 +291,7 @@ void formatAST(const ASTCreateQuery & ast, std::ostream & s, size_t indent, bo
}
}
void formatAST(const ASTDropQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line)
void formatAST(const ASTDropQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
{
if (ast.table.empty() && !ast.database.empty())
{
@ -261,13 +303,13 @@ void formatAST(const ASTDropQuery & ast, std::ostream & s, size_t indent, boo
<< (!ast.database.empty() ? backQuoteIfNeed(ast.database) + "." : "") << backQuoteIfNeed(ast.table);
}
void formatAST(const ASTOptimizeQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line)
void formatAST(const ASTOptimizeQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
{
s << (hilite ? hilite_keyword : "") << "OPTIMIZE TABLE " << (hilite ? hilite_none : "")
<< (!ast.database.empty() ? backQuoteIfNeed(ast.database) + "." : "") << backQuoteIfNeed(ast.table);
}
void formatAST(const ASTQueryWithTableAndOutput & ast, std::string name, std::ostream & s, size_t indent, bool hilite, bool one_line)
void formatAST(const ASTQueryWithTableAndOutput & ast, std::string name, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
{
s << (hilite ? hilite_keyword : "") << name << " " << (hilite ? hilite_none : "")
<< (!ast.database.empty() ? backQuoteIfNeed(ast.database) + "." : "") << backQuoteIfNeed(ast.table);
@ -281,22 +323,22 @@ void formatAST(const ASTQueryWithTableAndOutput & ast, std::string name, std::os
}
}
void formatAST(const ASTExistsQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line)
void formatAST(const ASTExistsQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
{
formatAST(static_cast<const ASTQueryWithTableAndOutput &>(ast), "EXISTS TABLE", s, indent, hilite, one_line);
}
void formatAST(const ASTDescribeQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line)
void formatAST(const ASTDescribeQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
{
formatAST(static_cast<const ASTQueryWithTableAndOutput &>(ast), "DESCRIBE TABLE", s, indent, hilite, one_line);
}
void formatAST(const ASTShowCreateQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line)
void formatAST(const ASTShowCreateQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
{
formatAST(static_cast<const ASTQueryWithTableAndOutput &>(ast), "SHOW CREATE TABLE", s, indent, hilite, one_line);
}
void formatAST(const ASTRenameQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line)
void formatAST(const ASTRenameQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
{
s << (hilite ? hilite_keyword : "") << "RENAME TABLE " << (hilite ? hilite_none : "");
@ -311,7 +353,7 @@ void formatAST(const ASTRenameQuery & ast, std::ostream & s, size_t indent, bo
}
}
void formatAST(const ASTSetQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line)
void formatAST(const ASTSetQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
{
s << (hilite ? hilite_keyword : "") << "SET " << (ast.global ? "GLOBAL " : "") << (hilite ? hilite_none : "");
@ -324,7 +366,7 @@ void formatAST(const ASTSetQuery & ast, std::ostream & s, size_t indent, bool
}
}
void formatAST(const ASTShowTablesQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line)
void formatAST(const ASTShowTablesQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
{
if (ast.databases)
{
@ -352,19 +394,19 @@ void formatAST(const ASTShowTablesQuery & ast, std::ostream & s, size_t indent,
}
}
void formatAST(const ASTUseQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line)
void formatAST(const ASTUseQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
{
s << (hilite ? hilite_keyword : "") << "USE " << (hilite ? hilite_none : "") << backQuoteIfNeed(ast.database);
return;
}
void formatAST(const ASTShowProcesslistQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line)
void formatAST(const ASTShowProcesslistQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
{
s << (hilite ? hilite_keyword : "") << "SHOW PROCESSLIST" << (hilite ? hilite_none : "");
return;
}
void formatAST(const ASTInsertQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line)
void formatAST(const ASTInsertQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
{
s << (hilite ? hilite_keyword : "") << "INSERT INTO " << (hilite ? hilite_none : "")
<< (!ast.database.empty() ? backQuoteIfNeed(ast.database) + "." : "") << backQuoteIfNeed(ast.table);
@ -394,16 +436,6 @@ void formatAST(const ASTInsertQuery & ast, std::ostream & s, size_t indent, bo
}
}
void formatAST(const ASTExpressionList & ast, std::ostream & s, size_t indent, bool hilite, bool one_line)
{
for (ASTs::const_iterator it = ast.children.begin(); it != ast.children.end(); ++it)
{
if (it != ast.children.begin())
s << ", ";
formatAST(**it, s, indent, hilite, one_line);
}
}
static void writeAlias(const String & name, std::ostream & s, bool hilite, bool one_line)
{
s << (hilite ? hilite_keyword : "") << " AS " << (hilite ? hilite_alias : "");
@ -415,8 +447,155 @@ static void writeAlias(const String & name, std::ostream & s, bool hilite, bool
s << (hilite ? hilite_none : "");
}
void formatAST(const ASTFunction & ast, std::ostream & s, size_t indent, bool hilite, bool one_line)
void formatAST(const ASTFunction & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
{
/// Если есть алиас, то требуются скобки вокруг всего выражения, включая алиас. Потому что запись вида 0 AS x + 0 синтаксически некорректна.
if (need_parens && !ast.alias.empty())
s << '(';
/// Стоит ли записать эту функцию в виде оператора?
bool written = false;
if (ast.arguments && !ast.parameters)
{
if (ast.arguments->children.size() == 1)
{
const char * operators[] =
{
"negate", "-",
"not", "NOT ",
nullptr
};
for (const char ** func = operators; *func; func += 2)
{
if (0 == strcmp(ast.name.c_str(), func[0]))
{
s << (hilite ? hilite_operator : "") << func[1] << (hilite ? hilite_none : "");
formatAST(*ast.arguments, s, indent, hilite, one_line, true);
written = true;
}
}
}
/** need_parens - нужны ли скобки вокруг выражения с оператором.
* Они нужны, только если это выражение входит в другое выражение с оператором.
*/
if (!written && ast.arguments->children.size() == 2)
{
const char * operators[] =
{
"multiply", " * ",
"divide", " / ",
"modulo", " % ",
"plus", " + ",
"minus", " - ",
"notEquals", " != ",
"lessOrEquals", " <= ",
"greaterOrEquals", " >= ",
"less", " < ",
"greater", " > ",
"equals", " = ",
"like", " LIKE ",
"notLike", " NOT LIKE ",
"in", " IN ",
"notIn", " NOT IN ",
nullptr
};
for (const char ** func = operators; *func; func += 2)
{
if (0 == strcmp(ast.name.c_str(), func[0]))
{
if (need_parens)
s << '(';
formatAST(*ast.arguments->children[0], s, indent, hilite, one_line, true);
s << (hilite ? hilite_operator : "") << func[1] << (hilite ? hilite_none : "");
formatAST(*ast.arguments->children[1], s, indent, hilite, one_line, true);
if (need_parens)
s << ')';
written = true;
}
}
if (!written && 0 == strcmp(ast.name.c_str(), "arrayElement"))
{
formatAST(*ast.arguments->children[0], s, indent, hilite, one_line, true);
s << (hilite ? hilite_operator : "") << '[' << (hilite ? hilite_none : "");
formatAST(*ast.arguments->children[1], s, indent, hilite, one_line, true);
s << (hilite ? hilite_operator : "") << ']' << (hilite ? hilite_none : "");
written = true;
}
if (!written && 0 == strcmp(ast.name.c_str(), "tupleElement"))
{
formatAST(*ast.arguments->children[0], s, indent, hilite, one_line, true);
s << (hilite ? hilite_operator : "") << "." << (hilite ? hilite_none : "");
formatAST(*ast.arguments->children[1], s, indent, hilite, one_line, true);
written = true;
}
}
if (!written && ast.arguments->children.size() >= 2)
{
const char * operators[] =
{
"and", " AND ",
"or", " OR ",
nullptr
};
for (const char ** func = operators; *func; func += 2)
{
if (0 == strcmp(ast.name.c_str(), func[0]))
{
if (need_parens)
s << '(';
for (size_t i = 0; i < ast.arguments->children.size(); ++i)
{
if (i != 0)
s << (hilite ? hilite_operator : "") << func[1] << (hilite ? hilite_none : "");
formatAST(*ast.arguments->children[i], s, indent, hilite, one_line, true);
}
if (need_parens)
s << ')';
written = true;
}
}
}
if (!written && ast.arguments->children.size() >= 1)
{
if (!written && 0 == strcmp(ast.name.c_str(), "array"))
{
s << (hilite ? hilite_operator : "") << '[' << (hilite ? hilite_none : "");
for (size_t i = 0; i < ast.arguments->children.size(); ++i)
{
if (i != 0)
s << ", ";
formatAST(*ast.arguments->children[i], s, indent, hilite, one_line, false);
}
s << (hilite ? hilite_operator : "") << ']' << (hilite ? hilite_none : "");
written = true;
}
if (!written && 0 == strcmp(ast.name.c_str(), "tuple"))
{
s << (hilite ? hilite_operator : "") << '(' << (hilite ? hilite_none : "");
for (size_t i = 0; i < ast.arguments->children.size(); ++i)
{
if (i != 0)
s << ", ";
formatAST(*ast.arguments->children[i], s, indent, hilite, one_line, false);
}
s << (hilite ? hilite_operator : "") << ')' << (hilite ? hilite_none : "");
written = true;
}
}
}
if (!written)
{
s << (hilite ? hilite_function : "") << ast.name;
if (ast.parameters)
@ -434,13 +613,21 @@ void formatAST(const ASTFunction & ast, std::ostream & s, size_t indent, bool
}
s << (hilite ? hilite_none : "");
}
if (!ast.alias.empty())
{
writeAlias(ast.alias, s, hilite, one_line);
if (need_parens)
s << ')';
}
}
void formatAST(const ASTIdentifier & ast, std::ostream & s, size_t indent, bool hilite, bool one_line)
void formatAST(const ASTIdentifier & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
{
if (need_parens && !ast.alias.empty())
s << '(';
s << (hilite ? hilite_identifier : "");
WriteBufferFromOStream wb(s, 32);
@ -450,18 +637,29 @@ void formatAST(const ASTIdentifier & ast, std::ostream & s, size_t indent, bo
s << (hilite ? hilite_none : "");
if (!ast.alias.empty())
{
writeAlias(ast.alias, s, hilite, one_line);
if (need_parens)
s << ')';
}
}
void formatAST(const ASTLiteral & ast, std::ostream & s, size_t indent, bool hilite, bool one_line)
void formatAST(const ASTLiteral & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
{
if (need_parens && !ast.alias.empty())
s << '(';
s << apply_visitor(FieldVisitorToString(), ast.value);
if (!ast.alias.empty())
{
writeAlias(ast.alias, s, hilite, one_line);
if (need_parens)
s << ')';
}
}
void formatAST(const ASTNameTypePair & ast, std::ostream & s, size_t indent, bool hilite, bool one_line)
void formatAST(const ASTNameTypePair & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
{
std::string indent_str = one_line ? "" : std::string(4 * indent, ' ');
std::string nl_or_ws = one_line ? " " : "\n";
@ -470,12 +668,12 @@ void formatAST(const ASTNameTypePair & ast, std::ostream & s, size_t indent, bo
formatAST(*ast.type, s, indent, hilite, one_line);
}
void formatAST(const ASTAsterisk & ast, std::ostream & s, size_t indent, bool hilite, bool one_line)
void formatAST(const ASTAsterisk & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
{
s << "*";
}
void formatAST(const ASTOrderByElement & ast, std::ostream & s, size_t indent, bool hilite, bool one_line)
void formatAST(const ASTOrderByElement & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
{
formatAST(*ast.children.front(), s, indent, hilite, one_line);
s << (hilite ? hilite_keyword : "") << (ast.direction == -1 ? " DESC" : " ASC") << (hilite ? hilite_none : "");
@ -486,7 +684,7 @@ void formatAST(const ASTOrderByElement & ast, std::ostream & s, size_t indent,
}
}
void formatAST(const ASTAlterQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line)
void formatAST(const ASTAlterQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
{
std::string nl_or_nothing = one_line ? "" : "\n";

View File

@ -12,7 +12,7 @@ int main(int argc, char ** argv)
DB::ParserCreateQuery parser;
DB::ASTPtr ast;
std::string input = "CREATE TABLE hits (URL String, UserAgentMinor2 FixedString(2), EventTime DateTime) ENGINE = Log";
std::string expected;
const char * expected = "";
const char * begin = input.data();
const char * end = begin + input.size();

View File

@ -19,7 +19,7 @@ int main(int argc, char ** argv)
" HAVING SUM(Refresh) > 100"
" ORDER BY Visits, PageViews"
" LIMIT 1000, 10";
std::string expected;
const char * expected = "";
const char * begin = input.data();
const char * end = begin + input.size();

View File

@ -21,12 +21,10 @@ StorageDistributed::StorageDistributed(
const String & remote_database_,
const String & remote_table_,
Cluster & cluster_,
const DataTypeFactory & data_type_factory_,
const Context & context_,
const String & sign_column_name_)
: name(name_), columns(columns_),
remote_database(remote_database_), remote_table(remote_table_),
data_type_factory(data_type_factory_),
sign_column_name(sign_column_name_),
context(context_),
cluster(cluster_)
@ -45,12 +43,11 @@ StoragePtr StorageDistributed::create(
const String & remote_database_,
const String & remote_table_,
const String & cluster_name,
const DataTypeFactory & data_type_factory_,
Context & context_,
const String & sign_column_name_)
{
context_.initClusters();
return (new StorageDistributed(name_, columns_, remote_database_, remote_table_, context_.getCluster(cluster_name), data_type_factory_, context_, sign_column_name_))->thisPtr();
return (new StorageDistributed(name_, columns_, remote_database_, remote_table_, context_.getCluster(cluster_name), context_, sign_column_name_))->thisPtr();
}
@ -60,11 +57,10 @@ StoragePtr StorageDistributed::create(
const String & remote_database_,
const String & remote_table_,
SharedPtr<Cluster> & owned_cluster_,
const DataTypeFactory & data_type_factory_,
Context & context_,
const String & sign_column_name_)
{
auto res = new StorageDistributed(name_, columns_, remote_database_, remote_table_, *owned_cluster_, data_type_factory_, context_, sign_column_name_);
auto res = new StorageDistributed(name_, columns_, remote_database_, remote_table_, *owned_cluster_, context_, sign_column_name_);
/// Захватываем владение объектом-кластером.
res->owned_cluster = owned_cluster_;

View File

@ -149,7 +149,7 @@ StoragePtr StorageFactory::get(
String sign_column_name = args.size() == 4 ? dynamic_cast<ASTIdentifier &>(*args[3]).name : "";
return StorageDistributed::create(table_name, columns, remote_database, remote_table, cluster_name,
context.getDataTypeFactory(), context, sign_column_name);
context, sign_column_name);
}
else if (name == "MergeTree" || name == "SummingMergeTree")
{

View File

@ -33,12 +33,12 @@ int main(int argc, char ** argv)
names_and_types->push_back(NameAndTypePair("a", new DataTypeArray(new DataTypeUInt32)));
ASTPtr primary_expr;
String exprected;
const char * expected = "";
String primary_expr_str = "d";
const char * begin = primary_expr_str.data();
const char * end = begin + primary_expr_str.size();
ParserExpressionList parser;
if (!parser.parse(begin, end, primary_expr, exprected))
if (!parser.parse(begin, end, primary_expr, expected))
throw Poco::Exception("Cannot parse " + primary_expr_str);
StoragePtr table = StorageMergeTree::create("./", "test", names_and_types, context, primary_expr, "d", NULL, 101);
@ -82,12 +82,12 @@ int main(int argc, char ** argv)
QueryProcessingStage::Enum stage;
ASTPtr select;
String exprected;
const char * expected = "";
String select_str = "SELECT * FROM test";
const char * begin = select_str.data();
const char * end = begin + select_str.size();
ParserSelectQuery parser;
if (!parser.parse(begin, end, select, exprected))
if (!parser.parse(begin, end, select, expected))
throw Poco::Exception("Cannot parse " + primary_expr_str);
SharedPtr<IBlockInputStream> in = table->read(column_names, select, Settings(), stage)[0];

View File

@ -24,7 +24,7 @@ int main(int argc, const char ** argv)
std::string query = "SELECT count() FROM pre.t WHERE (key > 9000 AND key < 100000 OR key > 200000 AND key < 1000000 OR key > 3000000 AND key < 8000000 OR key > 12000000)";
ASTPtr ast;
IParser::Pos pos = &query[0];
std::string error;
const char * error = "";
if (!parser.parse(pos, &query[0] + query.size(), ast, error))
{
std::cout << "couldn't parse query" << std::endl;

View File

@ -1,6 +1,7 @@
#pragma once
#include <zkutil/Types.h>
#include <zkutil/KeeperException.h>
#include <Poco/Util/LayeredConfiguration.h>
namespace zkutil
@ -19,6 +20,22 @@ class ZooKeeper
public:
ZooKeeper(const std::string & hosts, int32_t sessionTimeoutMs = DEFAULT_SESSION_TIMEOUT, WatchFunction * watch = nullptr);
/** конфиг вида
<zookeeper>
<node>
<host>example1</host>
<port>2181</port>
</node>
<node>
<host>example2</host>
<port>2181</port>
</node>
<session_timeout_ms>30000</session_timeout_ms>
</zookeeper>
*/
ZooKeeper(const Poco::Util::LayeredConfiguration & config, const std::string & config_name,
WatchFunction * watch = nullptr);
/** Возвращает true, если сессия навсегда завершена.
* Это возможно только если соединение было установлено, а потом разорвалось. Это достаточно редкая ситуация.
* С другой стороны, если, например, указан неправильный сервер или порт, попытки соединения будут продолжаться бесконечно,
@ -95,6 +112,7 @@ public:
OpResultsPtr tryMulti(const Ops & ops);
private:
void init(const std::string & hosts, int32_t sessionTimeoutMs, WatchFunction * watch_);
friend struct StateWatch;
zk::ZooKeeper impl;

View File

@ -43,9 +43,10 @@ struct StateWatch : public zk::Watch
}
};
ZooKeeper::ZooKeeper(const std::string & hosts, int32_t sessionTimeoutMs, WatchFunction * watch_)
: state_watch(watch_)
void ZooKeeper::init(const std::string & hosts, int32_t sessionTimeoutMs, WatchFunction * watch_)
{
state_watch = watch_;
CHECKED(impl.init(hosts, sessionTimeoutMs, boost::make_shared<StateWatch>(this)));
ACL perm;
@ -55,6 +56,48 @@ ZooKeeper::ZooKeeper(const std::string & hosts, int32_t sessionTimeoutMs, WatchF
default_acl.push_back(perm);
}
ZooKeeper::ZooKeeper(const std::string & hosts, int32_t sessionTimeoutMs, WatchFunction * watch_)
{
init(hosts, sessionTimeoutMs, watch_);
}
struct ZooKeeperArgs
{
ZooKeeperArgs(const Poco::Util::LayeredConfiguration & config, const std::string & config_name)
{
Poco::Util::AbstractConfiguration::Keys keys;
config.keys(config_name, keys);
std::string node_key = "node";
std::string node_key_ext = "node[";
session_timeout_ms = DEFAULT_SESSION_TIMEOUT;
for (const auto & key : keys)
{
if (key == node_key || key.compare(0, node_key.size(), node_key) == 0)
{
if (hosts.size())
hosts += std::string(" ");
hosts += config.getString(config_name + "." + key + ".host") + ":" + config.getString(config_name + "." + key + ".port");
}
else if (key == "session_timeout_ms")
{
session_timeout_ms = config.getInt(config_name + "." + key);
}
else throw KeeperException(std::string("Unknown key ") + key + " in config file");
}
}
std::string hosts;
size_t session_timeout_ms;
};
ZooKeeper::ZooKeeper(const Poco::Util::LayeredConfiguration & config, const std::string & config_name,
WatchFunction * watch)
{
ZooKeeperArgs args(config, config_name);
init(args.hosts, args.session_timeout_ms, watch);
}
void ZooKeeper::stateChanged(WatchEvent::type event, SessionState::type state, const std::string & path)
{
session_state = state;