diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2020-12-09 17:24:30 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2020-12-10 09:58:47 +0100 |
commit | f3d5877845358d011174cf87283b456cee6f7f53 (patch) | |
tree | 9160a407ac79b63f2130b5fa6bca51f83a866e1b | |
parent | 44b234a9bc589ee6c4afe3e1c386d536f750abe2 (diff) | |
download | php-git-f3d5877845358d011174cf87283b456cee6f7f53.tar.gz |
Backport fix for bug #70066
Given the number of duplicates this bug report had, it seems
worthwhile to fix this on PHP-7.4 as well.
Cherry-pick of 106e7e4bca7c0fd975eb219b18e3c34957ba8657.
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | ext/mysqlnd/mysqlnd_libmysql_compat.h | 2 | ||||
-rw-r--r-- | ext/pdo_mysql/mysql_driver.c | 11 | ||||
-rw-r--r-- | ext/pdo_mysql/mysql_statement.c | 6 | ||||
-rw-r--r-- | ext/pdo_mysql/tests/bug70066.phpt | 27 |
5 files changed, 37 insertions, 11 deletions
@@ -36,6 +36,8 @@ PHP NEWS statements). (Nikita) . Fixed bug #78152 (PDO::exec() - Bad error handling with multiple commands). (Nikita) + . Fixed bug #70066 (Unexpected "Cannot execute queries while other unbuffered + queries"). (Nikita) - Phpdbg: . Fixed bug #76813 (Access violation near NULL on source operand). (cmb) diff --git a/ext/mysqlnd/mysqlnd_libmysql_compat.h b/ext/mysqlnd/mysqlnd_libmysql_compat.h index 93f7254a7c..e737537f5c 100644 --- a/ext/mysqlnd/mysqlnd_libmysql_compat.h +++ b/ext/mysqlnd/mysqlnd_libmysql_compat.h @@ -82,7 +82,7 @@ #define mysql_stmt_param_count(s) mysqlnd_stmt_param_count((s)) #define mysql_stmt_num_rows(s) mysqlnd_stmt_num_rows((s)) #define mysql_stmt_insert_id(s) mysqlnd_stmt_insert_id((s)) -#define mysql_stmt_close(s) mysqlnd_stmt_close((s)) +#define mysql_stmt_close(s) mysqlnd_stmt_close((s), 0) #define mysql_stmt_bind_param(s,b) mysqlnd_stmt_bind_param((s), (b)) #define mysql_stmt_bind_result(s,b) mysqlnd_stmt_bind_result((s), (b)) #define mysql_stmt_errno(s) mysqlnd_stmt_errno((s)) diff --git a/ext/pdo_mysql/mysql_driver.c b/ext/pdo_mysql/mysql_driver.c index 2d8c4698e7..c5c04adf8a 100644 --- a/ext/pdo_mysql/mysql_driver.c +++ b/ext/pdo_mysql/mysql_driver.c @@ -203,18 +203,17 @@ static int mysql_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len } if (mysql_stmt_prepare(S->stmt, sql, sql_len)) { + if (nsql) { + efree(nsql); + } /* TODO: might need to pull statement specific info here? */ /* if the query isn't supported by the protocol, fallback to emulation */ if (mysql_errno(H->server) == 1295) { - if (nsql) { - efree(nsql); - } + mysql_stmt_close(S->stmt); + S->stmt = NULL; goto fallback; } pdo_mysql_error(dbh); - if (nsql) { - efree(nsql); - } PDO_DBG_RETURN(0); } if (nsql) { diff --git a/ext/pdo_mysql/mysql_statement.c b/ext/pdo_mysql/mysql_statement.c index b2c37dcfec..beb559f0c1 100644 --- a/ext/pdo_mysql/mysql_statement.c +++ b/ext/pdo_mysql/mysql_statement.c @@ -33,11 +33,9 @@ #ifdef PDO_USE_MYSQLND # define pdo_mysql_stmt_execute_prepared(stmt) pdo_mysql_stmt_execute_prepared_mysqlnd(stmt) # define pdo_free_bound_result(res) zval_ptr_dtor(res.zv) -# define pdo_mysql_stmt_close(stmt) mysqlnd_stmt_close(stmt, 0) #else # define pdo_mysql_stmt_execute_prepared(stmt) pdo_mysql_stmt_execute_prepared_libmysql(stmt) # define pdo_free_bound_result(res) efree(res.buffer) -# define pdo_mysql_stmt_close(stmt) mysql_stmt_close(stmt) #endif @@ -58,7 +56,7 @@ static int pdo_mysql_stmt_dtor(pdo_stmt_t *stmt) /* {{{ */ S->einfo.errmsg = NULL; } if (S->stmt) { - pdo_mysql_stmt_close(S->stmt); + mysql_stmt_close(S->stmt); S->stmt = NULL; } @@ -352,7 +350,7 @@ static int pdo_mysql_stmt_next_rowset(pdo_stmt_t *stmt) /* {{{ */ PDO_DBG_INF_FMT("stmt=%p", S->stmt); #if PDO_USE_MYSQLND - if (!H->emulate_prepare) { + if (S->stmt) { if (!mysqlnd_stmt_more_results(S->stmt)) { PDO_DBG_RETURN(0); } diff --git a/ext/pdo_mysql/tests/bug70066.phpt b/ext/pdo_mysql/tests/bug70066.phpt new file mode 100644 index 0000000000..54660fb3f6 --- /dev/null +++ b/ext/pdo_mysql/tests/bug70066.phpt @@ -0,0 +1,27 @@ +--TEST-- +Bug #70066: Unexpected "Cannot execute queries while other unbuffered queries" +--SKIPIF-- +<?php +if (!extension_loaded('pdo') || !extension_loaded('pdo_mysql')) die('skip not loaded'); +require_once(__DIR__ . DIRECTORY_SEPARATOR . 'skipif.inc'); +require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); +MySQLPDOTest::skip(); +?> +--FILE-- +<?php + +require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); + +$pdo = MySQLPDOTest::factory(); +$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); +$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0); + +$db = $pdo->query('SELECT DATABASE()')->fetchColumn(0); +// USE is not supported in the prepared statement protocol, +// so this will fall back to emulation. +$pdo->query('USE ' . $db); + +?> +===DONE=== +--EXPECT-- +===DONE=== |