1 | //===----------------------------------------------------------------------===// |
2 | // DuckDB |
3 | // |
4 | // duckdb/main/connection.hpp |
5 | // |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #pragma once |
10 | |
11 | #include "duckdb/common/enums/profiler_format.hpp" |
12 | #include "duckdb/common/serializer/buffered_file_writer.hpp" |
13 | #include "duckdb/common/winapi.hpp" |
14 | #include "duckdb/function/udf_function.hpp" |
15 | #include "duckdb/main/materialized_query_result.hpp" |
16 | #include "duckdb/main/pending_query_result.hpp" |
17 | #include "duckdb/main/prepared_statement.hpp" |
18 | #include "duckdb/main/query_result.hpp" |
19 | #include "duckdb/main/relation.hpp" |
20 | #include "duckdb/main/stream_query_result.hpp" |
21 | #include "duckdb/main/table_description.hpp" |
22 | #include "duckdb/parser/sql_statement.hpp" |
23 | |
24 | namespace duckdb { |
25 | |
26 | class ColumnDataCollection; |
27 | class ClientContext; |
28 | |
29 | class DatabaseInstance; |
30 | class DuckDB; |
31 | class LogicalOperator; |
32 | class SelectStatement; |
33 | struct BufferedCSVReaderOptions; |
34 | |
35 | typedef void (*warning_callback)(std::string); |
36 | |
37 | //! A connection to a database. This represents a (client) connection that can |
38 | //! be used to query the database. |
39 | class Connection { |
40 | public: |
41 | DUCKDB_API explicit Connection(DuckDB &database); |
42 | DUCKDB_API explicit Connection(DatabaseInstance &database); |
43 | DUCKDB_API ~Connection(); |
44 | |
45 | shared_ptr<ClientContext> context; |
46 | warning_callback warning_cb; |
47 | |
48 | public: |
49 | //! Returns query profiling information for the current query |
50 | DUCKDB_API string GetProfilingInformation(ProfilerPrintFormat format = ProfilerPrintFormat::QUERY_TREE); |
51 | |
52 | //! Interrupt execution of the current query |
53 | DUCKDB_API void Interrupt(); |
54 | |
55 | //! Enable query profiling |
56 | DUCKDB_API void EnableProfiling(); |
57 | //! Disable query profiling |
58 | DUCKDB_API void DisableProfiling(); |
59 | |
60 | DUCKDB_API void SetWarningCallback(warning_callback); |
61 | |
62 | //! Enable aggressive verification/testing of queries, should only be used in testing |
63 | DUCKDB_API void EnableQueryVerification(); |
64 | DUCKDB_API void DisableQueryVerification(); |
65 | //! Force parallel execution, even for smaller tables. Should only be used in testing. |
66 | DUCKDB_API void ForceParallelism(); |
67 | |
68 | //! Issues a query to the database and returns a QueryResult. This result can be either a StreamQueryResult or a |
69 | //! MaterializedQueryResult. The result can be stepped through with calls to Fetch(). Note that there can only be |
70 | //! one active StreamQueryResult per Connection object. Calling SendQuery() will invalidate any previously existing |
71 | //! StreamQueryResult. |
72 | DUCKDB_API unique_ptr<QueryResult> SendQuery(const string &query); |
73 | //! Issues a query to the database and materializes the result (if necessary). Always returns a |
74 | //! MaterializedQueryResult. |
75 | DUCKDB_API unique_ptr<MaterializedQueryResult> Query(const string &query); |
76 | //! Issues a query to the database and materializes the result (if necessary). Always returns a |
77 | //! MaterializedQueryResult. |
78 | DUCKDB_API unique_ptr<MaterializedQueryResult> Query(unique_ptr<SQLStatement> statement); |
79 | // prepared statements |
80 | template <typename... Args> |
81 | unique_ptr<QueryResult> Query(const string &query, Args... args) { |
82 | vector<Value> values; |
83 | return QueryParamsRecursive(query, values, args...); |
84 | } |
85 | |
86 | //! Issues a query to the database and returns a Pending Query Result. Note that "query" may only contain |
87 | //! a single statement. |
88 | DUCKDB_API unique_ptr<PendingQueryResult> PendingQuery(const string &query, bool allow_stream_result = false); |
89 | //! Issues a query to the database and returns a Pending Query Result |
90 | DUCKDB_API unique_ptr<PendingQueryResult> PendingQuery(unique_ptr<SQLStatement> statement, |
91 | bool allow_stream_result = false); |
92 | |
93 | //! Prepare the specified query, returning a prepared statement object |
94 | DUCKDB_API unique_ptr<PreparedStatement> Prepare(const string &query); |
95 | //! Prepare the specified statement, returning a prepared statement object |
96 | DUCKDB_API unique_ptr<PreparedStatement> Prepare(unique_ptr<SQLStatement> statement); |
97 | |
98 | //! Get the table info of a specific table (in the default schema), or nullptr if it cannot be found |
99 | DUCKDB_API unique_ptr<TableDescription> TableInfo(const string &table_name); |
100 | //! Get the table info of a specific table, or nullptr if it cannot be found |
101 | DUCKDB_API unique_ptr<TableDescription> TableInfo(const string &schema_name, const string &table_name); |
102 | |
103 | //! Extract a set of SQL statements from a specific query |
104 | DUCKDB_API vector<unique_ptr<SQLStatement>> (const string &query); |
105 | //! Extract the logical plan that corresponds to a query |
106 | DUCKDB_API unique_ptr<LogicalOperator> (const string &query); |
107 | |
108 | //! Appends a DataChunk to the specified table |
109 | DUCKDB_API void Append(TableDescription &description, DataChunk &chunk); |
110 | //! Appends a ColumnDataCollection to the specified table |
111 | DUCKDB_API void Append(TableDescription &description, ColumnDataCollection &collection); |
112 | |
113 | //! Returns a relation that produces a table from this connection |
114 | DUCKDB_API shared_ptr<Relation> Table(const string &tname); |
115 | DUCKDB_API shared_ptr<Relation> Table(const string &schema_name, const string &table_name); |
116 | //! Returns a relation that produces a view from this connection |
117 | DUCKDB_API shared_ptr<Relation> View(const string &tname); |
118 | DUCKDB_API shared_ptr<Relation> View(const string &schema_name, const string &table_name); |
119 | //! Returns a relation that calls a specified table function |
120 | DUCKDB_API shared_ptr<Relation> TableFunction(const string &tname); |
121 | DUCKDB_API shared_ptr<Relation> TableFunction(const string &tname, const vector<Value> &values, |
122 | const named_parameter_map_t &named_parameters); |
123 | DUCKDB_API shared_ptr<Relation> TableFunction(const string &tname, const vector<Value> &values); |
124 | //! Returns a relation that produces values |
125 | DUCKDB_API shared_ptr<Relation> Values(const vector<vector<Value>> &values); |
126 | DUCKDB_API shared_ptr<Relation> Values(const vector<vector<Value>> &values, const vector<string> &column_names, |
127 | const string &alias = "values" ); |
128 | DUCKDB_API shared_ptr<Relation> Values(const string &values); |
129 | DUCKDB_API shared_ptr<Relation> Values(const string &values, const vector<string> &column_names, |
130 | const string &alias = "values" ); |
131 | |
132 | //! Reads CSV file |
133 | DUCKDB_API shared_ptr<Relation> ReadCSV(const string &csv_file); |
134 | DUCKDB_API shared_ptr<Relation> ReadCSV(const string &csv_file, BufferedCSVReaderOptions &options); |
135 | DUCKDB_API shared_ptr<Relation> ReadCSV(const string &csv_file, const vector<string> &columns); |
136 | |
137 | //! Reads Parquet file |
138 | DUCKDB_API shared_ptr<Relation> ReadParquet(const string &parquet_file, bool binary_as_string); |
139 | //! Returns a relation from a query |
140 | DUCKDB_API shared_ptr<Relation> RelationFromQuery(const string &query, const string &alias = "queryrelation" , |
141 | const string &error = "Expected a single SELECT statement" ); |
142 | DUCKDB_API shared_ptr<Relation> RelationFromQuery(unique_ptr<SelectStatement> select_stmt, |
143 | const string &alias = "queryrelation" ); |
144 | |
145 | //! Returns a substrait BLOB from a valid query |
146 | DUCKDB_API string GetSubstrait(const string &query); |
147 | //! Returns a Query Result from a substrait blob |
148 | DUCKDB_API unique_ptr<QueryResult> FromSubstrait(const string &proto); |
149 | //! Returns a substrait BLOB from a valid query |
150 | DUCKDB_API string GetSubstraitJSON(const string &query); |
151 | //! Returns a Query Result from a substrait JSON |
152 | DUCKDB_API unique_ptr<QueryResult> FromSubstraitJSON(const string &json); |
153 | DUCKDB_API void BeginTransaction(); |
154 | DUCKDB_API void Commit(); |
155 | DUCKDB_API void Rollback(); |
156 | DUCKDB_API void SetAutoCommit(bool auto_commit); |
157 | DUCKDB_API bool IsAutoCommit(); |
158 | DUCKDB_API bool HasActiveTransaction(); |
159 | |
160 | //! Fetch a list of table names that are required for a given query |
161 | DUCKDB_API unordered_set<string> GetTableNames(const string &query); |
162 | |
163 | template <typename TR, typename... Args> |
164 | void CreateScalarFunction(const string &name, TR (*udf_func)(Args...)) { |
165 | scalar_function_t function = UDFWrapper::CreateScalarFunction<TR, Args...>(name, udf_func); |
166 | UDFWrapper::RegisterFunction<TR, Args...>(name, function, *context); |
167 | } |
168 | |
169 | template <typename TR, typename... Args> |
170 | void CreateScalarFunction(const string &name, vector<LogicalType> args, LogicalType ret_type, |
171 | TR (*udf_func)(Args...)) { |
172 | scalar_function_t function = |
173 | UDFWrapper::CreateScalarFunction<TR, Args...>(name, args, std::move(ret_type), udf_func); |
174 | UDFWrapper::RegisterFunction(name, args, ret_type, udf_function: function, context&: *context); |
175 | } |
176 | |
177 | template <typename TR, typename... Args> |
178 | void CreateVectorizedFunction(const string &name, scalar_function_t udf_func, |
179 | LogicalType varargs = LogicalType::INVALID) { |
180 | UDFWrapper::RegisterFunction<TR, Args...>(name, udf_func, *context, std::move(varargs)); |
181 | } |
182 | |
183 | void CreateVectorizedFunction(const string &name, vector<LogicalType> args, LogicalType ret_type, |
184 | scalar_function_t udf_func, LogicalType varargs = LogicalType::INVALID) { |
185 | UDFWrapper::RegisterFunction(name, args: std::move(args), ret_type: std::move(ret_type), udf_function: udf_func, context&: *context, |
186 | varargs: std::move(varargs)); |
187 | } |
188 | |
189 | //------------------------------------- Aggreate Functions ----------------------------------------// |
190 | template <typename UDF_OP, typename STATE, typename TR, typename TA> |
191 | void CreateAggregateFunction(const string &name) { |
192 | AggregateFunction function = UDFWrapper::CreateAggregateFunction<UDF_OP, STATE, TR, TA>(name); |
193 | UDFWrapper::RegisterAggrFunction(aggr_function: function, context&: *context); |
194 | } |
195 | |
196 | template <typename UDF_OP, typename STATE, typename TR, typename TA, typename TB> |
197 | void CreateAggregateFunction(const string &name) { |
198 | AggregateFunction function = UDFWrapper::CreateAggregateFunction<UDF_OP, STATE, TR, TA, TB>(name); |
199 | UDFWrapper::RegisterAggrFunction(aggr_function: function, context&: *context); |
200 | } |
201 | |
202 | template <typename UDF_OP, typename STATE, typename TR, typename TA> |
203 | void CreateAggregateFunction(const string &name, LogicalType ret_type, LogicalType input_typeA) { |
204 | AggregateFunction function = |
205 | UDFWrapper::CreateAggregateFunction<UDF_OP, STATE, TR, TA>(name, ret_type, input_typeA); |
206 | UDFWrapper::RegisterAggrFunction(aggr_function: function, context&: *context); |
207 | } |
208 | |
209 | template <typename UDF_OP, typename STATE, typename TR, typename TA, typename TB> |
210 | void CreateAggregateFunction(const string &name, LogicalType ret_type, LogicalType input_typeA, |
211 | LogicalType input_typeB) { |
212 | AggregateFunction function = |
213 | UDFWrapper::CreateAggregateFunction<UDF_OP, STATE, TR, TA, TB>(name, ret_type, input_typeA, input_typeB); |
214 | UDFWrapper::RegisterAggrFunction(aggr_function: function, context&: *context); |
215 | } |
216 | |
217 | void CreateAggregateFunction(const string &name, vector<LogicalType> arguments, LogicalType return_type, |
218 | aggregate_size_t state_size, aggregate_initialize_t initialize, |
219 | aggregate_update_t update, aggregate_combine_t combine, aggregate_finalize_t finalize, |
220 | aggregate_simple_update_t simple_update = nullptr, |
221 | bind_aggregate_function_t bind = nullptr, |
222 | aggregate_destructor_t destructor = nullptr) { |
223 | AggregateFunction function = |
224 | UDFWrapper::CreateAggregateFunction(name, arguments, return_type, state_size, initialize, update, combine, |
225 | finalize, simple_update, bind, destructor); |
226 | UDFWrapper::RegisterAggrFunction(aggr_function: function, context&: *context); |
227 | } |
228 | |
229 | private: |
230 | unique_ptr<QueryResult> QueryParamsRecursive(const string &query, vector<Value> &values); |
231 | |
232 | template <typename T, typename... Args> |
233 | unique_ptr<QueryResult> QueryParamsRecursive(const string &query, vector<Value> &values, T value, Args... args) { |
234 | values.push_back(Value::CreateValue<T>(value)); |
235 | return QueryParamsRecursive(query, values, args...); |
236 | } |
237 | }; |
238 | |
239 | } // namespace duckdb |
240 | |