From 506d953a8c286c489153fbb52515507f86a1a275 Mon Sep 17 00:00:00 2001 From: Rui Zhao Date: Fri, 11 Sep 2026 00:29:11 +0800 Subject: [PATCH 2/3] Decode an oid8 TOAST value with an ID past 2^32 The test_decoding tests run with a young OID counter, so the value IDs they see fit in 4 bytes and a chunk_id read as an Oid still matches. Move the counter past 2^32 in the logical decoding TAP test and decode one oid8 value there. --- src/test/recovery/t/006_logical_decoding.pl | 33 +++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/test/recovery/t/006_logical_decoding.pl b/src/test/recovery/t/006_logical_decoding.pl index 97d11f98b5..57d3cf91ee 100644 --- a/src/test/recovery/t/006_logical_decoding.pl +++ b/src/test/recovery/t/006_logical_decoding.pl @@ -20,6 +20,13 @@ $node_primary->append_conf( 'postgresql.conf', qq( wal_level = logical )); + +# Move the OID counter past 2^32, so that the oid8 TOAST values decoded at +# the end of this test have IDs that do not fit in 4 bytes. +my $next_oid = '4295067296'; # 2^32 + 100000 +command_ok( + [ 'pg_resetwal', '--next-oid' => $next_oid, $node_primary->data_dir ], + 'set an 8-byte OID counter'); $node_primary->start; $node_primary->safe_psql('postgres', @@ -275,6 +282,32 @@ is( $node_primary->safe_psql( qq(Check that reset timestamp is later after resetting stats for slot '$stats_test_slot1' again.) ); +# Decode an oid8 TOAST value whose ID is past 2^32. The reorder buffer +# collects the chunks by chunk_id, and has to read that column with the +# TOAST table's type, or the value is reported as unchanged. +$node_primary->safe_psql( + 'postgres', qq[ + CREATE TABLE toasted_oid8 (id int PRIMARY KEY, data text) + WITH (toast_value_type = 'oid8'); + ALTER TABLE toasted_oid8 ALTER COLUMN data SET STORAGE EXTERNAL; + SELECT pg_create_logical_replication_slot('oid8_slot', 'test_decoding'); + INSERT INTO toasted_oid8 VALUES (1, repeat('1234567890', 2000)); +]); +is( $node_primary->safe_psql( + 'postgres', + "SELECT pg_column_toast_chunk_id(data) > '$next_oid'::oid8 FROM toasted_oid8" + ), + 't', + 'oid8 TOAST value has an ID past 2^32'); +$result = $node_primary->safe_psql( + 'postgres', + "SELECT data FROM pg_logical_slot_get_changes('oid8_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1')" +); +like( + $result, + qr/data\[text\]:'(?:1234567890){2000}'/, + 'oid8 TOAST value past 2^32 is decoded in full'); + # done with the node $node_primary->stop; -- 2.43.7