1--TEST--
2mysqli_fetch_all() data types variation
3--EXTENSIONS--
4mysqli
5--SKIPIF--
6<?php
7require_once dirname(__DIR__) . "/test_setup/test_helpers.inc";
8mysqli_check_skip_test();
9?>
10--FILE--
11<?php
12require_once dirname(__DIR__) . "/test_setup/test_helpers.inc";
13
14$link = default_mysqli_connect();
15
16function func_mysqli_fetch_all(
17    mysqli $link,
18    string $engine,
19    string $sql_type,
20    string|int|null $sql_value,
21    mixed $php_value,
22    $offset,
23    $regexp_comparison = NULL
24) {
25    try {
26        mysqli_query($link, $sql = sprintf("CREATE TABLE test_mysqli_fetch_all_data_types_variation(id INT NOT NULL, label %s, PRIMARY KEY(id)) ENGINE = %s", $sql_type, $engine));
27    } catch (mysqli_sql_exception $e) {
28        // don't bail, engine might not support the datatype
29        echo  $e->getMessage(), PHP_EOL;
30        return;
31    }
32
33    if (is_null($php_value)) {
34        mysqli_query($link, $sql = sprintf("INSERT INTO test_mysqli_fetch_all_data_types_variation(id, label) VALUES (1, NULL)"));
35    } else {
36        if (is_string($sql_value)) {
37            mysqli_query($link, $sql = "INSERT INTO test_mysqli_fetch_all_data_types_variation(id, label) VALUES (1, '" . $sql_value . "')");
38        } else {
39            mysqli_query($link, $sql = sprintf("INSERT INTO test_mysqli_fetch_all_data_types_variation(id, label) VALUES (1, '%d')", $sql_value));
40        }
41    }
42
43    $result = mysqli_query($link, "SELECT id, label FROM test_mysqli_fetch_all_data_types_variation");
44    $tmp = mysqli_fetch_all($result, MYSQLI_BOTH);
45    $row = $tmp[0];
46
47    $fields = mysqli_fetch_fields($result);
48
49    if ($regexp_comparison) {
50        if (!preg_match($regexp_comparison, (string)$row['label']) || !preg_match($regexp_comparison, (string)$row[1])) {
51            printf("[%04d] Expecting %s/%s [reg exp = %s], got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4,
52                gettype($php_value), $php_value, $regexp_comparison,
53                gettype($row[1]), $row[1],
54                gettype($row['label']), $row['label'], mysqli_errno($link), mysqli_error($link));
55        }
56    } else {
57        if (($row['label'] !== $php_value) || ($row[1] != $php_value)) {
58            printf("[%04d] Expecting %s/%s, got %s/%s resp. %s/%s. [%d] %s\n", $offset + 4,
59                gettype($php_value), $php_value,
60                gettype($row[1]), $row[1],
61                gettype($row['label']), $row['label'], mysqli_errno($link), mysqli_error($link));
62        }
63    }
64    mysqli_query($link, 'DROP TABLE test_mysqli_fetch_all_data_types_variation');
65}
66
67// TODO Optimize this?
68function func_mysqli_fetch_array_make_string(int $len): string {
69    $ret = '';
70    for ($i = 0; $i < $len; $i++) {
71        $ret .= chr(mt_rand(65, 90));
72    }
73    return $ret;
74}
75
76$engine = get_default_db_engine();
77func_mysqli_fetch_all($link, $engine, "TINYINT", -11, "-11", 20);
78func_mysqli_fetch_all($link, $engine, "TINYINT", NULL, NULL, 30);
79func_mysqli_fetch_all($link, $engine, "TINYINT UNSIGNED", 1, "1", 40);
80func_mysqli_fetch_all($link, $engine, "TINYINT UNSIGNED", NULL, NULL, 50);
81
82func_mysqli_fetch_all($link, $engine, "BOOL", 1, "1", 60);
83func_mysqli_fetch_all($link, $engine, "BOOL", NULL, NULL, 70);
84func_mysqli_fetch_all($link, $engine, "BOOLEAN", 0, "0", 80);
85func_mysqli_fetch_all($link, $engine, "BOOLEAN", NULL, NULL, 90);
86
87func_mysqli_fetch_all($link, $engine, "SMALLINT", -32768, "-32768", 100);
88func_mysqli_fetch_all($link, $engine, "SMALLINT", 32767, "32767", 110);
89func_mysqli_fetch_all($link, $engine, "SMALLINT", NULL, NULL, 120);
90func_mysqli_fetch_all($link, $engine, "SMALLINT UNSIGNED", 65535, "65535", 130);
91func_mysqli_fetch_all($link, $engine, "SMALLINT UNSIGNED", NULL, NULL, 140);
92
93func_mysqli_fetch_all($link, $engine, "MEDIUMINT", -8388608, "-8388608", 150);
94func_mysqli_fetch_all($link, $engine, "MEDIUMINT", 8388607, "8388607", 160);
95func_mysqli_fetch_all($link, $engine, "MEDIUMINT", NULL, NULL, 170);
96func_mysqli_fetch_all($link, $engine, "MEDIUMINT UNSIGNED", 16777215, "16777215", 180);
97func_mysqli_fetch_all($link, $engine, "MEDIUMINT UNSIGNED", NULL, NULL, 190);
98
99func_mysqli_fetch_all($link, $engine, "INTEGER", -2147483648, "-2147483648", 200);
100func_mysqli_fetch_all($link, $engine, "INTEGER", 2147483647, "2147483647", 210);
101func_mysqli_fetch_all($link, $engine, "INTEGER", NULL, NULL, 220);
102func_mysqli_fetch_all($link, $engine, "INTEGER UNSIGNED", "4294967295", "4294967295", 230);
103func_mysqli_fetch_all($link, $engine, "INTEGER UNSIGNED", NULL, NULL, 240);
104
105func_mysqli_fetch_all($link, $engine, "BIGINT", "-9223372036854775808", "-9223372036854775808", 250);
106
107func_mysqli_fetch_all($link, $engine, "BIGINT", NULL, NULL, 260);
108func_mysqli_fetch_all($link, $engine, "BIGINT UNSIGNED", "18446744073709551615", "18446744073709551615", 270);
109func_mysqli_fetch_all($link, $engine, "BIGINT UNSIGNED", NULL, NULL, 280);
110
111func_mysqli_fetch_all($link, $engine, "FLOAT", (string)(-9223372036854775808 - 1.1), "-9.22337e+18", 290, "/-9\.22337e\+?[0]?18/iu");
112func_mysqli_fetch_all($link, $engine, "FLOAT", NULL, NULL, 300);
113func_mysqli_fetch_all($link, $engine, "FLOAT UNSIGNED", (string)(18446744073709551615 + 1.1), "1.84467e+19", 310, "/1\.84467e\+?[0]?19/iu");
114func_mysqli_fetch_all($link, $engine, "FLOAT UNSIGNED ", NULL, NULL, 320);
115
116func_mysqli_fetch_all($link, $engine, "DOUBLE(10,2)", "-99999999.99", "-99999999.99", 330);
117func_mysqli_fetch_all($link, $engine, "DOUBLE(10,2)", NULL, NULL, 340);
118func_mysqli_fetch_all($link, $engine, "DOUBLE(10,2) UNSIGNED", "99999999.99", "99999999.99", 350);
119func_mysqli_fetch_all($link, $engine, "DOUBLE(10,2) UNSIGNED", NULL, NULL, 360);
120
121func_mysqli_fetch_all($link, $engine, "DECIMAL(10,2)", "-99999999.99", "-99999999.99", 370);
122func_mysqli_fetch_all($link, $engine, "DECIMAL(10,2)", NULL, NULL, 380);
123func_mysqli_fetch_all($link, $engine, "DECIMAL(10,2)", "99999999.99", "99999999.99", 390);
124func_mysqli_fetch_all($link, $engine, "DECIMAL(10,2)", NULL, NULL, 400);
125
126// don't care about date() strict TZ warnings...
127func_mysqli_fetch_all($link, $engine, "DATE", @date('Y-m-d'), @date('Y-m-d'), 410);
128func_mysqli_fetch_all($link, $engine, "DATE NOT NULL", @date('Y-m-d'), @date('Y-m-d'), 420);
129func_mysqli_fetch_all($link, $engine, "DATE", NULL, NULL, 430);
130
131func_mysqli_fetch_all($link, $engine, "DATETIME", @date('Y-m-d H:i:s'), @date('Y-m-d H:i:s'), 440);
132func_mysqli_fetch_all($link, $engine, "DATETIME NOT NULL", @date('Y-m-d H:i:s'), @date('Y-m-d H:i:s'), 450);
133func_mysqli_fetch_all($link, $engine, "DATETIME", NULL, NULL, 460);
134
135func_mysqli_fetch_all($link, $engine, "TIMESTAMP", @date('Y-m-d H:i:s'), @date('Y-m-d H:i:s'), 470);
136
137func_mysqli_fetch_all($link, $engine, "TIME", @date('H:i:s'), @date('H:i:s'), 480);
138func_mysqli_fetch_all($link, $engine, "TIME NOT NULL", @date('H:i:s'), @date('H:i:s'), 490);
139func_mysqli_fetch_all($link, $engine, "TIME", NULL, NULL, 500);
140
141func_mysqli_fetch_all($link, $engine, "YEAR", @date('Y'), @date('Y'), 510);
142func_mysqli_fetch_all($link, $engine, "YEAR NOT NULL", @date('Y'), @date('Y'), 520);
143func_mysqli_fetch_all($link, $engine, "YEAR", NULL, NULL, 530);
144
145$string255 = func_mysqli_fetch_array_make_string(255);
146func_mysqli_fetch_all($link, $engine, "CHAR(1)", "a", "a", 540);
147func_mysqli_fetch_all($link, $engine, "CHAR(255)", $string255,  $string255, 550);
148func_mysqli_fetch_all($link, $engine, "CHAR(1) NOT NULL", "a", "a", 560);
149func_mysqli_fetch_all($link, $engine, "CHAR(1)", NULL, NULL, 570);
150
151$string16k = func_mysqli_fetch_array_make_string(16000);
152func_mysqli_fetch_all($link, $engine, "VARCHAR(1)", "a", "a", 580);
153func_mysqli_fetch_all($link, $engine, "VARCHAR(255)", $string255, $string255, 590);
154func_mysqli_fetch_all($link, $engine, "VARCHAR(16000)", $string16k, $string16k, 600);
155func_mysqli_fetch_all($link, $engine, "VARCHAR(1) NOT NULL", "a", "a", 610);
156func_mysqli_fetch_all($link, $engine, "VARCHAR(1)", NULL, NULL, 620);
157
158func_mysqli_fetch_all($link, $engine, "BINARY(1)", "a", "a", 630);
159func_mysqli_fetch_all($link, $engine, "BINARY(2)", chr(0) . "a", chr(0) . "a", 640);
160func_mysqli_fetch_all($link, $engine, "BINARY(1) NOT NULL", "b", "b", 650);
161func_mysqli_fetch_all($link, $engine, "BINARY(1)", NULL, NULL, 660);
162
163func_mysqli_fetch_all($link, $engine, "VARBINARY(1)", "a", "a", 670);
164func_mysqli_fetch_all($link, $engine, "VARBINARY(2)", chr(0) . "a", chr(0) . "a", 680);
165func_mysqli_fetch_all($link, $engine, "VARBINARY(1) NOT NULL", "b", "b", 690);
166func_mysqli_fetch_all($link, $engine, "VARBINARY(1)", NULL, NULL, 700);
167
168func_mysqli_fetch_all($link, $engine, "TINYBLOB", "a", "a", 710);
169func_mysqli_fetch_all($link, $engine, "TINYBLOB", chr(0) . "a", chr(0) . "a", 720);
170func_mysqli_fetch_all($link, $engine, "TINYBLOB NOT NULL", "b", "b", 730);
171func_mysqli_fetch_all($link, $engine, "TINYBLOB", NULL, NULL, 740);
172
173func_mysqli_fetch_all($link, $engine, "TINYTEXT", "a", "a", 750);
174func_mysqli_fetch_all($link, $engine, "TINYTEXT NOT NULL", "a", "a", 760);
175func_mysqli_fetch_all($link, $engine, "TINYTEXT", NULL, NULL, 770);
176
177func_mysqli_fetch_all($link, $engine, "BLOB", "a", "a", 780);
178func_mysqli_fetch_all($link, $engine, "BLOB", chr(0) . "a", chr(0) . "a", 780);
179func_mysqli_fetch_all($link, $engine, "BLOB", NULL, NULL, 790);
180
181func_mysqli_fetch_all($link, $engine, "TEXT", "a", "a", 800);
182func_mysqli_fetch_all($link, $engine, "TEXT", chr(0) . "a", chr(0) . "a", 810);
183func_mysqli_fetch_all($link, $engine, "TEXT", NULL, NULL, 820);
184
185func_mysqli_fetch_all($link, $engine, "MEDIUMBLOB", "a", "a", 830);
186func_mysqli_fetch_all($link, $engine, "MEDIUMBLOB", chr(0) . "a", chr(0) . "a", 840);
187func_mysqli_fetch_all($link, $engine, "MEDIUMBLOB", NULL, NULL, 850);
188
189func_mysqli_fetch_all($link, $engine, "MEDIUMTEXT", "a", "a", 860);
190func_mysqli_fetch_all($link, $engine, "MEDIUMTEXT", chr(0) . "a", chr(0) . "a", 870);
191func_mysqli_fetch_all($link, $engine, "MEDIUMTEXT", NULL, NULL, 880);
192
193func_mysqli_fetch_all($link, $engine, "LONGBLOB", "a", "a", 890);
194func_mysqli_fetch_all($link, $engine, "LONGTEXT", chr(0) . "a", chr(0) . "a", 900);
195func_mysqli_fetch_all($link, $engine, "LONGBLOB", NULL, NULL, 910);
196
197func_mysqli_fetch_all($link, $engine, "ENUM('a', 'b')", "a", "a", 920);
198func_mysqli_fetch_all($link, $engine, "ENUM('a', 'b')", NULL, NULL, 930);
199
200func_mysqli_fetch_all($link, $engine, "SET('a', 'b')", "a", "a", 940);
201func_mysqli_fetch_all($link, $engine, "SET('a', 'b')", NULL, NULL, 950);
202
203mysqli_close($link);
204
205// TODO Split below into new test?
206$link = default_mysqli_connect();
207mysqli_real_query($link, "SELECT 1 AS _one");
208$result = mysqli_use_result($link);
209
210/* on mysqlnd level this would not be allowed */
211if (!is_object($result)) {
212    printf("[018] Expecting object, got %s/%s. [%d] %s\n",
213        gettype($result), $result, mysqli_errno($link), mysqli_error($link));
214
215}
216
217$rows = mysqli_fetch_all($result, MYSQLI_ASSOC);
218if (!is_array($rows) || (count($rows) > 1) || !isset($rows[0]['_one']) || ($rows[0]['_one'] != 1)) {
219    printf("[019] Results seem wrong, dumping\n");
220    var_dump($rows);
221}
222
223print "OK";
224?>
225--CLEAN--
226<?php
227require_once dirname(__DIR__) . "/test_setup/test_helpers.inc";
228tear_down_table_on_default_connection('test_mysqli_fetch_all_data_types_variation');
229?>
230--EXPECT--
231OK
232