diff --git a/contrib/test_decoding/expected/stream.out b/contrib/test_decoding/expected/stream.out index a76f77601e..6a8a00a65b 100644 --- a/contrib/test_decoding/expected/stream.out +++ b/contrib/test_decoding/expected/stream.out @@ -128,6 +128,28 @@ SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 5 (1 row) +-- Test that accessing a TOAST table in streaming mode is allowed. +-- Create a table with a column that uses a TOASTed default value. +-- (temporarily hide query, to avoid the long CREATE TABLE stmt) +\set ECHO none +SET debug_logical_replication_streaming = immediate; +BEGIN; +INSERT INTO test_tab VALUES(1); +-- Force WAL flush, so that the above changes will be streamed. +SELECT 'force flush' FROM pg_switch_wal(); + ?column? +------------- + force flush +(1 row) + +SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1'); + count +------- + 3 +(1 row) + +COMMIT; +RESET debug_logical_replication_streaming; DROP TABLE stream_test; SELECT pg_drop_replication_slot('regression_slot'); pg_drop_replication_slot diff --git a/contrib/test_decoding/sql/stream.sql b/contrib/test_decoding/sql/stream.sql index 7f43f0c2ab..d7a696586e 100644 --- a/contrib/test_decoding/sql/stream.sql +++ b/contrib/test_decoding/sql/stream.sql @@ -59,5 +59,27 @@ ROLLBACK TO s1; COMMIT; SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1'); +-- Test that accessing a TOAST table in streaming mode is allowed. + +-- Create a table with a column that uses a TOASTed default value. +-- (temporarily hide query, to avoid the long CREATE TABLE stmt) +\set ECHO none +SELECT 'CREATE TABLE test_tab (a text DEFAULT ''' || string_agg('toast value', '') || ''');' FROM generate_series(1, 4000) +\gexec +\set ECHO all + +SET debug_logical_replication_streaming = immediate; + +BEGIN; +INSERT INTO test_tab VALUES(1); + +-- Force WAL flush, so that the above changes will be streamed. +SELECT 'force flush' FROM pg_switch_wal(); + +SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1'); +COMMIT; + +RESET debug_logical_replication_streaming; + DROP TABLE stream_test; SELECT pg_drop_replication_slot('regression_slot'); diff --git a/src/backend/access/index/genam.c b/src/backend/access/index/genam.c index e9c52a6bd9..58f33555f9 100644 --- a/src/backend/access/index/genam.c +++ b/src/backend/access/index/genam.c @@ -702,6 +702,14 @@ systable_beginscan_ordered(Relation heapRelation, index_rescan(sysscan->iscan, key, nkeys, NULL, 0); sysscan->scan = NULL; + /* + * If CheckXidAlive is set then set a flag to indicate that system table + * scan is in-progress. See detailed comments in xact.c where these + * variables are declared. + */ + if (TransactionIdIsValid(CheckXidAlive)) + bsysscan = true; + return sysscan; } @@ -746,6 +754,14 @@ systable_endscan_ordered(SysScanDesc sysscan) index_endscan(sysscan->iscan); if (sysscan->snapshot) UnregisterSnapshot(sysscan->snapshot); + + /* + * Reset the bsysscan flag at the end of the systable scan. See detailed + * comments in xact.c where these variables are declared. + */ + if (TransactionIdIsValid(CheckXidAlive)) + bsysscan = false; + pfree(sysscan); }