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 (false !== ($tmp = @mysqli_stmt_attr_set($stmt, 0, 0)))
45        printf("[005] Expecting false, 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--EXPECT--
277done!
278