Repository: diesel-rs/diesel
File: diesel/src/expression/cast.rs (Rust)

Code before:
    type SqlType = ST;
}
impl<E, ST, DB> query_builder::QueryFragment<DB> for Cast<E, ST>
where
    E: query_builder::QueryFragment<DB>,
    DB: diesel::backend::Backend,
    ST: KnownCastSqlTypeName<DB>,
{
    fn walk_ast<'b>(&'b self, mut out: query_builder::AstPass<'_, 'b, DB>) -> QueryResult<()> {
        out.push_sql("CAST(");
        self.expr.walk_ast(out.reborrow())?;
        out.push_sql(" AS ");
        out.push_sql(ST::sql_type_name());
        out.push_sql(")");
        Ok(())
    }
}

/// We know what to write as `sql_type` in the `CAST(expr AS sql_type)` SQL for
/// `Self`
///
/// That is what is returned by `Self::sql_type_name()`
#[diagnostic::on_unimplemented(
    note = "In order to use `CAST`, it is necessary that Diesel knows how to express the name \
		of this type in the given backend.",
    note = "This can be PRed into Diesel if the type is a standard SQL type."
)]
pub trait KnownCastSqlTypeName<DB> {
    /// What to write as `sql_type` in the `CAST(expr AS sql_type)` SQL for
    /// `Self`
    fn sql_type_name() -> &'static str;
}
impl<ST, DB> KnownCastSqlTypeName<DB> for sql_types::Nullable<ST>
where
    ST: KnownCastSqlTypeName<DB>,
{
    fn sql_type_name() -> &'static str {
        <ST as KnownCastSqlTypeName<DB>>::sql_type_name()
    }
}

macro_rules! type_name {
    ($($backend: ty: $backend_feature: literal { $($type: ident => $val: literal,)+ })*) => {
        $(
            $(
				#[cfg(feature = $backend_feature)]
                impl KnownCastSqlTypeName<$backend> for sql_types::$type {
                    fn sql_type_name() -> &'static str {
                        $val
                    }
                }

Review comment (suggestion):
We likely want to change this message to something more active like: If you run into this error message and believe that this cast should be supported open a PR that adds that trait implementation there (with link to the source or file path)

Code after:
    type SqlType = ST;
}

impl<E, ST, DB> query_builder::QueryFragment<DB> for Cast<E, ST>
where
    E: query_builder::QueryFragment<DB>,
    DB: diesel::backend::Backend,
    ST: KnownCastSqlTypeName<DB>,
{
    fn walk_ast<'b>(&'b self, mut out: query_builder::AstPass<'_, 'b, DB>) -> QueryResult<()> {
        out.push_sql("CAST(");
        self.expr.walk_ast(out.reborrow())?;
        out.push_sql(" AS ");
        out.push_sql(ST::SQL_TYPE_NAME);
        out.push_sql(")");
        Ok(())
    }
}

/// We know what to write as `sql_type` in the `CAST(expr AS sql_type)` SQL for
/// `Self`
///
/// That is what is returned by `Self::sql_type_name()`
#[diagnostic::on_unimplemented(
    note = "In order to use `CAST`, it is necessary that Diesel knows how to express the name \
		of this type in the given backend.",
    note = "If you run into this error message and believe that this cast should be supported \
            open a PR that adds that trait implementation here: https://github.com/diesel-rs/diesel/blob/2fafe60a8f4ca3407dca5fe010a6092fa8a1858a/diesel/src/expression/cast.rs#L113."
)]
pub trait KnownCastSqlTypeName<DB> {
    /// What to write as `sql_type` in the `CAST(expr AS sql_type)` SQL for
    /// `Self`
    const SQL_TYPE_NAME: &'static str;
}

impl<ST, DB> KnownCastSqlTypeName<DB> for sql_types::Nullable<ST>
where
    ST: KnownCastSqlTypeName<DB>,
{
    const SQL_TYPE_NAME: &'static str = <ST as KnownCastSqlTypeName<DB>>::SQL_TYPE_NAME;
}

macro_rules! type_name {
    ($($backend: ty: $backend_feature: literal { $($type: ident => $val: literal,)+ })*) => {
        $(
            $(
				#[cfg(feature = $backend_feature)]
                impl KnownCastSqlTypeName<$backend> for sql_types::$type {
                    const SQL_TYPE_NAME: &'static str = $val;
                }
            )*