Cast enums in lt()
, lte()
, gt()
, gte()
(#2014)
* Cast enums in lt, lte, gt, gte (revert 10f3de0, discussed under #1527) * Add tests for enum order comparisons
This commit is contained in:
parent
914ae2e166
commit
a73f699578
@ -20,18 +20,6 @@ pub struct ColumnDef {
|
||||
}
|
||||
|
||||
macro_rules! bind_oper {
|
||||
( $op: ident ) => {
|
||||
#[allow(missing_docs)]
|
||||
fn $op<V>(&self, v: V) -> SimpleExpr
|
||||
where
|
||||
V: Into<Value>,
|
||||
{
|
||||
Expr::col((self.entity_name(), *self)).$op(v)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! bind_oper_with_enum_casting {
|
||||
( $op: ident, $bin_op: ident ) => {
|
||||
#[allow(missing_docs)]
|
||||
fn $op<V>(&self, v: V) -> SimpleExpr
|
||||
@ -97,12 +85,12 @@ pub trait ColumnTrait: IdenStatic + Iterable + FromStr {
|
||||
(self.entity_name(), SeaRc::new(*self) as DynIden)
|
||||
}
|
||||
|
||||
bind_oper_with_enum_casting!(eq, Equal);
|
||||
bind_oper_with_enum_casting!(ne, NotEqual);
|
||||
bind_oper!(gt);
|
||||
bind_oper!(gte);
|
||||
bind_oper!(lt);
|
||||
bind_oper!(lte);
|
||||
bind_oper!(eq, Equal);
|
||||
bind_oper!(ne, NotEqual);
|
||||
bind_oper!(gt, GreaterThan);
|
||||
bind_oper!(gte, GreaterThanOrEqual);
|
||||
bind_oper!(lt, SmallerThan);
|
||||
bind_oper!(lte, SmallerThanOrEqual);
|
||||
|
||||
/// ```
|
||||
/// use sea_orm::{entity::*, query::*, tests_cfg::cake, DbBackend};
|
||||
|
@ -167,6 +167,57 @@ pub async fn insert_active_enum(db: &DatabaseConnection) -> Result<(), DbErr> {
|
||||
|
||||
assert_eq!(model, select_with_tea_not_in.one(db).await?.unwrap());
|
||||
|
||||
// String enums should be compared alphabetically in all supported DBs.
|
||||
// 'B' < 'S', so Big is considered "smaller" than Small.
|
||||
assert_eq!(
|
||||
model,
|
||||
Entity::find()
|
||||
.filter(Column::Category.lt(Category::Small))
|
||||
.one(db)
|
||||
.await?
|
||||
.unwrap()
|
||||
);
|
||||
|
||||
// Integer enums should be compared by value in all supported DBs.
|
||||
// 0 <= 1, so Black is considered "smaller or equal to" White.
|
||||
assert_eq!(
|
||||
model,
|
||||
Entity::find()
|
||||
.filter(Column::Color.lte(Color::White))
|
||||
.one(db)
|
||||
.await?
|
||||
.unwrap()
|
||||
);
|
||||
|
||||
// Native enum comparisons are not portable.
|
||||
//
|
||||
// Postgres enums are compared by their definition order
|
||||
// (see https://www.postgresql.org/docs/current/datatype-enum.html#DATATYPE-ENUM-ORDERING).
|
||||
// Tea was defined as ('EverydayTea', 'BreakfastTea'), so EverydayTea is considered "smaller" than BreakfastTea.
|
||||
//
|
||||
// SQLite doesn't support enum types and SeaORM works around this limitation by storing them as strings.
|
||||
// When treated as strings, EverydayTea is not "smaller" than BreakfastTea!
|
||||
//
|
||||
// MySQL should be the same as Postgres (see https://dev.mysql.com/doc/refman/8.0/en/enum.html#enum-sorting),
|
||||
// but in practice this test case behaves like SQLite. I'm not sure why.
|
||||
#[cfg(feature = "sqlx-postgres")]
|
||||
assert_eq!(
|
||||
model,
|
||||
Entity::find()
|
||||
.filter(Column::Tea.lt(Tea::BreakfastTea))
|
||||
.one(db)
|
||||
.await?
|
||||
.unwrap()
|
||||
);
|
||||
#[cfg(any(feature = "sqlx-mysql", feature = "sqlx-sqlite"))]
|
||||
assert_eq!(
|
||||
None,
|
||||
Entity::find()
|
||||
.filter(Column::Tea.lt(Tea::BreakfastTea))
|
||||
.one(db)
|
||||
.await?
|
||||
);
|
||||
|
||||
let res = model.delete(db).await?;
|
||||
|
||||
assert_eq!(res.rows_affected, 1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user