This topic describes the behavior of the LAST_INSERT_ID() function in OceanBase Database and the differences between OceanBase Database and MySQL.
The LAST_INSERT_ID() function is used to obtain the auto-increment ID value generated by the most recent INSERT operation. In OceanBase Database, the behavior of this function differs from that in MySQL in the following two aspects:
- Session-level LAST_INSERT_ID: The value is read and modified by using the
LAST_INSERT_ID()function. - Protocol-level LAST_INSERT_ID: The value is returned in the OK packet of the MySQL protocol.
MySQL behavior
Session-level LAST_INSERT_ID
The LAST_INSERT_ID value of a session can be read and modified by using the LAST_INSERT_ID(args) function:
-- Read the LAST_INSERT_ID value of a session.
SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 0 |
+------------------+
-- Modify the LAST_INSERT_ID value of a session by using the function.
SELECT LAST_INSERT_ID(10);
+--------------------+
| LAST_INSERT_ID(10) |
+--------------------+
| 10 |
+--------------------+
Protocol-level LAST_INSERT_ID
The LAST_INSERT_ID value in the OK packet of the MySQL protocol. When a DML statement modifies the LAST_INSERT_ID value of the session, the LAST_INSERT_ID value in the OK packet returned to the client after the DML statement is executed will be equivalent to the LAST_INSERT_ID value of the session. Otherwise, the LAST_INSERT_ID value returned to the client will be the value of the AUTO_INCREMENT column of the last row written by the DML operator.
Compatibility with MySQL databases
Fully compatible behaviors
OceanBase Database is fully compatible with MySQL in the following aspects:
- Reading and modifying session-level
LAST_INSERT_ID: The value ofLAST_INSERT_IDcan be read and modified through theLAST_INSERT_ID()function. - Setting the
LAST_INSERT_IDvalue through a function expression: The value can be set using theLAST_INSERT_ID(expr)function. - OK packet format at the protocol level: The response packet format for clients is consistent with MySQL.
- REPLACE statements: The value of the auto-increment column is returned for the first INSERT or the value of the auto-increment column that was overwritten.
- INSERT ... ON DUPLICATE KEY UPDATE statements: If there are no conflicts, the value of the auto-increment column of the first INSERT statement is returned. If there are conflicts, the value of the auto-increment column of the first INSERT statement is returned. If all the rows are in conflict, the value remains unchanged.
- Multi-row inserts: The value of the auto-increment column of the first INSERT statement is returned.
- IGNORE statements: If the primary key conflict causes the data to be not written,
LAST_INSERT_IDwill not be modified.
Note
Like MySQL, OceanBase Database also stores LAST_INSERT_ID in the session. The value of LAST_INSERT_ID can be obtained and modified through an expression in OceanBase Database, and the behavior is the same as that in MySQL.
Differences in behavior
The main differences between OceanBase Database and MySQL are as follows:
Notice
OceanBase currently uses the same packet format for client responses as MySQL, which includes LAST_INSERT_ID in OK packets. However, the behavior of this information is not fully consistent with MySQL. Specifically, when using DML statements to write to an AUTO_INCREMENT column, the changes in the LAST_INSERT_ID value are not fully compatible with MySQL.
Specifying an auto-increment column in an INSERT statement
MySQL behavior:
- When an auto-increment column is manually specified: The value of
LAST_INSERT_IDremains unchanged.
OceanBase Database behavior:
- When an auto-increment column is manually specified: The value of the auto-increment column returned is the ID of the first inserted row.
Note
This is the main difference between OceanBase Database and MySQL in the behavior of LAST_INSERT_ID. OceanBase Database cannot distinguish whether the current auto-increment column value is manually specified or obtained from the auto-increment service. Therefore, the behavior of LAST_INSERT_ID is kept consistent.
-- Create a test table.
CREATE TABLE `t1` (
`c1` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`c2` INT DEFAULT NULL,
PRIMARY KEY (`c1`),
UNIQUE KEY `c2` (`c2`)
);
-- Example 1: Modify the value using the LAST_INSERT_ID function (behavior is consistent between MySQL and OceanBase)
UPDATE t2 SET c1 = LAST_INSERT_ID(100) + c1 WHERE c2 = 1;
SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 100 |
+------------------+
-- Example 2: INSERT statement (behavior is consistent between MySQL and OceanBase)
INSERT INTO t1(c2) VALUES (1);
SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 1 |
+------------------+
-- Example 3: REPLACE statement (behavior is consistent between MySQL and OceanBase)
REPLACE INTO t1(c2) VALUES (2);
SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 2 |
+------------------+
-- Example 4: Multi-row insertion (both MySQL and OceanBase return the ID of the first inserted row)
INSERT INTO t1(c2) VALUES (3), (4);
SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 3 |
+------------------+
Detailed comparison table
| DML statement type | Scenario | LAST_INSERT_ID in MySQL session | LAST_INSERT_ID in OceanBase session | Description |
|---|---|---|---|---|
| INSERT | Primary key conflict | Remains unchanged | Remains unchanged | Consistent |
| Primary key does not conflict (Auto-increment column is not specified) | Auto-increment value of the first INSERT statement | Auto-increment value of the first INSERT statement | Consistent | |
| Primary key does not conflict (Auto-increment column is manually specified) | Remains unchanged | Auto-increment value of the first INSERT statement | OceanBase updates the value | |
| REPLACE | Auto-increment value of the first INSERT statement or the overwritten data | Auto-increment value of the first INSERT statement or the overwritten data | Consistent | |
| INSERT ... ON DUPLICATE KEY | No conflicts | Auto-increment value of the first INSERT statement | Auto-increment value of the first INSERT statement | Consistent |
| Partial conflicts | Auto-increment value of the first INSERT statement | Auto-increment value of the first INSERT statement | Consistent | |
| All conflicts | Remains unchanged | Remains unchanged | Consistent |
Compatibility plan
Note
The behavior takes effect in V4.3.3 and V4.4.1 and later. For OceanBase Database V4.3.5, the behavior is supported starting from V4.3.5 BP2.