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