mirror of
https://github.com/postgres/postgres.git
synced 2025-07-31 22:04:40 +03:00
Tweak publication fetching in psql
Viewing a table with \d in psql also shows the publications at table is in. If a publication is concurrently dropped, this shows an error, because the view pg_publication_tables internally uses pg_get_publication_tables(), which uses a catalog snapshot. This can be particularly annoying if a for-all-tables publication is concurrently dropped. To avoid that, write the query in psql differently. Expose the function pg_relation_is_publishable() to SQL and write the query using that. That still has a risk of being affected by concurrent catalog changes, but in this case it would be a table drop that causes problems, and then the psql \d command wouldn't be interesting anymore anyway. Reported-by: Tom Lane <tgl@sss.pgh.pa.us>
This commit is contained in:
@ -105,6 +105,30 @@ is_publishable_class(Oid relid, Form_pg_class reltuple)
|
|||||||
relid >= FirstNormalObjectId;
|
relid >= FirstNormalObjectId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SQL-callable variant of the above
|
||||||
|
*
|
||||||
|
* This returns null when the relation does not exist. This is intended to be
|
||||||
|
* used for example in psql to avoid gratuitous errors when there are
|
||||||
|
* concurrent catalog changes.
|
||||||
|
*/
|
||||||
|
Datum
|
||||||
|
pg_relation_is_publishable(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
Oid relid = PG_GETARG_OID(0);
|
||||||
|
HeapTuple tuple;
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
|
||||||
|
if (!tuple)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
result = is_publishable_class(relid, (Form_pg_class) GETSTRUCT(tuple));
|
||||||
|
ReleaseSysCache(tuple);
|
||||||
|
PG_RETURN_BOOL(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Insert new publication / relation mapping.
|
* Insert new publication / relation mapping.
|
||||||
*/
|
*/
|
||||||
|
@ -2536,12 +2536,16 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
if (pset.sversion >= 100000)
|
if (pset.sversion >= 100000)
|
||||||
{
|
{
|
||||||
printfPQExpBuffer(&buf,
|
printfPQExpBuffer(&buf,
|
||||||
"SELECT pub.pubname\n"
|
"SELECT pubname\n"
|
||||||
" FROM pg_catalog.pg_publication pub,\n"
|
"FROM pg_catalog.pg_publication p\n"
|
||||||
" pg_catalog.pg_get_publication_tables(pub.pubname)\n"
|
"JOIN pg_catalog.pg_publication_rel pr ON p.oid = pr.prpubid\n"
|
||||||
"WHERE relid = '%s'\n"
|
"WHERE pr.prrelid = '%s'\n"
|
||||||
|
"UNION ALL\n"
|
||||||
|
"SELECT pubname\n"
|
||||||
|
"FROM pg_catalog.pg_publication p\n"
|
||||||
|
"WHERE p.puballtables AND pg_relation_is_publishable('%s')\n"
|
||||||
"ORDER BY 1;",
|
"ORDER BY 1;",
|
||||||
oid);
|
oid, oid);
|
||||||
|
|
||||||
result = PSQLexec(buf.data);
|
result = PSQLexec(buf.data);
|
||||||
if (!result)
|
if (!result)
|
||||||
|
@ -53,6 +53,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 201706201
|
#define CATALOG_VERSION_NO 201706202
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -5436,6 +5436,8 @@ DESCR("get progress for all replication origins");
|
|||||||
/* publications */
|
/* publications */
|
||||||
DATA(insert OID = 6119 ( pg_get_publication_tables PGNSP PGUID 12 1 1000 0 0 f f f f t t s s 1 0 26 "25" "{25,26}" "{i,o}" "{pubname,relid}" _null_ _null_ pg_get_publication_tables _null_ _null_ _null_ ));
|
DATA(insert OID = 6119 ( pg_get_publication_tables PGNSP PGUID 12 1 1000 0 0 f f f f t t s s 1 0 26 "25" "{25,26}" "{i,o}" "{pubname,relid}" _null_ _null_ pg_get_publication_tables _null_ _null_ _null_ ));
|
||||||
DESCR("get OIDs of tables in a publication");
|
DESCR("get OIDs of tables in a publication");
|
||||||
|
DATA(insert OID = 6121 ( pg_relation_is_publishable PGNSP PGUID 12 1 0 0 0 f f f f t f s s 1 0 16 "2205" _null_ _null_ _null_ _null_ _null_ pg_relation_is_publishable _null_ _null_ _null_ ));
|
||||||
|
DESCR("returns whether a relation can be part of a publication");
|
||||||
|
|
||||||
/* rls */
|
/* rls */
|
||||||
DATA(insert OID = 3298 ( row_security_active PGNSP PGUID 12 1 0 0 0 f f f f t f s s 1 0 16 "26" _null_ _null_ _null_ _null_ _null_ row_security_active _null_ _null_ _null_ ));
|
DATA(insert OID = 3298 ( row_security_active PGNSP PGUID 12 1 0 0 0 f f f f t f s s 1 0 16 "26" _null_ _null_ _null_ _null_ _null_ row_security_active _null_ _null_ _null_ ));
|
||||||
|
Reference in New Issue
Block a user