1--TEST-- 2Bug #43497 (OCI8 XML/getClobVal aka temporary LOBs leak UGA memory) 3--SKIPIF-- 4<?php 5$target_dbs = array('oracledb' => true, 'timesten' => false); // test runs on these DBs 6require(__DIR__.'/skipif.inc'); 7if (getenv('SKIP_SLOW_TESTS')) die('skip slow tests excluded by request'); 8?> 9--FILE-- 10<?php 11 12require __DIR__.'/connect.inc'; 13 14function sessionid($c) // determines and returns current session ID 15{ 16 $query = "select sid from v\$session where audsid = userenv('sessionid')"; 17 18 $stmt = oci_parse($c, $query); 19 20 if (oci_execute($stmt, OCI_DEFAULT)) { 21 $row = oci_fetch($stmt); 22 return oci_result($stmt, 1); 23 } 24 25 return null; 26} 27 28 29function templobs($c, $sid) // returns number of temporary LOBs 30{ 31 $query = "select abstract_lobs from v\$temporary_lobs where sid = " . $sid; 32 33 $stmt = oci_parse($c, $query); 34 35 if (oci_execute($stmt, OCI_DEFAULT)) { 36 $row = oci_fetch($stmt); 37 $val = oci_result($stmt, 1); 38 oci_free_statement($stmt); 39 return $val; 40 } 41 return null; 42} 43 44 45// Read all XML data using explicit LOB locator 46function readxmltab_ex($c) 47{ 48 $stmt = oci_parse($c, "select extract(xml, '/').getclobval() from bug43497_tab"); 49 50 $cntchk = 0; 51 if (oci_execute($stmt)) { 52 while ($result = oci_fetch_array($stmt, OCI_NUM)) { 53 $result[0]->free(); // cleanup properly 54 ++$cntchk; 55 } 56 } 57 echo "Loop count check = $cntchk\n"; 58} 59 60// Read all XML data using explicit LOB locator but without freeing the temp lobs 61function readxmltab_ex_nofree($c) 62{ 63 $stmt = oci_parse($c, "select extract(xml, '/').getclobval() from bug43497_tab"); 64 65 $cntchk = 0; 66 if (oci_execute($stmt)) { 67 while ($result = oci_fetch_array($stmt, OCI_NUM)) { 68 ++$cntchk; 69 } 70 } 71 echo "Loop count check = $cntchk\n"; 72} 73 74// Read all XML data using implicit LOB locator 75function readxmltab_im($c) 76{ 77 $stmt = oci_parse($c, "select extract(xml, '/').getclobval() from bug43497_tab"); 78 79 $cntchk = 0; 80 if (oci_execute($stmt)) { 81 while ($result = oci_fetch_array($stmt, OCI_NUM+OCI_RETURN_LOBS)) { 82 ++$cntchk; 83 } 84 } 85 echo "Loop count check = $cntchk\n"; 86} 87 88function createxmltab($c) // create table w/ field of XML type 89{ 90 @dropxmltab($c); 91 $stmt = oci_parse($c, "create table bug43497_tab (id number primary key, xml xmltype)"); 92 oci_execute($stmt); 93} 94 95function dropxmltab($c) // delete table 96{ 97 $stmt = oci_parse($c, "drop table bug43497_tab"); 98 oci_execute($stmt); 99} 100 101 102function fillxmltab($c) 103{ 104 for ($id = 1; $id <= 100; $id++) { 105 106 // create an XML element string with random data 107 $s = "<data>"; 108 for ($j = 0; $j < 128; $j++) { 109 $s .= rand(); 110 } 111 $s .= "</data>\n"; 112 for ($j = 0; $j < 4; $j++) { 113 $s .= $s; 114 } 115 $data = "<?xml version=\"1.0\"?><records>" . $s . "</records>"; 116 117 // insert XML data into database 118 119 $stmt = oci_parse($c, "insert into bug43497_tab(id, xml) values (:id, sys.xmltype.createxml(:xml))"); 120 oci_bind_by_name($stmt, ":id", $id); 121 $clob = oci_new_descriptor($c, OCI_D_LOB); 122 oci_bind_by_name($stmt, ":xml", $clob, -1, OCI_B_CLOB); 123 $clob->writeTemporary($data); 124 oci_execute($stmt); 125 126 $clob->close(); 127 $clob->free(); 128 } 129} 130 131 132// Initialize 133 134createxmltab($c); 135fillxmltab($c); 136 137// Run Test 138 139$sid = sessionid($c); 140 141echo "Explicit LOB use\n"; 142for ($i = 1; $i <= 10; $i++) { 143 echo "\nRun = " . $i . "\n"; 144 echo "Temporary LOBs = " . templobs($c, $sid) . "\n"; 145 readxmltab_ex($c); 146} 147 148echo "\nImplicit LOB use\n"; 149for ($i = 1; $i <= 10; $i++) { 150 echo "\nRun = " . $i . "\n"; 151 echo "Temporary LOBs = " . templobs($c, $sid) . "\n"; 152 readxmltab_im($c); 153} 154 155echo "\nExplicit LOB with no free\n"; 156for ($i = 1; $i <= 10; $i++) { 157 echo "\nRun = " . $i . "\n"; 158 echo "Temporary LOBs = " . templobs($c, $sid) . "\n"; 159 readxmltab_ex_nofree($c); 160} 161 162 163 164// Cleanup 165 166dropxmltab($c); 167 168oci_close($c); 169 170echo "Done\n"; 171?> 172--EXPECT-- 173Explicit LOB use 174 175Run = 1 176Temporary LOBs = 0 177Loop count check = 100 178 179Run = 2 180Temporary LOBs = 0 181Loop count check = 100 182 183Run = 3 184Temporary LOBs = 0 185Loop count check = 100 186 187Run = 4 188Temporary LOBs = 0 189Loop count check = 100 190 191Run = 5 192Temporary LOBs = 0 193Loop count check = 100 194 195Run = 6 196Temporary LOBs = 0 197Loop count check = 100 198 199Run = 7 200Temporary LOBs = 0 201Loop count check = 100 202 203Run = 8 204Temporary LOBs = 0 205Loop count check = 100 206 207Run = 9 208Temporary LOBs = 0 209Loop count check = 100 210 211Run = 10 212Temporary LOBs = 0 213Loop count check = 100 214 215Implicit LOB use 216 217Run = 1 218Temporary LOBs = 0 219Loop count check = 100 220 221Run = 2 222Temporary LOBs = 0 223Loop count check = 100 224 225Run = 3 226Temporary LOBs = 0 227Loop count check = 100 228 229Run = 4 230Temporary LOBs = 0 231Loop count check = 100 232 233Run = 5 234Temporary LOBs = 0 235Loop count check = 100 236 237Run = 6 238Temporary LOBs = 0 239Loop count check = 100 240 241Run = 7 242Temporary LOBs = 0 243Loop count check = 100 244 245Run = 8 246Temporary LOBs = 0 247Loop count check = 100 248 249Run = 9 250Temporary LOBs = 0 251Loop count check = 100 252 253Run = 10 254Temporary LOBs = 0 255Loop count check = 100 256 257Explicit LOB with no free 258 259Run = 1 260Temporary LOBs = 0 261Loop count check = 100 262 263Run = 2 264Temporary LOBs = 0 265Loop count check = 100 266 267Run = 3 268Temporary LOBs = 0 269Loop count check = 100 270 271Run = 4 272Temporary LOBs = 0 273Loop count check = 100 274 275Run = 5 276Temporary LOBs = 0 277Loop count check = 100 278 279Run = 6 280Temporary LOBs = 0 281Loop count check = 100 282 283Run = 7 284Temporary LOBs = 0 285Loop count check = 100 286 287Run = 8 288Temporary LOBs = 0 289Loop count check = 100 290 291Run = 9 292Temporary LOBs = 0 293Loop count check = 100 294 295Run = 10 296Temporary LOBs = 0 297Loop count check = 100 298Done 299