From: Cameron Porter Date: Fri, 25 Oct 2019 06:32:12 +0000 (+0200) Subject: pdo_oci: Add support for setting and getting the oracle OCI 18c call timeout value. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=07964fc2b56c149407000f3aa968a7ac2f36d1fd;p=php pdo_oci: Add support for setting and getting the oracle OCI 18c call timeout value. --- diff --git a/NEWS b/NEWS index f914d9d264..102295dd7d 100644 --- a/NEWS +++ b/NEWS @@ -51,6 +51,10 @@ PHP NEWS . Fixed bug #77849 (Disable cloning of PDO handle/connection objects). (camporter) +- PDO_OCI: + . Added support for setting and getting the oracle OCI 18c call timeout. + (camporter) + - phpdbg: . Fixed bug #76596 (phpdbg support for display_errors=stderr). (kabel) . Fixed bug #76801 (too many open files). (alekitto) diff --git a/ext/pdo/tests/bug_69356.phpt b/ext/pdo/tests/bug_69356.phpt index 4fca242a91..0885a8264f 100644 --- a/ext/pdo/tests/bug_69356.phpt +++ b/ext/pdo/tests/bug_69356.phpt @@ -5,6 +5,7 @@ PDO Common: Bug #69356 (PDOStatement::debugDumpParams() truncates query) if (!extension_loaded('pdo')) die('skip'); $dir = getenv('REDIR_TEST_DIR'); if (false == $dir) die('skip no driver'); +if (!strncasecmp(getenv('PDOTEST_DSN'), 'oci', strlen('oci'))) die('skip query not supported'); require_once $dir . 'pdo_test.inc'; PDOTest::skip(); ?> diff --git a/ext/pdo_oci/oci_driver.c b/ext/pdo_oci/oci_driver.c index 58a63f58cb..3d9267ba85 100644 --- a/ext/pdo_oci/oci_driver.c +++ b/ext/pdo_oci/oci_driver.c @@ -537,6 +537,24 @@ static int oci_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval *val) / #else oci_drv_error("Unsupported attribute type"); return 0; +#endif + } + case PDO_OCI_ATTR_CALL_TIMEOUT: + { +#if (OCI_MAJOR_VERSION >= 18) + ub4 timeout = (ub4) lval; + + H->last_err = OCIAttrSet(H->svc, OCI_HTYPE_SVCCTX, + (dvoid *) &timeout, (ub4) 0, + OCI_ATTR_CALL_TIMEOUT, H->err); + if (H->last_err) { + oci_drv_error("OCIAttrSet: OCI_ATTR_CALL_TIMEOUT"); + return 0; + } + return 1; +#else + oci_drv_error("Unsupported attribute type"); + return 0; #endif } default: @@ -606,6 +624,26 @@ static int oci_handle_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return case PDO_ATTR_PREFETCH: ZVAL_LONG(return_value, H->prefetch); return TRUE; + case PDO_OCI_ATTR_CALL_TIMEOUT: + { +#if (OCI_MAJOR_VERSION >= 18) + ub4 timeout; + + H->last_err = OCIAttrGet(H->svc, OCI_HTYPE_SVCCTX, + (dvoid *) &timeout, NULL, + OCI_ATTR_CALL_TIMEOUT, H->err); + if (H->last_err) { + oci_drv_error("OCIAttrGet: OCI_ATTR_CALL_TIMEOUT"); + return FALSE; + } + + ZVAL_LONG(return_value, (zend_long) timeout); + return TRUE; +#else + oci_drv_error("Unsupported attribute type"); + return FALSE; +#endif + } default: return FALSE; diff --git a/ext/pdo_oci/pdo_oci.c b/ext/pdo_oci/pdo_oci.c index e9be6cd0a6..121378492a 100644 --- a/ext/pdo_oci/pdo_oci.c +++ b/ext/pdo_oci/pdo_oci.c @@ -92,6 +92,7 @@ PHP_MINIT_FUNCTION(pdo_oci) REGISTER_PDO_CLASS_CONST_LONG("OCI_ATTR_CLIENT_INFO", (zend_long)PDO_OCI_ATTR_CLIENT_INFO); REGISTER_PDO_CLASS_CONST_LONG("OCI_ATTR_CLIENT_IDENTIFIER", (zend_long)PDO_OCI_ATTR_CLIENT_IDENTIFIER); REGISTER_PDO_CLASS_CONST_LONG("OCI_ATTR_MODULE", (zend_long)PDO_OCI_ATTR_MODULE); + REGISTER_PDO_CLASS_CONST_LONG("OCI_ATTR_CALL_TIMEOUT", (zend_long)PDO_OCI_ATTR_CALL_TIMEOUT); php_pdo_register_driver(&pdo_oci_driver); diff --git a/ext/pdo_oci/php_pdo_oci_int.h b/ext/pdo_oci/php_pdo_oci_int.h index ee56720e19..488daf54e5 100644 --- a/ext/pdo_oci/php_pdo_oci_int.h +++ b/ext/pdo_oci/php_pdo_oci_int.h @@ -102,5 +102,6 @@ enum { PDO_OCI_ATTR_ACTION = PDO_ATTR_DRIVER_SPECIFIC, PDO_OCI_ATTR_CLIENT_INFO, PDO_OCI_ATTR_CLIENT_IDENTIFIER, - PDO_OCI_ATTR_MODULE + PDO_OCI_ATTR_MODULE, + PDO_OCI_ATTR_CALL_TIMEOUT }; diff --git a/ext/pdo_oci/tests/pdo_oci_attr_call_timeout.phpt b/ext/pdo_oci/tests/pdo_oci_attr_call_timeout.phpt new file mode 100644 index 0000000000..31df15320e --- /dev/null +++ b/ext/pdo_oci/tests/pdo_oci_attr_call_timeout.phpt @@ -0,0 +1,66 @@ +--TEST-- +PDO_OCI: Attribute: Setting and using call timeout +--SKIPIF-- +getAttribute(PDO::ATTR_CLIENT_VERSION), $matches); +if (!(isset($matches[0]) && $matches[0] >= 18)) { + die("skip works only with Oracle 18c or greater version of Oracle client libraries"); +} + +?> +--FILE-- +prepare("begin dbms_lock.sleep(:t); end;"); + + if (!$stmt) { + $error = $dbh->errorInfo(); + echo "Prepare error was ", $error[2], "\n"; + return; + } + $stmt->bindParam(":t", $t, PDO::PARAM_INT); + + $r = $stmt->execute(); + if ($r) { + echo "Execute succeeded\n"; + } else { + $error = $dbh->errorInfo(); + echo "Execute error was ", $error[2], "\n"; + } +} + +$dbh = PDOTest::factory(); +$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); + +echo "Test 1\n"; + +$dbh->setAttribute(PDO::OCI_ATTR_CALL_TIMEOUT, 4000); // milliseconds + +echo "call timeout:\n"; +var_dump($dbh->getAttribute(PDO::OCI_ATTR_CALL_TIMEOUT)); + +$r = mysleep($dbh, 8); // seconds + +?> +===DONE=== + +--EXPECTF-- +Test 1 +call timeout: +int(4000) +Execute error was OCIStmtExecute: ORA-%r(03136|03156)%r: %s + (%s:%d) +===DONE=== diff --git a/ext/pdo_oci/tests/pdo_oci_class_constants.phpt b/ext/pdo_oci/tests/pdo_oci_class_constants.phpt index 265e84b9ba..0946b3f89b 100644 --- a/ext/pdo_oci/tests/pdo_oci_class_constants.phpt +++ b/ext/pdo_oci/tests/pdo_oci_class_constants.phpt @@ -16,6 +16,7 @@ $expected = [ 'OCI_ATTR_ACTION' => true, 'OCI_ATTR_CLIENT_IDENTIFIER' => true, 'OCI_ATTR_MODULE' => true, + 'OCI_ATTR_CALL_TIMEOUT' => true, ]; $ref = new ReflectionClass('PDO'); diff --git a/ext/pdo_oci/tests/pdo_oci_debugdumpparams.phpt b/ext/pdo_oci/tests/pdo_oci_debugdumpparams.phpt new file mode 100644 index 0000000000..6f743c20d4 --- /dev/null +++ b/ext/pdo_oci/tests/pdo_oci_debugdumpparams.phpt @@ -0,0 +1,37 @@ +--TEST-- +PDO_OCI: Bug #69356 (PDOStatement::debugDumpParams() truncates query) +--SKIPIF-- + +--FILE-- +setAttribute(PDO::ATTR_EMULATE_PREPARES, true); +$stmt = $db->query(" + SELECT ' + Dumps the informations contained by a prepared statement directly on the output. It will provide the SQL query in use, the number of parameters used (Params), the list of parameters, with their name, type (paramtype) as an integer, their key name or position, and the position in the query (if this is supported by the PDO driver, otherwise, it will be -1). + This is a debug function, which dump directly the data on the normal output. + Tip: + As with anything that outputs its result directly to the browser, the output-control functions can be used to capture the output of this function, and save it in a string (for example). + This will only dumps the parameters in the statement at the moment of the dump. Extra parameters are not stored in the statement, and not displayed. + ' FROM DUAL +"); +var_dump($stmt->debugDumpParams()); +?> +--EXPECT-- +SQL: [845] + SELECT ' + Dumps the informations contained by a prepared statement directly on the output. It will provide the SQL query in use, the number of parameters used (Params), the list of parameters, with their name, type (paramtype) as an integer, their key name or position, and the position in the query (if this is supported by the PDO driver, otherwise, it will be -1). + This is a debug function, which dump directly the data on the normal output. + Tip: + As with anything that outputs its result directly to the browser, the output-control functions can be used to capture the output of this function, and save it in a string (for example). + This will only dumps the parameters in the statement at the moment of the dump. Extra parameters are not stored in the statement, and not displayed. + ' FROM DUAL + +Params: 0 +NULL