Skip to content

Commit a0194e7

Browse files
committed
add support for parse_tables scalar function returning list of structs
1 parent 1407f62 commit a0194e7

File tree

1 file changed

+57
-1
lines changed

1 file changed

+57
-1
lines changed

src/parse_tables.cpp

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)