mirror of https://github.com/jackc/pgx.git
Merge pull request #556 from DavidArchibald/composite
Register composite types as a `pgtype.Record`.pull/598/head
commit
856c67a8c8
48
conn.go
48
conn.go
|
@ -613,12 +613,9 @@ from pg_type t
|
|||
left join pg_type base_type on t.typelem=base_type.oid
|
||||
left join pg_class base_cls ON base_type.typrelid = base_cls.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')
|
||||
and (base_type.oid is null or base_type.typtype in('b', 'p', 'r', 'c'))
|
||||
and (cls.oid is null or cls.relkind='c')
|
||||
and (base_cls.oid is null or base_cls.relkind = 'c')
|
||||
t.typtype in('b', 'p', 'r', 'e')
|
||||
and (base_type.oid is null or base_type.typtype in('b', 'p', 'r'))
|
||||
)`
|
||||
)
|
||||
|
||||
|
@ -638,6 +635,10 @@ where (
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if err = c.initConnInfoComposite(cinfo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return cinfo, nil
|
||||
}
|
||||
|
||||
|
@ -750,6 +751,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
|
||||
|
|
|
@ -212,12 +212,9 @@ from pg_type t
|
|||
left join pg_type base_type on t.typelem=base_type.oid
|
||||
left join pg_class base_cls ON base_type.typrelid = base_cls.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')
|
||||
and (base_type.oid is null or base_type.typtype in('b', 'p', 'r', 'c'))
|
||||
and (cls.oid is null or cls.relkind='c')
|
||||
and (base_cls.oid is null or base_cls.relkind = 'c')
|
||||
t.typtype in('b', 'p', 'r', 'e')
|
||||
and (base_type.oid is null or base_type.typtype in('b', 'p', 'r'))
|
||||
)`,
|
||||
}),
|
||||
ExpectMessage(&pgproto3.Describe{
|
||||
|
@ -532,6 +529,47 @@ where (
|
|||
SendMessage(&pgproto3.ReadyForQuery{TxStatus: 'I'}),
|
||||
}...)
|
||||
|
||||
steps = append(steps, []Step{
|
||||
ExpectMessage(&pgproto3.Parse{
|
||||
Query: "select t.oid, t.typname\nfrom pg_type t\n\tjoin pg_class cls on t.typrelid=cls.oid\nwhere t.typtype = 'c'\n\tand cls.relkind='c'",
|
||||
}),
|
||||
ExpectMessage(&pgproto3.Describe{
|
||||
ObjectType: 'S',
|
||||
}),
|
||||
ExpectMessage(&pgproto3.Sync{}),
|
||||
SendMessage(&pgproto3.ParseComplete{}),
|
||||
SendMessage(&pgproto3.ParameterDescription{}),
|
||||
SendMessage(&pgproto3.RowDescription{
|
||||
Fields: []pgproto3.FieldDescription{
|
||||
{Name: "oid",
|
||||
TableOID: 1247,
|
||||
TableAttributeNumber: 65534,
|
||||
DataTypeOID: 26,
|
||||
DataTypeSize: 4,
|
||||
TypeModifier: -1,
|
||||
Format: 0,
|
||||
},
|
||||
{Name: "typname",
|
||||
TableOID: 1247,
|
||||
TableAttributeNumber: 1,
|
||||
DataTypeOID: 19,
|
||||
DataTypeSize: 64,
|
||||
TypeModifier: -1,
|
||||
Format: 0,
|
||||
},
|
||||
},
|
||||
}),
|
||||
SendMessage(&pgproto3.ReadyForQuery{TxStatus: 'I'}),
|
||||
ExpectMessage(&pgproto3.Bind{
|
||||
ResultFormatCodes: []int16{1, 1},
|
||||
}),
|
||||
ExpectMessage(&pgproto3.Execute{}),
|
||||
ExpectMessage(&pgproto3.Sync{}),
|
||||
SendMessage(&pgproto3.BindComplete{}),
|
||||
SendMessage(&pgproto3.CommandComplete{CommandTag: "SELECT 0"}),
|
||||
SendMessage(&pgproto3.ReadyForQuery{TxStatus: 'I'}),
|
||||
}...)
|
||||
|
||||
return steps
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue