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