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