mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Release cache tuple when no longer needed
There was a small buglet in commit 52e4f0cd47
whereby a tuple acquired
from cache was not released, giving rise to WARNING messages; fix that.
While at it, restructure the code a bit on stylistic grounds.
Author: Hou zj <houzj.fnst@fujitsu.com>
Reported-by: Peter Smith <smithpb2250@gmail.com>
Reviewed-by: Amit Kapila <amit.kapila16@gmail.com>
Discussion: https://postgr.es/m/CAHut+PvKTyhTBtYCQsP6Ph7=o-oWRSX+v+PXXLXp81-o2bazig@mail.gmail.com
This commit is contained in:
@ -925,8 +925,9 @@ AlterPublicationOptions(ParseState *pstate, AlterPublicationStmt *stmt,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* If the publication doesn't publish changes via the root partitioned
|
* If the publication doesn't publish changes via the root partitioned
|
||||||
* table, the partition's row filter and column list will be used. So disallow
|
* table, the partition's row filter and column list will be used. So
|
||||||
* using WHERE clause and column lists on partitioned table in this case.
|
* disallow using WHERE clause and column lists on partitioned table in
|
||||||
|
* this case.
|
||||||
*/
|
*/
|
||||||
if (!pubform->puballtables && publish_via_partition_root_given &&
|
if (!pubform->puballtables && publish_via_partition_root_given &&
|
||||||
!publish_via_partition_root)
|
!publish_via_partition_root)
|
||||||
@ -945,60 +946,60 @@ AlterPublicationOptions(ParseState *pstate, AlterPublicationStmt *stmt,
|
|||||||
|
|
||||||
foreach(lc, root_relids)
|
foreach(lc, root_relids)
|
||||||
{
|
{
|
||||||
HeapTuple rftuple;
|
|
||||||
Oid relid = lfirst_oid(lc);
|
Oid relid = lfirst_oid(lc);
|
||||||
bool has_column_list;
|
HeapTuple rftuple;
|
||||||
bool has_row_filter;
|
char relkind;
|
||||||
|
char *relname;
|
||||||
|
bool has_rowfilter;
|
||||||
|
bool has_collist;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Beware: we don't have lock on the relations, so cope silently
|
||||||
|
* with the cache lookups returning NULL.
|
||||||
|
*/
|
||||||
|
|
||||||
rftuple = SearchSysCache2(PUBLICATIONRELMAP,
|
rftuple = SearchSysCache2(PUBLICATIONRELMAP,
|
||||||
ObjectIdGetDatum(relid),
|
ObjectIdGetDatum(relid),
|
||||||
ObjectIdGetDatum(pubform->oid));
|
ObjectIdGetDatum(pubform->oid));
|
||||||
|
if (!HeapTupleIsValid(rftuple))
|
||||||
has_row_filter
|
continue;
|
||||||
= !heap_attisnull(rftuple, Anum_pg_publication_rel_prqual, NULL);
|
has_rowfilter = !heap_attisnull(rftuple, Anum_pg_publication_rel_prqual, NULL);
|
||||||
|
has_collist = !heap_attisnull(rftuple, Anum_pg_publication_rel_prattrs, NULL);
|
||||||
has_column_list
|
if (!has_rowfilter && !has_collist)
|
||||||
= !heap_attisnull(rftuple, Anum_pg_publication_rel_prattrs, NULL);
|
|
||||||
|
|
||||||
if (HeapTupleIsValid(rftuple) &&
|
|
||||||
(has_row_filter || has_column_list))
|
|
||||||
{
|
{
|
||||||
HeapTuple tuple;
|
|
||||||
|
|
||||||
tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
|
|
||||||
if (HeapTupleIsValid(tuple))
|
|
||||||
{
|
|
||||||
Form_pg_class relform = (Form_pg_class) GETSTRUCT(tuple);
|
|
||||||
|
|
||||||
if ((relform->relkind == RELKIND_PARTITIONED_TABLE) &&
|
|
||||||
has_row_filter)
|
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
||||||
errmsg("cannot set %s for publication \"%s\"",
|
|
||||||
"publish_via_partition_root = false",
|
|
||||||
stmt->pubname),
|
|
||||||
errdetail("The publication contains a WHERE clause for a partitioned table \"%s\" "
|
|
||||||
"which is not allowed when %s is false.",
|
|
||||||
NameStr(relform->relname),
|
|
||||||
"publish_via_partition_root")));
|
|
||||||
|
|
||||||
if ((relform->relkind == RELKIND_PARTITIONED_TABLE) &&
|
|
||||||
has_column_list)
|
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
|
||||||
errmsg("cannot set %s for publication \"%s\"",
|
|
||||||
"publish_via_partition_root = false",
|
|
||||||
stmt->pubname),
|
|
||||||
errdetail("The publication contains a column list for a partitioned table \"%s\" "
|
|
||||||
"which is not allowed when %s is false.",
|
|
||||||
NameStr(relform->relname),
|
|
||||||
"publish_via_partition_root")));
|
|
||||||
|
|
||||||
ReleaseSysCache(tuple);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReleaseSysCache(rftuple);
|
ReleaseSysCache(rftuple);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
relkind = get_rel_relkind(relid);
|
||||||
|
if (relkind != RELKIND_PARTITIONED_TABLE)
|
||||||
|
{
|
||||||
|
ReleaseSysCache(rftuple);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
relname = get_rel_name(relid);
|
||||||
|
if (relname == NULL) /* table concurrently dropped */
|
||||||
|
{
|
||||||
|
ReleaseSysCache(rftuple);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_rowfilter)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
|
errmsg("cannot set parameter \"%s\" to false for publication \"%s\"",
|
||||||
|
"publish_via_partition_root",
|
||||||
|
stmt->pubname),
|
||||||
|
errdetail("The publication contains a WHERE clause for partitioned table \"%s\", which is not allowed when \"%s\" is false.",
|
||||||
|
relname, "publish_via_partition_root")));
|
||||||
|
Assert(has_collist);
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
|
errmsg("cannot set parameter \"%s\" to false for publication \"%s\"",
|
||||||
|
"publish_via_partition_root",
|
||||||
|
stmt->pubname),
|
||||||
|
errdetail("The publication contains a column list for partitioned table \"%s\", which is not allowed when \"%s\" is false.",
|
||||||
|
relname, "publish_via_partition_root")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -588,8 +588,12 @@ UPDATE rf_tbl_abcd_part_pk SET a = 1;
|
|||||||
-- fail - cannot set PUBLISH_VIA_PARTITION_ROOT to false if any row filter is
|
-- fail - cannot set PUBLISH_VIA_PARTITION_ROOT to false if any row filter is
|
||||||
-- used for partitioned table
|
-- used for partitioned table
|
||||||
ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0);
|
ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0);
|
||||||
ERROR: cannot set publish_via_partition_root = false for publication "testpub6"
|
ERROR: cannot set parameter "publish_via_partition_root" to false for publication "testpub6"
|
||||||
DETAIL: The publication contains a WHERE clause for a partitioned table "rf_tbl_abcd_part_pk" which is not allowed when publish_via_partition_root is false.
|
DETAIL: The publication contains a WHERE clause for partitioned table "rf_tbl_abcd_part_pk", which is not allowed when "publish_via_partition_root" is false.
|
||||||
|
-- remove partitioned table's row filter
|
||||||
|
ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk;
|
||||||
|
-- ok - we don't have row filter for partitioned table.
|
||||||
|
ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0);
|
||||||
-- Now change the root filter to use a column "b"
|
-- Now change the root filter to use a column "b"
|
||||||
-- (which is not in the replica identity)
|
-- (which is not in the replica identity)
|
||||||
ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk_1 WHERE (b > 99);
|
ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk_1 WHERE (b > 99);
|
||||||
@ -951,8 +955,12 @@ UPDATE rf_tbl_abcd_part_pk SET a = 1;
|
|||||||
-- fail - cannot set PUBLISH_VIA_PARTITION_ROOT to false if any column list is
|
-- fail - cannot set PUBLISH_VIA_PARTITION_ROOT to false if any column list is
|
||||||
-- used for partitioned table
|
-- used for partitioned table
|
||||||
ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0);
|
ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0);
|
||||||
ERROR: cannot set publish_via_partition_root = false for publication "testpub6"
|
ERROR: cannot set parameter "publish_via_partition_root" to false for publication "testpub6"
|
||||||
DETAIL: The publication contains a column list for a partitioned table "rf_tbl_abcd_part_pk" which is not allowed when publish_via_partition_root is false.
|
DETAIL: The publication contains a column list for partitioned table "rf_tbl_abcd_part_pk", which is not allowed when "publish_via_partition_root" is false.
|
||||||
|
-- remove partitioned table's column list
|
||||||
|
ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk;
|
||||||
|
-- ok - we don't have column list for partitioned table.
|
||||||
|
ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0);
|
||||||
-- Now change the root column list to use a column "b"
|
-- Now change the root column list to use a column "b"
|
||||||
-- (which is not in the replica identity)
|
-- (which is not in the replica identity)
|
||||||
ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk_1 (b);
|
ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk_1 (b);
|
||||||
|
@ -352,6 +352,10 @@ UPDATE rf_tbl_abcd_part_pk SET a = 1;
|
|||||||
-- fail - cannot set PUBLISH_VIA_PARTITION_ROOT to false if any row filter is
|
-- fail - cannot set PUBLISH_VIA_PARTITION_ROOT to false if any row filter is
|
||||||
-- used for partitioned table
|
-- used for partitioned table
|
||||||
ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0);
|
ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0);
|
||||||
|
-- remove partitioned table's row filter
|
||||||
|
ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk;
|
||||||
|
-- ok - we don't have row filter for partitioned table.
|
||||||
|
ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0);
|
||||||
-- Now change the root filter to use a column "b"
|
-- Now change the root filter to use a column "b"
|
||||||
-- (which is not in the replica identity)
|
-- (which is not in the replica identity)
|
||||||
ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk_1 WHERE (b > 99);
|
ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk_1 WHERE (b > 99);
|
||||||
@ -635,6 +639,10 @@ UPDATE rf_tbl_abcd_part_pk SET a = 1;
|
|||||||
-- fail - cannot set PUBLISH_VIA_PARTITION_ROOT to false if any column list is
|
-- fail - cannot set PUBLISH_VIA_PARTITION_ROOT to false if any column list is
|
||||||
-- used for partitioned table
|
-- used for partitioned table
|
||||||
ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0);
|
ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0);
|
||||||
|
-- remove partitioned table's column list
|
||||||
|
ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk;
|
||||||
|
-- ok - we don't have column list for partitioned table.
|
||||||
|
ALTER PUBLICATION testpub6 SET (PUBLISH_VIA_PARTITION_ROOT=0);
|
||||||
-- Now change the root column list to use a column "b"
|
-- Now change the root column list to use a column "b"
|
||||||
-- (which is not in the replica identity)
|
-- (which is not in the replica identity)
|
||||||
ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk_1 (b);
|
ALTER PUBLICATION testpub6 SET TABLE rf_tbl_abcd_part_pk_1 (b);
|
||||||
|
Reference in New Issue
Block a user