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