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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: php dot net at boedah dot de
New email:
PHP Version: OS:

 

 [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)

Pull Requests

Pull requests:

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: Thu Nov 21 13:01:29 2024 UTC