php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #39199 Cannot load Lob data with more than 4000 bytes on ORACLE 10
Submitted: 2006-10-19 14:50 UTC Modified: 2010-12-10 02:19 UTC
Votes:11
Avg. Score:4.5 ± 0.8
Reproduced:8 of 8 (100.0%)
Same Version:3 (37.5%)
Same OS:5 (62.5%)
From: jarismar_silva at adplabs dot com dot br Assigned: felipe
Status: Closed Package: PDO related
PHP Version: 5.2.0 OS: *
Private report: No CVE-ID:
 [2006-10-19 14:50 UTC] jarismar_silva at adplabs dot com dot br
Description:
------------
Trying to read a CLOB field with has more than 4000 bytes result on empty stream.

Reproduce code:
---------------
<?php
/* Table structure
CREATE TABLE test_clob (
  id  NUMBER(10),
  data CLOB
)
*/

$sDSN = 'oci:dbname=//<server>:1521/<database>;charset=UTF-8';
$sUserName = '<user>';
$sPassword = '<passwd';

try {
  $oPDO = new PDO($sDSN, $sUserName, $sPassword, $aDriverOptions);
  $oStmt = $oPDO->prepare("insert into test_clob (id, data) values (:id, EMPTY_CLOB())");
  $iID = 1;
  $oStmt->bindParam(':id', $iID);
  if ($oStmt->execute()) {
    $oStmt = $oPDO->prepare("update test_clob set data=:value where id=1");
    $sData = '<4000 bytes or more>';
    $oStmt->bindParam(':value', $sData);
    if ($oStmt->execute() === false) {
      throw new Exception('Error on update clob');
    }
  } else {
    throw new Exception('Error on insert EMPTY_CLOB');
  }

  $oStmt = $oPDO->prepare("select data from test_clob where id = :id");
  $oStmt->bindParam('id', $iID);
  $oStmt->execute();
  $oResult = $oStmt->fetch();
  echo 'Read '.strlen(stream_get_contents($oResult['DATA'])).' characters <br>';

} catch (Exception $oE) {
  echo '<pre>';print_r($oStmt->errorInfo());echo "</pre><br>\n";
  echo $oException->getMessage()."<br>\n";
}
$oPDO = null;

Expected result:
----------------
Read N characters (N >0)

Actual result:
--------------
Read 0 characters

Patches

pdo_oci_stream_1.phpt (last revision 2010-12-09 02:58 UTC) by yes at example dot com)
pdo_oci_fread_1.phpt (last revision 2010-12-09 02:56 UTC) by yes at example dot com)
pdo_oci_stream_1.php (last revision 2010-12-07 07:44 UTC) by yes at example dot com)
oci_statement.c.diff (last revision 2010-12-07 07:42 UTC) by yes at example dot com)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-10-19 14:59 UTC] jarismar_silva at adplabs dot com dot br
jarismar_silva at adplabs.com.br
 [2006-10-23 12:10 UTC] jarismar_silva at adplabs dot com dot rb
I got this bug when working with Oracle instant client 10.2.0.1. Upgrading to 10.2.0.2 solved the problem.
 [2006-10-23 12:17 UTC] jarismar_silva at adplabs dot com dot br
I'm closing this bug, as updating to new Oracle instant client seems to solve the problem.
 [2006-11-07 17:05 UTC] jarismar_silva at adplabs dot com dot br
I'm reopening this bug. I have found that this bug still occurs with Oracle Client 10.2 and SuSE Enterprise Server v.9 Patch Lvl 3 / WinXP.
 [2006-11-07 17:11 UTC] diegotremper at gmail dot com
I obtained in the same error on Windows XP SP2
 [2006-11-07 17:25 UTC] jarismar_silva at adplabs dot com dot br
Previously (when close the bug) I have tested on Slackware 11 with Oracle Instant Client 10.2 and I stop getting this bug. The same on another box running Kubuntu and Oracle Instant Client 10.2. But I got the bug on a Suse server and many XP machines used on development.
 [2007-02-27 12:42 UTC] spatar at mail dot nnov dot ru
I have the similar problem.
My database has charset AL32UTF8. If a CLOB column's length is >2730 characters, then PDO returns empty stream for such CLOB.
With single-byte charset US7ASCII I can easily get CLOB of length >1000000 characters.

PHP: PHP 5.2.1RC3-dev (cli) (built: Feb  7 2007 16:57:25)
Oracle: 10.2.0.1.0
OS: SuSE Linux 9.2 (i586)

Reproduce code:
---------------

<?php

  mb_internal_encoding("utf-8");
  mb_http_output("utf-8");
  ob_start("mb_output_handler");

  try
  {
    $dbh = new PDO("oci:dbname=ORCL;charset=UTF8", "scott", "tiger");

    // It seems that "UTF8" is only correct value for "charset" in PDO constructor
    // because with "UTF8" it can read CLOB up to 2730 characters,
    // and with "UTF-8" or "AL32UTF8" it can read CLOB only up to 2048 characters.
    // Am I wrong?

    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $test_lengths = array(2000, 2730, 2731, 4000);

    foreach ($test_lengths as $test_length)
    {
      $dbh->beginTransaction();
      $stmt = $dbh->prepare("update test_lob set col_lob = ?");
      $stmt->bindValue(1, str_repeat("X", $test_length));
      $stmt->execute();
      $dbh->commit();

      echo "Column updated to $test_length characters\n";

      $stmt = $dbh->prepare("select * from test_lob");
      $stmt->execute();
      $stmt->setFetchMode(PDO::FETCH_NUM);
      $result = $stmt->fetchAll();

      echo "Read ".strlen(stream_get_contents($result[0][0]))." characters\n\n";
    }
  }
  catch (PDOException $e)
  {
    echo $e->getMessage()."\n";
    print_r($e->errorInfo);
  }

