dbms: development [#CONV-2944].

This commit is contained in:
Alexey Milovidov 2011-08-28 00:31:30 +00:00
parent 8fec27c1f6
commit b67b8d8b54
18 changed files with 306 additions and 77 deletions

View File

@ -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());

View File

@ -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; }

View File

@ -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);

View File

@ -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);

View File

@ -26,6 +26,8 @@ public:
{ {
} }
std::string getName() const { return "ColumnString"; }
ColumnPtr cloneEmpty() const ColumnPtr cloneEmpty() const
{ {
return new ColumnString; return new ColumnString;

View File

@ -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

View File

@ -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; }

View File

@ -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

View File

@ -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"; } };
}

View File

@ -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);
} }
}; };

View File

@ -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

View File

@ -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);
} }
}; };

View File

@ -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

View File

@ -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;
}
}; };
} }

View File

@ -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)

View 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;
}
}

View File

@ -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)

View File

@ -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();