duckdb 0.3.5-dev184.0 → 0.3.5-dev211.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/src/duckdb.cpp CHANGED
@@ -56331,6 +56331,67 @@ string PhysicalFilter::ParamsToString() const {
56331
56331
 
56332
56332
 
56333
56333
 
56334
+ //===----------------------------------------------------------------------===//
56335
+ // DuckDB
56336
+ //
56337
+ // duckdb/main/prepared_statement_data.hpp
56338
+ //
56339
+ //
56340
+ //===----------------------------------------------------------------------===//
56341
+
56342
+
56343
+
56344
+
56345
+
56346
+
56347
+
56348
+
56349
+
56350
+ namespace duckdb {
56351
+ class CatalogEntry;
56352
+ class PhysicalOperator;
56353
+ class SQLStatement;
56354
+
56355
+ class PreparedStatementData {
56356
+ public:
56357
+ DUCKDB_API explicit PreparedStatementData(StatementType type);
56358
+ DUCKDB_API ~PreparedStatementData();
56359
+
56360
+ StatementType statement_type;
56361
+ //! The unbound SQL statement that was prepared
56362
+ unique_ptr<SQLStatement> unbound_statement;
56363
+ //! The fully prepared physical plan of the prepared statement
56364
+ unique_ptr<PhysicalOperator> plan;
56365
+ //! The map of parameter index to the actual value entry
56366
+ unordered_map<idx_t, vector<unique_ptr<Value>>> value_map;
56367
+
56368
+ //! The result names of the transaction
56369
+ vector<string> names;
56370
+ //! The result types of the transaction
56371
+ vector<LogicalType> types;
56372
+
56373
+ //! Whether or not the statement is a read-only statement, or whether it can result in changes to the database
56374
+ bool read_only;
56375
+ //! Whether or not the statement requires a valid transaction. Almost all statements require this, with the
56376
+ //! exception of
56377
+ bool requires_valid_transaction;
56378
+ //! Whether or not the result can be streamed to the client
56379
+ bool allow_stream_result;
56380
+ //! Whether or not all parameters have successfully had their types determined
56381
+ bool bound_all_parameters;
56382
+
56383
+ //! The catalog version of when the prepared statement was bound
56384
+ //! If this version is lower than the current catalog version, we have to rebind the prepared statement
56385
+ idx_t catalog_version;
56386
+
56387
+ public:
56388
+ //! Bind a set of values to the prepared statement data
56389
+ DUCKDB_API void Bind(vector<Value> values);
56390
+ //! Get the expected SQL Type of the bound parameter
56391
+ DUCKDB_API LogicalType GetType(idx_t param_index);
56392
+ };
56393
+
56394
+ } // namespace duckdb
56334
56395
 
56335
56396
  namespace duckdb {
56336
56397
 
@@ -56339,6 +56400,8 @@ public:
56339
56400
  explicit PhysicalExecute(PhysicalOperator *plan);
56340
56401
 
56341
56402
  PhysicalOperator *plan;
56403
+ unique_ptr<PhysicalOperator> owned_plan;
56404
+ shared_ptr<PreparedStatementData> prepared;
56342
56405
  };
56343
56406
 
56344
56407
  } // namespace duckdb
