summaryrefslogtreecommitdiff
path: root/ext/pdo_mysql
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-12-08 16:37:00 +0100
committerNikita Popov <nikita.ppv@gmail.com>2020-12-08 16:41:35 +0100
commitbfa69d27bc867d62f2b74c189b90e15a0a41e864 (patch)
tree74ffb21ecd7da927c369f456efe0e004456cc13d /ext/pdo_mysql
parent713ef8511b1d8b10b56ab1cda1ea5fdfa54376a7 (diff)
downloadphp-git-bfa69d27bc867d62f2b74c189b90e15a0a41e864.tar.gz
Handle column count change in PDO MySQL
This has been fixed for PDO SQlite by GH-4313, however the same issue also applied to PDO MySQL. Move the column count setting function into the main PDO layer (and export it) and then use it in both PDO SQLite and PDO MySQL.
Diffstat (limited to 'ext/pdo_mysql')
-rw-r--r--ext/pdo_mysql/mysql_statement.c11
-rw-r--r--ext/pdo_mysql/tests/change_column_count.phpt60
2 files changed, 64 insertions, 7 deletions
diff --git a/ext/pdo_mysql/mysql_statement.c b/ext/pdo_mysql/mysql_statement.c
index 0d1cd348c7..c8a6a218ab 100644
--- a/ext/pdo_mysql/mysql_statement.c
+++ b/ext/pdo_mysql/mysql_statement.c
@@ -144,7 +144,7 @@ static int pdo_mysql_fill_stmt_from_result(pdo_stmt_t *stmt) /* {{{ */
}
stmt->row_count = (zend_long) mysql_num_rows(S->result);
- stmt->column_count = (int) mysql_num_fields(S->result);
+ php_pdo_stmt_set_column_count(stmt, (int) mysql_num_fields(S->result));
S->fields = mysql_fetch_fields(S->result);
} else {
/* this was a DML or DDL query (INSERT, UPDATE, DELETE, ... */
@@ -194,7 +194,7 @@ static int pdo_mysql_stmt_execute_prepared_libmysql(pdo_stmt_t *stmt) /* {{{ */
efree(S->out_length);
}
- stmt->column_count = (int)mysql_num_fields(S->result);
+ php_pdo_stmt_set_column_count(stmt, (int)mysql_num_fields(S->result));
S->bound_result = ecalloc(stmt->column_count, sizeof(MYSQL_BIND));
S->out_null = ecalloc(stmt->column_count, sizeof(my_bool));
S->out_length = ecalloc(stmt->column_count, sizeof(zend_ulong));
@@ -290,7 +290,7 @@ static int pdo_mysql_stmt_execute_prepared_mysqlnd(pdo_stmt_t *stmt) /* {{{ */
}
/* for SHOW/DESCRIBE and others the column/field count is not available before execute */
- stmt->column_count = mysql_stmt_field_count(S->stmt);
+ php_pdo_stmt_set_column_count(stmt, mysql_stmt_field_count(S->stmt));
for (i = 0; i < stmt->column_count; i++) {
mysqlnd_stmt_bind_one_result(S->stmt, i);
}
@@ -378,7 +378,7 @@ static int pdo_mysql_stmt_next_rowset(pdo_stmt_t *stmt) /* {{{ */
/* for SHOW/DESCRIBE and others the column/field count is not available before execute */
int i;
- stmt->column_count = mysql_stmt_field_count(S->stmt);
+ php_pdo_stmt_set_column_count(stmt, mysql_stmt_field_count(S->stmt));
for (i = 0; i < stmt->column_count; i++) {
mysqlnd_stmt_bind_one_result(S->stmt, i);
}
@@ -407,9 +407,6 @@ static int pdo_mysql_stmt_next_rowset(pdo_stmt_t *stmt) /* {{{ */
/* ensure that we free any previous unfetched results */
#ifndef PDO_USE_MYSQLND
if (S->stmt) {
- if (S->result) {
- stmt->column_count = (int)mysql_num_fields(S->result);
- }
mysql_stmt_free_result(S->stmt);
}
#endif
diff --git a/ext/pdo_mysql/tests/change_column_count.phpt b/ext/pdo_mysql/tests/change_column_count.phpt
new file mode 100644
index 0000000000..5bb521d300
--- /dev/null
+++ b/ext/pdo_mysql/tests/change_column_count.phpt
@@ -0,0 +1,60 @@
+--TEST--
+Change column count after statement has been prepared
+--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');
+
+$db = MySQLPDOTest::factory();
+$db->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
+
+$db->exec('DROP TABLE IF EXISTS test');
+$db->exec('CREATE TABLE test (id INTEGER PRIMARY KEY NOT NULL, name VARCHAR(255) NOT NULL)');
+
+$stmt = $db->prepare('INSERT INTO test (id, name) VALUES(:id, :name)');
+$stmt->execute([
+ 'id' => 10,
+ 'name' => 'test',
+]);
+
+$stmt = $db->prepare('SELECT * FROM test WHERE id = :id');
+$stmt->execute(['id' => 10]);
+var_dump($stmt->fetchAll(\PDO::FETCH_ASSOC));
+
+$db->exec('ALTER TABLE test ADD new_col VARCHAR(255)');
+$stmt->execute(['id' => 10]);
+var_dump($stmt->fetchAll(\PDO::FETCH_ASSOC));
+
+?>
+--CLEAN--
+<?php
+require __DIR__ . '/mysql_pdo_test.inc';
+MySQLPDOTest::dropTestTable();
+?>
+--EXPECT--
+array(1) {
+ [0]=>
+ array(2) {
+ ["id"]=>
+ string(2) "10"
+ ["name"]=>
+ string(4) "test"
+ }
+}
+array(1) {
+ [0]=>
+ array(3) {
+ ["id"]=>
+ string(2) "10"
+ ["name"]=>
+ string(4) "test"
+ ["new_col"]=>
+ NULL
+ }
+}