From 0def2573c5f0ff127d0c7dc12ec7da56ae6fb7fe Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 3 Feb 2014 14:46:51 -0500 Subject: [PATCH] Fix *-qualification of named parameters in SQL-language functions. Given a composite-type parameter named x, "$1.*" worked fine, but "x.*" not so much. This has been broken since named parameter references were added in commit 9bff0780cf5be2193a5bad0d3df2dbe143085264, so patch back to 9.2. Per bug #9085 from Hardy Falk. --- src/backend/executor/functions.c | 8 +++++ src/test/regress/expected/rowtypes.out | 47 ++++++++++++++++++++++++++ src/test/regress/sql/rowtypes.sql | 28 +++++++++++++++ 3 files changed, 83 insertions(+) diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c index 9c179707f4..b5af19acf1 100644 --- a/src/backend/executor/functions.c +++ b/src/backend/executor/functions.c @@ -310,6 +310,11 @@ sql_fn_post_column_ref(ParseState *pstate, ColumnRef *cref, Node *var) * (the first possibility takes precedence) * A.B.C A = function name, B = record-typed parameter name, * C = field name + * A.* Whole-row reference to composite parameter A. + * A.B.* Same, with A = function name, B = parameter name + * + * Here, it's sufficient to ignore the "*" in the last two cases --- the + * main parser will take care of expanding the whole-row reference. *---------- */ nnames = list_length(cref->fields); @@ -317,6 +322,9 @@ sql_fn_post_column_ref(ParseState *pstate, ColumnRef *cref, Node *var) if (nnames > 3) return NULL; + if (IsA(llast(cref->fields), A_Star)) + nnames--; + field1 = (Node *) linitial(cref->fields); Assert(IsA(field1, String)); name1 = strVal(field1); diff --git a/src/test/regress/expected/rowtypes.out b/src/test/regress/expected/rowtypes.out index e3ec9cde62..88e7bfab84 100644 --- a/src/test/regress/expected/rowtypes.out +++ b/src/test/regress/expected/rowtypes.out @@ -381,6 +381,53 @@ select * from price; (3 rows) rollback; +-- +-- Test case derived from bug #9085: check * qualification of composite +-- parameters for SQL functions +-- +create temp table compos (f1 int, f2 text); +create function fcompos1(v compos) returns void as $$ +insert into compos values (v); -- fail +$$ language sql; +ERROR: column "f1" is of type integer but expression is of type compos +LINE 2: insert into compos values (v); -- fail + ^ +HINT: You will need to rewrite or cast the expression. +create function fcompos1(v compos) returns void as $$ +insert into compos values (v.*); +$$ language sql; +create function fcompos2(v compos) returns void as $$ +select fcompos1(v); +$$ language sql; +create function fcompos3(v compos) returns void as $$ +select fcompos1(fcompos3.v.*); +$$ language sql; +select fcompos1(row(1,'one')); + fcompos1 +---------- + +(1 row) + +select fcompos2(row(2,'two')); + fcompos2 +---------- + +(1 row) + +select fcompos3(row(3,'three')); + fcompos3 +---------- + +(1 row) + +select * from compos; + f1 | f2 +----+------- + 1 | one + 2 | two + 3 | three +(3 rows) + -- -- We allow I/O conversion casts from composite types to strings to be -- invoked via cast syntax, but not functional syntax. This is because diff --git a/src/test/regress/sql/rowtypes.sql b/src/test/regress/sql/rowtypes.sql index 3e0f156945..65ebdc566a 100644 --- a/src/test/regress/sql/rowtypes.sql +++ b/src/test/regress/sql/rowtypes.sql @@ -185,6 +185,34 @@ select * from price; rollback; +-- +-- Test case derived from bug #9085: check * qualification of composite +-- parameters for SQL functions +-- + +create temp table compos (f1 int, f2 text); + +create function fcompos1(v compos) returns void as $$ +insert into compos values (v); -- fail +$$ language sql; + +create function fcompos1(v compos) returns void as $$ +insert into compos values (v.*); +$$ language sql; + +create function fcompos2(v compos) returns void as $$ +select fcompos1(v); +$$ language sql; + +create function fcompos3(v compos) returns void as $$ +select fcompos1(fcompos3.v.*); +$$ language sql; + +select fcompos1(row(1,'one')); +select fcompos2(row(2,'two')); +select fcompos3(row(3,'three')); +select * from compos; + -- -- We allow I/O conversion casts from composite types to strings to be -- invoked via cast syntax, but not functional syntax. This is because