Skip to content

Commit 438b025

Browse files
committed
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.
1 parent 012439b commit 438b025

10 files changed

+88
-13
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ PHP NEWS
2525
. Fixed bug #40913 (PDO_MYSQL: PDO::PARAM_LOB does not bind to a stream for
2626
fetching a BLOB). (Nikita)
2727

28+
. PDO SQLite:
29+
. Fixed bug #38334 (Proper data-type support for PDO_SQLITE). (Nikita)
30+
2831
- PSpell:
2932
. Convert resource<pspell> to object \PSpell. (Sara)
3033
. Convert resource<pspell config> to object \PSPellConfig. (Sara)

UPGRADING

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ PHP 8.1 UPGRADE NOTES
5353
matches the behavior of native prepared statements. You can restore the
5454
previous behavior by enabling the PDO::ATTR_STRINGIFY_FETCHES option.
5555

56+
- PDO SQLite:
57+
. Integers and floats in results sets will now be returned using native PHP
58+
types. You can restore the previous behavior by enabling the
59+
PDO::ATTR_STRINGFIY_FETCHES option.
60+
5661
- Standard:
5762
. version_compare() no longer accepts undocumented operator abbreviations.
5863

ext/pdo_sqlite/sqlite_statement.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,24 @@ static int pdo_sqlite_stmt_get_col(
267267
ZVAL_NULL(result);
268268
return 1;
269269

270+
case SQLITE_INTEGER: {
271+
int64_t i = sqlite3_column_int64(S->stmt, colno);
272+
#if SIZEOF_ZEND_LONG < 8
273+
if (i > ZEND_LONG_MAX || i < ZEND_LONG_MIN) {
274+
ZVAL_STRINGL(result,
275+
(char *) sqlite3_column_text(S->stmt, colno),
276+
sqlite3_column_bytes(S->stmt, colno));
277+
return 1;
278+
}
279+
#endif
280+
ZVAL_LONG(result, i);
281+
return 1;
282+
}
283+
284+
case SQLITE_FLOAT:
285+
ZVAL_DOUBLE(result, sqlite3_column_double(S->stmt, colno));
286+
return 1;
287+
270288
case SQLITE_BLOB:
271289
ZVAL_STRINGL_FAST(result,
272290
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
300318
switch (sqlite3_column_type(S->stmt, colno)) {
301319
case SQLITE_NULL:
302320
add_assoc_string(return_value, "native_type", "null");
321+
add_assoc_long(return_value, "pdo_type", PDO_PARAM_NULL);
303322
break;
304323

305324
case SQLITE_FLOAT:
306325
add_assoc_string(return_value, "native_type", "double");
326+
add_assoc_long(return_value, "pdo_type", PDO_PARAM_STR);
307327
break;
308328

309329
case SQLITE_BLOB:
310330
add_next_index_string(&flags, "blob");
311331
case SQLITE_TEXT:
312332
add_assoc_string(return_value, "native_type", "string");
333+
add_assoc_long(return_value, "pdo_type", PDO_PARAM_STR);
313334
break;
314335

315336
case SQLITE_INTEGER:
316337
add_assoc_string(return_value, "native_type", "integer");
338+
add_assoc_long(return_value, "pdo_type", PDO_PARAM_INT);
317339
break;
318340
}
319341

@@ -330,7 +352,6 @@ static int pdo_sqlite_stmt_col_meta(pdo_stmt_t *stmt, zend_long colno, zval *ret
330352
#endif
331353

332354
add_assoc_zval(return_value, "flags", &flags);
333-
add_assoc_long(return_value, "pdo_type", PDO_PARAM_STR);
334355

335356
return SUCCESS;
336357
}

ext/pdo_sqlite/tests/bug38334.phpt

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
--TEST--
2+
Bug #38334: Proper data-type support for PDO_SQLITE
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('pdo_sqlite')) print 'skip not loaded';
6+
?>
7+
--FILE--
8+
<?php
9+
10+
$db = new PDO('sqlite::memory:');
11+
$db->exec('CREATE TABLE test (i INTEGER , f DOUBLE, s VARCHAR(255))');
12+
$db->exec('INSERT INTO test VALUES (42, 46.7, "test")');
13+
var_dump($db->query('SELECT * FROM test')->fetch(PDO::FETCH_ASSOC));
14+
15+
// Check handling of integers larger than 32-bit.
16+
$db->exec('INSERT INTO test VALUES (10000000000, 0.0, "")');
17+
$i = $db->query('SELECT i FROM test WHERE f = 0.0')->fetchColumn(0);
18+
if (PHP_INT_SIZE >= 8) {
19+
var_dump($i === 10000000000);
20+
} else {
21+
var_dump($i === '10000000000');
22+
}
23+
24+
// Check storing of strings into integer/float columns.
25+
$db->exec('INSERT INTO test VALUES ("test", "test", "x")');
26+
var_dump($db->query('SELECT * FROM test WHERE s = "x"')->fetch(PDO::FETCH_ASSOC));
27+
28+
?>
29+
--EXPECT--
30+
array(3) {
31+
["i"]=>
32+
int(42)
33+
["f"]=>
34+
float(46.7)
35+
["s"]=>
36+
string(4) "test"
37+
}
38+
bool(true)
39+
array(3) {
40+
["i"]=>
41+
string(4) "test"
42+
["f"]=>
43+
string(4) "test"
44+
["s"]=>
45+
string(1) "x"
46+
}

ext/pdo_sqlite/tests/bug44327_2.phpt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ object(PDOStatement)#%d (1) {
3232
string(23) "select 1 as queryString"
3333
array(2) {
3434
["queryString"]=>
35-
string(1) "1"
35+
int(1)
3636
[0]=>
37-
string(1) "1"
37+
int(1)
3838
}
3939
NULL
4040
--------------------------------------------
@@ -45,6 +45,6 @@ object(PDOStatement)#%d (1) {
4545
string(23) "select 1 as queryString"
4646
object(PDORow)#%d (1) {
4747
["queryString"]=>
48-
string(1) "1"
48+
int(1)
4949
}
50-
string(1) "1"
50+
int(1)

