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