| 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 | |