diff --git a/src/backend/executor/nodeNamedtuplestorescan.c b/src/backend/executor/nodeNamedtuplestorescan.c index 4d898b1f83..b260ad2594 100644 --- a/src/backend/executor/nodeNamedtuplestorescan.c +++ b/src/backend/executor/nodeNamedtuplestorescan.c @@ -40,6 +40,7 @@ NamedTuplestoreScanNext(NamedTuplestoreScanState *node) * Get the next tuple from tuplestore. Return NULL if no more tuples. */ slot = node->ss.ss_ScanTupleSlot; + tuplestore_select_read_pointer(node->relation, node->readptr); (void) tuplestore_gettupleslot(node->relation, true, false, slot); return slot; } @@ -116,6 +117,7 @@ ExecInitNamedTuplestoreScan(NamedTuplestoreScan *node, EState *estate, int eflag * The new read pointer copies its position from read pointer 0, which * could be anywhere, so explicitly rewind it. */ + tuplestore_select_read_pointer(scanstate->relation, scanstate->readptr); tuplestore_rescan(scanstate->relation); /* diff --git a/src/test/regress/expected/plpgsql.out b/src/test/regress/expected/plpgsql.out index d294e53634..722715049c 100644 --- a/src/test/regress/expected/plpgsql.out +++ b/src/test/regress/expected/plpgsql.out @@ -5559,6 +5559,28 @@ LINE 1: SELECT (SELECT string_agg(id || '=' || name, ',') FROM d) QUERY: SELECT (SELECT string_agg(id || '=' || name, ',') FROM d) CONTEXT: PL/pgSQL function alter_table_under_transition_tables_upd_func() line 3 at RAISE -- +-- Test multiple reference to a transition table +-- +CREATE TABLE multi_test (i int); +INSERT INTO multi_test VALUES (1); +CREATE OR REPLACE FUNCTION multi_test_trig() RETURNS trigger +LANGUAGE plpgsql AS $$ +BEGIN + RAISE NOTICE 'count = %', (SELECT COUNT(*) FROM new_test); + RAISE NOTICE 'count union = %', + (SELECT COUNT(*) + FROM (SELECT * FROM new_test UNION ALL SELECT * FROM new_test) ss); + RETURN NULL; +END$$; +CREATE TRIGGER my_trigger AFTER UPDATE ON multi_test + REFERENCING NEW TABLE AS new_test OLD TABLE as old_test + FOR EACH STATEMENT EXECUTE PROCEDURE multi_test_trig(); +UPDATE multi_test SET i = i; +NOTICE: count = 1 +NOTICE: count union = 2 +DROP TABLE multi_test; +DROP FUNCTION multi_test_trig(); +-- -- Check type parsing and record fetching from partitioned tables -- CREATE TABLE partitioned_table (a int, b text) PARTITION BY LIST (a); diff --git a/src/test/regress/sql/plpgsql.sql b/src/test/regress/sql/plpgsql.sql index f17cf0b49b..f405d157bb 100644 --- a/src/test/regress/sql/plpgsql.sql +++ b/src/test/regress/sql/plpgsql.sql @@ -4503,6 +4503,32 @@ ALTER TABLE alter_table_under_transition_tables UPDATE alter_table_under_transition_tables SET id = id; +-- +-- Test multiple reference to a transition table +-- + +CREATE TABLE multi_test (i int); +INSERT INTO multi_test VALUES (1); + +CREATE OR REPLACE FUNCTION multi_test_trig() RETURNS trigger +LANGUAGE plpgsql AS $$ +BEGIN + RAISE NOTICE 'count = %', (SELECT COUNT(*) FROM new_test); + RAISE NOTICE 'count union = %', + (SELECT COUNT(*) + FROM (SELECT * FROM new_test UNION ALL SELECT * FROM new_test) ss); + RETURN NULL; +END$$; + +CREATE TRIGGER my_trigger AFTER UPDATE ON multi_test + REFERENCING NEW TABLE AS new_test OLD TABLE as old_test + FOR EACH STATEMENT EXECUTE PROCEDURE multi_test_trig(); + +UPDATE multi_test SET i = i; + +DROP TABLE multi_test; +DROP FUNCTION multi_test_trig(); + -- -- Check type parsing and record fetching from partitioned tables --