mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 08:32:02 +00:00
dbms: development [#CONV-2944].
This commit is contained in:
parent
8fec27c1f6
commit
b67b8d8b54
@ -33,6 +33,8 @@ public:
|
||||
data->clear();
|
||||
}
|
||||
|
||||
std::string getName() const { return "ColumnArray(" + data->getName() + ")"; }
|
||||
|
||||
ColumnPtr cloneEmpty() const
|
||||
{
|
||||
return new ColumnArray(data->cloneEmpty());
|
||||
|
@ -23,6 +23,7 @@ public:
|
||||
|
||||
ColumnConst(size_t s_, const T & data_) : s(s_), data(data_) {}
|
||||
|
||||
std::string getName() const { return "ColumnConst<" + TypeName<T>::get() + ">"; }
|
||||
bool isNumeric() const { return IsNumber<T>::value; }
|
||||
ColumnPtr cloneEmpty() const { return new ColumnConst(0, data); }
|
||||
size_t size() const { return s; }
|
||||
|
@ -26,6 +26,8 @@ public:
|
||||
clear();
|
||||
}
|
||||
|
||||
std::string getName() const { return "ColumnFixedArray(" + data->getName() + ")"; }
|
||||
|
||||
ColumnPtr cloneEmpty() const
|
||||
{
|
||||
return new ColumnFixedArray(data->cloneEmpty(), n);
|
||||
|
@ -26,6 +26,8 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
std::string getName() const { return "ColumnFixedString"; }
|
||||
|
||||
ColumnPtr cloneEmpty() const
|
||||
{
|
||||
return new ColumnFixedString(n);
|
||||
|
@ -26,6 +26,8 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
std::string getName() const { return "ColumnString"; }
|
||||
|
||||
ColumnPtr cloneEmpty() const
|
||||
{
|
||||
return new ColumnString;
|
||||
|
@ -24,6 +24,8 @@ public:
|
||||
ColumnVector() {}
|
||||
ColumnVector(size_t n) : data(n) {}
|
||||
|
||||
std::string getName() const { return "ColumnVector<" + TypeName<T>::get() + ">"; }
|
||||
|
||||
bool isNumeric() const { return IsNumber<T>::value; }
|
||||
|
||||
ColumnPtr cloneEmpty() const
|
||||
|
@ -20,6 +20,10 @@ typedef std::vector<ColumnPtr> Columns;
|
||||
class IColumn
|
||||
{
|
||||
public:
|
||||
/** Имя столбца. Для информационных сообщений.
|
||||
*/
|
||||
virtual std::string getName() const = 0;
|
||||
|
||||
/** Столбец представляет собой вектор чисел или числовую константу.
|
||||
*/
|
||||
virtual bool isNumeric() const { return false; }
|
||||
|
@ -1,5 +1,4 @@
|
||||
#ifndef DBMS_CORE_FIELD_H
|
||||
#define DBMS_CORE_FIELD_H
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
@ -151,20 +150,4 @@ template <> struct NearestFieldType<Float32> { typedef Float64 Type; };
|
||||
template <> struct NearestFieldType<Float64> { typedef Float64 Type; };
|
||||
template <> struct NearestFieldType<String> { typedef String Type; };
|
||||
|
||||
|
||||
template <typename T> struct IsNumber { static const bool value = false; };
|
||||
|
||||
template <> struct IsNumber<UInt8> { static const bool value = true; };
|
||||
template <> struct IsNumber<UInt16> { static const bool value = true; };
|
||||
template <> struct IsNumber<UInt32> { static const bool value = true; };
|
||||
template <> struct IsNumber<UInt64> { static const bool value = true; };
|
||||
template <> struct IsNumber<Int8> { static const bool value = true; };
|
||||
template <> struct IsNumber<Int16> { static const bool value = true; };
|
||||
template <> struct IsNumber<Int32> { static const bool value = true; };
|
||||
template <> struct IsNumber<Int64> { static const bool value = true; };
|
||||
template <> struct IsNumber<Float32> { static const bool value = true; };
|
||||
template <> struct IsNumber<Float64> { static const bool value = true; };
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,4 @@
|
||||
#ifndef DBMS_CORE_TYPES_H
|
||||
#define DBMS_CORE_TYPES_H
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <boost/none.hpp>
|
||||
@ -30,6 +29,34 @@ typedef double Float64;
|
||||
|
||||
typedef std::string String;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
template <typename T> struct IsNumber { static const bool value = false; };
|
||||
|
||||
template <> struct IsNumber<UInt8> { static const bool value = true; };
|
||||
template <> struct IsNumber<UInt16> { static const bool value = true; };
|
||||
template <> struct IsNumber<UInt32> { static const bool value = true; };
|
||||
template <> struct IsNumber<UInt64> { static const bool value = true; };
|
||||
template <> struct IsNumber<Int8> { static const bool value = true; };
|
||||
template <> struct IsNumber<Int16> { static const bool value = true; };
|
||||
template <> struct IsNumber<Int32> { static const bool value = true; };
|
||||
template <> struct IsNumber<Int64> { static const bool value = true; };
|
||||
template <> struct IsNumber<Float32> { static const bool value = true; };
|
||||
template <> struct IsNumber<Float64> { static const bool value = true; };
|
||||
|
||||
|
||||
template <typename T> struct TypeName;
|
||||
|
||||
template <> struct TypeName<Null> { static std::string get() { return "Null"; } };
|
||||
template <> struct TypeName<UInt8> { static std::string get() { return "UInt8"; } };
|
||||
template <> struct TypeName<UInt16> { static std::string get() { return "UInt16"; } };
|
||||
template <> struct TypeName<UInt32> { static std::string get() { return "UInt32"; } };
|
||||
template <> struct TypeName<UInt64> { static std::string get() { return "UInt64"; } };
|
||||
template <> struct TypeName<Int8> { static std::string get() { return "Int8"; } };
|
||||
template <> struct TypeName<Int16> { static std::string get() { return "Int16"; } };
|
||||
template <> struct TypeName<Int32> { static std::string get() { return "Int32"; } };
|
||||
template <> struct TypeName<Int64> { static std::string get() { return "Int64"; } };
|
||||
template <> struct TypeName<Float32> { static std::string get() { return "Float32"; } };
|
||||
template <> struct TypeName<Float64> { static std::string get() { return "Float64"; } };
|
||||
template <> struct TypeName<String> { static std::string get() { return "String"; } };
|
||||
|
||||
}
|
||||
|
@ -336,7 +336,8 @@ private:
|
||||
|| executeRightType<T0, Float64>(block, arguments, result, col_left))
|
||||
return true;
|
||||
else
|
||||
throw Exception("Illegal column of second argument of function " + getName(),
|
||||
throw Exception("Illegal column " + block.getByPosition(arguments[1]).column->getName()
|
||||
+ " of second argument of function " + getName(),
|
||||
ErrorCodes::ILLEGAL_COLUMN);
|
||||
}
|
||||
else if (ColumnConst<T0> * col_left = dynamic_cast<ColumnConst<T0> *>(&*block.getByPosition(arguments[0]).column))
|
||||
@ -353,7 +354,8 @@ private:
|
||||
|| executeConstRightType<T0, Float64>(block, arguments, result, col_left))
|
||||
return true;
|
||||
else
|
||||
throw Exception("Illegal column of second argument of function " + getName(),
|
||||
throw Exception("Illegal column " + block.getByPosition(arguments[1]).column->getName()
|
||||
+ " of second argument of function " + getName(),
|
||||
ErrorCodes::ILLEGAL_COLUMN);
|
||||
}
|
||||
|
||||
@ -412,7 +414,8 @@ public:
|
||||
|| executeLeftType<Int64>(block, arguments, result)
|
||||
|| executeLeftType<Float32>(block, arguments, result)
|
||||
|| executeLeftType<Float64>(block, arguments, result)))
|
||||
throw Exception("Illegal column of first argument of function " + getName(),
|
||||
throw Exception("Illegal column " + block.getByPosition(arguments[0]).column->getName()
|
||||
+ " of first argument of function " + getName(),
|
||||
ErrorCodes::ILLEGAL_COLUMN);
|
||||
}
|
||||
};
|
||||
|
@ -1203,7 +1203,8 @@ private:
|
||||
|| executeNumRightType<T0, Float64>(block, arguments, result, col_left))
|
||||
return true;
|
||||
else
|
||||
throw Exception("Illegal column of second argument of function " + getName(),
|
||||
throw Exception("Illegal column " + block.getByPosition(arguments[1]).column->getName()
|
||||
+ " of second argument of function " + getName(),
|
||||
ErrorCodes::ILLEGAL_COLUMN);
|
||||
}
|
||||
else if (ColumnConst<T0> * col_left = dynamic_cast<ColumnConst<T0> *>(&*block.getByPosition(arguments[0]).column))
|
||||
@ -1220,7 +1221,8 @@ private:
|
||||
|| executeNumConstRightType<T0, Float64>(block, arguments, result, col_left))
|
||||
return true;
|
||||
else
|
||||
throw Exception("Illegal column of second argument of function " + getName(),
|
||||
throw Exception("Illegal column " + block.getByPosition(arguments[1]).column->getName()
|
||||
+ " of second argument of function " + getName(),
|
||||
ErrorCodes::ILLEGAL_COLUMN);
|
||||
}
|
||||
|
||||
@ -1293,7 +1295,10 @@ private:
|
||||
dynamic_cast<ColumnUInt8 &>(c1_fixed_string->getData()).getData(), c1_fixed_string->getN(),
|
||||
c_res->getData());
|
||||
else
|
||||
throw Exception("Illegal columns of arguments of function " + getName(),
|
||||
throw Exception("Illegal columns "
|
||||
+ block.getByPosition(arguments[0]).column->getName() + " and "
|
||||
+ block.getByPosition(arguments[1]).column->getName()
|
||||
+ " of arguments of function " + getName(),
|
||||
ErrorCodes::ILLEGAL_COLUMN);
|
||||
}
|
||||
}
|
||||
@ -1345,7 +1350,8 @@ public:
|
||||
|| executeNumLeftType<Int64>(block, arguments, result)
|
||||
|| executeNumLeftType<Float32>(block, arguments, result)
|
||||
|| executeNumLeftType<Float64>(block, arguments, result)))
|
||||
throw Exception("Illegal column of first argument of function " + getName(),
|
||||
throw Exception("Illegal column " + block.getByPosition(arguments[0]).column->getName()
|
||||
+ " of first argument of function " + getName(),
|
||||
ErrorCodes::ILLEGAL_COLUMN);
|
||||
}
|
||||
else
|
||||
|
@ -200,7 +200,8 @@ private:
|
||||
|| executeRightType<T0, Float64>(block, arguments, result, col_left))
|
||||
return true;
|
||||
else
|
||||
throw Exception("Illegal column of second argument of function " + getName(),
|
||||
throw Exception("Illegal column " + block.getByPosition(arguments[1]).column->getName()
|
||||
+ " of second argument of function " + getName(),
|
||||
ErrorCodes::ILLEGAL_COLUMN);
|
||||
}
|
||||
else if (ColumnConst<T0> * col_left = dynamic_cast<ColumnConst<T0> *>(&*block.getByPosition(arguments[0]).column))
|
||||
@ -217,7 +218,8 @@ private:
|
||||
|| executeConstRightType<T0, Float64>(block, arguments, result, col_left))
|
||||
return true;
|
||||
else
|
||||
throw Exception("Illegal column of second argument of function " + getName(),
|
||||
throw Exception("Illegal column " + block.getByPosition(arguments[1]).column->getName()
|
||||
+ " of second argument of function " + getName(),
|
||||
ErrorCodes::ILLEGAL_COLUMN);
|
||||
}
|
||||
|
||||
@ -267,7 +269,8 @@ public:
|
||||
|| executeLeftType<Int64>(block, arguments, result)
|
||||
|| executeLeftType<Float32>(block, arguments, result)
|
||||
|| executeLeftType<Float64>(block, arguments, result)))
|
||||
throw Exception("Illegal column of first argument of function " + getName(),
|
||||
throw Exception("Illegal column " + block.getByPosition(arguments[0]).column->getName()
|
||||
+ " of first argument of function " + getName(),
|
||||
ErrorCodes::ILLEGAL_COLUMN);
|
||||
}
|
||||
};
|
||||
@ -349,7 +352,8 @@ public:
|
||||
|| executeType<Int64>(block, arguments, result)
|
||||
|| executeType<Float32>(block, arguments, result)
|
||||
|| executeType<Float64>(block, arguments, result)))
|
||||
throw Exception("Illegal column of argument of function " + getName(),
|
||||
throw Exception("Illegal column " + block.getByPosition(arguments[0]).column->getName()
|
||||
+ " of argument of function " + getName(),
|
||||
ErrorCodes::ILLEGAL_COLUMN);
|
||||
}
|
||||
};
|
||||
|
@ -1,5 +1,4 @@
|
||||
#ifndef DBMS_PARSERS_ASTSELECTQUERY_H
|
||||
#define DBMS_PARSERS_ASTSELECTQUERY_H
|
||||
#pragma once
|
||||
|
||||
#include <DB/Parsers/IAST.h>
|
||||
|
||||
@ -13,8 +12,16 @@ namespace DB
|
||||
class ASTSelectQuery : public IAST
|
||||
{
|
||||
public:
|
||||
ASTPtr select, from, where, group, having, order, limit;
|
||||
|
||||
ASTPtr select_expression_list;
|
||||
ASTPtr database;
|
||||
ASTPtr table;
|
||||
ASTPtr where_expression;
|
||||
ASTPtr group_expression_list;
|
||||
ASTPtr having_expression;
|
||||
ASTPtr order_expression_list;
|
||||
ASTPtr limit_offset;
|
||||
ASTPtr limit_length;
|
||||
|
||||
ASTSelectQuery() {}
|
||||
ASTSelectQuery(StringRange range_) : IAST(range_) {}
|
||||
|
||||
@ -23,5 +30,3 @@ public:
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,9 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <DB/Parsers/ASTSelectQuery.h>
|
||||
#include <DB/Parsers/IParserBase.h>
|
||||
#include <DB/Parsers/CommonParsers.h>
|
||||
#include <DB/Parsers/ExpressionListParsers.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
@ -14,34 +11,7 @@ class ParserSelectQuery : public IParserBase
|
||||
{
|
||||
protected:
|
||||
String getName() { return "SELECT query"; }
|
||||
|
||||
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
|
||||
{
|
||||
Pos begin = pos;
|
||||
|
||||
ASTPtr select_expression_list;
|
||||
|
||||
ParserWhiteSpaceOrComments ws;
|
||||
ParserString s("SELECT", true, true);
|
||||
ParserNotEmptyExpressionList exp_list;
|
||||
|
||||
ws.ignore(pos, end);
|
||||
|
||||
if (!s.ignore(pos, end, expected))
|
||||
return false;
|
||||
|
||||
ws.ignore(pos, end);
|
||||
|
||||
if (!exp_list.parse(pos, end, select_expression_list, expected))
|
||||
return false;
|
||||
|
||||
ASTSelectQuery * select_query = new ASTSelectQuery(StringRange(begin, pos));
|
||||
node = select_query;
|
||||
select_query->select = select_expression_list;
|
||||
select_query->children.push_back(select_query->select);
|
||||
|
||||
return true;
|
||||
}
|
||||
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -18,8 +18,9 @@ Block FilterBlockInputStream::read()
|
||||
return res;
|
||||
|
||||
size_t columns = res.columns();
|
||||
ColumnPtr column = res.getByPosition(filter_column).column;
|
||||
|
||||
ColumnConstUInt8 * column_const = dynamic_cast<ColumnConstUInt8 *>(&*res.getByPosition(filter_column).column);
|
||||
ColumnConstUInt8 * column_const = dynamic_cast<ColumnConstUInt8 *>(&*column);
|
||||
if (column_const)
|
||||
{
|
||||
return column_const->getData()
|
||||
@ -27,11 +28,11 @@ Block FilterBlockInputStream::read()
|
||||
: Block();
|
||||
}
|
||||
|
||||
ColumnUInt8 * column = dynamic_cast<ColumnUInt8 *>(&*res.getByPosition(filter_column).column);
|
||||
if (!column)
|
||||
throw Exception("Illegal type of column for filter. Must be ColumnUInt8 or ColumnConstUInt8.", ErrorCodes::ILLEGAL_TYPE_OF_COLUMN_FOR_FILTER);
|
||||
ColumnUInt8 * column_vec = dynamic_cast<ColumnUInt8 *>(&*column);
|
||||
if (!column_vec)
|
||||
throw Exception("Illegal type " + column->getName() + " of column for filter. Must be ColumnUInt8 or ColumnConstUInt8.", ErrorCodes::ILLEGAL_TYPE_OF_COLUMN_FOR_FILTER);
|
||||
|
||||
IColumn::Filter & filter = column->getData();
|
||||
IColumn::Filter & filter = column_vec->getData();
|
||||
|
||||
for (size_t i = 0; i < columns; ++i)
|
||||
if (i != filter_column)
|
||||
|
162
dbms/src/Parsers/ParserSelectQuery.cpp
Normal file
162
dbms/src/Parsers/ParserSelectQuery.cpp
Normal file
@ -0,0 +1,162 @@
|
||||
#include <DB/Parsers/ASTSelectQuery.h>
|
||||
#include <DB/Parsers/IParserBase.h>
|
||||
#include <DB/Parsers/CommonParsers.h>
|
||||
#include <DB/Parsers/ExpressionElementParsers.h>
|
||||
#include <DB/Parsers/ExpressionListParsers.h>
|
||||
#include <DB/Parsers/ParserSelectQuery.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
|
||||
bool ParserSelectQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected)
|
||||
{
|
||||
Pos begin = pos;
|
||||
|
||||
ASTSelectQuery * select_query = new ASTSelectQuery(StringRange(begin, pos));
|
||||
node = select_query;
|
||||
|
||||
ParserWhiteSpaceOrComments ws;
|
||||
ParserString s_select("SELECT", true, true);
|
||||
ParserString s_from("FROM", true, true);
|
||||
ParserString s_where("WHERE", true, true);
|
||||
ParserString s_group("GROUP", true, true);
|
||||
ParserString s_by("BY", true, true);
|
||||
ParserString s_having("HAVING", true, true);
|
||||
ParserString s_order("ORDER", true, true);
|
||||
ParserString s_limit("LIMIT", true, true);
|
||||
ParserNotEmptyExpressionList exp_list;
|
||||
ParserLogicalOrExpression exp_elem;
|
||||
|
||||
ws.ignore(pos, end);
|
||||
|
||||
/// SELECT expr list
|
||||
{
|
||||
if (!s_select.ignore(pos, end, expected))
|
||||
return false;
|
||||
|
||||
ws.ignore(pos, end);
|
||||
|
||||
if (!exp_list.parse(pos, end, select_query->select_expression_list, expected))
|
||||
return false;
|
||||
|
||||
ws.ignore(pos, end);
|
||||
}
|
||||
|
||||
/// FROM database.table или FROM table TODO subquery
|
||||
if (s_from.ignore(pos, end, expected))
|
||||
{
|
||||
ws.ignore(pos, end);
|
||||
|
||||
ParserString s_dot(".");
|
||||
ParserIdentifier ident;
|
||||
|
||||
if (!ident.parse(pos, end, select_query->table, expected))
|
||||
return false;
|
||||
|
||||
ws.ignore(pos, end);
|
||||
|
||||
if (s_dot.ignore(pos, end, expected))
|
||||
{
|
||||
select_query->database = select_query->table;
|
||||
if (!ident.parse(pos, end, select_query->table, expected))
|
||||
return false;
|
||||
|
||||
ws.ignore(pos, end);
|
||||
}
|
||||
}
|
||||
|
||||
/// WHERE expr
|
||||
if (s_where.ignore(pos, end, expected))
|
||||
{
|
||||
ws.ignore(pos, end);
|
||||
|
||||
if (!exp_elem.parse(pos, end, select_query->where_expression, expected))
|
||||
return false;
|
||||
|
||||
ws.ignore(pos, end);
|
||||
}
|
||||
|
||||
/// GROUP BY expr list
|
||||
if (s_group.ignore(pos, end, expected))
|
||||
{
|
||||
ws.ignore(pos, end);
|
||||
if (!s_by.ignore(pos, end, expected))
|
||||
return false;
|
||||
|
||||
if (!exp_list.parse(pos, end, select_query->group_expression_list, expected))
|
||||
return false;
|
||||
|
||||
ws.ignore(pos, end);
|
||||
}
|
||||
|
||||
/// HAVING expr
|
||||
if (s_having.ignore(pos, end, expected))
|
||||
{
|
||||
ws.ignore(pos, end);
|
||||
|
||||
if (!exp_elem.parse(pos, end, select_query->having_expression, expected))
|
||||
return false;
|
||||
|
||||
ws.ignore(pos, end);
|
||||
}
|
||||
|
||||
/// ORDER BY expr list TODO ASC, DESC
|
||||
if (s_order.ignore(pos, end, expected))
|
||||
{
|
||||
ws.ignore(pos, end);
|
||||
if (!s_by.ignore(pos, end, expected))
|
||||
return false;
|
||||
|
||||
if (!exp_list.parse(pos, end, select_query->order_expression_list, expected))
|
||||
return false;
|
||||
|
||||
ws.ignore(pos, end);
|
||||
}
|
||||
|
||||
/// LIMIT length или LIMIT offset, length
|
||||
if (s_limit.ignore(pos, end, expected))
|
||||
{
|
||||
ws.ignore(pos, end);
|
||||
|
||||
ParserString s_comma(",");
|
||||
ParserNumber num;
|
||||
|
||||
if (!num.parse(pos, end, select_query->limit_length, expected))
|
||||
return false;
|
||||
|
||||
ws.ignore(pos, end);
|
||||
|
||||
if (s_comma.ignore(pos, end, expected))
|
||||
{
|
||||
select_query->limit_offset = select_query->limit_length;
|
||||
if (!num.parse(pos, end, select_query->limit_length, expected))
|
||||
return false;
|
||||
|
||||
ws.ignore(pos, end);
|
||||
}
|
||||
}
|
||||
|
||||
select_query->children.push_back(select_query->select_expression_list);
|
||||
if (select_query->database)
|
||||
select_query->children.push_back(select_query->database);
|
||||
if (select_query->table)
|
||||
select_query->children.push_back(select_query->table);
|
||||
if (select_query->where_expression)
|
||||
select_query->children.push_back(select_query->where_expression);
|
||||
if (select_query->group_expression_list)
|
||||
select_query->children.push_back(select_query->group_expression_list);
|
||||
if (select_query->having_expression)
|
||||
select_query->children.push_back(select_query->having_expression);
|
||||
if (select_query->order_expression_list)
|
||||
select_query->children.push_back(select_query->order_expression_list);
|
||||
if (select_query->limit_offset)
|
||||
select_query->children.push_back(select_query->limit_offset);
|
||||
if (select_query->limit_length)
|
||||
select_query->children.push_back(select_query->limit_length);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -73,7 +73,53 @@ void formatAST(const IAST & ast, std::ostream & s)
|
||||
void formatAST(const ASTSelectQuery & ast, std::ostream & s)
|
||||
{
|
||||
s << "SELECT ";
|
||||
formatAST(*ast.select, s);
|
||||
formatAST(*ast.select_expression_list, s);
|
||||
|
||||
if (ast.table)
|
||||
{
|
||||
s << " FROM ";
|
||||
if (ast.database)
|
||||
{
|
||||
formatAST(*ast.database, s);
|
||||
s << ".";
|
||||
}
|
||||
formatAST(*ast.table, s);
|
||||
}
|
||||
|
||||
if (ast.where_expression)
|
||||
{
|
||||
s << " WHERE ";
|
||||
formatAST(*ast.where_expression, s);
|
||||
}
|
||||
|
||||
if (ast.group_expression_list)
|
||||
{
|
||||
s << " GROUP BY ";
|
||||
formatAST(*ast.group_expression_list, s);
|
||||
}
|
||||
|
||||
if (ast.having_expression)
|
||||
{
|
||||
s << " HAVING ";
|
||||
formatAST(*ast.having_expression, s);
|
||||
}
|
||||
|
||||
if (ast.order_expression_list)
|
||||
{
|
||||
s << " ORDER BY ";
|
||||
formatAST(*ast.order_expression_list, s);
|
||||
}
|
||||
|
||||
if (ast.limit_length)
|
||||
{
|
||||
s << " LIMIT ";
|
||||
if (ast.limit_offset)
|
||||
{
|
||||
formatAST(*ast.limit_offset, s);
|
||||
s << ", ";
|
||||
}
|
||||
formatAST(*ast.limit_length, s);
|
||||
}
|
||||
}
|
||||
|
||||
void formatAST(const ASTCreateQuery & ast, std::ostream & s)
|
||||
|
@ -11,7 +11,14 @@ int main(int argc, char ** argv)
|
||||
{
|
||||
DB::ParserSelectQuery parser;
|
||||
DB::ASTPtr ast;
|
||||
std::string input = "SELECT 18446744073709551615, f(1), '\\\\', [a, b, c], (a, b, c), 1 + 2 * -3, a = b OR c > d.1 + 2 * -g[0] AND NOT e < f * (x + y)";
|
||||
std::string input =
|
||||
" SELECT 18446744073709551615, f(1), '\\\\', [a, b, c], (a, b, c), 1 + 2 * -3, a = b OR c > d.1 + 2 * -g[0] AND NOT e < f * (x + y)"
|
||||
" FROM default.hits"
|
||||
" WHERE CounterID = 101500 AND UniqID % 3 = 0"
|
||||
" GROUP BY UniqID"
|
||||
" HAVING SUM(Refresh) > 100"
|
||||
" ORDER BY Visits, PageViews"
|
||||
" LIMIT 1000, 10";
|
||||
std::string expected;
|
||||
|
||||
const char * begin = input.data();
|
||||
|
Loading…
Reference in New Issue
Block a user