diff options
28 files changed, 161 insertions, 61 deletions
@@ -31,6 +31,12 @@ PHP 8.1 UPGRADE NOTES . The mysqlnd.fetch_copy_data ini setting has been removed. However, this should not result in user-visible behavior changes. +- PDO MySQL: + . Integers and floats in result sets will now be returned using native PHP + types instead of strings when using emulated prepared statements. This + matches the behavior of native prepared statements. You can restore the + previous behavior by enabling the PDO::ATTR_STRINGIFY_FETCHES option. + - Standard: . version_compare() no longer accepts undocumented operator abbreviations. diff --git a/ext/mysqlnd/mysqlnd.h b/ext/mysqlnd/mysqlnd.h index 582d8f152b..d9e99d69db 100644 --- a/ext/mysqlnd/mysqlnd.h +++ b/ext/mysqlnd/mysqlnd.h @@ -100,6 +100,8 @@ PHPAPI void mysqlnd_debug(const char *mode); /* Query */ #define mysqlnd_fetch_into(result, flags, ret_val) (result)->m.fetch_into((result), (flags), (ret_val) ZEND_FILE_LINE_CC) #define mysqlnd_fetch_row_c(result) (result)->m.fetch_row_c((result)) +#define mysqlnd_fetch_row_zval(result, row_ptr, fetched) \ + (result)->m.fetch_row((result), (row_ptr), 0, (fetched)) #define mysqlnd_fetch_all(result, flags, return_value) (result)->m.fetch_all((result), (flags), (return_value) ZEND_FILE_LINE_CC) #define mysqlnd_get_connection_stats(conn, values) ((conn)->data)->m->get_statistics((conn)->data, (values) ZEND_FILE_LINE_CC) #define mysqlnd_get_client_stats(values) _mysqlnd_get_client_stats(mysqlnd_global_stats, (values) ZEND_FILE_LINE_CC) diff --git a/ext/pdo_mysql/mysql_driver.c b/ext/pdo_mysql/mysql_driver.c index 04d0f52cbb..0523b81faf 100644 --- a/ext/pdo_mysql/mysql_driver.c +++ b/ext/pdo_mysql/mysql_driver.c @@ -826,6 +826,14 @@ static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options) goto cleanup; } +#ifdef PDO_USE_MYSQLND + bool int_and_float_native = true; + if (mysql_options(H->server, MYSQLND_OPT_INT_AND_FLOAT_NATIVE, (const char *) &int_and_float_native)) { + pdo_mysql_error(dbh); + goto cleanup; + } +#endif + if (vars[0].optval && mysql_options(H->server, MYSQL_SET_CHARSET_NAME, vars[0].optval)) { pdo_mysql_error(dbh); goto cleanup; diff --git a/ext/pdo_mysql/mysql_statement.c b/ext/pdo_mysql/mysql_statement.c index 5e0f03fbba..3e83c17599 100644 --- a/ext/pdo_mysql/mysql_statement.c +++ b/ext/pdo_mysql/mysql_statement.c @@ -34,7 +34,6 @@ # define pdo_mysql_stmt_execute_prepared(stmt) pdo_mysql_stmt_execute_prepared_libmysql(stmt) #endif - static void pdo_mysql_free_result(pdo_mysql_stmt *S) { if (S->result) { @@ -52,8 +51,16 @@ static void pdo_mysql_free_result(pdo_mysql_stmt *S) efree(S->out_length); S->bound_result = NULL; } +#else + if (S->current_row) { + unsigned column_count = mysql_num_fields(S->result); + for (unsigned i = 0; i < column_count; i++) { + zval_ptr_dtor_nogc(&S->current_row[i]); + } + efree(S->current_row); + S->current_row = NULL; + } #endif - mysql_free_result(S->result); S->result = NULL; } @@ -104,12 +111,6 @@ static int pdo_mysql_stmt_dtor(pdo_stmt_t *stmt) /* {{{ */ } } -#ifdef PDO_USE_MYSQLND - if (!S->stmt && S->current_data) { - mnd_efree(S->current_data); - } -#endif /* PDO_USE_MYSQLND */ - efree(S); PDO_DBG_RETURN(1); } @@ -553,9 +554,24 @@ static int pdo_mysql_stmt_fetch(pdo_stmt_t *stmt, enum pdo_fetch_orientation ori PDO_DBG_RETURN(1); } - if (!S->stmt && S->current_data) { - mnd_efree(S->current_data); + zval *row_data; + if (mysqlnd_fetch_row_zval(S->result, &row_data, &fetched_anything) == FAIL) { + pdo_mysql_error_stmt(stmt); + PDO_DBG_RETURN(0); + } + + if (!fetched_anything) { + PDO_DBG_RETURN(0); + } + + if (!S->current_row) { + S->current_row = ecalloc(sizeof(zval), stmt->column_count); } + for (unsigned i = 0; i < stmt->column_count; i++) { + zval_ptr_dtor_nogc(&S->current_row[i]); + ZVAL_COPY_VALUE(&S->current_row[i], &row_data[i]); + } + PDO_DBG_RETURN(1); #else int ret; @@ -577,7 +593,6 @@ static int pdo_mysql_stmt_fetch(pdo_stmt_t *stmt, enum pdo_fetch_orientation ori PDO_DBG_RETURN(1); } -#endif /* PDO_USE_MYSQLND */ if ((S->current_data = mysql_fetch_row(S->result)) == NULL) { if (!S->H->buffered && mysql_errno(S->H->server)) { @@ -588,6 +603,7 @@ static int pdo_mysql_stmt_fetch(pdo_stmt_t *stmt, enum pdo_fetch_orientation ori S->current_lengths = mysql_fetch_lengths(S->result); PDO_DBG_RETURN(1); +#endif /* PDO_USE_MYSQLND */ } /* }}} */ @@ -630,13 +646,10 @@ static int pdo_mysql_stmt_describe(pdo_stmt_t *stmt, int colno) /* {{{ */ cols[i].maxlen = S->fields[i].length; #ifdef PDO_USE_MYSQLND - if (S->stmt) { - cols[i].param_type = PDO_PARAM_ZVAL; - } else + cols[i].param_type = PDO_PARAM_ZVAL; +#else + cols[i].param_type = PDO_PARAM_STR; #endif - { - cols[i].param_type = PDO_PARAM_STR; - } } PDO_DBG_RETURN(1); } @@ -652,13 +665,6 @@ static int pdo_mysql_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, size_ PDO_DBG_RETURN(0); } - /* With mysqlnd data is stored inside mysqlnd, not S->current_data */ - if (!S->stmt) { - if (S->current_data == NULL || !S->result) { - PDO_DBG_RETURN(0); - } - } - if (colno >= stmt->column_count) { /* error invalid column */ PDO_DBG_RETURN(0); @@ -667,9 +673,12 @@ static int pdo_mysql_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, size_ if (S->stmt) { Z_TRY_ADDREF(S->stmt->data->result_bind[colno].zv); *ptr = (char*)&S->stmt->data->result_bind[colno].zv; - *len = sizeof(zval); - PDO_DBG_RETURN(1); + } else { + Z_TRY_ADDREF(S->current_row[colno]); + *ptr = (char*)&S->current_row[colno]; } + *len = sizeof(zval); + PDO_DBG_RETURN(1); #else if (S->stmt) { if (S->out_null[colno]) { @@ -688,10 +697,14 @@ static int pdo_mysql_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, size_ *len = S->out_length[colno]; PDO_DBG_RETURN(1); } -#endif + + if (S->current_data == NULL) { + PDO_DBG_RETURN(0); + } *ptr = S->current_data[colno]; *len = S->current_lengths[colno]; PDO_DBG_RETURN(1); +#endif } /* }}} */ static char *type_to_name_native(int type) /* {{{ */ diff --git a/ext/pdo_mysql/php_pdo_mysql_int.h b/ext/pdo_mysql/php_pdo_mysql_int.h index 553437829e..e83ac735dc 100644 --- a/ext/pdo_mysql/php_pdo_mysql_int.h +++ b/ext/pdo_mysql/php_pdo_mysql_int.h @@ -120,12 +120,6 @@ typedef struct { pdo_mysql_db_handle *H; MYSQL_RES *result; const MYSQL_FIELD *fields; - MYSQL_ROW current_data; -#ifdef PDO_USE_MYSQLND - const size_t *current_lengths; -#else - unsigned long *current_lengths; -#endif pdo_mysql_error_info einfo; #ifdef PDO_USE_MYSQLND MYSQLND_STMT *stmt; @@ -137,10 +131,14 @@ typedef struct { #ifndef PDO_USE_MYSQLND my_bool *in_null; zend_ulong *in_length; -#endif PDO_MYSQL_PARAM_BIND *bound_result; my_bool *out_null; zend_ulong *out_length; + MYSQL_ROW current_data; + unsigned long *current_lengths; +#else + zval *current_row; +#endif unsigned max_length:1; /* Whether all result sets have been fully consumed. * If this flag is not set, they need to be consumed during destruction. */ diff --git a/ext/pdo_mysql/tests/bug44327.phpt b/ext/pdo_mysql/tests/bug44327.phpt index 8fa0025dd6..ad31d21ff8 100644 --- a/ext/pdo_mysql/tests/bug44327.phpt +++ b/ext/pdo_mysql/tests/bug44327.phpt @@ -11,6 +11,7 @@ $db = MySQLPDOTest::factory(); <?php require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); $db = MySQLPDOTest::factory(); + $db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); $stmt = $db->prepare("SELECT 1 AS \"one\""); $stmt->execute(); @@ -51,7 +52,7 @@ string(1) "1" string(1) "1" string(17) "SELECT 1 AS "one"" ---------------------------------- -object(PDORow)#%d (2) { +object(PDORow)#5 (2) { ["queryString"]=> string(19) "SELECT id FROM test" ["id"]=> diff --git a/ext/pdo_mysql/tests/bug71145.phpt b/ext/pdo_mysql/tests/bug71145.phpt index b3f887d7c4..2f2834cbca 100644 --- a/ext/pdo_mysql/tests/bug71145.phpt +++ b/ext/pdo_mysql/tests/bug71145.phpt @@ -14,6 +14,7 @@ require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); $attr = array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci; SET SESSION sql_mode=traditional', + PDO::ATTR_STRINGIFY_FETCHES => true, ); putenv('PDOTEST_ATTR=' . serialize($attr)); diff --git a/ext/pdo_mysql/tests/bug75177.phpt b/ext/pdo_mysql/tests/bug75177.phpt index f6414f0b29..b580c9a929 100644 --- a/ext/pdo_mysql/tests/bug75177.phpt +++ b/ext/pdo_mysql/tests/bug75177.phpt @@ -5,6 +5,7 @@ PDO MySQL Bug #75177 Type 'bit' is fetched as unexpected string require_once(__DIR__ . DIRECTORY_SEPARATOR . 'skipif.inc'); require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); MySQLPDOTest::skip(); +if (!MySQLPDOTest::isPDOMySQLnd()) die('skip only for mysqlnd'); ?> --FILE-- <?php @@ -18,14 +19,23 @@ $pdo->query("INSERT INTO $tbl (`bit`) VALUES (1)"); $pdo->query("INSERT INTO $tbl (`bit`) VALUES (0b011)"); $pdo->query("INSERT INTO $tbl (`bit`) VALUES (0b01100)"); +$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); $ret = $pdo->query("SELECT * FROM $tbl")->fetchAll(); +foreach ($ret as $i) { + var_dump($i["bit"]); +} +$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); +$ret = $pdo->query("SELECT * FROM $tbl")->fetchAll(); foreach ($ret as $i) { var_dump($i["bit"]); } ?> --EXPECT-- -string(1) "1" -string(1) "3" -string(2) "12" +int(1) +int(3) +int(12) +int(1) +int(3) +int(12) diff --git a/ext/pdo_mysql/tests/bug80458.phpt b/ext/pdo_mysql/tests/bug80458.phpt index 86e171d302..10bf305d60 100644 --- a/ext/pdo_mysql/tests/bug80458.phpt +++ b/ext/pdo_mysql/tests/bug80458.phpt @@ -14,6 +14,7 @@ require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); $db = MySQLPDOTest::factory(); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); +$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); $db->query('DROP TABLE IF EXISTS test'); $db->query('CREATE TABLE test (first int) ENGINE = InnoDB'); @@ -127,9 +128,9 @@ array(1) { [0]=> array(2) { ["first"]=> - int(5) + string(1) "5" [0]=> - int(5) + string(1) "5" } } array(0) { @@ -138,9 +139,9 @@ array(1) { [0]=> array(2) { ["first"]=> - int(7) + string(1) "7" [0]=> - int(7) + string(1) "7" } } array(0) { @@ -179,8 +180,8 @@ array(1) { [0]=> array(2) { ["first"]=> - int(16) + string(2) "16" [0]=> - int(16) + string(2) "16" } } diff --git a/ext/pdo_mysql/tests/bug_33689.phpt b/ext/pdo_mysql/tests/bug_33689.phpt index 84b8f5b914..463a74ed58 100644 --- a/ext/pdo_mysql/tests/bug_33689.phpt +++ b/ext/pdo_mysql/tests/bug_33689.phpt @@ -27,8 +27,8 @@ $stmt->execute(); $tmp = $stmt->getColumnMeta(0); // libmysql and mysqlnd will show the pdo_type entry at a different position in the hash -if (!isset($tmp['pdo_type']) || (isset($tmp['pdo_type']) && $tmp['pdo_type'] != 2)) - printf("Expecting pdo_type = 2 got %s\n", $tmp['pdo_type']); +if (!isset($tmp['pdo_type']) || (isset($tmp['pdo_type']) && $tmp['pdo_type'] != 1)) + printf("Expecting pdo_type = 1 got %s\n", $tmp['pdo_type']); else unset($tmp['pdo_type']); diff --git a/ext/pdo_mysql/tests/bug_41125.phpt b/ext/pdo_mysql/tests/bug_41125.phpt index d96778d754..5962cec898 100644 --- a/ext/pdo_mysql/tests/bug_41125.phpt +++ b/ext/pdo_mysql/tests/bug_41125.phpt @@ -21,6 +21,7 @@ if ($version < 40100) <?php require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); $db = MySQLPDOTest::factory(); +$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); $db->exec("DROP TABLE IF EXISTS test"); // And now allow the evil to do his work diff --git a/ext/pdo_mysql/tests/bug_41997.phpt b/ext/pdo_mysql/tests/bug_41997.phpt index 769080f86a..8d20ed737e 100644 --- a/ext/pdo_mysql/tests/bug_41997.phpt +++ b/ext/pdo_mysql/tests/bug_41997.phpt @@ -21,6 +21,7 @@ if ($version < 50000) <?php require __DIR__ . '/mysql_pdo_test.inc'; $db = MySQLPDOTest::factory(); +$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); $db->exec('DROP PROCEDURE IF EXISTS p'); $db->exec('CREATE PROCEDURE p() BEGIN SELECT 1 AS "one"; END'); diff --git a/ext/pdo_mysql/tests/bug_61411.phpt b/ext/pdo_mysql/tests/bug_61411.phpt index 9390e2abff..d80c685cd7 100644 --- a/ext/pdo_mysql/tests/bug_61411.phpt +++ b/ext/pdo_mysql/tests/bug_61411.phpt @@ -30,6 +30,7 @@ if (!$attr) { } $attr[PDO::ATTR_PERSISTENT] = true; $attr[PDO::ATTR_EMULATE_PREPARES] = false; +$attr[PDO::ATTR_STRINGIFY_FETCHES] = true; putenv('PDOTEST_ATTR='.serialize($attr)); $db = MySQLPDOTest::factory(); @@ -46,8 +47,8 @@ print "done!"; --EXPECT-- array(2) { [1]=> - int(1) + string(1) "1" [0]=> - int(1) + string(1) "1" } done! diff --git a/ext/pdo_mysql/tests/change_column_count.phpt b/ext/pdo_mysql/tests/change_column_count.phpt index 5bb521d300..6349be3ea4 100644 --- a/ext/pdo_mysql/tests/change_column_count.phpt +++ b/ext/pdo_mysql/tests/change_column_count.phpt @@ -12,7 +12,8 @@ MySQLPDOTest::skip(); require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); $db = MySQLPDOTest::factory(); -$db->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); +$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); +$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); $db->exec('DROP TABLE IF EXISTS test'); $db->exec('CREATE TABLE test (id INTEGER PRIMARY KEY NOT NULL, name VARCHAR(255) NOT NULL)'); diff --git a/ext/pdo_mysql/tests/native_types.phpt b/ext/pdo_mysql/tests/native_types.phpt new file mode 100644 index 0000000000..8c6be68082 --- /dev/null +++ b/ext/pdo_mysql/tests/native_types.phpt @@ -0,0 +1,50 @@ +--TEST-- +PDO MySQL should use native types if ATTR_STRINGIFY_FETCHES is not enabled +--SKIPIF-- +<?php +require_once(__DIR__ . DIRECTORY_SEPARATOR . 'skipif.inc'); +require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); +MySQLPDOTest::skip(); +if (!MySQLPDOTest::isPDOMySQLnd()) die('skip mysqlnd only'); +?> +--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 (i INT, f FLOAT)'); +$db->exec('INSERT INTO test VALUES (42, 42.5)'); + +$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); +var_dump($db->query('SELECT * FROM test')->fetchAll(PDO::FETCH_ASSOC)); + +$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); +var_dump($db->query('SELECT * FROM test')->fetchAll(PDO::FETCH_ASSOC)); +?> +--CLEAN-- +<?php +require __DIR__ . '/mysql_pdo_test.inc'; +MySQLPDOTest::dropTestTable(); +?> +--EXPECT-- +array(1) { + [0]=> + array(2) { + ["i"]=> + int(42) + ["f"]=> + float(42.5) + } +} +array(1) { + [0]=> + array(2) { + ["i"]=> + int(42) + ["f"]=> + float(42.5) + } +} diff --git a/ext/pdo_mysql/tests/pdo_mysql_attr_case.phpt b/ext/pdo_mysql/tests/pdo_mysql_attr_case.phpt index 2b45154248..f9f0f55afb 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_attr_case.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_attr_case.phpt @@ -11,6 +11,7 @@ $db = MySQLPDOTest::factory(); <?php require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); $db = MySQLPDOTest::factory(); + $db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); MySQLPDOTest::createTestTable($db); $default = $db->getAttribute(PDO::ATTR_CASE); diff --git a/ext/pdo_mysql/tests/pdo_mysql_attr_init_command.phpt b/ext/pdo_mysql/tests/pdo_mysql_attr_init_command.phpt index c979075fd7..b12161d4f3 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_attr_init_command.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_attr_init_command.phpt @@ -24,6 +24,7 @@ error_reporting=E_ALL $create = sprintf('CREATE TABLE %s(id INT)', $table); var_dump($create); $db = new PDO($dsn, $user, $pass, array(PDO::MYSQL_ATTR_INIT_COMMAND => $create)); + $db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); $info = $db->errorInfo(); var_dump($info[0]); diff --git a/ext/pdo_mysql/tests/pdo_mysql_attr_multi_statements.phpt b/ext/pdo_mysql/tests/pdo_mysql_attr_multi_statements.phpt index f268117821..34d9d57ce3 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_attr_multi_statements.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_attr_multi_statements.phpt @@ -20,6 +20,7 @@ error_reporting=E_ALL $table = sprintf("test_%s", md5(mt_rand(0, PHP_INT_MAX))); $db = new PDO($dsn, $user, $pass); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); + $db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); $db->exec(sprintf('DROP TABLE IF EXISTS %s', $table)); $create = sprintf('CREATE TABLE %s(id INT)', $table); $db->exec($create); @@ -37,6 +38,7 @@ error_reporting=E_ALL // New connection, does not allow multiple statements. $db = new PDO($dsn, $user, $pass, array(PDO::MYSQL_ATTR_MULTI_STATEMENTS => false)); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); + $db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); $stmt = $db->query(sprintf('SELECT * FROM %s; INSERT INTO %s(id) VALUES (3)', $table, $table)); var_dump($stmt); $info = $db->errorInfo(); diff --git a/ext/pdo_mysql/tests/pdo_mysql_attr_statement_class.phpt b/ext/pdo_mysql/tests/pdo_mysql_attr_statement_class.phpt index 77f231d28f..4bbf639939 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_attr_statement_class.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_attr_statement_class.phpt @@ -11,6 +11,7 @@ $db = MySQLPDOTest::factory(); <?php require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); $db = MySQLPDOTest::factory(); + $db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); MySQLPDOTest::createTestTable($db); $default = $db->getAttribute(PDO::ATTR_STATEMENT_CLASS); diff --git a/ext/pdo_mysql/tests/pdo_mysql_begintransaction.phpt b/ext/pdo_mysql/tests/pdo_mysql_begintransaction.phpt index fb550b1aa2..cdecc97b2e 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_begintransaction.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_begintransaction.phpt @@ -13,6 +13,7 @@ if (false == MySQLPDOTest::detect_transactional_mysql_engine($db)) <?php require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); $db = MySQLPDOTest::factory(); + MySQLPDOTest::createTestTable($db, MySQLPDOTest::detect_transactional_mysql_engine($db)); if (1 !== $db->getAttribute(PDO::ATTR_AUTOCOMMIT)) @@ -31,6 +32,7 @@ if (false == MySQLPDOTest::detect_transactional_mysql_engine($db)) /* This is the PDO way to close a connection */ $db = null; $db = MySQLPDOTest::factory(); + $db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); /* Autocommit was off - by definition. Commit was not issued. DELETE should have been rolled back. */ if (!($stmt = $db->query('SELECT id, label FROM test ORDER BY id ASC'))) diff --git a/ext/pdo_mysql/tests/pdo_mysql_closecursor_error.phpt b/ext/pdo_mysql/tests/pdo_mysql_closecursor_error.phpt index 1f9421fe8a..5d4c933542 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_closecursor_error.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_closecursor_error.phpt @@ -10,6 +10,7 @@ MySQLPDOTest::skip(); <?php require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); $db = MySQLPDOTest::factory(); +$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); $stmt = $db->query('SELECT 1; SELECT x FROM does_not_exist'); var_dump($stmt->fetchAll()); diff --git a/ext/pdo_mysql/tests/pdo_mysql_pconnect.phpt b/ext/pdo_mysql/tests/pdo_mysql_pconnect.phpt index 51e5b7b44a..72a29f9e36 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_pconnect.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_pconnect.phpt @@ -23,7 +23,7 @@ MySQLPDOTest::skip(); $db1->exec('SET @pdo_persistent_connection=1'); $stmt = $db2->query('SELECT @pdo_persistent_connection as _pers'); $tmp = $stmt->fetch(PDO::FETCH_ASSOC); - if ($tmp['_pers'] !== '1') + if ($tmp['_pers'] != 1) printf("[001] Both handles should use the same connection."); $stmt = $db1->query('SELECT CONNECTION_ID() as _con1'); diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated.phpt index b23d697efa..f4f1dcd13d 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_emulated.phpt @@ -11,6 +11,7 @@ $db = MySQLPDOTest::factory(); <?php require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); $db = MySQLPDOTest::factory(); + $db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); function prepex($offset, &$db, $query, $input_params = null, $error_info = null) { diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_clear_error.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_clear_error.phpt index 88f9f5dcf1..5f32da7412 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_clear_error.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_clear_error.phpt @@ -11,6 +11,7 @@ $db = MySQLPDOTest::factory(); <?php require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); $db = MySQLPDOTest::factory(); + $db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); try { diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_dup_named_placeholder.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_dup_named_placeholder.phpt index 1c5ddc407f..8e52154902 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_dup_named_placeholder.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_dup_named_placeholder.phpt @@ -11,6 +11,7 @@ $db = MySQLPDOTest::factory(); <?php require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); $db = MySQLPDOTest::factory(); + $db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); try { diff --git a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_placeholder_everywhere.phpt b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_placeholder_everywhere.phpt index a7a76a462b..50819f9695 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_prepare_native_placeholder_everywhere.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_prepare_native_placeholder_everywhere.phpt @@ -11,6 +11,8 @@ $db = MySQLPDOTest::factory(); <?php require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); $db = MySQLPDOTest::factory(); + $db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); + try { $db->setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, 1); if (1 != $db->getAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY)) @@ -41,16 +43,7 @@ $db = MySQLPDOTest::factory(); var_export($stmt->errorCode(), true), var_export($stmt->errorInfo(), true)); - $tmp = $stmt->fetchAll(PDO::FETCH_ASSOC); - if (!MySQLPDOTest::isPDOMySQLnd()) { - if (isset($tmp[0]['id'])) { - // libmysql should return a string here whereas mysqlnd returns a native int - if (gettype($tmp[0]['id']) == 'string') - // convert to int for the test output... - settype($tmp[0]['id'], 'integer'); - } - } - var_dump($tmp); + var_dump($stmt->fetchAll(PDO::FETCH_ASSOC)); } catch (PDOException $e) { printf("[001] %s [%s] %s\n", @@ -82,7 +75,7 @@ array(1) { ["?"]=> string(2) "id" ["id"]=> - int(1) + string(1) "1" ["label"]=> string(4) "row1" } diff --git a/ext/pdo_mysql/tests/pdo_mysql_stmt_fetchobject.phpt b/ext/pdo_mysql/tests/pdo_mysql_stmt_fetchobject.phpt index e83a99f529..bb92353fbe 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_stmt_fetchobject.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_stmt_fetchobject.phpt @@ -21,6 +21,7 @@ if (!$ok) <?php require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); $db = MySQLPDOTest::factory(); +$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); MySQLPDOTest::createTestTable($db); try { diff --git a/ext/pdo_mysql/tests/pdo_mysql_subclass.phpt b/ext/pdo_mysql/tests/pdo_mysql_subclass.phpt index 0a996be8f5..d79de14862 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_subclass.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_subclass.phpt @@ -51,6 +51,7 @@ MySQLPDOTest::skip(); } $db = new MyPDO(PDO_MYSQL_TEST_DSN, PDO_MYSQL_TEST_USER, PDO_MYSQL_TEST_PASS); + $db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); $db->exec('DROP TABLE IF EXISTS test'); $db->exec('CREATE TABLE test(id INT)'); $db->exec('INSERT INTO test(id) VALUES (1), (2)'); |