Skip to content

Commit 998cd6a

Browse files
committed
Reconnect in do() if uses on a disconnected dbh
This is because calling mysql_stmt_prepare() after calling mysql_close() is not safe and is causing segfaults when running with MariaDB 10.3 libs.
1 parent 645e985 commit 998cd6a

File tree

3 files changed

+23
-2
lines changed

3 files changed

+23
-2
lines changed

dbdimp.c

+10
Original file line numberDiff line numberDiff line change
@@ -5318,6 +5318,16 @@ int mysql_db_reconnect(SV* h)
53185318
else
53195319
imp_dbh= (imp_dbh_t*) imp_xxh;
53205320

5321+
/* reconnect a closed connection, used in do() for implicit reconnect */
5322+
if (!DBIc_has(imp_dbh, DBIcf_ACTIVE) && DBIc_has(imp_dbh, DBIcf_AutoCommit)) {
5323+
if (my_login(aTHX_ h, imp_dbh)) {
5324+
DBIc_ACTIVE_on(imp_dbh);
5325+
DBIc_set(imp_dbh, DBIcf_AutoCommit, TRUE);
5326+
return TRUE;
5327+
}
5328+
return FALSE;
5329+
}
5330+
53215331
if (mysql_errno(imp_dbh->pmysql) != CR_SERVER_GONE_ERROR &&
53225332
mysql_errno(imp_dbh->pmysql) != CR_SERVER_LOST)
53235333
/* Other error */

mysql.xs

+3
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,9 @@ do(dbh, statement, attr=Nullsv, ...)
272272
MYSQL_BIND *bind= NULL;
273273
#endif
274274
ASYNC_CHECK_XS(dbh);
275+
if ((!DBIc_has(imp_dbh, DBIcf_ACTIVE)) &&
276+
(!mysql_db_reconnect(dbh)))
277+
XSRETURN_UNDEF;
275278
#if MYSQL_VERSION_ID >= MULTIPLE_RESULT_SET_VERSION
276279
while (mysql_next_result(imp_dbh->pmysql)==0)
277280
{

t/15reconnect.t

+10-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ eval {$dbh = DBI->connect($test_dsn, $test_user, $test_password,
1616
if ($@) {
1717
plan skip_all => "no database connection";
1818
}
19-
plan tests => 8 * 2;
19+
plan tests => 13 * 2;
2020

2121
for my $mysql_server_prepare (0, 1) {
2222
$dbh= DBI->connect("$test_dsn;mysql_server_prepare=$mysql_server_prepare;mysql_server_prepare_disable_fallback=1", $test_user, $test_password,
@@ -38,5 +38,13 @@ ok($dbh->do("SELECT 1"), "implicitly reconnecting handle with 'do'");
3838

3939
ok($dbh->{Active}, "checking for reactivated handle");
4040

41-
$dbh->disconnect();
41+
ok(!($dbh->{AutoCommit} = 0), "disabling autocommit");
42+
43+
ok($dbh->disconnect(), "disconnecting active handle");
44+
45+
ok(!$dbh->{Active}, "checking for inactive handle");
46+
47+
ok(!$dbh->do("SELECT 1"), "implicitly reconnecting handle with 'do'");
48+
49+
ok(!$dbh->{Active}, "checking for reactivated handle");
4250
}

0 commit comments

Comments
 (0)