1--TEST-- 2mysqli_poll() & INSERT SELECT 3--SKIPIF-- 4<?php 5require_once('skipif.inc'); 6require_once('skipifemb.inc'); 7require_once('connect.inc'); 8require_once('skipifconnectfailure.inc'); 9 10if (!$IS_MYSQLND) 11 die("skip mysqlnd only feature, compile PHP using --with-mysqli=mysqlnd"); 12?> 13--FILE-- 14<?php 15 require_once('table.inc'); 16 17 function get_connection() { 18 global $host, $user, $passwd, $db, $port, $socket; 19 20 if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) 21 printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); 22 return $link; 23 } 24 25 26 // Note: some queries will fail! They are supposed to fail. 27 $queries = array( 28 'CREATE TABLE IF NOT EXISTS bogus(id INT)', 29 'SET @a = 1', 30 'SELECT * FROM test ORDER BY id ASC LIMIT 2', 31 "INSERT INTO test(id, label) VALUES (100, 'z')", 32 'SELECT * FROM test ORDER BY id ASC LIMIT 2', 33 'SELECT', 34 'UPDATE test SET id = 101 WHERE id > 3', 35 'UPDATE_FIX test SET id = 101 WHERE id > 3', 36 'DROP TABLE IF EXISTS bogus', 37 'DELETE FROM test WHERE id = @a', 38 'DELETE FROM test WHERE id = 1', 39 ); 40 41 $link = get_connection(); 42 $have_proc = false; 43 mysqli_real_query($link, "DROP PROCEDURE IF EXISTS p"); 44 if (mysqli_real_query($link, 'CREATE PROCEDURE p(IN ver_in VARCHAR(25), OUT ver_out VARCHAR(25)) BEGIN SELECT ver_in INTO ver_out; END;')) { 45 $have_proc = true; 46 $queries[] = "CALL p('myversion', @version)"; 47 } 48 mysqli_close($link); 49 50 $links = array(); 51 for ($i = 0; $i < count($queries); $i++) { 52 53 $link = get_connection(); 54 55 if (true !== ($tmp = mysqli_query($link, $queries[$i], MYSQLI_ASYNC | MYSQLI_USE_RESULT))) 56 printf("[002] Expecting true got %s/%s\n", gettype($tmp), var_export($tmp, true)); 57 58 // WARNING KLUDGE NOTE 59 // Add a tiny delay to ensure that queries get executed in a certain order 60 // If your MySQL server is very slow the test may randomly fail! 61 usleep(20000); 62 63 $links[mysqli_thread_id($link)] = array( 64 'query' => $queries[$i], 65 'link' => $link, 66 'processed' => false, 67 ); 68 } 69 70 $saved_errors = array(); 71 do { 72 $poll_links = $poll_errors = $poll_reject = array(); 73 foreach ($links as $thread_id => $link) { 74 if (!$link['processed']) { 75 $poll_links[] = $link['link']; 76 $poll_errors[] = $link['link']; 77 $poll_reject[] = $link['link']; 78 } 79 } 80 if (0 == count($poll_links)) 81 break; 82 83 if (0 === ($num_ready = mysqli_poll($poll_links, $poll_errors, $poll_reject, 0, 200000))) 84 continue; 85 86 if (!empty($poll_errors)) { 87 die(var_dump($poll_errors)); 88 } 89 90 if (FALSE === $num_ready) { 91 die("Some mysqli indicated error"); 92 } 93 94 foreach ($poll_links as $link) { 95 $thread_id = mysqli_thread_id($link); 96 $links[$thread_id]['processed'] = true; 97 98 if (is_object($res = mysqli_reap_async_query($link))) { 99 // result set object 100 while ($row = mysqli_fetch_assoc($res)) { 101 // eat up all results 102 ; 103 } 104 mysqli_free_result($res); 105 } else { 106 // either there is no result (no SELECT) or there is an error 107 if (mysqli_errno($link) > 0) { 108 $saved_errors[$thread_id] = mysqli_errno($link); 109 printf("[003] '%s' caused %d\n", $links[$thread_id]['query'], mysqli_errno($link)); 110 } 111 } 112 } 113 114 } while (true); 115 116 // Checking if all lines are still usable 117 foreach ($links as $thread_id => $link) { 118 if (isset($saved_errors[$thread_id]) && 119 $saved_errors[$thread_id] != mysqli_errno($link['link'])) { 120 printf("[004] Error state not saved for query '%s', %d != %d\n", $link['query'], 121 $saved_errors[$thread_id], mysqli_errno($link['link'])); 122 } 123 124 if (!$res = mysqli_query($link['link'], 'SELECT * FROM test WHERE id = 100')) 125 printf("[005] Expecting true got %s/%s\n", gettype($tmp), var_export($tmp, true)); 126 if (!$row = mysqli_fetch_row($res)) 127 printf("[006] Expecting true got %s/%s\n", gettype($tmp), var_export($tmp, true)); 128 129 mysqli_free_result($res); 130 } 131 132 if ($res = mysqli_query($link['link'], "SELECT * FROM test WHERE id = 100")) { 133 $row = mysqli_fetch_assoc($res); 134 var_dump($row); 135 mysqli_free_result($res); 136 } 137 138 if ($have_proc && ($res = mysqli_query($link['link'], "SELECT @version as _version"))) { 139 $row = mysqli_fetch_assoc($res); 140 if ($row['_version'] != 'myversion') { 141 printf("[007] Check procedures\n"); 142 } 143 mysqli_free_result($res); 144 } 145 146 foreach ($links as $link) 147 mysqli_close($link['link']); 148 149 $link = get_connection(); 150 if (!mysqli_query($link, 'SELECT 1', MYSQLI_ASYNC)) 151 printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 152 153 if (!mysqli_query($link, 'SELECT 1', MYSQLI_ASYNC)) 154 printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 155 156 mysqli_close($link); 157 158 print "done!"; 159?> 160--CLEAN-- 161<?php 162require_once("connect.inc"); 163if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) 164 printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); 165 166if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) 167 printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 168 169if (!mysqli_query($link, "DROP TABLE IF EXISTS bogus")) 170 printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 171 172mysqli_query($link, "DROP PROCEDURE IF EXISTS p"); 173 174mysqli_close($link); 175?> 176 177--EXPECTF-- 178[003] 'SELECT' caused 1064 179[003] 'UPDATE test SET id = 101 WHERE id > 3' caused 1062 180[003] 'UPDATE_FIX test SET id = 101 WHERE id > 3' caused 1064 181array(2) { 182 [%u|b%"id"]=> 183 %unicode|string%(3) "100" 184 [%u|b%"label"]=> 185 %unicode|string%(1) "z" 186} 187[009] [2014] %s 188done! 189