|
8 | 8 | #include "duckdb/main/extension_util.hpp" |
9 | 9 | #include <duckdb/parser/parsed_data/create_scalar_function_info.hpp> |
10 | 10 |
|
| 11 | + |
11 | 12 | namespace duckdb { |
12 | 13 |
|
13 | | -inline void ParseTablesScalarFun(DataChunk &args, ExpressionState &state, Vector &result) { |
14 | | - auto &name_vector = args.data[0]; |
15 | | - UnaryExecutor::Execute<string_t, string_t>( |
16 | | - name_vector, result, args.size(), |
17 | | - [&](string_t name) { |
18 | | - return StringVector::AddString(result, "ParseTables "+name.GetString()+" 🐥"); |
19 | | - }); |
| 14 | +struct ParseTablesState : public GlobalTableFunctionState { |
| 15 | + idx_t row = 0; |
| 16 | +}; |
| 17 | + |
| 18 | +struct TableRefResult { |
| 19 | + string schema; |
| 20 | + string table; |
| 21 | + string context; |
| 22 | +}; |
| 23 | + |
| 24 | +// BIND function: runs during query planning to decide output schema |
| 25 | +static unique_ptr<FunctionData> Bind(ClientContext &context, |
| 26 | + TableFunctionBindInput &input, |
| 27 | + vector<LogicalType> &return_types, |
| 28 | + vector<string> &names) { |
| 29 | + return_types = {LogicalType::VARCHAR, LogicalType::VARCHAR, LogicalType::VARCHAR}; |
| 30 | + // schema name, table name, usage context (from, join, cte, etc) |
| 31 | + names = {"schema", "table", "context"}; |
| 32 | + return nullptr; |
| 33 | +} |
| 34 | + |
| 35 | +// INIT function: runs before table function execution |
| 36 | +static unique_ptr<GlobalTableFunctionState> MyInit(ClientContext &context, |
| 37 | + TableFunctionInitInput &input) { |
| 38 | + return make_uniq<ParseTablesState>(); |
20 | 39 | } |
21 | 40 |
|
| 41 | +// EXECUTE function: produces rows |
| 42 | +static void MyFunc(ClientContext &context, |
| 43 | + TableFunctionInput &data, |
| 44 | + DataChunk &output) { |
| 45 | + |
| 46 | + auto &state = (ParseTablesState &)*data.global_state; |
| 47 | + |
| 48 | + std::cout << "row: " << state.row << std::endl; |
| 49 | + |
| 50 | + if (state.row >= 1) { |
| 51 | + return; // no more rows to produce |
| 52 | + } |
| 53 | + |
| 54 | + // Example: single string column with 1 row |
| 55 | + // auto row_count = 1; |
| 56 | + output.SetCardinality(1); |
| 57 | + |
| 58 | + output.SetValue(0, 0, Value("my_schema")); |
| 59 | + output.SetValue(1, 0, Value("my_table")); |
| 60 | + output.SetValue(2, 0, Value("from")); |
| 61 | + |
| 62 | + state.row++; |
| 63 | +} |
| 64 | + |
| 65 | + |
| 66 | +// --------------------------------------------------- |
| 67 | +// EXTENSION SCAFFOLDING |
| 68 | + |
22 | 69 | static void LoadInternal(DatabaseInstance &instance) { |
23 | | - // Register a scalar function |
24 | | - auto parse_tables_scalar_function = ScalarFunction("parse_tables", {LogicalType::VARCHAR}, LogicalType::VARCHAR, ParseTablesScalarFun); |
25 | | - ExtensionUtil::RegisterFunction(instance, parse_tables_scalar_function); |
| 70 | + |
| 71 | + // Register parse_tables |
| 72 | + TableFunction tf("parse_tables", {LogicalType::VARCHAR}, MyFunc, Bind, MyInit); |
| 73 | + ExtensionUtil::RegisterFunction(instance, tf); |
26 | 74 | } |
27 | 75 |
|
28 | 76 | void ParseTablesExtension::Load(DuckDB &db) { |
|
0 commit comments