mirror of
https://github.com/jackc/pgx.git
synced 2025-05-25 00:40:04 +00:00
Prefix types in namespaces other than pg_catalog or public
It's possible to define a type (e.g., an enum) with the same name in two different schemas. When initializing data types after connecting, types defined within schemas other than pg_catalog or public should be qualified with their schema name to disambiguate them and ensure all types with the same base name get added to the map of OID to type. Prior to this commit, the last type scanned would "win", and all others with the same name would be missing from the ConnInfo type maps, which would subsequently cause any PREPARE involving columns of those missing types to return the error "unknown oid".
This commit is contained in:
parent
b70fb1c7cf
commit
953e08df99
6
conn.go
6
conn.go
@ -384,9 +384,13 @@ func (c *Conn) connect(config ConnConfig, network, address string, tlsConfig *tl
|
|||||||
func (c *Conn) initConnInfo() error {
|
func (c *Conn) initConnInfo() error {
|
||||||
nameOIDs := make(map[string]pgtype.OID, 256)
|
nameOIDs := make(map[string]pgtype.OID, 256)
|
||||||
|
|
||||||
rows, err := c.Query(`select t.oid, t.typname
|
rows, err := c.Query(`select t.oid,
|
||||||
|
case when nsp.nspname in ('pg_catalog', 'public') then t.typname
|
||||||
|
else nsp.nspname||'.'||t.typname
|
||||||
|
end
|
||||||
from pg_type t
|
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_namespace nsp on t.typnamespace=nsp.oid
|
||||||
where (
|
where (
|
||||||
t.typtype in('b', 'p', 'r', 'e')
|
t.typtype in('b', 'p', 'r', 'e')
|
||||||
and (base_type.oid is null or base_type.typtype in('b', 'p', 'r'))
|
and (base_type.oid is null or base_type.typtype in('b', 'p', 'r'))
|
||||||
|
28
conn_test.go
28
conn_test.go
@ -1953,3 +1953,31 @@ end$$;`)
|
|||||||
|
|
||||||
ensureConnValid(t, conn)
|
ensureConnValid(t, conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestConnInitConnInfo(t *testing.T) {
|
||||||
|
conn := mustConnect(t, *defaultConnConfig)
|
||||||
|
defer closeConn(t, conn)
|
||||||
|
|
||||||
|
// spot check that the standard postgres type names aren't qualified
|
||||||
|
nameOIDs := map[string]pgtype.OID{
|
||||||
|
"_int8": pgtype.Int8ArrayOID,
|
||||||
|
"int8": pgtype.Int8OID,
|
||||||
|
"json": pgtype.JSONOID,
|
||||||
|
"text": pgtype.TextOID,
|
||||||
|
}
|
||||||
|
for name, oid := range nameOIDs {
|
||||||
|
dtByName, ok := conn.ConnInfo.DataTypeForName(name)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("Expected type named %v to be present", name)
|
||||||
|
}
|
||||||
|
dtByOID, ok := conn.ConnInfo.DataTypeForOID(oid)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("Expected type OID %v to be present", oid)
|
||||||
|
}
|
||||||
|
if dtByName != dtByOID {
|
||||||
|
t.Fatalf("Expected type named %v to be the same as type OID %v", name, oid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ensureConnValid(t, conn)
|
||||||
|
}
|
||||||
|
@ -204,7 +204,17 @@ func AcceptUnauthenticatedConnRequestSteps() []Step {
|
|||||||
func PgxInitSteps() []Step {
|
func PgxInitSteps() []Step {
|
||||||
steps := []Step{
|
steps := []Step{
|
||||||
ExpectMessage(&pgproto3.Parse{
|
ExpectMessage(&pgproto3.Parse{
|
||||||
Query: "select t.oid, t.typname\nfrom pg_type t\nleft join pg_type base_type on t.typelem=base_type.oid\nwhere (\n\t t.typtype in('b', 'p', 'r', 'e')\n\t and (base_type.oid is null or base_type.typtype in('b', 'p', 'r'))\n\t)",
|
Query: `select t.oid,
|
||||||
|
case when nsp.nspname in ('pg_catalog', 'public') then t.typname
|
||||||
|
else nsp.nspname||'.'||t.typname
|
||||||
|
end
|
||||||
|
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
|
||||||
|
where (
|
||||||
|
t.typtype in('b', 'p', 'r', 'e')
|
||||||
|
and (base_type.oid is null or base_type.typtype in('b', 'p', 'r'))
|
||||||
|
)`,
|
||||||
}),
|
}),
|
||||||
ExpectMessage(&pgproto3.Describe{
|
ExpectMessage(&pgproto3.Describe{
|
||||||
ObjectType: 'S',
|
ObjectType: 'S',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user