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