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

Commitd102aaf

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 parent8e63884 commitd102aaf

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
@@ -38,6 +38,7 @@
3838
#include"plpgsql.h"
3939
#include"storage/proc.h"
4040
#include"tcop/cmdtag.h"
41+
#include"tcop/pquery.h"
4142
#include"tcop/tcopprot.h"
4243
#include"tcop/utility.h"
4344
#include"utils/array.h"
@@ -5958,6 +5959,15 @@ exec_eval_simple_expr(PLpgSQL_execstate *estate,
59585959
expr->expr_simple_lxid==curlxid)
59595960
return false;
59605961

5962+
/*
5963+
* Ensure that there's a portal-level snapshot, in case this simple
5964+
* expression is the first thing evaluated after a COMMIT or ROLLBACK.
5965+
* We'd have to do this anyway before executing the expression, so we
5966+
* might as well do it now to ensure that any possible replanning doesn't
5967+
* need to take a new snapshot.
5968+
*/
5969+
EnsurePortalSnapshotExists();
5970+
59615971
/*
59625972
* Check to see if the cached plan has been invalidated. If not, and this
59635973
* is the first use in the current transaction, save a plan refcount in

‎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