From fb5470c4117bbc3136ee5656edfd8a7463a2192a Mon Sep 17 00:00:00 2001 From: Rene Cannao Date: Sat, 11 Apr 2026 13:33:30 +0000 Subject: [PATCH] fix(mysqlx): resolve admin command aliases to canonical plugin form The MYSQLX admin command dispatch was sending the raw alias query text (e.g., 'LOAD MYSQLX USERS TO RUN') to dispatch_plugin_admin_command(), but the plugin only registered the canonical forms (e.g., 'LOAD MYSQLX USERS TO RUNTIME'). This caused all alias variants to fail with 'MYSQLX plugin is not loaded' even when the plugin was loaded and the canonical command worked. Add resolve_admin_alias_to_canonical() helper that matches an alias against a vector and returns the specified canonical command string. Update the MYSQLX dispatch block to resolve each alias to its canonical form before dispatching to the plugin manager. Tested all 20 variants (8 command groups x 2-4 aliases each): - LOAD/SAVE MYSQLX USERS/ROUTES/BACKEND_ENDPOINTS/VARIABLES - TO RUNTIME, FROM MEMORY, TO RUN, FROM MEM, TO MEMORY, FROM RUNTIME, TO MEM, FROM RUN aliases all work correctly. --- lib/Admin_Handler.cpp | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/lib/Admin_Handler.cpp b/lib/Admin_Handler.cpp index 3894da3c5..321b912f9 100644 --- a/lib/Admin_Handler.cpp +++ b/lib/Admin_Handler.cpp @@ -508,6 +508,19 @@ bool is_admin_command_or_alias(const std::vector& cmds, char *query return false; } +const char* resolve_admin_alias_to_canonical( + const std::vector& cmds, + const char* canonical, + char *query_no_space, int query_no_space_length +) { + for (std::vector::const_iterator it=cmds.begin(); it!=cmds.end(); ++it) { + if ((unsigned int)query_no_space_length==it->length() && !strncasecmp(it->c_str(), query_no_space, query_no_space_length)) { + return canonical; + } + } + return nullptr; +} + template bool FlushCommandWrapper(S* sess, const std::vector& cmds, char *query_no_space, int query_no_space_length, const string& name, const string& direction) { @@ -3880,18 +3893,18 @@ void admin_session_handler(S* sess, void *_pa, PtrSize_t *pkt) { //pthread_mutex_unlock(&admin_mutex); goto __run_query; } - if ( - is_admin_command_or_alias(LOAD_MYSQLX_USERS_FROM_MEMORY, query_no_space, query_no_space_length) || - is_admin_command_or_alias(SAVE_MYSQLX_USERS_TO_MEMORY, query_no_space, query_no_space_length) || - is_admin_command_or_alias(LOAD_MYSQLX_ROUTES_FROM_MEMORY, query_no_space, query_no_space_length) || - is_admin_command_or_alias(SAVE_MYSQLX_ROUTES_TO_MEMORY, query_no_space, query_no_space_length) || - is_admin_command_or_alias(LOAD_MYSQLX_BACKEND_ENDPOINTS_FROM_MEMORY, query_no_space, query_no_space_length) || - is_admin_command_or_alias(SAVE_MYSQLX_BACKEND_ENDPOINTS_TO_MEMORY, query_no_space, query_no_space_length) || - is_admin_command_or_alias(LOAD_MYSQLX_VARIABLES_FROM_MEMORY, query_no_space, query_no_space_length) || - is_admin_command_or_alias(SAVE_MYSQLX_VARIABLES_TO_MEMORY, query_no_space, query_no_space_length) - ) { + const char* mysqlx_canonical = nullptr; + if (!mysqlx_canonical) mysqlx_canonical = resolve_admin_alias_to_canonical(LOAD_MYSQLX_USERS_FROM_MEMORY, "LOAD MYSQLX USERS TO RUNTIME", query_no_space, query_no_space_length); + if (!mysqlx_canonical) mysqlx_canonical = resolve_admin_alias_to_canonical(SAVE_MYSQLX_USERS_TO_MEMORY, "SAVE MYSQLX USERS TO MEMORY", query_no_space, query_no_space_length); + if (!mysqlx_canonical) mysqlx_canonical = resolve_admin_alias_to_canonical(LOAD_MYSQLX_ROUTES_FROM_MEMORY, "LOAD MYSQLX ROUTES TO RUNTIME", query_no_space, query_no_space_length); + if (!mysqlx_canonical) mysqlx_canonical = resolve_admin_alias_to_canonical(SAVE_MYSQLX_ROUTES_TO_MEMORY, "SAVE MYSQLX ROUTES TO MEMORY", query_no_space, query_no_space_length); + if (!mysqlx_canonical) mysqlx_canonical = resolve_admin_alias_to_canonical(LOAD_MYSQLX_BACKEND_ENDPOINTS_FROM_MEMORY, "LOAD MYSQLX BACKEND ENDPOINTS TO RUNTIME", query_no_space, query_no_space_length); + if (!mysqlx_canonical) mysqlx_canonical = resolve_admin_alias_to_canonical(SAVE_MYSQLX_BACKEND_ENDPOINTS_TO_MEMORY, "SAVE MYSQLX BACKEND ENDPOINTS TO MEMORY", query_no_space, query_no_space_length); + if (!mysqlx_canonical) mysqlx_canonical = resolve_admin_alias_to_canonical(LOAD_MYSQLX_VARIABLES_FROM_MEMORY, "LOAD MYSQLX VARIABLES TO RUNTIME", query_no_space, query_no_space_length); + if (!mysqlx_canonical) mysqlx_canonical = resolve_admin_alias_to_canonical(SAVE_MYSQLX_VARIABLES_TO_MEMORY, "SAVE MYSQLX VARIABLES TO MEMORY", query_no_space, query_no_space_length); + if (mysqlx_canonical) { ProxySQL_Admin *SPA=(ProxySQL_Admin *)pa; - if (SPA->dispatch_plugin_admin_command(sess, query_no_space)) { + if (SPA->dispatch_plugin_admin_command(sess, mysqlx_canonical)) { run_query = false; goto __run_query; }