1--TEST--
2mysqli_get_client_stats()
3--SKIPIF--
4<?PHP
5require_once('skipif.inc');
6require_once('skipifconnectfailure.inc');
7if (!function_exists('mysqli_get_client_stats')) {
8    die("skip only available with mysqlnd");
9}
10?>
11--INI--
12mysqlnd.collect_statistics=1
13mysqlnd.collect_memory_statistics=1
14mysqli.allow_local_infile=1
15--FILE--
16<?php
17    /*
18    TODO
19    no_index_used - difficult to simulate because server/engine dependent
20    bad_index_used - difficult to simulate because server/engine dependent
21    flushed_normal_sets
22    flushed_ps_sets
23    explicit_close
24    implicit_close
25    disconnect_close
26    in_middle_of_command_close
27    explicit_free_result
28    implicit_free_result
29    explicit_stmt_close
30    implicit_stmt_close
31    */
32
33    function mysqli_get_client_stats_assert_eq($field, $current, $expected, &$test_counter, $desc = "") {
34
35        $test_counter++;
36        if (is_array($current) && is_array($expected)) {
37            if ($current[$field] !== $expected[$field]) {
38                printf("[%03d] %s Expecting %s = %s/%s, got %s/%s\n",
39                    $test_counter, $desc,
40                    $field, $expected[$field], gettype($expected[$field]),
41                    $current[$field], gettype($current[$field]));
42            }
43        } else if (is_array($current)) {
44            if ($current[$field] !== $expected) {
45                printf("[%03d] %s Expecting %s = %s/%s, got %s/%s\n",
46                    $test_counter, $desc,
47                    $field, $expected, gettype($expected),
48                    $current[$field], gettype($current[$field]));
49            }
50        } else {
51            if ($current !== $expected) {
52                printf("[%03d] %s Expecting %s = %s/%s, got %s/%s\n",
53                    $test_counter, $desc,
54                    $field, $expected, gettype($expected),
55                    $current, gettype($current));
56            }
57        }
58
59    }
60
61    function mysqli_get_client_stats_assert_gt($field, $current, $expected, &$test_counter, $desc = "") {
62
63        $test_counter++;
64        if (is_array($current) && is_array($expected)) {
65            if ($current[$field] <= $expected[$field]) {
66                printf("[%03d] %s Expecting %s > %s/%s, got %s/%s\n",
67                    $test_counter, $desc,
68                    $field, $expected[$field], gettype($expected[$field]),
69                    $current[$field], gettype($current[$field]));
70                }
71        } else {
72            if ($current <= $expected) {
73                printf("[%03d] %s Expecting %s > %s/%s, got %s/%s\n",
74                    $test_counter, $desc, $field,
75                    $expected, gettype($expected),
76                    $current, gettype($current));
77            }
78        }
79
80    }
81
82
83    require_once("connect.inc");
84
85    if (!is_array($info = mysqli_get_client_stats()) || empty($info))
86        printf("[002] Expecting array/any_non_empty, got %s/%s\n", gettype($info), $info);
87
88    var_dump($info);
89
90    if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
91        printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
92            $host, $user, $db, $port, $socket);
93        exit(1);
94    }
95
96    if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
97        printf("[004] Expecting array/any_non_empty, got %s/%s\n", gettype($new_info), $new_info);
98
99    if (count($info) != count($new_info)) {
100        printf("[005] Expecting the same number of entries in the arrays\n");
101        var_dump($info);
102        var_dump($new_info);
103    }
104
105    $test_counter = 6;
106
107    mysqli_get_client_stats_assert_gt('bytes_sent', $new_info, $info, $test_counter);
108    mysqli_get_client_stats_assert_gt('bytes_received', $new_info, $info, $test_counter);
109    mysqli_get_client_stats_assert_gt('packets_sent', $new_info, $info, $test_counter);
110    mysqli_get_client_stats_assert_gt('packets_received', $new_info, $info, $test_counter);
111    mysqli_get_client_stats_assert_gt('protocol_overhead_in', $new_info, $info, $test_counter);
112    mysqli_get_client_stats_assert_gt('protocol_overhead_out', $new_info, $info, $test_counter);
113
114    // we assume the above as tested and in the following we check only those
115    mysqli_get_client_stats_assert_eq('result_set_queries', $new_info, $info, $test_counter);
116
117    /* we need to skip this test in unicode - we send set names utf8 during mysql_connect */
118    mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, $info, $test_counter);
119    mysqli_get_client_stats_assert_eq('buffered_sets', $new_info, $info, $test_counter);
120    mysqli_get_client_stats_assert_eq('unbuffered_sets', $new_info, $info, $test_counter);
121    mysqli_get_client_stats_assert_eq('ps_buffered_sets', $new_info, $info, $test_counter);
122    mysqli_get_client_stats_assert_eq('ps_unbuffered_sets', $new_info, $info, $test_counter);
123
124    mysqli_get_client_stats_assert_eq('rows_skipped_ps', $new_info, $info, $test_counter);
125    mysqli_get_client_stats_assert_eq('copy_on_write_saved', $new_info, $info, $test_counter);
126    mysqli_get_client_stats_assert_eq('copy_on_write_performed', $new_info, $info, $test_counter);
127    mysqli_get_client_stats_assert_eq('command_buffer_too_small', $new_info, $info, $test_counter);
128    // This is not a mistake that I use string(1) "1" here! Andrey did not go for int to avoid any
129    // issues for very large numbers and 32 vs. 64bit systems
130    mysqli_get_client_stats_assert_eq('connect_success', $new_info, "1", $test_counter);
131    mysqli_get_client_stats_assert_eq('connect_failure', $new_info, $info, $test_counter);
132    mysqli_get_client_stats_assert_eq('connection_reused', $new_info, $info, $test_counter);
133
134    // No data fetched so far
135    mysqli_get_client_stats_assert_eq('bytes_received_real_data_normal', $new_info, "0", $test_counter);
136    mysqli_get_client_stats_assert_eq('bytes_received_real_data_ps', $new_info, "0", $test_counter);
137
138    require('table.inc');
139    if (!is_array($info = mysqli_get_client_stats()) || empty($info))
140        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
141            ++$test_counter, gettype($info), $info);
142
143    // fetch stats
144    $expected = $info;
145
146    // buffered normal
147    print "Testing buffered normal...\n";
148    if (!$res = mysqli_query($link, 'SELECT COUNT(*) AS _num FROM test', MYSQLI_STORE_RESULT))
149        printf("[%03d] SELECT COUNT() FROM test failed, [%d] %s\n",
150            ++$test_counter, mysqli_errno($link), mysqli_error($link));
151
152    $expected['rows_fetched_from_server_normal'] = (string)($expected['rows_fetched_from_server_normal'] + 1);
153    $expected['buffered_sets'] = (string)($expected['buffered_sets'] + 1);
154    $expected['result_set_queries'] = (string)($expected['result_set_queries'] + 1);
155    $expected['rows_buffered_from_client_normal'] = (string)($expected['rows_buffered_from_client_normal'] + 1);
156
157    if (!is_array($info = mysqli_get_client_stats()) || empty($info))
158        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
159            ++$test_counter, gettype($info), $info);
160
161    mysqli_get_client_stats_assert_gt('bytes_sent', $info, $expected, $test_counter);
162    mysqli_get_client_stats_assert_gt('bytes_received', $info, $expected, $test_counter);
163
164    // real_data_* get incremented after mysqli_*fetch*()
165    mysqli_get_client_stats_assert_eq('bytes_received_real_data_normal', $info, "0", $test_counter);
166    mysqli_get_client_stats_assert_eq('bytes_received_real_data_ps', $info, "0", $test_counter);
167
168    mysqli_get_client_stats_assert_eq('rows_fetched_from_server_normal', $info, $expected, $test_counter);
169    mysqli_get_client_stats_assert_eq('rows_fetched_from_client_normal_buffered', $info, $expected, $test_counter);
170    mysqli_get_client_stats_assert_eq('buffered_sets', $info, $expected, $test_counter);
171    mysqli_get_client_stats_assert_eq('result_set_queries', $info, $expected, $test_counter);
172    mysqli_get_client_stats_assert_eq('rows_buffered_from_client_normal', $info, $expected, $test_counter);
173
174    /* no change to rows_fetched_from_client_normal_buffered! */
175    if (!$row = mysqli_fetch_assoc($res))
176        printf("[%03d] fetch_assoc - SELECT COUNT() FROM test failed, [%d] %s\n",
177            ++$test_counter, mysqli_errno($link), mysqli_error($link));
178
179    $expected['rows_fetched_from_client_normal_buffered'] = (string)($expected['rows_fetched_from_client_normal_buffered'] + 1);
180
181    if (!is_array($info = mysqli_get_client_stats()) || empty($info))
182        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
183            ++$test_counter, gettype($info), $info);
184
185    // fetch will increment
186    mysqli_get_client_stats_assert_gt('bytes_received_real_data_normal', $info, $expected, $test_counter);
187    $expected['bytes_received_real_data_normal'] = $info['bytes_received_real_data_normal'];
188    mysqli_get_client_stats_assert_eq('bytes_received_real_data_ps', $info, "0", $test_counter);
189
190    mysqli_get_client_stats_assert_eq('rows_fetched_from_server_normal', $info, $expected, $test_counter);
191    mysqli_get_client_stats_assert_eq('rows_fetched_from_client_normal_buffered', $info, $expected, $test_counter);
192    mysqli_get_client_stats_assert_eq('rows_buffered_from_client_normal', $info, $expected, $test_counter);
193
194    $num_rows = $row['_num'];
195    mysqli_free_result($res);
196
197    print "Testing buffered normal... - SELECT id, label FROM test\n";
198    if (!$res = mysqli_query($link, 'SELECT id, label FROM test', MYSQLI_STORE_RESULT))
199        printf("[%03d] SELECT id, label FROM test failed, [%d] %s\n",
200            ++$test_counter, mysqli_errno($link), mysqli_error($link));
201
202
203    assert(mysqli_num_rows($res) == $num_rows);
204
205    if (!is_array($info = mysqli_get_client_stats()) || empty($info))
206        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
207            ++$test_counter, gettype($info), $info);
208
209
210    $expected['rows_fetched_from_server_normal'] = (string)($expected['rows_fetched_from_server_normal'] + $num_rows);
211    $expected['rows_buffered_from_client_normal'] = (string)($expected['rows_buffered_from_client_normal'] + $num_rows);
212    $expected['buffered_sets'] = (string)($expected['buffered_sets'] + 1);
213    $expected['result_set_queries'] = (string)($expected['result_set_queries'] + 1);
214
215    mysqli_get_client_stats_assert_eq('bytes_received_real_data_normal', $info, $expected, $test_counter);
216
217    mysqli_get_client_stats_assert_eq('rows_fetched_from_server_normal', $info, $expected, $test_counter);
218    mysqli_get_client_stats_assert_eq('rows_fetched_from_client_normal_buffered', $info, $expected, $test_counter);
219    mysqli_get_client_stats_assert_eq('buffered_sets', $info, $expected, $test_counter);
220    mysqli_get_client_stats_assert_eq('result_set_queries', $info, $expected, $test_counter);
221    mysqli_get_client_stats_assert_eq('rows_buffered_from_client_normal', $info, $expected, $test_counter);
222    mysqli_get_client_stats_assert_eq('rows_buffered_from_client_normal', $info, $expected, $test_counter);
223
224    /* fetching none, but stats should not be affected - current implementation */
225    mysqli_free_result($res);
226
227    if (!is_array($info = mysqli_get_client_stats()) || empty($info))
228        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
229            ++$test_counter, gettype($info), $info);
230
231
232    mysqli_get_client_stats_assert_eq('bytes_received_real_data_normal', $info, $expected, $test_counter);
233    mysqli_get_client_stats_assert_eq('rows_fetched_from_server_normal', $info, $expected, $test_counter);
234    mysqli_get_client_stats_assert_eq('rows_fetched_from_client_normal_buffered', $info, $expected, $test_counter);
235
236    print "Testing unbuffered normal...\n";
237    if (!$res = mysqli_query($link, 'SELECT id, label FROM test', MYSQLI_USE_RESULT))
238        printf("[%03d] SELECT id, label FROM test failed, [%d] %s\n",
239            ++$test_counter, mysqli_errno($link), mysqli_error($link));
240
241    if (!is_array($info = mysqli_get_client_stats()) || empty($info))
242        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
243            ++$test_counter, gettype($info), $info);
244
245    mysqli_get_client_stats_assert_eq('rows_fetched_from_server_normal', $info, $expected, $test_counter);
246    mysqli_get_client_stats_assert_eq('rows_fetched_from_client_normal_unbuffered', $info, $expected, $test_counter);
247    mysqli_get_client_stats_assert_eq('bytes_received_real_data_normal', $info, $expected, $test_counter);
248
249    while ($row = mysqli_fetch_assoc($res))
250        ;
251    mysqli_free_result($res);
252
253    $expected['rows_fetched_from_server_normal'] = (string)($expected['rows_fetched_from_server_normal'] + $num_rows);
254    $expected['rows_fetched_from_client_normal_unbuffered'] = (string)($expected['rows_fetched_from_client_normal_unbuffered'] + $num_rows);
255    $expected['unbuffered_sets'] = (string)($expected['unbuffered_sets'] + 1);
256    $expected['result_set_queries'] = (string)($expected['result_set_queries'] + 1);
257
258    if (!is_array($info = mysqli_get_client_stats()) || empty($info))
259        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
260            ++$test_counter, gettype($info), $info);
261
262    mysqli_get_client_stats_assert_gt('bytes_received_real_data_normal', $info, $expected, $test_counter);
263    $expected['bytes_received_real_data_normal'] = $info['bytes_received_real_data_normal'];
264
265    mysqli_get_client_stats_assert_eq('rows_fetched_from_server_normal', $info, $expected, $test_counter);
266    mysqli_get_client_stats_assert_eq('rows_fetched_from_client_normal_unbuffered', $info, $expected, $test_counter);
267    mysqli_get_client_stats_assert_eq('unbuffered_sets', $info, $expected, $test_counter);
268    mysqli_get_client_stats_assert_eq('result_set_queries', $info, $expected, $test_counter);
269
270    print "Testing unbuffered normal... - SELECT id, label FROM test, not all fetched\n";
271    if (!$res = mysqli_query($link, 'SELECT id, label FROM test', MYSQLI_USE_RESULT))
272        printf("[%03d] SELECT id, label FROM test failed, [%d] %s\n",
273            ++$test_counter, mysqli_errno($link), mysqli_error($link));
274
275    for ($i = 0; $i < $num_rows - 1; $i++)
276        $row = mysqli_fetch_assoc($res);
277
278    $expected['rows_fetched_from_server_normal'] = (string)($expected['rows_fetched_from_server_normal'] + $num_rows - 1);
279    $expected['rows_fetched_from_client_normal_unbuffered'] = (string)($expected['rows_fetched_from_client_normal_unbuffered'] + $num_rows - 1);
280    $expected['unbuffered_sets'] = (string)($expected['unbuffered_sets'] + 1);
281    $expected['result_set_queries'] = (string)($expected['result_set_queries'] + 1);
282
283    if (!is_array($info = mysqli_get_client_stats()) || empty($info))
284        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
285            ++$test_counter, gettype($info), $info);
286
287    mysqli_get_client_stats_assert_gt('bytes_received_real_data_normal', $info, $expected, $test_counter);
288    $expected['bytes_received_real_data_normal'] = $info['bytes_received_real_data_normal'];
289
290    mysqli_get_client_stats_assert_eq('rows_fetched_from_server_normal', $info, $expected, $test_counter);
291    mysqli_get_client_stats_assert_eq('rows_fetched_from_client_normal_unbuffered', $info, $expected, $test_counter);
292    mysqli_get_client_stats_assert_eq('unbuffered_sets', $info, $expected, $test_counter);
293    mysqli_get_client_stats_assert_eq('result_set_queries', $info, $expected, $test_counter);
294
295    print "Testing if implicit fetching and cleaning happens...\n";
296    mysqli_free_result($res);
297
298    /* last row has been implicitly cleaned from the wire by freeing the result set */
299    $expected['rows_fetched_from_server_normal'] = (string)($expected['rows_fetched_from_server_normal'] + 1);
300    $expected['rows_fetched_from_client_normal_unbuffered'] = (string)($expected['rows_fetched_from_client_normal_unbuffered'] + 1);
301    $expected['rows_skipped_normal'] = (string)($info['rows_skipped_normal'] + 1);
302    $expected['flushed_normal_sets'] = (string)($expected['flushed_normal_sets'] + 1);
303
304    if (!is_array($info = mysqli_get_client_stats()) || empty($info))
305        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
306            ++$test_counter, gettype($info), $info);
307
308    mysqli_get_client_stats_assert_eq('bytes_received_real_data_normal', $info, $expected, $test_counter);
309
310    mysqli_get_client_stats_assert_eq('rows_fetched_from_server_normal', $info, $expected, $test_counter);
311    mysqli_get_client_stats_assert_eq('rows_fetched_from_client_normal_unbuffered', $info, $expected, $test_counter);
312    mysqli_get_client_stats_assert_eq('rows_skipped_normal', $info, $expected, $test_counter);
313    mysqli_get_client_stats_assert_eq('flushed_normal_sets', $info, $expected, $test_counter);
314
315    print "Testing buffered Prepared Statements...\n";
316    if (!$stmt = mysqli_stmt_init($link))
317        printf("[%03d] stmt_init() failed, [%d] %s\n",
318            ++$test_counter, mysqli_errno($link), mysqli_error($link));
319
320    if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test') ||
321            !mysqli_stmt_execute($stmt))
322        printf("[%03d] prepare/execute failed, [%d] %s\n",
323            ++$test_counter, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
324
325    /* by default PS is unbuffered - no change */
326    mysqli_get_client_stats_assert_eq('rows_fetched_from_server_ps', $info, $expected, $test_counter);
327    mysqli_get_client_stats_assert_eq('rows_fetched_from_client_ps_buffered', $info, $expected, $test_counter);
328
329    if (!mysqli_stmt_store_result($stmt))
330        printf("[%03d] store_result failed, [%d] %s\n",
331            ++$test_counter, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
332    mysqli_stmt_free_result($stmt);
333
334    mysqli_get_client_stats_assert_eq('bytes_received_real_data_ps', $info, "0", $test_counter);
335    mysqli_get_client_stats_assert_eq('bytes_received_real_data_normal', $info, $expected, $test_counter);
336
337    $expected['rows_fetched_from_server_ps'] = (string)($expected['rows_fetched_from_server_ps'] + $num_rows);
338    $expected['result_set_queries'] = (string)($expected['result_set_queries'] + 1);
339    $expected['ps_buffered_sets'] = (string)($expected['ps_buffered_sets'] + 1);
340    $expected['rows_buffered_from_client_ps'] = (string)($expected['rows_buffered_from_client_ps'] + $num_rows);
341
342
343    if (!is_array($info = mysqli_get_client_stats()) || empty($info))
344        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
345            ++$test_counter, gettype($info), $info);
346
347    mysqli_get_client_stats_assert_eq('rows_fetched_from_server_ps', $info, $expected, $test_counter);
348    mysqli_get_client_stats_assert_eq('rows_fetched_from_client_ps_buffered', $info, $expected, $test_counter);
349    mysqli_get_client_stats_assert_eq('result_set_queries', $info, $expected, $test_counter);
350    mysqli_get_client_stats_assert_eq('ps_buffered_sets', $info, $expected, $test_counter);
351    mysqli_get_client_stats_assert_eq('rows_buffered_from_client_ps', $info, $expected, $test_counter);
352
353    mysqli_get_client_stats_assert_eq('bytes_received_real_data_ps', $info, "0", $test_counter);
354
355    print "Testing buffered Prepared Statements... - fetching all\n";
356
357    if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test') ||
358            !mysqli_stmt_execute($stmt))
359        printf("[%03d] prepare/execute failed, [%d] %s\n",
360            ++$test_counter, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
361
362    $id = $label = null;
363    if (!mysqli_stmt_bind_result($stmt, $id, $label))
364        printf("[%03d] bind_result failed, [%d] %s\n",
365            ++$test_counter, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
366
367    if (!mysqli_stmt_store_result($stmt))
368        printf("[%03d] store_result failed, [%d] %s\n",
369            ++$test_counter, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
370
371    while (mysqli_stmt_fetch($stmt))
372        ;
373
374    $expected['rows_fetched_from_server_ps'] = (string)($expected['rows_fetched_from_server_ps'] + $num_rows);
375    $expected['rows_fetched_from_client_ps_buffered'] = (string)($expected['rows_fetched_from_client_ps_buffered'] + $num_rows);
376    $expected['result_set_queries'] = (string)($expected['result_set_queries'] + 1);
377    $expected['ps_buffered_sets'] = (string)($expected['ps_buffered_sets'] + 1);
378    $expected['rows_buffered_from_client_ps'] = (string)($expected['rows_buffered_from_client_ps'] + $num_rows);
379
380    if (!is_array($info = mysqli_get_client_stats()) || empty($info))
381        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
382            ++$test_counter, gettype($info), $info);
383
384
385    mysqli_get_client_stats_assert_gt('bytes_received_real_data_ps', $info, $expected, $test_counter);
386    $expected['bytes_received_real_data_ps'] = $info['bytes_received_real_data_ps'];
387
388    mysqli_get_client_stats_assert_eq('rows_fetched_from_server_ps', $info, $expected, $test_counter);
389    mysqli_get_client_stats_assert_eq('rows_fetched_from_client_ps_buffered', $info, $expected, $test_counter);
390    mysqli_get_client_stats_assert_eq('result_set_queries', $info, $expected, $test_counter);
391    mysqli_get_client_stats_assert_eq('ps_buffered_sets', $info, $expected, $test_counter);
392    mysqli_get_client_stats_assert_eq('rows_buffered_from_client_ps', $info, $expected, $test_counter);
393
394    mysqli_stmt_free_result($stmt);
395
396    print "Testing buffered Prepared Statements... - fetching all but one\n";
397
398    if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test') ||
399            !mysqli_stmt_execute($stmt))
400        printf("[%03d] prepare/execute failed, [%d] %s\n",
401            ++$test_counter, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
402
403    $id = $label = null;
404    if (!mysqli_stmt_bind_result($stmt, $id, $label))
405        printf("[%03d] bind_result failed, [%d] %s\n",
406            ++$test_counter, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
407
408    if (!mysqli_stmt_store_result($stmt))
409        printf("[%03d] store_result failed, [%d] %s\n",
410            ++$test_counter, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
411
412    for ($i = 0; $i < $num_rows - 1; $i++)
413        mysqli_stmt_fetch($stmt);
414
415    $expected['rows_fetched_from_server_ps'] = (string)($expected['rows_fetched_from_server_ps'] + $num_rows);
416    $expected['rows_fetched_from_client_ps_buffered'] = (string)($expected['rows_fetched_from_client_ps_buffered'] + $num_rows - 1);
417    $expected['result_set_queries'] = (string)($expected['result_set_queries'] + 1);
418    $expected['ps_buffered_sets'] = (string)($expected['ps_buffered_sets'] + 1);
419    $expected['rows_buffered_from_client_ps'] = (string)($expected['rows_buffered_from_client_ps'] + $num_rows);
420
421    if (!is_array($info = mysqli_get_client_stats()) || empty($info))
422        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
423            ++$test_counter, gettype($info), $info);
424
425    mysqli_get_client_stats_assert_gt('bytes_received_real_data_ps', $info, $expected, $test_counter);
426    $expected['bytes_received_real_data_ps'] = $info['bytes_received_real_data_ps'];
427
428    mysqli_get_client_stats_assert_eq('rows_fetched_from_server_ps', $info, $expected, $test_counter);
429    mysqli_get_client_stats_assert_eq('rows_fetched_from_client_ps_buffered', $info, $expected, $test_counter);
430    mysqli_get_client_stats_assert_eq('result_set_queries', $info, $expected, $test_counter);
431    mysqli_get_client_stats_assert_eq('ps_buffered_sets', $info, $expected, $test_counter);
432    mysqli_get_client_stats_assert_eq('rows_buffered_from_client_ps', $info, $expected, $test_counter);
433
434    $expected['rows_skipped_ps'] = $info['rows_skipped_ps'];
435    mysqli_stmt_free_result($stmt);
436
437    if (!is_array($info = mysqli_get_client_stats()) || empty($info))
438        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
439            ++$test_counter, gettype($info), $info);
440
441    /* buffered result set - no skipping possible! */
442    mysqli_get_client_stats_assert_eq('rows_skipped_ps', $info, $expected, $test_counter);
443
444    print "Testing unbuffered Prepared Statements... - fetching all\n";
445
446    if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test') ||
447            !mysqli_stmt_execute($stmt))
448        printf("[%03d] prepare/execute failed, [%d] %s\n",
449            ++$test_counter, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
450
451    $id = $label = null;
452    if (!mysqli_stmt_bind_result($stmt, $id, $label))
453        printf("[%03d] bind_result failed, [%d] %s\n",
454            ++$test_counter, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
455
456    $i = 0;
457    while (mysqli_stmt_fetch($stmt))
458        $i++;
459    assert($num_rows = $i);
460
461    $expected['rows_fetched_from_server_ps'] = (string)($expected['rows_fetched_from_server_ps'] + $num_rows);
462    $expected['rows_fetched_from_client_ps_unbuffered'] = (string)($expected['rows_fetched_from_client_ps_unbuffered'] + $num_rows);
463    $expected['result_set_queries'] = (string)($expected['result_set_queries'] + 1);
464    $expected['ps_unbuffered_sets'] = (string)($expected['ps_unbuffered_sets'] + 1);
465
466    if (!is_array($info = mysqli_get_client_stats()) || empty($info))
467        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
468            ++$test_counter, gettype($info), $info);
469
470    mysqli_get_client_stats_assert_gt('bytes_received_real_data_ps', $info, $expected, $test_counter);
471    $expected['bytes_received_real_data_ps'] = $info['bytes_received_real_data_ps'];
472
473    mysqli_get_client_stats_assert_eq('rows_fetched_from_server_ps', $info, $expected, $test_counter);
474    mysqli_get_client_stats_assert_eq('rows_fetched_from_client_ps_unbuffered', $info, $expected, $test_counter);
475    mysqli_get_client_stats_assert_eq('result_set_queries', $info, $expected, $test_counter);
476    mysqli_get_client_stats_assert_eq('ps_unbuffered_sets', $info, $expected, $test_counter);
477    mysqli_get_client_stats_assert_eq('rows_buffered_from_client_ps', $info, $expected, $test_counter);
478
479    mysqli_stmt_free_result($stmt);
480
481    print "Testing unbuffered Prepared Statements... - fetching all but one\n";
482
483    if (!mysqli_stmt_prepare($stmt, 'SELECT id, label FROM test') ||
484            !mysqli_stmt_execute($stmt))
485        printf("[%03d] prepare/execute failed, [%d] %s\n",
486            ++$test_counter, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
487
488    $id = $label = null;
489    if (!mysqli_stmt_bind_result($stmt, $id, $label))
490        printf("[%03d] bind_result failed, [%d] %s\n",
491            ++$test_counter, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
492
493    for ($i = 0; $i < $num_rows - 1; $i++)
494        mysqli_stmt_fetch($stmt);
495
496    $expected['rows_fetched_from_server_ps'] = (string)($expected['rows_fetched_from_server_ps'] + $num_rows - 1);
497    $expected['rows_fetched_from_client_ps_unbuffered'] = (string)($expected['rows_fetched_from_client_ps_unbuffered'] + $num_rows - 1);
498    $expected['result_set_queries'] = (string)($expected['result_set_queries'] + 1);
499    $expected['ps_unbuffered_sets'] = (string)($expected['ps_unbuffered_sets'] + 1);
500
501    if (!is_array($info = mysqli_get_client_stats()) || empty($info))
502        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
503            ++$test_counter, gettype($info), $info);
504
505    mysqli_get_client_stats_assert_gt('bytes_received_real_data_ps', $info, $expected, $test_counter);
506    $expected['bytes_received_real_data_ps'] = $info['bytes_received_real_data_ps'];
507
508    mysqli_get_client_stats_assert_eq('rows_fetched_from_server_ps', $info, $expected, $test_counter);
509    mysqli_get_client_stats_assert_eq('rows_fetched_from_client_ps_unbuffered', $info, $expected, $test_counter);
510    mysqli_get_client_stats_assert_eq('result_set_queries', $info, $expected, $test_counter);
511    mysqli_get_client_stats_assert_eq('ps_unbuffered_sets', $info, $expected, $test_counter);
512    mysqli_get_client_stats_assert_eq('rows_buffered_from_client_ps', $info, $expected, $test_counter);
513
514    mysqli_stmt_free_result($stmt);
515    $expected['rows_skipped_ps'] = (string)($expected['rows_skipped_ps'] + 1);
516    $expected['flushed_ps_sets'] = (string)($expected['flushed_ps_sets'] + 1);
517    $expected['rows_fetched_from_server_ps'] = (string)($expected['rows_fetched_from_server_ps'] + 1);
518
519    if (!is_array($info = mysqli_get_client_stats()) || empty($info))
520        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
521            ++$test_counter, gettype($info), $info);
522
523    mysqli_get_client_stats_assert_eq('bytes_received_real_data_ps', $info, $expected, $test_counter);
524
525    mysqli_get_client_stats_assert_eq('rows_skipped_ps', $info, $expected, $test_counter);
526    mysqli_get_client_stats_assert_eq('flushed_ps_sets', $info, $expected, $test_counter);
527    mysqli_get_client_stats_assert_eq('rows_fetched_from_server_ps', $info, $expected, $test_counter);
528
529    /*
530    print "Checking for normal buffered side effects...\n";
531    foreach ($info as $k => $v)
532        if ($info[$k] != $expected[$k])
533            printf("$k - $v != %s\n", $expected[$k]);
534    */
535    print "... done with fetch statistics\n";
536
537    if (!is_array($info = mysqli_get_client_stats()) || empty($info))
538        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
539            ++$test_counter, gettype($info), $info);
540
541    mysqli_get_client_stats_assert_eq('bytes_received_real_data_normal', $info, $expected, $test_counter);
542    mysqli_get_client_stats_assert_eq('bytes_received_real_data_ps', $info, $expected, $test_counter);
543
544    //
545    // result_set_queries statistics
546    //
547
548    if (!is_array($info = mysqli_get_client_stats()) || empty($info))
549        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
550            ++$test_counter, gettype($info), $info);
551
552    if (!$res = mysqli_query($link, "SELECT id, label FROM test"))
553        printf("[%03d] SELECT failed, [%d] %s\n", ++$test_counter,
554            mysqli_errno($link), mysqli_error($link));
555
556    $rows = 0;
557    while ($row = mysqli_fetch_assoc($res))
558        $rows++;
559
560    if (0 == $rows)
561        printf("[%03d] Expecting at least one result, [%d] %s\n", ++$test_counter,
562            mysqli_errno($link), mysqli_error($link));
563
564    mysqli_free_result($res);
565
566    if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
567        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
568            ++$test_counter, gettype($new_info), $new_info);
569
570    mysqli_get_client_stats_assert_eq('result_set_queries', $new_info, (string)($info['result_set_queries'] + 1), $test_counter);
571    $info = $new_info;
572
573    mysqli_get_client_stats_assert_gt('bytes_received_real_data_normal', $info, $expected, $test_counter);
574    $expected['bytes_received_real_data_normal'] = $info['bytes_received_real_data_normal'];
575
576    //
577    // non_result_set_queries - DDL
578    //
579
580    // CREATE TABLE, DROP TABLE
581    if (!mysqli_query($link, "DROP TABLE IF EXISTS non_result_set_queries_test"))
582        printf("[%03d] DROP TABLE failed, [%d] %s\n", ++$test_counter,
583            mysqli_errno($link), mysqli_error($link));
584
585    if (!mysqli_query($link, "CREATE TABLE non_result_set_queries_test(id INT) ENGINE = " . $engine)) {
586        printf("[%03d] CREATE TABLE failed, [%d] %s\n", ++$test_counter,
587            mysqli_errno($link), mysqli_error($link));
588    } else {
589        if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
590            printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
591            ++$test_counter, gettype($new_info), $new_info);
592        mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 2), $test_counter, 'CREATE/DROP TABLE');
593    }
594    $info = $new_info;
595
596    // ALERT TABLE
597    if (!mysqli_query($link, "ALTER TABLE non_result_set_queries_test ADD label CHAR(1)")) {
598        printf("[%03d] ALTER TABLE failed, [%d] %s\n", ++$test_counter,
599            mysqli_errno($link), mysqli_error($link));
600    } else {
601        if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
602            printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
603                ++$test_counter, gettype($new_info), $new_info);
604        mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'ALTER TABLE');
605    }
606    $info = $new_info;
607
608    // CREATE INDEX, DROP INDEX
609    if (!mysqli_query($link, "CREATE INDEX idx_1 ON non_result_set_queries_test(id)")) {
610        printf("[%03d] CREATE INDEX failed, [%d] %s\n", ++$test_counter,
611            mysqli_errno($link), mysqli_error($link));
612    } else {
613
614        if (!mysqli_query($link, "DROP INDEX idx_1 ON non_result_set_queries_test"))
615            printf("[%03d] DROP INDEX failed, [%d] %s\n", ++$test_counter,
616                mysqli_errno($link), mysqli_error($link));
617
618        if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
619            printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
620                ++$test_counter, gettype($new_info), $new_info);
621        mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 2), $test_counter, 'DROP INDEX');
622    }
623    $info = $new_info;
624
625    // RENAME TABLE
626    if (!mysqli_query($link, "DROP TABLE IF EXISTS client_stats_test"))
627        printf("[%03d] Cleanup, DROP TABLE client_stats_test failed, [%d] %s\n", ++$test_counter,
628            mysqli_errno($link), mysqli_error($link));
629
630    if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
631        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
632            ++$test_counter, gettype($new_info), $new_info);
633    $info = $new_info;
634
635    if (!mysqli_query($link, "RENAME TABLE non_result_set_queries_test TO client_stats_test")) {
636        printf("[%03d] RENAME TABLE failed, [%d] %s\n", ++$test_counter,
637            mysqli_errno($link), mysqli_error($link));
638
639    } else {
640        if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
641            printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
642                ++$test_counter, gettype($new_info), $new_info);
643        mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'RENAME TABLE');
644
645    }
646    $info = $new_info;
647
648    if (!mysqli_query($link, "DROP TABLE IF EXISTS non_result_set_queries_test"))
649        printf("[%03d] Cleanup, DROP TABLE failed, [%d] %s\n", ++$test_counter,
650            mysqli_errno($link), mysqli_error($link));
651
652    if (!mysqli_query($link, "DROP TABLE IF EXISTS client_stats_test"))
653        printf("[%03d] Cleanup, DROP TABLE failed, [%d] %s\n", ++$test_counter,
654            mysqli_errno($link), mysqli_error($link));
655
656    // Let's see if we have privileges for CREATE DATABASE
657    mysqli_query($link, "DROP DATABASE IF EXISTS mysqli_get_client_stats");
658    if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
659        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
660            ++$test_counter, gettype($new_info), $new_info);
661    $info = $new_info;
662
663
664    // CREATE, ALTER, DROP DATABASE
665    if (mysqli_query($link, "CREATE DATABASE mysqli_get_client_stats")) {
666
667        if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
668            printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
669                ++$test_counter, gettype($new_info), $new_info);
670        mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'CREATE DATABASE');
671        $info = $new_info;
672
673        if (!mysqli_query($link, "ALTER DATABASE DEFAULT CHARACTER SET latin1"))
674            printf("[%03d] ALTER DATABASE failed, [%d] %s\n", ++$test_counter,
675                mysqli_errno($link), mysqli_error($link));
676
677        if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
678            printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
679                ++$test_counter, gettype($new_info), $new_info);
680        mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'CREATE DATABASE');
681        $info = $new_info;
682
683        if (!mysqli_query($link, "CREATE DATABASE mysqli_get_client_stats_"))
684            printf("[%03d] CREATE DATABASE failed, [%d] %s\n", ++$test_counter,
685                mysqli_errno($link), mysqli_error($link));
686        if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
687            printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
688                ++$test_counter, gettype($new_info), $new_info);
689        $info = $new_info;
690
691        if (!mysqli_query($link, "DROP DATABASE mysqli_get_client_stats_"))
692            printf("[%03d] DROP DATABASE failed, [%d] %s\n", ++$test_counter,
693                mysqli_errno($link), mysqli_error($link));
694
695        if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
696            printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
697                ++$test_counter, gettype($new_info), $new_info);
698        mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'DROP DATABASE');
699        $info = $new_info;
700    }
701
702    // CREATE SERVER, ALTER SERVER, DROP SERVER
703    // We don't really try to use federated, we just want to see if the syntax works
704    mysqli_query($link, "DROP SERVER IF EXISTS myself");
705
706    if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
707        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
708            ++$test_counter, gettype($new_info), $new_info);
709    $info = $new_info;
710
711    $sql = sprintf("CREATE SERVER myself FOREIGN DATA WRAPPER mysql OPTIONS (user '%s', password '%s', database '%s')",
712        $user, $passwd, $db);
713    if (mysqli_query($link, $sql)) {
714        // server knows about it
715
716        if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
717            printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
718                ++$test_counter, gettype($new_info), $new_info);
719
720        mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'CREATE SERVER');
721        $info = $new_info;
722
723        if (!mysqli_query($link, sprintf("ALTER SERVER myself OPTIONS(user '%s_')", $user)))
724            printf("[%03d] ALTER SERVER failed, [%d] %s\n", ++$test_counter,
725                mysqli_errno($link), mysqli_error($link));
726
727        if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
728            printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
729                ++$test_counter, gettype($new_info), $new_info);
730        mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'ALTER SERVER');
731        $info = $new_info;
732
733        if (!mysqli_query($link, "DROP SERVER myself"))
734            printf("[%03d] DROP SERVER failed, [%d] %s\n", ++$test_counter,
735                mysqli_errno($link), mysqli_error($link));
736
737        if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
738            printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
739                ++$test_counter, gettype($new_info), $new_info);
740        mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'DROP SERVER');
741        $info = $new_info;
742    }
743
744    mysqli_get_client_stats_assert_eq('bytes_received_real_data_normal', $info, $expected, $test_counter);
745    mysqli_get_client_stats_assert_eq('bytes_received_real_data_ps', $info, $expected, $test_counter);
746
747    /*
748    We don't test the NDB ones.
749    13.1. Data Definition Statements
750    13.1.3. ALTER LOGFILE GROUP Syntax
751    13.1.4. ALTER TABLESPACE Syntax
752    13.1.9. CREATE LOGFILE GROUP Syntax
753    13.1.10. CREATE TABLESPACE Syntax
754    13.1.15. DROP LOGFILE GROUP Syntax
755    13.1.16. DROP TABLESPACE Syntax
756    */
757
758    //
759    // DML
760    //
761    if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
762        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
763                ++$test_counter, gettype($new_info), $new_info);
764    $info = $new_info;
765
766    if (!mysqli_query($link, "INSERT INTO test(id) VALUES (100)"))
767        printf("[%03d] INSERT failed, [%d] %s\n", ++$test_counter,
768            mysqli_errno($link), mysqli_error($link));
769
770    if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
771        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
772            ++$test_counter, gettype($new_info), $new_info);
773    mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'INSERT');
774    $info = $new_info;
775
776    if (!mysqli_query($link, "UPDATE test SET label ='z' WHERE id = 100"))
777        printf("[%03d] UPDATE failed, [%d] %s\n", ++$test_counter,
778            mysqli_errno($link), mysqli_error($link));
779
780    if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
781        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
782            ++$test_counter, gettype($new_info), $new_info);
783    mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'UPDATE');
784    $info = $new_info;
785
786    if (!mysqli_query($link, "REPLACE INTO test(id, label) VALUES (100, 'b')"))
787        printf("[%03d] INSERT failed, [%d] %s\n", ++$test_counter,
788            mysqli_errno($link), mysqli_error($link));
789
790    if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
791        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
792            ++$test_counter, gettype($new_info), $new_info);
793    mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'REPLACE');
794    $info = $new_info;
795
796    // NOTE: this will NOT update dbl_ddls counter
797    if (!$res = mysqli_query($link, "SELECT id, label FROM test WHERE id = 100"))
798        printf("[%03d] SELECT@dml failed, [%d] %s\n", ++$test_counter,
799            mysqli_errno($link), mysqli_error($link));
800    mysqli_free_result($res);
801
802    if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
803        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
804            ++$test_counter, gettype($new_info), $new_info);
805    mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, $info, $test_counter, 'SELECT@dml');
806    $info = $new_info;
807
808    if (!mysqli_query($link, "DELETE FROM test WHERE id = 100"))
809        printf("[%03d] DELETE failed, [%d] %s\n", ++$test_counter,
810            mysqli_errno($link), mysqli_error($link));
811
812    if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
813        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
814            ++$test_counter, gettype($new_info), $new_info);
815    mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'DELETE');
816    $info = $new_info;
817
818    if (!$res = mysqli_query($link, "TRUNCATE TABLE test"))
819        printf("[%03d] TRUNCATE failed, [%d] %s\n", ++$test_counter,
820            mysqli_errno($link), mysqli_error($link));
821
822    if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
823        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
824            ++$test_counter, gettype($new_info), $new_info);
825    mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'TRUNCATE');
826    $info = $new_info;
827
828
829    $file = tempnam(sys_get_temp_dir(), 'mysqli_test');
830    if ($fp = fopen($file, 'w')) {
831        @fwrite($fp, '1;"a"');
832        fclose($fp);
833        chmod($file, 0644);
834        $sql = sprintf('LOAD DATA LOCAL INFILE "%s" INTO TABLE test', mysqli_real_escape_string($link, $file));
835        if (mysqli_query($link, $sql)) {
836            if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
837                printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
838                    ++$test_counter, gettype($new_info), $new_info);
839            mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, (string)($info['non_result_set_queries'] + 1), $test_counter, 'LOAD DATA LOCAL');
840            $info = $new_info;
841        }
842        unlink($file);
843    }
844
845    mysqli_get_client_stats_assert_eq('bytes_received_real_data_normal', $info, $expected, $test_counter);
846    mysqli_get_client_stats_assert_eq('bytes_received_real_data_ps', $info, $expected, $test_counter);
847
848    /*
849    We skip those:
850    13.2. Data Manipulation Statements
851    13.2.2. DO Syntax
852    13.2.3. HANDLER Syntax
853    13.2.5. LOAD DATA INFILE Syntax
854    */
855    mysqli_query($link, "DELETE FROM test");
856    if (!mysqli_query($link, "INSERT INTO test(id, label) VALUES (1, 'a'), (2, 'b')"))
857        printf("[%03d] Cannot insert new records, [%d] %s\n", ++$test_counter,
858            mysqli_errno($link), mysqli_error($link));
859
860    if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id"))
861        printf("[%03d] Cannot SELECT with mysqli_real_query(), [%d] %s\n", ++$test_counter,
862            mysqli_errno($link), mysqli_error($link));
863
864    if (!is_object($res = mysqli_use_result($link)))
865        printf("[%03d] mysqli_use_result() failed, [%d] %s\n", ++$test_counter,
866            mysqli_errno($link), mysqli_error($link));
867
868    while ($row = mysqli_fetch_assoc($res))
869        ;
870    mysqli_free_result($res);
871    if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
872        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
873            ++$test_counter, gettype($new_info), $new_info);
874    mysqli_get_client_stats_assert_eq('unbuffered_sets', $new_info, (string)($info['unbuffered_sets'] + 1), $test_counter, 'mysqli_use_result()');
875    $info = $new_info;
876
877    if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id"))
878        printf("[%03d] Cannot SELECT with mysqli_real_query() II, [%d] %s\n", ++$test_counter,
879            mysqli_errno($link), mysqli_error($link));
880
881    if (!is_object($res = mysqli_store_result($link)))
882        printf("[%03d] mysqli_use_result() failed, [%d] %s\n", ++$test_counter,
883            mysqli_errno($link), mysqli_error($link));
884
885    while ($row = mysqli_fetch_assoc($res))
886        ;
887    mysqli_free_result($res);
888    if (!is_array($new_info = mysqli_get_client_stats()) || empty($new_info))
889        printf("[%03d] Expecting array/any_non_empty, got %s/%s\n",
890            ++$test_counter, gettype($new_info), $new_info);
891    mysqli_get_client_stats_assert_eq('buffered_sets', $new_info, (string)($info['buffered_sets'] + 1), $test_counter, 'mysqli_use_result()');
892    $info = $new_info;
893
894    mysqli_close($link);
895
896    mysqli_get_client_stats_assert_gt('bytes_received_real_data_normal', $info, $expected, $test_counter);
897    $expected['bytes_received_real_data_normal'] = $info['bytes_received_real_data_normal'];
898    mysqli_get_client_stats_assert_eq('bytes_received_real_data_ps', $info, $expected, $test_counter);
899
900    /*
901    no_index_used
902    bad_index_used
903    flushed_normal_sets
904    flushed_ps_sets
905    explicit_close
906    implicit_close
907    disconnect_close
908    in_middle_of_command_close
909    explicit_free_result
910    implicit_free_result
911    explicit_stmt_close
912    implicit_stmt_close
913    */
914
915    print "done!";
916?>
917--CLEAN--
918<?php
919require_once("connect.inc");
920if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
921   printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
922
923if (!mysqli_query($link, "DROP TABLE IF EXISTS test"))
924	printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link));
925
926if (!mysqli_query($link, "DROP TABLE IF EXISTS non_result_set_queries_test"))
927	printf("[c003] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link));
928
929if (!mysqli_query($link, "DROP TABLE IF EXISTS client_stats_test"))
930	printf("[c004] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link));
931
932if (!mysqli_query($link, "DROP DATABASE IF EXISTS mysqli_get_client_stats_"))
933	printf("[c005] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link));
934
935if (!mysqli_query($link, "DROP DATABASE IF EXISTS mysqli_get_client_stats"))
936	printf("[c006] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link));
937
938if (!mysqli_query($link, "DROP SERVER IF EXISTS myself"))
939	printf("[c007] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link));
940
941mysqli_close($link);
942?>
943--EXPECTF--
944array(163) {
945  ["bytes_sent"]=>
946  string(1) "0"
947  ["bytes_received"]=>
948  string(1) "0"
949  ["packets_sent"]=>
950  string(1) "0"
951  ["packets_received"]=>
952  string(1) "0"
953  ["protocol_overhead_in"]=>
954  string(1) "0"
955  ["protocol_overhead_out"]=>
956  string(1) "0"
957  ["bytes_received_ok_packet"]=>
958  string(1) "0"
959  ["bytes_received_eof_packet"]=>
960  string(1) "0"
961  ["bytes_received_rset_header_packet"]=>
962  string(1) "0"
963  ["bytes_received_rset_field_meta_packet"]=>
964  string(1) "0"
965  ["bytes_received_rset_row_packet"]=>
966  string(1) "0"
967  ["bytes_received_prepare_response_packet"]=>
968  string(1) "0"
969  ["bytes_received_change_user_packet"]=>
970  string(1) "0"
971  ["packets_sent_command"]=>
972  string(1) "0"
973  ["packets_received_ok"]=>
974  string(1) "0"
975  ["packets_received_eof"]=>
976  string(1) "0"
977  ["packets_received_rset_header"]=>
978  string(1) "0"
979  ["packets_received_rset_field_meta"]=>
980  string(1) "0"
981  ["packets_received_rset_row"]=>
982  string(1) "0"
983  ["packets_received_prepare_response"]=>
984  string(1) "0"
985  ["packets_received_change_user"]=>
986  string(1) "0"
987  ["result_set_queries"]=>
988  string(1) "0"
989  ["non_result_set_queries"]=>
990  string(1) "0"
991  ["no_index_used"]=>
992  string(1) "0"
993  ["bad_index_used"]=>
994  string(1) "0"
995  ["slow_queries"]=>
996  string(1) "0"
997  ["buffered_sets"]=>
998  string(1) "0"
999  ["unbuffered_sets"]=>
1000  string(1) "0"
1001  ["ps_buffered_sets"]=>
1002  string(1) "0"
1003  ["ps_unbuffered_sets"]=>
1004  string(1) "0"
1005  ["flushed_normal_sets"]=>
1006  string(1) "0"
1007  ["flushed_ps_sets"]=>
1008  string(1) "0"
1009  ["ps_prepared_never_executed"]=>
1010  string(1) "0"
1011  ["ps_prepared_once_executed"]=>
1012  string(1) "0"
1013  ["rows_fetched_from_server_normal"]=>
1014  string(1) "0"
1015  ["rows_fetched_from_server_ps"]=>
1016  string(1) "0"
1017  ["rows_buffered_from_client_normal"]=>
1018  string(1) "0"
1019  ["rows_buffered_from_client_ps"]=>
1020  string(1) "0"
1021  ["rows_fetched_from_client_normal_buffered"]=>
1022  string(1) "0"
1023  ["rows_fetched_from_client_normal_unbuffered"]=>
1024  string(1) "0"
1025  ["rows_fetched_from_client_ps_buffered"]=>
1026  string(1) "0"
1027  ["rows_fetched_from_client_ps_unbuffered"]=>
1028  string(1) "0"
1029  ["rows_fetched_from_client_ps_cursor"]=>
1030  string(1) "0"
1031  ["rows_affected_normal"]=>
1032  string(1) "0"
1033  ["rows_affected_ps"]=>
1034  string(1) "0"
1035  ["rows_skipped_normal"]=>
1036  string(1) "0"
1037  ["rows_skipped_ps"]=>
1038  string(1) "0"
1039  ["copy_on_write_saved"]=>
1040  string(1) "0"
1041  ["copy_on_write_performed"]=>
1042  string(1) "0"
1043  ["command_buffer_too_small"]=>
1044  string(1) "0"
1045  ["connect_success"]=>
1046  string(1) "0"
1047  ["connect_failure"]=>
1048  string(1) "0"
1049  ["connection_reused"]=>
1050  string(1) "0"
1051  ["reconnect"]=>
1052  string(1) "0"
1053  ["pconnect_success"]=>
1054  string(1) "0"
1055  ["active_connections"]=>
1056  string(1) "0"
1057  ["active_persistent_connections"]=>
1058  string(1) "0"
1059  ["explicit_close"]=>
1060  string(1) "0"
1061  ["implicit_close"]=>
1062  string(1) "0"
1063  ["disconnect_close"]=>
1064  string(1) "0"
1065  ["in_middle_of_command_close"]=>
1066  string(1) "0"
1067  ["explicit_free_result"]=>
1068  string(1) "0"
1069  ["implicit_free_result"]=>
1070  string(1) "0"
1071  ["explicit_stmt_close"]=>
1072  string(1) "0"
1073  ["implicit_stmt_close"]=>
1074  string(1) "0"
1075  ["mem_emalloc_count"]=>
1076  string(1) "0"
1077  ["mem_emalloc_amount"]=>
1078  string(1) "0"
1079  ["mem_ecalloc_count"]=>
1080  string(1) "0"
1081  ["mem_ecalloc_amount"]=>
1082  string(1) "0"
1083  ["mem_erealloc_count"]=>
1084  string(1) "0"
1085  ["mem_erealloc_amount"]=>
1086  string(1) "0"
1087  ["mem_efree_count"]=>
1088  string(1) "0"
1089  ["mem_efree_amount"]=>
1090  string(1) "0"
1091  ["mem_malloc_count"]=>
1092  string(1) "0"
1093  ["mem_malloc_amount"]=>
1094  string(1) "0"
1095  ["mem_calloc_count"]=>
1096  string(%d) "%d"
1097  ["mem_calloc_amount"]=>
1098  string(%d) "%d"
1099  ["mem_realloc_count"]=>
1100  string(1) "0"
1101  ["mem_realloc_amount"]=>
1102  string(1) "0"
1103  ["mem_free_count"]=>
1104  string(1) "0"
1105  ["mem_free_amount"]=>
1106  string(1) "0"
1107  ["mem_estrndup_count"]=>
1108  string(1) "0"
1109  ["mem_strndup_count"]=>
1110  string(1) "0"
1111  ["mem_estrdup_count"]=>
1112  string(1) "0"
1113  ["mem_strdup_count"]=>
1114  string(1) "0"
1115  ["mem_edupl_count"]=>
1116  string(1) "0"
1117  ["mem_dupl_count"]=>
1118  string(1) "0"
1119  ["proto_text_fetched_null"]=>
1120  string(1) "0"
1121  ["proto_text_fetched_bit"]=>
1122  string(1) "0"
1123  ["proto_text_fetched_tinyint"]=>
1124  string(1) "0"
1125  ["proto_text_fetched_short"]=>
1126  string(1) "0"
1127  ["proto_text_fetched_int24"]=>
1128  string(1) "0"
1129  ["proto_text_fetched_int"]=>
1130  string(1) "0"
1131  ["proto_text_fetched_bigint"]=>
1132  string(1) "0"
1133  ["proto_text_fetched_decimal"]=>
1134  string(1) "0"
1135  ["proto_text_fetched_float"]=>
1136  string(1) "0"
1137  ["proto_text_fetched_double"]=>
1138  string(1) "0"
1139  ["proto_text_fetched_date"]=>
1140  string(1) "0"
1141  ["proto_text_fetched_year"]=>
1142  string(1) "0"
1143  ["proto_text_fetched_time"]=>
1144  string(1) "0"
1145  ["proto_text_fetched_datetime"]=>
1146  string(1) "0"
1147  ["proto_text_fetched_timestamp"]=>
1148  string(1) "0"
1149  ["proto_text_fetched_string"]=>
1150  string(1) "0"
1151  ["proto_text_fetched_blob"]=>
1152  string(1) "0"
1153  ["proto_text_fetched_enum"]=>
1154  string(1) "0"
1155  ["proto_text_fetched_set"]=>
1156  string(1) "0"
1157  ["proto_text_fetched_geometry"]=>
1158  string(1) "0"
1159  ["proto_text_fetched_other"]=>
1160  string(1) "0"
1161  ["proto_binary_fetched_null"]=>
1162  string(1) "0"
1163  ["proto_binary_fetched_bit"]=>
1164  string(1) "0"
1165  ["proto_binary_fetched_tinyint"]=>
1166  string(1) "0"
1167  ["proto_binary_fetched_short"]=>
1168  string(1) "0"
1169  ["proto_binary_fetched_int24"]=>
1170  string(1) "0"
1171  ["proto_binary_fetched_int"]=>
1172  string(1) "0"
1173  ["proto_binary_fetched_bigint"]=>
1174  string(1) "0"
1175  ["proto_binary_fetched_decimal"]=>
1176  string(1) "0"
1177  ["proto_binary_fetched_float"]=>
1178  string(1) "0"
1179  ["proto_binary_fetched_double"]=>
1180  string(1) "0"
1181  ["proto_binary_fetched_date"]=>
1182  string(1) "0"
1183  ["proto_binary_fetched_year"]=>
1184  string(1) "0"
1185  ["proto_binary_fetched_time"]=>
1186  string(1) "0"
1187  ["proto_binary_fetched_datetime"]=>
1188  string(1) "0"
1189  ["proto_binary_fetched_timestamp"]=>
1190  string(1) "0"
1191  ["proto_binary_fetched_string"]=>
1192  string(1) "0"
1193  ["proto_binary_fetched_json"]=>
1194  string(1) "0"
1195  ["proto_binary_fetched_blob"]=>
1196  string(1) "0"
1197  ["proto_binary_fetched_enum"]=>
1198  string(1) "0"
1199  ["proto_binary_fetched_set"]=>
1200  string(1) "0"
1201  ["proto_binary_fetched_geometry"]=>
1202  string(1) "0"
1203  ["proto_binary_fetched_other"]=>
1204  string(1) "0"
1205  ["init_command_executed_count"]=>
1206  string(1) "0"
1207  ["init_command_failed_count"]=>
1208  string(1) "0"
1209  ["com_quit"]=>
1210  string(1) "0"
1211  ["com_init_db"]=>
1212  string(1) "0"
1213  ["com_query"]=>
1214  string(1) "0"
1215  ["com_field_list"]=>
1216  string(1) "0"
1217  ["com_create_db"]=>
1218  string(1) "0"
1219  ["com_drop_db"]=>
1220  string(1) "0"
1221  ["com_refresh"]=>
1222  string(1) "0"
1223  ["com_shutdown"]=>
1224  string(1) "0"
1225  ["com_statistics"]=>
1226  string(1) "0"
1227  ["com_process_info"]=>
1228  string(1) "0"
1229  ["com_connect"]=>
1230  string(1) "0"
1231  ["com_process_kill"]=>
1232  string(1) "0"
1233  ["com_debug"]=>
1234  string(1) "0"
1235  ["com_ping"]=>
1236  string(1) "0"
1237  ["com_time"]=>
1238  string(1) "0"
1239  ["com_delayed_insert"]=>
1240  string(1) "0"
1241  ["com_change_user"]=>
1242  string(1) "0"
1243  ["com_binlog_dump"]=>
1244  string(1) "0"
1245  ["com_table_dump"]=>
1246  string(1) "0"
1247  ["com_connect_out"]=>
1248  string(1) "0"
1249  ["com_register_slave"]=>
1250  string(1) "0"
1251  ["com_stmt_prepare"]=>
1252  string(1) "0"
1253  ["com_stmt_execute"]=>
1254  string(1) "0"
1255  ["com_stmt_send_long_data"]=>
1256  string(1) "0"
1257  ["com_stmt_close"]=>
1258  string(1) "0"
1259  ["com_stmt_reset"]=>
1260  string(1) "0"
1261  ["com_stmt_set_option"]=>
1262  string(1) "0"
1263  ["com_stmt_fetch"]=>
1264  string(1) "0"
1265  ["com_deamon"]=>
1266  string(1) "0"
1267  ["bytes_received_real_data_normal"]=>
1268  string(1) "0"
1269  ["bytes_received_real_data_ps"]=>
1270  string(1) "0"
1271}
1272Testing buffered normal...
1273Testing buffered normal... - SELECT id, label FROM test
1274Testing unbuffered normal...
1275Testing unbuffered normal... - SELECT id, label FROM test, not all fetched
1276Testing if implicit fetching and cleaning happens...
1277Testing buffered Prepared Statements...
1278Testing buffered Prepared Statements... - fetching all
1279Testing buffered Prepared Statements... - fetching all but one
1280Testing unbuffered Prepared Statements... - fetching all
1281Testing unbuffered Prepared Statements... - fetching all but one
1282... done with fetch statistics
1283done!
1284