duckdb 0.3.2-dev5.0 → 0.3.2-dev68.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 +1120 -590
- package/src/duckdb.hpp +14 -4
package/src/duckdb.cpp
CHANGED
|
@@ -679,6 +679,7 @@ public:
|
|
|
679
679
|
|
|
680
680
|
|
|
681
681
|
|
|
682
|
+
|
|
682
683
|
namespace duckdb {
|
|
683
684
|
|
|
684
685
|
//! Represents a reference to a column from either the FROM clause or from an
|
|
@@ -689,13 +690,16 @@ public:
|
|
|
689
690
|
ColumnRefExpression(string column_name, string table_name);
|
|
690
691
|
//! Only specify the column name, the table name will be derived later
|
|
691
692
|
explicit ColumnRefExpression(string column_name);
|
|
693
|
+
//! Specify a set of names
|
|
694
|
+
explicit ColumnRefExpression(vector<string> column_names);
|
|
692
695
|
|
|
693
|
-
//!
|
|
694
|
-
string
|
|
695
|
-
//! Table name of the column name that is referenced (optional)
|
|
696
|
-
string table_name;
|
|
696
|
+
//! The stack of names in order of which they appear (column_names[0].column_names[1].column_names[2]....)
|
|
697
|
+
vector<string> column_names;
|
|
697
698
|
|
|
698
699
|
public:
|
|
700
|
+
bool IsQualified() const;
|
|
701
|
+
const string &GetColumnName() const;
|
|
702
|
+
const string &GetTableName() const;
|
|
699
703
|
bool IsScalar() const override {
|
|
700
704
|
return false;
|
|
701
705
|
}
|
|
@@ -972,6 +976,8 @@ struct BoundColumnReferenceInfo {
|
|
|
972
976
|
};
|
|
973
977
|
|
|
974
978
|
struct BindResult {
|
|
979
|
+
BindResult() {
|
|
980
|
+
}
|
|
975
981
|
explicit BindResult(string error) : error(error) {
|
|
976
982
|
}
|
|
977
983
|
explicit BindResult(unique_ptr<Expression> expr) : expression(move(expr)) {
|
|
@@ -1008,9 +1014,16 @@ public:
|
|
|
1008
1014
|
|
|
1009
1015
|
string Bind(unique_ptr<ParsedExpression> *expr, idx_t depth, bool root_expression = false);
|
|
1010
1016
|
|
|
1017
|
+
unique_ptr<ParsedExpression> CreateStructExtract(unique_ptr<ParsedExpression> base, string field_name);
|
|
1018
|
+
BindResult BindQualifiedColumnName(ColumnRefExpression &colref, const string &table_name);
|
|
1019
|
+
|
|
1020
|
+
unique_ptr<ParsedExpression> QualifyColumnName(const string &column_name, string &error_message);
|
|
1021
|
+
unique_ptr<ParsedExpression> QualifyColumnName(ColumnRefExpression &colref, string &error_message);
|
|
1022
|
+
|
|
1011
1023
|
// Bind table names to ColumnRefExpressions
|
|
1012
|
-
|
|
1013
|
-
|
|
1024
|
+
void QualifyColumnNames(unique_ptr<ParsedExpression> &expr);
|
|
1025
|
+
static void QualifyColumnNames(Binder &binder, unique_ptr<ParsedExpression> &expr);
|
|
1026
|
+
|
|
1014
1027
|
static unique_ptr<Expression> PushCollation(ClientContext &context, unique_ptr<Expression> source,
|
|
1015
1028
|
const string &collation, bool equality_only = false);
|
|
1016
1029
|
static void TestCollation(ClientContext &context, const string &collation);
|
|
@@ -1058,9 +1071,7 @@ protected:
|
|
|
1058
1071
|
virtual BindResult BindMacro(FunctionExpression &expr, MacroCatalogEntry *macro, idx_t depth,
|
|
1059
1072
|
unique_ptr<ParsedExpression> *expr_ptr);
|
|
1060
1073
|
|
|
1061
|
-
|
|
1062
|
-
virtual void ReplaceMacroParametersRecursive(ParsedExpression &expr, QueryNode &node);
|
|
1063
|
-
virtual void ReplaceMacroParametersRecursive(ParsedExpression &expr, TableRef &ref);
|
|
1074
|
+
void ReplaceMacroParametersRecursive(unique_ptr<ParsedExpression> &expr);
|
|
1064
1075
|
|
|
1065
1076
|
virtual string UnsupportedAggregateMessage();
|
|
1066
1077
|
virtual string UnsupportedUnnestMessage();
|
|
@@ -1117,8 +1128,11 @@ struct Binding {
|
|
|
1117
1128
|
|
|
1118
1129
|
public:
|
|
1119
1130
|
bool TryGetBindingIndex(const string &column_name, column_t &column_index);
|
|
1131
|
+
column_t GetBindingIndex(const string &column_name);
|
|
1120
1132
|
bool HasMatchingBinding(const string &column_name);
|
|
1133
|
+
virtual string ColumnNotFoundError(const string &column_name) const;
|
|
1121
1134
|
virtual BindResult Bind(ColumnRefExpression &colref, idx_t depth);
|
|
1135
|
+
virtual TableCatalogEntry *GetTableEntry();
|
|
1122
1136
|
};
|
|
1123
1137
|
|
|
1124
1138
|
//! TableBinding is exactly like the Binding, except it keeps track of which columns were bound in the linked LogicalGet
|
|
@@ -1132,11 +1146,16 @@ struct TableBinding : public Binding {
|
|
|
1132
1146
|
|
|
1133
1147
|
public:
|
|
1134
1148
|
BindResult Bind(ColumnRefExpression &colref, idx_t depth) override;
|
|
1149
|
+
TableCatalogEntry *GetTableEntry() override;
|
|
1150
|
+
string ColumnNotFoundError(const string &column_name) const override;
|
|
1135
1151
|
};
|
|
1136
1152
|
|
|
1137
1153
|
//! MacroBinding is like the Binding, except the alias and index are set by default. Used for binding Macro
|
|
1138
1154
|
//! Params/Arguments.
|
|
1139
1155
|
struct MacroBinding : public Binding {
|
|
1156
|
+
static constexpr const char *MACRO_NAME = "0_macro_parameters";
|
|
1157
|
+
|
|
1158
|
+
public:
|
|
1140
1159
|
MacroBinding(vector<LogicalType> types_p, vector<string> names_p, string macro_name);
|
|
1141
1160
|
|
|
1142
1161
|
//! Arguments
|
|
@@ -1191,6 +1210,10 @@ public:
|
|
|
1191
1210
|
string BindColumn(PositionalReferenceExpression &ref, string &table_name, string &column_name);
|
|
1192
1211
|
BindResult BindColumn(PositionalReferenceExpression &ref, idx_t depth);
|
|
1193
1212
|
|
|
1213
|
+
unique_ptr<ParsedExpression> CreateColumnReference(const string &table_name, const string &column_name);
|
|
1214
|
+
unique_ptr<ParsedExpression> CreateColumnReference(const string &schema_name, const string &table_name,
|
|
1215
|
+
const string &column_name);
|
|
1216
|
+
|
|
1194
1217
|
//! Generate column expressions for all columns that are present in the
|
|
1195
1218
|
//! referenced tables. This is used to resolve the * expression in a
|
|
1196
1219
|
//! selection list.
|
|
@@ -1259,12 +1282,13 @@ public:
|
|
|
1259
1282
|
//! Add all the bindings from a BindContext to this BindContext. The other BindContext is destroyed in the process.
|
|
1260
1283
|
void AddContext(BindContext other);
|
|
1261
1284
|
|
|
1262
|
-
private:
|
|
1263
|
-
void AddBinding(const string &alias, unique_ptr<Binding> binding);
|
|
1264
1285
|
//! Gets a binding of the specified name. Returns a nullptr and sets the out_error if the binding could not be
|
|
1265
1286
|
//! found.
|
|
1266
1287
|
Binding *GetBinding(const string &name, string &out_error);
|
|
1267
1288
|
|
|
1289
|
+
private:
|
|
1290
|
+
void AddBinding(const string &alias, unique_ptr<Binding> binding);
|
|
1291
|
+
|
|
1268
1292
|
private:
|
|
1269
1293
|
//! The set of bindings
|
|
1270
1294
|
case_insensitive_map_t<unique_ptr<Binding>> bindings;
|
|
@@ -1456,6 +1480,10 @@ public:
|
|
|
1456
1480
|
|
|
1457
1481
|
static void BindLogicalType(ClientContext &context, LogicalType &type, const string &schema = "");
|
|
1458
1482
|
|
|
1483
|
+
bool HasMatchingBinding(const string &table_name, const string &column_name, string &error_message);
|
|
1484
|
+
bool HasMatchingBinding(const string &schema_name, const string &table_name, const string &column_name,
|
|
1485
|
+
string &error_message);
|
|
1486
|
+
|
|
1459
1487
|
private:
|
|
1460
1488
|
//! The parent binder (if any)
|
|
1461
1489
|
shared_ptr<Binder> parent;
|
|
@@ -7765,6 +7793,7 @@ private:
|
|
|
7765
7793
|
|
|
7766
7794
|
|
|
7767
7795
|
|
|
7796
|
+
|
|
7768
7797
|
#include <functional>
|
|
7769
7798
|
|
|
7770
7799
|
namespace duckdb {
|
|
@@ -7776,6 +7805,11 @@ public:
|
|
|
7776
7805
|
static void EnumerateChildren(ParsedExpression &expr, const std::function<void(ParsedExpression &child)> &callback);
|
|
7777
7806
|
static void EnumerateChildren(ParsedExpression &expr,
|
|
7778
7807
|
const std::function<void(unique_ptr<ParsedExpression> &child)> &callback);
|
|
7808
|
+
|
|
7809
|
+
static void EnumerateTableRefChildren(TableRef &ref,
|
|
7810
|
+
const std::function<void(unique_ptr<ParsedExpression> &child)> &callback);
|
|
7811
|
+
static void EnumerateQueryNodeChildren(QueryNode &node,
|
|
7812
|
+
const std::function<void(unique_ptr<ParsedExpression> &child)> &callback);
|
|
7779
7813
|
};
|
|
7780
7814
|
|
|
7781
7815
|
} // namespace duckdb
|
|
@@ -7962,8 +7996,8 @@ unique_ptr<CatalogEntry> TableCatalogEntry::AlterEntry(ClientContext &context, A
|
|
|
7962
7996
|
static void RenameExpression(ParsedExpression &expr, RenameColumnInfo &info) {
|
|
7963
7997
|
if (expr.type == ExpressionType::COLUMN_REF) {
|
|
7964
7998
|
auto &colref = (ColumnRefExpression &)expr;
|
|
7965
|
-
if (colref.
|
|
7966
|
-
colref.
|
|
7999
|
+
if (colref.column_names[0] == info.old_name) {
|
|
8000
|
+
colref.column_names[0] = info.new_name;
|
|
7967
8001
|
}
|
|
7968
8002
|
}
|
|
7969
8003
|
ParsedExpressionIterator::EnumerateChildren(
|
|
@@ -11143,6 +11177,8 @@ string PhysicalOperatorToString(PhysicalOperatorType type) {
|
|
|
11143
11177
|
return "CREATE_INDEX";
|
|
11144
11178
|
case PhysicalOperatorType::EXPLAIN:
|
|
11145
11179
|
return "EXPLAIN";
|
|
11180
|
+
case PhysicalOperatorType::EXPLAIN_ANALYZE:
|
|
11181
|
+
return "EXPLAIN_ANALYZE";
|
|
11146
11182
|
case PhysicalOperatorType::EXECUTE:
|
|
11147
11183
|
return "EXECUTE";
|
|
11148
11184
|
case PhysicalOperatorType::VACUUM:
|
|
@@ -18315,7 +18351,7 @@ struct RegexpFun {
|
|
|
18315
18351
|
|
|
18316
18352
|
struct SubstringFun {
|
|
18317
18353
|
static void RegisterFunction(BuiltinFunctions &set);
|
|
18318
|
-
static string_t SubstringScalarFunction(Vector &result, string_t input,
|
|
18354
|
+
static string_t SubstringScalarFunction(Vector &result, string_t input, int64_t offset, int64_t length);
|
|
18319
18355
|
};
|
|
18320
18356
|
|
|
18321
18357
|
struct PrintfFun {
|
|
@@ -31936,6 +31972,7 @@ struct ExpressionInfo {
|
|
|
31936
31972
|
vector<unique_ptr<ExpressionInfo>> children;
|
|
31937
31973
|
// Extract ExpressionInformation from a given expression state
|
|
31938
31974
|
void ExtractExpressionsRecursive(unique_ptr<ExpressionState> &state);
|
|
31975
|
+
|
|
31939
31976
|
//! Whether or not expression has function
|
|
31940
31977
|
bool hasfunction;
|
|
31941
31978
|
//! The function Name
|
|
@@ -31951,6 +31988,7 @@ struct ExpressionInfo {
|
|
|
31951
31988
|
//! The ExpressionRootInfo keeps information related to the root of an expression tree
|
|
31952
31989
|
struct ExpressionRootInfo {
|
|
31953
31990
|
ExpressionRootInfo(ExpressionExecutorState &executor, string name);
|
|
31991
|
+
|
|
31954
31992
|
//! Count the number of time the executor called
|
|
31955
31993
|
uint64_t total_count = 0;
|
|
31956
31994
|
//! Count the number of time the executor called since last sampling
|
|
@@ -31974,6 +32012,7 @@ struct ExpressionRootInfo {
|
|
|
31974
32012
|
struct ExpressionExecutorInfo {
|
|
31975
32013
|
explicit ExpressionExecutorInfo() {};
|
|
31976
32014
|
explicit ExpressionExecutorInfo(ExpressionExecutor &executor, const string &name, int id);
|
|
32015
|
+
|
|
31977
32016
|
//! A vector which contain the pointer to all ExpressionRootInfo
|
|
31978
32017
|
vector<unique_ptr<ExpressionRootInfo>> roots;
|
|
31979
32018
|
//! Id, it will be used as index for executors_info vector
|
|
@@ -31981,11 +32020,12 @@ struct ExpressionExecutorInfo {
|
|
|
31981
32020
|
};
|
|
31982
32021
|
|
|
31983
32022
|
struct OperatorInformation {
|
|
32023
|
+
explicit OperatorInformation(double time_ = 0, idx_t elements_ = 0) : time(time_), elements(elements_) {
|
|
32024
|
+
}
|
|
32025
|
+
|
|
31984
32026
|
double time = 0;
|
|
31985
32027
|
idx_t elements = 0;
|
|
31986
32028
|
string name;
|
|
31987
|
-
explicit OperatorInformation(double time_ = 0, idx_t elements_ = 0) : time(time_), elements(elements_) {
|
|
31988
|
-
}
|
|
31989
32029
|
//! A vector of Expression Executor Info
|
|
31990
32030
|
vector<unique_ptr<ExpressionExecutorInfo>> executors_info;
|
|
31991
32031
|
};
|
|
@@ -32023,9 +32063,16 @@ class QueryProfiler {
|
|
|
32023
32063
|
public:
|
|
32024
32064
|
DUCKDB_API QueryProfiler()
|
|
32025
32065
|
: automatic_print_format(ProfilerPrintFormat::NONE), enabled(false), detailed_enabled(false), running(false),
|
|
32026
|
-
query_requires_profiling(false)
|
|
32066
|
+
query_requires_profiling(false), is_explain_analyze(false), stored_enabled(false),
|
|
32067
|
+
stored_automatic_print_format(ProfilerPrintFormat::NONE) {
|
|
32027
32068
|
}
|
|
32028
32069
|
|
|
32070
|
+
//! The format to automatically print query profiling information in (default: disabled)
|
|
32071
|
+
ProfilerPrintFormat automatic_print_format;
|
|
32072
|
+
//! The file to save query profiling information to, instead of printing it to the console (empty = print to
|
|
32073
|
+
//! console)
|
|
32074
|
+
string save_location;
|
|
32075
|
+
|
|
32029
32076
|
public:
|
|
32030
32077
|
struct TreeNode {
|
|
32031
32078
|
PhysicalOperatorType type;
|
|
@@ -32069,9 +32116,11 @@ public:
|
|
|
32069
32116
|
return detailed_enabled;
|
|
32070
32117
|
}
|
|
32071
32118
|
|
|
32072
|
-
DUCKDB_API void StartQuery(string query);
|
|
32119
|
+
DUCKDB_API void StartQuery(string query, bool is_explain_analyze = false);
|
|
32073
32120
|
DUCKDB_API void EndQuery();
|
|
32074
32121
|
|
|
32122
|
+
DUCKDB_API void StartExplainAnalyze();
|
|
32123
|
+
|
|
32075
32124
|
//! Adds the timings gathered by an OperatorProfiler to this query profiler
|
|
32076
32125
|
DUCKDB_API void Flush(OperatorProfiler &profiler);
|
|
32077
32126
|
|
|
@@ -32087,12 +32136,6 @@ public:
|
|
|
32087
32136
|
DUCKDB_API string ToJSON() const;
|
|
32088
32137
|
DUCKDB_API void WriteToFile(const char *path, string &info) const;
|
|
32089
32138
|
|
|
32090
|
-
//! The format to automatically print query profiling information in (default: disabled)
|
|
32091
|
-
ProfilerPrintFormat automatic_print_format;
|
|
32092
|
-
//! The file to save query profiling information to, instead of printing it to the console (empty = print to
|
|
32093
|
-
//! console)
|
|
32094
|
-
string save_location;
|
|
32095
|
-
|
|
32096
32139
|
idx_t OperatorSize() {
|
|
32097
32140
|
return tree_map.size();
|
|
32098
32141
|
}
|
|
@@ -32118,6 +32161,11 @@ private:
|
|
|
32118
32161
|
//! A map of a Physical Operator pointer to a tree node
|
|
32119
32162
|
TreeMap tree_map;
|
|
32120
32163
|
|
|
32164
|
+
bool is_explain_analyze;
|
|
32165
|
+
bool stored_enabled;
|
|
32166
|
+
ProfilerPrintFormat stored_automatic_print_format;
|
|
32167
|
+
string stored_save_location;
|
|
32168
|
+
|
|
32121
32169
|
public:
|
|
32122
32170
|
const TreeMap &GetTreeMap() const {
|
|
32123
32171
|
return tree_map;
|
|
@@ -37228,6 +37276,52 @@ bool Interval::GreaterThanEquals(interval_t left, interval_t right) {
|
|
|
37228
37276
|
return GreaterThan(left, right) || Equals(left, right);
|
|
37229
37277
|
}
|
|
37230
37278
|
|
|
37279
|
+
date_t Interval::Add(date_t left, interval_t right) {
|
|
37280
|
+
date_t result;
|
|
37281
|
+
if (right.months != 0) {
|
|
37282
|
+
int32_t year, month, day;
|
|
37283
|
+
Date::Convert(left, year, month, day);
|
|
37284
|
+
int32_t year_diff = right.months / Interval::MONTHS_PER_YEAR;
|
|
37285
|
+
year += year_diff;
|
|
37286
|
+
month += right.months - year_diff * Interval::MONTHS_PER_YEAR;
|
|
37287
|
+
if (month > Interval::MONTHS_PER_YEAR) {
|
|
37288
|
+
year++;
|
|
37289
|
+
month -= Interval::MONTHS_PER_YEAR;
|
|
37290
|
+
} else if (month <= 0) {
|
|
37291
|
+
year--;
|
|
37292
|
+
month += Interval::MONTHS_PER_YEAR;
|
|
37293
|
+
}
|
|
37294
|
+
day = MinValue<int32_t>(day, Date::MonthDays(year, month));
|
|
37295
|
+
result = Date::FromDate(year, month, day);
|
|
37296
|
+
} else {
|
|
37297
|
+
result = left;
|
|
37298
|
+
}
|
|
37299
|
+
if (right.days != 0) {
|
|
37300
|
+
if (!TryAddOperator::Operation(result.days, right.days, result.days)) {
|
|
37301
|
+
throw OutOfRangeException("Date out of range");
|
|
37302
|
+
}
|
|
37303
|
+
}
|
|
37304
|
+
if (right.micros != 0) {
|
|
37305
|
+
if (!TryAddOperator::Operation(result.days, int32_t(right.micros / Interval::MICROS_PER_DAY), result.days)) {
|
|
37306
|
+
throw OutOfRangeException("Date out of range");
|
|
37307
|
+
}
|
|
37308
|
+
}
|
|
37309
|
+
return result;
|
|
37310
|
+
}
|
|
37311
|
+
|
|
37312
|
+
dtime_t Interval::Add(dtime_t left, interval_t right, date_t &date) {
|
|
37313
|
+
int64_t diff = right.micros - ((right.micros / Interval::MICROS_PER_DAY) * Interval::MICROS_PER_DAY);
|
|
37314
|
+
left += diff;
|
|
37315
|
+
if (left.micros >= Interval::MICROS_PER_DAY) {
|
|
37316
|
+
left.micros -= Interval::MICROS_PER_DAY;
|
|
37317
|
+
date.days++;
|
|
37318
|
+
} else if (left.micros < 0) {
|
|
37319
|
+
left.micros += Interval::MICROS_PER_DAY;
|
|
37320
|
+
date.days--;
|
|
37321
|
+
}
|
|
37322
|
+
return left;
|
|
37323
|
+
}
|
|
37324
|
+
|
|
37231
37325
|
} // namespace duckdb
|
|
37232
37326
|
|
|
37233
37327
|
|
|
@@ -46204,7 +46298,38 @@ void FillEnumResultTemplate(Vector &source, Vector &result, idx_t count) {
|
|
|
46204
46298
|
}
|
|
46205
46299
|
}
|
|
46206
46300
|
|
|
46207
|
-
|
|
46301
|
+
void EnumToVarchar(Vector &source, Vector &result, idx_t count, PhysicalType enum_physical_type) {
|
|
46302
|
+
if (source.GetVectorType() == VectorType::CONSTANT_VECTOR) {
|
|
46303
|
+
result.SetVectorType(source.GetVectorType());
|
|
46304
|
+
} else {
|
|
46305
|
+
result.SetVectorType(VectorType::FLAT_VECTOR);
|
|
46306
|
+
}
|
|
46307
|
+
for (idx_t i = 0; i < count; i++) {
|
|
46308
|
+
auto src_val = source.GetValue(i);
|
|
46309
|
+
if (src_val.is_null) {
|
|
46310
|
+
result.SetValue(i, Value());
|
|
46311
|
+
continue;
|
|
46312
|
+
}
|
|
46313
|
+
auto str_vec = EnumType::GetValuesInsertOrder(source.GetType());
|
|
46314
|
+
uint64_t enum_idx;
|
|
46315
|
+
switch (enum_physical_type) {
|
|
46316
|
+
case PhysicalType::UINT8:
|
|
46317
|
+
enum_idx = src_val.value_.utinyint;
|
|
46318
|
+
break;
|
|
46319
|
+
case PhysicalType::UINT16:
|
|
46320
|
+
enum_idx = src_val.value_.usmallint;
|
|
46321
|
+
break;
|
|
46322
|
+
case PhysicalType::UINT32:
|
|
46323
|
+
enum_idx = src_val.value_.uinteger;
|
|
46324
|
+
break;
|
|
46325
|
+
default:
|
|
46326
|
+
throw InternalException("ENUM can only have unsigned integers (except UINT64) as physical types");
|
|
46327
|
+
}
|
|
46328
|
+
result.SetValue(i, Value(str_vec[enum_idx]));
|
|
46329
|
+
}
|
|
46330
|
+
}
|
|
46331
|
+
|
|
46332
|
+
static bool EnumCastSwitch(Vector &source, Vector &result, idx_t count, string *error_message, bool strict) {
|
|
46208
46333
|
auto enum_physical_type = source.GetType().InternalType();
|
|
46209
46334
|
switch (result.GetType().id()) {
|
|
46210
46335
|
case LogicalTypeId::ENUM: {
|
|
@@ -46225,38 +46350,17 @@ static bool EnumCastSwitch(Vector &source, Vector &result, idx_t count, string *
|
|
|
46225
46350
|
break;
|
|
46226
46351
|
}
|
|
46227
46352
|
case LogicalTypeId::VARCHAR: {
|
|
46228
|
-
|
|
46229
|
-
|
|
46230
|
-
|
|
46231
|
-
|
|
46232
|
-
|
|
46233
|
-
|
|
46234
|
-
|
|
46235
|
-
|
|
46236
|
-
|
|
46237
|
-
continue;
|
|
46238
|
-
}
|
|
46239
|
-
auto str_vec = EnumType::GetValuesInsertOrder(source.GetType());
|
|
46240
|
-
uint64_t enum_idx;
|
|
46241
|
-
switch (enum_physical_type) {
|
|
46242
|
-
case PhysicalType::UINT8:
|
|
46243
|
-
enum_idx = src_val.value_.utinyint;
|
|
46244
|
-
break;
|
|
46245
|
-
case PhysicalType::UINT16:
|
|
46246
|
-
enum_idx = src_val.value_.usmallint;
|
|
46247
|
-
break;
|
|
46248
|
-
case PhysicalType::UINT32:
|
|
46249
|
-
enum_idx = src_val.value_.uinteger;
|
|
46250
|
-
break;
|
|
46251
|
-
default:
|
|
46252
|
-
throw InternalException("ENUM can only have unsigned integers (except UINT64) as physical types");
|
|
46253
|
-
}
|
|
46254
|
-
result.SetValue(i, Value(str_vec[enum_idx]));
|
|
46255
|
-
}
|
|
46353
|
+
EnumToVarchar(source, result, count, enum_physical_type);
|
|
46354
|
+
break;
|
|
46355
|
+
}
|
|
46356
|
+
default: {
|
|
46357
|
+
// Cast to varchar
|
|
46358
|
+
Vector varchar_cast(LogicalType::VARCHAR, count);
|
|
46359
|
+
EnumToVarchar(source, varchar_cast, count, enum_physical_type);
|
|
46360
|
+
// Try to cast from varchar to whatever we wanted before
|
|
46361
|
+
VectorOperations::TryCast(varchar_cast, result, count, error_message, strict);
|
|
46256
46362
|
break;
|
|
46257
46363
|
}
|
|
46258
|
-
default:
|
|
46259
|
-
throw InternalException("Cast from Enum is not allowed");
|
|
46260
46364
|
}
|
|
46261
46365
|
return true;
|
|
46262
46366
|
}
|
|
@@ -46371,7 +46475,7 @@ bool VectorOperations::TryCast(Vector &source, Vector &result, idx_t count, stri
|
|
|
46371
46475
|
case LogicalTypeId::LIST:
|
|
46372
46476
|
return ListCastSwitch(source, result, count, error_message);
|
|
46373
46477
|
case LogicalTypeId::ENUM:
|
|
46374
|
-
return EnumCastSwitch(source, result, count, error_message);
|
|
46478
|
+
return EnumCastSwitch(source, result, count, error_message, strict);
|
|
46375
46479
|
default:
|
|
46376
46480
|
return TryVectorNullCast(source, result, count, error_message);
|
|
46377
46481
|
}
|
|
@@ -49644,6 +49748,7 @@ void ExpressionExecutor::ExecuteExpression(idx_t expr_idx, Vector &result) {
|
|
|
49644
49748
|
|
|
49645
49749
|
Value ExpressionExecutor::EvaluateScalar(const Expression &expr) {
|
|
49646
49750
|
D_ASSERT(expr.IsFoldable());
|
|
49751
|
+
D_ASSERT(expr.IsScalar());
|
|
49647
49752
|
// use an ExpressionExecutor to execute the expression
|
|
49648
49753
|
ExpressionExecutor executor(expr);
|
|
49649
49754
|
|
|
@@ -53943,7 +54048,6 @@ public:
|
|
|
53943
54048
|
}
|
|
53944
54049
|
|
|
53945
54050
|
bool ParallelSink() const override {
|
|
53946
|
-
// we can only parallelize if all aggregates are combinable
|
|
53947
54051
|
return true;
|
|
53948
54052
|
}
|
|
53949
54053
|
};
|
|
@@ -55927,6 +56031,112 @@ PhysicalExecute::PhysicalExecute(PhysicalOperator *plan)
|
|
|
55927
56031
|
: PhysicalOperator(PhysicalOperatorType::EXECUTE, plan->types, -1), plan(plan) {
|
|
55928
56032
|
}
|
|
55929
56033
|
|
|
56034
|
+
} // namespace duckdb
|
|
56035
|
+
//===----------------------------------------------------------------------===//
|
|
56036
|
+
// DuckDB
|
|
56037
|
+
//
|
|
56038
|
+
// duckdb/execution/operator/helper/physical_explain_analyze.hpp
|
|
56039
|
+
//
|
|
56040
|
+
//
|
|
56041
|
+
//===----------------------------------------------------------------------===//
|
|
56042
|
+
|
|
56043
|
+
|
|
56044
|
+
|
|
56045
|
+
|
|
56046
|
+
|
|
56047
|
+
|
|
56048
|
+
namespace duckdb {
|
|
56049
|
+
|
|
56050
|
+
class PhysicalExplainAnalyze : public PhysicalOperator {
|
|
56051
|
+
public:
|
|
56052
|
+
PhysicalExplainAnalyze(vector<LogicalType> types)
|
|
56053
|
+
: PhysicalOperator(PhysicalOperatorType::EXPLAIN_ANALYZE, move(types), 1) {
|
|
56054
|
+
}
|
|
56055
|
+
|
|
56056
|
+
public:
|
|
56057
|
+
// Source interface
|
|
56058
|
+
unique_ptr<GlobalSourceState> GetGlobalSourceState(ClientContext &context) const override;
|
|
56059
|
+
void GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate,
|
|
56060
|
+
LocalSourceState &lstate) const override;
|
|
56061
|
+
|
|
56062
|
+
public:
|
|
56063
|
+
// Sink Interface
|
|
56064
|
+
SinkResultType Sink(ExecutionContext &context, GlobalSinkState &state, LocalSinkState &lstate,
|
|
56065
|
+
DataChunk &input) const override;
|
|
56066
|
+
SinkFinalizeType Finalize(Pipeline &pipeline, Event &event, ClientContext &context,
|
|
56067
|
+
GlobalSinkState &gstate) const override;
|
|
56068
|
+
|
|
56069
|
+
unique_ptr<GlobalSinkState> GetGlobalSinkState(ClientContext &context) const override;
|
|
56070
|
+
|
|
56071
|
+
bool IsSink() const override {
|
|
56072
|
+
return true;
|
|
56073
|
+
}
|
|
56074
|
+
|
|
56075
|
+
bool ParallelSink() const override {
|
|
56076
|
+
return true;
|
|
56077
|
+
}
|
|
56078
|
+
};
|
|
56079
|
+
|
|
56080
|
+
} // namespace duckdb
|
|
56081
|
+
|
|
56082
|
+
|
|
56083
|
+
|
|
56084
|
+
|
|
56085
|
+
namespace duckdb {
|
|
56086
|
+
|
|
56087
|
+
//===--------------------------------------------------------------------===//
|
|
56088
|
+
// Sink
|
|
56089
|
+
//===--------------------------------------------------------------------===//
|
|
56090
|
+
class ExplainAnalyzeStateGlobalState : public GlobalSinkState {
|
|
56091
|
+
public:
|
|
56092
|
+
string analyzed_plan;
|
|
56093
|
+
};
|
|
56094
|
+
|
|
56095
|
+
SinkResultType PhysicalExplainAnalyze::Sink(ExecutionContext &context, GlobalSinkState &state, LocalSinkState &lstate,
|
|
56096
|
+
DataChunk &input) const {
|
|
56097
|
+
return SinkResultType::NEED_MORE_INPUT;
|
|
56098
|
+
}
|
|
56099
|
+
|
|
56100
|
+
SinkFinalizeType PhysicalExplainAnalyze::Finalize(Pipeline &pipeline, Event &event, ClientContext &context,
|
|
56101
|
+
GlobalSinkState &gstate_p) const {
|
|
56102
|
+
auto &gstate = (ExplainAnalyzeStateGlobalState &)gstate_p;
|
|
56103
|
+
gstate.analyzed_plan = context.profiler->ToString();
|
|
56104
|
+
return SinkFinalizeType::READY;
|
|
56105
|
+
}
|
|
56106
|
+
|
|
56107
|
+
unique_ptr<GlobalSinkState> PhysicalExplainAnalyze::GetGlobalSinkState(ClientContext &context) const {
|
|
56108
|
+
return make_unique<ExplainAnalyzeStateGlobalState>();
|
|
56109
|
+
}
|
|
56110
|
+
|
|
56111
|
+
//===--------------------------------------------------------------------===//
|
|
56112
|
+
// Source
|
|
56113
|
+
//===--------------------------------------------------------------------===//
|
|
56114
|
+
class ExplainAnalyzeState : public GlobalSourceState {
|
|
56115
|
+
public:
|
|
56116
|
+
ExplainAnalyzeState() : finished(false) {
|
|
56117
|
+
}
|
|
56118
|
+
|
|
56119
|
+
bool finished;
|
|
56120
|
+
};
|
|
56121
|
+
|
|
56122
|
+
unique_ptr<GlobalSourceState> PhysicalExplainAnalyze::GetGlobalSourceState(ClientContext &context) const {
|
|
56123
|
+
return make_unique<ExplainAnalyzeState>();
|
|
56124
|
+
}
|
|
56125
|
+
|
|
56126
|
+
void PhysicalExplainAnalyze::GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &source_state,
|
|
56127
|
+
LocalSourceState &lstate) const {
|
|
56128
|
+
auto &state = (ExplainAnalyzeState &)source_state;
|
|
56129
|
+
auto &gstate = (ExplainAnalyzeStateGlobalState &)*sink_state;
|
|
56130
|
+
if (state.finished) {
|
|
56131
|
+
return;
|
|
56132
|
+
}
|
|
56133
|
+
chunk.SetValue(0, 0, Value("analyzed_plan"));
|
|
56134
|
+
chunk.SetValue(1, 0, Value(gstate.analyzed_plan));
|
|
56135
|
+
chunk.SetCardinality(1);
|
|
56136
|
+
|
|
56137
|
+
state.finished = true;
|
|
56138
|
+
}
|
|
56139
|
+
|
|
55930
56140
|
} // namespace duckdb
|
|
55931
56141
|
//===----------------------------------------------------------------------===//
|
|
55932
56142
|
// DuckDB
|
|
@@ -58771,6 +58981,7 @@ struct TableScanBindData : public FunctionData {
|
|
|
58771
58981
|
//! The table scan function represents a sequential scan over one of DuckDB's base tables.
|
|
58772
58982
|
struct TableScanFunction {
|
|
58773
58983
|
static TableFunction GetFunction();
|
|
58984
|
+
static TableCatalogEntry *GetTableEntry(const TableFunction &function, const FunctionData *bind_data);
|
|
58774
58985
|
};
|
|
58775
58986
|
|
|
58776
58987
|
} // namespace duckdb
|
|
@@ -61172,15 +61383,9 @@ struct BufferedCSVReaderOptions {
|
|
|
61172
61383
|
//! Whether or not a type format is specified
|
|
61173
61384
|
std::map<LogicalTypeId, bool> has_format = {{LogicalTypeId::DATE, false}, {LogicalTypeId::TIMESTAMP, false}};
|
|
61174
61385
|
|
|
61175
|
-
|
|
61176
|
-
|
|
61177
|
-
|
|
61178
|
-
", ESCAPE='" + escape + (has_escape ? "'" : (auto_detect ? "' (auto detected)" : "' (default)")) +
|
|
61179
|
-
", HEADER=" + std::to_string(header) +
|
|
61180
|
-
(has_header ? "" : (auto_detect ? " (auto detected)" : "' (default)")) +
|
|
61181
|
-
", SAMPLE_SIZE=" + std::to_string(sample_chunk_size * sample_chunks) +
|
|
61182
|
-
", ALL_VARCHAR=" + std::to_string(all_varchar);
|
|
61183
|
-
}
|
|
61386
|
+
void SetDelimiter(const string &delimiter);
|
|
61387
|
+
|
|
61388
|
+
std::string ToString() const;
|
|
61184
61389
|
};
|
|
61185
61390
|
|
|
61186
61391
|
enum class ParserMode : uint8_t { PARSING = 0, SNIFFING_DIALECT = 1, SNIFFING_DATATYPES = 2, PARSING_HEADER = 3 };
|
|
@@ -61333,6 +61538,24 @@ private:
|
|
|
61333
61538
|
|
|
61334
61539
|
namespace duckdb {
|
|
61335
61540
|
|
|
61541
|
+
void BufferedCSVReaderOptions::SetDelimiter(const string &input) {
|
|
61542
|
+
this->delimiter = StringUtil::Replace(input, "\\t", "\t");
|
|
61543
|
+
this->has_delimiter = true;
|
|
61544
|
+
if (input.empty()) {
|
|
61545
|
+
throw BinderException("DELIM or SEP must not be empty");
|
|
61546
|
+
}
|
|
61547
|
+
}
|
|
61548
|
+
|
|
61549
|
+
std::string BufferedCSVReaderOptions::ToString() const {
|
|
61550
|
+
return "DELIMITER='" + delimiter + (has_delimiter ? "'" : (auto_detect ? "' (auto detected)" : "' (default)")) +
|
|
61551
|
+
", QUOTE='" + quote + (has_quote ? "'" : (auto_detect ? "' (auto detected)" : "' (default)")) +
|
|
61552
|
+
", ESCAPE='" + escape + (has_escape ? "'" : (auto_detect ? "' (auto detected)" : "' (default)")) +
|
|
61553
|
+
", HEADER=" + std::to_string(header) +
|
|
61554
|
+
(has_header ? "" : (auto_detect ? " (auto detected)" : "' (default)")) +
|
|
61555
|
+
", SAMPLE_SIZE=" + std::to_string(sample_chunk_size * sample_chunks) +
|
|
61556
|
+
", ALL_VARCHAR=" + std::to_string(all_varchar);
|
|
61557
|
+
}
|
|
61558
|
+
|
|
61336
61559
|
static string GetLineNumberStr(idx_t linenr, bool linenr_estimated) {
|
|
61337
61560
|
string estimated = (linenr_estimated ? string(" (estimated)") : string(""));
|
|
61338
61561
|
return to_string(linenr + 1) + estimated;
|
|
@@ -62146,7 +62369,7 @@ vector<LogicalType> BufferedCSVReader::RefineTypeDetection(const vector<LogicalT
|
|
|
62146
62369
|
if (requested_types.size() != options.num_cols) {
|
|
62147
62370
|
throw InvalidInputException(
|
|
62148
62371
|
"Error while determining column types: found %lld columns but expected %d. (%s)", options.num_cols,
|
|
62149
|
-
requested_types.size(), options.
|
|
62372
|
+
requested_types.size(), options.ToString());
|
|
62150
62373
|
} else {
|
|
62151
62374
|
detected_types = requested_types;
|
|
62152
62375
|
}
|
|
@@ -62404,7 +62627,7 @@ in_quotes:
|
|
|
62404
62627
|
} while (ReadBuffer(start));
|
|
62405
62628
|
// still in quoted state at the end of the file, error:
|
|
62406
62629
|
error_message = StringUtil::Format("Error in file \"%s\" on line %s: unterminated quotes. (%s)", options.file_path,
|
|
62407
|
-
GetLineNumberStr(linenr, linenr_estimated).c_str(), options.
|
|
62630
|
+
GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString());
|
|
62408
62631
|
return false;
|
|
62409
62632
|
unquote:
|
|
62410
62633
|
/* state: unquote */
|
|
@@ -62434,7 +62657,7 @@ unquote:
|
|
|
62434
62657
|
error_message = StringUtil::Format(
|
|
62435
62658
|
"Error in file \"%s\" on line %s: quote should be followed by end of value, end "
|
|
62436
62659
|
"of row or another quote. (%s)",
|
|
62437
|
-
options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.
|
|
62660
|
+
options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString());
|
|
62438
62661
|
return false;
|
|
62439
62662
|
}
|
|
62440
62663
|
if (delimiter_pos == options.delimiter.size()) {
|
|
@@ -62451,7 +62674,7 @@ unquote:
|
|
|
62451
62674
|
} while (ReadBuffer(start));
|
|
62452
62675
|
error_message = StringUtil::Format(
|
|
62453
62676
|
"Error in file \"%s\" on line %s: quote should be followed by end of value, end of row or another quote. (%s)",
|
|
62454
|
-
options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.
|
|
62677
|
+
options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString());
|
|
62455
62678
|
return false;
|
|
62456
62679
|
handle_escape:
|
|
62457
62680
|
escape_pos = 0;
|
|
@@ -62466,7 +62689,7 @@ handle_escape:
|
|
|
62466
62689
|
if (count > escape_pos && count > quote_pos) {
|
|
62467
62690
|
error_message = StringUtil::Format(
|
|
62468
62691
|
"Error in file \"%s\" on line %s: neither QUOTE nor ESCAPE is proceeded by ESCAPE. (%s)",
|
|
62469
|
-
options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.
|
|
62692
|
+
options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString());
|
|
62470
62693
|
return false;
|
|
62471
62694
|
}
|
|
62472
62695
|
if (quote_pos == options.quote.size() || escape_pos == options.escape.size()) {
|
|
@@ -62477,7 +62700,7 @@ handle_escape:
|
|
|
62477
62700
|
} while (ReadBuffer(start));
|
|
62478
62701
|
error_message =
|
|
62479
62702
|
StringUtil::Format("Error in file \"%s\" on line %s: neither QUOTE nor ESCAPE is proceeded by ESCAPE. (%s)",
|
|
62480
|
-
options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.
|
|
62703
|
+
options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString());
|
|
62481
62704
|
return false;
|
|
62482
62705
|
carriage_return:
|
|
62483
62706
|
/* state: carriage_return */
|
|
@@ -62609,7 +62832,7 @@ in_quotes:
|
|
|
62609
62832
|
} while (ReadBuffer(start));
|
|
62610
62833
|
// still in quoted state at the end of the file, error:
|
|
62611
62834
|
throw InvalidInputException("Error in file \"%s\" on line %s: unterminated quotes. (%s)", options.file_path,
|
|
62612
|
-
GetLineNumberStr(linenr, linenr_estimated).c_str(), options.
|
|
62835
|
+
GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString());
|
|
62613
62836
|
unquote:
|
|
62614
62837
|
/* state: unquote */
|
|
62615
62838
|
// this state handles the state directly after we unquote
|
|
@@ -62636,7 +62859,7 @@ unquote:
|
|
|
62636
62859
|
error_message = StringUtil::Format(
|
|
62637
62860
|
"Error in file \"%s\" on line %s: quote should be followed by end of value, end of "
|
|
62638
62861
|
"row or another quote. (%s)",
|
|
62639
|
-
options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.
|
|
62862
|
+
options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString());
|
|
62640
62863
|
return false;
|
|
62641
62864
|
}
|
|
62642
62865
|
handle_escape:
|
|
@@ -62646,13 +62869,13 @@ handle_escape:
|
|
|
62646
62869
|
if (position >= buffer_size && !ReadBuffer(start)) {
|
|
62647
62870
|
error_message = StringUtil::Format(
|
|
62648
62871
|
"Error in file \"%s\" on line %s: neither QUOTE nor ESCAPE is proceeded by ESCAPE. (%s)", options.file_path,
|
|
62649
|
-
GetLineNumberStr(linenr, linenr_estimated).c_str(), options.
|
|
62872
|
+
GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString());
|
|
62650
62873
|
return false;
|
|
62651
62874
|
}
|
|
62652
62875
|
if (buffer[position] != options.quote[0] && buffer[position] != options.escape[0]) {
|
|
62653
62876
|
error_message = StringUtil::Format(
|
|
62654
62877
|
"Error in file \"%s\" on line %s: neither QUOTE nor ESCAPE is proceeded by ESCAPE. (%s)", options.file_path,
|
|
62655
|
-
GetLineNumberStr(linenr, linenr_estimated).c_str(), options.
|
|
62878
|
+
GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString());
|
|
62656
62879
|
return false;
|
|
62657
62880
|
}
|
|
62658
62881
|
// escape was followed by quote or escape, go back to quoted state
|
|
@@ -62792,7 +63015,7 @@ void BufferedCSVReader::AddValue(char *str_val, idx_t length, idx_t &column, vec
|
|
|
62792
63015
|
if (column >= sql_types.size()) {
|
|
62793
63016
|
throw InvalidInputException("Error on line %s: expected %lld values per row, but got more. (%s)",
|
|
62794
63017
|
GetLineNumberStr(linenr, linenr_estimated).c_str(), sql_types.size(),
|
|
62795
|
-
options.
|
|
63018
|
+
options.ToString());
|
|
62796
63019
|
}
|
|
62797
63020
|
|
|
62798
63021
|
// insert the line number into the chunk
|
|
@@ -62847,7 +63070,7 @@ bool BufferedCSVReader::AddRow(DataChunk &insert_chunk, idx_t &column) {
|
|
|
62847
63070
|
if (column < sql_types.size() && mode != ParserMode::SNIFFING_DIALECT) {
|
|
62848
63071
|
throw InvalidInputException("Error on line %s: expected %lld values per row, but got %d. (%s)",
|
|
62849
63072
|
GetLineNumberStr(linenr, linenr_estimated).c_str(), sql_types.size(), column,
|
|
62850
|
-
options.
|
|
63073
|
+
options.ToString());
|
|
62851
63074
|
}
|
|
62852
63075
|
|
|
62853
63076
|
if (mode == ParserMode::SNIFFING_DIALECT) {
|
|
@@ -62900,7 +63123,7 @@ void BufferedCSVReader::Flush(DataChunk &insert_chunk) {
|
|
|
62900
63123
|
throw InvalidInputException("Error in file \"%s\" between line %llu and %llu in column \"%s\": "
|
|
62901
63124
|
"file is not valid UTF8. Parser options: %s",
|
|
62902
63125
|
options.file_path, linenr - parse_chunk.size(), linenr, col_name,
|
|
62903
|
-
options.
|
|
63126
|
+
options.ToString());
|
|
62904
63127
|
}
|
|
62905
63128
|
}
|
|
62906
63129
|
}
|
|
@@ -62934,11 +63157,11 @@ void BufferedCSVReader::Flush(DataChunk &insert_chunk) {
|
|
|
62934
63157
|
"(SAMPLE_SIZE=X [X rows] or SAMPLE_SIZE=-1 [all rows]), "
|
|
62935
63158
|
"or skipping column conversion (ALL_VARCHAR=1)",
|
|
62936
63159
|
error_message, col_name, linenr - parse_chunk.size() + 1, linenr,
|
|
62937
|
-
options.
|
|
63160
|
+
options.ToString());
|
|
62938
63161
|
} else {
|
|
62939
63162
|
throw InvalidInputException("%s between line %llu and %llu in column %s. Parser options: %s ",
|
|
62940
63163
|
error_message, linenr - parse_chunk.size(), linenr, col_name,
|
|
62941
|
-
options.
|
|
63164
|
+
options.ToString());
|
|
62942
63165
|
}
|
|
62943
63166
|
}
|
|
62944
63167
|
}
|
|
@@ -67690,15 +67913,47 @@ unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalExecute &o
|
|
|
67690
67913
|
|
|
67691
67914
|
|
|
67692
67915
|
|
|
67916
|
+
//===----------------------------------------------------------------------===//
|
|
67917
|
+
// DuckDB
|
|
67918
|
+
//
|
|
67919
|
+
// duckdb/parser/statement/explain_statement.hpp
|
|
67920
|
+
//
|
|
67921
|
+
//
|
|
67922
|
+
//===----------------------------------------------------------------------===//
|
|
67923
|
+
|
|
67924
|
+
|
|
67925
|
+
|
|
67926
|
+
|
|
67927
|
+
|
|
67928
|
+
|
|
67929
|
+
namespace duckdb {
|
|
67930
|
+
|
|
67931
|
+
enum class ExplainType : uint8_t { EXPLAIN_STANDARD, EXPLAIN_ANALYZE };
|
|
67932
|
+
|
|
67933
|
+
class ExplainStatement : public SQLStatement {
|
|
67934
|
+
public:
|
|
67935
|
+
ExplainStatement(unique_ptr<SQLStatement> stmt, ExplainType explain_type = ExplainType::EXPLAIN_STANDARD);
|
|
67936
|
+
|
|
67937
|
+
unique_ptr<SQLStatement> stmt;
|
|
67938
|
+
ExplainType explain_type;
|
|
67939
|
+
|
|
67940
|
+
public:
|
|
67941
|
+
unique_ptr<SQLStatement> Copy() const override;
|
|
67942
|
+
};
|
|
67943
|
+
|
|
67944
|
+
} // namespace duckdb
|
|
67945
|
+
|
|
67693
67946
|
|
|
67694
67947
|
namespace duckdb {
|
|
67695
67948
|
|
|
67696
67949
|
class LogicalExplain : public LogicalOperator {
|
|
67697
67950
|
public:
|
|
67698
|
-
|
|
67951
|
+
LogicalExplain(unique_ptr<LogicalOperator> plan, ExplainType explain_type)
|
|
67952
|
+
: LogicalOperator(LogicalOperatorType::LOGICAL_EXPLAIN), explain_type(explain_type) {
|
|
67699
67953
|
children.push_back(move(plan));
|
|
67700
67954
|
}
|
|
67701
67955
|
|
|
67956
|
+
ExplainType explain_type;
|
|
67702
67957
|
string physical_plan;
|
|
67703
67958
|
string logical_plan_unopt;
|
|
67704
67959
|
string logical_plan_opt;
|
|
@@ -67717,15 +67972,20 @@ protected:
|
|
|
67717
67972
|
|
|
67718
67973
|
|
|
67719
67974
|
|
|
67975
|
+
|
|
67720
67976
|
namespace duckdb {
|
|
67721
67977
|
|
|
67722
67978
|
unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalExplain &op) {
|
|
67723
67979
|
D_ASSERT(op.children.size() == 1);
|
|
67724
67980
|
auto logical_plan_opt = op.children[0]->ToString();
|
|
67725
67981
|
auto plan = CreatePlan(*op.children[0]);
|
|
67982
|
+
if (op.explain_type == ExplainType::EXPLAIN_ANALYZE) {
|
|
67983
|
+
auto result = make_unique<PhysicalExplainAnalyze>(op.types);
|
|
67984
|
+
result->children.push_back(move(plan));
|
|
67985
|
+
return move(result);
|
|
67986
|
+
}
|
|
67726
67987
|
|
|
67727
67988
|
op.physical_plan = plan->ToString();
|
|
67728
|
-
|
|
67729
67989
|
// the output of the explain
|
|
67730
67990
|
vector<string> keys, values;
|
|
67731
67991
|
switch (context.explain_output_type) {
|
|
@@ -68409,6 +68669,8 @@ public:
|
|
|
68409
68669
|
|
|
68410
68670
|
string GetName() const override;
|
|
68411
68671
|
string ParamsToString() const override;
|
|
68672
|
+
//! Returns the underlying table that is being scanned, or nullptr if there is none
|
|
68673
|
+
TableCatalogEntry *GetTable() const;
|
|
68412
68674
|
|
|
68413
68675
|
public:
|
|
68414
68676
|
vector<ColumnBinding> GetColumnBindings() override;
|
|
@@ -78943,7 +79205,7 @@ string MacroFunction::ValidateArguments(MacroCatalogEntry ¯o_func, FunctionE
|
|
|
78943
79205
|
error = StringUtil::Format(
|
|
78944
79206
|
"Macro function '%s(%s)' requires ", macro_func.name,
|
|
78945
79207
|
StringUtil::Join(parameters, parameters.size(), ", ", [](const unique_ptr<ParsedExpression> &p) {
|
|
78946
|
-
return ((ColumnRefExpression &)*p).
|
|
79208
|
+
return ((ColumnRefExpression &)*p).column_names[0];
|
|
78947
79209
|
}));
|
|
78948
79210
|
error += parameters.size() == 1 ? "a single positional argument"
|
|
78949
79211
|
: StringUtil::Format("%i positional arguments", parameters.size());
|
|
@@ -79172,6 +79434,14 @@ static void PragmaDisableForceExternal(ClientContext &context, const FunctionPar
|
|
|
79172
79434
|
context.force_external = false;
|
|
79173
79435
|
}
|
|
79174
79436
|
|
|
79437
|
+
static void PragmaEnableParquetBinaryAsString(ClientContext &context, const FunctionParameters ¶meters) {
|
|
79438
|
+
context.parquet_binary_as_strings = true;
|
|
79439
|
+
}
|
|
79440
|
+
|
|
79441
|
+
static void PragmaDisableParquetBinaryAsString(ClientContext &context, const FunctionParameters ¶meters) {
|
|
79442
|
+
context.parquet_binary_as_strings = false;
|
|
79443
|
+
}
|
|
79444
|
+
|
|
79175
79445
|
static void PragmaEnableObjectCache(ClientContext &context, const FunctionParameters ¶meters) {
|
|
79176
79446
|
DBConfig::GetConfig(context).object_cache_enable = true;
|
|
79177
79447
|
}
|
|
@@ -79347,6 +79617,11 @@ void PragmaFunctions::RegisterFunction(BuiltinFunctions &set) {
|
|
|
79347
79617
|
set.AddFunction(PragmaFunction::PragmaStatement("enable_print_progress_bar", PragmaEnablePrintProgressBar));
|
|
79348
79618
|
set.AddFunction(PragmaFunction::PragmaStatement("disable_print_progress_bar", PragmaDisablePrintProgressBar));
|
|
79349
79619
|
|
|
79620
|
+
set.AddFunction(
|
|
79621
|
+
PragmaFunction::PragmaStatement("enable_parquet_binary_as_string", PragmaEnableParquetBinaryAsString));
|
|
79622
|
+
set.AddFunction(
|
|
79623
|
+
PragmaFunction::PragmaStatement("disable_parquet_binary_as_string", PragmaDisableParquetBinaryAsString));
|
|
79624
|
+
|
|
79350
79625
|
set.AddFunction(
|
|
79351
79626
|
PragmaFunction::PragmaAssignment("set_progress_bar_time", PragmaSetProgressBarWaitTime, LogicalType::INTEGER));
|
|
79352
79627
|
|
|
@@ -80733,7 +81008,7 @@ int64_t DatePart::MicrosecondsOperator::Operation(timestamp_t input) {
|
|
|
80733
81008
|
template <>
|
|
80734
81009
|
int64_t DatePart::MicrosecondsOperator::Operation(interval_t input) {
|
|
80735
81010
|
// remove everything but the second & microsecond part
|
|
80736
|
-
return input.micros;
|
|
81011
|
+
return input.micros % Interval::MICROS_PER_MINUTE;
|
|
80737
81012
|
}
|
|
80738
81013
|
|
|
80739
81014
|
template <>
|
|
@@ -80813,8 +81088,17 @@ int64_t DatePart::EpochOperator::Operation(timestamp_t input) {
|
|
|
80813
81088
|
|
|
80814
81089
|
template <>
|
|
80815
81090
|
int64_t DatePart::EpochOperator::Operation(interval_t input) {
|
|
80816
|
-
|
|
80817
|
-
|
|
81091
|
+
int64_t interval_years = input.months / Interval::MONTHS_PER_YEAR;
|
|
81092
|
+
int64_t interval_days;
|
|
81093
|
+
interval_days = Interval::DAYS_PER_YEAR * interval_years;
|
|
81094
|
+
interval_days += Interval::DAYS_PER_MONTH * (input.months % Interval::MONTHS_PER_YEAR);
|
|
81095
|
+
interval_days += input.days;
|
|
81096
|
+
int64_t interval_epoch;
|
|
81097
|
+
interval_epoch = interval_days * Interval::SECS_PER_DAY;
|
|
81098
|
+
// we add 0.25 days per year to sort of account for leap days
|
|
81099
|
+
interval_epoch += interval_years * (Interval::SECS_PER_DAY / 4);
|
|
81100
|
+
interval_epoch += input.micros / Interval::MICROS_PER_SEC;
|
|
81101
|
+
return interval_epoch;
|
|
80818
81102
|
}
|
|
80819
81103
|
|
|
80820
81104
|
template <>
|
|
@@ -86034,36 +86318,7 @@ date_t AddOperator::Operation(int32_t left, date_t right) {
|
|
|
86034
86318
|
|
|
86035
86319
|
template <>
|
|
86036
86320
|
date_t AddOperator::Operation(date_t left, interval_t right) {
|
|
86037
|
-
|
|
86038
|
-
if (right.months != 0) {
|
|
86039
|
-
int32_t year, month, day;
|
|
86040
|
-
Date::Convert(left, year, month, day);
|
|
86041
|
-
int32_t year_diff = right.months / Interval::MONTHS_PER_YEAR;
|
|
86042
|
-
year += year_diff;
|
|
86043
|
-
month += right.months - year_diff * Interval::MONTHS_PER_YEAR;
|
|
86044
|
-
if (month > Interval::MONTHS_PER_YEAR) {
|
|
86045
|
-
year++;
|
|
86046
|
-
month -= Interval::MONTHS_PER_YEAR;
|
|
86047
|
-
} else if (month <= 0) {
|
|
86048
|
-
year--;
|
|
86049
|
-
month += Interval::MONTHS_PER_YEAR;
|
|
86050
|
-
}
|
|
86051
|
-
day = MinValue<int32_t>(day, Date::MonthDays(year, month));
|
|
86052
|
-
result = Date::FromDate(year, month, day);
|
|
86053
|
-
} else {
|
|
86054
|
-
result = left;
|
|
86055
|
-
}
|
|
86056
|
-
if (right.days != 0) {
|
|
86057
|
-
if (!TryAddOperator::Operation(result.days, right.days, result.days)) {
|
|
86058
|
-
throw OutOfRangeException("Date out of range");
|
|
86059
|
-
}
|
|
86060
|
-
}
|
|
86061
|
-
if (right.micros != 0) {
|
|
86062
|
-
if (!TryAddOperator::Operation(result.days, int32_t(right.micros / Interval::MICROS_PER_DAY), result.days)) {
|
|
86063
|
-
throw OutOfRangeException("Date out of range");
|
|
86064
|
-
}
|
|
86065
|
-
}
|
|
86066
|
-
return result;
|
|
86321
|
+
return Interval::Add(left, right);
|
|
86067
86322
|
}
|
|
86068
86323
|
|
|
86069
86324
|
template <>
|
|
@@ -86071,26 +86326,13 @@ date_t AddOperator::Operation(interval_t left, date_t right) {
|
|
|
86071
86326
|
return AddOperator::Operation<date_t, interval_t, date_t>(right, left);
|
|
86072
86327
|
}
|
|
86073
86328
|
|
|
86074
|
-
dtime_t AddIntervalToTimeOperation(dtime_t left, interval_t right, date_t &date) {
|
|
86075
|
-
int64_t diff = right.micros - ((right.micros / Interval::MICROS_PER_DAY) * Interval::MICROS_PER_DAY);
|
|
86076
|
-
left += diff;
|
|
86077
|
-
if (left.micros >= Interval::MICROS_PER_DAY) {
|
|
86078
|
-
left.micros -= Interval::MICROS_PER_DAY;
|
|
86079
|
-
date.days++;
|
|
86080
|
-
} else if (left.micros < 0) {
|
|
86081
|
-
left.micros += Interval::MICROS_PER_DAY;
|
|
86082
|
-
date.days--;
|
|
86083
|
-
}
|
|
86084
|
-
return left;
|
|
86085
|
-
}
|
|
86086
|
-
|
|
86087
86329
|
template <>
|
|
86088
86330
|
timestamp_t AddOperator::Operation(timestamp_t left, interval_t right) {
|
|
86089
86331
|
date_t date;
|
|
86090
86332
|
dtime_t time;
|
|
86091
86333
|
Timestamp::Convert(left, date, time);
|
|
86092
|
-
auto new_date =
|
|
86093
|
-
auto new_time =
|
|
86334
|
+
auto new_date = Interval::Add(date, right);
|
|
86335
|
+
auto new_time = Interval::Add(time, right, new_date);
|
|
86094
86336
|
return Timestamp::FromDatetime(new_date, new_time);
|
|
86095
86337
|
}
|
|
86096
86338
|
|
|
@@ -86223,7 +86465,7 @@ hugeint_t DecimalAddOverflowCheck::Operation(hugeint_t left, hugeint_t right) {
|
|
|
86223
86465
|
template <>
|
|
86224
86466
|
dtime_t AddTimeOperator::Operation(dtime_t left, interval_t right) {
|
|
86225
86467
|
date_t date(0);
|
|
86226
|
-
return
|
|
86468
|
+
return Interval::Add(left, right, date);
|
|
86227
86469
|
}
|
|
86228
86470
|
|
|
86229
86471
|
template <>
|
|
@@ -92175,7 +92417,7 @@ string_t SubstringASCII(Vector &result, string_t input, int64_t offset, int64_t
|
|
|
92175
92417
|
return SubstringSlice(result, input_data, start, end - start);
|
|
92176
92418
|
}
|
|
92177
92419
|
|
|
92178
|
-
string_t SubstringFun::SubstringScalarFunction(Vector &result, string_t input,
|
|
92420
|
+
string_t SubstringFun::SubstringScalarFunction(Vector &result, string_t input, int64_t offset, int64_t length) {
|
|
92179
92421
|
auto input_data = input.GetDataUnsafe();
|
|
92180
92422
|
auto input_size = input.GetSize();
|
|
92181
92423
|
|
|
@@ -92242,16 +92484,16 @@ static void SubstringFunction(DataChunk &args, ExpressionState &state, Vector &r
|
|
|
92242
92484
|
if (args.ColumnCount() == 3) {
|
|
92243
92485
|
auto &length_vector = args.data[2];
|
|
92244
92486
|
|
|
92245
|
-
TernaryExecutor::Execute<string_t,
|
|
92487
|
+
TernaryExecutor::Execute<string_t, int64_t, int64_t, string_t>(
|
|
92246
92488
|
input_vector, offset_vector, length_vector, result, args.size(),
|
|
92247
|
-
[&](string_t input_string,
|
|
92489
|
+
[&](string_t input_string, int64_t offset, int64_t length) {
|
|
92248
92490
|
return SubstringFun::SubstringScalarFunction(result, input_string, offset, length);
|
|
92249
92491
|
});
|
|
92250
92492
|
} else {
|
|
92251
|
-
BinaryExecutor::Execute<string_t,
|
|
92252
|
-
input_vector, offset_vector, result, args.size(), [&](string_t input_string,
|
|
92493
|
+
BinaryExecutor::Execute<string_t, int64_t, string_t>(
|
|
92494
|
+
input_vector, offset_vector, result, args.size(), [&](string_t input_string, int64_t offset) {
|
|
92253
92495
|
return SubstringFun::SubstringScalarFunction(result, input_string, offset,
|
|
92254
|
-
NumericLimits<
|
|
92496
|
+
NumericLimits<int64_t>::Maximum() - offset);
|
|
92255
92497
|
});
|
|
92256
92498
|
}
|
|
92257
92499
|
}
|
|
@@ -92262,15 +92504,15 @@ static void SubstringFunctionASCII(DataChunk &args, ExpressionState &state, Vect
|
|
|
92262
92504
|
if (args.ColumnCount() == 3) {
|
|
92263
92505
|
auto &length_vector = args.data[2];
|
|
92264
92506
|
|
|
92265
|
-
TernaryExecutor::Execute<string_t,
|
|
92507
|
+
TernaryExecutor::Execute<string_t, int64_t, int64_t, string_t>(
|
|
92266
92508
|
input_vector, offset_vector, length_vector, result, args.size(),
|
|
92267
|
-
[&](string_t input_string,
|
|
92509
|
+
[&](string_t input_string, int64_t offset, int64_t length) {
|
|
92268
92510
|
return SubstringASCII(result, input_string, offset, length);
|
|
92269
92511
|
});
|
|
92270
92512
|
} else {
|
|
92271
|
-
BinaryExecutor::Execute<string_t,
|
|
92272
|
-
input_vector, offset_vector, result, args.size(), [&](string_t input_string,
|
|
92273
|
-
return SubstringASCII(result, input_string, offset, NumericLimits<
|
|
92513
|
+
BinaryExecutor::Execute<string_t, int64_t, string_t>(
|
|
92514
|
+
input_vector, offset_vector, result, args.size(), [&](string_t input_string, int64_t offset) {
|
|
92515
|
+
return SubstringASCII(result, input_string, offset, NumericLimits<int64_t>::Maximum() - offset);
|
|
92274
92516
|
});
|
|
92275
92517
|
}
|
|
92276
92518
|
}
|
|
@@ -92292,10 +92534,10 @@ static unique_ptr<BaseStatistics> SubstringPropagateStats(ClientContext &context
|
|
|
92292
92534
|
|
|
92293
92535
|
void SubstringFun::RegisterFunction(BuiltinFunctions &set) {
|
|
92294
92536
|
ScalarFunctionSet substr("substring");
|
|
92295
|
-
substr.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::
|
|
92537
|
+
substr.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::BIGINT, LogicalType::BIGINT},
|
|
92296
92538
|
LogicalType::VARCHAR, SubstringFunction, false, nullptr, nullptr,
|
|
92297
92539
|
SubstringPropagateStats));
|
|
92298
|
-
substr.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::
|
|
92540
|
+
substr.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::BIGINT}, LogicalType::VARCHAR,
|
|
92299
92541
|
SubstringFunction, false, nullptr, nullptr, SubstringPropagateStats));
|
|
92300
92542
|
set.AddFunction(substr);
|
|
92301
92543
|
substr.name = "substr";
|
|
@@ -94477,11 +94719,7 @@ static int64_t ParseInteger(vector<Value> &set) {
|
|
|
94477
94719
|
//===--------------------------------------------------------------------===//
|
|
94478
94720
|
static bool ParseBaseOption(BufferedCSVReaderOptions &options, string &loption, vector<Value> &set) {
|
|
94479
94721
|
if (StringUtil::StartsWith(loption, "delim") || StringUtil::StartsWith(loption, "sep")) {
|
|
94480
|
-
options.
|
|
94481
|
-
options.has_delimiter = true;
|
|
94482
|
-
if (options.delimiter.length() == 0) {
|
|
94483
|
-
throw BinderException("DELIM or SEP must not be empty");
|
|
94484
|
-
}
|
|
94722
|
+
options.SetDelimiter(ParseString(set));
|
|
94485
94723
|
} else if (loption == "quote") {
|
|
94486
94724
|
options.quote = ParseString(set);
|
|
94487
94725
|
options.has_quote = true;
|
|
@@ -95766,8 +96004,7 @@ static unique_ptr<FunctionData> ReadCSVBind(ClientContext &context, vector<Value
|
|
|
95766
96004
|
if (kv.first == "auto_detect") {
|
|
95767
96005
|
options.auto_detect = kv.second.value_.boolean;
|
|
95768
96006
|
} else if (kv.first == "sep" || kv.first == "delim") {
|
|
95769
|
-
options.
|
|
95770
|
-
options.has_delimiter = true;
|
|
96007
|
+
options.SetDelimiter(kv.second.str_value);
|
|
95771
96008
|
} else if (kv.first == "header") {
|
|
95772
96009
|
options.header = kv.second.value_.boolean;
|
|
95773
96010
|
options.has_header = true;
|
|
@@ -98679,6 +98916,14 @@ TableFunction TableScanFunction::GetFunction() {
|
|
|
98679
98916
|
return scan_function;
|
|
98680
98917
|
}
|
|
98681
98918
|
|
|
98919
|
+
TableCatalogEntry *TableScanFunction::GetTableEntry(const TableFunction &function, const FunctionData *bind_data_p) {
|
|
98920
|
+
if (function.function != TableScanFunc || !bind_data_p) {
|
|
98921
|
+
return nullptr;
|
|
98922
|
+
}
|
|
98923
|
+
auto &bind_data = (TableScanBindData &)*bind_data_p;
|
|
98924
|
+
return bind_data.table;
|
|
98925
|
+
}
|
|
98926
|
+
|
|
98682
98927
|
} // namespace duckdb
|
|
98683
98928
|
|
|
98684
98929
|
|
|
@@ -100873,32 +101118,6 @@ public:
|
|
|
100873
101118
|
};
|
|
100874
101119
|
} // namespace duckdb
|
|
100875
101120
|
|
|
100876
|
-
//===----------------------------------------------------------------------===//
|
|
100877
|
-
// DuckDB
|
|
100878
|
-
//
|
|
100879
|
-
// duckdb/parser/statement/explain_statement.hpp
|
|
100880
|
-
//
|
|
100881
|
-
//
|
|
100882
|
-
//===----------------------------------------------------------------------===//
|
|
100883
|
-
|
|
100884
|
-
|
|
100885
|
-
|
|
100886
|
-
|
|
100887
|
-
|
|
100888
|
-
|
|
100889
|
-
namespace duckdb {
|
|
100890
|
-
|
|
100891
|
-
class ExplainStatement : public SQLStatement {
|
|
100892
|
-
public:
|
|
100893
|
-
explicit ExplainStatement(unique_ptr<SQLStatement> stmt);
|
|
100894
|
-
|
|
100895
|
-
unique_ptr<SQLStatement> stmt;
|
|
100896
|
-
|
|
100897
|
-
public:
|
|
100898
|
-
unique_ptr<SQLStatement> Copy() const override;
|
|
100899
|
-
};
|
|
100900
|
-
|
|
100901
|
-
} // namespace duckdb
|
|
100902
101121
|
|
|
100903
101122
|
//===----------------------------------------------------------------------===//
|
|
100904
101123
|
// DuckDB
|
|
@@ -101453,6 +101672,17 @@ unique_ptr<QueryResult> ClientContext::RunStatementInternal(ClientContextLock &l
|
|
|
101453
101672
|
return ExecutePreparedStatement(lock, query, move(prepared), move(bound_values), allow_stream_result);
|
|
101454
101673
|
}
|
|
101455
101674
|
|
|
101675
|
+
static bool IsExplainAnalyze(SQLStatement *statement) {
|
|
101676
|
+
if (!statement) {
|
|
101677
|
+
return false;
|
|
101678
|
+
}
|
|
101679
|
+
if (statement->type != StatementType::EXPLAIN_STATEMENT) {
|
|
101680
|
+
return false;
|
|
101681
|
+
}
|
|
101682
|
+
auto &explain = (ExplainStatement &)*statement;
|
|
101683
|
+
return explain.explain_type == ExplainType::EXPLAIN_ANALYZE;
|
|
101684
|
+
}
|
|
101685
|
+
|
|
101456
101686
|
unique_ptr<QueryResult> ClientContext::RunStatementOrPreparedStatement(ClientContextLock &lock, const string &query,
|
|
101457
101687
|
unique_ptr<SQLStatement> statement,
|
|
101458
101688
|
shared_ptr<PreparedStatementData> &prepared,
|
|
@@ -101484,7 +101714,7 @@ unique_ptr<QueryResult> ClientContext::RunStatementOrPreparedStatement(ClientCon
|
|
|
101484
101714
|
statement = move(copied_statement);
|
|
101485
101715
|
}
|
|
101486
101716
|
// start the profiler
|
|
101487
|
-
profiler->StartQuery(query);
|
|
101717
|
+
profiler->StartQuery(query, IsExplainAnalyze(statement ? statement.get() : prepared->unbound_statement.get()));
|
|
101488
101718
|
try {
|
|
101489
101719
|
if (statement) {
|
|
101490
101720
|
result = RunStatementInternal(lock, query, move(statement), allow_stream_result);
|
|
@@ -103272,7 +103502,10 @@ using std::ofstream;
|
|
|
103272
103502
|
|
|
103273
103503
|
namespace duckdb {
|
|
103274
103504
|
|
|
103275
|
-
void QueryProfiler::StartQuery(string query) {
|
|
103505
|
+
void QueryProfiler::StartQuery(string query, bool is_explain_analyze) {
|
|
103506
|
+
if (is_explain_analyze) {
|
|
103507
|
+
StartExplainAnalyze();
|
|
103508
|
+
}
|
|
103276
103509
|
if (!enabled) {
|
|
103277
103510
|
return;
|
|
103278
103511
|
}
|
|
@@ -103328,6 +103561,17 @@ void QueryProfiler::Finalize(TreeNode &node) {
|
|
|
103328
103561
|
}
|
|
103329
103562
|
}
|
|
103330
103563
|
|
|
103564
|
+
void QueryProfiler::StartExplainAnalyze() {
|
|
103565
|
+
this->is_explain_analyze = true;
|
|
103566
|
+
this->stored_enabled = enabled;
|
|
103567
|
+
this->stored_automatic_print_format = automatic_print_format;
|
|
103568
|
+
this->stored_save_location = save_location;
|
|
103569
|
+
|
|
103570
|
+
this->enabled = true;
|
|
103571
|
+
this->save_location = string();
|
|
103572
|
+
this->automatic_print_format = ProfilerPrintFormat::NONE;
|
|
103573
|
+
}
|
|
103574
|
+
|
|
103331
103575
|
void QueryProfiler::EndQuery() {
|
|
103332
103576
|
if (!enabled || !running) {
|
|
103333
103577
|
return;
|
|
@@ -103357,6 +103601,12 @@ void QueryProfiler::EndQuery() {
|
|
|
103357
103601
|
WriteToFile(save_location.c_str(), query_info);
|
|
103358
103602
|
}
|
|
103359
103603
|
}
|
|
103604
|
+
if (is_explain_analyze) {
|
|
103605
|
+
this->is_explain_analyze = false;
|
|
103606
|
+
this->enabled = stored_enabled;
|
|
103607
|
+
this->automatic_print_format = stored_automatic_print_format;
|
|
103608
|
+
this->save_location = stored_save_location;
|
|
103609
|
+
}
|
|
103360
103610
|
}
|
|
103361
103611
|
|
|
103362
103612
|
void QueryProfiler::StartPhase(string new_phase) {
|
|
@@ -106452,10 +106702,10 @@ shared_ptr<Relation> Relation::Join(const shared_ptr<Relation> &other, const str
|
|
|
106452
106702
|
throw ParserException("Expected a single expression as join condition");
|
|
106453
106703
|
}
|
|
106454
106704
|
auto &colref = (ColumnRefExpression &)*expr;
|
|
106455
|
-
if (
|
|
106456
|
-
throw ParserException("Expected
|
|
106705
|
+
if (colref.IsQualified()) {
|
|
106706
|
+
throw ParserException("Expected unqualified column for column in USING clause");
|
|
106457
106707
|
}
|
|
106458
|
-
using_columns.push_back(colref.
|
|
106708
|
+
using_columns.push_back(colref.column_names[0]);
|
|
106459
106709
|
}
|
|
106460
106710
|
return make_shared<JoinRelation>(shared_from_this(), other, move(using_columns), type);
|
|
106461
106711
|
} else {
|
|
@@ -115073,6 +115323,10 @@ unique_ptr<NodeStatistics> StatisticsPropagator::PropagateStatistics(LogicalProj
|
|
|
115073
115323
|
unique_ptr<LogicalOperator> *node_ptr) {
|
|
115074
115324
|
// first propagate to the child
|
|
115075
115325
|
node_stats = PropagateStatistics(proj.children[0]);
|
|
115326
|
+
if (proj.children[0]->type == LogicalOperatorType::LOGICAL_EMPTY_RESULT) {
|
|
115327
|
+
ReplaceWithEmptyResult(*node_ptr);
|
|
115328
|
+
return move(node_stats);
|
|
115329
|
+
}
|
|
115076
115330
|
|
|
115077
115331
|
// then propagate to each of the expressions
|
|
115078
115332
|
for (idx_t i = 0; i < proj.expressions.size(); i++) {
|
|
@@ -115998,6 +116252,7 @@ void Executor::BuildPipelines(PhysicalOperator *op, Pipeline *current) {
|
|
|
115998
116252
|
case PhysicalOperatorType::COPY_TO_FILE:
|
|
115999
116253
|
case PhysicalOperatorType::LIMIT:
|
|
116000
116254
|
case PhysicalOperatorType::EXPRESSION_SCAN:
|
|
116255
|
+
case PhysicalOperatorType::EXPLAIN_ANALYZE:
|
|
116001
116256
|
D_ASSERT(op->children.size() == 1);
|
|
116002
116257
|
// single operator:
|
|
116003
116258
|
// the operator becomes the data source of the current pipeline
|
|
@@ -121749,53 +122004,85 @@ unique_ptr<ParsedExpression> CollateExpression::Deserialize(ExpressionType type,
|
|
|
121749
122004
|
|
|
121750
122005
|
namespace duckdb {
|
|
121751
122006
|
|
|
121752
|
-
//! Specify both the column and table name
|
|
121753
122007
|
ColumnRefExpression::ColumnRefExpression(string column_name, string table_name)
|
|
121754
|
-
:
|
|
121755
|
-
|
|
122008
|
+
: ColumnRefExpression(table_name.empty() ? vector<string> {move(column_name)}
|
|
122009
|
+
: vector<string> {move(table_name), move(column_name)}) {
|
|
121756
122010
|
}
|
|
121757
122011
|
|
|
121758
|
-
ColumnRefExpression::ColumnRefExpression(string column_name) : ColumnRefExpression(move(column_name)
|
|
122012
|
+
ColumnRefExpression::ColumnRefExpression(string column_name) : ColumnRefExpression(vector<string> {move(column_name)}) {
|
|
122013
|
+
}
|
|
122014
|
+
|
|
122015
|
+
ColumnRefExpression::ColumnRefExpression(vector<string> column_names_p)
|
|
122016
|
+
: ParsedExpression(ExpressionType::COLUMN_REF, ExpressionClass::COLUMN_REF), column_names(move(column_names_p)) {
|
|
122017
|
+
#ifdef DEBUG
|
|
122018
|
+
for (auto &col_name : column_names) {
|
|
122019
|
+
D_ASSERT(!col_name.empty());
|
|
122020
|
+
}
|
|
122021
|
+
#endif
|
|
122022
|
+
}
|
|
122023
|
+
|
|
122024
|
+
bool ColumnRefExpression::IsQualified() const {
|
|
122025
|
+
return column_names.size() > 1;
|
|
122026
|
+
}
|
|
122027
|
+
|
|
122028
|
+
const string &ColumnRefExpression::GetColumnName() const {
|
|
122029
|
+
D_ASSERT(column_names.size() <= 3);
|
|
122030
|
+
return column_names.back();
|
|
122031
|
+
}
|
|
122032
|
+
|
|
122033
|
+
const string &ColumnRefExpression::GetTableName() const {
|
|
122034
|
+
D_ASSERT(column_names.size() >= 2 && column_names.size() <= 3);
|
|
122035
|
+
return column_names.size() == 3 ? column_names[1] : column_names[0];
|
|
121759
122036
|
}
|
|
121760
122037
|
|
|
121761
122038
|
string ColumnRefExpression::GetName() const {
|
|
121762
|
-
return !alias.empty() ? alias :
|
|
122039
|
+
return !alias.empty() ? alias : column_names.back();
|
|
121763
122040
|
}
|
|
121764
122041
|
|
|
121765
122042
|
string ColumnRefExpression::ToString() const {
|
|
121766
|
-
|
|
121767
|
-
|
|
121768
|
-
|
|
121769
|
-
|
|
122043
|
+
string result;
|
|
122044
|
+
for (idx_t i = 0; i < column_names.size(); i++) {
|
|
122045
|
+
if (i > 0) {
|
|
122046
|
+
result += ".";
|
|
122047
|
+
}
|
|
122048
|
+
result += column_names[i];
|
|
121770
122049
|
}
|
|
122050
|
+
return result;
|
|
121771
122051
|
}
|
|
121772
122052
|
|
|
121773
122053
|
bool ColumnRefExpression::Equals(const ColumnRefExpression *a, const ColumnRefExpression *b) {
|
|
121774
|
-
return a->
|
|
122054
|
+
return a->column_names == b->column_names;
|
|
121775
122055
|
}
|
|
121776
122056
|
|
|
121777
122057
|
hash_t ColumnRefExpression::Hash() const {
|
|
121778
122058
|
hash_t result = ParsedExpression::Hash();
|
|
121779
|
-
|
|
122059
|
+
for (auto &column_name : column_names) {
|
|
122060
|
+
result = CombineHash(result, duckdb::Hash<const char *>(column_name.c_str()));
|
|
122061
|
+
}
|
|
121780
122062
|
return result;
|
|
121781
122063
|
}
|
|
121782
122064
|
|
|
121783
122065
|
unique_ptr<ParsedExpression> ColumnRefExpression::Copy() const {
|
|
121784
|
-
auto copy = make_unique<ColumnRefExpression>(
|
|
122066
|
+
auto copy = make_unique<ColumnRefExpression>(column_names);
|
|
121785
122067
|
copy->CopyProperties(*this);
|
|
121786
122068
|
return move(copy);
|
|
121787
122069
|
}
|
|
121788
122070
|
|
|
121789
122071
|
void ColumnRefExpression::Serialize(Serializer &serializer) {
|
|
121790
122072
|
ParsedExpression::Serialize(serializer);
|
|
121791
|
-
serializer.
|
|
121792
|
-
|
|
122073
|
+
serializer.Write<idx_t>(column_names.size());
|
|
122074
|
+
for (auto &column_name : column_names) {
|
|
122075
|
+
serializer.WriteString(column_name);
|
|
122076
|
+
}
|
|
121793
122077
|
}
|
|
121794
122078
|
|
|
121795
122079
|
unique_ptr<ParsedExpression> ColumnRefExpression::Deserialize(ExpressionType type, Deserializer &source) {
|
|
121796
|
-
auto
|
|
121797
|
-
|
|
121798
|
-
|
|
122080
|
+
auto column_count = source.Read<idx_t>();
|
|
122081
|
+
vector<string> column_names;
|
|
122082
|
+
for (idx_t i = 0; i < column_count; i++) {
|
|
122083
|
+
column_names.push_back(source.Read<string>());
|
|
122084
|
+
}
|
|
122085
|
+
auto expression = make_unique<ColumnRefExpression>(move(column_names));
|
|
121799
122086
|
return move(expression);
|
|
121800
122087
|
}
|
|
121801
122088
|
|
|
@@ -123541,6 +123828,129 @@ unique_ptr<ParsedExpression> ParsedExpression::Deserialize(Deserializer &source)
|
|
|
123541
123828
|
|
|
123542
123829
|
|
|
123543
123830
|
|
|
123831
|
+
//===----------------------------------------------------------------------===//
|
|
123832
|
+
// DuckDB
|
|
123833
|
+
//
|
|
123834
|
+
// duckdb/parser/query_node/recursive_cte_node.hpp
|
|
123835
|
+
//
|
|
123836
|
+
//
|
|
123837
|
+
//===----------------------------------------------------------------------===//
|
|
123838
|
+
|
|
123839
|
+
|
|
123840
|
+
|
|
123841
|
+
|
|
123842
|
+
|
|
123843
|
+
|
|
123844
|
+
|
|
123845
|
+
namespace duckdb {
|
|
123846
|
+
|
|
123847
|
+
class RecursiveCTENode : public QueryNode {
|
|
123848
|
+
public:
|
|
123849
|
+
RecursiveCTENode() : QueryNode(QueryNodeType::RECURSIVE_CTE_NODE) {
|
|
123850
|
+
}
|
|
123851
|
+
|
|
123852
|
+
string ctename;
|
|
123853
|
+
bool union_all;
|
|
123854
|
+
//! The left side of the set operation
|
|
123855
|
+
unique_ptr<QueryNode> left;
|
|
123856
|
+
//! The right side of the set operation
|
|
123857
|
+
unique_ptr<QueryNode> right;
|
|
123858
|
+
//! Aliases of the recursive CTE node
|
|
123859
|
+
vector<string> aliases;
|
|
123860
|
+
|
|
123861
|
+
const vector<unique_ptr<ParsedExpression>> &GetSelectList() const override {
|
|
123862
|
+
return left->GetSelectList();
|
|
123863
|
+
}
|
|
123864
|
+
|
|
123865
|
+
public:
|
|
123866
|
+
bool Equals(const QueryNode *other) const override;
|
|
123867
|
+
//! Create a copy of this SelectNode
|
|
123868
|
+
unique_ptr<QueryNode> Copy() override;
|
|
123869
|
+
|
|
123870
|
+
//! Serializes a SelectNode to a stand-alone binary blob
|
|
123871
|
+
void Serialize(Serializer &serializer) override;
|
|
123872
|
+
//! Deserializes a blob back into a SelectNode
|
|
123873
|
+
static unique_ptr<QueryNode> Deserialize(Deserializer &source);
|
|
123874
|
+
};
|
|
123875
|
+
|
|
123876
|
+
} // namespace duckdb
|
|
123877
|
+
|
|
123878
|
+
|
|
123879
|
+
|
|
123880
|
+
|
|
123881
|
+
//===----------------------------------------------------------------------===//
|
|
123882
|
+
// DuckDB
|
|
123883
|
+
//
|
|
123884
|
+
// duckdb/parser/tableref/crossproductref.hpp
|
|
123885
|
+
//
|
|
123886
|
+
//
|
|
123887
|
+
//===----------------------------------------------------------------------===//
|
|
123888
|
+
|
|
123889
|
+
|
|
123890
|
+
|
|
123891
|
+
|
|
123892
|
+
|
|
123893
|
+
namespace duckdb {
|
|
123894
|
+
//! Represents a cross product
|
|
123895
|
+
class CrossProductRef : public TableRef {
|
|
123896
|
+
public:
|
|
123897
|
+
CrossProductRef() : TableRef(TableReferenceType::CROSS_PRODUCT) {
|
|
123898
|
+
}
|
|
123899
|
+
|
|
123900
|
+
//! The left hand side of the cross product
|
|
123901
|
+
unique_ptr<TableRef> left;
|
|
123902
|
+
//! The right hand side of the cross product
|
|
123903
|
+
unique_ptr<TableRef> right;
|
|
123904
|
+
|
|
123905
|
+
public:
|
|
123906
|
+
bool Equals(const TableRef *other_p) const override;
|
|
123907
|
+
|
|
123908
|
+
unique_ptr<TableRef> Copy() override;
|
|
123909
|
+
|
|
123910
|
+
//! Serializes a blob into a CrossProductRef
|
|
123911
|
+
void Serialize(Serializer &serializer) override;
|
|
123912
|
+
//! Deserializes a blob back into a CrossProductRef
|
|
123913
|
+
static unique_ptr<TableRef> Deserialize(Deserializer &source);
|
|
123914
|
+
};
|
|
123915
|
+
} // namespace duckdb
|
|
123916
|
+
|
|
123917
|
+
//===----------------------------------------------------------------------===//
|
|
123918
|
+
// DuckDB
|
|
123919
|
+
//
|
|
123920
|
+
// duckdb/parser/tableref/emptytableref.hpp
|
|
123921
|
+
//
|
|
123922
|
+
//
|
|
123923
|
+
//===----------------------------------------------------------------------===//
|
|
123924
|
+
|
|
123925
|
+
|
|
123926
|
+
|
|
123927
|
+
|
|
123928
|
+
|
|
123929
|
+
namespace duckdb {
|
|
123930
|
+
//! Represents a cross product
|
|
123931
|
+
class EmptyTableRef : public TableRef {
|
|
123932
|
+
public:
|
|
123933
|
+
EmptyTableRef() : TableRef(TableReferenceType::EMPTY) {
|
|
123934
|
+
}
|
|
123935
|
+
|
|
123936
|
+
public:
|
|
123937
|
+
bool Equals(const TableRef *other_p) const override;
|
|
123938
|
+
|
|
123939
|
+
unique_ptr<TableRef> Copy() override;
|
|
123940
|
+
|
|
123941
|
+
//! Serializes a blob into a DummyTableRef
|
|
123942
|
+
void Serialize(Serializer &serializer) override;
|
|
123943
|
+
//! Deserializes a blob back into a DummyTableRef
|
|
123944
|
+
static unique_ptr<TableRef> Deserialize(Deserializer &source);
|
|
123945
|
+
};
|
|
123946
|
+
} // namespace duckdb
|
|
123947
|
+
|
|
123948
|
+
|
|
123949
|
+
|
|
123950
|
+
|
|
123951
|
+
|
|
123952
|
+
|
|
123953
|
+
|
|
123544
123954
|
namespace duckdb {
|
|
123545
123955
|
|
|
123546
123956
|
void ParsedExpressionIterator::EnumerateChildren(const ParsedExpression &expression,
|
|
@@ -123676,6 +124086,91 @@ void ParsedExpressionIterator::EnumerateChildren(
|
|
|
123676
124086
|
}
|
|
123677
124087
|
}
|
|
123678
124088
|
|
|
124089
|
+
void ParsedExpressionIterator::EnumerateTableRefChildren(
|
|
124090
|
+
TableRef &ref, const std::function<void(unique_ptr<ParsedExpression> &child)> &callback) {
|
|
124091
|
+
switch (ref.type) {
|
|
124092
|
+
case TableReferenceType::CROSS_PRODUCT: {
|
|
124093
|
+
auto &cp_ref = (CrossProductRef &)ref;
|
|
124094
|
+
EnumerateTableRefChildren(*cp_ref.left, callback);
|
|
124095
|
+
EnumerateTableRefChildren(*cp_ref.right, callback);
|
|
124096
|
+
break;
|
|
124097
|
+
}
|
|
124098
|
+
case TableReferenceType::EXPRESSION_LIST: {
|
|
124099
|
+
auto &el_ref = (ExpressionListRef &)ref;
|
|
124100
|
+
for (idx_t i = 0; i < el_ref.values.size(); i++) {
|
|
124101
|
+
for (idx_t j = 0; j < el_ref.values[i].size(); j++) {
|
|
124102
|
+
callback(el_ref.values[i][j]);
|
|
124103
|
+
}
|
|
124104
|
+
}
|
|
124105
|
+
break;
|
|
124106
|
+
}
|
|
124107
|
+
case TableReferenceType::JOIN: {
|
|
124108
|
+
auto &j_ref = (JoinRef &)ref;
|
|
124109
|
+
EnumerateTableRefChildren(*j_ref.left, callback);
|
|
124110
|
+
EnumerateTableRefChildren(*j_ref.right, callback);
|
|
124111
|
+
callback(j_ref.condition);
|
|
124112
|
+
break;
|
|
124113
|
+
}
|
|
124114
|
+
case TableReferenceType::SUBQUERY: {
|
|
124115
|
+
auto &sq_ref = (SubqueryRef &)ref;
|
|
124116
|
+
EnumerateQueryNodeChildren(*sq_ref.subquery->node, callback);
|
|
124117
|
+
break;
|
|
124118
|
+
}
|
|
124119
|
+
case TableReferenceType::TABLE_FUNCTION: {
|
|
124120
|
+
auto &tf_ref = (TableFunctionRef &)ref;
|
|
124121
|
+
callback(tf_ref.function);
|
|
124122
|
+
break;
|
|
124123
|
+
}
|
|
124124
|
+
case TableReferenceType::BASE_TABLE:
|
|
124125
|
+
case TableReferenceType::EMPTY:
|
|
124126
|
+
// these TableRefs do not need to be unfolded
|
|
124127
|
+
break;
|
|
124128
|
+
default:
|
|
124129
|
+
throw NotImplementedException("TableRef type not implemented for traversal");
|
|
124130
|
+
}
|
|
124131
|
+
}
|
|
124132
|
+
|
|
124133
|
+
void ParsedExpressionIterator::EnumerateQueryNodeChildren(
|
|
124134
|
+
QueryNode &node, const std::function<void(unique_ptr<ParsedExpression> &child)> &callback) {
|
|
124135
|
+
switch (node.type) {
|
|
124136
|
+
case QueryNodeType::RECURSIVE_CTE_NODE: {
|
|
124137
|
+
auto &rcte_node = (RecursiveCTENode &)node;
|
|
124138
|
+
EnumerateQueryNodeChildren(*rcte_node.left, callback);
|
|
124139
|
+
EnumerateQueryNodeChildren(*rcte_node.right, callback);
|
|
124140
|
+
break;
|
|
124141
|
+
}
|
|
124142
|
+
case QueryNodeType::SELECT_NODE: {
|
|
124143
|
+
auto &sel_node = (SelectNode &)node;
|
|
124144
|
+
for (idx_t i = 0; i < sel_node.select_list.size(); i++) {
|
|
124145
|
+
callback(sel_node.select_list[i]);
|
|
124146
|
+
}
|
|
124147
|
+
for (idx_t i = 0; i < sel_node.groups.group_expressions.size(); i++) {
|
|
124148
|
+
callback(sel_node.groups.group_expressions[i]);
|
|
124149
|
+
}
|
|
124150
|
+
if (sel_node.where_clause) {
|
|
124151
|
+
callback(sel_node.where_clause);
|
|
124152
|
+
}
|
|
124153
|
+
if (sel_node.having) {
|
|
124154
|
+
callback(sel_node.having);
|
|
124155
|
+
}
|
|
124156
|
+
|
|
124157
|
+
EnumerateTableRefChildren(*sel_node.from_table.get(), callback);
|
|
124158
|
+
break;
|
|
124159
|
+
}
|
|
124160
|
+
case QueryNodeType::SET_OPERATION_NODE: {
|
|
124161
|
+
auto &setop_node = (SetOperationNode &)node;
|
|
124162
|
+
EnumerateQueryNodeChildren(*setop_node.left, callback);
|
|
124163
|
+
EnumerateQueryNodeChildren(*setop_node.right, callback);
|
|
124164
|
+
break;
|
|
124165
|
+
}
|
|
124166
|
+
default:
|
|
124167
|
+
throw NotImplementedException("QueryNode type not implemented for traversal");
|
|
124168
|
+
}
|
|
124169
|
+
for (auto &kv : node.cte_map) {
|
|
124170
|
+
EnumerateQueryNodeChildren(*kv.second->query->node, callback);
|
|
124171
|
+
}
|
|
124172
|
+
}
|
|
124173
|
+
|
|
123679
124174
|
} // namespace duckdb
|
|
123680
124175
|
|
|
123681
124176
|
|
|
@@ -129322,52 +129817,6 @@ string QueryErrorContext::FormatErrorRecursive(const string &msg, vector<Excepti
|
|
|
129322
129817
|
return Format(statement->query, error_message, query_location);
|
|
129323
129818
|
}
|
|
129324
129819
|
|
|
129325
|
-
} // namespace duckdb
|
|
129326
|
-
//===----------------------------------------------------------------------===//
|
|
129327
|
-
// DuckDB
|
|
129328
|
-
//
|
|
129329
|
-
// duckdb/parser/query_node/recursive_cte_node.hpp
|
|
129330
|
-
//
|
|
129331
|
-
//
|
|
129332
|
-
//===----------------------------------------------------------------------===//
|
|
129333
|
-
|
|
129334
|
-
|
|
129335
|
-
|
|
129336
|
-
|
|
129337
|
-
|
|
129338
|
-
|
|
129339
|
-
|
|
129340
|
-
namespace duckdb {
|
|
129341
|
-
|
|
129342
|
-
class RecursiveCTENode : public QueryNode {
|
|
129343
|
-
public:
|
|
129344
|
-
RecursiveCTENode() : QueryNode(QueryNodeType::RECURSIVE_CTE_NODE) {
|
|
129345
|
-
}
|
|
129346
|
-
|
|
129347
|
-
string ctename;
|
|
129348
|
-
bool union_all;
|
|
129349
|
-
//! The left side of the set operation
|
|
129350
|
-
unique_ptr<QueryNode> left;
|
|
129351
|
-
//! The right side of the set operation
|
|
129352
|
-
unique_ptr<QueryNode> right;
|
|
129353
|
-
//! Aliases of the recursive CTE node
|
|
129354
|
-
vector<string> aliases;
|
|
129355
|
-
|
|
129356
|
-
const vector<unique_ptr<ParsedExpression>> &GetSelectList() const override {
|
|
129357
|
-
return left->GetSelectList();
|
|
129358
|
-
}
|
|
129359
|
-
|
|
129360
|
-
public:
|
|
129361
|
-
bool Equals(const QueryNode *other) const override;
|
|
129362
|
-
//! Create a copy of this SelectNode
|
|
129363
|
-
unique_ptr<QueryNode> Copy() override;
|
|
129364
|
-
|
|
129365
|
-
//! Serializes a SelectNode to a stand-alone binary blob
|
|
129366
|
-
void Serialize(Serializer &serializer) override;
|
|
129367
|
-
//! Deserializes a blob back into a SelectNode
|
|
129368
|
-
static unique_ptr<QueryNode> Deserialize(Deserializer &source);
|
|
129369
|
-
};
|
|
129370
|
-
|
|
129371
129820
|
} // namespace duckdb
|
|
129372
129821
|
|
|
129373
129822
|
|
|
@@ -130046,12 +130495,12 @@ unique_ptr<SQLStatement> ExecuteStatement::Copy() const {
|
|
|
130046
130495
|
|
|
130047
130496
|
namespace duckdb {
|
|
130048
130497
|
|
|
130049
|
-
ExplainStatement::ExplainStatement(unique_ptr<SQLStatement> stmt)
|
|
130050
|
-
: SQLStatement(StatementType::EXPLAIN_STATEMENT), stmt(move(stmt)) {
|
|
130498
|
+
ExplainStatement::ExplainStatement(unique_ptr<SQLStatement> stmt, ExplainType explain_type)
|
|
130499
|
+
: SQLStatement(StatementType::EXPLAIN_STATEMENT), stmt(move(stmt)), explain_type(explain_type) {
|
|
130051
130500
|
}
|
|
130052
130501
|
|
|
130053
130502
|
unique_ptr<SQLStatement> ExplainStatement::Copy() const {
|
|
130054
|
-
auto result = make_unique<ExplainStatement>(stmt->Copy());
|
|
130503
|
+
auto result = make_unique<ExplainStatement>(stmt->Copy(), explain_type);
|
|
130055
130504
|
return move(result);
|
|
130056
130505
|
}
|
|
130057
130506
|
|
|
@@ -130456,41 +130905,6 @@ unique_ptr<TableRef> BaseTableRef::Copy() {
|
|
|
130456
130905
|
return move(copy);
|
|
130457
130906
|
}
|
|
130458
130907
|
} // namespace duckdb
|
|
130459
|
-
//===----------------------------------------------------------------------===//
|
|
130460
|
-
// DuckDB
|
|
130461
|
-
//
|
|
130462
|
-
// duckdb/parser/tableref/crossproductref.hpp
|
|
130463
|
-
//
|
|
130464
|
-
//
|
|
130465
|
-
//===----------------------------------------------------------------------===//
|
|
130466
|
-
|
|
130467
|
-
|
|
130468
|
-
|
|
130469
|
-
|
|
130470
|
-
|
|
130471
|
-
namespace duckdb {
|
|
130472
|
-
//! Represents a cross product
|
|
130473
|
-
class CrossProductRef : public TableRef {
|
|
130474
|
-
public:
|
|
130475
|
-
CrossProductRef() : TableRef(TableReferenceType::CROSS_PRODUCT) {
|
|
130476
|
-
}
|
|
130477
|
-
|
|
130478
|
-
//! The left hand side of the cross product
|
|
130479
|
-
unique_ptr<TableRef> left;
|
|
130480
|
-
//! The right hand side of the cross product
|
|
130481
|
-
unique_ptr<TableRef> right;
|
|
130482
|
-
|
|
130483
|
-
public:
|
|
130484
|
-
bool Equals(const TableRef *other_p) const override;
|
|
130485
|
-
|
|
130486
|
-
unique_ptr<TableRef> Copy() override;
|
|
130487
|
-
|
|
130488
|
-
//! Serializes a blob into a CrossProductRef
|
|
130489
|
-
void Serialize(Serializer &serializer) override;
|
|
130490
|
-
//! Deserializes a blob back into a CrossProductRef
|
|
130491
|
-
static unique_ptr<TableRef> Deserialize(Deserializer &source);
|
|
130492
|
-
};
|
|
130493
|
-
} // namespace duckdb
|
|
130494
130908
|
|
|
130495
130909
|
|
|
130496
130910
|
|
|
@@ -130534,36 +130948,6 @@ unique_ptr<TableRef> CrossProductRef::Deserialize(Deserializer &source) {
|
|
|
130534
130948
|
}
|
|
130535
130949
|
|
|
130536
130950
|
} // namespace duckdb
|
|
130537
|
-
//===----------------------------------------------------------------------===//
|
|
130538
|
-
// DuckDB
|
|
130539
|
-
//
|
|
130540
|
-
// duckdb/parser/tableref/emptytableref.hpp
|
|
130541
|
-
//
|
|
130542
|
-
//
|
|
130543
|
-
//===----------------------------------------------------------------------===//
|
|
130544
|
-
|
|
130545
|
-
|
|
130546
|
-
|
|
130547
|
-
|
|
130548
|
-
|
|
130549
|
-
namespace duckdb {
|
|
130550
|
-
//! Represents a cross product
|
|
130551
|
-
class EmptyTableRef : public TableRef {
|
|
130552
|
-
public:
|
|
130553
|
-
EmptyTableRef() : TableRef(TableReferenceType::EMPTY) {
|
|
130554
|
-
}
|
|
130555
|
-
|
|
130556
|
-
public:
|
|
130557
|
-
bool Equals(const TableRef *other_p) const override;
|
|
130558
|
-
|
|
130559
|
-
unique_ptr<TableRef> Copy() override;
|
|
130560
|
-
|
|
130561
|
-
//! Serializes a blob into a DummyTableRef
|
|
130562
|
-
void Serialize(Serializer &serializer) override;
|
|
130563
|
-
//! Deserializes a blob back into a DummyTableRef
|
|
130564
|
-
static unique_ptr<TableRef> Deserialize(Deserializer &source);
|
|
130565
|
-
};
|
|
130566
|
-
} // namespace duckdb
|
|
130567
130951
|
|
|
130568
130952
|
|
|
130569
130953
|
|
|
@@ -130833,13 +131217,6 @@ unique_ptr<TableRef> TableFunctionRef::Copy() {
|
|
|
130833
131217
|
|
|
130834
131218
|
|
|
130835
131219
|
|
|
130836
|
-
|
|
130837
|
-
|
|
130838
|
-
|
|
130839
|
-
|
|
130840
|
-
|
|
130841
|
-
|
|
130842
|
-
|
|
130843
131220
|
namespace duckdb {
|
|
130844
131221
|
|
|
130845
131222
|
string TableRef::ToString() const {
|
|
@@ -131220,28 +131597,13 @@ unique_ptr<ParsedExpression> Transformer::TransformColumnRef(duckdb_libpgquery::
|
|
|
131220
131597
|
if (fields->length < 1) {
|
|
131221
131598
|
throw InternalException("Unexpected field length");
|
|
131222
131599
|
}
|
|
131223
|
-
string
|
|
131224
|
-
|
|
131225
|
-
|
|
131226
|
-
auto colref = make_unique<ColumnRefExpression>(column_name, table_name);
|
|
131227
|
-
colref->query_location = root->location;
|
|
131228
|
-
return move(colref);
|
|
131229
|
-
} else if (fields->length == 2) {
|
|
131230
|
-
table_name = string(reinterpret_cast<duckdb_libpgquery::PGValue *>(fields->head->data.ptr_value)->val.str);
|
|
131231
|
-
auto col_node = reinterpret_cast<duckdb_libpgquery::PGNode *>(fields->head->next->data.ptr_value);
|
|
131232
|
-
switch (col_node->type) {
|
|
131233
|
-
case duckdb_libpgquery::T_PGString: {
|
|
131234
|
-
column_name = string(reinterpret_cast<duckdb_libpgquery::PGValue *>(col_node)->val.str);
|
|
131235
|
-
auto colref = make_unique<ColumnRefExpression>(column_name, table_name);
|
|
131236
|
-
colref->query_location = root->location;
|
|
131237
|
-
return move(colref);
|
|
131238
|
-
}
|
|
131239
|
-
default:
|
|
131240
|
-
throw NotImplementedException("ColumnRef not implemented!");
|
|
131241
|
-
}
|
|
131242
|
-
} else {
|
|
131243
|
-
throw NotImplementedException("ColumnRef not implemented!");
|
|
131600
|
+
vector<string> column_names;
|
|
131601
|
+
for (auto node = fields->head; node; node = node->next) {
|
|
131602
|
+
column_names.emplace_back(reinterpret_cast<duckdb_libpgquery::PGValue *>(node->data.ptr_value)->val.str);
|
|
131244
131603
|
}
|
|
131604
|
+
auto colref = make_unique<ColumnRefExpression>(move(column_names));
|
|
131605
|
+
colref->query_location = root->location;
|
|
131606
|
+
return move(colref);
|
|
131245
131607
|
}
|
|
131246
131608
|
case duckdb_libpgquery::T_PGAStar: {
|
|
131247
131609
|
return TransformStarExpression(head_node);
|
|
@@ -131912,10 +132274,10 @@ static string ExtractColumnFromLambda(ParsedExpression &expr) {
|
|
|
131912
132274
|
throw ParserException("Lambda parameter must be a column name");
|
|
131913
132275
|
}
|
|
131914
132276
|
auto &colref = (ColumnRefExpression &)expr;
|
|
131915
|
-
if (
|
|
132277
|
+
if (colref.IsQualified()) {
|
|
131916
132278
|
throw ParserException("Lambda parameter must be an unqualified name (e.g. 'x', not 'a.x')");
|
|
131917
132279
|
}
|
|
131918
|
-
return colref.
|
|
132280
|
+
return colref.column_names[0];
|
|
131919
132281
|
}
|
|
131920
132282
|
|
|
131921
132283
|
unique_ptr<ParsedExpression> Transformer::TransformLambda(duckdb_libpgquery::PGLambdaFunction *node) {
|
|
@@ -134397,7 +134759,19 @@ namespace duckdb {
|
|
|
134397
134759
|
unique_ptr<ExplainStatement> Transformer::TransformExplain(duckdb_libpgquery::PGNode *node) {
|
|
134398
134760
|
auto stmt = reinterpret_cast<duckdb_libpgquery::PGExplainStmt *>(node);
|
|
134399
134761
|
D_ASSERT(stmt);
|
|
134400
|
-
|
|
134762
|
+
auto explain_type = ExplainType::EXPLAIN_STANDARD;
|
|
134763
|
+
if (stmt->options) {
|
|
134764
|
+
for (auto n = stmt->options->head; n; n = n->next) {
|
|
134765
|
+
auto def_elem = ((duckdb_libpgquery::PGDefElem *)n->data.ptr_value)->defname;
|
|
134766
|
+
string elem(def_elem);
|
|
134767
|
+
if (elem == "analyze") {
|
|
134768
|
+
explain_type = ExplainType::EXPLAIN_ANALYZE;
|
|
134769
|
+
} else {
|
|
134770
|
+
throw NotImplementedException("Unimplemented explain type: %s", elem);
|
|
134771
|
+
}
|
|
134772
|
+
}
|
|
134773
|
+
}
|
|
134774
|
+
return make_unique<ExplainStatement>(TransformStatement(stmt->query), explain_type);
|
|
134401
134775
|
}
|
|
134402
134776
|
|
|
134403
134777
|
} // namespace duckdb
|
|
@@ -135570,6 +135944,34 @@ unordered_set<string> BindContext::GetMatchingBindings(const string &column_name
|
|
|
135570
135944
|
return result;
|
|
135571
135945
|
}
|
|
135572
135946
|
|
|
135947
|
+
unique_ptr<ParsedExpression> BindContext::CreateColumnReference(const string &table_name, const string &column_name) {
|
|
135948
|
+
string schema_name;
|
|
135949
|
+
return CreateColumnReference(schema_name, table_name, column_name);
|
|
135950
|
+
}
|
|
135951
|
+
|
|
135952
|
+
unique_ptr<ParsedExpression> BindContext::CreateColumnReference(const string &schema_name, const string &table_name,
|
|
135953
|
+
const string &column_name) {
|
|
135954
|
+
string error_message;
|
|
135955
|
+
vector<string> names;
|
|
135956
|
+
if (!schema_name.empty()) {
|
|
135957
|
+
names.push_back(schema_name);
|
|
135958
|
+
}
|
|
135959
|
+
names.push_back(table_name);
|
|
135960
|
+
names.push_back(column_name);
|
|
135961
|
+
|
|
135962
|
+
auto result = make_unique<ColumnRefExpression>(move(names));
|
|
135963
|
+
// because of case insensitivity in the binder we rename the column to the original name
|
|
135964
|
+
// as it appears in the binding itself
|
|
135965
|
+
auto binding = GetBinding(table_name, error_message);
|
|
135966
|
+
if (binding) {
|
|
135967
|
+
auto column_index = binding->GetBindingIndex(column_name);
|
|
135968
|
+
if (column_index < binding->names.size() && binding->names[column_index] != column_name) {
|
|
135969
|
+
result->alias = binding->names[column_index];
|
|
135970
|
+
}
|
|
135971
|
+
}
|
|
135972
|
+
return move(result);
|
|
135973
|
+
}
|
|
135974
|
+
|
|
135573
135975
|
Binding *BindContext::GetCTEBinding(const string &ctename) {
|
|
135574
135976
|
auto match = cte_bindings.find(ctename);
|
|
135575
135977
|
if (match == cte_bindings.end()) {
|
|
@@ -135595,12 +135997,12 @@ Binding *BindContext::GetBinding(const string &name, string &out_error) {
|
|
|
135595
135997
|
}
|
|
135596
135998
|
|
|
135597
135999
|
BindResult BindContext::BindColumn(ColumnRefExpression &colref, idx_t depth) {
|
|
135598
|
-
if (colref.
|
|
135599
|
-
|
|
136000
|
+
if (!colref.IsQualified()) {
|
|
136001
|
+
throw InternalException("Could not bind alias \"%s\"!", colref.GetColumnName());
|
|
135600
136002
|
}
|
|
135601
136003
|
|
|
135602
136004
|
string error;
|
|
135603
|
-
auto binding = GetBinding(colref.
|
|
136005
|
+
auto binding = GetBinding(colref.GetTableName(), error);
|
|
135604
136006
|
if (!binding) {
|
|
135605
136007
|
return BindResult(error);
|
|
135606
136008
|
}
|
|
@@ -136392,57 +136794,237 @@ BindResult ExpressionBinder::BindExpression(CollateExpression &expr, idx_t depth
|
|
|
136392
136794
|
|
|
136393
136795
|
|
|
136394
136796
|
|
|
136797
|
+
|
|
136798
|
+
|
|
136799
|
+
//===----------------------------------------------------------------------===//
|
|
136800
|
+
// DuckDB
|
|
136801
|
+
//
|
|
136802
|
+
// duckdb/planner/expression_binder/where_binder.hpp
|
|
136803
|
+
//
|
|
136804
|
+
//
|
|
136805
|
+
//===----------------------------------------------------------------------===//
|
|
136806
|
+
|
|
136807
|
+
|
|
136808
|
+
|
|
136809
|
+
|
|
136810
|
+
|
|
136395
136811
|
namespace duckdb {
|
|
136396
136812
|
|
|
136397
|
-
|
|
136398
|
-
|
|
136399
|
-
|
|
136400
|
-
|
|
136401
|
-
|
|
136402
|
-
|
|
136403
|
-
|
|
136404
|
-
|
|
136405
|
-
|
|
136406
|
-
|
|
136407
|
-
|
|
136408
|
-
|
|
136409
|
-
|
|
136410
|
-
|
|
136411
|
-
|
|
136412
|
-
|
|
136413
|
-
|
|
136414
|
-
|
|
136415
|
-
|
|
136416
|
-
|
|
136417
|
-
|
|
136813
|
+
class ColumnAliasBinder;
|
|
136814
|
+
|
|
136815
|
+
//! The WHERE binder is responsible for binding an expression within the WHERE clause of a SQL statement
|
|
136816
|
+
class WhereBinder : public ExpressionBinder {
|
|
136817
|
+
public:
|
|
136818
|
+
WhereBinder(Binder &binder, ClientContext &context, ColumnAliasBinder *column_alias_binder = nullptr);
|
|
136819
|
+
|
|
136820
|
+
protected:
|
|
136821
|
+
BindResult BindExpression(unique_ptr<ParsedExpression> *expr_ptr, idx_t depth,
|
|
136822
|
+
bool root_expression = false) override;
|
|
136823
|
+
|
|
136824
|
+
string UnsupportedAggregateMessage() override;
|
|
136825
|
+
|
|
136826
|
+
private:
|
|
136827
|
+
BindResult BindColumnRef(unique_ptr<ParsedExpression> *expr_ptr, idx_t depth, bool root_expression);
|
|
136828
|
+
|
|
136829
|
+
ColumnAliasBinder *column_alias_binder;
|
|
136830
|
+
};
|
|
136831
|
+
|
|
136832
|
+
} // namespace duckdb
|
|
136833
|
+
|
|
136834
|
+
|
|
136835
|
+
|
|
136836
|
+
|
|
136837
|
+
|
|
136838
|
+
|
|
136839
|
+
namespace duckdb {
|
|
136840
|
+
|
|
136841
|
+
unique_ptr<ParsedExpression> ExpressionBinder::QualifyColumnName(const string &column_name, string &error_message) {
|
|
136842
|
+
auto using_binding = binder.bind_context.GetUsingBinding(column_name);
|
|
136843
|
+
if (using_binding) {
|
|
136844
|
+
// we are referencing a USING column
|
|
136845
|
+
// check if we can refer to one of the base columns directly
|
|
136846
|
+
unique_ptr<Expression> expression;
|
|
136847
|
+
if (!using_binding->primary_binding.empty()) {
|
|
136848
|
+
// we can! just assign the table name and re-bind
|
|
136849
|
+
return make_unique<ColumnRefExpression>(column_name, using_binding->primary_binding);
|
|
136850
|
+
} else {
|
|
136851
|
+
// // we cannot! we need to bind this as a coalesce between all the relevant columns
|
|
136852
|
+
auto coalesce = make_unique<OperatorExpression>(ExpressionType::OPERATOR_COALESCE);
|
|
136853
|
+
for (auto &entry : using_binding->bindings) {
|
|
136854
|
+
coalesce->children.push_back(make_unique<ColumnRefExpression>(column_name, entry));
|
|
136418
136855
|
}
|
|
136856
|
+
return move(coalesce);
|
|
136419
136857
|
}
|
|
136420
|
-
|
|
136421
|
-
|
|
136422
|
-
|
|
136423
|
-
|
|
136858
|
+
}
|
|
136859
|
+
// no table name: find a binding that contains this
|
|
136860
|
+
if (binder.macro_binding != nullptr && binder.macro_binding->HasMatchingBinding(column_name)) {
|
|
136861
|
+
// priority to macro parameter bindings TODO: throw a warning when this name conflicts
|
|
136862
|
+
D_ASSERT(!binder.macro_binding->alias.empty());
|
|
136863
|
+
return make_unique<ColumnRefExpression>(column_name, binder.macro_binding->alias);
|
|
136864
|
+
} else {
|
|
136865
|
+
string table_name = binder.bind_context.GetMatchingBinding(column_name);
|
|
136866
|
+
if (table_name.empty()) {
|
|
136867
|
+
auto similar_bindings = binder.bind_context.GetSimilarBindings(column_name);
|
|
136868
|
+
string candidate_str = StringUtil::CandidatesMessage(similar_bindings, "Candidate bindings");
|
|
136869
|
+
error_message =
|
|
136870
|
+
StringUtil::Format("Referenced column \"%s\" not found in FROM clause!%s", column_name, candidate_str);
|
|
136871
|
+
return nullptr;
|
|
136872
|
+
}
|
|
136873
|
+
return binder.bind_context.CreateColumnReference(table_name, column_name);
|
|
136874
|
+
}
|
|
136875
|
+
}
|
|
136876
|
+
|
|
136877
|
+
void ExpressionBinder::QualifyColumnNames(unique_ptr<ParsedExpression> &expr) {
|
|
136878
|
+
switch (expr->type) {
|
|
136879
|
+
case ExpressionType::COLUMN_REF: {
|
|
136880
|
+
auto &colref = (ColumnRefExpression &)*expr;
|
|
136881
|
+
string error_message;
|
|
136882
|
+
auto new_expr = QualifyColumnName(colref, error_message);
|
|
136883
|
+
if (new_expr) {
|
|
136884
|
+
if (!expr->alias.empty()) {
|
|
136885
|
+
new_expr->alias = expr->alias;
|
|
136886
|
+
}
|
|
136887
|
+
expr = move(new_expr);
|
|
136888
|
+
}
|
|
136889
|
+
break;
|
|
136890
|
+
}
|
|
136891
|
+
case ExpressionType::POSITIONAL_REFERENCE: {
|
|
136892
|
+
auto &ref = (PositionalReferenceExpression &)*expr;
|
|
136893
|
+
if (ref.alias.empty()) {
|
|
136894
|
+
string table_name, column_name;
|
|
136895
|
+
auto error = binder.bind_context.BindColumn(ref, table_name, column_name);
|
|
136896
|
+
if (error.empty()) {
|
|
136897
|
+
ref.alias = column_name;
|
|
136898
|
+
}
|
|
136899
|
+
}
|
|
136900
|
+
break;
|
|
136901
|
+
}
|
|
136902
|
+
default:
|
|
136903
|
+
break;
|
|
136904
|
+
}
|
|
136905
|
+
ParsedExpressionIterator::EnumerateChildren(
|
|
136906
|
+
*expr, [&](unique_ptr<ParsedExpression> &child) { QualifyColumnNames(child); });
|
|
136907
|
+
}
|
|
136908
|
+
|
|
136909
|
+
void ExpressionBinder::QualifyColumnNames(Binder &binder, unique_ptr<ParsedExpression> &expr) {
|
|
136910
|
+
WhereBinder where_binder(binder, binder.context);
|
|
136911
|
+
where_binder.QualifyColumnNames(expr);
|
|
136912
|
+
}
|
|
136913
|
+
|
|
136914
|
+
unique_ptr<ParsedExpression> ExpressionBinder::CreateStructExtract(unique_ptr<ParsedExpression> base,
|
|
136915
|
+
string field_name) {
|
|
136916
|
+
vector<unique_ptr<ParsedExpression>> children;
|
|
136917
|
+
children.push_back(move(base));
|
|
136918
|
+
children.push_back(make_unique_base<ParsedExpression, ConstantExpression>(Value(move(field_name))));
|
|
136919
|
+
auto extract_fun = make_unique<FunctionExpression>("struct_extract", move(children));
|
|
136920
|
+
return move(extract_fun);
|
|
136921
|
+
}
|
|
136922
|
+
|
|
136923
|
+
unique_ptr<ParsedExpression> ExpressionBinder::QualifyColumnName(ColumnRefExpression &colref, string &error_message) {
|
|
136924
|
+
idx_t column_parts = colref.column_names.size();
|
|
136925
|
+
// column names can have an arbitrary amount of dots
|
|
136926
|
+
// here is how the resolution works:
|
|
136927
|
+
if (column_parts == 1) {
|
|
136928
|
+
// no dots (i.e. "part1")
|
|
136929
|
+
// -> part1 refers to a column
|
|
136930
|
+
// check if we can qualify the column name with the table name
|
|
136931
|
+
return QualifyColumnName(colref.GetColumnName(), error_message);
|
|
136932
|
+
} else if (column_parts == 2) {
|
|
136933
|
+
// one dot (i.e. "part1.part2")
|
|
136934
|
+
// EITHER:
|
|
136935
|
+
// -> part1 is a table, part2 is a column
|
|
136936
|
+
// -> part1 is a column, part2 is a property of that column (i.e. struct_extract)
|
|
136937
|
+
|
|
136938
|
+
// first check if part1 is a table
|
|
136939
|
+
if (binder.HasMatchingBinding(colref.column_names[0], colref.column_names[1], error_message)) {
|
|
136940
|
+
// it is! return the colref directly
|
|
136941
|
+
return binder.bind_context.CreateColumnReference(colref.column_names[0], colref.column_names[1]);
|
|
136424
136942
|
} else {
|
|
136425
|
-
|
|
136943
|
+
// otherwise check if we can turn this into a struct extract
|
|
136944
|
+
auto new_colref = make_unique<ColumnRefExpression>(colref.column_names[0]);
|
|
136945
|
+
string other_error;
|
|
136946
|
+
auto qualified_colref = QualifyColumnName(colref.column_names[0], other_error);
|
|
136947
|
+
if (!qualified_colref) {
|
|
136948
|
+
// we could not! bail
|
|
136949
|
+
return nullptr;
|
|
136950
|
+
}
|
|
136951
|
+
// we could: create a struct extract
|
|
136952
|
+
return CreateStructExtract(move(qualified_colref), colref.column_names[1]);
|
|
136426
136953
|
}
|
|
136427
|
-
|
|
136428
|
-
|
|
136429
|
-
|
|
136430
|
-
|
|
136431
|
-
|
|
136432
|
-
|
|
136954
|
+
} else {
|
|
136955
|
+
// two or more dots (i.e. "part1.part2.part3.part4...")
|
|
136956
|
+
// -> part1 is a schema, part2 is a table, part3 is a column name, part4 and beyond are struct fields
|
|
136957
|
+
// -> part1 is a table, part2 is a column name, part3 and beyond are struct fields
|
|
136958
|
+
// -> part1 is a column, part2 and beyond are struct fields
|
|
136959
|
+
|
|
136960
|
+
// we always prefer the most top-level view
|
|
136961
|
+
// i.e. in case of multiple resolution options, we resolve in order:
|
|
136962
|
+
// -> 1. resolve "part1" as a schema
|
|
136963
|
+
// -> 2. resolve "part1" as a table
|
|
136964
|
+
// -> 3. resolve "part1" as a column
|
|
136965
|
+
|
|
136966
|
+
unique_ptr<ParsedExpression> result_expr;
|
|
136967
|
+
idx_t struct_extract_start;
|
|
136968
|
+
// first check if part1 is a schema
|
|
136969
|
+
if (binder.HasMatchingBinding(colref.column_names[0], colref.column_names[1], colref.column_names[2],
|
|
136970
|
+
error_message)) {
|
|
136971
|
+
// it is! the column reference is "schema.table.column"
|
|
136972
|
+
// any additional fields are turned into struct_extract calls
|
|
136973
|
+
result_expr = binder.bind_context.CreateColumnReference(colref.column_names[0], colref.column_names[1],
|
|
136974
|
+
colref.column_names[2]);
|
|
136975
|
+
struct_extract_start = 3;
|
|
136976
|
+
} else if (binder.HasMatchingBinding(colref.column_names[0], colref.column_names[1], error_message)) {
|
|
136977
|
+
// part1 is a table
|
|
136978
|
+
// the column reference is "table.column"
|
|
136979
|
+
// any additional fields are turned into struct_extract calls
|
|
136980
|
+
result_expr = binder.bind_context.CreateColumnReference(colref.column_names[0], colref.column_names[1]);
|
|
136981
|
+
struct_extract_start = 2;
|
|
136982
|
+
} else {
|
|
136983
|
+
// part1 could be a column
|
|
136984
|
+
string col_error;
|
|
136985
|
+
result_expr = QualifyColumnName(colref.column_names[0], col_error);
|
|
136986
|
+
if (!result_expr) {
|
|
136987
|
+
// it is not! return the error
|
|
136988
|
+
return nullptr;
|
|
136989
|
+
}
|
|
136990
|
+
// it is! add the struct extract calls
|
|
136991
|
+
struct_extract_start = 1;
|
|
136992
|
+
}
|
|
136993
|
+
for (idx_t i = struct_extract_start; i < colref.column_names.size(); i++) {
|
|
136994
|
+
result_expr = CreateStructExtract(move(result_expr), colref.column_names[i]);
|
|
136433
136995
|
}
|
|
136996
|
+
return result_expr;
|
|
136997
|
+
}
|
|
136998
|
+
}
|
|
136999
|
+
|
|
137000
|
+
BindResult ExpressionBinder::BindExpression(ColumnRefExpression &colref_p, idx_t depth) {
|
|
137001
|
+
string error_message;
|
|
137002
|
+
auto expr = QualifyColumnName(colref_p, error_message);
|
|
137003
|
+
if (!expr) {
|
|
137004
|
+
return BindResult(binder.FormatError(colref_p, error_message));
|
|
137005
|
+
}
|
|
137006
|
+
if (expr->type != ExpressionType::COLUMN_REF) {
|
|
137007
|
+
return BindExpression(&expr, depth);
|
|
136434
137008
|
}
|
|
137009
|
+
auto &colref = (ColumnRefExpression &)*expr;
|
|
137010
|
+
D_ASSERT(colref.column_names.size() == 2 || colref.column_names.size() == 3);
|
|
137011
|
+
auto &table_name = colref.column_names.size() == 3 ? colref.column_names[1] : colref.column_names[0];
|
|
137012
|
+
// individual column reference
|
|
137013
|
+
// resolve to either a base table or a subquery expression
|
|
136435
137014
|
// if it was a macro parameter, let macro_binding bind it to the argument
|
|
136436
|
-
BindResult result
|
|
136437
|
-
|
|
136438
|
-
|
|
137015
|
+
BindResult result;
|
|
137016
|
+
if (binder.macro_binding && table_name == binder.macro_binding->alias) {
|
|
137017
|
+
result = binder.macro_binding->Bind(colref, depth);
|
|
137018
|
+
} else {
|
|
137019
|
+
result = binder.bind_context.BindColumn(colref, depth);
|
|
137020
|
+
}
|
|
136439
137021
|
if (!result.HasError()) {
|
|
136440
137022
|
BoundColumnReferenceInfo ref;
|
|
136441
|
-
ref.name = colref.
|
|
137023
|
+
ref.name = colref.column_names.back();
|
|
136442
137024
|
ref.query_location = colref.query_location;
|
|
136443
137025
|
bound_columns.push_back(move(ref));
|
|
136444
137026
|
} else {
|
|
136445
|
-
result.error = binder.FormatError(
|
|
137027
|
+
result.error = binder.FormatError(colref_p, result.error);
|
|
136446
137028
|
}
|
|
136447
137029
|
return result;
|
|
136448
137030
|
}
|
|
@@ -136740,11 +137322,6 @@ BindResult ExpressionBinder::BindExpression(LambdaExpression &expr, idx_t depth)
|
|
|
136740
137322
|
|
|
136741
137323
|
|
|
136742
137324
|
|
|
136743
|
-
|
|
136744
|
-
|
|
136745
|
-
|
|
136746
|
-
|
|
136747
|
-
|
|
136748
137325
|
namespace duckdb {
|
|
136749
137326
|
|
|
136750
137327
|
void ExpressionBinder::ReplaceMacroParametersRecursive(unique_ptr<ParsedExpression> &expr) {
|
|
@@ -136752,7 +137329,14 @@ void ExpressionBinder::ReplaceMacroParametersRecursive(unique_ptr<ParsedExpressi
|
|
|
136752
137329
|
case ExpressionClass::COLUMN_REF: {
|
|
136753
137330
|
// if expr is a parameter, replace it with its argument
|
|
136754
137331
|
auto &colref = (ColumnRefExpression &)*expr;
|
|
136755
|
-
|
|
137332
|
+
bool bind_macro_parameter = false;
|
|
137333
|
+
if (colref.IsQualified()) {
|
|
137334
|
+
bind_macro_parameter = colref.GetTableName() == MacroBinding::MACRO_NAME;
|
|
137335
|
+
} else {
|
|
137336
|
+
bind_macro_parameter = macro_binding->HasMatchingBinding(colref.GetColumnName());
|
|
137337
|
+
}
|
|
137338
|
+
if (bind_macro_parameter) {
|
|
137339
|
+
D_ASSERT(macro_binding->HasMatchingBinding(colref.GetColumnName()));
|
|
136756
137340
|
expr = macro_binding->ParamToArg(colref);
|
|
136757
137341
|
}
|
|
136758
137342
|
return;
|
|
@@ -136760,7 +137344,8 @@ void ExpressionBinder::ReplaceMacroParametersRecursive(unique_ptr<ParsedExpressi
|
|
|
136760
137344
|
case ExpressionClass::SUBQUERY: {
|
|
136761
137345
|
// replacing parameters within a subquery is slightly different
|
|
136762
137346
|
auto &sq = ((SubqueryExpression &)*expr).subquery;
|
|
136763
|
-
|
|
137347
|
+
ParsedExpressionIterator::EnumerateQueryNodeChildren(
|
|
137348
|
+
*sq->node, [&](unique_ptr<ParsedExpression> &child) { ReplaceMacroParametersRecursive(child); });
|
|
136764
137349
|
break;
|
|
136765
137350
|
}
|
|
136766
137351
|
default: // fall through
|
|
@@ -136771,89 +137356,6 @@ void ExpressionBinder::ReplaceMacroParametersRecursive(unique_ptr<ParsedExpressi
|
|
|
136771
137356
|
*expr, [&](unique_ptr<ParsedExpression> &child) { ReplaceMacroParametersRecursive(child); });
|
|
136772
137357
|
}
|
|
136773
137358
|
|
|
136774
|
-
void ExpressionBinder::ReplaceMacroParametersRecursive(ParsedExpression &expr, TableRef &ref) {
|
|
136775
|
-
switch (ref.type) {
|
|
136776
|
-
case TableReferenceType::CROSS_PRODUCT: {
|
|
136777
|
-
auto &cp_ref = (CrossProductRef &)ref;
|
|
136778
|
-
ReplaceMacroParametersRecursive(expr, *cp_ref.left);
|
|
136779
|
-
ReplaceMacroParametersRecursive(expr, *cp_ref.right);
|
|
136780
|
-
break;
|
|
136781
|
-
}
|
|
136782
|
-
case TableReferenceType::EXPRESSION_LIST: {
|
|
136783
|
-
auto &el_ref = (ExpressionListRef &)ref;
|
|
136784
|
-
for (idx_t i = 0; i < el_ref.values.size(); i++) {
|
|
136785
|
-
for (idx_t j = 0; j < el_ref.values[i].size(); j++) {
|
|
136786
|
-
ReplaceMacroParametersRecursive(el_ref.values[i][j]);
|
|
136787
|
-
}
|
|
136788
|
-
}
|
|
136789
|
-
break;
|
|
136790
|
-
}
|
|
136791
|
-
case TableReferenceType::JOIN: {
|
|
136792
|
-
auto &j_ref = (JoinRef &)ref;
|
|
136793
|
-
ReplaceMacroParametersRecursive(expr, *j_ref.left);
|
|
136794
|
-
ReplaceMacroParametersRecursive(expr, *j_ref.right);
|
|
136795
|
-
ReplaceMacroParametersRecursive(j_ref.condition);
|
|
136796
|
-
break;
|
|
136797
|
-
}
|
|
136798
|
-
case TableReferenceType::SUBQUERY: {
|
|
136799
|
-
auto &sq_ref = (SubqueryRef &)ref;
|
|
136800
|
-
ReplaceMacroParametersRecursive(expr, *sq_ref.subquery->node);
|
|
136801
|
-
break;
|
|
136802
|
-
}
|
|
136803
|
-
case TableReferenceType::TABLE_FUNCTION: {
|
|
136804
|
-
auto &tf_ref = (TableFunctionRef &)ref;
|
|
136805
|
-
ReplaceMacroParametersRecursive(tf_ref.function);
|
|
136806
|
-
break;
|
|
136807
|
-
}
|
|
136808
|
-
case TableReferenceType::BASE_TABLE:
|
|
136809
|
-
case TableReferenceType::EMPTY:
|
|
136810
|
-
// these TableRefs do not need to be unfolded
|
|
136811
|
-
break;
|
|
136812
|
-
default:
|
|
136813
|
-
throw NotImplementedException("TableRef type not implemented for macro's!");
|
|
136814
|
-
}
|
|
136815
|
-
}
|
|
136816
|
-
|
|
136817
|
-
void ExpressionBinder::ReplaceMacroParametersRecursive(ParsedExpression &expr, QueryNode &node) {
|
|
136818
|
-
switch (node.type) {
|
|
136819
|
-
case QueryNodeType::RECURSIVE_CTE_NODE: {
|
|
136820
|
-
auto &rcte_node = (RecursiveCTENode &)node;
|
|
136821
|
-
ReplaceMacroParametersRecursive(expr, *rcte_node.left);
|
|
136822
|
-
ReplaceMacroParametersRecursive(expr, *rcte_node.right);
|
|
136823
|
-
break;
|
|
136824
|
-
}
|
|
136825
|
-
case QueryNodeType::SELECT_NODE: {
|
|
136826
|
-
auto &sel_node = (SelectNode &)node;
|
|
136827
|
-
for (idx_t i = 0; i < sel_node.select_list.size(); i++) {
|
|
136828
|
-
ReplaceMacroParametersRecursive(sel_node.select_list[i]);
|
|
136829
|
-
}
|
|
136830
|
-
for (idx_t i = 0; i < sel_node.groups.group_expressions.size(); i++) {
|
|
136831
|
-
ReplaceMacroParametersRecursive(sel_node.groups.group_expressions[i]);
|
|
136832
|
-
}
|
|
136833
|
-
if (sel_node.where_clause != nullptr) {
|
|
136834
|
-
ReplaceMacroParametersRecursive(sel_node.where_clause);
|
|
136835
|
-
}
|
|
136836
|
-
if (sel_node.having != nullptr) {
|
|
136837
|
-
ReplaceMacroParametersRecursive(sel_node.having);
|
|
136838
|
-
}
|
|
136839
|
-
|
|
136840
|
-
ReplaceMacroParametersRecursive(expr, *sel_node.from_table.get());
|
|
136841
|
-
break;
|
|
136842
|
-
}
|
|
136843
|
-
case QueryNodeType::SET_OPERATION_NODE: {
|
|
136844
|
-
auto &setop_node = (SetOperationNode &)node;
|
|
136845
|
-
ReplaceMacroParametersRecursive(expr, *setop_node.left);
|
|
136846
|
-
ReplaceMacroParametersRecursive(expr, *setop_node.right);
|
|
136847
|
-
break;
|
|
136848
|
-
}
|
|
136849
|
-
default:
|
|
136850
|
-
throw NotImplementedException("QueryNode type not implemented for macro's!");
|
|
136851
|
-
}
|
|
136852
|
-
for (auto &kv : node.cte_map) {
|
|
136853
|
-
ReplaceMacroParametersRecursive(expr, *kv.second->query->node);
|
|
136854
|
-
}
|
|
136855
|
-
}
|
|
136856
|
-
|
|
136857
137359
|
BindResult ExpressionBinder::BindMacro(FunctionExpression &function, MacroCatalogEntry *macro_func, idx_t depth,
|
|
136858
137360
|
unique_ptr<ParsedExpression> *expr) {
|
|
136859
137361
|
auto ¯o_def = *macro_func->function;
|
|
@@ -136872,7 +137374,7 @@ BindResult ExpressionBinder::BindMacro(FunctionExpression &function, MacroCatalo
|
|
|
136872
137374
|
for (idx_t i = 0; i < macro_def.parameters.size(); i++) {
|
|
136873
137375
|
types.push_back(LogicalType::SQLNULL);
|
|
136874
137376
|
auto ¶m = (ColumnRefExpression &)*macro_def.parameters[i];
|
|
136875
|
-
names.push_back(param.
|
|
137377
|
+
names.push_back(param.GetColumnName());
|
|
136876
137378
|
}
|
|
136877
137379
|
// default parameters
|
|
136878
137380
|
for (auto it = macro_def.default_parameters.begin(); it != macro_def.default_parameters.end(); it++) {
|
|
@@ -137796,40 +138298,6 @@ private:
|
|
|
137796
138298
|
} // namespace duckdb
|
|
137797
138299
|
|
|
137798
138300
|
|
|
137799
|
-
//===----------------------------------------------------------------------===//
|
|
137800
|
-
// DuckDB
|
|
137801
|
-
//
|
|
137802
|
-
// duckdb/planner/expression_binder/where_binder.hpp
|
|
137803
|
-
//
|
|
137804
|
-
//
|
|
137805
|
-
//===----------------------------------------------------------------------===//
|
|
137806
|
-
|
|
137807
|
-
|
|
137808
|
-
|
|
137809
|
-
|
|
137810
|
-
|
|
137811
|
-
namespace duckdb {
|
|
137812
|
-
|
|
137813
|
-
class ColumnAliasBinder;
|
|
137814
|
-
|
|
137815
|
-
//! The WHERE binder is responsible for binding an expression within the WHERE clause of a SQL statement
|
|
137816
|
-
class WhereBinder : public ExpressionBinder {
|
|
137817
|
-
public:
|
|
137818
|
-
WhereBinder(Binder &binder, ClientContext &context, ColumnAliasBinder *column_alias_binder = nullptr);
|
|
137819
|
-
|
|
137820
|
-
protected:
|
|
137821
|
-
BindResult BindExpression(unique_ptr<ParsedExpression> *expr_ptr, idx_t depth,
|
|
137822
|
-
bool root_expression = false) override;
|
|
137823
|
-
|
|
137824
|
-
string UnsupportedAggregateMessage() override;
|
|
137825
|
-
|
|
137826
|
-
private:
|
|
137827
|
-
BindResult BindColumnRef(unique_ptr<ParsedExpression> *expr_ptr, idx_t depth, bool root_expression);
|
|
137828
|
-
|
|
137829
|
-
ColumnAliasBinder *column_alias_binder;
|
|
137830
|
-
};
|
|
137831
|
-
|
|
137832
|
-
} // namespace duckdb
|
|
137833
138301
|
|
|
137834
138302
|
|
|
137835
138303
|
|
|
@@ -138020,7 +138488,7 @@ unique_ptr<BoundQueryNode> Binder::BindNode(SelectNode &statement) {
|
|
|
138020
138488
|
for (idx_t i = 0; i < statement.select_list.size(); i++) {
|
|
138021
138489
|
auto &expr = statement.select_list[i];
|
|
138022
138490
|
result->names.push_back(expr->GetName());
|
|
138023
|
-
ExpressionBinder::
|
|
138491
|
+
ExpressionBinder::QualifyColumnNames(*this, expr);
|
|
138024
138492
|
if (!expr->alias.empty()) {
|
|
138025
138493
|
alias_map[expr->alias] = i;
|
|
138026
138494
|
result->names[i] = expr->alias;
|
|
@@ -138074,7 +138542,7 @@ unique_ptr<BoundQueryNode> Binder::BindNode(SelectNode &statement) {
|
|
|
138074
138542
|
// if we wouldn't do this then (SELECT test.a FROM test GROUP BY a) would not work because "test.a" <> "a"
|
|
138075
138543
|
// hence we convert "a" -> "test.a" in the unbound expression
|
|
138076
138544
|
unbound_groups[i] = move(group_binder.unbound_expression);
|
|
138077
|
-
ExpressionBinder::
|
|
138545
|
+
ExpressionBinder::QualifyColumnNames(*this, unbound_groups[i]);
|
|
138078
138546
|
info.map[unbound_groups[i].get()] = i;
|
|
138079
138547
|
}
|
|
138080
138548
|
}
|
|
@@ -138083,7 +138551,7 @@ unique_ptr<BoundQueryNode> Binder::BindNode(SelectNode &statement) {
|
|
|
138083
138551
|
// bind the HAVING clause, if any
|
|
138084
138552
|
if (statement.having) {
|
|
138085
138553
|
HavingBinder having_binder(*this, context, *result, info, alias_map);
|
|
138086
|
-
ExpressionBinder::
|
|
138554
|
+
ExpressionBinder::QualifyColumnNames(*this, statement.having);
|
|
138087
138555
|
result->having = having_binder.Bind(statement.having);
|
|
138088
138556
|
}
|
|
138089
138557
|
|
|
@@ -139372,11 +139840,11 @@ SchemaCatalogEntry *Binder::BindCreateFunctionInfo(CreateInfo &info) {
|
|
|
139372
139840
|
// positional parameters
|
|
139373
139841
|
for (idx_t i = 0; i < base.function->parameters.size(); i++) {
|
|
139374
139842
|
auto param = (ColumnRefExpression &)*base.function->parameters[i];
|
|
139375
|
-
if (
|
|
139376
|
-
throw BinderException("Invalid parameter name '%s'", param.ToString());
|
|
139843
|
+
if (param.IsQualified()) {
|
|
139844
|
+
throw BinderException("Invalid parameter name '%s': must be unqualified", param.ToString());
|
|
139377
139845
|
}
|
|
139378
139846
|
dummy_types.push_back(LogicalType::SQLNULL);
|
|
139379
|
-
dummy_names.push_back(param.
|
|
139847
|
+
dummy_names.push_back(param.GetColumnName());
|
|
139380
139848
|
}
|
|
139381
139849
|
// default parameters
|
|
139382
139850
|
for (auto it = base.function->default_parameters.begin(); it != base.function->default_parameters.end(); it++) {
|
|
@@ -139386,6 +139854,7 @@ SchemaCatalogEntry *Binder::BindCreateFunctionInfo(CreateInfo &info) {
|
|
|
139386
139854
|
}
|
|
139387
139855
|
auto this_macro_binding = make_unique<MacroBinding>(dummy_types, dummy_names, base.name);
|
|
139388
139856
|
macro_binding = this_macro_binding.get();
|
|
139857
|
+
ExpressionBinder::QualifyColumnNames(*this, base.function->expression);
|
|
139389
139858
|
|
|
139390
139859
|
// create a copy of the expression because we do not want to alter the original
|
|
139391
139860
|
auto expression = base.function->expression->Copy();
|
|
@@ -139895,7 +140364,7 @@ BoundStatement Binder::Bind(ExplainStatement &stmt) {
|
|
|
139895
140364
|
auto plan = Bind(*stmt.stmt);
|
|
139896
140365
|
// get the unoptimized logical plan, and create the explain statement
|
|
139897
140366
|
auto logical_plan_unopt = plan.plan->ToString();
|
|
139898
|
-
auto explain = make_unique<LogicalExplain>(move(plan.plan));
|
|
140367
|
+
auto explain = make_unique<LogicalExplain>(move(plan.plan), stmt.explain_type);
|
|
139899
140368
|
explain->logical_plan_unopt = logical_plan_unopt;
|
|
139900
140369
|
|
|
139901
140370
|
result.plan = move(explain);
|
|
@@ -141502,8 +141971,8 @@ bool Binder::BindFunctionParameters(vector<unique_ptr<ParsedExpression>> &expres
|
|
|
141502
141971
|
auto &comp = (ComparisonExpression &)*child;
|
|
141503
141972
|
if (comp.left->type == ExpressionType::COLUMN_REF) {
|
|
141504
141973
|
auto &colref = (ColumnRefExpression &)*comp.left;
|
|
141505
|
-
if (colref.
|
|
141506
|
-
parameter_name = colref.
|
|
141974
|
+
if (!colref.IsQualified()) {
|
|
141975
|
+
parameter_name = colref.GetColumnName();
|
|
141507
141976
|
child = move(comp.right);
|
|
141508
141977
|
}
|
|
141509
141978
|
}
|
|
@@ -141974,6 +142443,8 @@ unique_ptr<LogicalOperator> Binder::CreatePlan(BoundTableFunction &ref) {
|
|
|
141974
142443
|
|
|
141975
142444
|
|
|
141976
142445
|
|
|
142446
|
+
|
|
142447
|
+
|
|
141977
142448
|
#include <algorithm>
|
|
141978
142449
|
|
|
141979
142450
|
namespace duckdb {
|
|
@@ -142253,6 +142724,38 @@ void Binder::AddCorrelatedColumn(const CorrelatedColumnInfo &info) {
|
|
|
142253
142724
|
}
|
|
142254
142725
|
}
|
|
142255
142726
|
|
|
142727
|
+
bool Binder::HasMatchingBinding(const string &table_name, const string &column_name, string &error_message) {
|
|
142728
|
+
string empty_schema;
|
|
142729
|
+
return HasMatchingBinding(empty_schema, table_name, column_name, error_message);
|
|
142730
|
+
}
|
|
142731
|
+
|
|
142732
|
+
bool Binder::HasMatchingBinding(const string &schema_name, const string &table_name, const string &column_name,
|
|
142733
|
+
string &error_message) {
|
|
142734
|
+
Binding *binding;
|
|
142735
|
+
if (macro_binding && table_name == macro_binding->alias) {
|
|
142736
|
+
binding = macro_binding;
|
|
142737
|
+
} else {
|
|
142738
|
+
binding = bind_context.GetBinding(table_name, error_message);
|
|
142739
|
+
}
|
|
142740
|
+
if (!binding) {
|
|
142741
|
+
return false;
|
|
142742
|
+
}
|
|
142743
|
+
if (!schema_name.empty()) {
|
|
142744
|
+
auto table_entry = binding->GetTableEntry();
|
|
142745
|
+
if (!table_entry) {
|
|
142746
|
+
return false;
|
|
142747
|
+
}
|
|
142748
|
+
if (table_entry->schema->name != schema_name || table_entry->name != table_name) {
|
|
142749
|
+
return false;
|
|
142750
|
+
}
|
|
142751
|
+
}
|
|
142752
|
+
if (!binding->HasMatchingBinding(column_name)) {
|
|
142753
|
+
error_message = binding->ColumnNotFoundError(column_name);
|
|
142754
|
+
return false;
|
|
142755
|
+
}
|
|
142756
|
+
return true;
|
|
142757
|
+
}
|
|
142758
|
+
|
|
142256
142759
|
string Binder::FormatError(ParsedExpression &expr_context, const string &message) {
|
|
142257
142760
|
return FormatError(expr_context.query_location, message);
|
|
142258
142761
|
}
|
|
@@ -143344,13 +143847,13 @@ string AlterBinder::UnsupportedAggregateMessage() {
|
|
|
143344
143847
|
}
|
|
143345
143848
|
|
|
143346
143849
|
BindResult AlterBinder::BindColumn(ColumnRefExpression &colref) {
|
|
143347
|
-
if (
|
|
143348
|
-
|
|
143349
|
-
table.name);
|
|
143850
|
+
if (colref.column_names.size() > 1) {
|
|
143851
|
+
return BindQualifiedColumnName(colref, table.name);
|
|
143350
143852
|
}
|
|
143351
|
-
auto idx = table.GetColumnIndex(colref.
|
|
143853
|
+
auto idx = table.GetColumnIndex(colref.column_names[0], true);
|
|
143352
143854
|
if (idx == INVALID_INDEX) {
|
|
143353
|
-
throw BinderException("Table does not contain column %s referenced in alter statement!",
|
|
143855
|
+
throw BinderException("Table does not contain column %s referenced in alter statement!",
|
|
143856
|
+
colref.column_names[0]);
|
|
143354
143857
|
}
|
|
143355
143858
|
bound_columns.push_back(idx);
|
|
143356
143859
|
return BindResult(make_unique<BoundReferenceExpression>(table.columns[idx].type, bound_columns.size() - 1));
|
|
@@ -143364,9 +143867,9 @@ BindResult AlterBinder::BindColumn(ColumnRefExpression &colref) {
|
|
|
143364
143867
|
|
|
143365
143868
|
namespace duckdb {
|
|
143366
143869
|
|
|
143367
|
-
CheckBinder::CheckBinder(Binder &binder, ClientContext &context, string
|
|
143870
|
+
CheckBinder::CheckBinder(Binder &binder, ClientContext &context, string table_p, vector<ColumnDefinition> &columns,
|
|
143368
143871
|
unordered_set<column_t> &bound_columns)
|
|
143369
|
-
: ExpressionBinder(binder, context), table(move(
|
|
143872
|
+
: ExpressionBinder(binder, context), table(move(table_p)), columns(columns), bound_columns(bound_columns) {
|
|
143370
143873
|
target_type = LogicalType::INTEGER;
|
|
143371
143874
|
}
|
|
143372
143875
|
|
|
@@ -143388,18 +143891,29 @@ string CheckBinder::UnsupportedAggregateMessage() {
|
|
|
143388
143891
|
return "aggregate functions are not allowed in check constraints";
|
|
143389
143892
|
}
|
|
143390
143893
|
|
|
143894
|
+
BindResult ExpressionBinder::BindQualifiedColumnName(ColumnRefExpression &colref, const string &table_name) {
|
|
143895
|
+
idx_t struct_start = 0;
|
|
143896
|
+
if (colref.column_names[0] == table_name) {
|
|
143897
|
+
struct_start++;
|
|
143898
|
+
}
|
|
143899
|
+
auto result = make_unique_base<ParsedExpression, ColumnRefExpression>(colref.column_names.back());
|
|
143900
|
+
for (idx_t i = struct_start; i + 1 < colref.column_names.size(); i++) {
|
|
143901
|
+
result = CreateStructExtract(move(result), colref.column_names[i]);
|
|
143902
|
+
}
|
|
143903
|
+
return BindExpression(&result, 0);
|
|
143904
|
+
}
|
|
143905
|
+
|
|
143391
143906
|
BindResult CheckBinder::BindCheckColumn(ColumnRefExpression &colref) {
|
|
143392
|
-
if (
|
|
143393
|
-
|
|
143394
|
-
table);
|
|
143907
|
+
if (colref.column_names.size() > 1) {
|
|
143908
|
+
return BindQualifiedColumnName(colref, table);
|
|
143395
143909
|
}
|
|
143396
143910
|
for (idx_t i = 0; i < columns.size(); i++) {
|
|
143397
|
-
if (colref.
|
|
143911
|
+
if (colref.column_names[0] == columns[i].name) {
|
|
143398
143912
|
bound_columns.insert(i);
|
|
143399
143913
|
return BindResult(make_unique<BoundReferenceExpression>(columns[i].type, i));
|
|
143400
143914
|
}
|
|
143401
143915
|
}
|
|
143402
|
-
throw BinderException("Table does not contain column %s referenced in check constraint!", colref.
|
|
143916
|
+
throw BinderException("Table does not contain column %s referenced in check constraint!", colref.column_names[0]);
|
|
143403
143917
|
}
|
|
143404
143918
|
|
|
143405
143919
|
} // namespace duckdb
|
|
@@ -143417,11 +143931,11 @@ ColumnAliasBinder::ColumnAliasBinder(BoundSelectNode &node, const unordered_map<
|
|
|
143417
143931
|
|
|
143418
143932
|
BindResult ColumnAliasBinder::BindAlias(ExpressionBinder &enclosing_binder, ColumnRefExpression &expr, idx_t depth,
|
|
143419
143933
|
bool root_expression) {
|
|
143420
|
-
if (
|
|
143934
|
+
if (expr.IsQualified()) {
|
|
143421
143935
|
return BindResult(StringUtil::Format("Alias %s cannot be qualified.", expr.ToString()));
|
|
143422
143936
|
}
|
|
143423
143937
|
|
|
143424
|
-
auto alias_entry = alias_map.find(expr.
|
|
143938
|
+
auto alias_entry = alias_map.find(expr.column_names[0]);
|
|
143425
143939
|
if (alias_entry == alias_map.end()) {
|
|
143426
143940
|
return BindResult(StringUtil::Format("Alias %s is not found.", expr.ToString()));
|
|
143427
143941
|
}
|
|
@@ -143551,13 +144065,13 @@ BindResult GroupBinder::BindColumnRef(ColumnRefExpression &colref) {
|
|
|
143551
144065
|
// first try to bind to the base columns (original tables)
|
|
143552
144066
|
auto result = ExpressionBinder::BindExpression(colref, 0);
|
|
143553
144067
|
if (result.HasError()) {
|
|
143554
|
-
|
|
143555
|
-
// check if refers to an alias in the select clause
|
|
143556
|
-
auto alias_name = colref.column_name;
|
|
143557
|
-
if (!colref.table_name.empty()) {
|
|
144068
|
+
if (colref.IsQualified()) {
|
|
143558
144069
|
// explicit table name: not an alias reference
|
|
143559
144070
|
return result;
|
|
143560
144071
|
}
|
|
144072
|
+
// failed to bind the column and the node is the root expression with depth = 0
|
|
144073
|
+
// check if refers to an alias in the select clause
|
|
144074
|
+
auto alias_name = colref.column_names[0];
|
|
143561
144075
|
auto entry = alias_map.find(alias_name);
|
|
143562
144076
|
if (entry == alias_map.end()) {
|
|
143563
144077
|
// no matching alias found
|
|
@@ -143724,11 +144238,11 @@ unique_ptr<Expression> OrderBinder::Bind(unique_ptr<ParsedExpression> expr) {
|
|
|
143724
144238
|
// check if we can bind it to an alias in the select list
|
|
143725
144239
|
auto &colref = (ColumnRefExpression &)*expr;
|
|
143726
144240
|
// if there is an explicit table name we can't bind to an alias
|
|
143727
|
-
if (
|
|
144241
|
+
if (colref.IsQualified()) {
|
|
143728
144242
|
break;
|
|
143729
144243
|
}
|
|
143730
144244
|
// check the alias list
|
|
143731
|
-
auto entry = alias_map.find(colref.
|
|
144245
|
+
auto entry = alias_map.find(colref.column_names[0]);
|
|
143732
144246
|
if (entry != alias_map.end()) {
|
|
143733
144247
|
// it does! point it to that entry
|
|
143734
144248
|
return CreateProjectionReference(*expr, entry->second);
|
|
@@ -143745,7 +144259,7 @@ unique_ptr<Expression> OrderBinder::Bind(unique_ptr<ParsedExpression> expr) {
|
|
|
143745
144259
|
// general case
|
|
143746
144260
|
// first bind the table names of this entry
|
|
143747
144261
|
for (auto &binder : binders) {
|
|
143748
|
-
ExpressionBinder::
|
|
144262
|
+
ExpressionBinder::QualifyColumnNames(*binder, expr);
|
|
143749
144263
|
}
|
|
143750
144264
|
// first check if the ORDER BY clause already points to an entry in the projection list
|
|
143751
144265
|
auto entry = projection_map.find(expr.get());
|
|
@@ -143868,8 +144382,8 @@ idx_t SelectBinder::TryBindGroup(ParsedExpression &expr, idx_t depth) {
|
|
|
143868
144382
|
// first check the group alias map, if expr is a ColumnRefExpression
|
|
143869
144383
|
if (expr.type == ExpressionType::COLUMN_REF) {
|
|
143870
144384
|
auto &colref = (ColumnRefExpression &)expr;
|
|
143871
|
-
if (colref.
|
|
143872
|
-
auto alias_entry = info.alias_map.find(colref.
|
|
144385
|
+
if (!colref.IsQualified()) {
|
|
144386
|
+
auto alias_entry = info.alias_map.find(colref.column_names[0]);
|
|
143873
144387
|
if (alias_entry != info.alias_map.end()) {
|
|
143874
144388
|
// found entry!
|
|
143875
144389
|
return alias_entry->second;
|
|
@@ -143904,7 +144418,7 @@ BindResult SelectBinder::BindGroupingFunction(OperatorExpression &op, idx_t dept
|
|
|
143904
144418
|
vector<idx_t> group_indexes;
|
|
143905
144419
|
group_indexes.reserve(op.children.size());
|
|
143906
144420
|
for (auto &child : op.children) {
|
|
143907
|
-
ExpressionBinder::
|
|
144421
|
+
ExpressionBinder::QualifyColumnNames(binder, child);
|
|
143908
144422
|
auto idx = TryBindGroup(*child, depth);
|
|
143909
144423
|
if (idx == INVALID_INDEX) {
|
|
143910
144424
|
return BindResult(binder.FormatError(
|
|
@@ -144074,7 +144588,7 @@ bool ExpressionBinder::BindCorrelatedColumns(unique_ptr<ParsedExpression> &expr)
|
|
|
144074
144588
|
bool success = false;
|
|
144075
144589
|
while (!active_binders.empty()) {
|
|
144076
144590
|
auto &next_binder = active_binders.back();
|
|
144077
|
-
ExpressionBinder::
|
|
144591
|
+
ExpressionBinder::QualifyColumnNames(next_binder->binder, expr);
|
|
144078
144592
|
auto bind_result = next_binder->Bind(&expr, depth);
|
|
144079
144593
|
if (bind_result.empty()) {
|
|
144080
144594
|
success = true;
|
|
@@ -144235,33 +144749,6 @@ string ExpressionBinder::Bind(unique_ptr<ParsedExpression> *expr, idx_t depth, b
|
|
|
144235
144749
|
}
|
|
144236
144750
|
}
|
|
144237
144751
|
|
|
144238
|
-
void ExpressionBinder::BindTableNames(Binder &binder, ParsedExpression &expr, unordered_map<string, idx_t> *alias_map) {
|
|
144239
|
-
if (expr.type == ExpressionType::COLUMN_REF) {
|
|
144240
|
-
auto &colref = (ColumnRefExpression &)expr;
|
|
144241
|
-
if (colref.table_name.empty()) {
|
|
144242
|
-
// no table name: find a binding that contains this
|
|
144243
|
-
if (binder.macro_binding != nullptr && binder.macro_binding->HasMatchingBinding(colref.column_name)) {
|
|
144244
|
-
// macro parameters get priority
|
|
144245
|
-
colref.table_name = binder.macro_binding->alias;
|
|
144246
|
-
} else {
|
|
144247
|
-
colref.table_name = binder.bind_context.GetMatchingBinding(colref.column_name);
|
|
144248
|
-
}
|
|
144249
|
-
}
|
|
144250
|
-
binder.bind_context.BindColumn(colref, 0);
|
|
144251
|
-
} else if (expr.type == ExpressionType::POSITIONAL_REFERENCE) {
|
|
144252
|
-
auto &ref = (PositionalReferenceExpression &)expr;
|
|
144253
|
-
if (ref.alias.empty()) {
|
|
144254
|
-
string table_name, column_name;
|
|
144255
|
-
auto error = binder.bind_context.BindColumn(ref, table_name, column_name);
|
|
144256
|
-
if (error.empty()) {
|
|
144257
|
-
ref.alias = column_name;
|
|
144258
|
-
}
|
|
144259
|
-
}
|
|
144260
|
-
}
|
|
144261
|
-
ParsedExpressionIterator::EnumerateChildren(
|
|
144262
|
-
expr, [&](const ParsedExpression &child) { BindTableNames(binder, (ParsedExpression &)child, alias_map); });
|
|
144263
|
-
}
|
|
144264
|
-
|
|
144265
144752
|
} // namespace duckdb
|
|
144266
144753
|
|
|
144267
144754
|
|
|
@@ -145324,6 +145811,7 @@ bool LogicalFilter::SplitPredicates(vector<unique_ptr<Expression>> &expressions)
|
|
|
145324
145811
|
|
|
145325
145812
|
|
|
145326
145813
|
|
|
145814
|
+
|
|
145327
145815
|
namespace duckdb {
|
|
145328
145816
|
|
|
145329
145817
|
LogicalGet::LogicalGet(idx_t table_index, TableFunction function, unique_ptr<FunctionData> bind_data,
|
|
@@ -145336,6 +145824,10 @@ string LogicalGet::GetName() const {
|
|
|
145336
145824
|
return StringUtil::Upper(function.name);
|
|
145337
145825
|
}
|
|
145338
145826
|
|
|
145827
|
+
TableCatalogEntry *LogicalGet::GetTable() const {
|
|
145828
|
+
return TableScanFunction::GetTableEntry(function, bind_data.get());
|
|
145829
|
+
}
|
|
145830
|
+
|
|
145339
145831
|
string LogicalGet::ParamsToString() const {
|
|
145340
145832
|
string result;
|
|
145341
145833
|
for (auto &kv : table_filters.filters) {
|
|
@@ -146375,16 +146867,27 @@ bool Binding::TryGetBindingIndex(const string &column_name, column_t &result) {
|
|
|
146375
146867
|
return false;
|
|
146376
146868
|
}
|
|
146377
146869
|
|
|
146870
|
+
column_t Binding::GetBindingIndex(const string &column_name) {
|
|
146871
|
+
column_t result;
|
|
146872
|
+
if (!TryGetBindingIndex(column_name, result)) {
|
|
146873
|
+
throw InternalException("Binding index for column \"%s\" not found", column_name);
|
|
146874
|
+
}
|
|
146875
|
+
return result;
|
|
146876
|
+
}
|
|
146877
|
+
|
|
146378
146878
|
bool Binding::HasMatchingBinding(const string &column_name) {
|
|
146379
146879
|
column_t result;
|
|
146380
146880
|
return TryGetBindingIndex(column_name, result);
|
|
146381
146881
|
}
|
|
146382
146882
|
|
|
146883
|
+
string Binding::ColumnNotFoundError(const string &column_name) const {
|
|
146884
|
+
return StringUtil::Format("Values list \"%s\" does not have a column named \"%s\"", alias, column_name);
|
|
146885
|
+
}
|
|
146886
|
+
|
|
146383
146887
|
BindResult Binding::Bind(ColumnRefExpression &colref, idx_t depth) {
|
|
146384
146888
|
column_t column_index;
|
|
146385
|
-
if (!TryGetBindingIndex(colref.
|
|
146386
|
-
return BindResult(
|
|
146387
|
-
colref.column_name.c_str()));
|
|
146889
|
+
if (!TryGetBindingIndex(colref.GetColumnName(), column_index)) {
|
|
146890
|
+
return BindResult(ColumnNotFoundError(colref.GetColumnName()));
|
|
146388
146891
|
}
|
|
146389
146892
|
ColumnBinding binding;
|
|
146390
146893
|
binding.table_index = index;
|
|
@@ -146396,6 +146899,10 @@ BindResult Binding::Bind(ColumnRefExpression &colref, idx_t depth) {
|
|
|
146396
146899
|
return BindResult(make_unique<BoundColumnRefExpression>(colref.GetName(), sql_type, binding, depth));
|
|
146397
146900
|
}
|
|
146398
146901
|
|
|
146902
|
+
TableCatalogEntry *Binding::GetTableEntry() {
|
|
146903
|
+
return nullptr;
|
|
146904
|
+
}
|
|
146905
|
+
|
|
146399
146906
|
TableBinding::TableBinding(const string &alias, vector<LogicalType> types_p, vector<string> names_p, LogicalGet &get,
|
|
146400
146907
|
idx_t index, bool add_row_id)
|
|
146401
146908
|
: Binding(alias, move(types_p), move(names_p), index), get(get) {
|
|
@@ -146407,10 +146914,10 @@ TableBinding::TableBinding(const string &alias, vector<LogicalType> types_p, vec
|
|
|
146407
146914
|
}
|
|
146408
146915
|
|
|
146409
146916
|
BindResult TableBinding::Bind(ColumnRefExpression &colref, idx_t depth) {
|
|
146917
|
+
auto &column_name = colref.GetColumnName();
|
|
146410
146918
|
column_t column_index;
|
|
146411
|
-
if (!TryGetBindingIndex(
|
|
146412
|
-
return BindResult(
|
|
146413
|
-
colref.column_name));
|
|
146919
|
+
if (!TryGetBindingIndex(column_name, column_index)) {
|
|
146920
|
+
return BindResult(ColumnNotFoundError(column_name));
|
|
146414
146921
|
}
|
|
146415
146922
|
// fetch the type of the column
|
|
146416
146923
|
LogicalType col_type;
|
|
@@ -146444,15 +146951,22 @@ BindResult TableBinding::Bind(ColumnRefExpression &colref, idx_t depth) {
|
|
|
146444
146951
|
return BindResult(make_unique<BoundColumnRefExpression>(colref.GetName(), col_type, binding, depth));
|
|
146445
146952
|
}
|
|
146446
146953
|
|
|
146954
|
+
TableCatalogEntry *TableBinding::GetTableEntry() {
|
|
146955
|
+
return get.GetTable();
|
|
146956
|
+
}
|
|
146957
|
+
|
|
146958
|
+
string TableBinding::ColumnNotFoundError(const string &column_name) const {
|
|
146959
|
+
return StringUtil::Format("Table \"%s\" does not have a column named \"%s\"", alias, column_name);
|
|
146960
|
+
}
|
|
146961
|
+
|
|
146447
146962
|
MacroBinding::MacroBinding(vector<LogicalType> types_p, vector<string> names_p, string macro_name_p)
|
|
146448
|
-
: Binding(
|
|
146963
|
+
: Binding(MacroBinding::MACRO_NAME, move(types_p), move(names_p), -1), macro_name(move(macro_name_p)) {
|
|
146449
146964
|
}
|
|
146450
146965
|
|
|
146451
146966
|
BindResult MacroBinding::Bind(ColumnRefExpression &colref, idx_t depth) {
|
|
146452
146967
|
column_t column_index;
|
|
146453
|
-
if (!TryGetBindingIndex(colref.
|
|
146454
|
-
|
|
146455
|
-
StringUtil::Format("Macro \"%s\" does not have a parameter named \"%s\"", macro_name, colref.column_name));
|
|
146968
|
+
if (!TryGetBindingIndex(colref.GetColumnName(), column_index)) {
|
|
146969
|
+
throw InternalException("Column %s not found in macro", colref.GetColumnName());
|
|
146456
146970
|
}
|
|
146457
146971
|
ColumnBinding binding;
|
|
146458
146972
|
binding.table_index = index;
|
|
@@ -146464,8 +146978,8 @@ BindResult MacroBinding::Bind(ColumnRefExpression &colref, idx_t depth) {
|
|
|
146464
146978
|
|
|
146465
146979
|
unique_ptr<ParsedExpression> MacroBinding::ParamToArg(ColumnRefExpression &colref) {
|
|
146466
146980
|
column_t column_index;
|
|
146467
|
-
if (!TryGetBindingIndex(colref.
|
|
146468
|
-
throw
|
|
146981
|
+
if (!TryGetBindingIndex(colref.GetColumnName(), column_index)) {
|
|
146982
|
+
throw InternalException("Column %s not found in macro", colref.GetColumnName());
|
|
146469
146983
|
}
|
|
146470
146984
|
auto arg = arguments[column_index]->Copy();
|
|
146471
146985
|
arg->alias = colref.alias;
|
|
@@ -153439,7 +153953,7 @@ string ValidityStatistics::ToString() {
|
|
|
153439
153953
|
|
|
153440
153954
|
namespace duckdb {
|
|
153441
153955
|
|
|
153442
|
-
const uint64_t VERSION_NUMBER =
|
|
153956
|
+
const uint64_t VERSION_NUMBER = 28;
|
|
153443
153957
|
|
|
153444
153958
|
} // namespace duckdb
|
|
153445
153959
|
|
|
@@ -212116,7 +212630,6 @@ unsigned char *unicode_to_utf8(pg_wchar c, unsigned char *utf8string);
|
|
|
212116
212630
|
|
|
212117
212631
|
// max parse tree size approx 100 MB, should be enough
|
|
212118
212632
|
#define PG_MALLOC_SIZE 10240
|
|
212119
|
-
#define PG_MALLOC_LIMIT 1000
|
|
212120
212633
|
|
|
212121
212634
|
namespace duckdb_libpgquery {
|
|
212122
212635
|
|
|
@@ -212128,7 +212641,8 @@ struct pg_parser_state_str {
|
|
|
212128
212641
|
|
|
212129
212642
|
size_t malloc_pos;
|
|
212130
212643
|
size_t malloc_ptr_idx;
|
|
212131
|
-
char
|
|
212644
|
+
char **malloc_ptrs;
|
|
212645
|
+
size_t malloc_ptr_size;
|
|
212132
212646
|
};
|
|
212133
212647
|
|
|
212134
212648
|
static __thread parser_state pg_parser_state;
|
|
@@ -212138,8 +212652,13 @@ __thread PGNode *duckdb_newNodeMacroHolder;
|
|
|
212138
212652
|
#endif
|
|
212139
212653
|
|
|
212140
212654
|
static void allocate_new(parser_state *state, size_t n) {
|
|
212141
|
-
if (state->malloc_ptr_idx
|
|
212142
|
-
|
|
212655
|
+
if (state->malloc_ptr_idx >= state->malloc_ptr_size) {
|
|
212656
|
+
size_t new_size = state->malloc_ptr_size * 2;
|
|
212657
|
+
auto new_malloc_ptrs = (char **) malloc(sizeof(char *) * new_size);
|
|
212658
|
+
memcpy(new_malloc_ptrs, state->malloc_ptrs, state->malloc_ptr_size * sizeof(char*));
|
|
212659
|
+
free(state->malloc_ptrs);
|
|
212660
|
+
state->malloc_ptr_size = new_size;
|
|
212661
|
+
state->malloc_ptrs = new_malloc_ptrs;
|
|
212143
212662
|
}
|
|
212144
212663
|
if (n < PG_MALLOC_SIZE) {
|
|
212145
212664
|
n = PG_MALLOC_SIZE;
|
|
@@ -212170,6 +212689,8 @@ void pg_parser_init() {
|
|
|
212170
212689
|
pg_parser_state.pg_err_code = PGUNDEFINED;
|
|
212171
212690
|
pg_parser_state.pg_err_msg[0] = '\0';
|
|
212172
212691
|
|
|
212692
|
+
pg_parser_state.malloc_ptr_size = 4;
|
|
212693
|
+
pg_parser_state.malloc_ptrs = (char **) malloc(sizeof(char *) * pg_parser_state.malloc_ptr_size);
|
|
212173
212694
|
pg_parser_state.malloc_ptr_idx = 0;
|
|
212174
212695
|
allocate_new(&pg_parser_state, 1);
|
|
212175
212696
|
}
|
|
@@ -212179,8 +212700,16 @@ void pg_parser_parse(const char *query, parse_result *res) {
|
|
|
212179
212700
|
try {
|
|
212180
212701
|
res->parse_tree = duckdb_libpgquery::raw_parser(query);
|
|
212181
212702
|
res->success = pg_parser_state.pg_err_code == PGUNDEFINED;
|
|
212182
|
-
} catch (
|
|
212703
|
+
} catch (std::exception &ex) {
|
|
212183
212704
|
res->success = false;
|
|
212705
|
+
// copy the error message of the exception
|
|
212706
|
+
auto error_message = ex.what();
|
|
212707
|
+
uint32_t pos = 0;
|
|
212708
|
+
while(pos < 1023 && error_message[pos]) {
|
|
212709
|
+
pg_parser_state.pg_err_msg[pos] = error_message[pos];
|
|
212710
|
+
pos++;
|
|
212711
|
+
}
|
|
212712
|
+
pg_parser_state.pg_err_msg[pos] = '\0';
|
|
212184
212713
|
}
|
|
212185
212714
|
res->error_message = pg_parser_state.pg_err_msg;
|
|
212186
212715
|
res->error_location = pg_parser_state.pg_err_pos;
|
|
@@ -212194,6 +212723,7 @@ void pg_parser_cleanup() {
|
|
|
212194
212723
|
pg_parser_state.malloc_ptrs[ptr_idx] = nullptr;
|
|
212195
212724
|
}
|
|
212196
212725
|
}
|
|
212726
|
+
free(pg_parser_state.malloc_ptrs);
|
|
212197
212727
|
}
|
|
212198
212728
|
|
|
212199
212729
|
int ereport(int code, ...) {
|