1 | #include "duckdb/function/table/range.hpp" |
2 | #include "duckdb/main/client_context.hpp" |
3 | #include "duckdb/storage/storage_manager.hpp" |
4 | #include "duckdb/transaction/transaction_manager.hpp" |
5 | #include "duckdb/main/database_manager.hpp" |
6 | #include "duckdb/function/function_set.hpp" |
7 | |
8 | namespace duckdb { |
9 | |
10 | struct CheckpointBindData : public FunctionData { |
11 | explicit CheckpointBindData(optional_ptr<AttachedDatabase> db) : db(db) { |
12 | } |
13 | |
14 | optional_ptr<AttachedDatabase> db; |
15 | |
16 | public: |
17 | unique_ptr<FunctionData> Copy() const override { |
18 | return make_uniq<CheckpointBindData>(args: db); |
19 | } |
20 | |
21 | bool Equals(const FunctionData &other_p) const override { |
22 | auto &other = other_p.Cast<CheckpointBindData>(); |
23 | return db == other.db; |
24 | } |
25 | }; |
26 | |
27 | static unique_ptr<FunctionData> CheckpointBind(ClientContext &context, TableFunctionBindInput &input, |
28 | vector<LogicalType> &return_types, vector<string> &names) { |
29 | return_types.emplace_back(args: LogicalType::BOOLEAN); |
30 | names.emplace_back(args: "Success" ); |
31 | |
32 | optional_ptr<AttachedDatabase> db; |
33 | auto &db_manager = DatabaseManager::Get(db&: context); |
34 | if (!input.inputs.empty()) { |
35 | if (input.inputs[0].IsNull()) { |
36 | throw BinderException("Database cannot be NULL" ); |
37 | } |
38 | auto &db_name = StringValue::Get(value: input.inputs[0]); |
39 | db = db_manager.GetDatabase(context, name: db_name); |
40 | if (!db) { |
41 | throw BinderException("Database \"%s\" not found" , db_name); |
42 | } |
43 | } else { |
44 | db = db_manager.GetDatabase(context, name: DatabaseManager::GetDefaultDatabase(context)); |
45 | } |
46 | return make_uniq<CheckpointBindData>(args&: db); |
47 | } |
48 | |
49 | template <bool FORCE> |
50 | static void TemplatedCheckpointFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) { |
51 | auto &bind_data = data_p.bind_data->Cast<CheckpointBindData>(); |
52 | auto &transaction_manager = TransactionManager::Get(db&: *bind_data.db.get_mutable()); |
53 | transaction_manager.Checkpoint(context, force: FORCE); |
54 | } |
55 | |
56 | void CheckpointFunction::RegisterFunction(BuiltinFunctions &set) { |
57 | TableFunctionSet checkpoint("checkpoint" ); |
58 | checkpoint.AddFunction(function: TableFunction({}, TemplatedCheckpointFunction<false>, CheckpointBind)); |
59 | checkpoint.AddFunction(function: TableFunction({LogicalType::VARCHAR}, TemplatedCheckpointFunction<false>, CheckpointBind)); |
60 | set.AddFunction(set: checkpoint); |
61 | |
62 | TableFunctionSet force_checkpoint("force_checkpoint" ); |
63 | force_checkpoint.AddFunction(function: TableFunction({}, TemplatedCheckpointFunction<true>, CheckpointBind)); |
64 | force_checkpoint.AddFunction( |
65 | function: TableFunction({LogicalType::VARCHAR}, TemplatedCheckpointFunction<true>, CheckpointBind)); |
66 | set.AddFunction(set: force_checkpoint); |
67 | } |
68 | |
69 | } // namespace duckdb |
70 | |