]> granicus.if.org Git - postgresql/commitdiff
Add a new reloption, user_catalog_table.
authorRobert Haas <rhaas@postgresql.org>
Wed, 11 Dec 2013 00:17:34 +0000 (19:17 -0500)
committerRobert Haas <rhaas@postgresql.org>
Wed, 11 Dec 2013 00:17:34 +0000 (19:17 -0500)
When this reloption is set and wal_level=logical is configured,
we'll record the CIDs stamped by inserts, updates, and deletes to
the table just as we would for an actual catalog table.  This will
allow logical decoding to use historical MVCC snapshots to access
such tables just as they access ordinary catalog tables.

Replication solutions built around the logical decoding machinery
will likely need to set this operation for their configuration
tables; it might also be needed by extensions which perform table
access in their output functions.

Andres Freund, reviewed by myself and others.

src/backend/access/common/reloptions.c
src/backend/commands/tablecmds.c
src/include/utils/rel.h

index b5fd30a4f95933ef414607ca831464065d8cc9d6..31941e99edbd76fb8baf85a6c749fe1194cdb917 100644 (file)
@@ -61,6 +61,14 @@ static relopt_bool boolRelOpts[] =
                },
                true
        },
+       {
+               {
+                       "user_catalog_table",
+                       "Declare a table as an additional catalog table, e.g. for the purpose of logical replication",
+                       RELOPT_KIND_HEAP
+               },
+               false
+       },
        {
                {
                        "fastupdate",
@@ -1166,6 +1174,8 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
                offsetof(StdRdOptions, security_barrier)},
                {"check_option", RELOPT_TYPE_STRING,
                offsetof(StdRdOptions, check_option_offset)},
+               {"user_catalog_table", RELOPT_TYPE_BOOL,
+                offsetof(StdRdOptions, user_catalog_table)}
        };
 
        options = parseRelOptions(reloptions, validate, kind, &numoptions);
index 1d9f29a7b7c18742cc3c2639e20c4ba4bd0763fe..b9cd88d57015416066c7f3db70d9c681708426ff 100644 (file)
@@ -3532,6 +3532,12 @@ ATRewriteTables(List **wqueue, LOCKMODE lockmode)
                                                 errmsg("cannot rewrite system relation \"%s\"",
                                                                RelationGetRelationName(OldHeap))));
 
+                       if (RelationIsUsedAsCatalogTable(OldHeap))
+                               ereport(ERROR,
+                                               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                                                errmsg("cannot rewrite table \"%s\" used as a catalog table",
+                                                               RelationGetRelationName(OldHeap))));
+
                        /*
                         * Don't allow rewrite on temp tables of other backends ... their
                         * local buffer manager is not going to cope.
index ad878cf1a225b61c7fddb7016337cc09214aa8df..383744b3a0c350860dd054b206c5f652535d83b0 100644 (file)
@@ -217,6 +217,7 @@ typedef struct StdRdOptions
        AutoVacOpts autovacuum;         /* autovacuum-related options */
        bool            security_barrier;               /* for views */
        int                     check_option_offset;    /* for views */
+       bool            user_catalog_table;             /* use as an additional catalog relation */
 } StdRdOptions;
 
 #define HEAP_MIN_FILLFACTOR                    10
@@ -285,6 +286,15 @@ typedef struct StdRdOptions
                        ((StdRdOptions *) (relation)->rd_options)->check_option_offset, \
                        "cascaded") == 0 : false)
 
+/*
+ * RelationIsUsedAsCatalogTable
+ *             Returns whether the relation should be treated as a catalog table
+ *      from the pov of logical decoding.
+ */
+#define RelationIsUsedAsCatalogTable(relation) \
+       ((relation)->rd_options ?                               \
+        ((StdRdOptions *) (relation)->rd_options)->user_catalog_table : false)
+
 /*
  * RelationIsValid
  *             True iff relation descriptor is valid.
@@ -462,7 +472,7 @@ typedef struct StdRdOptions
 #define RelationIsAccessibleInLogicalDecoding(relation) \
        (XLogLogicalInfoActive() && \
         RelationNeedsWAL(relation) && \
-        IsCatalogRelation(relation))
+        (IsCatalogRelation(relation) || RelationIsUsedAsCatalogTable(relation)))
 
 /*
  * RelationIsLogicallyLogged
@@ -471,7 +481,9 @@ typedef struct StdRdOptions
  *
  * We don't log information for unlogged tables (since they don't WAL log
  * anyway) and for system tables (their content is hard to make sense of, and
- * it would complicate decoding slightly for little gain).
+ * it would complicate decoding slightly for little gain). Note that we *do*
+ * log information for user defined catalog tables since they presumably are
+ * interesting to the user...
  */
 #define RelationIsLogicallyLogged(relation) \
        (XLogLogicalInfoActive() && \