]> granicus.if.org Git - php/commitdiff
Fixed bug #70308 (PDO::ATTR_PREFETCH is ignored)
authorChristopher Jones <christopher.jones@oracle.com>
Thu, 20 Aug 2015 04:09:30 +0000 (14:09 +1000)
committerChristopher Jones <christopher.jones@oracle.com>
Thu, 20 Aug 2015 04:09:30 +0000 (14:09 +1000)
NEWS
ext/pdo_oci/oci_driver.c
ext/pdo_oci/php_pdo_oci_int.h
ext/pdo_oci/tests/checkliveness.phpt [new file with mode: 0644]
ext/pdo_oci/tests/pdo_oci_attr_prefetch_1.phpt

diff --git a/NEWS b/NEWS
index 7cb982a17786b6d81d826dfef54722bec2e2c944..c82c9358d09f463f3ea66098000a692c9277d277 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,9 @@ PHP                                                                        NEWS
     (marcio dot web2 at gmail dot com)
   . Fixed bug causing exception traces with anon classes to be truncated. (Bob)
 
+- PDO_OCI:
+  . Fixed bug #70308 (PDO::ATTR_PREFETCH is ignored). (Chris Jones)
+
 - SPL:
   . Fixed bug #70303 (Incorrect constructor reflection for ArrayObject). (cmb)
 
index 25515544769477c5672d162d2b0dd87e283d8b3f..6cd583493b80422c03f1edbb15e09ef3bf0dc9d9 100644 (file)
@@ -302,15 +302,13 @@ static int oci_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len,
 
        }
 
-       prefetch = pdo_oci_sanitize_prefetch((long) pdo_attr_lval(driver_options, PDO_ATTR_PREFETCH, PDO_OCI_PREFETCH_DEFAULT));
-       if (prefetch) {
+       prefetch = H->prefetch;  /* Note 0 is allowed so in future REF CURSORs can be used & then passed with no row loss*/
+       H->last_err = OCIAttrSet(S->stmt, OCI_HTYPE_STMT, &prefetch, 0,
+                                                        OCI_ATTR_PREFETCH_ROWS, H->err);
+       if (!H->last_err) {
+               prefetch *= PDO_OCI_PREFETCH_ROWSIZE;
                H->last_err = OCIAttrSet(S->stmt, OCI_HTYPE_STMT, &prefetch, 0,
-                       OCI_ATTR_PREFETCH_ROWS, H->err);
-               if (!H->last_err) {
-                       prefetch *= PDO_OCI_PREFETCH_ROWSIZE;
-                       H->last_err = OCIAttrSet(S->stmt, OCI_HTYPE_STMT, &prefetch, 0,
-                               OCI_ATTR_PREFETCH_MEMORY, H->err);
-               }
+                                                                OCI_ATTR_PREFETCH_MEMORY, H->err);
        }
 
        stmt->driver_data = S;
@@ -460,6 +458,10 @@ static int oci_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval *val) /
 
                dbh->auto_commit = (unsigned int) (Z_LVAL_P(val)) ? 1 : 0;
                return 1;
+       } else if (attr == PDO_ATTR_PREFETCH) {
+               convert_to_long(val);
+               H->prefetch = pdo_oci_sanitize_prefetch(Z_LVAL_P(val));
+               return 1;
        } else {
                return 0;
        }
@@ -524,6 +526,9 @@ static int oci_handle_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return
                        ZVAL_BOOL(return_value, dbh->auto_commit);
                        return TRUE;
 
+               case PDO_ATTR_PREFETCH:
+                       ZVAL_LONG(return_value, H->prefetch);
+                       return TRUE;
                default:
                        return FALSE;
 
@@ -602,6 +607,8 @@ static int pdo_oci_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ *
        H = pecalloc(1, sizeof(*H), dbh->is_persistent);
        dbh->driver_data = H;
 
