Skip to content

Commit b526e0e

Browse files
committed
Fix Bug #61207 PDO::nextRowset() after a multi-statement query doesn't always work
1 parent 2c43149 commit b526e0e

File tree

2 files changed

+138
-43
lines changed

2 files changed

+138
-43
lines changed

ext/pdo_mysql/mysql_statement.c

Lines changed: 35 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,39 @@ static void pdo_mysql_stmt_set_row_count(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */
131131
}
132132
/* }}} */
133133

134+
static int pdo_mysql_fill_stmt_from_result(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */
135+
{
136+
pdo_mysql_stmt *S = (pdo_mysql_stmt*)stmt->driver_data;
137+
pdo_mysql_db_handle *H = S->H;
138+
my_ulonglong row_count;
139+
PDO_DBG_ENTER("pdo_mysql_fill_stmt_from_result");
140+
141+
row_count = mysql_affected_rows(H->server);
142+
if (row_count == (my_ulonglong)-1) {
143+
/* we either have a query that returned a result set or an error occured
144+
lets see if we have access to a result set */
145+
if (!H->buffered) {
146+
S->result = mysql_use_result(H->server);
147+
} else {
148+
S->result = mysql_store_result(H->server);
149+
}
150+
if (NULL == S->result) {
151+
pdo_mysql_error_stmt(stmt);
152+
PDO_DBG_RETURN(0);
153+
}
154+
155+
stmt->row_count = (long) mysql_num_rows(S->result);
156+
stmt->column_count = (int) mysql_num_fields(S->result);
157+
S->fields = mysql_fetch_fields(S->result);
158+
} else {
159+
/* this was a DML or DDL query (INSERT, UPDATE, DELETE, ... */
160+
stmt->row_count = (long) row_count;
161+
}
162+
163+
PDO_DBG_RETURN(1);
164+
}
165+
/* }}} */
166+
134167
#ifdef HAVE_MYSQL_STMT_PREPARE
135168
static int pdo_mysql_stmt_execute_prepared_libmysql(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */
136169
{
@@ -310,30 +343,7 @@ static int pdo_mysql_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */
310343
PDO_DBG_RETURN(0);
311344
}
312345

313-
row_count = mysql_affected_rows(H->server);
314-
if (row_count == (my_ulonglong)-1) {
315-
/* we either have a query that returned a result set or an error occured
316-
lets see if we have access to a result set */
317-
if (!H->buffered) {
318-
S->result = mysql_use_result(H->server);
319-
} else {
320-
S->result = mysql_store_result(H->server);
321-
}
322-
if (NULL == S->result) {
323-
pdo_mysql_error_stmt(stmt);
324-
PDO_DBG_RETURN(0);
325-
}
326-
327-
stmt->row_count = (long) mysql_num_rows(S->result);
328-
stmt->column_count = (int) mysql_num_fields(S->result);
329-
S->fields = mysql_fetch_fields(S->result);
330-
331-
} else {
332-
/* this was a DML or DDL query (INSERT, UPDATE, DELETE, ... */
333-
stmt->row_count = (long) row_count;
334-
}
335-
336-
PDO_DBG_RETURN(1);
346+
PDO_DBG_RETURN(pdo_mysql_fill_stmt_from_result(stmt TSRMLS_CC));
337347
}
338348
/* }}} */
339349

@@ -421,25 +431,7 @@ static int pdo_mysql_stmt_next_rowset(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */
421431
/* No more results */
422432
PDO_DBG_RETURN(0);
423433
} else {
424-
if (!H->buffered) {
425-
S->result = mysql_use_result(H->server);
426-
row_count = 0;
427-
} else {
428-
S->result = mysql_store_result(H->server);
429-
if ((long)-1 == (row_count = (long) mysql_affected_rows(H->server))) {
430-
pdo_mysql_error_stmt(stmt);
431-
PDO_DBG_RETURN(0);
432-
}
433-
}
434-
435-
if (NULL == S->result) {
436-
PDO_DBG_RETURN(0);
437-
}
438-
439-
stmt->row_count = row_count;
440-
stmt->column_count = (int) mysql_num_fields(S->result);
441-
S->fields = mysql_fetch_fields(S->result);
442-
PDO_DBG_RETURN(1);
434+
PDO_DBG_RETURN(pdo_mysql_fill_stmt_from_result(stmt TSRMLS_CC));
443435
}
444436
#else
445437
strcpy(stmt->error_code, "HYC00");

ext/pdo_mysql/tests/bug_61207.phpt

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
--TEST--
2+
PDO MySQL Bug #61207 (PDO::nextRowset() after a multi-statement query doesn't always work)
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('pdo') || !extension_loaded('pdo_mysql')) die('skip not loaded');
6+
require dirname(__FILE__) . '/config.inc';
7+
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
8+
PDOTest::skip();
9+
?>
10+
--FILE--
11+
<?php
12+
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
13+
14+
$link = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
15+
16+
$link->query('create table `bug61207`( `id` int )');
17+
18+
$handle1 = $link->prepare('insert into bug61207(id) values(1);
19+
select * from bug61207 where id = ?;
20+
update bug61207 set id = 2 where id = ?;');
21+
22+
$handle1->bindValue('1', '1');
23+
$handle1->bindValue('2', '1');
24+
25+
$handle1->execute();
26+
$i = 1;
27+
print("Handle 1:\n");
28+
do {
29+
print('Rowset ' . $i++ . "\n");
30+
if ($handle1->columnCount() > 0)
31+
print("Results detected\n");
32+
} while($handle1->nextRowset());
33+
34+
$handle2 = $link->prepare('select * from bug61207 where id = ?;
35+
update bug61207 set id = 1 where id = ?;');
36+
37+
$handle2->bindValue('1', '2');
38+
$handle2->bindValue('2', '2');
39+
40+
$handle2->execute();
41+
42+
$i = 1;
43+
print("Handle 2:\n");
44+
do {
45+
print('Rowset ' . $i++ . "\n");
46+
if ($handle2->columnCount() > 0)
47+
print("Results detected\n");
48+
} while($handle2->nextRowset());
49+
50+
$handle3 = $link->prepare('update bug61207 set id = 2 where id = ?;
51+
select * from bug61207 where id = ?;');
52+
53+
$handle3->bindValue('1', '1');
54+
$handle3->bindValue('2', '2');
55+
56+
$handle3->execute();
57+
58+
$i = 1;
59+
print("Handle 3:\n");
60+
do {
61+
print('Rowset ' . $i++ . "\n");
62+
if ($handle3->columnCount() > 0)
63+
print("Results detected\n");
64+
} while($handle3->nextRowset());
65+
66+
$handle4 = $link->prepare('insert into bug61207(id) values(3);
67+
update bug61207 set id = 2 where id = ?;
68+
select * from bug61207 where id = ?;');
69+
70+
$handle4->bindValue('1', '3');
71+
$handle4->bindValue('2', '2');
72+
73+
$handle4->execute();
74+
75+
$i = 1;
76+
print("Handle 4:\n");
77+
do {
78+
print('Rowset ' . $i++ . "\n");
79+
if ($handle1->columnCount() > 0)
80+
print("Results detected\n");
81+
} while($handle1->nextRowset());
82+
83+
$link->query("DROP TABLE bug61207");
84+
?>
85+
--EXPECT--
86+
Handle 1:
87+
Rowset 1
88+
Rowset 2
89+
Results detected
90+
Rowset 3
91+
Handle 2:
92+
Rowset 1
93+
Results detected
94+
Rowset 2
95+
Handle 3:
96+
Rowset 1
97+
Rowset 2
98+
Results detected
99+
Handle 4:
100+
Rowset 1
101+
Rowset 2
102+
Rowset 3
103+
Results detected

0 commit comments

Comments
 (0)