Cast primary key column inside returning expression of insert statement (#1427)
This commit is contained in:
parent
5ffd8025f2
commit
51e6ad7170
@ -251,7 +251,7 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec<Attribute>) -> syn::Res
|
|||||||
Self::#field_name => sea_orm::sea_query::SimpleExpr::cast_as(
|
Self::#field_name => sea_orm::sea_query::SimpleExpr::cast_as(
|
||||||
Into::<sea_orm::sea_query::SimpleExpr>::into(expr),
|
Into::<sea_orm::sea_query::SimpleExpr>::into(expr),
|
||||||
sea_orm::sea_query::Alias::new(&#select_as),
|
sea_orm::sea_query::Alias::new(&#select_as),
|
||||||
),
|
)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if let Some(save_as) = save_as {
|
if let Some(save_as) = save_as {
|
||||||
@ -259,7 +259,7 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec<Attribute>) -> syn::Res
|
|||||||
Self::#field_name => sea_orm::sea_query::SimpleExpr::cast_as(
|
Self::#field_name => sea_orm::sea_query::SimpleExpr::cast_as(
|
||||||
Into::<sea_orm::sea_query::SimpleExpr>::into(val),
|
Into::<sea_orm::sea_query::SimpleExpr>::into(val),
|
||||||
sea_orm::sea_query::Alias::new(&#save_as),
|
sea_orm::sea_query::Alias::new(&#save_as),
|
||||||
),
|
)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,6 +349,14 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec<Attribute>) -> syn::Res
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add tailing comma
|
||||||
|
if !columns_select_as.is_empty() {
|
||||||
|
columns_select_as.push_punct(Comma::default());
|
||||||
|
}
|
||||||
|
if !columns_save_as.is_empty() {
|
||||||
|
columns_save_as.push_punct(Comma::default());
|
||||||
|
}
|
||||||
|
|
||||||
let primary_key = {
|
let primary_key = {
|
||||||
let auto_increment = auto_increment && primary_keys.len() == 1;
|
let auto_increment = auto_increment && primary_keys.len() == 1;
|
||||||
let primary_key_types = if primary_key_types.len() == 1 {
|
let primary_key_types = if primary_key_types.len() == 1 {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
error::*, ActiveModelTrait, ColumnTrait, ConnectionTrait, EntityTrait, Insert, IntoActiveModel,
|
error::*, ActiveModelTrait, ColumnTrait, ConnectionTrait, EntityTrait, Insert, IntoActiveModel,
|
||||||
Iterable, PrimaryKeyTrait, SelectModel, SelectorRaw, Statement, TryFromU64,
|
Iterable, PrimaryKeyToColumn, PrimaryKeyTrait, SelectModel, SelectorRaw, Statement, TryFromU64,
|
||||||
};
|
};
|
||||||
use sea_query::{Expr, FromValueTuple, Iden, InsertStatement, IntoColumnRef, Query, ValueTuple};
|
use sea_query::{Expr, FromValueTuple, Iden, InsertStatement, IntoColumnRef, Query, ValueTuple};
|
||||||
use std::{future::Future, marker::PhantomData};
|
use std::{future::Future, marker::PhantomData};
|
||||||
@ -40,8 +40,9 @@ where
|
|||||||
// so that self is dropped before entering await
|
// so that self is dropped before entering await
|
||||||
let mut query = self.query;
|
let mut query = self.query;
|
||||||
if db.support_returning() && <A::Entity as EntityTrait>::PrimaryKey::iter().count() > 0 {
|
if db.support_returning() && <A::Entity as EntityTrait>::PrimaryKey::iter().count() > 0 {
|
||||||
let returning = Query::returning().columns(
|
let returning = Query::returning().exprs(
|
||||||
<A::Entity as EntityTrait>::PrimaryKey::iter().map(|c| c.into_column_ref()),
|
<A::Entity as EntityTrait>::PrimaryKey::iter()
|
||||||
|
.map(|c| c.into_column().select_as(Expr::col(c.into_column_ref()))),
|
||||||
);
|
);
|
||||||
query.returning(returning);
|
query.returning(returning);
|
||||||
}
|
}
|
||||||
|
@ -227,7 +227,7 @@ mod tests {
|
|||||||
use sea_query::OnConflict;
|
use sea_query::OnConflict;
|
||||||
|
|
||||||
use crate::tests_cfg::cake;
|
use crate::tests_cfg::cake;
|
||||||
use crate::{ActiveValue, DbBackend, EntityTrait, Insert, QueryTrait};
|
use crate::{ActiveValue, DbBackend, DbErr, EntityTrait, Insert, IntoActiveModel, QueryTrait};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn insert_1() {
|
fn insert_1() {
|
||||||
@ -350,4 +350,129 @@ mod tests {
|
|||||||
r#"INSERT INTO "cake" ("id", "name") VALUES (2, 'Orange') ON CONFLICT ("name") DO UPDATE SET "name" = "excluded"."name""#,
|
r#"INSERT INTO "cake" ("id", "name") VALUES (2, 'Orange') ON CONFLICT ("name") DO UPDATE SET "name" = "excluded"."name""#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[smol_potat::test]
|
||||||
|
async fn insert_8() -> Result<(), DbErr> {
|
||||||
|
use crate::{ActiveModelTrait, DbBackend, MockDatabase, Statement, Transaction};
|
||||||
|
|
||||||
|
mod post {
|
||||||
|
use crate as sea_orm;
|
||||||
|
use crate::entity::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
|
||||||
|
#[sea_orm(table_name = "posts")]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(primary_key, select_as = "INTEGER", save_as = "TEXT")]
|
||||||
|
pub id: i32,
|
||||||
|
pub title: String,
|
||||||
|
pub text: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
||||||
|
}
|
||||||
|
|
||||||
|
let model = post::Model {
|
||||||
|
id: 1,
|
||||||
|
title: "News wrap up 2022".into(),
|
||||||
|
text: "brbrbrrrbrbrbrr...".into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let db = MockDatabase::new(DbBackend::Postgres)
|
||||||
|
.append_query_results([[model.clone()]])
|
||||||
|
.into_connection();
|
||||||
|
|
||||||
|
post::Entity::insert(model.into_active_model())
|
||||||
|
.exec(&db)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
db.into_transaction_log(),
|
||||||
|
[Transaction::many([Statement::from_sql_and_values(
|
||||||
|
DbBackend::Postgres,
|
||||||
|
r#"INSERT INTO "posts" ("id", "title", "text") VALUES (CAST($1 AS TEXT), $2, $3) RETURNING CAST("id" AS INTEGER)"#,
|
||||||
|
[
|
||||||
|
1.into(),
|
||||||
|
"News wrap up 2022".into(),
|
||||||
|
"brbrbrrrbrbrbrr...".into(),
|
||||||
|
]
|
||||||
|
)])]
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[smol_potat::test]
|
||||||
|
async fn insert_9() -> Result<(), DbErr> {
|
||||||
|
use crate::{
|
||||||
|
ActiveModelTrait, DbBackend, MockDatabase, MockExecResult, Statement, Transaction,
|
||||||
|
};
|
||||||
|
|
||||||
|
mod post {
|
||||||
|
use crate as sea_orm;
|
||||||
|
use crate::entity::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
|
||||||
|
#[sea_orm(table_name = "posts")]
|
||||||
|
pub struct Model {
|
||||||
|
#[sea_orm(
|
||||||
|
primary_key,
|
||||||
|
auto_increment = false,
|
||||||
|
select_as = "INTEGER",
|
||||||
|
save_as = "TEXT"
|
||||||
|
)]
|
||||||
|
pub id_primary: i32,
|
||||||
|
#[sea_orm(
|
||||||
|
primary_key,
|
||||||
|
auto_increment = false,
|
||||||
|
select_as = "INTEGER",
|
||||||
|
save_as = "TEXT"
|
||||||
|
)]
|
||||||
|
pub id_secondary: i32,
|
||||||
|
pub title: String,
|
||||||
|
pub text: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||||
|
pub enum Relation {}
|
||||||
|
|
||||||
|
impl ActiveModelBehavior for ActiveModel {}
|
||||||
|
}
|
||||||
|
|
||||||
|
let model = post::Model {
|
||||||
|
id_primary: 1,
|
||||||
|
id_secondary: 1001,
|
||||||
|
title: "News wrap up 2022".into(),
|
||||||
|
text: "brbrbrrrbrbrbrr...".into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let db = MockDatabase::new(DbBackend::Postgres)
|
||||||
|
.append_exec_results([MockExecResult {
|
||||||
|
last_insert_id: 1,
|
||||||
|
rows_affected: 1,
|
||||||
|
}])
|
||||||
|
.into_connection();
|
||||||
|
|
||||||
|
post::Entity::insert(model.into_active_model())
|
||||||
|
.exec(&db)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
db.into_transaction_log(),
|
||||||
|
[Transaction::many([Statement::from_sql_and_values(
|
||||||
|
DbBackend::Postgres,
|
||||||
|
r#"INSERT INTO "posts" ("id_primary", "id_secondary", "title", "text") VALUES (CAST($1 AS TEXT), CAST($2 AS TEXT), $3, $4) RETURNING CAST("id_primary" AS INTEGER), CAST("id_secondary" AS INTEGER)"#,
|
||||||
|
[
|
||||||
|
1.into(),
|
||||||
|
1001.into(),
|
||||||
|
"News wrap up 2022".into(),
|
||||||
|
"brbrbrrrbrbrbrr...".into(),
|
||||||
|
]
|
||||||
|
)])]
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user