diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/commands/functioncmds.c | 32 | ||||
-rw-r--r-- | src/test/regress/expected/create_type.out | 31 | ||||
-rw-r--r-- | src/test/regress/sql/create_type.sql | 17 |
3 files changed, 80 insertions, 0 deletions
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index 53c4ab359d..93d1065198 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -1189,6 +1189,8 @@ SetFunctionReturnType(Oid funcOid, Oid newRetType) Relation pg_proc_rel; HeapTuple tup; Form_pg_proc procForm; + ObjectAddress func_address; + ObjectAddress type_address; pg_proc_rel = heap_open(ProcedureRelationId, RowExclusiveLock); @@ -1209,6 +1211,20 @@ SetFunctionReturnType(Oid funcOid, Oid newRetType) CatalogUpdateIndexes(pg_proc_rel, tup); heap_close(pg_proc_rel, RowExclusiveLock); + + /* + * Also update the dependency to the new type. Opaque is a pinned type, so + * there is no old dependency record for it that we would need to remove. + */ + type_address.classId = TypeRelationId; + type_address.objectId = newRetType; + type_address.objectSubId = 0; + + func_address.classId = ProcedureRelationId; + func_address.objectId = funcOid; + func_address.objectSubId = 0; + + recordDependencyOn(&func_address, &type_address, DEPENDENCY_NORMAL); } @@ -1223,6 +1239,8 @@ SetFunctionArgType(Oid funcOid, int argIndex, Oid newArgType) Relation pg_proc_rel; HeapTuple tup; Form_pg_proc procForm; + ObjectAddress func_address; + ObjectAddress type_address; pg_proc_rel = heap_open(ProcedureRelationId, RowExclusiveLock); @@ -1244,6 +1262,20 @@ SetFunctionArgType(Oid funcOid, int argIndex, Oid newArgType) CatalogUpdateIndexes(pg_proc_rel, tup); heap_close(pg_proc_rel, RowExclusiveLock); + + /* + * Also update the dependency to the new type. Opaque is a pinned type, so + * there is no old dependency record for it that we would need to remove. + */ + type_address.classId = TypeRelationId; + type_address.objectId = newArgType; + type_address.objectSubId = 0; + + func_address.classId = ProcedureRelationId; + func_address.objectId = funcOid; + func_address.objectSubId = 0; + + recordDependencyOn(&func_address, &type_address, DEPENDENCY_NORMAL); } diff --git a/src/test/regress/expected/create_type.out b/src/test/regress/expected/create_type.out index 09459adc3f..670b03c624 100644 --- a/src/test/regress/expected/create_type.out +++ b/src/test/regress/expected/create_type.out @@ -109,6 +109,37 @@ 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 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 dependency transfer of opaque functions when creating a new type +CREATE FUNCTION base_fn_in(cstring) RETURNS opaque AS 'boolin' + LANGUAGE internal IMMUTABLE STRICT; +CREATE FUNCTION base_fn_out(opaque) RETURNS opaque AS 'boolout' + LANGUAGE internal IMMUTABLE STRICT; +CREATE TYPE base_type(INPUT = base_fn_in, OUTPUT = base_fn_out); +WARNING: changing argument type of function base_fn_out from "opaque" to base_type +WARNING: changing return type of function base_fn_in from "opaque" to base_type +WARNING: changing return type of function base_fn_out from "opaque" to "cstring" +DROP FUNCTION base_fn_in(cstring); -- error +ERROR: cannot drop function base_fn_in(cstring) because other objects depend on it +DETAIL: type base_type depends on function base_fn_in(cstring) +function base_fn_out(base_type) depends on type base_type +HINT: Use DROP ... CASCADE to drop the dependent objects too. +DROP FUNCTION base_fn_out(opaque); -- error +ERROR: function base_fn_out(opaque) does not exist +DROP TYPE base_type; -- error +ERROR: cannot drop type base_type because other objects depend on it +DETAIL: function base_fn_out(base_type) depends on type base_type +function base_fn_in(cstring) depends on type base_type +HINT: Use DROP ... CASCADE to drop the dependent objects too. +DROP TYPE base_type CASCADE; +NOTICE: drop cascades to 2 other objects +DETAIL: drop cascades to function base_fn_out(base_type) +drop cascades to function base_fn_in(cstring) -- 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 62bd53cfba..7297c077df 100644 --- a/src/test/regress/sql/create_type.sql +++ b/src/test/regress/sql/create_type.sql @@ -109,6 +109,23 @@ DROP TYPE default_test_row CASCADE; DROP TABLE default_test; +-- Check type create with input/output incompatibility +CREATE TYPE not_existing_type (INPUT = array_in, + OUTPUT = array_out, + ELEMENT = int, + INTERNALLENGTH = 32); + +-- Check dependency transfer of opaque functions when creating a new type +CREATE FUNCTION base_fn_in(cstring) RETURNS opaque AS 'boolin' + LANGUAGE internal IMMUTABLE STRICT; +CREATE FUNCTION base_fn_out(opaque) RETURNS opaque AS 'boolout' + LANGUAGE internal IMMUTABLE STRICT; +CREATE TYPE base_type(INPUT = base_fn_in, OUTPUT = base_fn_out); +DROP FUNCTION base_fn_in(cstring); -- error +DROP FUNCTION base_fn_out(opaque); -- error +DROP TYPE base_type; -- error +DROP TYPE base_type CASCADE; + -- Check usage of typmod with a user-defined type -- (we have borrowed numeric's typmod functions) |