pdo_pgsql always fill in NULL for empty BLOB
| Bug #46249 | pdo_pgsql always fill in NULL for empty BLOB | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Submitted: | 2008-10-07 18:00 UTC | Modified: | 2008-10-14 01:53 UTC |
|
||||||||||
| From: | hswong3i at gmail dot com | Assigned: | felipe (profile) | |||||||||||
| Status: | Closed | Package: | PDO related | |||||||||||
| PHP Version: | 5.2.6 | OS: | Debian | |||||||||||
| Private report: | No | CVE-ID: | None | |||||||||||
[2008-10-07 18:00 UTC] hswong3i at gmail dot com
Description: ------------ When pdo_pgsql working with: 1. BLOB field, 2. running INSERT/UPDATE queries, and 3. BLOB value with empty string '' It will always fill NULL into database and so result as buggy. INSERT/UPDATE BLOB value with NULL will function correctly. P.S. pdo_mysql is NOT buggy when running with similar programming logic, empty string pass into database correctly. Tested with PHP5.2.6 and PHP5.3-dev, both are buggy. Reproduce code: --------------- Please refer to http://drupal.org/node/316095#comment-1047830 for more information. Expected result: ---------------- Empty string should fill into database correctly. Actual result: -------------- Empty string is now stored as NULL.
Patches
Pull Requests
History
AllCommentsChangesGit/SVN commits
[2008-10-11 00:26 UTC] felipe@php.net
I can't reproduce using 5.3CVS: $db = new PDO('pgsql:host=localhost dbname=test', 'foo', 'bar', array(PDO::ATTR_STRINGIFY_FETCHES => TRUE)); $stmt = $db->prepare("INSERT INTO test_one_blob (blob1) VALUES (?)"); $stmt->execute(array('')); var_dump($db->errorinfo()); $stmt = $db->prepare("INSERT INTO test_one_blob (blob1) VALUES (:foo)"); $x = ''; $stmt->bindParam(':foo', $x); $stmt->execute(); var_dump($db->errorinfo()); $stmt = $db->query("INSERT INTO test_one_blob (blob1) VALUES ('')"); $stmt->execute(); teste=> select * from test_one_blob where blob1 is null; id | blob1 ----+------- (0 registros) Do you have tested using PDO directly, without Drupal's db_insert()?[2008-10-11 06:47 UTC] hswong3i at gmail dot com
[2008-10-11 11:47 UTC] felipe@php.net
[2008-10-11 19:05 UTC] felipe@php.net
[2008-10-12 16:39 UTC] hswong3i at gmail dot com
[2008-10-12 16:51 UTC] felipe@php.net
[2008-10-12 17:44 UTC] hswong3i at gmail dot com
[2008-10-13 02:31 UTC] hswong3i at gmail dot com
Bug still exists, but preform in another way... Please try the following code snippet: <?php function _var_dump($msg) { print("<code><pre>"); var_dump($msg); print("</pre></code>"); } function db_insert($sql, $data) { global $active_db; $stmt = $active_db->prepare($sql); $blob = fopen('php://memory', 'a'); fwrite($blob, $data); rewind($blob); $stmt->bindParam(':blob1', $blob, PDO::PARAM_LOB); $stmt->execute(); $id = $active_db->lastInsertId('test_one_blob_id_seq'); return $id; } function db_select($sql, $id) { global $active_db; $sql = 'SELECT * FROM "test_one_blob" WHERE "id" = :id'; $stmt = $active_db->prepare($sql); $stmt->bindParam(':id', $id); $stmt->execute(); return $stmt->fetch(PDO::FETCH_ASSOC); } $active_db = new PDO('pgsql:host=localhost dbname=DRUPAL_7', 'root', 'CHANGE', array(PDO::ATTR_STRINGIFY_FETCHES => TRUE)); // Test normal BLOB insert $data = "This is\000a test."; $id = db_insert('INSERT INTO "test_one_blob" ("blob1") VALUES (:blob1)', $data); $return = db_select('SELECT * FROM "test_one_blob" WHERE "id" = :id', $id); _var_dump("Test normal BLOB insert"); _var_dump($data); _var_dump($return['blob1']); _var_dump($data === $return['blob1']); // Test NULL BLOB insert $data = NULL; $id = db_insert('INSERT INTO "test_one_blob" ("blob1") VALUES (:blob1)', $data); $return = db_select('SELECT * FROM "test_one_blob" WHERE "id" = :id', $id); _var_dump("Test NULL BLOB insert"); _var_dump($data); _var_dump($return['blob1']); _var_dump($data === $return['blob1']); // Test empty BLOB insert $data = ""; $id = db_insert('INSERT INTO "test_one_blob" ("blob1") VALUES (:blob1)', $data); $return = db_select('SELECT * FROM "test_one_blob" WHERE "id" = :id', $id); _var_dump("Test empty BLOB insert"); _var_dump($data); _var_dump($return['blob1']); _var_dump($data === $return['blob1']); ?>[2008-10-13 02:32 UTC] hswong3i at gmail dot com
[2008-10-13 16:36 UTC] felipe@php.net
You aren't working with real NULL, but with a "empty resource". It's exaclty what happens to fwrite($fp, '') too. Only using the code below you will get the NULL as expect: $blob = null; $stmt->bindParam(':blob1', $blob, PDO::PARAM_LOB); Thanks.[2008-10-14 01:53 UTC] hswong3i at gmail dot com
Thanks felipe!! After update the code snippet of db_insert() as below, everything works fine: <?php function db_insert($sql, $data) { global $active_db; $stmt = $active_db->prepare($sql); if (is_null($data)) { $stmt->bindParam(':blob1', $data, PDO::PARAM_LOB); } else { $blob = fopen('php://memory', 'a'); fwrite($blob, $data); rewind($blob); $stmt->bindParam(':blob1', $blob, PDO::PARAM_LOB); } $stmt->execute(); $id = $active_db->lastInsertId('test_one_blob_id_seq'); return $id; } ?>