+       H->prefetch = PDO_OCI_PREFETCH_DEFAULT;
+
        /* allocate an environment */
 #if HAVE_OCIENVNLSCREATE
        if (vars[0].optval) {
index 683146a05e44dec232b8ab068ea04c96e930d7f1..fd01f0f7a897adb33921b326ac5e7f5eb4254031 100644 (file)
@@ -35,6 +35,7 @@ typedef struct {
        OCIError        *err;
        OCISvcCtx       *svc;
        /* OCI9; 0 == use NLS_LANG */
+       ub4                     prefetch;
        ub2                     charset;
        sword           last_err;
 
diff --git a/ext/pdo_oci/tests/checkliveness.phpt b/ext/pdo_oci/tests/checkliveness.phpt
new file mode 100644 (file)
index 0000000..4bb070f
--- /dev/null
@@ -0,0 +1,55 @@
+--TEST--
+PDO OCI checkliveness (code coverage)
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo') || !extension_loaded('pdo_oci')) die('skip not loaded');
+require dirname(__FILE__).'/../../pdo/tests/pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+
+require 'ext/pdo/tests/pdo_test.inc';
+$db = PDOTest::test_factory('ext/pdo_oci/tests/common.phpt');
+
+$dsn = getenv('PDOTEST_DSN');
+$user = getenv('PDOTEST_USER');
+$pass = getenv('PDOTEST_PASS');
+$attr = getenv('PDOTEST_ATTR');
+
+try {
+    $db = new PDO($dsn, $user, $pass, array(PDO::ATTR_PERSISTENT => true));
+} 
+catch (PDOException $e) {
+    echo 'Connection failed: ' . $e->getMessage();
+    exit;
+}
+
+// This triggers the call to check liveness
+try {
+    $db = new PDO($dsn, $user, $pass, array(PDO::ATTR_PERSISTENT => true));
+} 
+catch (PDOException $e) {
+    echo 'Connection failed: ' . $e->getMessage();
+    exit;
+}
+
+$db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
+
+try {
+    $stmt = $db->prepare('SELECT * FROM dual');
+    $stmt->execute();
+    $row = $stmt->fetch();
+    var_dump($row);
+} catch (PDOException $e) {
+    print $e->getMessage();
+}
+
+$db = null;
+--EXPECTF--
+array(2) {
+  ["DUMMY"]=>
+  string(1) "X"
+  [0]=>
+  string(1) "X"
+}
index 839fe83b02c0fa26253872bc36cee3112d56368d..0b42ecb660843826d9290a928edcc328cdd3b8f9 100644 (file)
@@ -13,12 +13,44 @@ require(dirname(__FILE__) . '/../../pdo/tests/pdo_test.inc');
 
 $dbh = PDOTest::factory();
 
-echo "Test connect: (value is ignored & has no effect)\n";
+echo "Test connect\n";
 putenv('PDOTEST_ATTR='.serialize(array(PDO::ATTR_PREFETCH=>101)));
 $dbh = PDOTest::factory();
 
-echo "Test set: (value is ignored & has no effect)\n";
+echo $dbh->getAttribute(PDO::ATTR_PREFETCH), "\n";
+
+// Verify can fetch
+$s = $dbh->prepare("select dummy from dual" );
+$s->execute();
+while ($r = $s->fetch()) {
+    echo $r[0] . "\n";
+}
+
+echo "Test set 102\n";
 $dbh->setAttribute(PDO::ATTR_PREFETCH, 102);
+echo $dbh->getAttribute(PDO::ATTR_PREFETCH), "\n";
+
+// Verify can fetch
+$s = $dbh->prepare("select dummy from dual" );
+$s->execute();
+while ($r = $s->fetch()) {
+    echo $r[0] . "\n";
+}
+
+echo "Test set -1: (Uses 0)\n";
+$dbh->setAttribute(PDO::ATTR_PREFETCH, -1);
+echo $dbh->getAttribute(PDO::ATTR_PREFETCH), "\n";
+
+// Verify can fetch
+$s = $dbh->prepare("select dummy from dual" );
+$s->execute();
+while ($r = $s->fetch()) {
+    echo $r[0] . "\n";
+}
+
+echo "Test set PHP_INT_MAX: (Uses default)\n";
+$dbh->setAttribute(PDO::ATTR_PREFETCH, PHP_INT_MAX);
+echo $dbh->getAttribute(PDO::ATTR_PREFETCH), "\n";
 
 // Verify can fetch
 $s = $dbh->prepare("select dummy from dual" );
@@ -31,7 +63,16 @@ echo "Done\n";
 
 ?>
 --EXPECT--
-Test connect: (value is ignored & has no effect)
-Test set: (value is ignored & has no effect)
+Test connect
+101
+X
+Test set 102
+102
+X
+Test set -1: (Uses 0)
+0
+X
+Test set PHP_INT_MAX: (Uses default)
+100
 X
 Done