Conflict functions
==================

bdr.alter_table_conflict_detection
----------------------------------

Allows the table owner to change how conflict detection works for a
given table.

Synopsis
^^^^^^^^

.. code:: sql

   bdr.alter_table_conflict_detection(relation regclass,
                                      method text,
                                      column_name name DEFAULT NULL)

Parameters
^^^^^^^^^^

- ``relation`` — Name of the relation for which to set the new conflict
  detection method.

- ``method`` — The conflict detection method to use.

- ``column_name`` — The column to use for storing the column detection
  data. This can be skipped, in which case the column name is chosen
  based on the conflict detection method. The ``row_origin`` method
  doesn’t require an extra column for metadata storage.

The recognized methods for conflict detection are:

- ``row_origin`` — Origin of the previous change made on the tuple (see
  :ref:`Origin conflict detection <Origin conflict detection>`  ). This is the only method supported that doesn’t
  require an extra column in the table.

- ``row_version`` — Row version column (see :ref:`Row version conflict detection <Row version conflict detection>`  ).

- ``column_commit_timestamp`` — Per-column commit timestamps (described
  in :ref:`CLCD <Conflicts>`  ).

- ``column_modify_timestamp`` — Per-column modification timestamp
  (described in :ref:`CLCD <Conflicts>`  ).

Notes
^^^^^

For more information about the difference between
``column_commit_timestamp`` and ``column_modify_timestamp`` conflict
detection methods, see :ref:`Timestamps in column-level conflict resolution <Timestamps in column-level conflict resolution>`  .

This function uses the same replication mechanism as ``DDL`` statements.
This means the replication is affected by the :ref:`ddl filters <Replication sets>` 
configuration.

The function takes a ``DML`` global lock on the relation for which
column-level conflict resolution is being enabled.

This function is transactional. You can roll back the effects with the
``ROLLBACK`` of the transaction, and the changes are visible to the
current transaction.

Only the owner of the ``relation`` can execute the
``bdr.alter_table_conflict_detection`` function unless
``bdr.backwards_compatibility`` is set to 30618 or less.

..  Warning::
   When changing the conflict detection method from one that uses an extra column to store metadata, that column is dropped.

..  Warning::
   This function disables CAMO and gives a warning, as long as warnings aren't disabled with `bdr.camo_enable_client_warnings` .

bdr.alter_node_set_conflict_resolver
------------------------------------

This function sets the behavior of conflict resolution on a given node.

.. _synopsis-1:

Synopsis
^^^^^^^^

.. code:: sql

   bdr.alter_node_set_conflict_resolver(node_name text,
                                        conflict_type text,
                                        conflict_resolver text)

.. _parameters-1:

Parameters
^^^^^^^^^^

- ``node_name`` — Name of the node that’s being changed.

- ``conflict_type`` — Conflict type for which to apply the setting (see
  :ref:`List of conflict types <List of conflict types>`  ).

- ``conflict_resolver`` — Resolver to use for the given conflict type
  (see :ref:`List of conflict resolvers <List of conflict resolvers>`  ).

.. _notes-1:

Notes
^^^^^

Currently you can change only the local node. The function call isn’t
replicated. If you want to change settings on multiple nodes, you must
run the function on each of them.

The configuration change made by this function overrides any default
behavior of conflict resolutions specified by ``bdr.create_node_group``
or ``bdr.alter_node_group`` .

This function is transactional. You can roll back the changes, and they
are visible to the current transaction.

bdr.alter_node_set_log_config
-----------------------------

Set the conflict logging configuration for a node.

.. _synopsis-2:

Synopsis
^^^^^^^^

.. code:: sql

   bdr.alter_node_set_log_config(node_name text,
                                 log_to_file bool DEFAULT true,
                                 log_to_table bool DEFAULT true,
                                 conflict_type text[] DEFAULT NULL,
                                 conflict_resolution text[] DEFAULT NULL)

.. _parameters-2:

Parameters
^^^^^^^^^^

- ``node_name`` — Name of the node that’s being changed.

- ``log_to_file`` — Whether to log to the node log file.

- ``log_to_table`` — Whether to log to the ``bdr.conflict_history``
  table.

- ``conflict_type`` — Conflict types to log. NULL (the default) means
  all.

- ``conflict_resolution`` — Conflict resolutions to log. NULL (the
  default) means all.

.. _notes-2:

Notes
^^^^^

You can change only the local node. The function call isn’t replicated.
If you want to change settings on multiple nodes, you must run the
function on each of them.

This function is transactional. You can roll back the changes, and
they’re visible to the current transaction.

Listing conflict logging configurations
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The view ``bdr.node_log_config`` shows all the logging configurations.
It lists the name of the logging configuration, where it logs, and the
conflict type and resolution it logs.

Logging conflicts to a table
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If ``log_to_table`` is set to true, conflicts are logged to a table. The
target table for conflict logging is ``bdr.conflict_history`` .

This table is range partitioned on the column ``local_time`` . The table
is managed by autopartition. By default, a new partition is created for
every day, and conflicts of the last one month are maintained. After
that, the old partitions are dropped. Autopartition creates between 7
and 14 partitions in advance. bdr_superuser can change these defaults.

Since conflicts generated for all tables managed by PGD are logged to
this table, it’s important to ensure that only legitimate users can read
the conflicted data. PGD does this by defining ROW LEVEL SECURITY
policies on the ``bdr.conflict_history`` table. Only owners of the
tables are allowed to read conflicts on the respective tables. If the
underlying tables have RLS policies defined, enabled, and enforced, then
even owners can’t read the conflicts. RLS policies created with the
FORCE option also apply to owners of the table. In that case, some or
all rows in the underlying table might not be readable even to the
owner. So PGD also enforces a stricter policy on the conflict log table.

The predefined role `bdr_read_all_conflicts <https://github.com/security/pgd-predefined-roles/#bdr_read_all_conflicts>`_  can be granted to users who need to
see all conflict details logged to the ``bdr.conflict_history`` table
without also granting them bdr_superuser role.

The default role bdr_read_all_stats has access to a catalog view called
``bdr.conflict_history_summary`` . This view doesn’t contain user data,
allowing monitoring of any conflicts logged.
