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