diff --git a/docs/content/preview/api/ysql/syntax_resources/ysql_grammar.ebnf b/docs/content/preview/api/ysql/syntax_resources/ysql_grammar.ebnf index 9ceea8ee064b..aed2f5205168 100644 --- a/docs/content/preview/api/ysql/syntax_resources/ysql_grammar.ebnf +++ b/docs/content/preview/api/ysql/syntax_resources/ysql_grammar.ebnf @@ -266,6 +266,18 @@ alter_materialized_view_action = ( 'RENAME' 'TO' new_name | 'SET' 'TABLESPACE' tablespace_name ) ; +(* 'ALTER' 'PUBLICATION' *) +alter_publication = + 'ALTER' 'PUBLICATION' publication_name + [ alter_publication_action { ',' alter_publication_action } ] ; + +alter_publication_action = + 'ADD' 'TABLE' table_name { ',' table_name } | + 'SET' 'TABLE' table_name { ',' table_name } | + 'DROP' 'TABLE' table_name { ',' table_name } | + 'RENAME' 'TO' publication_name | + 'OWNER' 'TO' new_owner ; + (* 'ALTER' 'SCHEMA' *) alter_schema = 'ALTER' 'SCHEMA' schema_name ( 'RENAME' 'TO' new_name | @@ -630,6 +642,20 @@ create_procedure = 'CREATE' [ 'OR' 'REPLACE' ] 'PROCEDURE' (* ( 'TRANSFORM' ( 'FOR' 'TYPE' type_name ) { ',' ( 'FOR' 'TYPE' type_name ) } bllewell: n/a except with implementation langauges like C *) unalterable_proc_attribute = 'LANGUAGE' lang_name | 'AS' subprogram_implementation ; +(* 'CREATE' 'PUBLICATION' *) +create_publication = + 'CREATE' 'PUBLICATION' publication_name + [ 'FOR' publication_for_option ] ; + +publication_for_option = + 'TABLE' table_name { ',' table_name } | + 'ALL' 'TABLES' ; + +(* 'CREATE_REPLICATION_SLOT' *) +create_replication_slot = + 'CREATE_REPLICATION_SLOT' slot_name 'LOGICAL' output_plugin + [ 'NOEXPORT_SNAPSHOT' | 'USE_SNAPSHOT' ] ; + (* 'CREATE' 'RULE' *) create_rule = 'CREATE' [ 'OR' 'REPLACE' ] 'RULE' rule_name 'AS' 'ON' rule_event 'TO' table_name \ [ 'WHERE' boolean_expression ] @@ -960,6 +986,13 @@ drop_procedure = 'DROP' 'PROCEDURE' [ 'IF' 'EXISTS' ] \ { ',' ( subprogram_name '(' [ subprogram_signature ] ')' ) } [ 'CASCADE' | 'RESTRICT' ] ; +(* 'DROP' 'PUBLICATION' *) +drop_publication = 'DROP' 'PUBLICATION' [ 'IF' 'EXISTS' ] publication_name + [ 'CASCADE' | 'RESTRICT' ] ; + +(* DROP_REPLICATION_SLOT *) +drop_replication_slot = DROP_REPLICATION_SLOT slot_name ; + (* 'DROP' 'ROLE' *) drop_role = 'DROP' 'ROLE' [ 'IF' 'EXISTS' ] role_name { ',' role_name } ; @@ -1256,6 +1289,14 @@ show_stmt = 'SHOW' ( run_time_parameter | 'ALL' ) ; (* 'SHOW' 'TRANSACTION' *) show_transaction = 'SHOW' 'TRANSACTION' 'ISOLATION' 'LEVEL' ; +(* 'START_REPLICATION' *) +start_replication = + 'START_REPLICATION' 'SLOT' slot_name 'LOGICAL' log_sequence_number + [ '(' start_replication_option { ',' start_replication_option } ')' ] ; + +start_replication_option = + start_replication_option_name [ start_replication_option_value ] ; + (* 'START' 'TRANSACTION' *) start_transaction = 'START' 'TRANSACTION' { transaction_mode } ; @@ -1353,7 +1394,13 @@ having_clause = 'HAVING' ( boolean_expression ) ; qualified_name = name { '.' name } ; role_name = name ; database_name = name ; +log_sequence_number = text_literal ; (* Format: 'XXX/XXX' representing a log sequence number *) +output_plugin = name ; +publication_name = name ; schema_name = name ; +slot_name = name ; +start_replication_option_name = text_literal ; +start_replication_option_value = text_literal ; table_name = qualified_name ; cte_name = name ; column_name = name ; diff --git a/docs/content/preview/api/ysql/the-sql-language/statements/_index.md b/docs/content/preview/api/ysql/the-sql-language/statements/_index.md index effa66a1a962..3fc43ec506ec 100644 --- a/docs/content/preview/api/ysql/the-sql-language/statements/_index.md +++ b/docs/content/preview/api/ysql/the-sql-language/statements/_index.md @@ -27,6 +27,7 @@ The YSQL statements are compatible with the SQL dialect that PostgreSQL supports | [`ALTER FOREIGN TABLE`](ddl_alter_foreign_table) | Change foreign table definition | | [`ALTER INDEX`](ddl_alter_index) | Change index definition | | [`ALTER MATERIALIZED VIEW`](ddl_alter_matview) | Change materialized view definition | +| [`ALTER PUBLICATION`](ddl_alter_publication) | Change publication definition | | [`ALTER SEQUENCE`](ddl_alter_sequence) | Change sequence definition | | [`ALTER SERVER`](ddl_alter_server) | Change foreign server definition | | [`ALTER SCHEMA`](ddl_alter_schema) | Change schema definition | @@ -45,6 +46,7 @@ The YSQL statements are compatible with the SQL dialect that PostgreSQL supports | [`CREATE OPERATOR`](ddl_create_operator) | Create an operator | | [`CREATE OPERATOR CLASS`](ddl_create_operator_class) | Create an operator class | | [`CREATE PROCEDURE`](ddl_create_procedure) | Create a procedure | +| [`CREATE PUBLICATION`](ddl_create_publication) | Create a publication | | [`CREATE RULE`](ddl_create_rule) | Create a rule | | [`CREATE SCHEMA`](ddl_create_schema) | Create a schema (namespace) | | [`CREATE SEQUENCE`](ddl_create_sequence) | Create a sequence generator | @@ -69,6 +71,7 @@ The YSQL statements are compatible with the SQL dialect that PostgreSQL supports | [`DROP OPERATOR`](ddl_drop_operator) | Delete an operator | | [`DROP OPERATOR CLASS`](ddl_drop_operator_class) | Delete an operator class | | [`DROP PROCEDURE`](ddl_drop_procedure) | Delete a procedure | +| [`DROP PUBLICATION`](ddl_drop_publication) | Delete a publication | | [`DROP RULE`](ddl_drop_rule) | Delete a rule | | [`DROP SCHEMA`](ddl_drop_schema) | Delete a schema from the system | | [`DROP SEQUENCE`](ddl_drop_sequence) | Delete a sequence generator | @@ -153,6 +156,14 @@ The YSQL statements are compatible with the SQL dialect that PostgreSQL supports | [`EXPLAIN`](perf_explain) | Explain an execution plan for a statement | | [`PREPARE`](perf_prepare) | Prepare a statement | +## Streaming replication protocol statements + +| Statement | Description | +| :-------- | :---------- | +| [`CREATE_REPLICATION_SLOT`](streaming_create_repl_slot) | Create a replication slot | +| [`DROP_REPLICATION_SLOT`](streaming_drop_repl_slot) | Drop a replication slot | +| [`START_REPLICATION`](streaming_start_replication) | Start streaming from a replication slot | + ## Other statements | Statement | Description | diff --git a/docs/content/preview/api/ysql/the-sql-language/statements/ddl_alter_publication.md b/docs/content/preview/api/ysql/the-sql-language/statements/ddl_alter_publication.md new file mode 100644 index 000000000000..7c22acceb751 --- /dev/null +++ b/docs/content/preview/api/ysql/the-sql-language/statements/ddl_alter_publication.md @@ -0,0 +1,91 @@ +--- +title: ALTER PUBLICATION statement [YSQL] +headerTitle: ALTER PUBLICATION +linkTitle: ALTER PUBLICATION +description: Change properties of an existing publication. +menu: + preview: + identifier: ddl_alter_publication + parent: statements +type: docs +--- + +## Synopsis + +Use the `ALTER PUBLICATION` statement to change properties of an existing publication. + +## Syntax + +{{%ebnf%}} + alter_publication, + alter_publication_action +{{%/ebnf%}} + +## Semantics + +### *alter_publication_action* + +Specify one of the following actions. + +#### ADD TABLE *table_name { ',' table_name }* + +Add the specified tables to the publication. + +#### SET TABLE *table_name { ',' table_name }* + +Replace the list of tables/schemas in the publication with the specified list. The existing tables/schemas that were present in the publication will be removed. + +#### DROP TABLE *table_name { ',' table_name }* + +Remove the specified tables from the publication. + +#### RENAME TO *publication_name* + +Rename the publication name to the specified name. + +#### OWNER TO *new_owner* + +Change the owner of the publication to the *new_owner*. + +### Permissions + +To alter a publication, the invoking user must own the publication. Adding a table to a publication additionally requires owning that table. To alter the owner, you must also be a direct or indirect member of the new owning role. The new owner must have `CREATE` privilege on the database. Also, the new owner of a `FOR ALL TABLES` publication must be a superuser. However, a superuser can change the ownership of a publication regardless of these restrictions. + +## Examples + +Assume that you have created the tables `users`, `departments`, and `employees`. + +To create a publication `my_publication`, use the following command: + +```sql +yugabyte=# CREATE PUBLICATION my_publication FOR TABLE employees; +``` + +Add the `users` and `departments` tables to the publication `my_publication`: + +```sql +yugabyte=# ALTER PUBLICATION my_publication ADD TABLE users, departments; +``` + +Drop the `employees` table from the publication `my_publication`: + +```sql +yugabyte=# ALTER PUBLICATION my_publication DROP TABLE employees; +``` + +Set the `departments` table to be the only table in the publication `my_publication`. The table `users` will be removed from the publication as a result of the command. + +```sql +yugabyte=# ALTER PUBLICATION my_publication SET TABLE departments; +``` + +Rename the publication `my_publication` to `renamed_publication`. + +```sql +yugabyte=# ALTER PUBLICATION my_publication RENAME TO renamed_publication; +``` + +## See also + +- [`CREATE PUBLICATION`](../ddl_create_publication) +- [`DROP PUBLICATION`](../ddl_drop_publication) diff --git a/docs/content/preview/api/ysql/the-sql-language/statements/ddl_create_publication.md b/docs/content/preview/api/ysql/the-sql-language/statements/ddl_create_publication.md new file mode 100644 index 000000000000..d5f774e9b95a --- /dev/null +++ b/docs/content/preview/api/ysql/the-sql-language/statements/ddl_create_publication.md @@ -0,0 +1,81 @@ +--- +title: CREATE PUBLICATION [YSQL] +headerTitle: CREATE PUBLICATION +linkTitle: CREATE PUBLICATION +description: Use the CREATE PUBLICATION statement to create a publication in a database. +menu: + preview: + identifier: ddl_create_publication + parent: statements +type: docs +--- + +## Synopsis + +Use the `CREATE PUBLICATION` statement to create a publication in a database. A publication is a set of changes generated from a table or a group of tables, and might also be described as a change set or replication set. It defines the publication name and the tables included in it. + +## Syntax + +{{%ebnf%}} + create_publication, + publication_for_option +{{%/ebnf%}} + +## Semantics + +Create a publication with *publication_name*. If `publication_name` already exists in the specified database, an error will be raised. + +### Tables + +The `FOR TABLE` option specifies a list of tables to add to the publication while the `FOR ALL TABLES` option marks the publication as one that replicates changes for all tables in the database, including tables created in the future. + +If `FOR TABLE` or `FOR ALL TABLES` are not specified, then the publication starts out with an empty set of tables. This is useful if tables are to be added later. + +### Permissions + +To create a publication, the invoking user must have the `CREATE` privilege for the current database. (Superusers bypass this check.) + +To add a table to a publication, the invoking user must have ownership rights on the table. The `FOR ALL TABLES` clause requires the invoking user to be a **superuser**. + +### Limitations + +Publishing a subset of operations (create, update, delete, truncate) via a Publication is not currently supported. + +## Examples + +### Publication with two tables + +```sql +yugabyte=# CREATE PUBLICATION mypublication FOR TABLE users, departments; +``` + +In this example, the publication `mypublication` consists of two tables, `users` and `departments`. + +```sql{.nocopy} +yugabyte=# select * from pg_publication; + pubname | pubowner | puballtables | pubinsert | pubupdate | pubdelete | pubtruncate +---------------+----------+--------------+-----------+-----------+-----------+------------- + mypublication | 13250 | f | t | t | t | t +(1 row) +``` + +### Publication for all tables + +```sql +yugabyte=# CREATE PUBLICATION puballtables FOR ALL TABLES; +``` + +In this example, the publication `puballtables` includes all the current as well as future tables. + +```sql{.nocopy} +yugabyte=# select * from pg_publication; + pubname | pubowner | puballtables | pubinsert | pubupdate | pubdelete | pubtruncate +---------------+----------+--------------+-----------+-----------+-----------+------------- + puballtables | 13250 | t | t | t | t | t +(1 row) +``` + +## See also + +- [`ALTER PUBLICATION`](../ddl_alter_publication) +- [`DROP PUBLICATION`](../ddl_drop_publication) diff --git a/docs/content/preview/api/ysql/the-sql-language/statements/ddl_drop_publication.md b/docs/content/preview/api/ysql/the-sql-language/statements/ddl_drop_publication.md new file mode 100644 index 000000000000..fbb8024430c6 --- /dev/null +++ b/docs/content/preview/api/ysql/the-sql-language/statements/ddl_drop_publication.md @@ -0,0 +1,48 @@ +--- +title: DROP PUBLICATION statement [YSQL] +headerTitle: DROP PUBLICATION +linkTitle: DROP PUBLICATION +description: Use the DROP PUBLICATION statement to remove a publication from a database. +menu: + preview: + identifier: ddl_drop_publication + parent: statements +aliases: + - /preview/api/ysql/commands/ddl_drop_publication/ +type: docs +--- + +## Synopsis + +Use the `DROP PUBLICATION` statement to remove a publication from a database. + +## Syntax + +{{%ebnf%}} + drop_publication, +{{%/ebnf%}} + +## Semantics + +Drop a publication named *publication_name*. If `publication_name` doesn't exist in the specified database, an error will be raised unless the `IF EXISTS` clause is used. + +### RESTRICT / CASCADE + +These key words do not have any effect, since there are no dependencies on publications. + +### Permissions + +A publication can only be dropped by its owner or a superuser. + +## Examples + +Basic example. + +```sql +yugabyte=# DROP PUBLICATION mypublication; +``` + +## See also + +- [`CREATE PUBLICATION`](../ddl_create_publication) +- [`ALTER PUBLICATION`](../ddl_alter_publication) diff --git a/docs/content/preview/api/ysql/the-sql-language/statements/streaming_create_repl_slot.md b/docs/content/preview/api/ysql/the-sql-language/statements/streaming_create_repl_slot.md new file mode 100644 index 000000000000..67c5e00206e9 --- /dev/null +++ b/docs/content/preview/api/ysql/the-sql-language/statements/streaming_create_repl_slot.md @@ -0,0 +1,58 @@ +--- +title: CREATE_REPLICATION_SLOT statement [YSQL] +headerTitle: CREATE_REPLICATION_SLOT +linkTitle: CREATE_REPLICATION_SLOT +description: Use the CREATE_REPLICATION_SLOT statement to create a replication slot. +menu: + preview: + identifier: streaming_create_repl_slot + parent: statements +type: docs +--- + +## Synopsis + +Use the `CREATE_REPLICATION_SLOT` statement to create a replication slot. + +## Syntax + +{{%ebnf%}} + create_replication_slot +{{%/ebnf%}} + +## Semantics + +### *slot_name* + +The name of the replication slot. The name of the replication slot must be **unique across all databases**. + +### *output_plugin* + +The name of the output plugin used for logical decoding. + +### NOEXPORT_SNAPSHOT / USE_SNAPSHOT + +Decides what to do with the snapshot created during logical slot initialization. + +`USE_SNAPSHOT` indicates the intention of the client to consume the snapshot. This option must be used in a transaction, and `CREATE_REPLICATION_SLOT` must be the first command run in that transaction. + +`NOEXPORT_SNAPSHOT` will just use the snapshot for logical decoding as normal but won't do anything else with it. + +## Examples + +Create a Replication Slot with name *test_replication_slot* and use the `yboutput` plugin. + +```sql +yugabyte=# CREATE_REPLICATION_SLOT test_replication_slot LOGICAL yboutput; +``` + +Create a Replication Slot with name test_replication_slot and use the `pgoutput` plugin. + +```sql +yugabyte=# CREATE_REPLICATION_SLOT test_replication_slot LOGICAL pgoutput; +``` + +## See also + +- [`DROP_REPLICATION_SLOT`](../streaming_drop_repl_slot) +- [`START_REPLICATION`](../streaming_start_replication) diff --git a/docs/content/preview/api/ysql/the-sql-language/statements/streaming_drop_repl_slot.md b/docs/content/preview/api/ysql/the-sql-language/statements/streaming_drop_repl_slot.md new file mode 100644 index 000000000000..f4fe4b868997 --- /dev/null +++ b/docs/content/preview/api/ysql/the-sql-language/statements/streaming_drop_repl_slot.md @@ -0,0 +1,40 @@ +--- +title: DROP_REPLICATION_SLOT statement [YSQL] +headerTitle: DROP_REPLICATION_SLOT +linkTitle: DROP_REPLICATION_SLOT +description: Use the DROP_REPLICATION_SLOT statement to drop an existing replication slot. +menu: + preview: + identifier: streaming_drop_repl_slot + parent: statements +type: docs +--- + +## Synopsis + +Use the `DROP_REPLICATION_SLOT` statement to drop a replication slot. + +## Syntax + +{{%ebnf%}} + drop_replication_slot +{{%/ebnf%}} + +## Semantics + +### *slot_name* + +The name of the replication slot. + +## Examples + +Drop a replication slot. + +```sql +yugabyte=# DROP_REPLICATION_SLOT test_replication_slot; +``` + +## See also + +- [`CREATE_REPLICATION_SLOT`](../streaming_create_repl_slot) +- [`START_REPLICATION`](../streaming_start_replication) diff --git a/docs/content/preview/api/ysql/the-sql-language/statements/streaming_start_replication.md b/docs/content/preview/api/ysql/the-sql-language/statements/streaming_start_replication.md new file mode 100644 index 000000000000..dcb5d5677d25 --- /dev/null +++ b/docs/content/preview/api/ysql/the-sql-language/statements/streaming_start_replication.md @@ -0,0 +1,76 @@ +--- +title: START_REPLICATION statement [YSQL] +headerTitle: START_REPLICATION +linkTitle: START_REPLICATION +description: Use the START_REPLICATION statement to start streaming from a replication slot. +menu: + preview: + identifier: streaming_start_replication + parent: statements +type: docs +--- + +## Synopsis + +Use the `START_REPLICATION` command to start streaming changes from a logical replication slot. + +## Syntax + +{{%ebnf%}} + start_replication, + log_sequence_number, + replication_option +{{%/ebnf%}} + +## Semantics + +Instructs the server to start streaming WAL for logical replication. The output plugin associated with the selected slot is used to process the output for streaming. + +### *slot_name* + +The name of the slot to stream changes from. This parameter is required, and must correspond to an existing logical replication slot created with [`CREATE_REPLICATION_SLOT`](../streaming_create_repl_slot). + +### *log_sequence_number* + +The log sequence number from where to start the streaming from. + +### *start_replication_option_name* + +The name of an option passed to the slot's logical decoding plugin. + +The applicable options accepted by the command depends on the output plugin of the replication slot. They can be viewed in the respective documentation of the output plugin itself. + +For `pgoutput` and `yboutput`, check the section [53.5.1. Logical Streaming Replication Parameters](https://www.postgresql.org/docs/11/protocol-logical-replication.html) in the PG documentation. + +For `wal2json`, refer to the [plugin documentation](https://github.com/eulerto/wal2json/tree/master?tab=readme-ov-file#parameters). + +### *start_replication_option_value* + +Optional value, in the form of a string constant, associated with the specified option. + +## Example + +We need to follow a few steps before we can start streaming from a replication slot. Assume that a table with name `users` already exists in the database. + +Create a publication `mypublication` which includes the table `users`. + +```sql +yugabyte=# CREATE PUBLICATION mypublication FOR TABLE users; +``` + +Create a replication slot with name `test_slot` and output plugin `pgoutput`. + +```sql +yugabyte=# CREATE_REPLICATION_SLOT test_slot LOGICAL pgoutput; +``` + +Start replication from the `test_slot` replication slot starting from LSN `0/2`. We also pass the `publication_names` parameter with value `mypublication` to the output plugin. `publication_names` is an output plugin parameter that is accepted by both `pgoutput` and `yboutput` to determine the tables to stream the data from. + +```sql +yugabyte=# START_REPLICATION test_slot LOGICAL 0/2 publication_names 'mypublication'; +``` + +## See also + +- [`CREATE_REPLICATION_SLOT`](../streaming_create_repl_slot) +- [`DROP_REPLICATION_SLOT`](../streaming_drop_repl_slot)