Skip to content

Commit 4fcf4e0

Browse files
committed
Fixed bug #57702 (Multi-row BLOB fetches)
1 parent 6a06587 commit 4fcf4e0

File tree

3 files changed

+168
-3
lines changed

3 files changed

+168
-3
lines changed

NEWS

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@ PHP NEWS
2020
- PDO_sqlite:
2121
. Fixed bug #63916 (PDO::PARAM_INT casts to 32bit int internally even
2222
on 64bit builds in pdo_sqlite). (srgoogleguy, Lars)
23+
. Fixed bug #57702 (Multi-row BLOB fetches). (hswong3i, Laruence)
2324
. Fixed bug #52958 (Segfault in PDO_OCI on cleanup after running a long
24-
testsuite) (hswong3i, Lars)
25+
testsuite). (hswong3i, Lars)
2526

2627
?? ??? 2012, PHP 5.4.11
2728

ext/pdo_oci/oci_statement.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ static int oci_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */
9999
switch (S->cols[i].dtype) {
100100
case SQLT_BLOB:
101101
case SQLT_CLOB:
102-
/* do nothing */
102+
OCIDescriptorFree(S->cols[i].data, OCI_DTYPE_LOB);
103103
break;
104104
default:
105105
efree(S->cols[i].data);
@@ -654,7 +654,6 @@ static int oci_blob_close(php_stream *stream, int close_handle TSRMLS_DC)
654654

655655
if (close_handle) {
656656
OCILobClose(self->S->H->svc, self->S->err, self->lob);
657-
OCIDescriptorFree(self->lob, OCI_DTYPE_LOB);
658657
efree(self);
659658
}
660659

ext/pdo_oci/tests/bug57702.phpt

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
--TEST--
2+
PDO OCI Bug #57702 (Multi-row BLOB fetches)
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+
// Note the PDO test setup sets PDO::ATTR_STRINGIFY_FETCHES to true
16+
// (and sets PDO::ATTR_CASE to PDO::CASE_LOWER)
17+
18+
$query = "begin execute immediate 'drop table mytable'; exception when others then if sqlcode <> -942 then raise; end if; end;";
19+
$stmt = $db->prepare($query);
20+
$stmt->execute();
21+
22+
$query = "create table bug57702 (id number, data1 blob, data2 blob)";
23+
$stmt = $db->prepare($query);
24+
$stmt->execute();
25+
26+
function do_insert($db, $id, $data1, $data2)
27+
{
28+
$db->beginTransaction();
29+
$stmt = $db->prepare("insert into bug57702 (id, data1, data2) values (:id, empty_blob(), empty_blob()) returning data1, data2 into :blob1, :blob2");
30+
$stmt->bindParam(':id', $id);
31+
$stmt->bindParam(':blob1', $blob1, PDO::PARAM_LOB);
32+
$stmt->bindParam(':blob2', $blob2, PDO::PARAM_LOB);
33+
$blob1 = null;
34+
$blob2 = null;
35+
$stmt->execute();
36+
37+
fwrite($blob1, $data1);
38+
fclose($blob1);
39+
fwrite($blob2, $data2);
40+
fclose($blob2);
41+
$db->commit();
42+
}
43+
44+
do_insert($db, 1, "row 1 col 1", "row 1 col 2");
45+
do_insert($db, 2, "row 2 col 1", "row 2 col 2");
46+
47+
////////////////////
48+
49+
echo "First Query\n";
50+
51+
// Fetch it back
52+
$stmt = $db->prepare('select data1, data2 from bug57702 order by id');
53+
$stmt->execute();
54+
$row = $stmt->fetch(PDO::FETCH_ASSOC);
55+
var_dump($row['data1']);
56+
var_dump($row['data2']);
57+
$row = $stmt->fetch(PDO::FETCH_ASSOC);
58+
var_dump($row['data1']);
59+
var_dump($row['data2']);
60+
61+
////////////////////
62+
63+
echo "\nSecond Query\n";
64+
65+
foreach($db->query("select data1 as d1, data2 as d2 from bug57702 order by id") as $row) {
66+
var_dump($row['d1']);
67+
var_dump($row['d2']);
68+
}
69+
70+
////////////////////
71+
72+
echo "\nThird Query\n";
73+
74+
$stmt = $db->prepare('select data1 as d3_1, data2 as d3_2 from bug57702 order by id');
75+
76+
$rs = $stmt->execute();
77+
$stmt->bindColumn('d3_1' , $clob1, PDO::PARAM_LOB);
78+
$stmt->bindColumn('d3_2' , $clob2, PDO::PARAM_LOB);
79+
80+
while ($stmt->fetch(PDO::FETCH_BOUND)) {
81+
var_dump($clob1);
82+
var_dump($clob2);
83+
}
84+
print "done\n";
85+
86+
////////////////////
87+
88+
echo "\nFourth Query\n";
89+
90+
$a = array();
91+
$i = 0;
92+
foreach($db->query("select data1 as d4_1, data2 as d4_2 from bug57702 order by id") as $row) {
93+
$a[$i][0] = $row['d4_1'];
94+
$a[$i][1] = $row['d4_2'];
95+
$i++;
96+
}
97+
98+
for ($i = 0; $i < count($a); $i++) {
99+
var_dump($a[$i][0]);
100+
var_dump($a[$i][1]);
101+
}
102+
103+
////////////////////
104+
105+
echo "\nFifth Query\n";
106+
107+
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false); // Let's use streams
108+
109+
// Since each column only has one lob descriptor, the last row is
110+
// shown twice because the lob descriptor for each column is reused in
111+
// the stream
112+
113+
$a = array();
114+
$i = 0;
115+
foreach($db->query("select data1 as d4_1, data2 as d4_2 from bug57702 order by id") as $row) {
116+
$a[$i][0] = $row['d4_1'];
117+
$a[$i][1] = $row['d4_2'];
118+
$i++;
119+
}
120+
121+
for ($i = 0; $i < count($a); $i++) {
122+
var_dump(stream_get_contents($a[$i][0]));
123+
var_dump(stream_get_contents($a[$i][1]));
124+
}
125+
126+
// Cleanup
127+
$query = "drop table bug57702";
128+
$stmt = $db->prepare($query);
129+
$stmt->execute();
130+
131+
print "done\n";
132+
133+
?>
134+
--EXPECTF--
135+
First Query
136+
string(11) "row 1 col 1"
137+
string(11) "row 1 col 2"
138+
string(11) "row 2 col 1"
139+
string(11) "row 2 col 2"
140+
141+
Second Query
142+
string(11) "row 1 col 1"
143+
string(11) "row 1 col 2"
144+
string(11) "row 2 col 1"
145+
string(11) "row 2 col 2"
146+
147+
Third Query
148+
string(11) "row 1 col 1"
149+
string(11) "row 1 col 2"
150+
string(11) "row 2 col 1"
151+
string(11) "row 2 col 2"
152+
done
153+
154+
Fourth Query
155+
string(11) "row 1 col 1"
156+
string(11) "row 1 col 2"
157+
string(11) "row 2 col 1"
158+
string(11) "row 2 col 2"
159+
160+
Fifth Query
161+
string(11) "row 2 col 1"
162+
string(11) "row 2 col 2"
163+
string(11) "row 2 col 1"
164+
string(11) "row 2 col 2"
165+
done

0 commit comments

Comments
 (0)