Skip to content

Quick Fix: Postgres decoding for ActiveEnum rs_type Text#3011

Closed
sinder38 wants to merge 2 commits intoSeaQL:masterfrom
sinder38:fix/pg-enum-decoding
Closed

Quick Fix: Postgres decoding for ActiveEnum rs_type Text#3011
sinder38 wants to merge 2 commits intoSeaQL:masterfrom
sinder38:fix/pg-enum-decoding

Conversation

@sinder38
Copy link
Contributor

@sinder38
Copy link
Contributor Author

@Huliiiiii,
After looking through it I think this should still be part of your #2955 and what I am doing here is more of "quick fix" instead of a real one.

Why:

The rs_type = "String" is the core issue as sea-orm forces all string enums through string at the sqlx layer, losing the type name information at compile time.
sea-orm's DeriveActiveEnum generates:

  impl TryGetable for Tea {
      fn try_get_by(res, idx) {
          let value = String::try_get_by(res, idx)?;  //forces through String
          Tea::try_from_value(&value)
      }
  }

String::type_info() returns PgTypeInfo::TEXT, not PgTypeInfo::with_name("tea"). So compatible() sees "TEXT" != "tea" and so fails.
This fix detects PgTypeKind::Enum at runtime and calls try_get_unchecked to bypass that check.

The proper compile-time fix would be:

The DeriveActiveEnum macro should generate an additional impl when db_type = "Enum" (it's a native PG enum, not a String enum):

  // So, for sqlx-postgres only, when db_type = "Enum":
  #[cfg(feature = "sqlx-postgres")]
  impl sqlx::Type<sqlx::Postgres> for Tea {
      fn type_info() -> sqlx::postgres::PgTypeInfo {
          sqlx::postgres::PgTypeInfo::with_name("tea") 
      }
  }

  #[cfg(feature = "sqlx-postgres")]
  impl<'r> sqlx::Decode<'r, sqlx::Postgres> for Tea {
      fn decode(value: sqlx::postgres::PgValueRef<'r>) -> Result<Self, ...> {
          let s = <&str as sqlx::Decode<sqlx::Postgres>>::decode(value)?;
          Tea::try_from_value(&s.to_owned()).map_err(|e| e.to_string().into())
      }
  }

And then TryGetable for Tea on postgres would call row.try_get::() directly without string intermediate. No runtime check, no try_get_unchecked.

@sinder38 sinder38 changed the title Fix Postgres decoding for ActiveEnum Quick Fix: Postgres decoding for ActiveEnum rs_type Text Mar 18, 2026
@Huliiiiii
Copy link
Member

Yes, I’m trying this solution.

@Huliiiiii
Copy link
Member

The fix has been added in #2955.

@Huliiiiii Huliiiiii closed this Mar 19, 2026
@sinder38 sinder38 deleted the fix/pg-enum-decoding branch March 19, 2026 14:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Returning model with enum field with find_by_statement

2 participants