Bug #77764 [Com]: Binding of SQLT_NUM variable resolves as NULL in SQL

From: Date: Sat, 04 Sep 2021 12:19:39 +0000
Subject: Bug #77764 [Com]: Binding of SQLT_NUM variable resolves as NULL in SQL
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-236399@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=77764&edit=1

 ID:                 77764
 Comment by:         php-oci8 dot pkoch at dfgh dot net
 Reported by:        m dot a dot ogarkov at gmail dot com
 Summary:            Binding of SQLT_NUM variable resolves as NULL in SQL
 Status:             Open
 Type:               Bug
 Package:            OCI8 related
 Operating System:   Linux
 PHP Version:        7.3.3
 Block user comment: N
 Private report:     N

 New Comment:

oci_bind_by_name() should reject $type==SQLT_NUM.

Bind-type SQLT_NUM will ask oci8 to store/fetch an integer value into/from a 21 byte array where the
integer is stored in the oracle-internal NUMBER-format.

But the pointer that is used with SQLT_NUM-binds points to an 8-byte integer value (zend_long).
It's unpredictable what happens in this case. OCI8 will write 21 bytes into a zend_long-value.
This overwrites 13 bytes immediately after the zend_long value and the zend_long-value will have a
wrong value.

On my machine

$conn=oci_new_connect('scott','tiger','ORCL');
$stat=oci_parse($conn, "begin :out:=123; end;");
oci_bind_by_name($stat, ":out", $result, -1, SQLT_NUM);
oci_execute($stat);
var_dump($result);

results in:

int(1573570)

I think the SQLT_NUM-implementation is missing and SQLT_NUM shoud be rejected until someone has
written a conversion-routine between PHP-double and Oracle-NUMBER format.


Previous Comments:
------------------------------------------------------------------------
[2019-03-26 19:55:45] camporter1 at gmail dot com

The basic issue is that SQLT_NUM is treated just like SLQT_INT, which allows long values only.

For proper handling of doubles (which involves behind the scenes changing them into a string)
I'd recommend using SQLT_LNG, or not providing the type at all which does the same thing.

------------------------------------------------------------------------
[2019-03-18 14:11:22] m dot a dot ogarkov at gmail dot com

Description:
------------
When binding with SQLT_NUM type, we get NULL in sql/plsql.
Variables is converted to INT, why int? 

Test script:
---------------
<?php
declare(strict_types=1);

$handle = oci_connect(getenv("DB_USER"), getenv("DB_PASSWORD"),
getenv("DB_HOST"));
$var = 15.123;
$st = oci_parse($handle, "SELECT :0 FROM DUAL");
oci_bind_by_name($st, ":0", $var, -1, SQLT_NUM);
oci_execute($st);
var_dump(oci_fetch_array($st));
var_dump($var);


Expected result:
----------------
we should get NUMBER sql type:
"15.123" => (float) 15.123
"15" => (float) 15

Actual result:
--------------
array(2) {
  [0]=>
  NULL
  [":0"]=>
  NULL
}
int(15)



------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=77764&edit=1


Thread (4 messages)

« previous php.bugs (#236399) next »