Skip to content

Commit b779d7d

Browse files
committed
Fix skip-empty-xacts with sequences in test_decoding
Regression tests need to use skip-empty-xacts = false, because there might be accidental concurrent activity (like autovacuum), particularly on slow machines. The tests added by 80901b3 failed to do that in a couple places, triggering occasional failures on buildfarm. Fixing the tests however uncovered a bug in the code, because sequence callbacks did not handle skip-empty-xacts properly. For trasactional increments we need to check/update the xact_wrote_changes flag, and emit the BEGIN if it's the first change in the transaction. Reported-by: Andres Freund Discussion: https://postgr.es/m/20220212220413.b25amklo7t4xb7ni%40alap3.anarazel.de
1 parent faa189c commit b779d7d

File tree

3 files changed

+31
-11
lines changed

3 files changed

+31
-11
lines changed

contrib/test_decoding/expected/sequence.out

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ SELECT nextval('test_sequence');
8787
(1 row)
8888

8989
-- show results and drop sequence
90-
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '0');
90+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
9191
data
9292
----------------------------------------------------------------------------------------
9393
BEGIN
@@ -236,7 +236,7 @@ SELECT nextval('test_table_a_seq');
236236
(1 row)
237237

238238
DROP TABLE test_table;
239-
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '0');
239+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
240240
data
241241
-------------------------------------------------------------------------------------------
242242
BEGIN
@@ -245,9 +245,7 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'inc
245245
sequence public.test_table_a_seq: transactional:0 last_value: 33 log_cnt: 0 is_called:1
246246
sequence public.test_table_a_seq: transactional:0 last_value: 3000 log_cnt: 0 is_called:1
247247
sequence public.test_table_a_seq: transactional:0 last_value: 3033 log_cnt: 0 is_called:1
248-
BEGIN
249-
COMMIT
250-
(8 rows)
248+
(6 rows)
251249

252250
-- savepoint test on table with serial column
253251
BEGIN;
@@ -259,7 +257,7 @@ INSERT INTO test_table (b) VALUES (300);
259257
ROLLBACK TO SAVEPOINT a;
260258
DROP TABLE test_table;
261259
COMMIT;
262-
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '0');
260+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
263261
data
264262
-----------------------------------------------------------------------------------------
265263
BEGIN
@@ -308,7 +306,7 @@ SELECT * FROM test_sequence;
308306

309307
DROP SEQUENCE test_sequence;
310308
COMMIT;
311-
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '0');
309+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
312310
data
313311
----------------------------------------------------------------------------------------
314312
BEGIN

contrib/test_decoding/sql/sequence.sql

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ SELECT setval('test_sequence', 3500, false);
2828
SELECT nextval('test_sequence');
2929

3030
-- show results and drop sequence
31-
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '0');
31+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
3232
DROP SEQUENCE test_sequence;
3333

3434
-- rollback on sequence creation and update
@@ -87,7 +87,7 @@ SELECT * from test_table_a_seq;
8787
SELECT nextval('test_table_a_seq');
8888

8989
DROP TABLE test_table;
90-
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '0');
90+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
9191

9292
-- savepoint test on table with serial column
9393
BEGIN;
@@ -99,7 +99,7 @@ INSERT INTO test_table (b) VALUES (300);
9999
ROLLBACK TO SAVEPOINT a;
100100
DROP TABLE test_table;
101101
COMMIT;
102-
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '0');
102+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
103103

104104
-- savepoint test on table with serial column
105105
BEGIN;
@@ -114,6 +114,6 @@ ROLLBACK TO SAVEPOINT a;
114114
SELECT * FROM test_sequence;
115115
DROP SEQUENCE test_sequence;
116116
COMMIT;
117-
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '0');
117+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
118118

119119
SELECT pg_drop_replication_slot('regression_slot');

contrib/test_decoding/test_decoding.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -774,10 +774,21 @@ pg_decode_sequence(LogicalDecodingContext *ctx, ReorderBufferTXN *txn,
774774
int64 last_value, int64 log_cnt, bool is_called)
775775
{
776776
TestDecodingData *data = ctx->output_plugin_private;
777+
TestDecodingTxnData *txndata = txn->output_plugin_private;
777778

778779
if (!data->include_sequences)
779780
return;
780781

782+
/* output BEGIN if we haven't yet, but only for the transactional case */
783+
if (transactional)
784+
{
785+
if (data->skip_empty_xacts && !txndata->xact_wrote_changes)
786+
{
787+
pg_output_begin(ctx, data, txn, false);
788+
}
789+
txndata->xact_wrote_changes = true;
790+
}
791+
781792
OutputPluginPrepareWrite(ctx, true);
782793
appendStringInfoString(ctx->out, "sequence ");
783794
appendStringInfoString(ctx->out,
@@ -994,10 +1005,21 @@ pg_decode_stream_sequence(LogicalDecodingContext *ctx, ReorderBufferTXN *txn,
9941005
int64 last_value, int64 log_cnt, bool is_called)
9951006
{
9961007
TestDecodingData *data = ctx->output_plugin_private;
1008+
TestDecodingTxnData *txndata = txn->output_plugin_private;
9971009

9981010
if (!data->include_sequences)
9991011
return;
10001012

1013+
/* output BEGIN if we haven't yet, but only for the transactional case */
1014+
if (transactional)
1015+
{
1016+
if (data->skip_empty_xacts && !txndata->xact_wrote_changes)
1017+
{
1018+
pg_output_begin(ctx, data, txn, false);
1019+
}
1020+
txndata->xact_wrote_changes = true;
1021+
}
1022+
10011023
OutputPluginPrepareWrite(ctx, true);
10021024
appendStringInfoString(ctx->out, "streaming sequence ");
10031025
appendStringInfoString(ctx->out,

0 commit comments

Comments
 (0)