Add oci_set_prefetch_lob()

This commit is contained in:
Christopher Jones 2021-11-28 12:06:25 +11:00
parent 6606cc04fe
commit ac91b83ceb
No known key found for this signature in database
GPG key ID: F3DF7046B54073C9
12 changed files with 298 additions and 60 deletions

View file

@ -28,9 +28,10 @@ PHP 8.2 UPGRADE NOTES
HTTP method in curl_getinfo() return value. HTTP method in curl_getinfo() return value.
- OCI8: - OCI8:
. Added an oci8.prefetch_lob_size directive to tune LOB query performance . Added an oci8.prefetch_lob_size directive and oci_set_prefetch_lob()
by reducing the number of round-trips between PHP and Oracle Database when function to tune LOB query performance by reducing the number of
fetching LOBS. This is usable with Oracle Database 12.2 or later. round-trips between PHP and Oracle Database when fetching LOBS. This is
usable with Oracle Database 12.2 or later.
- PCRE: - PCRE:
. Added support for the "n" (NO_AUTO_CAPTURE) modifier, which makes simple . Added support for the "n" (NO_AUTO_CAPTURE) modifier, which makes simple

View file

@ -211,7 +211,13 @@ if test "$PHP_OCI8" != "no"; then
oci8_php_version=`expr [$]1 \* 1000000 + [$]2 \* 1000 + [$]3` oci8_php_version=`expr [$]1 \* 1000000 + [$]2 \* 1000 + [$]3`
if test "$oci8_php_version" -lt "5002000"; then if test "$oci8_php_version" -lt "5002000"; then
AC_MSG_ERROR([You need at least PHP 5.2.0 to be able to use this version of OCI8. PHP $php_version found]) AC_MSG_ERROR([You need at least PHP 8.1.0 to be able to use this version of OCI8. Use OCI8 1.4 for PHP $php_version])
elif test "$oci8_php_version" -lt "7000000"; then
AC_MSG_ERROR([You need at least PHP 8.1.0 to be able to use this version of OCI8. Use OCI8 2.0 for PHP $php_version])
elif test "$oci8_php_version" -lt "8000000"; then
AC_MSG_ERROR([You need at least PHP 8.1.0 to be able to use this version of OCI8. Use OCI8 2.2 for PHP $php_version])
elif test "$oci8_php_version" -lt "8001000"; then
AC_MSG_ERROR([You need at least PHP 8.1.0 to be able to use this version of OCI8. Use OCI8 3.0 for PHP $php_version])
else else
AC_MSG_RESULT([$php_version, ok]) AC_MSG_RESULT([$php_version, ok])
fi fi

View file

@ -35,6 +35,9 @@
#ifdef HAVE_OCI8 #ifdef HAVE_OCI8
/* Note to maintainers: config.m4 should/does check the minimum PHP version so
* the below checks are obsolete - but are kept 'just in case' */
/* PHP 5.2 is the minimum supported version for OCI8 2.0 */ /* PHP 5.2 is the minimum supported version for OCI8 2.0 */
#if PHP_MAJOR_VERSION < 5 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION <= 1) #if PHP_MAJOR_VERSION < 5 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION <= 1)
#error Use PHP OCI8 1.4 for your version of PHP #error Use PHP OCI8 1.4 for your version of PHP
@ -42,8 +45,10 @@
/* PHP 7 is the minimum supported version for OCI8 2.1 */ /* PHP 7 is the minimum supported version for OCI8 2.1 */
#error Use PHP OCI8 2.0 for your version of PHP #error Use PHP OCI8 2.0 for your version of PHP
#elif PHP_MAJOR_VERSION < 8 #elif PHP_MAJOR_VERSION < 8
/* PHP 8 is the minimum supported version for OCI8 3.0 */ /* PHP 8 is the minimum supported version for OCI8 3 */
#error Use PHP OCI8 2.2 for your version of PHP #error Use PHP OCI8 2.2 for your version of PHP
#elif PHP_MAJOR_VERSION == 8 && PHP_MINOR_VERSION < 1
#error Use PHP OCI8 3.0 for your version of PHP
#endif #endif
#include "php_oci8.h" #include "php_oci8.h"
@ -174,7 +179,7 @@ PHP_INI_BEGIN()
#if ((OCI_MAJOR_VERSION > 10) || ((OCI_MAJOR_VERSION == 10) && (OCI_MINOR_VERSION >= 2))) #if ((OCI_MAJOR_VERSION > 10) || ((OCI_MAJOR_VERSION == 10) && (OCI_MINOR_VERSION >= 2)))
STD_PHP_INI_BOOLEAN("oci8.events", "0", PHP_INI_SYSTEM, OnUpdateBool, events, zend_oci_globals, oci_globals) STD_PHP_INI_BOOLEAN("oci8.events", "0", PHP_INI_SYSTEM, OnUpdateBool, events, zend_oci_globals, oci_globals)
#endif #endif
STD_PHP_INI_ENTRY( "oci8.prefetch_lob_size", "0", PHP_INI_ALL, OnUpdateLong, prefetch_lob_size, zend_oci_globals, oci_globals) STD_PHP_INI_ENTRY( "oci8.prefetch_lob_size", "0", PHP_INI_SYSTEM, OnUpdateLong, prefetch_lob_size, zend_oci_globals, oci_globals)
PHP_INI_END() PHP_INI_END()
/* }}} */ /* }}} */

