diff -U3 /tmp/cirrus-ci-build/contrib/test_decoding/expected/rewrite.out /tmp/cirrus-ci-build/contrib/test_decoding/results/rewrite.out --- /tmp/cirrus-ci-build/contrib/test_decoding/expected/rewrite.out 2025-12-24 20:55:54.419537987 +0000 +++ /tmp/cirrus-ci-build/contrib/test_decoding/results/rewrite.out 2025-12-24 21:01:48.099317412 +0000 @@ -116,49 +116,7 @@ -- make old files go away CHECKPOINT; SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - BEGIN - table public.replication_example: INSERT: id[integer]:2 somedata[integer]:2 text[character varying]:null - table public.replication_example: INSERT: id[integer]:3 somedata[integer]:3 text[character varying]:null testcolumn1[integer]:1 - COMMIT - BEGIN - table public.replication_example: INSERT: id[integer]:4 somedata[integer]:3 text[character varying]:null testcolumn1[integer]:null - table public.replication_example: INSERT: id[integer]:5 somedata[integer]:4 text[character varying]:null testcolumn1[integer]:2 testcolumn2[integer]:1 - COMMIT - BEGIN - table public.replication_example: INSERT: id[integer]:6 somedata[integer]:5 text[character varying]:null testcolumn1[integer]:3 testcolumn2[integer]:null - COMMIT - BEGIN - table public.replication_example: INSERT: id[integer]:7 somedata[integer]:6 text[character varying]:null testcolumn1[integer]:4 testcolumn2[integer]:null - table public.replication_example: INSERT: id[integer]:8 somedata[integer]:7 text[character varying]:null testcolumn1[integer]:5 testcolumn2[integer]:null testcolumn3[integer]:1 - COMMIT -(15 rows) - --- trigger repeated rewrites of a system catalog with a toast table, --- that previously was buggy: 20180914021046.oi7dm4ra3ot2g2kt@alap3.anarazel.de -VACUUM FULL pg_proc; VACUUM FULL pg_description; VACUUM FULL pg_shdescription; VACUUM FULL iamalargetable; -INSERT INTO replication_example(somedata, testcolumn1, testcolumn3) VALUES (8, 6, 1); -VACUUM FULL pg_proc; VACUUM FULL pg_description; VACUUM FULL pg_shdescription; VACUUM FULL iamalargetable; -INSERT INTO replication_example(somedata, testcolumn1, testcolumn3) VALUES (9, 7, 1); -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ - BEGIN - table public.replication_example: INSERT: id[integer]:9 somedata[integer]:8 text[character varying]:null testcolumn1[integer]:6 testcolumn2[integer]:null testcolumn3[integer]:1 - COMMIT - BEGIN - table public.replication_example: INSERT: id[integer]:10 somedata[integer]:9 text[character varying]:null testcolumn1[integer]:7 testcolumn2[integer]:null testcolumn3[integer]:1 - COMMIT -(6 rows) - -SELECT pg_drop_replication_slot('regression_slot'); - pg_drop_replication_slot --------------------------- - -(1 row) - -DROP TABLE IF EXISTS replication_example; -DROP FUNCTION iamalongfunction(); -DROP FUNCTION exec(text); -DROP ROLE regress_justforcomments; +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /tmp/cirrus-ci-build/contrib/test_decoding/expected/toast.out /tmp/cirrus-ci-build/contrib/test_decoding/results/toast.out --- /tmp/cirrus-ci-build/contrib/test_decoding/expected/toast.out 2025-12-24 20:55:54.419537987 +0000 +++ /tmp/cirrus-ci-build/contrib/test_decoding/results/toast.out 2025-12-24 21:01:48.199320240 +0000 @@ -1,390 +1,3 @@ --- predictability -SET synchronous_commit = on; -DROP TABLE IF EXISTS xpto; -NOTICE: table "xpto" does not exist, skipping -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); - ?column? ----------- - init -(1 row) - -CREATE SEQUENCE xpto_rand_seq START 79 INCREMENT 1499; -- portable "random" -CREATE TABLE xpto ( - id serial primary key, - toasted_col1 text, - rand1 float8 DEFAULT nextval('xpto_rand_seq'), - toasted_col2 text, - rand2 float8 DEFAULT nextval('xpto_rand_seq') -); --- uncompressed external toast data -INSERT INTO xpto (toasted_col1, toasted_col2) SELECT string_agg(g.i::text, ''), string_agg((g.i*2)::text, '') FROM generate_series(1, 2000) g(i); --- compressed external toast data -INSERT INTO xpto (toasted_col2) SELECT repeat(string_agg(to_char(g.i, 'FM0000'), ''), 50) FROM generate_series(1, 500) g(i); --- update of existing column -UPDATE xpto SET toasted_col1 = (SELECT string_agg(g.i::text, '') FROM generate_series(1, 2000) g(i)) WHERE id = 1; -UPDATE xpto SET rand1 = 123.456 WHERE id = 1; --- updating external via INSERT ... ON CONFLICT DO UPDATE -INSERT INTO xpto(id, toasted_col2) VALUES (2, 'toasted2-upsert') -ON CONFLICT (id) -DO UPDATE SET toasted_col2 = EXCLUDED.toasted_col2 || xpto.toasted_col2; -DELETE FROM xpto WHERE id = 1; -DROP TABLE IF EXISTS toasted_key; -NOTICE: table "toasted_key" does not exist, skipping -CREATE TABLE toasted_key ( - id serial, - toasted_key text PRIMARY KEY, - toasted_col1 text, - toasted_col2 text -); -ALTER TABLE toasted_key ALTER COLUMN toasted_key SET STORAGE EXTERNAL; -ALTER TABLE toasted_key ALTER COLUMN toasted_col1 SET STORAGE EXTERNAL; -INSERT INTO toasted_key(toasted_key, toasted_col1) VALUES(repeat('1234567890', 200), repeat('9876543210', 200)); --- test update of a toasted key without changing it -UPDATE toasted_key SET toasted_col2 = toasted_col1; --- test update of a toasted key, changing it -UPDATE toasted_key SET toasted_key = toasted_key || '1'; -DELETE FROM toasted_key; --- Test that HEAP2_MULTI_INSERT insertions with and without toasted --- columns are handled correctly -CREATE TABLE toasted_copy ( - id int primary key, -- no default, copy didn't use to handle that with multi inserts - data text -); -ALTER TABLE toasted_copy ALTER COLUMN data SET STORAGE EXTERNAL; -\copy toasted_copy FROM STDIN -SELECT substr(data, 1, 200) FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - substr ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - BEGIN - table public.xpto: INSERT: id[integer]:1 toasted_col1[text]:'1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 - COMMIT - BEGIN - table public.xpto: INSERT: id[integer]:2 toasted_col1[text]:null rand1[double precision]:3077 toasted_col2[text]:'00010002000300040005000600070008000900100011001200130014001500160017001800190020002100 - COMMIT - BEGIN - table public.xpto: UPDATE: id[integer]:1 toasted_col1[text]:'1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 - COMMIT - BEGIN - table public.xpto: UPDATE: id[integer]:1 toasted_col1[text]:unchanged-toast-datum rand1[double precision]:123.456 toasted_col2[text]:unchanged-toast-datum rand2[double precision]:1578 - COMMIT - BEGIN - table public.xpto: UPDATE: id[integer]:2 toasted_col1[text]:null rand1[double precision]:3077 toasted_col2[text]:'toasted2-upsert00010002000300040005000600070008000900100011001200130014001500160017001 - COMMIT - BEGIN - table public.xpto: DELETE: id[integer]:1 - COMMIT - BEGIN - table public.toasted_key: INSERT: id[integer]:1 toasted_key[text]:'1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123 - COMMIT - BEGIN - table public.toasted_key: UPDATE: old-key: toasted_key[text]:'123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678 - COMMIT - BEGIN - table public.toasted_key: UPDATE: old-key: toasted_key[text]:'123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678 - COMMIT - BEGIN - table public.toasted_key: DELETE: toasted_key[text]:'123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 - COMMIT - BEGIN - table public.toasted_copy: INSERT: id[integer]:1 data[text]:'untoasted1' - table public.toasted_copy: INSERT: id[integer]:2 data[text]:'toasted1-1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 - table public.toasted_copy: INSERT: id[integer]:3 data[text]:'untoasted2' - table public.toasted_copy: INSERT: id[integer]:4 data[text]:'toasted2-1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 - table public.toasted_copy: INSERT: id[integer]:5 data[text]:'untoasted3' - table public.toasted_copy: INSERT: id[integer]:6 data[text]:'untoasted4' - table public.toasted_copy: INSERT: id[integer]:7 data[text]:'untoasted5' - table public.toasted_copy: INSERT: id[integer]:8 data[text]:'untoasted6' - table public.toasted_copy: INSERT: id[integer]:9 data[text]:'untoasted7' - table public.toasted_copy: INSERT: id[integer]:10 data[text]:'untoasted8' - table public.toasted_copy: INSERT: id[integer]:11 data[text]:'untoasted9' - table public.toasted_copy: INSERT: id[integer]:12 data[text]:'untoasted10' - table public.toasted_copy: INSERT: id[integer]:13 data[text]:'untoasted11' - table public.toasted_copy: INSERT: id[integer]:14 data[text]:'untoasted12' - table public.toasted_copy: INSERT: id[integer]:15 data[text]:'untoasted13' - table public.toasted_copy: INSERT: id[integer]:16 data[text]:'untoasted14' - table public.toasted_copy: INSERT: id[integer]:17 data[text]:'untoasted15' - table public.toasted_copy: INSERT: id[integer]:18 data[text]:'untoasted16' - table public.toasted_copy: INSERT: id[integer]:19 data[text]:'untoasted17' - table public.toasted_copy: INSERT: id[integer]:20 data[text]:'untoasted18' - table public.toasted_copy: INSERT: id[integer]:21 data[text]:'untoasted19' - table public.toasted_copy: INSERT: id[integer]:22 data[text]:'untoasted20' - table public.toasted_copy: INSERT: id[integer]:23 data[text]:'untoasted21' - table public.toasted_copy: INSERT: id[integer]:24 data[text]:'untoasted22' - table public.toasted_copy: INSERT: id[integer]:25 data[text]:'untoasted23' - table public.toasted_copy: INSERT: id[integer]:26 data[text]:'untoasted24' - table public.toasted_copy: INSERT: id[integer]:27 data[text]:'untoasted25' - table public.toasted_copy: INSERT: id[integer]:28 data[text]:'untoasted26' - table public.toasted_copy: INSERT: id[integer]:29 data[text]:'untoasted27' - table public.toasted_copy: INSERT: id[integer]:30 data[text]:'untoasted28' - table public.toasted_copy: INSERT: id[integer]:31 data[text]:'untoasted29' - table public.toasted_copy: INSERT: id[integer]:32 data[text]:'untoasted30' - table public.toasted_copy: INSERT: id[integer]:33 data[text]:'untoasted31' - table public.toasted_copy: INSERT: id[integer]:34 data[text]:'untoasted32' - table public.toasted_copy: INSERT: id[integer]:35 data[text]:'untoasted33' - table public.toasted_copy: INSERT: id[integer]:36 data[text]:'untoasted34' - table public.toasted_copy: INSERT: id[integer]:37 data[text]:'untoasted35' - table public.toasted_copy: INSERT: id[integer]:38 data[text]:'untoasted36' - table public.toasted_copy: INSERT: id[integer]:39 data[text]:'untoasted37' - table public.toasted_copy: INSERT: id[integer]:40 data[text]:'untoasted38' - table public.toasted_copy: INSERT: id[integer]:41 data[text]:'untoasted39' - table public.toasted_copy: INSERT: id[integer]:42 data[text]:'untoasted40' - table public.toasted_copy: INSERT: id[integer]:43 data[text]:'untoasted41' - table public.toasted_copy: INSERT: id[integer]:44 data[text]:'untoasted42' - table public.toasted_copy: INSERT: id[integer]:45 data[text]:'untoasted43' - table public.toasted_copy: INSERT: id[integer]:46 data[text]:'untoasted44' - table public.toasted_copy: INSERT: id[integer]:47 data[text]:'untoasted45' - table public.toasted_copy: INSERT: id[integer]:48 data[text]:'untoasted46' - table public.toasted_copy: INSERT: id[integer]:49 data[text]:'untoasted47' - table public.toasted_copy: INSERT: id[integer]:50 data[text]:'untoasted48' - table public.toasted_copy: INSERT: id[integer]:51 data[text]:'untoasted49' - table public.toasted_copy: INSERT: id[integer]:52 data[text]:'untoasted50' - table public.toasted_copy: INSERT: id[integer]:53 data[text]:'untoasted51' - table public.toasted_copy: INSERT: id[integer]:54 data[text]:'untoasted52' - table public.toasted_copy: INSERT: id[integer]:55 data[text]:'untoasted53' - table public.toasted_copy: INSERT: id[integer]:56 data[text]:'untoasted54' - table public.toasted_copy: INSERT: id[integer]:57 data[text]:'untoasted55' - table public.toasted_copy: INSERT: id[integer]:58 data[text]:'untoasted56' - table public.toasted_copy: INSERT: id[integer]:59 data[text]:'untoasted57' - table public.toasted_copy: INSERT: id[integer]:60 data[text]:'untoasted58' - table public.toasted_copy: INSERT: id[integer]:61 data[text]:'untoasted59' - table public.toasted_copy: INSERT: id[integer]:62 data[text]:'untoasted60' - table public.toasted_copy: INSERT: id[integer]:63 data[text]:'untoasted61' - table public.toasted_copy: INSERT: id[integer]:64 data[text]:'untoasted62' - table public.toasted_copy: INSERT: id[integer]:65 data[text]:'untoasted63' - table public.toasted_copy: INSERT: id[integer]:66 data[text]:'untoasted64' - table public.toasted_copy: INSERT: id[integer]:67 data[text]:'untoasted65' - table public.toasted_copy: INSERT: id[integer]:68 data[text]:'untoasted66' - table public.toasted_copy: INSERT: id[integer]:69 data[text]:'untoasted67' - table public.toasted_copy: INSERT: id[integer]:70 data[text]:'untoasted68' - table public.toasted_copy: INSERT: id[integer]:71 data[text]:'untoasted69' - table public.toasted_copy: INSERT: id[integer]:72 data[text]:'untoasted70' - table public.toasted_copy: INSERT: id[integer]:73 data[text]:'untoasted71' - table public.toasted_copy: INSERT: id[integer]:74 data[text]:'untoasted72' - table public.toasted_copy: INSERT: id[integer]:75 data[text]:'untoasted73' - table public.toasted_copy: INSERT: id[integer]:76 data[text]:'untoasted74' - table public.toasted_copy: INSERT: id[integer]:77 data[text]:'untoasted75' - table public.toasted_copy: INSERT: id[integer]:78 data[text]:'untoasted76' - table public.toasted_copy: INSERT: id[integer]:79 data[text]:'untoasted77' - table public.toasted_copy: INSERT: id[integer]:80 data[text]:'untoasted78' - table public.toasted_copy: INSERT: id[integer]:81 data[text]:'untoasted79' - table public.toasted_copy: INSERT: id[integer]:82 data[text]:'untoasted80' - table public.toasted_copy: INSERT: id[integer]:83 data[text]:'untoasted81' - table public.toasted_copy: INSERT: id[integer]:84 data[text]:'untoasted82' - table public.toasted_copy: INSERT: id[integer]:85 data[text]:'untoasted83' - table public.toasted_copy: INSERT: id[integer]:86 data[text]:'untoasted84' - table public.toasted_copy: INSERT: id[integer]:87 data[text]:'untoasted85' - table public.toasted_copy: INSERT: id[integer]:88 data[text]:'untoasted86' - table public.toasted_copy: INSERT: id[integer]:89 data[text]:'untoasted87' - table public.toasted_copy: INSERT: id[integer]:90 data[text]:'untoasted88' - table public.toasted_copy: INSERT: id[integer]:91 data[text]:'untoasted89' - table public.toasted_copy: INSERT: id[integer]:92 data[text]:'untoasted90' - table public.toasted_copy: INSERT: id[integer]:93 data[text]:'untoasted91' - table public.toasted_copy: INSERT: id[integer]:94 data[text]:'untoasted92' - table public.toasted_copy: INSERT: id[integer]:95 data[text]:'untoasted93' - table public.toasted_copy: INSERT: id[integer]:96 data[text]:'untoasted94' - table public.toasted_copy: INSERT: id[integer]:97 data[text]:'untoasted95' - table public.toasted_copy: INSERT: id[integer]:98 data[text]:'untoasted96' - table public.toasted_copy: INSERT: id[integer]:99 data[text]:'untoasted97' - table public.toasted_copy: INSERT: id[integer]:100 data[text]:'untoasted98' - table public.toasted_copy: INSERT: id[integer]:101 data[text]:'untoasted99' - table public.toasted_copy: INSERT: id[integer]:102 data[text]:'untoasted100' - table public.toasted_copy: INSERT: id[integer]:103 data[text]:'untoasted101' - table public.toasted_copy: INSERT: id[integer]:104 data[text]:'untoasted102' - table public.toasted_copy: INSERT: id[integer]:105 data[text]:'untoasted103' - table public.toasted_copy: INSERT: id[integer]:106 data[text]:'untoasted104' - table public.toasted_copy: INSERT: id[integer]:107 data[text]:'untoasted105' - table public.toasted_copy: INSERT: id[integer]:108 data[text]:'untoasted106' - table public.toasted_copy: INSERT: id[integer]:109 data[text]:'untoasted107' - table public.toasted_copy: INSERT: id[integer]:110 data[text]:'untoasted108' - table public.toasted_copy: INSERT: id[integer]:111 data[text]:'untoasted109' - table public.toasted_copy: INSERT: id[integer]:112 data[text]:'untoasted110' - table public.toasted_copy: INSERT: id[integer]:113 data[text]:'untoasted111' - table public.toasted_copy: INSERT: id[integer]:114 data[text]:'untoasted112' - table public.toasted_copy: INSERT: id[integer]:115 data[text]:'untoasted113' - table public.toasted_copy: INSERT: id[integer]:116 data[text]:'untoasted114' - table public.toasted_copy: INSERT: id[integer]:117 data[text]:'untoasted115' - table public.toasted_copy: INSERT: id[integer]:118 data[text]:'untoasted116' - table public.toasted_copy: INSERT: id[integer]:119 data[text]:'untoasted117' - table public.toasted_copy: INSERT: id[integer]:120 data[text]:'untoasted118' - table public.toasted_copy: INSERT: id[integer]:121 data[text]:'untoasted119' - table public.toasted_copy: INSERT: id[integer]:122 data[text]:'untoasted120' - table public.toasted_copy: INSERT: id[integer]:123 data[text]:'untoasted121' - table public.toasted_copy: INSERT: id[integer]:124 data[text]:'untoasted122' - table public.toasted_copy: INSERT: id[integer]:125 data[text]:'untoasted123' - table public.toasted_copy: INSERT: id[integer]:126 data[text]:'untoasted124' - table public.toasted_copy: INSERT: id[integer]:127 data[text]:'untoasted125' - table public.toasted_copy: INSERT: id[integer]:128 data[text]:'untoasted126' - table public.toasted_copy: INSERT: id[integer]:129 data[text]:'untoasted127' - table public.toasted_copy: INSERT: id[integer]:130 data[text]:'untoasted128' - table public.toasted_copy: INSERT: id[integer]:131 data[text]:'untoasted129' - table public.toasted_copy: INSERT: id[integer]:132 data[text]:'untoasted130' - table public.toasted_copy: INSERT: id[integer]:133 data[text]:'untoasted131' - table public.toasted_copy: INSERT: id[integer]:134 data[text]:'untoasted132' - table public.toasted_copy: INSERT: id[integer]:135 data[text]:'untoasted133' - table public.toasted_copy: INSERT: id[integer]:136 data[text]:'untoasted134' - table public.toasted_copy: INSERT: id[integer]:137 data[text]:'untoasted135' - table public.toasted_copy: INSERT: id[integer]:138 data[text]:'untoasted136' - table public.toasted_copy: INSERT: id[integer]:139 data[text]:'untoasted137' - table public.toasted_copy: INSERT: id[integer]:140 data[text]:'untoasted138' - table public.toasted_copy: INSERT: id[integer]:141 data[text]:'untoasted139' - table public.toasted_copy: INSERT: id[integer]:142 data[text]:'untoasted140' - table public.toasted_copy: INSERT: id[integer]:143 data[text]:'untoasted141' - table public.toasted_copy: INSERT: id[integer]:144 data[text]:'untoasted142' - table public.toasted_copy: INSERT: id[integer]:145 data[text]:'untoasted143' - table public.toasted_copy: INSERT: id[integer]:146 data[text]:'untoasted144' - table public.toasted_copy: INSERT: id[integer]:147 data[text]:'untoasted145' - table public.toasted_copy: INSERT: id[integer]:148 data[text]:'untoasted146' - table public.toasted_copy: INSERT: id[integer]:149 data[text]:'untoasted147' - table public.toasted_copy: INSERT: id[integer]:150 data[text]:'untoasted148' - table public.toasted_copy: INSERT: id[integer]:151 data[text]:'untoasted149' - table public.toasted_copy: INSERT: id[integer]:152 data[text]:'untoasted150' - table public.toasted_copy: INSERT: id[integer]:153 data[text]:'untoasted151' - table public.toasted_copy: INSERT: id[integer]:154 data[text]:'untoasted152' - table public.toasted_copy: INSERT: id[integer]:155 data[text]:'untoasted153' - table public.toasted_copy: INSERT: id[integer]:156 data[text]:'untoasted154' - table public.toasted_copy: INSERT: id[integer]:157 data[text]:'untoasted155' - table public.toasted_copy: INSERT: id[integer]:158 data[text]:'untoasted156' - table public.toasted_copy: INSERT: id[integer]:159 data[text]:'untoasted157' - table public.toasted_copy: INSERT: id[integer]:160 data[text]:'untoasted158' - table public.toasted_copy: INSERT: id[integer]:161 data[text]:'untoasted159' - table public.toasted_copy: INSERT: id[integer]:162 data[text]:'untoasted160' - table public.toasted_copy: INSERT: id[integer]:163 data[text]:'untoasted161' - table public.toasted_copy: INSERT: id[integer]:164 data[text]:'untoasted162' - table public.toasted_copy: INSERT: id[integer]:165 data[text]:'untoasted163' - table public.toasted_copy: INSERT: id[integer]:166 data[text]:'untoasted164' - table public.toasted_copy: INSERT: id[integer]:167 data[text]:'untoasted165' - table public.toasted_copy: INSERT: id[integer]:168 data[text]:'untoasted166' - table public.toasted_copy: INSERT: id[integer]:169 data[text]:'untoasted167' - table public.toasted_copy: INSERT: id[integer]:170 data[text]:'untoasted168' - table public.toasted_copy: INSERT: id[integer]:171 data[text]:'untoasted169' - table public.toasted_copy: INSERT: id[integer]:172 data[text]:'untoasted170' - table public.toasted_copy: INSERT: id[integer]:173 data[text]:'untoasted171' - table public.toasted_copy: INSERT: id[integer]:174 data[text]:'untoasted172' - table public.toasted_copy: INSERT: id[integer]:175 data[text]:'untoasted173' - table public.toasted_copy: INSERT: id[integer]:176 data[text]:'untoasted174' - table public.toasted_copy: INSERT: id[integer]:177 data[text]:'untoasted175' - table public.toasted_copy: INSERT: id[integer]:178 data[text]:'untoasted176' - table public.toasted_copy: INSERT: id[integer]:179 data[text]:'untoasted177' - table public.toasted_copy: INSERT: id[integer]:180 data[text]:'untoasted178' - table public.toasted_copy: INSERT: id[integer]:181 data[text]:'untoasted179' - table public.toasted_copy: INSERT: id[integer]:182 data[text]:'untoasted180' - table public.toasted_copy: INSERT: id[integer]:183 data[text]:'untoasted181' - table public.toasted_copy: INSERT: id[integer]:184 data[text]:'untoasted182' - table public.toasted_copy: INSERT: id[integer]:185 data[text]:'untoasted183' - table public.toasted_copy: INSERT: id[integer]:186 data[text]:'untoasted184' - table public.toasted_copy: INSERT: id[integer]:187 data[text]:'untoasted185' - table public.toasted_copy: INSERT: id[integer]:188 data[text]:'untoasted186' - table public.toasted_copy: INSERT: id[integer]:189 data[text]:'untoasted187' - table public.toasted_copy: INSERT: id[integer]:190 data[text]:'untoasted188' - table public.toasted_copy: INSERT: id[integer]:191 data[text]:'untoasted189' - table public.toasted_copy: INSERT: id[integer]:192 data[text]:'untoasted190' - table public.toasted_copy: INSERT: id[integer]:193 data[text]:'untoasted191' - table public.toasted_copy: INSERT: id[integer]:194 data[text]:'untoasted192' - table public.toasted_copy: INSERT: id[integer]:195 data[text]:'untoasted193' - table public.toasted_copy: INSERT: id[integer]:196 data[text]:'untoasted194' - table public.toasted_copy: INSERT: id[integer]:197 data[text]:'untoasted195' - table public.toasted_copy: INSERT: id[integer]:198 data[text]:'untoasted196' - table public.toasted_copy: INSERT: id[integer]:199 data[text]:'untoasted197' - table public.toasted_copy: INSERT: id[integer]:200 data[text]:'untoasted198' - table public.toasted_copy: INSERT: id[integer]:201 data[text]:'toasted3-12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678 - table public.toasted_copy: INSERT: id[integer]:202 data[text]:'untoasted199' - table public.toasted_copy: INSERT: id[integer]:203 data[text]:'untoasted200' - COMMIT -(235 rows) - --- test we can decode "old" tuples bigger than the max heap tuple size correctly -DROP TABLE IF EXISTS toasted_several; -NOTICE: table "toasted_several" does not exist, skipping -CREATE TABLE toasted_several ( - id serial unique not null, - toasted_key text primary key, - toasted_col1 text, - toasted_col2 text -); -ALTER TABLE toasted_several REPLICA IDENTITY FULL; -ALTER TABLE toasted_several ALTER COLUMN toasted_key SET STORAGE EXTERNAL; -ALTER TABLE toasted_several ALTER COLUMN toasted_col1 SET STORAGE EXTERNAL; -ALTER TABLE toasted_several ALTER COLUMN toasted_col2 SET STORAGE EXTERNAL; --- Change the storage of the index back to EXTENDED, separately from --- the table. This is currently not doable via DDL, but it is --- supported internally. -UPDATE pg_attribute SET attstorage = 'x' WHERE attrelid = 'toasted_several_pkey'::regclass AND attname = 'toasted_key'; -INSERT INTO toasted_several(toasted_key) VALUES(repeat('9876543210', 10000)); -SELECT pg_column_size(toasted_key) > 2^16 FROM toasted_several; - ?column? ----------- - t -(1 row) - -SELECT regexp_replace(data, '^(.{100}).*(.{100})$', '\1..\2') FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - regexp_replace ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - BEGIN - table public.toasted_several: INSERT: id[integer]:1 toasted_key[text]:'98765432109876543210987654321..098765432109876543210987654321098765432109876543210' toasted_col1[text]:null toasted_col2[text]:null - COMMIT -(3 rows) - --- test update of a toasted key without changing it -UPDATE toasted_several SET toasted_col1 = toasted_key; -UPDATE toasted_several SET toasted_col2 = toasted_col1; -SELECT regexp_replace(data, '^(.{100}).*(.{100})$', '\1..\2') FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - regexp_replace ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - BEGIN - table public.toasted_several: INSERT: id[integer]:1 toasted_key[text]:'98765432109876543210987654321..098765432109876543210987654321098765432109876543210' toasted_col1[text]:null toasted_col2[text]:null - COMMIT - BEGIN - table public.toasted_several: UPDATE: old-key: id[integer]:1 toasted_key[text]:'98765432109876543210..432109876543210987654321098765432109876543210987654321098765432109876543210' toasted_col2[text]:null - COMMIT - BEGIN - table public.toasted_several: UPDATE: old-key: id[integer]:1 toasted_key[text]:'98765432109876543210..876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210' - COMMIT -(9 rows) - -/* - * update with large tuplebuf, in a transaction large enough to force to spool to disk - */ -BEGIN; -INSERT INTO toasted_several(toasted_key) SELECT * FROM generate_series(1, 10234); -UPDATE toasted_several SET toasted_col1 = toasted_col2 WHERE id = 1; -DELETE FROM toasted_several WHERE id = 1; -COMMIT; -DROP TABLE toasted_several; -SELECT regexp_replace(data, '^(.{100}).*(.{100})$', '\1..\2') FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1') -WHERE data NOT LIKE '%INSERT: %'; - regexp_replace ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - BEGIN - table public.toasted_several: UPDATE: old-key: id[integer]:1 toasted_key[text]:'98765432109876543210..7654321098765432109876543210987654321098765432109876543210' toasted_col2[text]:unchanged-toast-datum - table public.toasted_several: DELETE: id[integer]:1 toasted_key[text]:'98765432109876543210987654321..876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210' - COMMIT -(4 rows) - -/* - * Test decoding relation rewrite with toast. The insert into tbl2 within the - * same transaction is there to check that there is no remaining toast_hash not - * being reset. - */ -CREATE TABLE tbl1 (a INT, b TEXT); -CREATE TABLE tbl2 (a INT); -ALTER TABLE tbl1 ALTER COLUMN b SET STORAGE EXTERNAL; -BEGIN; -INSERT INTO tbl1 VALUES(1, repeat('a', 4000)) ; -ALTER TABLE tbl1 ADD COLUMN id serial primary key; -INSERT INTO tbl2 VALUES(1); -commit; -SELECT substr(data, 1, 200) FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - substr ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - BEGIN - table public.tbl1: INSERT: a[integer]:1 b[text]:'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - table public.tbl2: INSERT: a[integer]:1 - COMMIT -(4 rows) - -SELECT pg_drop_replication_slot('regression_slot'); - pg_drop_replication_slot --------------------------- - -(1 row) - +psql: error: connection to server on socket "/tmp/pg_regress-cdBOAK/.s.PGSQL.58928" failed: server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. diff -U3 /tmp/cirrus-ci-build/contrib/test_decoding/expected/permissions.out /tmp/cirrus-ci-build/contrib/test_decoding/results/permissions.out --- /tmp/cirrus-ci-build/contrib/test_decoding/expected/permissions.out 2025-12-24 20:55:54.419537987 +0000 +++ /tmp/cirrus-ci-build/contrib/test_decoding/results/permissions.out 2025-12-24 21:01:48.259321936 +0000 @@ -1,137 +1,2 @@ --- predictability -SET synchronous_commit = on; --- setup -CREATE ROLE regress_lr_normal; -CREATE ROLE regress_lr_superuser SUPERUSER; -CREATE ROLE regress_lr_replication REPLICATION; -CREATE TABLE lr_test(data text); --- superuser can control replication -SET ROLE regress_lr_superuser; -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); - ?column? ----------- - init -(1 row) - -INSERT INTO lr_test VALUES('lr_superuser_init'); -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data --------------------------------------------------------------- - BEGIN - table public.lr_test: INSERT: data[text]:'lr_superuser_init' - COMMIT -(3 rows) - -SELECT pg_drop_replication_slot('regression_slot'); - pg_drop_replication_slot --------------------------- - -(1 row) - -RESET ROLE; --- replication user can control replication -SET ROLE regress_lr_replication; -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); - ?column? ----------- - init -(1 row) - -INSERT INTO lr_test VALUES('lr_superuser_init'); -ERROR: permission denied for table lr_test -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data ------- -(0 rows) - -SELECT pg_drop_replication_slot('regression_slot'); - pg_drop_replication_slot --------------------------- - -(1 row) - -RESET ROLE; --- plain user *can't* can control replication -SET ROLE regress_lr_normal; -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); -ERROR: permission denied to use replication slots -DETAIL: Only roles with the REPLICATION attribute may use replication slots. -INSERT INTO lr_test VALUES('lr_superuser_init'); -ERROR: permission denied for table lr_test -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -ERROR: permission denied to use replication slots -DETAIL: Only roles with the REPLICATION attribute may use replication slots. -SELECT pg_drop_replication_slot('regression_slot'); -ERROR: permission denied to use replication slots -DETAIL: Only roles with the REPLICATION attribute may use replication slots. -SELECT pg_sync_replication_slots(); -ERROR: permission denied to use replication slots -DETAIL: Only roles with the REPLICATION attribute may use replication slots. -RESET ROLE; --- replication users can drop superuser created slots -SET ROLE regress_lr_superuser; -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); - ?column? ----------- - init -(1 row) - -RESET ROLE; -SET ROLE regress_lr_replication; -SELECT pg_drop_replication_slot('regression_slot'); - pg_drop_replication_slot --------------------------- - -(1 row) - -RESET ROLE; --- normal users can't drop existing slots -SET ROLE regress_lr_superuser; -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); - ?column? ----------- - init -(1 row) - -RESET ROLE; -SET ROLE regress_lr_normal; -SELECT pg_drop_replication_slot('regression_slot'); -ERROR: permission denied to use replication slots -DETAIL: Only roles with the REPLICATION attribute may use replication slots. -RESET ROLE; --- all users can see existing slots -SET ROLE regress_lr_superuser; -SELECT slot_name, plugin FROM pg_replication_slots; - slot_name | plugin ------------------+--------------- - regression_slot | test_decoding -(1 row) - -RESET ROLE; -SET ROLE regress_lr_replication; -SELECT slot_name, plugin FROM pg_replication_slots; - slot_name | plugin ------------------+--------------- - regression_slot | test_decoding -(1 row) - -RESET ROLE; -SET ROLE regress_lr_normal; -SELECT slot_name, plugin FROM pg_replication_slots; - slot_name | plugin ------------------+--------------- - regression_slot | test_decoding -(1 row) - -RESET ROLE; --- cleanup -SELECT pg_drop_replication_slot('regression_slot'); - pg_drop_replication_slot --------------------------- - -(1 row) - -DROP ROLE regress_lr_normal; -DROP ROLE regress_lr_superuser; -DROP ROLE regress_lr_replication; -DROP TABLE lr_test; +psql: error: connection to server on socket "/tmp/pg_regress-cdBOAK/.s.PGSQL.58928" failed: No such file or directory + Is the server running locally and accepting connections on that socket? diff -U3 /tmp/cirrus-ci-build/contrib/test_decoding/expected/decoding_in_xact.out /tmp/cirrus-ci-build/contrib/test_decoding/results/decoding_in_xact.out --- /tmp/cirrus-ci-build/contrib/test_decoding/expected/decoding_in_xact.out 2025-12-24 20:55:54.419537987 +0000 +++ /tmp/cirrus-ci-build/contrib/test_decoding/results/decoding_in_xact.out 2025-12-24 21:01:48.283322615 +0000 @@ -1,135 +1,2 @@ --- predictability -SET synchronous_commit = on; --- fail because we're creating a slot while in an xact with xid -BEGIN; -SELECT pg_current_xact_id() = '0'; - ?column? ----------- - f -(1 row) - -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); -ERROR: cannot create logical replication slot in transaction that has performed writes -ROLLBACK; --- fail because we're creating a slot while in a subxact whose topxact has an xid -BEGIN; -SELECT pg_current_xact_id() = '0'; - ?column? ----------- - f -(1 row) - -SAVEPOINT barf; -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); -ERROR: cannot create logical replication slot in transaction that has performed writes -ROLLBACK TO SAVEPOINT barf; -ROLLBACK; --- succeed, outside tx. -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); - ?column? ----------- - init -(1 row) - -SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); - ?column? ----------- - stop -(1 row) - --- succeed, in tx without xid. -BEGIN; -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); - ?column? ----------- - init -(1 row) - -COMMIT; -CREATE TABLE nobarf(id serial primary key, data text); -INSERT INTO nobarf(data) VALUES('1'); --- decoding works in transaction with xid -BEGIN; -SELECT pg_current_xact_id() = '0'; - ?column? ----------- - f -(1 row) - --- don't show yet, haven't committed -INSERT INTO nobarf(data) VALUES('2'); -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data ------------------------------------------------------------ - BEGIN - table public.nobarf: INSERT: id[integer]:1 data[text]:'1' - COMMIT -(3 rows) - -COMMIT; -INSERT INTO nobarf(data) VALUES('3'); -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data ------------------------------------------------------------ - BEGIN - table public.nobarf: INSERT: id[integer]:2 data[text]:'2' - COMMIT - BEGIN - table public.nobarf: INSERT: id[integer]:3 data[text]:'3' - COMMIT -(6 rows) - --- Decoding works in transaction that issues DDL --- --- We had issues handling relcache invalidations with these, see --- https://www.postgresql.org/message-id/e56be7d9-14b1-664d-0bfc-00ce9772721c@gmail.com -CREATE TABLE tbl_created_outside_xact(id SERIAL PRIMARY KEY); -BEGIN; - -- TRUNCATE changes the relfilenode and sends relcache invalidation - TRUNCATE tbl_created_outside_xact; - INSERT INTO tbl_created_outside_xact(id) VALUES('1'); - -- don't show yet, haven't committed - SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data ------- -(0 rows) - -COMMIT; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data --------------------------------------------------------------- - BEGIN - table public.tbl_created_outside_xact: TRUNCATE: (no-flags) - table public.tbl_created_outside_xact: INSERT: id[integer]:1 - COMMIT -(4 rows) - -SET debug_logical_replication_streaming = immediate; -BEGIN; - CREATE TABLE tbl_created_in_xact(id SERIAL PRIMARY KEY); - INSERT INTO tbl_created_in_xact VALUES (1); - CHECKPOINT; -- Force WAL flush, so that the above changes will be streamed - SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1'); - data ------------------------------------------- - opening a streamed block for transaction - streaming change for transaction - closing a streamed block for transaction -(3 rows) - -COMMIT; -RESET debug_logical_replication_streaming; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data ---------------------------------------------------------- - BEGIN - table public.tbl_created_in_xact: INSERT: id[integer]:1 - COMMIT -(3 rows) - -SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); - ?column? ----------- - stop -(1 row) - +psql: error: connection to server on socket "/tmp/pg_regress-cdBOAK/.s.PGSQL.58928" failed: No such file or directory + Is the server running locally and accepting connections on that socket? diff -U3 /tmp/cirrus-ci-build/contrib/test_decoding/expected/decoding_into_rel.out /tmp/cirrus-ci-build/contrib/test_decoding/results/decoding_into_rel.out --- /tmp/cirrus-ci-build/contrib/test_decoding/expected/decoding_into_rel.out 2025-12-24 20:55:54.419537987 +0000 +++ /tmp/cirrus-ci-build/contrib/test_decoding/results/decoding_into_rel.out 2025-12-24 21:01:48.327323860 +0000 @@ -1,111 +1,2 @@ --- test that we can insert the result of a get_changes call into a --- logged relation. That's really not a good idea in practical terms, --- but provides a nice test. --- predictability -SET synchronous_commit = on; -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); - ?column? ----------- - init -(1 row) - --- slot works -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data ------- -(0 rows) - --- create some changes -CREATE TABLE somechange(id serial primary key); -INSERT INTO somechange DEFAULT VALUES; -CREATE TABLE changeresult AS - SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -SELECT * FROM changeresult; - data ------------------------------------------------- - BEGIN - table public.somechange: INSERT: id[integer]:1 - COMMIT -(3 rows) - -INSERT INTO changeresult - SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -INSERT INTO changeresult - SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -SELECT * FROM changeresult; - data --------------------------------------------------------------------------------------------------------------------------------------------------- - BEGIN - table public.somechange: INSERT: id[integer]:1 - COMMIT - BEGIN - table public.changeresult: INSERT: data[text]:'BEGIN' - table public.changeresult: INSERT: data[text]:'table public.somechange: INSERT: id[integer]:1' - table public.changeresult: INSERT: data[text]:'COMMIT' - COMMIT - BEGIN - table public.changeresult: INSERT: data[text]:'BEGIN' - table public.changeresult: INSERT: data[text]:'table public.somechange: INSERT: id[integer]:1' - table public.changeresult: INSERT: data[text]:'COMMIT' - COMMIT - BEGIN - table public.changeresult: INSERT: data[text]:'BEGIN' - table public.changeresult: INSERT: data[text]:'table public.changeresult: INSERT: data[text]:''BEGIN''' - table public.changeresult: INSERT: data[text]:'table public.changeresult: INSERT: data[text]:''table public.somechange: INSERT: id[integer]:1''' - table public.changeresult: INSERT: data[text]:'table public.changeresult: INSERT: data[text]:''COMMIT''' - table public.changeresult: INSERT: data[text]:'COMMIT' - COMMIT -(20 rows) - -DROP TABLE changeresult; -DROP TABLE somechange; --- check calling logical decoding from pl/pgsql -CREATE FUNCTION slot_changes_wrapper(slot_name name) RETURNS SETOF TEXT AS $$ -BEGIN - RETURN QUERY - SELECT data FROM pg_logical_slot_peek_changes(slot_name, NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -END$$ LANGUAGE plpgsql; -SELECT * FROM slot_changes_wrapper('regression_slot'); - slot_changes_wrapper --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - BEGIN - table public.changeresult: INSERT: data[text]:'BEGIN' - table public.changeresult: INSERT: data[text]:'table public.changeresult: INSERT: data[text]:''BEGIN''' - table public.changeresult: INSERT: data[text]:'table public.changeresult: INSERT: data[text]:''table public.somechange: INSERT: id[integer]:1''' - table public.changeresult: INSERT: data[text]:'table public.changeresult: INSERT: data[text]:''COMMIT''' - table public.changeresult: INSERT: data[text]:'COMMIT' - table public.changeresult: INSERT: data[text]:'BEGIN' - table public.changeresult: INSERT: data[text]:'table public.changeresult: INSERT: data[text]:''BEGIN''' - table public.changeresult: INSERT: data[text]:'table public.changeresult: INSERT: data[text]:''table public.changeresult: INSERT: data[text]:''''BEGIN''''''' - table public.changeresult: INSERT: data[text]:'table public.changeresult: INSERT: data[text]:''table public.changeresult: INSERT: data[text]:''''table public.somechange: INSERT: id[integer]:1''''''' - table public.changeresult: INSERT: data[text]:'table public.changeresult: INSERT: data[text]:''table public.changeresult: INSERT: data[text]:''''COMMIT''''''' - table public.changeresult: INSERT: data[text]:'table public.changeresult: INSERT: data[text]:''COMMIT''' - table public.changeresult: INSERT: data[text]:'COMMIT' - COMMIT -(14 rows) - -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - BEGIN - table public.changeresult: INSERT: data[text]:'BEGIN' - table public.changeresult: INSERT: data[text]:'table public.changeresult: INSERT: data[text]:''BEGIN''' - table public.changeresult: INSERT: data[text]:'table public.changeresult: INSERT: data[text]:''table public.somechange: INSERT: id[integer]:1''' - table public.changeresult: INSERT: data[text]:'table public.changeresult: INSERT: data[text]:''COMMIT''' - table public.changeresult: INSERT: data[text]:'COMMIT' - table public.changeresult: INSERT: data[text]:'BEGIN' - table public.changeresult: INSERT: data[text]:'table public.changeresult: INSERT: data[text]:''BEGIN''' - table public.changeresult: INSERT: data[text]:'table public.changeresult: INSERT: data[text]:''table public.changeresult: INSERT: data[text]:''''BEGIN''''''' - table public.changeresult: INSERT: data[text]:'table public.changeresult: INSERT: data[text]:''table public.changeresult: INSERT: data[text]:''''table public.somechange: INSERT: id[integer]:1''''''' - table public.changeresult: INSERT: data[text]:'table public.changeresult: INSERT: data[text]:''table public.changeresult: INSERT: data[text]:''''COMMIT''''''' - table public.changeresult: INSERT: data[text]:'table public.changeresult: INSERT: data[text]:''COMMIT''' - table public.changeresult: INSERT: data[text]:'COMMIT' - COMMIT -(14 rows) - -SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); - ?column? ----------- - stop -(1 row) - +psql: error: connection to server on socket "/tmp/pg_regress-cdBOAK/.s.PGSQL.58928" failed: No such file or directory + Is the server running locally and accepting connections on that socket? diff -U3 /tmp/cirrus-ci-build/contrib/test_decoding/expected/binary.out /tmp/cirrus-ci-build/contrib/test_decoding/results/binary.out --- /tmp/cirrus-ci-build/contrib/test_decoding/expected/binary.out 2025-12-24 20:55:54.415493273 +0000 +++ /tmp/cirrus-ci-build/contrib/test_decoding/results/binary.out 2025-12-24 21:01:48.351324538 +0000 @@ -1,35 +1,2 @@ --- predictability -SET synchronous_commit = on; -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); - ?column? ----------- - init -(1 row) - --- succeeds, textual plugin, textual consumer -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'force-binary', '0', 'skip-empty-xacts', '1'); - data ------- -(0 rows) - --- fails, binary plugin, textual consumer -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'force-binary', '1', 'skip-empty-xacts', '1'); -ERROR: logical decoding output plugin "test_decoding" produces binary output, but function "pg_logical_slot_get_changes(name,pg_lsn,integer,text[])" expects textual data --- succeeds, textual plugin, binary consumer -SELECT data FROM pg_logical_slot_get_binary_changes('regression_slot', NULL, NULL, 'force-binary', '0', 'skip-empty-xacts', '1'); - data ------- -(0 rows) - --- succeeds, binary plugin, binary consumer -SELECT data FROM pg_logical_slot_get_binary_changes('regression_slot', NULL, NULL, 'force-binary', '1', 'skip-empty-xacts', '1'); - data ------- -(0 rows) - -SELECT 'init' FROM pg_drop_replication_slot('regression_slot'); - ?column? ----------- - init -(1 row) - +psql: error: connection to server on socket "/tmp/pg_regress-cdBOAK/.s.PGSQL.58928" failed: No such file or directory + Is the server running locally and accepting connections on that socket? diff -U3 /tmp/cirrus-ci-build/contrib/test_decoding/expected/prepared.out /tmp/cirrus-ci-build/contrib/test_decoding/results/prepared.out --- /tmp/cirrus-ci-build/contrib/test_decoding/expected/prepared.out 2025-12-24 20:55:54.419537987 +0000 +++ /tmp/cirrus-ci-build/contrib/test_decoding/results/prepared.out 2025-12-24 21:01:48.403326008 +0000 @@ -1,74 +1,2 @@ --- predictability -SET synchronous_commit = on; -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); - ?column? ----------- - init -(1 row) - -CREATE TABLE test_prepared1(id int); -CREATE TABLE test_prepared2(id int); --- test simple successful use of a prepared xact -BEGIN; -INSERT INTO test_prepared1 VALUES (1); -PREPARE TRANSACTION 'test_prepared#1'; -COMMIT PREPARED 'test_prepared#1'; -INSERT INTO test_prepared1 VALUES (2); --- test abort of a prepared xact -BEGIN; -INSERT INTO test_prepared1 VALUES (3); -PREPARE TRANSACTION 'test_prepared#2'; -ROLLBACK PREPARED 'test_prepared#2'; -INSERT INTO test_prepared1 VALUES (4); --- test prepared xact containing ddl -BEGIN; -INSERT INTO test_prepared1 VALUES (5); -ALTER TABLE test_prepared1 ADD COLUMN data text; -INSERT INTO test_prepared1 VALUES (6, 'frakbar'); -PREPARE TRANSACTION 'test_prepared#3'; --- test that we decode correctly while an uncommitted prepared xact --- with ddl exists. --- separate table because of the lock from the ALTER --- this will come before the '5' row above, as this commits before it. -INSERT INTO test_prepared2 VALUES (7); -COMMIT PREPARED 'test_prepared#3'; --- make sure stuff still works -INSERT INTO test_prepared1 VALUES (8); -INSERT INTO test_prepared2 VALUES (9); --- cleanup -DROP TABLE test_prepared1; -DROP TABLE test_prepared2; --- show results -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data -------------------------------------------------------------------------- - BEGIN - table public.test_prepared1: INSERT: id[integer]:1 - COMMIT - BEGIN - table public.test_prepared1: INSERT: id[integer]:2 - COMMIT - BEGIN - table public.test_prepared1: INSERT: id[integer]:4 - COMMIT - BEGIN - table public.test_prepared2: INSERT: id[integer]:7 - COMMIT - BEGIN - table public.test_prepared1: INSERT: id[integer]:5 - table public.test_prepared1: INSERT: id[integer]:6 data[text]:'frakbar' - COMMIT - BEGIN - table public.test_prepared1: INSERT: id[integer]:8 data[text]:null - COMMIT - BEGIN - table public.test_prepared2: INSERT: id[integer]:9 - COMMIT -(22 rows) - -SELECT pg_drop_replication_slot('regression_slot'); - pg_drop_replication_slot --------------------------- - -(1 row) - +psql: error: connection to server on socket "/tmp/pg_regress-cdBOAK/.s.PGSQL.58928" failed: No such file or directory + Is the server running locally and accepting connections on that socket? diff -U3 /tmp/cirrus-ci-build/contrib/test_decoding/expected/replorigin.out /tmp/cirrus-ci-build/contrib/test_decoding/results/replorigin.out --- /tmp/cirrus-ci-build/contrib/test_decoding/expected/replorigin.out 2025-12-24 20:55:54.419537987 +0000 +++ /tmp/cirrus-ci-build/contrib/test_decoding/results/replorigin.out 2025-12-24 21:01:48.427326687 +0000 @@ -1,328 +1,2 @@ --- predictability -SET synchronous_commit = on; --- superuser required by default -CREATE ROLE regress_origin_replication REPLICATION; -SET ROLE regress_origin_replication; -SELECT pg_replication_origin_advance('regress_test_decoding: perm', '0/1'); -ERROR: permission denied for function pg_replication_origin_advance -SELECT pg_replication_origin_create('regress_test_decoding: perm'); -ERROR: permission denied for function pg_replication_origin_create -SELECT pg_replication_origin_drop('regress_test_decoding: perm'); -ERROR: permission denied for function pg_replication_origin_drop -SELECT pg_replication_origin_oid('regress_test_decoding: perm'); -ERROR: permission denied for function pg_replication_origin_oid -SELECT pg_replication_origin_progress('regress_test_decoding: perm', false); -ERROR: permission denied for function pg_replication_origin_progress -SELECT pg_replication_origin_session_is_setup(); -ERROR: permission denied for function pg_replication_origin_session_is_setup -SELECT pg_replication_origin_session_progress(false); -ERROR: permission denied for function pg_replication_origin_session_progress -SELECT pg_replication_origin_session_reset(); -ERROR: permission denied for function pg_replication_origin_session_reset -SELECT pg_replication_origin_session_setup('regress_test_decoding: perm'); -ERROR: permission denied for function pg_replication_origin_session_setup -SELECT pg_replication_origin_xact_reset(); -ERROR: permission denied for function pg_replication_origin_xact_reset -SELECT pg_replication_origin_xact_setup('0/1', '2013-01-01 00:00'); -ERROR: permission denied for function pg_replication_origin_xact_setup -SELECT pg_show_replication_origin_status(); -ERROR: permission denied for function pg_show_replication_origin_status -RESET ROLE; -DROP ROLE regress_origin_replication; -CREATE TABLE origin_tbl(id serial primary key, data text); -CREATE TABLE target_tbl(id serial primary key, data text); -SELECT pg_replication_origin_create('regress_test_decoding: regression_slot'); - pg_replication_origin_create ------------------------------- - 1 -(1 row) - --- ensure duplicate creations fail -SELECT pg_replication_origin_create('regress_test_decoding: regression_slot'); -ERROR: duplicate key value violates unique constraint "pg_replication_origin_roname_index" -DETAIL: Key (roname)=(regress_test_decoding: regression_slot) already exists. --- ensure inactive origin cannot be set as session one if pid is specified -SELECT pg_replication_origin_session_setup('regress_test_decoding: regression_slot', -1); -ERROR: cannot use PID -1 for inactive replication origin with ID 1 ---ensure deletions work (once) -SELECT pg_replication_origin_create('regress_test_decoding: temp'); - pg_replication_origin_create ------------------------------- - 2 -(1 row) - -SELECT pg_replication_origin_drop('regress_test_decoding: temp'); - pg_replication_origin_drop ----------------------------- - -(1 row) - -SELECT pg_replication_origin_drop('regress_test_decoding: temp'); -ERROR: replication origin "regress_test_decoding: temp" does not exist --- specifying reserved origin names is not supported -SELECT pg_replication_origin_create('any'); -ERROR: replication origin name "any" is reserved -DETAIL: Origin names "any", "none", and names starting with "pg_" are reserved. -SELECT pg_replication_origin_create('none'); -ERROR: replication origin name "none" is reserved -DETAIL: Origin names "any", "none", and names starting with "pg_" are reserved. -SELECT pg_replication_origin_create('pg_replication_origin'); -ERROR: replication origin name "pg_replication_origin" is reserved -DETAIL: Origin names "any", "none", and names starting with "pg_" are reserved. --- various failure checks for undefined slots -select pg_replication_origin_advance('regress_test_decoding: temp', '0/1'); -ERROR: replication origin "regress_test_decoding: temp" does not exist -select pg_replication_origin_session_setup('regress_test_decoding: temp'); -ERROR: replication origin "regress_test_decoding: temp" does not exist -select pg_replication_origin_progress('regress_test_decoding: temp', true); -ERROR: replication origin "regress_test_decoding: temp" does not exist -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); - ?column? ----------- - init -(1 row) - --- origin tx -INSERT INTO origin_tbl(data) VALUES ('will be replicated and decoded and decoded again'); -INSERT INTO target_tbl(data) -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); --- as is normal, the insert into target_tbl shows up -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - BEGIN - table public.target_tbl: INSERT: id[integer]:1 data[text]:'BEGIN' - table public.target_tbl: INSERT: id[integer]:2 data[text]:'table public.origin_tbl: INSERT: id[integer]:1 data[text]:''will be replicated and decoded and decoded again''' - table public.target_tbl: INSERT: id[integer]:3 data[text]:'COMMIT' - COMMIT -(5 rows) - -INSERT INTO origin_tbl(data) VALUES ('will be replicated, but not decoded again'); --- mark session as replaying -SELECT pg_replication_origin_session_setup('regress_test_decoding: regression_slot'); - pg_replication_origin_session_setup -------------------------------------- - -(1 row) - --- ensure we prevent duplicate setup -SELECT pg_replication_origin_session_setup('regress_test_decoding: regression_slot'); -ERROR: cannot setup replication origin when one is already setup -SELECT '' FROM pg_logical_emit_message(false, 'test', 'this message will not be decoded'); - ?column? ----------- - -(1 row) - -BEGIN; --- setup transaction origin -SELECT pg_replication_origin_xact_setup('0/aabbccdd', '2013-01-01 00:00'); - pg_replication_origin_xact_setup ----------------------------------- - -(1 row) - -INSERT INTO target_tbl(data) -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'only-local', '1'); -COMMIT; --- check replication progress for the session is correct -SELECT pg_replication_origin_session_progress(false); - pg_replication_origin_session_progress ----------------------------------------- - 0/AABBCCDD -(1 row) - -SELECT pg_replication_origin_session_progress(true); - pg_replication_origin_session_progress ----------------------------------------- - 0/AABBCCDD -(1 row) - -SELECT pg_replication_origin_session_reset(); - pg_replication_origin_session_reset -------------------------------------- - -(1 row) - -SELECT local_id, external_id, remote_lsn, local_lsn <> '0/0' FROM pg_replication_origin_status; - local_id | external_id | remote_lsn | ?column? -----------+----------------------------------------+------------+---------- - 1 | regress_test_decoding: regression_slot | 0/AABBCCDD | t -(1 row) - --- check replication progress identified by name is correct -SELECT pg_replication_origin_progress('regress_test_decoding: regression_slot', false); - pg_replication_origin_progress --------------------------------- - 0/AABBCCDD -(1 row) - -SELECT pg_replication_origin_progress('regress_test_decoding: regression_slot', true); - pg_replication_origin_progress --------------------------------- - 0/AABBCCDD -(1 row) - --- ensure reset requires previously setup state -SELECT pg_replication_origin_session_reset(); -ERROR: no replication origin is configured --- and magically the replayed xact will be filtered! -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'only-local', '1'); - data ------- -(0 rows) - ---but new original changes still show up -INSERT INTO origin_tbl(data) VALUES ('will be replicated'); -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'only-local', '1'); - data --------------------------------------------------------------------------------- - BEGIN - table public.origin_tbl: INSERT: id[integer]:3 data[text]:'will be replicated' - COMMIT -(3 rows) - -SELECT pg_drop_replication_slot('regression_slot'); - pg_drop_replication_slot --------------------------- - -(1 row) - -SELECT pg_replication_origin_drop('regress_test_decoding: regression_slot'); - pg_replication_origin_drop ----------------------------- - -(1 row) - --- Set of transactions with no origin LSNs and commit timestamps set for --- this session. -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot_no_lsn', 'test_decoding'); - ?column? ----------- - init -(1 row) - -SELECT pg_replication_origin_create('regress_test_decoding: regression_slot_no_lsn'); - pg_replication_origin_create ------------------------------- - 1 -(1 row) - --- mark session as replaying -SELECT pg_replication_origin_session_setup('regress_test_decoding: regression_slot_no_lsn'); - pg_replication_origin_session_setup -------------------------------------- - -(1 row) - --- Simple transactions -BEGIN; -INSERT INTO origin_tbl(data) VALUES ('no_lsn, commit'); -COMMIT; -BEGIN; -INSERT INTO origin_tbl(data) VALUES ('no_lsn, rollback'); -ROLLBACK; --- 2PC transactions -BEGIN; -INSERT INTO origin_tbl(data) VALUES ('no_lsn, commit prepared'); -PREPARE TRANSACTION 'replorigin_prepared'; -COMMIT PREPARED 'replorigin_prepared'; -BEGIN; -INSERT INTO origin_tbl(data) VALUES ('no_lsn, rollback prepared'); -PREPARE TRANSACTION 'replorigin_prepared'; -ROLLBACK PREPARED 'replorigin_prepared'; -SELECT local_id, external_id, - remote_lsn <> '0/0' AS valid_remote_lsn, - local_lsn <> '0/0' AS valid_local_lsn - FROM pg_replication_origin_status; - local_id | external_id | valid_remote_lsn | valid_local_lsn -----------+-----------------------------------------------+------------------+----------------- - 1 | regress_test_decoding: regression_slot_no_lsn | f | t -(1 row) - -SELECT data FROM pg_logical_slot_get_changes('regression_slot_no_lsn', NULL, NULL, 'skip-empty-xacts', '1', 'include-xids', '0'); - data -------------------------------------------------------------------------------------- - BEGIN - table public.origin_tbl: INSERT: id[integer]:4 data[text]:'no_lsn, commit' - COMMIT - BEGIN - table public.origin_tbl: INSERT: id[integer]:6 data[text]:'no_lsn, commit prepared' - COMMIT -(6 rows) - --- Clean up -SELECT pg_replication_origin_session_reset(); - pg_replication_origin_session_reset -------------------------------------- - -(1 row) - -SELECT pg_drop_replication_slot('regression_slot_no_lsn'); - pg_drop_replication_slot --------------------------- - -(1 row) - -SELECT pg_replication_origin_drop('regress_test_decoding: regression_slot_no_lsn'); - pg_replication_origin_drop ----------------------------- - -(1 row) - --- Test that the pgoutput correctly filters changes corresponding to the provided origin value. -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'pgoutput'); - ?column? ----------- - init -(1 row) - -CREATE PUBLICATION pub FOR TABLE target_tbl; -SELECT pg_replication_origin_create('regress_test_decoding: regression_slot'); - pg_replication_origin_create ------------------------------- - 1 -(1 row) - --- mark session as replaying -SELECT pg_replication_origin_session_setup('regress_test_decoding: regression_slot'); - pg_replication_origin_session_setup -------------------------------------- - -(1 row) - -INSERT INTO target_tbl(data) VALUES ('test data'); --- The replayed change will be filtered. -SELECT count(*) = 0 FROM pg_logical_slot_peek_binary_changes('regression_slot', NULL, NULL, 'proto_version', '4', 'publication_names', 'pub', 'origin', 'none'); - ?column? ----------- - t -(1 row) - --- The replayed change will be output if the origin value is not specified. -SELECT count(*) != 0 FROM pg_logical_slot_peek_binary_changes('regression_slot', NULL, NULL, 'proto_version', '4', 'publication_names', 'pub'); - ?column? ----------- - t -(1 row) - --- Clean up -SELECT pg_replication_origin_session_reset(); - pg_replication_origin_session_reset -------------------------------------- - -(1 row) - -SELECT pg_drop_replication_slot('regression_slot'); - pg_drop_replication_slot --------------------------- - -(1 row) - -SELECT pg_replication_origin_drop('regress_test_decoding: regression_slot'); - pg_replication_origin_drop ----------------------------- - -(1 row) - -DROP PUBLICATION pub; +psql: error: connection to server on socket "/tmp/pg_regress-cdBOAK/.s.PGSQL.58928" failed: No such file or directory + Is the server running locally and accepting connections on that socket? diff -U3 /tmp/cirrus-ci-build/contrib/test_decoding/expected/time.out /tmp/cirrus-ci-build/contrib/test_decoding/results/time.out --- /tmp/cirrus-ci-build/contrib/test_decoding/expected/time.out 2025-12-24 20:55:54.419537987 +0000 +++ /tmp/cirrus-ci-build/contrib/test_decoding/results/time.out 2025-12-24 21:01:48.447327253 +0000 @@ -1,40 +1,2 @@ -SET synchronous_commit = on; -CREATE TABLE test_time(data text); --- remember the current time -SELECT set_config('test.time_before', NOW()::text, false) IS NOT NULL; - ?column? ----------- - t -(1 row) - -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); - ?column? ----------- - init -(1 row) - --- a single transaction, to get the commit time -INSERT INTO test_time(data) VALUES (''); --- parse the commit time from the changeset -SELECT set_config('test.time_after', regexp_replace(data, '^COMMIT \(at (.*)\)$', '\1'), false) IS NOT NULL -FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-timestamp', '1') -WHERE data ~ 'COMMIT' LIMIT 1; - ?column? ----------- - t -(1 row) - --- ensure commit time is sane in relation to the previous time -SELECT (time_after - time_before) <= '10 minutes'::interval, time_after >= time_before -FROM (SELECT current_setting('test.time_after')::timestamptz AS time_after, (SELECT current_setting('test.time_before')::timestamptz) AS time_before) AS d; - ?column? | ?column? -----------+---------- - t | t -(1 row) - -SELECT pg_drop_replication_slot('regression_slot'); - pg_drop_replication_slot --------------------------- - -(1 row) - +psql: error: connection to server on socket "/tmp/pg_regress-cdBOAK/.s.PGSQL.58928" failed: No such file or directory + Is the server running locally and accepting connections on that socket? diff -U3 /tmp/cirrus-ci-build/contrib/test_decoding/expected/messages.out /tmp/cirrus-ci-build/contrib/test_decoding/results/messages.out --- /tmp/cirrus-ci-build/contrib/test_decoding/expected/messages.out 2025-12-24 20:55:54.419537987 +0000 +++ /tmp/cirrus-ci-build/contrib/test_decoding/results/messages.out 2025-12-24 21:01:48.475328045 +0000 @@ -1,106 +1,2 @@ --- predictability -SET synchronous_commit = on; -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); - ?column? ----------- - init -(1 row) - --- These two cover the path for the flush variant. -SELECT 'msg1' FROM pg_logical_emit_message(true, 'test', 'msg1', true); - ?column? ----------- - msg1 -(1 row) - -SELECT 'msg2' FROM pg_logical_emit_message(false, 'test', 'msg2', true); - ?column? ----------- - msg2 -(1 row) - -BEGIN; -SELECT 'msg3' FROM pg_logical_emit_message(true, 'test', 'msg3'); - ?column? ----------- - msg3 -(1 row) - -SELECT 'msg4' FROM pg_logical_emit_message(false, 'test', 'msg4'); - ?column? ----------- - msg4 -(1 row) - -ROLLBACK; -BEGIN; -SELECT 'msg5' FROM pg_logical_emit_message(true, 'test', 'msg5'); - ?column? ----------- - msg5 -(1 row) - -SELECT 'msg6' FROM pg_logical_emit_message(false, 'test', 'msg6'); - ?column? ----------- - msg6 -(1 row) - -SELECT 'msg7' FROM pg_logical_emit_message(true, 'test', 'msg7'); - ?column? ----------- - msg7 -(1 row) - -COMMIT; -SELECT 'ignorethis' FROM pg_logical_emit_message(true, 'test', 'czechtastic'); - ?column? ------------- - ignorethis -(1 row) - -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'force-binary', '0', 'skip-empty-xacts', '1', 'include-xids', '0'); - data --------------------------------------------------------------------- - BEGIN - message: transactional: 1 prefix: test, sz: 4 content:msg1 - COMMIT - message: transactional: 0 prefix: test, sz: 4 content:msg2 - message: transactional: 0 prefix: test, sz: 4 content:msg4 - message: transactional: 0 prefix: test, sz: 4 content:msg6 - BEGIN - message: transactional: 1 prefix: test, sz: 4 content:msg5 - message: transactional: 1 prefix: test, sz: 4 content:msg7 - COMMIT - BEGIN - message: transactional: 1 prefix: test, sz: 11 content:czechtastic - COMMIT -(13 rows) - --- test db filtering -\set prevdb :DBNAME -\c template1 -SELECT 'otherdb1' FROM pg_logical_emit_message(false, 'test', 'otherdb1'); - ?column? ----------- - otherdb1 -(1 row) - -SELECT 'otherdb2' FROM pg_logical_emit_message(true, 'test', 'otherdb2'); - ?column? ----------- - otherdb2 -(1 row) - -\c :prevdb -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'force-binary', '0', 'skip-empty-xacts', '1'); - data ------- -(0 rows) - -SELECT 'cleanup' FROM pg_drop_replication_slot('regression_slot'); - ?column? ----------- - cleanup -(1 row) - +psql: error: connection to server on socket "/tmp/pg_regress-cdBOAK/.s.PGSQL.58928" failed: No such file or directory + Is the server running locally and accepting connections on that socket? diff -U3 /tmp/cirrus-ci-build/contrib/test_decoding/expected/spill.out /tmp/cirrus-ci-build/contrib/test_decoding/results/spill.out --- /tmp/cirrus-ci-build/contrib/test_decoding/expected/spill.out 2025-12-24 20:55:54.419537987 +0000 +++ /tmp/cirrus-ci-build/contrib/test_decoding/results/spill.out 2025-12-24 21:01:48.519329289 +0000 @@ -1,256 +1,2 @@ --- predictability -SET synchronous_commit = on; -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); - ?column? ----------- - init -(1 row) - -CREATE TABLE spill_test(data text); --- consume DDL -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data ------- -(0 rows) - --- spilling main xact -BEGIN; -INSERT INTO spill_test SELECT 'serialize-topbig--1:'||g.i FROM generate_series(1, 5000) g(i); -COMMIT; -SELECT (regexp_split_to_array(data, ':'))[4], COUNT(*), (array_agg(data))[1], (array_agg(data))[count(*)] -FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL) WHERE data ~ 'INSERT' -GROUP BY 1 ORDER BY 1; - regexp_split_to_array | count | array_agg | array_agg ------------------------+-------+---------------------------------------------------------------------+------------------------------------------------------------------------ - 'serialize-topbig--1 | 5000 | table public.spill_test: INSERT: data[text]:'serialize-topbig--1:1' | table public.spill_test: INSERT: data[text]:'serialize-topbig--1:5000' -(1 row) - --- spilling subxact, nothing in main -BEGIN; -SAVEPOINT s; -INSERT INTO spill_test SELECT 'serialize-subbig--1:'||g.i FROM generate_series(1, 5000) g(i); -RELEASE SAVEPOINT s; -COMMIT; -SELECT (regexp_split_to_array(data, ':'))[4], COUNT(*), (array_agg(data))[1], (array_agg(data))[count(*)] -FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL) WHERE data ~ 'INSERT' -GROUP BY 1 ORDER BY 1; - regexp_split_to_array | count | array_agg | array_agg ------------------------+-------+---------------------------------------------------------------------+------------------------------------------------------------------------ - 'serialize-subbig--1 | 5000 | table public.spill_test: INSERT: data[text]:'serialize-subbig--1:1' | table public.spill_test: INSERT: data[text]:'serialize-subbig--1:5000' -(1 row) - --- spilling subxact, spilling main xact -BEGIN; -SAVEPOINT s; -INSERT INTO spill_test SELECT 'serialize-subbig-topbig--1:'||g.i FROM generate_series(1, 5000) g(i); -RELEASE SAVEPOINT s; -INSERT INTO spill_test SELECT 'serialize-subbig-topbig--2:'||g.i FROM generate_series(5001, 10000) g(i); -COMMIT; -SELECT (regexp_split_to_array(data, ':'))[4], COUNT(*), (array_agg(data))[1], (array_agg(data))[count(*)] -FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL) WHERE data ~ 'INSERT' -GROUP BY 1 ORDER BY 1; - regexp_split_to_array | count | array_agg | array_agg ------------------------------+-------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------- - 'serialize-subbig-topbig--1 | 5000 | table public.spill_test: INSERT: data[text]:'serialize-subbig-topbig--1:1' | table public.spill_test: INSERT: data[text]:'serialize-subbig-topbig--1:5000' - 'serialize-subbig-topbig--2 | 5000 | table public.spill_test: INSERT: data[text]:'serialize-subbig-topbig--2:5001' | table public.spill_test: INSERT: data[text]:'serialize-subbig-topbig--2:10000' -(2 rows) - --- spilling subxact, non-spilling main xact -BEGIN; -SAVEPOINT s; -INSERT INTO spill_test SELECT 'serialize-subbig-topsmall--1:'||g.i FROM generate_series(1, 5000) g(i); -RELEASE SAVEPOINT s; -INSERT INTO spill_test SELECT 'serialize-subbig-topsmall--2:'||g.i FROM generate_series(5001, 5001) g(i); -COMMIT; -SELECT (regexp_split_to_array(data, ':'))[4], COUNT(*), (array_agg(data))[1], (array_agg(data))[count(*)] -FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL) WHERE data ~ 'INSERT' -GROUP BY 1 ORDER BY 1; - regexp_split_to_array | count | array_agg | array_agg --------------------------------+-------+---------------------------------------------------------------------------------+--------------------------------------------------------------------------------- - 'serialize-subbig-topsmall--1 | 5000 | table public.spill_test: INSERT: data[text]:'serialize-subbig-topsmall--1:1' | table public.spill_test: INSERT: data[text]:'serialize-subbig-topsmall--1:5000' - 'serialize-subbig-topsmall--2 | 1 | table public.spill_test: INSERT: data[text]:'serialize-subbig-topsmall--2:5001' | table public.spill_test: INSERT: data[text]:'serialize-subbig-topsmall--2:5001' -(2 rows) - --- not-spilling subxact, spilling main xact -BEGIN; -SAVEPOINT s; -INSERT INTO spill_test SELECT 'serialize-subbig-topbig--1:'||g.i FROM generate_series(1, 5000) g(i); -RELEASE SAVEPOINT s; -INSERT INTO spill_test SELECT 'serialize-subbig-topbig--2:'||g.i FROM generate_series(5001, 10000) g(i); -COMMIT; -SELECT (regexp_split_to_array(data, ':'))[4], COUNT(*), (array_agg(data))[1], (array_agg(data))[count(*)] -FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL) WHERE data ~ 'INSERT' -GROUP BY 1 ORDER BY 1; - regexp_split_to_array | count | array_agg | array_agg ------------------------------+-------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------- - 'serialize-subbig-topbig--1 | 5000 | table public.spill_test: INSERT: data[text]:'serialize-subbig-topbig--1:1' | table public.spill_test: INSERT: data[text]:'serialize-subbig-topbig--1:5000' - 'serialize-subbig-topbig--2 | 5000 | table public.spill_test: INSERT: data[text]:'serialize-subbig-topbig--2:5001' | table public.spill_test: INSERT: data[text]:'serialize-subbig-topbig--2:10000' -(2 rows) - --- spilling main xact, spilling subxact -BEGIN; -INSERT INTO spill_test SELECT 'serialize-topbig-subbig--1:'||g.i FROM generate_series(1, 5000) g(i); -SAVEPOINT s; -INSERT INTO spill_test SELECT 'serialize-topbig-subbig--2:'||g.i FROM generate_series(5001, 10000) g(i); -RELEASE SAVEPOINT s; -COMMIT; -SELECT (regexp_split_to_array(data, ':'))[4], COUNT(*), (array_agg(data))[1], (array_agg(data))[count(*)] -FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL) WHERE data ~ 'INSERT' -GROUP BY 1 ORDER BY 1; - regexp_split_to_array | count | array_agg | array_agg ------------------------------+-------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------- - 'serialize-topbig-subbig--1 | 5000 | table public.spill_test: INSERT: data[text]:'serialize-topbig-subbig--1:1' | table public.spill_test: INSERT: data[text]:'serialize-topbig-subbig--1:5000' - 'serialize-topbig-subbig--2 | 5000 | table public.spill_test: INSERT: data[text]:'serialize-topbig-subbig--2:5001' | table public.spill_test: INSERT: data[text]:'serialize-topbig-subbig--2:10000' -(2 rows) - --- spilling main xact, not spilling subxact -BEGIN; -INSERT INTO spill_test SELECT 'serialize-topbig-subsmall--1:'||g.i FROM generate_series(1, 5000) g(i); -SAVEPOINT s; -INSERT INTO spill_test SELECT 'serialize-topbig-subsmall--2:'||g.i FROM generate_series(5001, 5001) g(i); -RELEASE SAVEPOINT s; -COMMIT; -SELECT (regexp_split_to_array(data, ':'))[4], COUNT(*), (array_agg(data))[1], (array_agg(data))[count(*)] -FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL) WHERE data ~ 'INSERT' -GROUP BY 1 ORDER BY 1; - regexp_split_to_array | count | array_agg | array_agg --------------------------------+-------+---------------------------------------------------------------------------------+--------------------------------------------------------------------------------- - 'serialize-topbig-subsmall--1 | 5000 | table public.spill_test: INSERT: data[text]:'serialize-topbig-subsmall--1:1' | table public.spill_test: INSERT: data[text]:'serialize-topbig-subsmall--1:5000' - 'serialize-topbig-subsmall--2 | 1 | table public.spill_test: INSERT: data[text]:'serialize-topbig-subsmall--2:5001' | table public.spill_test: INSERT: data[text]:'serialize-topbig-subsmall--2:5001' -(2 rows) - --- spilling subxact, followed by another spilling subxact -BEGIN; -SAVEPOINT s1; -INSERT INTO spill_test SELECT 'serialize-subbig-subbig--1:'||g.i FROM generate_series(1, 5000) g(i); -RELEASE SAVEPOINT s1; -SAVEPOINT s2; -INSERT INTO spill_test SELECT 'serialize-subbig-subbig--2:'||g.i FROM generate_series(5001, 10000) g(i); -RELEASE SAVEPOINT s2; -COMMIT; -SELECT (regexp_split_to_array(data, ':'))[4], COUNT(*), (array_agg(data))[1], (array_agg(data))[count(*)] -FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL) WHERE data ~ 'INSERT' -GROUP BY 1 ORDER BY 1; - regexp_split_to_array | count | array_agg | array_agg ------------------------------+-------+-------------------------------------------------------------------------------+-------------------------------------------------------------------------------- - 'serialize-subbig-subbig--1 | 5000 | table public.spill_test: INSERT: data[text]:'serialize-subbig-subbig--1:1' | table public.spill_test: INSERT: data[text]:'serialize-subbig-subbig--1:5000' - 'serialize-subbig-subbig--2 | 5000 | table public.spill_test: INSERT: data[text]:'serialize-subbig-subbig--2:5001' | table public.spill_test: INSERT: data[text]:'serialize-subbig-subbig--2:10000' -(2 rows) - --- spilling subxact, followed by not spilling subxact -BEGIN; -SAVEPOINT s1; -INSERT INTO spill_test SELECT 'serialize-subbig-subsmall--1:'||g.i FROM generate_series(1, 5000) g(i); -RELEASE SAVEPOINT s1; -SAVEPOINT s2; -INSERT INTO spill_test SELECT 'serialize-subbig-subsmall--2:'||g.i FROM generate_series(5001, 5001) g(i); -RELEASE SAVEPOINT s2; -COMMIT; -SELECT (regexp_split_to_array(data, ':'))[4], COUNT(*), (array_agg(data))[1], (array_agg(data))[count(*)] -FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL) WHERE data ~ 'INSERT' -GROUP BY 1 ORDER BY 1; - regexp_split_to_array | count | array_agg | array_agg --------------------------------+-------+---------------------------------------------------------------------------------+--------------------------------------------------------------------------------- - 'serialize-subbig-subsmall--1 | 5000 | table public.spill_test: INSERT: data[text]:'serialize-subbig-subsmall--1:1' | table public.spill_test: INSERT: data[text]:'serialize-subbig-subsmall--1:5000' - 'serialize-subbig-subsmall--2 | 1 | table public.spill_test: INSERT: data[text]:'serialize-subbig-subsmall--2:5001' | table public.spill_test: INSERT: data[text]:'serialize-subbig-subsmall--2:5001' -(2 rows) - --- not spilling subxact, followed by spilling subxact -BEGIN; -SAVEPOINT s1; -INSERT INTO spill_test SELECT 'serialize-subsmall-subbig--1:'||g.i FROM generate_series(1, 1) g(i); -RELEASE SAVEPOINT s1; -SAVEPOINT s2; -INSERT INTO spill_test SELECT 'serialize-subsmall-subbig--2:'||g.i FROM generate_series(2, 5001) g(i); -RELEASE SAVEPOINT s2; -COMMIT; -SELECT (regexp_split_to_array(data, ':'))[4] COLLATE "C", COUNT(*), (array_agg(data))[1], (array_agg(data))[count(*)] -FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL) WHERE data ~ 'INSERT' -GROUP BY 1 ORDER BY 1; - regexp_split_to_array | count | array_agg | array_agg --------------------------------+-------+------------------------------------------------------------------------------+--------------------------------------------------------------------------------- - 'serialize-subsmall-subbig--1 | 1 | table public.spill_test: INSERT: data[text]:'serialize-subsmall-subbig--1:1' | table public.spill_test: INSERT: data[text]:'serialize-subsmall-subbig--1:1' - 'serialize-subsmall-subbig--2 | 5000 | table public.spill_test: INSERT: data[text]:'serialize-subsmall-subbig--2:2' | table public.spill_test: INSERT: data[text]:'serialize-subsmall-subbig--2:5001' -(2 rows) - --- spilling subxact, containing another spilling subxact -BEGIN; -SAVEPOINT s1; -INSERT INTO spill_test SELECT 'serialize-nested-subbig-subbig--1:'||g.i FROM generate_series(1, 5000) g(i); -SAVEPOINT s2; -INSERT INTO spill_test SELECT 'serialize-nested-subbig-subbig--2:'||g.i FROM generate_series(5001, 10000) g(i); -RELEASE SAVEPOINT s2; -RELEASE SAVEPOINT s1; -COMMIT; -SELECT (regexp_split_to_array(data, ':'))[4] COLLATE "C", COUNT(*), (array_agg(data))[1], (array_agg(data))[count(*)] -FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL) WHERE data ~ 'INSERT' -GROUP BY 1 ORDER BY 1; - regexp_split_to_array | count | array_agg | array_agg -------------------------------------+-------+--------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------- - 'serialize-nested-subbig-subbig--1 | 5000 | table public.spill_test: INSERT: data[text]:'serialize-nested-subbig-subbig--1:1' | table public.spill_test: INSERT: data[text]:'serialize-nested-subbig-subbig--1:5000' - 'serialize-nested-subbig-subbig--2 | 5000 | table public.spill_test: INSERT: data[text]:'serialize-nested-subbig-subbig--2:5001' | table public.spill_test: INSERT: data[text]:'serialize-nested-subbig-subbig--2:10000' -(2 rows) - --- spilling subxact, containing a not spilling subxact -BEGIN; -SAVEPOINT s1; -INSERT INTO spill_test SELECT 'serialize-nested-subbig-subsmall--1:'||g.i FROM generate_series(1, 5000) g(i); -SAVEPOINT s2; -INSERT INTO spill_test SELECT 'serialize-nested-subbig-subsmall--2:'||g.i FROM generate_series(5001, 5001) g(i); -RELEASE SAVEPOINT s2; -RELEASE SAVEPOINT s1; -COMMIT; -SELECT (regexp_split_to_array(data, ':'))[4] COLLATE "C", COUNT(*), (array_agg(data))[1], (array_agg(data))[count(*)] -FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL) WHERE data ~ 'INSERT' -GROUP BY 1 ORDER BY 1; - regexp_split_to_array | count | array_agg | array_agg ---------------------------------------+-------+----------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------- - 'serialize-nested-subbig-subsmall--1 | 5000 | table public.spill_test: INSERT: data[text]:'serialize-nested-subbig-subsmall--1:1' | table public.spill_test: INSERT: data[text]:'serialize-nested-subbig-subsmall--1:5000' - 'serialize-nested-subbig-subsmall--2 | 1 | table public.spill_test: INSERT: data[text]:'serialize-nested-subbig-subsmall--2:5001' | table public.spill_test: INSERT: data[text]:'serialize-nested-subbig-subsmall--2:5001' -(2 rows) - --- not spilling subxact, containing a spilling subxact -BEGIN; -SAVEPOINT s1; -INSERT INTO spill_test SELECT 'serialize-nested-subsmall-subbig--1:'||g.i FROM generate_series(1, 1) g(i); -SAVEPOINT s2; -INSERT INTO spill_test SELECT 'serialize-nested-subsmall-subbig--2:'||g.i FROM generate_series(2, 5001) g(i); -RELEASE SAVEPOINT s2; -RELEASE SAVEPOINT s1; -COMMIT; -SELECT (regexp_split_to_array(data, ':'))[4] COLLATE "C", COUNT(*), (array_agg(data))[1], (array_agg(data))[count(*)] -FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL) WHERE data ~ 'INSERT' -GROUP BY 1 ORDER BY 1; - regexp_split_to_array | count | array_agg | array_agg ---------------------------------------+-------+-------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------- - 'serialize-nested-subsmall-subbig--1 | 1 | table public.spill_test: INSERT: data[text]:'serialize-nested-subsmall-subbig--1:1' | table public.spill_test: INSERT: data[text]:'serialize-nested-subsmall-subbig--1:1' - 'serialize-nested-subsmall-subbig--2 | 5000 | table public.spill_test: INSERT: data[text]:'serialize-nested-subsmall-subbig--2:2' | table public.spill_test: INSERT: data[text]:'serialize-nested-subsmall-subbig--2:5001' -(2 rows) - --- not spilling subxact, containing a spilling subxact that aborts and one that commits -BEGIN; -SAVEPOINT s1; -INSERT INTO spill_test SELECT 'serialize-nested-subbig-subbigabort--1:'||g.i FROM generate_series(1, 5000) g(i); -SAVEPOINT s2; -INSERT INTO spill_test SELECT 'serialize-nested-subbig-subbigabort--2:'||g.i FROM generate_series(5001, 10000) g(i); -ROLLBACK TO SAVEPOINT s2; -SAVEPOINT s3; -INSERT INTO spill_test SELECT 'serialize-nested-subbig-subbigabort-subbig-3:'||g.i FROM generate_series(5001, 10000) g(i); -RELEASE SAVEPOINT s1; -COMMIT; -SELECT (regexp_split_to_array(data, ':'))[4] COLLATE "C", COUNT(*), (array_agg(data))[1], (array_agg(data))[count(*)] -FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL) WHERE data ~ 'INSERT' -GROUP BY 1 ORDER BY 1; - regexp_split_to_array | count | array_agg | array_agg ------------------------------------------------+-------+-------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------- - 'serialize-nested-subbig-subbigabort--1 | 5000 | table public.spill_test: INSERT: data[text]:'serialize-nested-subbig-subbigabort--1:1' | table public.spill_test: INSERT: data[text]:'serialize-nested-subbig-subbigabort--1:5000' - 'serialize-nested-subbig-subbigabort-subbig-3 | 5000 | table public.spill_test: INSERT: data[text]:'serialize-nested-subbig-subbigabort-subbig-3:5001' | table public.spill_test: INSERT: data[text]:'serialize-nested-subbig-subbigabort-subbig-3:10000' -(2 rows) - -DROP TABLE spill_test; -SELECT pg_drop_replication_slot('regression_slot'); - pg_drop_replication_slot --------------------------- - -(1 row) - +psql: error: connection to server on socket "/tmp/pg_regress-cdBOAK/.s.PGSQL.58928" failed: No such file or directory + Is the server running locally and accepting connections on that socket? diff -U3 /tmp/cirrus-ci-build/contrib/test_decoding/expected/slot.out /tmp/cirrus-ci-build/contrib/test_decoding/results/slot.out --- /tmp/cirrus-ci-build/contrib/test_decoding/expected/slot.out 2025-12-24 20:55:54.419537987 +0000 +++ /tmp/cirrus-ci-build/contrib/test_decoding/results/slot.out 2025-12-24 21:01:48.547330081 +0000 @@ -1,468 +1,2 @@ --- predictability -SET synchronous_commit = on; -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot_p', 'test_decoding'); - ?column? ----------- - init -(1 row) - -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot_t', 'test_decoding', true); - ?column? ----------- - init -(1 row) - -SELECT pg_drop_replication_slot('regression_slot_p'); - pg_drop_replication_slot --------------------------- - -(1 row) - -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot_p', 'test_decoding', false); - ?column? ----------- - init -(1 row) - -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot_t2', 'test_decoding', true); - ?column? ----------- - init -(1 row) - -SELECT pg_create_logical_replication_slot('foo', 'nonexistent'); -ERROR: could not access file "nonexistent": No such file or directory --- here we want to start a new session and wait till old one is gone -select pg_backend_pid() as oldpid \gset -\c - -SET synchronous_commit = on; -do 'declare c int = 0; -begin - while (select count(*) from pg_replication_slots where active_pid = ' - :'oldpid' - ') > 0 loop c := c + 1; perform pg_sleep(0.01); end loop; - raise log ''slot test looped % times'', c; -end'; --- should fail because the temporary slots were dropped automatically -SELECT pg_drop_replication_slot('regression_slot_t'); -ERROR: replication slot "regression_slot_t" does not exist -SELECT pg_drop_replication_slot('regression_slot_t2'); -ERROR: replication slot "regression_slot_t2" does not exist --- monitoring functions for slot directories -SELECT count(*) >= 0 AS ok FROM pg_ls_logicalmapdir(); - ok ----- - t -(1 row) - -SELECT count(*) >= 0 AS ok FROM pg_ls_logicalsnapdir(); - ok ----- - t -(1 row) - -SELECT count(*) >= 0 AS ok FROM pg_ls_replslotdir('regression_slot_p'); - ok ----- - t -(1 row) - -SELECT count(*) >= 0 AS ok FROM pg_ls_replslotdir('not_existing_slot'); -- fails -ERROR: replication slot "not_existing_slot" does not exist --- permanent slot has survived -SELECT pg_drop_replication_slot('regression_slot_p'); - pg_drop_replication_slot --------------------------- - -(1 row) - --- test switching between slots in a session -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot1', 'test_decoding', true); - ?column? ----------- - init -(1 row) - -CREATE TABLE replication_example(id SERIAL PRIMARY KEY, somedata int, text varchar(120)); -BEGIN; -INSERT INTO replication_example(somedata, text) VALUES (1, 1); -INSERT INTO replication_example(somedata, text) VALUES (1, 2); -COMMIT; -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot2', 'test_decoding', true); - ?column? ----------- - init -(1 row) - -INSERT INTO replication_example(somedata, text) VALUES (1, 3); -SELECT data FROM pg_logical_slot_get_changes('regression_slot1', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data ---------------------------------------------------------------------------------------------------------- - BEGIN - table public.replication_example: INSERT: id[integer]:1 somedata[integer]:1 text[character varying]:'1' - table public.replication_example: INSERT: id[integer]:2 somedata[integer]:1 text[character varying]:'2' - COMMIT - BEGIN - table public.replication_example: INSERT: id[integer]:3 somedata[integer]:1 text[character varying]:'3' - COMMIT -(7 rows) - -SELECT data FROM pg_logical_slot_get_changes('regression_slot2', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data ---------------------------------------------------------------------------------------------------------- - BEGIN - table public.replication_example: INSERT: id[integer]:3 somedata[integer]:1 text[character varying]:'3' - COMMIT -(3 rows) - -INSERT INTO replication_example(somedata, text) VALUES (1, 4); -INSERT INTO replication_example(somedata, text) VALUES (1, 5); -SELECT pg_current_wal_lsn() AS wal_lsn \gset -INSERT INTO replication_example(somedata, text) VALUES (1, 6); -SELECT end_lsn FROM pg_replication_slot_advance('regression_slot1', :'wal_lsn') \gset -SELECT slot_name FROM pg_replication_slot_advance('regression_slot2', pg_current_wal_lsn()); - slot_name ------------------- - regression_slot2 -(1 row) - -SELECT :'wal_lsn' = :'end_lsn'; - ?column? ----------- - t -(1 row) - -SELECT data FROM pg_logical_slot_get_changes('regression_slot1', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data ---------------------------------------------------------------------------------------------------------- - BEGIN - table public.replication_example: INSERT: id[integer]:6 somedata[integer]:1 text[character varying]:'6' - COMMIT -(3 rows) - -SELECT data FROM pg_logical_slot_get_changes('regression_slot2', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data ------- -(0 rows) - -DROP TABLE replication_example; --- error -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot1', 'test_decoding', true); -ERROR: replication slot "regression_slot1" already exists --- both should error as they should be dropped on error -SELECT pg_drop_replication_slot('regression_slot1'); -ERROR: replication slot "regression_slot1" does not exist -SELECT pg_drop_replication_slot('regression_slot2'); -ERROR: replication slot "regression_slot2" does not exist --- slot advance with physical slot, error with non-reserved slot -SELECT slot_name FROM pg_create_physical_replication_slot('regression_slot3'); - slot_name ------------------- - regression_slot3 -(1 row) - -SELECT pg_replication_slot_advance('regression_slot3', '0/0'); -- invalid LSN -ERROR: invalid target WAL LSN -SELECT pg_replication_slot_advance('regression_slot3', '0/1'); -- error -ERROR: replication slot "regression_slot3" cannot be advanced -DETAIL: This slot has never previously reserved WAL, or it has been invalidated. -SELECT pg_drop_replication_slot('regression_slot3'); - pg_drop_replication_slot --------------------------- - -(1 row) - --- --- Test copy functions for logical replication slots --- --- Create and copy logical slots -SELECT 'init' FROM pg_create_logical_replication_slot('orig_slot1', 'test_decoding', false); - ?column? ----------- - init -(1 row) - -SELECT 'copy' FROM pg_copy_logical_replication_slot('orig_slot1', 'copied_slot1_no_change'); - ?column? ----------- - copy -(1 row) - -SELECT 'copy' FROM pg_copy_logical_replication_slot('orig_slot1', 'copied_slot1_change_plugin', false, 'pgoutput'); - ?column? ----------- - copy -(1 row) - -SELECT 'copy' FROM pg_copy_logical_replication_slot('orig_slot1', 'copied_slot1_change_plugin_temp', true, 'pgoutput'); - ?column? ----------- - copy -(1 row) - --- Check all copied slots status -SELECT - o.slot_name, o.plugin, o.temporary, c.slot_name, c.plugin, c.temporary -FROM - (SELECT * FROM pg_replication_slots WHERE slot_name LIKE 'orig%') as o - LEFT JOIN pg_replication_slots as c ON o.restart_lsn = c.restart_lsn AND o.confirmed_flush_lsn = c.confirmed_flush_lsn -WHERE - o.slot_name != c.slot_name -ORDER BY o.slot_name, c.slot_name; - slot_name | plugin | temporary | slot_name | plugin | temporary -------------+---------------+-----------+---------------------------------+---------------+----------- - orig_slot1 | test_decoding | f | copied_slot1_change_plugin | pgoutput | f - orig_slot1 | test_decoding | f | copied_slot1_change_plugin_temp | pgoutput | t - orig_slot1 | test_decoding | f | copied_slot1_no_change | test_decoding | f -(3 rows) - --- Now we have maximum 4 replication slots. Check slots are properly --- released even when raise error during creating the target slot. -SELECT 'copy' FROM pg_copy_logical_replication_slot('orig_slot1', 'failed'); -- error -ERROR: all replication slots are in use -HINT: Free one or increase "max_replication_slots". --- temporary slots were dropped automatically -SELECT pg_drop_replication_slot('orig_slot1'); - pg_drop_replication_slot --------------------------- - -(1 row) - -SELECT pg_drop_replication_slot('copied_slot1_no_change'); - pg_drop_replication_slot --------------------------- - -(1 row) - -SELECT pg_drop_replication_slot('copied_slot1_change_plugin'); - pg_drop_replication_slot --------------------------- - -(1 row) - --- Test based on the temporary logical slot -SELECT 'init' FROM pg_create_logical_replication_slot('orig_slot2', 'test_decoding', true); - ?column? ----------- - init -(1 row) - -SELECT 'copy' FROM pg_copy_logical_replication_slot('orig_slot2', 'copied_slot2_no_change'); - ?column? ----------- - copy -(1 row) - -SELECT 'copy' FROM pg_copy_logical_replication_slot('orig_slot2', 'copied_slot2_change_plugin', true, 'pgoutput'); - ?column? ----------- - copy -(1 row) - -SELECT 'copy' FROM pg_copy_logical_replication_slot('orig_slot2', 'copied_slot2_change_plugin_temp', false, 'pgoutput'); - ?column? ----------- - copy -(1 row) - --- Check all copied slots status -SELECT - o.slot_name, o.plugin, o.temporary, c.slot_name, c.plugin, c.temporary -FROM - (SELECT * FROM pg_replication_slots WHERE slot_name LIKE 'orig%') as o - LEFT JOIN pg_replication_slots as c ON o.restart_lsn = c.restart_lsn AND o.confirmed_flush_lsn = c.confirmed_flush_lsn -WHERE - o.slot_name != c.slot_name -ORDER BY o.slot_name, c.slot_name; - slot_name | plugin | temporary | slot_name | plugin | temporary -------------+---------------+-----------+---------------------------------+---------------+----------- - orig_slot2 | test_decoding | t | copied_slot2_change_plugin | pgoutput | t - orig_slot2 | test_decoding | t | copied_slot2_change_plugin_temp | pgoutput | f - orig_slot2 | test_decoding | t | copied_slot2_no_change | test_decoding | t -(3 rows) - --- Cannot copy a logical slot to a physical slot -SELECT 'copy' FROM pg_copy_physical_replication_slot('orig_slot2', 'failed'); -- error -ERROR: cannot copy physical replication slot "orig_slot2" as a logical replication slot --- temporary slots were dropped automatically -SELECT pg_drop_replication_slot('copied_slot2_change_plugin_temp'); - pg_drop_replication_slot --------------------------- - -(1 row) - --- --- Test copy functions for physical replication slots --- --- Create and copy physical slots -SELECT 'init' FROM pg_create_physical_replication_slot('orig_slot1', true); - ?column? ----------- - init -(1 row) - -SELECT 'init' FROM pg_create_physical_replication_slot('orig_slot2', false); - ?column? ----------- - init -(1 row) - -SELECT 'copy' FROM pg_copy_physical_replication_slot('orig_slot1', 'copied_slot1_no_change'); - ?column? ----------- - copy -(1 row) - -SELECT 'copy' FROM pg_copy_physical_replication_slot('orig_slot1', 'copied_slot1_temp', true); - ?column? ----------- - copy -(1 row) - --- Check all copied slots status. Since all slots don't reserve WAL we check only other fields. -SELECT slot_name, slot_type, temporary FROM pg_replication_slots; - slot_name | slot_type | temporary -------------------------+-----------+----------- - orig_slot1 | physical | f - orig_slot2 | physical | f - copied_slot1_no_change | physical | f - copied_slot1_temp | physical | t -(4 rows) - --- Cannot copy a physical slot to a logical slot -SELECT 'copy' FROM pg_copy_logical_replication_slot('orig_slot1', 'failed'); -- error -ERROR: cannot copy logical replication slot "orig_slot1" as a physical replication slot --- Cannot copy a physical slot that doesn't reserve WAL -SELECT 'copy' FROM pg_copy_physical_replication_slot('orig_slot2', 'failed'); -- error -ERROR: cannot copy a replication slot that doesn't reserve WAL --- temporary slots were dropped automatically -SELECT pg_drop_replication_slot('orig_slot1'); - pg_drop_replication_slot --------------------------- - -(1 row) - -SELECT pg_drop_replication_slot('orig_slot2'); - pg_drop_replication_slot --------------------------- - -(1 row) - -SELECT pg_drop_replication_slot('copied_slot1_no_change'); - pg_drop_replication_slot --------------------------- - -(1 row) - --- Test based on the temporary physical slot -SELECT 'init' FROM pg_create_physical_replication_slot('orig_slot2', true, true); - ?column? ----------- - init -(1 row) - -SELECT 'copy' FROM pg_copy_physical_replication_slot('orig_slot2', 'copied_slot2_no_change'); - ?column? ----------- - copy -(1 row) - -SELECT 'copy' FROM pg_copy_physical_replication_slot('orig_slot2', 'copied_slot2_notemp', false); - ?column? ----------- - copy -(1 row) - --- Check all copied slots status -SELECT - o.slot_name, o.temporary, c.slot_name, c.temporary -FROM - (SELECT * FROM pg_replication_slots WHERE slot_name LIKE 'orig%') as o - LEFT JOIN pg_replication_slots as c ON o.restart_lsn = c.restart_lsn -WHERE - o.slot_name != c.slot_name -ORDER BY o.slot_name, c.slot_name; - slot_name | temporary | slot_name | temporary -------------+-----------+------------------------+----------- - orig_slot2 | t | copied_slot2_no_change | t - orig_slot2 | t | copied_slot2_notemp | f -(2 rows) - -SELECT pg_drop_replication_slot('orig_slot2'); - pg_drop_replication_slot --------------------------- - -(1 row) - -SELECT pg_drop_replication_slot('copied_slot2_no_change'); - pg_drop_replication_slot --------------------------- - -(1 row) - -SELECT pg_drop_replication_slot('copied_slot2_notemp'); - pg_drop_replication_slot --------------------------- - -(1 row) - --- Test failover option of slots. -SELECT 'init' FROM pg_create_logical_replication_slot('failover_true_slot', 'test_decoding', false, false, true); - ?column? ----------- - init -(1 row) - -SELECT 'init' FROM pg_create_logical_replication_slot('failover_false_slot', 'test_decoding', false, false, false); - ?column? ----------- - init -(1 row) - -SELECT 'init' FROM pg_create_logical_replication_slot('failover_default_slot', 'test_decoding', false, false); - ?column? ----------- - init -(1 row) - -SELECT 'init' FROM pg_create_logical_replication_slot('failover_true_temp_slot', 'test_decoding', true, false, true); -ERROR: cannot enable failover for a temporary replication slot -SELECT 'init' FROM pg_create_physical_replication_slot('physical_slot'); - ?column? ----------- - init -(1 row) - -SELECT slot_name, slot_type, failover FROM pg_replication_slots; - slot_name | slot_type | failover ------------------------+-----------+---------- - failover_true_slot | logical | t - failover_false_slot | logical | f - failover_default_slot | logical | f - physical_slot | physical | f -(4 rows) - -SELECT pg_drop_replication_slot('failover_true_slot'); - pg_drop_replication_slot --------------------------- - -(1 row) - -SELECT pg_drop_replication_slot('failover_false_slot'); - pg_drop_replication_slot --------------------------- - -(1 row) - -SELECT pg_drop_replication_slot('failover_default_slot'); - pg_drop_replication_slot --------------------------- - -(1 row) - -SELECT pg_drop_replication_slot('physical_slot'); - pg_drop_replication_slot --------------------------- - -(1 row) - +psql: error: connection to server on socket "/tmp/pg_regress-cdBOAK/.s.PGSQL.58928" failed: No such file or directory + Is the server running locally and accepting connections on that socket? diff -U3 /tmp/cirrus-ci-build/contrib/test_decoding/expected/truncate.out /tmp/cirrus-ci-build/contrib/test_decoding/results/truncate.out --- /tmp/cirrus-ci-build/contrib/test_decoding/expected/truncate.out 2025-12-24 20:55:54.419537987 +0000 +++ /tmp/cirrus-ci-build/contrib/test_decoding/results/truncate.out 2025-12-24 21:01:48.587331212 +0000 @@ -1,33 +1,2 @@ --- predictability -SET synchronous_commit = on; -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); - ?column? ----------- - init -(1 row) - -CREATE TABLE tab1 (id serial unique, data int); -CREATE TABLE tab2 (a int primary key, b int); -TRUNCATE tab1; -TRUNCATE tab1, tab1 RESTART IDENTITY CASCADE; -TRUNCATE tab1, tab2; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data ------------------------------------------------------- - BEGIN - table public.tab1: TRUNCATE: (no-flags) - COMMIT - BEGIN - table public.tab1: TRUNCATE: restart_seqs cascade - COMMIT - BEGIN - table public.tab1, public.tab2: TRUNCATE: (no-flags) - COMMIT -(9 rows) - -SELECT pg_drop_replication_slot('regression_slot'); - pg_drop_replication_slot --------------------------- - -(1 row) - +psql: error: connection to server on socket "/tmp/pg_regress-cdBOAK/.s.PGSQL.58928" failed: No such file or directory + Is the server running locally and accepting connections on that socket? diff -U3 /tmp/cirrus-ci-build/contrib/test_decoding/expected/stream.out /tmp/cirrus-ci-build/contrib/test_decoding/results/stream.out --- /tmp/cirrus-ci-build/contrib/test_decoding/expected/stream.out 2025-12-24 20:55:54.419537987 +0000 +++ /tmp/cirrus-ci-build/contrib/test_decoding/results/stream.out 2025-12-24 21:01:48.611331891 +0000 @@ -1,143 +1,2 @@ -SET synchronous_commit = on; -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); - ?column? ----------- - init -(1 row) - -CREATE TABLE stream_test(data text); --- consume DDL -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data ------- -(0 rows) - --- streaming test with sub-transaction -BEGIN; -savepoint s1; -SELECT 'msg5' FROM pg_logical_emit_message(true, 'test', repeat('a', 50)); - ?column? ----------- - msg5 -(1 row) - -INSERT INTO stream_test SELECT repeat('a', 2000) || g.i FROM generate_series(1, 35) g(i); -TRUNCATE table stream_test; -rollback to s1; -INSERT INTO stream_test SELECT repeat('a', 10) || g.i FROM generate_series(1, 20) g(i); -COMMIT; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1'); - data ----------------------------------------------------------- - opening a streamed block for transaction - streaming message: transactional: 1 prefix: test, sz: 50 - closing a streamed block for transaction - aborting streamed (sub)transaction - opening a streamed block for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - closing a streamed block for transaction - committing streamed transaction -(27 rows) - --- streaming test for toast changes -ALTER TABLE stream_test ALTER COLUMN data set storage external; --- consume DDL -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data ------- -(0 rows) - -INSERT INTO stream_test SELECT repeat('a', 6000) || g.i FROM generate_series(1, 10) g(i); -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1'); - data ------------------------------------------- - opening a streamed block for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - closing a streamed block for transaction - committing streamed transaction -(13 rows) - --- streaming test for toast with multi-insert -\COPY stream_test FROM STDIN -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1'); - data ------------------------------------------- - opening a streamed block for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - closing a streamed block for transaction - opening a streamed block for transaction - streaming change for transaction - closing a streamed block for transaction - committing streamed transaction -(17 rows) - -/* - * Test concurrent abort with toast data. When streaming the second insertion, we - * detect that the subtransaction was aborted, and reset the transaction while having - * the TOAST changes in memory, resulting in deallocating both decoded changes and - * TOAST reconstruction data. Memory usage counters must be updated correctly. - * - * Set debug_logical_replication_streaming to 'immediate' to disable the transaction - * status check happening before streaming the second insertion, so we can detect a - * concurrent abort while streaming. - */ -SET debug_logical_replication_streaming = immediate; -BEGIN; -INSERT INTO stream_test SELECT repeat(string_agg(to_char(g.i, 'FM0000'), ''), 50) FROM generate_series(1, 500) g(i); -ALTER TABLE stream_test ADD COLUMN i INT; -SAVEPOINT s1; -INSERT INTO stream_test(data, i) SELECT repeat(string_agg(to_char(g.i, 'FM0000'), ''), 50), 1 FROM generate_series(1, 500) g(i); -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'); - count -------- - 5 -(1 row) - -RESET debug_logical_replication_streaming; -DROP TABLE stream_test; -SELECT pg_drop_replication_slot('regression_slot'); - pg_drop_replication_slot --------------------------- - -(1 row) - +psql: error: connection to server on socket "/tmp/pg_regress-cdBOAK/.s.PGSQL.58928" failed: No such file or directory + Is the server running locally and accepting connections on that socket? diff -U3 /tmp/cirrus-ci-build/contrib/test_decoding/expected/stats.out /tmp/cirrus-ci-build/contrib/test_decoding/results/stats.out --- /tmp/cirrus-ci-build/contrib/test_decoding/expected/stats.out 2025-12-24 20:55:54.419537987 +0000 +++ /tmp/cirrus-ci-build/contrib/test_decoding/results/stats.out 2025-12-24 21:01:48.635332570 +0000 @@ -1,186 +1,2 @@ --- predictability -SET synchronous_commit = on; -SELECT 'init' FROM - pg_create_logical_replication_slot('regression_slot_stats1', 'test_decoding') s1, - pg_create_logical_replication_slot('regression_slot_stats2', 'test_decoding') s2, - pg_create_logical_replication_slot('regression_slot_stats3', 'test_decoding') s3; - ?column? ----------- - init -(1 row) - -CREATE TABLE stats_test(data text); --- non-spilled xact -SET logical_decoding_work_mem to '64MB'; -INSERT INTO stats_test values(1); -SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot_stats1', NULL, NULL, 'skip-empty-xacts', '1'); - count -------- - 3 -(1 row) - -SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot_stats2', NULL, NULL, 'skip-empty-xacts', '1'); - count -------- - 3 -(1 row) - -SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot_stats3', NULL, NULL, 'skip-empty-xacts', '1'); - count -------- - 3 -(1 row) - -SELECT pg_stat_force_next_flush(); - pg_stat_force_next_flush --------------------------- - -(1 row) - -SELECT slot_name, spill_txns = 0 AS spill_txns, spill_count = 0 AS spill_count, total_txns > 0 AS total_txns, total_bytes > 0 AS total_bytes, mem_exceeded_count = 0 AS mem_exceeded_count FROM pg_stat_replication_slots ORDER BY slot_name; - slot_name | spill_txns | spill_count | total_txns | total_bytes | mem_exceeded_count -------------------------+------------+-------------+------------+-------------+-------------------- - regression_slot_stats1 | t | t | t | t | t - regression_slot_stats2 | t | t | t | t | t - regression_slot_stats3 | t | t | t | t | t -(3 rows) - -RESET logical_decoding_work_mem; --- reset stats for one slot, others should be unaffected -SELECT pg_stat_reset_replication_slot('regression_slot_stats1'); - pg_stat_reset_replication_slot --------------------------------- - -(1 row) - -SELECT slot_name, spill_txns = 0 AS spill_txns, spill_count = 0 AS spill_count, total_txns > 0 AS total_txns, total_bytes > 0 AS total_bytes, mem_exceeded_count = 0 AS mem_exceeded_count FROM pg_stat_replication_slots ORDER BY slot_name; - slot_name | spill_txns | spill_count | total_txns | total_bytes | mem_exceeded_count -------------------------+------------+-------------+------------+-------------+-------------------- - regression_slot_stats1 | t | t | f | f | t - regression_slot_stats2 | t | t | t | t | t - regression_slot_stats3 | t | t | t | t | t -(3 rows) - --- reset stats for all slots -SELECT pg_stat_reset_replication_slot(NULL); - pg_stat_reset_replication_slot --------------------------------- - -(1 row) - -SELECT slot_name, spill_txns = 0 AS spill_txns, spill_count = 0 AS spill_count, total_txns > 0 AS total_txns, total_bytes > 0 AS total_bytes, mem_exceeded_count = 0 AS mem_exceeded_count FROM pg_stat_replication_slots ORDER BY slot_name; - slot_name | spill_txns | spill_count | total_txns | total_bytes | mem_exceeded_count -------------------------+------------+-------------+------------+-------------+-------------------- - regression_slot_stats1 | t | t | f | f | t - regression_slot_stats2 | t | t | f | f | t - regression_slot_stats3 | t | t | f | f | t -(3 rows) - --- verify accessing/resetting stats for non-existent slot does something reasonable -SELECT * FROM pg_stat_get_replication_slot('do-not-exist'); - slot_name | spill_txns | spill_count | spill_bytes | stream_txns | stream_count | stream_bytes | mem_exceeded_count | total_txns | total_bytes | slotsync_skip_count | slotsync_last_skip | stats_reset ---------------+------------+-------------+-------------+-------------+--------------+--------------+--------------------+------------+-------------+---------------------+--------------------+------------- - do-not-exist | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | -(1 row) - -SELECT pg_stat_reset_replication_slot('do-not-exist'); -ERROR: replication slot "do-not-exist" does not exist -SELECT * FROM pg_stat_get_replication_slot('do-not-exist'); - slot_name | spill_txns | spill_count | spill_bytes | stream_txns | stream_count | stream_bytes | mem_exceeded_count | total_txns | total_bytes | slotsync_skip_count | slotsync_last_skip | stats_reset ---------------+------------+-------------+-------------+-------------+--------------+--------------+--------------------+------------+-------------+---------------------+--------------------+------------- - do-not-exist | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | -(1 row) - --- spilling the xact -BEGIN; -INSERT INTO stats_test SELECT 'serialize-topbig--1:'||g.i FROM generate_series(1, 5000) g(i); -COMMIT; -SELECT count(*) FROM pg_logical_slot_peek_changes('regression_slot_stats1', NULL, NULL, 'skip-empty-xacts', '1'); - count -------- - 5002 -(1 row) - --- Check stats. We can't test the exact stats count as that can vary if any --- background transaction (say by autovacuum) happens in parallel to the main --- transaction. -SELECT pg_stat_force_next_flush(); - pg_stat_force_next_flush --------------------------- - -(1 row) - -SELECT slot_name, spill_txns > 0 AS spill_txns, spill_count > 0 AS spill_count, mem_exceeded_count > 0 AS mem_exceeded_count FROM pg_stat_replication_slots; - slot_name | spill_txns | spill_count | mem_exceeded_count -------------------------+------------+-------------+-------------------- - regression_slot_stats1 | t | t | t - regression_slot_stats2 | f | f | f - regression_slot_stats3 | f | f | f -(3 rows) - --- Ensure stats can be repeatedly accessed using the same stats snapshot. See --- https://postgr.es/m/20210317230447.c7uc4g3vbs4wi32i%40alap3.anarazel.de -BEGIN; -SELECT slot_name FROM pg_stat_replication_slots; - slot_name ------------------------- - regression_slot_stats1 - regression_slot_stats2 - regression_slot_stats3 -(3 rows) - -SELECT slot_name FROM pg_stat_replication_slots; - slot_name ------------------------- - regression_slot_stats1 - regression_slot_stats2 - regression_slot_stats3 -(3 rows) - -COMMIT; -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot_stats4_twophase', 'test_decoding', false, true) s4; - ?column? ----------- - init -(1 row) - --- The INSERT changes are large enough to be spilled but will not be, because --- the transaction is aborted. The logical decoding skips collecting further --- changes too. The transaction is prepared to make sure the decoding processes --- the aborted transaction. -BEGIN; -INSERT INTO stats_test SELECT 'serialize-toobig--1:'||g.i FROM generate_series(1, 5000) g(i); -PREPARE TRANSACTION 'test1_abort'; -ROLLBACK PREPARED 'test1_abort'; -SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot_stats4_twophase', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - count -------- - 1 -(1 row) - --- Verify that the decoding doesn't spill already-aborted transaction's changes. --- Given that there is no concurrent activities that are capturable by logical decoding, --- mem_exceeded_count should theoretically be 1 but we check if >0 here since it's --- more flexible for potential future changes and adequate for the testing purpose. -SELECT pg_stat_force_next_flush(); - pg_stat_force_next_flush --------------------------- - -(1 row) - -SELECT slot_name, spill_txns, spill_count, mem_exceeded_count > 0 as mem_exceeded_count FROM pg_stat_replication_slots WHERE slot_name = 'regression_slot_stats4_twophase'; - slot_name | spill_txns | spill_count | mem_exceeded_count ----------------------------------+------------+-------------+-------------------- - regression_slot_stats4_twophase | 0 | 0 | t -(1 row) - -DROP TABLE stats_test; -SELECT pg_drop_replication_slot('regression_slot_stats1'), - pg_drop_replication_slot('regression_slot_stats2'), - pg_drop_replication_slot('regression_slot_stats3'), - pg_drop_replication_slot('regression_slot_stats4_twophase'); - pg_drop_replication_slot | pg_drop_replication_slot | pg_drop_replication_slot | pg_drop_replication_slot ---------------------------+--------------------------+--------------------------+-------------------------- - | | | -(1 row) - +psql: error: connection to server on socket "/tmp/pg_regress-cdBOAK/.s.PGSQL.58928" failed: No such file or directory + Is the server running locally and accepting connections on that socket? diff -U3 /tmp/cirrus-ci-build/contrib/test_decoding/expected/twophase.out /tmp/cirrus-ci-build/contrib/test_decoding/results/twophase.out --- /tmp/cirrus-ci-build/contrib/test_decoding/expected/twophase.out 2025-12-24 20:55:54.419537987 +0000 +++ /tmp/cirrus-ci-build/contrib/test_decoding/results/twophase.out 2025-12-24 21:01:48.683333927 +0000 @@ -1,247 +1,2 @@ --- Test prepared transactions. When two-phase-commit is enabled, transactions are --- decoded at PREPARE time rather than at COMMIT PREPARED time. -SET synchronous_commit = on; -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding', false, true); - ?column? ----------- - init -(1 row) - -CREATE TABLE test_prepared1(id integer primary key); -CREATE TABLE test_prepared2(id integer primary key); --- Test that decoding happens at PREPARE time when two-phase-commit is enabled. --- Decoding after COMMIT PREPARED must have all the commands in the transaction. -BEGIN; -INSERT INTO test_prepared1 VALUES (1); -INSERT INTO test_prepared1 VALUES (2); --- should show nothing because the xact has not been prepared yet. -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data ------- -(0 rows) - -PREPARE TRANSACTION 'test_prepared#1'; --- should show both the above inserts and the PREPARE TRANSACTION. -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data ----------------------------------------------------- - BEGIN - table public.test_prepared1: INSERT: id[integer]:1 - table public.test_prepared1: INSERT: id[integer]:2 - PREPARE TRANSACTION 'test_prepared#1' -(4 rows) - -COMMIT PREPARED 'test_prepared#1'; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data ------------------------------------ - COMMIT PREPARED 'test_prepared#1' -(1 row) - --- Test that rollback of a prepared xact is decoded. -BEGIN; -INSERT INTO test_prepared1 VALUES (3); -PREPARE TRANSACTION 'test_prepared#2'; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data ----------------------------------------------------- - BEGIN - table public.test_prepared1: INSERT: id[integer]:3 - PREPARE TRANSACTION 'test_prepared#2' -(3 rows) - -ROLLBACK PREPARED 'test_prepared#2'; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data -------------------------------------- - ROLLBACK PREPARED 'test_prepared#2' -(1 row) - --- Test prepare of a xact containing ddl. Leaving xact uncommitted for next test. -BEGIN; -ALTER TABLE test_prepared1 ADD COLUMN data text; -INSERT INTO test_prepared1 VALUES (4, 'frakbar'); -PREPARE TRANSACTION 'test_prepared#3'; --- confirm that exclusive lock from the ALTER command is held on test_prepared1 table -SELECT 'test_prepared_1' AS relation, locktype, mode -FROM pg_locks -WHERE locktype = 'relation' - AND relation = 'test_prepared1'::regclass; - relation | locktype | mode ------------------+----------+--------------------- - test_prepared_1 | relation | RowExclusiveLock - test_prepared_1 | relation | AccessExclusiveLock -(2 rows) - --- The insert should show the newly altered column but not the DDL. -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data -------------------------------------------------------------------------- - BEGIN - table public.test_prepared1: INSERT: id[integer]:4 data[text]:'frakbar' - PREPARE TRANSACTION 'test_prepared#3' -(3 rows) - --- Test that we decode correctly while an uncommitted prepared xact --- with ddl exists. --- --- Use a separate table for the concurrent transaction because the lock from --- the ALTER will stop us inserting into the other one. --- -INSERT INTO test_prepared2 VALUES (5); -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data ----------------------------------------------------- - BEGIN - table public.test_prepared2: INSERT: id[integer]:5 - COMMIT -(3 rows) - -COMMIT PREPARED 'test_prepared#3'; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data ------------------------------------ - COMMIT PREPARED 'test_prepared#3' -(1 row) - --- make sure stuff still works -INSERT INTO test_prepared1 VALUES (6); -INSERT INTO test_prepared2 VALUES (7); -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data --------------------------------------------------------------------- - BEGIN - table public.test_prepared1: INSERT: id[integer]:6 data[text]:null - COMMIT - BEGIN - table public.test_prepared2: INSERT: id[integer]:7 - COMMIT -(6 rows) - --- Check 'CLUSTER' (as operation that hold exclusive lock) doesn't block --- logical decoding. -BEGIN; -INSERT INTO test_prepared1 VALUES (8, 'othercol'); -CLUSTER test_prepared1 USING test_prepared1_pkey; -INSERT INTO test_prepared1 VALUES (9, 'othercol2'); -PREPARE TRANSACTION 'test_prepared_lock'; -SELECT 'test_prepared1' AS relation, locktype, mode -FROM pg_locks -WHERE locktype = 'relation' - AND relation = 'test_prepared1'::regclass; - relation | locktype | mode -----------------+----------+--------------------- - test_prepared1 | relation | RowExclusiveLock - test_prepared1 | relation | ShareLock - test_prepared1 | relation | AccessExclusiveLock -(3 rows) - --- The above CLUSTER command shouldn't cause a timeout on 2pc decoding. -\set env_timeout '' -\getenv env_timeout PG_TEST_TIMEOUT_DEFAULT -SELECT COALESCE(NULLIF(:'env_timeout', ''), '180') || 's' AS timeout \gset -SET statement_timeout = :'timeout'; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data ---------------------------------------------------------------------------- - BEGIN - table public.test_prepared1: INSERT: id[integer]:8 data[text]:'othercol' - table public.test_prepared1: INSERT: id[integer]:9 data[text]:'othercol2' - PREPARE TRANSACTION 'test_prepared_lock' -(4 rows) - -RESET statement_timeout; -COMMIT PREPARED 'test_prepared_lock'; --- consume the commit -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data --------------------------------------- - COMMIT PREPARED 'test_prepared_lock' -(1 row) - --- Test savepoints and sub-xacts. Creating savepoints will create --- sub-xacts implicitly. -BEGIN; -CREATE TABLE test_prepared_savepoint (a int); -INSERT INTO test_prepared_savepoint VALUES (1); -SAVEPOINT test_savepoint; -INSERT INTO test_prepared_savepoint VALUES (2); -ROLLBACK TO SAVEPOINT test_savepoint; -PREPARE TRANSACTION 'test_prepared_savepoint'; --- should show only 1, not 2 -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data ------------------------------------------------------------- - BEGIN - table public.test_prepared_savepoint: INSERT: a[integer]:1 - PREPARE TRANSACTION 'test_prepared_savepoint' -(3 rows) - -COMMIT PREPARED 'test_prepared_savepoint'; --- consume the commit -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data -------------------------------------------- - COMMIT PREPARED 'test_prepared_savepoint' -(1 row) - --- Test that a GID containing "_nodecode" gets decoded at commit prepared time. -BEGIN; -INSERT INTO test_prepared1 VALUES (20); -PREPARE TRANSACTION 'test_prepared_nodecode'; --- should show nothing -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data ------- -(0 rows) - -COMMIT PREPARED 'test_prepared_nodecode'; --- should be decoded now -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data ---------------------------------------------------------------------- - BEGIN - table public.test_prepared1: INSERT: id[integer]:20 data[text]:null - COMMIT -(3 rows) - --- Test that accessing a TOAST table is permitted during the decoding of a --- prepared transaction. --- 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 -BEGIN; -INSERT INTO test_tab VALUES('test'); -PREPARE TRANSACTION 'test_toast_table_access'; -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 PREPARED 'test_toast_table_access'; --- consume commit prepared -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1'); - data -------------------------------------------- - COMMIT PREPARED 'test_toast_table_access' -(1 row) - --- Test 8: --- cleanup and make sure results are also empty -DROP TABLE test_prepared1; -DROP TABLE test_prepared2; -DROP TABLE test_prepared_savepoint; -DROP TABLE test_tab; --- show results. There should be nothing to show -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data ------- -(0 rows) - -SELECT pg_drop_replication_slot('regression_slot'); - pg_drop_replication_slot --------------------------- - -(1 row) - +psql: error: connection to server on socket "/tmp/pg_regress-cdBOAK/.s.PGSQL.58928" failed: No such file or directory + Is the server running locally and accepting connections on that socket? diff -U3 /tmp/cirrus-ci-build/contrib/test_decoding/expected/twophase_stream.out /tmp/cirrus-ci-build/contrib/test_decoding/results/twophase_stream.out --- /tmp/cirrus-ci-build/contrib/test_decoding/expected/twophase_stream.out 2025-12-24 20:55:54.419537987 +0000 +++ /tmp/cirrus-ci-build/contrib/test_decoding/results/twophase_stream.out 2025-12-24 21:01:48.751335849 +0000 @@ -1,131 +1,2 @@ --- Test streaming of two-phase commits -SET synchronous_commit = on; -SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding', false, true); - ?column? ----------- - init -(1 row) - -CREATE TABLE stream_test(data text); --- consume DDL -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data ------- -(0 rows) - --- streaming test with sub-transaction and PREPARE/COMMIT PREPARED -BEGIN; -SAVEPOINT s1; -SELECT 'msg5' FROM pg_logical_emit_message(true, 'test', repeat('a', 50)); - ?column? ----------- - msg5 -(1 row) - -INSERT INTO stream_test SELECT repeat('a', 2000) || g.i FROM generate_series(1, 35) g(i); -TRUNCATE table stream_test; -ROLLBACK TO s1; -INSERT INTO stream_test SELECT repeat('a', 10) || g.i FROM generate_series(1, 20) g(i); -PREPARE TRANSACTION 'test1'; --- should show the inserts after a ROLLBACK -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1'); - data ----------------------------------------------------------- - opening a streamed block for transaction - streaming message: transactional: 1 prefix: test, sz: 50 - closing a streamed block for transaction - aborting streamed (sub)transaction - opening a streamed block for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - streaming change for transaction - closing a streamed block for transaction - preparing streamed transaction 'test1' -(27 rows) - -COMMIT PREPARED 'test1'; ---should show the COMMIT PREPARED and the other changes in the transaction -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1'); - data -------------------------- - COMMIT PREPARED 'test1' -(1 row) - --- streaming test with sub-transaction and PREPARE/COMMIT PREPARED but with --- filtered gid. gids with '_nodecode' will not be decoded at prepare time. -BEGIN; -SAVEPOINT s1; -SELECT 'msg5' FROM pg_logical_emit_message(true, 'test', repeat('a', 50)); - ?column? ----------- - msg5 -(1 row) - -INSERT INTO stream_test SELECT repeat('a', 2000) || g.i FROM generate_series(1, 35) g(i); -TRUNCATE table stream_test; -ROLLBACK to s1; -INSERT INTO stream_test SELECT repeat('a', 10) || g.i FROM generate_series(1, 20) g(i); -PREPARE TRANSACTION 'test1_nodecode'; --- should NOT show inserts after a ROLLBACK -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1'); - data ----------------------------------------------------------- - opening a streamed block for transaction - streaming message: transactional: 1 prefix: test, sz: 50 - closing a streamed block for transaction - aborting streamed (sub)transaction -(4 rows) - -COMMIT PREPARED 'test1_nodecode'; --- should show the inserts but not show a COMMIT PREPARED but a COMMIT -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1'); - data -------------------------------------------------------------- - BEGIN - table public.stream_test: INSERT: data[text]:'aaaaaaaaaa1' - table public.stream_test: INSERT: data[text]:'aaaaaaaaaa2' - table public.stream_test: INSERT: data[text]:'aaaaaaaaaa3' - table public.stream_test: INSERT: data[text]:'aaaaaaaaaa4' - table public.stream_test: INSERT: data[text]:'aaaaaaaaaa5' - table public.stream_test: INSERT: data[text]:'aaaaaaaaaa6' - table public.stream_test: INSERT: data[text]:'aaaaaaaaaa7' - table public.stream_test: INSERT: data[text]:'aaaaaaaaaa8' - table public.stream_test: INSERT: data[text]:'aaaaaaaaaa9' - table public.stream_test: INSERT: data[text]:'aaaaaaaaaa10' - table public.stream_test: INSERT: data[text]:'aaaaaaaaaa11' - table public.stream_test: INSERT: data[text]:'aaaaaaaaaa12' - table public.stream_test: INSERT: data[text]:'aaaaaaaaaa13' - table public.stream_test: INSERT: data[text]:'aaaaaaaaaa14' - table public.stream_test: INSERT: data[text]:'aaaaaaaaaa15' - table public.stream_test: INSERT: data[text]:'aaaaaaaaaa16' - table public.stream_test: INSERT: data[text]:'aaaaaaaaaa17' - table public.stream_test: INSERT: data[text]:'aaaaaaaaaa18' - table public.stream_test: INSERT: data[text]:'aaaaaaaaaa19' - table public.stream_test: INSERT: data[text]:'aaaaaaaaaa20' - COMMIT -(22 rows) - -DROP TABLE stream_test; -SELECT pg_drop_replication_slot('regression_slot'); - pg_drop_replication_slot --------------------------- - -(1 row) - +psql: error: connection to server on socket "/tmp/pg_regress-cdBOAK/.s.PGSQL.58928" failed: No such file or directory + Is the server running locally and accepting connections on that socket?