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