@@ -323,17 +323,19 @@ std::unique_ptr<PreparedStatement> ClientContext::prepareWithParams(std::string_
323
323
324
324
static void bindParametersNoLock (PreparedStatement& preparedStatement,
325
325
const std::unordered_map<std::string, std::unique_ptr<Value>>& inputParams) {
326
- auto & parameterMap = preparedStatement.getParameterMapUnsafe ();
327
- for ( auto & [name, value] : inputParams) {
328
- if (!parameterMap. contains (name)) {
329
- throw Exception ( " Parameter " + name + " not found. " );
326
+ for ( auto & key : preparedStatement.getKnownParameters ()) {
327
+ if ( inputParams. contains (key) ) {
328
+ // Found input. Update parameter map.
329
+ preparedStatement. updateParameter (key, inputParams. at (key). get () );
330
330
}
331
- preparedStatement.validateExecuteParam (name, value.get ());
332
- // The much more natural `parameterMap.at(name) = std::move(v)` fails.
333
- // The reason is that other parts of the code rely on the existing Value object to be
334
- // modified in-place, not replaced in this map.
335
- *parameterMap.at (name) = std::move (*value);
336
331
}
332
+ for (auto & key : preparedStatement.getUnknownParameters ()) {
333
+ if (!inputParams.contains (key)) {
334
+ throw Exception (" Parameter " + key + " not found." );
335
+ }
336
+ preparedStatement.addParameter (key, inputParams.at (key).get ());
337
+ }
338
+
337
339
}
338
340
339
341
std::unique_ptr<QueryResult> ClientContext::executeWithParams (PreparedStatement* preparedStatement,
@@ -469,7 +471,7 @@ void ClientContext::validateTransaction(bool readOnly, bool requireTransaction)
469
471
470
472
ClientContext::PrepareResult ClientContext::prepareNoLock (
471
473
std::shared_ptr<Statement> parsedStatement, bool shouldCommitNewTransaction,
472
- std::optional<std:: unordered_map<std::string, std::shared_ptr<Value> >> inputParams) {
474
+ std::unordered_map<std::string, std::shared_ptr<Value>> inputParams) {
473
475
auto preparedStatement = std::make_unique<PreparedStatement>();
474
476
auto cachedStatement = std::make_unique<CachedPreparedStatement>();
475
477
cachedStatement->parsedStatement = parsedStatement;
@@ -489,12 +491,13 @@ ClientContext::PrepareResult ClientContext::prepareNoLock(
489
491
*transactionContext,
490
492
[&]() -> void {
491
493
auto binder = Binder (this , localDatabase->getBinderExtensions ());
492
- if (inputParams) {
493
- binder.setInputParameters (*inputParams);
494
+ auto expressionBinder = binder.getExpressionBinder ();
495
+ for (auto & [name, value] : inputParams) {
496
+ expressionBinder->addParameter (name, value);
494
497
}
495
498
const auto boundStatement = binder.bind (*parsedStatement);
496
- binder. validateAllInputParametersParsed ();
497
- preparedStatement->parameterMap = binder. getParameterMap ();
499
+ preparedStatement-> unknownParameters = expressionBinder-> getUnknownParameters ();
500
+ preparedStatement->parameterMap = expressionBinder-> getKnownParameters ();
498
501
cachedStatement->columns = boundStatement->getStatementResult ()->getColumns ();
499
502
auto planner = Planner (this );
500
503
auto bestPlan = planner.planStatement (*boundStatement);
0 commit comments