ClickHouse/src/Analyzer/JoinNode.h

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

166 lines
4.7 KiB
C++
Raw Normal View History

2022-08-15 16:34:10 +00:00
#pragma once
#include <Core/Joins.h>
#include <Storages/IStorage_fwd.h>
#include <Storages/TableLockHolder.h>
#include <Storages/StorageSnapshot.h>
#include <Interpreters/Context_fwd.h>
#include <Interpreters/StorageID.h>
#include <Analyzer/IQueryTreeNode.h>
namespace DB
{
2022-10-07 10:44:28 +00:00
/** Join node represents join in query tree.
*
* For JOIN without join expression, JOIN expression is null.
* Example: SELECT id FROM test_table_1 AS t1, test_table_2 AS t2;
*
* For JOIN with USING, JOIN expression contains list of identifier nodes. These nodes must be resolved
* during query analysis pass.
* Example: SELECT id FROM test_table_1 AS t1 INNER JOIN test_table_2 AS t2 USING (id);
*
* For JOIN with ON, JOIN expression contains single expression.
2022-10-19 10:25:27 +00:00
* Example: SELECT id FROM test_table_1 AS t1 INNER JOIN test_table_2 AS t2 ON t1.id = t2.id;
2022-08-15 16:34:10 +00:00
*/
class JoinNode;
using JoinNodePtr = std::shared_ptr<JoinNode>;
class JoinNode final : public IQueryTreeNode
{
public:
/** Construct join node with left table expression, right table expression and join expression.
* Example: SELECT id FROM test_table_1 INNER JOIN test_table_2 ON expression.
*
* test_table_1 - left table expression.
* test_table_2 - right table expression.
2022-10-19 10:25:27 +00:00
* expression - join expression.
2022-08-15 16:34:10 +00:00
*/
JoinNode(QueryTreeNodePtr left_table_expression_,
QueryTreeNodePtr right_table_expression_,
QueryTreeNodePtr join_expression_,
JoinLocality locality_,
JoinStrictness strictness_,
JoinKind kind_);
/// Get left table expression
const QueryTreeNodePtr & getLeftTableExpression() const
{
return children[left_table_expression_child_index];
}
/// Get left table expression
QueryTreeNodePtr & getLeftTableExpression()
{
return children[left_table_expression_child_index];
}
/// Get right table expression
const QueryTreeNodePtr & getRightTableExpression() const
{
return children[right_table_expression_child_index];
}
/// Get right table expression
QueryTreeNodePtr & getRightTableExpression()
{
return children[right_table_expression_child_index];
}
2022-10-19 10:25:27 +00:00
/// Returns true if join has join expression, false otherwise
bool hasJoinExpression() const
{
return children[join_expression_child_index] != nullptr;
}
2022-08-15 16:34:10 +00:00
/// Get join expression
const QueryTreeNodePtr & getJoinExpression() const
{
return children[join_expression_child_index];
}
/// Get join expression
QueryTreeNodePtr & getJoinExpression()
{
return children[join_expression_child_index];
}
2022-10-19 10:25:27 +00:00
/// Returns true if join has USING join expression, false otherwise
2022-08-15 16:34:10 +00:00
bool isUsingJoinExpression() const
{
2022-10-19 10:25:27 +00:00
return hasJoinExpression() && getJoinExpression()->getNodeType() == QueryTreeNodeType::LIST;
2022-08-15 16:34:10 +00:00
}
2022-10-19 10:25:27 +00:00
/// Returns true if join has ON join expression, false otherwise
2022-08-15 16:34:10 +00:00
bool isOnJoinExpression() const
{
2022-10-19 10:25:27 +00:00
return hasJoinExpression() && getJoinExpression()->getNodeType() != QueryTreeNodeType::LIST;
2022-08-15 16:34:10 +00:00
}
2022-10-19 10:25:27 +00:00
/// Get join locality
2022-08-15 16:34:10 +00:00
JoinLocality getLocality() const
{
return locality;
}
/// Set join locality
void setLocality(JoinLocality locality_value)
{
locality = locality_value;
}
2022-10-19 10:25:27 +00:00
/// Get join strictness
2022-08-15 16:34:10 +00:00
JoinStrictness getStrictness() const
{
return strictness;
}
2022-10-19 10:25:27 +00:00
/// Get join kind
2022-08-15 16:34:10 +00:00
JoinKind getKind() const
{
return kind;
}
2022-10-19 10:25:27 +00:00
/// Convert join node to ASTTableJoin
2022-08-15 16:34:10 +00:00
ASTPtr toASTTableJoin() const;
QueryTreeNodeType getNodeType() const override
{
return QueryTreeNodeType::JOIN;
}
2023-02-20 11:49:57 +00:00
/*
* Convert CROSS to INNER JOIN - changes JOIN kind and sets a new join expression
* (that was moved from WHERE clause).
* Expects the current kind to be CROSS (and join expression to be null because of that).
*/
2023-02-13 17:41:39 +00:00
void crossToInner(const QueryTreeNodePtr & join_expression_);
2022-08-15 16:34:10 +00:00
void dumpTreeImpl(WriteBuffer & buffer, FormatState & format_state, size_t indent) const override;
protected:
2022-08-15 16:34:10 +00:00
bool isEqualImpl(const IQueryTreeNode & rhs) const override;
void updateTreeHashImpl(HashState & state) const override;
QueryTreeNodePtr cloneImpl() const override;
2023-03-14 09:14:58 +00:00
ASTPtr toASTImpl(const ConvertToASTOptions & options) const override;
2022-08-15 16:34:10 +00:00
private:
JoinLocality locality = JoinLocality::Unspecified;
JoinStrictness strictness = JoinStrictness::Unspecified;
JoinKind kind = JoinKind::Inner;
static constexpr size_t left_table_expression_child_index = 0;
static constexpr size_t right_table_expression_child_index = 1;
static constexpr size_t join_expression_child_index = 2;
static constexpr size_t children_size = join_expression_child_index + 1;
};
}