1--TEST--
2mysqli_stmt_attr_set() - mysqlnd does not check for invalid codes
3--SKIPIF--
4<?php
5require_once('skipif.inc');
6require_once('skipifemb.inc');
7require_once('skipifconnectfailure.inc');
8?>
9--FILE--
10<?php
11	require_once("connect.inc");
12
13	$tmp    = NULL;
14	$link   = NULL;
15
16	if (!is_null($tmp = @mysqli_stmt_attr_set()))
17		printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
18
19	if (!is_null($tmp = @mysqli_stmt_attr_set($link)))
20		printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
21
22	if (!is_null($tmp = @mysqli_stmt_attr_set($link, $link)))
23		printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
24
25	if (!is_null($tmp = @mysqli_stmt_attr_set($link, $link, $link)))
26		printf("[004] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
27
28	require('table.inc');
29
30	$valid_attr = array(MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH);
31	if ((mysqli_get_client_version() > 50003) || $IS_MYSQLND) {
32		$valid_attr[] = MYSQLI_STMT_ATTR_CURSOR_TYPE;
33		$valid_attr[] =	MYSQLI_CURSOR_TYPE_NO_CURSOR;
34		$valid_attr[] =	MYSQLI_CURSOR_TYPE_READ_ONLY;
35		$valid_attr[] =	MYSQLI_CURSOR_TYPE_FOR_UPDATE;
36		$valid_attr[] =	MYSQLI_CURSOR_TYPE_SCROLLABLE;
37	}
38
39	if ((mysqli_get_client_version() > 50007) || $IS_MYSQLND)
40		$valid_attr[] = MYSQLI_STMT_ATTR_PREFETCH_ROWS;
41
42
43	$stmt = mysqli_stmt_init($link);
44	if (!is_null($tmp = @mysqli_stmt_attr_set($stmt, 0, 0)))
45		printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
46
47	$stmt->prepare("SELECT * FROM test");
48
49	mt_srand(microtime(true));
50
51	for ($i = -100; $i < 1000; $i++) {
52		if (in_array($i, $valid_attr))
53			continue;
54		$invalid_attr = $i;
55		if (false !== ($tmp = @mysqli_stmt_attr_set($stmt, $invalid_attr, 0))) {
56			printf("[006a] Expecting boolean/false for attribute %d, got %s/%s\n", $invalid_attr, gettype($tmp), $tmp);
57		}
58	}
59
60	for ($i = 0; $i < 2; $i++) {
61		do {
62			$invalid_attr = mt_rand(-1 * (min(4294967296, PHP_INT_MAX) + 1), min(4294967296, PHP_INT_MAX));
63		} while (in_array($invalid_attr, $valid_attr));
64		if (false !== ($tmp = @mysqli_stmt_attr_set($stmt, $invalid_attr, 0))) {
65			printf("[006b] Expecting boolean/false for attribute %d, got %s/%s\n", $invalid_attr, gettype($tmp), $tmp);
66		}
67	}
68	$stmt->close();
69
70	//
71	// MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH
72	//
73
74
75	// expecting max_length not to be set and be 0 in all cases
76	$stmt = mysqli_stmt_init($link);
77	$stmt->prepare("SELECT label FROM test");
78	$stmt->execute();
79	$stmt->store_result();
80	$res = $stmt->result_metadata();
81	$fields = $res->fetch_fields();
82	$max_lengths = array();
83	foreach ($fields as $k => $meta) {
84		$max_lengths[$meta->name] = $meta->max_length;
85		if ($meta->max_length !== 0)
86			printf("[007] max_length should be not set (= 0), got %s for field %s\n", $meta->max_length, $meta->name);
87	}
88	$res->close();
89	$stmt->close();
90
91	// expecting max_length to _be_ set
92	$stmt = mysqli_stmt_init($link);
93	$stmt->prepare("SELECT label FROM test");
94	$stmt->attr_set(MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, 1);
95	$res = $stmt->attr_get(MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH);
96	if ($res !== 1)
97		printf("[007.1] max_length should be 1, got %s\n", $res);
98	$stmt->execute();
99	$stmt->store_result();
100	$res = $stmt->result_metadata();
101	$fields = $res->fetch_fields();
102	$max_lengths = array();
103	foreach ($fields as $k => $meta) {
104		$max_lengths[$meta->name] = $meta->max_length;
105		if ($meta->max_length === 0)
106			printf("[008] max_length should be set (!= 0), got %s for field %s\n", $meta->max_length, $meta->name);
107	}
108	$res->close();
109	$stmt->close();
110
111	// expecting max_length not to be set
112	$stmt = mysqli_stmt_init($link);
113	$stmt->prepare("SELECT label FROM test");
114	$stmt->attr_set(MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, 0);
115	$res = $stmt->attr_get(MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH);
116	if ($res !== 0)
117		printf("[008.1] max_length should be 0, got %s\n", $res);
118	$stmt->execute();
119	$stmt->store_result();
120	$res = $stmt->result_metadata();
121	$fields = $res->fetch_fields();
122	$max_lengths = array();
123	foreach ($fields as $k => $meta) {
124		$max_lengths[$meta->name] = $meta->max_length;
125		if ($meta->max_length !== 0)
126			printf("[009] max_length should not be set (= 0), got %s for field %s\n", $meta->max_length, $meta->name);
127	}
128	$res->close();
129	$stmt->close();
130
131	//
132	// Cursors
133	//
134
135	if (mysqli_get_client_version() > 50003) {
136
137		$cursor_types = array(
138			MYSQLI_CURSOR_TYPE_NO_CURSOR,
139			MYSQLI_CURSOR_TYPE_READ_ONLY,
140			MYSQLI_CURSOR_TYPE_FOR_UPDATE,
141			MYSQLI_CURSOR_TYPE_SCROLLABLE
142		);
143		do {
144			$invalid_cursor_type = mt_rand(-1000, 1000);
145		} while (in_array($invalid_cursor_type, $cursor_types));
146
147		$stmt = mysqli_stmt_init($link);
148		$stmt->prepare("SELECT id, label FROM test");
149
150		if (false !== ($tmp = @$stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, $invalid_cursor_type)))
151			printf("[010] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
152
153		if (false !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_FOR_UPDATE)))
154			printf("[011] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
155
156		if (false !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_SCROLLABLE)))
157			printf("[012] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
158
159		if (true !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_NO_CURSOR)))
160			printf("[013] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
161
162		if (true !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_READ_ONLY)))
163			printf("[014] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
164
165		$stmt->close();
166
167		$stmt = mysqli_stmt_init($link);
168		$stmt->prepare("SELECT id, label FROM test");
169		$stmt->execute();
170		$id = $label = NULL;
171		$stmt->bind_result($id, $label);
172		$results = array();
173		while ($stmt->fetch())
174			$results[$id] = $label;
175		$stmt->close();
176		if (empty($results))
177			printf("[015] Results should not be empty, subsequent tests will probably fail!\n");
178
179		$stmt = mysqli_stmt_init($link);
180		$stmt->prepare("SELECT id, label FROM test");
181		if (true !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_NO_CURSOR)))
182			printf("[016] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
183		$stmt->execute();
184		$id = $label = NULL;
185		$stmt->bind_result($id, $label);
186		$results2 = array();
187		while ($stmt->fetch())
188			$results2[$id] = $label;
189		$stmt->close();
190		if ($results != $results2) {
191			printf("[017] Results should not differ. Dumping both result sets.\n");
192			var_dump($results);
193			var_dump($results2);
194		}
195
196		$stmt = mysqli_stmt_init($link);
197		$stmt->prepare("SELECT id, label FROM test");
198		if (true !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_READ_ONLY)))
199			printf("[018] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
200		$stmt->execute();
201		$id = $label = NULL;
202		$stmt->bind_result($id, $label);
203		$results2 = array();
204		while ($stmt->fetch())
205			$results2[$id] = $label;
206		$stmt->close();
207		if ($results != $results2) {
208			printf("[019] Results should not differ. Dumping both result sets.\n");
209			var_dump($results);
210			var_dump($results2);
211		}
212
213	}
214
215
216	//
217	// MYSQLI_STMT_ATTR_PREFETCH_ROWS
218	//
219
220	if (mysqli_get_client_version() > 50007) {
221
222		$stmt = mysqli_stmt_init($link);
223		$stmt->prepare("SELECT id, label FROM test");
224		if (true !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_PREFETCH_ROWS, 1)))
225			printf("[020] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
226		$stmt->execute();
227		$id = $label = NULL;
228		$stmt->bind_result($id, $label);
229		$results = array();
230		while ($stmt->fetch())
231			$results[$id] = $label;
232		$stmt->close();
233		if (empty($results))
234			printf("[021] Results should not be empty, subsequent tests will probably fail!\n");
235
236		/* prefetch is not supported
237		$stmt = mysqli_stmt_init($link);
238		$stmt->prepare("SELECT label FROM test");
239		if (false !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_PREFETCH_ROWS, -1)))
240			printf("[022] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
241		$stmt->close();
242
243		$stmt = mysqli_stmt_init($link);
244		$stmt->prepare("SELECT label FROM test");
245		if (true !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_PREFETCH_ROWS, PHP_INT_MAX)))
246				printf("[023] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
247		$stmt->close();
248
249		$stmt = mysqli_stmt_init($link);
250		$stmt->prepare("SELECT id, label FROM test");
251		if (true !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_PREFETCH_ROWS, 2)))
252			printf("[024] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp);
253		$stmt->execute();
254		$id = $label = NULL;
255		$stmt->bind_result($id, $label);
256		$results2 = array();
257		while ($stmt->fetch())
258			$results2[$id] = $label;
259		$stmt->close();
260		if ($results != $results2) {
261			printf("[025] Results should not differ. Dumping both result sets.\n");
262			var_dump($results);
263			var_dump($results2);
264		}
265		*/
266
267	}
268
269	mysqli_close($link);
270	print "done!";
271?>
272--CLEAN--
273<?php
274	require_once("clean_table.inc");
275?>
276--EXPECTF--
277done!
278