Make hypertables support replica identity

Add support for setting replica identity on hypertables via ALTER
TABLE. The replica identity is used in logical replication to identify
rows that have changed.

Currently, replica identity can only be altered on hypertables via the
root; changing it directly on chunks will raise an error.
This commit is contained in:
Erik Nordström 2023-03-31 14:22:35 +02:00 committed by Erik Nordström
parent 33a3e10f48
commit e2e7e5f286
13 changed files with 445 additions and 44 deletions

1
.unreleased/feature_5515 Normal file
View File

@ -0,0 +1 @@
Implements: #5515 Make hypertables support replica identity

View File

@ -1006,6 +1006,44 @@ chunk_insert_into_metadata_after_lock(const Chunk *chunk)
ts_chunk_constraints_insert_metadata(chunk->constraints);
}
/*
* Ensure the replica identity setting of a chunk matches that of the root
* table.
*/
static void
chunk_set_replica_identity(const Chunk *chunk)
{
Relation ht_rel = relation_open(chunk->hypertable_relid, AccessShareLock);
ReplicaIdentityStmt stmt = {
.type = T_ReplicaIdentityStmt,
.identity_type = ht_rel->rd_rel->relreplident,
};
AlterTableCmd cmd = {
.type = T_AlterTableCmd,
.def = (Node *) &stmt,
.subtype = AT_ReplicaIdentity,
};
CatalogSecurityContext sec_ctx;
if (stmt.identity_type == REPLICA_IDENTITY_INDEX)
{
ChunkIndexMapping idxm;
/* Lookup the corresponding chunk index. If this index is
* dropped, the behavior is the same as NOTHING (as per PG
* documentation). */
if (!ts_chunk_index_get_by_hypertable_indexrelid(chunk, ht_rel->rd_replidindex, &idxm))
stmt.identity_type = REPLICA_IDENTITY_NOTHING;
else
stmt.name = get_rel_name(idxm.indexoid);
}
ts_catalog_database_info_become_owner(ts_catalog_database_info_get(), &sec_ctx);
AlterTableInternal(chunk->table_id, list_make1(&cmd), false);
ts_catalog_restore_user(&sec_ctx);
table_close(ht_rel, NoLock);
}
static void
chunk_create_table_constraints(const Hypertable *ht, const Chunk *chunk)
{
@ -1020,6 +1058,8 @@ chunk_create_table_constraints(const Hypertable *ht, const Chunk *chunk)
chunk->fd.id,
chunk->table_id,
InvalidOid);
chunk_set_replica_identity(chunk);
}
}

View File

@ -787,7 +787,8 @@ chunk_index_tuple_found(TupleInfo *ti, void *const data)
}
bool
ts_chunk_index_get_by_indexrelid(Chunk *chunk, Oid chunk_indexrelid, ChunkIndexMapping *cim_out)
ts_chunk_index_get_by_indexrelid(const Chunk *chunk, Oid chunk_indexrelid,
ChunkIndexMapping *cim_out)
{
int tuples_found;
ScanKeyData scankey[2];
@ -835,7 +836,7 @@ chunk_hypertable_index_name_filter(const TupleInfo *ti, void *data)
}
TSDLLEXPORT bool
ts_chunk_index_get_by_hypertable_indexrelid(Chunk *chunk, Oid hypertable_indexrelid,
ts_chunk_index_get_by_hypertable_indexrelid(const Chunk *chunk, Oid hypertable_indexrelid,
ChunkIndexMapping *cim_out)
{
int tuples_found;

View File

@ -51,10 +51,10 @@ extern int ts_chunk_index_set_tablespace(Hypertable *ht, Oid hypertable_indexrel
extern void ts_chunk_index_create_from_constraint(int32 hypertable_id, Oid hypertable_constraint,
int32 chunk_id, Oid chunk_constraint);
extern List *ts_chunk_index_get_mappings(Hypertable *ht, Oid hypertable_indexrelid);
extern TSDLLEXPORT bool ts_chunk_index_get_by_hypertable_indexrelid(Chunk *chunk,
extern TSDLLEXPORT bool ts_chunk_index_get_by_hypertable_indexrelid(const Chunk *chunk,
Oid hypertable_indexrelid,
ChunkIndexMapping *cim_out);
extern TSDLLEXPORT bool ts_chunk_index_get_by_indexrelid(Chunk *chunk, Oid chunk_indexrelid,
extern TSDLLEXPORT bool ts_chunk_index_get_by_indexrelid(const Chunk *chunk, Oid chunk_indexrelid,
ChunkIndexMapping *cim_out);
extern TSDLLEXPORT void ts_chunk_index_mark_clustered(Oid chunkrelid, Oid indexrelid);

View File

@ -1342,12 +1342,6 @@ table_is_logged(Oid table_relid)
return get_rel_persistence(table_relid) == RELPERSISTENCE_PERMANENT;
}
static bool
table_has_replica_identity(const Relation rel)
{
return rel->rd_rel->relreplident != REPLICA_IDENTITY_DEFAULT;
}
inline static bool
table_has_rules(Relation rel)
{
@ -2184,12 +2178,6 @@ ts_hypertable_create_from_info(Oid table_relid, int32 hypertable_id, uint32 flag
errdetail(
"It is not possible to turn temporary or unlogged tables into hypertables.")));
if (table_has_replica_identity(rel))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("table \"%s\" has replica identity set", get_rel_name(table_relid)),
errdetail("Logical replication is not supported on hypertables.")));
if (table_has_rules(rel))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

View File

@ -3,6 +3,7 @@
* Please see the included NOTICE for copyright information and
* LICENSE-APACHE for a copy of the license.
*/
#include <catalog/pg_class_d.h>
#include <postgres.h>
#include <foreign/foreign.h>
#include <nodes/parsenodes.h>
@ -3218,6 +3219,64 @@ process_altertable_chunk(Hypertable *ht, Oid chunk_relid, void *arg)
AlterTableInternal(chunk_relid, list_make1(cmd), false);
}
static void
process_altertable_chunk_replica_identity(Hypertable *ht, Oid chunk_relid, void *arg)
{
AlterTableCmd *cmd = castNode(AlterTableCmd, copyObject(arg));
ReplicaIdentityStmt *stmt = castNode(ReplicaIdentityStmt, cmd->def);
char relkind = get_rel_relkind(chunk_relid);
/* If this is not a local chunk (e.g., it is foreign table representing a
* data node or OSM chunk), then we don't set replica identity locally */
if (relkind != RELKIND_RELATION)
return;
if (stmt->identity_type == REPLICA_IDENTITY_INDEX)
{
Chunk *chunk = ts_chunk_get_by_relid(chunk_relid, true);
Oid hyper_schema_oid = get_rel_namespace(ht->main_table_relid);
Oid hyper_index_oid = get_relname_relid(stmt->name, hyper_schema_oid);
ChunkIndexMapping cim;
Assert(OidIsValid(hyper_index_oid));
if (!ts_chunk_index_get_by_hypertable_indexrelid(chunk, hyper_index_oid, &cim))
elog(ERROR,
"chunk \"%s.%s\" has no index corresponding to hypertable index \"%s\"",
NameStr(chunk->fd.schema_name),
NameStr(chunk->fd.table_name),
stmt->name);
stmt->name = get_rel_name(cim.indexoid);
}
AlterTableInternal(chunk_relid, list_make1(cmd), false);
}
static void
process_altertable_replica_identity(Hypertable *ht, AlterTableCmd *cmd)
{
ReplicaIdentityStmt *stmt = castNode(ReplicaIdentityStmt, cmd->def);
if (stmt->identity_type == REPLICA_IDENTITY_INDEX)
{
Oid hyper_schema_oid = get_rel_namespace(ht->main_table_relid);
Oid hyper_index_oid;
hyper_index_oid = get_relname_relid(stmt->name, hyper_schema_oid);
if (!OidIsValid(hyper_index_oid))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("index \"%s\" for table \"%s.%s\" does not exist",
stmt->name,
NameStr(ht->fd.schema_name),
NameStr(ht->fd.table_name))));
}
foreach_chunk(ht, process_altertable_chunk_replica_identity, cmd);
}
static void
process_altertable_set_tablespace_end(Hypertable *ht, AlterTableCmd *cmd)
{
@ -3712,10 +3771,7 @@ process_altertable_end_subcmd(Hypertable *ht, Node *parsetree, ObjectAddress *ob
/* Break here to silence compiler */
break;
case AT_ReplicaIdentity:
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("hypertables do not support logical replication")));
/* Break here to silence compiler */
process_altertable_replica_identity(ht, cmd);
break;
case AT_EnableRule:
case AT_EnableAlwaysRule:

