Hi all, I just bumped into the following problem in HEAD (1c41e2a): =# create type my_array_float (INPUT = array_in, OUTPUT = array_out, ELEMENT = float4, INTERNALLENGTH = 32); ERROR: XX000: cache lookup failed for type 0 LOCATION: format_type_internal, format_type.c:135
First note that in ~9.4 the error message is correct: =# create type my_array_float (INPUT = array_in, OUTPUT = array_out, ELEMENT = float4, INTERNALLENGTH = 32); ERROR: 42883: function array_out(my_array_float) does not exist LOCATION: findTypeOutputFunction, typecmds.c:1709 Now, the problem is caused by findTypeOutputFunction() in DefineType() because process passes InvalidOid as type OID when creating a type shell, root cause being a2e35b5 because of this: + address = TypeShellMake(typeName, typeNamespace, GetUserId()); The fix consists in being sure that typoid uses the OID of the type shell created, aka the OID stored in adress.ObjectID. Attached is a patch with a regression test checking for shell creation with incompatible input/output functions (failure caused by output function here though) able to check this code path. Regards, -- Michael
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index 67e2ae2..37bcd53 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -217,6 +217,7 @@ DefineType(List *names, List *parameters) address = TypeShellMake(typeName, typeNamespace, GetUserId()); /* Make new shell type visible for modification below */ CommandCounterIncrement(); + typoid = address.objectId; /* * If the command was a parameterless CREATE TYPE, we're done --- @@ -1720,6 +1721,8 @@ findTypeOutputFunction(List *procname, Oid typeOid) if (OidIsValid(procOid)) return procOid; + Assert(OidIsValid(typeOid)); + /* No luck, try it with OPAQUE */ argList[0] = OPAQUEOID; diff --git a/src/test/regress/expected/create_type.out b/src/test/regress/expected/create_type.out index 35e8f5d..3646c2b 100644 --- a/src/test/regress/expected/create_type.out +++ b/src/test/regress/expected/create_type.out @@ -107,6 +107,12 @@ ERROR: type "text_w_default" already exists DROP TYPE default_test_row CASCADE; NOTICE: drop cascades to function get_default_test() DROP TABLE default_test; +-- Check shell type create with input/output incompatibility +CREATE TYPE not_existing_type (INPUT = array_in, + OUTPUT = array_out, + ELEMENT = int, + INTERNALLENGTH = 32); +ERROR: function array_out(not_existing_type) does not exist -- Check usage of typmod with a user-defined type -- (we have borrowed numeric's typmod functions) CREATE TEMP TABLE mytab (foo widget(42,13,7)); -- should fail diff --git a/src/test/regress/sql/create_type.sql b/src/test/regress/sql/create_type.sql index 96a075b..0c79050 100644 --- a/src/test/regress/sql/create_type.sql +++ b/src/test/regress/sql/create_type.sql @@ -106,6 +106,12 @@ DROP TYPE default_test_row CASCADE; DROP TABLE default_test; +-- Check shell type create with input/output incompatibility +CREATE TYPE not_existing_type (INPUT = array_in, + OUTPUT = array_out, + ELEMENT = int, + INTERNALLENGTH = 32); + -- Check usage of typmod with a user-defined type -- (we have borrowed numeric's typmod functions)
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers