ClickHouse/src/Analyzer/ColumnNode.h

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

158 lines
4.5 KiB
C++
Raw Normal View History

2022-07-14 11:20:16 +00:00
#pragma once
#include <Core/NamesAndTypes.h>
#include <Analyzer/IQueryTreeNode.h>
2023-02-01 13:33:32 +00:00
#include <DataTypes/DataTypeNullable.h>
2022-07-14 11:20:16 +00:00
namespace DB
{
2022-09-06 15:25:52 +00:00
namespace ErrorCodes
{
extern const int LOGICAL_ERROR;
}
2022-07-14 11:20:16 +00:00
/** Column node represents column in query tree.
2022-10-19 10:25:27 +00:00
* Column node can have weak pointer to its column source.
* Column source can be table expression, lambda, subquery.
2022-07-14 11:20:16 +00:00
*
2022-08-15 16:34:10 +00:00
* For table ALIAS columns. Column node must contain expression.
* For ARRAY JOIN join expression column. Column node must contain expression.
*
2022-07-14 11:20:16 +00:00
* During query analysis pass identifier node is resolved into column. See IdentifierNode.h.
*
* Examples:
* SELECT id FROM test_table. id is identifier that must be resolved to column node during query analysis pass.
* SELECT lambda(x -> x + 1, [1,2,3]). x is identifier inside lambda that must be resolved to column node during query analysis pass.
*
* Column node is initialized with column name, type and column source weak pointer.
2022-07-20 10:34:29 +00:00
* In case of ALIAS column node is initialized with column name, type, alias expression and column source weak pointer.
2022-07-14 11:20:16 +00:00
*/
class ColumnNode;
using ColumnNodePtr = std::shared_ptr<ColumnNode>;
class ColumnNode final : public IQueryTreeNode
{
public:
2022-10-19 10:25:27 +00:00
/// Construct column node with column name, type, column expression and column source weak pointer
2022-08-15 16:34:10 +00:00
ColumnNode(NameAndTypePair column_, QueryTreeNodePtr expression_node_, QueryTreeNodeWeakPtr column_source_);
2022-10-19 10:25:27 +00:00
/// Construct column node with column name, type and column source weak pointer
ColumnNode(NameAndTypePair column_, QueryTreeNodeWeakPtr column_source_);
2022-07-14 11:20:16 +00:00
/// Get column
const NameAndTypePair & getColumn() const
{
return column;
}
/// Get column name
const String & getColumnName() const
{
return column.name;
}
/// Get column type
const DataTypePtr & getColumnType() const
{
return column.type;
}
2022-08-20 14:01:50 +00:00
/// Set column type
void setColumnType(DataTypePtr column_type)
{
column.type = std::move(column_type);
}
2022-10-19 10:25:27 +00:00
/// Returns true if column node has expression, false otherwise
2022-08-15 16:34:10 +00:00
bool hasExpression() const
2022-07-20 10:34:29 +00:00
{
2022-08-15 16:34:10 +00:00
return children[expression_child_index] != nullptr;
2022-07-20 10:34:29 +00:00
}
2022-10-19 10:25:27 +00:00
/// Get column node expression node
2022-08-15 16:34:10 +00:00
const QueryTreeNodePtr & getExpression() const
2022-07-20 10:34:29 +00:00
{
2022-08-15 16:34:10 +00:00
return children[expression_child_index];
2022-07-20 10:34:29 +00:00
}
2022-10-19 10:25:27 +00:00
/// Get column node expression node
2022-08-15 16:34:10 +00:00
QueryTreeNodePtr & getExpression()
2022-07-20 10:34:29 +00:00
{
2022-08-15 16:34:10 +00:00
return children[expression_child_index];
2022-07-20 10:34:29 +00:00
}
2022-10-19 10:25:27 +00:00
/// Get column node expression node, if there are no expression node exception is thrown
2022-08-20 14:01:50 +00:00
QueryTreeNodePtr & getExpressionOrThrow()
{
if (!children[expression_child_index])
throw Exception(ErrorCodes::LOGICAL_ERROR, "Column expression is not initialized");
return children[expression_child_index];
}
2022-10-19 10:25:27 +00:00
/// Set column node expression node
2022-08-20 14:01:50 +00:00
void setExpression(QueryTreeNodePtr expression_value)
{
children[expression_child_index] = std::move(expression_value);
}
2022-07-14 11:20:16 +00:00
/** Get column source.
* If column source is not valid logical exception is thrown.
*/
QueryTreeNodePtr getColumnSource() const;
2022-09-03 12:11:09 +00:00
/** Get column source.
* If column source is not valid null is returned.
*/
QueryTreeNodePtr getColumnSourceOrNull() const;
2022-07-14 11:20:16 +00:00
QueryTreeNodeType getNodeType() const override
{
return QueryTreeNodeType::COLUMN;
}
DataTypePtr getResultType() const override
{
return column.type;
}
2023-02-01 13:33:32 +00:00
void convertToNullable() override
{
column.type = makeNullableSafe(column.type);
}
void dumpTreeImpl(WriteBuffer & buffer, FormatState & state, size_t indent) const override;
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 & hash_state) const override;
QueryTreeNodePtr cloneImpl() const override;
2023-03-14 09:14:58 +00:00
ASTPtr toASTImpl(const ConvertToASTOptions & options) const override;
2022-07-14 11:20:16 +00:00
private:
const QueryTreeNodeWeakPtr & getSourceWeakPointer() const
{
return weak_pointers[source_weak_pointer_index];
}
QueryTreeNodeWeakPtr & getSourceWeakPointer()
{
return weak_pointers[source_weak_pointer_index];
}
2022-07-14 11:20:16 +00:00
NameAndTypePair column;
2022-07-20 10:34:29 +00:00
2022-08-15 16:34:10 +00:00
static constexpr size_t expression_child_index = 0;
static constexpr size_t children_size = expression_child_index + 1;
static constexpr size_t source_weak_pointer_index = 0;
static constexpr size_t weak_pointers_size = source_weak_pointer_index + 1;
2022-07-14 11:20:16 +00:00
};
}