1 | #include "duckdb/function/table/sqlite_functions.hpp" |
2 | |
3 | #include "duckdb/catalog/catalog.hpp" |
4 | #include "duckdb/catalog/catalog_entry/collate_catalog_entry.hpp" |
5 | #include "duckdb/catalog/catalog_entry/schema_catalog_entry.hpp" |
6 | #include "duckdb/common/exception.hpp" |
7 | #include "duckdb/transaction/transaction.hpp" |
8 | |
9 | using namespace std; |
10 | |
11 | namespace duckdb { |
12 | |
13 | struct PragmaCollateData : public TableFunctionData { |
14 | PragmaCollateData() : initialized(false), offset(0) { |
15 | } |
16 | |
17 | bool initialized; |
18 | vector<CatalogEntry *> entries; |
19 | idx_t offset; |
20 | }; |
21 | |
22 | static unique_ptr<FunctionData> pragma_collate_bind(ClientContext &context, vector<Value> inputs, |
23 | vector<SQLType> &return_types, vector<string> &names) { |
24 | names.push_back("collname" ); |
25 | return_types.push_back(SQLType::VARCHAR); |
26 | |
27 | return make_unique<PragmaCollateData>(); |
28 | } |
29 | |
30 | static void pragma_collate_info(ClientContext &context, vector<Value> &input, DataChunk &output, |
31 | FunctionData *dataptr) { |
32 | auto &data = *((PragmaCollateData *)dataptr); |
33 | assert(input.size() == 0); |
34 | if (!data.initialized) { |
35 | // scan all the schemas |
36 | auto &transaction = Transaction::GetTransaction(context); |
37 | Catalog::GetCatalog(context).schemas.Scan(transaction, [&](CatalogEntry *entry) { |
38 | auto schema = (SchemaCatalogEntry *)entry; |
39 | schema->collations.Scan(transaction, [&](CatalogEntry *entry) { data.entries.push_back(entry); }); |
40 | }); |
41 | data.initialized = true; |
42 | } |
43 | |
44 | if (data.offset >= data.entries.size()) { |
45 | // finished returning values |
46 | return; |
47 | } |
48 | idx_t next = min(data.offset + STANDARD_VECTOR_SIZE, (idx_t)data.entries.size()); |
49 | output.SetCardinality(next - data.offset); |
50 | for (idx_t i = data.offset; i < next; i++) { |
51 | auto index = i - data.offset; |
52 | auto entry = (CollateCatalogEntry *)data.entries[i]; |
53 | |
54 | output.SetValue(0, index, Value(entry->name)); |
55 | } |
56 | |
57 | data.offset = next; |
58 | } |
59 | |
60 | void PragmaCollations::RegisterFunction(BuiltinFunctions &set) { |
61 | set.AddFunction(TableFunction("pragma_collations" , {}, pragma_collate_bind, pragma_collate_info, nullptr)); |
62 | } |
63 | |
64 | } // namespace duckdb |
65 | |