1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// Copyright (C) 2026 ren-yamanashi
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License, version 2.0,
// as published by the Free Software Foundation.
//
// This program is designed to work with certain software (including
// but not limited to OpenSSL) that is licensed under separate terms,
// as designated in a particular file or component or in included license
// documentation. The authors of this program hereby grant you an additional
// permission to link the program and your derivative works with the
// separately licensed software that they have either included with
// the program or referenced in the documentation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, see <https://www.gnu.org/licenses/>.
// Handlerton lifecycle entry points. `rusty_init_func` is the
// plugin-manifest-declared init callback that MySQL invokes once at plugin
// load; it queries the Rust side for the engine's capabilities and wires the
// corresponding handlerton callback pointers. `rusty_deinit_func` is the
// matching unload hook (no-op today). Split out of binding.cc so the
// handler-instance binding code stays focused.
#include "binding.hpp"
#include "my_dbug.h"
#include "rust_callbacks.hpp"
// Mirrors the hand-written `HTON_CAN_RECREATE` value in `src/sys.rs`; the
// Rust accessor returns it as the zero-config default, so a drift in the
// upstream macro would silently change the flag an unregistered engine gets.
static_assert(HTON_CAN_RECREATE == (1u << 2),
"HTON_CAN_RECREATE drifted; update src/sys.rs HTON_CAN_RECREATE");
static handler *rusty_create_handler(handlerton *hton, TABLE_SHARE *table,
bool, MEM_ROOT *mem_root) {
return new (mem_root) RustHandlerBase(hton, table);
}
extern "C" int rusty_init_func(void *p) {
DBUG_TRACE;
rust__plugin_init();
auto *hton = static_cast<handlerton *>(p);
hton->state = SHOW_OPTION_YES;
hton->create = rusty_create_handler;
hton->flags = rust__hton__flags();
// Always-on hooks are wired only when an engine registers a Handlerton, so a
// zero-config engine keeps these handlerton pointers NULL as before.
if (rust__hton__is_registered()) {
rusty_hton_wire_lifecycle(hton);
rusty_hton_wire_status(hton);
rusty_hton_wire_discovery(hton);
rusty_hton_wire_notifications(hton);
rusty_hton_wire_binlog(hton);
rusty_hton_wire_drop_database(hton);
rusty_hton_wire_fk_hooks(hton);
rusty_hton_wire_misc(hton);
// commit/rollback/prepare are capability-gated: a non-NULL commit is what
// tells MySQL the engine is transactional, so only wire them when declared.
if (rust__hton__is_transactional()) {
rusty_hton_wire_transactions(hton);
// start_consistent_snapshot only makes sense on a transactional engine;
// a non-NULL pointer commits the engine to honouring snapshot reads.
rusty_hton_wire_consistent_snapshot(hton);
}
// XA recovery acts on prepared transactions, which require the engine to
// be transactional, so wire the by-xid callbacks only when both hold;
// recover stays NULL regardless.
if (rust__hton__is_transactional() && rust__hton__is_xa()) {
rusty_hton_wire_xa(hton);
}
// Savepoints live inside a transaction, so they likewise require the
// transactional capability.
if (rust__hton__is_transactional() && rust__hton__is_savepoints()) {
rusty_hton_wire_savepoints(hton);
}
// partition_flags is the only signal MySQL uses to decide the engine
// implements handler::get_partition_handler, so leave it NULL unless the
// engine explicitly opts in via the PARTITIONING capability.
if (rust__hton__is_partitioning()) {
rusty_hton_wire_partitioning(hton);
}
// Tablespace callbacks must stay NULL on a tablespace-less engine — a
// non-NULL get_tablespace makes MySQL route tablespace work here.
if (rust__hton__is_tablespaces()) {
rusty_hton_wire_tablespaces(hton);
}
// Only the storage engine acting as the data dictionary backend (today,
// just InnoDB) may declare DICT_BACKEND.
if (rust__hton__is_dict_backend()) {
rusty_hton_wire_dict(hton);
}
// SDI callbacks are only meaningful for engines that own their SDI
// store (InnoDB-style).
if (rust__hton__is_sdi()) {
rusty_hton_wire_sdi(hton);
}
// ENGINE_LOG opt-in publishes the engine's redo / transaction log to
// performance_schema.log_status; a non-log engine keeps these NULL.
// redo_log_set_state lives under the same capability since both signal
// the engine owns a redo log surface.
if (rust__hton__is_engine_log()) {
rusty_hton_wire_engine_log(hton);
rusty_hton_wire_redo_log_set_state(hton);
}
// ENCRYPTION opt-in puts the engine on MySQL's master-key rotation path;
// non-encrypting engines keep rotate_encryption_master_key NULL.
if (rust__hton__is_encryption()) {
rusty_hton_wire_encryption(hton);
}
// SECONDARY_ENGINE opt-in connects the engine to MySQL's offload /
// hypergraph-optimizer interface (RAPID / HeatWave style); a primary
// engine keeps these NULL.
if (rust__hton__is_secondary_engine()) {
rusty_hton_wire_secondary_engine(hton);
}
// CLONE opt-in installs the clone_interface sub-struct as a unit; only
// clone-capable engines (InnoDB / clone plugin path) should declare it.
if (rust__hton__is_clone()) {
rusty_hton_wire_clone(hton);
}
// PAGE_TRACKING opt-in installs the page_track sub-struct as a unit;
// declared by engines that track changed pages for incremental backup.
if (rust__hton__is_page_tracking()) {
rusty_hton_wire_page_track(hton);
}
}
return 0;
}
extern "C" int rusty_deinit_func(void *) {
DBUG_TRACE;
return 0;
}