1--TEST--
2mysqli_store_result()
3--EXTENSIONS--
4mysqli
5--SKIPIF--
6<?php
7require_once('skipifconnectfailure.inc');
8?>
9--INI--
10mysqlnd.debug="d:t:O,{TMP}/mysqlnd.trace"
11mysqlnd.net_read_buffer_size=1
12mysqlnd.mempool_default_size=1
13mysqlnd.fetch_data_copy=0
14--FILE--
15<?php
16    require_once("connect.inc");
17
18    $tmp    = NULL;
19    $link   = NULL;
20
21    require('table.inc');
22
23    if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id"))
24        printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
25
26    if (!is_object($res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA)))
27        printf("[004] Expecting object, got %s/%s. [%d] %s\n",
28            gettype($res), $res, mysqli_errno($link), mysqli_error($link));
29
30    if (true !== ($tmp = mysqli_data_seek($res, 2)))
31        printf("[005] Expecting boolean/true, got %s/%s. [%d] %s\n",
32            gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link));
33
34    var_dump($res->fetch_assoc());
35
36    if (true !== ($tmp = mysqli_data_seek($res, 0)))
37        printf("[006] Expecting boolean/true, got %s/%s. [%d] %s\n",
38            gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link));
39
40    while ($row = $res->fetch_assoc()) {
41        printf("id = %d, label = %s\n", $row['id'], $row['label']);
42    }
43
44    mysqli_free_result($res);
45    mysqli_close($link);
46
47    if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
48        printf("[007] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
49            $host, $user, $db, $port, $socket);
50    }
51
52
53    if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id"))
54        printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
55
56    if (!is_object($res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA)))
57        printf("[009] Expecting object, got %s/%s. [%d] %s\n",
58            gettype($res), $res, mysqli_errno($link), mysqli_error($link));
59
60    $no_result = 0;
61    for ($i = 0; $i < 1000; $i++) {
62        $idx = mt_rand(-100, 100);
63        try {
64            if (true === @mysqli_data_seek($res, $idx)) {
65                $row = $res->fetch_assoc();
66                if (!isset($row['id']) || !isset($row['label'])) {
67                    printf("[010] Brute force seek %d returned %d\n", $idx, var_export($row, true));
68                }
69            } else {
70                $no_result++;
71            }
72        } catch (\ValueError $e) {
73            $no_result++;
74        }
75    }
76    printf("No result: %d\n", $no_result);
77
78    /* implicit free, implicit store */
79    /* meta and fetch lengths code */
80    if (!$res = mysqli_query($link, "SELECT CONCAT(id, id) AS _c, label FROM test ORDER BY id DESC LIMIT 2"))
81        printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
82
83    printf("Default\n");
84    var_dump(mysqli_fetch_lengths($res));
85    $fields = $res->fetch_fields();
86    while ($row = $res->fetch_assoc()) {
87        var_dump(mysqli_fetch_lengths($res));
88    }
89    var_dump(mysqli_fetch_lengths($res));
90
91    if (!$res = mysqli_real_query($link, "SELECT CONCAT(id, id) AS _c, label FROM test ORDER BY id DESC LIMIT 2"))
92        printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
93
94    if (!is_object($res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA)))
95        printf("[013] Expecting object, got %s/%s. [%d] %s\n",
96            gettype($res), $res, mysqli_errno($link), mysqli_error($link));
97
98    printf("Copy\n");
99    var_dump(mysqli_fetch_lengths($res));
100    $fields_copy = $res->fetch_fields();
101    while ($row = $res->fetch_assoc()) {
102        var_dump(mysqli_fetch_lengths($res));
103    }
104    var_dump(mysqli_fetch_lengths($res));
105
106    /* There's no need for in-depth testing here. If you want in-depth switch mysqlnd
107    globally to copy mode and run all the tests */
108    foreach ($fields as $k => $field_info) {
109        if ($fields_copy[$k] != $field_info) {
110            printf("[014] Metadata seems to differ, dumping\n");
111            var_dump($field_info);
112            var_dump($fields_copy[$k]);
113        }
114    }
115
116    /* fetch all */
117
118    if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id DESC LIMIT 2"))
119        printf("[015] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
120
121    if (!is_object($res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA)))
122        printf("[016] Expecting object, got %s/%s. [%d] %s\n",
123            gettype($res), $res, mysqli_errno($link), mysqli_error($link));
124
125    foreach (mysqli_fetch_all($res, MYSQLI_ASSOC) as $row) {
126        printf("id = %d label = %s\n", $row['id'], $row['label']);
127    }
128
129    if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id DESC LIMIT 2"))
130        printf("[017] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
131
132    if (!is_object($res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA)))
133        printf("[018] Expecting object, got %s/%s. [%d] %s\n",
134            gettype($res), $res, mysqli_errno($link), mysqli_error($link));
135
136    /* provoke out of sync */
137    if (!mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id DESC LIMIT 2"))
138        printf("[019] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
139
140    var_dump($res->fetch_assoc());
141
142    if (!$res = mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id ASC LIMIT 2"))
143        printf("[020] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
144
145    if (!is_object($res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA)))
146        printf("[021] Expecting object, got %s/%s. [%d] %s\n",
147            gettype($res), $res, mysqli_errno($link), mysqli_error($link));
148
149    /* user conn killed, res associated with conn, fetch from res */
150    unset($link);
151    var_dump($res->fetch_assoc());
152
153
154    if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
155        printf("[022] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
156            $host, $user, $db, $port, $socket);
157    }
158
159    if (!$res = mysqli_real_query($link, "INSERT INTO test(id, label) VALUES (100, 'z')"))
160        printf("[023] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
161
162    mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA);
163
164    if (mysqli_get_server_version($link) > 50000) {
165        // let's try to play with stored procedures
166        mysqli_real_query($link, 'DROP PROCEDURE IF EXISTS p');
167        if (mysqli_real_query($link, 'CREATE PROCEDURE p(OUT ver_param VARCHAR(25)) READS SQL DATA BEGIN SELECT id FROM test WHERE id >= 100 ORDER BY id; SELECT id + 1, label FROM test WHERE id > 0 AND id < 3 ORDER BY id; SELECT VERSION() INTO ver_param;
168END;')) {
169            mysqli_multi_query($link, "CALL p(@version)");
170            do {
171                if ($res = $link->store_result(MYSQLI_STORE_RESULT_COPY_DATA)) {
172                    printf("---\n");
173                    var_dump($res->fetch_all());
174                    $res->free();
175                } else {
176                    if ($link->errno) {
177                        echo "Store failed: (" . $link->errno . ") " . $link->error;
178                    }
179                }
180            } while ($link->more_results() && $link->next_result());
181            mysqli_real_query($link, 'SELECT @version AS p_version');
182            $res = mysqli_store_result($link, MYSQLI_STORE_RESULT_COPY_DATA);
183
184            $tmp = mysqli_fetch_assoc($res);
185            if (!is_array($tmp) || empty($tmp) || !isset($tmp['p_version']) || ('' == $tmp['p_version'])) {
186                printf("[024] Expecting array [%d] %s\n", mysqli_errno($link), mysqli_error($link));
187                var_dump($tmp);
188            }
189
190            mysqli_free_result($res);
191        } else {
192                printf("[025] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
193        }
194    }
195
196    print "done!";
197?>
198--CLEAN--
199<?php
200	require_once("clean_table.inc");
201?>
202--EXPECTF--
203array(2) {
204  ["id"]=>
205  string(1) "3"
206  ["label"]=>
207  string(1) "c"
208}
209id = 1, label = a
210id = 2, label = b
211id = 3, label = c
212id = 4, label = d
213id = 5, label = e
214id = 6, label = f
215No result: %d
216Default
217bool(false)
218array(2) {
219  [0]=>
220  int(2)
221  [1]=>
222  int(1)
223}
224array(2) {
225  [0]=>
226  int(2)
227  [1]=>
228  int(1)
229}
230bool(false)
231Copy
232bool(false)
233array(2) {
234  [0]=>
235  int(2)
236  [1]=>
237  int(1)
238}
239array(2) {
240  [0]=>
241  int(2)
242  [1]=>
243  int(1)
244}
245bool(false)
246id = 6 label = f
247id = 5 label = e
248array(2) {
249  ["id"]=>
250  string(1) "6"
251  ["label"]=>
252  string(1) "f"
253}
254[020] [2014] %s
255array(2) {
256  ["id"]=>
257  string(1) "6"
258  ["label"]=>
259  string(1) "f"
260}
261---
262array(1) {
263  [0]=>
264  array(1) {
265    [0]=>
266    string(3) "100"
267  }
268}
269---
270array(2) {
271  [0]=>
272  array(2) {
273    [0]=>
274    string(1) "2"
275    [1]=>
276    string(1) "a"
277  }
278  [1]=>
279  array(2) {
280    [0]=>
281    string(1) "3"
282    [1]=>
283    string(1) "b"
284  }
285}
286done!
287