@@ -2551,9 +2551,9 @@ IV mariadb_db_do6(SV *dbh, imp_dbh_t *imp_dbh, SV *statement_sv, SV *attribs, I3
2551
2551
bool disable_fallback_for_server_prepare = FALSE;
2552
2552
MYSQL_STMT * stmt = NULL ;
2553
2553
MYSQL_BIND * bind = NULL ;
2554
- MYSQL_RES * res ;
2555
2554
STRLEN blen ;
2556
2555
unsigned long int num_params ;
2556
+ unsigned int error ;
2557
2557
2558
2558
ASYNC_CHECK_RETURN (dbh , -2 );
2559
2559
@@ -2642,11 +2642,38 @@ IV mariadb_db_do6(SV *dbh, imp_dbh_t *imp_dbh, SV *statement_sv, SV *attribs, I3
2642
2642
imp_dbh -> async_query_in_flight = imp_dbh ;
2643
2643
}
2644
2644
2645
- while (mysql_next_result (imp_dbh -> pmysql ) == 0 )
2645
+ while ((next_result_rc = mysql_next_result (imp_dbh -> pmysql )) == 0 )
2646
+ {
2647
+ result = mysql_store_result (imp_dbh -> pmysql );
2648
+ if (!result )
2649
+ {
2650
+ if (mysql_errno (imp_dbh -> pmysql ))
2651
+ {
2652
+ mariadb_dr_do_error (dbh , mysql_errno (imp_dbh -> pmysql ), mysql_error (imp_dbh -> pmysql ), mysql_sqlstate (imp_dbh -> pmysql ));
2653
+ return -2 ;
2654
+ }
2655
+ }
2656
+ if (result )
2657
+ {
2658
+ mysql_free_result (result );
2659
+ result = NULL ;
2660
+ }
2661
+ }
2662
+
2663
+ if (next_result_rc > 0 )
2646
2664
{
2647
- res = mysql_use_result (imp_dbh -> pmysql );
2648
- if (res )
2649
- mysql_free_result (res );
2665
+ #if MYSQL_VERSION_ID < 50025
2666
+ /* Cover a protocol design error: error packet does not contain the server status.
2667
+ * Luckily, an error always aborts execution of a statement, so it is safe to turn off the flag. */
2668
+ imp_dbh -> pmysql -> server_status &= ~SERVER_MORE_RESULTS_EXISTS ;
2669
+ #endif
2670
+ /* This is error for previous unfetched result ret. So do not report server errors to caller which is expecting new result set. */
2671
+ error = mysql_errno (imp_dbh -> pmysql );
2672
+ 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 )
2673
+ {
2674
+ mariadb_dr_do_error (dbh , mysql_errno (imp_dbh -> pmysql ), mysql_error (imp_dbh -> pmysql ), mysql_sqlstate (imp_dbh -> pmysql ));
2675
+ return -2 ;
2676
+ }
2650
2677
}
2651
2678
2652
2679
if (use_server_side_prepare )
@@ -2804,7 +2831,12 @@ IV mariadb_db_do6(SV *dbh, imp_dbh_t *imp_dbh, SV *statement_sv, SV *attribs, I3
2804
2831
/* more results? -1 = no, >0 = error, 0 = yes (keep looping) */
2805
2832
while ((next_result_rc = mysql_next_result (imp_dbh -> pmysql )) == 0 )
2806
2833
{
2807
- result = mysql_use_result (imp_dbh -> pmysql );
2834
+ result = mysql_store_result (imp_dbh -> pmysql );
2835
+ if (mysql_errno (imp_dbh -> pmysql ))
2836
+ {
2837
+ next_result_rc = 1 ;
2838
+ break ;
2839
+ }
2808
2840
if (!result ) /* Next statement without result set, new insert id */
2809
2841
imp_dbh -> insertid = mysql_insert_id (imp_dbh -> pmysql );
2810
2842
if (result )
@@ -2814,6 +2846,12 @@ IV mariadb_db_do6(SV *dbh, imp_dbh_t *imp_dbh, SV *statement_sv, SV *attribs, I3
2814
2846
2815
2847
if (next_result_rc > 0 )
2816
2848
{
2849
+ #if MYSQL_VERSION_ID < 50025
2850
+ /* Cover a protocol design error: error packet does not contain the server status.
2851
+ * Luckily, an error always aborts execution of a statement, so it is safe to turn off the flag. */
2852
+ imp_dbh -> pmysql -> server_status &= ~SERVER_MORE_RESULTS_EXISTS ;
2853
+ #endif
2854
+
2817
2855
if (DBIc_DBISTATE (imp_dbh )-> debug >= 2 )
2818
2856
PerlIO_printf (DBIc_LOGPIO (imp_dbh ), "\t<- do() ERROR: %s\n" , mysql_error (imp_dbh -> pmysql ));
2819
2857
@@ -3668,7 +3706,7 @@ AV *mariadb_db_data_sources(SV *dbh, imp_dbh_t *imp_dbh, SV *attr)
3668
3706
return av ;
3669
3707
}
3670
3708
3671
- static int mariadb_st_free_result_sets (SV * sth , imp_sth_t * imp_sth );
3709
+ static bool mariadb_st_free_result_sets (SV * sth , imp_sth_t * imp_sth );
3672
3710
3673
3711
/*
3674
3712
**************************************************************************
@@ -3800,7 +3838,8 @@ mariadb_st_prepare_sv(
3800
3838
Clean-up previous result set(s) for sth to prevent
3801
3839
'Commands out of sync' error
3802
3840
*/
3803
- mariadb_st_free_result_sets (sth , imp_sth );
3841
+ if (!mariadb_st_free_result_sets (sth , imp_sth ))
3842
+ return 0 ;
3804
3843
3805
3844
if (imp_sth -> use_server_side_prepare )
3806
3845
{
@@ -3944,18 +3983,20 @@ mariadb_st_prepare_sv(
3944
3983
* Inputs: sth - Statement handle
3945
3984
* imp_sth - driver's private statement handle
3946
3985
*
3947
- * Returns: 1 ok
3948
- * 0 error
3986
+ * Returns: TRUE ok
3987
+ * FALSE error; mariadb_dr_do_error will be called
3949
3988
*************************************************************************/
3950
- static int mariadb_st_free_result_sets (SV * sth , imp_sth_t * imp_sth )
3989
+ static bool mariadb_st_free_result_sets (SV * sth , imp_sth_t * imp_sth )
3951
3990
{
3952
3991
dTHX ;
3953
3992
D_imp_dbh_from_sth ;
3954
3993
D_imp_xxh (sth );
3955
3994
int next_result_rc = -1 ;
3995
+ unsigned int error ;
3956
3996
3997
+ /* No connection, nothing to clean, no error */
3957
3998
if (!imp_dbh -> pmysql )
3958
- return 0 ;
3999
+ return TRUE ;
3959
4000
3960
4001
if (DBIc_TRACE_LEVEL (imp_xxh ) >= 2 )
3961
4002
PerlIO_printf (DBIc_LOGPIO (imp_xxh ), "\t>- mariadb_st_free_result_sets\n" );
@@ -3967,18 +4008,18 @@ static int mariadb_st_free_result_sets (SV * sth, imp_sth_t * imp_sth)
3967
4008
3968
4009
if (next_result_rc == 0 )
3969
4010
{
3970
- if (!(imp_sth -> result = mysql_use_result (imp_dbh -> pmysql )))
4011
+ if (!(imp_sth -> result = mysql_store_result (imp_dbh -> pmysql )))
3971
4012
{
3972
4013
/* Check for possible error */
3973
- if (mysql_field_count (imp_dbh -> pmysql ))
4014
+ if (mysql_errno (imp_dbh -> pmysql ))
3974
4015
{
3975
4016
if (DBIc_TRACE_LEVEL (imp_xxh ) >= 2 )
3976
4017
PerlIO_printf (DBIc_LOGPIO (imp_xxh ), "\t<- mariadb_st_free_result_sets ERROR: %s\n" ,
3977
4018
mysql_error (imp_dbh -> pmysql ));
3978
4019
3979
4020
mariadb_dr_do_error (sth , mysql_errno (imp_dbh -> pmysql ), mysql_error (imp_dbh -> pmysql ),
3980
4021
mysql_sqlstate (imp_dbh -> pmysql ));
3981
- return 0 ;
4022
+ return FALSE ;
3982
4023
}
3983
4024
}
3984
4025
}
@@ -3991,18 +4032,29 @@ static int mariadb_st_free_result_sets (SV * sth, imp_sth_t * imp_sth)
3991
4032
3992
4033
if (next_result_rc > 0 )
3993
4034
{
4035
+ #if MYSQL_VERSION_ID < 50025
4036
+ /* Cover a protocol design error: error packet does not contain the server status.
4037
+ * Luckily, an error always aborts execution of a statement, so it is safe to turn off the flag. */
4038
+ imp_dbh -> pmysql -> server_status &= ~SERVER_MORE_RESULTS_EXISTS ;
4039
+ #endif
4040
+
3994
4041
if (DBIc_TRACE_LEVEL (imp_xxh ) >= 2 )
3995
4042
PerlIO_printf (DBIc_LOGPIO (imp_xxh ), "\t<- mariadb_st_free_result_sets: Error while processing multi-result set: %s\n" ,
3996
4043
mysql_error (imp_dbh -> pmysql ));
3997
4044
3998
- mariadb_dr_do_error (sth , mysql_errno (imp_dbh -> pmysql ), mysql_error (imp_dbh -> pmysql ),
3999
- mysql_sqlstate (imp_dbh -> pmysql ));
4045
+ /* This is error for previous unfetched result ret. So do not report server errors to caller which is expecting new result set. */
4046
+ error = mysql_errno (imp_dbh -> pmysql );
4047
+ 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 )
4048
+ {
4049
+ mariadb_dr_do_error (sth , mysql_errno (imp_dbh -> pmysql ), mysql_error (imp_dbh -> pmysql ), mysql_sqlstate (imp_dbh -> pmysql ));
4050
+ return FALSE;
4051
+ }
4000
4052
}
4001
4053
4002
4054
if (DBIc_TRACE_LEVEL (imp_xxh ) >= 2 )
4003
4055
PerlIO_printf (DBIc_LOGPIO (imp_xxh ), "\t<- mariadb_st_free_result_sets\n" );
4004
4056
4005
- return 1 ;
4057
+ return TRUE ;
4006
4058
}
4007
4059
4008
4060
@@ -4083,6 +4135,11 @@ bool mariadb_st_more_results(SV* sth, imp_sth_t* imp_sth)
4083
4135
*/
4084
4136
if (next_result_return_code > 0 )
4085
4137
{
4138
+ #if MYSQL_VERSION_ID < 50025
4139
+ /* Cover a protocol design error: error packet does not contain the server status.
4140
+ * Luckily, an error always aborts execution of a statement, so it is safe to turn off the flag. */
4141
+ imp_dbh -> pmysql -> server_status &= ~SERVER_MORE_RESULTS_EXISTS ;
4142
+ #endif
4086
4143
mariadb_dr_do_error (sth , mysql_errno (imp_dbh -> pmysql ), mysql_error (imp_dbh -> pmysql ),
4087
4144
mysql_sqlstate (imp_dbh -> pmysql ));
4088
4145
@@ -4270,6 +4327,11 @@ static my_ulonglong mariadb_st_internal_execute(
4270
4327
(!mariadb_db_reconnect (h , NULL ) ||
4271
4328
(mysql_real_query (* svsock , sbuf , slen ))))
4272
4329
{
4330
+ #if MYSQL_VERSION_ID < 50025
4331
+ /* Cover a protocol design error: error packet does not contain the server status.
4332
+ * Luckily, an error always aborts execution of a statement, so it is safe to turn off the flag. */
4333
+ (* svsock )-> server_status &= ~SERVER_MORE_RESULTS_EXISTS ;
4334
+ #endif
4273
4335
rows = -1 ;
4274
4336
} else {
4275
4337
/** Store the result from the Query */
@@ -4538,7 +4600,8 @@ IV mariadb_st_execute_iv(SV* sth, imp_sth_t* imp_sth)
4538
4600
Clean-up previous result set(s) for sth to prevent
4539
4601
'Commands out of sync' error
4540
4602
*/
4541
- mariadb_st_free_result_sets (sth , imp_sth );
4603
+ if (!mariadb_st_free_result_sets (sth , imp_sth ))
4604
+ return -2 ;
4542
4605
4543
4606
if (use_server_side_prepare )
4544
4607
{
@@ -5332,7 +5395,8 @@ int mariadb_st_finish(SV* sth, imp_sth_t* imp_sth) {
5332
5395
Clean-up previous result set(s) for sth to prevent
5333
5396
'Commands out of sync' error
5334
5397
*/
5335
- mariadb_st_free_result_sets (sth , imp_sth );
5398
+ if (!mariadb_st_free_result_sets (sth , imp_sth ))
5399
+ return 0 ;
5336
5400
}
5337
5401
DBIc_ACTIVE_off (imp_sth );
5338
5402
if (DBIc_TRACE_LEVEL (imp_xxh ) >= 2 )
0 commit comments