1 (edited by jodybrabec 2016-03-03 20:23:52)

Topic: Oracle queries using oci_fetch_all causes Core Dumps

THIS ALSO REPORTED AT
https://bugs.php.net/bug.php?id=71708

Description:
------------
Oracle queries using oci_fetch_all causes Core Dumps sometimes if more than one record result set.

My setup: oracle-instantclient12.1-basic, OCI8 2.1.0, PHP 70, php70-php-cli (7.0.4-1.el6.remi - 2016-03-02), Red Hat EL 6.7, HTTPD 24

Observations on oci_fetch_all queries:
    1. If the query return set contains only one record, no problems.
    2. For more than one records return: Sometimes causes core dump (browser Error 500 Internal server error).
        a. If total return bytes is large, core dump probability increases (possible cap on rows * bytes per record per clumn cell)
        b. Or sometimes error on only 2+ records - yet removing various columns reduces error probability.
        c. Queries with "joins" increase error probability.


Test script:
---------------
// Cor dumps on many random queries - see Observations above
$statement= oci_parse($connID, $query);
oci_execute($statement)
// ================= BAD, CORE DUMP:
$numRows = oci_fetch_all($statement, $results);


Expected result:
----------------
yum php70-php-cli (remi) was updated last night, but still no work.

POSSIBLE WORKAROUND:

// *********** (THIS DOES NOT WORK RIGHT NOW!!!!) **********
$allCols = oci_num_fields($st);
$colNames = array();
for ($i_c = 1; $i_c <= $allCols; $i_c++) {
    $aColName  = oci_field_name($statement, $i_c);
    $colNames[] = $aColName;
}
$numRows = 0;
while (($row = oci_fetch_array($statement, OCI_BOTH)) != false) {
    $numRows++;
    foreach ($colNames as $i_c=>$aColName)
        $results[$aColName][] = $row[$aColName];
}


Actual result:
--------------
//~~~~~~~~~~~~~~~~~~~ CORE DUMP
#> tail /var/log/messages
Mar  2 22:17:17 node6 abrtd: Directory 'ccpp-2016-03-02-22:17:17-32306' creation detected
Mar  2 22:17:17 node6 abrt[32307]: Saved core dump of pid 32306 (/opt/remi/php70/root/usr/bin/php-cgi) to /var/spool/abrt/ccpp-2016-03-02-22:17:17-32306 (11370496 bytes)
Mar  2 22:17:17 node6 abrtd: Package 'php70-php-cli' isn't signed with proper key
Mar  2 22:17:17 node6 abrtd: 'post-create' on '/var/spool/abrt/ccpp-2016-03-02-22:17:17-32306' exited with 1
Mar  2 22:17:17 node6 abrtd: Deleting problem directory '/var/spool/abrt/ccpp-2016-03-02-22:17:17-32306'

Re: Oracle queries using oci_fetch_all causes Core Dumps

Thanks for the link. Have to wait for upstream answer.

How have you install OCI8 ?
(I recommend the php-oci8 or php70-php-oci8 package)

Laptop:  Fedora 38 + rpmfusion + remi (SCL only)
x86_64 builder: Fedora 39 + rpmfusion + remi-test
aarch64 builder: RHEL 9 with EPEL
Hosting Server: CentOS 8 Stream with EPEL, rpmfusion, remi

Re: Oracle queries using oci_fetch_all causes Core Dumps

Thanks, I'll try those versions.  For now I cooked up....

function my_oci_fetch_all($statement, &$output)
{
    /***
    * Workaround for oci_fetch_all - very similar to http://php.net/manual/en/function.oci-fetch-all.php
    * Uses oci_fetch_array iteratively (instead of oci_fetch_all which currently has problems whith 2+ query result set)
    * Fills &$output.  Returns the number of rows in &$output.
    * ##### Needs More Testing - let us know if problems #####
    * 2016-03-04 jodybrabec@gmail.com
     */
    $rows = 0;
    $allCols = oci_num_fields($statement);
    $colNames = array();
    for ($i_c = 1; $i_c <= $allCols; $i_c++) {
        $aColName  = oci_field_name($statement, $i_c);
        $colNames[$aColName] = $aColName; // force unique via key
    }
    while (($row = oci_fetch_array($statement, OCI_RETURN_LOBS)) != false)
    {
        $rows++;
        foreach ($colNames as $i_c=>$aColName)
            $output[$aColName][] = $row[$aColName];
    }
    return $rows;
}