duckdb 0.3.2-dev31.0 → 0.3.2-dev62.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 +723 -413
- package/src/duckdb.hpp +4 -2
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(
|
|
@@ -49700,6 +49734,7 @@ void ExpressionExecutor::ExecuteExpression(idx_t expr_idx, Vector &result) {
|
|
|
49700
49734
|
|
|
49701
49735
|
Value ExpressionExecutor::EvaluateScalar(const Expression &expr) {
|
|
49702
49736
|
D_ASSERT(expr.IsFoldable());
|
|
49737
|
+
D_ASSERT(expr.IsScalar());
|
|
49703
49738
|
// use an ExpressionExecutor to execute the expression
|
|
49704
49739
|
ExpressionExecutor executor(expr);
|
|
49705
49740
|
|
|
@@ -58827,6 +58862,7 @@ struct TableScanBindData : public FunctionData {
|
|
|
58827
58862
|
//! The table scan function represents a sequential scan over one of DuckDB's base tables.
|
|
58828
58863
|
struct TableScanFunction {
|
|
58829
58864
|
static TableFunction GetFunction();
|
|
58865
|
+
static TableCatalogEntry *GetTableEntry(const TableFunction &function, const FunctionData *bind_data);
|
|
58830
58866
|
};
|
|
58831
58867
|
|
|
58832
58868
|
} // namespace duckdb
|
|
@@ -68477,6 +68513,8 @@ public:
|
|
|
68477
68513
|
|
|
68478
68514
|
string GetName() const override;
|
|
68479
68515
|
string ParamsToString() const override;
|
|
68516
|
+
//! Returns the underlying table that is being scanned, or nullptr if there is none
|
|
68517
|
+
TableCatalogEntry *GetTable() const;
|
|
68480
68518
|
|
|
68481
68519
|
public:
|
|
68482
68520
|
vector<ColumnBinding> GetColumnBindings() override;
|
|
@@ -79011,7 +79049,7 @@ string MacroFunction::ValidateArguments(MacroCatalogEntry ¯o_func, FunctionE
|
|
|
79011
79049
|
error = StringUtil::Format(
|
|
79012
79050
|
"Macro function '%s(%s)' requires ", macro_func.name,
|
|
79013
79051
|
StringUtil::Join(parameters, parameters.size(), ", ", [](const unique_ptr<ParsedExpression> &p) {
|
|
79014
|
-
return ((ColumnRefExpression &)*p).
|
|
79052
|
+
return ((ColumnRefExpression &)*p).column_names[0];
|
|
79015
79053
|
}));
|
|
79016
79054
|
error += parameters.size() == 1 ? "a single positional argument"
|
|
79017
79055
|
: StringUtil::Format("%i positional arguments", parameters.size());
|
|
@@ -79240,6 +79278,14 @@ static void PragmaDisableForceExternal(ClientContext &context, const FunctionPar
|
|
|
79240
79278
|
context.force_external = false;
|
|
79241
79279
|
}
|
|
79242
79280
|
|
|
79281
|
+
static void PragmaEnableParquetBinaryAsString(ClientContext &context, const FunctionParameters ¶meters) {
|
|
79282
|
+
context.parquet_binary_as_strings = true;
|
|
79283
|
+
}
|
|
79284
|
+
|
|
79285
|
+
static void PragmaDisableParquetBinaryAsString(ClientContext &context, const FunctionParameters ¶meters) {
|
|
79286
|
+
context.parquet_binary_as_strings = false;
|
|
79287
|
+
}
|
|
79288
|
+
|
|
79243
79289
|
static void PragmaEnableObjectCache(ClientContext &context, const FunctionParameters ¶meters) {
|
|
79244
79290
|
DBConfig::GetConfig(context).object_cache_enable = true;
|
|
79245
79291
|
}
|
|
@@ -79415,6 +79461,11 @@ void PragmaFunctions::RegisterFunction(BuiltinFunctions &set) {
|
|
|
79415
79461
|
set.AddFunction(PragmaFunction::PragmaStatement("enable_print_progress_bar", PragmaEnablePrintProgressBar));
|
|
79416
79462
|
set.AddFunction(PragmaFunction::PragmaStatement("disable_print_progress_bar", PragmaDisablePrintProgressBar));
|
|
79417
79463
|
|
|
79464
|
+
set.AddFunction(
|
|
79465
|
+
PragmaFunction::PragmaStatement("enable_parquet_binary_as_string", PragmaEnableParquetBinaryAsString));
|
|
79466
|
+
set.AddFunction(
|
|
79467
|
+
PragmaFunction::PragmaStatement("disable_parquet_binary_as_string", PragmaDisableParquetBinaryAsString));
|
|
79468
|
+
|
|
79418
79469
|
set.AddFunction(
|
|
79419
79470
|
PragmaFunction::PragmaAssignment("set_progress_bar_time", PragmaSetProgressBarWaitTime, LogicalType::INTEGER));
|
|
79420
79471
|
|
|
@@ -98709,6 +98760,14 @@ TableFunction TableScanFunction::GetFunction() {
|
|
|
98709
98760
|
return scan_function;
|
|
98710
98761
|
}
|
|
98711
98762
|
|
|
98763
|
+
TableCatalogEntry *TableScanFunction::GetTableEntry(const TableFunction &function, const FunctionData *bind_data_p) {
|
|
98764
|
+
if (function.function != TableScanFunc || !bind_data_p) {
|
|
98765
|
+
return nullptr;
|
|
98766
|
+
}
|
|
98767
|
+
auto &bind_data = (TableScanBindData &)*bind_data_p;
|
|
98768
|
+
return bind_data.table;
|
|
98769
|
+
}
|
|
98770
|
+
|
|
98712
98771
|
} // namespace duckdb
|
|
98713
98772
|
|
|
98714
98773
|
|
|
@@ -106482,10 +106541,10 @@ shared_ptr<Relation> Relation::Join(const shared_ptr<Relation> &other, const str
|
|
|
106482
106541
|
throw ParserException("Expected a single expression as join condition");
|
|
106483
106542
|
}
|
|
106484
106543
|
auto &colref = (ColumnRefExpression &)*expr;
|
|
106485
|
-
if (
|
|
106486
|
-
throw ParserException("Expected
|
|
106544
|
+
if (colref.IsQualified()) {
|
|
106545
|
+
throw ParserException("Expected unqualified column for column in USING clause");
|
|
106487
106546
|
}
|
|
106488
|
-
using_columns.push_back(colref.
|
|
106547
|
+
using_columns.push_back(colref.column_names[0]);
|
|
106489
106548
|
}
|
|
106490
106549
|
return make_shared<JoinRelation>(shared_from_this(), other, move(using_columns), type);
|
|
106491
106550
|
} else {
|
|
@@ -115103,6 +115162,10 @@ unique_ptr<NodeStatistics> StatisticsPropagator::PropagateStatistics(LogicalProj
|
|
|
115103
115162
|
unique_ptr<LogicalOperator> *node_ptr) {
|
|
115104
115163
|
// first propagate to the child
|
|
115105
115164
|
node_stats = PropagateStatistics(proj.children[0]);
|
|
115165
|
+
if (proj.children[0]->type == LogicalOperatorType::LOGICAL_EMPTY_RESULT) {
|
|
115166
|
+
ReplaceWithEmptyResult(*node_ptr);
|
|
115167
|
+
return move(node_stats);
|
|
115168
|
+
}
|
|
115106
115169
|
|
|
115107
115170
|
// then propagate to each of the expressions
|
|
115108
115171
|
for (idx_t i = 0; i < proj.expressions.size(); i++) {
|
|
@@ -121779,53 +121842,85 @@ unique_ptr<ParsedExpression> CollateExpression::Deserialize(ExpressionType type,
|
|
|
121779
121842
|
|
|
121780
121843
|
namespace duckdb {
|
|
121781
121844
|
|
|
121782
|
-
//! Specify both the column and table name
|
|
121783
121845
|
ColumnRefExpression::ColumnRefExpression(string column_name, string table_name)
|
|
121784
|
-
:
|
|
121785
|
-
|
|
121846
|
+
: ColumnRefExpression(table_name.empty() ? vector<string> {move(column_name)}
|
|
121847
|
+
: vector<string> {move(table_name), move(column_name)}) {
|
|
121848
|
+
}
|
|
121849
|
+
|
|
121850
|
+
ColumnRefExpression::ColumnRefExpression(string column_name) : ColumnRefExpression(vector<string> {move(column_name)}) {
|
|
121851
|
+
}
|
|
121852
|
+
|
|
121853
|
+
ColumnRefExpression::ColumnRefExpression(vector<string> column_names_p)
|
|
121854
|
+
: ParsedExpression(ExpressionType::COLUMN_REF, ExpressionClass::COLUMN_REF), column_names(move(column_names_p)) {
|
|
121855
|
+
#ifdef DEBUG
|
|
121856
|
+
for (auto &col_name : column_names) {
|
|
121857
|
+
D_ASSERT(!col_name.empty());
|
|
121858
|
+
}
|
|
121859
|
+
#endif
|
|
121786
121860
|
}
|
|
121787
121861
|
|
|
121788
|
-
ColumnRefExpression::
|
|
121862
|
+
bool ColumnRefExpression::IsQualified() const {
|
|
121863
|
+
return column_names.size() > 1;
|
|
121864
|
+
}
|
|
121865
|
+
|
|
121866
|
+
const string &ColumnRefExpression::GetColumnName() const {
|
|
121867
|
+
D_ASSERT(column_names.size() <= 3);
|
|
121868
|
+
return column_names.back();
|
|
121869
|
+
}
|
|
121870
|
+
|
|
121871
|
+
const string &ColumnRefExpression::GetTableName() const {
|
|
121872
|
+
D_ASSERT(column_names.size() >= 2 && column_names.size() <= 3);
|
|
121873
|
+
return column_names.size() == 3 ? column_names[1] : column_names[0];
|
|
121789
121874
|
}
|
|
121790
121875
|
|
|
121791
121876
|
string ColumnRefExpression::GetName() const {
|
|
121792
|
-
return !alias.empty() ? alias :
|
|
121877
|
+
return !alias.empty() ? alias : column_names.back();
|
|
121793
121878
|
}
|
|
121794
121879
|
|
|
121795
121880
|
string ColumnRefExpression::ToString() const {
|
|
121796
|
-
|
|
121797
|
-
|
|
121798
|
-
|
|
121799
|
-
|
|
121881
|
+
string result;
|
|
121882
|
+
for (idx_t i = 0; i < column_names.size(); i++) {
|
|
121883
|
+
if (i > 0) {
|
|
121884
|
+
result += ".";
|
|
121885
|
+
}
|
|
121886
|
+
result += column_names[i];
|
|
121800
121887
|
}
|
|
121888
|
+
return result;
|
|
121801
121889
|
}
|
|
121802
121890
|
|
|
121803
121891
|
bool ColumnRefExpression::Equals(const ColumnRefExpression *a, const ColumnRefExpression *b) {
|
|
121804
|
-
return a->
|
|
121892
|
+
return a->column_names == b->column_names;
|
|
121805
121893
|
}
|
|
121806
121894
|
|
|
121807
121895
|
hash_t ColumnRefExpression::Hash() const {
|
|
121808
121896
|
hash_t result = ParsedExpression::Hash();
|
|
121809
|
-
|
|
121897
|
+
for (auto &column_name : column_names) {
|
|
121898
|
+
result = CombineHash(result, duckdb::Hash<const char *>(column_name.c_str()));
|
|
121899
|
+
}
|
|
121810
121900
|
return result;
|
|
121811
121901
|
}
|
|
121812
121902
|
|
|
121813
121903
|
unique_ptr<ParsedExpression> ColumnRefExpression::Copy() const {
|
|
121814
|
-
auto copy = make_unique<ColumnRefExpression>(
|
|
121904
|
+
auto copy = make_unique<ColumnRefExpression>(column_names);
|
|
121815
121905
|
copy->CopyProperties(*this);
|
|
121816
121906
|
return move(copy);
|
|
121817
121907
|
}
|
|
121818
121908
|
|
|
121819
121909
|
void ColumnRefExpression::Serialize(Serializer &serializer) {
|
|
121820
121910
|
ParsedExpression::Serialize(serializer);
|
|
121821
|
-
serializer.
|
|
121822
|
-
|
|
121911
|
+
serializer.Write<idx_t>(column_names.size());
|
|
121912
|
+
for (auto &column_name : column_names) {
|
|
121913
|
+
serializer.WriteString(column_name);
|
|
121914
|
+
}
|
|
121823
121915
|
}
|
|
121824
121916
|
|
|
121825
121917
|
unique_ptr<ParsedExpression> ColumnRefExpression::Deserialize(ExpressionType type, Deserializer &source) {
|
|
121826
|
-
auto
|
|
121827
|
-
|
|
121828
|
-
|
|
121918
|
+
auto column_count = source.Read<idx_t>();
|
|
121919
|
+
vector<string> column_names;
|
|
121920
|
+
for (idx_t i = 0; i < column_count; i++) {
|
|
121921
|
+
column_names.push_back(source.Read<string>());
|
|
121922
|
+
}
|
|
121923
|
+
auto expression = make_unique<ColumnRefExpression>(move(column_names));
|
|
121829
121924
|
return move(expression);
|
|
121830
121925
|
}
|
|
121831
121926
|
|
|
@@ -123571,6 +123666,129 @@ unique_ptr<ParsedExpression> ParsedExpression::Deserialize(Deserializer &source)
|
|
|
123571
123666
|
|
|
123572
123667
|
|
|
123573
123668
|
|
|
123669
|
+
//===----------------------------------------------------------------------===//
|
|
123670
|
+
// DuckDB
|
|
123671
|
+
//
|
|
123672
|
+
// duckdb/parser/query_node/recursive_cte_node.hpp
|
|
123673
|
+
//
|
|
123674
|
+
//
|
|
123675
|
+
//===----------------------------------------------------------------------===//
|
|
123676
|
+
|
|
123677
|
+
|
|
123678
|
+
|
|
123679
|
+
|
|
123680
|
+
|
|
123681
|
+
|
|
123682
|
+
|
|
123683
|
+
namespace duckdb {
|
|
123684
|
+
|
|
123685
|
+
class RecursiveCTENode : public QueryNode {
|
|
123686
|
+
public:
|
|
123687
|
+
RecursiveCTENode() : QueryNode(QueryNodeType::RECURSIVE_CTE_NODE) {
|
|
123688
|
+
}
|
|
123689
|
+
|
|
123690
|
+
string ctename;
|
|
123691
|
+
bool union_all;
|
|
123692
|
+
//! The left side of the set operation
|
|
123693
|
+
unique_ptr<QueryNode> left;
|
|
123694
|
+
//! The right side of the set operation
|
|
123695
|
+
unique_ptr<QueryNode> right;
|
|
123696
|
+
//! Aliases of the recursive CTE node
|
|
123697
|
+
vector<string> aliases;
|
|
123698
|
+
|
|
123699
|
+
const vector<unique_ptr<ParsedExpression>> &GetSelectList() const override {
|
|
123700
|
+
return left->GetSelectList();
|
|
123701
|
+
}
|
|
123702
|
+
|
|
123703
|
+
public:
|
|
123704
|
+
bool Equals(const QueryNode *other) const override;
|
|
123705
|
+
//! Create a copy of this SelectNode
|
|
123706
|
+
unique_ptr<QueryNode> Copy() override;
|
|
123707
|
+
|
|
123708
|
+
//! Serializes a SelectNode to a stand-alone binary blob
|
|
123709
|
+
void Serialize(Serializer &serializer) override;
|
|
123710
|
+
//! Deserializes a blob back into a SelectNode
|
|
123711
|
+
static unique_ptr<QueryNode> Deserialize(Deserializer &source);
|
|
123712
|
+
};
|
|
123713
|
+
|
|
123714
|
+
} // namespace duckdb
|
|
123715
|
+
|
|
123716
|
+
|
|
123717
|
+
|
|
123718
|
+
|
|
123719
|
+
//===----------------------------------------------------------------------===//
|
|
123720
|
+
// DuckDB
|
|
123721
|
+
//
|
|
123722
|
+
// duckdb/parser/tableref/crossproductref.hpp
|
|
123723
|
+
//
|
|
123724
|
+
//
|
|
123725
|
+
//===----------------------------------------------------------------------===//
|
|
123726
|
+
|
|
123727
|
+
|
|
123728
|
+
|
|
123729
|
+
|
|
123730
|
+
|
|
123731
|
+
namespace duckdb {
|
|
123732
|
+
//! Represents a cross product
|
|
123733
|
+
class CrossProductRef : public TableRef {
|
|
123734
|
+
public:
|
|
123735
|
+
CrossProductRef() : TableRef(TableReferenceType::CROSS_PRODUCT) {
|
|
123736
|
+
}
|
|
123737
|
+
|
|
123738
|
+
//! The left hand side of the cross product
|
|
123739
|
+
unique_ptr<TableRef> left;
|
|
123740
|
+
//! The right hand side of the cross product
|
|
123741
|
+
unique_ptr<TableRef> right;
|
|
123742
|
+
|
|
123743
|
+
public:
|
|
123744
|
+
bool Equals(const TableRef *other_p) const override;
|
|
123745
|
+
|
|
123746
|
+
unique_ptr<TableRef> Copy() override;
|
|
123747
|
+
|
|
123748
|
+
//! Serializes a blob into a CrossProductRef
|
|
123749
|
+
void Serialize(Serializer &serializer) override;
|
|
123750
|
+
//! Deserializes a blob back into a CrossProductRef
|
|
123751
|
+
static unique_ptr<TableRef> Deserialize(Deserializer &source);
|
|
123752
|
+
};
|
|
123753
|
+
} // namespace duckdb
|
|
123754
|
+
|
|
123755
|
+
//===----------------------------------------------------------------------===//
|
|
123756
|
+
// DuckDB
|
|
123757
|
+
//
|
|
123758
|
+
// duckdb/parser/tableref/emptytableref.hpp
|
|
123759
|
+
//
|
|
123760
|
+
//
|
|
123761
|
+
//===----------------------------------------------------------------------===//
|
|
123762
|
+
|
|
123763
|
+
|
|
123764
|
+
|
|
123765
|
+
|
|
123766
|
+
|
|
123767
|
+
namespace duckdb {
|
|
123768
|
+
//! Represents a cross product
|
|
123769
|
+
class EmptyTableRef : public TableRef {
|
|
123770
|
+
public:
|
|
123771
|
+
EmptyTableRef() : TableRef(TableReferenceType::EMPTY) {
|
|
123772
|
+
}
|
|
123773
|
+
|
|
123774
|
+
public:
|
|
123775
|
+
bool Equals(const TableRef *other_p) const override;
|
|
123776
|
+
|
|
123777
|
+
unique_ptr<TableRef> Copy() override;
|
|
123778
|
+
|
|
123779
|
+
//! Serializes a blob into a DummyTableRef
|
|
123780
|
+
void Serialize(Serializer &serializer) override;
|
|
123781
|
+
//! Deserializes a blob back into a DummyTableRef
|
|
123782
|
+
static unique_ptr<TableRef> Deserialize(Deserializer &source);
|
|
123783
|
+
};
|
|
123784
|
+
} // namespace duckdb
|
|
123785
|
+
|
|
123786
|
+
|
|
123787
|
+
|
|
123788
|
+
|
|
123789
|
+
|
|
123790
|
+
|
|
123791
|
+
|
|
123574
123792
|
namespace duckdb {
|
|
123575
123793
|
|
|
123576
123794
|
void ParsedExpressionIterator::EnumerateChildren(const ParsedExpression &expression,
|
|
@@ -123706,6 +123924,91 @@ void ParsedExpressionIterator::EnumerateChildren(
|
|
|
123706
123924
|
}
|
|
123707
123925
|
}
|
|
123708
123926
|
|
|
123927
|
+
void ParsedExpressionIterator::EnumerateTableRefChildren(
|
|
123928
|
+
TableRef &ref, const std::function<void(unique_ptr<ParsedExpression> &child)> &callback) {
|
|
123929
|
+
switch (ref.type) {
|
|
123930
|
+
case TableReferenceType::CROSS_PRODUCT: {
|
|
123931
|
+
auto &cp_ref = (CrossProductRef &)ref;
|
|
123932
|
+
EnumerateTableRefChildren(*cp_ref.left, callback);
|
|
123933
|
+
EnumerateTableRefChildren(*cp_ref.right, callback);
|
|
123934
|
+
break;
|
|
123935
|
+
}
|
|
123936
|
+
case TableReferenceType::EXPRESSION_LIST: {
|
|
123937
|
+
auto &el_ref = (ExpressionListRef &)ref;
|
|
123938
|
+
for (idx_t i = 0; i < el_ref.values.size(); i++) {
|
|
123939
|
+
for (idx_t j = 0; j < el_ref.values[i].size(); j++) {
|
|
123940
|
+
callback(el_ref.values[i][j]);
|
|
123941
|
+
}
|
|
123942
|
+
}
|
|
123943
|
+
break;
|
|
123944
|
+
}
|
|
123945
|
+
case TableReferenceType::JOIN: {
|
|
123946
|
+
auto &j_ref = (JoinRef &)ref;
|
|
123947
|
+
EnumerateTableRefChildren(*j_ref.left, callback);
|
|
123948
|
+
EnumerateTableRefChildren(*j_ref.right, callback);
|
|
123949
|
+
callback(j_ref.condition);
|
|
123950
|
+
break;
|
|
123951
|
+
}
|
|
123952
|
+
case TableReferenceType::SUBQUERY: {
|
|
123953
|
+
auto &sq_ref = (SubqueryRef &)ref;
|
|
123954
|
+
EnumerateQueryNodeChildren(*sq_ref.subquery->node, callback);
|
|
123955
|
+
break;
|
|
123956
|
+
}
|
|
123957
|
+
case TableReferenceType::TABLE_FUNCTION: {
|
|
123958
|
+
auto &tf_ref = (TableFunctionRef &)ref;
|
|
123959
|
+
callback(tf_ref.function);
|
|
123960
|
+
break;
|
|
123961
|
+
}
|
|
123962
|
+
case TableReferenceType::BASE_TABLE:
|
|
123963
|
+
case TableReferenceType::EMPTY:
|
|
123964
|
+
// these TableRefs do not need to be unfolded
|
|
123965
|
+
break;
|
|
123966
|
+
default:
|
|
123967
|
+
throw NotImplementedException("TableRef type not implemented for traversal");
|
|
123968
|
+
}
|
|
123969
|
+
}
|
|
123970
|
+
|
|
123971
|
+
void ParsedExpressionIterator::EnumerateQueryNodeChildren(
|
|
123972
|
+
QueryNode &node, const std::function<void(unique_ptr<ParsedExpression> &child)> &callback) {
|
|
123973
|
+
switch (node.type) {
|
|
123974
|
+
case QueryNodeType::RECURSIVE_CTE_NODE: {
|
|
123975
|
+
auto &rcte_node = (RecursiveCTENode &)node;
|
|
123976
|
+
EnumerateQueryNodeChildren(*rcte_node.left, callback);
|
|
123977
|
+
EnumerateQueryNodeChildren(*rcte_node.right, callback);
|
|
123978
|
+
break;
|
|
123979
|
+
}
|
|
123980
|
+
case QueryNodeType::SELECT_NODE: {
|
|
123981
|
+
auto &sel_node = (SelectNode &)node;
|
|
123982
|
+
for (idx_t i = 0; i < sel_node.select_list.size(); i++) {
|
|
123983
|
+
callback(sel_node.select_list[i]);
|
|
123984
|
+
}
|
|
123985
|
+
for (idx_t i = 0; i < sel_node.groups.group_expressions.size(); i++) {
|
|
123986
|
+
callback(sel_node.groups.group_expressions[i]);
|
|
123987
|
+
}
|
|
123988
|
+
if (sel_node.where_clause) {
|
|
123989
|
+
callback(sel_node.where_clause);
|
|
123990
|
+
}
|
|
123991
|
+
if (sel_node.having) {
|
|
123992
|
+
callback(sel_node.having);
|
|
123993
|
+
}
|
|
123994
|
+
|
|
123995
|
+
EnumerateTableRefChildren(*sel_node.from_table.get(), callback);
|
|
123996
|
+
break;
|
|
123997
|
+
}
|
|
123998
|
+
case QueryNodeType::SET_OPERATION_NODE: {
|
|
123999
|
+
auto &setop_node = (SetOperationNode &)node;
|
|
124000
|
+
EnumerateQueryNodeChildren(*setop_node.left, callback);
|
|
124001
|
+
EnumerateQueryNodeChildren(*setop_node.right, callback);
|
|
124002
|
+
break;
|
|
124003
|
+
}
|
|
124004
|
+
default:
|
|
124005
|
+
throw NotImplementedException("QueryNode type not implemented for traversal");
|
|
124006
|
+
}
|
|
124007
|
+
for (auto &kv : node.cte_map) {
|
|
124008
|
+
EnumerateQueryNodeChildren(*kv.second->query->node, callback);
|
|
124009
|
+
}
|
|
124010
|
+
}
|
|
124011
|
+
|
|
123709
124012
|
} // namespace duckdb
|
|
123710
124013
|
|
|
123711
124014
|
|
|
@@ -129352,52 +129655,6 @@ string QueryErrorContext::FormatErrorRecursive(const string &msg, vector<Excepti
|
|
|
129352
129655
|
return Format(statement->query, error_message, query_location);
|
|
129353
129656
|
}
|
|
129354
129657
|
|
|
129355
|
-
} // namespace duckdb
|
|
129356
|
-
//===----------------------------------------------------------------------===//
|
|
129357
|
-
// DuckDB
|
|
129358
|
-
//
|
|
129359
|
-
// duckdb/parser/query_node/recursive_cte_node.hpp
|
|
129360
|
-
//
|
|
129361
|
-
//
|
|
129362
|
-
//===----------------------------------------------------------------------===//
|
|
129363
|
-
|
|
129364
|
-
|
|
129365
|
-
|
|
129366
|
-
|
|
129367
|
-
|
|
129368
|
-
|
|
129369
|
-
|
|
129370
|
-
namespace duckdb {
|
|
129371
|
-
|
|
129372
|
-
class RecursiveCTENode : public QueryNode {
|
|
129373
|
-
public:
|
|
129374
|
-
RecursiveCTENode() : QueryNode(QueryNodeType::RECURSIVE_CTE_NODE) {
|
|
129375
|
-
}
|
|
129376
|
-
|
|
129377
|
-
string ctename;
|
|
129378
|
-
bool union_all;
|
|
129379
|
-
//! The left side of the set operation
|
|
129380
|
-
unique_ptr<QueryNode> left;
|
|
129381
|
-
//! The right side of the set operation
|
|
129382
|
-
unique_ptr<QueryNode> right;
|
|
129383
|
-
//! Aliases of the recursive CTE node
|
|
129384
|
-
vector<string> aliases;
|
|
129385
|
-
|
|
129386
|
-
const vector<unique_ptr<ParsedExpression>> &GetSelectList() const override {
|
|
129387
|
-
return left->GetSelectList();
|
|
129388
|
-
}
|
|
129389
|
-
|
|
129390
|
-
public:
|
|
129391
|
-
bool Equals(const QueryNode *other) const override;
|
|
129392
|
-
//! Create a copy of this SelectNode
|
|
129393
|
-
unique_ptr<QueryNode> Copy() override;
|
|
129394
|
-
|
|
129395
|
-
//! Serializes a SelectNode to a stand-alone binary blob
|
|
129396
|
-
void Serialize(Serializer &serializer) override;
|
|
129397
|
-
//! Deserializes a blob back into a SelectNode
|
|
129398
|
-
static unique_ptr<QueryNode> Deserialize(Deserializer &source);
|
|
129399
|
-
};
|
|
129400
|
-
|
|
129401
129658
|
} // namespace duckdb
|
|
129402
129659
|
|
|
129403
129660
|
|
|
@@ -130486,41 +130743,6 @@ unique_ptr<TableRef> BaseTableRef::Copy() {
|
|
|
130486
130743
|
return move(copy);
|
|
130487
130744
|
}
|
|
130488
130745
|
} // namespace duckdb
|
|
130489
|
-
//===----------------------------------------------------------------------===//
|
|
130490
|
-
// DuckDB
|
|
130491
|
-
//
|
|
130492
|
-
// duckdb/parser/tableref/crossproductref.hpp
|
|
130493
|
-
//
|
|
130494
|
-
//
|
|
130495
|
-
//===----------------------------------------------------------------------===//
|
|
130496
|
-
|
|
130497
|
-
|
|
130498
|
-
|
|
130499
|
-
|
|
130500
|
-
|
|
130501
|
-
namespace duckdb {
|
|
130502
|
-
//! Represents a cross product
|
|
130503
|
-
class CrossProductRef : public TableRef {
|
|
130504
|
-
public:
|
|
130505
|
-
CrossProductRef() : TableRef(TableReferenceType::CROSS_PRODUCT) {
|
|
130506
|
-
}
|
|
130507
|
-
|
|
130508
|
-
//! The left hand side of the cross product
|
|
130509
|
-
unique_ptr<TableRef> left;
|
|
130510
|
-
//! The right hand side of the cross product
|
|
130511
|
-
unique_ptr<TableRef> right;
|
|
130512
|
-
|
|
130513
|
-
public:
|
|
130514
|
-
bool Equals(const TableRef *other_p) const override;
|
|
130515
|
-
|
|
130516
|
-
unique_ptr<TableRef> Copy() override;
|
|
130517
|
-
|
|
130518
|
-
//! Serializes a blob into a CrossProductRef
|
|
130519
|
-
void Serialize(Serializer &serializer) override;
|
|
130520
|
-
//! Deserializes a blob back into a CrossProductRef
|
|
130521
|
-
static unique_ptr<TableRef> Deserialize(Deserializer &source);
|
|
130522
|
-
};
|
|
130523
|
-
} // namespace duckdb
|
|
130524
130746
|
|
|
130525
130747
|
|
|
130526
130748
|
|
|
@@ -130564,36 +130786,6 @@ unique_ptr<TableRef> CrossProductRef::Deserialize(Deserializer &source) {
|
|
|
130564
130786
|
}
|
|
130565
130787
|
|
|
130566
130788
|
} // namespace duckdb
|
|
130567
|
-
//===----------------------------------------------------------------------===//
|
|
130568
|
-
// DuckDB
|
|
130569
|
-
//
|
|
130570
|
-
// duckdb/parser/tableref/emptytableref.hpp
|
|
130571
|
-
//
|
|
130572
|
-
//
|
|
130573
|
-
//===----------------------------------------------------------------------===//
|
|
130574
|
-
|
|
130575
|
-
|
|
130576
|
-
|
|
130577
|
-
|
|
130578
|
-
|
|
130579
|
-
namespace duckdb {
|
|
130580
|
-
//! Represents a cross product
|
|
130581
|
-
class EmptyTableRef : public TableRef {
|
|
130582
|
-
public:
|
|
130583
|
-
EmptyTableRef() : TableRef(TableReferenceType::EMPTY) {
|
|
130584
|
-
}
|
|
130585
|
-
|
|
130586
|
-
public:
|
|
130587
|
-
bool Equals(const TableRef *other_p) const override;
|
|
130588
|
-
|
|
130589
|
-
unique_ptr<TableRef> Copy() override;
|
|
130590
|
-
|
|
130591
|
-
//! Serializes a blob into a DummyTableRef
|
|
130592
|
-
void Serialize(Serializer &serializer) override;
|
|
130593
|
-
//! Deserializes a blob back into a DummyTableRef
|
|
130594
|
-
static unique_ptr<TableRef> Deserialize(Deserializer &source);
|
|
130595
|
-
};
|
|
130596
|
-
} // namespace duckdb
|
|
130597
130789
|
|
|
130598
130790
|
|
|
130599
130791
|
|
|
@@ -130863,13 +131055,6 @@ unique_ptr<TableRef> TableFunctionRef::Copy() {
|
|
|
130863
131055
|
|
|
130864
131056
|
|
|
130865
131057
|
|
|
130866
|
-
|
|
130867
|
-
|
|
130868
|
-
|
|
130869
|
-
|
|
130870
|
-
|
|
130871
|
-
|
|
130872
|
-
|
|
130873
131058
|
namespace duckdb {
|
|
130874
131059
|
|
|
130875
131060
|
string TableRef::ToString() const {
|
|
@@ -131250,28 +131435,13 @@ unique_ptr<ParsedExpression> Transformer::TransformColumnRef(duckdb_libpgquery::
|
|
|
131250
131435
|
if (fields->length < 1) {
|
|
131251
131436
|
throw InternalException("Unexpected field length");
|
|
131252
131437
|
}
|
|
131253
|
-
string
|
|
131254
|
-
|
|
131255
|
-
|
|
131256
|
-
auto colref = make_unique<ColumnRefExpression>(column_name, table_name);
|
|
131257
|
-
colref->query_location = root->location;
|
|
131258
|
-
return move(colref);
|
|
131259
|
-
} else if (fields->length == 2) {
|
|
131260
|
-
table_name = string(reinterpret_cast<duckdb_libpgquery::PGValue *>(fields->head->data.ptr_value)->val.str);
|
|
131261
|
-
auto col_node = reinterpret_cast<duckdb_libpgquery::PGNode *>(fields->head->next->data.ptr_value);
|
|
131262
|
-
switch (col_node->type) {
|
|
131263
|
-
case duckdb_libpgquery::T_PGString: {
|
|
131264
|
-
column_name = string(reinterpret_cast<duckdb_libpgquery::PGValue *>(col_node)->val.str);
|
|
131265
|
-
auto colref = make_unique<ColumnRefExpression>(column_name, table_name);
|
|
131266
|
-
colref->query_location = root->location;
|
|
131267
|
-
return move(colref);
|
|
131268
|
-
}
|
|
131269
|
-
default:
|
|
131270
|
-
throw NotImplementedException("ColumnRef not implemented!");
|
|
131271
|
-
}
|
|
131272
|
-
} else {
|
|
131273
|
-
throw NotImplementedException("ColumnRef not implemented!");
|
|
131438
|
+
vector<string> column_names;
|
|
131439
|
+
for (auto node = fields->head; node; node = node->next) {
|
|
131440
|
+
column_names.emplace_back(reinterpret_cast<duckdb_libpgquery::PGValue *>(node->data.ptr_value)->val.str);
|
|
131274
131441
|
}
|
|
131442
|
+
auto colref = make_unique<ColumnRefExpression>(move(column_names));
|
|
131443
|
+
colref->query_location = root->location;
|
|
131444
|
+
return move(colref);
|
|
131275
131445
|
}
|
|
131276
131446
|
case duckdb_libpgquery::T_PGAStar: {
|
|
131277
131447
|
return TransformStarExpression(head_node);
|
|
@@ -131942,10 +132112,10 @@ static string ExtractColumnFromLambda(ParsedExpression &expr) {
|
|
|
131942
132112
|
throw ParserException("Lambda parameter must be a column name");
|
|
131943
132113
|
}
|
|
131944
132114
|
auto &colref = (ColumnRefExpression &)expr;
|
|
131945
|
-
if (
|
|
132115
|
+
if (colref.IsQualified()) {
|
|
131946
132116
|
throw ParserException("Lambda parameter must be an unqualified name (e.g. 'x', not 'a.x')");
|
|
131947
132117
|
}
|
|
131948
|
-
return colref.
|
|
132118
|
+
return colref.column_names[0];
|
|
131949
132119
|
}
|
|
131950
132120
|
|
|
131951
132121
|
unique_ptr<ParsedExpression> Transformer::TransformLambda(duckdb_libpgquery::PGLambdaFunction *node) {
|
|
@@ -135600,6 +135770,34 @@ unordered_set<string> BindContext::GetMatchingBindings(const string &column_name
|
|
|
135600
135770
|
return result;
|
|
135601
135771
|
}
|
|
135602
135772
|
|
|
135773
|
+
unique_ptr<ParsedExpression> BindContext::CreateColumnReference(const string &table_name, const string &column_name) {
|
|
135774
|
+
string schema_name;
|
|
135775
|
+
return CreateColumnReference(schema_name, table_name, column_name);
|
|
135776
|
+
}
|
|
135777
|
+
|
|
135778
|
+
unique_ptr<ParsedExpression> BindContext::CreateColumnReference(const string &schema_name, const string &table_name,
|
|
135779
|
+
const string &column_name) {
|
|
135780
|
+
string error_message;
|
|
135781
|
+
vector<string> names;
|
|
135782
|
+
if (!schema_name.empty()) {
|
|
135783
|
+
names.push_back(schema_name);
|
|
135784
|
+
}
|
|
135785
|
+
names.push_back(table_name);
|
|
135786
|
+
names.push_back(column_name);
|
|
135787
|
+
|
|
135788
|
+
auto result = make_unique<ColumnRefExpression>(move(names));
|
|
135789
|
+
// because of case insensitivity in the binder we rename the column to the original name
|
|
135790
|
+
// as it appears in the binding itself
|
|
135791
|
+
auto binding = GetBinding(table_name, error_message);
|
|
135792
|
+
if (binding) {
|
|
135793
|
+
auto column_index = binding->GetBindingIndex(column_name);
|
|
135794
|
+
if (column_index < binding->names.size() && binding->names[column_index] != column_name) {
|
|
135795
|
+
result->alias = binding->names[column_index];
|
|
135796
|
+
}
|
|
135797
|
+
}
|
|
135798
|
+
return move(result);
|
|
135799
|
+
}
|
|
135800
|
+
|
|
135603
135801
|
Binding *BindContext::GetCTEBinding(const string &ctename) {
|
|
135604
135802
|
auto match = cte_bindings.find(ctename);
|
|
135605
135803
|
if (match == cte_bindings.end()) {
|
|
@@ -135625,12 +135823,12 @@ Binding *BindContext::GetBinding(const string &name, string &out_error) {
|
|
|
135625
135823
|
}
|
|
135626
135824
|
|
|
135627
135825
|
BindResult BindContext::BindColumn(ColumnRefExpression &colref, idx_t depth) {
|
|
135628
|
-
if (colref.
|
|
135629
|
-
|
|
135826
|
+
if (!colref.IsQualified()) {
|
|
135827
|
+
throw InternalException("Could not bind alias \"%s\"!", colref.GetColumnName());
|
|
135630
135828
|
}
|
|
135631
135829
|
|
|
135632
135830
|
string error;
|
|
135633
|
-
auto binding = GetBinding(colref.
|
|
135831
|
+
auto binding = GetBinding(colref.GetTableName(), error);
|
|
135634
135832
|
if (!binding) {
|
|
135635
135833
|
return BindResult(error);
|
|
135636
135834
|
}
|
|
@@ -136422,57 +136620,237 @@ BindResult ExpressionBinder::BindExpression(CollateExpression &expr, idx_t depth
|
|
|
136422
136620
|
|
|
136423
136621
|
|
|
136424
136622
|
|
|
136623
|
+
|
|
136624
|
+
|
|
136625
|
+
//===----------------------------------------------------------------------===//
|
|
136626
|
+
// DuckDB
|
|
136627
|
+
//
|
|
136628
|
+
// duckdb/planner/expression_binder/where_binder.hpp
|
|
136629
|
+
//
|
|
136630
|
+
//
|
|
136631
|
+
//===----------------------------------------------------------------------===//
|
|
136632
|
+
|
|
136633
|
+
|
|
136634
|
+
|
|
136635
|
+
|
|
136636
|
+
|
|
136425
136637
|
namespace duckdb {
|
|
136426
136638
|
|
|
136427
|
-
|
|
136428
|
-
|
|
136429
|
-
|
|
136430
|
-
|
|
136431
|
-
|
|
136432
|
-
|
|
136433
|
-
|
|
136434
|
-
|
|
136435
|
-
|
|
136436
|
-
|
|
136437
|
-
|
|
136438
|
-
|
|
136439
|
-
|
|
136440
|
-
|
|
136441
|
-
|
|
136442
|
-
|
|
136443
|
-
|
|
136444
|
-
|
|
136445
|
-
|
|
136446
|
-
|
|
136447
|
-
|
|
136639
|
+
class ColumnAliasBinder;
|
|
136640
|
+
|
|
136641
|
+
//! The WHERE binder is responsible for binding an expression within the WHERE clause of a SQL statement
|
|
136642
|
+
class WhereBinder : public ExpressionBinder {
|
|
136643
|
+
public:
|
|
136644
|
+
WhereBinder(Binder &binder, ClientContext &context, ColumnAliasBinder *column_alias_binder = nullptr);
|
|
136645
|
+
|
|
136646
|
+
protected:
|
|
136647
|
+
BindResult BindExpression(unique_ptr<ParsedExpression> *expr_ptr, idx_t depth,
|
|
136648
|
+
bool root_expression = false) override;
|
|
136649
|
+
|
|
136650
|
+
string UnsupportedAggregateMessage() override;
|
|
136651
|
+
|
|
136652
|
+
private:
|
|
136653
|
+
BindResult BindColumnRef(unique_ptr<ParsedExpression> *expr_ptr, idx_t depth, bool root_expression);
|
|
136654
|
+
|
|
136655
|
+
ColumnAliasBinder *column_alias_binder;
|
|
136656
|
+
};
|
|
136657
|
+
|
|
136658
|
+
} // namespace duckdb
|
|
136659
|
+
|
|
136660
|
+
|
|
136661
|
+
|
|
136662
|
+
|
|
136663
|
+
|
|
136664
|
+
|
|
136665
|
+
namespace duckdb {
|
|
136666
|
+
|
|
136667
|
+
unique_ptr<ParsedExpression> ExpressionBinder::QualifyColumnName(const string &column_name, string &error_message) {
|
|
136668
|
+
auto using_binding = binder.bind_context.GetUsingBinding(column_name);
|
|
136669
|
+
if (using_binding) {
|
|
136670
|
+
// we are referencing a USING column
|
|
136671
|
+
// check if we can refer to one of the base columns directly
|
|
136672
|
+
unique_ptr<Expression> expression;
|
|
136673
|
+
if (!using_binding->primary_binding.empty()) {
|
|
136674
|
+
// we can! just assign the table name and re-bind
|
|
136675
|
+
return make_unique<ColumnRefExpression>(column_name, using_binding->primary_binding);
|
|
136676
|
+
} else {
|
|
136677
|
+
// // we cannot! we need to bind this as a coalesce between all the relevant columns
|
|
136678
|
+
auto coalesce = make_unique<OperatorExpression>(ExpressionType::OPERATOR_COALESCE);
|
|
136679
|
+
for (auto &entry : using_binding->bindings) {
|
|
136680
|
+
coalesce->children.push_back(make_unique<ColumnRefExpression>(column_name, entry));
|
|
136681
|
+
}
|
|
136682
|
+
return move(coalesce);
|
|
136683
|
+
}
|
|
136684
|
+
}
|
|
136685
|
+
// no table name: find a binding that contains this
|
|
136686
|
+
if (binder.macro_binding != nullptr && binder.macro_binding->HasMatchingBinding(column_name)) {
|
|
136687
|
+
// priority to macro parameter bindings TODO: throw a warning when this name conflicts
|
|
136688
|
+
D_ASSERT(!binder.macro_binding->alias.empty());
|
|
136689
|
+
return make_unique<ColumnRefExpression>(column_name, binder.macro_binding->alias);
|
|
136690
|
+
} else {
|
|
136691
|
+
string table_name = binder.bind_context.GetMatchingBinding(column_name);
|
|
136692
|
+
if (table_name.empty()) {
|
|
136693
|
+
auto similar_bindings = binder.bind_context.GetSimilarBindings(column_name);
|
|
136694
|
+
string candidate_str = StringUtil::CandidatesMessage(similar_bindings, "Candidate bindings");
|
|
136695
|
+
error_message =
|
|
136696
|
+
StringUtil::Format("Referenced column \"%s\" not found in FROM clause!%s", column_name, candidate_str);
|
|
136697
|
+
return nullptr;
|
|
136698
|
+
}
|
|
136699
|
+
return binder.bind_context.CreateColumnReference(table_name, column_name);
|
|
136700
|
+
}
|
|
136701
|
+
}
|
|
136702
|
+
|
|
136703
|
+
void ExpressionBinder::QualifyColumnNames(unique_ptr<ParsedExpression> &expr) {
|
|
136704
|
+
switch (expr->type) {
|
|
136705
|
+
case ExpressionType::COLUMN_REF: {
|
|
136706
|
+
auto &colref = (ColumnRefExpression &)*expr;
|
|
136707
|
+
string error_message;
|
|
136708
|
+
auto new_expr = QualifyColumnName(colref, error_message);
|
|
136709
|
+
if (new_expr) {
|
|
136710
|
+
if (!expr->alias.empty()) {
|
|
136711
|
+
new_expr->alias = expr->alias;
|
|
136712
|
+
}
|
|
136713
|
+
expr = move(new_expr);
|
|
136714
|
+
}
|
|
136715
|
+
break;
|
|
136716
|
+
}
|
|
136717
|
+
case ExpressionType::POSITIONAL_REFERENCE: {
|
|
136718
|
+
auto &ref = (PositionalReferenceExpression &)*expr;
|
|
136719
|
+
if (ref.alias.empty()) {
|
|
136720
|
+
string table_name, column_name;
|
|
136721
|
+
auto error = binder.bind_context.BindColumn(ref, table_name, column_name);
|
|
136722
|
+
if (error.empty()) {
|
|
136723
|
+
ref.alias = column_name;
|
|
136448
136724
|
}
|
|
136449
136725
|
}
|
|
136450
|
-
|
|
136451
|
-
|
|
136452
|
-
|
|
136453
|
-
|
|
136726
|
+
break;
|
|
136727
|
+
}
|
|
136728
|
+
default:
|
|
136729
|
+
break;
|
|
136730
|
+
}
|
|
136731
|
+
ParsedExpressionIterator::EnumerateChildren(
|
|
136732
|
+
*expr, [&](unique_ptr<ParsedExpression> &child) { QualifyColumnNames(child); });
|
|
136733
|
+
}
|
|
136734
|
+
|
|
136735
|
+
void ExpressionBinder::QualifyColumnNames(Binder &binder, unique_ptr<ParsedExpression> &expr) {
|
|
136736
|
+
WhereBinder where_binder(binder, binder.context);
|
|
136737
|
+
where_binder.QualifyColumnNames(expr);
|
|
136738
|
+
}
|
|
136739
|
+
|
|
136740
|
+
unique_ptr<ParsedExpression> ExpressionBinder::CreateStructExtract(unique_ptr<ParsedExpression> base,
|
|
136741
|
+
string field_name) {
|
|
136742
|
+
vector<unique_ptr<ParsedExpression>> children;
|
|
136743
|
+
children.push_back(move(base));
|
|
136744
|
+
children.push_back(make_unique_base<ParsedExpression, ConstantExpression>(Value(move(field_name))));
|
|
136745
|
+
auto extract_fun = make_unique<FunctionExpression>("struct_extract", move(children));
|
|
136746
|
+
return move(extract_fun);
|
|
136747
|
+
}
|
|
136748
|
+
|
|
136749
|
+
unique_ptr<ParsedExpression> ExpressionBinder::QualifyColumnName(ColumnRefExpression &colref, string &error_message) {
|
|
136750
|
+
idx_t column_parts = colref.column_names.size();
|
|
136751
|
+
// column names can have an arbitrary amount of dots
|
|
136752
|
+
// here is how the resolution works:
|
|
136753
|
+
if (column_parts == 1) {
|
|
136754
|
+
// no dots (i.e. "part1")
|
|
136755
|
+
// -> part1 refers to a column
|
|
136756
|
+
// check if we can qualify the column name with the table name
|
|
136757
|
+
return QualifyColumnName(colref.GetColumnName(), error_message);
|
|
136758
|
+
} else if (column_parts == 2) {
|
|
136759
|
+
// one dot (i.e. "part1.part2")
|
|
136760
|
+
// EITHER:
|
|
136761
|
+
// -> part1 is a table, part2 is a column
|
|
136762
|
+
// -> part1 is a column, part2 is a property of that column (i.e. struct_extract)
|
|
136763
|
+
|
|
136764
|
+
// first check if part1 is a table
|
|
136765
|
+
if (binder.HasMatchingBinding(colref.column_names[0], colref.column_names[1], error_message)) {
|
|
136766
|
+
// it is! return the colref directly
|
|
136767
|
+
return binder.bind_context.CreateColumnReference(colref.column_names[0], colref.column_names[1]);
|
|
136454
136768
|
} else {
|
|
136455
|
-
|
|
136769
|
+
// otherwise check if we can turn this into a struct extract
|
|
136770
|
+
auto new_colref = make_unique<ColumnRefExpression>(colref.column_names[0]);
|
|
136771
|
+
string other_error;
|
|
136772
|
+
auto qualified_colref = QualifyColumnName(colref.column_names[0], other_error);
|
|
136773
|
+
if (!qualified_colref) {
|
|
136774
|
+
// we could not! bail
|
|
136775
|
+
return nullptr;
|
|
136776
|
+
}
|
|
136777
|
+
// we could: create a struct extract
|
|
136778
|
+
return CreateStructExtract(move(qualified_colref), colref.column_names[1]);
|
|
136456
136779
|
}
|
|
136457
|
-
|
|
136458
|
-
|
|
136459
|
-
|
|
136460
|
-
|
|
136461
|
-
|
|
136462
|
-
|
|
136780
|
+
} else {
|
|
136781
|
+
// two or more dots (i.e. "part1.part2.part3.part4...")
|
|
136782
|
+
// -> part1 is a schema, part2 is a table, part3 is a column name, part4 and beyond are struct fields
|
|
136783
|
+
// -> part1 is a table, part2 is a column name, part3 and beyond are struct fields
|
|
136784
|
+
// -> part1 is a column, part2 and beyond are struct fields
|
|
136785
|
+
|
|
136786
|
+
// we always prefer the most top-level view
|
|
136787
|
+
// i.e. in case of multiple resolution options, we resolve in order:
|
|
136788
|
+
// -> 1. resolve "part1" as a schema
|
|
136789
|
+
// -> 2. resolve "part1" as a table
|
|
136790
|
+
// -> 3. resolve "part1" as a column
|
|
136791
|
+
|
|
136792
|
+
unique_ptr<ParsedExpression> result_expr;
|
|
136793
|
+
idx_t struct_extract_start;
|
|
136794
|
+
// first check if part1 is a schema
|
|
136795
|
+
if (binder.HasMatchingBinding(colref.column_names[0], colref.column_names[1], colref.column_names[2],
|
|
136796
|
+
error_message)) {
|
|
136797
|
+
// it is! the column reference is "schema.table.column"
|
|
136798
|
+
// any additional fields are turned into struct_extract calls
|
|
136799
|
+
result_expr = binder.bind_context.CreateColumnReference(colref.column_names[0], colref.column_names[1],
|
|
136800
|
+
colref.column_names[2]);
|
|
136801
|
+
struct_extract_start = 3;
|
|
136802
|
+
} else if (binder.HasMatchingBinding(colref.column_names[0], colref.column_names[1], error_message)) {
|
|
136803
|
+
// part1 is a table
|
|
136804
|
+
// the column reference is "table.column"
|
|
136805
|
+
// any additional fields are turned into struct_extract calls
|
|
136806
|
+
result_expr = binder.bind_context.CreateColumnReference(colref.column_names[0], colref.column_names[1]);
|
|
136807
|
+
struct_extract_start = 2;
|
|
136808
|
+
} else {
|
|
136809
|
+
// part1 could be a column
|
|
136810
|
+
string col_error;
|
|
136811
|
+
result_expr = QualifyColumnName(colref.column_names[0], col_error);
|
|
136812
|
+
if (!result_expr) {
|
|
136813
|
+
// it is not! return the error
|
|
136814
|
+
return nullptr;
|
|
136815
|
+
}
|
|
136816
|
+
// it is! add the struct extract calls
|
|
136817
|
+
struct_extract_start = 1;
|
|
136818
|
+
}
|
|
136819
|
+
for (idx_t i = struct_extract_start; i < colref.column_names.size(); i++) {
|
|
136820
|
+
result_expr = CreateStructExtract(move(result_expr), colref.column_names[i]);
|
|
136463
136821
|
}
|
|
136822
|
+
return result_expr;
|
|
136823
|
+
}
|
|
136824
|
+
}
|
|
136825
|
+
|
|
136826
|
+
BindResult ExpressionBinder::BindExpression(ColumnRefExpression &colref_p, idx_t depth) {
|
|
136827
|
+
string error_message;
|
|
136828
|
+
auto expr = QualifyColumnName(colref_p, error_message);
|
|
136829
|
+
if (!expr) {
|
|
136830
|
+
return BindResult(binder.FormatError(colref_p, error_message));
|
|
136831
|
+
}
|
|
136832
|
+
if (expr->type != ExpressionType::COLUMN_REF) {
|
|
136833
|
+
return BindExpression(&expr, depth);
|
|
136464
136834
|
}
|
|
136835
|
+
auto &colref = (ColumnRefExpression &)*expr;
|
|
136836
|
+
D_ASSERT(colref.column_names.size() == 2 || colref.column_names.size() == 3);
|
|
136837
|
+
auto &table_name = colref.column_names.size() == 3 ? colref.column_names[1] : colref.column_names[0];
|
|
136838
|
+
// individual column reference
|
|
136839
|
+
// resolve to either a base table or a subquery expression
|
|
136465
136840
|
// if it was a macro parameter, let macro_binding bind it to the argument
|
|
136466
|
-
BindResult result
|
|
136467
|
-
|
|
136468
|
-
|
|
136841
|
+
BindResult result;
|
|
136842
|
+
if (binder.macro_binding && table_name == binder.macro_binding->alias) {
|
|
136843
|
+
result = binder.macro_binding->Bind(colref, depth);
|
|
136844
|
+
} else {
|
|
136845
|
+
result = binder.bind_context.BindColumn(colref, depth);
|
|
136846
|
+
}
|
|
136469
136847
|
if (!result.HasError()) {
|
|
136470
136848
|
BoundColumnReferenceInfo ref;
|
|
136471
|
-
ref.name = colref.
|
|
136849
|
+
ref.name = colref.column_names.back();
|
|
136472
136850
|
ref.query_location = colref.query_location;
|
|
136473
136851
|
bound_columns.push_back(move(ref));
|
|
136474
136852
|
} else {
|
|
136475
|
-
result.error = binder.FormatError(
|
|
136853
|
+
result.error = binder.FormatError(colref_p, result.error);
|
|
136476
136854
|
}
|
|
136477
136855
|
return result;
|
|
136478
136856
|
}
|
|
@@ -136770,11 +137148,6 @@ BindResult ExpressionBinder::BindExpression(LambdaExpression &expr, idx_t depth)
|
|
|
136770
137148
|
|
|
136771
137149
|
|
|
136772
137150
|
|
|
136773
|
-
|
|
136774
|
-
|
|
136775
|
-
|
|
136776
|
-
|
|
136777
|
-
|
|
136778
137151
|
namespace duckdb {
|
|
136779
137152
|
|
|
136780
137153
|
void ExpressionBinder::ReplaceMacroParametersRecursive(unique_ptr<ParsedExpression> &expr) {
|
|
@@ -136782,7 +137155,14 @@ void ExpressionBinder::ReplaceMacroParametersRecursive(unique_ptr<ParsedExpressi
|
|
|
136782
137155
|
case ExpressionClass::COLUMN_REF: {
|
|
136783
137156
|
// if expr is a parameter, replace it with its argument
|
|
136784
137157
|
auto &colref = (ColumnRefExpression &)*expr;
|
|
136785
|
-
|
|
137158
|
+
bool bind_macro_parameter = false;
|
|
137159
|
+
if (colref.IsQualified()) {
|
|
137160
|
+
bind_macro_parameter = colref.GetTableName() == MacroBinding::MACRO_NAME;
|
|
137161
|
+
} else {
|
|
137162
|
+
bind_macro_parameter = macro_binding->HasMatchingBinding(colref.GetColumnName());
|
|
137163
|
+
}
|
|
137164
|
+
if (bind_macro_parameter) {
|
|
137165
|
+
D_ASSERT(macro_binding->HasMatchingBinding(colref.GetColumnName()));
|
|
136786
137166
|
expr = macro_binding->ParamToArg(colref);
|
|
136787
137167
|
}
|
|
136788
137168
|
return;
|
|
@@ -136790,7 +137170,8 @@ void ExpressionBinder::ReplaceMacroParametersRecursive(unique_ptr<ParsedExpressi
|
|
|
136790
137170
|
case ExpressionClass::SUBQUERY: {
|
|
136791
137171
|
// replacing parameters within a subquery is slightly different
|
|
136792
137172
|
auto &sq = ((SubqueryExpression &)*expr).subquery;
|
|
136793
|
-
|
|
137173
|
+
ParsedExpressionIterator::EnumerateQueryNodeChildren(
|
|
137174
|
+
*sq->node, [&](unique_ptr<ParsedExpression> &child) { ReplaceMacroParametersRecursive(child); });
|
|
136794
137175
|
break;
|
|
136795
137176
|
}
|
|
136796
137177
|
default: // fall through
|
|
@@ -136801,89 +137182,6 @@ void ExpressionBinder::ReplaceMacroParametersRecursive(unique_ptr<ParsedExpressi
|
|
|
136801
137182
|
*expr, [&](unique_ptr<ParsedExpression> &child) { ReplaceMacroParametersRecursive(child); });
|
|
136802
137183
|
}
|
|
136803
137184
|
|
|
136804
|
-
void ExpressionBinder::ReplaceMacroParametersRecursive(ParsedExpression &expr, TableRef &ref) {
|
|
136805
|
-
switch (ref.type) {
|
|
136806
|
-
case TableReferenceType::CROSS_PRODUCT: {
|
|
136807
|
-
auto &cp_ref = (CrossProductRef &)ref;
|
|
136808
|
-
ReplaceMacroParametersRecursive(expr, *cp_ref.left);
|
|
136809
|
-
ReplaceMacroParametersRecursive(expr, *cp_ref.right);
|
|
136810
|
-
break;
|
|
136811
|
-
}
|
|
136812
|
-
case TableReferenceType::EXPRESSION_LIST: {
|
|
136813
|
-
auto &el_ref = (ExpressionListRef &)ref;
|
|
136814
|
-
for (idx_t i = 0; i < el_ref.values.size(); i++) {
|
|
136815
|
-
for (idx_t j = 0; j < el_ref.values[i].size(); j++) {
|
|
136816
|
-
ReplaceMacroParametersRecursive(el_ref.values[i][j]);
|
|
136817
|
-
}
|
|
136818
|
-
}
|
|
136819
|
-
break;
|
|
136820
|
-
}
|
|
136821
|
-
case TableReferenceType::JOIN: {
|
|
136822
|
-
auto &j_ref = (JoinRef &)ref;
|
|
136823
|
-
ReplaceMacroParametersRecursive(expr, *j_ref.left);
|
|
136824
|
-
ReplaceMacroParametersRecursive(expr, *j_ref.right);
|
|
136825
|
-
ReplaceMacroParametersRecursive(j_ref.condition);
|
|
136826
|
-
break;
|
|
136827
|
-
}
|
|
136828
|
-
case TableReferenceType::SUBQUERY: {
|
|
136829
|
-
auto &sq_ref = (SubqueryRef &)ref;
|
|
136830
|
-
ReplaceMacroParametersRecursive(expr, *sq_ref.subquery->node);
|
|
136831
|
-
break;
|
|
136832
|
-
}
|
|
136833
|
-
case TableReferenceType::TABLE_FUNCTION: {
|
|
136834
|
-
auto &tf_ref = (TableFunctionRef &)ref;
|
|
136835
|
-
ReplaceMacroParametersRecursive(tf_ref.function);
|
|
136836
|
-
break;
|
|
136837
|
-
}
|
|
136838
|
-
case TableReferenceType::BASE_TABLE:
|
|
136839
|
-
case TableReferenceType::EMPTY:
|
|
136840
|
-
// these TableRefs do not need to be unfolded
|
|
136841
|
-
break;
|
|
136842
|
-
default:
|
|
136843
|
-
throw NotImplementedException("TableRef type not implemented for macro's!");
|
|
136844
|
-
}
|
|
136845
|
-
}
|
|
136846
|
-
|
|
136847
|
-
void ExpressionBinder::ReplaceMacroParametersRecursive(ParsedExpression &expr, QueryNode &node) {
|
|
136848
|
-
switch (node.type) {
|
|
136849
|
-
case QueryNodeType::RECURSIVE_CTE_NODE: {
|
|
136850
|
-
auto &rcte_node = (RecursiveCTENode &)node;
|
|
136851
|
-
ReplaceMacroParametersRecursive(expr, *rcte_node.left);
|
|
136852
|
-
ReplaceMacroParametersRecursive(expr, *rcte_node.right);
|
|
136853
|
-
break;
|
|
136854
|
-
}
|
|
136855
|
-
case QueryNodeType::SELECT_NODE: {
|
|
136856
|
-
auto &sel_node = (SelectNode &)node;
|
|
136857
|
-
for (idx_t i = 0; i < sel_node.select_list.size(); i++) {
|
|
136858
|
-
ReplaceMacroParametersRecursive(sel_node.select_list[i]);
|
|
136859
|
-
}
|
|
136860
|
-
for (idx_t i = 0; i < sel_node.groups.group_expressions.size(); i++) {
|
|
136861
|
-
ReplaceMacroParametersRecursive(sel_node.groups.group_expressions[i]);
|
|
136862
|
-
}
|
|
136863
|
-
if (sel_node.where_clause != nullptr) {
|
|
136864
|
-
ReplaceMacroParametersRecursive(sel_node.where_clause);
|
|
136865
|
-
}
|
|
136866
|
-
if (sel_node.having != nullptr) {
|
|
136867
|
-
ReplaceMacroParametersRecursive(sel_node.having);
|
|
136868
|
-
}
|
|
136869
|
-
|
|
136870
|
-
ReplaceMacroParametersRecursive(expr, *sel_node.from_table.get());
|
|
136871
|
-
break;
|
|
136872
|
-
}
|
|
136873
|
-
case QueryNodeType::SET_OPERATION_NODE: {
|
|
136874
|
-
auto &setop_node = (SetOperationNode &)node;
|
|
136875
|
-
ReplaceMacroParametersRecursive(expr, *setop_node.left);
|
|
136876
|
-
ReplaceMacroParametersRecursive(expr, *setop_node.right);
|
|
136877
|
-
break;
|
|
136878
|
-
}
|
|
136879
|
-
default:
|
|
136880
|
-
throw NotImplementedException("QueryNode type not implemented for macro's!");
|
|
136881
|
-
}
|
|
136882
|
-
for (auto &kv : node.cte_map) {
|
|
136883
|
-
ReplaceMacroParametersRecursive(expr, *kv.second->query->node);
|
|
136884
|
-
}
|
|
136885
|
-
}
|
|
136886
|
-
|
|
136887
137185
|
BindResult ExpressionBinder::BindMacro(FunctionExpression &function, MacroCatalogEntry *macro_func, idx_t depth,
|
|
136888
137186
|
unique_ptr<ParsedExpression> *expr) {
|
|
136889
137187
|
auto ¯o_def = *macro_func->function;
|
|
@@ -136902,7 +137200,7 @@ BindResult ExpressionBinder::BindMacro(FunctionExpression &function, MacroCatalo
|
|
|
136902
137200
|
for (idx_t i = 0; i < macro_def.parameters.size(); i++) {
|
|
136903
137201
|
types.push_back(LogicalType::SQLNULL);
|
|
136904
137202
|
auto ¶m = (ColumnRefExpression &)*macro_def.parameters[i];
|
|
136905
|
-
names.push_back(param.
|
|
137203
|
+
names.push_back(param.GetColumnName());
|
|
136906
137204
|
}
|
|
136907
137205
|
// default parameters
|
|
136908
137206
|
for (auto it = macro_def.default_parameters.begin(); it != macro_def.default_parameters.end(); it++) {
|
|
@@ -137826,40 +138124,6 @@ private:
|
|
|
137826
138124
|
} // namespace duckdb
|
|
137827
138125
|
|
|
137828
138126
|
|
|
137829
|
-
//===----------------------------------------------------------------------===//
|
|
137830
|
-
// DuckDB
|
|
137831
|
-
//
|
|
137832
|
-
// duckdb/planner/expression_binder/where_binder.hpp
|
|
137833
|
-
//
|
|
137834
|
-
//
|
|
137835
|
-
//===----------------------------------------------------------------------===//
|
|
137836
|
-
|
|
137837
|
-
|
|
137838
|
-
|
|
137839
|
-
|
|
137840
|
-
|
|
137841
|
-
namespace duckdb {
|
|
137842
|
-
|
|
137843
|
-
class ColumnAliasBinder;
|
|
137844
|
-
|
|
137845
|
-
//! The WHERE binder is responsible for binding an expression within the WHERE clause of a SQL statement
|
|
137846
|
-
class WhereBinder : public ExpressionBinder {
|
|
137847
|
-
public:
|
|
137848
|
-
WhereBinder(Binder &binder, ClientContext &context, ColumnAliasBinder *column_alias_binder = nullptr);
|
|
137849
|
-
|
|
137850
|
-
protected:
|
|
137851
|
-
BindResult BindExpression(unique_ptr<ParsedExpression> *expr_ptr, idx_t depth,
|
|
137852
|
-
bool root_expression = false) override;
|
|
137853
|
-
|
|
137854
|
-
string UnsupportedAggregateMessage() override;
|
|
137855
|
-
|
|
137856
|
-
private:
|
|
137857
|
-
BindResult BindColumnRef(unique_ptr<ParsedExpression> *expr_ptr, idx_t depth, bool root_expression);
|
|
137858
|
-
|
|
137859
|
-
ColumnAliasBinder *column_alias_binder;
|
|
137860
|
-
};
|
|
137861
|
-
|
|
137862
|
-
} // namespace duckdb
|
|
137863
138127
|
|
|
137864
138128
|
|
|
137865
138129
|
|
|
@@ -138050,7 +138314,7 @@ unique_ptr<BoundQueryNode> Binder::BindNode(SelectNode &statement) {
|
|
|
138050
138314
|
for (idx_t i = 0; i < statement.select_list.size(); i++) {
|
|
138051
138315
|
auto &expr = statement.select_list[i];
|
|
138052
138316
|
result->names.push_back(expr->GetName());
|
|
138053
|
-
ExpressionBinder::
|
|
138317
|
+
ExpressionBinder::QualifyColumnNames(*this, expr);
|
|
138054
138318
|
if (!expr->alias.empty()) {
|
|
138055
138319
|
alias_map[expr->alias] = i;
|
|
138056
138320
|
result->names[i] = expr->alias;
|
|
@@ -138104,7 +138368,7 @@ unique_ptr<BoundQueryNode> Binder::BindNode(SelectNode &statement) {
|
|
|
138104
138368
|
// if we wouldn't do this then (SELECT test.a FROM test GROUP BY a) would not work because "test.a" <> "a"
|
|
138105
138369
|
// hence we convert "a" -> "test.a" in the unbound expression
|
|
138106
138370
|
unbound_groups[i] = move(group_binder.unbound_expression);
|
|
138107
|
-
ExpressionBinder::
|
|
138371
|
+
ExpressionBinder::QualifyColumnNames(*this, unbound_groups[i]);
|
|
138108
138372
|
info.map[unbound_groups[i].get()] = i;
|
|
138109
138373
|
}
|
|
138110
138374
|
}
|
|
@@ -138113,7 +138377,7 @@ unique_ptr<BoundQueryNode> Binder::BindNode(SelectNode &statement) {
|
|
|
138113
138377
|
// bind the HAVING clause, if any
|
|
138114
138378
|
if (statement.having) {
|
|
138115
138379
|
HavingBinder having_binder(*this, context, *result, info, alias_map);
|
|
138116
|
-
ExpressionBinder::
|
|
138380
|
+
ExpressionBinder::QualifyColumnNames(*this, statement.having);
|
|
138117
138381
|
result->having = having_binder.Bind(statement.having);
|
|
138118
138382
|
}
|
|
138119
138383
|
|
|
@@ -139402,11 +139666,11 @@ SchemaCatalogEntry *Binder::BindCreateFunctionInfo(CreateInfo &info) {
|
|
|
139402
139666
|
// positional parameters
|
|
139403
139667
|
for (idx_t i = 0; i < base.function->parameters.size(); i++) {
|
|
139404
139668
|
auto param = (ColumnRefExpression &)*base.function->parameters[i];
|
|
139405
|
-
if (
|
|
139406
|
-
throw BinderException("Invalid parameter name '%s'", param.ToString());
|
|
139669
|
+
if (param.IsQualified()) {
|
|
139670
|
+
throw BinderException("Invalid parameter name '%s': must be unqualified", param.ToString());
|
|
139407
139671
|
}
|
|
139408
139672
|
dummy_types.push_back(LogicalType::SQLNULL);
|
|
139409
|
-
dummy_names.push_back(param.
|
|
139673
|
+
dummy_names.push_back(param.GetColumnName());
|
|
139410
139674
|
}
|
|
139411
139675
|
// default parameters
|
|
139412
139676
|
for (auto it = base.function->default_parameters.begin(); it != base.function->default_parameters.end(); it++) {
|
|
@@ -139416,6 +139680,7 @@ SchemaCatalogEntry *Binder::BindCreateFunctionInfo(CreateInfo &info) {
|
|
|
139416
139680
|
}
|
|
139417
139681
|
auto this_macro_binding = make_unique<MacroBinding>(dummy_types, dummy_names, base.name);
|
|
139418
139682
|
macro_binding = this_macro_binding.get();
|
|
139683
|
+
ExpressionBinder::QualifyColumnNames(*this, base.function->expression);
|
|
139419
139684
|
|
|
139420
139685
|
// create a copy of the expression because we do not want to alter the original
|
|
139421
139686
|
auto expression = base.function->expression->Copy();
|
|
@@ -141532,8 +141797,8 @@ bool Binder::BindFunctionParameters(vector<unique_ptr<ParsedExpression>> &expres
|
|
|
141532
141797
|
auto &comp = (ComparisonExpression &)*child;
|
|
141533
141798
|
if (comp.left->type == ExpressionType::COLUMN_REF) {
|
|
141534
141799
|
auto &colref = (ColumnRefExpression &)*comp.left;
|
|
141535
|
-
if (colref.
|
|
141536
|
-
parameter_name = colref.
|
|
141800
|
+
if (!colref.IsQualified()) {
|
|
141801
|
+
parameter_name = colref.GetColumnName();
|
|
141537
141802
|
child = move(comp.right);
|
|
141538
141803
|
}
|
|
141539
141804
|
}
|
|
@@ -142004,6 +142269,8 @@ unique_ptr<LogicalOperator> Binder::CreatePlan(BoundTableFunction &ref) {
|
|
|
142004
142269
|
|
|
142005
142270
|
|
|
142006
142271
|
|
|
142272
|
+
|
|
142273
|
+
|
|
142007
142274
|
#include <algorithm>
|
|
142008
142275
|
|
|
142009
142276
|
namespace duckdb {
|
|
@@ -142283,6 +142550,38 @@ void Binder::AddCorrelatedColumn(const CorrelatedColumnInfo &info) {
|
|
|
142283
142550
|
}
|
|
142284
142551
|
}
|
|
142285
142552
|
|
|
142553
|
+
bool Binder::HasMatchingBinding(const string &table_name, const string &column_name, string &error_message) {
|
|
142554
|
+
string empty_schema;
|
|
142555
|
+
return HasMatchingBinding(empty_schema, table_name, column_name, error_message);
|
|
142556
|
+
}
|
|
142557
|
+
|
|
142558
|
+
bool Binder::HasMatchingBinding(const string &schema_name, const string &table_name, const string &column_name,
|
|
142559
|
+
string &error_message) {
|
|
142560
|
+
Binding *binding;
|
|
142561
|
+
if (macro_binding && table_name == macro_binding->alias) {
|
|
142562
|
+
binding = macro_binding;
|
|
142563
|
+
} else {
|
|
142564
|
+
binding = bind_context.GetBinding(table_name, error_message);
|
|
142565
|
+
}
|
|
142566
|
+
if (!binding) {
|
|
142567
|
+
return false;
|
|
142568
|
+
}
|
|
142569
|
+
if (!schema_name.empty()) {
|
|
142570
|
+
auto table_entry = binding->GetTableEntry();
|
|
142571
|
+
if (!table_entry) {
|
|
142572
|
+
return false;
|
|
142573
|
+
}
|
|
142574
|
+
if (table_entry->schema->name != schema_name || table_entry->name != table_name) {
|
|
142575
|
+
return false;
|
|
142576
|
+
}
|
|
142577
|
+
}
|
|
142578
|
+
if (!binding->HasMatchingBinding(column_name)) {
|
|
142579
|
+
error_message = binding->ColumnNotFoundError(column_name);
|
|
142580
|
+
return false;
|
|
142581
|
+
}
|
|
142582
|
+
return true;
|
|
142583
|
+
}
|
|
142584
|
+
|
|
142286
142585
|
string Binder::FormatError(ParsedExpression &expr_context, const string &message) {
|
|
142287
142586
|
return FormatError(expr_context.query_location, message);
|
|
142288
142587
|
}
|
|
@@ -143374,13 +143673,13 @@ string AlterBinder::UnsupportedAggregateMessage() {
|
|
|
143374
143673
|
}
|
|
143375
143674
|
|
|
143376
143675
|
BindResult AlterBinder::BindColumn(ColumnRefExpression &colref) {
|
|
143377
|
-
if (
|
|
143378
|
-
|
|
143379
|
-
table.name);
|
|
143676
|
+
if (colref.column_names.size() > 1) {
|
|
143677
|
+
return BindQualifiedColumnName(colref, table.name);
|
|
143380
143678
|
}
|
|
143381
|
-
auto idx = table.GetColumnIndex(colref.
|
|
143679
|
+
auto idx = table.GetColumnIndex(colref.column_names[0], true);
|
|
143382
143680
|
if (idx == INVALID_INDEX) {
|
|
143383
|
-
throw BinderException("Table does not contain column %s referenced in alter statement!",
|
|
143681
|
+
throw BinderException("Table does not contain column %s referenced in alter statement!",
|
|
143682
|
+
colref.column_names[0]);
|
|
143384
143683
|
}
|
|
143385
143684
|
bound_columns.push_back(idx);
|
|
143386
143685
|
return BindResult(make_unique<BoundReferenceExpression>(table.columns[idx].type, bound_columns.size() - 1));
|
|
@@ -143394,9 +143693,9 @@ BindResult AlterBinder::BindColumn(ColumnRefExpression &colref) {
|
|
|
143394
143693
|
|
|
143395
143694
|
namespace duckdb {
|
|
143396
143695
|
|
|
143397
|
-
CheckBinder::CheckBinder(Binder &binder, ClientContext &context, string
|
|
143696
|
+
CheckBinder::CheckBinder(Binder &binder, ClientContext &context, string table_p, vector<ColumnDefinition> &columns,
|
|
143398
143697
|
unordered_set<column_t> &bound_columns)
|
|
143399
|
-
: ExpressionBinder(binder, context), table(move(
|
|
143698
|
+
: ExpressionBinder(binder, context), table(move(table_p)), columns(columns), bound_columns(bound_columns) {
|
|
143400
143699
|
target_type = LogicalType::INTEGER;
|
|
143401
143700
|
}
|
|
143402
143701
|
|
|
@@ -143418,18 +143717,29 @@ string CheckBinder::UnsupportedAggregateMessage() {
|
|
|
143418
143717
|
return "aggregate functions are not allowed in check constraints";
|
|
143419
143718
|
}
|
|
143420
143719
|
|
|
143720
|
+
BindResult ExpressionBinder::BindQualifiedColumnName(ColumnRefExpression &colref, const string &table_name) {
|
|
143721
|
+
idx_t struct_start = 0;
|
|
143722
|
+
if (colref.column_names[0] == table_name) {
|
|
143723
|
+
struct_start++;
|
|
143724
|
+
}
|
|
143725
|
+
auto result = make_unique_base<ParsedExpression, ColumnRefExpression>(colref.column_names.back());
|
|
143726
|
+
for (idx_t i = struct_start; i + 1 < colref.column_names.size(); i++) {
|
|
143727
|
+
result = CreateStructExtract(move(result), colref.column_names[i]);
|
|
143728
|
+
}
|
|
143729
|
+
return BindExpression(&result, 0);
|
|
143730
|
+
}
|
|
143731
|
+
|
|
143421
143732
|
BindResult CheckBinder::BindCheckColumn(ColumnRefExpression &colref) {
|
|
143422
|
-
if (
|
|
143423
|
-
|
|
143424
|
-
table);
|
|
143733
|
+
if (colref.column_names.size() > 1) {
|
|
143734
|
+
return BindQualifiedColumnName(colref, table);
|
|
143425
143735
|
}
|
|
143426
143736
|
for (idx_t i = 0; i < columns.size(); i++) {
|
|
143427
|
-
if (colref.
|
|
143737
|
+
if (colref.column_names[0] == columns[i].name) {
|
|
143428
143738
|
bound_columns.insert(i);
|
|
143429
143739
|
return BindResult(make_unique<BoundReferenceExpression>(columns[i].type, i));
|
|
143430
143740
|
}
|
|
143431
143741
|
}
|
|
143432
|
-
throw BinderException("Table does not contain column %s referenced in check constraint!", colref.
|
|
143742
|
+
throw BinderException("Table does not contain column %s referenced in check constraint!", colref.column_names[0]);
|
|
143433
143743
|
}
|
|
143434
143744
|
|
|
143435
143745
|
} // namespace duckdb
|
|
@@ -143447,11 +143757,11 @@ ColumnAliasBinder::ColumnAliasBinder(BoundSelectNode &node, const unordered_map<
|
|
|
143447
143757
|
|
|
143448
143758
|
BindResult ColumnAliasBinder::BindAlias(ExpressionBinder &enclosing_binder, ColumnRefExpression &expr, idx_t depth,
|
|
143449
143759
|
bool root_expression) {
|
|
143450
|
-
if (
|
|
143760
|
+
if (expr.IsQualified()) {
|
|
143451
143761
|
return BindResult(StringUtil::Format("Alias %s cannot be qualified.", expr.ToString()));
|
|
143452
143762
|
}
|
|
143453
143763
|
|
|
143454
|
-
auto alias_entry = alias_map.find(expr.
|
|
143764
|
+
auto alias_entry = alias_map.find(expr.column_names[0]);
|
|
143455
143765
|
if (alias_entry == alias_map.end()) {
|
|
143456
143766
|
return BindResult(StringUtil::Format("Alias %s is not found.", expr.ToString()));
|
|
143457
143767
|
}
|
|
@@ -143581,13 +143891,13 @@ BindResult GroupBinder::BindColumnRef(ColumnRefExpression &colref) {
|
|
|
143581
143891
|
// first try to bind to the base columns (original tables)
|
|
143582
143892
|
auto result = ExpressionBinder::BindExpression(colref, 0);
|
|
143583
143893
|
if (result.HasError()) {
|
|
143584
|
-
|
|
143585
|
-
// check if refers to an alias in the select clause
|
|
143586
|
-
auto alias_name = colref.column_name;
|
|
143587
|
-
if (!colref.table_name.empty()) {
|
|
143894
|
+
if (colref.IsQualified()) {
|
|
143588
143895
|
// explicit table name: not an alias reference
|
|
143589
143896
|
return result;
|
|
143590
143897
|
}
|
|
143898
|
+
// failed to bind the column and the node is the root expression with depth = 0
|
|
143899
|
+
// check if refers to an alias in the select clause
|
|
143900
|
+
auto alias_name = colref.column_names[0];
|
|
143591
143901
|
auto entry = alias_map.find(alias_name);
|
|
143592
143902
|
if (entry == alias_map.end()) {
|
|
143593
143903
|
// no matching alias found
|
|
@@ -143754,11 +144064,11 @@ unique_ptr<Expression> OrderBinder::Bind(unique_ptr<ParsedExpression> expr) {
|
|
|
143754
144064
|
// check if we can bind it to an alias in the select list
|
|
143755
144065
|
auto &colref = (ColumnRefExpression &)*expr;
|
|
143756
144066
|
// if there is an explicit table name we can't bind to an alias
|
|
143757
|
-
if (
|
|
144067
|
+
if (colref.IsQualified()) {
|
|
143758
144068
|
break;
|
|
143759
144069
|
}
|
|
143760
144070
|
// check the alias list
|
|
143761
|
-
auto entry = alias_map.find(colref.
|
|
144071
|
+
auto entry = alias_map.find(colref.column_names[0]);
|
|
143762
144072
|
if (entry != alias_map.end()) {
|
|
143763
144073
|
// it does! point it to that entry
|
|
143764
144074
|
return CreateProjectionReference(*expr, entry->second);
|
|
@@ -143775,7 +144085,7 @@ unique_ptr<Expression> OrderBinder::Bind(unique_ptr<ParsedExpression> expr) {
|
|
|
143775
144085
|
// general case
|
|
143776
144086
|
// first bind the table names of this entry
|
|
143777
144087
|
for (auto &binder : binders) {
|
|
143778
|
-
ExpressionBinder::
|
|
144088
|
+
ExpressionBinder::QualifyColumnNames(*binder, expr);
|
|
143779
144089
|
}
|
|
143780
144090
|
// first check if the ORDER BY clause already points to an entry in the projection list
|
|
143781
144091
|
auto entry = projection_map.find(expr.get());
|
|
@@ -143898,8 +144208,8 @@ idx_t SelectBinder::TryBindGroup(ParsedExpression &expr, idx_t depth) {
|
|
|
143898
144208
|
// first check the group alias map, if expr is a ColumnRefExpression
|
|
143899
144209
|
if (expr.type == ExpressionType::COLUMN_REF) {
|
|
143900
144210
|
auto &colref = (ColumnRefExpression &)expr;
|
|
143901
|
-
if (colref.
|
|
143902
|
-
auto alias_entry = info.alias_map.find(colref.
|
|
144211
|
+
if (!colref.IsQualified()) {
|
|
144212
|
+
auto alias_entry = info.alias_map.find(colref.column_names[0]);
|
|
143903
144213
|
if (alias_entry != info.alias_map.end()) {
|
|
143904
144214
|
// found entry!
|
|
143905
144215
|
return alias_entry->second;
|
|
@@ -143934,7 +144244,7 @@ BindResult SelectBinder::BindGroupingFunction(OperatorExpression &op, idx_t dept
|
|
|
143934
144244
|
vector<idx_t> group_indexes;
|
|
143935
144245
|
group_indexes.reserve(op.children.size());
|
|
143936
144246
|
for (auto &child : op.children) {
|
|
143937
|
-
ExpressionBinder::
|
|
144247
|
+
ExpressionBinder::QualifyColumnNames(binder, child);
|
|
143938
144248
|
auto idx = TryBindGroup(*child, depth);
|
|
143939
144249
|
if (idx == INVALID_INDEX) {
|
|
143940
144250
|
return BindResult(binder.FormatError(
|
|
@@ -144104,7 +144414,7 @@ bool ExpressionBinder::BindCorrelatedColumns(unique_ptr<ParsedExpression> &expr)
|
|
|
144104
144414
|
bool success = false;
|
|
144105
144415
|
while (!active_binders.empty()) {
|
|
144106
144416
|
auto &next_binder = active_binders.back();
|
|
144107
|
-
ExpressionBinder::
|
|
144417
|
+
ExpressionBinder::QualifyColumnNames(next_binder->binder, expr);
|
|
144108
144418
|
auto bind_result = next_binder->Bind(&expr, depth);
|
|
144109
144419
|
if (bind_result.empty()) {
|
|
144110
144420
|
success = true;
|
|
@@ -144265,33 +144575,6 @@ string ExpressionBinder::Bind(unique_ptr<ParsedExpression> *expr, idx_t depth, b
|
|
|
144265
144575
|
}
|
|
144266
144576
|
}
|
|
144267
144577
|
|
|
144268
|
-
void ExpressionBinder::BindTableNames(Binder &binder, ParsedExpression &expr, unordered_map<string, idx_t> *alias_map) {
|
|
144269
|
-
if (expr.type == ExpressionType::COLUMN_REF) {
|
|
144270
|
-
auto &colref = (ColumnRefExpression &)expr;
|
|
144271
|
-
if (colref.table_name.empty()) {
|
|
144272
|
-
// no table name: find a binding that contains this
|
|
144273
|
-
if (binder.macro_binding != nullptr && binder.macro_binding->HasMatchingBinding(colref.column_name)) {
|
|
144274
|
-
// macro parameters get priority
|
|
144275
|
-
colref.table_name = binder.macro_binding->alias;
|
|
144276
|
-
} else {
|
|
144277
|
-
colref.table_name = binder.bind_context.GetMatchingBinding(colref.column_name);
|
|
144278
|
-
}
|
|
144279
|
-
}
|
|
144280
|
-
binder.bind_context.BindColumn(colref, 0);
|
|
144281
|
-
} else if (expr.type == ExpressionType::POSITIONAL_REFERENCE) {
|
|
144282
|
-
auto &ref = (PositionalReferenceExpression &)expr;
|
|
144283
|
-
if (ref.alias.empty()) {
|
|
144284
|
-
string table_name, column_name;
|
|
144285
|
-
auto error = binder.bind_context.BindColumn(ref, table_name, column_name);
|
|
144286
|
-
if (error.empty()) {
|
|
144287
|
-
ref.alias = column_name;
|
|
144288
|
-
}
|
|
144289
|
-
}
|
|
144290
|
-
}
|
|
144291
|
-
ParsedExpressionIterator::EnumerateChildren(
|
|
144292
|
-
expr, [&](const ParsedExpression &child) { BindTableNames(binder, (ParsedExpression &)child, alias_map); });
|
|
144293
|
-
}
|
|
144294
|
-
|
|
144295
144578
|
} // namespace duckdb
|
|
144296
144579
|
|
|
144297
144580
|
|
|
@@ -145354,6 +145637,7 @@ bool LogicalFilter::SplitPredicates(vector<unique_ptr<Expression>> &expressions)
|
|
|
145354
145637
|
|
|
145355
145638
|
|
|
145356
145639
|
|
|
145640
|
+
|
|
145357
145641
|
namespace duckdb {
|
|
145358
145642
|
|
|
145359
145643
|
LogicalGet::LogicalGet(idx_t table_index, TableFunction function, unique_ptr<FunctionData> bind_data,
|
|
@@ -145366,6 +145650,10 @@ string LogicalGet::GetName() const {
|
|
|
145366
145650
|
return StringUtil::Upper(function.name);
|
|
145367
145651
|
}
|
|
145368
145652
|
|
|
145653
|
+
TableCatalogEntry *LogicalGet::GetTable() const {
|
|
145654
|
+
return TableScanFunction::GetTableEntry(function, bind_data.get());
|
|
145655
|
+
}
|
|
145656
|
+
|
|
145369
145657
|
string LogicalGet::ParamsToString() const {
|
|
145370
145658
|
string result;
|
|
145371
145659
|
for (auto &kv : table_filters.filters) {
|
|
@@ -146405,16 +146693,27 @@ bool Binding::TryGetBindingIndex(const string &column_name, column_t &result) {
|
|
|
146405
146693
|
return false;
|
|
146406
146694
|
}
|
|
146407
146695
|
|
|
146696
|
+
column_t Binding::GetBindingIndex(const string &column_name) {
|
|
146697
|
+
column_t result;
|
|
146698
|
+
if (!TryGetBindingIndex(column_name, result)) {
|
|
146699
|
+
throw InternalException("Binding index for column \"%s\" not found", column_name);
|
|
146700
|
+
}
|
|
146701
|
+
return result;
|
|
146702
|
+
}
|
|
146703
|
+
|
|
146408
146704
|
bool Binding::HasMatchingBinding(const string &column_name) {
|
|
146409
146705
|
column_t result;
|
|
146410
146706
|
return TryGetBindingIndex(column_name, result);
|
|
146411
146707
|
}
|
|
146412
146708
|
|
|
146709
|
+
string Binding::ColumnNotFoundError(const string &column_name) const {
|
|
146710
|
+
return StringUtil::Format("Values list \"%s\" does not have a column named \"%s\"", alias, column_name);
|
|
146711
|
+
}
|
|
146712
|
+
|
|
146413
146713
|
BindResult Binding::Bind(ColumnRefExpression &colref, idx_t depth) {
|
|
146414
146714
|
column_t column_index;
|
|
146415
|
-
if (!TryGetBindingIndex(colref.
|
|
146416
|
-
return BindResult(
|
|
146417
|
-
colref.column_name.c_str()));
|
|
146715
|
+
if (!TryGetBindingIndex(colref.GetColumnName(), column_index)) {
|
|
146716
|
+
return BindResult(ColumnNotFoundError(colref.GetColumnName()));
|
|
146418
146717
|
}
|
|
146419
146718
|
ColumnBinding binding;
|
|
146420
146719
|
binding.table_index = index;
|
|
@@ -146426,6 +146725,10 @@ BindResult Binding::Bind(ColumnRefExpression &colref, idx_t depth) {
|
|
|
146426
146725
|
return BindResult(make_unique<BoundColumnRefExpression>(colref.GetName(), sql_type, binding, depth));
|
|
146427
146726
|
}
|
|
146428
146727
|
|
|
146728
|
+
TableCatalogEntry *Binding::GetTableEntry() {
|
|
146729
|
+
return nullptr;
|
|
146730
|
+
}
|
|
146731
|
+
|
|
146429
146732
|
TableBinding::TableBinding(const string &alias, vector<LogicalType> types_p, vector<string> names_p, LogicalGet &get,
|
|
146430
146733
|
idx_t index, bool add_row_id)
|
|
146431
146734
|
: Binding(alias, move(types_p), move(names_p), index), get(get) {
|
|
@@ -146437,10 +146740,10 @@ TableBinding::TableBinding(const string &alias, vector<LogicalType> types_p, vec
|
|
|
146437
146740
|
}
|
|
146438
146741
|
|
|
146439
146742
|
BindResult TableBinding::Bind(ColumnRefExpression &colref, idx_t depth) {
|
|
146743
|
+
auto &column_name = colref.GetColumnName();
|
|
146440
146744
|
column_t column_index;
|
|
146441
|
-
if (!TryGetBindingIndex(
|
|
146442
|
-
return BindResult(
|
|
146443
|
-
colref.column_name));
|
|
146745
|
+
if (!TryGetBindingIndex(column_name, column_index)) {
|
|
146746
|
+
return BindResult(ColumnNotFoundError(column_name));
|
|
146444
146747
|
}
|
|
146445
146748
|
// fetch the type of the column
|
|
146446
146749
|
LogicalType col_type;
|
|
@@ -146474,15 +146777,22 @@ BindResult TableBinding::Bind(ColumnRefExpression &colref, idx_t depth) {
|
|
|
146474
146777
|
return BindResult(make_unique<BoundColumnRefExpression>(colref.GetName(), col_type, binding, depth));
|
|
146475
146778
|
}
|
|
146476
146779
|
|
|
146780
|
+
TableCatalogEntry *TableBinding::GetTableEntry() {
|
|
146781
|
+
return get.GetTable();
|
|
146782
|
+
}
|
|
146783
|
+
|
|
146784
|
+
string TableBinding::ColumnNotFoundError(const string &column_name) const {
|
|
146785
|
+
return StringUtil::Format("Table \"%s\" does not have a column named \"%s\"", alias, column_name);
|
|
146786
|
+
}
|
|
146787
|
+
|
|
146477
146788
|
MacroBinding::MacroBinding(vector<LogicalType> types_p, vector<string> names_p, string macro_name_p)
|
|
146478
|
-
: Binding(
|
|
146789
|
+
: Binding(MacroBinding::MACRO_NAME, move(types_p), move(names_p), -1), macro_name(move(macro_name_p)) {
|
|
146479
146790
|
}
|
|
146480
146791
|
|
|
146481
146792
|
BindResult MacroBinding::Bind(ColumnRefExpression &colref, idx_t depth) {
|
|
146482
146793
|
column_t column_index;
|
|
146483
|
-
if (!TryGetBindingIndex(colref.
|
|
146484
|
-
|
|
146485
|
-
StringUtil::Format("Macro \"%s\" does not have a parameter named \"%s\"", macro_name, colref.column_name));
|
|
146794
|
+
if (!TryGetBindingIndex(colref.GetColumnName(), column_index)) {
|
|
146795
|
+
throw InternalException("Column %s not found in macro", colref.GetColumnName());
|
|
146486
146796
|
}
|
|
146487
146797
|
ColumnBinding binding;
|
|
146488
146798
|
binding.table_index = index;
|
|
@@ -146494,8 +146804,8 @@ BindResult MacroBinding::Bind(ColumnRefExpression &colref, idx_t depth) {
|
|
|
146494
146804
|
|
|
146495
146805
|
unique_ptr<ParsedExpression> MacroBinding::ParamToArg(ColumnRefExpression &colref) {
|
|
146496
146806
|
column_t column_index;
|
|
146497
|
-
if (!TryGetBindingIndex(colref.
|
|
146498
|
-
throw
|
|
146807
|
+
if (!TryGetBindingIndex(colref.GetColumnName(), column_index)) {
|
|
146808
|
+
throw InternalException("Column %s not found in macro", colref.GetColumnName());
|
|
146499
146809
|
}
|
|
146500
146810
|
auto arg = arguments[column_index]->Copy();
|
|
146501
146811
|
arg->alias = colref.alias;
|
|
@@ -153469,7 +153779,7 @@ string ValidityStatistics::ToString() {
|
|
|
153469
153779
|
|
|
153470
153780
|
namespace duckdb {
|
|
153471
153781
|
|
|
153472
|
-
const uint64_t VERSION_NUMBER =
|
|
153782
|
+
const uint64_t VERSION_NUMBER = 28;
|
|
153473
153783
|
|
|
153474
153784
|
} // namespace duckdb
|
|
153475
153785
|
|