1--TEST--
2mysqli_stmt_result_metadata() - non SELECT statements
3--EXTENSIONS--
4mysqli
5--SKIPIF--
6<?php
7require_once 'skipifconnectfailure.inc';
8
9die("skip Check again when the Klingons visit earth - http://bugs.mysql.com/bug.php?id=42490");
10?>
11--FILE--
12<?php
13    require 'table.inc';
14
15    function testStatement($offset, $link, $sql, $expected_lib, $expected_mysqlnd, $check_mysqlnd, $compare) {
16
17        if (!$stmt = mysqli_stmt_init($link)) {
18            printf("[%04d - %s] [%d] %s\n",
19                $offset, $sql,
20                mysqli_errno($link), mysqli_error($link));
21            return false;
22        }
23
24        if (!@mysqli_stmt_prepare($stmt, $sql)) {
25            /* Not all server versions will support all statements */
26            /* Failing to prepare is OK */
27            return true;
28        }
29
30        if (empty($expected_lib) && (false !== $res)) {
31            printf("[%04d - %s] No metadata expected\n",
32                $offset + 1, $sql);
33            return false;
34        } else if (!empty($expected_lib) && (false == $res)) {
35            printf("[%04d - %s] Metadata expected\n",
36                $offset + 2, $sql);
37            return false;
38        }
39        if (!empty($expected_lib)) {
40            if (!is_object($res)) {
41                printf("[%04d - %s] [%d] %s\n",
42                    $offset + 3, $sql,
43                    mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
44                return false;
45            }
46            if (get_class($res) != 'mysqli_result') {
47                printf("[%04d - %s] Expecting object/mysqli_result got object/%s\n",
48                    $offset + 4, $sql, get_class($res));
49                return false;
50            }
51
52            $meta = array(
53                'num_fields'		=> mysqli_num_fields($res),
54                'fetch_field'		=> mysqli_fetch_field($res),
55                'fetch_field_direct0'	=> mysqli_fetch_field_direct($res, 0),
56                'fetch_field_direct1'	=> @mysqli_fetch_field_direct($res, 1),
57                'fetch_fields'		=> count(mysqli_fetch_fields($res)),
58                'field_count'		=> $res->field_count,
59                'field_seek-1'		=> @mysqli_field_seek($res, -1),
60                'field_seek0'		=> mysqli_field_seek($res, 0),
61                'field_tell'		=> mysqli_field_tell($res),
62            );
63            if (is_object($meta['fetch_field'])) {
64                $meta['fetch_field']->charsetnr	= 'ignore';
65                $meta['fetch_field']->flags	= 'ignore';
66            }
67            if (is_object($meta['fetch_field_direct0'])) {
68                $meta['fetch_field_direct0']->charsetnr	= 'ignore';
69                $meta['fetch_field_direct0']->flags	= 'ignore';
70            }
71            if (is_object($meta['fetch_field_direct1'])) {
72                $meta['fetch_field_direct1']->charsetnr	= 'ignore';
73                $meta['fetch_field_direct1']->flags	= 'ignore';
74            }
75            mysqli_free_result($res);
76
77            if ($meta != $expected_lib) {
78                printf("[%04d - %s] Metadata differs from expected values\n",
79                    $offset + 5, $sql);
80                var_dump($meta);
81                var_dump($expected_lib);
82                return false;
83            }
84        }
85
86        if (function_exists('mysqli_stmt_get_result')) {
87            /* mysqlnd only */
88            if (!mysqli_stmt_execute($stmt)) {
89                printf("[%04d - %s] [%d] %s\n",
90                    $offset + 6, $sql,
91                    mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
92                return false;
93            }
94
95            $res = mysqli_stmt_get_result($stmt);
96            if (false === $res && !empty($expected_mysqlnd)) {
97                printf("[%04d - %s] Expecting resultset [%d] %s\n",
98                    $offset + 7, $sql,
99                    mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
100                return false;
101            } else if (empty($expected_mysqlnd) && false !== $res) {
102                printf("[%04d - %s] Unexpected resultset [%d] %s\n",
103                    $offset + 8, $sql,
104                    mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
105                return false;
106            }
107
108            if (!is_object($res)) {
109                printf("[%04d - %s] [%d] %s\n",
110                    $offset + 9, $sql,
111                    mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
112                return false;
113            }
114            if ('mysqli_result' != get_class($res)) {
115                printf("[%04d - %s] Expecting object/mysqli_result got object/%s\n",
116                    $offset + 10, $sql,
117                    get_class($res));
118                return false;
119            }
120
121            $meta_res = array(
122                'num_fields'		=> mysqli_num_fields($res),
123                'fetch_field'		=> mysqli_fetch_field($res),
124                'fetch_field_direct0'	=> mysqli_fetch_field_direct($res, 0),
125                'fetch_field_direct1'	=> @mysqli_fetch_field_direct($res, 1),
126                'fetch_fields'		=> count(mysqli_fetch_fields($res)),
127                'field_count'		=> mysqli_field_count($link),
128                'field_seek-1'		=> @mysqli_field_seek($res, -1),
129                'field_seek0'		=> mysqli_field_seek($res, 0),
130                'field_tell'		=> mysqli_field_tell($res),
131            );
132            if (is_object($meta_res['fetch_field'])) {
133                $meta_res['fetch_field']->charsetnr	= 'ignore';
134                $meta_res['fetch_field']->flags	= 'ignore';
135            }
136            if (is_object($meta_res['fetch_field_direct0'])) {
137                $meta_res['fetch_field_direct0']->charsetnr	= 'ignore';
138                $meta_res['fetch_field_direct0']->flags	= 'ignore';
139            }
140            if (is_object($meta_res['fetch_field_direct1'])) {
141                $meta_res['fetch_field_direct1']->charsetnr	= 'ignore';
142                $meta_res['fetch_field_direct1']->flags	= 'ignore';
143            }
144            mysqli_free_result($res);
145            if ($check_mysqlnd && $meta_res != $expected_mysqlnd) {
146                printf("[%04d - %s] Metadata differs from expected\n",
147                    $offset + 11, $sql);
148                var_dump($meta_res);
149                var_dump($expected_mysqlnd);
150            } else {
151                if ($meta_res['field_count'] < 1) {
152                    printf("[%04d - %s] Metadata seems wrong, no fields?\n",
153                    $offset + 12, $sql);
154                    var_dump($meta_res);
155                    var_dump(mysqli_fetch_assoc($res));
156                }
157            }
158
159            if ($compare && $meta_res != $meta) {
160                printf("[%04d - %s] Metadata returned by mysqli_stmt_result_metadata() and mysqli_stmt_get_result() differ\n",
161                    $offset + 13, $sql);
162                var_dump($meta_res);
163                var_dump($meta);
164            }
165
166        }
167
168        mysqli_stmt_close($stmt);
169        return true;
170    }
171
172    /* Note: very weak testing, we accept almost any result */
173
174    testStatement(100, $link, 'ANALYZE TABLE test', array(), array(1), false, false);
175    testStatement(120, $link, 'OPTIMIZE TABLE test', array(), array(1), false, false);
176    testStatement(140, $link, 'REPAIR TABLE test', array(), array(1), false, false);
177
178    testStatement(160, $link, 'SHOW AUTHORS', array(), array(1), false, false);
179    testStatement(180, $link, 'SHOW CHARACTER SET', array(), array(1), false, false);
180    testStatement(200, $link, 'SHOW COLLATION', array(), array(1), false, false);
181    testStatement(220, $link, 'SHOW CONTRIBUTORS', array(), array(1), false, false);
182    testStatement(240, $link, 'SHOW CREATE DATABASE ' . $db, array(), array(1), false, false);
183    testStatement(260, $link, 'SHOW DATABASES', array(), array(1), false, false);
184    testStatement(280, $link, 'SHOW ENGINE InnoDB STATUS', array(), array(1), false, false);
185    testStatement(300, $link, 'SHOW ENGINES', array(), array(1), false, false);
186    testStatement(320, $link, 'SHOW PLUGINS', array(), array(1), false, false);
187    testStatement(340, $link, 'SHOW PROCESSLIST', array(), array(1), false, false);
188    testStatement(360, $link, 'SHOW FULL PROCESSLIST', array(), array(1), false, false);
189    testStatement(380, $link, 'SHOW STATUS', array(), array(1), false, false);
190    testStatement(400, $link, 'SHOW TABLE STATUS', array(), array(1), false, false);
191    testStatement(420, $link, 'SHOW TABLE STATUS', array(), array(1), false, false);
192    testStatement(440, $link, 'SHOW TABLES', array(), array(1), false, false);
193    testStatement(460, $link, 'SHOW OPEN TABLES', array(), array(1), false, false);
194    testStatement(460, $link, 'SHOW VARIABLES', array(), array(1), false, false);
195
196    $field0 = new stdClass();
197    $field0->name 		= 'id';
198    $field0->orgname 	= 'id';
199    $field0->table		= 'test';
200    $field0->orgtable	= 'test';
201    $field0->def 		= '';
202    $field0->max_length	= 0;
203    $field0->length		= 11;
204    $field0->charsetnr	= 'ignore';
205    $field0->flags		= 'ignore';
206    $field0->type		= MYSQLI_TYPE_LONG;
207    $field0->decimals	= 0;
208    $meta_lib = array(
209        'num_fields'		=> 1,
210        'fetch_field'		=> $field0,
211        'fetch_field_direct0'	=> $field0,
212        'fetch_field_direct1'	=> false,
213        'fetch_fields'		=> 1,
214        'field_count'		=> 1,
215        'field_seek-1'		=> false,
216        'field_seek0'		=> true,
217        'field_tell'		=> 0,
218    );
219    $meta_mysqlnd = $meta_lib;
220    testStatement(480, $link, 'SELECT id FROM test', $meta_lib, $meta_mysqlnd, true, true);
221
222    testStatement(500, $link, 'CHECKSUM TABLE test', array(), array(1), false, false);
223
224    mysqli_close($link);
225    print "done!";
226?>
227--CLEAN--
228<?php
229    require_once 'clean_table.inc';
230?>
231--EXPECT--
232done!
233