Re: [HACKERS] cache lookup error for shell type creation with incompatible output function (DDL deparsing bug)

2015-04-22 Thread Alvaro Herrera
Michael Paquier wrote:
 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

Argh.

 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.

Thanks, pushed.  I changed the line to be just below TypeShellMake,
which seems slightly better aligned to the comment just below, and in
fact it matches what DefineRange already uses.  I also modified a couple
of other places involving TypeCreate: one did not have the typoid =
addr.objectId assignment at all; while the other did, it actually seems
misplaced because at that spot we expect that typoid is already correct.
So I added an assert to the other place and changed that assignment to
an assert, too.

I scanned the rest of the bogus commit and couldn't find any other place
on which I made the same mistake.

Thanks for reporting,

-- 
Álvaro Herrerahttp://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training  Services


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] cache lookup error for shell type creation with incompatible output function (DDL deparsing bug)

2015-04-22 Thread Alvaro Herrera
Alvaro Herrera wrote:
 Michael Paquier wrote:
  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

I also wanted to point out, but forgot, that this command is not really
creating a shell type -- it's creating a full-blown type, because there
are args.  Shell types are created when no args are given.  This happens
to fail due to the internal creation of the shell type because of the
failure to look up the i/o functions, but as far as I can see the
original code should fail in any type creation in pretty much the same
way (didn't actually test that); not completely sure why this wasn't
more visible in regression tests.

I simply removed the word shell in the provided test case in the
committed version, anyway.

-- 
Álvaro Herrerahttp://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training  Services


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


[HACKERS] cache lookup error for shell type creation with incompatible output function (DDL deparsing bug)

2015-03-29 Thread Michael Paquier
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