1--TEST--
2mysqli_insert_id()
3--SKIPIF--
4<?php
5require_once('skipif.inc');
6require_once('skipifconnectfailure.inc');
7?>
8--FILE--
9<?php
10    require_once("connect.inc");
11
12    require('table.inc');
13
14    if (0 !== ($tmp = mysqli_insert_id($link)))
15        printf("[003] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp);
16
17    if (!$res = mysqli_query($link, "SELECT id, label FROM test ORDER BY id LIMIT 1")) {
18        printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
19    }
20    if (0 !== ($tmp = mysqli_insert_id($link)))
21        printf("[005] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp);
22    mysqli_free_result($res);
23
24    // no auto_increment column
25    if (!$res = mysqli_query($link, "INSERT INTO test(id, label) VALUES (100, 'a')")) {
26        printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
27    }
28    if (0 !== ($tmp = mysqli_insert_id($link)))
29        printf("[007] Expecting int/0, got %s/%s\n", gettype($tmp), $tmp);
30
31    if (!$res = mysqli_query($link, "ALTER TABLE test MODIFY id INT NOT NULL AUTO_INCREMENT")) {
32        printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
33    }
34
35    if (!$res = mysqli_query($link, "INSERT INTO test(label) VALUES ('a')")) {
36        printf("[009] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
37    }
38    if (($last_id = mysqli_insert_id($link)) <= 0)
39        printf("[010] Expecting int/any >0, got %s/%s\n", gettype($last_id), $last_id);
40
41    if (mysqli_query($link, "LOCK TABLE test WRITE")) {
42        /* we need exclusive access for a moment */
43        /* let's hope nobody changes auto_increment_increment while this code executes */
44        do {
45            if (mysqli_get_server_version($link) >= 50000) {
46                if (!$res = mysqli_query($link, 'SELECT @@auto_increment_increment AS inc')) {
47                    printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
48                    break;
49                }
50                if (!$row = mysqli_fetch_assoc($res)) {
51                    printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
52                    break;
53                }
54                mysqli_free_result($res);
55                $inc = $row['inc'];
56            } else {
57                $inc = 1;
58            }
59
60            if (!mysqli_query($link, "INSERT INTO test(label) VALUES ('b')")) {
61                printf("[013] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
62                break;
63            }
64            if (($next_id = mysqli_insert_id($link)) <= $last_id)
65                /*
66                very likely a bug, but someone could have done something on the server
67                between the second last insert and the lock, therefore don't stop just bail
68                */
69                printf("[014] Expecting int/any > %d, got %s/%s\n", $last_id, gettype($next_id), $next_id);
70
71            $last_id = $next_id;
72            if (!mysqli_query($link, "INSERT INTO test(label) VALUES ('c'), ('d'), ('e')")) {
73                printf("[015] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
74                break;
75            }
76            /*
77            Note: For a multiple-row insert, LAST_INSERT_ID() and mysql_insert_id() actually
78            return the AUTO_INCREMENT key from the first of the inserted rows. This allows
79            multiple-row inserts to be reproduced correctly on other servers in a replication setup.
80            */
81            if (($next_id = mysqli_insert_id($link)) != $last_id + $inc) {
82                printf("[016] Expecting int/%d, got %s/%s\n", $last_id + 1, gettype($next_id), $next_id);
83                break;
84            }
85
86            if (!$res = mysqli_query($link, "SELECT LAST_INSERT_ID() AS last_id")) {
87                printf("[017] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
88                break;
89            }
90            if (!$row = mysqli_fetch_assoc($res)) {
91                printf("[018] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
92                break;
93            }
94            mysqli_free_result($res);
95
96            if ($next_id != $row['last_id']) {
97                printf("[019] Something is wrong, check manually. Expecting %s got %s.\n",
98                    $next_id, $row['last_id']);
99                break;
100            }
101        } while (false);
102        mysqli_query($link, "UNLOCK TABLE test");
103    }
104
105    if (!$res = mysqli_query($link, "INSERT INTO test(id, label) VALUES (1000, 'a')")) {
106        printf("[020] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
107    }
108    if (1000 !== ($tmp = mysqli_insert_id($link)))
109        printf("[021] Expecting int/1000, got %s/%s\n", gettype($tmp), $tmp);
110
111    if (!$res = mysqli_query($link, "INSERT INTO test(label) VALUES ('b'), ('c')")) {
112        printf("[022] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
113    }
114    if (1000 >= ($tmp = mysqli_insert_id($link)))
115        printf("[023] Expecting int/>1000, got %s/%s\n", gettype($tmp), $tmp);
116
117    mysqli_close($link);
118
119    try {
120        mysqli_insert_id($link);
121    } catch (Error $exception) {
122        echo $exception->getMessage() . "\n";
123    }
124
125    print "done!";
126?>
127--CLEAN--
128<?php
129    require_once("clean_table.inc");
130?>
131--EXPECT--
132mysqli object is already closed
133done!
134