Skip to content

Commit af76506

Browse files
committed
Fixed bug #70308 (PDO::ATTR_PREFETCH is ignored)
1 parent f8ee809 commit af76506

File tree

5 files changed

+119
-12
lines changed

5 files changed

+119
-12
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ PHP NEWS
88
(marcio dot web2 at gmail dot com)
99
. Fixed bug causing exception traces with anon classes to be truncated. (Bob)
1010

11+
- PDO_OCI:
12+
. Fixed bug #70308 (PDO::ATTR_PREFETCH is ignored). (Chris Jones)
13+
1114
- SPL:
1215
. Fixed bug #70303 (Incorrect constructor reflection for ArrayObject). (cmb)
1316

ext/pdo_oci/oci_driver.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -302,15 +302,13 @@ static int oci_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len,
302302

303303
}
304304

305-
prefetch = pdo_oci_sanitize_prefetch((long) pdo_attr_lval(driver_options, PDO_ATTR_PREFETCH, PDO_OCI_PREFETCH_DEFAULT));
306-
if (prefetch) {
305+
prefetch = H->prefetch; /* Note 0 is allowed so in future REF CURSORs can be used & then passed with no row loss*/
306+
H->last_err = OCIAttrSet(S->stmt, OCI_HTYPE_STMT, &prefetch, 0,
307+
OCI_ATTR_PREFETCH_ROWS, H->err);
308+
if (!H->last_err) {
309+
prefetch *= PDO_OCI_PREFETCH_ROWSIZE;
307310
H->last_err = OCIAttrSet(S->stmt, OCI_HTYPE_STMT, &prefetch, 0,
308-
OCI_ATTR_PREFETCH_ROWS, H->err);
309-
if (!H->last_err) {
310-
prefetch *= PDO_OCI_PREFETCH_ROWSIZE;
311-
H->last_err = OCIAttrSet(S->stmt, OCI_HTYPE_STMT, &prefetch, 0,
312-
OCI_ATTR_PREFETCH_MEMORY, H->err);
313-
}
311+
OCI_ATTR_PREFETCH_MEMORY, H->err);
314312
}
315313

316314
stmt->driver_data = S;
@@ -460,6 +458,10 @@ static int oci_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval *val) /
460458

461459
dbh->auto_commit = (unsigned int) (Z_LVAL_P(val)) ? 1 : 0;
462460
return 1;
461+
} else if (attr == PDO_ATTR_PREFETCH) {
462+
convert_to_long(val);
463+
H->prefetch = pdo_oci_sanitize_prefetch(Z_LVAL_P(val));
464+
return 1;
463465
} else {
464466
return 0;
465467
}
@@ -524,6 +526,9 @@ static int oci_handle_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return
524526
ZVAL_BOOL(return_value, dbh->auto_commit);
525527
return TRUE;
526528

529+
case PDO_ATTR_PREFETCH:
530+
ZVAL_LONG(return_value, H->prefetch);
531+
return TRUE;
527532
default:
528533
return FALSE;
529534

@@ -602,6 +607,8 @@ static int pdo_oci_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ *
602607
H = pecalloc(1, sizeof(*H), dbh->is_persistent);
603608
dbh->driver_data = H;
604609

