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