1#include "duckdb/main/prepared_statement.hpp"
2#include "duckdb/common/exception.hpp"
3#include "duckdb/main/client_context.hpp"
4#include "duckdb/main/prepared_statement_data.hpp"
5
6namespace duckdb {
7
8PreparedStatement::PreparedStatement(shared_ptr<ClientContext> context, shared_ptr<PreparedStatementData> data_p,
9 string query, idx_t n_param, case_insensitive_map_t<idx_t> named_param_pam_p)
10 : context(std::move(context)), data(std::move(data_p)), query(std::move(query)), success(true), n_param(n_param),
11 named_param_map(std::move(named_param_pam_p)) {
12 D_ASSERT(data || !success);
13}
14
15PreparedStatement::PreparedStatement(PreservedError error) : context(nullptr), success(false), error(std::move(error)) {
16}
17
18PreparedStatement::~PreparedStatement() {
19}
20
21const string &PreparedStatement::GetError() {
22 D_ASSERT(HasError());
23 return error.Message();
24}
25
26PreservedError &PreparedStatement::GetErrorObject() {
27 return error;
28}
29
30bool PreparedStatement::HasError() const {
31 return !success;
32}
33
34idx_t PreparedStatement::ColumnCount() {
35 D_ASSERT(data);
36 return data->types.size();
37}
38
39StatementType PreparedStatement::GetStatementType() {
40 D_ASSERT(data);
41 return data->statement_type;
42}
43
44StatementProperties PreparedStatement::GetStatementProperties() {
45 D_ASSERT(data);
46 return data->properties;
47}
48
49const vector<LogicalType> &PreparedStatement::GetTypes() {
50 D_ASSERT(data);
51 return data->types;
52}
53
54const vector<string> &PreparedStatement::GetNames() {
55 D_ASSERT(data);
56 return data->names;
57}
58
59vector<LogicalType> PreparedStatement::GetExpectedParameterTypes() const {
60 D_ASSERT(data);
61 vector<LogicalType> expected_types(data->value_map.size());
62 for (auto &it : data->value_map) {
63 D_ASSERT(it.first >= 1);
64 idx_t param_index = it.first - 1;
65 D_ASSERT(param_index < expected_types.size());
66 D_ASSERT(it.second);
67 expected_types[param_index] = it.second->value.type();
68 }
69 return expected_types;
70}
71
72unique_ptr<QueryResult> PreparedStatement::Execute(vector<Value> &values, bool allow_stream_result) {
73 auto pending = PendingQuery(values, allow_stream_result);
74 if (pending->HasError()) {
75 return make_uniq<MaterializedQueryResult>(args&: pending->GetErrorObject());
76 }
77 return pending->Execute();
78}
79
80unique_ptr<PendingQueryResult> PreparedStatement::PendingQuery(vector<Value> &values, bool allow_stream_result) {
81 if (!success) {
82 throw InvalidInputException("Attempting to execute an unsuccessfully prepared statement!");
83 }
84 D_ASSERT(data);
85 PendingQueryParameters parameters;
86 parameters.parameters = &values;
87 parameters.allow_stream_result = allow_stream_result && data->properties.allow_stream_result;
88 auto result = context->PendingQuery(query, prepared&: data, parameters);
89 return result;
90}
91
92} // namespace duckdb
93