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