index 298de74af43dbe01fb087f4b3ba0b245c573bcee..646ab74d04943d45201dd47bb4285fff95814ea6 100644 (file)
@@ -7823,6 +7823,16 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l
</para></entry>
</row>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>subskiplsn</structfield> <type>pg_lsn</type>
+ </para>
+ <para>
+ Finish LSN of the transaction whose changes are to be skipped, if a valid
+ LSN; otherwise <literal>0/0</literal>.
+ </para></entry>
+ </row>
+
<row>
<entry role="catalog_table_entry"><para role="column_definition">
<structfield>subname</structfield> <type>name</type>
@@ -7893,16 +7903,6 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l
</para></entry>
</row>
- <row>
- <entry role="catalog_table_entry"><para role="column_definition">
- <structfield>subskiplsn</structfield> <type>pg_lsn</type>
- </para>
- <para>
- Finish LSN of the transaction whose changes are to be skipped, if a valid
- LSN; otherwise <literal>0/0</literal>.
- </para></entry>
- </row>
-
<row>
<entry role="catalog_table_entry"><para role="column_definition">
<structfield>subconninfo</structfield> <type>text</type>
index 0ff0982f7b2ee9d6c195934eba17fed404848bca..add51caadf2a1745b125d55001f5f1aba2d31db5 100644 (file)
@@ -63,6 +63,7 @@ GetSubscription(Oid subid, bool missing_ok)
sub = (Subscription *) palloc(sizeof(Subscription));
sub->oid = subid;
sub->dbid = subform->subdbid;
+ sub->skiplsn = subform->subskiplsn;
sub->name = pstrdup(NameStr(subform->subname));
sub->owner = subform->subowner;
sub->enabled = subform->subenabled;
@@ -70,7 +71,6 @@ GetSubscription(Oid subid, bool missing_ok)
sub->stream = subform->substream;
sub->twophasestate = subform->subtwophasestate;
sub->disableonerr = subform->subdisableonerr;
- sub->skiplsn = subform->subskiplsn;
/* Get conninfo */
datum = SysCacheGetAttr(SUBSCRIPTIONOID,
index 9eaa51df290564d5196bb18037d4ef7c154708e5..e701d1c676a44fad7856693571b8503381e4bc72 100644 (file)
@@ -1285,8 +1285,8 @@ REVOKE ALL ON pg_replication_origin_status FROM public;
-- All columns of pg_subscription except subconninfo are publicly readable.
REVOKE ALL ON pg_subscription FROM public;
-GRANT SELECT (oid, subdbid, subname, subowner, subenabled, subbinary,
- substream, subtwophasestate, subdisableonerr, subskiplsn, subslotname,
+GRANT SELECT (oid, subdbid, subskiplsn, subname, subowner, subenabled,
+ subbinary, substream, subtwophasestate, subdisableonerr, subslotname,
subsynccommit, subpublications)
ON pg_subscription TO public;
index 83192dbd51f05fe42bedc79f8094bee7599236ab..057ab4b6a3f300130234e5d1a19f2568ee5aa7d2 100644 (file)
@@ -596,6 +596,7 @@ CreateSubscription(ParseState *pstate, CreateSubscriptionStmt *stmt,
Anum_pg_subscription_oid);
values[Anum_pg_subscription_oid - 1] = ObjectIdGetDatum(subid);
values[Anum_pg_subscription_subdbid - 1] = ObjectIdGetDatum(MyDatabaseId);
+ values[Anum_pg_subscription_subskiplsn - 1] = LSNGetDatum(InvalidXLogRecPtr);
values[Anum_pg_subscription_subname - 1] =
DirectFunctionCall1(namein, CStringGetDatum(stmt->subname));
values[Anum_pg_subscription_subowner - 1] = ObjectIdGetDatum(owner);
@@ -607,7 +608,6 @@ CreateSubscription(ParseState *pstate, CreateSubscriptionStmt *stmt,
LOGICALREP_TWOPHASE_STATE_PENDING :
LOGICALREP_TWOPHASE_STATE_DISABLED);
values[Anum_pg_subscription_subdisableonerr - 1] = BoolGetDatum(opts.disableonerr);
- values[Anum_pg_subscription_subskiplsn - 1] = LSNGetDatum(InvalidXLogRecPtr);
values[Anum_pg_subscription_subconninfo - 1] =
CStringGetTextDatum(conninfo);
if (opts.slot_name)
index 9cf5ffb6ff089a39b2815a24e35a2ee2b667685e..b6742b12c5269d4827b036255eef199697c41cfd 100644 (file)
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 202204062
+#define CATALOG_VERSION_NO 202204071
#endif
index 599c2e4422ef285be07c7bac27e32b60a6b533cc..f006a92612a24d2221f01165aaca065bc1c7ca4e 100644 (file)
@@ -54,6 +54,10 @@ CATALOG(pg_subscription,6100,SubscriptionRelationId) BKI_SHARED_RELATION BKI_ROW
Oid subdbid BKI_LOOKUP(pg_database); /* Database the
* subscription is in. */
+
+ XLogRecPtr subskiplsn; /* All changes finished at this LSN are
+ * skipped */
+
NameData subname; /* Name of the subscription */
Oid subowner BKI_LOOKUP(pg_authid); /* Owner of the subscription */
@@ -71,9 +75,6 @@ CATALOG(pg_subscription,6100,SubscriptionRelationId) BKI_SHARED_RELATION BKI_ROW
bool subdisableonerr; /* True if a worker error should cause the
* subscription to be disabled */
- XLogRecPtr subskiplsn; /* All changes finished at this LSN are
- * skipped */
-
#ifdef CATALOG_VARLEN /* variable-length fields start here */
/* Connection string to the publisher */
text subconninfo BKI_FORCE_NOT_NULL;
Oid oid; /* Oid of the subscription */
Oid dbid; /* Oid of the database which subscription is
* in */
+ XLogRecPtr skiplsn; /* All changes finished at this LSN are
+ * skipped */
char *name; /* Name of the subscription */
Oid owner; /* Oid of the subscription owner */
bool enabled; /* Indicates if the subscription is enabled */
bool disableonerr; /* Indicates if the subscription should be
* automatically disabled if a worker error
* occurs */
- XLogRecPtr skiplsn; /* All changes finished at this LSN are
- * skipped */
char *conninfo; /* Connection string to the publisher */
char *slotname; /* Name of the replication slot */
char *synccommit; /* Synchronous commit setting for worker */
index 8370c1561cca9333efb32409391dadb4c676d01f..a2faefb4c02b27f00893822892d4d2ac4cc87ea3 100644 (file)
---------+---------
(0 rows)
+--
+-- When ALIGNOF_DOUBLE==4 (e.g. AIX), the C ABI may impose 8-byte alignment on
+-- some of the C types that correspond to TYPALIGN_DOUBLE SQL types. To ensure
+-- catalog C struct layout matches catalog tuple layout, arrange for the tuple
+-- offset of each fixed-width, attalign='d' catalog column to be divisible by 8
+-- unconditionally. Keep such columns before the first NameData column of the
+-- catalog, since packagers can override NAMEDATALEN to an odd number.
+--
+WITH check_columns AS (
+ SELECT relname, attname,
+ array(
+ SELECT t.oid
+ FROM pg_type t JOIN pg_attribute pa ON t.oid = pa.atttypid
+ WHERE pa.attrelid = a.attrelid AND
+ pa.attnum > 0 AND pa.attnum <= a.attnum
+ ORDER BY pa.attnum) AS coltypes
+ FROM pg_attribute a JOIN pg_class c ON c.oid = attrelid
+ JOIN pg_namespace n ON c.relnamespace = n.oid
+ WHERE attalign = 'd' AND relkind = 'r' AND
+ attnotnull AND attlen <> -1 AND n.nspname = 'pg_catalog'
+)
+SELECT relname, attname, coltypes, get_column_offset(coltypes)
+ FROM check_columns
+ WHERE get_column_offset(coltypes) % 8 != 0 OR
+ 'name'::regtype::oid = ANY(coltypes);
+ relname | attname | coltypes | get_column_offset
+---------+---------+----------+-------------------
+(0 rows)
+
index a9d0de3deac87a41e13a8dc9a27d4d289762b108..8b8ba7d778b4b45e33cb5dec89e47e61739efbaa 100644 (file)
RETURNS trigger
AS :'regresslib'
LANGUAGE C;
+CREATE FUNCTION get_column_offset (oid[])
+ RETURNS int
+ AS :'regresslib'
+ LANGUAGE C STRICT STABLE PARALLEL SAFE;
-- Use hand-rolled hash functions and operator classes to get predictable
-- result on different machines. The hash function for int4 simply returns
-- the sum of the values passed to it and the one for text returns the length
index 0802fb9136a1bb1aab1eb35a1a5851861e0e3c56..8b0c2d9d68401b07286b6ba5a0f5d81ef9535049 100644 (file)
#include "storage/spin.h"
#include "utils/builtins.h"
#include "utils/geo_decls.h"
+#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/rel.h"
#include "utils/typcache.h"
PG_RETURN_BOOL(IsBinaryCoercible(srctype, targettype));
}
+
+/*
+ * Return the column offset of the last data in the given array of
+ * data types. The input data types must be fixed-length data types.
+ */
+PG_FUNCTION_INFO_V1(get_column_offset);
+Datum
+get_column_offset(PG_FUNCTION_ARGS)
+{
+ ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
+ Oid *type_oids;
+ int ntypes;
+ int column_offset = 0;
+
+ if (ARR_HASNULL(ta) && array_contains_nulls(ta))
+ elog(ERROR, "argument must not contain nulls");
+
+ if (ARR_NDIM(ta) > 1)
+ elog(ERROR, "argument must be empty or one-dimensional array");
+
+ type_oids = (Oid *) ARR_DATA_PTR(ta);
+ ntypes = ArrayGetNItems(ARR_NDIM(ta), ARR_DIMS(ta));
+ for (int i = 0; i < ntypes; i++)
+ {
+ Oid typeoid = type_oids[i];
+ int16 typlen;
+ bool typbyval;
+ char typalign;
+
+ get_typlenbyvalalign(typeoid, &typlen, &typbyval, &typalign);
+
+ /* the data type must be fixed-length */
+ if (!(typbyval || (typlen > 0)))
+ elog(ERROR, "type %u is not fixed-length data type", typeoid);
+
+ column_offset = att_align_nominal(column_offset, typalign);
+
+ /* not include the last type size */
+ if (i != (ntypes - 1))
+ column_offset += typlen;
+ }
+
+ PG_RETURN_INT32(column_offset);
+}
index 162e5324b5d852bc8475976fdd018e21b4f550cb..c70ff781fafe9a0e316609ccf9e4576208ec740e 100644 (file)
FROM pg_class
WHERE relkind IN ('v', 'c', 'f', 'p', 'I')
AND relfilenode <> 0;
+
+--
+-- When ALIGNOF_DOUBLE==4 (e.g. AIX), the C ABI may impose 8-byte alignment on
+-- some of the C types that correspond to TYPALIGN_DOUBLE SQL types. To ensure
+-- catalog C struct layout matches catalog tuple layout, arrange for the tuple
+-- offset of each fixed-width, attalign='d' catalog column to be divisible by 8
+-- unconditionally. Keep such columns before the first NameData column of the
+-- catalog, since packagers can override NAMEDATALEN to an odd number.
+--
+WITH check_columns AS (
+ SELECT relname, attname,
+ array(
+ SELECT t.oid
+ FROM pg_type t JOIN pg_attribute pa ON t.oid = pa.atttypid
+ WHERE pa.attrelid = a.attrelid AND
+ pa.attnum > 0 AND pa.attnum <= a.attnum
+ ORDER BY pa.attnum) AS coltypes
+ FROM pg_attribute a JOIN pg_class c ON c.oid = attrelid
+ JOIN pg_namespace n ON c.relnamespace = n.oid
+ WHERE attalign = 'd' AND relkind = 'r' AND
+ attnotnull AND attlen <> -1 AND n.nspname = 'pg_catalog'
+)
+SELECT relname, attname, coltypes, get_column_offset(coltypes)
+ FROM check_columns
+ WHERE get_column_offset(coltypes) % 8 != 0 OR
+ 'name'::regtype::oid = ANY(coltypes);
index 1f3f2f172411deadc15519425fb93691139c0ba9..fbceb8cb464b035f7706e9de8649cc71a01352ba 100644 (file)
AS :'regresslib'
LANGUAGE C;
+CREATE FUNCTION get_column_offset (oid[])
+ RETURNS int
+ AS :'regresslib'
+ LANGUAGE C STRICT STABLE PARALLEL SAFE;
+
-- Use hand-rolled hash functions and operator classes to get predictable
-- result on different machines. The hash function for int4 simply returns
-- the sum of the values passed to it and the one for text returns the length