Skip to content

Commit

Permalink
Case-sensitive enum type casts (#789)
Browse files Browse the repository at this point in the history
  • Loading branch information
niklaskorz authored Oct 4, 2024
1 parent d94f386 commit a30b918
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/backend/postgres/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ impl QueryBuilder for PostgresQueryBuilder {
fn prepare_simple_expr(&self, simple_expr: &SimpleExpr, sql: &mut dyn SqlWriter) {
match simple_expr {
SimpleExpr::AsEnum(type_name, expr) => {
let simple_expr = expr.clone().cast_as(SeaRc::clone(type_name));
let simple_expr = expr.clone().cast_as_quoted(SeaRc::clone(type_name), self.quote());
self.prepare_simple_expr_common(&simple_expr, sql);
}
_ => QueryBuilder::prepare_simple_expr_common(self, simple_expr, sql),
Expand Down
36 changes: 34 additions & 2 deletions src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1883,7 +1883,7 @@ impl Expr {
/// );
/// assert_eq!(
/// query.to_string(PostgresQueryBuilder),
/// r#"SELECT CAST("font_size" AS text) FROM "character""#
/// r#"SELECT CAST("font_size" AS "text") FROM "character""#
/// );
/// assert_eq!(
/// query.to_string(SqliteQueryBuilder),
Expand All @@ -1902,7 +1902,7 @@ impl Expr {
/// );
/// assert_eq!(
/// query.to_string(PostgresQueryBuilder),
/// r#"INSERT INTO "character" ("font_size") VALUES (CAST('large' AS FontSizeEnum))"#
/// r#"INSERT INTO "character" ("font_size") VALUES (CAST('large' AS "FontSizeEnum"))"#
/// );
/// assert_eq!(
/// query.to_string(SqliteQueryBuilder),
Expand Down Expand Up @@ -2471,6 +2471,38 @@ impl SimpleExpr {
Self::FunctionCall(func)
}

/// Express a case-sensitive `CAST AS` expression.
///
/// # Examples
///
/// ```
/// use sea_query::{tests_cfg::*, *};
///
/// let query = Query::select()
/// .expr(Expr::value("1").cast_as_quoted(Alias::new("MyType"), '"'.into()))
/// .to_owned();
///
/// assert_eq!(
/// query.to_string(MysqlQueryBuilder),
/// r#"SELECT CAST('1' AS "MyType")"#
/// );
/// assert_eq!(
/// query.to_string(PostgresQueryBuilder),
/// r#"SELECT CAST('1' AS "MyType")"#
/// );
/// assert_eq!(
/// query.to_string(SqliteQueryBuilder),
/// r#"SELECT CAST('1' AS "MyType")"#
/// );
/// ```
pub fn cast_as_quoted<T>(self, type_name: T, q: Quote) -> Self
where
T: IntoIden,
{
let func = Func::cast_as_quoted(self, type_name, q);
Self::FunctionCall(func)
}

/// Create any binary operation
///
/// # Examples
Expand Down
38 changes: 38 additions & 0 deletions src/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,44 @@ impl Func {
))
}

/// Call `CAST` function with a case-sensitive custom type.
///
/// # Examples
///
/// ```
/// use sea_query::{tests_cfg::*, *};
///
/// let query = Query::select()
/// .expr(Func::cast_as_quoted("hello", Alias::new("MyType"), '"'.into()))
/// .to_owned();
///
/// assert_eq!(
/// query.to_string(MysqlQueryBuilder),
/// r#"SELECT CAST('hello' AS "MyType")"#
/// );
/// assert_eq!(
/// query.to_string(PostgresQueryBuilder),
/// r#"SELECT CAST('hello' AS "MyType")"#
/// );
/// assert_eq!(
/// query.to_string(SqliteQueryBuilder),
/// r#"SELECT CAST('hello' AS "MyType")"#
/// );
/// ```
pub fn cast_as_quoted<V, I>(expr: V, iden: I, q: Quote) -> FunctionCall
where
V: Into<SimpleExpr>,
I: IntoIden,
{
let expr: SimpleExpr = expr.into();
let mut quoted_type = String::new();
iden.into_iden().prepare(&mut quoted_type, q);
FunctionCall::new(Function::Cast).arg(expr.binary(
BinOper::As,
Expr::cust(quoted_type.as_str()),
))
}

/// Call `COALESCE` function.
///
/// # Examples
Expand Down

0 comments on commit a30b918

Please sign in to comment.