View file

@ -381,6 +381,9 @@ function oci_set_prefetch($statement, int $rows): bool {}
*/ */
function ocisetprefetch($statement, int $rows): bool {} function ocisetprefetch($statement, int $rows): bool {}
/** @param resource $statement */
function oci_set_prefetch_lob($statement, int $prefetch_lob_size): bool {}
/** @param resource $connection */ /** @param resource $connection */
function oci_set_client_identifier($connection, string $client_id): bool {} function oci_set_client_identifier($connection, string $client_id): bool {}

View file

@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead. /* This is a generated file, edit the .stub.php file instead.
* Stub hash: 46ee8ce62b36639636b4f5126e20a4b4e1df2e25 */ * Stub hash: 9db587b5d431b9dfe7178fd843ae8907db737a04 */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_oci_define_by_name, 0, 3, _IS_BOOL, 0) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_oci_define_by_name, 0, 3, _IS_BOOL, 0)
ZEND_ARG_INFO(0, statement) ZEND_ARG_INFO(0, statement)
@ -299,6 +299,11 @@ ZEND_END_ARG_INFO()
#define arginfo_ocisetprefetch arginfo_oci_set_prefetch #define arginfo_ocisetprefetch arginfo_oci_set_prefetch
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_oci_set_prefetch_lob, 0, 2, _IS_BOOL, 0)
ZEND_ARG_INFO(0, statement)
ZEND_ARG_TYPE_INFO(0, prefetch_lob_size, IS_LONG, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_oci_set_client_identifier, 0, 2, _IS_BOOL, 0) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_oci_set_client_identifier, 0, 2, _IS_BOOL, 0)
ZEND_ARG_INFO(0, connection) ZEND_ARG_INFO(0, connection)
ZEND_ARG_TYPE_INFO(0, client_id, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, client_id, IS_STRING, 0)
@ -596,6 +601,7 @@ ZEND_FUNCTION(oci_num_fields);
ZEND_FUNCTION(oci_parse); ZEND_FUNCTION(oci_parse);
ZEND_FUNCTION(oci_get_implicit_resultset); ZEND_FUNCTION(oci_get_implicit_resultset);
ZEND_FUNCTION(oci_set_prefetch); ZEND_FUNCTION(oci_set_prefetch);
ZEND_FUNCTION(oci_set_prefetch_lob);
ZEND_FUNCTION(oci_set_client_identifier); ZEND_FUNCTION(oci_set_client_identifier);
ZEND_FUNCTION(oci_set_edition); ZEND_FUNCTION(oci_set_edition);
ZEND_FUNCTION(oci_set_module_name); ZEND_FUNCTION(oci_set_module_name);
@ -710,6 +716,7 @@ static const zend_function_entry ext_functions[] = {
ZEND_FE(oci_get_implicit_resultset, arginfo_oci_get_implicit_resultset) ZEND_FE(oci_get_implicit_resultset, arginfo_oci_get_implicit_resultset)
ZEND_FE(oci_set_prefetch, arginfo_oci_set_prefetch) ZEND_FE(oci_set_prefetch, arginfo_oci_set_prefetch)
ZEND_DEP_FALIAS(ocisetprefetch, oci_set_prefetch, arginfo_ocisetprefetch) ZEND_DEP_FALIAS(ocisetprefetch, oci_set_prefetch, arginfo_ocisetprefetch)
ZEND_FE(oci_set_prefetch_lob, arginfo_oci_set_prefetch_lob)
ZEND_FE(oci_set_client_identifier, arginfo_oci_set_client_identifier) ZEND_FE(oci_set_client_identifier, arginfo_oci_set_client_identifier)
ZEND_FE(oci_set_edition, arginfo_oci_set_edition) ZEND_FE(oci_set_edition, arginfo_oci_set_edition)
ZEND_FE(oci_set_module_name, arginfo_oci_set_module_name) ZEND_FE(oci_set_module_name, arginfo_oci_set_module_name)

View file

@ -1633,6 +1633,30 @@ PHP_FUNCTION(oci_set_prefetch)
} }
/* }}} */ /* }}} */
/* {{{ Sets the amount of LOB data to be prefetched when OCI LOB locators are fetched */
PHP_FUNCTION(oci_set_prefetch_lob)
{
zval *z_statement;
php_oci_statement *statement;
zend_long prefetch_lob_size;
ZEND_PARSE_PARAMETERS_START(2, 2)
Z_PARAM_RESOURCE(z_statement)
Z_PARAM_LONG(prefetch_lob_size)
ZEND_PARSE_PARAMETERS_END();
PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement);
if (prefetch_lob_size < 0) {
zend_argument_value_error(2, "must be greater than or equal to 0");
RETURN_THROWS();
}
statement->prefetch_lob_size = (ub4) prefetch_lob_size;
RETURN_TRUE;
}
/* }}} */
/* {{{ Sets the client identifier attribute on the connection */ /* {{{ Sets the client identifier attribute on the connection */
PHP_FUNCTION(oci_set_client_identifier) PHP_FUNCTION(oci_set_client_identifier)
{ {

View file

@ -117,6 +117,12 @@ php_oci_statement *php_oci_statement_create(php_oci_connection *connection, char
php_oci_statement_set_prefetch(statement, (ub4)100); /* semi-arbitrary, "sensible default" */ php_oci_statement_set_prefetch(statement, (ub4)100); /* semi-arbitrary, "sensible default" */
} }
if (OCI_G(prefetch_lob_size) > 0) {
statement->prefetch_lob_size = (ub4)OCI_G(prefetch_lob_size);
} else {
statement->prefetch_lob_size = 0;
}
PHP_OCI_REGISTER_RESOURCE(statement, le_statement); PHP_OCI_REGISTER_RESOURCE(statement, le_statement);
OCI_G(num_statements)++; OCI_G(num_statements)++;
@ -173,6 +179,7 @@ php_oci_statement *php_oci_get_implicit_resultset(php_oci_statement *statement)
GC_ADDREF(statement2->connection->id); GC_ADDREF(statement2->connection->id);
php_oci_statement_set_prefetch(statement2, statement->prefetch_count); php_oci_statement_set_prefetch(statement2, statement->prefetch_count);
statement2->prefetch_lob_size = statement->prefetch_lob_size;
PHP_OCI_REGISTER_RESOURCE(statement2, le_statement); PHP_OCI_REGISTER_RESOURCE(statement2, le_statement);
@ -186,7 +193,7 @@ php_oci_statement *php_oci_get_implicit_resultset(php_oci_statement *statement)
/* {{{ php_oci_statement_set_prefetch() /* {{{ php_oci_statement_set_prefetch()
Set prefetch buffer size for the statement */ Set prefetch buffer size for the statement */
int php_oci_statement_set_prefetch(php_oci_statement *statement, ub4 prefetch ) int php_oci_statement_set_prefetch(php_oci_statement *statement, ub4 prefetch)
{ {
sword errstatus; sword errstatus;
@ -820,18 +827,30 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode)
return 1; return 1;
} }
/* Enable LOB data prefetching */
if ((outcol->data_type == SQLT_CLOB || outcol->data_type == SQLT_BLOB) && statement->prefetch_lob_size > 0) {
int get_lob_len = 1; /* == true */
PHP_OCI_CALL_RETURN(errstatus, OCIAttrSet, (outcol->oci_define, OCI_HTYPE_DEFINE, &get_lob_len, 0, OCI_ATTR_LOBPREFETCH_LENGTH, statement->err));
if (errstatus != OCI_SUCCESS) {
statement->errcode = php_oci_error(statement->err, errstatus);
PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
return 1;
}
PHP_OCI_CALL_RETURN(errstatus, OCIAttrSet, (outcol->oci_define, OCI_HTYPE_DEFINE, &(statement->prefetch_lob_size), 0, OCI_ATTR_LOBPREFETCH_SIZE, statement->err));
if (errstatus != OCI_SUCCESS) {
statement->errcode = php_oci_error(statement->err, errstatus);
PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
return 1;
}
}
/* additional define setup */ /* additional define setup */
switch (outcol->data_type) { switch (outcol->data_type) {
case SQLT_RSET:
case SQLT_BLOB: case SQLT_BLOB:
case SQLT_CLOB: case SQLT_CLOB:
if (OCI_G(prefetch_lob_size) > 0) {
int get_lob_len = 1; /* == true */
ub4 prefetch_size = OCI_G(prefetch_lob_size);
PHP_OCI_CALL_RETURN(errstatus, OCIAttrSet, (outcol->oci_define, OCI_HTYPE_DEFINE, &get_lob_len, 0, OCI_ATTR_LOBPREFETCH_LENGTH, statement->err));
PHP_OCI_CALL_RETURN(errstatus, OCIAttrSet, (outcol->oci_define, OCI_HTYPE_DEFINE, &prefetch_size, 0, OCI_ATTR_LOBPREFETCH_SIZE, statement->err));
}
ZEND_FALLTHROUGH;
case SQLT_RSET:
case SQLT_RDD: case SQLT_RDD:
case SQLT_BFILE: case SQLT_BFILE:
PHP_OCI_CALL_RETURN(errstatus, PHP_OCI_CALL_RETURN(errstatus,

View file

@ -10,7 +10,9 @@ http://pear.php.net/dtd/package-2.0.xsd">
<description> <description>
The OCI8 extension lets you access Oracle Database. The OCI8 extension lets you access Oracle Database.
Use 'pecl install oci8' to install for PHP 8. Use 'pecl install oci8' to install for PHP 8.1.
Use 'pecl install oci8-3.0.1' to install for PHP 8.0.
Use 'pecl install oci8-2.2.0' to install for PHP 7. Use 'pecl install oci8-2.2.0' to install for PHP 7.
@ -53,7 +55,7 @@ Oracle's standard cross-version connectivity applies. For example, PHP OCI8 lin
<active>no</active> <active>no</active>
</lead> </lead>
<date>2021-11-15</date> <date>2021-12-11</date>
<time>12:00:00</time> <time>12:00:00</time>
<version> <version>
@ -66,9 +68,9 @@ Oracle's standard cross-version connectivity applies. For example, PHP OCI8 lin
</stability> </stability>
<license uri="http://www.php.net/license">PHP</license> <license uri="http://www.php.net/license">PHP</license>
<notes> <notes>
This version is for PHP 8 only. This version is for PHP 8.1 only.
Added oci8.prefetch_lob_size directive to improve LOB query performance. Added oci8.prefetch_lob_size directive and oci_set_prefetch_lob() function to improve LOB query performance.
</notes> </notes>
<contents> <contents>
<dir name="/"> <dir name="/">
@ -373,6 +375,8 @@ Oracle's standard cross-version connectivity applies. For example, PHP OCI8 lin
<file name="lob_044.phpt" role="test" /> <file name="lob_044.phpt" role="test" />
<file name="lob_aliases.phpt" role="test" /> <file name="lob_aliases.phpt" role="test" />
<file name="lob_null.phpt" role="test" /> <file name="lob_null.phpt" role="test" />
<file name="lob_prefetch.phpt" role="test" />
<file name="lob_prefetch_ini.phpt" role="test" />
<file name="lob_temp.phpt" role="test" /> <file name="lob_temp.phpt" role="test" />
<file name="lob_temp1.phpt" role="test" /> <file name="lob_temp1.phpt" role="test" />
<file name="lob_temp2.phpt" role="test" /> <file name="lob_temp2.phpt" role="test" />
@ -435,7 +439,7 @@ Oracle's standard cross-version connectivity applies. For example, PHP OCI8 lin
<dependencies> <dependencies>
<required> <required>
<php> <php>
<min>8.0.0</min> <min>8.1.0</min>
</php> </php>
<pearinstaller> <pearinstaller>
<min>1.4.0b1</min> <min>1.4.0b1</min>

View file

@ -235,7 +235,8 @@ typedef struct {
unsigned has_data:1; /* statement has more data flag */ unsigned has_data:1; /* statement has more data flag */
unsigned has_descr:1; /* statement has at least one descriptor or cursor column */ unsigned has_descr:1; /* statement has at least one descriptor or cursor column */
ub2 stmttype; /* statement type */ ub2 stmttype; /* statement type */
ub4 prefetch_count; /* current prefetch count */ ub4 prefetch_count; /* row prefetch count */
ub4 prefetch_lob_size; /* LOB prefetch size */
} php_oci_statement; } php_oci_statement;
/* }}} */ /* }}} */

View file

@ -13,14 +13,14 @@ require(__DIR__.'/skipif.inc');
require __DIR__.'/connect.inc'; require __DIR__.'/connect.inc';
require __DIR__.'/create_table.inc'; require __DIR__.'/create_table.inc';
define("NUMROWS", 500); define("NUMROWS", 200);
define("LOBSIZE", 64000); define("LOBSIZE", 64000);
$ora_sql = $ora_sql =
"declare "declare
c clob; c clob;
b blob; b blob;
numrows number := 500; numrows number := " . NUMROWS . ";
dest_offset integer := 1; dest_offset integer := 1;
src_offset integer := 1; src_offset integer := 1;
warn integer; warn integer;
@ -44,8 +44,10 @@ $statement = oci_parse($c,$ora_sql);
oci_execute($statement); oci_execute($statement);
function get_clob_loc($c, $sql) { function get_clob_loc($c, $sql, $pfl) {
$stid = oci_parse($c, $sql); $stid = oci_parse($c, $sql);
if ($pfl >= 0)
oci_set_prefetch_lob($stid, $pfl);
oci_execute($stid); oci_execute($stid);
$l = []; $l = [];
while (($row = oci_fetch_array($stid, OCI_ASSOC)) != false) { while (($row = oci_fetch_array($stid, OCI_ASSOC)) != false) {
@ -56,8 +58,10 @@ function get_clob_loc($c, $sql) {
return($l); return($l);
} }
function get_clob_inline($c, $sql) { function get_clob_inline($c, $sql, $pfl) {
$stid = oci_parse($c, $sql); $stid = oci_parse($c, $sql);
if ($pfl >= 0)
oci_set_prefetch_lob($stid, $pfl);
oci_execute($stid); oci_execute($stid);
$l = []; $l = [];
while (($row = oci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_LOBS)) != false) { while (($row = oci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_LOBS)) != false) {
@ -81,8 +85,10 @@ function check_clobs($locarr, $inlinearr) {
} }
} }
function get_blob_loc($c, $sql) { function get_blob_loc($c, $sql, $pfl) {
$stid = oci_parse($c, $sql); $stid = oci_parse($c, $sql);
if ($pfl >= 0)
oci_set_prefetch_lob($stid, $pfl);
oci_execute($stid); oci_execute($stid);
$l = []; $l = [];
while (($row = oci_fetch_array($stid, OCI_ASSOC)) != false) { while (($row = oci_fetch_array($stid, OCI_ASSOC)) != false) {
@ -94,22 +100,28 @@ function get_blob_loc($c, $sql) {
} }
print("Test 1\n"); print("Test 1 - Default prefetch_lob_size\n");
$ig = ini_get("oci8.prefetch_lob_size"); $r = ini_get("oci8.prefetch_lob_size");
var_dump($ig); var_dump($r);
$ig = ini_set("oci8.prefetch_lob_size", "100000"); print("Test 2\n");
var_dump($ig);
$ig = ini_get("oci8.prefetch_lob_size"); $s = oci_parse($c, 'select * from dual');
var_dump($ig); $r = oci_set_prefetch_lob($s, 0);
var_dump($r);
print("Test 2 - CLOB prefetch_lob_size 100000\n"); try {
oci_set_prefetch_lob($s, -1);
} catch (ValueError $e) {
echo $e->getMessage(), "\n";
}
print("Test 3 - CLOB prefetch_lob_size 100000\n");
$sql = "select clob from ${schema}${table_name}" . " order by id"; $sql = "select clob from ${schema}${table_name}" . " order by id";
$locarr = get_clob_loc($c, $sql); $locarr = get_clob_loc($c, $sql, 100000);
$inlinearr = get_clob_inline($c, $sql); $inlinearr = get_clob_inline($c, $sql, 100000);
print(count($locarr) . "\n"); print(count($locarr) . "\n");
print(count($inlinearr) . "\n"); print(count($inlinearr) . "\n");
@ -117,12 +129,8 @@ check_clobs($locarr, $inlinearr);
print("Test 3 - CLOB prefetch_lob_size 100\n"); print("Test 3 - CLOB prefetch_lob_size 100\n");
ini_set("oci8.prefetch_lob_size", "100"); $locarr = get_clob_loc($c, $sql, 100);
$ig = ini_get("oci8.prefetch_lob_size"); $inlinearr = get_clob_inline($c, $sql, 100);
var_dump($ig);
$locarr = get_clob_loc($c, $sql);
$inlinearr = get_clob_inline($c, $sql);
print(count($locarr) . "\n"); print(count($locarr) . "\n");
print(count($inlinearr) . "\n"); print(count($inlinearr) . "\n");
@ -130,12 +138,8 @@ check_clobs($locarr, $inlinearr);
print("Test 4 - BLOB prefetch_lob_size 100000\n"); print("Test 4 - BLOB prefetch_lob_size 100000\n");
ini_set("oci8.prefetch_lob_size", "100000");
$ig = ini_get("oci8.prefetch_lob_size");
var_dump($ig);
$sql = "select blob from ${schema}${table_name}" . " order by id"; $sql = "select blob from ${schema}${table_name}" . " order by id";
$locarr = get_blob_loc($c, $sql); $locarr = get_blob_loc($c, $sql, 100000);
print(count($locarr) . "\n"); print(count($locarr) . "\n");
@ -144,20 +148,19 @@ require __DIR__.'/drop_table.inc';
?> ?>
DONE DONE
--EXPECTF-- --EXPECTF--
Test 1 Test 1 - Default prefetch_lob_size
string(1) "0" string(1) "0"
string(1) "0" Test 2
string(6) "100000" bool(true)
Test 2 - CLOB prefetch_lob_size 100000 oci_set_prefetch_lob(): Argument #2 ($prefetch_lob_size) must be greater than or equal to 0
500 Test 3 - CLOB prefetch_lob_size 100000
500 200
200
Comparing CLOBS Comparing CLOBS
Test 3 - CLOB prefetch_lob_size 100 Test 3 - CLOB prefetch_lob_size 100
string(3) "100" 200
500 200
500
Comparing CLOBS Comparing CLOBS
Test 4 - BLOB prefetch_lob_size 100000 Test 4 - BLOB prefetch_lob_size 100000
string(6) "100000" 200
500
DONE DONE

View file

@ -0,0 +1,165 @@
--TEST--
LOB prefetching with oci8.
--EXTENSIONS--
oci8
--SKIPIF--
<?php
$target_dbs = array('oracledb' => true, 'timesten' => false); // test runs on these DBs
require(__DIR__.'/skipif.inc');
?>
--INI--
oci8.prefetch_lob_size=100000
--FILE--
<?php
require __DIR__.'/connect.inc';
require __DIR__.'/create_table.inc';
define("NUMROWS", 200);
define("LOBSIZE", 64000);
$ora_sql =
"declare
c clob;
b blob;
numrows number := " . NUMROWS . ";
dest_offset integer := 1;
src_offset integer := 1;
warn integer;
ctx integer := dbms_lob.default_lang_ctx;
begin
for j in 1..numrows
loop
c := DBMS_RANDOM.string('L',TRUNC(DBMS_RANDOM.value(1000,1000)));
for i in 1..6
loop
c := c||c;
end loop;
dbms_lob.createtemporary(b, false);
dbms_lob.converttoblob(b, c, dbms_lob.lobmaxsize, dest_offset, src_offset, dbms_lob.default_csid, ctx, warn);
insert /*+ APPEND */ into ${schema}${table_name} (id, clob, blob) values (j, c, b);
end loop;
commit;
end;";
$statement = oci_parse($c,$ora_sql);
oci_execute($statement);
function get_clob_loc($c, $sql, $pfl) {
$stid = oci_parse($c, $sql);
if ($pfl >= 0)
oci_set_prefetch_lob($stid, $pfl);
oci_execute($stid);
$l = [];
while (($row = oci_fetch_array($stid, OCI_ASSOC)) != false) {
$l[] = $row['CLOB']->load();
$row['CLOB']->free();
if (strlen($l[0]) != LOBSIZE) { print("strlen(l) failure" . strlen($l)); exit; }
}
return($l);
}
function get_clob_inline($c, $sql, $pfl) {
$stid = oci_parse($c, $sql);
if ($pfl >= 0)
oci_set_prefetch_lob($stid, $pfl);
oci_execute($stid);
$l = [];
while (($row = oci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_LOBS)) != false) {
$l[] = $row['CLOB'];
if (strlen($l[0]) != LOBSIZE) { print("strlen(l) failure" . strlen($l)); exit; }
}
return($l);
}
function check_clobs($locarr, $inlinearr) {
print("Comparing CLOBS\n");
for ($i = 0; $i < NUMROWS; ++$i) {
if (strlen($locarr[$i]) != LOBSIZE) {
trigger_error("size mismatch at $i " . strlen($locarr[$i]), E_USER_ERROR);
exit;
}
if (strcmp($locarr[$i], $inlinearr[$i])) {
trigger_error("data mismatch at $i " . strlen($locarr[$i]) . " " . strlen($inlinearr[$i]), E_USER_ERROR);
exit;
}
}
}
function get_blob_loc($c, $sql, $pfl) {
$stid = oci_parse($c, $sql);
if ($pfl >= 0)
oci_set_prefetch_lob($stid, $pfl);
oci_execute($stid);
$l = [];
while (($row = oci_fetch_array($stid, OCI_ASSOC)) != false) {
$l[] = $row['BLOB']->load();
$row['BLOB']->free();
if (strlen($l[0]) != LOBSIZE) { print("strlen(l) failure" . strlen($l)); exit; }
}
return($l);
}
print("Test 1 - prefetch_lob_size\n");
$r = ini_get("oci8.prefetch_lob_size");
var_dump($r);
print("Test 2 - CLOB with current oci8.prefetch_lob_size\n");
$sql = "select clob from ${schema}${table_name}" . " order by id";
$locarr = get_clob_loc($c, $sql, -1);
$inlinearr = get_clob_inline($c, $sql, -1);
print(count($locarr) . "\n");
print(count($inlinearr) . "\n");
check_clobs($locarr, $inlinearr);
print("Test 3 - CLOB override prefetch_lob_size 0\n");
$locarr = get_clob_loc($c, $sql, 0);
$inlinearr = get_clob_inline($c, $sql, 0);
print(count($locarr) . "\n");
print(count($inlinearr) . "\n");
check_clobs($locarr, $inlinearr);
print("Test 4 - CLOB override prefetch_lob_size 1000\n");
$locarr = get_clob_loc($c, $sql, 1000);
$inlinearr = get_clob_inline($c, $sql, 1000);
print(count($locarr) . "\n");
print(count($inlinearr) . "\n");
check_clobs($locarr, $inlinearr);
print("Test 5 - BLOB with current ocig8.prefetch_lob_size \n");
$sql = "select blob from ${schema}${table_name}" . " order by id";
$locarr = get_blob_loc($c, $sql, -1);
print(count($locarr) . "\n");
require __DIR__.'/drop_table.inc';
?>
DONE
--EXPECTF--
Test 1 - prefetch_lob_size
string(6) "100000"
Test 2 - CLOB with current oci8.prefetch_lob_size
200
200
Comparing CLOBS
Test 3 - CLOB override prefetch_lob_size 0
200
200
Comparing CLOBS
Test 4 - CLOB override prefetch_lob_size 1000
200
200
Comparing CLOBS
Test 5 - BLOB with current ocig8.prefetch_lob_size
200
DONE

View file

@ -1273,7 +1273,7 @@ mysqlnd.collect_memory_statistics = Off
; https://php.net/oci8.statement-cache-size ; https://php.net/oci8.statement-cache-size
;oci8.statement_cache_size = 20 ;oci8.statement_cache_size = 20
; Tuning: Enables statement prefetching and sets the default number of ; Tuning: Enables row prefetching and sets the default number of
; rows that will be fetched automatically after statement execution. ; rows that will be fetched automatically after statement execution.
; https://php.net/oci8.default-prefetch ; https://php.net/oci8.default-prefetch
;oci8.default_prefetch = 100 ;oci8.default_prefetch = 100