mirror of
https://github.com/postgres/postgres.git
synced 2025-06-16 06:01:02 +03:00
Rework the options syntax for logical replication commands
For CREATE/ALTER PUBLICATION/SUBSCRIPTION, use similar option style as other statements that use a WITH clause for options. Author: Petr Jelinek <petr.jelinek@2ndquadrant.com>
This commit is contained in:
@ -222,8 +222,9 @@
|
|||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
When creating a subscription, the replication slot already exists. In
|
When creating a subscription, the replication slot already exists. In
|
||||||
that case, the subscription can be created using the <literal>NOCREATE
|
that case, the subscription can be created using
|
||||||
SLOT</literal> option to associate with the existing slot.
|
the <literal>create_slot = false</literal> option to associate with the
|
||||||
|
existing slot.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
@ -231,7 +232,7 @@
|
|||||||
<para>
|
<para>
|
||||||
When creating a subscription, the remote host is not reachable or in an
|
When creating a subscription, the remote host is not reachable or in an
|
||||||
unclear state. In that case, the subscription can be created using
|
unclear state. In that case, the subscription can be created using
|
||||||
the <literal>NOCONNECT</literal> option. The remote host will then not
|
the <literal>connect = false</literal> option. The remote host will then not
|
||||||
be contacted at all. This is what <application>pg_dump</application>
|
be contacted at all. This is what <application>pg_dump</application>
|
||||||
uses. The remote replication slot will then have to be created
|
uses. The remote replication slot will then have to be created
|
||||||
manually before the subscription can be activated.
|
manually before the subscription can be activated.
|
||||||
|
@ -21,17 +21,10 @@ PostgreSQL documentation
|
|||||||
|
|
||||||
<refsynopsisdiv>
|
<refsynopsisdiv>
|
||||||
<synopsis>
|
<synopsis>
|
||||||
ALTER PUBLICATION <replaceable class="PARAMETER">name</replaceable> WITH ( <replaceable class="PARAMETER">option</replaceable> [, ... ] )
|
|
||||||
|
|
||||||
<phrase>where <replaceable class="PARAMETER">option</replaceable> can be:</phrase>
|
|
||||||
|
|
||||||
PUBLISH INSERT | NOPUBLISH INSERT
|
|
||||||
| PUBLISH UPDATE | NOPUBLISH UPDATE
|
|
||||||
| PUBLISH DELETE | NOPUBLISH DELETE
|
|
||||||
|
|
||||||
ALTER PUBLICATION <replaceable class="PARAMETER">name</replaceable> ADD TABLE [ ONLY ] <replaceable class="PARAMETER">table_name</replaceable> [ * ] [, ...]
|
ALTER PUBLICATION <replaceable class="PARAMETER">name</replaceable> ADD TABLE [ ONLY ] <replaceable class="PARAMETER">table_name</replaceable> [ * ] [, ...]
|
||||||
ALTER PUBLICATION <replaceable class="PARAMETER">name</replaceable> SET TABLE [ ONLY ] <replaceable class="PARAMETER">table_name</replaceable> [ * ] [, ...]
|
ALTER PUBLICATION <replaceable class="PARAMETER">name</replaceable> SET TABLE [ ONLY ] <replaceable class="PARAMETER">table_name</replaceable> [ * ] [, ...]
|
||||||
ALTER PUBLICATION <replaceable class="PARAMETER">name</replaceable> DROP TABLE [ ONLY ] <replaceable class="PARAMETER">table_name</replaceable> [ * ] [, ...]
|
ALTER PUBLICATION <replaceable class="PARAMETER">name</replaceable> DROP TABLE [ ONLY ] <replaceable class="PARAMETER">table_name</replaceable> [ * ] [, ...]
|
||||||
|
ALTER PUBLICATION <replaceable class="PARAMETER">name</replaceable> SET ( <replaceable class="parameter">publication_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] )
|
||||||
ALTER PUBLICATION <replaceable class="PARAMETER">name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER }
|
ALTER PUBLICATION <replaceable class="PARAMETER">name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER }
|
||||||
ALTER PUBLICATION <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable>new_name</replaceable>
|
ALTER PUBLICATION <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable>new_name</replaceable>
|
||||||
</synopsis>
|
</synopsis>
|
||||||
@ -44,8 +37,7 @@ ALTER PUBLICATION <replaceable class="PARAMETER">name</replaceable> RENAME TO <r
|
|||||||
The first variant of this command listed in the synopsis can change
|
The first variant of this command listed in the synopsis can change
|
||||||
all of the publication properties specified in
|
all of the publication properties specified in
|
||||||
<xref linkend="sql-createpublication">. Properties not mentioned in the
|
<xref linkend="sql-createpublication">. Properties not mentioned in the
|
||||||
command retain their previous settings. Database superusers can change any
|
command retain their previous settings.
|
||||||
of these settings for any role.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -79,21 +71,6 @@ ALTER PUBLICATION <replaceable class="PARAMETER">name</replaceable> RENAME TO <r
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><literal>PUBLISH INSERT</literal></term>
|
|
||||||
<term><literal>NOPUBLISH INSERT</literal></term>
|
|
||||||
<term><literal>PUBLISH UPDATE</literal></term>
|
|
||||||
<term><literal>NOPUBLISH UPDATE</literal></term>
|
|
||||||
<term><literal>PUBLISH DELETE</literal></term>
|
|
||||||
<term><literal>NOPUBLISH DELETE</literal></term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
These clauses alter properties originally set by
|
|
||||||
<xref linkend="SQL-CREATEPUBLICATION">. See there for more information.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><replaceable class="parameter">table_name</replaceable></term>
|
<term><replaceable class="parameter">table_name</replaceable></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
@ -107,6 +84,16 @@ ALTER PUBLICATION <replaceable class="PARAMETER">name</replaceable> RENAME TO <r
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>SET ( <replaceable class="parameter">publication_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] )</literal></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
This clause alters publication parameters originally set by
|
||||||
|
<xref linkend="SQL-CREATEPUBLICATION">. See there for more information.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><replaceable class="parameter">new_owner</replaceable></term>
|
<term><replaceable class="parameter">new_owner</replaceable></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
@ -131,9 +118,9 @@ ALTER PUBLICATION <replaceable class="PARAMETER">name</replaceable> RENAME TO <r
|
|||||||
<title>Examples</title>
|
<title>Examples</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Change the publication to not publish inserts:
|
Change the publication to publish only deletes and updates:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
ALTER PUBLICATION noinsert WITH (NOPUBLISH INSERT);
|
ALTER PUBLICATION noinsert SET (publish = 'update, delete');
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
@ -21,23 +21,12 @@ PostgreSQL documentation
|
|||||||
|
|
||||||
<refsynopsisdiv>
|
<refsynopsisdiv>
|
||||||
<synopsis>
|
<synopsis>
|
||||||
ALTER SUBSCRIPTION <replaceable class="PARAMETER">name</replaceable> WITH ( <replaceable class="PARAMETER">suboption</replaceable> [, ... ] )
|
|
||||||
|
|
||||||
<phrase>where <replaceable class="PARAMETER">suboption</replaceable> can be:</phrase>
|
|
||||||
|
|
||||||
SLOT NAME = <replaceable class="PARAMETER">slot_name</replaceable>
|
|
||||||
| SYNCHRONOUS_COMMIT = <replaceable class="PARAMETER">synchronous_commit</replaceable>
|
|
||||||
|
|
||||||
ALTER SUBSCRIPTION <replaceable class="PARAMETER">name</replaceable> SET PUBLICATION <replaceable class="PARAMETER">publication_name</replaceable> [, ...] { REFRESH WITH ( <replaceable class="PARAMETER">puboption</replaceable> [, ... ] ) | NOREFRESH }
|
|
||||||
ALTER SUBSCRIPTION <replaceable class="PARAMETER">name</replaceable> REFRESH PUBLICATION [ WITH ( <replaceable class="PARAMETER">puboption</replaceable> [, ... ] ) ]
|
|
||||||
|
|
||||||
<phrase>where <replaceable class="PARAMETER">puboption</replaceable> can be:</phrase>
|
|
||||||
|
|
||||||
COPY DATA | NOCOPY DATA
|
|
||||||
|
|
||||||
ALTER SUBSCRIPTION <replaceable class="PARAMETER">name</replaceable> CONNECTION '<replaceable>conninfo</replaceable>'
|
ALTER SUBSCRIPTION <replaceable class="PARAMETER">name</replaceable> CONNECTION '<replaceable>conninfo</replaceable>'
|
||||||
|
ALTER SUBSCRIPTION <replaceable class="PARAMETER">name</replaceable> SET PUBLICATION <replaceable class="PARAMETER">publication_name</replaceable> [, ...] { REFRESH [ WITH ( <replaceable class="PARAMETER">refresh_option</replaceable> <replaceable class="PARAMETER">value</replaceable> [, ... ] ) ] | SKIP REFRESH }
|
||||||
|
ALTER SUBSCRIPTION <replaceable class="PARAMETER">name</replaceable> REFRESH PUBLICATION [ WITH ( <replaceable class="PARAMETER">refresh_option</replaceable> <replaceable class="PARAMETER">value</replaceable> [, ... ] ) ]
|
||||||
ALTER SUBSCRIPTION <replaceable class="PARAMETER">name</replaceable> ENABLE
|
ALTER SUBSCRIPTION <replaceable class="PARAMETER">name</replaceable> ENABLE
|
||||||
ALTER SUBSCRIPTION <replaceable class="PARAMETER">name</replaceable> DISABLE
|
ALTER SUBSCRIPTION <replaceable class="PARAMETER">name</replaceable> DISABLE
|
||||||
|
ALTER SUBSCRIPTION <replaceable class="PARAMETER">name</replaceable> SET ( <replaceable class="parameter">subscription_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] )
|
||||||
ALTER SUBSCRIPTION <replaceable class="PARAMETER">name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER }
|
ALTER SUBSCRIPTION <replaceable class="PARAMETER">name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_USER | SESSION_USER }
|
||||||
ALTER SUBSCRIPTION <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable>new_name</replaceable>
|
ALTER SUBSCRIPTION <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable>new_name</replaceable>
|
||||||
</synopsis>
|
</synopsis>
|
||||||
@ -73,11 +62,9 @@ ALTER SUBSCRIPTION <replaceable class="PARAMETER">name</replaceable> RENAME TO <
|
|||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><literal>CONNECTION '<replaceable class="parameter">conninfo</replaceable>'</literal></term>
|
<term><literal>CONNECTION '<replaceable class="parameter">conninfo</replaceable>'</literal></term>
|
||||||
<term><literal>SLOT NAME = <replaceable class="parameter">slot_name</replaceable></literal></term>
|
|
||||||
<term><literal>SYNCHRONOUS_COMMIT = <replaceable class="PARAMETER">synchronous_commit</replaceable></literal></term>
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
These clauses alter properties originally set by
|
This clause alters the connection property originally set by
|
||||||
<xref linkend="SQL-CREATESUBSCRIPTION">. See there for more
|
<xref linkend="SQL-CREATESUBSCRIPTION">. See there for more
|
||||||
information.
|
information.
|
||||||
</para>
|
</para>
|
||||||
@ -91,11 +78,17 @@ ALTER SUBSCRIPTION <replaceable class="PARAMETER">name</replaceable> RENAME TO <
|
|||||||
Changes list of subscribed publications. See
|
Changes list of subscribed publications. See
|
||||||
<xref linkend="SQL-CREATESUBSCRIPTION"> for more information.
|
<xref linkend="SQL-CREATESUBSCRIPTION"> for more information.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
When <literal>REFRESH</literal> is specified, this command will also
|
When <literal>REFRESH</literal> is specified, this command will also act
|
||||||
act like <literal>REFRESH PUBLICATION</literal>. When
|
like <literal>REFRESH
|
||||||
<literal>NOREFRESH</literal> is specified, the comamnd will not try to
|
PUBLICATION</literal>. <literal>refresh_option</literal> specifies
|
||||||
refresh table information.
|
additional options for the refresh operation, as described
|
||||||
|
under <literal>REFRESH PUBLICATION</literal>. When
|
||||||
|
<literal>SKIP REFRESH</literal> is specified, the command will not try
|
||||||
|
to refresh table information. Note that
|
||||||
|
either <literal>REFRESH</literal> or <literal>SKIP REFRESH</literal>
|
||||||
|
must be specified.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -104,16 +97,28 @@ ALTER SUBSCRIPTION <replaceable class="PARAMETER">name</replaceable> RENAME TO <
|
|||||||
<term><literal>REFRESH PUBLICATION</literal></term>
|
<term><literal>REFRESH PUBLICATION</literal></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Fetch missing table information from publisher. This will start
|
Fetch missing table information from publisher. This will start
|
||||||
replication of tables that were added to the subscribed-to publications
|
replication of tables that were added to the subscribed-to publications
|
||||||
since the last invocation of <command>REFRESH PUBLICATION</command> or
|
since the last invocation of <command>REFRESH PUBLICATION</command> or
|
||||||
since <command>CREATE SUBSCRIPTION</command>.
|
since <command>CREATE SUBSCRIPTION</command>.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The <literal>COPY DATA</literal> and <literal>NOCOPY DATA</literal>
|
<literal>refresh_option</literal> specifies additional options for the
|
||||||
options specify if the existing data in the publications that are being
|
refresh operation. The supported options are:
|
||||||
subscribed to should be copied. <literal>COPY DATA</literal> is the
|
|
||||||
default.
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>copy_data</literal> (<type>boolean</type>)</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Specifies whether the existing data in the publications that are
|
||||||
|
being subscribed to should be copied once the replication starts.
|
||||||
|
The default is <literal>true</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -138,6 +143,18 @@ ALTER SUBSCRIPTION <replaceable class="PARAMETER">name</replaceable> RENAME TO <
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>SET ( <replaceable class="parameter">subscription_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] )</literal></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
This clause alters parameters originally set by
|
||||||
|
<xref linkend="SQL-CREATESUBSCRIPTION">. See there for more
|
||||||
|
information. The allowed options are <literal>slot_name</literal> and
|
||||||
|
<literal>synchronous_commit</literal>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><replaceable class="parameter">new_owner</replaceable></term>
|
<term><replaceable class="parameter">new_owner</replaceable></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
@ -165,7 +182,7 @@ ALTER SUBSCRIPTION <replaceable class="PARAMETER">name</replaceable> RENAME TO <
|
|||||||
Change the publication subscribed by a subscription to
|
Change the publication subscribed by a subscription to
|
||||||
<literal>insert_only</literal>:
|
<literal>insert_only</literal>:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
ALTER SUBSCRIPTION mysub SET PUBLICATION insert_only;
|
ALTER SUBSCRIPTION mysub SET PUBLICATION insert_only REFRESH;
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
@ -24,13 +24,8 @@ PostgreSQL documentation
|
|||||||
CREATE PUBLICATION <replaceable class="parameter">name</replaceable>
|
CREATE PUBLICATION <replaceable class="parameter">name</replaceable>
|
||||||
[ FOR TABLE [ ONLY ] <replaceable class="parameter">table_name</replaceable> [ * ] [, ...]
|
[ FOR TABLE [ ONLY ] <replaceable class="parameter">table_name</replaceable> [ * ] [, ...]
|
||||||
| FOR ALL TABLES ]
|
| FOR ALL TABLES ]
|
||||||
[ WITH ( <replaceable class="parameter">option</replaceable> [, ... ] ) ]
|
[ WITH ( <replaceable class="parameter">publication_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] ) ]
|
||||||
|
|
||||||
<phrase>where <replaceable class="parameter">option</replaceable> can be:</phrase>
|
|
||||||
|
|
||||||
PUBLISH INSERT | NOPUBLISH INSERT
|
|
||||||
| PUBLISH UPDATE | NOPUBLISH UPDATE
|
|
||||||
| PUBLISH DELETE | NOPUBLISH DELETE
|
|
||||||
</synopsis>
|
</synopsis>
|
||||||
</refsynopsisdiv>
|
</refsynopsisdiv>
|
||||||
|
|
||||||
@ -97,37 +92,29 @@ CREATE PUBLICATION <replaceable class="parameter">name</replaceable>
|
|||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><literal>PUBLISH INSERT</literal></term>
|
<term><literal>WITH ( <replaceable class="parameter">publication_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] )</literal></term>
|
||||||
<term><literal>NOPUBLISH INSERT</literal></term>
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
These clauses determine whether the new publication will send
|
This clause specifies optional parameters for a publication. The
|
||||||
the <command>INSERT</command> operations to the subscribers.
|
following parameters are supported:
|
||||||
<literal>PUBLISH INSERT</literal> is the default.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
<variablelist>
|
||||||
<term><literal>PUBLISH UPDATE</literal></term>
|
<varlistentry>
|
||||||
<term><literal>NOPUBLISH UPDATE</literal></term>
|
<term><literal>publish</literal> (<type>string</type>)</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
These clauses determine whether the new publication will send
|
This parameter determines which DML operations will be published by
|
||||||
the <command>UPDATE</command> operations to the subscribers.
|
the new publication to the subscribers. The value is
|
||||||
<literal>PUBLISH UPDATE</literal> is the default.
|
comma-separated list of operations. The allowed operations are
|
||||||
</para>
|
<literal>insert</literal>, <literal>update</literal>, and
|
||||||
</listitem>
|
<literal>delete</literal>. The default is to publish all actions,
|
||||||
</varlistentry>
|
and so the default value for this option is
|
||||||
|
<literal>'insert, update, delete'</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><literal>PUBLISH DELETE</literal></term>
|
|
||||||
<term><literal>NOPUBLISH DELETE</literal></term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
These clauses determine whether the new publication will send
|
|
||||||
the <command>DELETE</command> operations to the subscribers.
|
|
||||||
<literal>PUBLISH DELETE</literal> is the default.
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -203,7 +190,7 @@ CREATE PUBLICATION alltables FOR ALL TABLES;
|
|||||||
operations in one table:
|
operations in one table:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
CREATE PUBLICATION insert_only FOR TABLE mydata
|
CREATE PUBLICATION insert_only FOR TABLE mydata
|
||||||
WITH (NOPUBLISH UPDATE, NOPUBLISH DELETE);
|
WITH (publish = 'insert');
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
@ -23,17 +23,8 @@ PostgreSQL documentation
|
|||||||
<synopsis>
|
<synopsis>
|
||||||
CREATE SUBSCRIPTION <replaceable class="PARAMETER">subscription_name</replaceable>
|
CREATE SUBSCRIPTION <replaceable class="PARAMETER">subscription_name</replaceable>
|
||||||
CONNECTION '<replaceable class="PARAMETER">conninfo</replaceable>'
|
CONNECTION '<replaceable class="PARAMETER">conninfo</replaceable>'
|
||||||
PUBLICATION { <replaceable class="PARAMETER">publication_name</replaceable> [, ...] }
|
PUBLICATION <replaceable class="PARAMETER">publication_name</replaceable> [, ...]
|
||||||
[ WITH ( <replaceable class="PARAMETER">option</replaceable> [, ... ] ) ]
|
[ WITH ( <replaceable class="parameter">subscription_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] ) ]
|
||||||
|
|
||||||
<phrase>where <replaceable class="PARAMETER">option</replaceable> can be:</phrase>
|
|
||||||
|
|
||||||
| ENABLED | DISABLED
|
|
||||||
| CREATE SLOT | NOCREATE SLOT
|
|
||||||
| SLOT NAME = <replaceable class="PARAMETER">slot_name</replaceable>
|
|
||||||
| COPY DATA | NOCOPY DATA
|
|
||||||
| SYNCHRONOUS_COMMIT = <replaceable class="PARAMETER">synchronous_commit</replaceable>
|
|
||||||
| NOCONNECT
|
|
||||||
</synopsis>
|
</synopsis>
|
||||||
</refsynopsisdiv>
|
</refsynopsisdiv>
|
||||||
|
|
||||||
@ -59,7 +50,7 @@ CREATE SUBSCRIPTION <replaceable class="PARAMETER">subscription_name</replaceabl
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
<command>CREATE SUBSCRIPTION</command> cannot be executed inside a
|
<command>CREATE SUBSCRIPTION</command> cannot be executed inside a
|
||||||
transaction block when <literal>CREATE SLOT</literal> is specified.
|
transaction block when the parameter <literal>create_slot</literal> is specified.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -97,116 +88,129 @@ CREATE SUBSCRIPTION <replaceable class="PARAMETER">subscription_name</replaceabl
|
|||||||
<term><literal>PUBLICATION <replaceable class="parameter">publication_name</replaceable></literal></term>
|
<term><literal>PUBLICATION <replaceable class="parameter">publication_name</replaceable></literal></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Name(s) of the publications on the publisher to subscribe to.
|
Names of the publications on the publisher to subscribe to.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><literal>ENABLED</literal></term>
|
<term><literal>WITH ( <replaceable class="parameter">subscription_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] )</literal></term>
|
||||||
<term><literal>DISABLED</literal></term>
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Specifies whether the subscription should be actively replicating or
|
This clause specifies optional parameters for a subscription. The
|
||||||
if it should be just setup but not started yet. Note that the
|
following parameters are supported:
|
||||||
replication slot as described above is created in either case.
|
|
||||||
<literal>ENABLED</literal> is the default.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
<variablelist>
|
||||||
<term><literal>CREATE SLOT</literal></term>
|
<varlistentry>
|
||||||
<term><literal>NOCREATE SLOT</literal></term>
|
<term><literal>copy_data</literal> (<type>boolean</type>)</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Specifies whether the command should create the replication slot on the
|
Specifies whether the existing data in the publications that are
|
||||||
publisher. <literal>CREATE SLOT</literal> is the default.
|
being subscribed to should be copied once the replication starts.
|
||||||
</para>
|
The default is <literal>true</literal>.
|
||||||
</listitem>
|
</para>
|
||||||
</varlistentry>
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><literal>SLOT NAME = <replaceable class="parameter">slot_name</replaceable></literal></term>
|
<term><literal>create_slot</literal> (<type>boolean</type>)</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Name of the replication slot to use. The default behavior is to use
|
Specifies whether the command should create the replication slot on
|
||||||
<literal>subscription_name</> for slot name.
|
the publisher. The default is <literal>true</literal>.
|
||||||
</para>
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<para>
|
<varlistentry>
|
||||||
When <literal>SLOT NAME</literal> is set to
|
<term><literal>enabled</literal> (<type>boolean</type>)</term>
|
||||||
<literal>NONE</literal>, there will be no replication slot associated
|
<listitem>
|
||||||
with the subscription. This can be used if the replication slot will be
|
<para>
|
||||||
created later manually. Such subscriptions must also have both
|
Specifies whether the subscription should be actively replicating,
|
||||||
<literal>ENABLED</literal> and <literal>CREATE SLOT</literal> set
|
or whether it should be just setup but not started yet. The default
|
||||||
to <literal>false</literal>.
|
is <literal>true</literal>.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><literal>COPY DATA</literal></term>
|
<term><literal>slot_name</literal> (<type>string</type>)</term>
|
||||||
<term><literal>NOCOPY DATA</literal></term>
|
<listitem>
|
||||||
<listitem>
|
<para>
|
||||||
<para>
|
Name of the replication slot to use. The default behavior is to
|
||||||
Specifies if the existing data in the publications that are being
|
use the name of the subscription for the slot name.
|
||||||
subscribed to should be copied once the replication starts.
|
</para>
|
||||||
<literal>COPY DATA</literal> is the default.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
<para>
|
||||||
<term><literal>SYNCHRONOUS_COMMIT = <replaceable class="PARAMETER">synchronous_commit</replaceable></literal></term>
|
When <literal>slot_name</literal> is set to
|
||||||
<listitem>
|
<literal>NONE</literal>, there will be no replication slot
|
||||||
<para>
|
associated with the subscription. This can be used if the
|
||||||
The value of this parameter overrides the
|
replication slot will be created later manually. Such
|
||||||
<xref linkend="guc-synchronous-commit"> setting. The default value is
|
subscriptions must also have both <literal>enabled</literal> and
|
||||||
<literal>off</literal>.
|
<literal>create_slot</literal> set to <literal>false</literal>.
|
||||||
</para>
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<para>
|
<varlistentry>
|
||||||
It is safe to use <literal>off</literal> for logical replication: If the
|
<term><literal>synchronous_commit</literal> (<type>enum</type>)</term>
|
||||||
subscriber loses transactions because of missing synchronization, the
|
<listitem>
|
||||||
data will be resent from the publisher.
|
<para>
|
||||||
</para>
|
The value of this parameter overrides the
|
||||||
|
<xref linkend="guc-synchronous-commit"> setting. The default
|
||||||
|
value is <literal>off</literal>.
|
||||||
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
A different setting might be appropriate when doing synchronous logical
|
It is safe to use <literal>off</literal> for logical replication:
|
||||||
replication. The logical replication workers report the positions of
|
If the subscriber loses transactions because of missing
|
||||||
writes and flushes to the publisher, and when using synchronous
|
synchronization, the data will be resent from the publisher.
|
||||||
replication, the publisher will wait for the actual flush. This means
|
</para>
|
||||||
that setting <literal>SYNCHRONOUS_COMMIT</literal> for the subscriber
|
|
||||||
to <literal>off</literal> when the subscription is used for synchronous
|
|
||||||
replication might increase the latency for <command>COMMIT</command> on
|
|
||||||
the publisher. In this scenario, it can be advantageous to set
|
|
||||||
<literal>SYNCHRONOUS_COMMIT</literal> to <literal>local</literal> or
|
|
||||||
higher.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
<para>
|
||||||
<term><literal>NOCONNECT</literal></term>
|
A different setting might be appropriate when doing synchronous
|
||||||
<listitem>
|
logical replication. The logical replication workers report the
|
||||||
<para>
|
positions of writes and flushes to the publisher, and when using
|
||||||
Instructs <command>CREATE SUBSCRIPTION</command> to skip the initial
|
synchronous replication, the publisher will wait for the actual
|
||||||
connection to the provider. This will change default values of other
|
flush. This means that setting
|
||||||
options to <literal>DISABLED</literal>,
|
<literal>synchronous_commit</literal> for the subscriber to
|
||||||
<literal>NOCREATE SLOT</literal>, and <literal>NOCOPY DATA</literal>.
|
<literal>off</literal> when the subscription is used for
|
||||||
</para>
|
synchronous replication might increase the latency for
|
||||||
<para>
|
<command>COMMIT</command> on the publisher. In this scenario, it
|
||||||
It's not allowed to combine <literal>NOCONNECT</literal> and
|
can be advantageous to set <literal>synchronous_commit</literal>
|
||||||
<literal>ENABLED</literal>, <literal>CREATE SLOT</literal>, or
|
to <literal>local</literal> or higher.
|
||||||
<literal>COPY DATA</literal>.
|
</para>
|
||||||
</para>
|
</listitem>
|
||||||
<para>
|
</varlistentry>
|
||||||
Since no connection is made when this option is specified, the tables
|
|
||||||
are not subscribed, so after you enable the subscription nothing will
|
<varlistentry>
|
||||||
be replicated. It is required to run
|
<term><literal>connect</literal> (<type>boolean</type>)</term>
|
||||||
<literal>ALTER SUBSCRIPTION ... REFRESH PUBLICATION</> in order for
|
<listitem>
|
||||||
tables to be subscribed.
|
<para>
|
||||||
|
Specifies whether the <command>CREATE SUBSCRIPTION</command>
|
||||||
|
should connect to the publisher at all. Setting this to
|
||||||
|
<literal>false</literal> will change default values of
|
||||||
|
<literal>enabled</literal>, <literal>create_slot</literal> and
|
||||||
|
<literal>copy_data</literal> to <literal>false</literal>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
It is not allowed to combine <literal>connect</literal> set to
|
||||||
|
<literal>false</literal> and <literal>enabled</literal>,
|
||||||
|
<literal>create_slot</literal>, or <literal>copy_data</literal>
|
||||||
|
set to <literal>true</literal>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Since no connection is made when this option is specified, the
|
||||||
|
tables are not subscribed, and so after you enable the subscription
|
||||||
|
nothing will be replicated. It is required to run
|
||||||
|
<literal>ALTER SUBSCRIPTION ... REFRESH PUBLICATION</> in order
|
||||||
|
for tables to be subscribed.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -246,7 +250,7 @@ CREATE SUBSCRIPTION mysub
|
|||||||
CREATE SUBSCRIPTION mysub
|
CREATE SUBSCRIPTION mysub
|
||||||
CONNECTION 'host=192.168.1.50 port=5432 user=foo dbname=foodb'
|
CONNECTION 'host=192.168.1.50 port=5432 user=foo dbname=foodb'
|
||||||
PUBLICATION insert_only
|
PUBLICATION insert_only
|
||||||
WITH (DISABLED);
|
WITH (enabled = false);
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/rel.h"
|
#include "utils/rel.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
#include "utils/varlena.h"
|
||||||
|
|
||||||
/* Same as MAXNUMMESSAGES in sinvaladt.c */
|
/* Same as MAXNUMMESSAGES in sinvaladt.c */
|
||||||
#define MAX_RELCACHE_INVAL_MSGS 4096
|
#define MAX_RELCACHE_INVAL_MSGS 4096
|
||||||
@ -58,18 +59,14 @@ static void PublicationDropTables(Oid pubid, List *rels, bool missing_ok);
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
parse_publication_options(List *options,
|
parse_publication_options(List *options,
|
||||||
bool *publish_insert_given,
|
bool *publish_given,
|
||||||
bool *publish_insert,
|
bool *publish_insert,
|
||||||
bool *publish_update_given,
|
|
||||||
bool *publish_update,
|
bool *publish_update,
|
||||||
bool *publish_delete_given,
|
|
||||||
bool *publish_delete)
|
bool *publish_delete)
|
||||||
{
|
{
|
||||||
ListCell *lc;
|
ListCell *lc;
|
||||||
|
|
||||||
*publish_insert_given = false;
|
*publish_given = false;
|
||||||
*publish_update_given = false;
|
|
||||||
*publish_delete_given = false;
|
|
||||||
|
|
||||||
/* Defaults are true */
|
/* Defaults are true */
|
||||||
*publish_insert = true;
|
*publish_insert = true;
|
||||||
@ -81,68 +78,54 @@ parse_publication_options(List *options,
|
|||||||
{
|
{
|
||||||
DefElem *defel = (DefElem *) lfirst(lc);
|
DefElem *defel = (DefElem *) lfirst(lc);
|
||||||
|
|
||||||
if (strcmp(defel->defname, "publish insert") == 0)
|
if (strcmp(defel->defname, "publish") == 0)
|
||||||
{
|
{
|
||||||
if (*publish_insert_given)
|
char *publish;
|
||||||
|
List *publish_list;
|
||||||
|
ListCell *lc;
|
||||||
|
|
||||||
|
if (*publish_given)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||||
errmsg("conflicting or redundant options")));
|
errmsg("conflicting or redundant options")));
|
||||||
|
|
||||||
*publish_insert_given = true;
|
/*
|
||||||
*publish_insert = defGetBoolean(defel);
|
* If publish option was given only the explicitly listed actions
|
||||||
}
|
* should be published.
|
||||||
else if (strcmp(defel->defname, "nopublish insert") == 0)
|
*/
|
||||||
{
|
*publish_insert = false;
|
||||||
if (*publish_insert_given)
|
*publish_update = false;
|
||||||
|
*publish_delete = false;
|
||||||
|
|
||||||
|
*publish_given = true;
|
||||||
|
publish = defGetString(defel);
|
||||||
|
|
||||||
|
if (!SplitIdentifierString(publish, ',', &publish_list))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||||
errmsg("conflicting or redundant options")));
|
errmsg("invalid publish list")));
|
||||||
|
|
||||||
*publish_insert_given = true;
|
/* Process the option list. */
|
||||||
*publish_insert = !defGetBoolean(defel);
|
foreach (lc, publish_list)
|
||||||
}
|
{
|
||||||
else if (strcmp(defel->defname, "publish update") == 0)
|
char *publish_opt = (char *)lfirst(lc);
|
||||||
{
|
|
||||||
if (*publish_update_given)
|
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
|
||||||
errmsg("conflicting or redundant options")));
|
|
||||||
|
|
||||||
*publish_update_given = true;
|
if (strcmp(publish_opt, "insert") == 0)
|
||||||
*publish_update = defGetBoolean(defel);
|
*publish_insert = true;
|
||||||
}
|
else if (strcmp(publish_opt, "update") == 0)
|
||||||
else if (strcmp(defel->defname, "nopublish update") == 0)
|
*publish_update = true;
|
||||||
{
|
else if (strcmp(publish_opt, "delete") == 0)
|
||||||
if (*publish_update_given)
|
*publish_delete = true;
|
||||||
ereport(ERROR,
|
else
|
||||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
ereport(ERROR,
|
||||||
errmsg("conflicting or redundant options")));
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||||
|
errmsg("unrecognized \"publish\" value: \"%s\"", publish_opt)));
|
||||||
*publish_update_given = true;
|
}
|
||||||
*publish_update = !defGetBoolean(defel);
|
|
||||||
}
|
|
||||||
else if (strcmp(defel->defname, "publish delete") == 0)
|
|
||||||
{
|
|
||||||
if (*publish_delete_given)
|
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
|
||||||
errmsg("conflicting or redundant options")));
|
|
||||||
|
|
||||||
*publish_delete_given = true;
|
|
||||||
*publish_delete = defGetBoolean(defel);
|
|
||||||
}
|
|
||||||
else if (strcmp(defel->defname, "nopublish delete") == 0)
|
|
||||||
{
|
|
||||||
if (*publish_delete_given)
|
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
|
||||||
errmsg("conflicting or redundant options")));
|
|
||||||
|
|
||||||
*publish_delete_given = true;
|
|
||||||
*publish_delete = !defGetBoolean(defel);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
elog(ERROR, "unrecognized option: %s", defel->defname);
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||||
|
errmsg("unrecognized publication parameter: %s", defel->defname)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,9 +141,7 @@ CreatePublication(CreatePublicationStmt *stmt)
|
|||||||
bool nulls[Natts_pg_publication];
|
bool nulls[Natts_pg_publication];
|
||||||
Datum values[Natts_pg_publication];
|
Datum values[Natts_pg_publication];
|
||||||
HeapTuple tup;
|
HeapTuple tup;
|
||||||
bool publish_insert_given;
|
bool publish_given;
|
||||||
bool publish_update_given;
|
|
||||||
bool publish_delete_given;
|
|
||||||
bool publish_insert;
|
bool publish_insert;
|
||||||
bool publish_update;
|
bool publish_update;
|
||||||
bool publish_delete;
|
bool publish_delete;
|
||||||
@ -199,9 +180,8 @@ CreatePublication(CreatePublicationStmt *stmt)
|
|||||||
values[Anum_pg_publication_pubowner - 1] = ObjectIdGetDatum(GetUserId());
|
values[Anum_pg_publication_pubowner - 1] = ObjectIdGetDatum(GetUserId());
|
||||||
|
|
||||||
parse_publication_options(stmt->options,
|
parse_publication_options(stmt->options,
|
||||||
&publish_insert_given, &publish_insert,
|
&publish_given, &publish_insert,
|
||||||
&publish_update_given, &publish_update,
|
&publish_update, &publish_delete);
|
||||||
&publish_delete_given, &publish_delete);
|
|
||||||
|
|
||||||
values[Anum_pg_publication_puballtables - 1] =
|
values[Anum_pg_publication_puballtables - 1] =
|
||||||
BoolGetDatum(stmt->for_all_tables);
|
BoolGetDatum(stmt->for_all_tables);
|
||||||
@ -253,40 +233,30 @@ AlterPublicationOptions(AlterPublicationStmt *stmt, Relation rel,
|
|||||||
bool nulls[Natts_pg_publication];
|
bool nulls[Natts_pg_publication];
|
||||||
bool replaces[Natts_pg_publication];
|
bool replaces[Natts_pg_publication];
|
||||||
Datum values[Natts_pg_publication];
|
Datum values[Natts_pg_publication];
|
||||||
bool publish_insert_given;
|
bool publish_given;
|
||||||
bool publish_update_given;
|
|
||||||
bool publish_delete_given;
|
|
||||||
bool publish_insert;
|
bool publish_insert;
|
||||||
bool publish_update;
|
bool publish_update;
|
||||||
bool publish_delete;
|
bool publish_delete;
|
||||||
ObjectAddress obj;
|
ObjectAddress obj;
|
||||||
|
|
||||||
parse_publication_options(stmt->options,
|
parse_publication_options(stmt->options,
|
||||||
&publish_insert_given, &publish_insert,
|
&publish_given, &publish_insert,
|
||||||
&publish_update_given, &publish_update,
|
&publish_update, &publish_delete);
|
||||||
&publish_delete_given, &publish_delete);
|
|
||||||
|
|
||||||
/* Everything ok, form a new tuple. */
|
/* Everything ok, form a new tuple. */
|
||||||
memset(values, 0, sizeof(values));
|
memset(values, 0, sizeof(values));
|
||||||
memset(nulls, false, sizeof(nulls));
|
memset(nulls, false, sizeof(nulls));
|
||||||
memset(replaces, false, sizeof(replaces));
|
memset(replaces, false, sizeof(replaces));
|
||||||
|
|
||||||
if (publish_insert_given)
|
if (publish_given)
|
||||||
{
|
{
|
||||||
values[Anum_pg_publication_pubinsert - 1] =
|
values[Anum_pg_publication_pubinsert - 1] = BoolGetDatum(publish_insert);
|
||||||
BoolGetDatum(publish_insert);
|
|
||||||
replaces[Anum_pg_publication_pubinsert - 1] = true;
|
replaces[Anum_pg_publication_pubinsert - 1] = true;
|
||||||
}
|
|
||||||
if (publish_update_given)
|
values[Anum_pg_publication_pubupdate - 1] = BoolGetDatum(publish_update);
|
||||||
{
|
|
||||||
values[Anum_pg_publication_pubupdate - 1] =
|
|
||||||
BoolGetDatum(publish_update);
|
|
||||||
replaces[Anum_pg_publication_pubupdate - 1] = true;
|
replaces[Anum_pg_publication_pubupdate - 1] = true;
|
||||||
}
|
|
||||||
if (publish_delete_given)
|
values[Anum_pg_publication_pubdelete - 1] = BoolGetDatum(publish_delete);
|
||||||
{
|
|
||||||
values[Anum_pg_publication_pubdelete - 1] =
|
|
||||||
BoolGetDatum(publish_delete);
|
|
||||||
replaces[Anum_pg_publication_pubdelete - 1] = true;
|
replaces[Anum_pg_publication_pubdelete - 1] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ parse_subscription_options(List *options, bool *connect, bool *enabled_given,
|
|||||||
{
|
{
|
||||||
DefElem *defel = (DefElem *) lfirst(lc);
|
DefElem *defel = (DefElem *) lfirst(lc);
|
||||||
|
|
||||||
if (strcmp(defel->defname, "noconnect") == 0 && connect)
|
if (strcmp(defel->defname, "connect") == 0 && connect)
|
||||||
{
|
{
|
||||||
if (connect_given)
|
if (connect_given)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
@ -101,7 +101,7 @@ parse_subscription_options(List *options, bool *connect, bool *enabled_given,
|
|||||||
errmsg("conflicting or redundant options")));
|
errmsg("conflicting or redundant options")));
|
||||||
|
|
||||||
connect_given = true;
|
connect_given = true;
|
||||||
*connect = !defGetBoolean(defel);
|
*connect = defGetBoolean(defel);
|
||||||
}
|
}
|
||||||
else if (strcmp(defel->defname, "enabled") == 0 && enabled)
|
else if (strcmp(defel->defname, "enabled") == 0 && enabled)
|
||||||
{
|
{
|
||||||
@ -113,17 +113,7 @@ parse_subscription_options(List *options, bool *connect, bool *enabled_given,
|
|||||||
*enabled_given = true;
|
*enabled_given = true;
|
||||||
*enabled = defGetBoolean(defel);
|
*enabled = defGetBoolean(defel);
|
||||||
}
|
}
|
||||||
else if (strcmp(defel->defname, "disabled") == 0 && enabled)
|
else if (strcmp(defel->defname, "create_slot") == 0 && create_slot)
|
||||||
{
|
|
||||||
if (*enabled_given)
|
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
|
||||||
errmsg("conflicting or redundant options")));
|
|
||||||
|
|
||||||
*enabled_given = true;
|
|
||||||
*enabled = !defGetBoolean(defel);
|
|
||||||
}
|
|
||||||
else if (strcmp(defel->defname, "create slot") == 0 && create_slot)
|
|
||||||
{
|
{
|
||||||
if (create_slot_given)
|
if (create_slot_given)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
@ -133,17 +123,7 @@ parse_subscription_options(List *options, bool *connect, bool *enabled_given,
|
|||||||
create_slot_given = true;
|
create_slot_given = true;
|
||||||
*create_slot = defGetBoolean(defel);
|
*create_slot = defGetBoolean(defel);
|
||||||
}
|
}
|
||||||
else if (strcmp(defel->defname, "nocreate slot") == 0 && create_slot)
|
else if (strcmp(defel->defname, "slot_name") == 0 && slot_name)
|
||||||
{
|
|
||||||
if (create_slot_given)
|
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
|
||||||
errmsg("conflicting or redundant options")));
|
|
||||||
|
|
||||||
create_slot_given = true;
|
|
||||||
*create_slot = !defGetBoolean(defel);
|
|
||||||
}
|
|
||||||
else if (strcmp(defel->defname, "slot name") == 0 && slot_name)
|
|
||||||
{
|
{
|
||||||
if (*slot_name_given)
|
if (*slot_name_given)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
@ -157,7 +137,7 @@ parse_subscription_options(List *options, bool *connect, bool *enabled_given,
|
|||||||
if (strcmp(*slot_name, "none") == 0)
|
if (strcmp(*slot_name, "none") == 0)
|
||||||
*slot_name = NULL;
|
*slot_name = NULL;
|
||||||
}
|
}
|
||||||
else if (strcmp(defel->defname, "copy data") == 0 && copy_data)
|
else if (strcmp(defel->defname, "copy_data") == 0 && copy_data)
|
||||||
{
|
{
|
||||||
if (copy_data_given)
|
if (copy_data_given)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
@ -167,16 +147,6 @@ parse_subscription_options(List *options, bool *connect, bool *enabled_given,
|
|||||||
copy_data_given = true;
|
copy_data_given = true;
|
||||||
*copy_data = defGetBoolean(defel);
|
*copy_data = defGetBoolean(defel);
|
||||||
}
|
}
|
||||||
else if (strcmp(defel->defname, "nocopy data") == 0 && copy_data)
|
|
||||||
{
|
|
||||||
if (copy_data_given)
|
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
|
||||||
errmsg("conflicting or redundant options")));
|
|
||||||
|
|
||||||
copy_data_given = true;
|
|
||||||
*copy_data = !defGetBoolean(defel);
|
|
||||||
}
|
|
||||||
else if (strcmp(defel->defname, "synchronous_commit") == 0 &&
|
else if (strcmp(defel->defname, "synchronous_commit") == 0 &&
|
||||||
synchronous_commit)
|
synchronous_commit)
|
||||||
{
|
{
|
||||||
@ -336,7 +306,7 @@ CreateSubscription(CreateSubscriptionStmt *stmt, bool isTopLevel)
|
|||||||
* replication slot.
|
* replication slot.
|
||||||
*/
|
*/
|
||||||
if (create_slot)
|
if (create_slot)
|
||||||
PreventTransactionChain(isTopLevel, "CREATE SUBSCRIPTION ... CREATE SLOT");
|
PreventTransactionChain(isTopLevel, "CREATE SUBSCRIPTION ... WITH (create_slot = true)");
|
||||||
|
|
||||||
if (!superuser())
|
if (!superuser())
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
|
@ -338,7 +338,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
|
|||||||
database_name access_method_clause access_method attr_name
|
database_name access_method_clause access_method attr_name
|
||||||
name cursor_name file_name
|
name cursor_name file_name
|
||||||
index_name opt_index_name cluster_index_specification
|
index_name opt_index_name cluster_index_specification
|
||||||
def_key
|
|
||||||
|
|
||||||
%type <list> func_name handler_name qual_Op qual_all_Op subquery_Op
|
%type <list> func_name handler_name qual_Op qual_all_Op subquery_Op
|
||||||
opt_class opt_inline_handler opt_validator validator_clause
|
opt_class opt_inline_handler opt_validator validator_clause
|
||||||
@ -652,7 +651,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
|
|||||||
MAPPING MATCH MATERIALIZED MAXVALUE METHOD MINUTE_P MINVALUE MODE MONTH_P MOVE
|
MAPPING MATCH MATERIALIZED MAXVALUE METHOD MINUTE_P MINVALUE MODE MONTH_P MOVE
|
||||||
|
|
||||||
NAME_P NAMES NATIONAL NATURAL NCHAR NEW NEXT NO NONE
|
NAME_P NAMES NATIONAL NATURAL NCHAR NEW NEXT NO NONE
|
||||||
NOREFRESH NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLIF
|
NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLIF
|
||||||
NULLS_P NUMERIC
|
NULLS_P NUMERIC
|
||||||
|
|
||||||
OBJECT_P OF OFF OFFSET OIDS OLD ON ONLY OPERATOR OPTION OPTIONS OR
|
OBJECT_P OF OFF OFFSET OIDS OLD ON ONLY OPERATOR OPTION OPTIONS OR
|
||||||
@ -5673,21 +5672,16 @@ def_list: def_elem { $$ = list_make1($1); }
|
|||||||
| def_list ',' def_elem { $$ = lappend($1, $3); }
|
| def_list ',' def_elem { $$ = lappend($1, $3); }
|
||||||
;
|
;
|
||||||
|
|
||||||
def_elem: def_key '=' def_arg
|
def_elem: ColLabel '=' def_arg
|
||||||
{
|
{
|
||||||
$$ = makeDefElem($1, (Node *) $3, @1);
|
$$ = makeDefElem($1, (Node *) $3, @1);
|
||||||
}
|
}
|
||||||
| def_key
|
| ColLabel
|
||||||
{
|
{
|
||||||
$$ = makeDefElem($1, NULL, @1);
|
$$ = makeDefElem($1, NULL, @1);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
def_key:
|
|
||||||
ColLabel { $$ = $1; }
|
|
||||||
| ColLabel ColLabel { $$ = psprintf("%s %s", $1, $2); }
|
|
||||||
;
|
|
||||||
|
|
||||||
/* Note: any simple identifier will be returned as a type name! */
|
/* Note: any simple identifier will be returned as a type name! */
|
||||||
def_arg: func_type { $$ = (Node *)$1; }
|
def_arg: func_type { $$ = (Node *)$1; }
|
||||||
| reserved_keyword { $$ = (Node *)makeString(pstrdup($1)); }
|
| reserved_keyword { $$ = (Node *)makeString(pstrdup($1)); }
|
||||||
@ -9173,9 +9167,10 @@ publication_for_tables:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* ALTER PUBLICATION name [ WITH ] options
|
* ALTER PUBLICATION name SET ( options )
|
||||||
*
|
*
|
||||||
* ALTER PUBLICATION name ADD TABLE table [, table2]
|
* ALTER PUBLICATION name ADD TABLE table [, table2]
|
||||||
*
|
*
|
||||||
@ -9186,7 +9181,7 @@ publication_for_tables:
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
AlterPublicationStmt:
|
AlterPublicationStmt:
|
||||||
ALTER PUBLICATION name WITH definition
|
ALTER PUBLICATION name SET definition
|
||||||
{
|
{
|
||||||
AlterPublicationStmt *n = makeNode(AlterPublicationStmt);
|
AlterPublicationStmt *n = makeNode(AlterPublicationStmt);
|
||||||
n->pubname = $3;
|
n->pubname = $3;
|
||||||
@ -9254,12 +9249,12 @@ publication_name_item:
|
|||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* ALTER SUBSCRIPTION name [ WITH ] options
|
* ALTER SUBSCRIPTION name ...
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
AlterSubscriptionStmt:
|
AlterSubscriptionStmt:
|
||||||
ALTER SUBSCRIPTION name WITH definition
|
ALTER SUBSCRIPTION name SET definition
|
||||||
{
|
{
|
||||||
AlterSubscriptionStmt *n =
|
AlterSubscriptionStmt *n =
|
||||||
makeNode(AlterSubscriptionStmt);
|
makeNode(AlterSubscriptionStmt);
|
||||||
@ -9296,7 +9291,7 @@ AlterSubscriptionStmt:
|
|||||||
n->options = $8;
|
n->options = $8;
|
||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
| ALTER SUBSCRIPTION name SET PUBLICATION publication_name_list NOREFRESH
|
| ALTER SUBSCRIPTION name SET PUBLICATION publication_name_list SKIP REFRESH
|
||||||
{
|
{
|
||||||
AlterSubscriptionStmt *n =
|
AlterSubscriptionStmt *n =
|
||||||
makeNode(AlterSubscriptionStmt);
|
makeNode(AlterSubscriptionStmt);
|
||||||
@ -14758,7 +14753,6 @@ unreserved_keyword:
|
|||||||
| NEW
|
| NEW
|
||||||
| NEXT
|
| NEXT
|
||||||
| NO
|
| NO
|
||||||
| NOREFRESH
|
|
||||||
| NOTHING
|
| NOTHING
|
||||||
| NOTIFY
|
| NOTIFY
|
||||||
| NOWAIT
|
| NOWAIT
|
||||||
|
@ -3460,6 +3460,7 @@ dumpPublication(Archive *fout, PublicationInfo *pubinfo)
|
|||||||
PQExpBuffer delq;
|
PQExpBuffer delq;
|
||||||
PQExpBuffer query;
|
PQExpBuffer query;
|
||||||
PQExpBuffer labelq;
|
PQExpBuffer labelq;
|
||||||
|
bool first = true;
|
||||||
|
|
||||||
if (!(pubinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
|
if (!(pubinfo->dobj.dump & DUMP_COMPONENT_DEFINITION))
|
||||||
return;
|
return;
|
||||||
@ -3479,23 +3480,32 @@ dumpPublication(Archive *fout, PublicationInfo *pubinfo)
|
|||||||
if (pubinfo->puballtables)
|
if (pubinfo->puballtables)
|
||||||
appendPQExpBufferStr(query, " FOR ALL TABLES");
|
appendPQExpBufferStr(query, " FOR ALL TABLES");
|
||||||
|
|
||||||
appendPQExpBufferStr(query, " WITH (");
|
appendPQExpBufferStr(query, " WITH (publish = '");
|
||||||
if (pubinfo->pubinsert)
|
if (pubinfo->pubinsert)
|
||||||
appendPQExpBufferStr(query, "PUBLISH INSERT");
|
{
|
||||||
else
|
appendPQExpBufferStr(query, "insert");
|
||||||
appendPQExpBufferStr(query, "NOPUBLISH INSERT");
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!first)
|
||||||
|
appendPQExpBufferStr(query, ", ");
|
||||||
|
|
||||||
if (pubinfo->pubupdate)
|
if (pubinfo->pubupdate)
|
||||||
appendPQExpBufferStr(query, ", PUBLISH UPDATE");
|
{
|
||||||
else
|
appendPQExpBufferStr(query, "update");
|
||||||
appendPQExpBufferStr(query, ", NOPUBLISH UPDATE");
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!first)
|
||||||
|
appendPQExpBufferStr(query, ", ");
|
||||||
|
|
||||||
if (pubinfo->pubdelete)
|
if (pubinfo->pubdelete)
|
||||||
appendPQExpBufferStr(query, ", PUBLISH DELETE");
|
{
|
||||||
else
|
appendPQExpBufferStr(query, "delete");
|
||||||
appendPQExpBufferStr(query, ", NOPUBLISH DELETE");
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
appendPQExpBufferStr(query, ");\n");
|
appendPQExpBufferStr(query, "');\n");
|
||||||
|
|
||||||
ArchiveEntry(fout, pubinfo->dobj.catId, pubinfo->dobj.dumpId,
|
ArchiveEntry(fout, pubinfo->dobj.catId, pubinfo->dobj.dumpId,
|
||||||
pubinfo->dobj.name,
|
pubinfo->dobj.name,
|
||||||
@ -3817,11 +3827,11 @@ dumpSubscription(Archive *fout, SubscriptionInfo *subinfo)
|
|||||||
appendPQExpBufferStr(publications, fmtId(pubnames[i]));
|
appendPQExpBufferStr(publications, fmtId(pubnames[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
appendPQExpBuffer(query, " PUBLICATION %s WITH (NOCONNECT, SLOT NAME = ", publications->data);
|
appendPQExpBuffer(query, " PUBLICATION %s WITH (connect = false, slot_name = ", publications->data);
|
||||||
appendStringLiteralAH(query, subinfo->subslotname, fout);
|
appendStringLiteralAH(query, subinfo->subslotname, fout);
|
||||||
|
|
||||||
if (strcmp(subinfo->subsynccommit, "off") != 0)
|
if (strcmp(subinfo->subsynccommit, "off") != 0)
|
||||||
appendPQExpBuffer(query, ", SYNCHRONOUS_COMMIT = %s", fmtId(subinfo->subsynccommit));
|
appendPQExpBuffer(query, ", synchronous_commit = %s", fmtId(subinfo->subsynccommit));
|
||||||
|
|
||||||
appendPQExpBufferStr(query, ");\n");
|
appendPQExpBufferStr(query, ");\n");
|
||||||
|
|
||||||
|
@ -4351,7 +4351,7 @@ qr/CREATE TRANSFORM FOR integer LANGUAGE sql \(FROM SQL WITH FUNCTION pg_catalog
|
|||||||
create_order => 50,
|
create_order => 50,
|
||||||
create_sql => 'CREATE PUBLICATION pub1;',
|
create_sql => 'CREATE PUBLICATION pub1;',
|
||||||
regexp => qr/^
|
regexp => qr/^
|
||||||
\QCREATE PUBLICATION pub1 WITH (PUBLISH INSERT, PUBLISH UPDATE, PUBLISH DELETE);\E
|
\QCREATE PUBLICATION pub1 WITH (publish = 'insert, update, delete');\E
|
||||||
/xm,
|
/xm,
|
||||||
like => {
|
like => {
|
||||||
binary_upgrade => 1,
|
binary_upgrade => 1,
|
||||||
@ -4384,11 +4384,9 @@ qr/CREATE TRANSFORM FOR integer LANGUAGE sql \(FROM SQL WITH FUNCTION pg_catalog
|
|||||||
create_order => 50,
|
create_order => 50,
|
||||||
create_sql => 'CREATE PUBLICATION pub2
|
create_sql => 'CREATE PUBLICATION pub2
|
||||||
FOR ALL TABLES
|
FOR ALL TABLES
|
||||||
WITH (NOPUBLISH INSERT,
|
WITH (publish = \'\');',
|
||||||
NOPUBLISH UPDATE,
|
|
||||||
NOPUBLISH DELETE);',
|
|
||||||
regexp => qr/^
|
regexp => qr/^
|
||||||
\QCREATE PUBLICATION pub2 FOR ALL TABLES WITH (NOPUBLISH INSERT, NOPUBLISH UPDATE, NOPUBLISH DELETE);\E
|
\QCREATE PUBLICATION pub2 FOR ALL TABLES WITH (publish = '');\E
|
||||||
/xm,
|
/xm,
|
||||||
like => {
|
like => {
|
||||||
binary_upgrade => 1,
|
binary_upgrade => 1,
|
||||||
@ -4421,9 +4419,9 @@ qr/CREATE TRANSFORM FOR integer LANGUAGE sql \(FROM SQL WITH FUNCTION pg_catalog
|
|||||||
create_order => 50,
|
create_order => 50,
|
||||||
create_sql => 'CREATE SUBSCRIPTION sub1
|
create_sql => 'CREATE SUBSCRIPTION sub1
|
||||||
CONNECTION \'dbname=doesnotexist\' PUBLICATION pub1
|
CONNECTION \'dbname=doesnotexist\' PUBLICATION pub1
|
||||||
WITH (NOCONNECT);',
|
WITH (connect = false);',
|
||||||
regexp => qr/^
|
regexp => qr/^
|
||||||
\QCREATE SUBSCRIPTION sub1 CONNECTION 'dbname=doesnotexist' PUBLICATION pub1 WITH (NOCONNECT, SLOT NAME = 'sub1');\E
|
\QCREATE SUBSCRIPTION sub1 CONNECTION 'dbname=doesnotexist' PUBLICATION pub1 WITH (connect = false, slot_name = 'sub1');\E
|
||||||
/xm,
|
/xm,
|
||||||
like => {
|
like => {
|
||||||
binary_upgrade => 1,
|
binary_upgrade => 1,
|
||||||
|
@ -1504,28 +1504,27 @@ psql_completion(const char *text, int start, int end)
|
|||||||
COMPLETE_WITH_LIST6("WITH (", "ADD TABLE", "SET TABLE", "DROP TABLE",
|
COMPLETE_WITH_LIST6("WITH (", "ADD TABLE", "SET TABLE", "DROP TABLE",
|
||||||
"OWNER TO", "RENAME TO");
|
"OWNER TO", "RENAME TO");
|
||||||
}
|
}
|
||||||
/* ALTER PUBLICATION <name> .. WITH ( ... */
|
/* ALTER PUBLICATION <name> .. SET ( ... */
|
||||||
else if (HeadMatches3("ALTER", "PUBLICATION",MatchAny) && TailMatches2("WITH", "("))
|
else if (HeadMatches3("ALTER", "PUBLICATION",MatchAny) && TailMatches2("SET", "("))
|
||||||
{
|
{
|
||||||
COMPLETE_WITH_LIST6("PUBLISH INSERT", "NOPUBLISH INSERT", "PUBLISH UPDATE",
|
COMPLETE_WITH_CONST("publish");
|
||||||
"NOPUBLISH UPDATE", "PUBLISH DELETE", "NOPUBLISH DELETE");
|
|
||||||
}
|
}
|
||||||
/* ALTER SUBSCRIPTION <name> ... */
|
/* ALTER SUBSCRIPTION <name> ... */
|
||||||
else if (Matches3("ALTER","SUBSCRIPTION",MatchAny))
|
else if (Matches3("ALTER","SUBSCRIPTION",MatchAny))
|
||||||
{
|
{
|
||||||
COMPLETE_WITH_LIST8("WITH (", "CONNECTION", "SET PUBLICATION", "ENABLE",
|
COMPLETE_WITH_LIST8("SET (", "CONNECTION", "SET PUBLICATION", "ENABLE",
|
||||||
"DISABLE", "OWNER TO", "RENAME TO", "REFRESH PUBLICATION WITH (");
|
"DISABLE", "OWNER TO", "RENAME TO", "REFRESH PUBLICATION WITH (");
|
||||||
}
|
}
|
||||||
/* ALTER SUBSCRIPTION <name> REFRESH PUBLICATION WITH ( ... */
|
/* ALTER SUBSCRIPTION <name> REFRESH PUBLICATION WITH ( ... */
|
||||||
else if (HeadMatches3("ALTER", "SUBSCRIPTION", MatchAny) &&
|
else if (HeadMatches3("ALTER", "SUBSCRIPTION", MatchAny) &&
|
||||||
TailMatches4("REFRESH", "PUBLICATION", "WITH", "("))
|
TailMatches4("REFRESH", "PUBLICATION", "WITH", "("))
|
||||||
{
|
{
|
||||||
COMPLETE_WITH_LIST2("COPY DATA", "NOCOPY DATA");
|
COMPLETE_WITH_CONST("copy_data");
|
||||||
}
|
}
|
||||||
/* ALTER SUBSCRIPTION <name> .. WITH ( ... */
|
/* ALTER SUBSCRIPTION <name> .. SET ( ... */
|
||||||
else if (HeadMatches3("ALTER", "SUBSCRIPTION", MatchAny) && TailMatches2("WITH", "("))
|
else if (HeadMatches3("ALTER", "SUBSCRIPTION", MatchAny) && TailMatches2("SET", "("))
|
||||||
{
|
{
|
||||||
COMPLETE_WITH_CONST("SLOT NAME");
|
COMPLETE_WITH_CONST("slot_name");
|
||||||
}
|
}
|
||||||
/* ALTER SCHEMA <name> */
|
/* ALTER SCHEMA <name> */
|
||||||
else if (Matches3("ALTER", "SCHEMA", MatchAny))
|
else if (Matches3("ALTER", "SCHEMA", MatchAny))
|
||||||
@ -2349,9 +2348,7 @@ psql_completion(const char *text, int start, int end)
|
|||||||
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
|
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL);
|
||||||
/* Complete "CREATE PUBLICATION <name> [...] WITH" */
|
/* Complete "CREATE PUBLICATION <name> [...] WITH" */
|
||||||
else if (HeadMatches2("CREATE", "PUBLICATION") && TailMatches2("WITH", "("))
|
else if (HeadMatches2("CREATE", "PUBLICATION") && TailMatches2("WITH", "("))
|
||||||
COMPLETE_WITH_LIST2("PUBLISH", "NOPUBLISH");
|
COMPLETE_WITH_CONST("publish");
|
||||||
else if (HeadMatches2("CREATE", "PUBLICATION") && TailMatches3("WITH", "(", MatchAny))
|
|
||||||
COMPLETE_WITH_LIST3("INSERT", "UPDATE", "DELETE");
|
|
||||||
|
|
||||||
/* CREATE RULE */
|
/* CREATE RULE */
|
||||||
/* Complete "CREATE RULE <sth>" with "AS ON" */
|
/* Complete "CREATE RULE <sth>" with "AS ON" */
|
||||||
@ -2427,9 +2424,8 @@ psql_completion(const char *text, int start, int end)
|
|||||||
COMPLETE_WITH_CONST("WITH (");
|
COMPLETE_WITH_CONST("WITH (");
|
||||||
/* Complete "CREATE SUBSCRIPTION <name> ... WITH ( <opt>" */
|
/* Complete "CREATE SUBSCRIPTION <name> ... WITH ( <opt>" */
|
||||||
else if (HeadMatches2("CREATE", "SUBSCRIPTION") && TailMatches2("WITH", "("))
|
else if (HeadMatches2("CREATE", "SUBSCRIPTION") && TailMatches2("WITH", "("))
|
||||||
COMPLETE_WITH_LIST8("ENABLED", "DISABLED", "CREATE SLOT",
|
COMPLETE_WITH_LIST5("enabled", "create_slot", "slot_name",
|
||||||
"NOCREATE SLOT", "SLOT NAME", "COPY DATA", "NOCOPY DATA",
|
"copy_data", "connect");
|
||||||
"NOCONNECT");
|
|
||||||
|
|
||||||
/* CREATE TRIGGER --- is allowed inside CREATE SCHEMA, so use TailMatches */
|
/* CREATE TRIGGER --- is allowed inside CREATE SCHEMA, so use TailMatches */
|
||||||
/* complete CREATE TRIGGER <name> with BEFORE,AFTER,INSTEAD OF */
|
/* complete CREATE TRIGGER <name> with BEFORE,AFTER,INSTEAD OF */
|
||||||
|
@ -259,7 +259,6 @@ PG_KEYWORD("new", NEW, UNRESERVED_KEYWORD)
|
|||||||
PG_KEYWORD("next", NEXT, UNRESERVED_KEYWORD)
|
PG_KEYWORD("next", NEXT, UNRESERVED_KEYWORD)
|
||||||
PG_KEYWORD("no", NO, UNRESERVED_KEYWORD)
|
PG_KEYWORD("no", NO, UNRESERVED_KEYWORD)
|
||||||
PG_KEYWORD("none", NONE, COL_NAME_KEYWORD)
|
PG_KEYWORD("none", NONE, COL_NAME_KEYWORD)
|
||||||
PG_KEYWORD("norefresh", NOREFRESH, UNRESERVED_KEYWORD)
|
|
||||||
PG_KEYWORD("not", NOT, RESERVED_KEYWORD)
|
PG_KEYWORD("not", NOT, RESERVED_KEYWORD)
|
||||||
PG_KEYWORD("nothing", NOTHING, UNRESERVED_KEYWORD)
|
PG_KEYWORD("nothing", NOTHING, UNRESERVED_KEYWORD)
|
||||||
PG_KEYWORD("notify", NOTIFY, UNRESERVED_KEYWORD)
|
PG_KEYWORD("notify", NOTIFY, UNRESERVED_KEYWORD)
|
||||||
|
@ -69,7 +69,7 @@ CREATE SCHEMA dummy_seclabel_test;
|
|||||||
SECURITY LABEL ON SCHEMA dummy_seclabel_test IS 'unclassified'; -- OK
|
SECURITY LABEL ON SCHEMA dummy_seclabel_test IS 'unclassified'; -- OK
|
||||||
SET client_min_messages = error;
|
SET client_min_messages = error;
|
||||||
CREATE PUBLICATION dummy_pub;
|
CREATE PUBLICATION dummy_pub;
|
||||||
CREATE SUBSCRIPTION dummy_sub CONNECTION '' PUBLICATION foo WITH (NOCONNECT, SLOT NAME = NONE);
|
CREATE SUBSCRIPTION dummy_sub CONNECTION '' PUBLICATION foo WITH (connect = false, slot_name = NONE);
|
||||||
RESET client_min_messages;
|
RESET client_min_messages;
|
||||||
SECURITY LABEL ON PUBLICATION dummy_pub IS 'classified';
|
SECURITY LABEL ON PUBLICATION dummy_pub IS 'classified';
|
||||||
SECURITY LABEL ON SUBSCRIPTION dummy_sub IS 'classified';
|
SECURITY LABEL ON SUBSCRIPTION dummy_sub IS 'classified';
|
||||||
|
@ -73,7 +73,7 @@ SECURITY LABEL ON SCHEMA dummy_seclabel_test IS 'unclassified'; -- OK
|
|||||||
|
|
||||||
SET client_min_messages = error;
|
SET client_min_messages = error;
|
||||||
CREATE PUBLICATION dummy_pub;
|
CREATE PUBLICATION dummy_pub;
|
||||||
CREATE SUBSCRIPTION dummy_sub CONNECTION '' PUBLICATION foo WITH (NOCONNECT, SLOT NAME = NONE);
|
CREATE SUBSCRIPTION dummy_sub CONNECTION '' PUBLICATION foo WITH (connect = false, slot_name = NONE);
|
||||||
RESET client_min_messages;
|
RESET client_min_messages;
|
||||||
SECURITY LABEL ON PUBLICATION dummy_pub IS 'classified';
|
SECURITY LABEL ON PUBLICATION dummy_pub IS 'classified';
|
||||||
SECURITY LABEL ON SUBSCRIPTION dummy_sub IS 'classified';
|
SECURITY LABEL ON SUBSCRIPTION dummy_sub IS 'classified';
|
||||||
|
@ -37,7 +37,7 @@ CREATE TRANSFORM FOR int LANGUAGE SQL (
|
|||||||
FROM SQL WITH FUNCTION varchar_transform(internal),
|
FROM SQL WITH FUNCTION varchar_transform(internal),
|
||||||
TO SQL WITH FUNCTION int4recv(internal));
|
TO SQL WITH FUNCTION int4recv(internal));
|
||||||
CREATE PUBLICATION addr_pub FOR TABLE addr_nsp.gentable;
|
CREATE PUBLICATION addr_pub FOR TABLE addr_nsp.gentable;
|
||||||
CREATE SUBSCRIPTION addr_sub CONNECTION '' PUBLICATION bar WITH (NOCONNECT, SLOT NAME = NONE);
|
CREATE SUBSCRIPTION addr_sub CONNECTION '' PUBLICATION bar WITH (connect = false, slot_name = NONE);
|
||||||
WARNING: tables were not subscribed, you will have to run ALTER SUBSCRIPTION ... REFRESH PUBLICATION to subscribe the tables
|
WARNING: tables were not subscribed, you will have to run ALTER SUBSCRIPTION ... REFRESH PUBLICATION to subscribe the tables
|
||||||
CREATE STATISTICS addr_nsp.gentable_stat ON (a,b) FROM addr_nsp.gentable;
|
CREATE STATISTICS addr_nsp.gentable_stat ON (a,b) FROM addr_nsp.gentable;
|
||||||
-- test some error cases
|
-- test some error cases
|
||||||
|
@ -13,8 +13,13 @@ SELECT obj_description(p.oid, 'pg_publication') FROM pg_publication p;
|
|||||||
test publication
|
test publication
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
CREATE PUBLICATION testpib_ins_trunct WITH (nopublish delete, nopublish update);
|
CREATE PUBLICATION testpib_ins_trunct WITH (publish = insert);
|
||||||
ALTER PUBLICATION testpub_default WITH (nopublish insert, nopublish delete);
|
ALTER PUBLICATION testpub_default SET (publish = update);
|
||||||
|
-- error cases
|
||||||
|
CREATE PUBLICATION testpub_xxx WITH (foo);
|
||||||
|
ERROR: unrecognized publication parameter: foo
|
||||||
|
CREATE PUBLICATION testpub_xxx WITH (publish = 'cluster, vacuum');
|
||||||
|
ERROR: unrecognized "publish" value: "cluster"
|
||||||
\dRp
|
\dRp
|
||||||
List of publications
|
List of publications
|
||||||
Name | Owner | Inserts | Updates | Deletes
|
Name | Owner | Inserts | Updates | Deletes
|
||||||
@ -23,7 +28,7 @@ ALTER PUBLICATION testpub_default WITH (nopublish insert, nopublish delete);
|
|||||||
testpub_default | regress_publication_user | f | t | f
|
testpub_default | regress_publication_user | f | t | f
|
||||||
(2 rows)
|
(2 rows)
|
||||||
|
|
||||||
ALTER PUBLICATION testpub_default WITH (publish insert, publish delete);
|
ALTER PUBLICATION testpub_default SET (publish = 'insert, update, delete');
|
||||||
\dRp
|
\dRp
|
||||||
List of publications
|
List of publications
|
||||||
Name | Owner | Inserts | Updates | Deletes
|
Name | Owner | Inserts | Updates | Deletes
|
||||||
@ -38,8 +43,8 @@ CREATE TABLE testpub_tbl1 (id serial primary key, data text);
|
|||||||
CREATE TABLE pub_test.testpub_nopk (foo int, bar int);
|
CREATE TABLE pub_test.testpub_nopk (foo int, bar int);
|
||||||
CREATE VIEW testpub_view AS SELECT 1;
|
CREATE VIEW testpub_view AS SELECT 1;
|
||||||
CREATE TABLE testpub_parted (a int) PARTITION BY LIST (a);
|
CREATE TABLE testpub_parted (a int) PARTITION BY LIST (a);
|
||||||
CREATE PUBLICATION testpub_foralltables FOR ALL TABLES WITH (nopublish delete, nopublish update);
|
CREATE PUBLICATION testpub_foralltables FOR ALL TABLES WITH (publish = 'insert');
|
||||||
ALTER PUBLICATION testpub_foralltables WITH (publish update);
|
ALTER PUBLICATION testpub_foralltables SET (publish = 'insert, update');
|
||||||
CREATE TABLE testpub_tbl2 (id serial primary key, data text);
|
CREATE TABLE testpub_tbl2 (id serial primary key, data text);
|
||||||
-- fail - can't add to for all tables publication
|
-- fail - can't add to for all tables publication
|
||||||
ALTER PUBLICATION testpub_foralltables ADD TABLE testpub_tbl2;
|
ALTER PUBLICATION testpub_foralltables ADD TABLE testpub_tbl2;
|
||||||
|
@ -17,18 +17,18 @@ LINE 1: CREATE SUBSCRIPTION testsub PUBLICATION foo;
|
|||||||
^
|
^
|
||||||
-- fail - cannot do CREATE SUBSCRIPTION CREATE SLOT inside transaction block
|
-- fail - cannot do CREATE SUBSCRIPTION CREATE SLOT inside transaction block
|
||||||
BEGIN;
|
BEGIN;
|
||||||
CREATE SUBSCRIPTION testsub CONNECTION 'testconn' PUBLICATION testpub WITH (CREATE SLOT);
|
CREATE SUBSCRIPTION testsub CONNECTION 'testconn' PUBLICATION testpub WITH (create_slot);
|
||||||
ERROR: CREATE SUBSCRIPTION ... CREATE SLOT cannot run inside a transaction block
|
ERROR: CREATE SUBSCRIPTION ... WITH (create_slot = true) cannot run inside a transaction block
|
||||||
COMMIT;
|
COMMIT;
|
||||||
-- fail - invalid connection string
|
-- fail - invalid connection string
|
||||||
CREATE SUBSCRIPTION testsub CONNECTION 'testconn' PUBLICATION testpub;
|
CREATE SUBSCRIPTION testsub CONNECTION 'testconn' PUBLICATION testpub;
|
||||||
ERROR: invalid connection string syntax: missing "=" after "testconn" in connection info string
|
ERROR: invalid connection string syntax: missing "=" after "testconn" in connection info string
|
||||||
|
|
||||||
-- fail - duplicate publications
|
-- fail - duplicate publications
|
||||||
CREATE SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist' PUBLICATION foo, testpub, foo WITH (NOCONNECT);
|
CREATE SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist' PUBLICATION foo, testpub, foo WITH (connect = false);
|
||||||
ERROR: publication name "foo" used more than once
|
ERROR: publication name "foo" used more than once
|
||||||
-- ok
|
-- ok
|
||||||
CREATE SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (NOCONNECT);
|
CREATE SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (connect = false);
|
||||||
WARNING: tables were not subscribed, you will have to run ALTER SUBSCRIPTION ... REFRESH PUBLICATION to subscribe the tables
|
WARNING: tables were not subscribed, you will have to run ALTER SUBSCRIPTION ... REFRESH PUBLICATION to subscribe the tables
|
||||||
COMMENT ON SUBSCRIPTION testsub IS 'test subscription';
|
COMMENT ON SUBSCRIPTION testsub IS 'test subscription';
|
||||||
SELECT obj_description(s.oid, 'pg_subscription') FROM pg_subscription s;
|
SELECT obj_description(s.oid, 'pg_subscription') FROM pg_subscription s;
|
||||||
@ -38,11 +38,11 @@ SELECT obj_description(s.oid, 'pg_subscription') FROM pg_subscription s;
|
|||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- fail - name already exists
|
-- fail - name already exists
|
||||||
CREATE SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (NOCONNECT);
|
CREATE SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (connect = false);
|
||||||
ERROR: subscription "testsub" already exists
|
ERROR: subscription "testsub" already exists
|
||||||
-- fail - must be superuser
|
-- fail - must be superuser
|
||||||
SET SESSION AUTHORIZATION 'regress_subscription_user2';
|
SET SESSION AUTHORIZATION 'regress_subscription_user2';
|
||||||
CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION foo WITH (NOCONNECT);
|
CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION foo WITH (connect = false);
|
||||||
ERROR: must be superuser to create subscriptions
|
ERROR: must be superuser to create subscriptions
|
||||||
SET SESSION AUTHORIZATION 'regress_subscription_user';
|
SET SESSION AUTHORIZATION 'regress_subscription_user';
|
||||||
-- fail - invalid connection string
|
-- fail - invalid connection string
|
||||||
@ -56,9 +56,9 @@ ERROR: invalid connection string syntax: missing "=" after "foobar" in connecti
|
|||||||
testsub | regress_subscription_user | f | {testpub} | off | dbname=doesnotexist
|
testsub | regress_subscription_user | f | {testpub} | off | dbname=doesnotexist
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
ALTER SUBSCRIPTION testsub SET PUBLICATION testpub2, testpub3 NOREFRESH;
|
ALTER SUBSCRIPTION testsub SET PUBLICATION testpub2, testpub3 SKIP REFRESH;
|
||||||
ALTER SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist2';
|
ALTER SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist2';
|
||||||
ALTER SUBSCRIPTION testsub WITH (SLOT NAME = 'newname');
|
ALTER SUBSCRIPTION testsub SET (slot_name = 'newname');
|
||||||
-- fail
|
-- fail
|
||||||
ALTER SUBSCRIPTION doesnotexist CONNECTION 'dbname=doesnotexist2';
|
ALTER SUBSCRIPTION doesnotexist CONNECTION 'dbname=doesnotexist2';
|
||||||
ERROR: subscription "doesnotexist" does not exist
|
ERROR: subscription "doesnotexist" does not exist
|
||||||
@ -93,8 +93,8 @@ ALTER SUBSCRIPTION testsub RENAME TO testsub_dummy;
|
|||||||
ERROR: must be owner of subscription testsub
|
ERROR: must be owner of subscription testsub
|
||||||
RESET ROLE;
|
RESET ROLE;
|
||||||
ALTER SUBSCRIPTION testsub RENAME TO testsub_foo;
|
ALTER SUBSCRIPTION testsub RENAME TO testsub_foo;
|
||||||
ALTER SUBSCRIPTION testsub_foo WITH (SYNCHRONOUS_COMMIT = local);
|
ALTER SUBSCRIPTION testsub_foo SET (synchronous_commit = local);
|
||||||
ALTER SUBSCRIPTION testsub_foo WITH (SYNCHRONOUS_COMMIT = foobar);
|
ALTER SUBSCRIPTION testsub_foo SET (synchronous_commit = foobar);
|
||||||
ERROR: invalid value for parameter "synchronous_commit": "foobar"
|
ERROR: invalid value for parameter "synchronous_commit": "foobar"
|
||||||
HINT: Available values: local, remote_write, remote_apply, on, off.
|
HINT: Available values: local, remote_write, remote_apply, on, off.
|
||||||
\dRs+
|
\dRs+
|
||||||
@ -118,7 +118,7 @@ BEGIN;
|
|||||||
DROP SUBSCRIPTION testsub;
|
DROP SUBSCRIPTION testsub;
|
||||||
ERROR: DROP SUBSCRIPTION cannot run inside a transaction block
|
ERROR: DROP SUBSCRIPTION cannot run inside a transaction block
|
||||||
COMMIT;
|
COMMIT;
|
||||||
ALTER SUBSCRIPTION testsub WITH (SLOT NAME = NONE);
|
ALTER SUBSCRIPTION testsub SET (slot_name = NONE);
|
||||||
-- now it works
|
-- now it works
|
||||||
BEGIN;
|
BEGIN;
|
||||||
DROP SUBSCRIPTION testsub;
|
DROP SUBSCRIPTION testsub;
|
||||||
|
@ -40,7 +40,7 @@ CREATE TRANSFORM FOR int LANGUAGE SQL (
|
|||||||
FROM SQL WITH FUNCTION varchar_transform(internal),
|
FROM SQL WITH FUNCTION varchar_transform(internal),
|
||||||
TO SQL WITH FUNCTION int4recv(internal));
|
TO SQL WITH FUNCTION int4recv(internal));
|
||||||
CREATE PUBLICATION addr_pub FOR TABLE addr_nsp.gentable;
|
CREATE PUBLICATION addr_pub FOR TABLE addr_nsp.gentable;
|
||||||
CREATE SUBSCRIPTION addr_sub CONNECTION '' PUBLICATION bar WITH (NOCONNECT, SLOT NAME = NONE);
|
CREATE SUBSCRIPTION addr_sub CONNECTION '' PUBLICATION bar WITH (connect = false, slot_name = NONE);
|
||||||
CREATE STATISTICS addr_nsp.gentable_stat ON (a,b) FROM addr_nsp.gentable;
|
CREATE STATISTICS addr_nsp.gentable_stat ON (a,b) FROM addr_nsp.gentable;
|
||||||
|
|
||||||
-- test some error cases
|
-- test some error cases
|
||||||
|
@ -11,13 +11,17 @@ CREATE PUBLICATION testpub_default;
|
|||||||
COMMENT ON PUBLICATION testpub_default IS 'test publication';
|
COMMENT ON PUBLICATION testpub_default IS 'test publication';
|
||||||
SELECT obj_description(p.oid, 'pg_publication') FROM pg_publication p;
|
SELECT obj_description(p.oid, 'pg_publication') FROM pg_publication p;
|
||||||
|
|
||||||
CREATE PUBLICATION testpib_ins_trunct WITH (nopublish delete, nopublish update);
|
CREATE PUBLICATION testpib_ins_trunct WITH (publish = insert);
|
||||||
|
|
||||||
ALTER PUBLICATION testpub_default WITH (nopublish insert, nopublish delete);
|
ALTER PUBLICATION testpub_default SET (publish = update);
|
||||||
|
|
||||||
|
-- error cases
|
||||||
|
CREATE PUBLICATION testpub_xxx WITH (foo);
|
||||||
|
CREATE PUBLICATION testpub_xxx WITH (publish = 'cluster, vacuum');
|
||||||
|
|
||||||
\dRp
|
\dRp
|
||||||
|
|
||||||
ALTER PUBLICATION testpub_default WITH (publish insert, publish delete);
|
ALTER PUBLICATION testpub_default SET (publish = 'insert, update, delete');
|
||||||
|
|
||||||
\dRp
|
\dRp
|
||||||
|
|
||||||
@ -28,8 +32,8 @@ CREATE TABLE pub_test.testpub_nopk (foo int, bar int);
|
|||||||
CREATE VIEW testpub_view AS SELECT 1;
|
CREATE VIEW testpub_view AS SELECT 1;
|
||||||
CREATE TABLE testpub_parted (a int) PARTITION BY LIST (a);
|
CREATE TABLE testpub_parted (a int) PARTITION BY LIST (a);
|
||||||
|
|
||||||
CREATE PUBLICATION testpub_foralltables FOR ALL TABLES WITH (nopublish delete, nopublish update);
|
CREATE PUBLICATION testpub_foralltables FOR ALL TABLES WITH (publish = 'insert');
|
||||||
ALTER PUBLICATION testpub_foralltables WITH (publish update);
|
ALTER PUBLICATION testpub_foralltables SET (publish = 'insert, update');
|
||||||
|
|
||||||
CREATE TABLE testpub_tbl2 (id serial primary key, data text);
|
CREATE TABLE testpub_tbl2 (id serial primary key, data text);
|
||||||
-- fail - can't add to for all tables publication
|
-- fail - can't add to for all tables publication
|
||||||
|
@ -15,27 +15,27 @@ CREATE SUBSCRIPTION testsub PUBLICATION foo;
|
|||||||
|
|
||||||
-- fail - cannot do CREATE SUBSCRIPTION CREATE SLOT inside transaction block
|
-- fail - cannot do CREATE SUBSCRIPTION CREATE SLOT inside transaction block
|
||||||
BEGIN;
|
BEGIN;
|
||||||
CREATE SUBSCRIPTION testsub CONNECTION 'testconn' PUBLICATION testpub WITH (CREATE SLOT);
|
CREATE SUBSCRIPTION testsub CONNECTION 'testconn' PUBLICATION testpub WITH (create_slot);
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- fail - invalid connection string
|
-- fail - invalid connection string
|
||||||
CREATE SUBSCRIPTION testsub CONNECTION 'testconn' PUBLICATION testpub;
|
CREATE SUBSCRIPTION testsub CONNECTION 'testconn' PUBLICATION testpub;
|
||||||
|
|
||||||
-- fail - duplicate publications
|
-- fail - duplicate publications
|
||||||
CREATE SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist' PUBLICATION foo, testpub, foo WITH (NOCONNECT);
|
CREATE SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist' PUBLICATION foo, testpub, foo WITH (connect = false);
|
||||||
|
|
||||||
-- ok
|
-- ok
|
||||||
CREATE SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (NOCONNECT);
|
CREATE SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (connect = false);
|
||||||
|
|
||||||
COMMENT ON SUBSCRIPTION testsub IS 'test subscription';
|
COMMENT ON SUBSCRIPTION testsub IS 'test subscription';
|
||||||
SELECT obj_description(s.oid, 'pg_subscription') FROM pg_subscription s;
|
SELECT obj_description(s.oid, 'pg_subscription') FROM pg_subscription s;
|
||||||
|
|
||||||
-- fail - name already exists
|
-- fail - name already exists
|
||||||
CREATE SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (NOCONNECT);
|
CREATE SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (connect = false);
|
||||||
|
|
||||||
-- fail - must be superuser
|
-- fail - must be superuser
|
||||||
SET SESSION AUTHORIZATION 'regress_subscription_user2';
|
SET SESSION AUTHORIZATION 'regress_subscription_user2';
|
||||||
CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION foo WITH (NOCONNECT);
|
CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION foo WITH (connect = false);
|
||||||
SET SESSION AUTHORIZATION 'regress_subscription_user';
|
SET SESSION AUTHORIZATION 'regress_subscription_user';
|
||||||
|
|
||||||
-- fail - invalid connection string
|
-- fail - invalid connection string
|
||||||
@ -43,9 +43,9 @@ ALTER SUBSCRIPTION testsub CONNECTION 'foobar';
|
|||||||
|
|
||||||
\dRs+
|
\dRs+
|
||||||
|
|
||||||
ALTER SUBSCRIPTION testsub SET PUBLICATION testpub2, testpub3 NOREFRESH;
|
ALTER SUBSCRIPTION testsub SET PUBLICATION testpub2, testpub3 SKIP REFRESH;
|
||||||
ALTER SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist2';
|
ALTER SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist2';
|
||||||
ALTER SUBSCRIPTION testsub WITH (SLOT NAME = 'newname');
|
ALTER SUBSCRIPTION testsub SET (slot_name = 'newname');
|
||||||
|
|
||||||
-- fail
|
-- fail
|
||||||
ALTER SUBSCRIPTION doesnotexist CONNECTION 'dbname=doesnotexist2';
|
ALTER SUBSCRIPTION doesnotexist CONNECTION 'dbname=doesnotexist2';
|
||||||
@ -69,8 +69,8 @@ ALTER SUBSCRIPTION testsub RENAME TO testsub_dummy;
|
|||||||
RESET ROLE;
|
RESET ROLE;
|
||||||
|
|
||||||
ALTER SUBSCRIPTION testsub RENAME TO testsub_foo;
|
ALTER SUBSCRIPTION testsub RENAME TO testsub_foo;
|
||||||
ALTER SUBSCRIPTION testsub_foo WITH (SYNCHRONOUS_COMMIT = local);
|
ALTER SUBSCRIPTION testsub_foo SET (synchronous_commit = local);
|
||||||
ALTER SUBSCRIPTION testsub_foo WITH (SYNCHRONOUS_COMMIT = foobar);
|
ALTER SUBSCRIPTION testsub_foo SET (synchronous_commit = foobar);
|
||||||
|
|
||||||
\dRs+
|
\dRs+
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ BEGIN;
|
|||||||
DROP SUBSCRIPTION testsub;
|
DROP SUBSCRIPTION testsub;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
ALTER SUBSCRIPTION testsub WITH (SLOT NAME = NONE);
|
ALTER SUBSCRIPTION testsub SET (slot_name = NONE);
|
||||||
|
|
||||||
-- now it works
|
-- now it works
|
||||||
BEGIN;
|
BEGIN;
|
||||||
|
@ -40,7 +40,7 @@ my $publisher_connstr = $node_publisher->connstr . ' dbname=postgres';
|
|||||||
$node_publisher->safe_psql('postgres',
|
$node_publisher->safe_psql('postgres',
|
||||||
"CREATE PUBLICATION tap_pub");
|
"CREATE PUBLICATION tap_pub");
|
||||||
$node_publisher->safe_psql('postgres',
|
$node_publisher->safe_psql('postgres',
|
||||||
"CREATE PUBLICATION tap_pub_ins_only WITH (nopublish delete, nopublish update)");
|
"CREATE PUBLICATION tap_pub_ins_only WITH (publish = insert)");
|
||||||
$node_publisher->safe_psql('postgres',
|
$node_publisher->safe_psql('postgres',
|
||||||
"ALTER PUBLICATION tap_pub ADD TABLE tab_rep, tab_full");
|
"ALTER PUBLICATION tap_pub ADD TABLE tab_rep, tab_full");
|
||||||
$node_publisher->safe_psql('postgres',
|
$node_publisher->safe_psql('postgres',
|
||||||
@ -136,7 +136,7 @@ $node_publisher->poll_query_until('postgres',
|
|||||||
$oldpid = $node_publisher->safe_psql('postgres',
|
$oldpid = $node_publisher->safe_psql('postgres',
|
||||||
"SELECT pid FROM pg_stat_replication WHERE application_name = '$appname';");
|
"SELECT pid FROM pg_stat_replication WHERE application_name = '$appname';");
|
||||||
$node_subscriber->safe_psql('postgres',
|
$node_subscriber->safe_psql('postgres',
|
||||||
"ALTER SUBSCRIPTION tap_sub SET PUBLICATION tap_pub_ins_only REFRESH WITH (NOCOPY DATA)");
|
"ALTER SUBSCRIPTION tap_sub SET PUBLICATION tap_pub_ins_only REFRESH WITH (copy_data = false)");
|
||||||
$node_publisher->poll_query_until('postgres',
|
$node_publisher->poll_query_until('postgres',
|
||||||
"SELECT pid != $oldpid FROM pg_stat_replication WHERE application_name = '$appname';")
|
"SELECT pid != $oldpid FROM pg_stat_replication WHERE application_name = '$appname';")
|
||||||
or die "Timed out while waiting for apply to restart";
|
or die "Timed out while waiting for apply to restart";
|
||||||
@ -159,13 +159,13 @@ is($result, qq(20|-20|-1), 'check changes skipped after subscription publication
|
|||||||
|
|
||||||
# check alter publication (relcache invalidation etc)
|
# check alter publication (relcache invalidation etc)
|
||||||
$node_publisher->safe_psql('postgres',
|
$node_publisher->safe_psql('postgres',
|
||||||
"ALTER PUBLICATION tap_pub_ins_only WITH (publish delete)");
|
"ALTER PUBLICATION tap_pub_ins_only SET (publish = 'insert, delete')");
|
||||||
$node_publisher->safe_psql('postgres',
|
$node_publisher->safe_psql('postgres',
|
||||||
"ALTER PUBLICATION tap_pub_ins_only ADD TABLE tab_full");
|
"ALTER PUBLICATION tap_pub_ins_only ADD TABLE tab_full");
|
||||||
$node_publisher->safe_psql('postgres',
|
$node_publisher->safe_psql('postgres',
|
||||||
"DELETE FROM tab_ins WHERE a > 0");
|
"DELETE FROM tab_ins WHERE a > 0");
|
||||||
$node_subscriber->safe_psql('postgres',
|
$node_subscriber->safe_psql('postgres',
|
||||||
"ALTER SUBSCRIPTION tap_sub REFRESH PUBLICATION WITH (NOCOPY DATA)");
|
"ALTER SUBSCRIPTION tap_sub REFRESH PUBLICATION WITH (copy_data = false)");
|
||||||
$node_publisher->safe_psql('postgres',
|
$node_publisher->safe_psql('postgres',
|
||||||
"INSERT INTO tab_full VALUES(0)");
|
"INSERT INTO tab_full VALUES(0)");
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ $node_publisher->safe_psql('postgres',
|
|||||||
|
|
||||||
my $appname = 'tap_sub';
|
my $appname = 'tap_sub';
|
||||||
$node_subscriber->safe_psql('postgres',
|
$node_subscriber->safe_psql('postgres',
|
||||||
"CREATE SUBSCRIPTION tap_sub CONNECTION '$publisher_connstr application_name=$appname' PUBLICATION tap_pub WITH (SLOT NAME = tap_sub_slot)");
|
"CREATE SUBSCRIPTION tap_sub CONNECTION '$publisher_connstr application_name=$appname' PUBLICATION tap_pub WITH (slot_name = tap_sub_slot)");
|
||||||
|
|
||||||
# Wait for subscriber to finish initialization
|
# Wait for subscriber to finish initialization
|
||||||
my $caughtup_query =
|
my $caughtup_query =
|
||||||
|
@ -34,7 +34,7 @@ $node_publisher->safe_psql('postgres',
|
|||||||
|
|
||||||
my $appname = 'tap_sub';
|
my $appname = 'tap_sub';
|
||||||
$node_subscriber->safe_psql('postgres',
|
$node_subscriber->safe_psql('postgres',
|
||||||
"CREATE SUBSCRIPTION tap_sub CONNECTION '$publisher_connstr application_name=$appname' PUBLICATION tap_pub WITH (NOCOPY DATA)");
|
"CREATE SUBSCRIPTION tap_sub CONNECTION '$publisher_connstr application_name=$appname' PUBLICATION tap_pub WITH (copy_data = false)");
|
||||||
|
|
||||||
# Wait for subscriber to finish initialization
|
# Wait for subscriber to finish initialization
|
||||||
my $caughtup_query =
|
my $caughtup_query =
|
||||||
|
@ -82,7 +82,7 @@ is($result, qq(20), 'initial data synced for second sub');
|
|||||||
|
|
||||||
# now check another subscription for the same node pair
|
# now check another subscription for the same node pair
|
||||||
$node_subscriber->safe_psql('postgres',
|
$node_subscriber->safe_psql('postgres',
|
||||||
"CREATE SUBSCRIPTION tap_sub2 CONNECTION '$publisher_connstr application_name=$appname' PUBLICATION tap_pub WITH (NOCOPY DATA)");
|
"CREATE SUBSCRIPTION tap_sub2 CONNECTION '$publisher_connstr application_name=$appname' PUBLICATION tap_pub WITH (copy_data = false)");
|
||||||
|
|
||||||
# wait for it to start
|
# wait for it to start
|
||||||
$node_subscriber->poll_query_until('postgres', "SELECT pid IS NOT NULL FROM pg_stat_subscription WHERE subname = 'tap_sub2' AND relid IS NULL")
|
$node_subscriber->poll_query_until('postgres', "SELECT pid IS NOT NULL FROM pg_stat_subscription WHERE subname = 'tap_sub2' AND relid IS NULL")
|
||||||
|
Reference in New Issue
Block a user