610+
H->prefetch = PDO_OCI_PREFETCH_DEFAULT;
611+
605612
/* allocate an environment */
606613
#if HAVE_OCIENVNLSCREATE
607614
if (vars[0].optval) {

ext/pdo_oci/php_pdo_oci_int.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ typedef struct {
3535
OCIError *err;
3636
OCISvcCtx *svc;
3737
/* OCI9; 0 == use NLS_LANG */
38+
ub4 prefetch;
3839
ub2 charset;
3940
sword last_err;
4041

ext/pdo_oci/tests/checkliveness.phpt

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
--TEST--
2+
PDO OCI checkliveness (code coverage)
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('pdo') || !extension_loaded('pdo_oci')) die('skip not loaded');
6+
require dirname(__FILE__).'/../../pdo/tests/pdo_test.inc';
7+
PDOTest::skip();
8+
?>
9+
--FILE--
10+
<?php
11+
12+
require 'ext/pdo/tests/pdo_test.inc';
13+
$db = PDOTest::test_factory('ext/pdo_oci/tests/common.phpt');
14+
15+
$dsn = getenv('PDOTEST_DSN');
16+
$user = getenv('PDOTEST_USER');
17+
$pass = getenv('PDOTEST_PASS');
18+
$attr = getenv('PDOTEST_ATTR');
19+
20+
try {
21+
$db = new PDO($dsn, $user, $pass, array(PDO::ATTR_PERSISTENT => true));
22+
}
23+
catch (PDOException $e) {
24+
echo 'Connection failed: ' . $e->getMessage();
25+
exit;
26+
}
27+
28+
// This triggers the call to check liveness
29+
try {
30+
$db = new PDO($dsn, $user, $pass, array(PDO::ATTR_PERSISTENT => true));
31+
}
32+
catch (PDOException $e) {
33+
echo 'Connection failed: ' . $e->getMessage();
34+
exit;
35+
}
36+
37+
$db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
38+
39+
try {
40+
$stmt = $db->prepare('SELECT * FROM dual');
41+
$stmt->execute();
42+
$row = $stmt->fetch();
43+
var_dump($row);
44+
} catch (PDOException $e) {
45+
print $e->getMessage();
46+
}
47+
48+
$db = null;
49+
--EXPECTF--
50+
array(2) {
51+
["DUMMY"]=>
52+
string(1) "X"
53+
[0]=>
54+
string(1) "X"
55+
}

ext/pdo_oci/tests/pdo_oci_attr_prefetch_1.phpt

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,44 @@ require(dirname(__FILE__) . '/../../pdo/tests/pdo_test.inc');
1313

1414
$dbh = PDOTest::factory();
1515

16-
echo "Test connect: (value is ignored & has no effect)\n";
16+
echo "Test connect\n";
1717
putenv('PDOTEST_ATTR='.serialize(array(PDO::ATTR_PREFETCH=>101)));
1818
$dbh = PDOTest::factory();
1919

20-
echo "Test set: (value is ignored & has no effect)\n";
20+
echo $dbh->getAttribute(PDO::ATTR_PREFETCH), "\n";
21+
22+
// Verify can fetch
23+
$s = $dbh->prepare("select dummy from dual" );
24+
$s->execute();
25+
while ($r = $s->fetch()) {
26+
echo $r[0] . "\n";
27+
}
28+
29+
echo "Test set 102\n";
2130
$dbh->setAttribute(PDO::ATTR_PREFETCH, 102);
31+
echo $dbh->getAttribute(PDO::ATTR_PREFETCH), "\n";
32+
33+
// Verify can fetch
34+
$s = $dbh->prepare("select dummy from dual" );
35+
$s->execute();
36+
while ($r = $s->fetch()) {
37+
echo $r[0] . "\n";
38+
}
39+
40+
echo "Test set -1: (Uses 0)\n";
41+
$dbh->setAttribute(PDO::ATTR_PREFETCH, -1);
42+
echo $dbh->getAttribute(PDO::ATTR_PREFETCH), "\n";
43+
44+
// Verify can fetch
45+
$s = $dbh->prepare("select dummy from dual" );
46+
$s->execute();
47+
while ($r = $s->fetch()) {
48+
echo $r[0] . "\n";
49+
}
50+
51+
echo "Test set PHP_INT_MAX: (Uses default)\n";
52+
$dbh->setAttribute(PDO::ATTR_PREFETCH, PHP_INT_MAX);
53+
echo $dbh->getAttribute(PDO::ATTR_PREFETCH), "\n";
2254

2355
// Verify can fetch
2456
$s = $dbh->prepare("select dummy from dual" );
@@ -31,7 +63,16 @@ echo "Done\n";
3163

3264
?>
3365
--EXPECT--
34-
Test connect: (value is ignored & has no effect)
35-
Test set: (value is ignored & has no effect)
66+
Test connect
67+
101
68+
X
69+
Test set 102
70+
102
71+
X
72+
Test set -1: (Uses 0)
73+
0
74+
X
75+
Test set PHP_INT_MAX: (Uses default)
76+
100
3677
X
3778
Done

0 commit comments

Comments
 (0)