Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit77200c5

Browse files
committed
Restore the portal-level snapshot for simple expressions, too.
Commits84f5c29 et al missed the need to cover plpgsql's "simpleexpression" code path. If the first thing we execute after aCOMMIT/ROLLBACK is one of those, rather than a full-fledged SPI command,we must explicitly do EnsurePortalSnapshotExists() to make sure we havean outer snapshot. Note that it wouldn't be good enough to just push asnapshot for the duration of the expression execution: what comes backmight be toasted, so we'd better have a snapshot protecting it.The test case demonstrating this fact cheats a bit by marking a SQLfunction immutable even though it fetches from a table. That'snothing that users haven't been seen to do, though.Per report from Jim Nasby. Back-patch to v11, like the previous fix.Discussion:https://postgr.es/m/378885e4-f85f-fc28-6c91-c4d1c080bf26@amazon.com
1 parentea5ae3a commit77200c5

File tree

3 files changed

+49
-0
lines changed

3 files changed

+49
-0
lines changed

‎src/pl/plpgsql/src/expected/plpgsql_transaction.out

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,24 @@ SELECT * FROM test1;
430430
---+---
431431
(0 rows)
432432

433+
-- detoast result of simple expression after commit
434+
CREATE TEMP TABLE test4(f1 text);
435+
ALTER TABLE test4 ALTER COLUMN f1 SET STORAGE EXTERNAL; -- disable compression
436+
INSERT INTO test4 SELECT repeat('xyzzy', 2000);
437+
-- immutable mark is a bit of a lie, but it serves to make call a simple expr
438+
-- that will return a still-toasted value
439+
CREATE FUNCTION data_source(i int) RETURNS TEXT LANGUAGE sql
440+
AS 'select f1 from test4' IMMUTABLE;
441+
DO $$
442+
declare x text;
443+
begin
444+
for i in 1..3 loop
445+
x := data_source(i);
446+
commit;
447+
end loop;
448+
raise notice 'length(x) = %', length(x);
449+
end $$;
450+
NOTICE: length(x) = 10000
433451
-- operations on composite types vs. internal transactions
434452
DO LANGUAGE plpgsql $$
435453
declare

‎src/pl/plpgsql/src/pl_exec.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include"parser/parse_type.h"
3737
#include"parser/scansup.h"
3838
#include"storage/proc.h"
39+
#include"tcop/pquery.h"
3940
#include"tcop/tcopprot.h"
4041
#include"tcop/utility.h"
4142
#include"utils/array.h"
@@ -6123,6 +6124,15 @@ exec_eval_simple_expr(PLpgSQL_execstate *estate,
61236124
if (expr->expr_simple_in_use&&expr->expr_simple_lxid==curlxid)
61246125
return false;
61256126

6127+
/*
6128+
* Ensure that there's a portal-level snapshot, in case this simple
6129+
* expression is the first thing evaluated after a COMMIT or ROLLBACK.
6130+
* We'd have to do this anyway before executing the expression, so we
6131+
* might as well do it now to ensure that any possible replanning doesn't
6132+
* need to take a new snapshot.
6133+
*/
6134+
EnsurePortalSnapshotExists();
6135+
61266136
/*
61276137
* Revalidate cached plan, so that we will notice if it became stale. (We
61286138
* need to hold a refcount while using the plan, anyway.) If replanning

‎src/pl/plpgsql/src/sql/plpgsql_transaction.sql

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,27 @@ $$;
354354
SELECT*FROM test1;
355355

356356

357+
-- detoast result of simple expression after commit
358+
CREATE TEMP TABLE test4(f1text);
359+
ALTERTABLE test4 ALTER COLUMN f1SET STORAGE EXTERNAL;-- disable compression
360+
INSERT INTO test4SELECT repeat('xyzzy',2000);
361+
362+
-- immutable mark is a bit of a lie, but it serves to make call a simple expr
363+
-- that will return a still-toasted value
364+
CREATEFUNCTIONdata_source(iint) RETURNSTEXT LANGUAGE sql
365+
AS'select f1 from test4' IMMUTABLE;
366+
367+
DO $$
368+
declare xtext;
369+
begin
370+
for iin1..3 loop
371+
x := data_source(i);
372+
commit;
373+
end loop;
374+
raise notice'length(x) = %', length(x);
375+
end $$;
376+
377+
357378
-- operations on composite types vs. internal transactions
358379
DO LANGUAGE plpgsql $$
359380
declare

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp