11#include " parse_tables.hpp"
22#include " duckdb.hpp"
33#include " duckdb/parser/parser.hpp"
4+ #include " duckdb/parser/parser_options.hpp"
5+ #include < algorithm>
6+ #include < cctype>
47#include " duckdb/parser/statement/select_statement.hpp"
58#include " duckdb/parser/query_node/select_node.hpp"
9+ #include " duckdb/parser/query_node/cte_node.hpp"
610#include " duckdb/parser/tableref/basetableref.hpp"
711#include " duckdb/parser/tableref/joinref.hpp"
812#include " duckdb/parser/tableref/subqueryref.hpp"
9- #include " duckdb/main/extension_util.hpp"
1013#include " duckdb/function/scalar/nested_functions.hpp"
1114
12-
1315namespace duckdb {
1416
1517inline const char *ToString (TableContext context) {
@@ -128,7 +130,7 @@ static void ExtractTablesFromQueryNode(
128130 if (node.type == QueryNodeType::SELECT_NODE) {
129131 auto &select_node = (SelectNode &)node;
130132
131- // Emit CTE definitions
133+ // Handle CTE definitions
132134 for (const auto &entry : select_node.cte_map .map ) {
133135 results.push_back (TableRefResult{
134136 " " , entry.first , TableContext::CTE
@@ -142,6 +144,14 @@ static void ExtractTablesFromQueryNode(
142144 if (select_node.from_table ) {
143145 ExtractTablesFromRef (*select_node.from_table , results, context, true , &select_node.cte_map );
144146 }
147+ }
148+ // additional step necessary for duckdb v1.4.0: unwrap CTE node
149+ else if (node.type == QueryNodeType::CTE_NODE) {
150+ auto &cte_node = (CTENode &)node;
151+
152+ if (cte_node.child ) {
153+ ExtractTablesFromQueryNode (*cte_node.child , results, context, cte_map);
154+ }
145155 }
146156}
147157
@@ -152,9 +162,8 @@ static void ExtractTablesFromSQL(const std::string &sql, std::vector<TableRefRes
152162 parser.ParseQuery (sql);
153163 } catch (const ParserException &ex) {
154164 // swallow parser exceptions to make this function more robust. is_parsable can be used if needed
155- return ;
165+ return ;
156166 }
157-
158167
159168 for (auto &stmt : parser.statements ) {
160169 if (stmt->type == StatementType::SELECT_STATEMENT) {
@@ -323,19 +332,19 @@ static void IsParsableFunction(DataChunk &args, ExpressionState &state, Vector &
323332// Extension scaffolding
324333// ---------------------------------------------------
325334
326- void RegisterParseTablesFunction (DatabaseInstance &db ) {
335+ void RegisterParseTablesFunction (ExtensionLoader &loader ) {
327336 TableFunction tf (" parse_tables" , {LogicalType::VARCHAR}, ParseTablesFunction, ParseTablesBind, ParseTablesInit);
328- ExtensionUtil:: RegisterFunction (db, tf);
337+ loader. RegisterFunction (tf);
329338}
330339
331- void RegisterParseTableScalarFunction (DatabaseInstance &db ) {
340+ void RegisterParseTableScalarFunction (ExtensionLoader &loader ) {
332341 // parse_table_names is overloaded, allowing for an optional boolean argument
333342 // that indicates whether to include CTEs in the result
334343 // usage: parse_tables(sql_query [, include_cte])
335344 ScalarFunctionSet set (" parse_table_names" );
336345 set.AddFunction (ScalarFunction ({LogicalType::VARCHAR}, LogicalType::LIST (LogicalType::VARCHAR), ParseTablesScalarFunction));
337346 set.AddFunction (ScalarFunction ({LogicalType::VARCHAR, LogicalType::BOOLEAN}, LogicalType::LIST (LogicalType::VARCHAR), ParseTablesScalarFunction));
338- ExtensionUtil:: RegisterFunction (db, set);
347+ loader. RegisterFunction (set);
339348
340349 // parse_tables_struct is a scalar function that returns a list of structs
341350 auto return_type = LogicalType::LIST (LogicalType::STRUCT ({
@@ -344,11 +353,11 @@ void RegisterParseTableScalarFunction(DatabaseInstance &db) {
344353 {" context" , LogicalType::VARCHAR}
345354 }));
346355 ScalarFunction sf (" parse_tables" , {LogicalType::VARCHAR}, return_type, ParseTablesScalarFunction_struct);
347- ExtensionUtil:: RegisterFunction (db, sf);
356+ loader. RegisterFunction (sf);
348357
349358 // is_parsable is a scalar function that returns a boolean indicating whether the SQL query is parsable (no parse errors)
350359 ScalarFunction is_parsable (" is_parsable" , {LogicalType::VARCHAR}, LogicalType::BOOLEAN, IsParsableFunction);
351- ExtensionUtil:: RegisterFunction (db, is_parsable);
360+ loader. RegisterFunction (is_parsable);
352361}
353362
354363} // namespace duckdb
0 commit comments