diff --git a/conn.go b/conn.go index 0cf6c167..b613707e 100644 --- a/conn.go +++ b/conn.go @@ -404,11 +404,9 @@ func initPostgresql(c *Conn) (*pgtype.ConnInfo, error) { from pg_type t left join pg_type base_type on t.typelem=base_type.oid left join pg_namespace nsp on t.typnamespace=nsp.oid -left join pg_class cls on t.typrelid=cls.oid where ( - t.typtype in('b', 'p', 'r', 'e', 'c') + t.typtype in('b', 'p', 'r', 'e') and (base_type.oid is null or base_type.typtype in('b', 'p', 'r')) - and (cls.oid is null or cls.relkind='c') )` ) @@ -428,6 +426,10 @@ where ( return nil, err } + if err = c.initConnInfoComposite(cinfo); err != nil { + return nil, err + } + return cinfo, nil } @@ -540,6 +542,43 @@ where t.typtype = 'd' return nil } +func (c *Conn) initConnInfoComposite(cinfo *pgtype.ConnInfo) error { + nameOIDs := make(map[string]pgtype.OID, 1) + + rows, err := c.Query(`select t.oid, t.typname +from pg_type t + join pg_class cls on t.typrelid=cls.oid +where t.typtype = 'c' + and cls.relkind='c'`) + if err != nil { + return err + } + + for rows.Next() { + var oid pgtype.OID + var name pgtype.Text + if err := rows.Scan(&oid, &name); err != nil { + return err + } + + nameOIDs[name.String] = oid + } + + if rows.Err() != nil { + return rows.Err() + } + + for name, oid := range nameOIDs { + cinfo.RegisterDataType(pgtype.DataType{ + Value: &pgtype.Record{}, + Name: name, + OID: oid, + }) + } + + return nil +} + // crateDBTypesQuery checks if the given err is likely to be the result of // CrateDB not implementing the pg_types table correctly. If yes, a CrateDB // specific query against pg_types is executed and its results are returned. If diff --git a/pgmock/pgmock.go b/pgmock/pgmock.go index d4ab0d13..4d15f7b8 100644 --- a/pgmock/pgmock.go +++ b/pgmock/pgmock.go @@ -211,11 +211,9 @@ func PgxInitSteps() []Step { from pg_type t left join pg_type base_type on t.typelem=base_type.oid left join pg_namespace nsp on t.typnamespace=nsp.oid -left join pg_class cls on t.typrelid=cls.oid where ( - t.typtype in('b', 'p', 'r', 'e', 'c') + t.typtype in('b', 'p', 'r', 'e') and (base_type.oid is null or base_type.typtype in('b', 'p', 'r')) - and (cls.oid is null or cls.relkind='c') )`, }), ExpectMessage(&pgproto3.Describe{