diff --git a/expected/default.out b/expected/default.out index 69c85f5336c4..3619c9c532ec 100644 --- a/expected/default.out +++ b/expected/default.out @@ -2,6 +2,7 @@ -- predictability SET synchronous_commit = on; CREATE TABLE w2j_default (a serial, b integer DEFAULT 6, c text DEFAULT 'wal2json', d timestamp DEFAULT '2020-07-12 11:55:30', e integer DEFAULT NULL, f integer, PRIMARY KEY(a)); +CREATE TABLE w2j_truncate (a serial primary key, b text not null); SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); ?column? ---------- @@ -11,6 +12,9 @@ SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2js INSERT INTO w2j_default (b, c ,d, e, f) VALUES(2, 'test', '2020-03-01 08:09:00', 80, 10); INSERT INTO w2j_default DEFAULT VALUES; UPDATE w2j_default SET b = 3 WHERE a = 1; +INSERT INTO w2j_truncate (b) VALUES('foo@bar.com'); +TRUNCATE w2j_truncate; +INSERT INTO w2j_truncate (b) VALUES('foo@bar.com'); -- without include-default parameter SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1'); data @@ -18,7 +22,10 @@ SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'fo {"change":[{"kind":"insert","schema":"public","table":"w2j_default","columnnames":["a","b","c","d","e","f"],"columntypes":["integer","integer","text","timestamp without time zone","integer","integer"],"columnvalues":[1,2,"test","Sun Mar 01 08:09:00 2020",80,10]}]} {"change":[{"kind":"insert","schema":"public","table":"w2j_default","columnnames":["a","b","c","d","e","f"],"columntypes":["integer","integer","text","timestamp without time zone","integer","integer"],"columnvalues":[2,6,"wal2json","Sun Jul 12 11:55:30 2020",null,null]}]} {"change":[{"kind":"update","schema":"public","table":"w2j_default","columnnames":["a","b","c","d","e","f"],"columntypes":["integer","integer","text","timestamp without time zone","integer","integer"],"columnvalues":[1,3,"test","Sun Mar 01 08:09:00 2020",80,10],"oldkeys":{"keynames":["a"],"keytypes":["integer"],"keyvalues":[1]}}]} -(3 rows) + {"change":[{"kind":"insert","schema":"public","table":"w2j_truncate","columnnames":["a","b"],"columntypes":["integer","text"],"columnvalues":[1,"foo@bar.com"]}]} + {"change":[]} + {"change":[{"kind":"insert","schema":"public","table":"w2j_truncate","columnnames":["a","b"],"columntypes":["integer","text"],"columnvalues":[2,"foo@bar.com"]}]} +(6 rows) SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); data @@ -32,7 +39,16 @@ SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'fo {"action":"B"} {"action":"U","schema":"public","table":"w2j_default","columns":[{"name":"a","type":"integer","value":1},{"name":"b","type":"integer","value":3},{"name":"c","type":"text","value":"test"},{"name":"d","type":"timestamp without time zone","value":"Sun Mar 01 08:09:00 2020"},{"name":"e","type":"integer","value":80},{"name":"f","type":"integer","value":10}],"identity":[{"name":"a","type":"integer","value":1}]} {"action":"C"} -(9 rows) + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_truncate","columns":[{"name":"a","type":"integer","value":1},{"name":"b","type":"text","value":"foo@bar.com"}]} + {"action":"C"} + {"action":"B"} + {"action":"T","schema":"public","table":"w2j_truncate"} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_truncate","columns":[{"name":"a","type":"integer","value":2},{"name":"b","type":"text","value":"foo@bar.com"}]} + {"action":"C"} +(18 rows) -- with include-default parameter SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-default', '1'); @@ -41,7 +57,10 @@ SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'fo {"change":[{"kind":"insert","schema":"public","table":"w2j_default","columnnames":["a","b","c","d","e","f"],"columntypes":["integer","integer","text","timestamp without time zone","integer","integer"],"columndefaults":["nextval('w2j_default_a_seq'::regclass)","6","'wal2json'::text","'Sun Jul 12 11:55:30 2020'::timestamp without time zone",null,null],"columnvalues":[1,2,"test","Sun Mar 01 08:09:00 2020",80,10]}]} {"change":[{"kind":"insert","schema":"public","table":"w2j_default","columnnames":["a","b","c","d","e","f"],"columntypes":["integer","integer","text","timestamp without time zone","integer","integer"],"columndefaults":["nextval('w2j_default_a_seq'::regclass)","6","'wal2json'::text","'Sun Jul 12 11:55:30 2020'::timestamp without time zone",null,null],"columnvalues":[2,6,"wal2json","Sun Jul 12 11:55:30 2020",null,null]}]} {"change":[{"kind":"update","schema":"public","table":"w2j_default","columnnames":["a","b","c","d","e","f"],"columntypes":["integer","integer","text","timestamp without time zone","integer","integer"],"columndefaults":["nextval('w2j_default_a_seq'::regclass)","6","'wal2json'::text","'Sun Jul 12 11:55:30 2020'::timestamp without time zone",null,null],"columnvalues":[1,3,"test","Sun Mar 01 08:09:00 2020",80,10],"oldkeys":{"keynames":["a"],"keytypes":["integer"],"keyvalues":[1]}}]} -(3 rows) + {"change":[{"kind":"insert","schema":"public","table":"w2j_truncate","columnnames":["a","b"],"columntypes":["integer","text"],"columndefaults":["nextval('w2j_truncate_a_seq'::regclass)",null],"columnvalues":[1,"foo@bar.com"]}]} + {"change":[]} + {"change":[{"kind":"insert","schema":"public","table":"w2j_truncate","columnnames":["a","b"],"columntypes":["integer","text"],"columndefaults":["nextval('w2j_truncate_a_seq'::regclass)",null],"columnvalues":[2,"foo@bar.com"]}]} +(6 rows) SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'include-default', '1'); data @@ -55,7 +74,16 @@ SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'fo {"action":"B"} {"action":"U","schema":"public","table":"w2j_default","columns":[{"name":"a","type":"integer","value":1,"default":"nextval('w2j_default_a_seq'::regclass)"},{"name":"b","type":"integer","value":3,"default":"6"},{"name":"c","type":"text","value":"test","default":"'wal2json'::text"},{"name":"d","type":"timestamp without time zone","value":"Sun Mar 01 08:09:00 2020","default":"'Sun Jul 12 11:55:30 2020'::timestamp without time zone"},{"name":"e","type":"integer","value":80,"default":null},{"name":"f","type":"integer","value":10,"default":null}],"identity":[{"name":"a","type":"integer","value":1}]} {"action":"C"} -(9 rows) + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_truncate","columns":[{"name":"a","type":"integer","value":1,"default":"nextval('w2j_truncate_a_seq'::regclass)"},{"name":"b","type":"text","value":"foo@bar.com","default":null}]} + {"action":"C"} + {"action":"B"} + {"action":"T","schema":"public","table":"w2j_truncate"} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_truncate","columns":[{"name":"a","type":"integer","value":2,"default":"nextval('w2j_truncate_a_seq'::regclass)"},{"name":"b","type":"text","value":"foo@bar.com","default":null}]} + {"action":"C"} +(18 rows) SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); ?column? @@ -64,3 +92,4 @@ SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); (1 row) DROP TABLE w2j_default; +DROP TABLE w2j_truncate; diff --git a/sql/default.sql b/sql/default.sql index 8d3d107efb45..5b8575996bf2 100644 --- a/sql/default.sql +++ b/sql/default.sql @@ -4,6 +4,7 @@ SET synchronous_commit = on; CREATE TABLE w2j_default (a serial, b integer DEFAULT 6, c text DEFAULT 'wal2json', d timestamp DEFAULT '2020-07-12 11:55:30', e integer DEFAULT NULL, f integer, PRIMARY KEY(a)); +CREATE TABLE w2j_truncate (a serial primary key, b text not null); SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); @@ -11,6 +12,10 @@ INSERT INTO w2j_default (b, c ,d, e, f) VALUES(2, 'test', '2020-03-01 08:09:00', INSERT INTO w2j_default DEFAULT VALUES; UPDATE w2j_default SET b = 3 WHERE a = 1; +INSERT INTO w2j_truncate (b) VALUES('foo@bar.com'); +TRUNCATE w2j_truncate; +INSERT INTO w2j_truncate (b) VALUES('foo@bar.com'); + -- without include-default parameter SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1'); SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); @@ -22,3 +27,4 @@ SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'fo SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); DROP TABLE w2j_default; +DROP TABLE w2j_truncate; diff --git a/wal2json.c b/wal2json.c index 4f92d80b43db..04fb0c54df57 100644 --- a/wal2json.c +++ b/wal2json.c @@ -135,8 +135,8 @@ static void pg_decode_truncate(LogicalDecodingContext *ctx, ReorderBufferChange *change); #endif -static void columns_to_stringinfo(LogicalDecodingContext *ctx, TupleDesc tupdesc, HeapTuple tuple, bool addcomma, Oid reloid); -static void tuple_to_stringinfo(LogicalDecodingContext *ctx, TupleDesc tupdesc, HeapTuple tuple, Bitmapset *bs, bool replident, bool addcomma, Oid reloid); +static void columns_to_stringinfo(LogicalDecodingContext *ctx, TupleDesc tupdesc, HeapTuple tuple, bool addcomma, Relation relation); +static void tuple_to_stringinfo(LogicalDecodingContext *ctx, TupleDesc tupdesc, HeapTuple tuple, Bitmapset *bs, bool replident, bool addcomma, Relation relation); static void pk_to_stringinfo(LogicalDecodingContext *ctx, TupleDesc tupdesc, HeapTuple tuple, Bitmapset *bs, bool addcomma); static void identity_to_stringinfo(LogicalDecodingContext *ctx, TupleDesc tupdesc, HeapTuple tuple, Bitmapset *bs); static bool parse_table_identifier(List *qualified_tables, char separator, List **select_tables); @@ -949,7 +949,7 @@ pg_decode_commit_txn_v2(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, * replident: is this tuple a replica identity? */ static void -tuple_to_stringinfo(LogicalDecodingContext *ctx, TupleDesc tupdesc, HeapTuple tuple, Bitmapset *bs, bool replident, bool addcomma, Oid reloid) +tuple_to_stringinfo(LogicalDecodingContext *ctx, TupleDesc tupdesc, HeapTuple tuple, Bitmapset *bs, bool replident, bool addcomma, Relation relation) { JsonDecodingData *data; int natt; @@ -1169,7 +1169,7 @@ tuple_to_stringinfo(LogicalDecodingContext *ctx, TupleDesc tupdesc, HeapTuple tu ScanKeyInit(&scankeys[0], Anum_pg_attrdef_adrelid, BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(reloid)); + ObjectIdGetDatum(relation->rd_id)); ScanKeyInit(&scankeys[1], Anum_pg_attrdef_adnum, BTEqualStrategyNumber, F_INT2EQ, @@ -1187,7 +1187,7 @@ tuple_to_stringinfo(LogicalDecodingContext *ctx, TupleDesc tupdesc, HeapTuple tu { result = TextDatumGetCString(DirectFunctionCall2(pg_get_expr, def_value, - ObjectIdGetDatum(tuple->t_tableOid))); + ObjectIdGetDatum(relation->rd_id))); appendStringInfo(&coldefaults, "%s\"%s\"", comma, result); pfree(result); @@ -1346,9 +1346,9 @@ tuple_to_stringinfo(LogicalDecodingContext *ctx, TupleDesc tupdesc, HeapTuple tu /* Print columns information */ static void -columns_to_stringinfo(LogicalDecodingContext *ctx, TupleDesc tupdesc, HeapTuple tuple, bool addcomma, Oid reloid) +columns_to_stringinfo(LogicalDecodingContext *ctx, TupleDesc tupdesc, HeapTuple tuple, bool addcomma, Relation relation) { - tuple_to_stringinfo(ctx, tupdesc, tuple, NULL, false, addcomma, reloid); + tuple_to_stringinfo(ctx, tupdesc, tuple, NULL, false, addcomma, relation); } /* Print replica identity information */ @@ -1356,7 +1356,7 @@ static void identity_to_stringinfo(LogicalDecodingContext *ctx, TupleDesc tupdesc, HeapTuple tuple, Bitmapset *bs) { /* Last parameter does not matter */ - tuple_to_stringinfo(ctx, tupdesc, tuple, bs, true, false, InvalidOid); + tuple_to_stringinfo(ctx, tupdesc, tuple, bs, true, false, NULL); } /* Print primary key information */ @@ -1751,17 +1751,17 @@ pg_decode_change_v1(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, if (data->include_pk && OidIsValid(relation->rd_replidindex) && relation->rd_rel->relreplident == REPLICA_IDENTITY_DEFAULT) { - columns_to_stringinfo(ctx, tupdesc, &change->data.tp.newtuple->tuple, true, change->data.tp.relnode.relNode); + columns_to_stringinfo(ctx, tupdesc, &change->data.tp.newtuple->tuple, true, relation); pk_to_stringinfo(ctx, tupdesc, &change->data.tp.newtuple->tuple, pkbs, false); } else { - columns_to_stringinfo(ctx, tupdesc, &change->data.tp.newtuple->tuple, false, change->data.tp.relnode.relNode); + columns_to_stringinfo(ctx, tupdesc, &change->data.tp.newtuple->tuple, false, relation); } break; case REORDER_BUFFER_CHANGE_UPDATE: /* Print the new tuple */ - columns_to_stringinfo(ctx, tupdesc, &change->data.tp.newtuple->tuple, true, change->data.tp.relnode.relNode); + columns_to_stringinfo(ctx, tupdesc, &change->data.tp.newtuple->tuple, true, relation); if (data->include_pk && OidIsValid(relation->rd_replidindex) && relation->rd_rel->relreplident == REPLICA_IDENTITY_DEFAULT) pk_to_stringinfo(ctx, tupdesc, &change->data.tp.newtuple->tuple, pkbs, true);