@@ -261,6 +261,54 @@ static void ParseTablesScalarFunction(DataChunk &args, ExpressionState &state, V
261261 });
262262}
263263
264+ static void ParseTablesScalarFunction_struct (DataChunk &args, ExpressionState &state, Vector &result) {
265+ UnaryExecutor::Execute<string_t , list_entry_t >(args.data [0 ], result, args.size (),
266+ [&result](string_t query) -> list_entry_t {
267+ // Parse the SQL query and extract table names
268+ auto query_string = query.GetString ();
269+ std::vector<TableRefResult> parsed_tables;
270+ ExtractTablesFromSQL (query_string, parsed_tables);
271+
272+ auto current_size = ListVector::GetListSize (result);
273+ auto number_of_tables = parsed_tables.size ();
274+ auto new_size = current_size + number_of_tables;
275+
276+ // Grow list vector if needed
277+ if (ListVector::GetListCapacity (result) < new_size) {
278+ ListVector::Reserve (result, new_size);
279+ }
280+
281+ // Get the struct child vector of the list
282+ auto &struct_vector = ListVector::GetEntry (result);
283+
284+ // Ensure list size is updated
285+ ListVector::SetListSize (result, new_size);
286+
287+ // Get the fields in the STRUCT
288+ auto &entries = StructVector::GetEntries (struct_vector);
289+ auto &table_entry = *entries[0 ]; // "table" field
290+ auto &schema_entry = *entries[1 ]; // "schema" field
291+ auto &context_entry = *entries[2 ]; // "context" field
292+
293+
294+ auto table_data = FlatVector::GetData<string_t >(table_entry);
295+ auto schema_data = FlatVector::GetData<string_t >(schema_entry);
296+ auto context_data = FlatVector::GetData<string_t >(context_entry);
297+
298+
299+ for (size_t i = 0 ; i < number_of_tables; i++) {
300+ const auto &table = parsed_tables[i];
301+ auto idx = current_size + i;
302+
303+ table_data[idx] = StringVector::AddStringOrBlob (table_entry, table.table );
304+ schema_data[idx] = StringVector::AddStringOrBlob (schema_entry, table.schema );
305+ context_data[idx] = StringVector::AddStringOrBlob (context_entry, ToString (table.context ));
306+ }
307+
308+ return list_entry_t (current_size, number_of_tables);
309+ });
310+ }
311+
264312// Extension scaffolding
265313// ---------------------------------------------------
266314
@@ -273,11 +321,19 @@ void RegisterParseTableScalarFunction(DatabaseInstance &db) {
273321 // parse tables is overloaded, allowing for an optional boolean argument
274322 // that indicates whether to include CTEs in the result
275323 // usage: parse_tables(sql_query [, include_cte])
276- ScalarFunctionSet set (" parse_tables " );
324+ ScalarFunctionSet set (" parse_table_names " );
277325 set.AddFunction (ScalarFunction ({LogicalType::VARCHAR}, LogicalType::LIST (LogicalType::VARCHAR), ParseTablesScalarFunction));
278326 set.AddFunction (ScalarFunction ({LogicalType::VARCHAR, LogicalType::BOOLEAN}, LogicalType::LIST (LogicalType::VARCHAR), ParseTablesScalarFunction));
279327
280328 ExtensionUtil::RegisterFunction (db, set);
329+
330+ auto return_type = LogicalType::LIST (LogicalType::STRUCT ({
331+ {" schema" , LogicalType::VARCHAR},
332+ {" table" , LogicalType::VARCHAR},
333+ {" context" , LogicalType::VARCHAR}
334+ }));
335+ ScalarFunction sf (" parse_tables" , {LogicalType::VARCHAR}, return_type, ParseTablesScalarFunction_struct);
336+ ExtensionUtil::RegisterFunction (db, sf);
281337}
282338
283339} // namespace duckdb
0 commit comments