Skip to content

Commit b070c47

Browse files
committed
Correctly handle errors when cleaning up result set
Ensure that mariadb_st_free_result_sets() function always returns correct value and ensure that callers of mariadb_st_free_result_sets() propagates error back to DBI.
1 parent 475330b commit b070c47

File tree

1 file changed

+22
-12
lines changed

1 file changed

+22
-12
lines changed

dbdimp.c

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3695,7 +3695,7 @@ AV *mariadb_db_data_sources(SV *dbh, imp_dbh_t *imp_dbh, SV *attr)
36953695
return av;
36963696
}
36973697

3698-
static int mariadb_st_free_result_sets (SV * sth, imp_sth_t * imp_sth);
3698+
static bool mariadb_st_free_result_sets(SV *sth, imp_sth_t *imp_sth);
36993699

37003700
/*
37013701
**************************************************************************
@@ -3827,7 +3827,8 @@ mariadb_st_prepare_sv(
38273827
Clean-up previous result set(s) for sth to prevent
38283828
'Commands out of sync' error
38293829
*/
3830-
mariadb_st_free_result_sets(sth, imp_sth);
3830+
if (!mariadb_st_free_result_sets(sth, imp_sth))
3831+
return 0;
38313832

38323833
if (imp_sth->use_server_side_prepare)
38333834
{
@@ -3971,18 +3972,20 @@ mariadb_st_prepare_sv(
39713972
* Inputs: sth - Statement handle
39723973
* imp_sth - driver's private statement handle
39733974
*
3974-
* Returns: 1 ok
3975-
* 0 error
3975+
* Returns: TRUE ok
3976+
* FALSE error; mariadb_dr_do_error will be called
39763977
*************************************************************************/
3977-
static int mariadb_st_free_result_sets (SV * sth, imp_sth_t * imp_sth)
3978+
static bool mariadb_st_free_result_sets(SV *sth, imp_sth_t *imp_sth)
39783979
{
39793980
dTHX;
39803981
D_imp_dbh_from_sth;
39813982
D_imp_xxh(sth);
39823983
int next_result_rc= -1;
3984+
unsigned int error;
39833985

3986+
/* No connection, nothing to clean, no error */
39843987
if (!imp_dbh->pmysql)
3985-
return 0;
3988+
return TRUE;
39863989

39873990
if (DBIc_TRACE_LEVEL(imp_xxh) >= 2)
39883991
PerlIO_printf(DBIc_LOGPIO(imp_xxh), "\t>- mariadb_st_free_result_sets\n");
@@ -4005,7 +4008,7 @@ static int mariadb_st_free_result_sets (SV * sth, imp_sth_t * imp_sth)
40054008

40064009
mariadb_dr_do_error(sth, mysql_errno(imp_dbh->pmysql), mysql_error(imp_dbh->pmysql),
40074010
mysql_sqlstate(imp_dbh->pmysql));
4008-
return 0;
4011+
return FALSE;
40094012
}
40104013
}
40114014
}
@@ -4022,14 +4025,19 @@ static int mariadb_st_free_result_sets (SV * sth, imp_sth_t * imp_sth)
40224025
PerlIO_printf(DBIc_LOGPIO(imp_xxh), "\t<- mariadb_st_free_result_sets: Error while processing multi-result set: %s\n",
40234026
mysql_error(imp_dbh->pmysql));
40244027

4025-
mariadb_dr_do_error(sth, mysql_errno(imp_dbh->pmysql), mysql_error(imp_dbh->pmysql),
4026-
mysql_sqlstate(imp_dbh->pmysql));
4028+
/* This is error for previous unfetched result ret. So do not report server errors to caller which is expecting new result set. */
4029+
error = mysql_errno(imp_dbh->pmysql);
4030+
if (error == CR_COMMANDS_OUT_OF_SYNC || error == CR_OUT_OF_MEMORY || error == CR_SERVER_GONE_ERROR || error == CR_SERVER_LOST || error == CR_UNKNOWN_ERROR)
4031+
{
4032+
mariadb_dr_do_error(sth, mysql_errno(imp_dbh->pmysql), mysql_error(imp_dbh->pmysql), mysql_sqlstate(imp_dbh->pmysql));
4033+
return FALSE;
4034+
}
40274035
}
40284036

40294037
if (DBIc_TRACE_LEVEL(imp_xxh) >= 2)
40304038
PerlIO_printf(DBIc_LOGPIO(imp_xxh), "\t<- mariadb_st_free_result_sets\n");
40314039

4032-
return 1;
4040+
return TRUE;
40334041
}
40344042

40354043

@@ -4565,7 +4573,8 @@ IV mariadb_st_execute_iv(SV* sth, imp_sth_t* imp_sth)
45654573
Clean-up previous result set(s) for sth to prevent
45664574
'Commands out of sync' error
45674575
*/
4568-
mariadb_st_free_result_sets (sth, imp_sth);
4576+
if (!mariadb_st_free_result_sets(sth, imp_sth))
4577+
return -2;
45694578

45704579
if (use_server_side_prepare)
45714580
{
@@ -5359,7 +5368,8 @@ int mariadb_st_finish(SV* sth, imp_sth_t* imp_sth) {
53595368
Clean-up previous result set(s) for sth to prevent
53605369
'Commands out of sync' error
53615370
*/
5362-
mariadb_st_free_result_sets(sth, imp_sth);
5371+
if (!mariadb_st_free_result_sets(sth, imp_sth))
5372+
return 0;
53635373
}
53645374
DBIc_ACTIVE_off(imp_sth);
53655375
if (DBIc_TRACE_LEVEL(imp_xxh) >= 2)

0 commit comments

Comments
 (0)