View File

@ -791,3 +791,114 @@ ALTER TABLE i4474 ALTER COLUMN time SET statistics 10;
SET ROLE role_4474;
INSERT INTO i4474 SELECT '2021-01-01';
RESET ROLE;
DROP TABLE i4474 CASCADE;
DROP ROLE role_4474;
-- verify that setting replica identity works and chunks inherit the
-- root table's setting
CREATE TABLE replid(time timestamptz, value int);
SELECT create_hypertable('replid', 'time', chunk_time_interval => interval '1 day', create_default_indexes => false);
NOTICE: adding not-null constraint to column "time"
create_hypertable
----------------------
(16,public,replid,t)
(1 row)
-- replica identity set to default
SELECT relreplident FROM pg_class WHERE relname = 'replid';
relreplident
--------------
d
(1 row)
INSERT INTO replid VALUES ('2023-01-01', 1);
-- the new chunk should have the same replica identity setting
SELECT relname, relreplident FROM show_chunks('replid') ch INNER JOIN pg_class c ON (ch = c.oid) ORDER BY relname;
relname | relreplident
--------------------+--------------
_hyper_16_31_chunk | d
(1 row)
-- test change to replica identity full
ALTER TABLE replid REPLICA IDENTITY FULL;
SELECT relname, relreplident FROM pg_class WHERE relname = 'replid' ORDER BY relname;
relname | relreplident
---------+--------------
replid | f
(1 row)
-- the chunk's setting should also change to FULL
SELECT relname, relreplident FROM show_chunks('replid') ch INNER JOIN pg_class c ON (ch = c.oid) ORDER BY relname;
relname | relreplident
--------------------+--------------
_hyper_16_31_chunk | f
(1 row)
-- change to replica identity index
CREATE UNIQUE INDEX time_key ON replid (time);
ALTER TABLE replid REPLICA IDENTITY USING INDEX time_key;
SELECT relname, relreplident FROM pg_class WHERE relname = 'replid' ORDER BY relname;
relname | relreplident
---------+--------------
replid | i
(1 row)
SELECT relname, relreplident FROM show_chunks('replid') ch INNER JOIN pg_class c ON (ch = c.oid) ORDER BY relname;
relname | relreplident
--------------------+--------------
_hyper_16_31_chunk | i
(1 row)
SELECT indexrelid::regclass::text AS index_name
FROM show_chunks('replid') chid
INNER JOIN pg_index i ON (i.indrelid = chid) AND indisreplident=true
ORDER BY index_name;
index_name
---------------------------------------------------
_timescaledb_internal._hyper_16_31_chunk_time_key
(1 row)
INSERT INTO replid VALUES ('2023-01-02', 2);
-- the new chunk will also have replica identity "index"
SELECT relname, relreplident FROM show_chunks('replid') ch INNER JOIN pg_class c ON (ch = c.oid) ORDER BY relname;
relname | relreplident
--------------------+--------------
_hyper_16_31_chunk | i
_hyper_16_32_chunk | i
(2 rows)
SELECT indexrelid::regclass::text AS index_name
FROM show_chunks('replid') chid
INNER JOIN pg_index i ON (i.indrelid = chid) AND indisreplident=true
ORDER BY index_name;
index_name
---------------------------------------------------
_timescaledb_internal._hyper_16_31_chunk_time_key
_timescaledb_internal._hyper_16_32_chunk_time_key
(2 rows)
-- drop the replica identity index and create a new chunk. The new
-- chunk should have replica identity "NOTHING" since this is the
-- behavior of replica identity index when the index is dropped.
DROP INDEX time_key;
INSERT INTO replid VALUES ('2023-01-03', 3);
-- no indexes left
SELECT relname, relreplident FROM show_chunks('replid') ch INNER JOIN pg_class c ON (ch = c.oid) ORDER BY relname;
relname | relreplident
--------------------+--------------
_hyper_16_31_chunk | i
_hyper_16_32_chunk | i
_hyper_16_33_chunk | n
(3 rows)
SELECT indexrelid::regclass::text AS index_name
FROM show_chunks('replid') chid
INNER JOIN pg_index i ON (i.indrelid = chid) AND indisreplident=true
ORDER BY index_name;
index_name
------------
(0 rows)
-- Alter replica identity directly on a chunk is not supported
SELECT ch AS chunk_name FROM show_chunks('replid') ch ORDER BY chunk_name LIMIT 1 \gset
ALTER TABLE :chunk_name REPLICA IDENTITY FULL;
ERROR: operation not supported on chunk tables

