1#include "duckdb/function/table/system_functions.hpp"
2#include "duckdb/common/types/chunk_collection.hpp"
3#include "duckdb/main/config.hpp"
4#include "duckdb/main/client_context.hpp"
5#include "duckdb/common/enum_util.hpp"
6
7namespace duckdb {
8
9struct DuckDBSettingValue {
10 string name;
11 string value;
12 string description;
13 string input_type;
14};
15
16struct DuckDBSettingsData : public GlobalTableFunctionState {
17 DuckDBSettingsData() : offset(0) {
18 }
19
20 vector<DuckDBSettingValue> settings;
21 idx_t offset;
22};
23
24static unique_ptr<FunctionData> DuckDBSettingsBind(ClientContext &context, TableFunctionBindInput &input,
25 vector<LogicalType> &return_types, vector<string> &names) {
26 names.emplace_back(args: "name");
27 return_types.emplace_back(args: LogicalType::VARCHAR);
28
29 names.emplace_back(args: "value");
30 return_types.emplace_back(args: LogicalType::VARCHAR);
31
32 names.emplace_back(args: "description");
33 return_types.emplace_back(args: LogicalType::VARCHAR);
34
35 names.emplace_back(args: "input_type");
36 return_types.emplace_back(args: LogicalType::VARCHAR);
37
38 return nullptr;
39}
40
41unique_ptr<GlobalTableFunctionState> DuckDBSettingsInit(ClientContext &context, TableFunctionInitInput &input) {
42 auto result = make_uniq<DuckDBSettingsData>();
43
44 auto &config = DBConfig::GetConfig(context);
45 auto options_count = DBConfig::GetOptionCount();
46 for (idx_t i = 0; i < options_count; i++) {
47 auto option = DBConfig::GetOptionByIndex(index: i);
48 D_ASSERT(option);
49 DuckDBSettingValue value;
50 value.name = option->name;
51 value.value = option->get_setting(context).ToString();
52 value.description = option->description;
53 value.input_type = EnumUtil::ToString(value: option->parameter_type);
54
55 result->settings.push_back(x: std::move(value));
56 }
57 for (auto &ext_param : config.extension_parameters) {
58 Value setting_val;
59 string setting_str_val;
60 if (context.TryGetCurrentSetting(key: ext_param.first, result&: setting_val)) {
61 setting_str_val = setting_val.ToString();
62 }
63 DuckDBSettingValue value;
64 value.name = ext_param.first;
65 value.value = std::move(setting_str_val);
66 value.description = ext_param.second.description;
67 value.input_type = ext_param.second.type.ToString();
68
69 result->settings.push_back(x: std::move(value));
70 }
71 return std::move(result);
72}
73
74void DuckDBSettingsFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) {
75 auto &data = data_p.global_state->Cast<DuckDBSettingsData>();
76 if (data.offset >= data.settings.size()) {
77 // finished returning values
78 return;
79 }
80 // start returning values
81 // either fill up the chunk or return all the remaining columns
82 idx_t count = 0;
83 while (data.offset < data.settings.size() && count < STANDARD_VECTOR_SIZE) {
84 auto &entry = data.settings[data.offset++];
85
86 // return values:
87 // name, LogicalType::VARCHAR
88 output.SetValue(col_idx: 0, index: count, val: Value(entry.name));
89 // value, LogicalType::VARCHAR
90 output.SetValue(col_idx: 1, index: count, val: Value(entry.value));
91 // description, LogicalType::VARCHAR
92 output.SetValue(col_idx: 2, index: count, val: Value(entry.description));
93 // input_type, LogicalType::VARCHAR
94 output.SetValue(col_idx: 3, index: count, val: Value(entry.input_type));
95 count++;
96 }
97 output.SetCardinality(count);
98}
99
100void DuckDBSettingsFun::RegisterFunction(BuiltinFunctions &set) {
101 set.AddFunction(
102 function: TableFunction("duckdb_settings", {}, DuckDBSettingsFunction, DuckDBSettingsBind, DuckDBSettingsInit));
103}
104
105} // namespace duckdb
106