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 } 110 } 111 } 112 113 } while (true); 114 115 // Checking if all lines are still usable 116 foreach ($links as $thread_id => $link) { 117 if (isset($saved_errors[$thread_id])) { 118 printf("[003] '%s' caused %d\n", 119 $links[$thread_id]['query'], $saved_errors[$thread_id]); 120 if ($saved_errors[$thread_id] != mysqli_errno($link['link'])) { 121 printf("[004] Error state not saved for query '%s', %d != %d\n", $link['query'], 122 $saved_errors[$thread_id], mysqli_errno($link['link'])); 123 } 124 } 125 126 if (!$res = mysqli_query($link['link'], 'SELECT * FROM test WHERE id = 100')) 127 printf("[005] Expecting true got %s/%s\n", gettype($tmp), var_export($tmp, true)); 128 if (!$row = mysqli_fetch_row($res)) 129 printf("[006] Expecting true got %s/%s\n", gettype($tmp), var_export($tmp, true)); 130 131 mysqli_free_result($res); 132 } 133 134 if ($res = mysqli_query($link['link'], "SELECT * FROM test WHERE id = 100")) { 135 $row = mysqli_fetch_assoc($res); 136 var_dump($row); 137 mysqli_free_result($res); 138 } 139 140 if ($have_proc && ($res = mysqli_query($link['link'], "SELECT @version as _version"))) { 141 $row = mysqli_fetch_assoc($res); 142 if ($row['_version'] != 'myversion') { 143 printf("[007] Check procedures\n"); 144 } 145 mysqli_free_result($res); 146 } 147 148 foreach ($links as $link) 149 mysqli_close($link['link']); 150 151 $link = get_connection(); 152 if (!mysqli_query($link, 'SELECT 1', MYSQLI_ASYNC)) 153 printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 154 155 if (!mysqli_query($link, 'SELECT 1', MYSQLI_ASYNC)) 156 printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 157 158 mysqli_close($link); 159 160 print "done!"; 161?> 162--CLEAN-- 163<?php 164require_once("connect.inc"); 165if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) 166 printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); 167 168if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) 169 printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 170 171if (!mysqli_query($link, "DROP TABLE IF EXISTS bogus")) 172 printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 173 174mysqli_query($link, "DROP PROCEDURE IF EXISTS p"); 175 176mysqli_close($link); 177?> 178--EXPECTF-- 179[003] 'SELECT' caused 1064 180[003] 'UPDATE test SET id = 101 WHERE id > 3' caused 1062 181[003] 'UPDATE_FIX test SET id = 101 WHERE id > 3' caused 1064 182array(2) { 183 ["id"]=> 184 string(3) "100" 185 ["label"]=> 186 string(1) "z" 187} 188[009] [2014] %s 189done! 190