2022-07-14 11:20:16 +00:00
|
|
|
#pragma once
|
|
|
|
|
2022-08-31 15:21:17 +00:00
|
|
|
#include <Core/NamesAndTypes.h>
|
|
|
|
#include <Core/Field.h>
|
|
|
|
|
2022-07-14 11:20:16 +00:00
|
|
|
#include <Analyzer/Identifier.h>
|
|
|
|
#include <Analyzer/IQueryTreeNode.h>
|
|
|
|
#include <Analyzer/ListNode.h>
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
|
|
|
/** Query node represents query in query tree.
|
|
|
|
*/
|
|
|
|
class QueryNode;
|
|
|
|
using QueryNodePtr = std::shared_ptr<QueryNode>;
|
|
|
|
|
|
|
|
class QueryNode final : public IQueryTreeNode
|
|
|
|
{
|
|
|
|
public:
|
2022-07-18 17:20:28 +00:00
|
|
|
explicit QueryNode();
|
|
|
|
|
|
|
|
bool isSubquery() const
|
|
|
|
{
|
|
|
|
return is_subquery;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setIsSubquery(bool is_subquery_value)
|
|
|
|
{
|
|
|
|
is_subquery = is_subquery_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isCTE() const
|
|
|
|
{
|
|
|
|
return is_cte;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setIsCTE(bool is_cte_value)
|
|
|
|
{
|
|
|
|
is_cte = is_cte_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::string & getCTEName() const
|
|
|
|
{
|
|
|
|
return cte_name;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setCTEName(std::string cte_name_value)
|
|
|
|
{
|
|
|
|
cte_name = std::move(cte_name_value);
|
|
|
|
}
|
2022-07-14 11:20:16 +00:00
|
|
|
|
2022-08-25 18:35:16 +00:00
|
|
|
void setIsDistinct(bool is_distinct_value)
|
|
|
|
{
|
|
|
|
is_distinct = is_distinct_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isDistinct() const
|
|
|
|
{
|
|
|
|
return is_distinct;
|
|
|
|
}
|
|
|
|
|
2022-08-26 16:23:26 +00:00
|
|
|
void setIsLimitWithTies(bool is_limit_with_ties_value)
|
|
|
|
{
|
|
|
|
is_limit_with_ties = is_limit_with_ties_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isLimitWithTies() const
|
|
|
|
{
|
|
|
|
return is_limit_with_ties;
|
|
|
|
}
|
|
|
|
|
2022-08-26 13:06:14 +00:00
|
|
|
bool hasWith() const
|
|
|
|
{
|
|
|
|
return !getWith().getNodes().empty();
|
|
|
|
}
|
|
|
|
|
2022-07-14 11:20:16 +00:00
|
|
|
const ListNode & getWith() const
|
|
|
|
{
|
|
|
|
return children[with_child_index]->as<const ListNode &>();
|
|
|
|
}
|
|
|
|
|
|
|
|
ListNode & getWith()
|
|
|
|
{
|
|
|
|
return children[with_child_index]->as<ListNode &>();
|
|
|
|
}
|
|
|
|
|
|
|
|
const QueryTreeNodePtr & getWithNode() const
|
|
|
|
{
|
|
|
|
return children[with_child_index];
|
|
|
|
}
|
|
|
|
|
|
|
|
QueryTreeNodePtr & getWithNode()
|
|
|
|
{
|
|
|
|
return children[with_child_index];
|
|
|
|
}
|
|
|
|
|
|
|
|
const ListNode & getProjection() const
|
|
|
|
{
|
|
|
|
return children[projection_child_index]->as<const ListNode &>();
|
|
|
|
}
|
|
|
|
|
|
|
|
ListNode & getProjection()
|
|
|
|
{
|
|
|
|
return children[projection_child_index]->as<ListNode &>();
|
|
|
|
}
|
|
|
|
|
|
|
|
const QueryTreeNodePtr & getProjectionNode() const
|
|
|
|
{
|
|
|
|
return children[projection_child_index];
|
|
|
|
}
|
|
|
|
|
|
|
|
QueryTreeNodePtr & getProjectionNode()
|
|
|
|
{
|
|
|
|
return children[projection_child_index];
|
|
|
|
}
|
|
|
|
|
2022-08-23 09:50:02 +00:00
|
|
|
const QueryTreeNodePtr & getJoinTree() const
|
2022-07-14 11:20:16 +00:00
|
|
|
{
|
2022-08-23 09:50:02 +00:00
|
|
|
return children[join_tree_child_index];
|
2022-07-14 11:20:16 +00:00
|
|
|
}
|
|
|
|
|
2022-08-23 09:50:02 +00:00
|
|
|
QueryTreeNodePtr & getJoinTree()
|
2022-07-14 11:20:16 +00:00
|
|
|
{
|
2022-08-23 09:50:02 +00:00
|
|
|
return children[join_tree_child_index];
|
2022-07-14 11:20:16 +00:00
|
|
|
}
|
|
|
|
|
2022-08-25 14:19:35 +00:00
|
|
|
bool hasPrewhere() const
|
|
|
|
{
|
|
|
|
return children[prewhere_child_index] != nullptr;
|
|
|
|
}
|
|
|
|
|
2022-07-14 11:20:16 +00:00
|
|
|
const QueryTreeNodePtr & getPrewhere() const
|
|
|
|
{
|
|
|
|
return children[prewhere_child_index];
|
|
|
|
}
|
|
|
|
|
|
|
|
QueryTreeNodePtr & getPrewhere()
|
|
|
|
{
|
|
|
|
return children[prewhere_child_index];
|
|
|
|
}
|
|
|
|
|
2022-08-15 16:34:10 +00:00
|
|
|
bool hasWhere() const
|
|
|
|
{
|
|
|
|
return children[where_child_index] != nullptr;
|
|
|
|
}
|
|
|
|
|
2022-07-14 11:20:16 +00:00
|
|
|
const QueryTreeNodePtr & getWhere() const
|
|
|
|
{
|
|
|
|
return children[where_child_index];
|
|
|
|
}
|
|
|
|
|
|
|
|
QueryTreeNodePtr & getWhere()
|
|
|
|
{
|
|
|
|
return children[where_child_index];
|
|
|
|
}
|
|
|
|
|
2022-08-25 14:19:35 +00:00
|
|
|
bool hasGroupBy() const
|
|
|
|
{
|
|
|
|
return !getGroupBy().getNodes().empty();
|
|
|
|
}
|
|
|
|
|
|
|
|
const ListNode & getGroupBy() const
|
|
|
|
{
|
|
|
|
return children[group_by_child_index]->as<ListNode &>();
|
|
|
|
}
|
|
|
|
|
|
|
|
ListNode & getGroupBy()
|
|
|
|
{
|
|
|
|
return children[group_by_child_index]->as<ListNode &>();
|
|
|
|
}
|
|
|
|
|
|
|
|
const QueryTreeNodePtr & getGroupByNode() const
|
|
|
|
{
|
|
|
|
return children[group_by_child_index];
|
|
|
|
}
|
|
|
|
|
|
|
|
QueryTreeNodePtr & getGroupByNode()
|
|
|
|
{
|
|
|
|
return children[group_by_child_index];
|
|
|
|
}
|
|
|
|
|
2022-09-02 10:30:12 +00:00
|
|
|
bool hasHaving() const
|
|
|
|
{
|
|
|
|
return getHaving() != nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
const QueryTreeNodePtr & getHaving() const
|
|
|
|
{
|
|
|
|
return children[having_child_index];
|
|
|
|
}
|
|
|
|
|
|
|
|
QueryTreeNodePtr & getHaving()
|
|
|
|
{
|
|
|
|
return children[having_child_index];
|
|
|
|
}
|
|
|
|
|
2022-08-26 13:06:14 +00:00
|
|
|
bool hasOrderBy() const
|
|
|
|
{
|
|
|
|
return !getOrderBy().getNodes().empty();
|
|
|
|
}
|
|
|
|
|
|
|
|
const ListNode & getOrderBy() const
|
|
|
|
{
|
|
|
|
return children[order_by_child_index]->as<const ListNode &>();
|
|
|
|
}
|
|
|
|
|
|
|
|
ListNode & getOrderBy()
|
|
|
|
{
|
|
|
|
return children[order_by_child_index]->as<ListNode &>();
|
|
|
|
}
|
|
|
|
|
|
|
|
const QueryTreeNodePtr & getOrderByNode() const
|
|
|
|
{
|
|
|
|
return children[order_by_child_index];
|
|
|
|
}
|
|
|
|
|
|
|
|
QueryTreeNodePtr & getOrderByNode()
|
|
|
|
{
|
|
|
|
return children[order_by_child_index];
|
|
|
|
}
|
|
|
|
|
2022-08-26 16:23:26 +00:00
|
|
|
bool hasLimit() const
|
|
|
|
{
|
|
|
|
return children[limit_child_index] != nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
const QueryTreeNodePtr & getLimit() const
|
|
|
|
{
|
|
|
|
return children[limit_child_index];
|
|
|
|
}
|
|
|
|
|
|
|
|
QueryTreeNodePtr & getLimit()
|
|
|
|
{
|
|
|
|
return children[limit_child_index];
|
|
|
|
}
|
|
|
|
|
|
|
|
bool hasOffset() const
|
|
|
|
{
|
|
|
|
return children[offset_child_index] != nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
const QueryTreeNodePtr & getOffset() const
|
|
|
|
{
|
|
|
|
return children[offset_child_index];
|
|
|
|
}
|
|
|
|
|
|
|
|
QueryTreeNodePtr & getOffset()
|
|
|
|
{
|
|
|
|
return children[offset_child_index];
|
|
|
|
}
|
|
|
|
|
2022-08-31 15:21:17 +00:00
|
|
|
const NamesAndTypes & getProjectionColumns() const
|
|
|
|
{
|
|
|
|
return projection_columns;
|
|
|
|
}
|
|
|
|
|
|
|
|
void resolveProjectionColumns(NamesAndTypes projection_columns_value)
|
|
|
|
{
|
|
|
|
projection_columns = std::move(projection_columns_value);
|
|
|
|
}
|
2022-08-15 16:34:10 +00:00
|
|
|
|
2022-07-14 11:20:16 +00:00
|
|
|
QueryTreeNodeType getNodeType() const override
|
|
|
|
{
|
|
|
|
return QueryTreeNodeType::QUERY;
|
|
|
|
}
|
|
|
|
|
2022-07-22 15:09:56 +00:00
|
|
|
String getName() const override;
|
|
|
|
|
2022-08-31 15:21:17 +00:00
|
|
|
DataTypePtr getResultType() const override
|
|
|
|
{
|
|
|
|
if (constant_value)
|
|
|
|
return constant_value->getType();
|
|
|
|
|
|
|
|
throw Exception(ErrorCodes::UNSUPPORTED_METHOD, "Method getResultType is not supported for non scalar query node");
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Perform constant folding for scalar subquery node
|
|
|
|
void performConstantFolding(ConstantValuePtr constant_folded_value)
|
|
|
|
{
|
|
|
|
constant_value = std::move(constant_folded_value);
|
|
|
|
}
|
|
|
|
|
|
|
|
ConstantValuePtr getConstantValueOrNull() const override
|
|
|
|
{
|
|
|
|
return constant_value;
|
|
|
|
}
|
|
|
|
|
2022-07-19 10:54:45 +00:00
|
|
|
void dumpTreeImpl(WriteBuffer & buffer, FormatState & format_state, size_t indent) const override;
|
2022-07-14 11:20:16 +00:00
|
|
|
|
2022-07-15 13:32:53 +00:00
|
|
|
bool isEqualImpl(const IQueryTreeNode & rhs) const override;
|
|
|
|
|
2022-07-14 11:20:16 +00:00
|
|
|
void updateTreeHashImpl(HashState &) const override;
|
|
|
|
|
2022-07-19 10:54:45 +00:00
|
|
|
protected:
|
2022-07-14 11:20:16 +00:00
|
|
|
ASTPtr toASTImpl() const override;
|
|
|
|
|
|
|
|
QueryTreeNodePtr cloneImpl() const override;
|
|
|
|
|
|
|
|
private:
|
2022-07-18 17:20:28 +00:00
|
|
|
bool is_subquery = false;
|
|
|
|
bool is_cte = false;
|
2022-08-25 18:35:16 +00:00
|
|
|
bool is_distinct = false;
|
2022-08-26 16:23:26 +00:00
|
|
|
bool is_limit_with_ties = false;
|
2022-07-18 17:20:28 +00:00
|
|
|
std::string cte_name;
|
2022-08-31 15:21:17 +00:00
|
|
|
NamesAndTypes projection_columns;
|
|
|
|
ConstantValuePtr constant_value;
|
2022-07-18 17:20:28 +00:00
|
|
|
|
2022-07-14 11:20:16 +00:00
|
|
|
static constexpr size_t with_child_index = 0;
|
|
|
|
static constexpr size_t projection_child_index = 1;
|
2022-08-23 09:50:02 +00:00
|
|
|
static constexpr size_t join_tree_child_index = 2;
|
2022-07-14 11:20:16 +00:00
|
|
|
static constexpr size_t prewhere_child_index = 3;
|
|
|
|
static constexpr size_t where_child_index = 4;
|
|
|
|
static constexpr size_t group_by_child_index = 5;
|
|
|
|
static constexpr size_t having_child_index = 6;
|
|
|
|
static constexpr size_t order_by_child_index = 7;
|
|
|
|
static constexpr size_t limit_child_index = 8;
|
2022-08-26 16:23:26 +00:00
|
|
|
static constexpr size_t offset_child_index = 9;
|
|
|
|
static constexpr size_t children_size = offset_child_index + 1;
|
2022-07-14 11:20:16 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|