summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-12-08 14:28:18 +0100
committerNikita Popov <nikita.ppv@gmail.com>2020-12-08 17:01:56 +0100
commit2df09b9b64ed30c8d999538d1747d511ffd0af9c (patch)
tree79235b368a3d46fae4fec273ec6eba1d1e4d8973
parentbfa69d27bc867d62f2b74c189b90e15a0a41e864 (diff)
downloadphp-git-2df09b9b64ed30c8d999538d1747d511ffd0af9c.tar.gz
PDO MySQL: Normalize handling of empty stored procedure result set
MySQL always returns a trailing empty result set for stored procedure calls, which is used to convey status information. The PDO MySQL implementation is presently confused about what to do with it: If mysqlnd is used and native prepared statements are used, this result set is skipped. In all other cases it is not skipped. We also have quite a few XFAILed tests relating to this. This patch normalizes (for PHP-8.0 only) the behavior towards always retaining the empty result set. This is simply how MySQL stored procedures work (some expletives omitted here) and we can't distinguish this "useless" result set from an empty result of a multi query. Multi queries are not a concern for native prepared statements, as PDO does not allow them in that case, but they are a concern for emulated prepared statements. Closes GH-6497.
-rw-r--r--ext/pdo_mysql/mysql_statement.c10
-rw-r--r--ext/pdo_mysql/tests/bug_39858.phpt10
-rw-r--r--ext/pdo_mysql/tests/bug_41997.phpt4
-rw-r--r--ext/pdo_mysql/tests/pdo_mysql_attr_oracle_nulls.phpt60
-rw-r--r--ext/pdo_mysql/tests/pdo_mysql_multi_stmt_nextrowset.phpt8
-rw-r--r--ext/pdo_mysql/tests/pdo_mysql_stmt_nextrowset.phpt10
6 files changed, 66 insertions, 36 deletions
diff --git a/ext/pdo_mysql/mysql_statement.c b/ext/pdo_mysql/mysql_statement.c
index c8a6a218ab..9d544b23c2 100644
--- a/ext/pdo_mysql/mysql_statement.c
+++ b/ext/pdo_mysql/mysql_statement.c
@@ -359,16 +359,6 @@ static int pdo_mysql_stmt_next_rowset(pdo_stmt_t *stmt) /* {{{ */
PDO_DBG_RETURN(0);
}
- if (!mysqlnd_stmt_more_results(S->stmt)) {
- /*
- MySQL gives us n + 1 result sets for
- CALL proc() and n result sets returned by the proc itself.
- Result set n + 1 is about the procedure call itself.
- As the PDO emulation does not return it, we skip it as well
- */
- PDO_DBG_RETURN(0);
- }
-
/* TODO - this code is stolen from execute() - see above */
if (S->result) {
mysql_free_result(S->result);
diff --git a/ext/pdo_mysql/tests/bug_39858.phpt b/ext/pdo_mysql/tests/bug_39858.phpt
index e33415eb67..d421d31a38 100644
--- a/ext/pdo_mysql/tests/bug_39858.phpt
+++ b/ext/pdo_mysql/tests/bug_39858.phpt
@@ -18,8 +18,6 @@ if ($version < 50000)
die(sprintf("skip Need MySQL Server 5.0.0+, found %d.%02d.%02d (%d)\n",
$matches[1], $matches[2], $matches[3], $version));
?>
---XFAIL--
-nextRowset() problem with stored proc & emulation mode & mysqlnd
--FILE--
<?php
require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
@@ -79,6 +77,8 @@ array(1) {
string(1) "4"
}
}
+array(0) {
+}
array(1) {
[0]=>
array(1) {
@@ -86,6 +86,8 @@ array(1) {
string(1) "4"
}
}
+array(0) {
+}
Native Prepared Statements...
array(1) {
[0]=>
@@ -94,6 +96,8 @@ array(1) {
string(1) "4"
}
}
+array(0) {
+}
array(1) {
[0]=>
array(1) {
@@ -101,4 +105,6 @@ array(1) {
string(1) "4"
}
}
+array(0) {
+}
done!
diff --git a/ext/pdo_mysql/tests/bug_41997.phpt b/ext/pdo_mysql/tests/bug_41997.phpt
index 7ce2e810d4..769080f86a 100644
--- a/ext/pdo_mysql/tests/bug_41997.phpt
+++ b/ext/pdo_mysql/tests/bug_41997.phpt
@@ -1,7 +1,5 @@
--TEST--
PDO MySQL Bug #41997 (stored procedure call returning single rowset blocks future queries)
---XFAIL--
-nextRowset() problem with stored proc & emulation mode & mysqlnd
--SKIPIF--
<?php
require_once(__DIR__ . DIRECTORY_SEPARATOR . 'skipif.inc');
@@ -46,6 +44,8 @@ array(1) {
string(1) "1"
}
}
+array(0) {
+}
array(3) {
[0]=>
string(5) "00000"
diff --git a/ext/pdo_mysql/tests/pdo_mysql_attr_oracle_nulls.phpt b/ext/pdo_mysql/tests/pdo_mysql_attr_oracle_nulls.phpt
index 6d922a037d..6e98c85bdf 100644
--- a/ext/pdo_mysql/tests/pdo_mysql_attr_oracle_nulls.phpt
+++ b/ext/pdo_mysql/tests/pdo_mysql_attr_oracle_nulls.phpt
@@ -53,31 +53,13 @@ MySQLPDOTest::skip();
// requires MySQL 5+
$stmt = $db->prepare('CALL p()');
$stmt->execute();
- $expected = array(
- array(
- "z" => NULL,
- "a" => NULL,
- "b" => " ",
- "c" => NULL,
- "d" => " d",
- "e" => " e",
- ),
- );
do {
- $tmp = $stmt->fetchAll(PDO::FETCH_ASSOC);
- if ($tmp != $expected) {
- printf("[004] Expecting %s got %s\n",
- var_export($expected, true), var_export($tmp, true));
- }
+ var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
} while ($stmt->nextRowset());
$stmt->execute();
do {
- $tmp = $stmt->fetchAll(PDO::FETCH_ASSOC);
- if ($tmp != $expected) {
- printf("[005] Expecting %s got %s\n",
- var_export($expected, true), var_export($tmp, true));
- }
+ var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
} while ($stmt->nextRowset());
}
@@ -124,4 +106,42 @@ array(1) {
string(3) "%se"
}
}
+array(1) {
+ [0]=>
+ array(6) {
+ ["z"]=>
+ NULL
+ ["a"]=>
+ string(0) ""
+ ["b"]=>
+ string(1) " "
+ ["c"]=>
+ string(0) ""
+ ["d"]=>
+ string(2) " d"
+ ["e"]=>
+ string(2) " e"
+ }
+}
+array(0) {
+}
+array(1) {
+ [0]=>
+ array(6) {
+ ["z"]=>
+ NULL
+ ["a"]=>
+ string(0) ""
+ ["b"]=>
+ string(1) " "
+ ["c"]=>
+ string(0) ""
+ ["d"]=>
+ string(2) " d"
+ ["e"]=>
+ string(2) " e"
+ }
+}
+array(0) {
+}
done!
diff --git a/ext/pdo_mysql/tests/pdo_mysql_multi_stmt_nextrowset.phpt b/ext/pdo_mysql/tests/pdo_mysql_multi_stmt_nextrowset.phpt
index e17a233109..a65fd2eed2 100644
--- a/ext/pdo_mysql/tests/pdo_mysql_multi_stmt_nextrowset.phpt
+++ b/ext/pdo_mysql/tests/pdo_mysql_multi_stmt_nextrowset.phpt
@@ -132,6 +132,8 @@ array(3) {
string(1) "a"
}
}
+array(0) {
+}
bool(false)
array(3) {
[0]=>
@@ -173,6 +175,8 @@ array(3) {
string(1) "a"
}
}
+array(0) {
+}
bool(false)
Warning: PDO::query(): SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'INSERT INTO test (id, label) VALUES (99, 'x')' at line 1 in %s on line %d
@@ -219,6 +223,8 @@ array(3) {
string(1) "a"
}
}
+array(0) {
+}
bool(false)
array(3) {
[0]=>
@@ -260,6 +266,8 @@ array(3) {
string(1) "a"
}
}
+array(0) {
+}
bool(false)
string(5) "00000"
done!
diff --git a/ext/pdo_mysql/tests/pdo_mysql_stmt_nextrowset.phpt b/ext/pdo_mysql/tests/pdo_mysql_stmt_nextrowset.phpt
index eac4b9e4d8..91a4615a52 100644
--- a/ext/pdo_mysql/tests/pdo_mysql_stmt_nextrowset.phpt
+++ b/ext/pdo_mysql/tests/pdo_mysql_stmt_nextrowset.phpt
@@ -1,7 +1,5 @@
--TEST--
MySQL PDOStatement->nextRowSet()
---XFAIL--
-nextRowset() problem with stored proc & emulation mode & mysqlnd
--SKIPIF--
<?php
require_once(__DIR__ . DIRECTORY_SEPARATOR . 'skipif.inc');
@@ -159,6 +157,8 @@ array(3) {
string(1) "a"
}
}
+array(0) {
+}
bool(false)
array(1) {
[0]=>
@@ -208,6 +208,8 @@ array(3) {
string(1) "a"
}
}
+array(0) {
+}
bool(false)
Native PS...
array(1) {
@@ -258,6 +260,8 @@ array(3) {
string(1) "a"
}
}
+array(0) {
+}
bool(false)
array(1) {
[0]=>
@@ -307,5 +311,7 @@ array(3) {
string(1) "a"
}
}
+array(0) {
+}
bool(false)
done!