Bug #72267 [NEW]: SQLite PDOStatement iterator problems

From: Date: Thu, 26 May 2016 13:50:44 +0000
Subject: Bug #72267 [NEW]: SQLite PDOStatement iterator problems
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-201282@lists.php.net to get a copy of this message
From:             baptiste dot gaillard at gomoob dot com
Operating system: 
PHP version:      Irrelevant
Package:          PDO SQLite
Bug Type:         Bug
Bug description:SQLite PDOStatement iterator problems

Description:
------------
This has been reported on Stackoverflow here
http://stackoverflow.com/questions/37431600/pdo-sqlite-extension-pdostatement-bug
but nobody provided a satisfying response.

When we use an in memory SQLite and a PDOStatement inside a foreach loop
the iterator state associated to the PDOStatement can be updated by
other PDOStatement in the source code. 

Please test the provided test script provided with this case, this
script shows that the PDOStatement used in a foreach loop can be
modified by other PDOStatement objects. The output displays "1" and "3"
but should display only "1" IMO. 

This behavior does not appear with MySQL so I think this behavior is
clearly not expected and is very dangerous.

The official PHP documentation indicates a PDOStatement "Represents a
prepared statement and, after the statement is executed, an associated
result set.".

So we expect the PDOStatement to be something like an "in memory" object
which embeds our results and which cannot be touched ("magically") by
other peaces of code elsewhere. 

Test script:
---------------
// Insert 2 rows inside our table
$pdoStatementInsert = $pdo->prepare(
    'insert into scheduled_task(id, task_class, date_and_time,
task_parameters) values(?,?,?,?)'
);
$pdoStatementInsert->execute([1, 'tk1', '2015-01-01', '{}']);
$pdoStatementInsert->execute([2, 'tk2', '2015-01-02', '{}']);

// Ensure the 2 rows were inserted
$pdoStatementCount->execute();
var_dump('Then table has size \'' .
intval($pdoStatementCount->fetchColumn()) . '\'.');

// Now create a statement to select only the first row
$pdoStatementSelect1 = $pdo->query('select * from scheduled_task where
date_and_time < \'2015-01-02\'');

// Here it seems their is a bug with the Iterator associated to the PDO
Statement
foreach($pdoStatementSelect1 as $row) {
    var_dump($row['id']);

    // Inserts a new row inside our table
    $pdoStatementInsert = $pdo->prepare(
        'insert into scheduled_task(id, task_class, date_and_time,
task_parameters) values(?,?,?,?)'
    );
    if($pdoStatementInsert->execute([3, 'tk3', '2015-01-01', '{}'])
===
false)  {
        var_dump('Fail inserting row in loop !');
        var_dump($pdoStatementInsert->errorCode());
        var_dump($pdoStatementInsert->errorInfo());
    }

    // Deletes the first row
    $pdo->query('delete from scheduled_task where id = ' . $row['id']);
}

// This fails with SQLite, we should have 2 rows inside our table here
$pdoStatementCount->execute();
var_dump('At the end table has size \'' .
intval($pdoStatementCount->fetchColumn()) . '\'.');

Expected result:
----------------
string(32) "At beginning table has size '0'."
string(24) "Then table has size '2'."
string(1) "1"
string(30) "At the end table has size '2'."

Actual result:
--------------
string(32) "At beginning table has size '0'."
string(24) "Then table has size '2'."
string(1) "1"
string(1) "3"
string(30) "At the end table has size '1'."

-- 
Edit bug report at https://bugs.php.net/bug.php?id=72267&edit=1
-- 
Try a snapshot (PHP 5.4):   https://bugs.php.net/fix.php?id=72267&r=trysnapshot54
Try a snapshot (PHP 5.5):   https://bugs.php.net/fix.php?id=72267&r=trysnapshot55
Try a snapshot (trunk):     https://bugs.php.net/fix.php?id=72267&r=trysnapshottrunk
Fixed in SVN:               https://bugs.php.net/fix.php?id=72267&r=fixed
Fixed in release:           https://bugs.php.net/fix.php?id=72267&r=alreadyfixed
Need backtrace:             https://bugs.php.net/fix.php?id=72267&r=needtrace
Need Reproduce Script:      https://bugs.php.net/fix.php?id=72267&r=needscript
Try newer version:          https://bugs.php.net/fix.php?id=72267&r=oldversion
Not developer issue:        https://bugs.php.net/fix.php?id=72267&r=support
Expected behavior:          https://bugs.php.net/fix.php?id=72267&r=notwrong
Not enough info:            https://bugs.php.net/fix.php?id=72267&r=notenoughinfo
Submitted twice:            https://bugs.php.net/fix.php?id=72267&r=submittedtwice
register_globals:           https://bugs.php.net/fix.php?id=72267&r=globals
PHP 4 support discontinued: https://bugs.php.net/fix.php?id=72267&r=php4
Daylight Savings:           https://bugs.php.net/fix.php?id=72267&r=dst
IIS Stability:              https://bugs.php.net/fix.php?id=72267&r=isapi
Install GNU Sed:            https://bugs.php.net/fix.php?id=72267&r=gnused
Floating point limitations: https://bugs.php.net/fix.php?id=72267&r=float
No Zend Extensions:         https://bugs.php.net/fix.php?id=72267&r=nozend
MySQL Configuration Error:  https://bugs.php.net/fix.php?id=72267&r=mysqlcfg



Thread (2 messages)

« previous php.bugs (#201282) next »