?>

Expected result:
----------------

Column updated to 2000 characters
Read 2000 characters

Column updated to 2730 characters
Read 2730 characters

Column updated to 2731 characters
Read 2731 characters

Column updated to 4000 characters
Read 4000 characters

Actual result:
--------------

Column updated to 2000 characters
Read 2000 characters

Column updated to 2730 characters
Read 2730 characters

Column updated to 2731 characters
Read 0 characters

SQLSTATE[HY000]: General error: 3127 OCIStmtExecute: ORA-03127: no new operations allowed until the active operation ends
 (/home/spatar/mvtm/www/php5.2-200701101130/ext/pdo_oci/oci_statement.c:142)
Array
(
    [0] => HY000
    [1] => 3127
    [2] => OCIStmtExecute: ORA-03127: no new operations allowed until the active operation ends
 (/home/spatar/mvtm/www/php5.2-200701101130/ext/pdo_oci/oci_statement.c:142)
)
Segmentation fault

GDB backtrace:
--------------

#0  0x086ac65a in ?? ()
#1  0x00000008 in ?? ()
#2  0xb728a73e in kpulbcr () from /u01/app/oracle/OraHome1/lib/libclntsh.so.10.1
#3  0xb75bec0c in ttcdrv () from /u01/app/oracle/OraHome1/lib/libclntsh.so.10.1
#4  0xb74b3f11 in nioqwa () from /u01/app/oracle/OraHome1/lib/libclntsh.so.10.1
#5  0xb7318327 in upirtrc () from /u01/app/oracle/OraHome1/lib/libclntsh.so.10.1
#6  0xb728dfc6 in kpurcsc () from /u01/app/oracle/OraHome1/lib/libclntsh.so.10.1
#7  0xb727c634 in kpulcls () from /u01/app/oracle/OraHome1/lib/libclntsh.so.10.1
#8  0xb731dac2 in OCILobClose () from /u01/app/oracle/OraHome1/lib/libclntsh.so.10.1
#9  0x08166de0 in oci_blob_close ()
#10 0x0828c66c in _php_stream_free ()
#11 0x0828c8c3 in stream_resource_regular_dtor ()
#12 0x082bf15e in list_entry_destructor ()
#13 0x082bd65b in zend_hash_del_key_or_index ()
#14 0x082bf31d in _zend_list_delete ()
#15 0x082aa669 in _zval_ptr_dtor ()
#16 0x082bd3e9 in zend_hash_destroy ()
#17 0x082b41c3 in _zval_dtor_func ()
#18 0x082aa669 in _zval_ptr_dtor ()
#19 0x082bd3e9 in zend_hash_destroy ()
#20 0x082b41c3 in _zval_dtor_func ()
#21 0x082aa669 in _zval_ptr_dtor ()
#22 0x082bd0ec in zend_hash_apply_deleter ()
#23 0x082bd2e7 in zend_hash_graceful_reverse_destroy ()
#24 0x082aca6d in shutdown_executor ()
#25 0x082b4bf7 in zend_deactivate ()
#26 0x0827b2f0 in php_request_shutdown ()
#27 0x0831a5f6 in main ()
 [2007-02-27 13:09 UTC] spatar at mail dot nnov dot ru
Forgot to paste table creation in my previous post:

create table TEST_LOB
(
  COL_LOB CLOB
);
insert into TEST_LOB values (NULL);
commit;

Also I've tested with PHP 5.2.1 and result is the same.
 [2007-02-28 22:28 UTC] spatar at mail dot nnov dot ru
A quote from OCILobRead() documentation:
"If the callback function is not defined, then the OCI_NEED_DATA error code will be returned. The application must call OCILobRead() over and over again to read more pieces of the LOB until the OCI_NEED_DATA error code is not returned."

A quote from OCILobWrite() documentation:
"If no callback function is defined, then OCILobWrite() returns the OCI_NEED_DATA error code. The application must call OCILobWrite() again to write more pieces of the LOB."

I propose the patch for php-5.2.1/ext/pdo_oci/oci_statement.c:

614c614
<	if (r != OCI_SUCCESS) {
---
>	if ((r != OCI_SUCCESS) && (r != OCI_NEED_DATA)) {
633c633
<	if (r != OCI_SUCCESS) {
---
>	if ((r != OCI_SUCCESS) && (r != OCI_NEED_DATA)) {
 [2009-04-25 14:39 UTC] jani@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php5.2-latest.tar.gz
 
For Windows:

  http://windows.php.net/snapshots/


 [2009-05-03 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2010-12-04 18:08 UTC] sixd@php.net
-Status: No Feedback +Status: Open -Assigned To: wez +Assigned To:
 [2010-12-04 18:08 UTC] sixd@php.net
Still reproduces.
Workaround is to use fread()
 [2010-12-10 01:33 UTC] felipe@php.net
Automatic comment from SVN on behalf of felipe
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=306149
Log: - Fixed bug #39199 (Cannot load Lob data with more than 4000 bytes on ORACLE 10)
  patch by: spatar at mail dot nnov dot ru
 [2010-12-10 02:19 UTC] felipe@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: felipe
 [2010-12-10 02:19 UTC] felipe@php.net
This bug has been fixed in SVN.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.

Thanks for the patch!
 [2011-09-14 12:41 UTC] php at codejungle dot org
I have the same problem, but with pdo (odbc & ms sql).
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Sun Apr 20 05:03:19 2014 UTC