Fix Bug #61207 PDO::nextRowset() after a multi-statement query doesn't always work

This commit is contained in:
Johannes Schlüter 2012-03-05 23:38:15 +00:00
parent 77e1a1ab6e
commit 5c896b344a
2 changed files with 138 additions and 43 deletions

View File

@ -125,6 +125,39 @@ static void pdo_mysql_stmt_set_row_count(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */
}
/* }}} */
static int pdo_mysql_fill_stmt_from_result(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */
{
pdo_mysql_stmt *S = (pdo_mysql_stmt*)stmt->driver_data;
pdo_mysql_db_handle *H = S->H;
my_ulonglong row_count;
PDO_DBG_ENTER("pdo_mysql_fill_stmt_from_result");
row_count = mysql_affected_rows(H->server);
if (row_count == (my_ulonglong)-1) {
/* we either have a query that returned a result set or an error occured
lets see if we have access to a result set */
if (!H->buffered) {
S->result = mysql_use_result(H->server);
} else {
S->result = mysql_store_result(H->server);
}
if (NULL == S->result) {
pdo_mysql_error_stmt(stmt);
PDO_DBG_RETURN(0);
}
stmt->row_count = (long) mysql_num_rows(S->result);
stmt->column_count = (int) mysql_num_fields(S->result);
S->fields = mysql_fetch_fields(S->result);
} else {
/* this was a DML or DDL query (INSERT, UPDATE, DELETE, ... */
stmt->row_count = (long) row_count;
}
PDO_DBG_RETURN(1);
}
/* }}} */
#ifndef PDO_USE_MYSQLND
static int pdo_mysql_stmt_execute_prepared_libmysql(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */
{
@ -302,30 +335,7 @@ static int pdo_mysql_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */
PDO_DBG_RETURN(0);
}
row_count = mysql_affected_rows(H->server);
if (row_count == (my_ulonglong)-1) {
/* we either have a query that returned a result set or an error occured
lets see if we have access to a result set */
if (!H->buffered) {
S->result = mysql_use_result(H->server);
} else {
S->result = mysql_store_result(H->server);
}
if (NULL == S->result) {
pdo_mysql_error_stmt(stmt);
PDO_DBG_RETURN(0);
}
stmt->row_count = (long) mysql_num_rows(S->result);
stmt->column_count = (int) mysql_num_fields(S->result);
S->fields = mysql_fetch_fields(S->result);
} else {
/* this was a DML or DDL query (INSERT, UPDATE, DELETE, ... */
stmt->row_count = (long) row_count;
}
PDO_DBG_RETURN(1);
PDO_DBG_RETURN(pdo_mysql_fill_stmt_from_result(stmt TSRMLS_CC));
}
/* }}} */
@ -412,25 +422,7 @@ static int pdo_mysql_stmt_next_rowset(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */
/* No more results */
PDO_DBG_RETURN(0);
} else {
if (!H->buffered) {
S->result = mysql_use_result(H->server);
row_count = 0;
} else {
S->result = mysql_store_result(H->server);
if ((long)-1 == (row_count = (long) mysql_affected_rows(H->server))) {
pdo_mysql_error_stmt(stmt);
PDO_DBG_RETURN(0);
}
}
if (NULL == S->result) {
PDO_DBG_RETURN(0);
}
stmt->row_count = row_count;
stmt->column_count = (int) mysql_num_fields(S->result);
S->fields = mysql_fetch_fields(S->result);
PDO_DBG_RETURN(1);
PDO_DBG_RETURN(pdo_mysql_fill_stmt_from_result(stmt TSRMLS_CC));
}
}
/* }}} */

View File

@ -0,0 +1,103 @@
--TEST--
PDO MySQL Bug #61207 (PDO::nextRowset() after a multi-statement query doesn't always work)
--SKIPIF--
<?php
if (!extension_loaded('pdo') || !extension_loaded('pdo_mysql')) die('skip not loaded');
require dirname(__FILE__) . '/config.inc';
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
PDOTest::skip();
?>
--FILE--
<?php
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
$link = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
$link->query('create table `bug61207`( `id` int )');
$handle1 = $link->prepare('insert into bug61207(id) values(1);
select * from bug61207 where id = ?;
update bug61207 set id = 2 where id = ?;');
$handle1->bindValue('1', '1');
$handle1->bindValue('2', '1');
$handle1->execute();
$i = 1;
print("Handle 1:\n");
do {
print('Rowset ' . $i++ . "\n");
if ($handle1->columnCount() > 0)
print("Results detected\n");
} while($handle1->nextRowset());
$handle2 = $link->prepare('select * from bug61207 where id = ?;
update bug61207 set id = 1 where id = ?;');
$handle2->bindValue('1', '2');
$handle2->bindValue('2', '2');
$handle2->execute();
$i = 1;
print("Handle 2:\n");
do {
print('Rowset ' . $i++ . "\n");
if ($handle2->columnCount() > 0)
print("Results detected\n");
} while($handle2->nextRowset());
$handle3 = $link->prepare('update bug61207 set id = 2 where id = ?;
select * from bug61207 where id = ?;');
$handle3->bindValue('1', '1');
$handle3->bindValue('2', '2');
$handle3->execute();
$i = 1;
print("Handle 3:\n");
do {
print('Rowset ' . $i++ . "\n");
if ($handle3->columnCount() > 0)
print("Results detected\n");
} while($handle3->nextRowset());
$handle4 = $link->prepare('insert into bug61207(id) values(3);
update bug61207 set id = 2 where id = ?;
select * from bug61207 where id = ?;');
$handle4->bindValue('1', '3');
$handle4->bindValue('2', '2');
$handle4->execute();
$i = 1;
print("Handle 4:\n");
do {
print('Rowset ' . $i++ . "\n");
if ($handle1->columnCount() > 0)
print("Results detected\n");
} while($handle1->nextRowset());
$link->query("DROP TABLE bug61207");
?>
--EXPECT--
Handle 1:
Rowset 1
Rowset 2
Results detected
Rowset 3
Handle 2:
Rowset 1
Results detected
Rowset 2
Handle 3:
Rowset 1
Rowset 2
Results detected
Handle 4:
Rowset 1
Rowset 2
Rowset 3
Results detected