Skip to content

Commit 106e7e4

Browse files
committed
Fixed bug #70066
If we fall back to emulated prepared statements, destroy S->stmt, so the code doesn't get confused about which mode we're in.
1 parent fcfa7fd commit 106e7e4

File tree

5 files changed

+37
-11
lines changed

5 files changed

+37
-11
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ PHP NEWS
4545
(Nikita)
4646
. Fixed bug #66878 (Multiple rowsets not returned unless PDO statement object
4747
is unset()). (Nikita)
48+
. Fixed bug #70066 (Unexpected "Cannot execute queries while other unbuffered
49+
queries"). (Nikita)
4850

4951
- Phar:
5052
. Fixed bug #73809 (Phar Zip parse crash - mmap fail). (cmb)

ext/mysqlnd/mysqlnd_libmysql_compat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080
#define mysql_stmt_param_count(s) mysqlnd_stmt_param_count((s))
8181
#define mysql_stmt_num_rows(s) mysqlnd_stmt_num_rows((s))
8282
#define mysql_stmt_insert_id(s) mysqlnd_stmt_insert_id((s))
83-
#define mysql_stmt_close(s) mysqlnd_stmt_close((s))
83+
#define mysql_stmt_close(s) mysqlnd_stmt_close((s), 0)
8484
#define mysql_stmt_bind_param(s,b) mysqlnd_stmt_bind_param((s), (b))
8585
#define mysql_stmt_bind_result(s,b) mysqlnd_stmt_bind_result((s), (b))
8686
#define mysql_stmt_errno(s) mysqlnd_stmt_errno((s))

ext/pdo_mysql/mysql_driver.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -201,18 +201,17 @@ static int mysql_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len
201201
}
202202

203203
if (mysql_stmt_prepare(S->stmt, sql, sql_len)) {
204+
if (nsql) {
205+
efree(nsql);
206+
}
204207
/* TODO: might need to pull statement specific info here? */
205208
/* if the query isn't supported by the protocol, fallback to emulation */
206209
if (mysql_errno(H->server) == 1295) {
207-
if (nsql) {
208-
efree(nsql);
209-
}
210+
mysql_stmt_close(S->stmt);
211+
S->stmt = NULL;
210212
goto fallback;
211213
}
212214
pdo_mysql_error(dbh);
213-
if (nsql) {
214-
efree(nsql);
215-
}
216215
PDO_DBG_RETURN(0);
217216
}
218217
if (nsql) {

ext/pdo_mysql/mysql_statement.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,9 @@
3131
#ifdef PDO_USE_MYSQLND
3232
# define pdo_mysql_stmt_execute_prepared(stmt) pdo_mysql_stmt_execute_prepared_mysqlnd(stmt)
3333
# define pdo_free_bound_result(res) zval_ptr_dtor(res.zv)
34-
# define pdo_mysql_stmt_close(stmt) mysqlnd_stmt_close(stmt, 0)
3534
#else
3635
# define pdo_mysql_stmt_execute_prepared(stmt) pdo_mysql_stmt_execute_prepared_libmysql(stmt)
3736
# define pdo_free_bound_result(res) efree(res.buffer)
38-
# define pdo_mysql_stmt_close(stmt) mysql_stmt_close(stmt)
3937
#endif
4038

4139

@@ -56,7 +54,7 @@ static int pdo_mysql_stmt_dtor(pdo_stmt_t *stmt) /* {{{ */
5654
S->einfo.errmsg = NULL;
5755
}
5856
if (S->stmt) {
59-
pdo_mysql_stmt_close(S->stmt);
57+
mysql_stmt_close(S->stmt);
6058
S->stmt = NULL;
6159
}
6260

@@ -363,7 +361,7 @@ static int pdo_mysql_stmt_next_rowset(pdo_stmt_t *stmt) /* {{{ */
363361
}
364362

365363
#ifdef PDO_USE_MYSQLND
366-
if (!H->emulate_prepare) {
364+
if (S->stmt) {
367365
if (mysqlnd_stmt_next_result(S->stmt)) {
368366
pdo_mysql_error_stmt(stmt);
369367
S->done = 1;

ext/pdo_mysql/tests/bug70066.phpt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
Bug #70066: Unexpected "Cannot execute queries while other unbuffered queries"
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('pdo') || !extension_loaded('pdo_mysql')) die('skip not loaded');
6+
require_once(__DIR__ . DIRECTORY_SEPARATOR . 'skipif.inc');
7+
require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
8+
MySQLPDOTest::skip();
9+
?>
10+
--FILE--
11+
<?php
12+
13+
require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
14+
15+
$pdo = MySQLPDOTest::factory();
16+
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
17+
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
18+
19+
$db = $pdo->query('SELECT DATABASE()')->fetchColumn(0);
20+
// USE is not supported in the prepared statement protocol,
21+
// so this will fall back to emulation.
22+
$pdo->query('USE ' . $db);
23+
24+
?>
25+
===DONE===
26+
--EXPECT--
27+
===DONE===

0 commit comments

Comments
 (0)