mysqli_fetch_array_large.phpt 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. --TEST--
  2. mysqli_fetch_array() - large packages (to test compression)
  3. --SKIPIF--
  4. <?php
  5. require_once('skipif.inc');
  6. require_once('skipifconnectfailure.inc');
  7. ?>
  8. --INI--
  9. memory_limit=-1
  10. --FILE--
  11. <?php
  12. require_once("connect.inc");
  13. function mysqli_fetch_array_large($offset, $link, $package_size) {
  14. /* we are aiming for maximum compression to test MYSQLI_CLIENT_COMPRESS */
  15. $random_char = str_repeat('a', 255);
  16. $sql = "INSERT INTO test(label) VALUES ";
  17. while (strlen($sql) < ($package_size - 259))
  18. $sql .= sprintf("('%s'), ", $random_char);
  19. $sql = substr($sql, 0, -2);
  20. $len = strlen($sql);
  21. assert($len < $package_size);
  22. if (!@mysqli_query($link, $sql)) {
  23. if (1153 == mysqli_errno($link) || 2006 == mysqli_errno($link) || stristr(mysqli_error($link), 'max_allowed_packet'))
  24. /*
  25. myslqnd - [1153] Got a packet bigger than 'max_allowed_packet' bytes
  26. libmysql -[2006] MySQL server has gone away
  27. */
  28. return false;
  29. printf("[%03d + 1] len = %d, [%d] %s\n", $offset, $len, mysqli_errno($link), mysqli_error($link));
  30. return false;
  31. }
  32. /* buffered result set - let's hope we do not run into PHP memory limit... */
  33. if (!$res = mysqli_query($link, "SELECT id, label FROM test")) {
  34. printf("[%03d + 2] len = %d, [%d] %s\n", $offset, $len, mysqli_errno($link), mysqli_error($link));
  35. return false;
  36. }
  37. while ($row = mysqli_fetch_assoc($res)) {
  38. if ($row['label'] != $random_char) {
  39. printf("[%03d + 3] Wrong results - expecting '%s' got '%s', len = %d, [%d] %s\n",
  40. $offset, $random_char, $row['label'], $len, mysqli_errno($link), mysqli_error($link));
  41. return false;
  42. }
  43. }
  44. mysqli_free_result($res);
  45. if (!$stmt = mysqli_prepare($link, "SELECT id, label FROM test")) {
  46. printf("[%03d + 4] len = %d, [%d] %s\n", $offset, $len, mysqli_errno($link), mysqli_error($link));
  47. return false;
  48. }
  49. /* unbuffered result set */
  50. if (!mysqli_stmt_execute($stmt)) {
  51. printf("[%03d + 5] len = %d, [%d] %s, [%d] %s\n", $offset, $len, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt), mysqli_errno($link), mysqli_error($link));
  52. return false;
  53. }
  54. $id = $label = NULL;
  55. if (!mysqli_stmt_bind_result($stmt, $id, $label)) {
  56. printf("[%03d + 6] len = %d, [%d] %s, [%d] %s\n", $offset, $len, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt), mysqli_errno($link), mysqli_error($link));
  57. return false;
  58. }
  59. while (mysqli_stmt_fetch($stmt)) {
  60. if ($label != $random_char) {
  61. printf("[%03d + 7] Wrong results - expecting '%s' got '%s', len = %d, [%d] %s\n",
  62. $offset, $random_char, $label, $len, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
  63. return false;
  64. }
  65. }
  66. mysqli_stmt_free_result($stmt);
  67. mysqli_stmt_close($stmt);
  68. return true;
  69. }
  70. function parse_memory_limit($limit) {
  71. $val = trim($limit);
  72. $last = strtolower($val[strlen($val)-1]);
  73. switch($last) {
  74. // The 'G' modifier is available since PHP 5.1.0
  75. case 'g':
  76. $val *= 1024;
  77. case 'm':
  78. $val *= 1024;
  79. case 'k':
  80. $val *= 1024;
  81. default:
  82. break;
  83. }
  84. return $val;
  85. }
  86. function test_fetch($host, $user, $passwd, $db, $port, $socket, $engine, $flags = null) {
  87. $link = mysqli_init();
  88. if (!my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket, $flags)) {
  89. printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
  90. $host, $user, $db, $port, $socket);
  91. return false;
  92. }
  93. if (!mysqli_query($link, "DROP TABLE IF EXISTS test") ||
  94. !mysqli_query($link, sprintf("CREATE TABLE test(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, label VARCHAR(255)) ENGINE = %s", $engine))) {
  95. printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
  96. return false;
  97. }
  98. $package_size = 524288;
  99. $offset = 3;
  100. $limit = (ini_get('memory_limit') > 0) ? parse_memory_limit(ini_get('memory_limit')) : pow(2, 32);
  101. /* try to respect php.ini but make run time a soft limit */
  102. $max_runtime = (ini_get('max_execution_time') > 0) ? ini_get('max_execution_time') : 30;
  103. set_time_limit(0);
  104. do {
  105. if ($package_size > $limit) {
  106. printf("stop: memory limit - %s vs. %s\n", $package_size, $limit);
  107. break;
  108. }
  109. $start = microtime(true);
  110. if (!mysqli_fetch_array_large($offset++, $link, $package_size)) {
  111. printf("stop: packet size - %d\n", $package_size);
  112. break;
  113. }
  114. $duration = microtime(true) - $start;
  115. $max_runtime -= $duration;
  116. if ($max_runtime < ($duration * 3)) {
  117. /* likely the next iteration will not be within max_execution_time */
  118. printf("stop: time limit - %2.2fs\n", $max_runtime);
  119. break;
  120. }
  121. $package_size += $package_size;
  122. } while (true);
  123. mysqli_close($link);
  124. return true;
  125. }
  126. test_fetch($host, $user, $passwd, $db, $port, $socket, $engine, null);
  127. test_fetch($host, $user, $passwd, $db, $port, $socket, $engine, MYSQLI_CLIENT_COMPRESS);
  128. print "done!";
  129. ?>
  130. --CLEAN--
  131. <?php
  132. require_once("clean_table.inc");
  133. ?>
  134. --EXPECTF--
  135. stop: %s
  136. stop: %s
  137. done!