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