@@ -56996,66 +57059,8 @@ void PhysicalPragma::GetData(ExecutionContext &context, DataChunk &chunk, Global
56996
57059
 
56997
57060
 
56998
57061
 
56999
- //===----------------------------------------------------------------------===//
57000
- // DuckDB
57001
- //
57002
- // duckdb/main/prepared_statement_data.hpp
57003
- //
57004
- //
57005
- //===----------------------------------------------------------------------===//
57006
-
57007
-
57008
-
57009
-
57010
-
57011
-
57012
-
57013
57062
 
57014
57063
 
57015
- namespace duckdb {
57016
- class CatalogEntry;
57017
- class PhysicalOperator;
57018
- class SQLStatement;
57019
-
57020
- class PreparedStatementData {
57021
- public:
57022
- DUCKDB_API explicit PreparedStatementData(StatementType type);
57023
- DUCKDB_API ~PreparedStatementData();
57024
-
57025
- StatementType statement_type;
57026
- //! The unbound SQL statement that was prepared
57027
- unique_ptr<SQLStatement> unbound_statement;
57028
- //! The fully prepared physical plan of the prepared statement
57029
- unique_ptr<PhysicalOperator> plan;
57030
- //! The map of parameter index to the actual value entry
57031
- unordered_map<idx_t, vector<unique_ptr<Value>>> value_map;
57032
-
57033
- //! The result names of the transaction
57034
- vector<string> names;
57035
- //! The result types of the transaction
57036
- vector<LogicalType> types;
57037
-
57038
- //! Whether or not the statement is a read-only statement, or whether it can result in changes to the database
57039
- bool read_only;
57040
- //! Whether or not the statement requires a valid transaction. Almost all statements require this, with the
57041
- //! exception of
57042
- bool requires_valid_transaction;
57043
- //! Whether or not the result can be streamed to the client
57044
- bool allow_stream_result;
57045
-
57046
- //! The catalog version of when the prepared statement was bound
57047
- //! If this version is lower than the current catalog version, we have to rebind the prepared statement
57048
- idx_t catalog_version;
57049
-
57050
- public:
57051
- //! Bind a set of values to the prepared statement data
57052
- DUCKDB_API void Bind(vector<Value> values);
57053
- //! Get the expected SQL Type of the bound parameter
57054
- DUCKDB_API LogicalType GetType(idx_t param_index);
57055
- };
57056
-
57057
- } // namespace duckdb
57058
-
57059
57064
  namespace duckdb {
57060
57065
 
57061
57066
  class PhysicalPrepare : public PhysicalOperator {
@@ -70506,8 +70511,17 @@ protected:
70506
70511
  namespace duckdb {
70507
70512
 
70508
70513
  unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalExecute &op) {
70509
- D_ASSERT(op.children.size() == 0);
70510
- return make_unique<PhysicalExecute>(op.prepared->plan.get());
70514
+ if (!op.prepared->plan) {
70515
+ D_ASSERT(op.children.size() == 1);
70516
+ auto owned_plan = CreatePlan(*op.children[0]);
70517
+ auto execute = make_unique<PhysicalExecute>(owned_plan.get());
70518
+ execute->owned_plan = move(owned_plan);
70519
+ execute->prepared = move(op.prepared);
70520
+ return move(execute);
70521
+ } else {
70522
+ D_ASSERT(op.children.size() == 0);
70523
+ return make_unique<PhysicalExecute>(op.prepared->plan.get());
70524
+ }
70511
70525
  }
70512
70526
 
70513
70527
  } // namespace duckdb
@@ -81353,10 +81367,14 @@ int64_t CastRules::ImplicitCast(const LogicalType &from, const LogicalType &to)
81353
81367
  // anything can be cast to ANY type for no cost
81354
81368
  return 0;
81355
81369
  }
81356
- if (from.id() == LogicalTypeId::SQLNULL || from.id() == LogicalTypeId::UNKNOWN) {
81357
- // NULL expression or parameter expression can be cast to anything
81370
+ if (from.id() == LogicalTypeId::SQLNULL) {
81371
+ // NULL expression can be cast to anything
81358
81372
  return TargetTypeCost(to);
81359
81373
  }
81374
+ if (from.id() == LogicalTypeId::UNKNOWN) {
81375
+ // parameter expression can be cast to anything for no cost
81376
+ return 0;
81377
+ }
81360
81378
  if (from.id() == LogicalTypeId::BLOB && to.id() == LogicalTypeId::VARCHAR) {
81361
81379
  // Implicit cast not allowed from BLOB to VARCHAR
81362
81380
  return -1;
@@ -81824,11 +81842,11 @@ static int64_t BindFunctionCost(SimpleFunction &func, vector<LogicalType> &argum
81824
81842
  }
81825
81843
 
81826
81844
  template <class T>
81827
- static idx_t BindFunctionFromArguments(const string &name, vector<T> &functions, vector<LogicalType> &arguments,
81828
- string &error) {
81845
+ static vector<idx_t> BindFunctionsFromArguments(const string &name, vector<T> &functions,
81846
+ vector<LogicalType> &arguments, string &error) {
81829
81847
  idx_t best_function = DConstants::INVALID_INDEX;
81830
81848
  int64_t lowest_cost = NumericLimits<int64_t>::Maximum();
81831
- vector<idx_t> conflicting_functions;
81849
+ vector<idx_t> candidate_functions;
81832
81850
  for (idx_t f_idx = 0; f_idx < functions.size(); f_idx++) {
81833
81851
  auto &func = functions[f_idx];
81834
81852
  // check the arguments of the function
@@ -81838,32 +81856,16 @@ static idx_t BindFunctionFromArguments(const string &name, vector<T> &functions,
81838
81856
  continue;
81839
81857
  }
81840
81858
  if (cost == lowest_cost) {
81841
- conflicting_functions.push_back(f_idx);
81859
+ candidate_functions.push_back(f_idx);
81842
81860
  continue;
81843
81861
  }
81844
81862
  if (cost > lowest_cost) {
81845
81863
  continue;
81846
81864
  }
81847
- conflicting_functions.clear();
81865
+ candidate_functions.clear();
81848
81866
  lowest_cost = cost;
81849
81867
  best_function = f_idx;
81850
81868
  }
81851
- if (!conflicting_functions.empty()) {
81852
- // there are multiple possible function definitions
81853
- // throw an exception explaining which overloads are there
81854
- conflicting_functions.push_back(best_function);
81855
- string call_str = Function::CallToString(name, arguments);
81856
- string candidate_str = "";
81857
- for (auto &conf : conflicting_functions) {
81858
- auto &f = functions[conf];
81859
- candidate_str += "\t" + f.ToString() + "\n";
81860
- }
81861
- error =
81862
- StringUtil::Format("Could not choose a best candidate function for the function call \"%s\". In order to "
81863
- "select one, please add explicit type casts.\n\tCandidate functions:\n%s",
81864
- call_str, candidate_str);
81865
- return DConstants::INVALID_INDEX;
81866
- }
81867
81869
  if (best_function == DConstants::INVALID_INDEX) {
81868
81870
  // no matching function was found, throw an error
81869
81871
  string call_str = Function::CallToString(name, arguments);
@@ -81874,24 +81876,77 @@ static idx_t BindFunctionFromArguments(const string &name, vector<T> &functions,
81874
81876
  error = StringUtil::Format("No function matches the given name and argument types '%s'. You might need to add "
81875
81877
  "explicit type casts.\n\tCandidate functions:\n%s",
81876
81878
  call_str, candidate_str);
81879
+ return candidate_functions;
81880
+ }
81881
+ candidate_functions.push_back(best_function);
81882
+ return candidate_functions;
81883
+ }
81884
+
81885
+ template <class T>
81886
+ static idx_t MultipleCandidateException(const string &name, vector<T> &functions, vector<idx_t> &candidate_functions,
81887
+ vector<LogicalType> &arguments, string &error) {
81888
+ D_ASSERT(functions.size() > 1);
81889
+ // there are multiple possible function definitions
81890
+ // throw an exception explaining which overloads are there
81891
+ string call_str = Function::CallToString(name, arguments);
81892
+ string candidate_str = "";
81893
+ for (auto &conf : candidate_functions) {
81894
+ auto &f = functions[conf];
81895
+ candidate_str += "\t" + f.ToString() + "\n";
81896
+ }
81897
+ error = StringUtil::Format("Could not choose a best candidate function for the function call \"%s\". In order to "
81898
+ "select one, please add explicit type casts.\n\tCandidate functions:\n%s",
81899
+ call_str, candidate_str);
81900
+ return DConstants::INVALID_INDEX;
81901
+ }
81902
+
81903
+ template <class T>
81904
+ static idx_t BindFunctionFromArguments(const string &name, vector<T> &functions, vector<LogicalType> &arguments,
81905
+ string &error, bool &cast_parameters) {
81906
+ auto candidate_functions = BindFunctionsFromArguments<T>(name, functions, arguments, error);
81907
+ if (candidate_functions.empty()) {
81908
+ // no candidates
81877
81909
  return DConstants::INVALID_INDEX;
81878
81910
  }
81879
- return best_function;
81911
+ cast_parameters = true;
81912
+ if (candidate_functions.size() > 1) {
81913
+ // multiple candidates, check if there are any unknown arguments
81914
+ bool has_parameters = false;
81915
+ for (auto &arg_type : arguments) {
81916
+ if (arg_type.id() == LogicalTypeId::UNKNOWN) {
81917
+ //! there are! disable casting of parameters, but do not throw an error
81918
+ cast_parameters = false;
81919
+ has_parameters = true;
81920
+ break;
81921
+ }
81922
+ }
81923
+ if (!has_parameters) {
81924
+ return MultipleCandidateException(name, functions, candidate_functions, arguments, error);
81925
+ }
81926
+ }
81927
+ return candidate_functions[0];
81880
81928
  }
81881
81929
 
81882
81930
  idx_t Function::BindFunction(const string &name, vector<ScalarFunction> &functions, vector<LogicalType> &arguments,
81883
- string &error) {
81884
- return BindFunctionFromArguments(name, functions, arguments, error);
81931
+ string &error, bool &cast_parameters) {
81932
+ return BindFunctionFromArguments(name, functions, arguments, error, cast_parameters);
81933
+ }
81934
+
81935
+ idx_t Function::BindFunction(const string &name, vector<AggregateFunction> &functions, vector<LogicalType> &arguments,
81936
+ string &error, bool &cast_parameters) {
81937
+ return BindFunctionFromArguments(name, functions, arguments, error, cast_parameters);
81885
81938
  }
81886
81939
 
81887
81940
  idx_t Function::BindFunction(const string &name, vector<AggregateFunction> &functions, vector<LogicalType> &arguments,
81888
81941
  string &error) {
81889
- return BindFunctionFromArguments(name, functions, arguments, error);
81942
+ bool cast_parameters;
81943
+ return BindFunction(name, functions, arguments, error, cast_parameters);
81890
81944
  }
81891
81945
 
81892
81946
  idx_t Function::BindFunction(const string &name, vector<TableFunction> &functions, vector<LogicalType> &arguments,
81893
81947
  string &error) {
81894
- return BindFunctionFromArguments(name, functions, arguments, error);
81948
+ bool cast_parameters;
81949
+ return BindFunctionFromArguments(name, functions, arguments, error, cast_parameters);
81895
81950
  }
81896
81951
 
81897
81952
  idx_t Function::BindFunction(const string &name, vector<PragmaFunction> &functions, PragmaInfo &info, string &error) {
@@ -81899,7 +81954,8 @@ idx_t Function::BindFunction(const string &name, vector<PragmaFunction> &functio
81899
81954
  for (auto &value : info.parameters) {
81900
81955
  types.push_back(value.type());
81901
81956
  }
81902
- idx_t entry = BindFunctionFromArguments(name, functions, types, error);
81957
+ bool cast_parameters;
81958
+ idx_t entry = BindFunctionFromArguments(name, functions, types, error, cast_parameters);
81903
81959
  if (entry == DConstants::INVALID_INDEX) {
81904
81960
  throw BinderException(error);
81905
81961
  }
@@ -81923,9 +81979,9 @@ vector<LogicalType> GetLogicalTypesFromExpressions(vector<unique_ptr<Expression>
81923
81979
  }
81924
81980
 
81925
81981
  idx_t Function::BindFunction(const string &name, vector<ScalarFunction> &functions,
81926
- vector<unique_ptr<Expression>> &arguments, string &error) {
81982
+ vector<unique_ptr<Expression>> &arguments, string &error, bool &cast_parameters) {
81927
81983
  auto types = GetLogicalTypesFromExpressions(arguments);
81928
- return Function::BindFunction(name, functions, types, error);
81984
+ return Function::BindFunction(name, functions, types, error, cast_parameters);
81929
81985
  }
81930
81986
 
81931
81987
  idx_t Function::BindFunction(const string &name, vector<AggregateFunction> &functions,
@@ -81955,23 +82011,21 @@ LogicalTypeComparisonResult RequiresCast(const LogicalType &source_type, const L
81955
82011
  return LogicalTypeComparisonResult::DIFFERENT_TYPES;
81956
82012
  }
81957
82013
 
81958
- void BaseScalarFunction::CastToFunctionArguments(vector<unique_ptr<Expression>> &children) {
82014
+ void BaseScalarFunction::CastToFunctionArguments(vector<unique_ptr<Expression>> &children,
82015
+ bool cast_parameter_expressions) {
81959
82016
  for (idx_t i = 0; i < children.size(); i++) {
81960
82017
  auto target_type = i < this->arguments.size() ? this->arguments[i] : this->varargs;
81961
82018
  target_type.Verify();
82019
+ // check if the source type is a paramter, and we have disabled casting of parameters
82020
+ if (children[i]->return_type.id() == LogicalTypeId::UNKNOWN && !cast_parameter_expressions) {
82021
+ continue;
82022
+ }
81962
82023
  // check if the type of child matches the type of function argument
81963
82024
  // if not we need to add a cast
81964
82025
  auto cast_result = RequiresCast(children[i]->return_type, target_type);
81965
82026
  // except for one special case: if the function accepts ANY argument
81966
82027
  // in that case we don't add a cast
81967
- if (cast_result == LogicalTypeComparisonResult::TARGET_IS_ANY) {
81968
- if (children[i]->return_type.id() == LogicalTypeId::UNKNOWN) {
81969
- // UNLESS the child is a prepared statement parameter
81970
- // in that case we default the prepared statement parameter to VARCHAR
81971
- children[i]->return_type =
81972
- ExpressionBinder::ExchangeType(target_type, LogicalTypeId::ANY, LogicalType::VARCHAR);
81973
- }
81974
- } else if (cast_result == LogicalTypeComparisonResult::DIFFERENT_TYPES) {
82028
+ if (cast_result == LogicalTypeComparisonResult::DIFFERENT_TYPES) {
81975
82029
  children[i] = BoundCastExpression::AddCastToType(move(children[i]), target_type);
81976
82030
  }
81977
82031
  }
@@ -81993,25 +82047,27 @@ unique_ptr<BoundFunctionExpression> ScalarFunction::BindScalarFunction(ClientCon
81993
82047
  vector<unique_ptr<Expression>> children,
81994
82048
  string &error, bool is_operator) {
81995
82049
  // bind the function
81996
- idx_t best_function = Function::BindFunction(func.name, func.functions, children, error);
82050
+ bool cast_parameters;
82051
+ idx_t best_function = Function::BindFunction(func.name, func.functions, children, error, cast_parameters);
81997
82052
  if (best_function == DConstants::INVALID_INDEX) {
81998
82053
  return nullptr;
81999
82054
  }
82055
+
82000
82056
  // found a matching function!
82001
82057
  auto &bound_function = func.functions[best_function];
82002
- return ScalarFunction::BindScalarFunction(context, bound_function, move(children), is_operator);
82058
+ return ScalarFunction::BindScalarFunction(context, bound_function, move(children), is_operator, cast_parameters);
82003
82059
  }
82004
82060
 
82005
82061
  unique_ptr<BoundFunctionExpression> ScalarFunction::BindScalarFunction(ClientContext &context,
82006
82062
  ScalarFunction bound_function,
82007
82063
  vector<unique_ptr<Expression>> children,
82008
- bool is_operator) {
82064
+ bool is_operator, bool cast_parameters) {
82009
82065
  unique_ptr<FunctionData> bind_info;
82010
82066
  if (bound_function.bind) {
82011
82067
  bind_info = bound_function.bind(context, bound_function, children);
82012
82068
  }
82013
82069
  // check if we need to add casts to the children
82014
- bound_function.CastToFunctionArguments(children);
82070
+ bound_function.CastToFunctionArguments(children, cast_parameters);
82015
82071
 
82016
82072
  // now create the function
82017
82073
  auto return_type = bound_function.return_type;
@@ -82019,10 +82075,9 @@ unique_ptr<BoundFunctionExpression> ScalarFunction::BindScalarFunction(ClientCon
82019
82075
  move(bind_info), is_operator);
82020
82076
  }
82021
82077
 
82022
- unique_ptr<BoundAggregateExpression>
82023
- AggregateFunction::BindAggregateFunction(ClientContext &context, AggregateFunction bound_function,
82024
- vector<unique_ptr<Expression>> children, unique_ptr<Expression> filter,
82025
- bool is_distinct, unique_ptr<BoundOrderModifier> order_bys) {
82078
+ unique_ptr<BoundAggregateExpression> AggregateFunction::BindAggregateFunction(
82079
+ ClientContext &context, AggregateFunction bound_function, vector<unique_ptr<Expression>> children,
82080
+ unique_ptr<Expression> filter, bool is_distinct, unique_ptr<BoundOrderModifier> order_bys, bool cast_parameters) {
82026
82081
  unique_ptr<FunctionData> bind_info;
82027
82082
  if (bound_function.bind) {
82028
82083
  bind_info = bound_function.bind(context, bound_function, children);
@@ -82031,7 +82086,7 @@ AggregateFunction::BindAggregateFunction(ClientContext &context, AggregateFuncti
82031
82086
  }
82032
82087
 
82033
82088
  // check if we need to add casts to the children
82034
- bound_function.CastToFunctionArguments(children);
82089
+ bound_function.CastToFunctionArguments(children, cast_parameters);
82035
82090
 
82036
82091
  // Special case: for ORDER BY aggregates, we wrap the aggregate function in a SortedAggregateFunction
82037
82092
  // The children are the sort clauses and the binding contains the ordering data.
@@ -88040,6 +88095,10 @@ static unique_ptr<FunctionData> ArraySliceBind(ClientContext &context, ScalarFun
88040
88095
  bound_function.arguments[1] = LogicalType::INTEGER;
88041
88096
  bound_function.arguments[2] = LogicalType::INTEGER;
88042
88097
  break;
88098
+ case LogicalTypeId::UNKNOWN:
88099
+ bound_function.arguments[0] = LogicalTypeId::UNKNOWN;
88100
+ bound_function.return_type = LogicalType::SQLNULL;
88101
+ break;
88043
88102
  default:
88044
88103
  throw BinderException("ARRAY_SLICE can only operate on LISTs and VARCHARs");
88045
88104
  }
@@ -88237,10 +88296,22 @@ static unique_ptr<FunctionData> ListContainsOrPositionBind(ClientContext &contex
88237
88296
  bound_function.arguments[0] = list;
88238
88297
  bound_function.arguments[1] = value;
88239
88298
  bound_function.return_type = LogicalTypeId::SQLNULL;
88299
+ } else if (list.id() == LogicalTypeId::UNKNOWN) {
88300
+ bound_function.return_type = RETURN_TYPE;
88301
+ if (value.id() != LogicalTypeId::UNKNOWN) {
88302
+ // only list is a parameter, cast it to a list of value type
88303
+ bound_function.arguments[0] = LogicalType::LIST(value);
88304
+ bound_function.arguments[1] = value;
88305
+ }
88306
+ } else if (value.id() == LogicalTypeId::UNKNOWN) {
88307
+ // only value is a parameter: we expect the child type of list
88308
+ auto const &child_type = ListType::GetChildType(list);
88309
+ bound_function.arguments[0] = list;
88310
+ bound_function.arguments[1] = child_type;
88311
+ bound_function.return_type = RETURN_TYPE;
88240
88312
  } else {
88241
- auto const &child_type = ListType::GetChildType(arguments[0]->return_type);
88313
+ auto const &child_type = ListType::GetChildType(list);
88242
88314
  auto max_child_type = LogicalType::MaxLogicalType(child_type, value);
88243
- ExpressionBinder::ResolveParameterType(max_child_type);
88244
88315
  auto list_type = LogicalType::LIST(max_child_type);
88245
88316
 
88246
88317
  bound_function.arguments[0] = list_type;
@@ -88416,6 +88487,11 @@ static unique_ptr<FunctionData> ListFlattenBind(ClientContext &context, ScalarFu
88416
88487
  bound_function.return_type = LogicalType(LogicalTypeId::SQLNULL);
88417
88488
  return make_unique<VariableReturnBindData>(bound_function.return_type);
88418
88489
  }
88490
+ if (input_type.id() == LogicalTypeId::UNKNOWN) {
88491
+ bound_function.arguments[0] = LogicalType(LogicalTypeId::UNKNOWN);
88492
+ bound_function.return_type = LogicalType(LogicalTypeId::SQLNULL);
88493
+ return nullptr;
88494
+ }
88419
88495
  D_ASSERT(input_type.id() == LogicalTypeId::LIST);
88420
88496
 
88421
88497
  auto child_type = ListType::GetChildType(input_type);
@@ -88619,8 +88695,8 @@ static unique_ptr<FunctionData> ListAggregateBind(ClientContext &context, Scalar
88619
88695
  return make_unique<VariableReturnBindData>(bound_function.return_type);
88620
88696
  }
88621
88697
 
88622
- D_ASSERT(LogicalTypeId::LIST == arguments[0]->return_type.id());
88623
- auto list_child_type = ListType::GetChildType(arguments[0]->return_type);
88698
+ bool is_parameter = arguments[0]->return_type.id() == LogicalTypeId::UNKNOWN;
88699
+ auto list_child_type = is_parameter ? LogicalTypeId::UNKNOWN : ListType::GetChildType(arguments[0]->return_type);
88624
88700
  bound_function.return_type = list_child_type;
88625
88701
 
88626
88702
  if (!arguments[1]->IsFoldable()) {
@@ -88636,8 +88712,7 @@ static unique_ptr<FunctionData> ListAggregateBind(ClientContext &context, Scalar
88636
88712
 
88637
88713
  // create the child expression and its type
88638
88714
  vector<unique_ptr<Expression>> children;
88639
- auto expr = make_unique<BoundConstantExpression>(Value(LogicalType::SQLNULL));
88640
- expr->return_type = list_child_type;
88715
+ auto expr = make_unique<BoundConstantExpression>(Value(list_child_type));
88641
88716
  children.push_back(move(expr));
88642
88717
 
88643
88718
  // look up the aggregate function in the catalog
@@ -88646,6 +88721,12 @@ static unique_ptr<FunctionData> ListAggregateBind(ClientContext &context, Scalar
88646
88721
  context, DEFAULT_SCHEMA, function_name, false, error_context);
88647
88722
  D_ASSERT(func->type == CatalogType::AGGREGATE_FUNCTION_ENTRY);
88648
88723
 
88724
+ if (is_parameter) {
88725
+ bound_function.arguments[0] = LogicalTypeId::UNKNOWN;
88726
+ bound_function.return_type = LogicalType::SQLNULL;
88727
+ return nullptr;
88728
+ }
88729
+
88649
88730
  // find a matching aggregate function
88650
88731
  string error;
88651
88732
  auto best_function_idx = Function::BindFunction(func->name, func->functions, types, error);
@@ -88657,8 +88738,8 @@ static unique_ptr<FunctionData> ListAggregateBind(ClientContext &context, Scalar
88657
88738
  auto &best_function = func->functions[best_function_idx];
88658
88739
  auto bound_aggr_function = AggregateFunction::BindAggregateFunction(context, best_function, move(children));
88659
88740
 
88660
- bound_function.arguments[0] =
88661
- LogicalType::LIST(bound_aggr_function->function.arguments[0]); // for proper casting of the vectors
88741
+ // for proper casting of the vectors
88742
+ bound_function.arguments[0] = LogicalType::LIST(bound_aggr_function->function.arguments[0]);
88662
88743
  bound_function.return_type = bound_aggr_function->function.return_type;
88663
88744
  return make_unique<ListAggregatesBindData>(bound_function.return_type, move(bound_aggr_function));
88664
88745
  }
@@ -88770,7 +88851,6 @@ static unique_ptr<FunctionData> ListConcatBind(ClientContext &context, ScalarFun
88770
88851
  for (const auto &argument : arguments) {
88771
88852
  child_type = LogicalType::MaxLogicalType(child_type, ListType::GetChildType(argument->return_type));
88772
88853
  }
88773
- ExpressionBinder::ResolveParameterType(child_type);
88774
88854
  auto list_type = LogicalType::LIST(move(child_type));
88775
88855
 
88776
88856
  bound_function.arguments[0] = list_type;
@@ -88970,8 +89050,8 @@ static void ExecuteListExtract(Vector &result, Vector &list, Vector &offsets, co
88970
89050
  }
88971
89051
 
88972
89052
  static void ExecuteStringExtract(Vector &result, Vector &input_vector, Vector &subscript_vector, const idx_t count) {
88973
- BinaryExecutor::Execute<string_t, int32_t, string_t>(
88974
- input_vector, subscript_vector, result, count, [&](string_t input_string, int32_t subscript) {
89053
+ BinaryExecutor::Execute<string_t, int64_t, string_t>(
89054
+ input_vector, subscript_vector, result, count, [&](string_t input_string, int64_t subscript) {
88975
89055
  return SubstringFun::SubstringScalarFunction(result, input_string, subscript, 1);
88976
89056
  });
88977
89057
  }
@@ -89041,7 +89121,7 @@ void ListExtractFun::RegisterFunction(BuiltinFunctions &set) {
89041
89121
  ScalarFunction lfun({LogicalType::LIST(LogicalType::ANY), LogicalType::BIGINT}, LogicalType::ANY,
89042
89122
  ListExtractFunction, false, false, ListExtractBind, nullptr, ListExtractStats);
89043
89123
 
89044
- ScalarFunction sfun({LogicalType::VARCHAR, LogicalType::INTEGER}, LogicalType::VARCHAR, ListExtractFunction, false,
89124
+ ScalarFunction sfun({LogicalType::VARCHAR, LogicalType::BIGINT}, LogicalType::VARCHAR, ListExtractFunction, false,
89045
89125
  false, nullptr);
89046
89126
 
89047
89127
  ScalarFunctionSet list_extract("list_extract");
@@ -89476,7 +89556,6 @@ static unique_ptr<FunctionData> ListValueBind(ClientContext &context, ScalarFunc
89476
89556
  for (idx_t i = 0; i < arguments.size(); i++) {
89477
89557
  child_type = LogicalType::MaxLogicalType(child_type, arguments[i]->return_type);
89478
89558
  }
89479
- ExpressionBinder::ResolveParameterType(child_type);
89480
89559
 
89481
89560
  // this is more for completeness reasons
89482
89561
  bound_function.varargs = child_type;
@@ -95458,6 +95537,10 @@ unique_ptr<FunctionData> BindPrintfFunction(ClientContext &context, ScalarFuncti
95458
95537
  // decimal type: add cast to double
95459
95538
  bound_function.arguments.emplace_back(LogicalType::DOUBLE);
95460
95539
  break;
95540
+ case LogicalTypeId::UNKNOWN:
95541
+ // parameter: accept any input and rebind later
95542
+ bound_function.arguments.emplace_back(LogicalType::ANY);
95543
+ break;
95461
95544
  default:
95462
95545
  // all other types: add cast to string
95463
95546
  bound_function.arguments.emplace_back(LogicalType::VARCHAR);
@@ -97168,7 +97251,6 @@ static unique_ptr<FunctionData> StructPackBind(ClientContext &context, ScalarFun
97168
97251
  if (name_collision_set.find(child->alias) != name_collision_set.end()) {
97169
97252
  throw BinderException("Duplicate struct entry name \"%s\"", child->alias);
97170
97253
  }
97171
- ExpressionBinder::ResolveParameterType(arguments[i]);
97172
97254
  name_collision_set.insert(child->alias);
97173
97255
  struct_children.push_back(make_pair(child->alias, arguments[i]->return_type));
97174
97256
  }
@@ -107650,6 +107732,7 @@ public:
107650
107732
  vector<string> names;
107651
107733
  vector<LogicalType> types;
107652
107734
  unordered_map<idx_t, vector<unique_ptr<Value>>> value_map;
107735
+ vector<LogicalType> parameter_types;
107653
107736
 
107654
107737
  shared_ptr<Binder> binder;
107655
107738
  ClientContext &context;
@@ -107657,18 +107740,13 @@ public:
107657
107740
  bool read_only;
107658
107741
  bool requires_valid_transaction;
107659
107742
  bool allow_stream_result;
107743
+ bool bound_all_parameters;
107660
107744
 
107661
107745
  private:
107662
107746
  void CreatePlan(SQLStatement &statement);
107663
107747
  shared_ptr<PreparedStatementData> PrepareSQLStatement(unique_ptr<SQLStatement> statement);
107664
107748
  void PlanPrepare(unique_ptr<SQLStatement> statement);
107665
107749
  void PlanExecute(unique_ptr<SQLStatement> statement);
107666
-
107667
- // void VerifyQuery(BoundSQLStatement &statement);
107668
- // void VerifyNode(BoundQueryNode &statement);
107669
- // void VerifyExpression(Expression &expr, vector<unique_ptr<Expression>> &copies);
107670
-
107671
- // bool StatementRequiresValidTransaction(BoundSQLStatement &statement);
107672
107750
  };
107673
107751
  } // namespace duckdb
107674
107752
 
@@ -107988,13 +108066,19 @@ unique_ptr<QueryResult> ClientContext::FetchResultInternal(ClientContextLock &lo
107988
108066
  }
107989
108067
 
107990
108068
  shared_ptr<PreparedStatementData> ClientContext::CreatePreparedStatement(ClientContextLock &lock, const string &query,
107991
- unique_ptr<SQLStatement> statement) {
108069
+ unique_ptr<SQLStatement> statement,
108070
+ vector<Value> *values) {
107992
108071
  StatementType statement_type = statement->type;
107993
108072
  auto result = make_shared<PreparedStatementData>(statement_type);
107994
108073
 
107995
108074
  auto &profiler = QueryProfiler::Get(*this);
107996
108075
  profiler.StartPhase("planner");
107997
108076
  Planner planner(*this);
108077
+ if (values) {
108078
+ for (auto &value : *values) {
108079
+ planner.parameter_types.push_back(value.type());
108080
+ }
108081
+ }
107998
108082
  planner.CreatePlan(move(statement));
107999
108083
  D_ASSERT(planner.plan);
108000
108084
  profiler.EndPhase();
@@ -108011,6 +108095,7 @@ shared_ptr<PreparedStatementData> ClientContext::CreatePreparedStatement(ClientC
108011
108095
  result->types = planner.types;
108012
108096
  result->value_map = move(planner.value_map);
108013
108097
  result->catalog_version = Transaction::GetTransaction(*this).catalog_version;
108098
+ result->bound_all_parameters = planner.bound_all_parameters;
108014
108099
 
108015
108100
  if (config.enable_optimizer) {
108016
108101
  profiler.StartPhase("optimizer");
@@ -108319,15 +108404,17 @@ ClientContext::PendingStatementOrPreparedStatement(ClientContextLock &lock, cons
108319
108404
  result = PendingStatementInternal(lock, query, move(statement));
108320
108405
  } else {
108321
108406
  auto &catalog = Catalog::GetCatalog(*this);
108322
- if (prepared->unbound_statement && catalog.GetCatalogVersion() != prepared->catalog_version) {
108323
- D_ASSERT(prepared->unbound_statement.get());
108407
+ if (prepared->unbound_statement &&
108408
+ (catalog.GetCatalogVersion() != prepared->catalog_version || !prepared->bound_all_parameters)) {
108324
108409
  // catalog was modified: rebind the statement before execution
108325
- auto new_prepared = CreatePreparedStatement(lock, query, prepared->unbound_statement->Copy());
108326
- if (prepared->types != new_prepared->types) {
108410
+ auto new_prepared = CreatePreparedStatement(lock, query, prepared->unbound_statement->Copy(), values);
108411
+ if (prepared->types != new_prepared->types && prepared->bound_all_parameters) {
108327
108412
  throw BinderException("Rebinding statement after catalog change resulted in change of types");
108328
108413
  }
108414
+ D_ASSERT(new_prepared->bound_all_parameters);
108329
108415
  new_prepared->unbound_statement = move(prepared->unbound_statement);
108330
108416
  prepared = move(new_prepared);
108417
+ prepared->bound_all_parameters = false;
108331
108418
  }
108332
108419
  result = PendingPreparedStatement(lock, prepared, *values);
108333
108420
  }
@@ -118881,7 +118968,8 @@ unique_ptr<PendingQueryResult> PreparedStatement::PendingQuery(vector<Value> &va
118881
118968
  namespace duckdb {
118882
118969
 
118883
118970
  PreparedStatementData::PreparedStatementData(StatementType type)
118884
- : statement_type(type), read_only(true), requires_valid_transaction(true), allow_stream_result(false) {
118971
+ : statement_type(type), read_only(true), requires_valid_transaction(true), allow_stream_result(false),
118972
+ bound_all_parameters(true) {
118885
118973
  }
118886
118974
 
118887
118975
  PreparedStatementData::~PreparedStatementData() {
@@ -153608,7 +153696,8 @@ BindResult SelectBinder::BindAggregate(FunctionExpression &aggr, AggregateFuncti
153608
153696
  }
153609
153697
 
153610
153698
  // bind the aggregate
153611
- idx_t best_function = Function::BindFunction(func->name, func->functions, types, error);
153699
+ bool cast_parameters;
153700
+ idx_t best_function = Function::BindFunction(func->name, func->functions, types, error, cast_parameters);
153612
153701
  if (best_function == DConstants::INVALID_INDEX) {
153613
153702
  throw BinderException(binder.FormatError(aggr, error));
153614
153703
  }
@@ -153628,8 +153717,8 @@ BindResult SelectBinder::BindAggregate(FunctionExpression &aggr, AggregateFuncti
153628
153717
  }
153629
153718
  }
153630
153719
 
153631
- auto aggregate = AggregateFunction::BindAggregateFunction(context, bound_function, move(children),
153632
- move(bound_filter), aggr.distinct, move(order_bys));
153720
+ auto aggregate = AggregateFunction::BindAggregateFunction(
153721
+ context, bound_function, move(children), move(bound_filter), aggr.distinct, move(order_bys), cast_parameters);
153633
153722
  if (aggr.export_state) {
153634
153723
  aggregate = ExportAggregateFunction::Bind(move(aggregate));
153635
153724
  }
@@ -153741,7 +153830,6 @@ BindResult ExpressionBinder::BindExpression(CaseExpression &expr, idx_t depth) {
153741
153830
  auto &then_expr = (BoundExpression &)*check.then_expr;
153742
153831
  return_type = LogicalType::MaxLogicalType(return_type, then_expr.expr->return_type);
153743
153832
  }
153744
- ExpressionBinder::ResolveParameterType(return_type);
153745
153833
 
153746
153834
  // bind all the individual components of the CASE statement
153747
153835
  auto result = make_unique<BoundCaseExpression>(return_type);
@@ -154167,10 +154255,6 @@ LogicalType BoundComparisonExpression::BindComparison(LogicalType left_type, Log
154167
154255
  }
154168
154256
  }
154169
154257
  return result_type;
154170
- case LogicalTypeId::UNKNOWN:
154171
- // comparing two prepared statement parameters (e.g. SELECT ?=?)
154172
- // default to VARCHAR
154173
- return LogicalType::VARCHAR;
154174
154258
  default:
154175
154259
  return result_type;
154176
154260
  }
@@ -154483,7 +154567,6 @@ static LogicalType ResolveInType(OperatorExpression &op, vector<BoundExpression
154483
154567
  for (idx_t i = 1; i < children.size(); i++) {
154484
154568
  max_type = LogicalType::MaxLogicalType(max_type, children[i]->expr->return_type);
154485
154569
  }
154486
- ExpressionBinder::ResolveParameterType(max_type);
154487
154570
 
154488
154571
  // cast all children to the same type
154489
154572
  for (idx_t i = 0; i < children.size(); i++) {
@@ -154498,7 +154581,6 @@ static LogicalType ResolveOperatorType(OperatorExpression &op, vector<BoundExpre
154498
154581
  case ExpressionType::OPERATOR_IS_NULL:
154499
154582
  case ExpressionType::OPERATOR_IS_NOT_NULL:
154500
154583
  // IS (NOT) NULL always returns a boolean, and does not cast its children
154501
- ExpressionBinder::ResolveParameterType(children[0]->expr);
154502
154584
  return LogicalType::BOOLEAN;
154503
154585
  case ExpressionType::COMPARE_IN:
154504
154586
  case ExpressionType::COMPARE_NOT_IN:
@@ -154612,6 +154694,9 @@ BindResult ExpressionBinder::BindExpression(ParameterExpression &expr, idx_t dep
154612
154694
  throw std::runtime_error("Unexpected prepared parameter. This type of statement can't be prepared!");
154613
154695
  }
154614
154696
  binder.parameters->push_back(bound_parameter.get());
154697
+ if (binder.parameter_types && expr.parameter_nr <= binder.parameter_types->size()) {
154698
+ bound_parameter->return_type = (*binder.parameter_types)[expr.parameter_nr - 1];
154699
+ }
154615
154700
  return BindResult(move(bound_parameter));
154616
154701
  }
154617
154702
 
@@ -154708,7 +154793,9 @@ BindResult ExpressionBinder::BindExpression(SubqueryExpression &expr, idx_t dept
154708
154793
  auto bound_node = move(bound_subquery->bound_node);
154709
154794
  LogicalType return_type =
154710
154795
  expr.subquery_type == SubqueryType::SCALAR ? bound_node->types[0] : LogicalType(LogicalTypeId::BOOLEAN);
154711
- D_ASSERT(return_type.id() != LogicalTypeId::UNKNOWN);
154796
+ if (return_type.id() == LogicalTypeId::UNKNOWN) {
154797
+ return_type = LogicalType::SQLNULL;
154798
+ }
154712
154799
 
154713
154800
  auto result = make_unique<BoundSubqueryExpression>(return_type);
154714
154801
  if (expr.subquery_type == SubqueryType::ANY) {
@@ -160081,6 +160168,7 @@ Binder::Binder(bool, ClientContext &context, shared_ptr<Binder> parent_p, bool i
160081
160168
  : context(context), read_only(true), requires_valid_transaction(true), allow_stream_result(false),
160082
160169
  parent(move(parent_p)), bound_tables(0), inherit_ctes(inherit_ctes_p) {
160083
160170
  parameters = nullptr;
160171
+ parameter_types = nullptr;
160084
160172
  if (parent) {
160085
160173
  // We have to inherit macro parameter bindings from the parent binder, if there is a parent.
160086
160174
  macro_binding = parent->macro_binding;
@@ -160089,6 +160177,7 @@ Binder::Binder(bool, ClientContext &context, shared_ptr<Binder> parent_p, bool i
160089
160177
  bind_context.SetCTEBindings(parent->bind_context.GetCTEBindings());
160090
160178
  bind_context.cte_references = parent->bind_context.cte_references;
160091
160179
  parameters = parent->parameters;
160180
+ parameter_types = parent->parameter_types;
160092
160181
  }
160093
160182
  }
160094
160183
  }
@@ -162459,19 +162548,6 @@ LogicalType ExpressionBinder::ExchangeNullType(const LogicalType &type) {
162459
162548
  return ExchangeType(type, LogicalTypeId::SQLNULL, LogicalType::INTEGER);
162460
162549
  }
162461
162550
 
162462
- void ExpressionBinder::ResolveParameterType(LogicalType &type) {
162463
- if (type.id() == LogicalTypeId::UNKNOWN) {
162464
- type = LogicalType::VARCHAR;
162465
- }
162466
- }
162467
-
162468
- void ExpressionBinder::ResolveParameterType(unique_ptr<Expression> &expr) {
162469
- if (ContainsType(expr->return_type, LogicalTypeId::UNKNOWN)) {
162470
- auto result_type = ExchangeType(expr->return_type, LogicalTypeId::UNKNOWN, LogicalType::VARCHAR);
162471
- expr = BoundCastExpression::AddCastToType(move(expr), result_type);
162472
- }
162473
- }
162474
-
162475
162551
  unique_ptr<Expression> ExpressionBinder::Bind(unique_ptr<ParsedExpression> &expr, LogicalType *result_type,
162476
162552
  bool root_expression) {
162477
162553
  // bind the main expression
@@ -162500,9 +162576,6 @@ unique_ptr<Expression> ExpressionBinder::Bind(unique_ptr<ParsedExpression> &expr
162500
162576
  result = BoundCastExpression::AddCastToType(move(result), result_type);
162501
162577
  }
162502
162578
  }
162503
- // check if we failed to convert any parameters
162504
- // if we did, we push a cast
162505
- ExpressionBinder::ResolveParameterType(result);
162506
162579
  }
162507
162580
  if (result_type) {
162508
162581
  *result_type = result->return_type;
@@ -163908,6 +163981,7 @@ void Planner::CreatePlan(SQLStatement &statement) {
163908
163981
  // first bind the tables and columns to the catalog
163909
163982
  profiler.StartPhase("binder");
163910
163983
  binder->parameters = &bound_parameters;
163984
+ binder->parameter_types = &parameter_types;
163911
163985
  auto bound_statement = binder->Bind(statement);
163912
163986
  profiler.EndPhase();
163913
163987
 
@@ -163917,20 +163991,23 @@ void Planner::CreatePlan(SQLStatement &statement) {
163917
163991
  this->names = bound_statement.names;
163918
163992
  this->types = bound_statement.types;
163919
163993
  this->plan = move(bound_statement.plan);
163994
+ this->bound_all_parameters = true;
163920
163995
 
163921
163996
  // set up a map of parameter number -> value entries
163922
163997
  for (auto &expr : bound_parameters) {
163923
163998
  // check if the type of the parameter could be resolved
163924
163999
  if (expr->return_type.id() == LogicalTypeId::INVALID || expr->return_type.id() == LogicalTypeId::UNKNOWN) {
163925
- throw BinderException("Could not determine type of parameters");
164000
+ this->bound_all_parameters = false;
164001
+ continue;
163926
164002
  }
163927
164003
  auto value = make_unique<Value>(expr->return_type);
163928
164004
  expr->value = value.get();
163929
164005
  // check if the parameter number has been used before
163930
- if (value_map.find(expr->parameter_nr) == value_map.end()) {
164006
+ auto entry = value_map.find(expr->parameter_nr);
164007
+ if (entry == value_map.end()) {
163931
164008
  // not used before, create vector
163932
164009
  value_map[expr->parameter_nr] = vector<unique_ptr<Value>>();
163933
- } else if (value_map[expr->parameter_nr].back()->type() != value->type()) {
164010
+ } else if (entry->second.back()->type() != value->type()) {
163934
164011
  // used before, but types are inconsistent
163935
164012
  throw BinderException("Inconsistent types found for parameter with index %llu", expr->parameter_nr);
163936
164013
  }
@@ -163952,6 +164029,7 @@ shared_ptr<PreparedStatementData> Planner::PrepareSQLStatement(unique_ptr<SQLSta
163952
164029
  prepared_data->requires_valid_transaction = this->requires_valid_transaction;
163953
164030
  prepared_data->allow_stream_result = this->allow_stream_result;
163954
164031
  prepared_data->catalog_version = Transaction::GetTransaction(context).catalog_version;
164032
+ prepared_data->bound_all_parameters = this->bound_all_parameters;
163955
164033
  return prepared_data;
163956
164034
  }
163957
164035
 
@@ -163969,30 +164047,43 @@ void Planner::PlanExecute(unique_ptr<SQLStatement> statement) {
163969
164047
  auto prepared = entry->second;
163970
164048
  auto &catalog = Catalog::GetCatalog(context);
163971
164049
  bool rebound = false;
163972
- if (catalog.GetCatalogVersion() != entry->second->catalog_version) {
163973
- // catalog was modified: rebind the statement before running the execute
163974
- prepared = PrepareSQLStatement(entry->second->unbound_statement->Copy());
163975
- if (prepared->types != entry->second->types) {
163976
- throw BinderException("Rebinding statement \"%s\" after catalog change resulted in change of types",
163977
- stmt.name);
163978
- }
163979
- rebound = true;
163980
- }
163981
164050
 
163982
- // the bound prepared statement is ready: bind any supplied parameters
164051
+ // bind any supplied parameters
163983
164052
  vector<Value> bind_values;
163984
164053
  for (idx_t i = 0; i < stmt.values.size(); i++) {
163985
164054
  ConstantBinder cbinder(*binder, context, "EXECUTE statement");
163986
- if (prepared->value_map.count(i + 1)) {
163987
- cbinder.target_type = prepared->GetType(i + 1);
163988
- }
163989
164055
  auto bound_expr = cbinder.Bind(stmt.values[i]);
163990
164056
 
163991
164057
  Value value = ExpressionExecutor::EvaluateScalar(*bound_expr);
163992
164058
  bind_values.push_back(move(value));
163993
164059
  }
164060
+ bool all_bound = prepared->bound_all_parameters;
164061
+ if (catalog.GetCatalogVersion() != entry->second->catalog_version || !all_bound) {
164062
+ // catalog was modified or statement does not have clear types: rebind the statement before running the execute
164063
+ for (auto &value : bind_values) {
164064
+ parameter_types.push_back(value.type());
164065
+ }
164066
+ prepared = PrepareSQLStatement(entry->second->unbound_statement->Copy());
164067
+ if (all_bound && prepared->types != entry->second->types) {
164068
+ throw BinderException("Rebinding statement \"%s\" after catalog change resulted in change of types",
164069
+ stmt.name);
164070
+ }
164071
+ D_ASSERT(prepared->bound_all_parameters);
164072
+ rebound = true;
164073
+ }
164074
+ // add casts to the prepared statement parameters as required
164075
+ for (idx_t i = 0; i < bind_values.size(); i++) {
164076
+ if (prepared->value_map.count(i + 1) == 0) {
164077
+ continue;
164078
+ }
164079
+ bind_values[i] = bind_values[i].CastAs(prepared->GetType(i + 1));
164080
+ }
164081
+
163994
164082
  prepared->Bind(move(bind_values));
163995
164083
  if (rebound) {
164084
+ auto execute_plan = make_unique<LogicalExecute>(move(prepared));
164085
+ execute_plan->children.push_back(move(plan));
164086
+ this->plan = move(execute_plan);
163996
164087
  return;
163997
164088
  }
163998
164089
 
@@ -164002,6 +164093,7 @@ void Planner::PlanExecute(unique_ptr<SQLStatement> statement) {
164002
164093
  this->allow_stream_result = prepared->allow_stream_result;
164003
164094
  this->names = prepared->names;
164004
164095
  this->types = prepared->types;
164096
+ this->bound_all_parameters = prepared->bound_all_parameters;
164005
164097
  this->plan = make_unique<LogicalExecute>(move(prepared));
164006
164098
  }
164007
164099
 
@@ -164016,6 +164108,7 @@ void Planner::PlanPrepare(unique_ptr<SQLStatement> statement) {
164016
164108
  // this is required because most clients ALWAYS invoke prepared statements
164017
164109
  this->requires_valid_transaction = false;
164018
164110
  this->allow_stream_result = false;
164111
+ this->bound_all_parameters = true;
164019
164112
  this->names = {"Success"};
164020
164113
  this->types = {LogicalType::BOOLEAN};
164021
164114
  this->plan = move(prepare);