]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Improve subscriber's error message for wrong publication relkind.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 15 Feb 2022 17:21:28 +0000 (12:21 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 15 Feb 2022 17:21:28 +0000 (12:21 -0500)
Pre-v13 versions only support logical replication from plain tables,
while v13 and later also allow partitioned tables to be published.
If you tried to subscribe an older server to such a publication,
you got "table XXX not found on publisher", which is pretty
unhelpful/confusing.  Arrange to deliver a more on-point error
message.  As commit c314c147c did in v13, remove the relkind check
from the query WHERE clause altogether, so that "not there"
is distinguishable from "wrong relkind".

Per report from Radoslav Nedyalkov.  Patch v10-v12.

Discussion: https://postgr.es/m/2952568.1644876730@sss.pgh.pa.us

src/backend/replication/logical/tablesync.c

index 2db88dc41a0cb2caff31717b568e496b496e3700..d87c8324c3a9ef328b5d28ad7916c7a14d0c6d1b 100644 (file)
@@ -646,9 +646,10 @@ fetch_remote_table_info(char *nspname, char *relname,
        WalRcvExecResult *res;
        StringInfoData cmd;
        TupleTableSlot *slot;
-       Oid                     tableRow[2] = {OIDOID, CHAROID};
+       Oid                     tableRow[3] = {OIDOID, CHAROID, CHAROID};
        Oid                     attrRow[4] = {TEXTOID, OIDOID, INT4OID, BOOLOID};
        bool            isnull;
+       char            relkind;
        int                     natt;
 
        lrel->nspname = nspname;
@@ -656,13 +657,12 @@ fetch_remote_table_info(char *nspname, char *relname,
 
        /* First fetch Oid and replica identity. */
        initStringInfo(&cmd);
-       appendStringInfo(&cmd, "SELECT c.oid, c.relreplident"
+       appendStringInfo(&cmd, "SELECT c.oid, c.relreplident, c.relkind"
                                         "  FROM pg_catalog.pg_class c"
                                         "  INNER JOIN pg_catalog.pg_namespace n"
                                         "        ON (c.relnamespace = n.oid)"
                                         " WHERE n.nspname = %s"
-                                        "   AND c.relname = %s"
-                                        "   AND c.relkind = 'r'",
+                                        "   AND c.relname = %s",
                                         quote_literal_cstr(nspname),
                                         quote_literal_cstr(relname));
        res = walrcv_exec(LogRepWorkerWalRcvConn, cmd.data,
@@ -683,6 +683,19 @@ fetch_remote_table_info(char *nspname, char *relname,
        Assert(!isnull);
        lrel->replident = DatumGetChar(slot_getattr(slot, 2, &isnull));
        Assert(!isnull);
+       relkind = DatumGetChar(slot_getattr(slot, 3, &isnull));
+       Assert(!isnull);
+
+       /*
+        * Newer PG versions allow things that aren't plain tables to appear in
+        * publications.  We don't handle that in this version, but try to provide
+        * a useful error message.
+        */
+       if (relkind != RELKIND_RELATION)
+               ereport(ERROR,
+                               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                                errmsg("logical replication source relation \"%s.%s\" is not a table",
+                                               nspname, relname)));
 
        ExecDropSingleTupleTableSlot(slot);
        walrcv_clear_result(res);