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