Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit c314c14

Browse files
committed
Prepare to support non-tables in publications
This by itself doesn't change any functionality but prepares the way for having relations other than base tables in publications. Make arrangements for COPY handling the initial table sync. For non-tables we have to use COPY (SELECT ...) instead of directly copying from the table, but then we have to take care to omit generated columns from the column list. Also, remove a hardcoded reference to relkind = 'r' and rely on the publisher to send only what it can actually publish, which will be correct even in future cross-version scenarios. Reviewed-by: Amit Langote <amitlangote09@gmail.com> Discussion: https://www.postgresql.org/message-id/flat/CA+HiwqH=Y85vRK3mOdjEkqFK+E=ST=eQiHdpj43L=_eJMOOznQ@mail.gmail.com
1 parent 1d253ba commit c314c14

File tree

2 files changed

+28
-9
lines changed

2 files changed

+28
-9
lines changed

src/backend/replication/logical/tablesync.c

+27-9
Original file line numberDiff line numberDiff line change
@@ -639,8 +639,8 @@ fetch_remote_table_info(char *nspname, char *relname,
639639
WalRcvExecResult *res;
640640
StringInfoData cmd;
641641
TupleTableSlot *slot;
642-
Oid tableRow[2] = {OIDOID, CHAROID};
643-
Oid attrRow[4] = {TEXTOID, OIDOID, INT4OID, BOOLOID};
642+
Oid tableRow[] = {OIDOID, CHAROID, CHAROID};
643+
Oid attrRow[] = {TEXTOID, OIDOID, INT4OID, BOOLOID};
644644
bool isnull;
645645
int natt;
646646

@@ -649,16 +649,15 @@ fetch_remote_table_info(char *nspname, char *relname,
649649

650650
/* First fetch Oid and replica identity. */
651651
initStringInfo(&cmd);
652-
appendStringInfo(&cmd, "SELECT c.oid, c.relreplident"
652+
appendStringInfo(&cmd, "SELECT c.oid, c.relreplident, c.relkind"
653653
" FROM pg_catalog.pg_class c"
654654
" INNER JOIN pg_catalog.pg_namespace n"
655655
" ON (c.relnamespace = n.oid)"
656656
" WHERE n.nspname = %s"
657-
" AND c.relname = %s"
658-
" AND c.relkind = 'r'",
657+
" AND c.relname = %s",
659658
quote_literal_cstr(nspname),
660659
quote_literal_cstr(relname));
661-
res = walrcv_exec(wrconn, cmd.data, 2, tableRow);
660+
res = walrcv_exec(wrconn, cmd.data, lengthof(tableRow), tableRow);
662661

663662
if (res->status != WALRCV_OK_TUPLES)
664663
ereport(ERROR,
@@ -675,6 +674,8 @@ fetch_remote_table_info(char *nspname, char *relname,
675674
Assert(!isnull);
676675
lrel->replident = DatumGetChar(slot_getattr(slot, 2, &isnull));
677676
Assert(!isnull);
677+
lrel->relkind = DatumGetChar(slot_getattr(slot, 3, &isnull));
678+
Assert(!isnull);
678679

679680
ExecDropSingleTupleTableSlot(slot);
680681
walrcv_clear_result(res);
@@ -696,7 +697,7 @@ fetch_remote_table_info(char *nspname, char *relname,
696697
lrel->remoteid,
697698
(walrcv_server_version(wrconn) >= 120000 ? "AND a.attgenerated = ''" : ""),
698699
lrel->remoteid);
699-
res = walrcv_exec(wrconn, cmd.data, 4, attrRow);
700+
res = walrcv_exec(wrconn, cmd.data, lengthof(attrRow), attrRow);
700701

701702
if (res->status != WALRCV_OK_TUPLES)
702703
ereport(ERROR,
@@ -765,8 +766,25 @@ copy_table(Relation rel)
765766

766767
/* Start copy on the publisher. */
767768
initStringInfo(&cmd);
768-
appendStringInfo(&cmd, "COPY %s TO STDOUT",
769-
quote_qualified_identifier(lrel.nspname, lrel.relname));
769+
if (lrel.relkind == RELKIND_RELATION)
770+
appendStringInfo(&cmd, "COPY %s TO STDOUT",
771+
quote_qualified_identifier(lrel.nspname, lrel.relname));
772+
else
773+
{
774+
/*
775+
* For non-tables, we need to do COPY (SELECT ...), but we can't just
776+
* do SELECT * because we need to not copy generated columns.
777+
*/
778+
appendStringInfo(&cmd, "COPY (SELECT ");
779+
for (int i = 0; i < lrel.natts; i++)
780+
{
781+
appendStringInfoString(&cmd, quote_identifier(lrel.attnames[i]));
782+
if (i < lrel.natts - 1)
783+
appendStringInfoString(&cmd, ", ");
784+
}
785+
appendStringInfo(&cmd, " FROM %s) TO STDOUT",
786+
quote_qualified_identifier(lrel.nspname, lrel.relname));
787+
}
770788
res = walrcv_exec(wrconn, cmd.data, 0, NULL);
771789
pfree(cmd.data);
772790
if (res->status != WALRCV_OK_COPY_OUT)

src/include/replication/logicalproto.h

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ typedef struct LogicalRepRelation
4949
char **attnames; /* column names */
5050
Oid *atttyps; /* column types */
5151
char replident; /* replica identity */
52+
char relkind; /* remote relation kind */
5253
Bitmapset *attkeys; /* Bitmap of key columns */
5354
} LogicalRepRelation;
5455

0 commit comments

Comments
 (0)