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
18namespace duckdb {
19class BindContext;
20class BoundQueryNode;
21class ColumnRefExpression;
22class SubqueryRef;
23class LogicalGet;
24class TableCatalogEntry;
25class TableFunctionCatalogEntry;
26class BoundTableFunction;
27class StandardEntry;
28struct ColumnBinding;
29
30enum 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.
33struct 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
51public:
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
59public:
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
77struct EntryBinding : public Binding {
78public:
79 static constexpr const BindingType TYPE = BindingType::CATALOG_ENTRY;
80
81public:
82 EntryBinding(const string &alias, vector<LogicalType> types, vector<string> names, idx_t index,
83 StandardEntry &entry);
84 StandardEntry &entry;
85
86public:
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.
92struct TableBinding : public Binding {
93public:
94 static constexpr const BindingType TYPE = BindingType::TABLE;
95
96public:
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
106public:
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
114protected:
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.
120struct DummyBinding : public Binding {
121public:
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
126public:
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
134public:
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