Skip to content

Commit 1353b11

Browse files
committed
Fix plpgsql's handling of simple expressions in scrollable cursors.
exec_save_simple_expr did not account for the possibility that standard_planner would stick a Materialize node atop the plan of even a simple Result, if CURSOR_OPT_SCROLL is set. This led to an "unexpected plan node type" error. This is a very old bug, but it'd only be reached by declaring a cursor for a "SELECT simple-expression" query and explicitly marking it scrollable, which is an odd thing to do. So the lack of prior reports isn't too surprising. Bug: #18859 Reported-by: Olleg Samoylov <splarv@ya.ru> Author: Andrei Lepikhov <lepihov@gmail.com> Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://postgr.es/m/18859-0d5f28ac99a37059@postgresql.org Backpatch-through: 13
1 parent 97ce4d3 commit 1353b11

File tree

3 files changed

+30
-5
lines changed

3 files changed

+30
-5
lines changed

src/pl/plpgsql/src/expected/plpgsql_simple.out

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,14 @@ select simplecaller();
118118
44
119119
(1 row)
120120

121+
-- Check handling of simple expression in a scrollable cursor (bug #18859)
122+
do $$
123+
declare
124+
p_CurData refcursor;
125+
val int;
126+
begin
127+
open p_CurData scroll for select 42;
128+
fetch p_CurData into val;
129+
raise notice 'val = %', val;
130+
end; $$;
131+
NOTICE: val = 42

src/pl/plpgsql/src/pl_exec.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8141,10 +8141,12 @@ exec_save_simple_expr(PLpgSQL_expr *expr, CachedPlan *cplan)
81418141
/*
81428142
* Ordinarily, the plan node should be a simple Result. However, if
81438143
* debug_parallel_query is on, the planner might've stuck a Gather node
8144-
* atop that. The simplest way to deal with this is to look through the
8145-
* Gather node. The Gather node's tlist would normally contain a Var
8146-
* referencing the child node's output, but it could also be a Param, or
8147-
* it could be a Const that setrefs.c copied as-is.
8144+
* atop that; and/or if this plan is for a scrollable cursor, the planner
8145+
* might've stuck a Material node atop it. The simplest way to deal with
8146+
* this is to look through the Gather and/or Material nodes. The upper
8147+
* node's tlist would normally contain a Var referencing the child node's
8148+
* output, but it could also be a Param, or it could be a Const that
8149+
* setrefs.c copied as-is.
81488150
*/
81498151
plan = stmt->planTree;
81508152
for (;;)
@@ -8162,7 +8164,7 @@ exec_save_simple_expr(PLpgSQL_expr *expr, CachedPlan *cplan)
81628164
((Result *) plan)->resconstantqual == NULL);
81638165
break;
81648166
}
8165-
else if (IsA(plan, Gather))
8167+
else if (IsA(plan, Gather) || IsA(plan, Material))
81668168
{
81678169
Assert(plan->lefttree != NULL &&
81688170
plan->righttree == NULL &&

src/pl/plpgsql/src/sql/plpgsql_simple.sql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,15 @@ as $$select 22 + 22$$;
102102
select simplecaller();
103103

104104
select simplecaller();
105+
106+
-- Check handling of simple expression in a scrollable cursor (bug #18859)
107+
108+
do $$
109+
declare
110+
p_CurData refcursor;
111+
val int;
112+
begin
113+
open p_CurData scroll for select 42;
114+
fetch p_CurData into val;
115+
raise notice 'val = %', val;
116+
end; $$;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy