diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c index 67efdbbf58..cabcf0966a 100644 --- a/src/backend/catalog/pg_publication.c +++ b/src/backend/catalog/pg_publication.c @@ -277,7 +277,7 @@ GetPubPartitionOptionRelations(List *result, PublicationPartOpt pub_partopt, /* * Returns the relid of the topmost ancestor that is published via this - * publication, otherwise return InvalidOid. + * publication if any, otherwise return InvalidOid. */ Oid GetTopMostAncestorInPublication(Oid puboid, List *ancestors) diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c index ac243ff4b8..2ceee39e54 100644 --- a/src/backend/commands/publicationcmds.c +++ b/src/backend/commands/publicationcmds.c @@ -78,7 +78,6 @@ static void PublicationAddSchemas(Oid pubid, List *schemas, bool if_not_exists, AlterPublicationStmt *stmt); static void PublicationDropSchemas(Oid pubid, List *schemas, bool missing_ok); - static void parse_publication_options(ParseState *pstate, List *options, @@ -258,7 +257,7 @@ CheckObjSchemaNotAlreadyInPublication(List *rels, List *schemaidlist, * Returns true, if any of the columns used in row filter WHERE clause is not * part of REPLICA IDENTITY, false, otherwise. * - * Remember the invalid column number, if there is any to be later used in + * Remember the invalid column number if there is any, to be later used in * error message. */ static bool @@ -301,8 +300,8 @@ contain_invalid_rfcolumn_walker(Node *node, rf_context *context) * Check, if all columns referenced in the filter expression are part of the * REPLICA IDENTITY index or not. * - * Returns true if any invalid column is found and remember the invalid column - * number. + * Returns true if any invalid column is found and store the invalid column + * number in invalid_rfcolumn. */ bool contain_invalid_rfcolumn(Oid pubid, Relation relation, List *ancestors, @@ -360,6 +359,7 @@ contain_invalid_rfcolumn(Oid pubid, Relation relation, List *ancestors, Node *rfnode; Bitmapset *bms = NULL; + context.invalid_rfcolnum = InvalidAttrNumber; context.pubviaroot = pub->pubviaroot; context.parentid = publish_as_relid; context.relid = relid; @@ -379,8 +379,7 @@ contain_invalid_rfcolumn(Oid pubid, Relation relation, List *ancestors, rfnode = stringToNode(TextDatumGetCString(rfdatum)); result = contain_invalid_rfcolumn_walker(rfnode, &context); - if (invalid_rfcolumn) - *invalid_rfcolumn = context.invalid_rfcolnum; + *invalid_rfcolumn = context.invalid_rfcolnum; bms_free(bms); pfree(rfnode); @@ -574,9 +573,8 @@ TransformPubWhereClauses(List *tables, const char *queryString) assign_expr_collations(pstate, whereclause); /* - * Walk the parse-tree of this publication row filter expression and - * throw an error if anything not permitted or unexpected is - * encountered. + * We allow only simple expressions in row filters. See + * check_simple_rowfilter_expr_walker. */ check_simple_rowfilter_expr(whereclause, pri->relation); diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 478177d850..413515c917 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -9769,9 +9769,9 @@ PublicationObjSpec: { /* * The OptWhereClause must be stored here but it is - * valid only for tables. If the ColId was mistakenly - * not a table this will be detected later in - * preprocess_pubobj_list() and an error will be thrown. + * valid only for tables. For non-table objects, an + * error will be thrown later via + * preprocess_pubobj_list(). */ $$->pubtable = makeNode(PublicationTable); $$->pubtable->relation = makeRangeVar(NULL, $1, @1); diff --git a/src/backend/replication/logical/tablesync.c b/src/backend/replication/logical/tablesync.c index e0f42c3341..886ef320ba 100644 --- a/src/backend/replication/logical/tablesync.c +++ b/src/backend/replication/logical/tablesync.c @@ -808,17 +808,19 @@ fetch_remote_table_info(char *nspname, char *relname, * expression of a table in multiple publications from being included * multiple times in the final expression. * - * For initial synchronization, row filtering can be ignored in 2 cases: + * We do need to copy the row even if it matches one of the publications, + * so, we later combine all the quals with OR. * - * 1) one of the subscribed publications has puballtables set to true + * For initial synchronization, row filtering can be ignored in following + * cases: * - * 2) one of the subscribed publications is declared as ALL TABLES IN - * SCHEMA that includes this relation + * 1) one of the subscribed publications for the table hasn't specified any + * row filter + * + * 2) one of the subscribed publications has puballtables set to true * - * These 2 cases don't allow row filter expressions, so an absence of - * relation row filter expressions is a sufficient reason to copy the - * entire table, even though other publications may have a row filter for - * this relation. + * 3) one of the subscribed publications is declared as ALL TABLES IN + * SCHEMA that includes this relation */ if (walrcv_server_version(LogRepWorkerWalRcvConn) >= 150000) {