From b526e0e410c8a8e88768776d91d0ef32036581b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Schl=C3=BCter?= Date: Mon, 5 Mar 2012 23:38:15 +0000 Subject: Fix Bug #61207 PDO::nextRowset() after a multi-statement query doesn't always work --- ext/pdo_mysql/mysql_statement.c | 78 +++++++++++++--------------- ext/pdo_mysql/tests/bug_61207.phpt | 103 +++++++++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+), 43 deletions(-) create mode 100644 ext/pdo_mysql/tests/bug_61207.phpt diff --git a/ext/pdo_mysql/mysql_statement.c b/ext/pdo_mysql/mysql_statement.c index 3ce9636205..c4d322ffd1 100755 --- a/ext/pdo_mysql/mysql_statement.c +++ b/ext/pdo_mysql/mysql_statement.c @@ -131,6 +131,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); +} +/* }}} */ + #ifdef HAVE_MYSQL_STMT_PREPARE static int pdo_mysql_stmt_execute_prepared_libmysql(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */ { @@ -310,30 +343,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)); } /* }}} */ @@ -421,25 +431,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)); } #else strcpy(stmt->error_code, "HYC00"); diff --git a/ext/pdo_mysql/tests/bug_61207.phpt b/ext/pdo_mysql/tests/bug_61207.phpt new file mode 100644 index 0000000000..917b322180 --- /dev/null +++ b/ext/pdo_mysql/tests/bug_61207.phpt @@ -0,0 +1,103 @@ +--TEST-- +PDO MySQL Bug #61207 (PDO::nextRowset() after a multi-statement query doesn't always work) +--SKIPIF-- + +--FILE-- +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 -- cgit v1.2.1