Merge pull request #556 from DavidArchibald/composite

Register composite types as a `pgtype.Record`.
pull/598/head
Jack Christensen 2019-09-09 21:27:47 -05:00 committed by GitHub
commit 856c67a8c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 86 additions and 10 deletions

48
conn.go
View File

@ -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

View File

@ -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
}