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