1//===----------------------------------------------------------------------===//
2// DuckDB
3//
4// duckdb/main/relation.hpp
5//
6//
7//===----------------------------------------------------------------------===//
8
9#pragma once
10
11#include "duckdb/common/common.hpp"
12#include "duckdb/common/enums/join_type.hpp"
13#include "duckdb/common/enums/relation_type.hpp"
14#include "duckdb/common/winapi.hpp"
15#include "duckdb/main/query_result.hpp"
16#include "duckdb/parser/column_definition.hpp"
17#include "duckdb/common/named_parameter_map.hpp"
18#include "duckdb/main/client_context.hpp"
19#include "duckdb/main/external_dependencies.hpp"
20#include "duckdb/parser/statement/explain_statement.hpp"
21
22#include <memory>
23
24namespace duckdb {
25struct BoundStatement;
26
27class ClientContextWrapper;
28class Binder;
29class LogicalOperator;
30class QueryNode;
31class TableRef;
32
33class Relation : public std::enable_shared_from_this<Relation> {
34public:
35 Relation(const std::shared_ptr<ClientContext> &context, RelationType type) : context(context), type(type) {
36 }
37 Relation(ClientContextWrapper &context, RelationType type) : context(context.GetContext()), type(type) {
38 }
39 virtual ~Relation() {
40 }
41
42 ClientContextWrapper context;
43
44 RelationType type;
45
46 shared_ptr<ExternalDependency> extra_dependencies;
47
48public:
49 DUCKDB_API virtual const vector<ColumnDefinition> &Columns() = 0;
50 DUCKDB_API virtual unique_ptr<QueryNode> GetQueryNode();
51 DUCKDB_API virtual BoundStatement Bind(Binder &binder);
52 DUCKDB_API virtual string GetAlias();
53
54 DUCKDB_API unique_ptr<QueryResult> ExecuteOrThrow();
55 DUCKDB_API unique_ptr<QueryResult> Execute();
56 DUCKDB_API string ToString();
57 DUCKDB_API virtual string ToString(idx_t depth) = 0;
58
59 DUCKDB_API void Print();
60 DUCKDB_API void Head(idx_t limit = 10);
61
62 DUCKDB_API shared_ptr<Relation> CreateView(const string &name, bool replace = true, bool temporary = false);
63 DUCKDB_API shared_ptr<Relation> CreateView(const string &schema_name, const string &name, bool replace = true,
64 bool temporary = false);
65 DUCKDB_API unique_ptr<QueryResult> Query(const string &sql);
66 DUCKDB_API unique_ptr<QueryResult> Query(const string &name, const string &sql);
67
68 //! Explain the query plan of this relation
69 DUCKDB_API unique_ptr<QueryResult> Explain(ExplainType type = ExplainType::EXPLAIN_STANDARD);
70
71 DUCKDB_API virtual unique_ptr<TableRef> GetTableRef();
72 virtual bool IsReadOnly() {
73 return true;
74 }
75
76public:
77 // PROJECT
78 DUCKDB_API shared_ptr<Relation> Project(const string &select_list);
79 DUCKDB_API shared_ptr<Relation> Project(const string &expression, const string &alias);
80 DUCKDB_API shared_ptr<Relation> Project(const string &select_list, const vector<string> &aliases);
81 DUCKDB_API shared_ptr<Relation> Project(const vector<string> &expressions);
82 DUCKDB_API shared_ptr<Relation> Project(const vector<string> &expressions, const vector<string> &aliases);
83
84 // FILTER
85 DUCKDB_API shared_ptr<Relation> Filter(const string &expression);
86 DUCKDB_API shared_ptr<Relation> Filter(const vector<string> &expressions);
87
88 // LIMIT
89 DUCKDB_API shared_ptr<Relation> Limit(int64_t n, int64_t offset = 0);
90
91 // ORDER
92 DUCKDB_API shared_ptr<Relation> Order(const string &expression);
93 DUCKDB_API shared_ptr<Relation> Order(const vector<string> &expressions);
94
95 // JOIN operation
96 DUCKDB_API shared_ptr<Relation> Join(const shared_ptr<Relation> &other, const string &condition,
97 JoinType type = JoinType::INNER);
98
99 // CROSS PRODUCT operation
100 DUCKDB_API shared_ptr<Relation> CrossProduct(const shared_ptr<Relation> &other);
101
102 // SET operations
103 DUCKDB_API shared_ptr<Relation> Union(const shared_ptr<Relation> &other);
104 DUCKDB_API shared_ptr<Relation> Except(const shared_ptr<Relation> &other);
105 DUCKDB_API shared_ptr<Relation> Intersect(const shared_ptr<Relation> &other);
106
107 // DISTINCT operation
108 DUCKDB_API shared_ptr<Relation> Distinct();
109
110 // AGGREGATES
111 DUCKDB_API shared_ptr<Relation> Aggregate(const string &aggregate_list);
112 DUCKDB_API shared_ptr<Relation> Aggregate(const vector<string> &aggregates);
113 DUCKDB_API shared_ptr<Relation> Aggregate(const string &aggregate_list, const string &group_list);
114 DUCKDB_API shared_ptr<Relation> Aggregate(const vector<string> &aggregates, const vector<string> &groups);
115
116 // ALIAS
117 DUCKDB_API shared_ptr<Relation> Alias(const string &alias);
118
119 //! Insert the data from this relation into a table
120 DUCKDB_API shared_ptr<Relation> InsertRel(const string &schema_name, const string &table_name);
121 DUCKDB_API void Insert(const string &table_name);
122 DUCKDB_API void Insert(const string &schema_name, const string &table_name);
123 //! Insert a row (i.e.,list of values) into a table
124 DUCKDB_API void Insert(const vector<vector<Value>> &values);
125 //! Create a table and insert the data from this relation into that table
126 DUCKDB_API shared_ptr<Relation> CreateRel(const string &schema_name, const string &table_name);
127 DUCKDB_API void Create(const string &table_name);
128 DUCKDB_API void Create(const string &schema_name, const string &table_name);
129
130 //! Write a relation to a CSV file
131 DUCKDB_API shared_ptr<Relation>
132 WriteCSVRel(const string &csv_file,
133 case_insensitive_map_t<vector<Value>> options = case_insensitive_map_t<vector<Value>>());
134 DUCKDB_API void WriteCSV(const string &csv_file,
135 case_insensitive_map_t<vector<Value>> options = case_insensitive_map_t<vector<Value>>());
136 //! Write a relation to a Parquet file
137 DUCKDB_API shared_ptr<Relation>
138 WriteParquetRel(const string &parquet_file,
139 case_insensitive_map_t<vector<Value>> options = case_insensitive_map_t<vector<Value>>());
140 DUCKDB_API void
141 WriteParquet(const string &parquet_file,
142 case_insensitive_map_t<vector<Value>> options = case_insensitive_map_t<vector<Value>>());
143
144 //! Update a table, can only be used on a TableRelation
145 DUCKDB_API virtual void Update(const string &update, const string &condition = string());
146 //! Delete from a table, can only be used on a TableRelation
147 DUCKDB_API virtual void Delete(const string &condition = string());
148 //! Create a relation from calling a table in/out function on the input relation
149 //! Create a relation from calling a table in/out function on the input relation
150 DUCKDB_API shared_ptr<Relation> TableFunction(const std::string &fname, const vector<Value> &values);
151 DUCKDB_API shared_ptr<Relation> TableFunction(const std::string &fname, const vector<Value> &values,
152 const named_parameter_map_t &named_parameters);
153
154public:
155 //! Whether or not the relation inherits column bindings from its child or not, only relevant for binding
156 virtual bool InheritsColumnBindings() {
157 return false;
158 }
159 virtual Relation *ChildRelation() {
160 return nullptr;
161 }
162 DUCKDB_API vector<shared_ptr<ExternalDependency>> GetAllDependencies();
163
164protected:
165 DUCKDB_API string RenderWhitespace(idx_t depth);
166
167public:
168 template <class TARGET>
169 TARGET &Cast() {
170 D_ASSERT(dynamic_cast<TARGET *>(this));
171 return reinterpret_cast<TARGET &>(*this);
172 }
173 template <class TARGET>
174 const TARGET &Cast() const {
175 D_ASSERT(dynamic_cast<const TARGET *>(this));
176 return reinterpret_cast<const TARGET &>(*this);
177 }
178};
179
180} // namespace duckdb
181