Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nbfq2-0007u6-7f for pgsql-hackers@arkaria.postgresql.org; Tue, 05 Apr 2022 09:51:02 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1nbfq1-0004IC-76 for pgsql-hackers@arkaria.postgresql.org; Tue, 05 Apr 2022 09:51:01 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nbfq0-0004I3-Qm for pgsql-hackers@lists.postgresql.org; Tue, 05 Apr 2022 09:51:00 +0000 Received: from mail-ed1-x529.google.com ([2a00:1450:4864:20::529]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1nbfpx-0008St-VE for pgsql-hackers@lists.postgresql.org; Tue, 05 Apr 2022 09:51:00 +0000 Received: by mail-ed1-x529.google.com with SMTP id w18so7968804edi.13 for ; Tue, 05 Apr 2022 02:50:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cybertec-at.20210112.gappssmtp.com; s=20210112; h=from:to:subject:mime-version:date:message-id; bh=2buBz64CS+wXlAXY2A5lW6S9CPc+wkKq7iOOM6nJDog=; b=Da1D/FzqpS0MOtxZw8FWUWMyEaBqKQBpYz9+WpP8VDt1TfUcdW/jm3w9TC3zNAZyZZ LM22KxFyMwUOKx+DPfCqh6mp5m0tb5BezzGs5srnaxn9AjUMLhpmis6tiM/gsuZ27E5N LO2g9yHZWZcziXwTlqefdQfBMOyr9lZClzFgBbqVoZx6qjr6Ghtk1c7qPvaa7E5Iyhsl 0UxypiZasLVBe937QVSAgdIlld0CkGyoubtEJfO559rwc3TsjDjYe1QuUnYbQmEWtluD aUwCZyXaHX5pCFONOd8Ve8/zeDsGnv2xXXqLh2ipE0qRCOf9Im/fTR1id5auOsYBfs7c e2WQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:mime-version:date:message-id; bh=2buBz64CS+wXlAXY2A5lW6S9CPc+wkKq7iOOM6nJDog=; b=C+0sTWMNQ7tydpd3f13DzaKzFJOxQG6nepw0OXQ2B65ktIFBas4Lh7nHdLmbjAzuGQ txrMD2fNbcGNmdJJWru1X8x7rjVfkGNKum0QtBrtdhw8fhlmzF4RBBpFhzrTMzORyBVs qP/Ia+8dImaUwOIMS1tbz21FTQ1oxQmrQpGWcYigvdnfBNKPrAurbcqDrAIXamSDf3sw u31S5SXeJbcOldyUT7zHO8vtN+k5shcxYZcKIa+BfjaE+QY3Lgqbom2iHx1N5EYCAM7w CSzwGnRpubNSQJ3GP/7Tz+RLLjlfMW/OfOQNvAx5mJW0Z9tAU9JdJ4wQBP0eYuRtTA34 lcGA== X-Gm-Message-State: AOAM5321SdbUhf7Yxj52mJ3FV088E8VN9OSr5v1K98d/Rgu2Qq+NyDFz zrN0QRVjdmgGVIk/K7DQeO5WeDbRtbYK6g== X-Google-Smtp-Source: ABdhPJwK5XNv1d21+m0l6jQxQf1PobvOrPQ4yKqciGxDc22fRCoqwLOma17acNZE7RfzbXwG2vIt8Q== X-Received: by 2002:a50:e696:0:b0:419:998d:5feb with SMTP id z22-20020a50e696000000b00419998d5febmr2664326edm.122.1649152241542; Tue, 05 Apr 2022 02:50:41 -0700 (PDT) Received: from antos (85-207-121-76.static.bluetone.cz. [85.207.121.76]) by smtp.gmail.com with ESMTPSA id h9-20020aa7c949000000b0041b4d8ae50csm6424483edt.34.2022.04.05.02.50.40 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Apr 2022 02:50:40 -0700 (PDT) From: Antonin Houska To: pgsql-hackers@lists.postgresql.org Subject: Logical replication row filtering and TOAST X-Mailer: MH-E 8.6+git; nmh 1.7+dev; GNU Emacs 27.2.50 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Date: Tue, 05 Apr 2022 11:50:55 +0200 Message-ID: <84638.1649152255@antos> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --=-=-= Content-Type: text/plain I spent some time thinking about a special case of evaluation of the row filter and wrote a comment that might be useful (see the attachment). However now I think that it's not perfect if the code really relies on the fact that value of an indexed column cannot be TOASTed due to size restrictions. I could hit two different error messages when trying activate TOAST on an index column (in this case PG was build with 16kB pages), but still I think the code is unnecessarily fragile if it relies on such errors: ERROR: index row requires 8224 bytes, maximum size is 8191 ERROR: index row size 8048 exceeds btree version 4 maximum 5432 for index "b_pkey" DETAIL: Index row references tuple (0,3) in relation "b". HINT: Values larger than 1/3 of a buffer page cannot be indexed. Note that at least in ExtractReplicaIdentity() we do expect that an indexed column value can be TOASTed. /* * If the tuple, which by here only contains indexed columns, still has * toasted columns, force them to be inlined. This is somewhat unlikely * since there's limits on the size of indexed columns, so we don't * duplicate toast_flatten_tuple()s functionality in the above loop over * the indexed columns, even if it would be more efficient. */ if (HeapTupleHasExternal(key_tuple)) { HeapTuple oldtup = key_tuple; key_tuple = toast_flatten_tuple(oldtup, desc); heap_freetuple(oldtup); } Do I miss anything? -- Antonin Houska Web: https://www.cybertec-postgresql.com --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=logical_rep_row_filter_comment.diff diff --git a/src/backend/replication/pgoutput/pgoutput.c b/src/backend/replication/pgoutput/pgoutput.c index 20d0b1e1253..2be5aaa18c4 100644 --- a/src/backend/replication/pgoutput/pgoutput.c +++ b/src/backend/replication/pgoutput/pgoutput.c @@ -1246,6 +1246,15 @@ pgoutput_row_filter(Relation relation, TupleTableSlot *old_slot, */ if (!new_slot || !old_slot) { + /* + * For UPDATE, we should only get here if the replica identity is != + * FULL and thus all the identity columns are index columns, i.e. + * never TOASTed. Therefore, we don't need to care of the unchanged + * toasted replica identity columns like we do below. + */ + Assert(relation->rd_rel->relreplident != REPLICA_IDENTITY_FULL || + map_changetype_pubaction[*action] != PUBACTION_UPDATE); + ecxt->ecxt_scantuple = new_slot ? new_slot : old_slot; result = pgoutput_row_filter_exec_expr(filter_exprstate, ecxt); --=-=-=--