duckdb 0.3.2-dev5.0 → 0.3.2-dev50.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 +887 -544
- package/src/duckdb.hpp +11 -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(
|
|
@@ -18315,7 +18349,7 @@ struct RegexpFun {
|
|
|
18315
18349
|
|
|
18316
18350
|
struct SubstringFun {
|
|
18317
18351
|
static void RegisterFunction(BuiltinFunctions &set);
|
|
18318
|
-
static string_t SubstringScalarFunction(Vector &result, string_t input,
|
|
18352
|
+
static string_t SubstringScalarFunction(Vector &result, string_t input, int64_t offset, int64_t length);
|
|
18319
18353
|
};
|
|
18320
18354
|
|
|
18321
18355
|
struct PrintfFun {
|
|
@@ -37228,6 +37262,52 @@ bool Interval::GreaterThanEquals(interval_t left, interval_t right) {
|
|
|
37228
37262
|
return GreaterThan(left, right) || Equals(left, right);
|
|
37229
37263
|
}
|
|
37230
37264
|
|
|
37265
|
+
date_t Interval::Add(date_t left, interval_t right) {
|
|
37266
|
+
date_t result;
|
|
37267
|
+
if (right.months != 0) {
|
|
37268
|
+
int32_t year, month, day;
|
|
37269
|
+
Date::Convert(left, year, month, day);
|
|
37270
|
+
int32_t year_diff = right.months / Interval::MONTHS_PER_YEAR;
|
|
37271
|
+
year += year_diff;
|
|
37272
|
+
month += right.months - year_diff * Interval::MONTHS_PER_YEAR;
|
|
37273
|
+
if (month > Interval::MONTHS_PER_YEAR) {
|
|
37274
|
+
year++;
|
|
37275
|
+
month -= Interval::MONTHS_PER_YEAR;
|
|
37276
|
+
} else if (month <= 0) {
|
|
37277
|
+
year--;
|
|
37278
|
+
month += Interval::MONTHS_PER_YEAR;
|
|
37279
|
+
}
|
|
37280
|
+
day = MinValue<int32_t>(day, Date::MonthDays(year, month));
|
|
37281
|
+
result = Date::FromDate(year, month, day);
|
|
37282
|
+
} else {
|
|
37283
|
+
result = left;
|
|
37284
|
+
}
|
|
37285
|
+
if (right.days != 0) {
|
|
37286
|
+
if (!TryAddOperator::Operation(result.days, right.days, result.days)) {
|
|
37287
|
+
throw OutOfRangeException("Date out of range");
|
|
37288
|
+
}
|
|
37289
|
+
}
|
|
37290
|
+
if (right.micros != 0) {
|
|
37291
|
+
if (!TryAddOperator::Operation(result.days, int32_t(right.micros / Interval::MICROS_PER_DAY), result.days)) {
|
|
37292
|
+
throw OutOfRangeException("Date out of range");
|
|
37293
|
+
}
|
|
37294
|
+
}
|
|
37295
|
+
return result;
|
|
37296
|
+
}
|
|
37297
|
+
|
|
37298
|
+
dtime_t Interval::Add(dtime_t left, interval_t right, date_t &date) {
|
|
37299
|
+
int64_t diff = right.micros - ((right.micros / Interval::MICROS_PER_DAY) * Interval::MICROS_PER_DAY);
|
|
37300
|
+
left += diff;
|
|
37301
|
+
if (left.micros >= Interval::MICROS_PER_DAY) {
|
|
37302
|
+
left.micros -= Interval::MICROS_PER_DAY;
|
|
37303
|
+
date.days++;
|
|
37304
|
+
} else if (left.micros < 0) {
|
|
37305
|
+
left.micros += Interval::MICROS_PER_DAY;
|
|
37306
|
+
date.days--;
|
|
37307
|
+
}
|
|
37308
|
+
return left;
|
|
37309
|
+
}
|
|
37310
|
+
|
|
37231
37311
|
} // namespace duckdb
|
|
37232
37312
|
|
|
37233
37313
|
|
|
@@ -46204,7 +46284,38 @@ void FillEnumResultTemplate(Vector &source, Vector &result, idx_t count) {
|
|
|
46204
46284
|
}
|
|
46205
46285
|
}
|
|
46206
46286
|
|
|
46207
|
-
|
|
46287
|
+
void EnumToVarchar(Vector &source, Vector &result, idx_t count, PhysicalType enum_physical_type) {
|
|
46288
|
+
if (source.GetVectorType() == VectorType::CONSTANT_VECTOR) {
|
|
46289
|
+
result.SetVectorType(source.GetVectorType());
|
|
46290
|
+
} else {
|
|
46291
|
+
result.SetVectorType(VectorType::FLAT_VECTOR);
|
|
46292
|
+
}
|
|
46293
|
+
for (idx_t i = 0; i < count; i++) {
|
|
46294
|
+
auto src_val = source.GetValue(i);
|
|
46295
|
+
if (src_val.is_null) {
|
|
46296
|
+
result.SetValue(i, Value());
|
|
46297
|
+
continue;
|
|
46298
|
+
}
|
|
46299
|
+
auto str_vec = EnumType::GetValuesInsertOrder(source.GetType());
|
|
46300
|
+
uint64_t enum_idx;
|
|
46301
|
+
switch (enum_physical_type) {
|
|
46302
|
+
case PhysicalType::UINT8:
|
|
46303
|
+
enum_idx = src_val.value_.utinyint;
|
|
46304
|
+
break;
|
|
46305
|
+
case PhysicalType::UINT16:
|
|
46306
|
+
enum_idx = src_val.value_.usmallint;
|
|
46307
|
+
break;
|
|
46308
|
+
case PhysicalType::UINT32:
|
|
46309
|
+
enum_idx = src_val.value_.uinteger;
|
|
46310
|
+
break;
|
|
46311
|
+
default:
|
|
46312
|
+
throw InternalException("ENUM can only have unsigned integers (except UINT64) as physical types");
|
|
46313
|
+
}
|
|
46314
|
+
result.SetValue(i, Value(str_vec[enum_idx]));
|
|
46315
|
+
}
|
|
46316
|
+
}
|
|
46317
|
+
|
|
46318
|
+
static bool EnumCastSwitch(Vector &source, Vector &result, idx_t count, string *error_message, bool strict) {
|
|
46208
46319
|
auto enum_physical_type = source.GetType().InternalType();
|
|
46209
46320
|
switch (result.GetType().id()) {
|
|
46210
46321
|
case LogicalTypeId::ENUM: {
|
|
@@ -46225,38 +46336,17 @@ static bool EnumCastSwitch(Vector &source, Vector &result, idx_t count, string *
|
|
|
46225
46336
|
break;
|
|
46226
46337
|
}
|
|
46227
46338
|
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
|
-
}
|
|
46339
|
+
EnumToVarchar(source, result, count, enum_physical_type);
|
|
46340
|
+
break;
|
|
46341
|
+
}
|
|
46342
|
+
default: {
|
|
46343
|
+
// Cast to varchar
|
|
46344
|
+
Vector varchar_cast(LogicalType::VARCHAR, count);
|
|
46345
|
+
EnumToVarchar(source, varchar_cast, count, enum_physical_type);
|
|
46346
|
+
// Try to cast from varchar to whatever we wanted before
|
|
46347
|
+
VectorOperations::TryCast(varchar_cast, result, count, error_message, strict);
|
|
46256
46348
|
break;
|
|
46257
46349
|
}
|
|
46258
|
-
default:
|
|
46259
|
-
throw InternalException("Cast from Enum is not allowed");
|
|
46260
46350
|
}
|
|
46261
46351
|
return true;
|
|
46262
46352
|
}
|
|
@@ -46371,7 +46461,7 @@ bool VectorOperations::TryCast(Vector &source, Vector &result, idx_t count, stri
|
|
|
46371
46461
|
case LogicalTypeId::LIST:
|
|
46372
46462
|
return ListCastSwitch(source, result, count, error_message);
|
|
46373
46463
|
case LogicalTypeId::ENUM:
|
|
46374
|
-
return EnumCastSwitch(source, result, count, error_message);
|
|
46464
|
+
return EnumCastSwitch(source, result, count, error_message, strict);
|
|
46375
46465
|
default:
|
|
46376
46466
|
return TryVectorNullCast(source, result, count, error_message);
|
|
46377
46467
|
}
|
|
@@ -49644,6 +49734,7 @@ void ExpressionExecutor::ExecuteExpression(idx_t expr_idx, Vector &result) {
|
|
|
49644
49734
|
|
|
49645
49735
|
Value ExpressionExecutor::EvaluateScalar(const Expression &expr) {
|
|
49646
49736
|
D_ASSERT(expr.IsFoldable());
|
|
49737
|
+
D_ASSERT(expr.IsScalar());
|
|
49647
49738
|
// use an ExpressionExecutor to execute the expression
|
|
49648
49739
|
ExpressionExecutor executor(expr);
|
|
49649
49740
|
|
|
@@ -58771,6 +58862,7 @@ struct TableScanBindData : public FunctionData {
|
|
|
58771
58862
|
//! The table scan function represents a sequential scan over one of DuckDB's base tables.
|
|
58772
58863
|
struct TableScanFunction {
|
|
58773
58864
|
static TableFunction GetFunction();
|
|
58865
|
+
static TableCatalogEntry *GetTableEntry(const TableFunction &function, const FunctionData *bind_data);
|
|
58774
58866
|
};
|
|
58775
58867
|
|
|
58776
58868
|
} // namespace duckdb
|
|
@@ -61172,15 +61264,9 @@ struct BufferedCSVReaderOptions {
|
|
|
61172
61264
|
//! Whether or not a type format is specified
|
|
61173
61265
|
std::map<LogicalTypeId, bool> has_format = {{LogicalTypeId::DATE, false}, {LogicalTypeId::TIMESTAMP, false}};
|
|
61174
61266
|
|
|
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
|
-
}
|
|
61267
|
+
void SetDelimiter(const string &delimiter);
|
|
61268
|
+
|
|
61269
|
+
std::string ToString() const;
|
|
61184
61270
|
};
|
|
61185
61271
|
|
|
61186
61272
|
enum class ParserMode : uint8_t { PARSING = 0, SNIFFING_DIALECT = 1, SNIFFING_DATATYPES = 2, PARSING_HEADER = 3 };
|
|
@@ -61333,6 +61419,24 @@ private:
|
|
|
61333
61419
|
|
|
61334
61420
|
namespace duckdb {
|
|
61335
61421
|
|
|
61422
|
+
void BufferedCSVReaderOptions::SetDelimiter(const string &input) {
|
|
61423
|
+
this->delimiter = StringUtil::Replace(input, "\\t", "\t");
|
|
61424
|
+
this->has_delimiter = true;
|
|
61425
|
+
if (input.empty()) {
|
|
61426
|
+
throw BinderException("DELIM or SEP must not be empty");
|
|
61427
|
+
}
|
|
61428
|
+
}
|
|
61429
|
+
|
|
61430
|
+
std::string BufferedCSVReaderOptions::ToString() const {
|
|
61431
|
+
return "DELIMITER='" + delimiter + (has_delimiter ? "'" : (auto_detect ? "' (auto detected)" : "' (default)")) +
|
|
61432
|
+
", QUOTE='" + quote + (has_quote ? "'" : (auto_detect ? "' (auto detected)" : "' (default)")) +
|
|
61433
|
+
", ESCAPE='" + escape + (has_escape ? "'" : (auto_detect ? "' (auto detected)" : "' (default)")) +
|
|
61434
|
+
", HEADER=" + std::to_string(header) +
|
|
61435
|
+
(has_header ? "" : (auto_detect ? " (auto detected)" : "' (default)")) +
|
|
61436
|
+
", SAMPLE_SIZE=" + std::to_string(sample_chunk_size * sample_chunks) +
|
|
61437
|
+
", ALL_VARCHAR=" + std::to_string(all_varchar);
|
|
61438
|
+
}
|
|
61439
|
+
|
|
61336
61440
|
static string GetLineNumberStr(idx_t linenr, bool linenr_estimated) {
|
|
61337
61441
|
string estimated = (linenr_estimated ? string(" (estimated)") : string(""));
|
|
61338
61442
|
return to_string(linenr + 1) + estimated;
|
|
@@ -62146,7 +62250,7 @@ vector<LogicalType> BufferedCSVReader::RefineTypeDetection(const vector<LogicalT
|
|
|
62146
62250
|
if (requested_types.size() != options.num_cols) {
|
|
62147
62251
|
throw InvalidInputException(
|
|
62148
62252
|
"Error while determining column types: found %lld columns but expected %d. (%s)", options.num_cols,
|
|
62149
|
-
requested_types.size(), options.
|
|
62253
|
+
requested_types.size(), options.ToString());
|
|
62150
62254
|
} else {
|
|
62151
62255
|
detected_types = requested_types;
|
|
62152
62256
|
}
|
|
@@ -62404,7 +62508,7 @@ in_quotes:
|
|
|
62404
62508
|
} while (ReadBuffer(start));
|
|
62405
62509
|
// still in quoted state at the end of the file, error:
|
|
62406
62510
|
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.
|
|
62511
|
+
GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString());
|
|
62408
62512
|
return false;
|
|
62409
62513
|
unquote:
|
|
62410
62514
|
/* state: unquote */
|
|
@@ -62434,7 +62538,7 @@ unquote:
|
|
|
62434
62538
|
error_message = StringUtil::Format(
|
|
62435
62539
|
"Error in file \"%s\" on line %s: quote should be followed by end of value, end "
|
|
62436
62540
|
"of row or another quote. (%s)",
|
|
62437
|
-
options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.
|
|
62541
|
+
options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString());
|
|
62438
62542
|
return false;
|
|
62439
62543
|
}
|
|
62440
62544
|
if (delimiter_pos == options.delimiter.size()) {
|
|
@@ -62451,7 +62555,7 @@ unquote:
|
|
|
62451
62555
|
} while (ReadBuffer(start));
|
|
62452
62556
|
error_message = StringUtil::Format(
|
|
62453
62557
|
"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.
|
|
62558
|
+
options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString());
|
|
62455
62559
|
return false;
|
|
62456
62560
|
handle_escape:
|
|
62457
62561
|
escape_pos = 0;
|
|
@@ -62466,7 +62570,7 @@ handle_escape:
|
|
|
62466
62570
|
if (count > escape_pos && count > quote_pos) {
|
|
62467
62571
|
error_message = StringUtil::Format(
|
|
62468
62572
|
"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.
|
|
62573
|
+
options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString());
|
|
62470
62574
|
return false;
|
|
62471
62575
|
}
|
|
62472
62576
|
if (quote_pos == options.quote.size() || escape_pos == options.escape.size()) {
|
|
@@ -62477,7 +62581,7 @@ handle_escape:
|
|
|
62477
62581
|
} while (ReadBuffer(start));
|
|
62478
62582
|
error_message =
|
|
62479
62583
|
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.
|
|
62584
|
+
options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString());
|
|
62481
62585
|
return false;
|
|
62482
62586
|
carriage_return:
|
|
62483
62587
|
/* state: carriage_return */
|
|
@@ -62609,7 +62713,7 @@ in_quotes:
|
|
|
62609
62713
|
} while (ReadBuffer(start));
|
|
62610
62714
|
// still in quoted state at the end of the file, error:
|
|
62611
62715
|
throw InvalidInputException("Error in file \"%s\" on line %s: unterminated quotes. (%s)", options.file_path,
|
|
62612
|
-
GetLineNumberStr(linenr, linenr_estimated).c_str(), options.
|
|
62716
|
+
GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString());
|
|
62613
62717
|
unquote:
|
|
62614
62718
|
/* state: unquote */
|
|
62615
62719
|
// this state handles the state directly after we unquote
|
|
@@ -62636,7 +62740,7 @@ unquote:
|
|
|
62636
62740
|
error_message = StringUtil::Format(
|
|
62637
62741
|
"Error in file \"%s\" on line %s: quote should be followed by end of value, end of "
|
|
62638
62742
|
"row or another quote. (%s)",
|
|
62639
|
-
options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.
|
|
62743
|
+
options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString());
|
|
62640
62744
|
return false;
|
|
62641
62745
|
}
|
|
62642
62746
|
handle_escape:
|
|
@@ -62646,13 +62750,13 @@ handle_escape:
|
|
|
62646
62750
|
if (position >= buffer_size && !ReadBuffer(start)) {
|
|
62647
62751
|
error_message = StringUtil::Format(
|
|
62648
62752
|
"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.
|
|
62753
|
+
GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString());
|
|
62650
62754
|
return false;
|
|
62651
62755
|
}
|
|
62652
62756
|
if (buffer[position] != options.quote[0] && buffer[position] != options.escape[0]) {
|
|
62653
62757
|
error_message = StringUtil::Format(
|
|
62654
62758
|
"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.
|
|
62759
|
+
GetLineNumberStr(linenr, linenr_estimated).c_str(), options.ToString());
|
|
62656
62760
|
return false;
|
|
62657
62761
|
}
|
|
62658
62762
|
// escape was followed by quote or escape, go back to quoted state
|
|
@@ -62792,7 +62896,7 @@ void BufferedCSVReader::AddValue(char *str_val, idx_t length, idx_t &column, vec
|
|
|
62792
62896
|
if (column >= sql_types.size()) {
|
|
62793
62897
|
throw InvalidInputException("Error on line %s: expected %lld values per row, but got more. (%s)",
|
|
62794
62898
|
GetLineNumberStr(linenr, linenr_estimated).c_str(), sql_types.size(),
|
|
62795
|
-
options.
|
|
62899
|
+
options.ToString());
|
|
62796
62900
|
}
|
|
62797
62901
|
|
|
62798
62902
|
// insert the line number into the chunk
|
|
@@ -62847,7 +62951,7 @@ bool BufferedCSVReader::AddRow(DataChunk &insert_chunk, idx_t &column) {
|
|
|
62847
62951
|
if (column < sql_types.size() && mode != ParserMode::SNIFFING_DIALECT) {
|
|
62848
62952
|
throw InvalidInputException("Error on line %s: expected %lld values per row, but got %d. (%s)",
|
|
62849
62953
|
GetLineNumberStr(linenr, linenr_estimated).c_str(), sql_types.size(), column,
|
|
62850
|
-
options.
|
|
62954
|
+
options.ToString());
|
|
62851
62955
|
}
|
|
62852
62956
|
|
|
62853
62957
|
if (mode == ParserMode::SNIFFING_DIALECT) {
|
|
@@ -62900,7 +63004,7 @@ void BufferedCSVReader::Flush(DataChunk &insert_chunk) {
|
|
|
62900
63004
|
throw InvalidInputException("Error in file \"%s\" between line %llu and %llu in column \"%s\": "
|
|
62901
63005
|
"file is not valid UTF8. Parser options: %s",
|
|
62902
63006
|
options.file_path, linenr - parse_chunk.size(), linenr, col_name,
|
|
62903
|
-
options.
|
|
63007
|
+
options.ToString());
|
|
62904
63008
|
}
|
|
62905
63009
|
}
|
|
62906
63010
|
}
|
|
@@ -62934,11 +63038,11 @@ void BufferedCSVReader::Flush(DataChunk &insert_chunk) {
|
|
|
62934
63038
|
"(SAMPLE_SIZE=X [X rows] or SAMPLE_SIZE=-1 [all rows]), "
|
|
62935
63039
|
"or skipping column conversion (ALL_VARCHAR=1)",
|
|
62936
63040
|
error_message, col_name, linenr - parse_chunk.size() + 1, linenr,
|
|
62937
|
-
options.
|
|
63041
|
+
options.ToString());
|
|
62938
63042
|
} else {
|
|
62939
63043
|
throw InvalidInputException("%s between line %llu and %llu in column %s. Parser options: %s ",
|
|
62940
63044
|
error_message, linenr - parse_chunk.size(), linenr, col_name,
|
|
62941
|
-
options.
|
|
63045
|
+
options.ToString());
|
|
62942
63046
|
}
|
|
62943
63047
|
}
|
|
62944
63048
|
}
|
|
@@ -68409,6 +68513,8 @@ public:
|
|
|
68409
68513
|
|
|
68410
68514
|
string GetName() const override;
|
|
68411
68515
|
string ParamsToString() const override;
|
|
68516
|
+
//! Returns the underlying table that is being scanned, or nullptr if there is none
|
|
68517
|
+
TableCatalogEntry *GetTable() const;
|
|
68412
68518
|
|
|
68413
68519
|
public:
|
|
68414
68520
|
vector<ColumnBinding> GetColumnBindings() override;
|
|
@@ -78943,7 +79049,7 @@ string MacroFunction::ValidateArguments(MacroCatalogEntry ¯o_func, FunctionE
|
|
|
78943
79049
|
error = StringUtil::Format(
|
|
78944
79050
|
"Macro function '%s(%s)' requires ", macro_func.name,
|
|
78945
79051
|
StringUtil::Join(parameters, parameters.size(), ", ", [](const unique_ptr<ParsedExpression> &p) {
|
|
78946
|
-
return ((ColumnRefExpression &)*p).
|
|
79052
|
+
return ((ColumnRefExpression &)*p).column_names[0];
|
|
78947
79053
|
}));
|
|
78948
79054
|
error += parameters.size() == 1 ? "a single positional argument"
|
|
78949
79055
|
: StringUtil::Format("%i positional arguments", parameters.size());
|
|
@@ -80733,7 +80839,7 @@ int64_t DatePart::MicrosecondsOperator::Operation(timestamp_t input) {
|
|
|
80733
80839
|
template <>
|
|
80734
80840
|
int64_t DatePart::MicrosecondsOperator::Operation(interval_t input) {
|
|
80735
80841
|
// remove everything but the second & microsecond part
|
|
80736
|
-
return input.micros;
|
|
80842
|
+
return input.micros % Interval::MICROS_PER_MINUTE;
|
|
80737
80843
|
}
|
|
80738
80844
|
|
|
80739
80845
|
template <>
|
|
@@ -80813,8 +80919,17 @@ int64_t DatePart::EpochOperator::Operation(timestamp_t input) {
|
|
|
80813
80919
|
|
|
80814
80920
|
template <>
|
|
80815
80921
|
int64_t DatePart::EpochOperator::Operation(interval_t input) {
|
|
80816
|
-
|
|
80817
|
-
|
|
80922
|
+
int64_t interval_years = input.months / Interval::MONTHS_PER_YEAR;
|
|
80923
|
+
int64_t interval_days;
|
|
80924
|
+
interval_days = Interval::DAYS_PER_YEAR * interval_years;
|
|
80925
|
+
interval_days += Interval::DAYS_PER_MONTH * (input.months % Interval::MONTHS_PER_YEAR);
|
|
80926
|
+
interval_days += input.days;
|
|
80927
|
+
int64_t interval_epoch;
|
|
80928
|
+
interval_epoch = interval_days * Interval::SECS_PER_DAY;
|
|
80929
|
+
// we add 0.25 days per year to sort of account for leap days
|
|
80930
|
+
interval_epoch += interval_years * (Interval::SECS_PER_DAY / 4);
|
|
80931
|
+
interval_epoch += input.micros / Interval::MICROS_PER_SEC;
|
|
80932
|
+
return interval_epoch;
|
|
80818
80933
|
}
|
|
80819
80934
|
|
|
80820
80935
|
template <>
|
|
@@ -86034,36 +86149,7 @@ date_t AddOperator::Operation(int32_t left, date_t right) {
|
|
|
86034
86149
|
|
|
86035
86150
|
template <>
|
|
86036
86151
|
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;
|
|
86152
|
+
return Interval::Add(left, right);
|
|
86067
86153
|
}
|
|
86068
86154
|
|
|
86069
86155
|
template <>
|
|
@@ -86071,26 +86157,13 @@ date_t AddOperator::Operation(interval_t left, date_t right) {
|
|
|
86071
86157
|
return AddOperator::Operation<date_t, interval_t, date_t>(right, left);
|
|
86072
86158
|
}
|
|
86073
86159
|
|
|
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
86160
|
template <>
|
|
86088
86161
|
timestamp_t AddOperator::Operation(timestamp_t left, interval_t right) {
|
|
86089
86162
|
date_t date;
|
|
86090
86163
|
dtime_t time;
|
|
86091
86164
|
Timestamp::Convert(left, date, time);
|
|
86092
|
-
auto new_date =
|
|
86093
|
-
auto new_time =
|
|
86165
|
+
auto new_date = Interval::Add(date, right);
|
|
86166
|
+
auto new_time = Interval::Add(time, right, new_date);
|
|
86094
86167
|
return Timestamp::FromDatetime(new_date, new_time);
|
|
86095
86168
|
}
|
|
86096
86169
|
|
|
@@ -86223,7 +86296,7 @@ hugeint_t DecimalAddOverflowCheck::Operation(hugeint_t left, hugeint_t right) {
|
|
|
86223
86296
|
template <>
|
|
86224
86297
|
dtime_t AddTimeOperator::Operation(dtime_t left, interval_t right) {
|
|
86225
86298
|
date_t date(0);
|
|
86226
|
-
return
|
|
86299
|
+
return Interval::Add(left, right, date);
|
|
86227
86300
|
}
|
|
86228
86301
|
|
|
86229
86302
|
template <>
|
|
@@ -92175,7 +92248,7 @@ string_t SubstringASCII(Vector &result, string_t input, int64_t offset, int64_t
|
|
|
92175
92248
|
return SubstringSlice(result, input_data, start, end - start);
|
|
92176
92249
|
}
|
|
92177
92250
|
|
|
92178
|
-
string_t SubstringFun::SubstringScalarFunction(Vector &result, string_t input,
|
|
92251
|
+
string_t SubstringFun::SubstringScalarFunction(Vector &result, string_t input, int64_t offset, int64_t length) {
|
|
92179
92252
|
auto input_data = input.GetDataUnsafe();
|
|
92180
92253
|
auto input_size = input.GetSize();
|
|
92181
92254
|
|
|
@@ -92242,16 +92315,16 @@ static void SubstringFunction(DataChunk &args, ExpressionState &state, Vector &r
|
|
|
92242
92315
|
if (args.ColumnCount() == 3) {
|
|
92243
92316
|
auto &length_vector = args.data[2];
|
|
92244
92317
|
|
|
92245
|
-
TernaryExecutor::Execute<string_t,
|
|
92318
|
+
TernaryExecutor::Execute<string_t, int64_t, int64_t, string_t>(
|
|
92246
92319
|
input_vector, offset_vector, length_vector, result, args.size(),
|
|
92247
|
-
[&](string_t input_string,
|
|
92320
|
+
[&](string_t input_string, int64_t offset, int64_t length) {
|
|
92248
92321
|
return SubstringFun::SubstringScalarFunction(result, input_string, offset, length);
|
|
92249
92322
|
});
|
|
92250
92323
|
} else {
|
|
92251
|
-
BinaryExecutor::Execute<string_t,
|
|
92252
|
-
input_vector, offset_vector, result, args.size(), [&](string_t input_string,
|
|
92324
|
+
BinaryExecutor::Execute<string_t, int64_t, string_t>(
|
|
92325
|
+
input_vector, offset_vector, result, args.size(), [&](string_t input_string, int64_t offset) {
|
|
92253
92326
|
return SubstringFun::SubstringScalarFunction(result, input_string, offset,
|
|
92254
|
-
NumericLimits<
|
|
92327
|
+
NumericLimits<int64_t>::Maximum() - offset);
|
|
92255
92328
|
});
|
|
92256
92329
|
}
|
|
92257
92330
|
}
|
|
@@ -92262,15 +92335,15 @@ static void SubstringFunctionASCII(DataChunk &args, ExpressionState &state, Vect
|
|
|
92262
92335
|
if (args.ColumnCount() == 3) {
|
|
92263
92336
|
auto &length_vector = args.data[2];
|
|
92264
92337
|
|
|
92265
|
-
TernaryExecutor::Execute<string_t,
|
|
92338
|
+
TernaryExecutor::Execute<string_t, int64_t, int64_t, string_t>(
|
|
92266
92339
|
input_vector, offset_vector, length_vector, result, args.size(),
|
|
92267
|
-
[&](string_t input_string,
|
|
92340
|
+
[&](string_t input_string, int64_t offset, int64_t length) {
|
|
92268
92341
|
return SubstringASCII(result, input_string, offset, length);
|
|
92269
92342
|
});
|
|
92270
92343
|
} 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<
|
|
92344
|
+
BinaryExecutor::Execute<string_t, int64_t, string_t>(
|
|
92345
|
+
input_vector, offset_vector, result, args.size(), [&](string_t input_string, int64_t offset) {
|
|
92346
|
+
return SubstringASCII(result, input_string, offset, NumericLimits<int64_t>::Maximum() - offset);
|
|
92274
92347
|
});
|
|
92275
92348
|
}
|
|
92276
92349
|
}
|
|
@@ -92292,10 +92365,10 @@ static unique_ptr<BaseStatistics> SubstringPropagateStats(ClientContext &context
|
|
|
92292
92365
|
|
|
92293
92366
|
void SubstringFun::RegisterFunction(BuiltinFunctions &set) {
|
|
92294
92367
|
ScalarFunctionSet substr("substring");
|
|
92295
|
-
substr.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::
|
|
92368
|
+
substr.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::BIGINT, LogicalType::BIGINT},
|
|
92296
92369
|
LogicalType::VARCHAR, SubstringFunction, false, nullptr, nullptr,
|
|
92297
92370
|
SubstringPropagateStats));
|
|
92298
|
-
substr.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::
|
|
92371
|
+
substr.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::BIGINT}, LogicalType::VARCHAR,
|
|
92299
92372
|
SubstringFunction, false, nullptr, nullptr, SubstringPropagateStats));
|
|
92300
92373
|
set.AddFunction(substr);
|
|
92301
92374
|
substr.name = "substr";
|
|
@@ -94477,11 +94550,7 @@ static int64_t ParseInteger(vector<Value> &set) {
|
|
|
94477
94550
|
//===--------------------------------------------------------------------===//
|
|
94478
94551
|
static bool ParseBaseOption(BufferedCSVReaderOptions &options, string &loption, vector<Value> &set) {
|
|
94479
94552
|
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
|
-
}
|
|
94553
|
+
options.SetDelimiter(ParseString(set));
|
|
94485
94554
|
} else if (loption == "quote") {
|
|
94486
94555
|
options.quote = ParseString(set);
|
|
94487
94556
|
options.has_quote = true;
|
|
@@ -95766,8 +95835,7 @@ static unique_ptr<FunctionData> ReadCSVBind(ClientContext &context, vector<Value
|
|
|
95766
95835
|
if (kv.first == "auto_detect") {
|
|
95767
95836
|
options.auto_detect = kv.second.value_.boolean;
|
|
95768
95837
|
} else if (kv.first == "sep" || kv.first == "delim") {
|
|
95769
|
-
options.
|
|
95770
|
-
options.has_delimiter = true;
|
|
95838
|
+
options.SetDelimiter(kv.second.str_value);
|
|
95771
95839
|
} else if (kv.first == "header") {
|
|
95772
95840
|
options.header = kv.second.value_.boolean;
|
|
95773
95841
|
options.has_header = true;
|
|
@@ -98679,6 +98747,14 @@ TableFunction TableScanFunction::GetFunction() {
|
|
|
98679
98747
|
return scan_function;
|
|
98680
98748
|
}
|
|
98681
98749
|
|
|
98750
|
+
TableCatalogEntry *TableScanFunction::GetTableEntry(const TableFunction &function, const FunctionData *bind_data_p) {
|
|
98751
|
+
if (function.function != TableScanFunc || !bind_data_p) {
|
|
98752
|
+
return nullptr;
|
|
98753
|
+
}
|
|
98754
|
+
auto &bind_data = (TableScanBindData &)*bind_data_p;
|
|
98755
|
+
return bind_data.table;
|
|
98756
|
+
}
|
|
98757
|
+
|
|
98682
98758
|
} // namespace duckdb
|
|
98683
98759
|
|
|
98684
98760
|
|
|
@@ -106452,10 +106528,10 @@ shared_ptr<Relation> Relation::Join(const shared_ptr<Relation> &other, const str
|
|
|
106452
106528
|
throw ParserException("Expected a single expression as join condition");
|
|
106453
106529
|
}
|
|
106454
106530
|
auto &colref = (ColumnRefExpression &)*expr;
|
|
106455
|
-
if (
|
|
106456
|
-
throw ParserException("Expected
|
|
106531
|
+
if (colref.IsQualified()) {
|
|
106532
|
+
throw ParserException("Expected unqualified column for column in USING clause");
|
|
106457
106533
|
}
|
|
106458
|
-
using_columns.push_back(colref.
|
|
106534
|
+
using_columns.push_back(colref.column_names[0]);
|
|
106459
106535
|
}
|
|
106460
106536
|
return make_shared<JoinRelation>(shared_from_this(), other, move(using_columns), type);
|
|
106461
106537
|
} else {
|
|
@@ -115073,6 +115149,10 @@ unique_ptr<NodeStatistics> StatisticsPropagator::PropagateStatistics(LogicalProj
|
|
|
115073
115149
|
unique_ptr<LogicalOperator> *node_ptr) {
|
|
115074
115150
|
// first propagate to the child
|
|
115075
115151
|
node_stats = PropagateStatistics(proj.children[0]);
|
|
115152
|
+
if (proj.children[0]->type == LogicalOperatorType::LOGICAL_EMPTY_RESULT) {
|
|
115153
|
+
ReplaceWithEmptyResult(*node_ptr);
|
|
115154
|
+
return move(node_stats);
|
|
115155
|
+
}
|
|
115076
115156
|
|
|
115077
115157
|
// then propagate to each of the expressions
|
|
115078
115158
|
for (idx_t i = 0; i < proj.expressions.size(); i++) {
|
|
@@ -121749,53 +121829,85 @@ unique_ptr<ParsedExpression> CollateExpression::Deserialize(ExpressionType type,
|
|
|
121749
121829
|
|
|
121750
121830
|
namespace duckdb {
|
|
121751
121831
|
|
|
121752
|
-
//! Specify both the column and table name
|
|
121753
121832
|
ColumnRefExpression::ColumnRefExpression(string column_name, string table_name)
|
|
121754
|
-
:
|
|
121755
|
-
|
|
121833
|
+
: ColumnRefExpression(table_name.empty() ? vector<string> {move(column_name)}
|
|
121834
|
+
: vector<string> {move(table_name), move(column_name)}) {
|
|
121835
|
+
}
|
|
121836
|
+
|
|
121837
|
+
ColumnRefExpression::ColumnRefExpression(string column_name) : ColumnRefExpression(vector<string> {move(column_name)}) {
|
|
121838
|
+
}
|
|
121839
|
+
|
|
121840
|
+
ColumnRefExpression::ColumnRefExpression(vector<string> column_names_p)
|
|
121841
|
+
: ParsedExpression(ExpressionType::COLUMN_REF, ExpressionClass::COLUMN_REF), column_names(move(column_names_p)) {
|
|
121842
|
+
#ifdef DEBUG
|
|
121843
|
+
for (auto &col_name : column_names) {
|
|
121844
|
+
D_ASSERT(!col_name.empty());
|
|
121845
|
+
}
|
|
121846
|
+
#endif
|
|
121847
|
+
}
|
|
121848
|
+
|
|
121849
|
+
bool ColumnRefExpression::IsQualified() const {
|
|
121850
|
+
return column_names.size() > 1;
|
|
121851
|
+
}
|
|
121852
|
+
|
|
121853
|
+
const string &ColumnRefExpression::GetColumnName() const {
|
|
121854
|
+
D_ASSERT(column_names.size() <= 3);
|
|
121855
|
+
return column_names.back();
|
|
121756
121856
|
}
|
|
121757
121857
|
|
|
121758
|
-
|
|
121858
|
+
const string &ColumnRefExpression::GetTableName() const {
|
|
121859
|
+
D_ASSERT(column_names.size() >= 2 && column_names.size() <= 3);
|
|
121860
|
+
return column_names.size() == 3 ? column_names[1] : column_names[0];
|
|
121759
121861
|
}
|
|
121760
121862
|
|
|
121761
121863
|
string ColumnRefExpression::GetName() const {
|
|
121762
|
-
return !alias.empty() ? alias :
|
|
121864
|
+
return !alias.empty() ? alias : column_names.back();
|
|
121763
121865
|
}
|
|
121764
121866
|
|
|
121765
121867
|
string ColumnRefExpression::ToString() const {
|
|
121766
|
-
|
|
121767
|
-
|
|
121768
|
-
|
|
121769
|
-
|
|
121868
|
+
string result;
|
|
121869
|
+
for (idx_t i = 0; i < column_names.size(); i++) {
|
|
121870
|
+
if (i > 0) {
|
|
121871
|
+
result += ".";
|
|
121872
|
+
}
|
|
121873
|
+
result += column_names[i];
|
|
121770
121874
|
}
|
|
121875
|
+
return result;
|
|
121771
121876
|
}
|
|
121772
121877
|
|
|
121773
121878
|
bool ColumnRefExpression::Equals(const ColumnRefExpression *a, const ColumnRefExpression *b) {
|
|
121774
|
-
return a->
|
|
121879
|
+
return a->column_names == b->column_names;
|
|
121775
121880
|
}
|
|
121776
121881
|
|
|
121777
121882
|
hash_t ColumnRefExpression::Hash() const {
|
|
121778
121883
|
hash_t result = ParsedExpression::Hash();
|
|
121779
|
-
|
|
121884
|
+
for (auto &column_name : column_names) {
|
|
121885
|
+
result = CombineHash(result, duckdb::Hash<const char *>(column_name.c_str()));
|
|
121886
|
+
}
|
|
121780
121887
|
return result;
|
|
121781
121888
|
}
|
|
121782
121889
|
|
|
121783
121890
|
unique_ptr<ParsedExpression> ColumnRefExpression::Copy() const {
|
|
121784
|
-
auto copy = make_unique<ColumnRefExpression>(
|
|
121891
|
+
auto copy = make_unique<ColumnRefExpression>(column_names);
|
|
121785
121892
|
copy->CopyProperties(*this);
|
|
121786
121893
|
return move(copy);
|
|
121787
121894
|
}
|
|
121788
121895
|
|
|
121789
121896
|
void ColumnRefExpression::Serialize(Serializer &serializer) {
|
|
121790
121897
|
ParsedExpression::Serialize(serializer);
|
|
121791
|
-
serializer.
|
|
121792
|
-
|
|
121898
|
+
serializer.Write<idx_t>(column_names.size());
|
|
121899
|
+
for (auto &column_name : column_names) {
|
|
121900
|
+
serializer.WriteString(column_name);
|
|
121901
|
+
}
|
|
121793
121902
|
}
|
|
121794
121903
|
|
|
121795
121904
|
unique_ptr<ParsedExpression> ColumnRefExpression::Deserialize(ExpressionType type, Deserializer &source) {
|
|
121796
|
-
auto
|
|
121797
|
-
|
|
121798
|
-
|
|
121905
|
+
auto column_count = source.Read<idx_t>();
|
|
121906
|
+
vector<string> column_names;
|
|
121907
|
+
for (idx_t i = 0; i < column_count; i++) {
|
|
121908
|
+
column_names.push_back(source.Read<string>());
|
|
121909
|
+
}
|
|
121910
|
+
auto expression = make_unique<ColumnRefExpression>(move(column_names));
|
|
121799
121911
|
return move(expression);
|
|
121800
121912
|
}
|
|
121801
121913
|
|
|
@@ -123541,6 +123653,129 @@ unique_ptr<ParsedExpression> ParsedExpression::Deserialize(Deserializer &source)
|
|
|
123541
123653
|
|
|
123542
123654
|
|
|
123543
123655
|
|
|
123656
|
+
//===----------------------------------------------------------------------===//
|
|
123657
|
+
// DuckDB
|
|
123658
|
+
//
|
|
123659
|
+
// duckdb/parser/query_node/recursive_cte_node.hpp
|
|
123660
|
+
//
|
|
123661
|
+
//
|
|
123662
|
+
//===----------------------------------------------------------------------===//
|
|
123663
|
+
|
|
123664
|
+
|
|
123665
|
+
|
|
123666
|
+
|
|
123667
|
+
|
|
123668
|
+
|
|
123669
|
+
|
|
123670
|
+
namespace duckdb {
|
|
123671
|
+
|
|
123672
|
+
class RecursiveCTENode : public QueryNode {
|
|
123673
|
+
public:
|
|
123674
|
+
RecursiveCTENode() : QueryNode(QueryNodeType::RECURSIVE_CTE_NODE) {
|
|
123675
|
+
}
|
|
123676
|
+
|
|
123677
|
+
string ctename;
|
|
123678
|
+
bool union_all;
|
|
123679
|
+
//! The left side of the set operation
|
|
123680
|
+
unique_ptr<QueryNode> left;
|
|
123681
|
+
//! The right side of the set operation
|
|
123682
|
+
unique_ptr<QueryNode> right;
|
|
123683
|
+
//! Aliases of the recursive CTE node
|
|
123684
|
+
vector<string> aliases;
|
|
123685
|
+
|
|
123686
|
+
const vector<unique_ptr<ParsedExpression>> &GetSelectList() const override {
|
|
123687
|
+
return left->GetSelectList();
|
|
123688
|
+
}
|
|
123689
|
+
|
|
123690
|
+
public:
|
|
123691
|
+
bool Equals(const QueryNode *other) const override;
|
|
123692
|
+
//! Create a copy of this SelectNode
|
|
123693
|
+
unique_ptr<QueryNode> Copy() override;
|
|
123694
|
+
|
|
123695
|
+
//! Serializes a SelectNode to a stand-alone binary blob
|
|
123696
|
+
void Serialize(Serializer &serializer) override;
|
|
123697
|
+
//! Deserializes a blob back into a SelectNode
|
|
123698
|
+
static unique_ptr<QueryNode> Deserialize(Deserializer &source);
|
|
123699
|
+
};
|
|
123700
|
+
|
|
123701
|
+
} // namespace duckdb
|
|
123702
|
+
|
|
123703
|
+
|
|
123704
|
+
|
|
123705
|
+
|
|
123706
|
+
//===----------------------------------------------------------------------===//
|
|
123707
|
+
// DuckDB
|
|
123708
|
+
//
|
|
123709
|
+
// duckdb/parser/tableref/crossproductref.hpp
|
|
123710
|
+
//
|
|
123711
|
+
//
|
|
123712
|
+
//===----------------------------------------------------------------------===//
|
|
123713
|
+
|
|
123714
|
+
|
|
123715
|
+
|
|
123716
|
+
|
|
123717
|
+
|
|
123718
|
+
namespace duckdb {
|
|
123719
|
+
//! Represents a cross product
|
|
123720
|
+
class CrossProductRef : public TableRef {
|
|
123721
|
+
public:
|
|
123722
|
+
CrossProductRef() : TableRef(TableReferenceType::CROSS_PRODUCT) {
|
|
123723
|
+
}
|
|
123724
|
+
|
|
123725
|
+
//! The left hand side of the cross product
|
|
123726
|
+
unique_ptr<TableRef> left;
|
|
123727
|
+
//! The right hand side of the cross product
|
|
123728
|
+
unique_ptr<TableRef> right;
|
|
123729
|
+
|
|
123730
|
+
public:
|
|
123731
|
+
bool Equals(const TableRef *other_p) const override;
|
|
123732
|
+
|
|
123733
|
+
unique_ptr<TableRef> Copy() override;
|
|
123734
|
+
|
|
123735
|
+
//! Serializes a blob into a CrossProductRef
|
|
123736
|
+
void Serialize(Serializer &serializer) override;
|
|
123737
|
+
//! Deserializes a blob back into a CrossProductRef
|
|
123738
|
+
static unique_ptr<TableRef> Deserialize(Deserializer &source);
|
|
123739
|
+
};
|
|
123740
|
+
} // namespace duckdb
|
|
123741
|
+
|
|
123742
|
+
//===----------------------------------------------------------------------===//
|
|
123743
|
+
// DuckDB
|
|
123744
|
+
//
|
|
123745
|
+
// duckdb/parser/tableref/emptytableref.hpp
|
|
123746
|
+
//
|
|
123747
|
+
//
|
|
123748
|
+
//===----------------------------------------------------------------------===//
|
|
123749
|
+
|
|
123750
|
+
|
|
123751
|
+
|
|
123752
|
+
|
|
123753
|
+
|
|
123754
|
+
namespace duckdb {
|
|
123755
|
+
//! Represents a cross product
|
|
123756
|
+
class EmptyTableRef : public TableRef {
|
|
123757
|
+
public:
|
|
123758
|
+
EmptyTableRef() : TableRef(TableReferenceType::EMPTY) {
|
|
123759
|
+
}
|
|
123760
|
+
|
|
123761
|
+
public:
|
|
123762
|
+
bool Equals(const TableRef *other_p) const override;
|
|
123763
|
+
|
|
123764
|
+
unique_ptr<TableRef> Copy() override;
|
|
123765
|
+
|
|
123766
|
+
//! Serializes a blob into a DummyTableRef
|
|
123767
|
+
void Serialize(Serializer &serializer) override;
|
|
123768
|
+
//! Deserializes a blob back into a DummyTableRef
|
|
123769
|
+
static unique_ptr<TableRef> Deserialize(Deserializer &source);
|
|
123770
|
+
};
|
|
123771
|
+
} // namespace duckdb
|
|
123772
|
+
|
|
123773
|
+
|
|
123774
|
+
|
|
123775
|
+
|
|
123776
|
+
|
|
123777
|
+
|
|
123778
|
+
|
|
123544
123779
|
namespace duckdb {
|
|
123545
123780
|
|
|
123546
123781
|
void ParsedExpressionIterator::EnumerateChildren(const ParsedExpression &expression,
|
|
@@ -123676,6 +123911,91 @@ void ParsedExpressionIterator::EnumerateChildren(
|
|
|
123676
123911
|
}
|
|
123677
123912
|
}
|
|
123678
123913
|
|
|
123914
|
+
void ParsedExpressionIterator::EnumerateTableRefChildren(
|
|
123915
|
+
TableRef &ref, const std::function<void(unique_ptr<ParsedExpression> &child)> &callback) {
|
|
123916
|
+
switch (ref.type) {
|
|
123917
|
+
case TableReferenceType::CROSS_PRODUCT: {
|
|
123918
|
+
auto &cp_ref = (CrossProductRef &)ref;
|
|
123919
|
+
EnumerateTableRefChildren(*cp_ref.left, callback);
|
|
123920
|
+
EnumerateTableRefChildren(*cp_ref.right, callback);
|
|
123921
|
+
break;
|
|
123922
|
+
}
|
|
123923
|
+
case TableReferenceType::EXPRESSION_LIST: {
|
|
123924
|
+
auto &el_ref = (ExpressionListRef &)ref;
|
|
123925
|
+
for (idx_t i = 0; i < el_ref.values.size(); i++) {
|
|
123926
|
+
for (idx_t j = 0; j < el_ref.values[i].size(); j++) {
|
|
123927
|
+
callback(el_ref.values[i][j]);
|
|
123928
|
+
}
|
|
123929
|
+
}
|
|
123930
|
+
break;
|
|
123931
|
+
}
|
|
123932
|
+
case TableReferenceType::JOIN: {
|
|
123933
|
+
auto &j_ref = (JoinRef &)ref;
|
|
123934
|
+
EnumerateTableRefChildren(*j_ref.left, callback);
|
|
123935
|
+
EnumerateTableRefChildren(*j_ref.right, callback);
|
|
123936
|
+
callback(j_ref.condition);
|
|
123937
|
+
break;
|
|
123938
|
+
}
|
|
123939
|
+
case TableReferenceType::SUBQUERY: {
|
|
123940
|
+
auto &sq_ref = (SubqueryRef &)ref;
|
|
123941
|
+
EnumerateQueryNodeChildren(*sq_ref.subquery->node, callback);
|
|
123942
|
+
break;
|
|
123943
|
+
}
|
|
123944
|
+
case TableReferenceType::TABLE_FUNCTION: {
|
|
123945
|
+
auto &tf_ref = (TableFunctionRef &)ref;
|
|
123946
|
+
callback(tf_ref.function);
|
|
123947
|
+
break;
|
|
123948
|
+
}
|
|
123949
|
+
case TableReferenceType::BASE_TABLE:
|
|
123950
|
+
case TableReferenceType::EMPTY:
|
|
123951
|
+
// these TableRefs do not need to be unfolded
|
|
123952
|
+
break;
|
|
123953
|
+
default:
|
|
123954
|
+
throw NotImplementedException("TableRef type not implemented for traversal");
|
|
123955
|
+
}
|
|
123956
|
+
}
|
|
123957
|
+
|
|
123958
|
+
void ParsedExpressionIterator::EnumerateQueryNodeChildren(
|
|
123959
|
+
QueryNode &node, const std::function<void(unique_ptr<ParsedExpression> &child)> &callback) {
|
|
123960
|
+
switch (node.type) {
|
|
123961
|
+
case QueryNodeType::RECURSIVE_CTE_NODE: {
|
|
123962
|
+
auto &rcte_node = (RecursiveCTENode &)node;
|
|
123963
|
+
EnumerateQueryNodeChildren(*rcte_node.left, callback);
|
|
123964
|
+
EnumerateQueryNodeChildren(*rcte_node.right, callback);
|
|
123965
|
+
break;
|
|
123966
|
+
}
|
|
123967
|
+
case QueryNodeType::SELECT_NODE: {
|
|
123968
|
+
auto &sel_node = (SelectNode &)node;
|
|
123969
|
+
for (idx_t i = 0; i < sel_node.select_list.size(); i++) {
|
|
123970
|
+
callback(sel_node.select_list[i]);
|
|
123971
|
+
}
|
|
123972
|
+
for (idx_t i = 0; i < sel_node.groups.group_expressions.size(); i++) {
|
|
123973
|
+
callback(sel_node.groups.group_expressions[i]);
|
|
123974
|
+
}
|
|
123975
|
+
if (sel_node.where_clause) {
|
|
123976
|
+
callback(sel_node.where_clause);
|
|
123977
|
+
}
|
|
123978
|
+
if (sel_node.having) {
|
|
123979
|
+
callback(sel_node.having);
|
|
123980
|
+
}
|
|
123981
|
+
|
|
123982
|
+
EnumerateTableRefChildren(*sel_node.from_table.get(), callback);
|
|
123983
|
+
break;
|
|
123984
|
+
}
|
|
123985
|
+
case QueryNodeType::SET_OPERATION_NODE: {
|
|
123986
|
+
auto &setop_node = (SetOperationNode &)node;
|
|
123987
|
+
EnumerateQueryNodeChildren(*setop_node.left, callback);
|
|
123988
|
+
EnumerateQueryNodeChildren(*setop_node.right, callback);
|
|
123989
|
+
break;
|
|
123990
|
+
}
|
|
123991
|
+
default:
|
|
123992
|
+
throw NotImplementedException("QueryNode type not implemented for traversal");
|
|
123993
|
+
}
|
|
123994
|
+
for (auto &kv : node.cte_map) {
|
|
123995
|
+
EnumerateQueryNodeChildren(*kv.second->query->node, callback);
|
|
123996
|
+
}
|
|
123997
|
+
}
|
|
123998
|
+
|
|
123679
123999
|
} // namespace duckdb
|
|
123680
124000
|
|
|
123681
124001
|
|
|
@@ -129322,52 +129642,6 @@ string QueryErrorContext::FormatErrorRecursive(const string &msg, vector<Excepti
|
|
|
129322
129642
|
return Format(statement->query, error_message, query_location);
|
|
129323
129643
|
}
|
|
129324
129644
|
|
|
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
129645
|
} // namespace duckdb
|
|
129372
129646
|
|
|
129373
129647
|
|
|
@@ -130456,41 +130730,6 @@ unique_ptr<TableRef> BaseTableRef::Copy() {
|
|
|
130456
130730
|
return move(copy);
|
|
130457
130731
|
}
|
|
130458
130732
|
} // 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
130733
|
|
|
130495
130734
|
|
|
130496
130735
|
|
|
@@ -130534,36 +130773,6 @@ unique_ptr<TableRef> CrossProductRef::Deserialize(Deserializer &source) {
|
|
|
130534
130773
|
}
|
|
130535
130774
|
|
|
130536
130775
|
} // 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
130776
|
|
|
130568
130777
|
|
|
130569
130778
|
|
|
@@ -130833,13 +131042,6 @@ unique_ptr<TableRef> TableFunctionRef::Copy() {
|
|
|
130833
131042
|
|
|
130834
131043
|
|
|
130835
131044
|
|
|
130836
|
-
|
|
130837
|
-
|
|
130838
|
-
|
|
130839
|
-
|
|
130840
|
-
|
|
130841
|
-
|
|
130842
|
-
|
|
130843
131045
|
namespace duckdb {
|
|
130844
131046
|
|
|
130845
131047
|
string TableRef::ToString() const {
|
|
@@ -131220,28 +131422,13 @@ unique_ptr<ParsedExpression> Transformer::TransformColumnRef(duckdb_libpgquery::
|
|
|
131220
131422
|
if (fields->length < 1) {
|
|
131221
131423
|
throw InternalException("Unexpected field length");
|
|
131222
131424
|
}
|
|
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!");
|
|
131425
|
+
vector<string> column_names;
|
|
131426
|
+
for (auto node = fields->head; node; node = node->next) {
|
|
131427
|
+
column_names.emplace_back(reinterpret_cast<duckdb_libpgquery::PGValue *>(node->data.ptr_value)->val.str);
|
|
131244
131428
|
}
|
|
131429
|
+
auto colref = make_unique<ColumnRefExpression>(move(column_names));
|
|
131430
|
+
colref->query_location = root->location;
|
|
131431
|
+
return move(colref);
|
|
131245
131432
|
}
|
|
131246
131433
|
case duckdb_libpgquery::T_PGAStar: {
|
|
131247
131434
|
return TransformStarExpression(head_node);
|
|
@@ -131912,10 +132099,10 @@ static string ExtractColumnFromLambda(ParsedExpression &expr) {
|
|
|
131912
132099
|
throw ParserException("Lambda parameter must be a column name");
|
|
131913
132100
|
}
|
|
131914
132101
|
auto &colref = (ColumnRefExpression &)expr;
|
|
131915
|
-
if (
|
|
132102
|
+
if (colref.IsQualified()) {
|
|
131916
132103
|
throw ParserException("Lambda parameter must be an unqualified name (e.g. 'x', not 'a.x')");
|
|
131917
132104
|
}
|
|
131918
|
-
return colref.
|
|
132105
|
+
return colref.column_names[0];
|
|
131919
132106
|
}
|
|
131920
132107
|
|
|
131921
132108
|
unique_ptr<ParsedExpression> Transformer::TransformLambda(duckdb_libpgquery::PGLambdaFunction *node) {
|
|
@@ -135570,6 +135757,34 @@ unordered_set<string> BindContext::GetMatchingBindings(const string &column_name
|
|
|
135570
135757
|
return result;
|
|
135571
135758
|
}
|
|
135572
135759
|
|
|
135760
|
+
unique_ptr<ParsedExpression> BindContext::CreateColumnReference(const string &table_name, const string &column_name) {
|
|
135761
|
+
string schema_name;
|
|
135762
|
+
return CreateColumnReference(schema_name, table_name, column_name);
|
|
135763
|
+
}
|
|
135764
|
+
|
|
135765
|
+
unique_ptr<ParsedExpression> BindContext::CreateColumnReference(const string &schema_name, const string &table_name,
|
|
135766
|
+
const string &column_name) {
|
|
135767
|
+
string error_message;
|
|
135768
|
+
vector<string> names;
|
|
135769
|
+
if (!schema_name.empty()) {
|
|
135770
|
+
names.push_back(schema_name);
|
|
135771
|
+
}
|
|
135772
|
+
names.push_back(table_name);
|
|
135773
|
+
names.push_back(column_name);
|
|
135774
|
+
|
|
135775
|
+
auto result = make_unique<ColumnRefExpression>(move(names));
|
|
135776
|
+
// because of case insensitivity in the binder we rename the column to the original name
|
|
135777
|
+
// as it appears in the binding itself
|
|
135778
|
+
auto binding = GetBinding(table_name, error_message);
|
|
135779
|
+
if (binding) {
|
|
135780
|
+
auto column_index = binding->GetBindingIndex(column_name);
|
|
135781
|
+
if (column_index < binding->names.size() && binding->names[column_index] != column_name) {
|
|
135782
|
+
result->alias = binding->names[column_index];
|
|
135783
|
+
}
|
|
135784
|
+
}
|
|
135785
|
+
return move(result);
|
|
135786
|
+
}
|
|
135787
|
+
|
|
135573
135788
|
Binding *BindContext::GetCTEBinding(const string &ctename) {
|
|
135574
135789
|
auto match = cte_bindings.find(ctename);
|
|
135575
135790
|
if (match == cte_bindings.end()) {
|
|
@@ -135595,12 +135810,12 @@ Binding *BindContext::GetBinding(const string &name, string &out_error) {
|
|
|
135595
135810
|
}
|
|
135596
135811
|
|
|
135597
135812
|
BindResult BindContext::BindColumn(ColumnRefExpression &colref, idx_t depth) {
|
|
135598
|
-
if (colref.
|
|
135599
|
-
|
|
135813
|
+
if (!colref.IsQualified()) {
|
|
135814
|
+
throw InternalException("Could not bind alias \"%s\"!", colref.GetColumnName());
|
|
135600
135815
|
}
|
|
135601
135816
|
|
|
135602
135817
|
string error;
|
|
135603
|
-
auto binding = GetBinding(colref.
|
|
135818
|
+
auto binding = GetBinding(colref.GetTableName(), error);
|
|
135604
135819
|
if (!binding) {
|
|
135605
135820
|
return BindResult(error);
|
|
135606
135821
|
}
|
|
@@ -136392,57 +136607,237 @@ BindResult ExpressionBinder::BindExpression(CollateExpression &expr, idx_t depth
|
|
|
136392
136607
|
|
|
136393
136608
|
|
|
136394
136609
|
|
|
136610
|
+
|
|
136611
|
+
|
|
136612
|
+
//===----------------------------------------------------------------------===//
|
|
136613
|
+
// DuckDB
|
|
136614
|
+
//
|
|
136615
|
+
// duckdb/planner/expression_binder/where_binder.hpp
|
|
136616
|
+
//
|
|
136617
|
+
//
|
|
136618
|
+
//===----------------------------------------------------------------------===//
|
|
136619
|
+
|
|
136620
|
+
|
|
136621
|
+
|
|
136622
|
+
|
|
136623
|
+
|
|
136395
136624
|
namespace duckdb {
|
|
136396
136625
|
|
|
136397
|
-
|
|
136398
|
-
|
|
136399
|
-
|
|
136400
|
-
|
|
136401
|
-
|
|
136402
|
-
|
|
136403
|
-
|
|
136404
|
-
|
|
136405
|
-
|
|
136406
|
-
|
|
136407
|
-
|
|
136408
|
-
|
|
136409
|
-
|
|
136410
|
-
|
|
136411
|
-
|
|
136412
|
-
|
|
136413
|
-
|
|
136414
|
-
|
|
136415
|
-
|
|
136416
|
-
|
|
136417
|
-
|
|
136626
|
+
class ColumnAliasBinder;
|
|
136627
|
+
|
|
136628
|
+
//! The WHERE binder is responsible for binding an expression within the WHERE clause of a SQL statement
|
|
136629
|
+
class WhereBinder : public ExpressionBinder {
|
|
136630
|
+
public:
|
|
136631
|
+
WhereBinder(Binder &binder, ClientContext &context, ColumnAliasBinder *column_alias_binder = nullptr);
|
|
136632
|
+
|
|
136633
|
+
protected:
|
|
136634
|
+
BindResult BindExpression(unique_ptr<ParsedExpression> *expr_ptr, idx_t depth,
|
|
136635
|
+
bool root_expression = false) override;
|
|
136636
|
+
|
|
136637
|
+
string UnsupportedAggregateMessage() override;
|
|
136638
|
+
|
|
136639
|
+
private:
|
|
136640
|
+
BindResult BindColumnRef(unique_ptr<ParsedExpression> *expr_ptr, idx_t depth, bool root_expression);
|
|
136641
|
+
|
|
136642
|
+
ColumnAliasBinder *column_alias_binder;
|
|
136643
|
+
};
|
|
136644
|
+
|
|
136645
|
+
} // namespace duckdb
|
|
136646
|
+
|
|
136647
|
+
|
|
136648
|
+
|
|
136649
|
+
|
|
136650
|
+
|
|
136651
|
+
|
|
136652
|
+
namespace duckdb {
|
|
136653
|
+
|
|
136654
|
+
unique_ptr<ParsedExpression> ExpressionBinder::QualifyColumnName(const string &column_name, string &error_message) {
|
|
136655
|
+
auto using_binding = binder.bind_context.GetUsingBinding(column_name);
|
|
136656
|
+
if (using_binding) {
|
|
136657
|
+
// we are referencing a USING column
|
|
136658
|
+
// check if we can refer to one of the base columns directly
|
|
136659
|
+
unique_ptr<Expression> expression;
|
|
136660
|
+
if (!using_binding->primary_binding.empty()) {
|
|
136661
|
+
// we can! just assign the table name and re-bind
|
|
136662
|
+
return make_unique<ColumnRefExpression>(column_name, using_binding->primary_binding);
|
|
136663
|
+
} else {
|
|
136664
|
+
// // we cannot! we need to bind this as a coalesce between all the relevant columns
|
|
136665
|
+
auto coalesce = make_unique<OperatorExpression>(ExpressionType::OPERATOR_COALESCE);
|
|
136666
|
+
for (auto &entry : using_binding->bindings) {
|
|
136667
|
+
coalesce->children.push_back(make_unique<ColumnRefExpression>(column_name, entry));
|
|
136418
136668
|
}
|
|
136669
|
+
return move(coalesce);
|
|
136419
136670
|
}
|
|
136420
|
-
|
|
136421
|
-
|
|
136422
|
-
|
|
136423
|
-
|
|
136671
|
+
}
|
|
136672
|
+
// no table name: find a binding that contains this
|
|
136673
|
+
if (binder.macro_binding != nullptr && binder.macro_binding->HasMatchingBinding(column_name)) {
|
|
136674
|
+
// priority to macro parameter bindings TODO: throw a warning when this name conflicts
|
|
136675
|
+
D_ASSERT(!binder.macro_binding->alias.empty());
|
|
136676
|
+
return make_unique<ColumnRefExpression>(column_name, binder.macro_binding->alias);
|
|
136677
|
+
} else {
|
|
136678
|
+
string table_name = binder.bind_context.GetMatchingBinding(column_name);
|
|
136679
|
+
if (table_name.empty()) {
|
|
136680
|
+
auto similar_bindings = binder.bind_context.GetSimilarBindings(column_name);
|
|
136681
|
+
string candidate_str = StringUtil::CandidatesMessage(similar_bindings, "Candidate bindings");
|
|
136682
|
+
error_message =
|
|
136683
|
+
StringUtil::Format("Referenced column \"%s\" not found in FROM clause!%s", column_name, candidate_str);
|
|
136684
|
+
return nullptr;
|
|
136685
|
+
}
|
|
136686
|
+
return binder.bind_context.CreateColumnReference(table_name, column_name);
|
|
136687
|
+
}
|
|
136688
|
+
}
|
|
136689
|
+
|
|
136690
|
+
void ExpressionBinder::QualifyColumnNames(unique_ptr<ParsedExpression> &expr) {
|
|
136691
|
+
switch (expr->type) {
|
|
136692
|
+
case ExpressionType::COLUMN_REF: {
|
|
136693
|
+
auto &colref = (ColumnRefExpression &)*expr;
|
|
136694
|
+
string error_message;
|
|
136695
|
+
auto new_expr = QualifyColumnName(colref, error_message);
|
|
136696
|
+
if (new_expr) {
|
|
136697
|
+
if (!expr->alias.empty()) {
|
|
136698
|
+
new_expr->alias = expr->alias;
|
|
136699
|
+
}
|
|
136700
|
+
expr = move(new_expr);
|
|
136701
|
+
}
|
|
136702
|
+
break;
|
|
136703
|
+
}
|
|
136704
|
+
case ExpressionType::POSITIONAL_REFERENCE: {
|
|
136705
|
+
auto &ref = (PositionalReferenceExpression &)*expr;
|
|
136706
|
+
if (ref.alias.empty()) {
|
|
136707
|
+
string table_name, column_name;
|
|
136708
|
+
auto error = binder.bind_context.BindColumn(ref, table_name, column_name);
|
|
136709
|
+
if (error.empty()) {
|
|
136710
|
+
ref.alias = column_name;
|
|
136711
|
+
}
|
|
136712
|
+
}
|
|
136713
|
+
break;
|
|
136714
|
+
}
|
|
136715
|
+
default:
|
|
136716
|
+
break;
|
|
136717
|
+
}
|
|
136718
|
+
ParsedExpressionIterator::EnumerateChildren(
|
|
136719
|
+
*expr, [&](unique_ptr<ParsedExpression> &child) { QualifyColumnNames(child); });
|
|
136720
|
+
}
|
|
136721
|
+
|
|
136722
|
+
void ExpressionBinder::QualifyColumnNames(Binder &binder, unique_ptr<ParsedExpression> &expr) {
|
|
136723
|
+
WhereBinder where_binder(binder, binder.context);
|
|
136724
|
+
where_binder.QualifyColumnNames(expr);
|
|
136725
|
+
}
|
|
136726
|
+
|
|
136727
|
+
unique_ptr<ParsedExpression> ExpressionBinder::CreateStructExtract(unique_ptr<ParsedExpression> base,
|
|
136728
|
+
string field_name) {
|
|
136729
|
+
vector<unique_ptr<ParsedExpression>> children;
|
|
136730
|
+
children.push_back(move(base));
|
|
136731
|
+
children.push_back(make_unique_base<ParsedExpression, ConstantExpression>(Value(move(field_name))));
|
|
136732
|
+
auto extract_fun = make_unique<FunctionExpression>("struct_extract", move(children));
|
|
136733
|
+
return move(extract_fun);
|
|
136734
|
+
}
|
|
136735
|
+
|
|
136736
|
+
unique_ptr<ParsedExpression> ExpressionBinder::QualifyColumnName(ColumnRefExpression &colref, string &error_message) {
|
|
136737
|
+
idx_t column_parts = colref.column_names.size();
|
|
136738
|
+
// column names can have an arbitrary amount of dots
|
|
136739
|
+
// here is how the resolution works:
|
|
136740
|
+
if (column_parts == 1) {
|
|
136741
|
+
// no dots (i.e. "part1")
|
|
136742
|
+
// -> part1 refers to a column
|
|
136743
|
+
// check if we can qualify the column name with the table name
|
|
136744
|
+
return QualifyColumnName(colref.GetColumnName(), error_message);
|
|
136745
|
+
} else if (column_parts == 2) {
|
|
136746
|
+
// one dot (i.e. "part1.part2")
|
|
136747
|
+
// EITHER:
|
|
136748
|
+
// -> part1 is a table, part2 is a column
|
|
136749
|
+
// -> part1 is a column, part2 is a property of that column (i.e. struct_extract)
|
|
136750
|
+
|
|
136751
|
+
// first check if part1 is a table
|
|
136752
|
+
if (binder.HasMatchingBinding(colref.column_names[0], colref.column_names[1], error_message)) {
|
|
136753
|
+
// it is! return the colref directly
|
|
136754
|
+
return binder.bind_context.CreateColumnReference(colref.column_names[0], colref.column_names[1]);
|
|
136424
136755
|
} else {
|
|
136425
|
-
|
|
136756
|
+
// otherwise check if we can turn this into a struct extract
|
|
136757
|
+
auto new_colref = make_unique<ColumnRefExpression>(colref.column_names[0]);
|
|
136758
|
+
string other_error;
|
|
136759
|
+
auto qualified_colref = QualifyColumnName(colref.column_names[0], other_error);
|
|
136760
|
+
if (!qualified_colref) {
|
|
136761
|
+
// we could not! bail
|
|
136762
|
+
return nullptr;
|
|
136763
|
+
}
|
|
136764
|
+
// we could: create a struct extract
|
|
136765
|
+
return CreateStructExtract(move(qualified_colref), colref.column_names[1]);
|
|
136426
136766
|
}
|
|
136427
|
-
|
|
136428
|
-
|
|
136429
|
-
|
|
136430
|
-
|
|
136431
|
-
|
|
136432
|
-
|
|
136767
|
+
} else {
|
|
136768
|
+
// two or more dots (i.e. "part1.part2.part3.part4...")
|
|
136769
|
+
// -> part1 is a schema, part2 is a table, part3 is a column name, part4 and beyond are struct fields
|
|
136770
|
+
// -> part1 is a table, part2 is a column name, part3 and beyond are struct fields
|
|
136771
|
+
// -> part1 is a column, part2 and beyond are struct fields
|
|
136772
|
+
|
|
136773
|
+
// we always prefer the most top-level view
|
|
136774
|
+
// i.e. in case of multiple resolution options, we resolve in order:
|
|
136775
|
+
// -> 1. resolve "part1" as a schema
|
|
136776
|
+
// -> 2. resolve "part1" as a table
|
|
136777
|
+
// -> 3. resolve "part1" as a column
|
|
136778
|
+
|
|
136779
|
+
unique_ptr<ParsedExpression> result_expr;
|
|
136780
|
+
idx_t struct_extract_start;
|
|
136781
|
+
// first check if part1 is a schema
|
|
136782
|
+
if (binder.HasMatchingBinding(colref.column_names[0], colref.column_names[1], colref.column_names[2],
|
|
136783
|
+
error_message)) {
|
|
136784
|
+
// it is! the column reference is "schema.table.column"
|
|
136785
|
+
// any additional fields are turned into struct_extract calls
|
|
136786
|
+
result_expr = binder.bind_context.CreateColumnReference(colref.column_names[0], colref.column_names[1],
|
|
136787
|
+
colref.column_names[2]);
|
|
136788
|
+
struct_extract_start = 3;
|
|
136789
|
+
} else if (binder.HasMatchingBinding(colref.column_names[0], colref.column_names[1], error_message)) {
|
|
136790
|
+
// part1 is a table
|
|
136791
|
+
// the column reference is "table.column"
|
|
136792
|
+
// any additional fields are turned into struct_extract calls
|
|
136793
|
+
result_expr = binder.bind_context.CreateColumnReference(colref.column_names[0], colref.column_names[1]);
|
|
136794
|
+
struct_extract_start = 2;
|
|
136795
|
+
} else {
|
|
136796
|
+
// part1 could be a column
|
|
136797
|
+
string col_error;
|
|
136798
|
+
result_expr = QualifyColumnName(colref.column_names[0], col_error);
|
|
136799
|
+
if (!result_expr) {
|
|
136800
|
+
// it is not! return the error
|
|
136801
|
+
return nullptr;
|
|
136802
|
+
}
|
|
136803
|
+
// it is! add the struct extract calls
|
|
136804
|
+
struct_extract_start = 1;
|
|
136805
|
+
}
|
|
136806
|
+
for (idx_t i = struct_extract_start; i < colref.column_names.size(); i++) {
|
|
136807
|
+
result_expr = CreateStructExtract(move(result_expr), colref.column_names[i]);
|
|
136433
136808
|
}
|
|
136809
|
+
return result_expr;
|
|
136810
|
+
}
|
|
136811
|
+
}
|
|
136812
|
+
|
|
136813
|
+
BindResult ExpressionBinder::BindExpression(ColumnRefExpression &colref_p, idx_t depth) {
|
|
136814
|
+
string error_message;
|
|
136815
|
+
auto expr = QualifyColumnName(colref_p, error_message);
|
|
136816
|
+
if (!expr) {
|
|
136817
|
+
return BindResult(binder.FormatError(colref_p, error_message));
|
|
136818
|
+
}
|
|
136819
|
+
if (expr->type != ExpressionType::COLUMN_REF) {
|
|
136820
|
+
return BindExpression(&expr, depth);
|
|
136434
136821
|
}
|
|
136822
|
+
auto &colref = (ColumnRefExpression &)*expr;
|
|
136823
|
+
D_ASSERT(colref.column_names.size() == 2 || colref.column_names.size() == 3);
|
|
136824
|
+
auto &table_name = colref.column_names.size() == 3 ? colref.column_names[1] : colref.column_names[0];
|
|
136825
|
+
// individual column reference
|
|
136826
|
+
// resolve to either a base table or a subquery expression
|
|
136435
136827
|
// if it was a macro parameter, let macro_binding bind it to the argument
|
|
136436
|
-
BindResult result
|
|
136437
|
-
|
|
136438
|
-
|
|
136828
|
+
BindResult result;
|
|
136829
|
+
if (binder.macro_binding && table_name == binder.macro_binding->alias) {
|
|
136830
|
+
result = binder.macro_binding->Bind(colref, depth);
|
|
136831
|
+
} else {
|
|
136832
|
+
result = binder.bind_context.BindColumn(colref, depth);
|
|
136833
|
+
}
|
|
136439
136834
|
if (!result.HasError()) {
|
|
136440
136835
|
BoundColumnReferenceInfo ref;
|
|
136441
|
-
ref.name = colref.
|
|
136836
|
+
ref.name = colref.column_names.back();
|
|
136442
136837
|
ref.query_location = colref.query_location;
|
|
136443
136838
|
bound_columns.push_back(move(ref));
|
|
136444
136839
|
} else {
|
|
136445
|
-
result.error = binder.FormatError(
|
|
136840
|
+
result.error = binder.FormatError(colref_p, result.error);
|
|
136446
136841
|
}
|
|
136447
136842
|
return result;
|
|
136448
136843
|
}
|
|
@@ -136740,11 +137135,6 @@ BindResult ExpressionBinder::BindExpression(LambdaExpression &expr, idx_t depth)
|
|
|
136740
137135
|
|
|
136741
137136
|
|
|
136742
137137
|
|
|
136743
|
-
|
|
136744
|
-
|
|
136745
|
-
|
|
136746
|
-
|
|
136747
|
-
|
|
136748
137138
|
namespace duckdb {
|
|
136749
137139
|
|
|
136750
137140
|
void ExpressionBinder::ReplaceMacroParametersRecursive(unique_ptr<ParsedExpression> &expr) {
|
|
@@ -136752,7 +137142,14 @@ void ExpressionBinder::ReplaceMacroParametersRecursive(unique_ptr<ParsedExpressi
|
|
|
136752
137142
|
case ExpressionClass::COLUMN_REF: {
|
|
136753
137143
|
// if expr is a parameter, replace it with its argument
|
|
136754
137144
|
auto &colref = (ColumnRefExpression &)*expr;
|
|
136755
|
-
|
|
137145
|
+
bool bind_macro_parameter = false;
|
|
137146
|
+
if (colref.IsQualified()) {
|
|
137147
|
+
bind_macro_parameter = colref.GetTableName() == MacroBinding::MACRO_NAME;
|
|
137148
|
+
} else {
|
|
137149
|
+
bind_macro_parameter = macro_binding->HasMatchingBinding(colref.GetColumnName());
|
|
137150
|
+
}
|
|
137151
|
+
if (bind_macro_parameter) {
|
|
137152
|
+
D_ASSERT(macro_binding->HasMatchingBinding(colref.GetColumnName()));
|
|
136756
137153
|
expr = macro_binding->ParamToArg(colref);
|
|
136757
137154
|
}
|
|
136758
137155
|
return;
|
|
@@ -136760,7 +137157,8 @@ void ExpressionBinder::ReplaceMacroParametersRecursive(unique_ptr<ParsedExpressi
|
|
|
136760
137157
|
case ExpressionClass::SUBQUERY: {
|
|
136761
137158
|
// replacing parameters within a subquery is slightly different
|
|
136762
137159
|
auto &sq = ((SubqueryExpression &)*expr).subquery;
|
|
136763
|
-
|
|
137160
|
+
ParsedExpressionIterator::EnumerateQueryNodeChildren(
|
|
137161
|
+
*sq->node, [&](unique_ptr<ParsedExpression> &child) { ReplaceMacroParametersRecursive(child); });
|
|
136764
137162
|
break;
|
|
136765
137163
|
}
|
|
136766
137164
|
default: // fall through
|
|
@@ -136771,89 +137169,6 @@ void ExpressionBinder::ReplaceMacroParametersRecursive(unique_ptr<ParsedExpressi
|
|
|
136771
137169
|
*expr, [&](unique_ptr<ParsedExpression> &child) { ReplaceMacroParametersRecursive(child); });
|
|
136772
137170
|
}
|
|
136773
137171
|
|
|
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
137172
|
BindResult ExpressionBinder::BindMacro(FunctionExpression &function, MacroCatalogEntry *macro_func, idx_t depth,
|
|
136858
137173
|
unique_ptr<ParsedExpression> *expr) {
|
|
136859
137174
|
auto ¯o_def = *macro_func->function;
|
|
@@ -136872,7 +137187,7 @@ BindResult ExpressionBinder::BindMacro(FunctionExpression &function, MacroCatalo
|
|
|
136872
137187
|
for (idx_t i = 0; i < macro_def.parameters.size(); i++) {
|
|
136873
137188
|
types.push_back(LogicalType::SQLNULL);
|
|
136874
137189
|
auto ¶m = (ColumnRefExpression &)*macro_def.parameters[i];
|
|
136875
|
-
names.push_back(param.
|
|
137190
|
+
names.push_back(param.GetColumnName());
|
|
136876
137191
|
}
|
|
136877
137192
|
// default parameters
|
|
136878
137193
|
for (auto it = macro_def.default_parameters.begin(); it != macro_def.default_parameters.end(); it++) {
|
|
@@ -137796,40 +138111,6 @@ private:
|
|
|
137796
138111
|
} // namespace duckdb
|
|
137797
138112
|
|
|
137798
138113
|
|
|
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
138114
|
|
|
137834
138115
|
|
|
137835
138116
|
|
|
@@ -138020,7 +138301,7 @@ unique_ptr<BoundQueryNode> Binder::BindNode(SelectNode &statement) {
|
|
|
138020
138301
|
for (idx_t i = 0; i < statement.select_list.size(); i++) {
|
|
138021
138302
|
auto &expr = statement.select_list[i];
|
|
138022
138303
|
result->names.push_back(expr->GetName());
|
|
138023
|
-
ExpressionBinder::
|
|
138304
|
+
ExpressionBinder::QualifyColumnNames(*this, expr);
|
|
138024
138305
|
if (!expr->alias.empty()) {
|
|
138025
138306
|
alias_map[expr->alias] = i;
|
|
138026
138307
|
result->names[i] = expr->alias;
|
|
@@ -138074,7 +138355,7 @@ unique_ptr<BoundQueryNode> Binder::BindNode(SelectNode &statement) {
|
|
|
138074
138355
|
// if we wouldn't do this then (SELECT test.a FROM test GROUP BY a) would not work because "test.a" <> "a"
|
|
138075
138356
|
// hence we convert "a" -> "test.a" in the unbound expression
|
|
138076
138357
|
unbound_groups[i] = move(group_binder.unbound_expression);
|
|
138077
|
-
ExpressionBinder::
|
|
138358
|
+
ExpressionBinder::QualifyColumnNames(*this, unbound_groups[i]);
|
|
138078
138359
|
info.map[unbound_groups[i].get()] = i;
|
|
138079
138360
|
}
|
|
138080
138361
|
}
|
|
@@ -138083,7 +138364,7 @@ unique_ptr<BoundQueryNode> Binder::BindNode(SelectNode &statement) {
|
|
|
138083
138364
|
// bind the HAVING clause, if any
|
|
138084
138365
|
if (statement.having) {
|
|
138085
138366
|
HavingBinder having_binder(*this, context, *result, info, alias_map);
|
|
138086
|
-
ExpressionBinder::
|
|
138367
|
+
ExpressionBinder::QualifyColumnNames(*this, statement.having);
|
|
138087
138368
|
result->having = having_binder.Bind(statement.having);
|
|
138088
138369
|
}
|
|
138089
138370
|
|
|
@@ -139372,11 +139653,11 @@ SchemaCatalogEntry *Binder::BindCreateFunctionInfo(CreateInfo &info) {
|
|
|
139372
139653
|
// positional parameters
|
|
139373
139654
|
for (idx_t i = 0; i < base.function->parameters.size(); i++) {
|
|
139374
139655
|
auto param = (ColumnRefExpression &)*base.function->parameters[i];
|
|
139375
|
-
if (
|
|
139376
|
-
throw BinderException("Invalid parameter name '%s'", param.ToString());
|
|
139656
|
+
if (param.IsQualified()) {
|
|
139657
|
+
throw BinderException("Invalid parameter name '%s': must be unqualified", param.ToString());
|
|
139377
139658
|
}
|
|
139378
139659
|
dummy_types.push_back(LogicalType::SQLNULL);
|
|
139379
|
-
dummy_names.push_back(param.
|
|
139660
|
+
dummy_names.push_back(param.GetColumnName());
|
|
139380
139661
|
}
|
|
139381
139662
|
// default parameters
|
|
139382
139663
|
for (auto it = base.function->default_parameters.begin(); it != base.function->default_parameters.end(); it++) {
|
|
@@ -139386,6 +139667,7 @@ SchemaCatalogEntry *Binder::BindCreateFunctionInfo(CreateInfo &info) {
|
|
|
139386
139667
|
}
|
|
139387
139668
|
auto this_macro_binding = make_unique<MacroBinding>(dummy_types, dummy_names, base.name);
|
|
139388
139669
|
macro_binding = this_macro_binding.get();
|
|
139670
|
+
ExpressionBinder::QualifyColumnNames(*this, base.function->expression);
|
|
139389
139671
|
|
|
139390
139672
|
// create a copy of the expression because we do not want to alter the original
|
|
139391
139673
|
auto expression = base.function->expression->Copy();
|
|
@@ -141502,8 +141784,8 @@ bool Binder::BindFunctionParameters(vector<unique_ptr<ParsedExpression>> &expres
|
|
|
141502
141784
|
auto &comp = (ComparisonExpression &)*child;
|
|
141503
141785
|
if (comp.left->type == ExpressionType::COLUMN_REF) {
|
|
141504
141786
|
auto &colref = (ColumnRefExpression &)*comp.left;
|
|
141505
|
-
if (colref.
|
|
141506
|
-
parameter_name = colref.
|
|
141787
|
+
if (!colref.IsQualified()) {
|
|
141788
|
+
parameter_name = colref.GetColumnName();
|
|
141507
141789
|
child = move(comp.right);
|
|
141508
141790
|
}
|
|
141509
141791
|
}
|
|
@@ -141974,6 +142256,8 @@ unique_ptr<LogicalOperator> Binder::CreatePlan(BoundTableFunction &ref) {
|
|
|
141974
142256
|
|
|
141975
142257
|
|
|
141976
142258
|
|
|
142259
|
+
|
|
142260
|
+
|
|
141977
142261
|
#include <algorithm>
|
|
141978
142262
|
|
|
141979
142263
|
namespace duckdb {
|
|
@@ -142253,6 +142537,38 @@ void Binder::AddCorrelatedColumn(const CorrelatedColumnInfo &info) {
|
|
|
142253
142537
|
}
|
|
142254
142538
|
}
|
|
142255
142539
|
|
|
142540
|
+
bool Binder::HasMatchingBinding(const string &table_name, const string &column_name, string &error_message) {
|
|
142541
|
+
string empty_schema;
|
|
142542
|
+
return HasMatchingBinding(empty_schema, table_name, column_name, error_message);
|
|
142543
|
+
}
|
|
142544
|
+
|
|
142545
|
+
bool Binder::HasMatchingBinding(const string &schema_name, const string &table_name, const string &column_name,
|
|
142546
|
+
string &error_message) {
|
|
142547
|
+
Binding *binding;
|
|
142548
|
+
if (macro_binding && table_name == macro_binding->alias) {
|
|
142549
|
+
binding = macro_binding;
|
|
142550
|
+
} else {
|
|
142551
|
+
binding = bind_context.GetBinding(table_name, error_message);
|
|
142552
|
+
}
|
|
142553
|
+
if (!binding) {
|
|
142554
|
+
return false;
|
|
142555
|
+
}
|
|
142556
|
+
if (!schema_name.empty()) {
|
|
142557
|
+
auto table_entry = binding->GetTableEntry();
|
|
142558
|
+
if (!table_entry) {
|
|
142559
|
+
return false;
|
|
142560
|
+
}
|
|
142561
|
+
if (table_entry->schema->name != schema_name || table_entry->name != table_name) {
|
|
142562
|
+
return false;
|
|
142563
|
+
}
|
|
142564
|
+
}
|
|
142565
|
+
if (!binding->HasMatchingBinding(column_name)) {
|
|
142566
|
+
error_message = binding->ColumnNotFoundError(column_name);
|
|
142567
|
+
return false;
|
|
142568
|
+
}
|
|
142569
|
+
return true;
|
|
142570
|
+
}
|
|
142571
|
+
|
|
142256
142572
|
string Binder::FormatError(ParsedExpression &expr_context, const string &message) {
|
|
142257
142573
|
return FormatError(expr_context.query_location, message);
|
|
142258
142574
|
}
|
|
@@ -143344,13 +143660,13 @@ string AlterBinder::UnsupportedAggregateMessage() {
|
|
|
143344
143660
|
}
|
|
143345
143661
|
|
|
143346
143662
|
BindResult AlterBinder::BindColumn(ColumnRefExpression &colref) {
|
|
143347
|
-
if (
|
|
143348
|
-
|
|
143349
|
-
table.name);
|
|
143663
|
+
if (colref.column_names.size() > 1) {
|
|
143664
|
+
return BindQualifiedColumnName(colref, table.name);
|
|
143350
143665
|
}
|
|
143351
|
-
auto idx = table.GetColumnIndex(colref.
|
|
143666
|
+
auto idx = table.GetColumnIndex(colref.column_names[0], true);
|
|
143352
143667
|
if (idx == INVALID_INDEX) {
|
|
143353
|
-
throw BinderException("Table does not contain column %s referenced in alter statement!",
|
|
143668
|
+
throw BinderException("Table does not contain column %s referenced in alter statement!",
|
|
143669
|
+
colref.column_names[0]);
|
|
143354
143670
|
}
|
|
143355
143671
|
bound_columns.push_back(idx);
|
|
143356
143672
|
return BindResult(make_unique<BoundReferenceExpression>(table.columns[idx].type, bound_columns.size() - 1));
|
|
@@ -143364,9 +143680,9 @@ BindResult AlterBinder::BindColumn(ColumnRefExpression &colref) {
|
|
|
143364
143680
|
|
|
143365
143681
|
namespace duckdb {
|
|
143366
143682
|
|
|
143367
|
-
CheckBinder::CheckBinder(Binder &binder, ClientContext &context, string
|
|
143683
|
+
CheckBinder::CheckBinder(Binder &binder, ClientContext &context, string table_p, vector<ColumnDefinition> &columns,
|
|
143368
143684
|
unordered_set<column_t> &bound_columns)
|
|
143369
|
-
: ExpressionBinder(binder, context), table(move(
|
|
143685
|
+
: ExpressionBinder(binder, context), table(move(table_p)), columns(columns), bound_columns(bound_columns) {
|
|
143370
143686
|
target_type = LogicalType::INTEGER;
|
|
143371
143687
|
}
|
|
143372
143688
|
|
|
@@ -143388,18 +143704,29 @@ string CheckBinder::UnsupportedAggregateMessage() {
|
|
|
143388
143704
|
return "aggregate functions are not allowed in check constraints";
|
|
143389
143705
|
}
|
|
143390
143706
|
|
|
143707
|
+
BindResult ExpressionBinder::BindQualifiedColumnName(ColumnRefExpression &colref, const string &table_name) {
|
|
143708
|
+
idx_t struct_start = 0;
|
|
143709
|
+
if (colref.column_names[0] == table_name) {
|
|
143710
|
+
struct_start++;
|
|
143711
|
+
}
|
|
143712
|
+
auto result = make_unique_base<ParsedExpression, ColumnRefExpression>(colref.column_names.back());
|
|
143713
|
+
for (idx_t i = struct_start; i + 1 < colref.column_names.size(); i++) {
|
|
143714
|
+
result = CreateStructExtract(move(result), colref.column_names[i]);
|
|
143715
|
+
}
|
|
143716
|
+
return BindExpression(&result, 0);
|
|
143717
|
+
}
|
|
143718
|
+
|
|
143391
143719
|
BindResult CheckBinder::BindCheckColumn(ColumnRefExpression &colref) {
|
|
143392
|
-
if (
|
|
143393
|
-
|
|
143394
|
-
table);
|
|
143720
|
+
if (colref.column_names.size() > 1) {
|
|
143721
|
+
return BindQualifiedColumnName(colref, table);
|
|
143395
143722
|
}
|
|
143396
143723
|
for (idx_t i = 0; i < columns.size(); i++) {
|
|
143397
|
-
if (colref.
|
|
143724
|
+
if (colref.column_names[0] == columns[i].name) {
|
|
143398
143725
|
bound_columns.insert(i);
|
|
143399
143726
|
return BindResult(make_unique<BoundReferenceExpression>(columns[i].type, i));
|
|
143400
143727
|
}
|
|
143401
143728
|
}
|
|
143402
|
-
throw BinderException("Table does not contain column %s referenced in check constraint!", colref.
|
|
143729
|
+
throw BinderException("Table does not contain column %s referenced in check constraint!", colref.column_names[0]);
|
|
143403
143730
|
}
|
|
143404
143731
|
|
|
143405
143732
|
} // namespace duckdb
|
|
@@ -143417,11 +143744,11 @@ ColumnAliasBinder::ColumnAliasBinder(BoundSelectNode &node, const unordered_map<
|
|
|
143417
143744
|
|
|
143418
143745
|
BindResult ColumnAliasBinder::BindAlias(ExpressionBinder &enclosing_binder, ColumnRefExpression &expr, idx_t depth,
|
|
143419
143746
|
bool root_expression) {
|
|
143420
|
-
if (
|
|
143747
|
+
if (expr.IsQualified()) {
|
|
143421
143748
|
return BindResult(StringUtil::Format("Alias %s cannot be qualified.", expr.ToString()));
|
|
143422
143749
|
}
|
|
143423
143750
|
|
|
143424
|
-
auto alias_entry = alias_map.find(expr.
|
|
143751
|
+
auto alias_entry = alias_map.find(expr.column_names[0]);
|
|
143425
143752
|
if (alias_entry == alias_map.end()) {
|
|
143426
143753
|
return BindResult(StringUtil::Format("Alias %s is not found.", expr.ToString()));
|
|
143427
143754
|
}
|
|
@@ -143551,13 +143878,13 @@ BindResult GroupBinder::BindColumnRef(ColumnRefExpression &colref) {
|
|
|
143551
143878
|
// first try to bind to the base columns (original tables)
|
|
143552
143879
|
auto result = ExpressionBinder::BindExpression(colref, 0);
|
|
143553
143880
|
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()) {
|
|
143881
|
+
if (colref.IsQualified()) {
|
|
143558
143882
|
// explicit table name: not an alias reference
|
|
143559
143883
|
return result;
|
|
143560
143884
|
}
|
|
143885
|
+
// failed to bind the column and the node is the root expression with depth = 0
|
|
143886
|
+
// check if refers to an alias in the select clause
|
|
143887
|
+
auto alias_name = colref.column_names[0];
|
|
143561
143888
|
auto entry = alias_map.find(alias_name);
|
|
143562
143889
|
if (entry == alias_map.end()) {
|
|
143563
143890
|
// no matching alias found
|
|
@@ -143724,11 +144051,11 @@ unique_ptr<Expression> OrderBinder::Bind(unique_ptr<ParsedExpression> expr) {
|
|
|
143724
144051
|
// check if we can bind it to an alias in the select list
|
|
143725
144052
|
auto &colref = (ColumnRefExpression &)*expr;
|
|
143726
144053
|
// if there is an explicit table name we can't bind to an alias
|
|
143727
|
-
if (
|
|
144054
|
+
if (colref.IsQualified()) {
|
|
143728
144055
|
break;
|
|
143729
144056
|
}
|
|
143730
144057
|
// check the alias list
|
|
143731
|
-
auto entry = alias_map.find(colref.
|
|
144058
|
+
auto entry = alias_map.find(colref.column_names[0]);
|
|
143732
144059
|
if (entry != alias_map.end()) {
|
|
143733
144060
|
// it does! point it to that entry
|
|
143734
144061
|
return CreateProjectionReference(*expr, entry->second);
|
|
@@ -143745,7 +144072,7 @@ unique_ptr<Expression> OrderBinder::Bind(unique_ptr<ParsedExpression> expr) {
|
|
|
143745
144072
|
// general case
|
|
143746
144073
|
// first bind the table names of this entry
|
|
143747
144074
|
for (auto &binder : binders) {
|
|
143748
|
-
ExpressionBinder::
|
|
144075
|
+
ExpressionBinder::QualifyColumnNames(*binder, expr);
|
|
143749
144076
|
}
|
|
143750
144077
|
// first check if the ORDER BY clause already points to an entry in the projection list
|
|
143751
144078
|
auto entry = projection_map.find(expr.get());
|
|
@@ -143868,8 +144195,8 @@ idx_t SelectBinder::TryBindGroup(ParsedExpression &expr, idx_t depth) {
|
|
|
143868
144195
|
// first check the group alias map, if expr is a ColumnRefExpression
|
|
143869
144196
|
if (expr.type == ExpressionType::COLUMN_REF) {
|
|
143870
144197
|
auto &colref = (ColumnRefExpression &)expr;
|
|
143871
|
-
if (colref.
|
|
143872
|
-
auto alias_entry = info.alias_map.find(colref.
|
|
144198
|
+
if (!colref.IsQualified()) {
|
|
144199
|
+
auto alias_entry = info.alias_map.find(colref.column_names[0]);
|
|
143873
144200
|
if (alias_entry != info.alias_map.end()) {
|
|
143874
144201
|
// found entry!
|
|
143875
144202
|
return alias_entry->second;
|
|
@@ -143904,7 +144231,7 @@ BindResult SelectBinder::BindGroupingFunction(OperatorExpression &op, idx_t dept
|
|
|
143904
144231
|
vector<idx_t> group_indexes;
|
|
143905
144232
|
group_indexes.reserve(op.children.size());
|
|
143906
144233
|
for (auto &child : op.children) {
|
|
143907
|
-
ExpressionBinder::
|
|
144234
|
+
ExpressionBinder::QualifyColumnNames(binder, child);
|
|
143908
144235
|
auto idx = TryBindGroup(*child, depth);
|
|
143909
144236
|
if (idx == INVALID_INDEX) {
|
|
143910
144237
|
return BindResult(binder.FormatError(
|
|
@@ -144074,7 +144401,7 @@ bool ExpressionBinder::BindCorrelatedColumns(unique_ptr<ParsedExpression> &expr)
|
|
|
144074
144401
|
bool success = false;
|
|
144075
144402
|
while (!active_binders.empty()) {
|
|
144076
144403
|
auto &next_binder = active_binders.back();
|
|
144077
|
-
ExpressionBinder::
|
|
144404
|
+
ExpressionBinder::QualifyColumnNames(next_binder->binder, expr);
|
|
144078
144405
|
auto bind_result = next_binder->Bind(&expr, depth);
|
|
144079
144406
|
if (bind_result.empty()) {
|
|
144080
144407
|
success = true;
|
|
@@ -144235,33 +144562,6 @@ string ExpressionBinder::Bind(unique_ptr<ParsedExpression> *expr, idx_t depth, b
|
|
|
144235
144562
|
}
|
|
144236
144563
|
}
|
|
144237
144564
|
|
|
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
144565
|
} // namespace duckdb
|
|
144266
144566
|
|
|
144267
144567
|
|
|
@@ -145324,6 +145624,7 @@ bool LogicalFilter::SplitPredicates(vector<unique_ptr<Expression>> &expressions)
|
|
|
145324
145624
|
|
|
145325
145625
|
|
|
145326
145626
|
|
|
145627
|
+
|
|
145327
145628
|
namespace duckdb {
|
|
145328
145629
|
|
|
145329
145630
|
LogicalGet::LogicalGet(idx_t table_index, TableFunction function, unique_ptr<FunctionData> bind_data,
|
|
@@ -145336,6 +145637,10 @@ string LogicalGet::GetName() const {
|
|
|
145336
145637
|
return StringUtil::Upper(function.name);
|
|
145337
145638
|
}
|
|
145338
145639
|
|
|
145640
|
+
TableCatalogEntry *LogicalGet::GetTable() const {
|
|
145641
|
+
return TableScanFunction::GetTableEntry(function, bind_data.get());
|
|
145642
|
+
}
|
|
145643
|
+
|
|
145339
145644
|
string LogicalGet::ParamsToString() const {
|
|
145340
145645
|
string result;
|
|
145341
145646
|
for (auto &kv : table_filters.filters) {
|
|
@@ -146375,16 +146680,27 @@ bool Binding::TryGetBindingIndex(const string &column_name, column_t &result) {
|
|
|
146375
146680
|
return false;
|
|
146376
146681
|
}
|
|
146377
146682
|
|
|
146683
|
+
column_t Binding::GetBindingIndex(const string &column_name) {
|
|
146684
|
+
column_t result;
|
|
146685
|
+
if (!TryGetBindingIndex(column_name, result)) {
|
|
146686
|
+
throw InternalException("Binding index for column \"%s\" not found", column_name);
|
|
146687
|
+
}
|
|
146688
|
+
return result;
|
|
146689
|
+
}
|
|
146690
|
+
|
|
146378
146691
|
bool Binding::HasMatchingBinding(const string &column_name) {
|
|
146379
146692
|
column_t result;
|
|
146380
146693
|
return TryGetBindingIndex(column_name, result);
|
|
146381
146694
|
}
|
|
146382
146695
|
|
|
146696
|
+
string Binding::ColumnNotFoundError(const string &column_name) const {
|
|
146697
|
+
return StringUtil::Format("Values list \"%s\" does not have a column named \"%s\"", alias, column_name);
|
|
146698
|
+
}
|
|
146699
|
+
|
|
146383
146700
|
BindResult Binding::Bind(ColumnRefExpression &colref, idx_t depth) {
|
|
146384
146701
|
column_t column_index;
|
|
146385
|
-
if (!TryGetBindingIndex(colref.
|
|
146386
|
-
return BindResult(
|
|
146387
|
-
colref.column_name.c_str()));
|
|
146702
|
+
if (!TryGetBindingIndex(colref.GetColumnName(), column_index)) {
|
|
146703
|
+
return BindResult(ColumnNotFoundError(colref.GetColumnName()));
|
|
146388
146704
|
}
|
|
146389
146705
|
ColumnBinding binding;
|
|
146390
146706
|
binding.table_index = index;
|
|
@@ -146396,6 +146712,10 @@ BindResult Binding::Bind(ColumnRefExpression &colref, idx_t depth) {
|
|
|
146396
146712
|
return BindResult(make_unique<BoundColumnRefExpression>(colref.GetName(), sql_type, binding, depth));
|
|
146397
146713
|
}
|
|
146398
146714
|
|
|
146715
|
+
TableCatalogEntry *Binding::GetTableEntry() {
|
|
146716
|
+
return nullptr;
|
|
146717
|
+
}
|
|
146718
|
+
|
|
146399
146719
|
TableBinding::TableBinding(const string &alias, vector<LogicalType> types_p, vector<string> names_p, LogicalGet &get,
|
|
146400
146720
|
idx_t index, bool add_row_id)
|
|
146401
146721
|
: Binding(alias, move(types_p), move(names_p), index), get(get) {
|
|
@@ -146407,10 +146727,10 @@ TableBinding::TableBinding(const string &alias, vector<LogicalType> types_p, vec
|
|
|
146407
146727
|
}
|
|
146408
146728
|
|
|
146409
146729
|
BindResult TableBinding::Bind(ColumnRefExpression &colref, idx_t depth) {
|
|
146730
|
+
auto &column_name = colref.GetColumnName();
|
|
146410
146731
|
column_t column_index;
|
|
146411
|
-
if (!TryGetBindingIndex(
|
|
146412
|
-
return BindResult(
|
|
146413
|
-
colref.column_name));
|
|
146732
|
+
if (!TryGetBindingIndex(column_name, column_index)) {
|
|
146733
|
+
return BindResult(ColumnNotFoundError(column_name));
|
|
146414
146734
|
}
|
|
146415
146735
|
// fetch the type of the column
|
|
146416
146736
|
LogicalType col_type;
|
|
@@ -146444,15 +146764,22 @@ BindResult TableBinding::Bind(ColumnRefExpression &colref, idx_t depth) {
|
|
|
146444
146764
|
return BindResult(make_unique<BoundColumnRefExpression>(colref.GetName(), col_type, binding, depth));
|
|
146445
146765
|
}
|
|
146446
146766
|
|
|
146767
|
+
TableCatalogEntry *TableBinding::GetTableEntry() {
|
|
146768
|
+
return get.GetTable();
|
|
146769
|
+
}
|
|
146770
|
+
|
|
146771
|
+
string TableBinding::ColumnNotFoundError(const string &column_name) const {
|
|
146772
|
+
return StringUtil::Format("Table \"%s\" does not have a column named \"%s\"", alias, column_name);
|
|
146773
|
+
}
|
|
146774
|
+
|
|
146447
146775
|
MacroBinding::MacroBinding(vector<LogicalType> types_p, vector<string> names_p, string macro_name_p)
|
|
146448
|
-
: Binding(
|
|
146776
|
+
: Binding(MacroBinding::MACRO_NAME, move(types_p), move(names_p), -1), macro_name(move(macro_name_p)) {
|
|
146449
146777
|
}
|
|
146450
146778
|
|
|
146451
146779
|
BindResult MacroBinding::Bind(ColumnRefExpression &colref, idx_t depth) {
|
|
146452
146780
|
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));
|
|
146781
|
+
if (!TryGetBindingIndex(colref.GetColumnName(), column_index)) {
|
|
146782
|
+
throw InternalException("Column %s not found in macro", colref.GetColumnName());
|
|
146456
146783
|
}
|
|
146457
146784
|
ColumnBinding binding;
|
|
146458
146785
|
binding.table_index = index;
|
|
@@ -146464,8 +146791,8 @@ BindResult MacroBinding::Bind(ColumnRefExpression &colref, idx_t depth) {
|
|
|
146464
146791
|
|
|
146465
146792
|
unique_ptr<ParsedExpression> MacroBinding::ParamToArg(ColumnRefExpression &colref) {
|
|
146466
146793
|
column_t column_index;
|
|
146467
|
-
if (!TryGetBindingIndex(colref.
|
|
146468
|
-
throw
|
|
146794
|
+
if (!TryGetBindingIndex(colref.GetColumnName(), column_index)) {
|
|
146795
|
+
throw InternalException("Column %s not found in macro", colref.GetColumnName());
|
|
146469
146796
|
}
|
|
146470
146797
|
auto arg = arguments[column_index]->Copy();
|
|
146471
146798
|
arg->alias = colref.alias;
|
|
@@ -153439,7 +153766,7 @@ string ValidityStatistics::ToString() {
|
|
|
153439
153766
|
|
|
153440
153767
|
namespace duckdb {
|
|
153441
153768
|
|
|
153442
|
-
const uint64_t VERSION_NUMBER =
|
|
153769
|
+
const uint64_t VERSION_NUMBER = 28;
|
|
153443
153770
|
|
|
153444
153771
|
} // namespace duckdb
|
|
153445
153772
|
|
|
@@ -212116,7 +212443,6 @@ unsigned char *unicode_to_utf8(pg_wchar c, unsigned char *utf8string);
|
|
|
212116
212443
|
|
|
212117
212444
|
// max parse tree size approx 100 MB, should be enough
|
|
212118
212445
|
#define PG_MALLOC_SIZE 10240
|
|
212119
|
-
#define PG_MALLOC_LIMIT 1000
|
|
212120
212446
|
|
|
212121
212447
|
namespace duckdb_libpgquery {
|
|
212122
212448
|
|
|
@@ -212128,7 +212454,8 @@ struct pg_parser_state_str {
|
|
|
212128
212454
|
|
|
212129
212455
|
size_t malloc_pos;
|
|
212130
212456
|
size_t malloc_ptr_idx;
|
|
212131
|
-
char
|
|
212457
|
+
char **malloc_ptrs;
|
|
212458
|
+
size_t malloc_ptr_size;
|
|
212132
212459
|
};
|
|
212133
212460
|
|
|
212134
212461
|
static __thread parser_state pg_parser_state;
|
|
@@ -212138,8 +212465,13 @@ __thread PGNode *duckdb_newNodeMacroHolder;
|
|
|
212138
212465
|
#endif
|
|
212139
212466
|
|
|
212140
212467
|
static void allocate_new(parser_state *state, size_t n) {
|
|
212141
|
-
if (state->malloc_ptr_idx
|
|
212142
|
-
|
|
212468
|
+
if (state->malloc_ptr_idx >= state->malloc_ptr_size) {
|
|
212469
|
+
size_t new_size = state->malloc_ptr_size * 2;
|
|
212470
|
+
auto new_malloc_ptrs = (char **) malloc(sizeof(char *) * new_size);
|
|
212471
|
+
memcpy(new_malloc_ptrs, state->malloc_ptrs, state->malloc_ptr_size * sizeof(char*));
|
|
212472
|
+
free(state->malloc_ptrs);
|
|
212473
|
+
state->malloc_ptr_size = new_size;
|
|
212474
|
+
state->malloc_ptrs = new_malloc_ptrs;
|
|
212143
212475
|
}
|
|
212144
212476
|
if (n < PG_MALLOC_SIZE) {
|
|
212145
212477
|
n = PG_MALLOC_SIZE;
|
|
@@ -212170,6 +212502,8 @@ void pg_parser_init() {
|
|
|
212170
212502
|
pg_parser_state.pg_err_code = PGUNDEFINED;
|
|
212171
212503
|
pg_parser_state.pg_err_msg[0] = '\0';
|
|
212172
212504
|
|
|
212505
|
+
pg_parser_state.malloc_ptr_size = 4;
|
|
212506
|
+
pg_parser_state.malloc_ptrs = (char **) malloc(sizeof(char *) * pg_parser_state.malloc_ptr_size);
|
|
212173
212507
|
pg_parser_state.malloc_ptr_idx = 0;
|
|
212174
212508
|
allocate_new(&pg_parser_state, 1);
|
|
212175
212509
|
}
|
|
@@ -212179,8 +212513,16 @@ void pg_parser_parse(const char *query, parse_result *res) {
|
|
|
212179
212513
|
try {
|
|
212180
212514
|
res->parse_tree = duckdb_libpgquery::raw_parser(query);
|
|
212181
212515
|
res->success = pg_parser_state.pg_err_code == PGUNDEFINED;
|
|
212182
|
-
} catch (
|
|
212516
|
+
} catch (std::exception &ex) {
|
|
212183
212517
|
res->success = false;
|
|
212518
|
+
// copy the error message of the exception
|
|
212519
|
+
auto error_message = ex.what();
|
|
212520
|
+
uint32_t pos = 0;
|
|
212521
|
+
while(pos < 1023 && error_message[pos]) {
|
|
212522
|
+
pg_parser_state.pg_err_msg[pos] = error_message[pos];
|
|
212523
|
+
pos++;
|
|
212524
|
+
}
|
|
212525
|
+
pg_parser_state.pg_err_msg[pos] = '\0';
|
|
212184
212526
|
}
|
|
212185
212527
|
res->error_message = pg_parser_state.pg_err_msg;
|
|
212186
212528
|
res->error_location = pg_parser_state.pg_err_pos;
|
|
@@ -212194,6 +212536,7 @@ void pg_parser_cleanup() {
|
|
|
212194
212536
|
pg_parser_state.malloc_ptrs[ptr_idx] = nullptr;
|
|
212195
212537
|
}
|
|
212196
212538
|
}
|
|
212539
|
+
free(pg_parser_state.malloc_ptrs);
|
|
212197
212540
|
}
|
|
212198
212541
|
|
|
212199
212542
|
int ereport(int code, ...) {
|