What's new in SeaQuery 0.32.x
π We are pleased to release SeaQuery 0.32.0 / 0.32.1! Here are some feature highlights π:
New Featuresβ
Unify Expr and SimpleExpr Methods with ExprTrait #791β
Previously, "operator" methods (e.g. add, eq) are duplicated across Expr and SimpleExpr, but the list of methods is slightly different for each. And since Expr and SimpleExpr are distinct types, it makes writing generic code difficult.
The ExprTrait looks like this:
pub trait ExprTrait: Sized {
// Required methods
fn as_enum<N>(self, type_name: N) -> SimpleExpr
where N: IntoIden;
fn binary<O, R>(self, op: O, right: R) -> SimpleExpr
where O: Into<BinOper>,
R: Into<SimpleExpr>;
fn cast_as<N>(self, type_name: N) -> SimpleExpr
where N: IntoIden;
fn unary(self, o: UnOper) -> SimpleExpr;
// Provided methods
fn add<R>(self, right: R) -> SimpleExpr where R: Into<SimpleExpr> { ... }
fn and<R>(self, right: R) -> SimpleExpr where R: Into<SimpleExpr> { ... }
fn between<A, B>(self, a: A, b: B) -> SimpleExpr
where A: Into<SimpleExpr>,
B: Into<SimpleExpr> { ... }
fn div<R>(self, right: R) -> SimpleExpr where R: Into<SimpleExpr> { ... }
fn eq<R>(self, right: R) -> SimpleExpr where R: Into<SimpleExpr> { ... }
fn equals<C>(self, col: C) -> SimpleExpr where C: IntoColumnRef { ... }
// omitting the where clause below to make it more concise ..
fn gt<R>(self, right: R) -> SimpleExpr;
fn gte<R>(self, right: R) -> SimpleExpr;
fn in_subquery(self, sel: SelectStatement) -> SimpleExpr;
fn in_tuples<V, I>(self, v: I) -> SimpleExpr;
fn is<R>(self, right: R) -> SimpleExpr;
fn is_in<V, I>(self, v: I) -> SimpleExpr;
fn is_not<R>(self, right: R) -> SimpleExpr;
fn is_not_in<V, I>(self, v: I) -> SimpleExpr;
fn is_not_null(self) -> SimpleExpr;
fn is_null(self) -> SimpleExpr;
fn left_shift<R>(self, right: R) -> SimpleExpr;
fn like<L>(self, like: L) -> SimpleExpr;
fn lt<R>(self, right: R) -> SimpleExpr;
fn lte<R>(self, right: R) -> SimpleExpr;
fn modulo<R>(self, right: R) -> SimpleExpr;
fn mul<R>(self, right: R) -> SimpleExpr;
fn ne<R>(self, right: R) -> SimpleExpr;
fn not(self) -> SimpleExpr;
fn not_between<A, B>(self, a: A, b: B) -> SimpleExpr;
fn not_equals<C>(self, col: C) -> SimpleExpr;
fn not_in_subquery(self, sel: SelectStatement) -> SimpleExpr;
fn not_like<L>(self, like: L) -> SimpleExpr;
fn or<R>(self, right: R) -> SimpleExpr;
fn right_shift<R>(self, right: R) -> SimpleExpr;
fn sub<R>(self, right: R) -> SimpleExpr;
fn bit_and<R>(self, right: R) -> SimpleExpr;
fn bit_or<R>(self, right: R) -> SimpleExpr;
}
- Added
ExprTraitto unifyExprandSimpleExprmethods - Added
impl<T> ExprTrait for T where T: Into<SimpleExpr>to maintain backwards compatibility for allInto<SimpleExpr>types, such asValueandFunctionCall - Added
trait PgExpr: ExprTrait: database specific expression for Postgres andimpl PgExprforFunctionCall,ColumnRef,Keyword,LikeExpr,Value - Added
trait SqliteExpr: ExprTrait: database specific expression for SQLite andimpl SqliteExprforFunctionCall,ColumnRef,Keyword,LikeExpr,Value
Support of Postgres Vector #774β
- Construct Postgres query with vector extension
- Added
postgres-vectorfeature flag - Added
Value::Vector,ColumnType::Vector,ColumnDef::vector(),PgBinOper::EuclideanDistance,PgBinOper::NegativeInnerProductandPgBinOper::CosineDistance
Example:
assert_eq!(
Query::select()
.columns([Char::Character])
.from(Char::Table)
.and_where(
Expr::col(Char::Character).eq(Expr::val(pgvector::Vector::from(vec![1.0, 2.0])))
)
.to_string(PostgresQueryBuilder),
r#"SELECT "character" FROM "character" WHERE "character" = '[1,2]'"#
);
Support Partial Index #478β
- Support partial index
CREATE INDEX .. WHERE ..
Example (Postgres):
assert_eq!(
Index::create()
.unique()
.nulls_not_distinct()
.name("partial-index-glyph-image-not-null")
.table(Glyph::Table)
.col(Glyph::Image)
.and_where(Expr::col(Glyph::Image).is_not_null())
.to_string(PostgresQueryBuilder),
r#"CREATE UNIQUE INDEX "partial-index-glyph-image-not-null" ON "glyph" ("image") NULLS NOT DISTINCT WHERE "image" IS NOT NULL"#
);
Example (Sqlite):
assert_eq!(
Index::create()
.if_not_exists()
.unique()
.name("partial-index-glyph-image-not-null")
.table(Glyph::Table)
.col(Glyph::Image)
.and_where(Expr::col(Glyph::Image).is_not_null())
.to_string(SqliteQueryBuilder),
r#"CREATE UNIQUE INDEX IF NOT EXISTS "partial-index-glyph-image-not-null" ON "glyph" ("image") WHERE "image" IS NOT NULL"#
);
Get Null Valueβ
This one may seem a little bummer, but it is type system problem. In order to support the Postgres protocol, SeaQuery's Value enum does not have a Null variant. This new Value::as_null method allows you to:
- construct a typed null value
- nullify a value
- define generic functions (
impl Into<Value>)
let v = Value::Int(Some(2));
let n = v.as_null();
assert_eq!(n, Value::Int(None));
// one liner:
assert_eq!(Into::<Value>::into(2.2).as_null(), Value::Double(None));
Bitwise AND/OR Operators #841β
Examples:
let query = Query::select()
.expr(1.bit_and(2).eq(3))
.to_owned();
assert_eq!(
query.to_string(PostgresQueryBuilder),
r#"SELECT (1 & 2) = 3"#
);
let query = Query::select()
.expr(1.bit_or(2).eq(3))
.to_owned();
assert_eq!(
query.to_string(PostgresQueryBuilder),
r#"SELECT (1 | 2) = 3"#
);
Enhancementsβ
- #817 Replaced
Educewith manual implementations- This is an effort to cut down compilation time
- #844 Added
GREATEST&LEASTfunction - #836 Added
ValueType::enum_type_name() - #835 Removed "one common table" restriction on recursive CTE
sea-query-deriveβ
We've finally done it! Removing the last bit of syn v1 from our dependency tree:
sea-query % cargo tree |grep 'syn '
β βββ syn v2.0.39
β β βββ syn v2.0.39 (*)
β βββ syn v2.0.39 (*)
βββ syn v2.0.39 (*)
βββ syn v2.0.39 (*)
β β βββ syn v2.0.39 (*)
- Merged
#[enum_def]intosea-query-derive - #769
#[enum_def]now impl additionalIdenStaticandAsRef<str>
sea-query-attrβ
We've merged this crate into sea-query-derive, and they will be maintained together from now on.
- Updated
syn,heckanddarling sea-query-attris now deprecated
Upgradesβ
Integration Examplesβ
SeaQuery plays well with the other crates in the rust ecosystem.
Communityβ
SeaQL.org is an independent open-source organization run by passionate οΈdevelopers. If you like our projects, please star β and share our repositories. If you feel generous, a small donation via GitHub Sponsor will be greatly appreciated, and goes a long way towards sustaining the organization π’.
SeaQuery is a community driven project. We welcome you to participate, contribute and together build for Rust's future π¦.
Rustacean Sticker Pack π¦β
The Rustacean Sticker Pack is the perfect way to express your passion for Rust. Our stickers are made with a premium water-resistant vinyl with a unique matte finish. Stick them on your laptop, notebook, or any gadget to show off your love for Rust!
Moreover, all proceeds contributes directly to the ongoing development of SeaQL projects.
Sticker Pack Contents:
- Logo of SeaQL projects: SeaQL, SeaORM, SeaQuery, Seaography, FireDBG
- Mascot of SeaQL: Terres the Hermit Crab
- Mascot of Rust: Ferris the Crab
- The Rustacean word
Support SeaQL and get a Sticker Pack!

