Autocommit/ROLLBACK failures throw away the root cause error
Opened this issue · 0 comments
SineSwiper commented
The C code implementation has a few blocks like this:
if (
#if MYSQL_VERSION_ID >=SERVER_PREPARE_VERSION
mysql_autocommit(imp_dbh->pmysql, bool_value)
#else
mysql_real_query(imp_dbh->pmysql,
bool_value ? "SET AUTOCOMMIT=1" : "SET AUTOCOMMIT=0",
16)
#endif
)
{
do_error(dbh, TX_ERR_AUTOCOMMIT,
bool_value ?
"Turning on AutoCommit failed" :
"Turning off AutoCommit failed"
,NULL);
return TRUE; /* TRUE means we handled it - important to avoid spurious errors */
}
In these cases, the driver is attempting to send SQL via mysql_real_query
, where it could fail, but sends a generic "This thing failed" error message. The real root cause could be a connection failure, or a restart, or some other weird MySQL error message, but that's all thrown out here. Other do_error
calls look like this:
do_error(dbh, mysql_errno(imp_dbh->pmysql),
mysql_error(imp_dbh->pmysql) ,mysql_sqlstate(imp_dbh->pmysql));
This queries the state of the last error and sends that bit. This is the real error message that matters.
Another case of this design bug is here:
if (imp_dbh->has_transactions)
{
if (!DBIc_has(imp_dbh, DBIcf_AutoCommit))
#if MYSQL_VERSION_ID < SERVER_PREPARE_VERSION
if ( mysql_real_query(imp_dbh->pmysql, "ROLLBACK", 8))
#else
if (mysql_rollback(imp_dbh->pmysql))
#endif
do_error(dbh, TX_ERR_ROLLBACK,"ROLLBACK failed" ,NULL);
}
Again, it throws out the root cause error and sends out a generic error message. This code block is in dbd_db_destroy
, but dbd_db_rollback
actually sends out the right error message.