1#include "duckdb/parser/expression/parameter_expression.hpp"
2#include "duckdb/planner/binder.hpp"
3#include "duckdb/planner/expression/bound_constant_expression.hpp"
4#include "duckdb/planner/expression/bound_parameter_expression.hpp"
5#include "duckdb/planner/expression_binder.hpp"
6
7namespace duckdb {
8
9BindResult ExpressionBinder::BindExpression(ParameterExpression &expr, idx_t depth) {
10 D_ASSERT(expr.parameter_nr > 0);
11 auto bound_parameter = make_uniq<BoundParameterExpression>(args&: expr.parameter_nr);
12 bound_parameter->alias = expr.alias;
13 if (!binder.parameters) {
14 throw BinderException("Unexpected prepared parameter. This type of statement can't be prepared!");
15 }
16 auto parameter_idx = expr.parameter_nr;
17 // check if a parameter value has already been supplied
18 if (parameter_idx <= binder.parameters->parameter_data.size()) {
19 // it has! emit a constant directly
20 auto &data = binder.parameters->parameter_data[parameter_idx - 1];
21 auto constant = make_uniq<BoundConstantExpression>(args&: data.value);
22 constant->alias = expr.alias;
23 return BindResult(std::move(constant));
24 }
25 auto entry = binder.parameters->parameters.find(x: parameter_idx);
26 if (entry == binder.parameters->parameters.end()) {
27 // no entry yet: create a new one
28 auto data = make_shared<BoundParameterData>();
29 data->return_type = binder.parameters->GetReturnType(index: parameter_idx - 1);
30 bound_parameter->return_type = data->return_type;
31 bound_parameter->parameter_data = data;
32 binder.parameters->parameters[parameter_idx] = std::move(data);
33 } else {
34 // a prepared statement with this parameter index was already there: use it
35 auto &data = entry->second;
36 bound_parameter->parameter_data = data;
37 bound_parameter->return_type = binder.parameters->GetReturnType(index: parameter_idx - 1);
38 }
39 return BindResult(std::move(bound_parameter));
40}
41
42} // namespace duckdb
43