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