mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-02-23 19:39:53 +08:00
Add decoding of sequences to test_decoding
Commit 0da92dc530
improved the logical decoding infrastructure to handle
sequences, and did various changes to related parts (WAL logging etc.).
But it did not include any implementation of the new callbacks added to
OutputPluginCallbacks.
This extends test_decoding with two callbacks to decode sequences. The
decoding of sequences may be disabled using 'include-sequences', a new
option of the output plugin.
Author: Tomas Vondra, Cary Huang
Reviewed-by: Peter Eisentraut, Hannu Krosing, Andres Freund
Discussion: https://postgr.es/m/d045f3c2-6cfb-06d3-5540-e63c320df8bc@enterprisedb.com
Discussion: https://postgr.es/m/1710ed7e13b.cd7177461430746.3372264562543607781@highgo.ca
This commit is contained in:
parent
44fa84881f
commit
80901b3291
@ -5,7 +5,8 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin"
|
||||
|
||||
REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
|
||||
decoding_into_rel binary prepared replorigin time messages \
|
||||
spill slot truncate stream stats twophase twophase_stream
|
||||
spill slot truncate stream stats twophase twophase_stream \
|
||||
sequence
|
||||
ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
|
||||
oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
|
||||
twophase_snapshot
|
||||
|
File diff suppressed because one or more lines are too long
@ -58,7 +58,7 @@ SELECT pg_current_xact_id() = '0';
|
||||
|
||||
-- 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');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
data
|
||||
-----------------------------------------------------------
|
||||
BEGIN
|
||||
|
@ -19,7 +19,7 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'inc
|
||||
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 data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
SELECT * FROM changeresult;
|
||||
data
|
||||
------------------------------------------------
|
||||
@ -29,9 +29,9 @@ SELECT * FROM changeresult;
|
||||
(3 rows)
|
||||
|
||||
INSERT INTO changeresult
|
||||
SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
INSERT INTO changeresult
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
SELECT * FROM changeresult;
|
||||
data
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@ -63,7 +63,7 @@ DROP TABLE somechange;
|
||||
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');
|
||||
SELECT data FROM pg_logical_slot_peek_changes(slot_name, NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
END$$ LANGUAGE plpgsql;
|
||||
SELECT * FROM slot_changes_wrapper('regression_slot');
|
||||
slot_changes_wrapper
|
||||
@ -84,7 +84,7 @@ SELECT * FROM slot_changes_wrapper('regression_slot');
|
||||
COMMIT
|
||||
(14 rows)
|
||||
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
data
|
||||
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
BEGIN
|
||||
|
@ -7,7 +7,7 @@ step s0init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_sl
|
||||
init
|
||||
(1 row)
|
||||
|
||||
step s0start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false');
|
||||
step s0start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false', 'include-sequences', 'false');
|
||||
data
|
||||
----
|
||||
(0 rows)
|
||||
@ -27,7 +27,7 @@ t
|
||||
(1 row)
|
||||
|
||||
step s0w: INSERT INTO do_write DEFAULT VALUES;
|
||||
step s0start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false');
|
||||
step s0start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false', 'include-sequences', 'false');
|
||||
data
|
||||
--------------------------------------------
|
||||
BEGIN
|
||||
@ -50,7 +50,7 @@ step s0init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_sl
|
||||
init
|
||||
(1 row)
|
||||
|
||||
step s0start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false');
|
||||
step s0start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false', 'include-sequences', 'false');
|
||||
data
|
||||
----
|
||||
(0 rows)
|
||||
@ -71,7 +71,7 @@ t
|
||||
|
||||
step s0alter: ALTER TABLE do_write ADD column ts timestamptz;
|
||||
step s0w: INSERT INTO do_write DEFAULT VALUES;
|
||||
step s0start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false');
|
||||
step s0start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false', 'include-sequences', 'false');
|
||||
data
|
||||
------------------------------------------------------------------------------
|
||||
BEGIN
|
||||
|
@ -35,7 +35,7 @@ init
|
||||
step s2c: COMMIT;
|
||||
step s1insert: INSERT INTO do_write DEFAULT VALUES;
|
||||
step s1checkpoint: CHECKPOINT;
|
||||
step s1start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false');
|
||||
step s1start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false', 'include-sequences', 'false');
|
||||
data
|
||||
--------------------------------------------------------------------
|
||||
BEGIN
|
||||
@ -46,7 +46,7 @@ COMMIT
|
||||
step s1insert: INSERT INTO do_write DEFAULT VALUES;
|
||||
step s1alter: ALTER TABLE do_write ADD COLUMN addedbys1 int;
|
||||
step s1insert: INSERT INTO do_write DEFAULT VALUES;
|
||||
step s1start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false');
|
||||
step s1start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false', 'include-sequences', 'false');
|
||||
data
|
||||
--------------------------------------------------------------------------------------------
|
||||
BEGIN
|
||||
|
@ -72,9 +72,9 @@ SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_d
|
||||
-- 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');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
-- 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');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
data
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
BEGIN
|
||||
|
@ -64,7 +64,7 @@ SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_d
|
||||
|
||||
CREATE TABLE replication_example(id SERIAL PRIMARY KEY, somedata int, text varchar(120));
|
||||
INSERT INTO replication_example(somedata) VALUES (1);
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
data
|
||||
----------------------------------------------------------------------------------------------------------
|
||||
BEGIN
|
||||
@ -141,7 +141,7 @@ VACUUM FULL pg_proc; VACUUM FULL pg_description; VACUUM FULL pg_shdescription; V
|
||||
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');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
data
|
||||
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
BEGIN
|
||||
|
327
contrib/test_decoding/expected/sequence.out
Normal file
327
contrib/test_decoding/expected/sequence.out
Normal file
@ -0,0 +1,327 @@
|
||||
-- predictability
|
||||
SET synchronous_commit = on;
|
||||
SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding');
|
||||
?column?
|
||||
----------
|
||||
init
|
||||
(1 row)
|
||||
|
||||
CREATE SEQUENCE test_sequence;
|
||||
-- test the sequence changes by several nextval() calls
|
||||
SELECT nextval('test_sequence');
|
||||
nextval
|
||||
---------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
SELECT nextval('test_sequence');
|
||||
nextval
|
||||
---------
|
||||
2
|
||||
(1 row)
|
||||
|
||||
SELECT nextval('test_sequence');
|
||||
nextval
|
||||
---------
|
||||
3
|
||||
(1 row)
|
||||
|
||||
SELECT nextval('test_sequence');
|
||||
nextval
|
||||
---------
|
||||
4
|
||||
(1 row)
|
||||
|
||||
-- test the sequence changes by several ALTER commands
|
||||
ALTER SEQUENCE test_sequence INCREMENT BY 10;
|
||||
SELECT nextval('test_sequence');
|
||||
nextval
|
||||
---------
|
||||
14
|
||||
(1 row)
|
||||
|
||||
ALTER SEQUENCE test_sequence START WITH 3000;
|
||||
ALTER SEQUENCE test_sequence MAXVALUE 10000;
|
||||
ALTER SEQUENCE test_sequence RESTART WITH 4000;
|
||||
SELECT nextval('test_sequence');
|
||||
nextval
|
||||
---------
|
||||
4000
|
||||
(1 row)
|
||||
|
||||
-- test the sequence changes by several setval() calls
|
||||
SELECT setval('test_sequence', 3500);
|
||||
setval
|
||||
--------
|
||||
3500
|
||||
(1 row)
|
||||
|
||||
SELECT nextval('test_sequence');
|
||||
nextval
|
||||
---------
|
||||
3510
|
||||
(1 row)
|
||||
|
||||
SELECT setval('test_sequence', 3500, true);
|
||||
setval
|
||||
--------
|
||||
3500
|
||||
(1 row)
|
||||
|
||||
SELECT nextval('test_sequence');
|
||||
nextval
|
||||
---------
|
||||
3510
|
||||
(1 row)
|
||||
|
||||
SELECT setval('test_sequence', 3500, false);
|
||||
setval
|
||||
--------
|
||||
3500
|
||||
(1 row)
|
||||
|
||||
SELECT nextval('test_sequence');
|
||||
nextval
|
||||
---------
|
||||
3500
|
||||
(1 row)
|
||||
|
||||
-- show results and drop sequence
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '0');
|
||||
data
|
||||
----------------------------------------------------------------------------------------
|
||||
BEGIN
|
||||
sequence public.test_sequence: transactional:1 last_value: 1 log_cnt: 0 is_called:0
|
||||
COMMIT
|
||||
sequence public.test_sequence: transactional:0 last_value: 33 log_cnt: 0 is_called:1
|
||||
BEGIN
|
||||
sequence public.test_sequence: transactional:1 last_value: 4 log_cnt: 0 is_called:1
|
||||
COMMIT
|
||||
sequence public.test_sequence: transactional:0 last_value: 334 log_cnt: 0 is_called:1
|
||||
BEGIN
|
||||
sequence public.test_sequence: transactional:1 last_value: 14 log_cnt: 32 is_called:1
|
||||
COMMIT
|
||||
BEGIN
|
||||
sequence public.test_sequence: transactional:1 last_value: 14 log_cnt: 0 is_called:1
|
||||
COMMIT
|
||||
BEGIN
|
||||
sequence public.test_sequence: transactional:1 last_value: 4000 log_cnt: 0 is_called:0
|
||||
COMMIT
|
||||
sequence public.test_sequence: transactional:0 last_value: 4320 log_cnt: 0 is_called:1
|
||||
sequence public.test_sequence: transactional:0 last_value: 3500 log_cnt: 0 is_called:1
|
||||
sequence public.test_sequence: transactional:0 last_value: 3830 log_cnt: 0 is_called:1
|
||||
sequence public.test_sequence: transactional:0 last_value: 3500 log_cnt: 0 is_called:1
|
||||
sequence public.test_sequence: transactional:0 last_value: 3830 log_cnt: 0 is_called:1
|
||||
sequence public.test_sequence: transactional:0 last_value: 3500 log_cnt: 0 is_called:0
|
||||
sequence public.test_sequence: transactional:0 last_value: 3820 log_cnt: 0 is_called:1
|
||||
(24 rows)
|
||||
|
||||
DROP SEQUENCE test_sequence;
|
||||
-- rollback on sequence creation and update
|
||||
BEGIN;
|
||||
CREATE SEQUENCE test_sequence;
|
||||
CREATE TABLE test_table (a INT);
|
||||
SELECT nextval('test_sequence');
|
||||
nextval
|
||||
---------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
SELECT nextval('test_sequence');
|
||||
nextval
|
||||
---------
|
||||
2
|
||||
(1 row)
|
||||
|
||||
SELECT nextval('test_sequence');
|
||||
nextval
|
||||
---------
|
||||
3
|
||||
(1 row)
|
||||
|
||||
SELECT setval('test_sequence', 3000);
|
||||
setval
|
||||
--------
|
||||
3000
|
||||
(1 row)
|
||||
|
||||
SELECT nextval('test_sequence');
|
||||
nextval
|
||||
---------
|
||||
3001
|
||||
(1 row)
|
||||
|
||||
SELECT nextval('test_sequence');
|
||||
nextval
|
||||
---------
|
||||
3002
|
||||
(1 row)
|
||||
|
||||
SELECT nextval('test_sequence');
|
||||
nextval
|
||||
---------
|
||||
3003
|
||||
(1 row)
|
||||
|
||||
ALTER SEQUENCE test_sequence RESTART WITH 6000;
|
||||
INSERT INTO test_table VALUES( (SELECT nextval('test_sequence')) );
|
||||
SELECT nextval('test_sequence');
|
||||
nextval
|
||||
---------
|
||||
6001
|
||||
(1 row)
|
||||
|
||||
ROLLBACK;
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
data
|
||||
------
|
||||
(0 rows)
|
||||
|
||||
-- rollback on table creation with serial column
|
||||
BEGIN;
|
||||
CREATE TABLE test_table (a SERIAL, b INT);
|
||||
INSERT INTO test_table (b) VALUES (100);
|
||||
INSERT INTO test_table (b) VALUES (200);
|
||||
INSERT INTO test_table (b) VALUES (300);
|
||||
SELECT setval('test_table_a_seq', 3000);
|
||||
setval
|
||||
--------
|
||||
3000
|
||||
(1 row)
|
||||
|
||||
INSERT INTO test_table (b) VALUES (400);
|
||||
INSERT INTO test_table (b) VALUES (500);
|
||||
INSERT INTO test_table (b) VALUES (600);
|
||||
ALTER SEQUENCE test_table_a_seq RESTART WITH 6000;
|
||||
INSERT INTO test_table (b) VALUES (700);
|
||||
INSERT INTO test_table (b) VALUES (800);
|
||||
INSERT INTO test_table (b) VALUES (900);
|
||||
ROLLBACK;
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
data
|
||||
------
|
||||
(0 rows)
|
||||
|
||||
-- rollback on table with serial column
|
||||
CREATE TABLE test_table (a SERIAL, b INT);
|
||||
BEGIN;
|
||||
INSERT INTO test_table (b) VALUES (100);
|
||||
INSERT INTO test_table (b) VALUES (200);
|
||||
INSERT INTO test_table (b) VALUES (300);
|
||||
SELECT setval('test_table_a_seq', 3000);
|
||||
setval
|
||||
--------
|
||||
3000
|
||||
(1 row)
|
||||
|
||||
INSERT INTO test_table (b) VALUES (400);
|
||||
INSERT INTO test_table (b) VALUES (500);
|
||||
INSERT INTO test_table (b) VALUES (600);
|
||||
ALTER SEQUENCE test_table_a_seq RESTART WITH 6000;
|
||||
INSERT INTO test_table (b) VALUES (700);
|
||||
INSERT INTO test_table (b) VALUES (800);
|
||||
INSERT INTO test_table (b) VALUES (900);
|
||||
ROLLBACK;
|
||||
-- check table and sequence values after rollback
|
||||
SELECT * from test_table_a_seq;
|
||||
last_value | log_cnt | is_called
|
||||
------------+---------+-----------
|
||||
3003 | 30 | t
|
||||
(1 row)
|
||||
|
||||
SELECT nextval('test_table_a_seq');
|
||||
nextval
|
||||
---------
|
||||
3004
|
||||
(1 row)
|
||||
|
||||
DROP TABLE test_table;
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '0');
|
||||
data
|
||||
-------------------------------------------------------------------------------------------
|
||||
BEGIN
|
||||
sequence public.test_table_a_seq: transactional:1 last_value: 1 log_cnt: 0 is_called:0
|
||||
COMMIT
|
||||
sequence public.test_table_a_seq: transactional:0 last_value: 33 log_cnt: 0 is_called:1
|
||||
sequence public.test_table_a_seq: transactional:0 last_value: 3000 log_cnt: 0 is_called:1
|
||||
sequence public.test_table_a_seq: transactional:0 last_value: 3033 log_cnt: 0 is_called:1
|
||||
BEGIN
|
||||
COMMIT
|
||||
(8 rows)
|
||||
|
||||
-- savepoint test on table with serial column
|
||||
BEGIN;
|
||||
CREATE TABLE test_table (a SERIAL, b INT);
|
||||
INSERT INTO test_table (b) VALUES (100);
|
||||
INSERT INTO test_table (b) VALUES (200);
|
||||
SAVEPOINT a;
|
||||
INSERT INTO test_table (b) VALUES (300);
|
||||
ROLLBACK TO SAVEPOINT a;
|
||||
DROP TABLE test_table;
|
||||
COMMIT;
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '0');
|
||||
data
|
||||
-----------------------------------------------------------------------------------------
|
||||
BEGIN
|
||||
sequence public.test_table_a_seq: transactional:1 last_value: 1 log_cnt: 0 is_called:0
|
||||
sequence public.test_table_a_seq: transactional:1 last_value: 33 log_cnt: 0 is_called:1
|
||||
table public.test_table: INSERT: a[integer]:1 b[integer]:100
|
||||
table public.test_table: INSERT: a[integer]:2 b[integer]:200
|
||||
COMMIT
|
||||
(6 rows)
|
||||
|
||||
-- savepoint test on table with serial column
|
||||
BEGIN;
|
||||
CREATE SEQUENCE test_sequence;
|
||||
SELECT nextval('test_sequence');
|
||||
nextval
|
||||
---------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
SELECT setval('test_sequence', 3000);
|
||||
setval
|
||||
--------
|
||||
3000
|
||||
(1 row)
|
||||
|
||||
SELECT nextval('test_sequence');
|
||||
nextval
|
||||
---------
|
||||
3001
|
||||
(1 row)
|
||||
|
||||
SAVEPOINT a;
|
||||
ALTER SEQUENCE test_sequence START WITH 7000;
|
||||
SELECT setval('test_sequence', 5000);
|
||||
setval
|
||||
--------
|
||||
5000
|
||||
(1 row)
|
||||
|
||||
ROLLBACK TO SAVEPOINT a;
|
||||
SELECT * FROM test_sequence;
|
||||
last_value | log_cnt | is_called
|
||||
------------+---------+-----------
|
||||
3001 | 32 | t
|
||||
(1 row)
|
||||
|
||||
DROP SEQUENCE test_sequence;
|
||||
COMMIT;
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '0');
|
||||
data
|
||||
----------------------------------------------------------------------------------------
|
||||
BEGIN
|
||||
sequence public.test_sequence: transactional:1 last_value: 1 log_cnt: 0 is_called:0
|
||||
sequence public.test_sequence: transactional:1 last_value: 33 log_cnt: 0 is_called:1
|
||||
sequence public.test_sequence: transactional:1 last_value: 3000 log_cnt: 0 is_called:1
|
||||
sequence public.test_sequence: transactional:1 last_value: 3033 log_cnt: 0 is_called:1
|
||||
COMMIT
|
||||
(6 rows)
|
||||
|
||||
SELECT pg_drop_replication_slot('regression_slot');
|
||||
pg_drop_replication_slot
|
||||
--------------------------
|
||||
|
||||
(1 row)
|
||||
|
@ -95,7 +95,7 @@ SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot2', 'test_
|
||||
(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');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot1', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
data
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
BEGIN
|
||||
|
@ -52,7 +52,7 @@ CREATE TABLE toasted_copy (
|
||||
);
|
||||
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');
|
||||
SELECT substr(data, 1, 200) FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
substr
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
BEGIN
|
||||
@ -316,7 +316,7 @@ SELECT pg_column_size(toasted_key) > 2^16 FROM toasted_several;
|
||||
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');
|
||||
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', 'include-sequences', '0');
|
||||
regexp_replace
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
BEGIN
|
||||
@ -327,7 +327,7 @@ SELECT regexp_replace(data, '^(.{100}).*(.{100})$', '\1..\2') FROM pg_logical_sl
|
||||
-- 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');
|
||||
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', 'include-sequences', '0');
|
||||
regexp_replace
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
BEGIN
|
||||
@ -350,7 +350,7 @@ 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')
|
||||
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', 'include-sequences', '0')
|
||||
WHERE data NOT LIKE '%INSERT: %';
|
||||
regexp_replace
|
||||
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@ -373,7 +373,7 @@ 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');
|
||||
SELECT substr(data, 1, 200) FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
substr
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
BEGIN
|
||||
|
@ -11,7 +11,7 @@ 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');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
data
|
||||
------------------------------------------------------
|
||||
BEGIN
|
||||
|
@ -13,7 +13,7 @@ teardown
|
||||
session "s0"
|
||||
setup { SET synchronous_commit=on; }
|
||||
step "s0init" {SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding');}
|
||||
step "s0start" {SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false');}
|
||||
step "s0start" {SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false', 'include-sequences', 'false');}
|
||||
step "s0alter" {ALTER TABLE do_write ADD column ts timestamptz; }
|
||||
step "s0w" { INSERT INTO do_write DEFAULT VALUES; }
|
||||
|
||||
|
@ -16,7 +16,7 @@ session "s1"
|
||||
setup { SET synchronous_commit=on; }
|
||||
|
||||
step "s1init" {SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding');}
|
||||
step "s1start" {SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false');}
|
||||
step "s1start" {SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false', 'include-sequences', 'false');}
|
||||
step "s1insert" { INSERT INTO do_write DEFAULT VALUES; }
|
||||
step "s1checkpoint" { CHECKPOINT; }
|
||||
step "s1alter" { ALTER TABLE do_write ADD COLUMN addedbys1 int; }
|
||||
|
@ -64,7 +64,7 @@ ALTER TABLE replication_example RENAME COLUMN text TO somenum;
|
||||
INSERT INTO replication_example(somedata, somenum) VALUES (4, 1);
|
||||
|
||||
-- collect all changes
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
|
||||
ALTER TABLE replication_example ALTER COLUMN somenum TYPE int4 USING (somenum::int4);
|
||||
-- check that this doesn't produce any changes from the heap rewrite
|
||||
@ -97,7 +97,7 @@ CREATE TABLE tr_unique(id2 serial unique NOT NULL, data int);
|
||||
INSERT INTO tr_unique(data) VALUES(10);
|
||||
ALTER TABLE tr_unique RENAME TO tr_pkey;
|
||||
ALTER TABLE tr_pkey ADD COLUMN id serial primary key;
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-rewrites', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-rewrites', '1', 'include-sequences', '0');
|
||||
|
||||
INSERT INTO tr_pkey(data) VALUES(1);
|
||||
--show deletion with primary key
|
||||
@ -121,7 +121,7 @@ COMMIT;
|
||||
|
||||
/* display results, but hide most of the output */
|
||||
SELECT count(*), min(data), max(data)
|
||||
FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1')
|
||||
FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0')
|
||||
GROUP BY substring(data, 1, 24)
|
||||
ORDER BY 1,2;
|
||||
|
||||
@ -173,7 +173,7 @@ INSERT INTO tr_sub(path) VALUES ('1-top-2-#1');
|
||||
RELEASE SAVEPOINT b;
|
||||
COMMIT;
|
||||
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
|
||||
-- check that we handle xlog assignments correctly
|
||||
BEGIN;
|
||||
@ -287,7 +287,7 @@ ALTER TABLE replication_metadata SET (user_catalog_table = false);
|
||||
INSERT INTO replication_metadata(relation, options)
|
||||
VALUES ('zaphod', NULL);
|
||||
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
|
||||
/*
|
||||
* check whether we handle updates/deletes correct with & without a pkey
|
||||
@ -398,7 +398,7 @@ UPDATE toasttable
|
||||
SET toasted_col1 = (SELECT string_agg(g.i::text, '') FROM generate_series(1, 2000) g(i))
|
||||
WHERE id = 1;
|
||||
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
|
||||
INSERT INTO toasttable(toasted_col1) SELECT string_agg(g.i::text, '') FROM generate_series(1, 2000) g(i);
|
||||
|
||||
|
@ -32,7 +32,7 @@ BEGIN;
|
||||
SELECT pg_current_xact_id() = '0';
|
||||
-- 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');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
COMMIT;
|
||||
|
||||
INSERT INTO nobarf(data) VALUES('3');
|
||||
|
@ -15,14 +15,14 @@ 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 data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
|
||||
SELECT * FROM changeresult;
|
||||
|
||||
INSERT INTO changeresult
|
||||
SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
INSERT INTO changeresult
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
|
||||
SELECT * FROM changeresult;
|
||||
DROP TABLE changeresult;
|
||||
@ -32,11 +32,11 @@ DROP TABLE somechange;
|
||||
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');
|
||||
SELECT data FROM pg_logical_slot_peek_changes(slot_name, NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
END$$ LANGUAGE plpgsql;
|
||||
|
||||
SELECT * FROM slot_changes_wrapper('regression_slot');
|
||||
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
|
||||
SELECT 'stop' FROM pg_drop_replication_slot('regression_slot');
|
||||
|
@ -41,10 +41,10 @@ SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_d
|
||||
-- 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');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
|
||||
-- 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');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
|
||||
INSERT INTO origin_tbl(data) VALUES ('will be replicated, but not decoded again');
|
||||
|
||||
|
@ -35,7 +35,7 @@ SELECT pg_relation_size((SELECT reltoastrelid FROM pg_class WHERE oid = 'pg_shde
|
||||
SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding');
|
||||
CREATE TABLE replication_example(id SERIAL PRIMARY KEY, somedata int, text varchar(120));
|
||||
INSERT INTO replication_example(somedata) VALUES (1);
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
|
||||
BEGIN;
|
||||
INSERT INTO replication_example(somedata) VALUES (2);
|
||||
@ -98,7 +98,7 @@ VACUUM FULL pg_proc; VACUUM FULL pg_description; VACUUM FULL pg_shdescription; V
|
||||
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');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
|
||||
SELECT pg_drop_replication_slot('regression_slot');
|
||||
DROP TABLE IF EXISTS replication_example;
|
||||
|
119
contrib/test_decoding/sql/sequence.sql
Normal file
119
contrib/test_decoding/sql/sequence.sql
Normal file
@ -0,0 +1,119 @@
|
||||
-- predictability
|
||||
SET synchronous_commit = on;
|
||||
SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding');
|
||||
|
||||
CREATE SEQUENCE test_sequence;
|
||||
|
||||
-- test the sequence changes by several nextval() calls
|
||||
SELECT nextval('test_sequence');
|
||||
SELECT nextval('test_sequence');
|
||||
SELECT nextval('test_sequence');
|
||||
SELECT nextval('test_sequence');
|
||||
|
||||
-- test the sequence changes by several ALTER commands
|
||||
ALTER SEQUENCE test_sequence INCREMENT BY 10;
|
||||
SELECT nextval('test_sequence');
|
||||
|
||||
ALTER SEQUENCE test_sequence START WITH 3000;
|
||||
ALTER SEQUENCE test_sequence MAXVALUE 10000;
|
||||
ALTER SEQUENCE test_sequence RESTART WITH 4000;
|
||||
SELECT nextval('test_sequence');
|
||||
|
||||
-- test the sequence changes by several setval() calls
|
||||
SELECT setval('test_sequence', 3500);
|
||||
SELECT nextval('test_sequence');
|
||||
SELECT setval('test_sequence', 3500, true);
|
||||
SELECT nextval('test_sequence');
|
||||
SELECT setval('test_sequence', 3500, false);
|
||||
SELECT nextval('test_sequence');
|
||||
|
||||
-- show results and drop sequence
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '0');
|
||||
DROP SEQUENCE test_sequence;
|
||||
|
||||
-- rollback on sequence creation and update
|
||||
BEGIN;
|
||||
CREATE SEQUENCE test_sequence;
|
||||
CREATE TABLE test_table (a INT);
|
||||
SELECT nextval('test_sequence');
|
||||
SELECT nextval('test_sequence');
|
||||
SELECT nextval('test_sequence');
|
||||
SELECT setval('test_sequence', 3000);
|
||||
SELECT nextval('test_sequence');
|
||||
SELECT nextval('test_sequence');
|
||||
SELECT nextval('test_sequence');
|
||||
ALTER SEQUENCE test_sequence RESTART WITH 6000;
|
||||
INSERT INTO test_table VALUES( (SELECT nextval('test_sequence')) );
|
||||
SELECT nextval('test_sequence');
|
||||
ROLLBACK;
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
|
||||
-- rollback on table creation with serial column
|
||||
BEGIN;
|
||||
CREATE TABLE test_table (a SERIAL, b INT);
|
||||
INSERT INTO test_table (b) VALUES (100);
|
||||
INSERT INTO test_table (b) VALUES (200);
|
||||
INSERT INTO test_table (b) VALUES (300);
|
||||
SELECT setval('test_table_a_seq', 3000);
|
||||
INSERT INTO test_table (b) VALUES (400);
|
||||
INSERT INTO test_table (b) VALUES (500);
|
||||
INSERT INTO test_table (b) VALUES (600);
|
||||
ALTER SEQUENCE test_table_a_seq RESTART WITH 6000;
|
||||
INSERT INTO test_table (b) VALUES (700);
|
||||
INSERT INTO test_table (b) VALUES (800);
|
||||
INSERT INTO test_table (b) VALUES (900);
|
||||
ROLLBACK;
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
|
||||
-- rollback on table with serial column
|
||||
CREATE TABLE test_table (a SERIAL, b INT);
|
||||
|
||||
BEGIN;
|
||||
INSERT INTO test_table (b) VALUES (100);
|
||||
INSERT INTO test_table (b) VALUES (200);
|
||||
INSERT INTO test_table (b) VALUES (300);
|
||||
SELECT setval('test_table_a_seq', 3000);
|
||||
INSERT INTO test_table (b) VALUES (400);
|
||||
INSERT INTO test_table (b) VALUES (500);
|
||||
INSERT INTO test_table (b) VALUES (600);
|
||||
ALTER SEQUENCE test_table_a_seq RESTART WITH 6000;
|
||||
INSERT INTO test_table (b) VALUES (700);
|
||||
INSERT INTO test_table (b) VALUES (800);
|
||||
INSERT INTO test_table (b) VALUES (900);
|
||||
ROLLBACK;
|
||||
|
||||
-- check table and sequence values after rollback
|
||||
SELECT * from test_table_a_seq;
|
||||
SELECT nextval('test_table_a_seq');
|
||||
|
||||
DROP TABLE test_table;
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '0');
|
||||
|
||||
-- savepoint test on table with serial column
|
||||
BEGIN;
|
||||
CREATE TABLE test_table (a SERIAL, b INT);
|
||||
INSERT INTO test_table (b) VALUES (100);
|
||||
INSERT INTO test_table (b) VALUES (200);
|
||||
SAVEPOINT a;
|
||||
INSERT INTO test_table (b) VALUES (300);
|
||||
ROLLBACK TO SAVEPOINT a;
|
||||
DROP TABLE test_table;
|
||||
COMMIT;
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '0');
|
||||
|
||||
-- savepoint test on table with serial column
|
||||
BEGIN;
|
||||
CREATE SEQUENCE test_sequence;
|
||||
SELECT nextval('test_sequence');
|
||||
SELECT setval('test_sequence', 3000);
|
||||
SELECT nextval('test_sequence');
|
||||
SAVEPOINT a;
|
||||
ALTER SEQUENCE test_sequence START WITH 7000;
|
||||
SELECT setval('test_sequence', 5000);
|
||||
ROLLBACK TO SAVEPOINT a;
|
||||
SELECT * FROM test_sequence;
|
||||
DROP SEQUENCE test_sequence;
|
||||
COMMIT;
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '0');
|
||||
|
||||
SELECT pg_drop_replication_slot('regression_slot');
|
@ -50,7 +50,7 @@ SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot2', 'test_
|
||||
|
||||
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');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot1', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot2', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
|
||||
INSERT INTO replication_example(somedata, text) VALUES (1, 4);
|
||||
|
@ -264,7 +264,7 @@ ALTER TABLE toasted_copy ALTER COLUMN data SET STORAGE EXTERNAL;
|
||||
202 untoasted199
|
||||
203 untoasted200
|
||||
\.
|
||||
SELECT substr(data, 1, 200) FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');
|
||||
SELECT substr(data, 1, 200) FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
|
||||
-- test we can decode "old" tuples bigger than the max heap tuple size correctly
|
||||
DROP TABLE IF EXISTS toasted_several;
|
||||
@ -287,13 +287,13 @@ UPDATE pg_attribute SET attstorage = 'x' WHERE attrelid = 'toasted_several_pkey'
|
||||
INSERT INTO toasted_several(toasted_key) VALUES(repeat('9876543210', 10000));
|
||||
SELECT pg_column_size(toasted_key) > 2^16 FROM toasted_several;
|
||||
|
||||
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');
|
||||
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', 'include-sequences', '0');
|
||||
|
||||
-- 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');
|
||||
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', 'include-sequences', '0');
|
||||
|
||||
/*
|
||||
* update with large tuplebuf, in a transaction large enough to force to spool to disk
|
||||
@ -306,7 +306,7 @@ 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')
|
||||
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', 'include-sequences', '0')
|
||||
WHERE data NOT LIKE '%INSERT: %';
|
||||
|
||||
/*
|
||||
@ -322,6 +322,6 @@ 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');
|
||||
SELECT substr(data, 1, 200) FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
|
||||
SELECT pg_drop_replication_slot('regression_slot');
|
||||
|
@ -10,5 +10,5 @@ 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');
|
||||
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'include-sequences', '0');
|
||||
SELECT pg_drop_replication_slot('regression_slot');
|
||||
|
@ -35,6 +35,7 @@ typedef struct
|
||||
bool include_timestamp;
|
||||
bool skip_empty_xacts;
|
||||
bool only_local;
|
||||
bool include_sequences;
|
||||
} TestDecodingData;
|
||||
|
||||
/*
|
||||
@ -76,6 +77,10 @@ static void pg_decode_message(LogicalDecodingContext *ctx,
|
||||
ReorderBufferTXN *txn, XLogRecPtr message_lsn,
|
||||
bool transactional, const char *prefix,
|
||||
Size sz, const char *message);
|
||||
static void pg_decode_sequence(LogicalDecodingContext *ctx,
|
||||
ReorderBufferTXN *txn, XLogRecPtr sequence_lsn,
|
||||
Relation rel, bool transactional,
|
||||
int64 last_value, int64 log_cnt, bool is_called);
|
||||
static bool pg_decode_filter_prepare(LogicalDecodingContext *ctx,
|
||||
TransactionId xid,
|
||||
const char *gid);
|
||||
@ -116,6 +121,10 @@ static void pg_decode_stream_message(LogicalDecodingContext *ctx,
|
||||
ReorderBufferTXN *txn, XLogRecPtr message_lsn,
|
||||
bool transactional, const char *prefix,
|
||||
Size sz, const char *message);
|
||||
static void pg_decode_stream_sequence(LogicalDecodingContext *ctx,
|
||||
ReorderBufferTXN *txn, XLogRecPtr sequence_lsn,
|
||||
Relation rel, bool transactional,
|
||||
int64 last_value, int64 log_cnt, bool is_called);
|
||||
static void pg_decode_stream_truncate(LogicalDecodingContext *ctx,
|
||||
ReorderBufferTXN *txn,
|
||||
int nrelations, Relation relations[],
|
||||
@ -141,6 +150,7 @@ _PG_output_plugin_init(OutputPluginCallbacks *cb)
|
||||
cb->filter_by_origin_cb = pg_decode_filter;
|
||||
cb->shutdown_cb = pg_decode_shutdown;
|
||||
cb->message_cb = pg_decode_message;
|
||||
cb->sequence_cb = pg_decode_sequence;
|
||||
cb->filter_prepare_cb = pg_decode_filter_prepare;
|
||||
cb->begin_prepare_cb = pg_decode_begin_prepare_txn;
|
||||
cb->prepare_cb = pg_decode_prepare_txn;
|
||||
@ -153,6 +163,7 @@ _PG_output_plugin_init(OutputPluginCallbacks *cb)
|
||||
cb->stream_commit_cb = pg_decode_stream_commit;
|
||||
cb->stream_change_cb = pg_decode_stream_change;
|
||||
cb->stream_message_cb = pg_decode_stream_message;
|
||||
cb->stream_sequence_cb = pg_decode_stream_sequence;
|
||||
cb->stream_truncate_cb = pg_decode_stream_truncate;
|
||||
}
|
||||
|
||||
@ -173,6 +184,7 @@ pg_decode_startup(LogicalDecodingContext *ctx, OutputPluginOptions *opt,
|
||||
data->include_xids = true;
|
||||
data->include_timestamp = false;
|
||||
data->skip_empty_xacts = false;
|
||||
data->include_sequences = true;
|
||||
data->only_local = false;
|
||||
|
||||
ctx->output_plugin_private = data;
|
||||
@ -265,6 +277,17 @@ pg_decode_startup(LogicalDecodingContext *ctx, OutputPluginOptions *opt,
|
||||
errmsg("could not parse value \"%s\" for parameter \"%s\"",
|
||||
strVal(elem->arg), elem->defname)));
|
||||
}
|
||||
else if (strcmp(elem->defname, "include-sequences") == 0)
|
||||
{
|
||||
|
||||
if (elem->arg == NULL)
|
||||
data->include_sequences = false;
|
||||
else if (!parse_bool(strVal(elem->arg), &data->include_sequences))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("could not parse value \"%s\" for parameter \"%s\"",
|
||||
strVal(elem->arg), elem->defname)));
|
||||
}
|
||||
else
|
||||
{
|
||||
ereport(ERROR,
|
||||
@ -744,6 +767,27 @@ pg_decode_message(LogicalDecodingContext *ctx,
|
||||
OutputPluginWrite(ctx, true);
|
||||
}
|
||||
|
||||
static void
|
||||
pg_decode_sequence(LogicalDecodingContext *ctx, ReorderBufferTXN *txn,
|
||||
XLogRecPtr sequence_lsn, Relation rel,
|
||||
bool transactional,
|
||||
int64 last_value, int64 log_cnt, bool is_called)
|
||||
{
|
||||
TestDecodingData *data = ctx->output_plugin_private;
|
||||
|
||||
if (!data->include_sequences)
|
||||
return;
|
||||
|
||||
OutputPluginPrepareWrite(ctx, true);
|
||||
appendStringInfoString(ctx->out, "sequence ");
|
||||
appendStringInfoString(ctx->out,
|
||||
quote_qualified_identifier(get_namespace_name(get_rel_namespace(RelationGetRelid(rel))),
|
||||
RelationGetRelationName(rel)));
|
||||
appendStringInfo(ctx->out, ": transactional:%d last_value: " INT64_FORMAT " log_cnt: " INT64_FORMAT " is_called:%d",
|
||||
transactional, last_value, log_cnt, is_called);
|
||||
OutputPluginWrite(ctx, true);
|
||||
}
|
||||
|
||||
static void
|
||||
pg_decode_stream_start(LogicalDecodingContext *ctx,
|
||||
ReorderBufferTXN *txn)
|
||||
@ -943,6 +987,27 @@ pg_decode_stream_message(LogicalDecodingContext *ctx,
|
||||
OutputPluginWrite(ctx, true);
|
||||
}
|
||||
|
||||
static void
|
||||
pg_decode_stream_sequence(LogicalDecodingContext *ctx, ReorderBufferTXN *txn,
|
||||
XLogRecPtr sequence_lsn, Relation rel,
|
||||
bool transactional,
|
||||
int64 last_value, int64 log_cnt, bool is_called)
|
||||
{
|
||||
TestDecodingData *data = ctx->output_plugin_private;
|
||||
|
||||
if (!data->include_sequences)
|
||||
return;
|
||||
|
||||
OutputPluginPrepareWrite(ctx, true);
|
||||
appendStringInfoString(ctx->out, "streaming sequence ");
|
||||
appendStringInfoString(ctx->out,
|
||||
quote_qualified_identifier(get_namespace_name(get_rel_namespace(RelationGetRelid(rel))),
|
||||
RelationGetRelationName(rel)));
|
||||
appendStringInfo(ctx->out, ": transactional:%d last_value: " INT64_FORMAT " log_cnt: " INT64_FORMAT " is_called:%d",
|
||||
transactional, last_value, log_cnt, is_called);
|
||||
OutputPluginWrite(ctx, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* In streaming mode, we don't display the detailed information of Truncate.
|
||||
* See pg_decode_stream_change.
|
||||
|
Loading…
Reference in New Issue
Block a user