bug43497.phpt 6.1 KB

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