mirror of https://github.com/postgres/postgres
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
pull/77/head
parent
44fa84881f
commit
80901b3291
File diff suppressed because one or more lines are too long
@ -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) |
||||
|
@ -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'); |
Loading…
Reference in new issue