1#include "duckdb/function/table/system_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
8namespace duckdb {
9
10struct PragmaCollateData : public GlobalTableFunctionState {
11 PragmaCollateData() : offset(0) {
12 }
13
14 vector<string> entries;
15 idx_t offset;
16};
17
18static unique_ptr<FunctionData> PragmaCollateBind(ClientContext &context, TableFunctionBindInput &input,
19 vector<LogicalType> &return_types, vector<string> &names) {
20 names.emplace_back(args: "collname");
21 return_types.emplace_back(args: LogicalType::VARCHAR);
22
23 return nullptr;
24}
25
26unique_ptr<GlobalTableFunctionState> PragmaCollateInit(ClientContext &context, TableFunctionInitInput &input) {
27 auto result = make_uniq<PragmaCollateData>();
28
29 auto schemas = Catalog::GetAllSchemas(context);
30 for (auto schema : schemas) {
31 schema.get().Scan(context, type: CatalogType::COLLATION_ENTRY,
32 callback: [&](CatalogEntry &entry) { result->entries.push_back(x: entry.name); });
33 }
34 return std::move(result);
35}
36
37static void PragmaCollateFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) {
38 auto &data = data_p.global_state->Cast<PragmaCollateData>();
39 if (data.offset >= data.entries.size()) {
40 // finished returning values
41 return;
42 }
43 idx_t next = MinValue<idx_t>(a: data.offset + STANDARD_VECTOR_SIZE, b: data.entries.size());
44 output.SetCardinality(next - data.offset);
45 for (idx_t i = data.offset; i < next; i++) {
46 auto index = i - data.offset;
47 output.SetValue(col_idx: 0, index, val: Value(data.entries[i]));
48 }
49
50 data.offset = next;
51}
52
53void PragmaCollations::RegisterFunction(BuiltinFunctions &set) {
54 set.AddFunction(
55 function: TableFunction("pragma_collations", {}, PragmaCollateFunction, PragmaCollateBind, PragmaCollateInit));
56}
57
58} // namespace duckdb
59