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 1nk7y5-0000Jj-HJ for pgsql-hackers@arkaria.postgresql.org; Thu, 28 Apr 2022 17:30:17 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1nk7y4-0004ff-92 for pgsql-hackers@arkaria.postgresql.org; Thu, 28 Apr 2022 17:30:16 +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 1nk7y3-0004fW-Fa for pgsql-hackers@lists.postgresql.org; Thu, 28 Apr 2022 17:30:15 +0000 Received: from mail-ej1-x635.google.com ([2a00:1450:4864:20::635]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1nk7y0-0003at-4N for pgsql-hackers@lists.postgresql.org; Thu, 28 Apr 2022 17:30:14 +0000 Received: by mail-ej1-x635.google.com with SMTP id k23so10972820ejd.3 for ; Thu, 28 Apr 2022 10:30:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=enterprisedb.com; s=google; h=message-id:date:mime-version:user-agent:subject:content-language:to :cc:references:from:in-reply-to:content-transfer-encoding; bh=vjqkO+uiEtnaQHRxakNqEF+DMqTZTIagulDuzskBtvY=; b=UUCrmsGCgrBoAfeXALhoajcjYZ66aKW4qA92V8/Jr7xpk7eN8LboQCB7pqwx6mV2Bx hLiyLXe4SuSuNx5/goii89iv+4kUYJSWvoOuKVI4vbm0eLS2CUCDs2e7vYPrasGqEXfX WYTxTRDZuBxE+uqgw6uxplA9c/cjUyZ0cVhEE287X+LdzijcwBQmOgeX5EK739fxcxvU WYy8hU0YBVuZJ7amTuEYiHDjyTa8hiOqLzL5u7li9OeVDKCdMqNtyr1dZ2kNQkwXdP5W HtzPDm7OIBOZ7E9KcSEfQmga9unKNEZvDQIjv+KPIxQXWi31tGT2j6JSC65wHUKR16AP sW8Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:date:mime-version:user-agent:subject :content-language:to:cc:references:from:in-reply-to :content-transfer-encoding; bh=vjqkO+uiEtnaQHRxakNqEF+DMqTZTIagulDuzskBtvY=; b=cDbFflLny8zq92EbZYY1XZm6+YK84FyrgmvT6sP4crIQM7uJJzn7/c5QYGkRR3w8Gg UMcla0VmRdqf4P1siDXo4QyaKlXmjjls9dQdCHnPljYFtY3h7vdu7l+jhUk4kmT7bfyx AoJRJnghTGMlkOXp60aYF2xNUykojJmMBkDiNUEqNSvTQyHfC7PjQ/PaL36bPC51HSGj 76wsH/2wgRmGLUl6vDlFFcGPR+DTfrjuPJFO8TrCqSBS8rvrSsNLL3e3yZt0+vFLY62B +usZ6tQ/LzY9+tJwflBpkJobBJHkFxqTks8n2583rFJEwhk+76OeYCqgZLzxrDHleoXr GRdg== X-Gm-Message-State: AOAM533655yhXTgXDpNivNe4xcnHX6ga3DMCQ/OPRlF3d+JsBZVfNz3B H7PYJdxAisuqnwG6LpXcXudL0eQiij4hWHo1UizxrDLxBLI5M8TYEopGXWE8/JhJOTUBwj0Izjb Q2u0/n3x14YiUuwBzJOoSL6NOQHB7tP0Far+RYG5nN0WO3tUKZHZLEz/RuJd+Rk+uM5lIlOv+9H U/wj1BWRtHDZM7yX52wQURVOhP79WOCAjaRz0h78MVBA/9Ph7dGO5a X-Google-Smtp-Source: ABdhPJx9hzvYhXN3a8JMqv+lRIZRi+qdRbVGky+YQus6PYyecBQJ015YT0K8/u5hnnCVUEwxGci0Pg== X-Received: by 2002:a17:907:6da5:b0:6f3:c4b1:378b with SMTP id sb37-20020a1709076da500b006f3c4b1378bmr9436955ejc.307.1651167010126; Thu, 28 Apr 2022 10:30:10 -0700 (PDT) Received: from [10.137.0.17] (static-84-42-175-93.net.upcbroadband.cz. [84.42.175.93]) by smtp.gmail.com with ESMTPSA id d26-20020a170906305a00b006f3a7ffbb0esm221837ejd.70.2022.04.28.10.30.09 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 28 Apr 2022 10:30:09 -0700 (PDT) Message-ID: <765985d7-c464-2a73-6acf-268b341173aa@enterprisedb.com> Date: Thu, 28 Apr 2022 19:30:08 +0200 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.7.0 Subject: Re: bogus: logical replication rows/cols combinations Content-Language: en-US To: Peter Eisentraut , Amit Kapila , Alvaro Herrera Cc: Pg Hackers References: <006d5ffc-1e7a-5cf2-c507-88eee6e0c14d@enterprisedb.com> <202204270943.4ol7indtwv3i@alvherre.pgsql> <39077967-c327-eddb-ac4b-7d64117944fb@enterprisedb.com> From: Tomas Vondra In-Reply-To: <39077967-c327-eddb-ac4b-7d64117944fb@enterprisedb.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-CLOUD-SEC-AV-Info: enterprisedb,google_mail,monitor X-CLOUD-SEC-AV-Sent: true X-Gm-Spam: 0 X-Gm-Phishy: 0 List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 4/28/22 14:26, Peter Eisentraut wrote: > On 27.04.22 12:33, Amit Kapila wrote: >> Currently, when the subscription has multiple publications, we combine >> the objects, and actions of those publications. It happens for >> 'publish_via_partition_root', publication actions, tables, column >> lists, or row filters. I think the whole design works on this idea >> even the initial table sync. I think it might need a major change >> (which I am not sure about at this stage) if we want to make the >> initial sync also behave similar to what you are proposing. > > If one publication says "publish if insert" and another publication says > "publish if update", then the combination of that is clearly "publish if > insert or update".  Similarly, if one publication says "WHERE (foo)" and > one says "WHERE (bar)", then the combination is "WHERE (foo OR bar)". > > But if one publication says "publish columns a and b if condition-X" and > another publication says "publish columns a and c if not-condition-X", > then the combination is clearly *not* "publish columns a, b, c if true". >  That is not logical, in the literal sense of that word. > > I wonder how we handle the combination of > > pub1: publish=insert WHERE (foo) > pub2: publish=update WHERE (bar) > > I think it would be incorrect if the combination is > > pub1, pub2: publish=insert,update WHERE (foo OR bar). That's a good question, actually. No, we don't combine the publications like this, the row filters are kept "per action". But the exact behavior turns out to be rather confusing in this case. (Note: This has nothing to do with column lists.) Consider an example similar to what Alvaro posted earlier: create table uno (a int primary key, b int, c int); create publication uno for table uno where (a > 0) with (publish='insert'); create publication dos for table uno where (a < 0) with (publish='update'); And do this: insert into uno values (1, 2, 3), (-1, 3, 4) which on the subscriber produces just one row, because (a<0) replicates only updates: a | b | c ---+---+--- 1 | 2 | 3 (1 row) Now, let's update the (a<0) row. update uno set a = 2 where a = -1; It might seem reasonable to expect the updated row (2,3,4) to appear on the subscriber, but no - that's not what happens. Because we have (a<0) for UPDATE, and we evaluate this on the old row (matches) and new row (does not match). And pgoutput_row_filter() decides the update needs to be converted to DELETE, despite the old row was not replicated at all. I'm not sure if pgoutput_row_filter() can even make reasonable decisions with such configuration (combination of row filters, actions ...). But it sure seems confusing, because if you just inserted the updated row, it would get replicated. Which brings me to a second problem, related to this one. Imagine you create the subscription *after* inserting the two rows. In that case you get this: a | b | c ----+---+--- 1 | 2 | 3 -1 | 3 | 4 (2 rows) because tablesync.c ignores which actions is the publication (and thus the rowfilter) defined for. I think it's natural to expect that (INSERT + sync) and (sync + INSERT) produce the same output on the subscriber. I'm not sure we can actually make this perfectly sane with arbitrary combinations of filters and actions. It would probably depend on whether the actions are commutative, associative and stuff like that. But maybe we can come up with restrictions that'd make this sane? regards -- Tomas Vondra EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company