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