From 0255f2ac6b29ad799e6fa5bf6ddb98a741c6dce8 Mon Sep 17 00:00:00 2001 From: Euler Taveira Date: Sat, 21 Oct 2017 09:12:40 -0300 Subject: [PATCH] Support type name with modifier Issue #31 asked for type name with type modifier (if available). This commit implemented type modifier inclusion by default. It is possible to use the old type name, if you use the option 'include-typmod' as 'false'. I'll change the regression tests to use the new format later. I've added a new test (typmod) to exercise this new option. --- Makefile | 2 +- expected/bytea.out | 2 +- expected/delete1.out | 2 +- expected/delete2.out | 2 +- expected/delete3.out | 2 +- expected/delete4.out | 2 +- expected/insert1.out | 2 +- expected/savepoint.out | 2 +- expected/specialvalue.out | 2 +- expected/toast.out | 2 +- expected/typmod.out | 135 ++++++++++++++++++++++++++++++++++++++ expected/update1.out | 2 +- expected/update2.out | 2 +- expected/update3.out | 2 +- expected/update4.out | 2 +- sql/bytea.sql | 2 +- sql/delete1.sql | 2 +- sql/delete2.sql | 2 +- sql/delete3.sql | 2 +- sql/delete4.sql | 2 +- sql/insert1.sql | 2 +- sql/savepoint.sql | 2 +- sql/specialvalue.sql | 2 +- sql/toast.sql | 2 +- sql/typmod.sql | 39 +++++++++++ sql/update1.sql | 2 +- sql/update2.sql | 2 +- sql/update3.sql | 2 +- sql/update4.sql | 2 +- wal2json.c | 33 +++++++++- 30 files changed, 231 insertions(+), 30 deletions(-) create mode 100644 expected/typmod.out create mode 100644 sql/typmod.sql diff --git a/Makefile b/Makefile index c82b478c8af8..5c24d344f4a1 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ MODULES = wal2json # message test will fail for <= 9.5 REGRESS = cmdline insert1 update1 update2 update3 update4 delete1 delete2 \ - delete3 delete4 savepoint specialvalue toast bytea message + delete3 delete4 savepoint specialvalue toast bytea message typmod PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) diff --git a/expected/bytea.out b/expected/bytea.out index 599189f953cb..e40b91028181 100644 --- a/expected/bytea.out +++ b/expected/bytea.out @@ -22,7 +22,7 @@ SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2js INSERT INTO xpto (bincol) SELECT decode(string_agg(to_char(round(g.i * random()), 'FM0000'), ''), 'hex') FROM generate_series(500, 5000) g(i); UPDATE xpto SET rand1 = 123.456 WHERE id = 1; DELETE FROM xpto WHERE id = 1; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1', 'include-typmod', '0'); WARNING: column "bincol" has an unchanged TOAST data ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ diff --git a/expected/delete1.out b/expected/delete1.out index 9daee0da15ca..db93d327aa45 100644 --- a/expected/delete1.out +++ b/expected/delete1.out @@ -76,7 +76,7 @@ DELETE FROM table_without_pk WHERE b = 1; DELETE FROM table_with_pk WHERE b = 1; -- DELETE: unique DELETE FROM table_with_unique WHERE b = 1; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1', 'include-typmod', '0'); WARNING: table "table_without_pk" without primary key or replica identity is nothing WARNING: table "table_with_unique" without primary key or replica identity is nothing data diff --git a/expected/delete2.out b/expected/delete2.out index 752b8bfc5be2..338b711b53e3 100644 --- a/expected/delete2.out +++ b/expected/delete2.out @@ -80,7 +80,7 @@ ALTER TABLE table_without_pk REPLICA IDENTITY DEFAULT; ALTER TABLE table_with_unique REPLICA IDENTITY NOTHING; DELETE FROM table_with_unique WHERE b = 1; ALTER TABLE table_with_unique REPLICA IDENTITY DEFAULT; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1', 'include-typmod', '0'); WARNING: table "table_with_pk" without primary key or replica identity is nothing WARNING: table "table_without_pk" without primary key or replica identity is nothing WARNING: table "table_with_unique" without primary key or replica identity is nothing diff --git a/expected/delete3.out b/expected/delete3.out index 2cae9df5f6b9..9824f15ba378 100644 --- a/expected/delete3.out +++ b/expected/delete3.out @@ -82,7 +82,7 @@ ALTER TABLE table_without_pk REPLICA IDENTITY DEFAULT; ALTER TABLE table_with_unique REPLICA IDENTITY FULL; DELETE FROM table_with_unique WHERE b = 1; ALTER TABLE table_with_unique REPLICA IDENTITY DEFAULT; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1', 'include-typmod', '0'); data ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- { + diff --git a/expected/delete4.out b/expected/delete4.out index 5059cdff93b5..5d0bbfe9f206 100644 --- a/expected/delete4.out +++ b/expected/delete4.out @@ -35,7 +35,7 @@ ALTER TABLE table_with_unique REPLICA IDENTITY USING INDEX table_with_unique_g_n DELETE FROM table_with_unique WHERE b = 1; DELETE FROM table_with_unique WHERE n = true; ALTER TABLE table_with_unique REPLICA IDENTITY DEFAULT; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1', 'include-typmod', '0'); data ----------------------------------------------------------------- { + diff --git a/expected/insert1.out b/expected/insert1.out index 6ee618aa08ba..9fc6870d365d 100644 --- a/expected/insert1.out +++ b/expected/insert1.out @@ -71,7 +71,7 @@ INSERT INTO table_with_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1 INSERT INTO table_without_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); INSERT INTO table_with_unique (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); COMMIT; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1', 'include-typmod', '0'); data ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- { + diff --git a/expected/savepoint.out b/expected/savepoint.out index 4790391966a4..241449a6af8d 100644 --- a/expected/savepoint.out +++ b/expected/savepoint.out @@ -23,7 +23,7 @@ ROLLBACK TO SAVEPOINT sp2; RELEASE SAVEPOINT sp1; INSERT INTO xpto (b) VALUES('francisco'); END; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1', 'include-typmod', '0'); data ---------------------------------------------------------- { + diff --git a/expected/specialvalue.out b/expected/specialvalue.out index ad0c94a86086..7916ec1a35a7 100644 --- a/expected/specialvalue.out +++ b/expected/specialvalue.out @@ -17,7 +17,7 @@ INSERT INTO xpto (b, c, d) VALUES('f', 'test2', 'nan'); INSERT INTO xpto (b, c, d) VALUES(NULL, 'null', '-inf'); INSERT INTO xpto (b, c, d) VALUES(TRUE, E'valid: '' " \\ / \b \f \n \r \t \u207F \u967F invalid: \\g \\k end', 123.456); COMMIT; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1', 'include-typmod', '0'); data -------------------------------------------------------------------------------------------------------------------------- { + diff --git a/expected/toast.out b/expected/toast.out index d9676463f012..baa43fbb19dc 100644 --- a/expected/toast.out +++ b/expected/toast.out @@ -29,7 +29,7 @@ INSERT INTO xpto (toasted_col2) SELECT repeat(string_agg(to_char(g.i, 'FM0000'), 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; DELETE FROM xpto WHERE id = 1; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1', 'include-typmod', '0'); WARNING: column "toasted_col2" has an unchanged TOAST WARNING: column "toasted_col1" has an unchanged TOAST WARNING: column "toasted_col2" has an unchanged TOAST diff --git a/expected/typmod.out b/expected/typmod.out new file mode 100644 index 000000000000..82473fa70cde --- /dev/null +++ b/expected/typmod.out @@ -0,0 +1,135 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +DROP TABLE IF EXISTS table_with_pk; +CREATE TABLE table_with_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +PRIMARY KEY(b, c, d) +); +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +INSERT INTO table_with_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +UPDATE table_with_pk SET f = -f WHERE b = 1; +-- UPDATE: pk change +DELETE FROM table_with_pk WHERE b = 1; +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'pretty-print', '1'); + data +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "table_with_pk", + + "columnnames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "columntypes": ["smallint", "smallint", "integer", "bigint", "numeric(5,3)", "real", "double precision", "character(10)", "character varying(30)", "text", "bit varying(20)", "timestamp without time zone", "date", "boolean", "json", "tsvector"],+ + "columnvalues": [1, 1, 2, 3, 3.540, 876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"] + + } + + ] + + } + { + + "change": [ + + { + + "kind": "update", + + "schema": "public", + + "table": "table_with_pk", + + "columnnames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "columntypes": ["smallint", "smallint", "integer", "bigint", "numeric(5,3)", "real", "double precision", "character(10)", "character varying(30)", "text", "bit varying(20)", "timestamp without time zone", "date", "boolean", "json", "tsvector"],+ + "columnvalues": [1, 1, 2, 3, 3.540, -876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"], + + "oldkeys": { + + "keynames": ["b", "c", "d"], + + "keytypes": ["smallint", "integer", "bigint"], + + "keyvalues": [1, 2, 3] + + } + + } + + ] + + } + { + + "change": [ + + { + + "kind": "delete", + + "schema": "public", + + "table": "table_with_pk", + + "oldkeys": { + + "keynames": ["b", "c", "d"], + + "keytypes": ["smallint", "integer", "bigint"], + + "keyvalues": [1, 2, 3] + + } + + } + + ] + + } +(3 rows) + +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1', 'include-typmod', '0'); + data +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "table_with_pk", + + "columnnames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "columntypes": ["int2", "int2", "int4", "int8", "numeric", "float4", "float8", "bpchar", "varchar", "text", "varbit", "timestamp", "date", "bool", "json", "tsvector"], + + "columnvalues": [1, 1, 2, 3, 3.540, 876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"] + + } + + ] + + } + { + + "change": [ + + { + + "kind": "update", + + "schema": "public", + + "table": "table_with_pk", + + "columnnames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "columntypes": ["int2", "int2", "int4", "int8", "numeric", "float4", "float8", "bpchar", "varchar", "text", "varbit", "timestamp", "date", "bool", "json", "tsvector"], + + "columnvalues": [1, 1, 2, 3, 3.540, -876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"],+ + "oldkeys": { + + "keynames": ["b", "c", "d"], + + "keytypes": ["int2", "int4", "int8"], + + "keyvalues": [1, 2, 3] + + } + + } + + ] + + } + { + + "change": [ + + { + + "kind": "delete", + + "schema": "public", + + "table": "table_with_pk", + + "oldkeys": { + + "keynames": ["b", "c", "d"], + + "keytypes": ["int2", "int4", "int8"], + + "keyvalues": [1, 2, 3] + + } + + } + + ] + + } +(3 rows) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + diff --git a/expected/update1.out b/expected/update1.out index 510784c9dfd7..e9b2140cfe88 100644 --- a/expected/update1.out +++ b/expected/update1.out @@ -78,7 +78,7 @@ UPDATE table_with_pk SET f = -f WHERE b = 1; UPDATE table_with_pk SET b = -b WHERE b = 1; -- UPDATE: unique UPDATE table_with_unique SET n = false WHERE b = 1; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1', 'include-typmod', '0'); WARNING: table "table_without_pk" without primary key or replica identity is nothing WARNING: table "table_with_unique" without primary key or replica identity is nothing data diff --git a/expected/update2.out b/expected/update2.out index d945780c3c53..e30c337ac0c9 100644 --- a/expected/update2.out +++ b/expected/update2.out @@ -80,7 +80,7 @@ ALTER TABLE table_without_pk REPLICA IDENTITY DEFAULT; ALTER TABLE table_with_unique REPLICA IDENTITY NOTHING; UPDATE table_with_unique SET f = -f WHERE b = 1; ALTER TABLE table_with_unique REPLICA IDENTITY DEFAULT; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1', 'include-typmod', '0'); WARNING: table "table_with_pk" without primary key or replica identity is nothing WARNING: table "table_without_pk" without primary key or replica identity is nothing WARNING: table "table_with_unique" without primary key or replica identity is nothing diff --git a/expected/update3.out b/expected/update3.out index afdd698a34a6..9cf2a6f278b3 100644 --- a/expected/update3.out +++ b/expected/update3.out @@ -80,7 +80,7 @@ ALTER TABLE table_without_pk REPLICA IDENTITY DEFAULT; ALTER TABLE table_with_unique REPLICA IDENTITY FULL; UPDATE table_with_unique SET f = -f WHERE b = 1; ALTER TABLE table_with_unique REPLICA IDENTITY DEFAULT; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1', 'include-typmod', '0'); data ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- { + diff --git a/expected/update4.out b/expected/update4.out index 2a84c15e4c29..957f5d69e09a 100644 --- a/expected/update4.out +++ b/expected/update4.out @@ -36,7 +36,7 @@ ALTER TABLE table_with_unique REPLICA IDENTITY USING INDEX table_with_unique_g_n UPDATE table_with_unique SET c = -c WHERE b = 1; UPDATE table_with_unique SET g = -g WHERE n = true; ALTER TABLE table_with_unique REPLICA IDENTITY DEFAULT; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1', 'include-typmod', '0'); data -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- { + diff --git a/sql/bytea.sql b/sql/bytea.sql index 85c7fcba3936..157fc38dcc20 100644 --- a/sql/bytea.sql +++ b/sql/bytea.sql @@ -18,5 +18,5 @@ INSERT INTO xpto (bincol) SELECT decode(string_agg(to_char(round(g.i * random()) UPDATE xpto SET rand1 = 123.456 WHERE id = 1; DELETE FROM xpto WHERE id = 1; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1', 'include-typmod', '0'); SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/sql/delete1.sql b/sql/delete1.sql index 947689bcca1d..1bc2c84ba969 100644 --- a/sql/delete1.sql +++ b/sql/delete1.sql @@ -82,5 +82,5 @@ DELETE FROM table_with_pk WHERE b = 1; -- DELETE: unique DELETE FROM table_with_unique WHERE b = 1; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1', 'include-typmod', '0'); SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/sql/delete2.sql b/sql/delete2.sql index e8e6aa12b0b0..c8aa76f1e955 100644 --- a/sql/delete2.sql +++ b/sql/delete2.sql @@ -86,5 +86,5 @@ ALTER TABLE table_with_unique REPLICA IDENTITY NOTHING; DELETE FROM table_with_unique WHERE b = 1; ALTER TABLE table_with_unique REPLICA IDENTITY DEFAULT; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1', 'include-typmod', '0'); SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/sql/delete3.sql b/sql/delete3.sql index b4029dca182a..f32f969843f9 100644 --- a/sql/delete3.sql +++ b/sql/delete3.sql @@ -88,5 +88,5 @@ ALTER TABLE table_with_unique REPLICA IDENTITY FULL; DELETE FROM table_with_unique WHERE b = 1; ALTER TABLE table_with_unique REPLICA IDENTITY DEFAULT; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1', 'include-typmod', '0'); SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/sql/delete4.sql b/sql/delete4.sql index 2e27c6376709..f4492b1e6cd6 100644 --- a/sql/delete4.sql +++ b/sql/delete4.sql @@ -37,5 +37,5 @@ DELETE FROM table_with_unique WHERE b = 1; DELETE FROM table_with_unique WHERE n = true; ALTER TABLE table_with_unique REPLICA IDENTITY DEFAULT; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1', 'include-typmod', '0'); SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/sql/insert1.sql b/sql/insert1.sql index e4d36eccf2ca..d849ff062a30 100644 --- a/sql/insert1.sql +++ b/sql/insert1.sql @@ -74,5 +74,5 @@ INSERT INTO table_without_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUE INSERT INTO table_with_unique (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); COMMIT; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1', 'include-typmod', '0'); SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/sql/savepoint.sql b/sql/savepoint.sql index 3df3950f9595..9fd5a2a1ee3b 100644 --- a/sql/savepoint.sql +++ b/sql/savepoint.sql @@ -24,5 +24,5 @@ RELEASE SAVEPOINT sp1; INSERT INTO xpto (b) VALUES('francisco'); END; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1', 'include-typmod', '0'); SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/sql/specialvalue.sql b/sql/specialvalue.sql index f44165164ae9..b23c249a73d1 100644 --- a/sql/specialvalue.sql +++ b/sql/specialvalue.sql @@ -17,5 +17,5 @@ INSERT INTO xpto (b, c, d) VALUES(NULL, 'null', '-inf'); INSERT INTO xpto (b, c, d) VALUES(TRUE, E'valid: '' " \\ / \b \f \n \r \t \u207F \u967F invalid: \\g \\k end', 123.456); COMMIT; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1', 'include-typmod', '0'); SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/sql/toast.sql b/sql/toast.sql index 0d1ed2ff40a1..1bcede60fc0e 100644 --- a/sql/toast.sql +++ b/sql/toast.sql @@ -29,5 +29,5 @@ UPDATE xpto SET rand1 = 123.456 WHERE id = 1; DELETE FROM xpto WHERE id = 1; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1', 'include-typmod', '0'); SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/sql/typmod.sql b/sql/typmod.sql new file mode 100644 index 000000000000..33b323709062 --- /dev/null +++ b/sql/typmod.sql @@ -0,0 +1,39 @@ +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; + +DROP TABLE IF EXISTS table_with_pk; + +CREATE TABLE table_with_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +PRIMARY KEY(b, c, d) +); + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +INSERT INTO table_with_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); + +UPDATE table_with_pk SET f = -f WHERE b = 1; + +-- UPDATE: pk change +DELETE FROM table_with_pk WHERE b = 1; + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1', 'include-typmod', '0'); +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/sql/update1.sql b/sql/update1.sql index 2e6663f0e817..83485ad142df 100644 --- a/sql/update1.sql +++ b/sql/update1.sql @@ -85,5 +85,5 @@ UPDATE table_with_pk SET b = -b WHERE b = 1; -- UPDATE: unique UPDATE table_with_unique SET n = false WHERE b = 1; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1', 'include-typmod', '0'); SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/sql/update2.sql b/sql/update2.sql index fc92d789623b..f1ce1ce0eb56 100644 --- a/sql/update2.sql +++ b/sql/update2.sql @@ -86,5 +86,5 @@ ALTER TABLE table_with_unique REPLICA IDENTITY NOTHING; UPDATE table_with_unique SET f = -f WHERE b = 1; ALTER TABLE table_with_unique REPLICA IDENTITY DEFAULT; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1', 'include-typmod', '0'); SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/sql/update3.sql b/sql/update3.sql index b689dffc2428..d28054ed10bd 100644 --- a/sql/update3.sql +++ b/sql/update3.sql @@ -86,5 +86,5 @@ ALTER TABLE table_with_unique REPLICA IDENTITY FULL; UPDATE table_with_unique SET f = -f WHERE b = 1; ALTER TABLE table_with_unique REPLICA IDENTITY DEFAULT; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1', 'include-typmod', '0'); SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/sql/update4.sql b/sql/update4.sql index ad094d2deacf..9c77162219f4 100644 --- a/sql/update4.sql +++ b/sql/update4.sql @@ -38,5 +38,5 @@ UPDATE table_with_unique SET c = -c WHERE b = 1; UPDATE table_with_unique SET g = -g WHERE n = true; ALTER TABLE table_with_unique REPLICA IDENTITY DEFAULT; -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'pretty-print', '1', 'include-typmod', '0'); SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/wal2json.c b/wal2json.c index 98a91e619c8a..b5bf3f80e556 100644 --- a/wal2json.c +++ b/wal2json.c @@ -47,6 +47,7 @@ typedef struct bool include_timestamp; /* include transaction timestamp */ bool include_schemas; /* qualify tables */ bool include_types; /* include data types */ + bool include_typmod; /* include typmod in types */ bool pretty_print; /* pretty-print JSON? */ bool write_in_chunks; /* write in chunks? */ @@ -116,6 +117,7 @@ pg_decode_startup(LogicalDecodingContext *ctx, OutputPluginOptions *opt, bool is data->include_timestamp = false; data->include_schemas = true; data->include_types = true; + data->include_typmod = true; data->pretty_print = false; data->write_in_chunks = false; data->include_lsn = false; @@ -185,6 +187,19 @@ pg_decode_startup(LogicalDecodingContext *ctx, OutputPluginOptions *opt, bool is errmsg("could not parse value \"%s\" for parameter \"%s\"", strVal(elem->arg), elem->defname))); } + else if (strcmp(elem->defname, "include-typmod") == 0) + { + if (elem->arg == NULL) + { + elog(LOG, "include-typmod argument is null"); + data->include_typmod = true; + } + else if (!parse_bool(strVal(elem->arg), &data->include_typmod)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("could not parse value \"%s\" for parameter \"%s\"", + strVal(elem->arg), elem->defname))); + } else if (strcmp(elem->defname, "pretty-print") == 0) { if (elem->arg == NULL) @@ -451,7 +466,6 @@ tuple_to_stringinfo(LogicalDecodingContext *ctx, TupleDesc tupdesc, HeapTuple tu Form_pg_attribute attr; /* the attribute itself */ Oid typid; /* type of current attribute */ HeapTuple type_tuple; /* information about a type */ - Form_pg_type type_form; Oid typoutput; /* output function */ bool typisvarlena; Datum origval; /* possibly toasted Datum */ @@ -490,7 +504,6 @@ tuple_to_stringinfo(LogicalDecodingContext *ctx, TupleDesc tupdesc, HeapTuple tu type_tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid)); if (!HeapTupleIsValid(type_tuple)) elog(ERROR, "cache lookup failed for type %u", typid); - type_form = (Form_pg_type) GETSTRUCT(type_tuple); /* Get information needed for printing values of a type */ getTypeOutputInfo(typid, &typoutput, &typisvarlena); @@ -513,7 +526,21 @@ tuple_to_stringinfo(LogicalDecodingContext *ctx, TupleDesc tupdesc, HeapTuple tu appendStringInfo(&colnames, "%s\"%s\"", comma, NameStr(attr->attname)); if (data->include_types) - appendStringInfo(&coltypes, "%s\"%s\"", comma, NameStr(type_form->typname)); + { + if (data->include_typmod) + { + char *type_str; + + type_str = TextDatumGetCString(DirectFunctionCall2(format_type, attr->atttypid, attr->atttypmod)); + appendStringInfo(&coltypes, "%s\"%s\"", comma, type_str); + pfree(type_str); + } + else + { + Form_pg_type type_form = (Form_pg_type) GETSTRUCT(type_tuple); + appendStringInfo(&coltypes, "%s\"%s\"", comma, NameStr(type_form->typname)); + } + } ReleaseSysCache(type_tuple);