Skip to content

Commit 990bb34

Browse files
kamil-tekielanikic
authored andcommitted
Handle mysqli errors in more cases
Report errors autocommit, commit, rollback and mysqli_stmt_attr_set. Additionally, copy the error from conn to stmt when preparing fails, so these errors are also handled by mysqli_stmt_prepare. Closes GH-6157.
1 parent fe55fe1 commit 990bb34

File tree

3 files changed

+46
-0
lines changed

3 files changed

+46
-0
lines changed

ext/mysqli/mysqli_api.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ PHP_FUNCTION(mysqli_autocommit)
171171
MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
172172

173173
if (mysql_autocommit(mysql->mysql, (my_bool)automode)) {
174+
MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
174175
RETURN_FALSE;
175176
}
176177
RETURN_TRUE;
@@ -754,6 +755,7 @@ PHP_FUNCTION(mysqli_commit)
754755
#else
755756
if (FAIL == mysqlnd_commit(mysql->mysql, flags, name)) {
756757
#endif
758+
MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
757759
RETURN_FALSE;
758760
}
759761
RETURN_TRUE;
@@ -1989,6 +1991,7 @@ PHP_FUNCTION(mysqli_rollback)
19891991
#else
19901992
if (FAIL == mysqlnd_rollback(mysql->mysql, flags, name)) {
19911993
#endif
1994+
MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
19921995
RETURN_FALSE;
19931996
}
19941997
RETURN_TRUE;
@@ -2350,6 +2353,7 @@ PHP_FUNCTION(mysqli_stmt_attr_set)
23502353
#else
23512354
if (FAIL == mysql_stmt_attr_set(stmt->stmt, attr, mode_p)) {
23522355
#endif
2356+
MYSQLI_REPORT_STMT_ERROR(stmt->stmt);
23532357
RETURN_FALSE;
23542358
}
23552359
RETURN_TRUE;

ext/mysqli/tests/mysqli_report.phpt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,20 @@ require_once('skipifconnectfailure.inc');
4949
printf("[009] select_db should have failed\n");
5050
// mysqli_store_result() and mysqli_use_result() cannot be tested, because one would need to cause an error inside the C function to test it
5151

52+
mysqli_multi_query($link, "SELECT 1; FOO;");
53+
mysqli_autocommit($link, true);
54+
mysqli_commit($link);
55+
mysqli_rollback($link);
56+
$stmt = mysqli_stmt_init($link);
57+
mysqli_stmt_prepare($stmt, "SELECT id FROM test WHERE id > ?");
58+
while(mysqli_more_results($link)) {
59+
mysqli_next_result($link);
60+
$res = mysqli_store_result($link);
61+
}
62+
mysqli_next_result($link);
63+
64+
$stmt = mysqli_prepare($link, "SELECT 1");
65+
mysqli_stmt_attr_set($stmt, MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_FOR_UPDATE);
5266

5367
// Check that none of the above would have caused any error messages if MYSQL_REPORT_ERROR would
5468
// not have been set. If that would be the case, the test would be broken.
@@ -65,6 +79,21 @@ require_once('skipifconnectfailure.inc');
6579
mysqli_real_query($link, "FOO");
6680
mysqli_select_db($link, "Oh lord, let this be an unknown database name");
6781

82+
mysqli_multi_query($link, "SELECT 1; FOO;");
83+
mysqli_autocommit($link, true);
84+
mysqli_commit($link);
85+
mysqli_rollback($link);
86+
$stmt = mysqli_stmt_init($link);
87+
mysqli_stmt_prepare($stmt, "SELECT id FROM test WHERE id > ?");
88+
while(mysqli_more_results($link)) {
89+
mysqli_next_result($link);
90+
$res = mysqli_store_result($link);
91+
}
92+
mysqli_next_result($link);
93+
94+
$stmt = mysqli_prepare($link, "SELECT 1");
95+
mysqli_stmt_attr_set($stmt, MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_FOR_UPDATE);
96+
6897
/*
6998
Internal macro MYSQL_REPORT_STMT_ERROR
7099
*/
@@ -294,6 +323,18 @@ Warning: mysqli_prepare(): (%d/%d): You have an error in your SQL syntax; check
294323

295324
Warning: mysqli_real_query(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'FOO' at line 1 in %s on line %d
296325

326+
Warning: mysqli_autocommit(): (%s/%d): Commands out of sync; you can't run this command now in %s on line %d
327+
328+
Warning: mysqli_commit(): (%s/%d): Commands out of sync; you can't run this command now in %s on line %d
329+
330+
Warning: mysqli_rollback(): (%s/%d): Commands out of sync; you can't run this command now in %s on line %d
331+
332+
Warning: mysqli_stmt_prepare(): (%s/%d): Commands out of sync; you can't run this command now in %s on line %d
333+
334+
Warning: mysqli_store_result(): (%s/%d): You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'FOO' at line 1 in %s on line %d
335+
336+
Warning: mysqli_stmt_attr_set(): (%s/%d): Not implemented in %s on line %d
337+
297338
Warning: mysqli_kill(): processid should have positive value in %s on line %d
298339

299340
Warning: mysqli_stmt_prepare(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'FOO' at line 1 in %s on line %d

ext/mysqlnd/mysqlnd_ps.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,7 @@ MYSQLND_METHOD(mysqlnd_stmt, prepare)(MYSQLND_STMT * const s, const char * const
411411

412412
ret = conn->command->stmt_prepare(conn, query_string);
413413
if (FAIL == ret) {
414+
COPY_CLIENT_ERROR(stmt->error_info, *conn->error_info);
414415
goto fail;
415416
}
416417
}

0 commit comments

Comments
 (0)