Re: row filtering for logical replication

Dilip Kumar <dilipbalaut@gmail.com>

From: Dilip Kumar <dilipbalaut@gmail.com>
To: Ajin Cherian <itsajin@gmail.com>
Cc: Peter Smith <smithpb2250@gmail.com>, "houzj.fnst@fujitsu.com" <houzj.fnst@fujitsu.com>, Greg Nancarrow <gregn4422@gmail.com>, Euler Taveira <euler@eulerto.com>, Rahila Syed <rahilasyed90@gmail.com>, Peter Eisentraut <peter.eisentraut@enterprisedb.com>, Önder Kalacı <onderkalaci@gmail.com>, japin <japinli@hotmail.com>, Michael Paquier <michael@paquier.xyz>, David Steele <david@pgmasters.net>, Craig Ringer <craig@2ndquadrant.com>, Amit Kapila <amit.kapila16@gmail.com>, Amit Langote <amitlangote09@gmail.com>, PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>
Date: 2021-11-16T08:49:43Z
Lists: pgsql-hackers

Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. Release cache tuple when no longer needed

  2. Add some additional tests for row filters in logical replication.

  3. Fix one of the tests introduced in commit 52e4f0cd47.

  4. Allow specifying row filters for logical replication of tables.

  5. Move scanint8() to numutils.c

  6. Replace Test::More plans with done_testing

  7. Reduce relcache access in WAL sender streaming logical changes

  8. Small cleanups related to PUBLICATION framework code

  9. Add a view to show the stats of subscription workers.

  10. Allow publishing the tables of schema.

  11. Doc: improve documentation of CREATE/ALTER SUBSCRIPTION.

  12. Add PublicationTable and PublicationRelInfo structs

  13. Remove unused argument "txn" in maybe_send_schema().

  14. Add prepare API support for streaming transactions in logical replication.

  15. Unify PostgresNode's new() and get_new_node() methods

  16. Use l*_node() family of functions where appropriate

  17. Add support for prepared transactions to built-in logical replication.

  18. Restore the portal-level snapshot after procedure COMMIT/ROLLBACK.

  19. Rename a parse node to be more general

  20. Remove unused column atttypmod from initial tablesync query

  21. SEARCH and CYCLE clauses

On Mon, Nov 15, 2021 at 2:44 PM Dilip Kumar <dilipbalaut@gmail.com> wrote:
>
> On Fri, Nov 12, 2021 at 3:49 PM Ajin Cherian <itsajin@gmail.com> wrote:
> >
> > Attaching version 39-

I have reviewed, 0001* and I have a few comments on it

---
>If you choose to do the initial table synchronization, only data that satisfies
>the row filters is sent.

I think this comment is not correct, I think the correct statement
would be "only data that satisfies the row filters is pulled by the
subscriber"

---

---
+   The <literal>WHERE</literal> clause should contain only columns that are
+   part of the primary key or be covered  by <literal>REPLICA
+   IDENTITY</literal> otherwise, <command>DELETE</command> operations will not
+   be replicated. That's because old row is used and it only contains primary
+   key or columns that are part of the <literal>REPLICA IDENTITY</literal>; the
+   remaining columns are <literal>NULL</literal>. For <command>INSERT</command>
+   and <command>UPDATE</command> operations, any column might be used in the
+   <literal>WHERE</literal> clause.

I think this message is not correct, because for update also we can
not have filters on the non-key attribute right?  Even w.r.t the first
patch also if the non update non key toast columns are there we can
not apply filters on those.  So this comment seems misleading to me.

---

-    Oid            relid = RelationGetRelid(targetrel->relation);
..
+    relid = RelationGetRelid(targetrel);
+

Why this change is required, I mean instead of fetching the relid
during the variable declaration why do we need to do it separately
now?

---

+    if (expr == NULL)
+        ereport(ERROR,
+                (errcode(ERRCODE_CANNOT_COERCE),
+                 errmsg("row filter returns type %s that cannot be
coerced to the expected type %s",

Instead of "coerced to" can we use "cast to"?  That will be in sync
with other simmilar kind od user exposed error message.
----

+static ExprState *
+pgoutput_row_filter_init_expr(Node *rfnode)
+{
.....
+    /*
+     * Cache ExprState using CacheMemoryContext. This is the same code as
+     * ExecPrepareExpr() but that is not used because it doesn't use an EState.
+     * It should probably be another function in the executor to handle the
+     * execution outside a normal Plan tree context.
+     */
+    oldctx = MemoryContextSwitchTo(CacheMemoryContext);
+    expr = expression_planner(expr);
+    exprstate = ExecInitExpr(expr, NULL);
+    MemoryContextSwitchTo(oldctx);
+
+    return exprstate;
+}

I can see the caller of this function is already switching to
CacheMemoryContext, so what is the point in doing it again here?
Maybe if called is expected to do show we can Asssert on the
CurrentMemoryContext.

-- 
Regards,
Dilip Kumar
EnterpriseDB: http://www.enterprisedb.com