View File

@ -94,18 +94,6 @@ ALTER TABLE "Hypertable_1" SET UNLOGGED;
ERROR: logging cannot be turned off for hypertables
\set ON_ERROR_STOP 1
ALTER TABLE "Hypertable_1" SET LOGGED;
CREATE TABLE PUBLIC."Hypertable_1_replica_ident" (
time BIGINT NOT NULL,
"Device_id" TEXT NOT NULL,
temp_c int NOT NULL DEFAULT -1
);
ALTER TABLE "Hypertable_1_replica_ident" REPLICA IDENTITY FULL;
\set ON_ERROR_STOP 0
SELECT * FROM create_hypertable('"public"."Hypertable_1_replica_ident"', 'time', chunk_time_interval=>_timescaledb_internal.interval_to_usec('1 month'));
ERROR: table "Hypertable_1_replica_ident" has replica identity set
ALTER TABLE "Hypertable_1" REPLICA IDENTITY FULL;
ERROR: hypertables do not support logical replication
\set ON_ERROR_STOP 1
CREATE TABLE PUBLIC."Hypertable_1_rule" (
time BIGINT NOT NULL,
"Device_id" TEXT NOT NULL,

View File

@ -446,4 +446,62 @@ ALTER TABLE i4474 ALTER COLUMN time SET statistics 10;
SET ROLE role_4474;
INSERT INTO i4474 SELECT '2021-01-01';
RESET ROLE;
DROP TABLE i4474 CASCADE;
DROP ROLE role_4474;
-- verify that setting replica identity works and chunks inherit the
-- root table's setting
CREATE TABLE replid(time timestamptz, value int);
SELECT create_hypertable('replid', 'time', chunk_time_interval => interval '1 day', create_default_indexes => false);
-- replica identity set to default
SELECT relreplident FROM pg_class WHERE relname = 'replid';
INSERT INTO replid VALUES ('2023-01-01', 1);
-- the new chunk should have the same replica identity setting
SELECT relname, relreplident FROM show_chunks('replid') ch INNER JOIN pg_class c ON (ch = c.oid) ORDER BY relname;
-- test change to replica identity full
ALTER TABLE replid REPLICA IDENTITY FULL;
SELECT relname, relreplident FROM pg_class WHERE relname = 'replid' ORDER BY relname;
-- the chunk's setting should also change to FULL
SELECT relname, relreplident FROM show_chunks('replid') ch INNER JOIN pg_class c ON (ch = c.oid) ORDER BY relname;
-- change to replica identity index
CREATE UNIQUE INDEX time_key ON replid (time);
ALTER TABLE replid REPLICA IDENTITY USING INDEX time_key;
SELECT relname, relreplident FROM pg_class WHERE relname = 'replid' ORDER BY relname;
SELECT relname, relreplident FROM show_chunks('replid') ch INNER JOIN pg_class c ON (ch = c.oid) ORDER BY relname;
SELECT indexrelid::regclass::text AS index_name
FROM show_chunks('replid') chid
INNER JOIN pg_index i ON (i.indrelid = chid) AND indisreplident=true
ORDER BY index_name;
INSERT INTO replid VALUES ('2023-01-02', 2);
-- the new chunk will also have replica identity "index"
SELECT relname, relreplident FROM show_chunks('replid') ch INNER JOIN pg_class c ON (ch = c.oid) ORDER BY relname;
SELECT indexrelid::regclass::text AS index_name
FROM show_chunks('replid') chid
INNER JOIN pg_index i ON (i.indrelid = chid) AND indisreplident=true
ORDER BY index_name;
-- drop the replica identity index and create a new chunk. The new
-- chunk should have replica identity "NOTHING" since this is the
-- behavior of replica identity index when the index is dropped.
DROP INDEX time_key;
INSERT INTO replid VALUES ('2023-01-03', 3);
-- no indexes left
SELECT relname, relreplident FROM show_chunks('replid') ch INNER JOIN pg_class c ON (ch = c.oid) ORDER BY relname;
SELECT indexrelid::regclass::text AS index_name
FROM show_chunks('replid') chid
INNER JOIN pg_index i ON (i.indrelid = chid) AND indisreplident=true
ORDER BY index_name;
-- Alter replica identity directly on a chunk is not supported
SELECT ch AS chunk_name FROM show_chunks('replid') ch ORDER BY chunk_name LIMIT 1 \gset
ALTER TABLE :chunk_name REPLICA IDENTITY FULL;
SELECT relname, relreplident FROM show_chunks('replid') ch INNER JOIN pg_class c ON (ch = c.oid) ORDER BY relname;

View File

@ -85,18 +85,6 @@ ALTER TABLE "Hypertable_1" SET UNLOGGED;
\set ON_ERROR_STOP 1
ALTER TABLE "Hypertable_1" SET LOGGED;
CREATE TABLE PUBLIC."Hypertable_1_replica_ident" (
time BIGINT NOT NULL,
"Device_id" TEXT NOT NULL,
temp_c int NOT NULL DEFAULT -1
);
ALTER TABLE "Hypertable_1_replica_ident" REPLICA IDENTITY FULL;
\set ON_ERROR_STOP 0
SELECT * FROM create_hypertable('"public"."Hypertable_1_replica_ident"', 'time', chunk_time_interval=>_timescaledb_internal.interval_to_usec('1 month'));
ALTER TABLE "Hypertable_1" REPLICA IDENTITY FULL;
\set ON_ERROR_STOP 1
CREATE TABLE PUBLIC."Hypertable_1_rule" (
time BIGINT NOT NULL,

View File

@ -793,6 +793,7 @@ dist_ddl_process_alter_table(const ProcessUtilityArgs *args)
case AT_DropNotNull:
case AT_AddIndex:
case AT_AlterColumnType:
case AT_ReplicaIdentity:
exec_type = set_alter_table_exec_type(exec_type, DIST_DDL_EXEC_ON_END);
break;
case AT_ChangeOwner:

View File

@ -596,6 +596,160 @@ SELECT * FROM show_chunks('disttable');
_timescaledb_internal._dist_hyper_1_5_chunk
(5 rows)
-- Replica identity
SELECT * FROM test.remote_exec(NULL,
$$
SELECT relname, relreplident FROM pg_class WHERE relname = 'disttable' ORDER BY relname;
SELECT relname, relreplident FROM show_chunks('disttable') ch INNER JOIN pg_class c ON (ch = c.oid) ORDER BY relname;
$$);
NOTICE: [db_dist_ddl_1]:
SELECT relname, relreplident FROM pg_class WHERE relname = 'disttable' ORDER BY relname
NOTICE: [db_dist_ddl_1]:
relname |relreplident
---------+------------
disttable|d
(1 row)
NOTICE: [db_dist_ddl_1]:
SELECT relname, relreplident FROM show_chunks('disttable') ch INNER JOIN pg_class c ON (ch = c.oid) ORDER BY relname
NOTICE: [db_dist_ddl_1]:
relname |relreplident
---------------------+------------
_dist_hyper_1_1_chunk|d
_dist_hyper_1_2_chunk|d
_dist_hyper_1_3_chunk|d
_dist_hyper_1_4_chunk|d
_dist_hyper_1_5_chunk|d
(5 rows)
NOTICE: [db_dist_ddl_2]:
SELECT relname, relreplident FROM pg_class WHERE relname = 'disttable' ORDER BY relname
NOTICE: [db_dist_ddl_2]:
relname |relreplident
---------+------------
disttable|d
(1 row)
NOTICE: [db_dist_ddl_2]:
SELECT relname, relreplident FROM show_chunks('disttable') ch INNER JOIN pg_class c ON (ch = c.oid) ORDER BY relname
NOTICE: [db_dist_ddl_2]:
relname |relreplident
---------------------+------------
_dist_hyper_1_1_chunk|d
_dist_hyper_1_2_chunk|d
_dist_hyper_1_3_chunk|d
_dist_hyper_1_4_chunk|d
_dist_hyper_1_5_chunk|d
(5 rows)
NOTICE: [db_dist_ddl_3]:
SELECT relname, relreplident FROM pg_class WHERE relname = 'disttable' ORDER BY relname
NOTICE: [db_dist_ddl_3]:
relname |relreplident
---------+------------
disttable|d
(1 row)
NOTICE: [db_dist_ddl_3]:
SELECT relname, relreplident FROM show_chunks('disttable') ch INNER JOIN pg_class c ON (ch = c.oid) ORDER BY relname
NOTICE: [db_dist_ddl_3]:
relname |relreplident
---------------------+------------
_dist_hyper_1_1_chunk|d
_dist_hyper_1_2_chunk|d
_dist_hyper_1_3_chunk|d
_dist_hyper_1_4_chunk|d
_dist_hyper_1_5_chunk|d
(5 rows)
remote_exec
-------------
(1 row)
ALTER TABLE disttable REPLICA IDENTITY FULL;
SELECT * FROM test.remote_exec(NULL,
$$
SELECT relname, relreplident FROM pg_class WHERE relname = 'disttable' ORDER BY relname;
SELECT relname, relreplident FROM show_chunks('disttable') ch INNER JOIN pg_class c ON (ch = c.oid) ORDER BY relname;
$$);
NOTICE: [db_dist_ddl_1]:
SELECT relname, relreplident FROM pg_class WHERE relname = 'disttable' ORDER BY relname
NOTICE: [db_dist_ddl_1]:
relname |relreplident
---------+------------
disttable|f
(1 row)
NOTICE: [db_dist_ddl_1]:
SELECT relname, relreplident FROM show_chunks('disttable') ch INNER JOIN pg_class c ON (ch = c.oid) ORDER BY relname
NOTICE: [db_dist_ddl_1]:
relname |relreplident
---------------------+------------
_dist_hyper_1_1_chunk|f
_dist_hyper_1_2_chunk|f
_dist_hyper_1_3_chunk|f
_dist_hyper_1_4_chunk|f
_dist_hyper_1_5_chunk|f
(5 rows)
NOTICE: [db_dist_ddl_2]:
SELECT relname, relreplident FROM pg_class WHERE relname = 'disttable' ORDER BY relname
NOTICE: [db_dist_ddl_2]:
relname |relreplident
---------+------------
disttable|f
(1 row)
NOTICE: [db_dist_ddl_2]:
SELECT relname, relreplident FROM show_chunks('disttable') ch INNER JOIN pg_class c ON (ch = c.oid) ORDER BY relname
NOTICE: [db_dist_ddl_2]:
relname |relreplident
---------------------+------------
_dist_hyper_1_1_chunk|f
_dist_hyper_1_2_chunk|f
_dist_hyper_1_3_chunk|f
_dist_hyper_1_4_chunk|f
_dist_hyper_1_5_chunk|f
(5 rows)
NOTICE: [db_dist_ddl_3]:
SELECT relname, relreplident FROM pg_class WHERE relname = 'disttable' ORDER BY relname
NOTICE: [db_dist_ddl_3]:
relname |relreplident
---------+------------
disttable|f
(1 row)
NOTICE: [db_dist_ddl_3]:
SELECT relname, relreplident FROM show_chunks('disttable') ch INNER JOIN pg_class c ON (ch = c.oid) ORDER BY relname
NOTICE: [db_dist_ddl_3]:
relname |relreplident
---------------------+------------
_dist_hyper_1_1_chunk|f
_dist_hyper_1_2_chunk|f
_dist_hyper_1_3_chunk|f
_dist_hyper_1_4_chunk|f
_dist_hyper_1_5_chunk|f
(5 rows)
remote_exec
-------------
(1 row)
-- Rename column
ALTER TABLE disttable RENAME COLUMN description TO descr;
SELECT * FROM test.show_columns('disttable')

View File

@ -194,6 +194,21 @@ INSERT INTO disttable VALUES
SELECT * FROM show_chunks('disttable');
-- Replica identity
SELECT * FROM test.remote_exec(NULL,
$$
SELECT relname, relreplident FROM pg_class WHERE relname = 'disttable' ORDER BY relname;
SELECT relname, relreplident FROM show_chunks('disttable') ch INNER JOIN pg_class c ON (ch = c.oid) ORDER BY relname;
$$);
ALTER TABLE disttable REPLICA IDENTITY FULL;
SELECT * FROM test.remote_exec(NULL,
$$
SELECT relname, relreplident FROM pg_class WHERE relname = 'disttable' ORDER BY relname;
SELECT relname, relreplident FROM show_chunks('disttable') ch INNER JOIN pg_class c ON (ch = c.oid) ORDER BY relname;
$$);
-- Rename column
ALTER TABLE disttable RENAME COLUMN description TO descr;
SELECT * FROM test.show_columns('disttable')