ClickHouse/src/Analyzer/QueryNode.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

629 lines
16 KiB
C++
Raw Normal View History

2022-07-14 11:20:16 +00:00
#pragma once
2022-10-12 13:46:50 +00:00
#include <Common/SettingsChanges.h>
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>
#include <Analyzer/TableExpressionModifiers.h>
2022-07-14 11:20:16 +00:00
namespace DB
{
2022-09-06 15:25:52 +00:00
namespace ErrorCodes
{
extern const int UNSUPPORTED_METHOD;
}
2022-07-14 11:20:16 +00:00
/** Query node represents query in query tree.
2022-10-12 13:46:50 +00:00
*
* Example: SELECT * FROM test_table WHERE id == 0;
* Example: SELECT * FROM test_table_1 AS t1 INNER JOIN test_table_2 AS t2 ON t1.id = t2.id;
*
* Query node consists of following sections.
* 1. WITH section.
* 2. PROJECTION section.
* 3. JOIN TREE section.
* Example: SELECT * FROM test_table_1 AS t1 INNER JOIN test_table_2 AS t2 ON t1.id = t2.id;
* test_table_1 AS t1 INNER JOIN test_table_2 AS t2 ON t1.id = t2.id - JOIN TREE section.
* 4. PREWHERE section.
* 5. WHERE section.
* 6. GROUP BY section.
* 7. HAVING section.
* 8. WINDOW section.
* Example: SELECT * FROM test_table WINDOW window AS (PARTITION BY id);
* 9. ORDER BY section.
* 10. INTERPOLATE section.
* Example: SELECT * FROM test_table ORDER BY id WITH FILL INTERPOLATE (value AS value + 1);
* value AS value + 1 - INTERPOLATE section.
* 11. LIMIT BY limit section.
* 12. LIMIT BY offset section.
* 13. LIMIT BY section.
* Example: SELECT * FROM test_table LIMIT 1 AS a OFFSET 5 AS b BY id, value;
* 1 AS a - LIMIT BY limit section.
* 5 AS b - LIMIT BY offset section.
* id, value - LIMIT BY section.
* 14. LIMIT section.
* 15. OFFSET section.
*
* Query node contains settings changes that must be applied before query analysis or execution.
* Example: SELECT * FROM test_table SETTINGS prefer_column_name_to_alias = 1, join_use_nulls = 1;
*
* Query node can be used as CTE.
* Example: WITH cte_subquery AS (SELECT 1) SELECT * FROM cte_subquery;
*
* Query node can be used as scalar subquery.
* Example: SELECT (SELECT 1) AS scalar_subquery.
*
* During query analysis pass query node must be resolved with projection columns.
2022-07-14 11:20:16 +00:00
*/
class QueryNode;
using QueryNodePtr = std::shared_ptr<QueryNode>;
class QueryNode final : public IQueryTreeNode
{
public:
2022-07-18 17:20:28 +00:00
explicit QueryNode();
2022-10-12 13:46:50 +00:00
/// Returns true if query node is subquery, false otherwise
2022-07-18 17:20:28 +00:00
bool isSubquery() const
{
return is_subquery;
}
2022-10-12 13:46:50 +00:00
/// Set query node is subquery
2022-07-18 17:20:28 +00:00
void setIsSubquery(bool is_subquery_value)
{
is_subquery = is_subquery_value;
}
2022-10-12 13:46:50 +00:00
/// Returns true if query node is CTE, false otherwise
2022-07-18 17:20:28 +00:00
bool isCTE() const
{
return is_cte;
}
2022-10-12 13:46:50 +00:00
/// Set query node is CTE
2022-07-18 17:20:28 +00:00
void setIsCTE(bool is_cte_value)
{
is_cte = is_cte_value;
}
2022-10-12 13:46:50 +00:00
/// Get query node CTE name
2022-07-18 17:20:28 +00:00
const std::string & getCTEName() const
{
return cte_name;
}
2022-10-12 13:46:50 +00:00
/// Set query node CTE name
2022-07-18 17:20:28 +00:00
void setCTEName(std::string cte_name_value)
{
cte_name = std::move(cte_name_value);
}
2022-07-14 11:20:16 +00:00
2022-10-12 13:46:50 +00:00
/// Returns true if query node has DISTINCT, false otherwise
2022-08-25 18:35:16 +00:00
bool isDistinct() const
{
return is_distinct;
}
2022-10-12 13:46:50 +00:00
/// Set query node DISTINCT value
void setIsDistinct(bool is_distinct_value)
2022-08-26 16:23:26 +00:00
{
2022-10-12 13:46:50 +00:00
is_distinct = is_distinct_value;
2022-08-26 16:23:26 +00:00
}
2022-10-12 13:46:50 +00:00
/// Returns true if query node has LIMIT WITH TIES, false otherwise
2022-08-26 16:23:26 +00:00
bool isLimitWithTies() const
{
return is_limit_with_ties;
}
2022-10-12 13:46:50 +00:00
/// Set query node LIMIT WITH TIES value
void setIsLimitWithTies(bool is_limit_with_ties_value)
{
2022-10-12 13:46:50 +00:00
is_limit_with_ties = is_limit_with_ties_value;
}
2022-10-12 13:46:50 +00:00
/// Returns true, if query node has GROUP BY WITH TOTALS, false otherwise
bool isGroupByWithTotals() const
{
return is_group_by_with_totals;
}
2022-10-12 13:46:50 +00:00
/// Set query node GROUP BY WITH TOTALS value
void setIsGroupByWithTotals(bool is_group_by_with_totals_value)
{
2022-10-12 13:46:50 +00:00
is_group_by_with_totals = is_group_by_with_totals_value;
}
2022-10-12 13:46:50 +00:00
/// Returns true, if query node has GROUP BY with ROLLUP modifier, false otherwise
bool isGroupByWithRollup() const
{
return is_group_by_with_rollup;
}
2022-10-12 13:46:50 +00:00
/// Set query node GROUP BY with ROLLUP modifier value
void setIsGroupByWithRollup(bool is_group_by_with_rollup_value)
{
2022-10-12 13:46:50 +00:00
is_group_by_with_rollup = is_group_by_with_rollup_value;
}
2022-10-12 13:46:50 +00:00
/// Returns true, if query node has GROUP BY with CUBE modifier, false otherwise
bool isGroupByWithCube() const
{
return is_group_by_with_cube;
}
2022-10-12 13:46:50 +00:00
/// Set query node GROUP BY with CUBE modifier value
void setIsGroupByWithCube(bool is_group_by_with_cube_value)
{
2022-10-12 13:46:50 +00:00
is_group_by_with_cube = is_group_by_with_cube_value;
}
2022-10-12 13:46:50 +00:00
/// Returns true, if query node has GROUP BY with GROUPING SETS modifier, false otherwise
bool isGroupByWithGroupingSets() const
{
return is_group_by_with_grouping_sets;
}
2022-10-12 13:46:50 +00:00
/// Set query node GROUP BY with GROUPING SETS modifier value
void setIsGroupByWithGroupingSets(bool is_group_by_with_grouping_sets_value)
{
is_group_by_with_grouping_sets = is_group_by_with_grouping_sets_value;
}
/// Return true if query node has table expression modifiers, false otherwise
bool hasTableExpressionModifiers() const
{
return table_expression_modifiers.has_value();
}
/// Get table expression modifiers
std::optional<TableExpressionModifiers> getTableExpressionModifiers() const
{
return table_expression_modifiers;
}
/// Set table expression modifiers
void setTableExpressionModifiers(TableExpressionModifiers table_expression_modifiers_value)
{
table_expression_modifiers = std::move(table_expression_modifiers_value);
}
2022-10-12 13:46:50 +00:00
/// Returns true if query node WITH section is not empty
2022-08-26 13:06:14 +00:00
bool hasWith() const
{
return !getWith().getNodes().empty();
}
2022-10-12 13:46:50 +00:00
/// Get WITH section
2022-07-14 11:20:16 +00:00
const ListNode & getWith() const
{
return children[with_child_index]->as<const ListNode &>();
}
2022-10-12 13:46:50 +00:00
/// Get WITH section
2022-07-14 11:20:16 +00:00
ListNode & getWith()
{
return children[with_child_index]->as<ListNode &>();
}
2022-10-12 13:46:50 +00:00
/// Get WITH section node
2022-07-14 11:20:16 +00:00
const QueryTreeNodePtr & getWithNode() const
{
return children[with_child_index];
}
2022-10-12 13:46:50 +00:00
/// Get WITH section node
2022-07-14 11:20:16 +00:00
QueryTreeNodePtr & getWithNode()
{
return children[with_child_index];
}
2022-10-12 13:46:50 +00:00
/// Get PROJECTION section
2022-07-14 11:20:16 +00:00
const ListNode & getProjection() const
{
return children[projection_child_index]->as<const ListNode &>();
}
2022-10-12 13:46:50 +00:00
/// Get PROJECTION section
2022-07-14 11:20:16 +00:00
ListNode & getProjection()
{
return children[projection_child_index]->as<ListNode &>();
}
2022-10-12 13:46:50 +00:00
/// Get PROJECTION section node
2022-07-14 11:20:16 +00:00
const QueryTreeNodePtr & getProjectionNode() const
{
return children[projection_child_index];
}
2022-10-12 13:46:50 +00:00
/// Get PROJECTION section node
2022-07-14 11:20:16 +00:00
QueryTreeNodePtr & getProjectionNode()
{
return children[projection_child_index];
}
2022-10-12 13:46:50 +00:00
/// Get JOIN TREE section node
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-10-12 13:46:50 +00:00
/// Get JOIN TREE section node
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-10-12 13:46:50 +00:00
/// Returns true if query node PREWHERE section is not empty
2022-08-25 14:19:35 +00:00
bool hasPrewhere() const
{
return children[prewhere_child_index] != nullptr;
}
2022-10-12 13:46:50 +00:00
/// Get PREWHERE section node
2022-07-14 11:20:16 +00:00
const QueryTreeNodePtr & getPrewhere() const
{
return children[prewhere_child_index];
}
2022-10-12 13:46:50 +00:00
/// Get PREWHERE section node
2022-07-14 11:20:16 +00:00
QueryTreeNodePtr & getPrewhere()
{
return children[prewhere_child_index];
}
2022-10-12 13:46:50 +00:00
/// Returns true if query node WHERE section is not empty
2022-08-15 16:34:10 +00:00
bool hasWhere() const
{
return children[where_child_index] != nullptr;
}
2022-10-12 13:46:50 +00:00
/// Get WHERE section node
2022-07-14 11:20:16 +00:00
const QueryTreeNodePtr & getWhere() const
{
return children[where_child_index];
}
2022-10-12 13:46:50 +00:00
/// Get WHERE section node
2022-07-14 11:20:16 +00:00
QueryTreeNodePtr & getWhere()
{
return children[where_child_index];
}
2022-10-12 13:46:50 +00:00
/// Returns true if query node GROUP BY section is not empty
2022-08-25 14:19:35 +00:00
bool hasGroupBy() const
{
return !getGroupBy().getNodes().empty();
}
2022-10-12 13:46:50 +00:00
/// Get GROUP BY section
2022-08-25 14:19:35 +00:00
const ListNode & getGroupBy() const
{
return children[group_by_child_index]->as<ListNode &>();
}
2022-10-12 13:46:50 +00:00
/// Get GROUP BY section
2022-08-25 14:19:35 +00:00
ListNode & getGroupBy()
{
return children[group_by_child_index]->as<ListNode &>();
}
2022-10-12 13:46:50 +00:00
/// Get GROUP BY section node
2022-08-25 14:19:35 +00:00
const QueryTreeNodePtr & getGroupByNode() const
{
return children[group_by_child_index];
}
2022-10-12 13:46:50 +00:00
/// Get GROUP BY section node
2022-08-25 14:19:35 +00:00
QueryTreeNodePtr & getGroupByNode()
{
return children[group_by_child_index];
}
2022-10-12 13:46:50 +00:00
/// Returns true if query node HAVING section is not empty
2022-09-02 10:30:12 +00:00
bool hasHaving() const
{
return getHaving() != nullptr;
}
2022-10-12 13:46:50 +00:00
/// Get HAVING section node
2022-09-02 10:30:12 +00:00
const QueryTreeNodePtr & getHaving() const
{
return children[having_child_index];
}
2022-10-12 13:46:50 +00:00
/// Get HAVING section node
2022-09-02 10:30:12 +00:00
QueryTreeNodePtr & getHaving()
{
return children[having_child_index];
}
2022-10-12 13:46:50 +00:00
/// Returns true if query node WINDOW section is not empty
bool hasWindow() const
{
return !getWindow().getNodes().empty();
}
/// Get WINDOW section
const ListNode & getWindow() const
{
return children[window_child_index]->as<const ListNode &>();
}
/// Get WINDOW section
ListNode & getWindow()
{
return children[window_child_index]->as<ListNode &>();
}
/// Get WINDOW section node
const QueryTreeNodePtr & getWindowNode() const
{
return children[window_child_index];
}
/// Get WINDOW section node
QueryTreeNodePtr & getWindowNode()
{
return children[window_child_index];
}
/// Returns true if query node ORDER BY section is not empty
2022-08-26 13:06:14 +00:00
bool hasOrderBy() const
{
return !getOrderBy().getNodes().empty();
}
2022-10-12 13:46:50 +00:00
/// Get ORDER BY section
2022-08-26 13:06:14 +00:00
const ListNode & getOrderBy() const
{
return children[order_by_child_index]->as<const ListNode &>();
}
2022-10-12 13:46:50 +00:00
/// Get ORDER BY section
2022-08-26 13:06:14 +00:00
ListNode & getOrderBy()
{
return children[order_by_child_index]->as<ListNode &>();
}
2022-10-12 13:46:50 +00:00
/// Get ORDER BY section node
2022-08-26 13:06:14 +00:00
const QueryTreeNodePtr & getOrderByNode() const
{
return children[order_by_child_index];
}
2022-10-12 13:46:50 +00:00
/// Get ORDER BY section node
2022-08-26 13:06:14 +00:00
QueryTreeNodePtr & getOrderByNode()
{
return children[order_by_child_index];
}
2022-10-12 13:46:50 +00:00
/// Returns true if query node INTERPOLATE section is not empty
2022-09-03 16:20:09 +00:00
bool hasInterpolate() const
{
return getInterpolate() != nullptr;
}
2022-10-12 13:46:50 +00:00
/// Get INTERPOLATE section node
2022-09-03 16:20:09 +00:00
const QueryTreeNodePtr & getInterpolate() const
{
return children[interpolate_child_index];
}
2022-10-12 13:46:50 +00:00
/// Get INTERPOLATE section node
2022-09-03 16:20:09 +00:00
QueryTreeNodePtr & getInterpolate()
{
return children[interpolate_child_index];
}
2022-10-12 13:46:50 +00:00
/// Returns true if query node LIMIT BY LIMIT section is not empty
2022-09-03 17:21:17 +00:00
bool hasLimitByLimit() const
{
return children[limit_by_limit_child_index] != nullptr;
}
2022-10-12 13:46:50 +00:00
/// Get LIMIT BY LIMIT section node
2022-09-03 17:21:17 +00:00
const QueryTreeNodePtr & getLimitByLimit() const
{
return children[limit_by_limit_child_index];
}
2022-10-12 13:46:50 +00:00
/// Get LIMIT BY LIMIT section node
2022-09-03 17:21:17 +00:00
QueryTreeNodePtr & getLimitByLimit()
{
return children[limit_by_limit_child_index];
}
2022-10-12 13:46:50 +00:00
/// Returns true if query node LIMIT BY OFFSET section is not empty
2022-09-03 17:21:17 +00:00
bool hasLimitByOffset() const
{
return children[limit_by_offset_child_index] != nullptr;
}
2022-10-12 13:46:50 +00:00
/// Get LIMIT BY OFFSET section node
2022-09-03 17:21:17 +00:00
const QueryTreeNodePtr & getLimitByOffset() const
{
return children[limit_by_offset_child_index];
}
2022-10-12 13:46:50 +00:00
/// Get LIMIT BY OFFSET section node
2022-09-03 17:21:17 +00:00
QueryTreeNodePtr & getLimitByOffset()
{
return children[limit_by_offset_child_index];
}
2022-10-12 13:46:50 +00:00
/// Returns true if query node LIMIT BY section is not empty
2022-09-03 17:21:17 +00:00
bool hasLimitBy() const
{
return !getLimitBy().getNodes().empty();
}
2022-10-12 13:46:50 +00:00
/// Get LIMIT BY section
2022-09-03 17:21:17 +00:00
const ListNode & getLimitBy() const
{
return children[limit_by_child_index]->as<const ListNode &>();
}
2022-10-12 13:46:50 +00:00
/// Get LIMIT BY section
2022-09-03 17:21:17 +00:00
ListNode & getLimitBy()
{
return children[limit_by_child_index]->as<ListNode &>();
}
2022-10-12 13:46:50 +00:00
/// Get LIMIT BY section node
2022-09-03 17:21:17 +00:00
const QueryTreeNodePtr & getLimitByNode() const
{
return children[limit_by_child_index];
}
2022-10-12 13:46:50 +00:00
/// Get LIMIT BY section node
2022-09-03 17:21:17 +00:00
QueryTreeNodePtr & getLimitByNode()
{
return children[limit_by_child_index];
}
2022-10-12 13:46:50 +00:00
/// Returns true if query node LIMIT section is not empty
2022-08-26 16:23:26 +00:00
bool hasLimit() const
{
return children[limit_child_index] != nullptr;
}
2022-10-12 13:46:50 +00:00
/// Get LIMIT section node
2022-08-26 16:23:26 +00:00
const QueryTreeNodePtr & getLimit() const
{
return children[limit_child_index];
}
2022-10-12 13:46:50 +00:00
/// Get LIMIT section node
2022-08-26 16:23:26 +00:00
QueryTreeNodePtr & getLimit()
{
return children[limit_child_index];
}
2022-10-12 13:46:50 +00:00
/// Returns true if query node OFFSET section is not empty
2022-08-26 16:23:26 +00:00
bool hasOffset() const
{
return children[offset_child_index] != nullptr;
}
2022-10-12 13:46:50 +00:00
/// Get OFFSET section node
2022-08-26 16:23:26 +00:00
const QueryTreeNodePtr & getOffset() const
{
return children[offset_child_index];
}
2022-10-12 13:46:50 +00:00
/// Get OFFSET section node
2022-08-26 16:23:26 +00:00
QueryTreeNodePtr & getOffset()
{
return children[offset_child_index];
}
2022-10-12 13:46:50 +00:00
/// Returns true if query node has settings changes specified, false otherwise
bool hasSettingsChanges() const
{
return !settings_changes.empty();
}
/// Get query node settings changes
const SettingsChanges & getSettingsChanges() const
{
return settings_changes;
}
/// Set query node settings changes value
void setSettingsChanges(SettingsChanges settings_changes_value)
{
settings_changes = std::move(settings_changes_value);
}
/// Get query node projection columns
2022-08-31 15:21:17 +00:00
const NamesAndTypes & getProjectionColumns() const
{
return projection_columns;
}
2022-10-12 13:46:50 +00:00
/// Resolve query node projection columns
2022-08-31 15:21:17 +00:00
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;
}
void dumpTreeImpl(WriteBuffer & buffer, FormatState & format_state, size_t indent) const override;
2022-07-14 11:20:16 +00:00
protected:
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;
QueryTreeNodePtr cloneImpl() const override;
ASTPtr toASTImpl() const override;
2022-07-14 11:20:16 +00:00
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;
bool is_group_by_with_totals = false;
bool is_group_by_with_rollup = false;
bool is_group_by_with_cube = false;
bool is_group_by_with_grouping_sets = 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;
std::optional<TableExpressionModifiers> table_expression_modifiers;
2022-10-12 13:46:50 +00:00
SettingsChanges settings_changes;
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;
2022-09-12 14:14:40 +00:00
static constexpr size_t window_child_index = 7;
static constexpr size_t order_by_child_index = 8;
static constexpr size_t interpolate_child_index = 9;
static constexpr size_t limit_by_limit_child_index = 10;
static constexpr size_t limit_by_offset_child_index = 11;
static constexpr size_t limit_by_child_index = 12;
static constexpr size_t limit_child_index = 13;
static constexpr size_t offset_child_index = 14;
2022-08-26 16:23:26 +00:00
static constexpr size_t children_size = offset_child_index + 1;
2022-07-14 11:20:16 +00:00
};
}