ext/pdo_sqlite/tests/bug44327_3.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ object(PDORow)#%d (2) {
2323
["queryString"]=>
2424
string(25) "select 1 as queryStringxx"
2525
["queryStringxx"]=>
26-
string(1) "1"
26+
int(1)
2727
}
2828
string(25) "select 1 as queryStringxx"
2929
NULL
30-
string(1) "1"
30+
int(1)
3131
---
3232
NULL
3333
NULL

ext/pdo_sqlite/tests/bug78192.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ array(1) {
2929
[0]=>
3030
array(2) {
3131
["id"]=>
32-
string(2) "10"
32+
int(10)
3333
["name"]=>
3434
string(4) "test"
3535
}
@@ -38,7 +38,7 @@ array(1) {
3838
[0]=>
3939
array(3) {
4040
["id"]=>
41-
string(2) "10"
41+
int(10)
4242
["name"]=>
4343
string(4) "test"
4444
["new_col"]=>

ext/pdo_sqlite/tests/bug79664.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ if ($stmt->columnCount()) {
1818
array(6) {
1919
["native_type"]=>
2020
string(4) "null"
21+
["pdo_type"]=>
22+
int(0)
2123
["flags"]=>
2224
array(0) {
2325
}
24-
["pdo_type"]=>
25-
int(3)
2626
["name"]=>
2727
string(1) "1"
2828
["len"]=>

ext/pdo_sqlite/tests/bug_63916-2.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@ var_dump($num,$result[0]);
2424
?>
2525
--EXPECT--
2626
int(2147483647)
27-
string(10) "2147483647"
27+
int(2147483647)

ext/pdo_sqlite/tests/bug_63916.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@ var_dump($num,$result[0]);
2424
?>
2525
--EXPECT--
2626
int(100004313234244)
27-
string(15) "100004313234244"
27+
int(100004313234244)

0 commit comments

Comments
 (0)