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_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_class base_cls ON base_type.typrelid = base_cls.oid
|
||||||
left join pg_namespace nsp on t.typnamespace=nsp.oid
|
left join pg_namespace nsp on t.typnamespace=nsp.oid
|
||||||
left join pg_class cls on t.typrelid=cls.oid
|
|
||||||
where (
|
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', 'c'))
|
and (base_type.oid is null or base_type.typtype in('b', 'p', 'r'))
|
||||||
and (cls.oid is null or cls.relkind='c')
|
|
||||||
and (base_cls.oid is null or base_cls.relkind = 'c')
|
|
||||||
)`
|
)`
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -638,6 +635,10 @@ where (
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err = c.initConnInfoComposite(cinfo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return cinfo, nil
|
return cinfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -750,6 +751,43 @@ where t.typtype = 'd'
|
||||||
return nil
|
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
|
// 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
|
// 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
|
// 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_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_class base_cls ON base_type.typrelid = base_cls.oid
|
||||||
left join pg_namespace nsp on t.typnamespace=nsp.oid
|
left join pg_namespace nsp on t.typnamespace=nsp.oid
|
||||||
left join pg_class cls on t.typrelid=cls.oid
|
|
||||||
where (
|
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', 'c'))
|
and (base_type.oid is null or base_type.typtype in('b', 'p', 'r'))
|
||||||
and (cls.oid is null or cls.relkind='c')
|
|
||||||
and (base_cls.oid is null or base_cls.relkind = 'c')
|
|
||||||
)`,
|
)`,
|
||||||
}),
|
}),
|
||||||
ExpectMessage(&pgproto3.Describe{
|
ExpectMessage(&pgproto3.Describe{
|
||||||
|
@ -532,6 +529,47 @@ where (
|
||||||
SendMessage(&pgproto3.ReadyForQuery{TxStatus: 'I'}),
|
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
|
return steps
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue