1 | //===----------------------------------------------------------------------===// |
2 | // DuckDB |
3 | // |
4 | // duckdb/planner/table_binding.hpp |
5 | // |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #pragma once |
10 | |
11 | #include "duckdb/common/common.hpp" |
12 | #include "duckdb/common/case_insensitive_map.hpp" |
13 | #include "duckdb/parser/column_definition.hpp" |
14 | #include "duckdb/parser/parsed_expression.hpp" |
15 | #include "duckdb/planner/expression_binder.hpp" |
16 | #include "duckdb/catalog/catalog_entry/table_column_type.hpp" |
17 | |
18 | namespace duckdb { |
19 | class BindContext; |
20 | class BoundQueryNode; |
21 | class ColumnRefExpression; |
22 | class SubqueryRef; |
23 | class LogicalGet; |
24 | class TableCatalogEntry; |
25 | class TableFunctionCatalogEntry; |
26 | class BoundTableFunction; |
27 | class StandardEntry; |
28 | struct ColumnBinding; |
29 | |
30 | enum class BindingType { BASE, TABLE, DUMMY, CATALOG_ENTRY }; |
31 | |
32 | //! A Binding represents a binding to a table, table-producing function or subquery with a specified table index. |
33 | struct Binding { |
34 | Binding(BindingType binding_type, const string &alias, vector<LogicalType> types, vector<string> names, |
35 | idx_t index); |
36 | virtual ~Binding() = default; |
37 | |
38 | //! The type of Binding |
39 | BindingType binding_type; |
40 | //! The alias of the binding |
41 | string alias; |
42 | //! The table index of the binding |
43 | idx_t index; |
44 | //! The types of the bound columns |
45 | vector<LogicalType> types; |
46 | //! Column names of the subquery |
47 | vector<string> names; |
48 | //! Name -> index for the names |
49 | case_insensitive_map_t<column_t> name_map; |
50 | |
51 | public: |
52 | bool TryGetBindingIndex(const string &column_name, column_t &column_index); |
53 | column_t GetBindingIndex(const string &column_name); |
54 | bool HasMatchingBinding(const string &column_name); |
55 | virtual string ColumnNotFoundError(const string &column_name) const; |
56 | virtual BindResult Bind(ColumnRefExpression &colref, idx_t depth); |
57 | virtual optional_ptr<StandardEntry> GetStandardEntry(); |
58 | |
59 | public: |
60 | template <class TARGET> |
61 | TARGET &Cast() { |
62 | if (binding_type != TARGET::TYPE) { |
63 | throw InternalException("Failed to cast binding to type - binding type mismatch" ); |
64 | } |
65 | return reinterpret_cast<TARGET &>(*this); |
66 | } |
67 | |
68 | template <class TARGET> |
69 | const TARGET &Cast() const { |
70 | if (binding_type != TARGET::TYPE) { |
71 | throw InternalException("Failed to cast binding to type - binding type mismatch" ); |
72 | } |
73 | return reinterpret_cast<const TARGET &>(*this); |
74 | } |
75 | }; |
76 | |
77 | struct EntryBinding : public Binding { |
78 | public: |
79 | static constexpr const BindingType TYPE = BindingType::CATALOG_ENTRY; |
80 | |
81 | public: |
82 | EntryBinding(const string &alias, vector<LogicalType> types, vector<string> names, idx_t index, |
83 | StandardEntry &entry); |
84 | StandardEntry &entry; |
85 | |
86 | public: |
87 | optional_ptr<StandardEntry> GetStandardEntry() override; |
88 | }; |
89 | |
90 | //! TableBinding is exactly like the Binding, except it keeps track of which columns were bound in the linked LogicalGet |
91 | //! node for projection pushdown purposes. |
92 | struct TableBinding : public Binding { |
93 | public: |
94 | static constexpr const BindingType TYPE = BindingType::TABLE; |
95 | |
96 | public: |
97 | TableBinding(const string &alias, vector<LogicalType> types, vector<string> names, |
98 | vector<column_t> &bound_column_ids, optional_ptr<StandardEntry> entry, idx_t index, |
99 | bool add_row_id = false); |
100 | |
101 | //! A reference to the set of bound column ids |
102 | vector<column_t> &bound_column_ids; |
103 | //! The underlying catalog entry (if any) |
104 | optional_ptr<StandardEntry> entry; |
105 | |
106 | public: |
107 | unique_ptr<ParsedExpression> ExpandGeneratedColumn(const string &column_name); |
108 | BindResult Bind(ColumnRefExpression &colref, idx_t depth) override; |
109 | optional_ptr<StandardEntry> GetStandardEntry() override; |
110 | string ColumnNotFoundError(const string &column_name) const override; |
111 | // These are columns that are present in the name_map, appearing in the order that they're bound |
112 | const vector<column_t> &GetBoundColumnIds() const; |
113 | |
114 | protected: |
115 | ColumnBinding GetColumnBinding(column_t column_index); |
116 | }; |
117 | |
118 | //! DummyBinding is like the Binding, except the alias and index are set by default. Used for binding lambdas and macro |
119 | //! parameters. |
120 | struct DummyBinding : public Binding { |
121 | public: |
122 | static constexpr const BindingType TYPE = BindingType::DUMMY; |
123 | // NOTE: changing this string conflicts with the storage version |
124 | static constexpr const char *DUMMY_NAME = "0_macro_parameters" ; |
125 | |
126 | public: |
127 | DummyBinding(vector<LogicalType> types_p, vector<string> names_p, string dummy_name_p); |
128 | |
129 | //! Arguments |
130 | vector<unique_ptr<ParsedExpression>> *arguments; |
131 | //! The name of the dummy binding |
132 | string dummy_name; |
133 | |
134 | public: |
135 | BindResult Bind(ColumnRefExpression &colref, idx_t depth) override; |
136 | BindResult Bind(ColumnRefExpression &colref, idx_t lambda_index, idx_t depth); |
137 | |
138 | //! Given the parameter colref, returns a copy of the argument that was supplied for this parameter |
139 | unique_ptr<ParsedExpression> ParamToArg(ColumnRefExpression &colref); |
140 | }; |
141 | |
142 | } // namespace duckdb |
143 | |