1--TEST--
2mysqli_stmt_bind_param()
3--EXTENSIONS--
4mysqli
5--SKIPIF--
6<?php
7require_once('skipifconnectfailure.inc');
8?>
9--FILE--
10<?php
11    /*
12    The way we test the INSERT and data types overlaps with
13    the mysqli_stmt_bind_result test in large parts. There is only
14    one difference. This test uses mysqli_query()/mysqli_fetch_assoc() to
15    fetch the inserted values. This way we test
16    mysqli_query()/mysqli_fetch_assoc() for all possible data types
17    in this file and we test mysqli_stmt_bind_result() in the other
18    test -- therefore the "duplicate" makes some sense to me.
19    */
20    require_once("connect.inc");
21
22    require('table.inc');
23
24    $stmt = mysqli_stmt_init($link);
25    if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (?, ?)"))
26        printf("[003] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
27
28    $id = null;
29    $label = null;
30
31    /*
32    libmysql gives a less descriptive error message but mysqlnd,
33    we did not unify the error messages but ignore this slight difference silently
34    */
35    try {
36        if (!false === ($tmp = mysqli_stmt_bind_param($stmt, " ", $tmp)))
37            printf("[003d] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
38    } catch (\ArgumentCountError $e) {
39        echo $e->getMessage() . \PHP_EOL;
40    }
41
42    try {
43        if (!false === ($tmp = mysqli_stmt_bind_param($stmt, "", $id, $label)))
44            printf("[003a] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
45    } catch (\ValueError $e) {
46        echo $e->getMessage() . \PHP_EOL;
47    }
48
49    /* TODO: somehwhat undocumented syntax! */
50    $param = array($id);
51    try {
52        if (!false === ($tmp = mysqli_stmt_bind_param($stmt, "is", $param)))
53         printf("[003b] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
54    } catch (\ArgumentCountError $e) {
55        echo $e->getMessage() . \PHP_EOL;
56    }
57
58    $param = array($id, $label, $id);
59    try {
60        if (!false === ($tmp = mysqli_stmt_bind_param($stmt, " ", $tmp)))
61            printf("[003d] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
62    } catch (\ArgumentCountError $e) {
63        echo $e->getMessage() . \PHP_EOL;
64    }
65    try {
66        if (!false === ($tmp = mysqli_stmt_bind_param($stmt, "is", $param)))
67            printf("[003c] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
68    } catch (\ArgumentCountError $e) {
69        echo $e->getMessage() . \PHP_EOL;
70    }
71
72    try {
73        if (!false === ($tmp = mysqli_stmt_bind_param($stmt, "a", $id)))
74            printf("[004] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
75    } catch (\ArgumentCountError $e) {
76        echo $e->getMessage() . \PHP_EOL;
77    }
78
79    try {
80        if (!false === ($tmp = mysqli_stmt_bind_param($stmt, "a", $id, $label)))
81            printf("[005] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
82    } catch (\ArgumentCountError $e) {
83        echo $e->getMessage() . \PHP_EOL;
84    }
85
86    try {
87        mysqli_stmt_bind_param($stmt, "aa", $id, $label);
88    } catch (ValueError $e) {
89        echo $e->getMessage() . \PHP_EOL;
90    }
91
92    try {
93        mysqli_stmt_bind_param($stmt, "ia", $id, $label);
94    } catch (ValueError $e) {
95        echo $e->getMessage() . \PHP_EOL;
96    }
97
98    try {
99        if (!true === ($tmp = mysqli_stmt_bind_param($stmt, "is", $id, $label)))
100            printf("[008] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
101    } catch (\ArgumentCountError $e) {
102        echo $e->getMessage() . \PHP_EOL;
103    }
104
105    if (function_exists("memory_get_usage")) {
106        $mem = memory_get_usage();
107        for ($i = 0; $i < 20000; $i++) {
108            if (!true === ($tmp = mysqli_stmt_bind_param($stmt, "is", $id, $label)))
109                printf("[008][$i] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
110        }
111        if (($tmp = (memory_get_usage() - $mem)) > 600)
112            printf("[009] Function seems to be leaking, because it used %d bytes. During tests it used only 92 bytes.", $tmp);
113    }
114
115    $id = 100;
116    $label = "z";
117    if (!mysqli_stmt_execute($stmt))
118        printf("[010] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
119
120    mysqli_stmt_close($stmt);
121
122    if (!($res = mysqli_query($link, "SELECT id, label FROM test WHERE id = " . $id)))
123        printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
124    $row = mysqli_fetch_assoc($res);
125    if (($row['id'] != $id) || ($row['label'] != $label))
126        printf("[012] Expecting '%s'/%s', got '%s'/%s'!\n", $id, $label, $row['id'], $row['label']);
127    mysqli_free_result($res);
128
129    function func_mysqli_stmt_bind_datatype($link, $engine, $bind_type, $sql_type, $bind_value, $offset, $alternative = null) {
130
131        if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) {
132            printf("[%03d] [%d] %s\n", $offset, mysqli_errno($link), mysqli_error($link));
133            return false;
134        }
135
136        if (!mysqli_query($link, sprintf("CREATE TABLE test(id INT NOT NULL, label %s, PRIMARY KEY(id)) ENGINE = %s", $sql_type, $engine))) {
137            // don't bail - it might be that the server does not support the data type
138            return false;
139        }
140
141        if (!$stmt = mysqli_stmt_init($link)) {
142            printf("[%03d] [%d] %s\n", $offset + 1, mysqli_errno($link), mysqli_error($link));
143            return false;
144        }
145
146        if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUE (?, ?)")) {
147            printf("[%03d] [%d] %s\n", $offset + 2, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
148            return false;
149        }
150
151        $id = 1;
152        if (!mysqli_stmt_bind_param($stmt, "i" . $bind_type, $id, $bind_value)) {
153            printf("[%03d] [%d] %s\n", $offset + 3, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
154            return false;
155        }
156
157        if (!mysqli_stmt_execute($stmt)) {
158            printf("[%03d] [%d] %s\n", $offset + 4, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
159            return false;
160        }
161        mysqli_stmt_close($stmt);
162
163        if (!$res = mysqli_query($link, "SELECT id, label FROM test")) {
164            printf("[%03d] [%d] %s\n", $offset + 5, mysqli_errno($link), mysqli_error($link));
165            return false;
166        }
167
168        if (!$row = mysqli_fetch_assoc($res)) {
169            printf("[%03d] [%d] %s\n", $offset + 5, mysqli_errno($link), mysqli_error($link));
170            return false;
171        }
172
173        if ($alternative) {
174            if (($row['id'] != $id) || (($row['label'] != $bind_value) && ($row['label'] != $alternative))) {
175                printf("[%03d] Testing '%s', '%s': expecting '%s'/'%s' (%s), got '%s'/'%s'\n",
176                    $offset + 6, $bind_type, $sql_type,
177                    $id, $bind_value, gettype($bind_value), $row['id'], $row['label']);
178                return false;
179            }
180        } else {
181            if (($row['id'] != $id) || ($row['label'] != $bind_value)) {
182                printf("[%03d] Testing '%s', '%s': expecting '%s'/'%s', got '%s'/'%s'\n",
183                    $offset + 6, $bind_type, $sql_type,
184                    $id, $bind_value, $row['id'], $row['label']);
185                return false;
186            }
187        }
188
189        mysqli_free_result($res);
190        return true;
191    }
192
193    function func_mysqli_stmt_bind_make_string($len) {
194
195        $ret = '';
196        for ($i = 0; $i < $len; $i++)
197            $ret .= chr(mt_rand(65, 90));
198
199        return $ret;
200    }
201
202    func_mysqli_stmt_bind_datatype($link, $engine, "i", "TINYINT", -11, 20);
203    func_mysqli_stmt_bind_datatype($link, $engine, "i", "TINYINT", NULL, 30);
204    func_mysqli_stmt_bind_datatype($link, $engine, "i", "TINYINT UNSIGNED", 1, 40);
205    func_mysqli_stmt_bind_datatype($link, $engine, "i", "TINYINT UNSIGNED", NULL, 50);
206
207    func_mysqli_stmt_bind_datatype($link, $engine, "i", "BOOL", 1, 60);
208    func_mysqli_stmt_bind_datatype($link, $engine, "i", "BOOL", NULL, 70);
209    func_mysqli_stmt_bind_datatype($link, $engine, "i", "BOOLEAN", 0, 80);
210    func_mysqli_stmt_bind_datatype($link, $engine, "i", "BOOLEAN", NULL, 90);
211
212    func_mysqli_stmt_bind_datatype($link, $engine, "i", "SMALLINT", -32768, 100);
213    func_mysqli_stmt_bind_datatype($link, $engine, "i", "SMALLINT", 32767, 110);
214    func_mysqli_stmt_bind_datatype($link, $engine, "i", "SMALLINT", NULL, 120);
215    func_mysqli_stmt_bind_datatype($link, $engine, "i", "SMALLINT UNSIGNED", 65535, 130);
216    func_mysqli_stmt_bind_datatype($link, $engine, "i", "SMALLINT UNSIGNED", NULL, 140);
217
218    func_mysqli_stmt_bind_datatype($link, $engine, "i", "MEDIUMINT", -8388608, 150);
219    func_mysqli_stmt_bind_datatype($link, $engine, "i", "MEDIUMINT", 8388607, 160);
220    func_mysqli_stmt_bind_datatype($link, $engine, "i", "MEDIUMINT", NULL, 170);
221    func_mysqli_stmt_bind_datatype($link, $engine, "i", "MEDIUMINT UNSIGNED", 16777215, 180);
222    func_mysqli_stmt_bind_datatype($link, $engine, "i", "MEDIUMINT UNSIGNED", NULL, 190);
223
224    func_mysqli_stmt_bind_datatype($link, $engine, "i", "INTEGER", -2147483648, 200);
225    func_mysqli_stmt_bind_datatype($link, $engine, "i", "INTEGER", 2147483647, 210);
226    func_mysqli_stmt_bind_datatype($link, $engine, "i", "INTEGER", NULL, 220);
227    func_mysqli_stmt_bind_datatype($link, $engine, "i", "INTEGER UNSIGNED", (defined("PHP_INT_MAX")) ? min(4294967295, PHP_INT_MAX) : 1, 230);
228    func_mysqli_stmt_bind_datatype($link, $engine, "d", "INTEGER UNSIGNED", 4294967295, 240);
229    func_mysqli_stmt_bind_datatype($link, $engine, "i", "INTEGER UNSIGNED", NULL, 250);
230
231    func_mysqli_stmt_bind_datatype($link, $engine, "i", "BIGINT", -1 * PHP_INT_MAX + 1, 260);
232    func_mysqli_stmt_bind_datatype($link, $engine, "i", "BIGINT", NULL, 270);
233    func_mysqli_stmt_bind_datatype($link, $engine, "i", "BIGINT", PHP_INT_MAX, 280);
234    func_mysqli_stmt_bind_datatype($link, $engine, "i", "BIGINT UNSIGNED", NULL, 290);
235
236    func_mysqli_stmt_bind_datatype($link, $engine, "s", "BIGINT", "-9223372036854775808", 900);
237    // ?? func_mysqli_stmt_bind_datatype($link, $engine, "d", "BIGINT", -9223372036854775808, 910);
238    func_mysqli_stmt_bind_datatype($link, $engine, "s", "BIGINT UNSIGNED", "18446744073709551615", 920);
239
240/*
241    ??
242    func_mysqli_stmt_bind_datatype($link, $engine, "d", "FLOAT", -9223372036854775808 - 1.1, 300);
243    func_mysqli_stmt_bind_datatype($link, $engine, "d", "FLOAT UNSIGNED", 18446744073709551615 + 1.1, 320);
244    */
245    func_mysqli_stmt_bind_datatype($link, $engine, "d", "FLOAT", NULL, 310);
246    func_mysqli_stmt_bind_datatype($link, $engine, "d", "FLOAT UNSIGNED ", NULL, 330);
247    if (2147483647 == PHP_INT_MAX) {
248        func_mysqli_stmt_bind_datatype($link, $engine, "d", "FLOAT UNSIGNED", PHP_INT_MAX, 930, '2.14748e+09');
249        func_mysqli_stmt_bind_datatype($link, $engine, "d", "FLOAT", -1 * PHP_INT_MAX + 1, 940, '-2.14748e+09');
250    }
251    func_mysqli_stmt_bind_datatype($link, $engine, "s", "FLOAT", "-9223372036854775808", 300, '-9.22337e+18');
252    func_mysqli_stmt_bind_datatype($link, $engine, "s", "FLOAT UNSIGNED", "18446744073709551615", 320, '1.84467e+19');
253    func_mysqli_stmt_bind_datatype($link, $engine, "d", "FLOAT", -10.01, 950);
254    func_mysqli_stmt_bind_datatype($link, $engine, "d", "FLOAT UNSIGNED", 10.01, 960);
255
256    func_mysqli_stmt_bind_datatype($link, $engine, "d", "DOUBLE(10,2)", NULL, 350);
257    func_mysqli_stmt_bind_datatype($link, $engine, "d", "DOUBLE(10,2) UNSIGNED", NULL, 370);
258    func_mysqli_stmt_bind_datatype($link, $engine, "d", "DOUBLE(10,2)", -99999999.99, 340);
259    func_mysqli_stmt_bind_datatype($link, $engine, "d", "DOUBLE(10,2) UNSIGNED", 99999999.99, 360);
260
261    /*
262    func_mysqli_stmt_bind_datatype($link, $engine, "d", "DOUBLE(10,2)", -99999999.99, 340);
263    func_mysqli_stmt_bind_datatype($link, $engine, "d", "DOUBLE(10,2) UNSIGNED", 99999999.99, 360);
264        */
265    func_mysqli_stmt_bind_datatype($link, $engine, "d", "DECIMAL(10,2)", -99999999.99, 380);
266    func_mysqli_stmt_bind_datatype($link, $engine, "d", "DECIMAL(10,2)", NULL, 390);
267    func_mysqli_stmt_bind_datatype($link, $engine, "d", "DECIMAL(10,2)", 99999999.99, 400);
268    func_mysqli_stmt_bind_datatype($link, $engine, "d", "DECIMAL(10,2)", NULL, 410);
269
270    // don't care about date() strict TZ warnings...
271    func_mysqli_stmt_bind_datatype($link, $engine, "s", "DATE", @date('Y-m-d'), 420);
272    func_mysqli_stmt_bind_datatype($link, $engine, "s", "DATE NOT NULL", @date('Y-m-d'), 430);
273    func_mysqli_stmt_bind_datatype($link, $engine, "s", "DATE", NULL, 440);
274
275    func_mysqli_stmt_bind_datatype($link, $engine, "s", "DATETIME", @date('Y-m-d H:i:s'), 450);
276    func_mysqli_stmt_bind_datatype($link, $engine, "s", "DATETIME NOT NULL", @date('Y-m-d H:i:s'), 460);
277    func_mysqli_stmt_bind_datatype($link, $engine, "s", "DATETIME", NULL, 470);
278
279    func_mysqli_stmt_bind_datatype($link, $engine, "s", "TIMESTAMP", @date('Y-m-d H:i:s'), 480);
280
281    func_mysqli_stmt_bind_datatype($link, $engine, "s", "TIME", @date('H:i:s'), 490);
282    func_mysqli_stmt_bind_datatype($link, $engine, "s", "TIME NOT NULL", @date('H:i:s'), 500);
283    func_mysqli_stmt_bind_datatype($link, $engine, "s", "TIME", NULL, 510);
284
285    func_mysqli_stmt_bind_datatype($link, $engine, "s", "YEAR", @date('Y'), 520);
286    func_mysqli_stmt_bind_datatype($link, $engine, "s", "YEAR NOT NULL", @date('Y'), 530);
287    func_mysqli_stmt_bind_datatype($link, $engine, "s", "YEAR", NULL, 540);
288
289    $string255 = func_mysqli_stmt_bind_make_string(255);
290    func_mysqli_stmt_bind_datatype($link, $engine, "s", "CHAR(1)", "a", 550);
291    func_mysqli_stmt_bind_datatype($link, $engine, "s", "CHAR(255)", $string255, 560);
292    func_mysqli_stmt_bind_datatype($link, $engine, "s", "CHAR(1) NOT NULL", "a", 570);
293    func_mysqli_stmt_bind_datatype($link, $engine, "s", "CHAR(1)", NULL, 580);
294
295    $string65k = func_mysqli_stmt_bind_make_string(65535);
296    func_mysqli_stmt_bind_datatype($link, $engine, "s", "VARCHAR(1)", "a", 590);
297    func_mysqli_stmt_bind_datatype($link, $engine, "s", "VARCHAR(255)", $string255, 600);
298    func_mysqli_stmt_bind_datatype($link, $engine, "s", "VARCHAR(65635)", $string65k, 610);
299    func_mysqli_stmt_bind_datatype($link, $engine, "s", "VARCHAR(1) NOT NULL", "a", 620);
300    func_mysqli_stmt_bind_datatype($link, $engine, "s", "VARCHAR(1)", NULL, 630);
301
302    func_mysqli_stmt_bind_datatype($link, $engine, "s", "BINARY(1)", "a", 640);
303    func_mysqli_stmt_bind_datatype($link, $engine, "s", "BINARY(1)", chr(0), 650);
304    func_mysqli_stmt_bind_datatype($link, $engine, "s", "BINARY(1) NOT NULL", "b", 660);
305    func_mysqli_stmt_bind_datatype($link, $engine, "s", "BINARY(1)", NULL, 670);
306
307    func_mysqli_stmt_bind_datatype($link, $engine, "s", "VARBINARY(1)", "a", 680);
308    func_mysqli_stmt_bind_datatype($link, $engine, "s", "VARBINARY(1)", chr(0), 690);
309    func_mysqli_stmt_bind_datatype($link, $engine, "s", "VARBINARY(1) NOT NULL", "b", 700);
310    func_mysqli_stmt_bind_datatype($link, $engine, "s", "VARBINARY(1)", NULL, 710);
311
312    func_mysqli_stmt_bind_datatype($link, $engine, "s", "TINYBLOB", "a", 720);
313    func_mysqli_stmt_bind_datatype($link, $engine, "s", "TINYBLOB", chr(0), 730);
314    func_mysqli_stmt_bind_datatype($link, $engine, "s", "TINYBLOB NOT NULL", "b", 740);
315    func_mysqli_stmt_bind_datatype($link, $engine, "s", "TINYBLOB", NULL, 750);
316
317    func_mysqli_stmt_bind_datatype($link, $engine, "s", "TINYTEXT", "a", 760);
318    func_mysqli_stmt_bind_datatype($link, $engine, "s", "TINYTEXT NOT NULL", "a", 770);
319    func_mysqli_stmt_bind_datatype($link, $engine, "s", "TINYTEXT", NULL, 780);
320
321    // Note: you cannot insert any blob values this way. But you can check the API at least partly this way
322    // Extra BLOB tests are in mysqli_stmt_send_long()
323    func_mysqli_stmt_bind_datatype($link, $engine, "b", "BLOB", "", 790);
324    func_mysqli_stmt_bind_datatype($link, $engine, "b", "TEXT", "", 800);
325    func_mysqli_stmt_bind_datatype($link, $engine, "b", "MEDIUMBLOB", "", 810);
326    func_mysqli_stmt_bind_datatype($link, $engine, "b", "MEDIUMTEXT", "", 820);
327    func_mysqli_stmt_bind_datatype($link, $engine, "b", "LONGBLOB", "", 830);
328    func_mysqli_stmt_bind_datatype($link, $engine, "b", "LONGTEXT", "", 840);
329
330    func_mysqli_stmt_bind_datatype($link, $engine, "s", "ENUM('a', 'b')", "a", 850);
331    func_mysqli_stmt_bind_datatype($link, $engine, "s", "ENUM('a', 'b')", NULL, 860);
332    func_mysqli_stmt_bind_datatype($link, $engine, "s", "SET('a', 'b')", "a", 870);
333    func_mysqli_stmt_bind_datatype($link, $engine, "s", "SET('a', 'b')", NULL, 880);
334
335    if (mysqli_get_server_version($link) >= 50600)
336        func_mysqli_stmt_bind_datatype($link, $engine, "s", "TIME", "13:27:34.123456", 890, "13:27:34");
337
338    $stmt = mysqli_stmt_init($link);
339    if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (?, ?)"))
340        printf("[2000] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
341
342    $id = null;
343    $label = null;
344    if (true !== ($tmp = mysqli_stmt_bind_param($stmt, "is", $id, $label)))
345        printf("[2001] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
346
347    mysqli_stmt_execute($stmt);
348
349    if (true !== ($tmp = mysqli_stmt_bind_param($stmt, "is", $id, $label)))
350        printf("[2002] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
351
352    mysqli_stmt_close($stmt);
353    include("table.inc");
354
355    if (!$stmt = mysqli_stmt_init($link))
356        printf("[2003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
357
358    if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (?, ?)"))
359        printf("[2004] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
360
361    $id = $label = null;
362    if (true !== ($tmp = $stmt->bind_param('is', $id, $label)))
363        printf("[2005] Expecting boolean/true got %s/%s, [%d] %s\n",
364            gettype($tmp), $tmp,
365            $stmt->errno, $stmt->error);
366
367    $id = 100; $label = 'z';
368    if (!$stmt->execute())
369        printf("[2006] [%d] %s\n", $stmt->errno, $stmt->error);
370
371    if (!$res = mysqli_query($link, "SELECT id, label FROM test WHERE id = 100"))
372        printf("[2007] Expecting record 100/z, [%d] %s\n", mysqli_errno($link), mysqli_error($link));
373
374    if (!$row = mysqli_fetch_assoc($res))
375        printf("[2008] Expecting row, [%d] %s\n", mysqli_errno($link), mysqli_error($link));
376
377    if ($row['id'] != 100  || $row['label'] != 'z') {
378        printf("[2009] Row seems wrong, dumping record\n");
379        var_dump($row);
380    }
381    mysqli_free_result($res);
382
383    $value_list = array(array('id' => 101, 'label' => 'a'), array('id' => 102, 'label' => 'b'));
384    if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (?, ?)"))
385        printf("[2010] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
386
387        foreach ($value_list as $k => $values) {
388        if (!mysqli_stmt_bind_param($stmt, 'is', $values['id'], $values['label'])) {
389            printf("[2011] bind_param() failed for id = %d, [%d] %s\n",
390                $values['id'], mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
391            continue;
392        }
393        if (!$stmt->execute())
394            printf("[2012] [%d] execute() failed for id = %d, [%d] %s\n",
395                $values['id'], mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
396
397        if (!$res = mysqli_query($link, sprintf("SELECT label FROM test WHERE id = %d", $values['id'])))
398            printf("[2013] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
399        if (!$row = mysqli_fetch_assoc($res))
400            printf("[2014] Cannot find row id = %d\n", $values['id']);
401        else if (isset($row['label']) && ($values['label'] != $row['label']))
402            printf("[2015] Expecting label = %s, got label = %s\n", $values['label'], $row['label']);
403
404        mysqli_free_result($res);
405    }
406
407    mysqli_stmt_close($stmt);
408    mysqli_close($link);
409
410    print "done!";
411?>
412--CLEAN--
413<?php
414    require_once("clean_table.inc");
415?>
416--EXPECT--
417The number of variables must match the number of parameters in the prepared statement
418mysqli_stmt_bind_param(): Argument #2 ($types) cannot be empty
419The number of elements in the type definition string must match the number of bind variables
420The number of variables must match the number of parameters in the prepared statement
421The number of elements in the type definition string must match the number of bind variables
422The number of variables must match the number of parameters in the prepared statement
423The number of elements in the type definition string must match the number of bind variables
424mysqli_stmt_bind_param(): Argument #2 ($types) must only contain the "b", "d", "i", "s" type specifiers
425mysqli_stmt_bind_param(): Argument #2 ($types) must only contain the "b", "d", "i", "s" type specifiers
426done!
427