Last Insert ID unpackaging fails for MySQL when using Default values for autoincremented key
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 9.9k
- Forks
- 734
- Avg merge
- 6h 36m
- Merged PRs (30d)
- 8
Description
Description
When inserting a value in a table with several primary keys and using the default value for an auto-incremented one, the insert fails.
Known to be reproducible with MySQL.
Steps to Reproduce
- First create a simple database having a table with several one primary key, one being auto-incremented
- MySQL dump 10.13 Distrib 8.0.28, for Linux (x86_64)
--
-- Host: localhost Database: sea
-- ------------------------------------------------------
-- Server version 8.0.28-0ubuntu0.20.04.3
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `GAME`
--
DROP TABLE IF EXISTS `GAME`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `GAME` (
`id` int NOT NULL AUTO_INCREMENT,
`home_team_id` int NOT NULL,
`away_team_id` int NOT NULL,
PRIMARY KEY (`id`,`home_team_id`,`away_team_id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2022-04-04 19:18:04
Table schema :

- Create a new cargo project and generate the entities with the sea-orm-cli
cargo new sea_orm_issue
cd sea_orm_issue
sea-orm-cli generate entity -o src/entities/
Entity generated :
//! SeaORM Entity. Generated by sea-orm-codegen 0.7.0
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
#[sea_orm(table_name = "GAME")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: i32,
#[sea_orm(primary_key, auto_increment = false)]
pub home_team_id: i32,
#[sea_orm(primary_key, auto_increment = false)]
pub away_team_id: i32,
}
#[derive(Copy, Clone, Debug, EnumIter)]
pub enum Relation {}
impl RelationTrait for Relation {
fn def(&self) -> RelationDef {
panic!("No RelationDef")
}
}
impl ActiveModelBehavior for ActiveModel {}
- Add the following dependencies in Cargo.toml :
[dependencies]
sea-orm = { version ="0.7" , features = ["runtime-async-std-native-tls", "sqlx-mysql"]}
tokio = { version = "1.17.0", features = ["full"] }
env_logger = "0.9.0"
- Create a simple main to insert your entity :
pub mod entities;
use entities::{game};
use sea_orm::{entity::*, error::*, Database, DbConn};
#[tokio::main]
async fn main() -> Result<(), DbErr> {
env_logger::init();
let db: DbConn = Database::connect("mysql://sea_usr:password@dbhost:3306/sea").await.unwrap();
let new_game = game::ActiveModel {
home_team_id: Set(1),
away_team_id: Set(2),
..Default::default()
};
new_game.insert(&db).await?;
Ok(())
}
- Run it
cargo r
- And it should throw the following error (detailed log.txt attached)
cargo r
Finished dev [unoptimized + debuginfo] target(s) in 0.21s
Running `target/debug/sea-orm-issue-multiple-pk`
Error: Exec("Fail to unpack last_insert_id")
Let's note that :
- the issue doesn't occur when we have a single primary key in the table
- the entity is persisted despite the error being thrown
Expected Behavior
The entity should be inserted in the table, and no error should be thrown.
Actual Behavior
The entity is inserted in the table, but an error is thrown
Reproduces How Often
On every insert for a mysql database
Versions
- MySQL v8
- Rust 1.57
- Sea-ORM 0.7.0
- Rust 1.57
Additional Information
A sample project will be shared
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the generated entities/game model and the main insertion shown in the report, then reproduce the failure using MySQL 8 and the attached log.txt details. Trace the insert and last-insert-ID handling until the composite-primary-key case is isolated. Done means the row is inserted without an error, matching the expected behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- mysql, rust
- Domain
- backend, databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100