By default, all data from all published tables will be replicated to the appropriate subscribers. The replicated data can be reduced by using a row filter. A user might choose to use row filters for behavioral, security or performance reasons. If a published table sets a row filter, a row is replicated only if its data satisfies the row filter expression. This allows a set of tables to be partially replicated. The row filter is defined per table. Use a WHERE
clause after the table name for each published table that requires data to be filtered out. The WHERE
clause must be enclosed by parentheses. See CREATE PUBLICATION for details.
Row filters are applied before publishing the changes. If the row filter evaluates to false
or NULL
then the row is not replicated. The WHERE
clause expression is evaluated with the same role used for the replication connection (i.e. the role specified in the CONNECTION
clause of the CREATE SUBSCRIPTION). Row filters have no effect for TRUNCATE
command.
The WHERE
clause allows only simple expressions. It cannot contain user-defined functions, operators, types, and collations, system column references or non-immutable built-in functions.
If a publication publishes UPDATE
or DELETE
operations, the row filter WHERE
clause must contain only columns that are covered by the replica identity (see REPLICA IDENTITY
). If a publication publishes only INSERT
operations, the row filter WHERE
clause can use any column.
Whenever an UPDATE
is processed, the row filter expression is evaluated for both the old and new row (i.e. using the data before and after the update). If both evaluations are true
, it replicates the UPDATE
change. If both evaluations are false
, it doesn't replicate the change. If only one of the old/new rows matches the row filter expression, the UPDATE
is transformed to INSERT
or DELETE
, to avoid any data inconsistency. The row on the subscriber should reflect what is defined by the row filter expression on the publisher.
If the old row satisfies the row filter expression (it was sent to the subscriber) but the new row doesn't, then, from a data consistency perspective the old row should be removed from the subscriber. So the UPDATE
is transformed into a DELETE
.
If the old row doesn't satisfy the row filter expression (it wasn't sent to the subscriber) but the new row does, then, from a data consistency perspective the new row should be added to the subscriber. So the UPDATE
is transformed into an INSERT
.
Table 31.1 summarizes the applied transformations.
UPDATE
Transformation SummaryOld row | New row | Transformation |
---|---|---|
If the publication contains a partitioned table, the publication parameter publish_via_partition_root
determines which row filter is used. If publish_via_partition_root
is true
, the root partitioned table's row filter is used. Otherwise, if publish_via_partition_root
is false
(default), each partition's row filter is used.
If the subscription requires copying pre-existing table data and a publication contains WHERE
clauses, only data that satisfies the row filter expressions is copied to the subscriber.
If the subscription has several publications in which a table has been published with different WHERE
clauses, rows that satisfy any of the expressions will be copied. See Section 31.3.6 for details.
Because initial data synchronization does not take into account the publish
parameter when copying existing table data, some rows may be copied that would not be replicated using DML. Refer to Section 31.7.1, and see Section 31.2.2 for examples.
If the subscriber is in a release prior to 15, copy pre-existing data doesn't use row filters even if they are defined in the publication. This is because old releases can only copy the entire table data.
If the subscription has several publications in which the same table has been published with different row filters (for the same publish
operation), those expressions get ORed together, so that rows satisfying any of the expressions will be replicated. This means all the other row filters for the same table become redundant if:
One of the publications has no row filter.
One of the publications was created using FOR ALL TABLES
. This clause does not allow row filters.
One of the publications was created using FOR TABLES IN SCHEMA
and the table belongs to the referred schema. This clause does not allow row filters.
Create some tables to be used in the following examples.
Create some publications. Publication p1
has one table (t1
) and that table has a row filter. Publication p2
has two tables. Table t1
has no row filter, and table t2
has a row filter. Publication p3
has two tables, and both of them have a row filter.
psql
can be used to show the row filter expressions (if defined) for each publication.
psql
can be used to show the row filter expressions (if defined) for each table. See that table t1
is a member of two publications, but has a row filter only in p1
. See that table t2
is a member of two publications, and has a different row filter in each of them.
On the subscriber node, create a table t1
with the same definition as the one on the publisher, and also create the subscription s1
that subscribes to the publication p1
.
Insert some rows. Only the rows satisfying the t1 WHERE
clause of publication p1
are replicated.
Update some data, where the old and new row values both satisfy the t1 WHERE
clause of publication p1
. The UPDATE
replicates the change as normal.
Update some data, where the old row values did not satisfy the t1 WHERE
clause of publication p1
, but the new row values do satisfy it. The UPDATE
is transformed into an INSERT
and the change is replicated. See the new row on the subscriber.
Update some data, where the old row values satisfied the t1 WHERE
clause of publication p1
, but the new row values do not satisfy it. The UPDATE
is transformed into a DELETE
and the change is replicated. See that the row is removed from the subscriber.
The following examples show how the publication parameter publish_via_partition_root
determines whether the row filter of the parent or child table will be used in the case of partitioned tables.
Create a partitioned table on the publisher.
Create the same tables on the subscriber.
Create a publication p4
, and then subscribe to it. The publication parameter publish_via_partition_root
is set as true. There are row filters defined on both the partitioned table (parent
), and on the partition (child
).
Insert some values directly into the parent
and child
tables. They replicate using the row filter of parent
(because publish_via_partition_root
is true).
Repeat the same test, but with a different value for publish_via_partition_root
. The publication parameter publish_via_partition_root
is set as false. A row filter is defined on the partition (child
).
Do the inserts on the publisher same as before. They replicate using the row filter of child
(because publish_via_partition_root
is false).
no match
no match
don't replicate
no match
match
INSERT
match
no match
DELETE
match
match
UPDATE