Re: dubious optimization of the function in SELECT INTO target list

From: Oleksii Kliukin <alexk(at)hintbits(dot)com>
To: Adrian Klaver <adrian(dot)klaver(at)aklaver(dot)com>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: dubious optimization of the function in SELECT INTO target list
Date: 2015-10-06 21:00:58
Message-ID: 58E91AD2-4DC4-482C-B4D9-DB179D1341A9@hintbits.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general


> On 06 Oct 2015, at 22:50, Adrian Klaver <adrian(dot)klaver(at)aklaver(dot)com> wrote:
>
> On 10/06/2015 01:48 PM, Oleksii Kliukin wrote:
>>
>>> On 06 Oct 2015, at 22:40, Adrian Klaver <adrian(dot)klaver(at)aklaver(dot)com <mailto:adrian(dot)klaver(at)aklaver(dot)com>
>>> <mailto:adrian(dot)klaver(at)aklaver(dot)com <mailto:adrian(dot)klaver(at)aklaver(dot)com>>> wrote:
>>>
>>> On 10/06/2015 01:13 PM, Oleksii Kliukin wrote:
>>>>
>>>> Basically, if we invoke the first example, the foo table with have only
>>>> 1 row and not 10, as supplied by the generate_series.
>>>> However, when ORDER BY is attached to the query, or aggregate (such as
>>>> max, min or array_agg) is wrapped around the test(id) call, the test
>>>> function is called exactly 10 times. If I replace the SELECT INTO with
>>>> PERFORM, it would also be called 10 times. Unfortunately, it is not
>>>> possible to use PERFORM directly in the CTE expression.
>>>
>>> What CTE expression?
>>
>> Any CTE expression :-). The example here is just an illustration to
>> expose the issue. The real-world query I came across used a complex CTE
>> expression and called a function at the end of it inside the SELECT INTO
>> statement.
>
> Remember SELECT INTO inside plpgsql is different from SELECT INTO outside:
>
> http://www.postgresql.org/docs/9.4/interactive/plpgsql-statements.html#PLPGSQL-STATEMENTS-SQL-ONEROW <http://www.postgresql.org/docs/9.4/interactive/plpgsql-statements.html#PLPGSQL-STATEMENTS-SQL-ONEROW>
>
> "Tip: Note that this interpretation of SELECT with INTO is quite different from PostgreSQL's regular SELECT INTO command, wherein the INTO target is a newly created table. If you want to create a table from a SELECT result inside a PL/pgSQL function, use the syntax CREATE TABLE ... AS SELECT.

Thank you. In this case SELECT INTO was consciously called inside the pl/pgSQL function, as one cannot do SELECT function() from pl/pgSQL without storing the result of the function somewhere (with the INTO clause).

The problem itself has nothing to do with CTEs, the only reason why I’ve mentioned it is to justify why I didn’t use PERFORM instead of SELECT INTO (the following thread http://www.postgresql.org/message-id/91873FFA-838D-4A16-ABED-A0255ED5168F@justatheory.com <http://www.postgresql.org/message-id/91873FFA-838D-4A16-ABED-A0255ED5168F@justatheory.com> gives more details, although it is irrelevant to the problem being described).

Kind regards
--
Oleksii

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Adrian Klaver 2015-10-06 21:11:10 Re: dubious optimization of the function in SELECT INTO target list
Previous Message Adrian Klaver 2015-10-06 20:50:51 Re: dubious optimization of the function in SELECT INTO target list