4 -- Create a replication slot
5 SELECT slot_name FROM pg_create_logical_replication_slot('custom_slot', 'wal2sql');
11 -- DEFAULT case with PRIMARY KEY
12 CREATE TABLE aa (a int primary key, b text NOT NULL);
13 INSERT INTO aa VALUES (1, 'aa'), (2, 'bb');
14 -- Update of Non-selective column
15 UPDATE aa SET b = 'cc' WHERE a = 1;
16 -- Update of only selective column
17 UPDATE aa SET a = 3 WHERE a = 1;
18 -- Update of both columns
19 UPDATE aa SET a = 4, b = 'dd' WHERE a = 2;
20 DELETE FROM aa WHERE a = 4;
21 -- Have a look at changes with different modes.
22 -- In the second call changes are consumed to not impact the next cases.
23 SELECT data FROM pg_logical_slot_peek_changes('custom_slot', NULL, NULL, 'include_transaction', 'off');
25 ---------------------------------------------------
26 INSERT INTO public.aa (a, b) VALUES (1, 'aa');
27 INSERT INTO public.aa (a, b) VALUES (2, 'bb');
28 UPDATE public.aa SET a = 1, b = 'cc' WHERE a = 1;
29 UPDATE public.aa SET a = 3, b = 'cc' WHERE a = 1;
30 UPDATE public.aa SET a = 4, b = 'dd' WHERE a = 2;
31 DELETE FROM public.aa WHERE a = 4;
34 SELECT data FROM pg_logical_slot_get_changes('custom_slot', NULL, NULL, 'include_transaction', 'on');
36 ---------------------------------------------------
40 INSERT INTO public.aa (a, b) VALUES (1, 'aa');
41 INSERT INTO public.aa (a, b) VALUES (2, 'bb');
44 UPDATE public.aa SET a = 1, b = 'cc' WHERE a = 1;
47 UPDATE public.aa SET a = 3, b = 'cc' WHERE a = 1;
50 UPDATE public.aa SET a = 4, b = 'dd' WHERE a = 2;
53 DELETE FROM public.aa WHERE a = 4;
58 -- DEFAULT case without PRIMARY KEY
59 CREATE TABLE aa (a int, b text NOT NULL);
60 INSERT INTO aa VALUES (1, 'aa'), (2, 'bb');
61 -- Update of Non-selective column
62 UPDATE aa SET b = 'cc' WHERE a = 1;
63 -- Update of only selective column
64 UPDATE aa SET a = 3 WHERE a = 1;
65 -- Update of both columns
66 UPDATE aa SET a = 4, b = 'dd' WHERE a = 2;
67 DELETE FROM aa WHERE a = 4;
68 -- Have a look at changes with different modes.
69 -- In the second call changes are consumed to not impact the next cases.
70 SELECT data FROM pg_logical_slot_peek_changes('custom_slot', NULL, NULL, 'include_transaction', 'off');
72 ------------------------------------------------
73 INSERT INTO public.aa (a, b) VALUES (1, 'aa');
74 INSERT INTO public.aa (a, b) VALUES (2, 'bb');
77 SELECT data FROM pg_logical_slot_get_changes('custom_slot', NULL, NULL, 'include_transaction', 'on');
79 ------------------------------------------------
85 INSERT INTO public.aa (a, b) VALUES (1, 'aa');
86 INSERT INTO public.aa (a, b) VALUES (2, 'bb');
100 CREATE TABLE aa (a int NOT NULL, b text);
101 CREATE UNIQUE INDEX aai ON aa(a);
102 ALTER TABLE aa REPLICA IDENTITY USING INDEX aai;
103 INSERT INTO aa VALUES (1, 'aa'), (2, 'bb');
104 -- Update of Non-selective column
105 UPDATE aa SET b = 'cc' WHERE a = 1;
106 -- Update of only selective column
107 UPDATE aa SET a = 3 WHERE a = 1;
108 -- Update of both columns
109 UPDATE aa SET a = 4, b = 'dd' WHERE a = 2;
110 DELETE FROM aa WHERE a = 4;
111 -- Have a look at changes with different modes
112 SELECT data FROM pg_logical_slot_peek_changes('custom_slot', NULL, NULL, 'include_transaction', 'off');
114 ---------------------------------------------------
115 INSERT INTO public.aa (a, b) VALUES (1, 'aa');
116 INSERT INTO public.aa (a, b) VALUES (2, 'bb');
117 UPDATE public.aa SET a = 1, b = 'cc' WHERE a = 1;
118 UPDATE public.aa SET a = 3, b = 'cc' WHERE a = 1;
119 UPDATE public.aa SET a = 4, b = 'dd' WHERE a = 2;
120 DELETE FROM public.aa WHERE a = 4;
123 SELECT data FROM pg_logical_slot_get_changes('custom_slot', NULL, NULL, 'include_transaction', 'on');
125 ---------------------------------------------------
135 INSERT INTO public.aa (a, b) VALUES (1, 'aa');
136 INSERT INTO public.aa (a, b) VALUES (2, 'bb');
139 UPDATE public.aa SET a = 1, b = 'cc' WHERE a = 1;
142 UPDATE public.aa SET a = 3, b = 'cc' WHERE a = 1;
145 UPDATE public.aa SET a = 4, b = 'dd' WHERE a = 2;
148 DELETE FROM public.aa WHERE a = 4;
153 -- INDEX case using a second column
154 CREATE TABLE aa (b text, a int NOT NULL);
155 CREATE UNIQUE INDEX aai ON aa(a);
156 ALTER TABLE aa REPLICA IDENTITY USING INDEX aai;
157 INSERT INTO aa VALUES ('aa', 1), ('bb', 2);
158 -- Update of Non-selective column
159 UPDATE aa SET b = 'cc' WHERE a = 1;
160 -- Update of only selective column
161 UPDATE aa SET a = 3 WHERE a = 1;
162 -- Update of both columns
163 UPDATE aa SET a = 4, b = 'dd' WHERE a = 2;
164 DELETE FROM aa WHERE a = 4;
165 -- Have a look at changes with different modes
166 SELECT data FROM pg_logical_slot_peek_changes('custom_slot', NULL, NULL, 'include_transaction', 'off');
168 ---------------------------------------------------
169 INSERT INTO public.aa (b, a) VALUES ('aa', 1);
170 INSERT INTO public.aa (b, a) VALUES ('bb', 2);
171 UPDATE public.aa SET b = 'cc', a = 1 WHERE a = 1;
172 UPDATE public.aa SET b = 'cc', a = 3 WHERE a = 1;
173 UPDATE public.aa SET b = 'dd', a = 4 WHERE a = 2;
174 DELETE FROM public.aa WHERE a = 4;
177 SELECT data FROM pg_logical_slot_get_changes('custom_slot', NULL, NULL, 'include_transaction', 'on');
179 ---------------------------------------------------
189 INSERT INTO public.aa (b, a) VALUES ('aa', 1);
190 INSERT INTO public.aa (b, a) VALUES ('bb', 2);
193 UPDATE public.aa SET b = 'cc', a = 1 WHERE a = 1;
196 UPDATE public.aa SET b = 'cc', a = 3 WHERE a = 1;
199 UPDATE public.aa SET b = 'dd', a = 4 WHERE a = 2;
202 DELETE FROM public.aa WHERE a = 4;
208 CREATE TABLE aa (a int primary key, b text NOT NULL);
209 ALTER TABLE aa REPLICA IDENTITY FULL;
210 INSERT INTO aa VALUES (1, 'aa'), (2, 'bb');
211 -- Update of Non-selective column
212 UPDATE aa SET b = 'cc' WHERE a = 1;
213 -- Update of only selective column
214 UPDATE aa SET a = 3 WHERE a = 1;
215 -- Update of both columns
216 UPDATE aa SET a = 4, b = 'dd' WHERE a = 2;
217 DELETE FROM aa WHERE a = 4;
218 -- Have a look at changes with different modes
219 SELECT data FROM pg_logical_slot_peek_changes('custom_slot', NULL, NULL, 'include_transaction', 'off');
221 ----------------------------------------------------------------
222 INSERT INTO public.aa (a, b) VALUES (1, 'aa');
223 INSERT INTO public.aa (a, b) VALUES (2, 'bb');
224 UPDATE public.aa SET a = 1, b = 'cc' WHERE a = 1 AND b = 'aa';
225 UPDATE public.aa SET a = 3, b = 'cc' WHERE a = 1 AND b = 'cc';
226 UPDATE public.aa SET a = 4, b = 'dd' WHERE a = 2 AND b = 'bb';
227 DELETE FROM public.aa WHERE a = 4 AND b = 'dd';
230 SELECT data FROM pg_logical_slot_get_changes('custom_slot', NULL, NULL, 'include_transaction', 'on');
232 ----------------------------------------------------------------
240 INSERT INTO public.aa (a, b) VALUES (1, 'aa');
241 INSERT INTO public.aa (a, b) VALUES (2, 'bb');
244 UPDATE public.aa SET a = 1, b = 'cc' WHERE a = 1 AND b = 'aa';
247 UPDATE public.aa SET a = 3, b = 'cc' WHERE a = 1 AND b = 'cc';
250 UPDATE public.aa SET a = 4, b = 'dd' WHERE a = 2 AND b = 'bb';
253 DELETE FROM public.aa WHERE a = 4 AND b = 'dd';
259 CREATE TABLE aa (a int primary key, b text NOT NULL);
260 ALTER TABLE aa REPLICA IDENTITY NOTHING;
261 INSERT INTO aa VALUES (1, 'aa'), (2, 'bb');
262 UPDATE aa SET b = 'cc' WHERE a = 1;
263 UPDATE aa SET a = 3 WHERE a = 1;
264 DELETE FROM aa WHERE a = 4;
265 -- Have a look at changes with different modes
266 SELECT data FROM pg_logical_slot_peek_changes('custom_slot', NULL, NULL, 'include_transaction', 'off');
268 ------------------------------------------------
269 INSERT INTO public.aa (a, b) VALUES (1, 'aa');
270 INSERT INTO public.aa (a, b) VALUES (2, 'bb');
273 SELECT data FROM pg_logical_slot_get_changes('custom_slot', NULL, NULL, 'include_transaction', 'on');
275 ------------------------------------------------
283 INSERT INTO public.aa (a, b) VALUES (1, 'aa');
284 INSERT INTO public.aa (a, b) VALUES (2, 'bb');
293 -- Special value handling for various data types
294 -- boolean, with true and false values correctly shaped
295 CREATE TABLE aa (a boolean);
296 INSERT INTO aa VALUES (true);
297 INSERT INTO aa VALUES (false);
298 SELECT data FROM pg_logical_slot_get_changes('custom_slot', NULL, NULL, 'include_transaction', 'off');
300 -------------------------------------------
301 INSERT INTO public.aa (a) VALUES (true);
302 INSERT INTO public.aa (a) VALUES (false);
306 -- numeric and flost with Nan and infinity - quotes should be correctly placed
307 CREATE TABLE aa (a numeric, b float4, c float8);
308 INSERT INTO aa VALUES ('Nan'::numeric, 'Nan'::float4, 'Nan'::float8);
309 INSERT INTO aa VALUES (1.0, '+Infinity'::float4, '+Infinity'::float8);
310 INSERT INTO aa VALUES (2.0, '-Infinity'::float4, '-Infinity'::float8);
311 INSERT INTO aa VALUES (3.0, 4.0, 5.0);
312 SELECT data FROM pg_logical_slot_get_changes('custom_slot', NULL, NULL, 'include_transaction', 'off');
314 -------------------------------------------------------------------------
315 INSERT INTO public.aa (a, b, c) VALUES ('NaN', 'NaN', 'NaN');
316 INSERT INTO public.aa (a, b, c) VALUES (1.0, 'Infinity', 'Infinity');
317 INSERT INTO public.aa (a, b, c) VALUES (2.0, '-Infinity', '-Infinity');
318 INSERT INTO public.aa (a, b, c) VALUES (3.0, 4, 5);
322 -- Unchanged toast datum
323 CREATE TABLE tt (a int primary key, t text);
324 ALTER TABLE tt ALTER COLUMN t SET STORAGE EXTERNAL;
325 INSERT INTO tt VALUES (1, 'foo');
326 INSERT INTO tt VALUES (2, repeat('x', 3000));
327 UPDATE tt SET t=t WHERE a=1;
328 UPDATE tt SET t=t WHERE a=2;
329 SELECT substr(data, 1, 50), substr(data, 3000, 45)
330 FROM pg_logical_slot_get_changes('custom_slot', NULL, NULL, 'include_transaction', 'off');
332 ----------------------------------------------------+-----------------------------------------------
333 INSERT INTO public.tt (a, t) VALUES (1, 'foo'); |
334 INSERT INTO public.tt (a, t) VALUES (2, 'xxxxxxxxx | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');
335 UPDATE public.tt SET a = 1, t = 'foo' WHERE a = 1; |
336 UPDATE public.tt SET a = 2 WHERE a = 2; |
340 -- DDL message handling via pg_logical_emit_message
341 -- Test that messages with 'ddl' prefix are captured and output correctly
342 CREATE TABLE ddl_test (id int primary key, name text);
343 INSERT INTO ddl_test VALUES (1, 'first');
344 -- Emit a DDL message (simulating what event triggers would do)
345 -- Don't display LSN as it changes between test runs
346 DO $$ BEGIN PERFORM pg_logical_emit_message(true, 'ddl', 'ALTER TABLE public.ddl_test ADD COLUMN email text;'); END $$;
347 INSERT INTO ddl_test VALUES (2, 'second');
348 -- Emit another DDL message
349 DO $$ BEGIN PERFORM pg_logical_emit_message(true, 'ddl', 'ALTER TABLE public.ddl_test DROP COLUMN name;'); END $$;
350 INSERT INTO ddl_test VALUES (3, 'third');
351 -- Test non-ddl message (should be ignored)
352 DO $$ BEGIN PERFORM pg_logical_emit_message(true, 'other', 'This should not appear in output'); END $$;
353 INSERT INTO ddl_test VALUES (4, 'fourth');
354 -- Check that DDL messages appear in the stream at the correct positions
355 SELECT data FROM pg_logical_slot_get_changes('custom_slot', NULL, NULL, 'include_transaction', 'on');
357 --------------------------------------------------------------
363 INSERT INTO public.ddl_test (id, name) VALUES (1, 'first');
366 ALTER TABLE public.ddl_test ADD COLUMN email text;
369 INSERT INTO public.ddl_test (id, name) VALUES (2, 'second');
372 ALTER TABLE public.ddl_test DROP COLUMN name;
375 INSERT INTO public.ddl_test (id, name) VALUES (3, 'third');
380 INSERT INTO public.ddl_test (id, name) VALUES (4, 'fourth');
385 -- Drop replication slot
386 SELECT pg_drop_replication_slot('custom_slot');
387 pg_drop_replication_slot
388 --------------------------