Skip to content

PDO::PARAM_INT is ignored in pdo_oci ext #12578

Open
@mvorisek

Description

@mvorisek

Description

The following code:

<?php

$sql = 'SELECT :a a, dump(:a) a_type, :b b, dump(:b) b_type, '
    . '4 num, dump(4) num_type, \'4\' str, dump(\'4\') str_type, '
    . '(select 1 from dual where \'04\' = :a) a_where, '
    . '(select 1 from dual where \'04\' = 4) num_where '
    . 'FROM dual';
$num = 4;
$str = '4';

// test oci8 ext
$conn = oci_connect('system', 'atk4_pass', '127.0.0.1/xe');
$statement = oci_parse($conn, $sql);
oci_bind_by_name($statement, ':a', $num, -1, SQLT_INT);
oci_bind_by_name($statement, ':b', $str);
oci_execute($statement);
$row = oci_fetch_array($statement, OCI_ASSOC);
print_r($row);
var_dump($row['A_WHERE']);

// test pdo_oci
$pdo = new \PDO('oci:dbname=127.0.0.1/xe', 'system', 'atk4_pass');
$statement = $pdo->prepare($sql);
$statement->bindValue(':a', $num, \PDO::PARAM_INT);
$statement->bindValue(':b', $str);
$statement->execute();
$row = $statement->fetch(\PDO::FETCH_ASSOC);
print_r($row);
var_dump($row['A_WHERE']);

Expected output:

- actual
+ expected
 Array
 (
     [A] => 4
     [A_TYPE] => Typ=2 Len=2: 193,5
     [B] => 4
     [B_TYPE] => Typ=1 Len=1: 52
     [NUM] => 4
     [NUM_TYPE] => Typ=2 Len=2: 193,5
     [STR] => 4
     [STR_TYPE] => Typ=96 Len=1: 52
     [A_WHERE] => 1
     [NUM_WHERE] => 1
 )
 string(1) "1"
 Array
 (
     [A] => 4
-    [A_TYPE] => Typ=1 Len=1: 52
+    [A_TYPE] => Typ=2 Len=2: 193,5
     [B] => 4
     [B_TYPE] => Typ=1 Len=1: 52
     [NUM] => 4
     [NUM_TYPE] => Typ=2 Len=2: 193,5
     [STR] => 4
     [STR_TYPE] => Typ=96 Len=1: 52
-    [A_WHERE] =>
+    [A_WHERE] => 1
     [NUM_WHERE] => 1
 )
-NULL
+string(1) "1"

As you can see, oci8 binds the parameter with correct type, but pdo_oci has a bug. pdo_oci needs to be fixed as binding with incorrect type have implications as shown in the example ('04' = 4 is true, but '04' = '4' is not).

In other DBs (I tested MySQL, PostgreSQL, T-SQL/MSSQL) PDO seems to be honoring the bind type correctly.

Can be tested localy using Dockerized Oracle Database:

docker run -it -p 1521:1521 -eORACLE_PASSWORD=atk4_pass gvenzl/oracle-xe:18-slim-faststart

PHP Version

any

Operating System

any

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions