From c05bc666554fd8daa6d47ebe3c0f6c26d7b8e4e9 Mon Sep 17 00:00:00 2001 From: Wazir Ahmed Date: Tue, 24 Feb 2026 09:12:44 +0530 Subject: [PATCH] fix: MCP variables overwritten due to incorrect flush logic `flush_mcp_variables___runtime_to_database()` ignores the `replace` parameter. The prepared statement is hardcoded to `REPLACE INTO`, so even when callers pass `replace=false` (e.g. `GenericRefreshStatistics`), the function overwrites values in memory config with stale runtime values. Signed-off-by: Wazir Ahmed --- lib/Admin_FlushVariables.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/lib/Admin_FlushVariables.cpp b/lib/Admin_FlushVariables.cpp index d7bf3ced4..6e9ccb362 100644 --- a/lib/Admin_FlushVariables.cpp +++ b/lib/Admin_FlushVariables.cpp @@ -1432,16 +1432,25 @@ void ProxySQL_Admin::flush_mcp_variables___runtime_to_database(SQLite3DB* db, bo db->execute("DELETE FROM runtime_global_variables WHERE variable_name LIKE 'mcp-%'"); } int rc; - auto [rc1, statement1_unique] = db->prepare_v2("REPLACE INTO global_variables(variable_name, variable_value) VALUES(?1, ?2)"); + const char* a; + if (replace) { + a = "REPLACE INTO global_variables(variable_name, variable_value) VALUES(?1, ?2)"; + } else { + a = "INSERT OR IGNORE INTO global_variables(variable_name, variable_value) VALUES(?1, ?2)"; + } + auto [rc1, stmt1] = db->prepare_v2(a); ASSERT_SQLITE_OK(rc1, db); - sqlite3_stmt* statement1 = statement1_unique.get(); + sqlite3_stmt* statement1 = stmt1.get(); // Only prepare runtime_global_variables statement if runtime flag is set // (table may not exist during early initialization) sqlite3_stmt* statement2 = nullptr; + stmt_unique_ptr stmt2 {}; if (runtime) { - rc = db->prepare_v2("INSERT INTO runtime_global_variables(variable_name, variable_value) VALUES(?1, ?2)", &statement2); - ASSERT_SQLITE_OK(rc, db); + auto [rc2, st2] = db->prepare_v2("INSERT INTO runtime_global_variables(variable_name, variable_value) VALUES(?1, ?2)"); + ASSERT_SQLITE_OK(rc2, db); + stmt2 = std::move(st2); + statement2 = stmt2.get(); } if (use_lock) { @@ -1474,11 +1483,6 @@ void ProxySQL_Admin::flush_mcp_variables___runtime_to_database(SQLite3DB* db, bo free(qualified_name); } - // Clean up statement2 if we allocated it - if (statement2) { - sqlite3_finalize(statement2); - } - if (use_lock) { GloMCPH->wrunlock(); }