From 67b0c4aa9558465f16340db7223b4d234310abd0 Mon Sep 17 00:00:00 2001 From: Anway Durge <124391429+itzanway@users.noreply.github.com> Date: Sat, 28 Mar 2026 02:06:53 +0530 Subject: [PATCH] MDEV-39196: SELECT from information schema fails when FederatedX loses underlying table When a remote table is unavailable, FederatedX was passing a hard error back to the SQL layer, causing INFORMATION_SCHEMA queries to abort entirely. This patch intercepts the remote error in ha_federatedx::info, downgrades it to a warning using push_warning_printf, and includes the local table name in the warning message so the user knows which table is inaccessible. Signed-off-by: Anway Durge <124391429+itzanway@users.noreply.github.com> --- mysql-test/suite/federated/federated.test | 2 +- .../federated/federatedx_mdev39196.result | 22 +++++++++ .../suite/federated/federatedx_mdev39196.test | 46 +++++++++++++++++++ storage/federatedx/ha_federatedx.cc | 30 +++++++++++- 4 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 mysql-test/suite/federated/federatedx_mdev39196.result create mode 100644 mysql-test/suite/federated/federatedx_mdev39196.test diff --git a/mysql-test/suite/federated/federated.test b/mysql-test/suite/federated/federated.test index 0cb0551d23e66..2432fa2ba8c97 100644 --- a/mysql-test/suite/federated/federated.test +++ b/mysql-test/suite/federated/federated.test @@ -17,7 +17,7 @@ create table t1 (a int); --replace_result $MASTER_MYPORT MASTER_PORT eval create table fed (a int) engine=Federated CONNECTION='mysql://root@127.0.0.1:$MASTER_MYPORT/test/t1'; drop table t1; ---error 1146,1431 +--error ER_FOREIGN_DATA_SOURCE_DOESNT_EXIST,ER_GET_ERRMSG select * from fed; drop table fed; diff --git a/mysql-test/suite/federated/federatedx_mdev39196.result b/mysql-test/suite/federated/federatedx_mdev39196.result new file mode 100644 index 0000000000000..7fbc2729396a6 --- /dev/null +++ b/mysql-test/suite/federated/federatedx_mdev39196.result @@ -0,0 +1,22 @@ +# +# MDEV-39196: INFORMATION_SCHEMA query must succeed with a +# warning when a FederatedX remote table is unreachable. +# +# Verify the federated table works before dropping remote table. +SELECT * FROM federated.t1; +id name +1 foo +# Drop the remote table to simulate unreachable/missing table. +# INFORMATION_SCHEMA query must succeed and issue a warning. +SELECT TABLE_NAME, TABLE_ROWS + FROM information_schema.TABLES + WHERE TABLE_SCHEMA = 'federated' + AND TABLE_NAME = 't1'; +TABLE_NAME TABLE_ROWS +t1 1 +# Warning must be present. +SHOW WARNINGS; +Level Code Message +Warning 1430 FederatedX: Table 't1' is inaccessible: 1146 : Remote table does not exist +# Cleanup. +DROP TABLE IF EXISTS federated.t1; diff --git a/mysql-test/suite/federated/federatedx_mdev39196.test b/mysql-test/suite/federated/federatedx_mdev39196.test new file mode 100644 index 0000000000000..b7c3b062922dc --- /dev/null +++ b/mysql-test/suite/federated/federatedx_mdev39196.test @@ -0,0 +1,46 @@ +# MDEV-39196: SELECT from information_schema fails when FederatedX +# loses underlying table. +--source include/not_embedded.inc +--source include/federated.inc + +--echo # +--echo # MDEV-39196: INFORMATION_SCHEMA query must succeed with a +--echo # warning when a FederatedX remote table is unreachable. +--echo # + +--connection slave +CREATE TABLE federated.t1 ( + id INT NOT NULL, + name VARCHAR(64) +) ENGINE=MyISAM; +INSERT INTO federated.t1 VALUES (1, 'foo'); + +--connection master +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval CREATE TABLE federated.t1 ( + id INT NOT NULL, + name VARCHAR(64) +) ENGINE=FEDERATED + CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; + +--echo # Verify the federated table works before dropping remote table. +SELECT * FROM federated.t1; + +--echo # Drop the remote table to simulate unreachable/missing table. +--connection slave +DROP TABLE federated.t1; + +--connection master +--echo # INFORMATION_SCHEMA query must succeed and issue a warning. +SELECT TABLE_NAME, TABLE_ROWS + FROM information_schema.TABLES + WHERE TABLE_SCHEMA = 'federated' + AND TABLE_NAME = 't1'; + +--echo # Warning must be present. +SHOW WARNINGS; + +--echo # Cleanup. +DROP TABLE IF EXISTS federated.t1; + +--source include/federated_cleanup.inc diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc index e43ae3923165e..3e821ecabd043 100644 --- a/storage/federatedx/ha_federatedx.cc +++ b/storage/federatedx/ha_federatedx.cc @@ -3130,8 +3130,34 @@ int ha_federatedx::info(uint flag) error: if (iop && *iop) { - my_printf_error((*iop)->error_code(), "Received error: %d : %s", MYF(0), - (*iop)->error_code(), (*iop)->error_str()); + uint remote_err= (uint)(*iop)->error_code(); + /* + Only downgrade to a warning for errors that mean the remote server + or table is temporarily unreachable (connection failure, table + dropped on remote side). All other errors including access-denied + must remain hard errors so callers receive the correct errno. + */ + switch (remote_err) + { + case 2002: /* CR_CONNECTION_ERROR - can't connect via socket */ + case 2003: /* CR_CONN_HOST_ERROR - can't connect to host */ + case 2005: /* CR_UNKNOWN_HOST - unknown host */ + case 2006: /* CR_SERVER_GONE_ERROR - server has gone away */ + case 2013: /* CR_SERVER_LOST - lost connection during query */ + case 1146: /* ER_NO_SUCH_TABLE - remote table dropped */ + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_GET_ERRMSG, + "FederatedX: Table '%s' is inaccessible: " + "%d : %s", + share->table_name, + (*iop)->error_code(), + (*iop)->error_str()); + error_code= 0; + break; + default: + error_code= ER_QUERY_ON_FOREIGN_DATA_SOURCE; + break; + } } else if (remote_error_number != -1 /* error already reported */) {