Skip to content

Commit

Permalink
Do not call mariadb_db_reconnect() during changing $dbh attributes wh…
Browse files Browse the repository at this point in the history
…en not needed

Currently mariadb_db_STORE_attrib() function (handler for changing dbh
attributes via $dbh->{...} = ... syntax) at its beginning calls function
mariadb_db_reconnect() to ensure that imp_dbh->pmysql connection structure
is initialized.

Change logic of mariadb_db_STORE_attrib() function to call function
mariadb_db_reconnect() only when the changing of attribute really requires
active connection.

This change fixes a problem that Perl for locatized variables is trying to
restore its original value after leaving the scope, and this is failing for
restoring the DBI attributes.

Trying to change common DBI attributes (those which first letter is upper
case) except the AutoConnect, is not handled by DBD::MariaDB driver, and
therefore DBD::MariaDB driver does not have to check if the connection is
still active.
  • Loading branch information
pali authored and choroba committed Dec 25, 2024
1 parent c3a389f commit bca1103
Showing 1 changed file with 30 additions and 8 deletions.
38 changes: 30 additions & 8 deletions dbdimp.c
Original file line number Diff line number Diff line change
Expand Up @@ -3372,14 +3372,6 @@ mariadb_db_STORE_attrib(
char *key = SvPV(keysv, kl); /* needs to process get magic */
const bool bool_value = SvTRUE_nomg(valuesv);

if (!imp_dbh->pmysql && !mariadb_db_reconnect(dbh, NULL))
{
mariadb_dr_do_error(dbh, CR_SERVER_GONE_ERROR, "MySQL server has gone away", "HY000");
if (memEQs(key, kl, "AutoCommit"))
croak_autocommit_failure(); /* does not return */
return 0;
}

if (memEQs(key, kl, "AutoCommit"))
{
bool oldval = DBIc_has(imp_dbh, DBIcf_AutoCommit) ? TRUE : FALSE;
Expand All @@ -3390,6 +3382,11 @@ mariadb_db_STORE_attrib(
/* if setting AutoCommit on ... */
if (!imp_dbh->no_autocommit_cmd)
{
if (!imp_dbh->pmysql && !mariadb_db_reconnect(dbh, NULL))
{
mariadb_dr_do_error(dbh, CR_SERVER_GONE_ERROR, "MySQL server has gone away", "HY000");
croak_autocommit_failure(); /* does not return */
}
if (
mysql_autocommit(imp_dbh->pmysql, bool_value)
)
Expand Down Expand Up @@ -3440,10 +3437,20 @@ mariadb_db_STORE_attrib(
error_nul_character(dbh, "mariadb_fabric_opt_group");
return 0;
}
if (!imp_dbh->pmysql && !mariadb_db_reconnect(dbh, NULL))
{
mariadb_dr_do_error(dbh, CR_SERVER_GONE_ERROR, "MySQL server has gone away", "HY000");
return 0;
}
mysql_options(imp_dbh->pmysql, FABRIC_OPT_GROUP, str);
}
else if (memEQs(key, kl, "mariadb_fabric_opt_default_mode"))
{
if (!imp_dbh->pmysql && !mariadb_db_reconnect(dbh, NULL))
{
mariadb_dr_do_error(dbh, CR_SERVER_GONE_ERROR, "MySQL server has gone away", "HY000");
return 0;
}
if (SvOK(valuesv)) {
STRLEN len;
const char *str = SvPV_nomg(valuesv, len);
Expand All @@ -3468,6 +3475,11 @@ mariadb_db_STORE_attrib(
mariadb_dr_do_error(dbh, CR_UNKNOWN_ERROR, "Valid settings for FABRIC_OPT_MODE are 'ro' or 'rw'", "HY000");
return 0;
}
if (!imp_dbh->pmysql && !mariadb_db_reconnect(dbh, NULL))
{
mariadb_dr_do_error(dbh, CR_SERVER_GONE_ERROR, "MySQL server has gone away", "HY000");
return 0;
}
mysql_options(imp_dbh->pmysql, FABRIC_OPT_MODE, str);
}
else if (memEQs(key, kl, "mariadb_fabric_opt_group_credentials"))
Expand All @@ -3483,6 +3495,11 @@ mariadb_db_STORE_attrib(
/* MYSQL_OPT_MAX_ALLOWED_PACKET was added in MariaDB 10.2.6 and MariaDB 10.3.1 */
UV uv = SvUV_nomg(valuesv);
unsigned long packet_size = (uv <= ULONG_MAX ? uv : ULONG_MAX);
if (!imp_dbh->pmysql && !mariadb_db_reconnect(dbh, NULL))
{
mariadb_dr_do_error(dbh, CR_SERVER_GONE_ERROR, "MySQL server has gone away", "HY000");
return 0;
}
mysql_options(imp_dbh->pmysql, MYSQL_OPT_MAX_ALLOWED_PACKET, &packet_size);
#else
/* before MySQL 5.7.9 and MariaDB 10.2.6 and MariaDB 10.3.0 it is not possible to change max_allowed_packet after connection was established */
Expand All @@ -3495,6 +3512,11 @@ mariadb_db_STORE_attrib(
{
if (!imp_dbh->connected) /* When not connected, it is handled in mariadb_dr_connect() */
return 0;
if (!imp_dbh->pmysql && !mariadb_db_reconnect(dbh, NULL))
{
mariadb_dr_do_error(dbh, CR_SERVER_GONE_ERROR, "MySQL server has gone away", "HY000");
return 0;
}
if (mysql_set_server_option(imp_dbh->pmysql, bool_value ? MYSQL_OPTION_MULTI_STATEMENTS_ON : MYSQL_OPTION_MULTI_STATEMENTS_OFF) != 0)
{
mariadb_dr_do_error(dbh, mysql_errno(imp_dbh->pmysql), mysql_error(imp_dbh->pmysql), mysql_sqlstate(imp_dbh->pmysql));
Expand Down

0 comments on commit bca1103

Please sign in to comment.