php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #60994 PDO_OCI: Reading a multibyte CLOB caps at 8192 characters
Submitted: 2012-02-06 16:13 UTC Modified: 2023-02-07 15:37 UTC
Votes:8
Avg. Score:4.6 ± 0.5
Reproduced:8 of 8 (100.0%)
Same Version:7 (87.5%)
Same OS:1 (12.5%)
From: php dot net at boedah dot de Assigned: ramsey (profile)
Status: Closed Package: PDO OCI
PHP Version: Irrelevant OS: OEL 5 / RHEL5 / Win7
Private report: No CVE-ID: None
View Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please !
Your email address:
MUST BE VALID
Solve the problem:
28 + 1 = ?
Subscribe to this entry?

 
 [2012-02-06 16:13 UTC] php dot net at boedah dot de
Description:
------------
Inserting large multibyte strings works fine,
reading them back in results in only 8192 characters read (=24576 bytes).

Even if inserting mixed single-multibyte strings, reading caps at 8192 
characters (even though the byte count is far less).

Inserting and reading 100000 single bytes work, though.

Attached a file with more debug output.

== PHP ==

We are using ZendServer 5.5.0:

PHP 5.3.8-ZS5.5.0 (cli) (built: Aug 23 2011 05:20:27)
Copyright (c) 1997-2011 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2011 Zend Technologies

But this bug also is on PHP 5.4.0RC8-dev

== Oracle ==

Oracle XE 10.2.0.1, but also on Enterprise 10.2.0.4.0.
Characterset: AL32UTF8

Test table:

create table TEST_LOB (
    tl_id         NUMBER(3),
    tl_byte_16    VARCHAR2(16 BYTE),
    tl_char_16    VARCHAR2(16 CHAR),
    tl_byte_4000  VARCHAR2(4000 BYTE),
    tl_char_4000  VARCHAR2(4000 CHAR),
    tl_blob       BLOB,
    tl_clob       CLOB,
    tl_date       DATE,
    tl_number     NUMBER
)


Test script:
---------------
$dsn = 'oci:dbname=(DESCRIPTION=(ADDRESS_LIST=(
                ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521)))
                (CONNECT_DATA=(SID=xe)));charset=AL32UTF8';
$username = 'USER';
$password = 'PW';
$lobTestTablename = 'TEST_LOB';
$id = -1;
$clobData = str_repeat('…', 8193);

$pdo = new PDO($dsn, $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->exec("delete from $lobTestTablename where tl_id < 0");
$pdoStmt = $pdo->prepare("insert into $lobTestTablename (tl_id, tl_clob) values (?, ?)");
$pdoStmt->bindParam(1, $id, PDO::PARAM_INT, null, null);
$pdoStmt->bindParam(2, $clobData, PDO::PARAM_STR, strlen($clobData), null);
$pdoStmt->execute();
$pdoStmt = $pdo->query("select * from $lobTestTablename where TL_ID = $id");
$row = $pdoStmt->fetch(PDO::FETCH_ASSOC);
$dataRead = stream_get_contents($row['TL_CLOB']);
printf("values equal: %s\n", var_export($clobData === $dataRead, true));

Expected result:
----------------
values equal: false

Actual result:
--------------
values equal: true

Patches

PdoOciClobReadError-test-with-more-debug-output (last revision 2012-02-06 16:19 UTC by php dot net at boedah dot de)

Add a Patch

Pull Requests

Pull requests:

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-02-06 16:20 UTC] php dot net at boedah dot de
adding the full code sample as patch did not work in the first place
-> attached it now
 [2012-02-07 02:42 UTC] aharvey@php.net
-Package: PDO related +Package: Oracle related
 [2012-06-26 22:37 UTC] sixd@php.net
-Package: Oracle related +Package: PDO related
 [2014-01-01 12:40 UTC] felipe@php.net
-Package: PDO related +Package: PDO OCI
 [2015-10-09 16:35 UTC] ashnazg@php.net
Comments on my experience with this bug -- http://stackoverflow.com/questions/33026617/pdo-oci-truncates-large-multibyte-clobs

I had the same experience using raw OCI, but found a way to work around it by passing a length value to LOB->read() that is larger than the actual CLOB, thus forcing it to read it all in one big read rather than in smaller chunks via a "while !LOB->eof() then LOB->read()" loop.  

Since PDO OCI already transforms the LOB into a Stream internally before returning it in my row, I have to guess that it is internally doing the same kind of loop, and thus is losing data in the same way.

Since I can't see a way in PDO OCI to force the same read-it-all-at-once behavior, I'm stuck.

My environments:  
- PHP 5.5.24 on RHEL6, oci8 v1.4.10
- PHP 5.5.11 on Win7, oci8 v1.4.10
 [2015-10-12 20:25 UTC] ashnazg@php.net
PHPT test for this bug is in PR #1566 (https://github.com/php/php-src/pull/1566)
 [2020-03-04 01:42 UTC] rstark at us dot ibm dot com
I have submitted a PR for this issue https://github.com/php/php-src/pull/5233
 [2021-11-22 14:40 UTC] cmb@php.net
The following pull request has been associated:

Patch Name: Fix PDO OCI Bug #60994 (Reading a multibyte CLOB caps at 8192 charact…
On GitHub:  https://github.com/php/php-src/pull/5233
Patch:      https://github.com/php/php-src/pull/5233.patch
 [2023-02-07 15:37 UTC] ramsey@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: ramsey
 [2023-02-07 15:37 UTC] ramsey@php.net
The fix for this bug has been committed.
If you are still experiencing this bug, try to check out latest source from https://github.com/php/php-src and re-test.
Thank you for the report, and for helping us make PHP better.

See discussion on https://github.com/php/php-src/pull/8018
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Mar 29 12:01:27 2024 UTC