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/package.json +1 -1
- package/src/duckdb.cpp +271 -178
- package/src/duckdb.hpp +18 -15
- package/src/parquet-amalgamation.cpp +27998 -27998
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
|
-
|
|
70510
|
-
|
|
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
|
|
81357
|
-
// NULL expression
|
|
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
|
|
81828
|
-
|
|
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>
|
|
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
|
-
|
|
81859
|
+
candidate_functions.push_back(f_idx);
|
|
81842
81860
|
continue;
|
|
81843
81861
|
}
|
|
81844
81862
|
if (cost > lowest_cost) {
|
|
81845
81863
|
continue;
|
|
81846
81864
|
}
|
|
81847
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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::
|
|
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
|
-
|
|
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
|
-
|
|
82024
|
-
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
88661
|
-
|
|
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,
|
|
88974
|
-
input_vector, subscript_vector, result, count, [&](string_t input_string,
|
|
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::
|
|
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 &&
|
|
108323
|
-
|
|
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
|
-
|
|
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(
|
|
153632
|
-
|
|
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
|
-
|
|
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 = ¶meter_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
|
-
|
|
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
|
-
|
|
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 (
|
|
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
|
-
//
|
|
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);
|