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