duckdb 0.8.2-dev2399.0 → 0.8.2-dev2669.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/binding.gyp +1 -0
- package/package.json +1 -1
- package/src/duckdb/extension/icu/icu-datepart.cpp +3 -3
- package/src/duckdb/src/catalog/catalog_entry/duck_table_entry.cpp +1 -1
- package/src/duckdb/src/catalog/default/default_functions.cpp +5 -0
- package/src/duckdb/src/common/enum_util.cpp +35 -1
- package/src/duckdb/src/common/http_state.cpp +78 -0
- package/src/duckdb/src/core_functions/function_list.cpp +2 -2
- package/src/duckdb/src/core_functions/scalar/list/array_slice.cpp +314 -82
- package/src/duckdb/src/execution/expression_executor/execute_parameter.cpp +2 -2
- package/src/duckdb/src/execution/index/art/art.cpp +43 -31
- package/src/duckdb/src/execution/index/art/leaf.cpp +47 -33
- package/src/duckdb/src/execution/index/art/node.cpp +31 -24
- package/src/duckdb/src/execution/index/art/prefix.cpp +100 -16
- package/src/duckdb/src/execution/operator/schema/physical_create_index.cpp +54 -31
- package/src/duckdb/src/execution/physical_plan/plan_create_index.cpp +32 -15
- package/src/duckdb/src/function/table/arrow/arrow_duck_schema.cpp +57 -0
- package/src/duckdb/src/function/table/arrow.cpp +95 -92
- package/src/duckdb/src/function/table/arrow_conversion.cpp +45 -68
- package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
- package/src/duckdb/src/include/duckdb/common/case_insensitive_map.hpp +1 -0
- package/src/duckdb/src/include/duckdb/common/enum_util.hpp +8 -0
- package/src/duckdb/src/include/duckdb/common/helper.hpp +8 -3
- package/src/duckdb/src/include/duckdb/common/http_state.hpp +61 -28
- package/src/duckdb/src/include/duckdb/common/types/value.hpp +4 -1
- package/src/duckdb/src/include/duckdb/core_functions/scalar/list_functions.hpp +4 -4
- package/src/duckdb/src/include/duckdb/execution/index/art/art.hpp +7 -5
- package/src/duckdb/src/include/duckdb/execution/index/art/leaf.hpp +6 -6
- package/src/duckdb/src/include/duckdb/execution/index/art/node.hpp +6 -0
- package/src/duckdb/src/include/duckdb/execution/index/art/prefix.hpp +9 -11
- package/src/duckdb/src/include/duckdb/execution/operator/schema/physical_create_index.hpp +8 -1
- package/src/duckdb/src/include/duckdb/function/table/arrow/arrow_duck_schema.hpp +99 -0
- package/src/duckdb/src/include/duckdb/function/table/arrow.hpp +6 -36
- package/src/duckdb/src/include/duckdb/main/capi/capi_internal.hpp +3 -1
- package/src/duckdb/src/include/duckdb/main/client_context.hpp +15 -14
- package/src/duckdb/src/include/duckdb/main/prepared_statement.hpp +73 -5
- package/src/duckdb/src/include/duckdb/main/prepared_statement_data.hpp +6 -6
- package/src/duckdb/src/include/duckdb/parser/expression/operator_expression.hpp +20 -3
- package/src/duckdb/src/include/duckdb/parser/expression/parameter_expression.hpp +17 -1
- package/src/duckdb/src/include/duckdb/parser/statement/execute_statement.hpp +1 -1
- package/src/duckdb/src/include/duckdb/parser/transformer.hpp +5 -3
- package/src/duckdb/src/include/duckdb/planner/bound_parameter_map.hpp +2 -1
- package/src/duckdb/src/include/duckdb/planner/expression/bound_parameter_data.hpp +20 -5
- package/src/duckdb/src/include/duckdb/planner/expression/bound_parameter_expression.hpp +3 -3
- package/src/duckdb/src/include/duckdb/planner/planner.hpp +4 -3
- package/src/duckdb/src/include/duckdb/storage/object_cache.hpp +1 -1
- package/src/duckdb/src/include/duckdb/verification/prepared_statement_verifier.hpp +1 -1
- package/src/duckdb/src/include/duckdb.h +16 -0
- package/src/duckdb/src/main/capi/pending-c.cpp +6 -0
- package/src/duckdb/src/main/capi/prepared-c.cpp +52 -4
- package/src/duckdb/src/main/client_context.cpp +27 -17
- package/src/duckdb/src/main/client_verify.cpp +17 -0
- package/src/duckdb/src/main/extension/extension_helper.cpp +2 -1
- package/src/duckdb/src/main/prepared_statement.cpp +38 -11
- package/src/duckdb/src/main/prepared_statement_data.cpp +23 -18
- package/src/duckdb/src/parser/expression/parameter_expression.cpp +7 -7
- package/src/duckdb/src/parser/statement/execute_statement.cpp +2 -2
- package/src/duckdb/src/parser/transform/expression/transform_array_access.cpp +13 -4
- package/src/duckdb/src/parser/transform/expression/transform_param_ref.cpp +45 -26
- package/src/duckdb/src/parser/transform/statement/transform_prepare.cpp +28 -6
- package/src/duckdb/src/parser/transformer.cpp +27 -9
- package/src/duckdb/src/planner/binder/expression/bind_parameter_expression.cpp +10 -10
- package/src/duckdb/src/planner/binder/statement/bind_execute.cpp +13 -7
- package/src/duckdb/src/planner/expression/bound_parameter_expression.cpp +13 -13
- package/src/duckdb/src/planner/planner.cpp +7 -6
- package/src/duckdb/src/storage/checkpoint_manager.cpp +1 -1
- package/src/duckdb/src/storage/serialization/serialize_expression.cpp +3 -3
- package/src/duckdb/src/storage/serialization/serialize_parsed_expression.cpp +2 -2
- package/src/duckdb/src/verification/prepared_statement_verifier.cpp +16 -11
- package/src/duckdb/third_party/libpg_query/include/nodes/parsenodes.hpp +1 -0
- package/src/duckdb/third_party/libpg_query/src_backend_parser_gram.cpp +12855 -12282
- package/src/duckdb/ub_src_common.cpp +2 -0
- package/src/duckdb/ub_src_function_table_arrow.cpp +2 -0
@@ -63,7 +63,7 @@ public:
|
|
63
63
|
//! Returns the result names of the prepared statement
|
64
64
|
DUCKDB_API const vector<string> &GetNames();
|
65
65
|
//! Returns the map of parameter index to the expected type of parameter
|
66
|
-
DUCKDB_API
|
66
|
+
DUCKDB_API case_insensitive_map_t<LogicalType> GetExpectedParameterTypes() const;
|
67
67
|
|
68
68
|
//! Create a pending query result of the prepared statement with the given set of arguments
|
69
69
|
template <typename... Args>
|
@@ -72,6 +72,20 @@ public:
|
|
72
72
|
return PendingQueryRecursive(values, args...);
|
73
73
|
}
|
74
74
|
|
75
|
+
//! Create a pending query result of the prepared statement with the given set of arguments
|
76
|
+
DUCKDB_API unique_ptr<PendingQueryResult> PendingQuery(vector<Value> &values, bool allow_stream_result = true);
|
77
|
+
|
78
|
+
//! Create a pending query result of the prepared statement with the given set named arguments
|
79
|
+
DUCKDB_API unique_ptr<PendingQueryResult> PendingQuery(case_insensitive_map_t<Value> &named_values,
|
80
|
+
bool allow_stream_result = true);
|
81
|
+
|
82
|
+
//! Execute the prepared statement with the given set of values
|
83
|
+
DUCKDB_API unique_ptr<QueryResult> Execute(vector<Value> &values, bool allow_stream_result = true);
|
84
|
+
|
85
|
+
//! Execute the prepared statement with the given set of named+unnamed values
|
86
|
+
DUCKDB_API unique_ptr<QueryResult> Execute(case_insensitive_map_t<Value> &named_values,
|
87
|
+
bool allow_stream_result = true);
|
88
|
+
|
75
89
|
//! Execute the prepared statement with the given set of arguments
|
76
90
|
template <typename... Args>
|
77
91
|
unique_ptr<QueryResult> Execute(Args... args) {
|
@@ -79,11 +93,65 @@ public:
|
|
79
93
|
return ExecuteRecursive(values, args...);
|
80
94
|
}
|
81
95
|
|
82
|
-
|
83
|
-
|
96
|
+
template <class PAYLOAD>
|
97
|
+
static string ExcessValuesException(const case_insensitive_map_t<idx_t> ¶meters,
|
98
|
+
case_insensitive_map_t<PAYLOAD> &values) {
|
99
|
+
// Too many values
|
100
|
+
set<string> excess_set;
|
101
|
+
for (auto &pair : values) {
|
102
|
+
auto &name = pair.first;
|
103
|
+
if (!parameters.count(name)) {
|
104
|
+
excess_set.insert(name);
|
105
|
+
}
|
106
|
+
}
|
107
|
+
vector<string> excess_values;
|
108
|
+
for (auto &val : excess_set) {
|
109
|
+
excess_values.push_back(val);
|
110
|
+
}
|
111
|
+
return StringUtil::Format("Parameter argument/count mismatch, identifiers of the excess parameters: %s",
|
112
|
+
StringUtil::Join(excess_values, ", "));
|
113
|
+
}
|
84
114
|
|
85
|
-
|
86
|
-
|
115
|
+
template <class PAYLOAD>
|
116
|
+
static string MissingValuesException(const case_insensitive_map_t<idx_t> ¶meters,
|
117
|
+
case_insensitive_map_t<PAYLOAD> &values) {
|
118
|
+
// Missing values
|
119
|
+
set<string> missing_set;
|
120
|
+
for (auto &pair : parameters) {
|
121
|
+
auto &name = pair.first;
|
122
|
+
if (!values.count(name)) {
|
123
|
+
missing_set.insert(name);
|
124
|
+
}
|
125
|
+
}
|
126
|
+
vector<string> missing_values;
|
127
|
+
for (auto &val : missing_set) {
|
128
|
+
missing_values.push_back(val);
|
129
|
+
}
|
130
|
+
return StringUtil::Format("Values were not provided for the following prepared statement parameters: %s",
|
131
|
+
StringUtil::Join(missing_values, ", "));
|
132
|
+
}
|
133
|
+
|
134
|
+
template <class PAYLOAD>
|
135
|
+
static void VerifyParameters(case_insensitive_map_t<PAYLOAD> &provided,
|
136
|
+
const case_insensitive_map_t<idx_t> &expected) {
|
137
|
+
if (expected.size() == provided.size()) {
|
138
|
+
// Same amount of identifiers, if
|
139
|
+
for (auto &pair : expected) {
|
140
|
+
auto &identifier = pair.first;
|
141
|
+
if (!provided.count(identifier)) {
|
142
|
+
throw InvalidInputException(MissingValuesException(expected, provided));
|
143
|
+
}
|
144
|
+
}
|
145
|
+
return;
|
146
|
+
}
|
147
|
+
// Mismatch in expected and provided parameters/values
|
148
|
+
if (expected.size() > provided.size()) {
|
149
|
+
throw InvalidInputException(MissingValuesException(expected, provided));
|
150
|
+
} else {
|
151
|
+
D_ASSERT(provided.size() > expected.size());
|
152
|
+
throw InvalidInputException(ExcessValuesException(expected, provided));
|
153
|
+
}
|
154
|
+
}
|
87
155
|
|
88
156
|
private:
|
89
157
|
unique_ptr<PendingQueryResult> PendingQueryRecursive(vector<Value> &values) {
|
@@ -31,8 +31,6 @@ public:
|
|
31
31
|
unique_ptr<SQLStatement> unbound_statement;
|
32
32
|
//! The fully prepared physical plan of the prepared statement
|
33
33
|
unique_ptr<PhysicalOperator> plan;
|
34
|
-
//! The map of parameter index to the actual value entry
|
35
|
-
bound_parameter_map_t value_map;
|
36
34
|
|
37
35
|
//! The result names of the transaction
|
38
36
|
vector<string> names;
|
@@ -45,17 +43,19 @@ public:
|
|
45
43
|
//! The catalog version of when the prepared statement was bound
|
46
44
|
//! If this version is lower than the current catalog version, we have to rebind the prepared statement
|
47
45
|
idx_t catalog_version;
|
46
|
+
//! The map of parameter index to the actual value entry
|
47
|
+
bound_parameter_map_t value_map;
|
48
48
|
|
49
49
|
public:
|
50
50
|
void CheckParameterCount(idx_t parameter_count);
|
51
51
|
//! Whether or not the prepared statement data requires the query to rebound for the given parameters
|
52
|
-
bool RequireRebind(ClientContext &context,
|
52
|
+
bool RequireRebind(ClientContext &context, optional_ptr<case_insensitive_map_t<Value>> values);
|
53
53
|
//! Bind a set of values to the prepared statement data
|
54
|
-
DUCKDB_API void Bind(
|
54
|
+
DUCKDB_API void Bind(case_insensitive_map_t<Value> values);
|
55
55
|
//! Get the expected SQL Type of the bound parameter
|
56
|
-
DUCKDB_API LogicalType GetType(
|
56
|
+
DUCKDB_API LogicalType GetType(const string &identifier);
|
57
57
|
//! Try to get the expected SQL Type of the bound parameter
|
58
|
-
DUCKDB_API bool TryGetType(
|
58
|
+
DUCKDB_API bool TryGetType(const string &identifier, LogicalType &result);
|
59
59
|
};
|
60
60
|
|
61
61
|
} // namespace duckdb
|
@@ -12,6 +12,7 @@
|
|
12
12
|
#include "duckdb/common/vector.hpp"
|
13
13
|
#include "duckdb/common/string_util.hpp"
|
14
14
|
#include "duckdb/parser/qualified_name.hpp"
|
15
|
+
#include "duckdb/parser/expression/constant_expression.hpp"
|
15
16
|
|
16
17
|
namespace duckdb {
|
17
18
|
//! Represents a built-in operator expression
|
@@ -86,9 +87,25 @@ public:
|
|
86
87
|
return "(" + entry.children[0]->ToString() + " IS NOT NULL)";
|
87
88
|
case ExpressionType::ARRAY_EXTRACT:
|
88
89
|
return entry.children[0]->ToString() + "[" + entry.children[1]->ToString() + "]";
|
89
|
-
case ExpressionType::ARRAY_SLICE:
|
90
|
-
|
91
|
-
|
90
|
+
case ExpressionType::ARRAY_SLICE: {
|
91
|
+
string begin = entry.children[1]->ToString();
|
92
|
+
if (begin == "[]") {
|
93
|
+
begin = "";
|
94
|
+
}
|
95
|
+
string end = entry.children[2]->ToString();
|
96
|
+
if (end == "[]") {
|
97
|
+
if (entry.children.size() == 4) {
|
98
|
+
end = "-";
|
99
|
+
} else {
|
100
|
+
end = "";
|
101
|
+
}
|
102
|
+
}
|
103
|
+
if (entry.children.size() == 4) {
|
104
|
+
return entry.children[0]->ToString() + "[" + begin + ":" + end + ":" + entry.children[3]->ToString() +
|
105
|
+
"]";
|
106
|
+
}
|
107
|
+
return entry.children[0]->ToString() + "[" + begin + ":" + end + "]";
|
108
|
+
}
|
92
109
|
case ExpressionType::STRUCT_EXTRACT: {
|
93
110
|
if (entry.children[1]->type != ExpressionType::VALUE_CONSTANT) {
|
94
111
|
return string();
|
@@ -11,6 +11,22 @@
|
|
11
11
|
#include "duckdb/parser/parsed_expression.hpp"
|
12
12
|
|
13
13
|
namespace duckdb {
|
14
|
+
|
15
|
+
// Parameters come in three different types:
|
16
|
+
// auto-increment:
|
17
|
+
// token: '?'
|
18
|
+
// name: -
|
19
|
+
// number: 0
|
20
|
+
// positional:
|
21
|
+
// token: '$<number>'
|
22
|
+
// name: -
|
23
|
+
// number: <number>
|
24
|
+
// named:
|
25
|
+
// token: '$<name>'
|
26
|
+
// name: <name>
|
27
|
+
// number: 0
|
28
|
+
enum class PreparedParamType : uint8_t { AUTO_INCREMENT, POSITIONAL, NAMED, INVALID };
|
29
|
+
|
14
30
|
class ParameterExpression : public ParsedExpression {
|
15
31
|
public:
|
16
32
|
static constexpr const ExpressionClass TYPE = ExpressionClass::PARAMETER;
|
@@ -18,7 +34,7 @@ public:
|
|
18
34
|
public:
|
19
35
|
ParameterExpression();
|
20
36
|
|
21
|
-
|
37
|
+
string identifier;
|
22
38
|
|
23
39
|
public:
|
24
40
|
bool IsScalar() const override {
|
@@ -23,6 +23,7 @@
|
|
23
23
|
#include "nodes/parsenodes.hpp"
|
24
24
|
#include "nodes/primnodes.hpp"
|
25
25
|
#include "pg_definitions.hpp"
|
26
|
+
#include "duckdb/parser/expression/parameter_expression.hpp"
|
26
27
|
|
27
28
|
namespace duckdb {
|
28
29
|
|
@@ -67,6 +68,8 @@ private:
|
|
67
68
|
idx_t prepared_statement_parameter_index = 0;
|
68
69
|
//! Map from named parameter to parameter index;
|
69
70
|
case_insensitive_map_t<idx_t> named_param_map;
|
71
|
+
//! Last parameter type
|
72
|
+
PreparedParamType last_param_type = PreparedParamType::INVALID;
|
70
73
|
//! Holds window expressions defined by name. We need those when transforming the expressions referring to them.
|
71
74
|
unordered_map<string, duckdb_libpgquery::PGWindowDef *> window_clauses;
|
72
75
|
//! The set of pivot entries to create
|
@@ -82,9 +85,8 @@ private:
|
|
82
85
|
Transformer &RootTransformer();
|
83
86
|
const Transformer &RootTransformer() const;
|
84
87
|
void SetParamCount(idx_t new_count);
|
85
|
-
void
|
86
|
-
bool
|
87
|
-
bool HasNamedParameters() const;
|
88
|
+
void SetParam(const string &name, idx_t index, PreparedParamType type);
|
89
|
+
bool GetParam(const string &name, idx_t &index, PreparedParamType type);
|
88
90
|
|
89
91
|
void AddPivotEntry(string enum_name, unique_ptr<SelectNode> source, unique_ptr<ParsedExpression> column,
|
90
92
|
unique_ptr<QueryNode> subquery);
|
@@ -10,11 +10,12 @@
|
|
10
10
|
|
11
11
|
#include "duckdb/common/types.hpp"
|
12
12
|
#include "duckdb/common/unordered_map.hpp"
|
13
|
+
#include "duckdb/common/case_insensitive_map.hpp"
|
13
14
|
|
14
15
|
namespace duckdb {
|
15
16
|
|
16
17
|
struct BoundParameterData;
|
17
18
|
|
18
|
-
using bound_parameter_map_t =
|
19
|
+
using bound_parameter_map_t = case_insensitive_map_t<shared_ptr<BoundParameterData>>;
|
19
20
|
|
20
21
|
} // namespace duckdb
|
@@ -11,19 +11,32 @@
|
|
11
11
|
#include "duckdb/common/types/value.hpp"
|
12
12
|
#include "duckdb/planner/bound_parameter_map.hpp"
|
13
13
|
#include "duckdb/common/field_writer.hpp"
|
14
|
+
#include "duckdb/common/case_insensitive_map.hpp"
|
14
15
|
|
15
16
|
namespace duckdb {
|
16
17
|
|
17
18
|
struct BoundParameterData {
|
19
|
+
public:
|
18
20
|
BoundParameterData() {
|
19
21
|
}
|
20
22
|
explicit BoundParameterData(Value val) : value(std::move(val)), return_type(value.type()) {
|
21
23
|
}
|
22
24
|
|
25
|
+
private:
|
23
26
|
Value value;
|
27
|
+
|
28
|
+
public:
|
24
29
|
LogicalType return_type;
|
25
30
|
|
26
31
|
public:
|
32
|
+
void SetValue(Value val) {
|
33
|
+
value = std::move(val);
|
34
|
+
}
|
35
|
+
|
36
|
+
const Value &GetValue() const {
|
37
|
+
return value;
|
38
|
+
}
|
39
|
+
|
27
40
|
void Serialize(Serializer &serializer) const {
|
28
41
|
FieldWriter writer(serializer);
|
29
42
|
value.Serialize(writer.GetSerializer());
|
@@ -45,17 +58,19 @@ public:
|
|
45
58
|
};
|
46
59
|
|
47
60
|
struct BoundParameterMap {
|
48
|
-
explicit BoundParameterMap(
|
61
|
+
explicit BoundParameterMap(case_insensitive_map_t<BoundParameterData> ¶meter_data)
|
62
|
+
: parameter_data(parameter_data) {
|
49
63
|
}
|
50
64
|
|
51
65
|
bound_parameter_map_t parameters;
|
52
|
-
|
66
|
+
case_insensitive_map_t<BoundParameterData> ¶meter_data;
|
53
67
|
|
54
|
-
LogicalType GetReturnType(
|
55
|
-
|
68
|
+
LogicalType GetReturnType(const string &identifier) {
|
69
|
+
auto it = parameter_data.find(identifier);
|
70
|
+
if (it == parameter_data.end()) {
|
56
71
|
return LogicalTypeId::UNKNOWN;
|
57
72
|
}
|
58
|
-
return
|
73
|
+
return it->second.return_type;
|
59
74
|
}
|
60
75
|
};
|
61
76
|
|
@@ -18,9 +18,9 @@ public:
|
|
18
18
|
static constexpr const ExpressionClass TYPE = ExpressionClass::BOUND_PARAMETER;
|
19
19
|
|
20
20
|
public:
|
21
|
-
explicit BoundParameterExpression(
|
21
|
+
explicit BoundParameterExpression(const string &identifier);
|
22
22
|
|
23
|
-
|
23
|
+
string identifier;
|
24
24
|
shared_ptr<BoundParameterData> parameter_data;
|
25
25
|
|
26
26
|
public:
|
@@ -47,7 +47,7 @@ public:
|
|
47
47
|
static unique_ptr<Expression> FormatDeserialize(FormatDeserializer &deserializer);
|
48
48
|
|
49
49
|
private:
|
50
|
-
BoundParameterExpression(bound_parameter_map_t &global_parameter_set,
|
50
|
+
BoundParameterExpression(bound_parameter_map_t &global_parameter_set, string identifier, LogicalType return_type,
|
51
51
|
shared_ptr<BoundParameterData> parameter_data);
|
52
52
|
};
|
53
53
|
|
@@ -25,21 +25,22 @@ class Planner {
|
|
25
25
|
public:
|
26
26
|
explicit Planner(ClientContext &context);
|
27
27
|
|
28
|
+
public:
|
28
29
|
unique_ptr<LogicalOperator> plan;
|
29
30
|
vector<string> names;
|
30
31
|
vector<LogicalType> types;
|
31
|
-
|
32
|
-
vector<BoundParameterData> parameter_data;
|
32
|
+
case_insensitive_map_t<BoundParameterData> parameter_data;
|
33
33
|
|
34
34
|
shared_ptr<Binder> binder;
|
35
35
|
ClientContext &context;
|
36
36
|
|
37
37
|
StatementProperties properties;
|
38
|
+
bound_parameter_map_t value_map;
|
38
39
|
|
39
40
|
public:
|
40
41
|
void CreatePlan(unique_ptr<SQLStatement> statement);
|
41
42
|
static void VerifyPlan(ClientContext &context, unique_ptr<LogicalOperator> &op,
|
42
|
-
bound_parameter_map_t
|
43
|
+
optional_ptr<bound_parameter_map_t> map = nullptr);
|
43
44
|
|
44
45
|
private:
|
45
46
|
void CreatePlan(SQLStatement &statement);
|
@@ -21,7 +21,7 @@ public:
|
|
21
21
|
const std::function<unique_ptr<QueryResult>(const string &, unique_ptr<SQLStatement>)> &run) override;
|
22
22
|
|
23
23
|
private:
|
24
|
-
|
24
|
+
case_insensitive_map_t<unique_ptr<ParsedExpression>> values;
|
25
25
|
unique_ptr<SQLStatement> prepare_statement;
|
26
26
|
unique_ptr<SQLStatement> execute_statement;
|
27
27
|
unique_ptr<SQLStatement> dealloc_statement;
|
@@ -944,6 +944,16 @@ Returns 0 if the query was not successfully prepared.
|
|
944
944
|
*/
|
945
945
|
DUCKDB_API idx_t duckdb_nparams(duckdb_prepared_statement prepared_statement);
|
946
946
|
|
947
|
+
/*!
|
948
|
+
Returns the name used to identify the parameter
|
949
|
+
The returned string should be freed using `duckdb_free`.
|
950
|
+
|
951
|
+
Returns NULL if the index is out of range for the provided prepared statement.
|
952
|
+
|
953
|
+
* prepared_statement: The prepared statement for which to get the parameter name from.
|
954
|
+
*/
|
955
|
+
const char *duckdb_parameter_name(duckdb_prepared_statement prepared_statement, idx_t index);
|
956
|
+
|
947
957
|
/*!
|
948
958
|
Returns the parameter type for the parameter at the given index.
|
949
959
|
|
@@ -960,6 +970,12 @@ Clear the params bind to the prepared statement.
|
|
960
970
|
*/
|
961
971
|
DUCKDB_API duckdb_state duckdb_clear_bindings(duckdb_prepared_statement prepared_statement);
|
962
972
|
|
973
|
+
/*!
|
974
|
+
Retrieve the index of the parameter for the prepared statement, identified by name
|
975
|
+
*/
|
976
|
+
DUCKDB_API duckdb_state duckdb_bind_parameter_index(duckdb_prepared_statement prepared_statement, idx_t *param_idx_out,
|
977
|
+
const char *name);
|
978
|
+
|
963
979
|
/*!
|
964
980
|
Binds a bool value to the prepared statement at the specified index.
|
965
981
|
*/
|
@@ -2,12 +2,17 @@
|
|
2
2
|
#include "duckdb/main/query_result.hpp"
|
3
3
|
#include "duckdb/main/pending_query_result.hpp"
|
4
4
|
#include "duckdb/common/preserved_error.hpp"
|
5
|
+
#include "duckdb/common/case_insensitive_map.hpp"
|
6
|
+
#include "duckdb/common/optional_ptr.hpp"
|
5
7
|
|
8
|
+
using duckdb::case_insensitive_map_t;
|
6
9
|
using duckdb::make_uniq;
|
10
|
+
using duckdb::optional_ptr;
|
7
11
|
using duckdb::PendingExecutionResult;
|
8
12
|
using duckdb::PendingQueryResult;
|
9
13
|
using duckdb::PendingStatementWrapper;
|
10
14
|
using duckdb::PreparedStatementWrapper;
|
15
|
+
using duckdb::Value;
|
11
16
|
|
12
17
|
duckdb_state duckdb_pending_prepared_internal(duckdb_prepared_statement prepared_statement,
|
13
18
|
duckdb_pending_result *out_result, bool allow_streaming) {
|
@@ -17,6 +22,7 @@ duckdb_state duckdb_pending_prepared_internal(duckdb_prepared_statement prepared
|
|
17
22
|
auto wrapper = reinterpret_cast<PreparedStatementWrapper *>(prepared_statement);
|
18
23
|
auto result = new PendingStatementWrapper();
|
19
24
|
result->allow_streaming = allow_streaming;
|
25
|
+
|
20
26
|
try {
|
21
27
|
result->statement = wrapper->statement->PendingQuery(wrapper->values, allow_streaming);
|
22
28
|
} catch (const duckdb::Exception &ex) {
|
@@ -2,7 +2,10 @@
|
|
2
2
|
#include "duckdb/main/query_result.hpp"
|
3
3
|
#include "duckdb/main/prepared_statement_data.hpp"
|
4
4
|
#include "duckdb/common/types/decimal.hpp"
|
5
|
+
#include "duckdb/common/optional_ptr.hpp"
|
6
|
+
#include "duckdb/common/case_insensitive_map.hpp"
|
5
7
|
|
8
|
+
using duckdb::case_insensitive_map_t;
|
6
9
|
using duckdb::Connection;
|
7
10
|
using duckdb::date_t;
|
8
11
|
using duckdb::dtime_t;
|
@@ -10,8 +13,10 @@ using duckdb::ExtractStatementsWrapper;
|
|
10
13
|
using duckdb::hugeint_t;
|
11
14
|
using duckdb::LogicalType;
|
12
15
|
using duckdb::MaterializedQueryResult;
|
16
|
+
using duckdb::optional_ptr;
|
13
17
|
using duckdb::PreparedStatementWrapper;
|
14
18
|
using duckdb::QueryResultType;
|
19
|
+
using duckdb::StringUtil;
|
15
20
|
using duckdb::timestamp_t;
|
16
21
|
using duckdb::Value;
|
17
22
|
|
@@ -84,13 +89,42 @@ idx_t duckdb_nparams(duckdb_prepared_statement prepared_statement) {
|
|
84
89
|
return wrapper->statement->n_param;
|
85
90
|
}
|
86
91
|
|
92
|
+
static duckdb::string duckdb_parameter_name_internal(duckdb_prepared_statement prepared_statement, idx_t index) {
|
93
|
+
auto wrapper = (PreparedStatementWrapper *)prepared_statement;
|
94
|
+
if (!wrapper || !wrapper->statement || wrapper->statement->HasError()) {
|
95
|
+
return duckdb::string();
|
96
|
+
}
|
97
|
+
if (index > wrapper->statement->n_param) {
|
98
|
+
return duckdb::string();
|
99
|
+
}
|
100
|
+
for (auto &item : wrapper->statement->named_param_map) {
|
101
|
+
auto &identifier = item.first;
|
102
|
+
auto ¶m_idx = item.second;
|
103
|
+
if (param_idx == index) {
|
104
|
+
// Found the matching parameter
|
105
|
+
return identifier;
|
106
|
+
}
|
107
|
+
}
|
108
|
+
// No parameter was found with this index
|
109
|
+
return duckdb::string();
|
110
|
+
}
|
111
|
+
|
112
|
+
const char *duckdb_parameter_name(duckdb_prepared_statement prepared_statement, idx_t index) {
|
113
|
+
auto identifier = duckdb_parameter_name_internal(prepared_statement, index);
|
114
|
+
if (identifier == duckdb::string()) {
|
115
|
+
return NULL;
|
116
|
+
}
|
117
|
+
return strdup(identifier.c_str());
|
118
|
+
}
|
119
|
+
|
87
120
|
duckdb_type duckdb_param_type(duckdb_prepared_statement prepared_statement, idx_t param_idx) {
|
88
121
|
auto wrapper = reinterpret_cast<PreparedStatementWrapper *>(prepared_statement);
|
89
122
|
if (!wrapper || !wrapper->statement || wrapper->statement->HasError()) {
|
90
123
|
return DUCKDB_TYPE_INVALID;
|
91
124
|
}
|
92
125
|
LogicalType param_type;
|
93
|
-
|
126
|
+
auto identifier = std::to_string(param_idx);
|
127
|
+
if (!wrapper->statement->data->TryGetType(identifier, param_type)) {
|
94
128
|
return DUCKDB_TYPE_INVALID;
|
95
129
|
}
|
96
130
|
return ConvertCPPTypeToC(param_type);
|
@@ -113,10 +147,23 @@ static duckdb_state duckdb_bind_value(duckdb_prepared_statement prepared_stateme
|
|
113
147
|
if (param_idx <= 0 || param_idx > wrapper->statement->n_param) {
|
114
148
|
return DuckDBError;
|
115
149
|
}
|
116
|
-
|
117
|
-
|
150
|
+
auto identifier = duckdb_parameter_name_internal(prepared_statement, param_idx);
|
151
|
+
wrapper->values[identifier] = val;
|
152
|
+
return DuckDBSuccess;
|
153
|
+
}
|
154
|
+
|
155
|
+
duckdb_state duckdb_bind_parameter_index(duckdb_prepared_statement prepared_statement, idx_t *param_idx_out,
|
156
|
+
const char *name) {
|
157
|
+
auto wrapper = (PreparedStatementWrapper *)prepared_statement;
|
158
|
+
if (!wrapper || !wrapper->statement || wrapper->statement->HasError()) {
|
159
|
+
return DuckDBError;
|
160
|
+
}
|
161
|
+
auto &statement = wrapper->statement;
|
162
|
+
auto entry = statement->named_param_map.find(name);
|
163
|
+
if (entry == statement->named_param_map.end()) {
|
164
|
+
return DuckDBError;
|
118
165
|
}
|
119
|
-
|
166
|
+
*param_idx_out = entry->second;
|
120
167
|
return DuckDBSuccess;
|
121
168
|
}
|
122
169
|
|
@@ -232,6 +279,7 @@ duckdb_state duckdb_execute_prepared(duckdb_prepared_statement prepared_statemen
|
|
232
279
|
if (!wrapper || !wrapper->statement || wrapper->statement->HasError()) {
|
233
280
|
return DuckDBError;
|
234
281
|
}
|
282
|
+
|
235
283
|
auto result = wrapper->statement->Execute(wrapper->values, false);
|
236
284
|
return duckdb_translate_result(std::move(result), out_result);
|
237
285
|
}
|