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