mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-12-01 03:52:15 +00:00
dbms: development [#CONV-2944].
This commit is contained in:
parent
8fec27c1f6
commit
b67b8d8b54
@ -33,6 +33,8 @@ public:
|
|||||||
data->clear();
|
data->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string getName() const { return "ColumnArray(" + data->getName() + ")"; }
|
||||||
|
|
||||||
ColumnPtr cloneEmpty() const
|
ColumnPtr cloneEmpty() const
|
||||||
{
|
{
|
||||||
return new ColumnArray(data->cloneEmpty());
|
return new ColumnArray(data->cloneEmpty());
|
||||||
|
@ -23,6 +23,7 @@ public:
|
|||||||
|
|
||||||
ColumnConst(size_t s_, const T & data_) : s(s_), data(data_) {}
|
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; }
|
bool isNumeric() const { return IsNumber<T>::value; }
|
||||||
ColumnPtr cloneEmpty() const { return new ColumnConst(0, data); }
|
ColumnPtr cloneEmpty() const { return new ColumnConst(0, data); }
|
||||||
size_t size() const { return s; }
|
size_t size() const { return s; }
|
||||||
|
@ -26,6 +26,8 @@ public:
|
|||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string getName() const { return "ColumnFixedArray(" + data->getName() + ")"; }
|
||||||
|
|
||||||
ColumnPtr cloneEmpty() const
|
ColumnPtr cloneEmpty() const
|
||||||
{
|
{
|
||||||
return new ColumnFixedArray(data->cloneEmpty(), n);
|
return new ColumnFixedArray(data->cloneEmpty(), n);
|
||||||
|
@ -26,6 +26,8 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string getName() const { return "ColumnFixedString"; }
|
||||||
|
|
||||||
ColumnPtr cloneEmpty() const
|
ColumnPtr cloneEmpty() const
|
||||||
{
|
{
|
||||||
return new ColumnFixedString(n);
|
return new ColumnFixedString(n);
|
||||||
|
@ -26,6 +26,8 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string getName() const { return "ColumnString"; }
|
||||||
|
|
||||||
ColumnPtr cloneEmpty() const
|
ColumnPtr cloneEmpty() const
|
||||||
{
|
{
|
||||||
return new ColumnString;
|
return new ColumnString;
|
||||||
|
@ -24,6 +24,8 @@ public:
|
|||||||
ColumnVector() {}
|
ColumnVector() {}
|
||||||
ColumnVector(size_t n) : data(n) {}
|
ColumnVector(size_t n) : data(n) {}
|
||||||
|
|
||||||
|
std::string getName() const { return "ColumnVector<" + TypeName<T>::get() + ">"; }
|
||||||
|
|
||||||
bool isNumeric() const { return IsNumber<T>::value; }
|
bool isNumeric() const { return IsNumber<T>::value; }
|
||||||
|
|
||||||
ColumnPtr cloneEmpty() const
|
ColumnPtr cloneEmpty() const
|
||||||
|
@ -20,6 +20,10 @@ typedef std::vector<ColumnPtr> Columns;
|
|||||||
class IColumn
|
class IColumn
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
/** Имя столбца. Для информационных сообщений.
|
||||||
|
*/
|
||||||
|
virtual std::string getName() const = 0;
|
||||||
|
|
||||||
/** Столбец представляет собой вектор чисел или числовую константу.
|
/** Столбец представляет собой вектор чисел или числовую константу.
|
||||||
*/
|
*/
|
||||||
virtual bool isNumeric() const { return false; }
|
virtual bool isNumeric() const { return false; }
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#ifndef DBMS_CORE_FIELD_H
|
#pragma once
|
||||||
#define DBMS_CORE_FIELD_H
|
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@ -151,20 +150,4 @@ template <> struct NearestFieldType<Float32> { typedef Float64 Type; };
|
|||||||
template <> struct NearestFieldType<Float64> { typedef Float64 Type; };
|
template <> struct NearestFieldType<Float64> { typedef Float64 Type; };
|
||||||
template <> struct NearestFieldType<String> { typedef String 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
|
#pragma once
|
||||||
#define DBMS_CORE_TYPES_H
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <boost/none.hpp>
|
#include <boost/none.hpp>
|
||||||
@ -30,6 +29,34 @@ typedef double Float64;
|
|||||||
|
|
||||||
typedef std::string String;
|
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))
|
|| executeRightType<T0, Float64>(block, arguments, result, col_left))
|
||||||
return true;
|
return true;
|
||||||
else
|
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);
|
ErrorCodes::ILLEGAL_COLUMN);
|
||||||
}
|
}
|
||||||
else if (ColumnConst<T0> * col_left = dynamic_cast<ColumnConst<T0> *>(&*block.getByPosition(arguments[0]).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))
|
|| executeConstRightType<T0, Float64>(block, arguments, result, col_left))
|
||||||
return true;
|
return true;
|
||||||
else
|
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);
|
ErrorCodes::ILLEGAL_COLUMN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -412,7 +414,8 @@ public:
|
|||||||
|| executeLeftType<Int64>(block, arguments, result)
|
|| executeLeftType<Int64>(block, arguments, result)
|
||||||
|| executeLeftType<Float32>(block, arguments, result)
|
|| executeLeftType<Float32>(block, arguments, result)
|
||||||
|| executeLeftType<Float64>(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);
|
ErrorCodes::ILLEGAL_COLUMN);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1203,7 +1203,8 @@ private:
|
|||||||
|| executeNumRightType<T0, Float64>(block, arguments, result, col_left))
|
|| executeNumRightType<T0, Float64>(block, arguments, result, col_left))
|
||||||
return true;
|
return true;
|
||||||
else
|
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);
|
ErrorCodes::ILLEGAL_COLUMN);
|
||||||
}
|
}
|
||||||
else if (ColumnConst<T0> * col_left = dynamic_cast<ColumnConst<T0> *>(&*block.getByPosition(arguments[0]).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))
|
|| executeNumConstRightType<T0, Float64>(block, arguments, result, col_left))
|
||||||
return true;
|
return true;
|
||||||
else
|
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);
|
ErrorCodes::ILLEGAL_COLUMN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1293,7 +1295,10 @@ private:
|
|||||||
dynamic_cast<ColumnUInt8 &>(c1_fixed_string->getData()).getData(), c1_fixed_string->getN(),
|
dynamic_cast<ColumnUInt8 &>(c1_fixed_string->getData()).getData(), c1_fixed_string->getN(),
|
||||||
c_res->getData());
|
c_res->getData());
|
||||||
else
|
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);
|
ErrorCodes::ILLEGAL_COLUMN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1345,7 +1350,8 @@ public:
|
|||||||
|| executeNumLeftType<Int64>(block, arguments, result)
|
|| executeNumLeftType<Int64>(block, arguments, result)
|
||||||
|| executeNumLeftType<Float32>(block, arguments, result)
|
|| executeNumLeftType<Float32>(block, arguments, result)
|
||||||
|| executeNumLeftType<Float64>(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);
|
ErrorCodes::ILLEGAL_COLUMN);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -200,7 +200,8 @@ private:
|
|||||||
|| executeRightType<T0, Float64>(block, arguments, result, col_left))
|
|| executeRightType<T0, Float64>(block, arguments, result, col_left))
|
||||||
return true;
|
return true;
|
||||||
else
|
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);
|
ErrorCodes::ILLEGAL_COLUMN);
|
||||||
}
|
}
|
||||||
else if (ColumnConst<T0> * col_left = dynamic_cast<ColumnConst<T0> *>(&*block.getByPosition(arguments[0]).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))
|
|| executeConstRightType<T0, Float64>(block, arguments, result, col_left))
|
||||||
return true;
|
return true;
|
||||||
else
|
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);
|
ErrorCodes::ILLEGAL_COLUMN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,7 +269,8 @@ public:
|
|||||||
|| executeLeftType<Int64>(block, arguments, result)
|
|| executeLeftType<Int64>(block, arguments, result)
|
||||||
|| executeLeftType<Float32>(block, arguments, result)
|
|| executeLeftType<Float32>(block, arguments, result)
|
||||||
|| executeLeftType<Float64>(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);
|
ErrorCodes::ILLEGAL_COLUMN);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -349,7 +352,8 @@ public:
|
|||||||
|| executeType<Int64>(block, arguments, result)
|
|| executeType<Int64>(block, arguments, result)
|
||||||
|| executeType<Float32>(block, arguments, result)
|
|| executeType<Float32>(block, arguments, result)
|
||||||
|| executeType<Float64>(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);
|
ErrorCodes::ILLEGAL_COLUMN);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#ifndef DBMS_PARSERS_ASTSELECTQUERY_H
|
#pragma once
|
||||||
#define DBMS_PARSERS_ASTSELECTQUERY_H
|
|
||||||
|
|
||||||
#include <DB/Parsers/IAST.h>
|
#include <DB/Parsers/IAST.h>
|
||||||
|
|
||||||
@ -13,7 +12,15 @@ namespace DB
|
|||||||
class ASTSelectQuery : public IAST
|
class ASTSelectQuery : public IAST
|
||||||
{
|
{
|
||||||
public:
|
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() {}
|
||||||
ASTSelectQuery(StringRange range_) : IAST(range_) {}
|
ASTSelectQuery(StringRange range_) : IAST(range_) {}
|
||||||
@ -23,5 +30,3 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <DB/Parsers/ASTSelectQuery.h>
|
|
||||||
#include <DB/Parsers/IParserBase.h>
|
#include <DB/Parsers/IParserBase.h>
|
||||||
#include <DB/Parsers/CommonParsers.h>
|
|
||||||
#include <DB/Parsers/ExpressionListParsers.h>
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
@ -14,34 +11,7 @@ class ParserSelectQuery : public IParserBase
|
|||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
String getName() { return "SELECT query"; }
|
String getName() { return "SELECT query"; }
|
||||||
|
bool parseImpl(Pos & pos, Pos end, ASTPtr & node, String & expected);
|
||||||
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;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,9 @@ Block FilterBlockInputStream::read()
|
|||||||
return res;
|
return res;
|
||||||
|
|
||||||
size_t columns = res.columns();
|
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)
|
if (column_const)
|
||||||
{
|
{
|
||||||
return column_const->getData()
|
return column_const->getData()
|
||||||
@ -27,11 +28,11 @@ Block FilterBlockInputStream::read()
|
|||||||
: Block();
|
: Block();
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnUInt8 * column = dynamic_cast<ColumnUInt8 *>(&*res.getByPosition(filter_column).column);
|
ColumnUInt8 * column_vec = dynamic_cast<ColumnUInt8 *>(&*column);
|
||||||
if (!column)
|
if (!column_vec)
|
||||||
throw Exception("Illegal type of column for filter. Must be ColumnUInt8 or ColumnConstUInt8.", ErrorCodes::ILLEGAL_TYPE_OF_COLUMN_FOR_FILTER);
|
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)
|
for (size_t i = 0; i < columns; ++i)
|
||||||
if (i != filter_column)
|
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)
|
void formatAST(const ASTSelectQuery & ast, std::ostream & s)
|
||||||
{
|
{
|
||||||
s << "SELECT ";
|
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)
|
void formatAST(const ASTCreateQuery & ast, std::ostream & s)
|
||||||
|
@ -11,7 +11,14 @@ int main(int argc, char ** argv)
|
|||||||
{
|
{
|
||||||
DB::ParserSelectQuery parser;
|
DB::ParserSelectQuery parser;
|
||||||
DB::ASTPtr ast;
|
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;
|
std::string expected;
|
||||||
|
|
||||||
const char * begin = input.data();
|
const char * begin = input.data();
|
||||||
|
Loading…
Reference in New Issue
Block a user