1#include "duckdb/function/table/system_functions.hpp"
2
3#include "duckdb/catalog/catalog.hpp"
4#include "duckdb/catalog/catalog_entry/schema_catalog_entry.hpp"
5#include "duckdb/catalog/catalog_entry/sequence_catalog_entry.hpp"
6#include "duckdb/common/exception.hpp"
7#include "duckdb/main/client_context.hpp"
8#include "duckdb/main/client_data.hpp"
9
10namespace duckdb {
11
12struct DuckDBSequencesData : public GlobalTableFunctionState {
13 DuckDBSequencesData() : offset(0) {
14 }
15
16 vector<reference<SequenceCatalogEntry>> entries;
17 idx_t offset;
18};
19
20static unique_ptr<FunctionData> DuckDBSequencesBind(ClientContext &context, TableFunctionBindInput &input,
21 vector<LogicalType> &return_types, vector<string> &names) {
22 names.emplace_back(args: "database_name");
23 return_types.emplace_back(args: LogicalType::VARCHAR);
24
25 names.emplace_back(args: "database_oid");
26 return_types.emplace_back(args: LogicalType::BIGINT);
27
28 names.emplace_back(args: "schema_name");
29 return_types.emplace_back(args: LogicalType::VARCHAR);
30
31 names.emplace_back(args: "schema_oid");
32 return_types.emplace_back(args: LogicalType::BIGINT);
33
34 names.emplace_back(args: "sequence_name");
35 return_types.emplace_back(args: LogicalType::VARCHAR);
36
37 names.emplace_back(args: "sequence_oid");
38 return_types.emplace_back(args: LogicalType::BIGINT);
39
40 names.emplace_back(args: "temporary");
41 return_types.emplace_back(args: LogicalType::BOOLEAN);
42
43 names.emplace_back(args: "start_value");
44 return_types.emplace_back(args: LogicalType::BIGINT);
45
46 names.emplace_back(args: "min_value");
47 return_types.emplace_back(args: LogicalType::BIGINT);
48
49 names.emplace_back(args: "max_value");
50 return_types.emplace_back(args: LogicalType::BIGINT);
51
52 names.emplace_back(args: "increment_by");
53 return_types.emplace_back(args: LogicalType::BIGINT);
54
55 names.emplace_back(args: "cycle");
56 return_types.emplace_back(args: LogicalType::BOOLEAN);
57
58 names.emplace_back(args: "last_value");
59 return_types.emplace_back(args: LogicalType::BIGINT);
60
61 names.emplace_back(args: "sql");
62 return_types.emplace_back(args: LogicalType::VARCHAR);
63
64 return nullptr;
65}
66
67unique_ptr<GlobalTableFunctionState> DuckDBSequencesInit(ClientContext &context, TableFunctionInitInput &input) {
68 auto result = make_uniq<DuckDBSequencesData>();
69
70 // scan all the schemas for tables and collect themand collect them
71 auto schemas = Catalog::GetAllSchemas(context);
72 for (auto &schema : schemas) {
73 schema.get().Scan(context, type: CatalogType::SEQUENCE_ENTRY,
74 callback: [&](CatalogEntry &entry) { result->entries.push_back(x: entry.Cast<SequenceCatalogEntry>()); });
75 };
76 return std::move(result);
77}
78
79void DuckDBSequencesFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) {
80 auto &data = data_p.global_state->Cast<DuckDBSequencesData>();
81 if (data.offset >= data.entries.size()) {
82 // finished returning values
83 return;
84 }
85 // start returning values
86 // either fill up the chunk or return all the remaining columns
87 idx_t count = 0;
88 while (data.offset < data.entries.size() && count < STANDARD_VECTOR_SIZE) {
89 auto &seq = data.entries[data.offset++].get();
90
91 // return values:
92 idx_t col = 0;
93 // database_name, VARCHAR
94 output.SetValue(col_idx: col++, index: count, val: seq.catalog.GetName());
95 // database_oid, BIGINT
96 output.SetValue(col_idx: col++, index: count, val: Value::BIGINT(value: seq.catalog.GetOid()));
97 // schema_name, VARCHAR
98 output.SetValue(col_idx: col++, index: count, val: Value(seq.schema.name));
99 // schema_oid, BIGINT
100 output.SetValue(col_idx: col++, index: count, val: Value::BIGINT(value: seq.schema.oid));
101 // sequence_name, VARCHAR
102 output.SetValue(col_idx: col++, index: count, val: Value(seq.name));
103 // sequence_oid, BIGINT
104 output.SetValue(col_idx: col++, index: count, val: Value::BIGINT(value: seq.oid));
105 // temporary, BOOLEAN
106 output.SetValue(col_idx: col++, index: count, val: Value::BOOLEAN(value: seq.temporary));
107 // start_value, BIGINT
108 output.SetValue(col_idx: col++, index: count, val: Value::BIGINT(value: seq.start_value));
109 // min_value, BIGINT
110 output.SetValue(col_idx: col++, index: count, val: Value::BIGINT(value: seq.min_value));
111 // max_value, BIGINT
112 output.SetValue(col_idx: col++, index: count, val: Value::BIGINT(value: seq.max_value));
113 // increment_by, BIGINT
114 output.SetValue(col_idx: col++, index: count, val: Value::BIGINT(value: seq.increment));
115 // cycle, BOOLEAN
116 output.SetValue(col_idx: col++, index: count, val: Value::BOOLEAN(value: seq.cycle));
117 // last_value, BIGINT
118 output.SetValue(col_idx: col++, index: count, val: seq.usage_count == 0 ? Value() : Value::BOOLEAN(value: seq.last_value));
119 // sql, LogicalType::VARCHAR
120 output.SetValue(col_idx: col++, index: count, val: Value(seq.ToSQL()));
121
122 count++;
123 }
124 output.SetCardinality(count);
125}
126
127void DuckDBSequencesFun::RegisterFunction(BuiltinFunctions &set) {
128 set.AddFunction(
129 function: TableFunction("duckdb_sequences", {}, DuckDBSequencesFunction, DuckDBSequencesBind, DuckDBSequencesInit));
130}
131
132} // namespace duckdb
133