1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Support native types in PDO SQLite

Return integers and floats as native types if possible. As usual,
the old behavior can be restored by enabling ATTR_STRINGIFY_FETCHES.

Fixes bug #38334.
This commit is contained in:
Nikita Popov
2020-12-23 10:57:19 +01:00
parent 012439b78e
commit 438b025a28
10 changed files with 88 additions and 13 deletions

3
NEWS
View File

@@ -25,6 +25,9 @@ PHP NEWS
. Fixed bug #40913 (PDO_MYSQL: PDO::PARAM_LOB does not bind to a stream for
fetching a BLOB). (Nikita)
. PDO SQLite:
. Fixed bug #38334 (Proper data-type support for PDO_SQLITE). (Nikita)
- PSpell:
. Convert resource<pspell> to object \PSpell. (Sara)
. Convert resource<pspell config> to object \PSPellConfig. (Sara)

View File

@@ -53,6 +53,11 @@ PHP 8.1 UPGRADE NOTES
matches the behavior of native prepared statements. You can restore the
previous behavior by enabling the PDO::ATTR_STRINGIFY_FETCHES option.
- PDO SQLite:
. Integers and floats in results sets will now be returned using native PHP
types. You can restore the previous behavior by enabling the
PDO::ATTR_STRINGFIY_FETCHES option.
- Standard:
. version_compare() no longer accepts undocumented operator abbreviations.

View File

@@ -267,6 +267,24 @@ static int pdo_sqlite_stmt_get_col(
ZVAL_NULL(result);
return 1;
case SQLITE_INTEGER: {
int64_t i = sqlite3_column_int64(S->stmt, colno);
#if SIZEOF_ZEND_LONG < 8
if (i > ZEND_LONG_MAX || i < ZEND_LONG_MIN) {
ZVAL_STRINGL(result,
(char *) sqlite3_column_text(S->stmt, colno),
sqlite3_column_bytes(S->stmt, colno));
return 1;
}
#endif
ZVAL_LONG(result, i);
return 1;
}
case SQLITE_FLOAT:
ZVAL_DOUBLE(result, sqlite3_column_double(S->stmt, colno));
return 1;
case SQLITE_BLOB:
ZVAL_STRINGL_FAST(result,
sqlite3_column_blob(S->stmt, colno), sqlite3_column_bytes(S->stmt, colno));
@@ -300,20 +318,24 @@ static int pdo_sqlite_stmt_col_meta(pdo_stmt_t *stmt, zend_long colno, zval *ret
switch (sqlite3_column_type(S->stmt, colno)) {
case SQLITE_NULL:
add_assoc_string(return_value, "native_type", "null");
add_assoc_long(return_value, "pdo_type", PDO_PARAM_NULL);
break;
case SQLITE_FLOAT:
add_assoc_string(return_value, "native_type", "double");
add_assoc_long(return_value, "pdo_type", PDO_PARAM_STR);
break;
case SQLITE_BLOB:
add_next_index_string(&flags, "blob");
case SQLITE_TEXT:
add_assoc_string(return_value, "native_type", "string");
add_assoc_long(return_value, "pdo_type", PDO_PARAM_STR);
break;
case SQLITE_INTEGER:
add_assoc_string(return_value, "native_type", "integer");
add_assoc_long(return_value, "pdo_type", PDO_PARAM_INT);
break;
}
@@ -330,7 +352,6 @@ static int pdo_sqlite_stmt_col_meta(pdo_stmt_t *stmt, zend_long colno, zval *ret
#endif
add_assoc_zval(return_value, "flags", &flags);
add_assoc_long(return_value, "pdo_type", PDO_PARAM_STR);
return SUCCESS;
}

View File

@@ -0,0 +1,46 @@
--TEST--
Bug #38334: Proper data-type support for PDO_SQLITE
--SKIPIF--
<?php
if (!extension_loaded('pdo_sqlite')) print 'skip not loaded';
?>
--FILE--
<?php
$db = new PDO('sqlite::memory:');
$db->exec('CREATE TABLE test (i INTEGER , f DOUBLE, s VARCHAR(255))');
$db->exec('INSERT INTO test VALUES (42, 46.7, "test")');
var_dump($db->query('SELECT * FROM test')->fetch(PDO::FETCH_ASSOC));
// Check handling of integers larger than 32-bit.
$db->exec('INSERT INTO test VALUES (10000000000, 0.0, "")');
$i = $db->query('SELECT i FROM test WHERE f = 0.0')->fetchColumn(0);
if (PHP_INT_SIZE >= 8) {
var_dump($i === 10000000000);
} else {
var_dump($i === '10000000000');
}
// Check storing of strings into integer/float columns.
$db->exec('INSERT INTO test VALUES ("test", "test", "x")');
var_dump($db->query('SELECT * FROM test WHERE s = "x"')->fetch(PDO::FETCH_ASSOC));
?>
--EXPECT--
array(3) {
["i"]=>
int(42)
["f"]=>
float(46.7)
["s"]=>
string(4) "test"
}
bool(true)
array(3) {
["i"]=>
string(4) "test"
["f"]=>
string(4) "test"
["s"]=>
string(1) "x"
}

View File

@@ -32,9 +32,9 @@ object(PDOStatement)#%d (1) {
string(23) "select 1 as queryString"
array(2) {
["queryString"]=>
string(1) "1"
int(1)
[0]=>
string(1) "1"
int(1)
}
NULL
--------------------------------------------
@@ -45,6 +45,6 @@ object(PDOStatement)#%d (1) {
string(23) "select 1 as queryString"
object(PDORow)#%d (1) {
["queryString"]=>
string(1) "1"
int(1)
}
string(1) "1"
int(1)

View File

@@ -23,11 +23,11 @@ object(PDORow)#%d (2) {
["queryString"]=>
string(25) "select 1 as queryStringxx"
["queryStringxx"]=>
string(1) "1"
int(1)
}
string(25) "select 1 as queryStringxx"
NULL
string(1) "1"
int(1)
---
NULL
NULL

View File

@@ -29,7 +29,7 @@ array(1) {
[0]=>
array(2) {
["id"]=>
string(2) "10"
int(10)
["name"]=>
string(4) "test"
}
@@ -38,7 +38,7 @@ array(1) {
[0]=>
array(3) {
["id"]=>
string(2) "10"
int(10)
["name"]=>
string(4) "test"
["new_col"]=>

View File

@@ -18,11 +18,11 @@ if ($stmt->columnCount()) {
array(6) {
["native_type"]=>
string(4) "null"
["pdo_type"]=>
int(0)
["flags"]=>
array(0) {
}
["pdo_type"]=>
int(3)
["name"]=>
string(1) "1"
["len"]=>

View File

@@ -24,4 +24,4 @@ var_dump($num,$result[0]);
?>
--EXPECT--
int(2147483647)
string(10) "2147483647"
int(2147483647)

View File

@@ -24,4 +24,4 @@ var_dump($num,$result[0]);
?>
--EXPECT--
int(100004313234244)
string(15) "100004313234244"
int(100004313234244)