Skip to content

Commit a380f4d

Browse files
committed
feat(Postgres): support nested domain types
1 parent 1678b19 commit a380f4d

File tree

3 files changed

+44
-1
lines changed

3 files changed

+44
-1
lines changed

sqlx-postgres/src/type_info.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1013,7 +1013,7 @@ impl PgType {
10131013
/// If `soft_eq` is true and `self` or `other` is `DeclareWithOid` but not both, return `true`
10141014
/// before checking names.
10151015
fn eq_impl(&self, other: &Self, soft_eq: bool) -> bool {
1016-
if let (Some(a), Some(b)) = (self.try_oid(), other.try_oid()) {
1016+
if let (Some(a), Some(b)) = (self.base_oid(), other.base_oid()) {
10171017
// If there are OIDs available, use OIDs to perform a direct match
10181018
return a == b;
10191019
}
@@ -1035,6 +1035,17 @@ impl PgType {
10351035
// Otherwise, perform a match on the name
10361036
name_eq(self.name(), other.name())
10371037
}
1038+
1039+
// Returns the OID of the type, returns the OID of the base_type for Domain types
1040+
fn base_oid(&self) -> Option<Oid> {
1041+
match self {
1042+
PgType::Custom(custom) => match &custom.kind {
1043+
PgTypeKind::Domain(domain) => domain.base_oid(),
1044+
_ => Some(custom.oid),
1045+
},
1046+
ty => ty.try_oid(),
1047+
}
1048+
}
10381049
}
10391050

10401051
impl TypeInfo for PgTypeInfo {

tests/postgres/setup.sql

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,12 @@ CREATE SCHEMA IF NOT EXISTS foo;
6363
CREATE TYPE foo."Foo" as ENUM ('Bar', 'Baz');
6464

6565
CREATE TABLE mytable(f HSTORE);
66+
67+
CREATE DOMAIN positive_int AS integer CHECK (VALUE >= 0);
68+
CREATE DOMAIN percentage AS positive_int CHECK (VALUE < 100);
69+
70+
CREATE TYPE person as (
71+
id int,
72+
age positive_int,
73+
percent percentage
74+
);

tests/postgres/types.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,3 +657,26 @@ CREATE TEMPORARY TABLE user_login (
657657

658658
Ok(())
659659
}
660+
661+
#[sqlx_macros::test]
662+
async fn test_nested_domain_types() -> anyhow::Result<()> {
663+
#[derive(sqlx::Type)]
664+
struct Person {
665+
id: i32,
666+
age: i32,
667+
percent: i32,
668+
}
669+
670+
let mut conn = new::<Postgres>().await?;
671+
672+
let p: Person = sqlx::query_scalar("select ROW(1, 21::positive_int, 50::percentage)::person")
673+
.fetch_one(&mut conn)
674+
.await
675+
.unwrap();
676+
677+
assert!(p.id == 1);
678+
assert!(p.age == 21);
679+
assert!(p.percent == 50);
680+
681+
Ok(())
682+
}

0 commit comments

Comments
 (0)