1--TEST--
2mysqli_fetch_array() - large packages (to test compression)
3--SKIPIF--
4<?php
5require_once('skipif.inc');
6require_once('skipifconnectfailure.inc');
7?>
8--FILE--
9<?php
10	require_once("connect.inc");
11
12	function mysqli_fetch_array_large($offset, $link, $package_size) {
13
14		/* we are aiming for maximum compression to test MYSQLI_CLIENT_COMPRESS */
15		$random_char = str_repeat('a', 255);
16		$sql = "INSERT INTO test(label) VALUES ";
17
18		while (strlen($sql) < ($package_size - 259))
19			$sql .= sprintf("('%s'), ", $random_char);
20
21		$sql = substr($sql, 0, -2);
22		$len = strlen($sql);
23		assert($len < $package_size);
24
25		if (!@mysqli_query($link, $sql)) {
26			if (1153 == mysqli_errno($link) || 2006 == mysqli_errno($link) || stristr(mysqli_error($link), 'max_allowed_packet'))
27				/*
28					myslqnd - [1153] Got a packet bigger than 'max_allowed_packet' bytes
29					libmysql -[2006] MySQL server has gone away
30				*/
31				return false;
32
33			printf("[%03d + 1] len = %d, [%d] %s\n", $offset, $len, mysqli_errno($link), mysqli_error($link));
34			return false;
35		}
36
37		/* buffered result set - let's hope we do not run into PHP memory limit... */
38		if (!$res = mysqli_query($link, "SELECT id, label FROM test")) {
39			printf("[%03d + 2] len = %d, [%d] %s\n", $offset, $len, mysqli_errno($link), mysqli_error($link));
40			return false;
41		}
42
43		while ($row = mysqli_fetch_assoc($res)) {
44			if ($row['label'] != $random_char) {
45				printf("[%03d + 3] Wrong results - expecting '%s' got '%s', len = %d, [%d] %s\n",
46					$offset, $random_char, $row['label'], $len, mysqli_errno($link), mysqli_error($link));
47				return false;
48			}
49		}
50		mysqli_free_result($res);
51
52		if (!$stmt = mysqli_prepare($link, "SELECT id, label FROM test")) {
53			printf("[%03d + 4] len = %d, [%d] %s\n", $offset, $len, mysqli_errno($link), mysqli_error($link));
54			return false;
55		}
56
57		/* unbuffered result set */
58		if (!mysqli_stmt_execute($stmt)) {
59			printf("[%03d + 5] len = %d, [%d] %s, [%d] %s\n", $offset, $len, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt), mysqli_errno($link), mysqli_error($link));
60			return false;
61		}
62
63		$id = $label = NULL;
64		if (!mysqli_stmt_bind_result($stmt, $id, $label)) {
65			printf("[%03d + 6] len = %d, [%d] %s, [%d] %s\n", $offset, $len, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt), mysqli_errno($link), mysqli_error($link));
66			return false;
67		}
68
69		while (mysqli_stmt_fetch($stmt)) {
70			if ($label != $random_char) {
71				printf("[%03d + 7] Wrong results - expecting '%s' got '%s', len = %d, [%d] %s\n",
72					$offset, $random_char, $label, $len, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
73				return false;
74			}
75		}
76
77		mysqli_stmt_free_result($stmt);
78		mysqli_stmt_close($stmt);
79
80		return true;
81	}
82
83	function parse_memory_limit($limit) {
84
85		$val = trim($limit);
86		$last = strtolower($val[strlen($val)-1]);
87
88		switch($last) {
89				// The 'G' modifier is available since PHP 5.1.0
90				case 'g':
91					$val *= 1024;
92				case 'm':
93					$val *= 1024;
94				case 'k':
95					$val *= 1024;
96				default:
97					break;
98    	}
99			return $val;
100	}
101
102
103	function test_fetch($host, $user, $passwd, $db, $port, $socket, $engine, $flags = null) {
104
105		$link = mysqli_init();
106		if (!my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket, $flags)) {
107			printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
108			$host, $user, $db, $port, $socket);
109			return false;
110		}
111
112		if (!mysqli_query($link, "DROP TABLE IF EXISTS test") ||
113			!mysqli_query($link, sprintf("CREATE TABLE test(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, label VARCHAR(255)) ENGINE = %s", $engine))) {
114			printf("[002] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
115			return false;
116		}
117
118		$package_size = 524288;
119		$offset = 3;
120		$limit = (ini_get('memory_limit') > 0) ? parse_memory_limit(ini_get('memory_limit')) : pow(2, 32);
121
122		/* try to respect php.ini but make run time a soft limit */
123		$max_runtime = (ini_get('max_execution_time') > 0) ? ini_get('max_execution_time') : 30;
124		set_time_limit(0);
125
126		do {
127			if ($package_size > $limit) {
128				printf("stop: memory limit - %s vs. %s\n", $package_size, $limit);
129				break;
130			}
131
132			$start = microtime(true);
133			if (!mysqli_fetch_array_large($offset++, $link, $package_size)) {
134				printf("stop: packet size - %d\n", $package_size);
135				break;
136			}
137
138			$duration = microtime(true) - $start;
139			$max_runtime -= $duration;
140			if ($max_runtime < ($duration * 3)) {
141				/* likely the next iteration will not be within max_execution_time */
142				printf("stop: time limit - %2.2fs\n", $max_runtime);
143				break;
144			}
145
146			$package_size += $package_size;
147
148		} while (true);
149
150
151		mysqli_close($link);
152		return true;
153	}
154
155
156	test_fetch($host, $user, $passwd, $db, $port, $socket, $engine, null);
157	test_fetch($host, $user, $passwd, $db, $port, $socket, $engine, MYSQLI_CLIENT_COMPRESS);
158	print "done!";
159?>
160--CLEAN--
161<?php
162	require_once("clean_table.inc");
163?>
164--EXPECTF--
165stop: %s
166stop: %s
167done!