Fixup for MDEV-35446

The previous commit for fixing MDEV-35446 disabled setting
Galera errors on COM_STMT_PREPARE commands.
As a side effect, a number of tests were started to fail
due to the client receiving different error codes from the
ones expected in the test dependending on whether --ps-protocol
was used.
Also, in the case of test galera_ftwrl, it was found that
it is expected that during COM_STMT_PREPARE command, we
may perform a sync wait operation, which can fail with
LOCK_WAIT_TIMEOUT error.
The revised fix consists in anticipating the call to
wsrep_after_command_before_result(), so that we check for
BF aborts or errors during statement prepare, before sending
back the statement metadata message to client.

Signed-off-by: Julius Goryavsky <julius.goryavsky@mariadb.com>
This commit is contained in:
Daniele Sciascia 2024-12-10 15:08:38 +01:00 committed by Julius Goryavsky
parent ee2dc336d7
commit d72c5d1ace
2 changed files with 27 additions and 8 deletions

View file

@ -1165,8 +1165,7 @@ static bool wsrep_command_no_result(char command)
{
return (command == COM_STMT_FETCH ||
command == COM_STMT_SEND_LONG_DATA ||
command == COM_STMT_CLOSE ||
command == COM_STMT_PREPARE);
command == COM_STMT_CLOSE);
}
#endif /* WITH_WSREP */
#ifndef EMBEDDED_LIBRARY
@ -2444,13 +2443,23 @@ dispatch_end:
{
DEBUG_SYNC(thd, "wsrep_at_dispatch_end_before_result");
}
wsrep_after_command_before_result(thd);
if (wsrep_current_error(thd) && !wsrep_command_no_result(command))
if (thd->wsrep_cs().state() == wsrep::client_state::s_exec)
{
/* todo: Pass wsrep client state current error to override */
wsrep_override_error(thd, wsrep_current_error(thd),
wsrep_current_error_status(thd));
WSREP_LOG_THD(thd, "leave");
wsrep_after_command_before_result(thd);
if (wsrep_current_error(thd) && !wsrep_command_no_result(command))
{
/* todo: Pass wsrep client state current error to override */
wsrep_override_error(thd, wsrep_current_error(thd),
wsrep_current_error_status(thd));
WSREP_LOG_THD(thd, "leave");
}
}
else
{
/* wsrep_after_command_before_result() already called elsewhere
or not necessary to call it */
assert(thd->wsrep_cs().state() == wsrep::client_state::s_none ||
thd->wsrep_cs().state() == wsrep::client_state::s_result);
}
if (WSREP(thd))
{

View file

@ -2355,6 +2355,16 @@ static bool check_prepared_statement(Prepared_statement *stmt)
#ifdef WITH_WSREP
if (wsrep_sync_wait(thd, sql_command))
goto error;
if (!stmt->is_sql_prepare())
{
wsrep_after_command_before_result(thd);
if (wsrep_current_error(thd))
{
wsrep_override_error(thd, wsrep_current_error(thd),
wsrep_current_error_status(thd));
goto error;
}
}
#endif
switch (sql_command) {
case SQLCOM_REPLACE: