Skip to content

Releases: SeaQL/sea-query

1.0.0-rc.33

09 Apr 21:18

Choose a tag to compare

New Features

  • Add Value::Enum — a typed enum value that generates a literal cast in Postgres #1051
let value = sea_query::Enum {
    type_name: "FontSizeEnum".to_owned().into(),
    value: "large".into(),
};

assert_eq!(
    Query::insert()
        .into_table(Char::Table)
        .columns([Char::FontSize])
        .values_panic([Expr::val(value)])
        .to_string(PostgresQueryBuilder),
    r#"INSERT INTO "character" ("font_size") VALUES ('large'::"FontSizeEnum")"#
);

Arrays of enum values are also supported (requires postgres-array):

let value = Value::Array(
    ArrayType::Enum(Box::new("FontSizeEnum".to_owned().into())),
    Some(Box::new(vec![
        sea_query::Enum { type_name: "FontSizeEnum".to_owned().into(), value: "large".into() }.into(),
    ])),
);

// Generates: INSERT INTO "character" ("font_size") VALUES ($1::"FontSizeEnum"[])
  • Add Postgres advisory lock functions #1062
assert_eq!(
    Query::select()
        .expr(PgFunc::advisory_lock(Expr::val(12345_i64)))
        .to_owned()
        .to_string(PostgresQueryBuilder),
    r#"SELECT PG_ADVISORY_LOCK(12345)"#
);

Full set of functions added: PgFunc::advisory_lock, advisory_lock_shared, try_advisory_lock, try_advisory_lock_shared, advisory_unlock, advisory_unlock_shared, advisory_unlock_all, advisory_xact_lock, advisory_xact_lock_shared, try_advisory_xact_lock, try_advisory_xact_lock_shared

  • Add SelectExprTrait for ergonomic alias and window chaining #1040
// Attach alias directly on an expression
Query::select()
    .expr(Expr::col(Char::Character).alias("C"))
    .from(Char::Table);

// Chain window function inline
Query::select()
    .from(Char::Table)
    .expr(
        Expr::col(Char::Character)
            .max()
            .over(WindowStatement::partition_by(Char::FontSize))
            .alias("C"),
    );

// Reference a named window
Query::select()
    .from(Char::Table)
    .expr(Expr::col(Char::Character).max().over("w"))
    .window("w", WindowStatement::partition_by(Char::FontSize));

Enhancements

  • Allow schema-referencing foreign keys in SQLite backend — the schema qualifier is stripped since SQLite foreign key syntax does not support it #1056
  • Fix null array handling: Array::Null.is_empty() now correctly returns false; null and empty are distinct states #1034
  • Rename Value::as_ref_array to Value::as_array; old name kept as a deprecated alias #1034
  • Add PostgresValues::as_types() — returns the corresponding postgres::Type for each bound value #967

House Keeping

  • Simplify FunctionCall::new(PgFunc::...) calls

1.0.0-rc.32

09 Apr 21:17

Choose a tag to compare

New Features

  • Support EXPLAIN statements #1044
// Postgres
assert_eq!(
    ExplainStatement::new()
        .analyze()
        .format(ExplainFormat::Json)
        .statement(
            Query::select()
                .column(Char::Character)
                .from(Char::Table)
                .to_owned(),
        )
        .to_string(PostgresQueryBuilder),
    r#"EXPLAIN (ANALYZE, FORMAT JSON) SELECT "character" FROM "character""#
);

// MySQL
assert_eq!(
    ExplainStatement::new()
        .format(ExplainFormat::Json)
        .statement(
            Query::select()
                .column(Char::Character)
                .from(Char::Table)
                .to_owned(),
        )
        .to_string(MysqlQueryBuilder),
    "EXPLAIN FORMAT = JSON SELECT `character` FROM `character`"
);

// SQLite
assert_eq!(
    ExplainStatement::new()
        .query_plan()
        .statement(
            Query::select()
                .column(Char::Character)
                .from(Char::Table)
                .to_owned(),
        )
        .to_string(SqliteQueryBuilder),
    r#"EXPLAIN QUERY PLAN SELECT "character" FROM "character""#
);
  • Support for FILTER clause on aggregate functions #1043
let query = Query::select()
    .expr_as(
        Func::count(Expr::val(1))
            .filter(
                Cond::all()
                    .add(Expr::col(Char::Character).eq("foo"))
                    .add(Expr::col(Char::SizeW).eq(1))
            ),
        Alias::new("filtered_total")
    )
    .expr_as(Func::count(Expr::val(1)), Alias::new("total"))
    .from(Char::Table)
    .to_owned();

assert_eq!(
    query.to_string(PostgresQueryBuilder),
    r#"SELECT COUNT(1) FILTER (WHERE "character" = 'foo' AND "size_w" = 1) AS "filtered_total", COUNT(1) AS "total" FROM "character""#
);
  • Add ALTER TABLE DROP CONSTRAINT
let table = Table::alter()
    .table(Font::Table)
    .drop_constraint("font_name_key")
    .to_owned();

assert_eq!(
    table.to_string(MysqlQueryBuilder),
    r#"ALTER TABLE `font` DROP CONSTRAINT `font_name_key`"#
);
assert_eq!(
    table.to_string(PostgresQueryBuilder),
    r#"ALTER TABLE "font" DROP CONSTRAINT "font_name_key""#
);

House Keeping

  • Bump Rust version to 1.88
  • Bump rusqlite to 0.38.0 #1059
  • Update time to 0.3.47 #1057

1.0.0-rc.31

08 Feb 20:46

Choose a tag to compare

  • Implement SELECT INTO for Postgres #1021
  • Added PgExpr eq_any and ne_all

0.32.7

06 Aug 11:58

Choose a tag to compare

Enhancements

  • Added ValueType::is_option

Bug Fixes

  • Fix incorrect casting of ChronoDateTimeWithTimeZone in Value::Array #933
  • Add missing parenthesis to WINDOW clause #919
SELECT .. OVER "w" FROM "character" WINDOW "w" AS (PARTITION BY "ww")
  • Fix serializing iden as a value in ALTER TYPE ... RENAME TO ... statements #924
ALTER TYPE "font" RENAME TO "typeface"
  • Fixed the issue where milliseconds were truncated when formatting Value::Constant #929
'2025-01-01 00:00:00.000000'
                    ^^^^^^^

0.32.6

27 May 09:14

Choose a tag to compare

Enhancements

  • impl From<Condition> and From<ConditionExpression> for SimpleExpr #886

0.32.5

07 May 20:46

Choose a tag to compare

New features

  • Support for creating functional indexes in PostgreSQL and MySQL #869

Enhancements

  • Make RcOrArc a documented type alias instead of a direct reexport #875
  • Impl Iden for &'static str (don't wrap strings in Alias::new) #882

0.32.4

17 Apr 21:37

Choose a tag to compare

New Features

  • Added support for temporary tables #878
let statement = Table::create()
    .table(Font::Table)
    .temporary()
    .col(
        ColumnDef::new(Font::Id)
            .integer()
            .not_null()
            .primary_key()
            .auto_increment()
    )
    .col(ColumnDef::new(Font::Name).string().not_null())
    .take();

assert_eq!(
    statement.to_string(MysqlQueryBuilder),
    [
        "CREATE TEMPORARY TABLE `font` (",
        "`id` int NOT NULL PRIMARY KEY AUTO_INCREMENT,",
        "`name` varchar(255) NOT NULL",
        ")",
    ]
    .join(" ")
);
  • Added Value::dummy_value
use sea_query::Value;
let v = Value::Int(None);
let n = v.dummy_value();
assert_eq!(n, Value::Int(Some(0)));

Bug Fixes

  • Quote type properly in AsEnum casting #880
let query = Query::select()
    .expr(Expr::col(Char::FontSize).as_enum(TextArray))
    .from(Char::Table)
    .to_owned();

assert_eq!(
    query.to_string(PostgresQueryBuilder),
    r#"SELECT CAST("font_size" AS "text"[]) FROM "character""#
);

0.32.3

16 Mar 19:49

Choose a tag to compare

New Features

  • Support Update FROM .. #861
let query = Query::update()
    .table(Glyph::Table)
    .value(Glyph::Tokens, Expr::column((Char::Table, Char::Character)))
    .from(Char::Table)
    .cond_where(
        Expr::col((Glyph::Table, Glyph::Image))
            .eq(Expr::col((Char::Table, Char::UserData))),
    )
    .to_owned();

assert_eq!(
    query.to_string(PostgresQueryBuilder),
    r#"UPDATE "glyph" SET "tokens" = "character"."character" FROM "character" WHERE "glyph"."image" = "character"."user_data""#
);
assert_eq!(
    query.to_string(SqliteQueryBuilder),
    r#"UPDATE "glyph" SET "tokens" = "character"."character" FROM "character" WHERE "glyph"."image" = "character"."user_data""#
);
  • Support TABLESAMPLE (Postgres) #865
use sea_query::extension::postgres::PostgresSelectStatementExt;

let query = Query::select()
    .columns([Glyph::Image])
    .from(Glyph::Table)
    .table_sample(SampleMethod::SYSTEM, 50.0, None)
    .to_owned();

assert_eq!(
    query.to_string(PostgresQueryBuilder),
    r#"SELECT "image" FROM "glyph" TABLESAMPLE SYSTEM (50)"#
);
  • Support ALTER COLUMN USING .. (Postgres) #848
let table = Table::alter()
    .table(Char::Table)
    .modify_column(
        ColumnDef::new(Char::Id)
            .integer()
            .using(Expr::col(Char::Id).cast_as(Alias::new("integer"))),
    )
    .to_owned();

assert_eq!(
    table.to_string(PostgresQueryBuilder),
    [
        r#"ALTER TABLE "character""#,
        r#"ALTER COLUMN "id" TYPE integer USING CAST("id" AS integer)"#,
    ]
    .join(" ")
);

House Keeping

  • Updated ordered-float to 4
  • Updated thiserror to 2

0.32.2

18 Feb 00:33

Choose a tag to compare

New Features

  • Added with_cte to use WITH clauses in all statements #859
let select = SelectStatement::new()
    .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
    .from(Glyph::Table)
    .to_owned();
let cte = CommonTableExpression::new()
    .query(select)
    .table_name(Alias::new("cte"))
    .to_owned();
let select = SelectStatement::new()
    .columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
    .from(Alias::new("cte"))
    .with_cte(cte)
    .to_owned();
assert_eq!(
    select.to_string(PostgresQueryBuilder),
    [
        r#"WITH "cte" AS"#,
        r#"(SELECT "id", "image", "aspect""#,
        r#"FROM "glyph")"#,
        r#"SELECT "id", "image", "aspect" FROM "cte""#,
    ]
    .join(" ")
);

Enhancements

  • Added Expr::column #852
  • Added Postgres function DATE_TRUNC #825
  • Added INCLUDE clause for Postgres BTree index #826

Bug Fixes

  • Write empty Postgres array as '{}' #854

0.32.1

01 Dec 19:34

Choose a tag to compare

New Features

  • Added Value::as_null
let v = Value::Int(Some(2));
let n = v.as_null();

assert_eq!(n, Value::Int(None));
  • Added bitwise and/or operators (bit_and, bit_or) #841
let query = Query::select()
    .expr(1.bit_and(2).eq(3))
    .to_owned();

assert_eq!(
    query.to_string(PostgresQueryBuilder),
    r#"SELECT (1 & 2) = 3"#
);

Enhancements

  • Added GREATEST & LEAST function #844
  • Added ValueType::enum_type_name() #836
  • Removed "one common table" restriction on recursive CTE #835

House keeping

  • Remove unnecessary string hashes #815