Re: [WIP] UNNEST(REFCURSOR): allowing SELECT to consume data from aREFCURSOR - Mailing list pgsql-hackers

From Dent John
Subject Re: [WIP] UNNEST(REFCURSOR): allowing SELECT to consume data from aREFCURSOR
Date
Msg-id E0211DFA-37B7-43B7-9EDF-DEE1ACE041DF@QQdd.eu
Whole thread Raw
In response to Re: [WIP] UNNEST(REFCURSOR): allowing SELECT to consume data from a REFCURSOR  ("Daniel Verite" <daniel@manitou-mail.org>)
List pgsql-hackers
> On 14 Jan 2020, at 14:53, Daniel Verite <daniel@manitou-mail.org> wrote:
>
> What is the expected result anyway? A single column with a "record"
> type? FWIW I notice that with plpgsql, this is not allowed to happen:

Hmm. How interesting.

I had not really investigated what happens in the case of a function returning SETOF (untyped) RECORD in a SELECT
clausebecause, whatever the result, there’s no mechanism to access the individual fields. 

As you highlight, it doesn’t work at all in plpgsql, and plperl is the same.

However, SQL language functions get away with it. For example, inspired by _pg_expandarray():

CREATE OR REPLACE FUNCTION public.my_pg_expandarray(anyarray)
RETURNS SETOF record
LANGUAGE sql
IMMUTABLE PARALLEL SAFE STRICT
AS $function$
    select $1[s], s - pg_catalog.array_lower($1,1) + 1
        from pg_catalog.generate_series(pg_catalog.array_lower($1,1),
            pg_catalog.array_upper($1,1), 1) as g(s)
$function$

postgres=# select my_pg_expandarray (array[0, 1, 2, 3, 4]);
 my_pg_expandarray
-------------------
 (0,1)
 (1,2)
 (2,3)
 (3,4)
 (4,5)
(5 rows)

Back in the FROM clause, it’s possible to manipulate the individual fields:

postgres=# select b, a from my_pg_expandarray (array[0, 1, 2, 3, 4]) as r(a int, b int);
 b | a
---+---
 1 | 0
 2 | 1
 3 | 2
 4 | 3
 5 | 4
(5 rows)

It’s quite interesting. All the other PLs make explicit checks for rsinfo.expectedDesc being non-NULL, but fmgr_sql()
explicitlycalls out the contrary: “[…] note we do not require caller to provide an expectedDesc.” So I guess either
there’ssomething special about the SQL PL, or perhaps the other PLs are just inheriting a pattern of being cautious. 

Either way, though, there’s no way that I can see to "get at” the fields inside the anonymous record that is returned
whenthe function is in the SELECT list. 

But back to the failure, I still need to make it not crash. I guess it doesn’t matter whether I simply refuse to work
ifcalled from the SELECT list, or just return an anonymous record, like fmgr_sql() does. 

d.


pgsql-hackers by date:

Previous
From: Tom Lane
Date:
Subject: Re: Patch to document base64 encoding
Next
From: Bruce Momjian
Date:
Subject: Re: Decade indication