1//===----------------------------------------------------------------------===//
2// DuckDB
3//
4// duckdb/planner/logical_operator.hpp
5//
6//
7//===----------------------------------------------------------------------===//
8
9#pragma once
10
11#include "duckdb/catalog/catalog.hpp"
12#include "duckdb/common/common.hpp"
13#include "duckdb/common/enums/logical_operator_type.hpp"
14#include "duckdb/optimizer/join_order/estimated_properties.hpp"
15#include "duckdb/planner/column_binding.hpp"
16#include "duckdb/planner/expression.hpp"
17#include "duckdb/planner/logical_operator_visitor.hpp"
18#include "duckdb/planner/plan_serialization.hpp"
19
20#include <algorithm>
21#include <functional>
22
23namespace duckdb {
24
25class FieldWriter;
26class FieldReader;
27
28//! The current version of the plan serialization format. Exposed via by @Serializer & @Deserializer
29//! to be used by various Operator to know what format to read and write.
30extern const uint64_t PLAN_SERIALIZATION_VERSION;
31
32//! LogicalOperator is the base class of the logical operators present in the
33//! logical query tree
34class LogicalOperator {
35public:
36 explicit LogicalOperator(LogicalOperatorType type);
37 LogicalOperator(LogicalOperatorType type, vector<unique_ptr<Expression>> expressions);
38 virtual ~LogicalOperator();
39
40 //! The type of the logical operator
41 LogicalOperatorType type;
42 //! The set of children of the operator
43 vector<unique_ptr<LogicalOperator>> children;
44 //! The set of expressions contained within the operator, if any
45 vector<unique_ptr<Expression>> expressions;
46 //! The types returned by this logical operator. Set by calling LogicalOperator::ResolveTypes.
47 vector<LogicalType> types;
48 //! Estimated Cardinality
49 idx_t estimated_cardinality;
50 bool has_estimated_cardinality;
51
52 unique_ptr<EstimatedProperties> estimated_props;
53
54public:
55 virtual vector<ColumnBinding> GetColumnBindings();
56 static vector<ColumnBinding> GenerateColumnBindings(idx_t table_idx, idx_t column_count);
57 static vector<LogicalType> MapTypes(const vector<LogicalType> &types, const vector<idx_t> &projection_map);
58 static vector<ColumnBinding> MapBindings(const vector<ColumnBinding> &types, const vector<idx_t> &projection_map);
59
60 //! Resolve the types of the logical operator and its children
61 void ResolveOperatorTypes();
62
63 virtual string GetName() const;
64 virtual string ParamsToString() const;
65 virtual string ToString() const;
66 DUCKDB_API void Print();
67 //! Debug method: verify that the integrity of expressions & child nodes are maintained
68 virtual void Verify(ClientContext &context);
69
70 void AddChild(unique_ptr<LogicalOperator> child);
71 virtual idx_t EstimateCardinality(ClientContext &context);
72
73 //! Serializes a LogicalOperator to a stand-alone binary blob
74 void Serialize(Serializer &serializer) const;
75 //! Serializes an LogicalOperator to a stand-alone binary blob
76 virtual void Serialize(FieldWriter &writer) const = 0;
77
78 static unique_ptr<LogicalOperator> Deserialize(Deserializer &deserializer, PlanDeserializationState &state);
79
80 virtual unique_ptr<LogicalOperator> Copy(ClientContext &context) const;
81
82 virtual bool RequireOptimizer() const {
83 return true;
84 }
85
86 //! Allows LogicalOperators to opt out of serialization
87 virtual bool SupportSerialization() const {
88 return true;
89 };
90
91 //! Returns the set of table indexes of this operator
92 virtual vector<idx_t> GetTableIndex() const;
93
94protected:
95 //! Resolve types for this specific operator
96 virtual void ResolveTypes() = 0;
97
98public:
99 template <class TARGET>
100 TARGET &Cast() {
101 if (TARGET::TYPE != LogicalOperatorType::LOGICAL_INVALID && type != TARGET::TYPE) {
102 throw InternalException("Failed to cast logical operator to type - logical operator type mismatch");
103 }
104 return reinterpret_cast<TARGET &>(*this);
105 }
106
107 template <class TARGET>
108 const TARGET &Cast() const {
109 if (TARGET::TYPE != LogicalOperatorType::LOGICAL_INVALID && type != TARGET::TYPE) {
110 throw InternalException("Failed to cast logical operator to type - logical operator type mismatch");
111 }
112 return reinterpret_cast<const TARGET &>(*this);
113 }
114};
115} // namespace duckdb
116