Skip to content

Commit 888b565

Browse files
committed
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 9bff078, so patch back to 9.2. Per bug #9085 from Hardy Falk.
1 parent c077029 commit 888b565

File tree

3 files changed

+83
-0
lines changed

3 files changed

+83
-0
lines changed

src/backend/executor/functions.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,13 +309,21 @@ sql_fn_post_column_ref(ParseState *pstate, ColumnRef *cref, Node *var)
309309
* (the first possibility takes precedence)
310310
* A.B.C A = function name, B = record-typed parameter name,
311311
* C = field name
312+
* A.* Whole-row reference to composite parameter A.
313+
* A.B.* Same, with A = function name, B = parameter name
314+
*
315+
* Here, it's sufficient to ignore the "*" in the last two cases --- the
316+
* main parser will take care of expanding the whole-row reference.
312317
*----------
313318
*/
314319
nnames = list_length(cref->fields);
315320

316321
if (nnames > 3)
317322
return NULL;
318323

324+
if (IsA(llast(cref->fields), A_Star))
325+
nnames--;
326+
319327
field1 = (Node *) linitial(cref->fields);
320328
Assert(IsA(field1, String));
321329
name1 = strVal(field1);

src/test/regress/expected/rowtypes.out

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,53 @@ select * from price;
383383
(3 rows)
384384

385385
rollback;
386+
--
387+
-- Test case derived from bug #9085: check * qualification of composite
388+
-- parameters for SQL functions
389+
--
390+
create temp table compos (f1 int, f2 text);
391+
create function fcompos1(v compos) returns void as $$
392+
insert into compos values (v); -- fail
393+
$$ language sql;
394+
ERROR: column "f1" is of type integer but expression is of type compos
395+
LINE 2: insert into compos values (v); -- fail
396+
^
397+
HINT: You will need to rewrite or cast the expression.
398+
create function fcompos1(v compos) returns void as $$
399+
insert into compos values (v.*);
400+
$$ language sql;
401+
create function fcompos2(v compos) returns void as $$
402+
select fcompos1(v);
403+
$$ language sql;
404+
create function fcompos3(v compos) returns void as $$
405+
select fcompos1(fcompos3.v.*);
406+
$$ language sql;
407+
select fcompos1(row(1,'one'));
408+
fcompos1
409+
----------
410+
411+
(1 row)
412+
413+
select fcompos2(row(2,'two'));
414+
fcompos2
415+
----------
416+
417+
(1 row)
418+
419+
select fcompos3(row(3,'three'));
420+
fcompos3
421+
----------
422+
423+
(1 row)
424+
425+
select * from compos;
426+
f1 | f2
427+
----+-------
428+
1 | one
429+
2 | two
430+
3 | three
431+
(3 rows)
432+
386433
--
387434
-- We allow I/O conversion casts from composite types to strings to be
388435
-- invoked via cast syntax, but not functional syntax. This is because

src/test/regress/sql/rowtypes.sql

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,34 @@ select * from price;
185185

186186
rollback;
187187

188+
--
189+
-- Test case derived from bug #9085: check * qualification of composite
190+
-- parameters for SQL functions
191+
--
192+
193+
create temp table compos (f1 int, f2 text);
194+
195+
create function fcompos1(v compos) returns void as $$
196+
insert into compos values (v); -- fail
197+
$$ language sql;
198+
199+
create function fcompos1(v compos) returns void as $$
200+
insert into compos values (v.*);
201+
$$ language sql;
202+
203+
create function fcompos2(v compos) returns void as $$
204+
select fcompos1(v);
205+
$$ language sql;
206+
207+
create function fcompos3(v compos) returns void as $$
208+
select fcompos1(fcompos3.v.*);
209+
$$ language sql;
210+
211+
select fcompos1(row(1,'one'));
212+
select fcompos2(row(2,'two'));
213+
select fcompos3(row(3,'three'));
214+
select * from compos;
215+
188216
--
189217
-- We allow I/O conversion casts from composite types to strings to be
190218
-- invoked via cast syntax, but not functional syntax. This is because

0 commit comments

Comments
 (0)