duckdb 0.3.2-dev29.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 +731 -418
- package/src/duckdb.hpp +2 -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());
|
|
@@ -98709,6 +98747,14 @@ TableFunction TableScanFunction::GetFunction() {
|
|
|
98709
98747
|
return scan_function;
|
|
98710
98748
|
}
|
|
98711
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
|
+
|
|
98712
98758
|
} // namespace duckdb
|
|
98713
98759
|
|
|
98714
98760
|
|
|
@@ -106482,10 +106528,10 @@ shared_ptr<Relation> Relation::Join(const shared_ptr<Relation> &other, const str
|
|
|
106482
106528
|
throw ParserException("Expected a single expression as join condition");
|
|
106483
106529
|
}
|
|
106484
106530
|
auto &colref = (ColumnRefExpression &)*expr;
|
|
106485
|
-
if (
|
|
106486
|
-
throw ParserException("Expected
|
|
106531
|
+
if (colref.IsQualified()) {
|
|
106532
|
+
throw ParserException("Expected unqualified column for column in USING clause");
|
|
106487
106533
|
}
|
|
106488
|
-
using_columns.push_back(colref.
|
|
106534
|
+
using_columns.push_back(colref.column_names[0]);
|
|
106489
106535
|
}
|
|
106490
106536
|
return make_shared<JoinRelation>(shared_from_this(), other, move(using_columns), type);
|
|
106491
106537
|
} else {
|
|
@@ -115103,6 +115149,10 @@ unique_ptr<NodeStatistics> StatisticsPropagator::PropagateStatistics(LogicalProj
|
|
|
115103
115149
|
unique_ptr<LogicalOperator> *node_ptr) {
|
|
115104
115150
|
// first propagate to the child
|
|
115105
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
|
+
}
|
|
115106
115156
|
|
|
115107
115157
|
// then propagate to each of the expressions
|
|
115108
115158
|
for (idx_t i = 0; i < proj.expressions.size(); i++) {
|
|
@@ -121779,53 +121829,85 @@ unique_ptr<ParsedExpression> CollateExpression::Deserialize(ExpressionType type,
|
|
|
121779
121829
|
|
|
121780
121830
|
namespace duckdb {
|
|
121781
121831
|
|
|
121782
|
-
//! Specify both the column and table name
|
|
121783
121832
|
ColumnRefExpression::ColumnRefExpression(string column_name, string table_name)
|
|
121784
|
-
:
|
|
121785
|
-
|
|
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)}) {
|
|
121786
121838
|
}
|
|
121787
121839
|
|
|
121788
|
-
ColumnRefExpression::ColumnRefExpression(string
|
|
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();
|
|
121856
|
+
}
|
|
121857
|
+
|
|
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];
|
|
121789
121861
|
}
|
|
121790
121862
|
|
|
121791
121863
|
string ColumnRefExpression::GetName() const {
|
|
121792
|
-
return !alias.empty() ? alias :
|
|
121864
|
+
return !alias.empty() ? alias : column_names.back();
|
|
121793
121865
|
}
|
|
121794
121866
|
|
|
121795
121867
|
string ColumnRefExpression::ToString() const {
|
|
121796
|
-
|
|
121797
|
-
|
|
121798
|
-
|
|
121799
|
-
|
|
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];
|
|
121800
121874
|
}
|
|
121875
|
+
return result;
|
|
121801
121876
|
}
|
|
121802
121877
|
|
|
121803
121878
|
bool ColumnRefExpression::Equals(const ColumnRefExpression *a, const ColumnRefExpression *b) {
|
|
121804
|
-
return a->
|
|
121879
|
+
return a->column_names == b->column_names;
|
|
121805
121880
|
}
|
|
121806
121881
|
|
|
121807
121882
|
hash_t ColumnRefExpression::Hash() const {
|
|
121808
121883
|
hash_t result = ParsedExpression::Hash();
|
|
121809
|
-
|
|
121884
|
+
for (auto &column_name : column_names) {
|
|
121885
|
+
result = CombineHash(result, duckdb::Hash<const char *>(column_name.c_str()));
|
|
121886
|
+
}
|
|
121810
121887
|
return result;
|
|
121811
121888
|
}
|
|
121812
121889
|
|
|
121813
121890
|
unique_ptr<ParsedExpression> ColumnRefExpression::Copy() const {
|
|
121814
|
-
auto copy = make_unique<ColumnRefExpression>(
|
|
121891
|
+
auto copy = make_unique<ColumnRefExpression>(column_names);
|
|
121815
121892
|
copy->CopyProperties(*this);
|
|
121816
121893
|
return move(copy);
|
|
121817
121894
|
}
|
|
121818
121895
|
|
|
121819
121896
|
void ColumnRefExpression::Serialize(Serializer &serializer) {
|
|
121820
121897
|
ParsedExpression::Serialize(serializer);
|
|
121821
|
-
serializer.
|
|
121822
|
-
|
|
121898
|
+
serializer.Write<idx_t>(column_names.size());
|
|
121899
|
+
for (auto &column_name : column_names) {
|
|
121900
|
+
serializer.WriteString(column_name);
|
|
121901
|
+
}
|
|
121823
121902
|
}
|
|
121824
121903
|
|
|
121825
121904
|
unique_ptr<ParsedExpression> ColumnRefExpression::Deserialize(ExpressionType type, Deserializer &source) {
|
|
121826
|
-
auto
|
|
121827
|
-
|
|
121828
|
-
|
|
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));
|
|
121829
121911
|
return move(expression);
|
|
121830
121912
|
}
|
|
121831
121913
|
|
|
@@ -123571,6 +123653,129 @@ unique_ptr<ParsedExpression> ParsedExpression::Deserialize(Deserializer &source)
|
|
|
123571
123653
|
|
|
123572
123654
|
|
|
123573
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
|
+
|
|
123574
123779
|
namespace duckdb {
|
|
123575
123780
|
|
|
123576
123781
|
void ParsedExpressionIterator::EnumerateChildren(const ParsedExpression &expression,
|
|
@@ -123706,6 +123911,91 @@ void ParsedExpressionIterator::EnumerateChildren(
|
|
|
123706
123911
|
}
|
|
123707
123912
|
}
|
|
123708
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
|
+
|
|
123709
123999
|
} // namespace duckdb
|
|
123710
124000
|
|
|
123711
124001
|
|
|
@@ -129352,52 +129642,6 @@ string QueryErrorContext::FormatErrorRecursive(const string &msg, vector<Excepti
|
|
|
129352
129642
|
return Format(statement->query, error_message, query_location);
|
|
129353
129643
|
}
|
|
129354
129644
|
|
|
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
129645
|
} // namespace duckdb
|
|
129402
129646
|
|
|
129403
129647
|
|
|
@@ -130486,41 +130730,6 @@ unique_ptr<TableRef> BaseTableRef::Copy() {
|
|
|
130486
130730
|
return move(copy);
|
|
130487
130731
|
}
|
|
130488
130732
|
} // 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
130733
|
|
|
130525
130734
|
|
|
130526
130735
|
|
|
@@ -130564,36 +130773,6 @@ unique_ptr<TableRef> CrossProductRef::Deserialize(Deserializer &source) {
|
|
|
130564
130773
|
}
|
|
130565
130774
|
|
|
130566
130775
|
} // 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
130776
|
|
|
130598
130777
|
|
|
130599
130778
|
|
|
@@ -130863,13 +131042,6 @@ unique_ptr<TableRef> TableFunctionRef::Copy() {
|
|
|
130863
131042
|
|
|
130864
131043
|
|
|
130865
131044
|
|
|
130866
|
-
|
|
130867
|
-
|
|
130868
|
-
|
|
130869
|
-
|
|
130870
|
-
|
|
130871
|
-
|
|
130872
|
-
|
|
130873
131045
|
namespace duckdb {
|
|
130874
131046
|
|
|
130875
131047
|
string TableRef::ToString() const {
|
|
@@ -131250,28 +131422,13 @@ unique_ptr<ParsedExpression> Transformer::TransformColumnRef(duckdb_libpgquery::
|
|
|
131250
131422
|
if (fields->length < 1) {
|
|
131251
131423
|
throw InternalException("Unexpected field length");
|
|
131252
131424
|
}
|
|
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!");
|
|
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);
|
|
131274
131428
|
}
|
|
131429
|
+
auto colref = make_unique<ColumnRefExpression>(move(column_names));
|
|
131430
|
+
colref->query_location = root->location;
|
|
131431
|
+
return move(colref);
|
|
131275
131432
|
}
|
|
131276
131433
|
case duckdb_libpgquery::T_PGAStar: {
|
|
131277
131434
|
return TransformStarExpression(head_node);
|
|
@@ -131942,10 +132099,10 @@ static string ExtractColumnFromLambda(ParsedExpression &expr) {
|
|
|
131942
132099
|
throw ParserException("Lambda parameter must be a column name");
|
|
131943
132100
|
}
|
|
131944
132101
|
auto &colref = (ColumnRefExpression &)expr;
|
|
131945
|
-
if (
|
|
132102
|
+
if (colref.IsQualified()) {
|
|
131946
132103
|
throw ParserException("Lambda parameter must be an unqualified name (e.g. 'x', not 'a.x')");
|
|
131947
132104
|
}
|
|
131948
|
-
return colref.
|
|
132105
|
+
return colref.column_names[0];
|
|
131949
132106
|
}
|
|
131950
132107
|
|
|
131951
132108
|
unique_ptr<ParsedExpression> Transformer::TransformLambda(duckdb_libpgquery::PGLambdaFunction *node) {
|
|
@@ -135600,6 +135757,34 @@ unordered_set<string> BindContext::GetMatchingBindings(const string &column_name
|
|
|
135600
135757
|
return result;
|
|
135601
135758
|
}
|
|
135602
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
|
+
|
|
135603
135788
|
Binding *BindContext::GetCTEBinding(const string &ctename) {
|
|
135604
135789
|
auto match = cte_bindings.find(ctename);
|
|
135605
135790
|
if (match == cte_bindings.end()) {
|
|
@@ -135625,12 +135810,12 @@ Binding *BindContext::GetBinding(const string &name, string &out_error) {
|
|
|
135625
135810
|
}
|
|
135626
135811
|
|
|
135627
135812
|
BindResult BindContext::BindColumn(ColumnRefExpression &colref, idx_t depth) {
|
|
135628
|
-
if (colref.
|
|
135629
|
-
|
|
135813
|
+
if (!colref.IsQualified()) {
|
|
135814
|
+
throw InternalException("Could not bind alias \"%s\"!", colref.GetColumnName());
|
|
135630
135815
|
}
|
|
135631
135816
|
|
|
135632
135817
|
string error;
|
|
135633
|
-
auto binding = GetBinding(colref.
|
|
135818
|
+
auto binding = GetBinding(colref.GetTableName(), error);
|
|
135634
135819
|
if (!binding) {
|
|
135635
135820
|
return BindResult(error);
|
|
135636
135821
|
}
|
|
@@ -136422,57 +136607,237 @@ BindResult ExpressionBinder::BindExpression(CollateExpression &expr, idx_t depth
|
|
|
136422
136607
|
|
|
136423
136608
|
|
|
136424
136609
|
|
|
136610
|
+
|
|
136611
|
+
|
|
136612
|
+
//===----------------------------------------------------------------------===//
|
|
136613
|
+
// DuckDB
|
|
136614
|
+
//
|
|
136615
|
+
// duckdb/planner/expression_binder/where_binder.hpp
|
|
136616
|
+
//
|
|
136617
|
+
//
|
|
136618
|
+
//===----------------------------------------------------------------------===//
|
|
136619
|
+
|
|
136620
|
+
|
|
136621
|
+
|
|
136622
|
+
|
|
136623
|
+
|
|
136425
136624
|
namespace duckdb {
|
|
136426
136625
|
|
|
136427
|
-
|
|
136428
|
-
|
|
136429
|
-
|
|
136430
|
-
|
|
136431
|
-
|
|
136432
|
-
|
|
136433
|
-
|
|
136434
|
-
|
|
136435
|
-
|
|
136436
|
-
|
|
136437
|
-
|
|
136438
|
-
|
|
136439
|
-
|
|
136440
|
-
|
|
136441
|
-
|
|
136442
|
-
|
|
136443
|
-
|
|
136444
|
-
|
|
136445
|
-
|
|
136446
|
-
|
|
136447
|
-
|
|
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));
|
|
136448
136668
|
}
|
|
136669
|
+
return move(coalesce);
|
|
136449
136670
|
}
|
|
136450
|
-
|
|
136451
|
-
|
|
136452
|
-
|
|
136453
|
-
|
|
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]);
|
|
136454
136755
|
} else {
|
|
136455
|
-
|
|
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]);
|
|
136456
136766
|
}
|
|
136457
|
-
|
|
136458
|
-
|
|
136459
|
-
|
|
136460
|
-
|
|
136461
|
-
|
|
136462
|
-
|
|
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]);
|
|
136463
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);
|
|
136464
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
|
|
136465
136827
|
// if it was a macro parameter, let macro_binding bind it to the argument
|
|
136466
|
-
BindResult result
|
|
136467
|
-
|
|
136468
|
-
|
|
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
|
+
}
|
|
136469
136834
|
if (!result.HasError()) {
|
|
136470
136835
|
BoundColumnReferenceInfo ref;
|
|
136471
|
-
ref.name = colref.
|
|
136836
|
+
ref.name = colref.column_names.back();
|
|
136472
136837
|
ref.query_location = colref.query_location;
|
|
136473
136838
|
bound_columns.push_back(move(ref));
|
|
136474
136839
|
} else {
|
|
136475
|
-
result.error = binder.FormatError(
|
|
136840
|
+
result.error = binder.FormatError(colref_p, result.error);
|
|
136476
136841
|
}
|
|
136477
136842
|
return result;
|
|
136478
136843
|
}
|
|
@@ -136770,11 +137135,6 @@ BindResult ExpressionBinder::BindExpression(LambdaExpression &expr, idx_t depth)
|
|
|
136770
137135
|
|
|
136771
137136
|
|
|
136772
137137
|
|
|
136773
|
-
|
|
136774
|
-
|
|
136775
|
-
|
|
136776
|
-
|
|
136777
|
-
|
|
136778
137138
|
namespace duckdb {
|
|
136779
137139
|
|
|
136780
137140
|
void ExpressionBinder::ReplaceMacroParametersRecursive(unique_ptr<ParsedExpression> &expr) {
|
|
@@ -136782,7 +137142,14 @@ void ExpressionBinder::ReplaceMacroParametersRecursive(unique_ptr<ParsedExpressi
|
|
|
136782
137142
|
case ExpressionClass::COLUMN_REF: {
|
|
136783
137143
|
// if expr is a parameter, replace it with its argument
|
|
136784
137144
|
auto &colref = (ColumnRefExpression &)*expr;
|
|
136785
|
-
|
|
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()));
|
|
136786
137153
|
expr = macro_binding->ParamToArg(colref);
|
|
136787
137154
|
}
|
|
136788
137155
|
return;
|
|
@@ -136790,7 +137157,8 @@ void ExpressionBinder::ReplaceMacroParametersRecursive(unique_ptr<ParsedExpressi
|
|
|
136790
137157
|
case ExpressionClass::SUBQUERY: {
|
|
136791
137158
|
// replacing parameters within a subquery is slightly different
|
|
136792
137159
|
auto &sq = ((SubqueryExpression &)*expr).subquery;
|
|
136793
|
-
|
|
137160
|
+
ParsedExpressionIterator::EnumerateQueryNodeChildren(
|
|
137161
|
+
*sq->node, [&](unique_ptr<ParsedExpression> &child) { ReplaceMacroParametersRecursive(child); });
|
|
136794
137162
|
break;
|
|
136795
137163
|
}
|
|
136796
137164
|
default: // fall through
|
|
@@ -136801,89 +137169,6 @@ void ExpressionBinder::ReplaceMacroParametersRecursive(unique_ptr<ParsedExpressi
|
|
|
136801
137169
|
*expr, [&](unique_ptr<ParsedExpression> &child) { ReplaceMacroParametersRecursive(child); });
|
|
136802
137170
|
}
|
|
136803
137171
|
|
|
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
137172
|
BindResult ExpressionBinder::BindMacro(FunctionExpression &function, MacroCatalogEntry *macro_func, idx_t depth,
|
|
136888
137173
|
unique_ptr<ParsedExpression> *expr) {
|
|
136889
137174
|
auto ¯o_def = *macro_func->function;
|
|
@@ -136902,7 +137187,7 @@ BindResult ExpressionBinder::BindMacro(FunctionExpression &function, MacroCatalo
|
|
|
136902
137187
|
for (idx_t i = 0; i < macro_def.parameters.size(); i++) {
|
|
136903
137188
|
types.push_back(LogicalType::SQLNULL);
|
|
136904
137189
|
auto ¶m = (ColumnRefExpression &)*macro_def.parameters[i];
|
|
136905
|
-
names.push_back(param.
|
|
137190
|
+
names.push_back(param.GetColumnName());
|
|
136906
137191
|
}
|
|
136907
137192
|
// default parameters
|
|
136908
137193
|
for (auto it = macro_def.default_parameters.begin(); it != macro_def.default_parameters.end(); it++) {
|
|
@@ -137826,40 +138111,6 @@ private:
|
|
|
137826
138111
|
} // namespace duckdb
|
|
137827
138112
|
|
|
137828
138113
|
|
|
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
138114
|
|
|
137864
138115
|
|
|
137865
138116
|
|
|
@@ -138050,7 +138301,7 @@ unique_ptr<BoundQueryNode> Binder::BindNode(SelectNode &statement) {
|
|
|
138050
138301
|
for (idx_t i = 0; i < statement.select_list.size(); i++) {
|
|
138051
138302
|
auto &expr = statement.select_list[i];
|
|
138052
138303
|
result->names.push_back(expr->GetName());
|
|
138053
|
-
ExpressionBinder::
|
|
138304
|
+
ExpressionBinder::QualifyColumnNames(*this, expr);
|
|
138054
138305
|
if (!expr->alias.empty()) {
|
|
138055
138306
|
alias_map[expr->alias] = i;
|
|
138056
138307
|
result->names[i] = expr->alias;
|
|
@@ -138104,7 +138355,7 @@ unique_ptr<BoundQueryNode> Binder::BindNode(SelectNode &statement) {
|
|
|
138104
138355
|
// if we wouldn't do this then (SELECT test.a FROM test GROUP BY a) would not work because "test.a" <> "a"
|
|
138105
138356
|
// hence we convert "a" -> "test.a" in the unbound expression
|
|
138106
138357
|
unbound_groups[i] = move(group_binder.unbound_expression);
|
|
138107
|
-
ExpressionBinder::
|
|
138358
|
+
ExpressionBinder::QualifyColumnNames(*this, unbound_groups[i]);
|
|
138108
138359
|
info.map[unbound_groups[i].get()] = i;
|
|
138109
138360
|
}
|
|
138110
138361
|
}
|
|
@@ -138113,7 +138364,7 @@ unique_ptr<BoundQueryNode> Binder::BindNode(SelectNode &statement) {
|
|
|
138113
138364
|
// bind the HAVING clause, if any
|
|
138114
138365
|
if (statement.having) {
|
|
138115
138366
|
HavingBinder having_binder(*this, context, *result, info, alias_map);
|
|
138116
|
-
ExpressionBinder::
|
|
138367
|
+
ExpressionBinder::QualifyColumnNames(*this, statement.having);
|
|
138117
138368
|
result->having = having_binder.Bind(statement.having);
|
|
138118
138369
|
}
|
|
138119
138370
|
|
|
@@ -139402,11 +139653,11 @@ SchemaCatalogEntry *Binder::BindCreateFunctionInfo(CreateInfo &info) {
|
|
|
139402
139653
|
// positional parameters
|
|
139403
139654
|
for (idx_t i = 0; i < base.function->parameters.size(); i++) {
|
|
139404
139655
|
auto param = (ColumnRefExpression &)*base.function->parameters[i];
|
|
139405
|
-
if (
|
|
139406
|
-
throw BinderException("Invalid parameter name '%s'", param.ToString());
|
|
139656
|
+
if (param.IsQualified()) {
|
|
139657
|
+
throw BinderException("Invalid parameter name '%s': must be unqualified", param.ToString());
|
|
139407
139658
|
}
|
|
139408
139659
|
dummy_types.push_back(LogicalType::SQLNULL);
|
|
139409
|
-
dummy_names.push_back(param.
|
|
139660
|
+
dummy_names.push_back(param.GetColumnName());
|
|
139410
139661
|
}
|
|
139411
139662
|
// default parameters
|
|
139412
139663
|
for (auto it = base.function->default_parameters.begin(); it != base.function->default_parameters.end(); it++) {
|
|
@@ -139416,6 +139667,7 @@ SchemaCatalogEntry *Binder::BindCreateFunctionInfo(CreateInfo &info) {
|
|
|
139416
139667
|
}
|
|
139417
139668
|
auto this_macro_binding = make_unique<MacroBinding>(dummy_types, dummy_names, base.name);
|
|
139418
139669
|
macro_binding = this_macro_binding.get();
|
|
139670
|
+
ExpressionBinder::QualifyColumnNames(*this, base.function->expression);
|
|
139419
139671
|
|
|
139420
139672
|
// create a copy of the expression because we do not want to alter the original
|
|
139421
139673
|
auto expression = base.function->expression->Copy();
|
|
@@ -141532,8 +141784,8 @@ bool Binder::BindFunctionParameters(vector<unique_ptr<ParsedExpression>> &expres
|
|
|
141532
141784
|
auto &comp = (ComparisonExpression &)*child;
|
|
141533
141785
|
if (comp.left->type == ExpressionType::COLUMN_REF) {
|
|
141534
141786
|
auto &colref = (ColumnRefExpression &)*comp.left;
|
|
141535
|
-
if (colref.
|
|
141536
|
-
parameter_name = colref.
|
|
141787
|
+
if (!colref.IsQualified()) {
|
|
141788
|
+
parameter_name = colref.GetColumnName();
|
|
141537
141789
|
child = move(comp.right);
|
|
141538
141790
|
}
|
|
141539
141791
|
}
|
|
@@ -142004,6 +142256,8 @@ unique_ptr<LogicalOperator> Binder::CreatePlan(BoundTableFunction &ref) {
|
|
|
142004
142256
|
|
|
142005
142257
|
|
|
142006
142258
|
|
|
142259
|
+
|
|
142260
|
+
|
|
142007
142261
|
#include <algorithm>
|
|
142008
142262
|
|
|
142009
142263
|
namespace duckdb {
|
|
@@ -142283,6 +142537,38 @@ void Binder::AddCorrelatedColumn(const CorrelatedColumnInfo &info) {
|
|
|
142283
142537
|
}
|
|
142284
142538
|
}
|
|
142285
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
|
+
|
|
142286
142572
|
string Binder::FormatError(ParsedExpression &expr_context, const string &message) {
|
|
142287
142573
|
return FormatError(expr_context.query_location, message);
|
|
142288
142574
|
}
|
|
@@ -143374,13 +143660,13 @@ string AlterBinder::UnsupportedAggregateMessage() {
|
|
|
143374
143660
|
}
|
|
143375
143661
|
|
|
143376
143662
|
BindResult AlterBinder::BindColumn(ColumnRefExpression &colref) {
|
|
143377
|
-
if (
|
|
143378
|
-
|
|
143379
|
-
table.name);
|
|
143663
|
+
if (colref.column_names.size() > 1) {
|
|
143664
|
+
return BindQualifiedColumnName(colref, table.name);
|
|
143380
143665
|
}
|
|
143381
|
-
auto idx = table.GetColumnIndex(colref.
|
|
143666
|
+
auto idx = table.GetColumnIndex(colref.column_names[0], true);
|
|
143382
143667
|
if (idx == INVALID_INDEX) {
|
|
143383
|
-
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]);
|
|
143384
143670
|
}
|
|
143385
143671
|
bound_columns.push_back(idx);
|
|
143386
143672
|
return BindResult(make_unique<BoundReferenceExpression>(table.columns[idx].type, bound_columns.size() - 1));
|
|
@@ -143394,9 +143680,9 @@ BindResult AlterBinder::BindColumn(ColumnRefExpression &colref) {
|
|
|
143394
143680
|
|
|
143395
143681
|
namespace duckdb {
|
|
143396
143682
|
|
|
143397
|
-
CheckBinder::CheckBinder(Binder &binder, ClientContext &context, string
|
|
143683
|
+
CheckBinder::CheckBinder(Binder &binder, ClientContext &context, string table_p, vector<ColumnDefinition> &columns,
|
|
143398
143684
|
unordered_set<column_t> &bound_columns)
|
|
143399
|
-
: ExpressionBinder(binder, context), table(move(
|
|
143685
|
+
: ExpressionBinder(binder, context), table(move(table_p)), columns(columns), bound_columns(bound_columns) {
|
|
143400
143686
|
target_type = LogicalType::INTEGER;
|
|
143401
143687
|
}
|
|
143402
143688
|
|
|
@@ -143418,18 +143704,29 @@ string CheckBinder::UnsupportedAggregateMessage() {
|
|
|
143418
143704
|
return "aggregate functions are not allowed in check constraints";
|
|
143419
143705
|
}
|
|
143420
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
|
+
|
|
143421
143719
|
BindResult CheckBinder::BindCheckColumn(ColumnRefExpression &colref) {
|
|
143422
|
-
if (
|
|
143423
|
-
|
|
143424
|
-
table);
|
|
143720
|
+
if (colref.column_names.size() > 1) {
|
|
143721
|
+
return BindQualifiedColumnName(colref, table);
|
|
143425
143722
|
}
|
|
143426
143723
|
for (idx_t i = 0; i < columns.size(); i++) {
|
|
143427
|
-
if (colref.
|
|
143724
|
+
if (colref.column_names[0] == columns[i].name) {
|
|
143428
143725
|
bound_columns.insert(i);
|
|
143429
143726
|
return BindResult(make_unique<BoundReferenceExpression>(columns[i].type, i));
|
|
143430
143727
|
}
|
|
143431
143728
|
}
|
|
143432
|
-
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]);
|
|
143433
143730
|
}
|
|
143434
143731
|
|
|
143435
143732
|
} // namespace duckdb
|
|
@@ -143447,11 +143744,11 @@ ColumnAliasBinder::ColumnAliasBinder(BoundSelectNode &node, const unordered_map<
|
|
|
143447
143744
|
|
|
143448
143745
|
BindResult ColumnAliasBinder::BindAlias(ExpressionBinder &enclosing_binder, ColumnRefExpression &expr, idx_t depth,
|
|
143449
143746
|
bool root_expression) {
|
|
143450
|
-
if (
|
|
143747
|
+
if (expr.IsQualified()) {
|
|
143451
143748
|
return BindResult(StringUtil::Format("Alias %s cannot be qualified.", expr.ToString()));
|
|
143452
143749
|
}
|
|
143453
143750
|
|
|
143454
|
-
auto alias_entry = alias_map.find(expr.
|
|
143751
|
+
auto alias_entry = alias_map.find(expr.column_names[0]);
|
|
143455
143752
|
if (alias_entry == alias_map.end()) {
|
|
143456
143753
|
return BindResult(StringUtil::Format("Alias %s is not found.", expr.ToString()));
|
|
143457
143754
|
}
|
|
@@ -143581,13 +143878,13 @@ BindResult GroupBinder::BindColumnRef(ColumnRefExpression &colref) {
|
|
|
143581
143878
|
// first try to bind to the base columns (original tables)
|
|
143582
143879
|
auto result = ExpressionBinder::BindExpression(colref, 0);
|
|
143583
143880
|
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()) {
|
|
143881
|
+
if (colref.IsQualified()) {
|
|
143588
143882
|
// explicit table name: not an alias reference
|
|
143589
143883
|
return result;
|
|
143590
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];
|
|
143591
143888
|
auto entry = alias_map.find(alias_name);
|
|
143592
143889
|
if (entry == alias_map.end()) {
|
|
143593
143890
|
// no matching alias found
|
|
@@ -143754,11 +144051,11 @@ unique_ptr<Expression> OrderBinder::Bind(unique_ptr<ParsedExpression> expr) {
|
|
|
143754
144051
|
// check if we can bind it to an alias in the select list
|
|
143755
144052
|
auto &colref = (ColumnRefExpression &)*expr;
|
|
143756
144053
|
// if there is an explicit table name we can't bind to an alias
|
|
143757
|
-
if (
|
|
144054
|
+
if (colref.IsQualified()) {
|
|
143758
144055
|
break;
|
|
143759
144056
|
}
|
|
143760
144057
|
// check the alias list
|
|
143761
|
-
auto entry = alias_map.find(colref.
|
|
144058
|
+
auto entry = alias_map.find(colref.column_names[0]);
|
|
143762
144059
|
if (entry != alias_map.end()) {
|
|
143763
144060
|
// it does! point it to that entry
|
|
143764
144061
|
return CreateProjectionReference(*expr, entry->second);
|
|
@@ -143775,7 +144072,7 @@ unique_ptr<Expression> OrderBinder::Bind(unique_ptr<ParsedExpression> expr) {
|
|
|
143775
144072
|
// general case
|
|
143776
144073
|
// first bind the table names of this entry
|
|
143777
144074
|
for (auto &binder : binders) {
|
|
143778
|
-
ExpressionBinder::
|
|
144075
|
+
ExpressionBinder::QualifyColumnNames(*binder, expr);
|
|
143779
144076
|
}
|
|
143780
144077
|
// first check if the ORDER BY clause already points to an entry in the projection list
|
|
143781
144078
|
auto entry = projection_map.find(expr.get());
|
|
@@ -143898,8 +144195,8 @@ idx_t SelectBinder::TryBindGroup(ParsedExpression &expr, idx_t depth) {
|
|
|
143898
144195
|
// first check the group alias map, if expr is a ColumnRefExpression
|
|
143899
144196
|
if (expr.type == ExpressionType::COLUMN_REF) {
|
|
143900
144197
|
auto &colref = (ColumnRefExpression &)expr;
|
|
143901
|
-
if (colref.
|
|
143902
|
-
auto alias_entry = info.alias_map.find(colref.
|
|
144198
|
+
if (!colref.IsQualified()) {
|
|
144199
|
+
auto alias_entry = info.alias_map.find(colref.column_names[0]);
|
|
143903
144200
|
if (alias_entry != info.alias_map.end()) {
|
|
143904
144201
|
// found entry!
|
|
143905
144202
|
return alias_entry->second;
|
|
@@ -143934,7 +144231,7 @@ BindResult SelectBinder::BindGroupingFunction(OperatorExpression &op, idx_t dept
|
|
|
143934
144231
|
vector<idx_t> group_indexes;
|
|
143935
144232
|
group_indexes.reserve(op.children.size());
|
|
143936
144233
|
for (auto &child : op.children) {
|
|
143937
|
-
ExpressionBinder::
|
|
144234
|
+
ExpressionBinder::QualifyColumnNames(binder, child);
|
|
143938
144235
|
auto idx = TryBindGroup(*child, depth);
|
|
143939
144236
|
if (idx == INVALID_INDEX) {
|
|
143940
144237
|
return BindResult(binder.FormatError(
|
|
@@ -144104,7 +144401,7 @@ bool ExpressionBinder::BindCorrelatedColumns(unique_ptr<ParsedExpression> &expr)
|
|
|
144104
144401
|
bool success = false;
|
|
144105
144402
|
while (!active_binders.empty()) {
|
|
144106
144403
|
auto &next_binder = active_binders.back();
|
|
144107
|
-
ExpressionBinder::
|
|
144404
|
+
ExpressionBinder::QualifyColumnNames(next_binder->binder, expr);
|
|
144108
144405
|
auto bind_result = next_binder->Bind(&expr, depth);
|
|
144109
144406
|
if (bind_result.empty()) {
|
|
144110
144407
|
success = true;
|
|
@@ -144265,33 +144562,6 @@ string ExpressionBinder::Bind(unique_ptr<ParsedExpression> *expr, idx_t depth, b
|
|
|
144265
144562
|
}
|
|
144266
144563
|
}
|
|
144267
144564
|
|
|
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
144565
|
} // namespace duckdb
|
|
144296
144566
|
|
|
144297
144567
|
|
|
@@ -145354,6 +145624,7 @@ bool LogicalFilter::SplitPredicates(vector<unique_ptr<Expression>> &expressions)
|
|
|
145354
145624
|
|
|
145355
145625
|
|
|
145356
145626
|
|
|
145627
|
+
|
|
145357
145628
|
namespace duckdb {
|
|
145358
145629
|
|
|
145359
145630
|
LogicalGet::LogicalGet(idx_t table_index, TableFunction function, unique_ptr<FunctionData> bind_data,
|
|
@@ -145366,6 +145637,10 @@ string LogicalGet::GetName() const {
|
|
|
145366
145637
|
return StringUtil::Upper(function.name);
|
|
145367
145638
|
}
|
|
145368
145639
|
|
|
145640
|
+
TableCatalogEntry *LogicalGet::GetTable() const {
|
|
145641
|
+
return TableScanFunction::GetTableEntry(function, bind_data.get());
|
|
145642
|
+
}
|
|
145643
|
+
|
|
145369
145644
|
string LogicalGet::ParamsToString() const {
|
|
145370
145645
|
string result;
|
|
145371
145646
|
for (auto &kv : table_filters.filters) {
|
|
@@ -146405,16 +146680,27 @@ bool Binding::TryGetBindingIndex(const string &column_name, column_t &result) {
|
|
|
146405
146680
|
return false;
|
|
146406
146681
|
}
|
|
146407
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
|
+
|
|
146408
146691
|
bool Binding::HasMatchingBinding(const string &column_name) {
|
|
146409
146692
|
column_t result;
|
|
146410
146693
|
return TryGetBindingIndex(column_name, result);
|
|
146411
146694
|
}
|
|
146412
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
|
+
|
|
146413
146700
|
BindResult Binding::Bind(ColumnRefExpression &colref, idx_t depth) {
|
|
146414
146701
|
column_t column_index;
|
|
146415
|
-
if (!TryGetBindingIndex(colref.
|
|
146416
|
-
return BindResult(
|
|
146417
|
-
colref.column_name.c_str()));
|
|
146702
|
+
if (!TryGetBindingIndex(colref.GetColumnName(), column_index)) {
|
|
146703
|
+
return BindResult(ColumnNotFoundError(colref.GetColumnName()));
|
|
146418
146704
|
}
|
|
146419
146705
|
ColumnBinding binding;
|
|
146420
146706
|
binding.table_index = index;
|
|
@@ -146426,6 +146712,10 @@ BindResult Binding::Bind(ColumnRefExpression &colref, idx_t depth) {
|
|
|
146426
146712
|
return BindResult(make_unique<BoundColumnRefExpression>(colref.GetName(), sql_type, binding, depth));
|
|
146427
146713
|
}
|
|
146428
146714
|
|
|
146715
|
+
TableCatalogEntry *Binding::GetTableEntry() {
|
|
146716
|
+
return nullptr;
|
|
146717
|
+
}
|
|
146718
|
+
|
|
146429
146719
|
TableBinding::TableBinding(const string &alias, vector<LogicalType> types_p, vector<string> names_p, LogicalGet &get,
|
|
146430
146720
|
idx_t index, bool add_row_id)
|
|
146431
146721
|
: Binding(alias, move(types_p), move(names_p), index), get(get) {
|
|
@@ -146437,10 +146727,10 @@ TableBinding::TableBinding(const string &alias, vector<LogicalType> types_p, vec
|
|
|
146437
146727
|
}
|
|
146438
146728
|
|
|
146439
146729
|
BindResult TableBinding::Bind(ColumnRefExpression &colref, idx_t depth) {
|
|
146730
|
+
auto &column_name = colref.GetColumnName();
|
|
146440
146731
|
column_t column_index;
|
|
146441
|
-
if (!TryGetBindingIndex(
|
|
146442
|
-
return BindResult(
|
|
146443
|
-
colref.column_name));
|
|
146732
|
+
if (!TryGetBindingIndex(column_name, column_index)) {
|
|
146733
|
+
return BindResult(ColumnNotFoundError(column_name));
|
|
146444
146734
|
}
|
|
146445
146735
|
// fetch the type of the column
|
|
146446
146736
|
LogicalType col_type;
|
|
@@ -146474,15 +146764,22 @@ BindResult TableBinding::Bind(ColumnRefExpression &colref, idx_t depth) {
|
|
|
146474
146764
|
return BindResult(make_unique<BoundColumnRefExpression>(colref.GetName(), col_type, binding, depth));
|
|
146475
146765
|
}
|
|
146476
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
|
+
|
|
146477
146775
|
MacroBinding::MacroBinding(vector<LogicalType> types_p, vector<string> names_p, string macro_name_p)
|
|
146478
|
-
: Binding(
|
|
146776
|
+
: Binding(MacroBinding::MACRO_NAME, move(types_p), move(names_p), -1), macro_name(move(macro_name_p)) {
|
|
146479
146777
|
}
|
|
146480
146778
|
|
|
146481
146779
|
BindResult MacroBinding::Bind(ColumnRefExpression &colref, idx_t depth) {
|
|
146482
146780
|
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));
|
|
146781
|
+
if (!TryGetBindingIndex(colref.GetColumnName(), column_index)) {
|
|
146782
|
+
throw InternalException("Column %s not found in macro", colref.GetColumnName());
|
|
146486
146783
|
}
|
|
146487
146784
|
ColumnBinding binding;
|
|
146488
146785
|
binding.table_index = index;
|
|
@@ -146494,8 +146791,8 @@ BindResult MacroBinding::Bind(ColumnRefExpression &colref, idx_t depth) {
|
|
|
146494
146791
|
|
|
146495
146792
|
unique_ptr<ParsedExpression> MacroBinding::ParamToArg(ColumnRefExpression &colref) {
|
|
146496
146793
|
column_t column_index;
|
|
146497
|
-
if (!TryGetBindingIndex(colref.
|
|
146498
|
-
throw
|
|
146794
|
+
if (!TryGetBindingIndex(colref.GetColumnName(), column_index)) {
|
|
146795
|
+
throw InternalException("Column %s not found in macro", colref.GetColumnName());
|
|
146499
146796
|
}
|
|
146500
146797
|
auto arg = arguments[column_index]->Copy();
|
|
146501
146798
|
arg->alias = colref.alias;
|
|
@@ -153469,7 +153766,7 @@ string ValidityStatistics::ToString() {
|
|
|
153469
153766
|
|
|
153470
153767
|
namespace duckdb {
|
|
153471
153768
|
|
|
153472
|
-
const uint64_t VERSION_NUMBER =
|
|
153769
|
+
const uint64_t VERSION_NUMBER = 28;
|
|
153473
153770
|
|
|
153474
153771
|
} // namespace duckdb
|
|
153475
153772
|
|
|
@@ -212146,7 +212443,6 @@ unsigned char *unicode_to_utf8(pg_wchar c, unsigned char *utf8string);
|
|
|
212146
212443
|
|
|
212147
212444
|
// max parse tree size approx 100 MB, should be enough
|
|
212148
212445
|
#define PG_MALLOC_SIZE 10240
|
|
212149
|
-
#define PG_MALLOC_LIMIT 1000
|
|
212150
212446
|
|
|
212151
212447
|
namespace duckdb_libpgquery {
|
|
212152
212448
|
|
|
@@ -212158,7 +212454,8 @@ struct pg_parser_state_str {
|
|
|
212158
212454
|
|
|
212159
212455
|
size_t malloc_pos;
|
|
212160
212456
|
size_t malloc_ptr_idx;
|
|
212161
|
-
char
|
|
212457
|
+
char **malloc_ptrs;
|
|
212458
|
+
size_t malloc_ptr_size;
|
|
212162
212459
|
};
|
|
212163
212460
|
|
|
212164
212461
|
static __thread parser_state pg_parser_state;
|
|
@@ -212168,8 +212465,13 @@ __thread PGNode *duckdb_newNodeMacroHolder;
|
|
|
212168
212465
|
#endif
|
|
212169
212466
|
|
|
212170
212467
|
static void allocate_new(parser_state *state, size_t n) {
|
|
212171
|
-
if (state->malloc_ptr_idx
|
|
212172
|
-
|
|
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;
|
|
212173
212475
|
}
|
|
212174
212476
|
if (n < PG_MALLOC_SIZE) {
|
|
212175
212477
|
n = PG_MALLOC_SIZE;
|
|
@@ -212200,6 +212502,8 @@ void pg_parser_init() {
|
|
|
212200
212502
|
pg_parser_state.pg_err_code = PGUNDEFINED;
|
|
212201
212503
|
pg_parser_state.pg_err_msg[0] = '\0';
|
|
212202
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);
|
|
212203
212507
|
pg_parser_state.malloc_ptr_idx = 0;
|
|
212204
212508
|
allocate_new(&pg_parser_state, 1);
|
|
212205
212509
|
}
|
|
@@ -212209,8 +212513,16 @@ void pg_parser_parse(const char *query, parse_result *res) {
|
|
|
212209
212513
|
try {
|
|
212210
212514
|
res->parse_tree = duckdb_libpgquery::raw_parser(query);
|
|
212211
212515
|
res->success = pg_parser_state.pg_err_code == PGUNDEFINED;
|
|
212212
|
-
} catch (
|
|
212516
|
+
} catch (std::exception &ex) {
|
|
212213
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';
|
|
212214
212526
|
}
|
|
212215
212527
|
res->error_message = pg_parser_state.pg_err_msg;
|
|
212216
212528
|
res->error_location = pg_parser_state.pg_err_pos;
|
|
@@ -212224,6 +212536,7 @@ void pg_parser_cleanup() {
|
|
|
212224
212536
|
pg_parser_state.malloc_ptrs[ptr_idx] = nullptr;
|
|
212225
212537
|
}
|
|
212226
212538
|
}
|
|
212539
|
+
free(pg_parser_state.malloc_ptrs);
|
|
212227
212540
|
}
|
|
212228
212541
|
|
|
212229
212542
|
int ereport(int code, ...) {
|