1--TEST--
2MySQL PDO->lastInsertId()
3--EXTENSIONS--
4pdo_mysql
5--SKIPIF--
6<?php
7require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
8MySQLPDOTest::skip();
9$db = MySQLPDOTest::factory();
10?>
11--FILE--
12<?php
13    require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
14    $db = MySQLPDOTest::factory();
15
16    try {
17        if ('0' !== ($tmp = $db->lastInsertId()))
18            printf("[001] No query has been run, lastInsertId() should return '0'/string got '%s'/%s\n",
19                var_export($tmp, true), gettype($tmp));
20
21        if ('0' !== ($tmp = $db->lastInsertId('sequence_name')))
22            printf("[002] MySQL does not support sequences, expecting '0'/string got '%s'/%s\n",
23                var_export($tmp, true), gettype($tmp));
24
25        $db->exec('DROP TABLE IF EXISTS test');
26        if ('0' !== ($tmp = $db->lastInsertId()))
27            printf("[003] Expecting '0'/string got '%s'/%s", var_export($tmp, true), gettype($tmp));
28
29        $db->exec(sprintf('CREATE TABLE test(id INT, col1 CHAR(10)) ENGINE=%s', PDO_MYSQL_TEST_ENGINE));
30        if ('0' !== ($tmp = $db->lastInsertId()))
31            printf("[004] Expecting '0'/string got '%s'/%s", var_export($tmp, true), gettype($tmp));
32
33        $stmt = $db->query('SELECT id FROM test LIMIT 1');
34        if ('0' !== ($tmp = $db->lastInsertId()))
35            printf("[005] Expecting '0'/string got '%s'/%s", var_export($tmp, true), gettype($tmp));
36
37        // no auto increment column
38        $db->exec("INSERT INTO test(id, col1) VALUES (100, 'a')");
39        if ('0' !== ($tmp = $db->lastInsertId()))
40            printf("[006] Expecting '0'/string got '%s'/%s", var_export($tmp, true), gettype($tmp));
41
42        $db->exec('ALTER TABLE test MODIFY id INT AUTO_INCREMENT PRIMARY KEY');
43        if ('0' !== ($tmp = $db->lastInsertId()))
44            printf("[006] Expecting '0'/string got '%s'/%s", var_export($tmp, true), gettype($tmp));
45
46        // duplicate key
47        @$db->exec("INSERT INTO test(id, col1) VALUES (100, 'a')");
48        if ('0' !== ($tmp = $db->lastInsertId()))
49            printf("[007] Expecting '0'/string got '%s'/%s", var_export($tmp, true), gettype($tmp));
50
51        $db->exec("INSERT INTO test(id, col1) VALUES (101, 'b')");
52        if ('101' !== ($tmp = $db->lastInsertId()))
53            printf("[008] Expecting '0'/string got '%s'/%s", var_export($tmp, true), gettype($tmp));
54
55        $db->exec('ALTER TABLE test MODIFY col1 CHAR(10) UNIQUE');
56        // replace = delete + insert -> new auto increment value
57        $db->exec("REPLACE INTO test(col1) VALUES ('b')");
58        $next_id = (int)$db->lastInsertId();
59
60        if ($next_id <= 101)
61            printf("[009] Expecting at least 102, got %d\n",$next_id);
62
63        $stmt = $db->query('SELECT LAST_INSERT_ID() as _last_id');
64        $row = $stmt->fetch(PDO::FETCH_ASSOC);
65        $last_id = $row['_last_id'];
66        if ($next_id != $last_id) {
67            printf("[010] LAST_INSERT_ID() = %d and lastInserId() = %d differ\n",
68                $last_id, $next_id);
69        }
70
71        $db->exec("INSERT INTO test(col1) VALUES ('c'), ('d'), ('e')");
72        $next_id = (int)$db->lastInsertId();
73        if ($next_id <= $last_id)
74            printf("[011] Expecting at least %d, got %d\n", $last_id + 1, $next_id);
75
76        // warnings are unhandy, lets go for exceptions for a second
77        $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
78        try {
79            $ignore_exception = true;
80            $db->exec('LOCK TABLE test WRITE');
81            $ignore_exception = false;
82
83            if (MySQLPDOTest::getServerVersion($db) >= 50000) {
84                $stmt = $db->query('SELECT @@auto_increment_increment AS inc');
85                $row = $stmt->fetch(PDO::FETCH_ASSOC);
86                $inc = $row['inc'];
87            } else {
88                $inc = 1;
89            }
90
91            $stmt = $db->query('SELECT LAST_INSERT_ID() as _last_id');
92            $row = $stmt->fetch(PDO::FETCH_ASSOC);
93            $last_id = $row['_last_id'];
94
95            $db->exec("INSERT INTO test(col1) VALUES ('z')");
96            $next_id = (int)$db->lastInsertId();
97            if ($next_id < ($last_id + $inc))
98                printf("[012] Expecting at least %d, got %d\n", $last_id + $inc, $next_id);
99
100        } catch (PDOException $e) {
101            if (!$ignore_exception)
102                printf("[014] %s, [%s} %s\n", $e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
103        }
104        $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
105        @$db->exec('UNLOCK TABLE test');
106
107    } catch (PDOException $e) {
108        printf("[001] %s [%s] %s\n",
109            $e->getMessage(), $db->errorCode(), implode(' ', $db->errorInfo()));
110    }
111
112    print "done!";
113?>
114--CLEAN--
115<?php
116require __DIR__ . '/mysql_pdo_test.inc';
117MySQLPDOTest::dropTestTable();
118?>
119--EXPECT--
120done!
121