]> granicus.if.org Git - postgresql/commitdiff
Fix *-qualification of named parameters in SQL-language functions.
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 3 Feb 2014 19:46:57 +0000 (14:46 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 3 Feb 2014 19:46:57 +0000 (14:46 -0500)
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
src/test/regress/expected/rowtypes.out
src/test/regress/sql/rowtypes.sql

index ef184b69e25a30e006a3ccbe1c45d6adf0b5bdcd..a94a53d5e48fc63d66ebd182aa12f6e3a505c297 100644 (file)
@@ -309,6 +309,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);
@@ -316,6 +321,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);
index e4b67e7c771c7b5695934ebb9b9af96ff856b015..5616d6f7f2ad0f9c6106ddac4e70256002a95b1f 100644 (file)
@@ -383,6 +383,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
index 3e0f156945335e44a8fee474a9dea95d29fd0043..65ebdc566abf455187096439ef5c9c031a600257 100644 (file)
@@ -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