Commit 0fa0b487 authored by Tom Lane's avatar Tom Lane

Correctly mark pg_subscription_rel.srsublsn as nullable.

The code has always set this column to NULL when it's not valid,
but the catalog header's description failed to reflect that,
as did the SGML docs, as did some of the code.  To prevent future
coding errors of the same ilk, let's hide the field from C code
as though it were variable-length (which, in a sense, it is).

As with commit 72eab84a, we can only fix this cleanly in HEAD
and v13; the problem extends further back but we'll need some
klugery in the released branches.

Discussion: https://postgr.es/m/367660.1595202498@sss.pgh.pa.us
parent d5daae47
...@@ -7631,7 +7631,9 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l ...@@ -7631,7 +7631,9 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l
<structfield>srsublsn</structfield> <type>pg_lsn</type> <structfield>srsublsn</structfield> <type>pg_lsn</type>
</para> </para>
<para> <para>
End LSN for <literal>s</literal> and <literal>r</literal> states. Remote LSN of the state change used for synchronization coordination
when in <literal>s</literal> or <literal>r</literal> states,
otherwise null
</para></entry> </para></entry>
</row> </row>
</tbody> </tbody>
......
...@@ -452,13 +452,20 @@ GetSubscriptionRelations(Oid subid) ...@@ -452,13 +452,20 @@ GetSubscriptionRelations(Oid subid)
{ {
Form_pg_subscription_rel subrel; Form_pg_subscription_rel subrel;
SubscriptionRelState *relstate; SubscriptionRelState *relstate;
Datum d;
bool isnull;
subrel = (Form_pg_subscription_rel) GETSTRUCT(tup); subrel = (Form_pg_subscription_rel) GETSTRUCT(tup);
relstate = (SubscriptionRelState *) palloc(sizeof(SubscriptionRelState)); relstate = (SubscriptionRelState *) palloc(sizeof(SubscriptionRelState));
relstate->relid = subrel->srrelid; relstate->relid = subrel->srrelid;
relstate->state = subrel->srsubstate; relstate->state = subrel->srsubstate;
relstate->lsn = subrel->srsublsn; d = SysCacheGetAttr(SUBSCRIPTIONRELMAP, tup,
Anum_pg_subscription_rel_srsublsn, &isnull);
if (isnull)
relstate->lsn = InvalidXLogRecPtr;
else
relstate->lsn = DatumGetLSN(d);
res = lappend(res, relstate); res = lappend(res, relstate);
} }
...@@ -504,13 +511,20 @@ GetSubscriptionNotReadyRelations(Oid subid) ...@@ -504,13 +511,20 @@ GetSubscriptionNotReadyRelations(Oid subid)
{ {
Form_pg_subscription_rel subrel; Form_pg_subscription_rel subrel;
SubscriptionRelState *relstate; SubscriptionRelState *relstate;
Datum d;
bool isnull;
subrel = (Form_pg_subscription_rel) GETSTRUCT(tup); subrel = (Form_pg_subscription_rel) GETSTRUCT(tup);
relstate = (SubscriptionRelState *) palloc(sizeof(SubscriptionRelState)); relstate = (SubscriptionRelState *) palloc(sizeof(SubscriptionRelState));
relstate->relid = subrel->srrelid; relstate->relid = subrel->srrelid;
relstate->state = subrel->srsubstate; relstate->state = subrel->srsubstate;
relstate->lsn = subrel->srsublsn; d = SysCacheGetAttr(SUBSCRIPTIONRELMAP, tup,
Anum_pg_subscription_rel_srsublsn, &isnull);
if (isnull)
relstate->lsn = InvalidXLogRecPtr;
else
relstate->lsn = DatumGetLSN(d);
res = lappend(res, relstate); res = lappend(res, relstate);
} }
......
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 202007192 #define CATALOG_VERSION_NO 202007202
#endif #endif
...@@ -33,8 +33,18 @@ CATALOG(pg_subscription_rel,6102,SubscriptionRelRelationId) ...@@ -33,8 +33,18 @@ CATALOG(pg_subscription_rel,6102,SubscriptionRelRelationId)
Oid srsubid; /* Oid of subscription */ Oid srsubid; /* Oid of subscription */
Oid srrelid; /* Oid of relation */ Oid srrelid; /* Oid of relation */
char srsubstate; /* state of the relation in subscription */ char srsubstate; /* state of the relation in subscription */
XLogRecPtr srsublsn; /* remote lsn of the state change used for
* synchronization coordination */ /*
* Although srsublsn is a fixed-width type, it is allowed to be NULL, so
* we prevent direct C code access to it just as for a varlena field.
*/
#ifdef CATALOG_VARLEN /* variable-length fields start here */
XLogRecPtr srsublsn BKI_FORCE_NULL; /* remote LSN of the state change
* used for synchronization
* coordination, or NULL if not
* valid */
#endif
} FormData_pg_subscription_rel; } FormData_pg_subscription_rel;
typedef FormData_pg_subscription_rel *Form_pg_subscription_rel; typedef FormData_pg_subscription_rel *Form_pg_subscription_rel;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment