ClickHouse/dbms/include/DB/Parsers/IAST.h

135 lines
4.2 KiB
C
Raw Normal View History

2011-08-09 19:19:00 +00:00
#pragma once
2010-06-24 19:12:10 +00:00
#include <list>
#include <set>
2011-08-09 19:19:00 +00:00
#include <sstream>
2010-06-24 19:12:10 +00:00
#include <Poco/SharedPtr.h>
#include <Yandex/Common.h>
2010-06-24 19:12:10 +00:00
#include <DB/Core/Types.h>
2011-09-25 03:37:09 +00:00
#include <DB/Core/Exception.h>
#include <DB/Core/ErrorCodes.h>
2013-06-21 20:34:19 +00:00
#include <DB/IO/WriteHelpers.h>
2010-06-24 19:12:10 +00:00
#include <DB/Parsers/StringRange.h>
2012-12-27 16:23:12 +00:00
#include <iostream>
2010-06-24 19:12:10 +00:00
namespace DB
{
using Poco::SharedPtr;
typedef std::set<String> IdentifierNameSet;
2010-06-24 19:12:10 +00:00
/** Элемент синтаксического дерева (в дальнейшем - направленного ациклического графа с элементами семантики)
*/
class IAST
2011-08-13 21:05:18 +00:00
{
2010-06-24 19:12:10 +00:00
public:
2012-05-22 19:32:56 +00:00
typedef std::vector<SharedPtr<IAST> > ASTs;
2011-08-13 21:05:18 +00:00
ASTs children;
StringRange range;
2013-02-11 11:22:15 +00:00
/** Строка с полным запросом.
* Этот указатель не дает ее удалить, пока range в нее ссылается.
*/
StringPtr query_string;
2011-08-28 02:22:23 +00:00
/** Идентификатор части выражения. Используется при интерпретации, чтобы вычислять не всё выражение сразу,
* а по частям (например, сначала WHERE, потом фильтрация, потом всё остальное).
*/
unsigned part_id;
2011-08-09 19:19:00 +00:00
2011-12-12 06:15:34 +00:00
IAST() : range(NULL, NULL), part_id(0) {}
IAST(StringRange range_) : range(range_), part_id(0) {}
2011-08-13 21:05:18 +00:00
virtual ~IAST() {}
2011-09-25 03:37:09 +00:00
/** Получить каноническое имя столбца, если элемент является столбцом */
virtual String getColumnName() const { throw Exception("Trying to get name of not a column: " + getID(), ErrorCodes::NOT_A_COLUMN); }
2011-11-06 04:21:09 +00:00
/** Получить алиас, если он есть, или каноническое имя столбца; если элемент является столбцом */
2012-12-27 16:23:12 +00:00
virtual String getAlias() const { return getColumnName(); }
2011-08-13 21:05:18 +00:00
2011-08-09 19:19:00 +00:00
/** Получить текст, который идентифицирует этот элемент. */
2012-12-27 16:23:12 +00:00
virtual String getID() const = 0;
2011-08-09 19:19:00 +00:00
2011-12-12 06:15:34 +00:00
/** Получить глубокую копию дерева. */
virtual SharedPtr<IAST> clone() const = 0;
2011-08-09 19:19:00 +00:00
/** Получить текст, который идентифицирует этот элемент и всё поддерево.
* Обычно он содержит идентификатор элемента и getTreeID от всех детей.
*/
2012-12-27 16:23:12 +00:00
String getTreeID() const
2011-08-09 19:19:00 +00:00
{
std::stringstream s;
s << getID();
if (!children.empty())
{
s << "(";
2012-12-27 16:23:12 +00:00
for (ASTs::const_iterator it = children.begin(); it != children.end(); ++it)
2011-08-09 19:19:00 +00:00
{
if (it != children.begin())
s << ", ";
s << (*it)->getTreeID();
}
s << ")";
}
return s.str();
}
2011-09-25 03:37:09 +00:00
2012-12-27 16:23:12 +00:00
void dumpTree(std::ostream & ostr, size_t indent = 0) const
2011-09-25 03:37:09 +00:00
{
String indent_str(indent, '-');
2011-12-12 06:15:34 +00:00
ostr << indent_str << getID() << ", " << this << ", part_id = " << part_id << std::endl;
2012-12-27 16:23:12 +00:00
for (ASTs::const_iterator it = children.begin(); it != children.end(); ++it)
2011-09-25 03:37:09 +00:00
(*it)->dumpTree(ostr, indent + 1);
}
/** Проверить глубину дерева.
* Если задано max_depth и глубина больше - кинуть исключение.
*/
size_t checkDepth(size_t max_depth) const
{
size_t res = 0;
for (ASTs::const_iterator it = children.begin(); it != children.end(); ++it)
if (max_depth == 0 || (res = (*it)->checkDepth(max_depth - 1)) > max_depth - 1)
2013-06-21 20:34:19 +00:00
throw Exception("AST is too deep. Maximum: " + toString(max_depth), ErrorCodes::TOO_DEEP_AST);
return res + 1;
}
/** То же самое для общего количества элементов дерева.
*/
size_t checkSize(size_t max_size) const
{
size_t res = 1;
for (ASTs::const_iterator it = children.begin(); it != children.end(); ++it)
res += (*it)->checkSize(max_size);
if (res > max_size)
2013-06-21 20:34:19 +00:00
throw Exception("AST is too big. Maximum: " + toString(max_size), ErrorCodes::TOO_BIG_AST);
return res;
}
/** Получить set из имен индентификаторов
*/
virtual void collectIdentifierNames(IdentifierNameSet & set) const
{
for (ASTs::const_iterator it = children.begin(); it != children.end(); ++it)
(*it)->collectIdentifierNames(set);
}
2010-06-24 19:12:10 +00:00
};
2011-08-09 19:19:00 +00:00
typedef SharedPtr<IAST> ASTPtr;
2012-05-22 19:32:56 +00:00
typedef std::vector<ASTPtr> ASTs;
2010-06-24 19:12:10 +00:00
}