>From cc1776d4963b0ae837f61320ba36a6ff3ad7a7cb Mon Sep 17 00:00:00 2001 From: Jim Nasby Date: Mon, 27 Apr 2015 18:54:51 -0500 Subject: [PATCH] Allow SQL functions to accept a record --- src/backend/catalog/pg_proc.c | 10 +++++++--- src/test/regress/expected/create_function_3.out | 17 ++++++++++++++--- src/test/regress/sql/create_function_3.sql | 6 +++++- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c index 1229829..daf3297 100644 --- a/src/backend/catalog/pg_proc.c +++ b/src/backend/catalog/pg_proc.c @@ -870,14 +870,18 @@ fmgr_sql_validator(PG_FUNCTION_ARGS) errmsg("SQL functions cannot return type %s", format_type_be(proc->prorettype)))); - /* Disallow pseudotypes in arguments */ - /* except for polymorphic */ + /* + * Disallow pseudotypes in arguments except for polymorphic and record. In + * the context of validating a function, record may as well be polymorphic, + * so treat it as such. + */ haspolyarg = false; for (i = 0; i < proc->pronargs; i++) { if (get_typtype(proc->proargtypes.values[i]) == TYPTYPE_PSEUDO) { - if (IsPolymorphicType(proc->proargtypes.values[i])) + if (IsPolymorphicType(proc->proargtypes.values[i]) || + proc->proargtypes.values[i] == RECORDOID) haspolyarg = true; else ereport(ERROR, diff --git a/src/test/regress/expected/create_function_3.out b/src/test/regress/expected/create_function_3.out index 6a4352c..cd370e3 100644 --- a/src/test/regress/expected/create_function_3.out +++ b/src/test/regress/expected/create_function_3.out @@ -16,16 +16,26 @@ CREATE FUNCTION functest_A_2(text[]) RETURNS int LANGUAGE 'sql' AS 'SELECT $1[0]::int'; CREATE FUNCTION functest_A_3() RETURNS bool LANGUAGE 'sql' AS 'SELECT false'; +CREATE FUNCTION functest_A_4(record) RETURNS regtype LANGUAGE 'sql' + AS 'SELECT pg_catalog.pg_typeof($1)'; +SELECT functest_A_4(NULL::pg_catalog.pg_class); + functest_a_4 +-------------- + pg_class +(1 row) + SELECT proname, prorettype::regtype, proargtypes::regtype[] FROM pg_proc WHERE oid in ('functest_A_1'::regproc, 'functest_A_2'::regproc, - 'functest_A_3'::regproc) ORDER BY proname; + 'functest_A_3'::regproc, + 'functest_A_4'::regproc) ORDER BY proname; proname | prorettype | proargtypes --------------+------------+------------------- functest_a_1 | boolean | [0:1]={text,date} functest_a_2 | integer | [0:0]={text[]} functest_a_3 | boolean | {} -(3 rows) + functest_a_4 | regtype | [0:0]={record} +(4 rows) -- -- IMMUTABLE | STABLE | VOLATILE @@ -219,10 +229,11 @@ SELECT routine_name, ordinal_position, parameter_name, parameter_default -- Cleanups DROP SCHEMA temp_func_test CASCADE; -NOTICE: drop cascades to 19 other objects +NOTICE: drop cascades to 20 other objects DETAIL: drop cascades to function functest_a_1(text,date) drop cascades to function functest_a_2(text[]) drop cascades to function functest_a_3() +drop cascades to function functest_a_4(record) drop cascades to function functest_b_1(integer) drop cascades to function functest_b_2(integer) drop cascades to function functest_b_3(integer) diff --git a/src/test/regress/sql/create_function_3.sql b/src/test/regress/sql/create_function_3.sql index 86d69ba..1af911a 100644 --- a/src/test/regress/sql/create_function_3.sql +++ b/src/test/regress/sql/create_function_3.sql @@ -19,10 +19,14 @@ CREATE FUNCTION functest_A_2(text[]) RETURNS int LANGUAGE 'sql' AS 'SELECT $1[0]::int'; CREATE FUNCTION functest_A_3() RETURNS bool LANGUAGE 'sql' AS 'SELECT false'; +CREATE FUNCTION functest_A_4(record) RETURNS regtype LANGUAGE 'sql' + AS 'SELECT pg_catalog.pg_typeof($1)'; +SELECT functest_A_4(NULL::pg_catalog.pg_class); SELECT proname, prorettype::regtype, proargtypes::regtype[] FROM pg_proc WHERE oid in ('functest_A_1'::regproc, 'functest_A_2'::regproc, - 'functest_A_3'::regproc) ORDER BY proname; + 'functest_A_3'::regproc, + 'functest_A_4'::regproc) ORDER BY proname; -- -- IMMUTABLE | STABLE | VOLATILE -- 2.1.2