diff --git a/docs/content/preview/architecture/transactions/read-restart-error.md b/docs/content/preview/architecture/transactions/read-restart-error.md index dd22c87623b4..ca08f91eeded 100644 --- a/docs/content/preview/architecture/transactions/read-restart-error.md +++ b/docs/content/preview/architecture/transactions/read-restart-error.md @@ -32,6 +32,35 @@ A detailed scenario that explains how clock skew can result in the above mention * It should return the data even if the client issued the read from a different node after writing the data, because the following guarantee needs to be maintained: the database should always return data that was committed in the past (past refers to the user-perceived past, and not based on machine clocks). - * It should not return the data if the write is performed in the future (that is, after the read point had been chosen) **and** had a write timestamp later than the read point. Because if that is allowed, everything written in future would be trivially visible to the read. Note that the latter condition is important because it is okay to return data that was written after the read point was picked, if the write timestamp was earlier than the read point (this doesn't break and consistency or isolation guarantees). + * It should not return the data if the write is performed in the future (that is, after the read point had been chosen) **and** had a write timestamp later than the read point. Because if that is allowed, everything written in future would be trivially visible to the read. Note that the latter condition is important because it is okay to return data that was written after the read point was picked, if the write timestamp was earlier than the read point (this doesn't break any consistency or isolation guarantees). * If node `N2` finds writes in the range `(T1, T1+max_clock_skew]`, to avoid breaking the strong guarantee that a reader should always be able to read what was committed earlier, and to avoid reading data with a later write timestamp which was also actually written after the read had been issued, node `N2` raises a `Read restart` error. + +## Troubleshooting + +You can handle and mitigate read restart errors using the following techniques: + +- Implement retry logic in the application. Application retries can help mitigate read restart errors. Moreover, a statement or a transaction may fail in other ways such as transaction conflicts or infrastructure failures. Therefore, a retry mechanism is strongly recommended for a cloud-native, distributed database such as YugabyteDB. +- Use SERIALIZABLE READ ONLY DEFERRABLE mode whenever possible. Read restart errors usually occur when the query is a SELECT statement with a large output footprint and there are concurrent writes that satisfy the SELECT statement. + + Using DEFERRABLE will avoid a read restart error altogether. However, the tradeoff is that the statement waits out the maximum permissible clock skew before reading the data (which is max_clock_skew_usec that has a default of 500ms). This is not an issue for large SELECT statements running in the background because latency is not a priority. + + Examples: + + Set transaction properties at the session level. + ```sql + SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE READ ONLY DEFERRABLE; + SELECT * FROM large_table; + ``` + + Enclose the offending query within a transaction block. + ```sql + BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE READ ONLY DEFERRABLE; + SELECT * FROM large_table; + COMMIT; + ``` +- Using read only, deferrable transactions is not always feasible, either because the query is not read only, or the query is part of a read-write transaction, or because an additional 500ms of latency is not acceptable. In these cases, try increasing the value of `ysql_output_buffer_size`. + + This will enable YugabyteDB to retry the query internally on behalf of the user. As long as the output of a statement hasn't crossed ysql_output_buffer_size to result in flushing partial data to the external client, the YSQL query layer retries read restart errors for all statements in a Read Committed transaction block, for the first statement in a Repeatable Read transaction block, and for any standalone statement outside a transaction block. As a tradeoff, increasing the buffer size also increases the memory consumed by the YSQL backend processes, resulting in a higher risk of out-of-memory errors. + + Be aware that increasing `ysql_output_buffer_size` is not a silver bullet. For example, the COPY command can still raise a read restart error even though the command has a one line output. Increasing `ysql_output_buffer_size` is not useful in this scenario. The application must retry the COPY command instead. Another example is DMLs such as INSERT/UPDATE/DELETE. These do not have enough output to overflow the buffer size. However, when these statements are executed in the middle of a REPEATABLE READ transaction (e.g. BEGIN ISOLATION LEVEL REPEATABLE READ; ... INSERT ... COMMIT;), a read restart error cannot be retried internally by YugabyteDB. The onus is on the application to ROLLBACK and retry the transaction. diff --git a/docs/content/preview/drivers-orms/java/yugabyte-jdbc.md b/docs/content/preview/drivers-orms/java/yugabyte-jdbc.md index ee491682ee6f..6fc8324c76c3 100644 --- a/docs/content/preview/drivers-orms/java/yugabyte-jdbc.md +++ b/docs/content/preview/drivers-orms/java/yugabyte-jdbc.md @@ -126,7 +126,7 @@ The following table describes the connection parameters required to connect, inc | user | User connecting to the database | yugabyte | password | User password | yugabyte | `load-balance` | [Uniform load balancing](../../smart-drivers/#cluster-aware-connection-load-balancing) | Defaults to upstream driver behavior unless set to 'true' -| `yb-servers-refresh-interval` | If `load_balance` is true, the interval in seconds to refresh the servers list | 300 +| `yb-servers-refresh-interval` | If `load-balance` is true, the interval in seconds to refresh the servers list | 300 | `topology-keys` | [Topology-aware load balancing](../../smart-drivers/#topology-aware-connection-load-balancing) | If `load-balance` is true, uses uniform load balancing unless set to comma-separated geo-locations in the form `cloud.region.zone`. The following is an example JDBC URL for connecting to YugabyteDB: diff --git a/docs/content/preview/drivers-orms/nodejs/yugabyte-node-driver.md b/docs/content/preview/drivers-orms/nodejs/yugabyte-node-driver.md index 44d1b4893ba7..31f31ad5138f 100644 --- a/docs/content/preview/drivers-orms/nodejs/yugabyte-node-driver.md +++ b/docs/content/preview/drivers-orms/nodejs/yugabyte-node-driver.md @@ -76,7 +76,7 @@ The following table describes the connection parameters required to connect, inc | user | Database user | yugabyte | | password | User password | yugabyte | | `loadBalance` | [Uniform load balancing](../../smart-drivers/#cluster-aware-connection-load-balancing) | Defaults to upstream driver behavior unless set to 'true' | -| `ybServersRefreshInterval` | If `load_balance` is true, the interval in seconds to refresh the node list | 300 +| `ybServersRefreshInterval` | If `loadBalance` is true, the interval in seconds to refresh the node list | 300 | `topologyKeys` | [Topology-aware load balancing](../../smart-drivers/#topology-aware-connection-load-balancing) | If `loadBalance` is true, uses uniform load balancing unless set to comma-separated geo-locations in the form `cloud.region.zone`. | Create a client to connect to the cluster using a connection string. The following is an example connection string for connecting to a YugabyteDB cluster with uniform and topology load balancing: diff --git a/docs/content/preview/secure/vulnerability-disclosure-policy.md b/docs/content/preview/secure/vulnerability-disclosure-policy.md index ad59bb679dc7..d28931b231cd 100644 --- a/docs/content/preview/secure/vulnerability-disclosure-policy.md +++ b/docs/content/preview/secure/vulnerability-disclosure-policy.md @@ -14,7 +14,7 @@ type: docs An important part of Yugabyte's strategy for building a secure platform for our users is vulnerability reporting. We value working with the broader security research community and understand that fostering that relationship will help Yugabyte improve its own security posture. We take vulnerabilities very seriously regardless of source, and strongly encourage people to report security vulnerabilities **privately to our security team** before disclosing them in a public forum. Our goal is to surface vulnerabilities and resolve them privately before they can be exploited. -## Our Commitment +## Our commitment 1. **In scope** We commit to investigate and address any reported issues, and request that you use the following process for the reporting of security vulnerabilities in the following products: @@ -30,7 +30,7 @@ An important part of Yugabyte's strategy for building a secure platform for our 1. We assure you that we will not initiate legal action against researchers who are acting in good faith and adhering to this process. -## The Process +## The process 1. **Report the Concern.** If you have any security concerns or would like to report undisclosed security vulnerabilities in our products or services, please email us at [security@yugabyte.com](mailto:security@yugabyte.com). Note that we do not accept bug reports at this address. @@ -49,7 +49,7 @@ An important part of Yugabyte's strategy for building a secure platform for our 1. **Use Common Sense.** Please use common sense when looking for security issues with our products. Attacking or compromising Yugabyte users' installations, or attacks on our infrastructure are not permitted. -## Next Steps +## Next steps 1. We will promptly investigate any reported issue. In certain cases, we may work privately with you to resolve the vulnerability. We may choose not to disclose information publicly while we investigate and mitigate any risk. @@ -81,18 +81,18 @@ Note that this policy covers only vulnerabilities in the query layer of PostgreS | Product | Name | Fixed in YugabyteDB version | Status | | :------ | :--- | :--------------------- | :----- | -| PostgreSQL (YSQL) | {{}} | | Not applicable | -| PostgreSQL (YSQL) | {{}} | | Not applicable | +| PostgreSQL (YSQL) | {{}} | | Not applicable: YugabyteDB only runs on Linux, this vulnerability is Windows-specific. | +| PostgreSQL (YSQL) | {{}} | | Not applicable: YugabyteDB only runs on Linux, this vulnerability is Windows-specific. | | PostgreSQL (YSQL) | {{}} | [v2.7.1](/preview/releases/ybdb-releases/end-of-life/v2.7/#v2-7-1-1-may-25-2021)| Resolved | | PostgreSQL (YSQL) | {{}} | [v2.12.11.0](/preview/releases/ybdb-releases/end-of-life/v2.12/#v2.12.11.0), {{}}, {{}} | Resolved | | PostgreSQL (YSQL) | {{}} | [v2.12.11.0](/preview/releases/ybdb-releases/end-of-life/v2.12/#v2.12.11.0), {{}}, {{}} | Resolved | | PostgreSQL (YSQL) | {{}} | [v2.12.11.0](/preview/releases/ybdb-releases/end-of-life/v2.12/#v2.12.11.0), {{}}, {{}} | Resolved | | PostgreSQL (YSQL) | {{}} | [v2.12.11.0](/preview/releases/ybdb-releases/end-of-life/v2.12/#v2.12.11.0), {{}}, {{}} | Resolved | -| PostgreSQL (YSQL) | {{}} | | Not applicable | -| PostgreSQL (YSQL) | {{}} | | Not applicable | -| PostgreSQL (YSQL) | {{}} | | Not applicable | -| PostgreSQL (YSQL) | {{}} | | Not applicable | -| PostgreSQL (YSQL) | {{}} | | Not applicable | +| PostgreSQL (YSQL) | {{}} | | Not applicable: YugabyteDB only runs on Linux, this vulnerability is Windows-specific. | +| PostgreSQL (YSQL) | {{}} | | Not applicable: YugabyteDB only runs on Linux, this vulnerability is Windows-specific. | +| PostgreSQL (YSQL) | {{}} | | Not applicable: pg_ctlcluster is not included in installation. | +| PostgreSQL (YSQL) | {{}} | | Not applicable: YugabyteDB only runs on Linux, this vulnerability is Windows-specific. | +| PostgreSQL (YSQL) | {{}} | | Not applicable: YugabyteDB does not use logical replication. | | PostgreSQL (YSQL) | {{}} | [v2.12.11.0](/preview/releases/ybdb-releases/end-of-life/v2.12/#v2.12.11.0), {{}}, {{}}, {{}}| Resolved | | PostgreSQL (YSQL) | {{}} | | Resolved | | PostgreSQL (YSQL) | {{}} | [v2.7.1](/preview/releases/ybdb-releases/end-of-life/v2.7/#v2-7-1-1-may-25-2021) or later | Resolved | @@ -111,5 +111,5 @@ Note that this policy covers only vulnerabilities in the query layer of PostgreS | PostgreSQL (YSQL) | {{}} | [v2.12.10.0](/preview/releases/ybdb-releases/end-of-life/v2.12/#v2.12.10.0), {{}}, {{}}| Resolved | | PostgreSQL (YSQL) | {{}} | {{}}| Resolved | | PostgreSQL (YSQL) | {{}} | {{}}, {{}}, {{}}, {{}}| Resolved | -| PostgreSQL (YSQL) | {{}} | | Not applicable | +| PostgreSQL (YSQL) | {{}} | | Not applicable: [aiven-extras](https://github.com/aiven/aiven-extras) is not included in installation. | | PostgreSQL (YSQL) | {{}} | {{}}, {{}}, {{}}, {{}}| Resolved | diff --git a/docs/content/stable/architecture/transactions/read-restart-error.md b/docs/content/stable/architecture/transactions/read-restart-error.md index 60b052e68282..d4c31b204e7e 100644 --- a/docs/content/stable/architecture/transactions/read-restart-error.md +++ b/docs/content/stable/architecture/transactions/read-restart-error.md @@ -32,6 +32,35 @@ A detailed scenario that explains how clock skew can result in the above mention * It should return the data even if the client issued the read from a different node after writing the data, because the following guarantee needs to be maintained: the database should always return data that was committed in the past (past refers to the user-perceived past, and not based on machine clocks). - * It should not return the data if the write is performed in the future (that is, after the read point had been chosen) **and** had a write timestamp later than the read point. Because if that is allowed, everything written in future would be trivially visible to the read. Note that the latter condition is important because it is okay to return data that was written after the read point was picked, if the write timestamp was earlier than the read point (this doesn't break and consistency or isolation guarantees). + * It should not return the data if the write is performed in the future (that is, after the read point had been chosen) **and** had a write timestamp later than the read point. Because if that is allowed, everything written in future would be trivially visible to the read. Note that the latter condition is important because it is okay to return data that was written after the read point was picked, if the write timestamp was earlier than the read point (this doesn't break any consistency or isolation guarantees). * If node `N2` finds writes in the range `(T1, T1+max_clock_skew]`, to avoid breaking the strong guarantee that a reader should always be able to read what was committed earlier, and to avoid reading data with a later write timestamp which was also actually written after the read had been issued, node `N2` raises a `Read restart` error. + +## Troubleshooting + +You can handle and mitigate read restart errors using the following techniques: + +- Implement retry logic in the application. Application retries can help mitigate read restart errors. Moreover, a statement or a transaction may fail in other ways such as transaction conflicts or infrastructure failures. Therefore, a retry mechanism is strongly recommended for a cloud-native, distributed database such as YugabyteDB. +- Use SERIALIZABLE READ ONLY DEFERRABLE mode whenever possible. Read restart errors usually occur when the query is a SELECT statement with a large output footprint and there are concurrent writes that satisfy the SELECT statement. + + Using DEFERRABLE will avoid a read restart error altogether. However, the tradeoff is that the statement waits out the maximum permissible clock skew before reading the data (which is max_clock_skew_usec that has a default of 500ms). This is not an issue for large SELECT statements running in the background because latency is not a priority. + + Examples: + + Set transaction properties at the session level. + ```sql + SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE READ ONLY DEFERRABLE; + SELECT * FROM large_table; + ``` + + Enclose the offending query within a transaction block. + ```sql + BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE READ ONLY DEFERRABLE; + SELECT * FROM large_table; + COMMIT; + ``` +- Using read only, deferrable transactions is not always feasible, either because the query is not read only, or the query is part of a read-write transaction, or because an additional 500ms of latency is not acceptable. In these cases, try increasing the value of `ysql_output_buffer_size`. + + This will enable YugabyteDB to retry the query internally on behalf of the user. As long as the output of a statement hasn't crossed ysql_output_buffer_size to result in flushing partial data to the external client, the YSQL query layer retries read restart errors for all statements in a Read Committed transaction block, for the first statement in a Repeatable Read transaction block, and for any standalone statement outside a transaction block. As a tradeoff, increasing the buffer size also increases the memory consumed by the YSQL backend processes, resulting in a higher risk of out-of-memory errors. + + Be aware that increasing `ysql_output_buffer_size` is not a silver bullet. For example, the COPY command can still raise a read restart error even though the command has a one line output. Increasing `ysql_output_buffer_size` is not useful in this scenario. The application must retry the COPY command instead. Another example is DMLs such as INSERT/UPDATE/DELETE. These do not have enough output to overflow the buffer size. However, when these statements are executed in the middle of a REPEATABLE READ transaction (e.g. BEGIN ISOLATION LEVEL REPEATABLE READ; ... INSERT ... COMMIT;), a read restart error cannot be retried internally by YugabyteDB. The onus is on the application to ROLLBACK and retry the transaction. diff --git a/docs/content/stable/drivers-orms/java/yugabyte-jdbc.md b/docs/content/stable/drivers-orms/java/yugabyte-jdbc.md index 23eb355a5671..b3e861166617 100644 --- a/docs/content/stable/drivers-orms/java/yugabyte-jdbc.md +++ b/docs/content/stable/drivers-orms/java/yugabyte-jdbc.md @@ -121,7 +121,7 @@ The following table describes the connection parameters required to connect, inc | user | User connecting to the database | yugabyte | password | User password | yugabyte | `load-balance` | [Uniform load balancing](../../smart-drivers/#cluster-aware-connection-load-balancing) | Defaults to upstream driver behavior unless set to 'true' -| `yb-servers-refresh-interval` | If `load_balance` is true, the interval in seconds to refresh the servers list | 300 +| `yb-servers-refresh-interval` | If `load-balance` is true, the interval in seconds to refresh the servers list | 300 | `topology-keys` | [Topology-aware load balancing](../../smart-drivers/#topology-aware-connection-load-balancing) | If `load-balance` is true, uses uniform load balancing unless set to comma-separated geo-locations in the form `cloud.region.zone`. The following is an example JDBC URL for connecting to YugabyteDB: diff --git a/docs/content/stable/drivers-orms/nodejs/yugabyte-node-driver.md b/docs/content/stable/drivers-orms/nodejs/yugabyte-node-driver.md index 1118e6af9031..35da9a937b49 100644 --- a/docs/content/stable/drivers-orms/nodejs/yugabyte-node-driver.md +++ b/docs/content/stable/drivers-orms/nodejs/yugabyte-node-driver.md @@ -76,7 +76,7 @@ The following table describes the connection parameters required to connect, inc | user | Database user | yugabyte | | password | User password | yugabyte | | `loadBalance` | [Uniform load balancing](../../smart-drivers/#cluster-aware-connection-load-balancing) | Defaults to upstream driver behavior unless set to 'true' | -| `ybServersRefreshInterval` | If `load_balance` is true, the interval in seconds to refresh the node list | 300 +| `ybServersRefreshInterval` | If `loadBalance` is true, the interval in seconds to refresh the node list | 300 | `topologyKeys` | [Topology-aware load balancing](../../smart-drivers/#topology-aware-connection-load-balancing) | If `loadBalance` is true, uses uniform load balancing unless set to comma-separated geo-locations in the form `cloud.region.zone`. | Create a client to connect to the cluster using a connection string. The following is an example connection string for connecting to a YugabyteDB cluster with uniform and topology load balancing: diff --git a/docs/content/v2.18/drivers-orms/java/yugabyte-jdbc.md b/docs/content/v2.18/drivers-orms/java/yugabyte-jdbc.md index 5d31be202861..494ddd507f83 100644 --- a/docs/content/v2.18/drivers-orms/java/yugabyte-jdbc.md +++ b/docs/content/v2.18/drivers-orms/java/yugabyte-jdbc.md @@ -114,7 +114,7 @@ The following table describes the connection parameters required to connect, inc | user | User connecting to the database | yugabyte | password | User password | yugabyte | `load-balance` | [Uniform load balancing](../../smart-drivers/#cluster-aware-connection-load-balancing) | Defaults to upstream driver behavior unless set to 'true' -| `yb-servers-refresh-interval` | If `load_balance` is true, the interval in seconds to refresh the servers list | 300 +| `yb-servers-refresh-interval` | If `load-balance` is true, the interval in seconds to refresh the servers list | 300 | `topology-keys` | [Topology-aware load balancing](../../smart-drivers/#topology-aware-connection-load-balancing) | If `load-balance` is true, uses uniform load balancing unless set to comma-separated geo-locations in the form `cloud.region.zone`. The following is an example JDBC URL for connecting to YugabyteDB: diff --git a/docs/content/v2.18/drivers-orms/nodejs/yugabyte-node-driver.md b/docs/content/v2.18/drivers-orms/nodejs/yugabyte-node-driver.md index 0c936d68fa0d..c395a1fdfa0f 100644 --- a/docs/content/v2.18/drivers-orms/nodejs/yugabyte-node-driver.md +++ b/docs/content/v2.18/drivers-orms/nodejs/yugabyte-node-driver.md @@ -76,7 +76,7 @@ The following table describes the connection parameters required to connect, inc | user | Database user | yugabyte | | password | User password | yugabyte | | `loadBalance` | [Uniform load balancing](../../smart-drivers/#cluster-aware-connection-load-balancing) | Defaults to upstream driver behavior unless set to 'true' | -| `ybServersRefreshInterval` | If `load_balance` is true, the interval in seconds to refresh the node list | 300 +| `ybServersRefreshInterval` | If `loadBalance` is true, the interval in seconds to refresh the node list | 300 | `topologyKeys` | [Topology-aware load balancing](../../smart-drivers/#topology-aware-connection-load-balancing) | If `loadBalance` is true, uses uniform load balancing unless set to comma-separated geo-locations in the form `cloud.region.zone`. | Create a client to connect to the cluster using a connection string. The following is an example connection string for connecting to a YugabyteDB cluster with uniform and topology load balancing: diff --git a/docs/content/v2.20/drivers-orms/java/yugabyte-jdbc.md b/docs/content/v2.20/drivers-orms/java/yugabyte-jdbc.md index 277961d39963..31f719b477fc 100644 --- a/docs/content/v2.20/drivers-orms/java/yugabyte-jdbc.md +++ b/docs/content/v2.20/drivers-orms/java/yugabyte-jdbc.md @@ -114,7 +114,7 @@ The following table describes the connection parameters required to connect, inc | user | User connecting to the database | yugabyte | password | User password | yugabyte | `load-balance` | [Uniform load balancing](../../smart-drivers/#cluster-aware-connection-load-balancing) | Defaults to upstream driver behavior unless set to 'true' -| `yb-servers-refresh-interval` | If `load_balance` is true, the interval in seconds to refresh the servers list | 300 +| `yb-servers-refresh-interval` | If `load-balance` is true, the interval in seconds to refresh the servers list | 300 | `topology-keys` | [Topology-aware load balancing](../../smart-drivers/#topology-aware-connection-load-balancing) | If `load-balance` is true, uses uniform load balancing unless set to comma-separated geo-locations in the form `cloud.region.zone`. The following is an example JDBC URL for connecting to YugabyteDB: diff --git a/docs/content/v2.20/drivers-orms/nodejs/yugabyte-node-driver.md b/docs/content/v2.20/drivers-orms/nodejs/yugabyte-node-driver.md index 9759e9271215..782c722ed5c1 100644 --- a/docs/content/v2.20/drivers-orms/nodejs/yugabyte-node-driver.md +++ b/docs/content/v2.20/drivers-orms/nodejs/yugabyte-node-driver.md @@ -76,7 +76,7 @@ The following table describes the connection parameters required to connect, inc | user | Database user | yugabyte | | password | User password | yugabyte | | `loadBalance` | [Uniform load balancing](../../smart-drivers/#cluster-aware-connection-load-balancing) | Defaults to upstream driver behavior unless set to 'true' | -| `ybServersRefreshInterval` | If `load_balance` is true, the interval in seconds to refresh the node list | 300 +| `ybServersRefreshInterval` | If `loadBalance` is true, the interval in seconds to refresh the node list | 300 | `topologyKeys` | [Topology-aware load balancing](../../smart-drivers/#topology-aware-connection-load-balancing) | If `loadBalance` is true, uses uniform load balancing unless set to comma-separated geo-locations in the form `cloud.region.zone`. | Create a client to connect to the cluster using a connection string. The following is an example connection string for connecting to a YugabyteDB cluster with uniform and topology load balancing: diff --git a/java/yb-pgsql/src/test/java/org/yb/pgsql/TestPgReplicationSlot.java b/java/yb-pgsql/src/test/java/org/yb/pgsql/TestPgReplicationSlot.java index f16f3035ee3a..1932d707e17e 100644 --- a/java/yb-pgsql/src/test/java/org/yb/pgsql/TestPgReplicationSlot.java +++ b/java/yb-pgsql/src/test/java/org/yb/pgsql/TestPgReplicationSlot.java @@ -920,9 +920,12 @@ void replicationConnectionConsumptionAllDataTypes(String pluginName) throws Exce + "col_tsrange TSRANGE, " + "col_tstzrange TSTZRANGE, " + "col_daterange DATERANGE, " - + "col_discount coupon_discount_type)"; + + "col_hstore HSTORE, " + + "col_discount coupon_discount_type, " + +" col_discount_array coupon_discount_type[])"; try (Statement stmt = connection.createStatement()) { + stmt.execute("CREATE EXTENSION IF NOT EXISTS hstore;"); stmt.execute("CREATE TYPE coupon_discount_type AS ENUM ('FIXED', 'PERCENTAGE');"); stmt.execute(create_stmt); if (pluginName.equals(PG_OUTPUT_PLUGIN_NAME)) { @@ -948,7 +951,8 @@ void replicationConnectionConsumptionAllDataTypes(String pluginName) throws Exce + "'550e8400-e29b-41d4-a716-446655440000', B'101010', '2024-02-01 12:34:56+00:00', " + "'[1,10)', '[100,1000)', '[2024-01-01, 2024-12-31)', " + "'[2024-01-01 00:00:00+00:00, 2024-12-31 15:59:59+00:00)', " - + "'[2024-01-01, 2024-12-31)', 'FIXED');"); + + "'[2024-01-01, 2024-12-31)','key1 => value1, key2 => value2'::hstore, 'FIXED', " + + "array['FIXED', 'PERCENTAGE']::coupon_discount_type[]);"); } PGReplicationStream stream = replConnection.replicationStream() @@ -961,12 +965,14 @@ void replicationConnectionConsumptionAllDataTypes(String pluginName) throws Exce List result = new ArrayList(); // 1 Relation, begin, type, insert and commit record. - result.addAll(receiveMessage(stream, 5)); + result.addAll(receiveMessage(stream, 7)); List expectedResult = new ArrayList() { { add(PgOutputBeginMessage.CreateForComparison(LogSequenceNumber.valueOf("0/4"), 2)); + add(PgOutputTypeMessage.CreateForComparison("public", "hstore")); add(PgOutputTypeMessage.CreateForComparison("public", "coupon_discount_type")); + add(PgOutputTypeMessage.CreateForComparison("public", "_coupon_discount_type")); if (pluginName.equals(YB_OUTPUT_PLUGIN_NAME)) { add(PgOutputRelationMessage.CreateForComparison("public", "test_table", 'c', Arrays.asList(PgOutputRelationMessageColumn.CreateForComparison("a", 23), @@ -1004,8 +1010,15 @@ void replicationConnectionConsumptionAllDataTypes(String pluginName) throws Exce PgOutputRelationMessageColumn.CreateForComparison("col_tsrange", 3908), PgOutputRelationMessageColumn.CreateForComparison("col_tstzrange", 3910), PgOutputRelationMessageColumn.CreateForComparison("col_daterange", 3912), + // The Oids for columns below are not fixed. Changing the order of creation of + // objects (extensions, tables etc.) in the test will change these Oids. Hence, + // skip comparing the Oids of these types. PgOutputRelationMessageColumn.CreateForComparison( - "col_discount", /* IGNORED */ 0, /* compareDataType */ false)))); + "col_hstore", 16385, /* compareDataType */ false), + PgOutputRelationMessageColumn.CreateForComparison( + "col_discount", 16518, /* compareDataType */ false), + PgOutputRelationMessageColumn.CreateForComparison( + "col_discount_array", 16517, /* compareDataType */ false)))); } else { // The replica identity for test_table in case of pgoutput is DEFAULT. add(PgOutputRelationMessage.CreateForComparison("public", "test_table", 'd', @@ -1044,10 +1057,17 @@ void replicationConnectionConsumptionAllDataTypes(String pluginName) throws Exce PgOutputRelationMessageColumn.CreateForComparison("col_tsrange", 3908), PgOutputRelationMessageColumn.CreateForComparison("col_tstzrange", 3910), PgOutputRelationMessageColumn.CreateForComparison("col_daterange", 3912), + // The Oids for columns below are not fixed. Changing the order of creation of + // objects (extensions, tables etc.) in the test will change these Oids. Hence, + // skip comparing the Oids of these types. + PgOutputRelationMessageColumn.CreateForComparison( + "col_hstore", 16385, /* compareDataType */ false), + PgOutputRelationMessageColumn.CreateForComparison( + "col_discount", 16518, /* compareDataType */ false), PgOutputRelationMessageColumn.CreateForComparison( - "col_discount", /* IGNORED */ 0, /* compareDataType */ false)))); + "col_discount_array", 16517, /* compareDataType */ false)))); } - add(PgOutputInsertMessage.CreateForComparison(new PgOutputMessageTuple((short) 36, + add(PgOutputInsertMessage.CreateForComparison(new PgOutputMessageTuple((short) 38, Arrays.asList(new PgOutputMessageTupleColumnValue("1"), new PgOutputMessageTupleColumnValue("110110"), new PgOutputMessageTupleColumnValue("t"), @@ -1087,7 +1107,9 @@ void replicationConnectionConsumptionAllDataTypes(String pluginName) throws Exce convertTimestampToSystemTimezone("2024-01-01T00:00:00.00Z"), convertTimestampToSystemTimezone("2024-12-31T15:59:59.00Z"))), new PgOutputMessageTupleColumnValue("[2024-01-01,2024-12-31)"), - new PgOutputMessageTupleColumnValue("FIXED"))))); + new PgOutputMessageTupleColumnValue("\"key1\"=>\"value1\", \"key2\"=>\"value2\""), + new PgOutputMessageTupleColumnValue("FIXED"), + new PgOutputMessageTupleColumnValue("{FIXED,PERCENTAGE}"))))); add(PgOutputCommitMessage.CreateForComparison( LogSequenceNumber.valueOf("0/4"), LogSequenceNumber.valueOf("0/5"))); } diff --git a/managed/src/main/java/api/v2/controllers/UniverseApiControllerImp.java b/managed/src/main/java/api/v2/controllers/UniverseApiControllerImp.java index eeacfa4f1392..2502809742c8 100644 --- a/managed/src/main/java/api/v2/controllers/UniverseApiControllerImp.java +++ b/managed/src/main/java/api/v2/controllers/UniverseApiControllerImp.java @@ -10,6 +10,7 @@ import api.v2.models.UniverseDeleteSpec; import api.v2.models.UniverseEditEncryptionInTransit; import api.v2.models.UniverseEditGFlags; +import api.v2.models.UniverseEditKubernetesOverrides; import api.v2.models.UniverseEditSpec; import api.v2.models.UniverseRestart; import api.v2.models.UniverseRollbackUpgradeReq; @@ -64,7 +65,7 @@ public YBATask deleteCluster( public YBATask editGFlags( Request request, UUID cUUID, UUID uniUUID, UniverseEditGFlags universeEditGFlags) throws Exception { - return universeUpgradeHandler.editGFlags(request, cUUID, uniUUID, universeEditGFlags); + return universeUpgradeHandler.editGFlags(cUUID, uniUUID, universeEditGFlags); } @Override @@ -78,66 +79,72 @@ public YBATask deleteUniverse( public YBATask startSoftwareUpgrade( Request request, UUID cUUID, UUID uniUUID, UniverseSoftwareUpgradeStart uniUpgrade) throws Exception { - return universeUpgradeHandler.startSoftwareUpgrade(request, cUUID, uniUUID, uniUpgrade); + return universeUpgradeHandler.startSoftwareUpgrade(cUUID, uniUUID, uniUpgrade); } @Override public YBATask finalizeSoftwareUpgrade( Request request, UUID cUUID, UUID uniUUID, UniverseSoftwareUpgradeFinalize finalizeInfo) throws Exception { - return universeUpgradeHandler.finalizeSoftwareUpgrade(request, cUUID, uniUUID, finalizeInfo); + return universeUpgradeHandler.finalizeSoftwareUpgrade(cUUID, uniUUID, finalizeInfo); } @Override public UniverseSoftwareUpgradeFinalizeInfo getFinalizeSoftwareUpgradeInfo( Request request, UUID cUUID, UUID uniUUID) throws Exception { - return universeUpgradeHandler.getSoftwareUpgradeFinalizeInfo(request, cUUID, uniUUID); + return universeUpgradeHandler.getSoftwareUpgradeFinalizeInfo(cUUID, uniUUID); } @Override public YBATask startThirdPartySoftwareUpgrade( Request request, UUID cUUID, UUID uniUUID, UniverseThirdPartySoftwareUpgradeStart uniUpgrade) throws Exception { - return universeUpgradeHandler.startThirdPartySoftwareUpgrade( - request, cUUID, uniUUID, uniUpgrade); + return universeUpgradeHandler.startThirdPartySoftwareUpgrade(cUUID, uniUUID, uniUpgrade); } @Override public YBATask rollbackSoftwareUpgrade( Request request, UUID cUUID, UUID uniUUID, UniverseRollbackUpgradeReq req) throws Exception { - return universeUpgradeHandler.rollbackSoftwareUpgrade(request, cUUID, uniUUID, req); + return universeUpgradeHandler.rollbackSoftwareUpgrade(cUUID, uniUUID, req); } @Override public UniverseSoftwareUpgradePrecheckResp precheckSoftwareUpgrade( Request request, UUID cUUID, UUID uniUUID, UniverseSoftwareUpgradePrecheckReq req) throws Exception { - return universeUpgradeHandler.precheckSoftwareUpgrade(request, cUUID, uniUUID, req); + return universeUpgradeHandler.precheckSoftwareUpgrade(cUUID, uniUUID, req); } @Override public YBATask restartUniverse( Request request, UUID cUUID, UUID uniUUID, UniverseRestart uniUpgrade) throws Exception { - return universeUpgradeHandler.restartUniverse(request, cUUID, uniUUID, uniUpgrade); + return universeUpgradeHandler.restartUniverse(cUUID, uniUUID, uniUpgrade); } @Override public YBATask systemdEnable( Request request, UUID cUUID, UUID uniUUID, UniverseSystemdEnableStart systemd) throws Exception { - return universeUpgradeHandler.systemdEnable(request, cUUID, uniUUID, systemd); + return universeUpgradeHandler.systemdEnable(cUUID, uniUUID, systemd); } @Override public YBATask encryptionInTransitToggle( Request request, UUID cUUID, UUID uniUUID, UniverseEditEncryptionInTransit spec) throws Exception { - return universeUpgradeHandler.tlsToggle(request, cUUID, uniUUID, spec); + return universeUpgradeHandler.tlsToggle(cUUID, uniUUID, spec); } @Override public YBATask encryptionInTransitCertRotate( Request request, UUID cUUID, UUID uniUUID, UniverseCertRotateSpec spec) throws Exception { - return universeUpgradeHandler.certRotate(request, cUUID, uniUUID, spec); + return universeUpgradeHandler.certRotate(cUUID, uniUUID, spec); + } + + @Override + public YBATask editKubernetesOverrides( + Request request, UUID cUUID, UUID uniUUID, UniverseEditKubernetesOverrides spec) + throws Exception { + return universeUpgradeHandler.editKubernetesOverrides(cUUID, uniUUID, spec); } } diff --git a/managed/src/main/java/api/v2/handlers/UniverseUpgradesManagementHandler.java b/managed/src/main/java/api/v2/handlers/UniverseUpgradesManagementHandler.java index b1c5884640f3..1b0c6121bf69 100644 --- a/managed/src/main/java/api/v2/handlers/UniverseUpgradesManagementHandler.java +++ b/managed/src/main/java/api/v2/handlers/UniverseUpgradesManagementHandler.java @@ -6,6 +6,7 @@ import api.v2.mappers.UniverseCertsRotateParamsMapper; import api.v2.mappers.UniverseDefinitionTaskParamsMapper; import api.v2.mappers.UniverseEditGFlagsMapper; +import api.v2.mappers.UniverseEditKubernetesOverridesParamsMapper; import api.v2.mappers.UniverseRestartParamsMapper; import api.v2.mappers.UniverseRollbackUpgradeMapper; import api.v2.mappers.UniverseSoftwareFinalizeMapper; @@ -18,6 +19,7 @@ import api.v2.models.UniverseCertRotateSpec; import api.v2.models.UniverseEditEncryptionInTransit; import api.v2.models.UniverseEditGFlags; +import api.v2.models.UniverseEditKubernetesOverrides; import api.v2.models.UniverseRestart; import api.v2.models.UniverseRollbackUpgradeReq; import api.v2.models.UniverseSoftwareUpgradeFinalize; @@ -42,6 +44,7 @@ import com.yugabyte.yw.forms.CertsRotateParams; import com.yugabyte.yw.forms.FinalizeUpgradeParams; import com.yugabyte.yw.forms.GFlagsUpgradeParams; +import com.yugabyte.yw.forms.KubernetesOverridesUpgradeParams; import com.yugabyte.yw.forms.RestartTaskParams; import com.yugabyte.yw.forms.RollbackUpgradeParams; import com.yugabyte.yw.forms.SoftwareUpgradeParams; @@ -57,7 +60,6 @@ import com.yugabyte.yw.models.extended.SoftwareUpgradeInfoResponse; import java.util.UUID; import lombok.extern.slf4j.Slf4j; -import play.mvc.Http; @Singleton @Slf4j @@ -66,8 +68,7 @@ public class UniverseUpgradesManagementHandler extends ApiControllerUtils { @Inject public Commissioner commissioner; @Inject private RuntimeConfGetter confGetter; - public YBATask editGFlags( - Http.Request request, UUID cUUID, UUID uniUUID, UniverseEditGFlags editGFlags) + public YBATask editGFlags(UUID cUUID, UUID uniUUID, UniverseEditGFlags editGFlags) throws JsonProcessingException { log.info("Starting v2 edit GFlags with {}", editGFlags); @@ -96,7 +97,7 @@ public YBATask editGFlags( } public YBATask startSoftwareUpgrade( - Http.Request request, UUID cUUID, UUID uniUUID, UniverseSoftwareUpgradeStart upgradeStart) + UUID cUUID, UUID uniUUID, UniverseSoftwareUpgradeStart upgradeStart) throws JsonProcessingException { Customer customer = Customer.getOrBadRequest(cUUID); Universe universe = Universe.getOrBadRequest(uniUUID, customer); @@ -122,7 +123,7 @@ public YBATask startSoftwareUpgrade( } public YBATask finalizeSoftwareUpgrade( - Http.Request request, UUID cUUID, UUID uniUUID, UniverseSoftwareUpgradeFinalize upgradeStart) + UUID cUUID, UUID uniUUID, UniverseSoftwareUpgradeFinalize upgradeStart) throws JsonProcessingException { Customer customer = Customer.getOrBadRequest(cUUID); Universe universe = Universe.getOrBadRequest(uniUUID, customer); @@ -141,7 +142,7 @@ public YBATask finalizeSoftwareUpgrade( } public UniverseSoftwareUpgradeFinalizeInfo getSoftwareUpgradeFinalizeInfo( - Http.Request request, UUID cUUID, UUID uniUUID) { + UUID cUUID, UUID uniUUID) { Customer customer = Customer.getOrBadRequest(cUUID); Universe.getOrBadRequest(uniUUID, customer); @@ -153,10 +154,7 @@ public UniverseSoftwareUpgradeFinalizeInfo getSoftwareUpgradeFinalizeInfo( } public YBATask startThirdPartySoftwareUpgrade( - Http.Request request, - UUID cUUID, - UUID uniUUID, - UniverseThirdPartySoftwareUpgradeStart upgradeStart) + UUID cUUID, UUID uniUUID, UniverseThirdPartySoftwareUpgradeStart upgradeStart) throws JsonProcessingException { Customer customer = Customer.getOrBadRequest(cUUID); Universe universe = Universe.getOrBadRequest(uniUUID, customer); @@ -176,8 +174,7 @@ public YBATask startThirdPartySoftwareUpgrade( return ybaTask; } - public YBATask rollbackSoftwareUpgrade( - Http.Request request, UUID cUUID, UUID uniUUID, UniverseRollbackUpgradeReq req) + public YBATask rollbackSoftwareUpgrade(UUID cUUID, UUID uniUUID, UniverseRollbackUpgradeReq req) throws Exception { Customer customer = Customer.getOrBadRequest(cUUID); Universe universe = Universe.getOrBadRequest(uniUUID, customer); @@ -195,11 +192,7 @@ public YBATask rollbackSoftwareUpgrade( } public UniverseSoftwareUpgradePrecheckResp precheckSoftwareUpgrade( - Http.Request request, - UUID cUUID, - UUID uniUUID, - UniverseSoftwareUpgradePrecheckReq precheckReq) - throws Exception { + UUID cUUID, UUID uniUUID, UniverseSoftwareUpgradePrecheckReq precheckReq) throws Exception { if (confGetter.getGlobalConf(GlobalConfKeys.enableReleasesRedesign)) { Release.getByVersionOrBadRequest(precheckReq.getYbSoftwareVersion()); } @@ -210,8 +203,7 @@ public UniverseSoftwareUpgradePrecheckResp precheckSoftwareUpgrade( v1Resp); } - public YBATask restartUniverse( - Http.Request request, UUID cUUID, UUID uniUUID, UniverseRestart uniRestart) + public YBATask restartUniverse(UUID cUUID, UUID uniUUID, UniverseRestart uniRestart) throws JsonProcessingException { Customer customer = Customer.getOrBadRequest(cUUID); Universe universe = Universe.getOrBadRequest(uniUUID, customer); @@ -250,8 +242,7 @@ public YBATask restartUniverse( return ybaTask; } - public YBATask systemdEnable( - Http.Request request, UUID cUUID, UUID uniUUID, UniverseSystemdEnableStart systemd) + public YBATask systemdEnable(UUID cUUID, UUID uniUUID, UniverseSystemdEnableStart systemd) throws JsonProcessingException { Customer customer = Customer.getOrBadRequest(cUUID); Universe universe = Universe.getOrBadRequest(uniUUID, customer); @@ -271,8 +262,7 @@ public YBATask systemdEnable( return ybaTask; } - public YBATask tlsToggle( - Http.Request request, UUID cUUID, UUID uniUUID, UniverseEditEncryptionInTransit spec) + public YBATask tlsToggle(UUID cUUID, UUID uniUUID, UniverseEditEncryptionInTransit spec) throws JsonProcessingException { Customer customer = Customer.getOrBadRequest(cUUID); @@ -289,8 +279,7 @@ public YBATask tlsToggle( return ybaTask; } - public YBATask certRotate( - Http.Request request, UUID cUUID, UUID uniUUID, UniverseCertRotateSpec spec) + public YBATask certRotate(UUID cUUID, UUID uniUUID, UniverseCertRotateSpec spec) throws JsonProcessingException { Customer customer = Customer.getOrBadRequest(cUUID); @@ -306,4 +295,23 @@ public YBATask certRotate( log.info("Started cert rotate task {}", mapper.writeValueAsString(ybaTask)); return ybaTask; } + + public YBATask editKubernetesOverrides( + UUID cUUID, UUID uniUUID, UniverseEditKubernetesOverrides spec) + throws JsonProcessingException { + Customer customer = Customer.getOrBadRequest(cUUID); + Universe universe = Universe.getOrBadRequest(uniUUID, customer); + + KubernetesOverridesUpgradeParams v1Params = + UniverseDefinitionTaskParamsMapper.INSTANCE.toKubernetesOverridesUpgradeParams( + universe.getUniverseDetails()); + v1Params = + UniverseEditKubernetesOverridesParamsMapper.INSTANCE.copyToV1KubernetesOverridesParams( + spec, v1Params); + + UUID taskUUID = v1Handler.upgradeKubernetesOverrides(v1Params, customer, universe); + YBATask ybaTask = new YBATask().taskUuid(taskUUID).resourceUuid(uniUUID); + log.info("Started kubernetes overrides upgrade task {}", mapper.writeValueAsString(ybaTask)); + return ybaTask; + } } diff --git a/managed/src/main/java/api/v2/mappers/UniverseDefinitionTaskParamsMapper.java b/managed/src/main/java/api/v2/mappers/UniverseDefinitionTaskParamsMapper.java index 247f3ff6ca70..9924a632b815 100644 --- a/managed/src/main/java/api/v2/mappers/UniverseDefinitionTaskParamsMapper.java +++ b/managed/src/main/java/api/v2/mappers/UniverseDefinitionTaskParamsMapper.java @@ -19,6 +19,7 @@ import com.yugabyte.yw.forms.FinalizeUpgradeParams; import com.yugabyte.yw.forms.GFlagsUpgradeParams; import com.yugabyte.yw.forms.KubernetesGFlagsUpgradeParams; +import com.yugabyte.yw.forms.KubernetesOverridesUpgradeParams; import com.yugabyte.yw.forms.RestartTaskParams; import com.yugabyte.yw.forms.RollbackUpgradeParams; import com.yugabyte.yw.forms.SoftwareUpgradeParams; @@ -154,6 +155,15 @@ public ThirdpartySoftwareUpgradeParams toThirdpartySoftwareUpgradeParams( @Mapping(target = "nonPrimaryClusters", ignore = true) public CertsRotateParams toCertsRotateParams(UniverseDefinitionTaskParams source); + @Mapping(target = "existingLBs", ignore = true) + @Mapping(target = "primaryCluster", ignore = true) + @Mapping(target = "TServers", ignore = true) + @Mapping(target = "readOnlyClusters", ignore = true) + @Mapping(target = "addOnClusters", ignore = true) + @Mapping(target = "nonPrimaryClusters", ignore = true) + public KubernetesOverridesUpgradeParams toKubernetesOverridesUpgradeParams( + UniverseDefinitionTaskParams source); + @Mapping(target = "spec", source = ".") UniverseCreateSpec toV2UniverseCreateSpec(UniverseDefinitionTaskParams v1UniverseTaskParams); diff --git a/managed/src/main/java/api/v2/mappers/UniverseEditKubernetesOverridesParamsMapper.java b/managed/src/main/java/api/v2/mappers/UniverseEditKubernetesOverridesParamsMapper.java new file mode 100644 index 000000000000..4dbcff77b135 --- /dev/null +++ b/managed/src/main/java/api/v2/mappers/UniverseEditKubernetesOverridesParamsMapper.java @@ -0,0 +1,19 @@ +package api.v2.mappers; + +import api.v2.models.UniverseEditKubernetesOverrides; +import com.yugabyte.yw.forms.KubernetesOverridesUpgradeParams; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +@Mapper(config = CentralConfig.class) +public interface UniverseEditKubernetesOverridesParamsMapper { + UniverseEditKubernetesOverridesParamsMapper INSTANCE = + Mappers.getMapper(UniverseEditKubernetesOverridesParamsMapper.class); + + @Mapping(source = "overrides", target = "universeOverrides") + KubernetesOverridesUpgradeParams copyToV1KubernetesOverridesParams( + UniverseEditKubernetesOverrides source, + @MappingTarget KubernetesOverridesUpgradeParams target); +} diff --git a/managed/src/main/java/com/yugabyte/yw/commissioner/tasks/CreateXClusterConfig.java b/managed/src/main/java/com/yugabyte/yw/commissioner/tasks/CreateXClusterConfig.java index 99f278148bf6..5a5cc067815a 100644 --- a/managed/src/main/java/com/yugabyte/yw/commissioner/tasks/CreateXClusterConfig.java +++ b/managed/src/main/java/com/yugabyte/yw/commissioner/tasks/CreateXClusterConfig.java @@ -20,6 +20,7 @@ import com.yugabyte.yw.forms.DrConfigCreateForm; import com.yugabyte.yw.forms.RestoreBackupParams; import com.yugabyte.yw.forms.XClusterConfigCreateFormData; +import com.yugabyte.yw.forms.XClusterConfigCreateFormData.BootstrapParams.BootstrapBackupParams; import com.yugabyte.yw.models.Backup; import com.yugabyte.yw.models.Customer; import com.yugabyte.yw.models.PitrConfig; @@ -86,10 +87,7 @@ protected boolean checkBootstrapRequired( } Duration xclusterWaitTimeout = - this.confGetter.getConfForScope(sourceUniverse, UniverseConfKeys.xclusterSetupAlterTimeout); - long sleepTimeMs; - int iterationNum = 0; - Duration currentElapsedTime; + confGetter.getConfForScope(sourceUniverse, UniverseConfKeys.xclusterSetupAlterTimeout); try (YBClient client = ybService.getClient( @@ -333,6 +331,15 @@ protected void addSubtasksToCreateXClusterConfig( } } + protected void addSubtasksToCreateXClusterConfig( + XClusterConfig xClusterConfig, + Set sourceDbIds, + @Nullable DrConfigCreateForm.PitrParams pitrParams, + boolean isForceBootstrap) { + addSubtasksToCreateXClusterConfig( + xClusterConfig, null, null, null, sourceDbIds, pitrParams, isForceBootstrap); + } + protected void addSubtasksToCreateXClusterConfig( XClusterConfig xClusterConfig, Set sourceDbIds, @@ -395,9 +402,8 @@ protected void addSubtasksForTablesNotNeedBootstrap( } // Set up PITRs for txn/db scoped xCluster. - if (xClusterConfig.getType() != (ConfigType.Basic)) { + if (xClusterConfig.getType() != ConfigType.Basic) { Set namespaces; - if (xClusterConfig.getType() == ConfigType.Db) { namespaces = getNamespaces(sourceUniverse, sourceDbIds); if (namespaces.size() != sourceDbIds.size()) { @@ -533,7 +539,12 @@ protected void addSubtasksForTablesNeedBootstrap( // For db scoped replication, we will skip backup/restore subtasks at runtime if bootstrapping // is not required. For non-db scoped replication, we always perform backup restore here. Predicate bootstrapRequiredPredicate = - (task) -> { + task -> { + if (xClusterConfig.isUsedForDr() + && xClusterConfig.getDrConfig().getFailoverXClusterConfig() != null) { + return false; + } + if (xClusterConfig.getType() == ConfigType.Db) { return checkBootstrapRequired(namespaceId, ybService, sourceUniverse, xClusterConfig); } @@ -598,13 +609,21 @@ protected void addSubtasksForTablesNeedBootstrap( sourceUniverse.isYbcEnabled() && targetUniverse.isYbcEnabled() && confGetter.getGlobalConf(GlobalConfKeys.enableYbcForXCluster); + + BootstrapBackupParams backupParams = null; + if (bootstrapParams == null) { + if (xClusterConfig.isUsedForDr()) { + backupParams = new BootstrapBackupParams(); + backupParams.storageConfigUUID = xClusterConfig.getDrConfig().getStorageConfigUuid(); + backupParams.parallelism = xClusterConfig.getDrConfig().getParallelism(); + } + } else { + backupParams = bootstrapParams.backupRequestParams; + } + BackupRequestParams backupRequestParams = getBackupRequestParams( - sourceUniverse, - bootstrapParams, - tablesInfoListNeedBootstrap, - namespaceName, - tableType); + sourceUniverse, backupParams, tablesInfoListNeedBootstrap, namespaceName, tableType); Backup backup = createAllBackupSubtasks( backupRequestParams, @@ -667,7 +686,8 @@ protected void addSubtasksForTablesNeedBootstrap( .setSubTaskGroupType(UserTaskDetails.SubTaskGroupType.RestoringBackup); } else if (tableType == CommonTypes.TableType.PGSQL_TABLE_TYPE) { // Delete hanging replication streams, otherwise deleting the database will fail. - createDeleteRemnantStreamsTask(targetUniverse.getUniverseUUID(), namespaceName); + createDeleteRemnantStreamsTask(targetUniverse.getUniverseUUID(), namespaceName) + .setShouldRunPredicate(bootstrapRequiredPredicate); // If the table type is YSQL, delete the database from the target universe before restore. createDeleteKeySpaceTask( namespaceName, CommonTypes.TableType.PGSQL_TABLE_TYPE, true /*ysqlForce*/) @@ -848,18 +868,18 @@ protected void addSubtasksForTablesNeedBootstrap( return dbToTablesInfoMapNeedBootstrap; } - static BackupRequestParams getBackupRequestParams( + private static BackupRequestParams getBackupRequestParams( Universe sourceUniverse, - XClusterConfigCreateFormData.BootstrapParams bootstrapParams, + BootstrapBackupParams backupParams, @Nullable List tablesInfoListNeedBootstrap, String namespaceName, CommonTypes.TableType tableType) { BackupRequestParams backupRequestParams; - if (bootstrapParams != null && bootstrapParams.backupRequestParams != null) { + if (backupParams != null) { backupRequestParams = new BackupRequestParams(); - backupRequestParams.storageConfigUUID = bootstrapParams.backupRequestParams.storageConfigUUID; - backupRequestParams.parallelism = bootstrapParams.backupRequestParams.parallelism; + backupRequestParams.storageConfigUUID = backupParams.storageConfigUUID; + backupRequestParams.parallelism = backupParams.parallelism; } else { // In case the user does not pass the backup parameters, use the default values. backupRequestParams = new BackupRequestParams(); @@ -869,7 +889,7 @@ static BackupRequestParams getBackupRequestParams( Backup.fetchLatestByState(backupRequestParams.customerUUID, Backup.BackupState.Completed); if (latestCompletedBackupOptional.isEmpty()) { throw new RuntimeException( - "bootstrapParams in XClusterConfigCreateFormData is null, and storageConfigUUID " + "backupParams in XClusterConfigCreateFormData is null, and storageConfigUUID " + "cannot be determined based on the latest successful backup"); } backupRequestParams.storageConfigUUID = diff --git a/managed/src/main/java/com/yugabyte/yw/commissioner/tasks/EditDrConfig.java b/managed/src/main/java/com/yugabyte/yw/commissioner/tasks/EditDrConfig.java index ef1f13079bdf..8781d5cbd30e 100644 --- a/managed/src/main/java/com/yugabyte/yw/commissioner/tasks/EditDrConfig.java +++ b/managed/src/main/java/com/yugabyte/yw/commissioner/tasks/EditDrConfig.java @@ -160,17 +160,22 @@ protected void addSubtasksToUseNewXClusterConfig( createXClusterConfigSetStatusTask(newXClusterConfig, XClusterConfigStatusType.Updating); - createXClusterConfigSetStatusForTablesTask( - newXClusterConfig, - getTableIds(taskParams().getTableInfoList()), - XClusterTableConfig.Status.Updating); - - addSubtasksToCreateXClusterConfig( - newXClusterConfig, - taskParams().getTableInfoList(), - taskParams().getMainTableIndexTablesMap(), - taskParams().getSourceTableIdsWithNoTableOnTargetUniverse(), - taskParams().getPitrParams()); + if (newXClusterConfig.getType() == XClusterConfig.ConfigType.Db) { + addSubtasksToCreateXClusterConfig( + newXClusterConfig, taskParams().getDbs(), taskParams().getPitrParams()); + } else { + createXClusterConfigSetStatusForTablesTask( + newXClusterConfig, + getTableIds(taskParams().getTableInfoList()), + XClusterTableConfig.Status.Updating); + + addSubtasksToCreateXClusterConfig( + newXClusterConfig, + taskParams().getTableInfoList(), + taskParams().getMainTableIndexTablesMap(), + taskParams().getSourceTableIdsWithNoTableOnTargetUniverse(), + taskParams().getPitrParams()); + } createXClusterConfigSetStatusTask(newXClusterConfig, XClusterConfigStatusType.Running) .setSubTaskGroupType(UserTaskDetails.SubTaskGroupType.ConfigureUniverse); diff --git a/managed/src/main/java/com/yugabyte/yw/commissioner/tasks/RestartXClusterConfig.java b/managed/src/main/java/com/yugabyte/yw/commissioner/tasks/RestartXClusterConfig.java index 71aac5fc5c65..5204bb216126 100644 --- a/managed/src/main/java/com/yugabyte/yw/commissioner/tasks/RestartXClusterConfig.java +++ b/managed/src/main/java/com/yugabyte/yw/commissioner/tasks/RestartXClusterConfig.java @@ -10,11 +10,14 @@ import com.yugabyte.yw.models.Restore; import com.yugabyte.yw.models.Universe; import com.yugabyte.yw.models.XClusterConfig; +import com.yugabyte.yw.models.XClusterConfig.ConfigType; import com.yugabyte.yw.models.XClusterConfig.XClusterConfigStatusType; import com.yugabyte.yw.models.XClusterTableConfig; +import java.util.List; import java.util.Set; import javax.inject.Inject; import lombok.extern.slf4j.Slf4j; +import org.yb.master.MasterDdlOuterClass; @Slf4j public class RestartXClusterConfig extends EditXClusterConfig { @@ -44,32 +47,42 @@ public void run() { createCheckXUniverseAutoFlag(sourceUniverse, targetUniverse) .setSubTaskGroupType(UserTaskDetails.SubTaskGroupType.PreflightChecks); - // Set table type for old xCluster configs. - xClusterConfig.updateTableType(taskParams().getTableInfoList()); + // TODO full DB scoped restart support + List tableInfoList = + taskParams().getTableInfoList(); + Set tableIds = getTableIds(tableInfoList); - // Do not skip bootstrapping for the following tables. It will check if it is required. - if (taskParams().getBootstrapParams() != null) { - xClusterConfig.updateNeedBootstrapForTables( - taskParams().getBootstrapParams().tables, true /* needBootstrap */); - } + boolean isRestartWholeConfig; + if (xClusterConfig.getType() != ConfigType.Db) { + // Set table type for old xCluster configs. + xClusterConfig.updateTableType(tableInfoList); - createXClusterConfigSetStatusTask( - xClusterConfig, XClusterConfig.XClusterConfigStatusType.Updating) - .setSubTaskGroupType(UserTaskDetails.SubTaskGroupType.DeleteXClusterReplication); + // Do not skip bootstrapping for the following tables. It will check if it is required. + if (taskParams().getBootstrapParams() != null) { + xClusterConfig.updateNeedBootstrapForTables( + taskParams().getBootstrapParams().tables, true /* needBootstrap */); + } - Set tableIds = getTableIds(taskParams().getTableInfoList()); + createXClusterConfigSetStatusTask( + xClusterConfig, XClusterConfig.XClusterConfigStatusType.Updating) + .setSubTaskGroupType(UserTaskDetails.SubTaskGroupType.DeleteXClusterReplication); + + // A replication group with no tables in it cannot exist in YBDB. If all the tables + // must be removed from the replication group, remove the replication group. + isRestartWholeConfig = + xClusterConfig.getTableIdsWithReplicationSetup(tableIds, true /* done */).size() + >= xClusterConfig.getTableIdsWithReplicationSetup().size(); + } else { + isRestartWholeConfig = + taskParams().getDbs().size() == xClusterConfig.getNamespaces().size(); + } - // A replication group with no tables in it cannot exist in YBDB. If all the tables must be - // removed from the replication group, remove the replication group. - boolean isRestartWholeConfig = - xClusterConfig.getTableIdsWithReplicationSetup(tableIds, true /* done */).size() - >= xClusterConfig.getTableIdsWithReplicationSetup().size(); log.info("isRestartWholeConfig is {}", isRestartWholeConfig); if (isRestartWholeConfig) { - createXClusterConfigSetStatusForTablesTask( - xClusterConfig, - getTableIds(taskParams().getTableInfoList()), - XClusterTableConfig.Status.Updating); + if (xClusterConfig.getType() != ConfigType.Db) { + createXClusterConfigSetStatusForTablesTask( + xClusterConfig, getTableIds(tableInfoList), XClusterTableConfig.Status.Updating); + } // Delete the replication group. createDeleteXClusterConfigSubtasks( @@ -91,19 +104,25 @@ public void run() { createXClusterConfigSetStatusTask( xClusterConfig, XClusterConfig.XClusterConfigStatusType.Updating); - createXClusterConfigSetStatusForTablesTask( - xClusterConfig, - getTableIds(taskParams().getTableInfoList()), - XClusterTableConfig.Status.Updating); - - addSubtasksToCreateXClusterConfig( - xClusterConfig, - taskParams().getTableInfoList(), - taskParams().getMainTableIndexTablesMap(), - taskParams().getSourceTableIdsWithNoTableOnTargetUniverse(), - null, - taskParams().getPitrParams(), - taskParams().isForceBootstrap()); + if (xClusterConfig.getType() == ConfigType.Db) { + addSubtasksToCreateXClusterConfig( + xClusterConfig, + taskParams().getDbs(), + taskParams().getPitrParams(), + taskParams().isForceBootstrap()); + } else { + createXClusterConfigSetStatusForTablesTask( + xClusterConfig, getTableIds(tableInfoList), XClusterTableConfig.Status.Updating); + + addSubtasksToCreateXClusterConfig( + xClusterConfig, + tableInfoList, + taskParams().getMainTableIndexTablesMap(), + taskParams().getSourceTableIdsWithNoTableOnTargetUniverse(), + null, + taskParams().getPitrParams(), + taskParams().isForceBootstrap()); + } } else { createXClusterConfigSetStatusForTablesTask( xClusterConfig, tableIds, XClusterTableConfig.Status.Updating); @@ -115,10 +134,7 @@ public void run() { xClusterConfig, tableIds, XClusterTableConfig.Status.Updating); addSubtasksToAddTablesToXClusterConfig( - xClusterConfig, - taskParams().getTableInfoList(), - taskParams().getMainTableIndexTablesMap(), - tableIds); + xClusterConfig, tableInfoList, taskParams().getMainTableIndexTablesMap(), tableIds); } createXClusterConfigSetStatusTask( diff --git a/managed/src/main/java/com/yugabyte/yw/commissioner/tasks/UniverseTaskBase.java b/managed/src/main/java/com/yugabyte/yw/commissioner/tasks/UniverseTaskBase.java index 601f4ef749ce..817eac76503b 100644 --- a/managed/src/main/java/com/yugabyte/yw/commissioner/tasks/UniverseTaskBase.java +++ b/managed/src/main/java/com/yugabyte/yw/commissioner/tasks/UniverseTaskBase.java @@ -5485,9 +5485,12 @@ protected void createDeleteXClusterConfigSubtasks( createDeleteReplicationTask(xClusterConfig, forceDelete) .setSubTaskGroupType(UserTaskDetails.SubTaskGroupType.DeleteXClusterReplication); if (xClusterConfig.getType() == ConfigType.Db) { - // TODO: add forceDelete. - createDeleteReplicationOnSourceTask(xClusterConfig) - .setSubTaskGroupType(UserTaskDetails.SubTaskGroupType.DeleteXClusterReplication); + // If it's in the middle of a repair, there's no replication on source. + if (!(xClusterConfig.isUsedForDr() && xClusterConfig.getDrConfig().isHalted())) { + // TODO: add forceDelete. + createDeleteReplicationOnSourceTask(xClusterConfig) + .setSubTaskGroupType(UserTaskDetails.SubTaskGroupType.DeleteXClusterReplication); + } } else { // Delete bootstrap IDs created by bootstrap universe subtask. createDeleteBootstrapIdsTask(xClusterConfig, xClusterConfig.getTableIds(), forceDelete) diff --git a/managed/src/main/java/com/yugabyte/yw/commissioner/tasks/XClusterConfigTaskBase.java b/managed/src/main/java/com/yugabyte/yw/commissioner/tasks/XClusterConfigTaskBase.java index 1cfc565dae74..5046a6549033 100644 --- a/managed/src/main/java/com/yugabyte/yw/commissioner/tasks/XClusterConfigTaskBase.java +++ b/managed/src/main/java/com/yugabyte/yw/commissioner/tasks/XClusterConfigTaskBase.java @@ -2043,6 +2043,32 @@ public static Map getIndexTableIdToParentTableIdMap( tableInfo -> getTableId(tableInfo), tableInfo -> tableInfo.getIndexedTableId())); } + public static List getRequestedTableInfoList( + Set dbIds, + List sourceTableInfoList) { + List requestedTableInfoList = + sourceTableInfoList.stream() + .filter( + tableInfo -> + isXClusterSupported(tableInfo) + && dbIds.contains(tableInfo.getNamespace().getId().toStringUtf8())) + .collect(Collectors.toList()); + Set foundDbIds = + requestedTableInfoList.stream() + .map(tableInfo -> tableInfo.getNamespace().getId().toStringUtf8()) + .collect(Collectors.toSet()); + // Ensure all DB names are found. + if (foundDbIds.size() != dbIds.size()) { + Set missingDbIds = + dbIds.stream().filter(dbId -> !foundDbIds.contains(dbId)).collect(Collectors.toSet()); + throw new IllegalArgumentException( + String.format( + "Some of the DB ids were not found: was %d, found %d, missing dbs: %s", + dbIds.size(), foundDbIds.size(), missingDbIds)); + } + return requestedTableInfoList; + } + // DR methods. // -------------------------------------------------------------------------------- protected DrConfig getDrConfigFromTaskParams() { diff --git a/managed/src/main/java/com/yugabyte/yw/commissioner/tasks/subtasks/xcluster/WaitForReplicationDrain.java b/managed/src/main/java/com/yugabyte/yw/commissioner/tasks/subtasks/xcluster/WaitForReplicationDrain.java index cce1be59a618..1c1db1f3c3df 100644 --- a/managed/src/main/java/com/yugabyte/yw/commissioner/tasks/subtasks/xcluster/WaitForReplicationDrain.java +++ b/managed/src/main/java/com/yugabyte/yw/commissioner/tasks/subtasks/xcluster/WaitForReplicationDrain.java @@ -55,7 +55,8 @@ public void run() { if (!Set.of(ConfigType.Txn, ConfigType.Db).contains(xClusterConfig.getType())) { throw new IllegalArgumentException( String.format( - "WaitForReplicationDrain only works for Txn xCluster; the current type is %s", + "WaitForReplicationDrain only works for Txn or DB scoped xCluster; the current type" + + " is %s", xClusterConfig.getType())); } @@ -91,6 +92,8 @@ public void run() { universe.getUniverseUUID(), xClusterConfig, rgInfo.errorMessage())); } + log.debug("Got namespace infos: {}", rgInfo.getNamespaceInfos()); + rgInfo.getNamespaceInfos().stream() .filter(i -> xClusterConfig.getDbIds().contains(i.getNamespaceId())) .forEach(i -> activeStreamIds.addAll(i.getTableStreamsMap().values())); diff --git a/managed/src/main/java/com/yugabyte/yw/controllers/DrConfigController.java b/managed/src/main/java/com/yugabyte/yw/controllers/DrConfigController.java index a76dc0f63a18..211a208bfee1 100644 --- a/managed/src/main/java/com/yugabyte/yw/controllers/DrConfigController.java +++ b/managed/src/main/java/com/yugabyte/yw/controllers/DrConfigController.java @@ -1,5 +1,8 @@ package com.yugabyte.yw.controllers; +import static com.yugabyte.yw.commissioner.tasks.XClusterConfigTaskBase.getRequestedTableInfoList; +import static org.yb.master.MasterReplicationOuterClass.GetUniverseReplicationInfoResponsePB.*; + import com.google.common.collect.Sets; import com.google.inject.Inject; import com.yugabyte.yw.commissioner.Commissioner; @@ -442,30 +445,46 @@ public Result restart( autoFlagUtil.checkSourcePromotedAutoFlagsPromotedOnTarget(sourceUniverse, targetUniverse); } - List sourceTableInfoList = - XClusterConfigTaskBase.getTableInfoList(ybService, sourceUniverse); + log.info("DR state is {}", drConfig.getState()); - // Todo: Always add non existing tables to the xCluster config on restart. - // Empty `dbs` field indicates a request to restart the entire config. - // This is consistent with the restart xCluster config behaviour. - Set tableIds = - CollectionUtils.isEmpty(restartForm.dbs) - ? xClusterConfig.getTableIds() - : XClusterConfigTaskBase.getTableIds( - getRequestedTableInfoList(restartForm.dbs, sourceTableInfoList)); + XClusterConfigTaskParams taskParams; + if (xClusterConfig.getType() != ConfigType.Db) { + List sourceTableInfoList = + XClusterConfigTaskBase.getTableInfoList(ybService, sourceUniverse); - log.info("DR state is {}", drConfig.getState()); - XClusterConfigTaskParams taskParams = - XClusterConfigController.getRestartTaskParams( - ybService, - xClusterConfig, - sourceUniverse, - targetUniverse, - tableIds, - restartForm.bootstrapParams, - false /* dryRun */, - isForceDelete, - drConfig.isHalted() /*isForceBootstrap*/); + // Todo: Always add non existing tables to the xCluster config on restart. + // Empty `dbs` field indicates a request to restart the entire config. + // This is consistent with the restart xCluster config behaviour. + Set tableIds = + CollectionUtils.isEmpty(restartForm.dbs) + ? xClusterConfig.getTableIds() + : XClusterConfigTaskBase.getTableIds( + getRequestedTableInfoList(restartForm.dbs, sourceTableInfoList)); + + taskParams = + XClusterConfigController.getRestartTaskParams( + ybService, + xClusterConfig, + sourceUniverse, + targetUniverse, + tableIds, + restartForm.bootstrapParams, + false /* dryRun */, + isForceDelete, + drConfig.isHalted() /*isForceBootstrap*/); + } else { + taskParams = + XClusterConfigController.getDbScopedRestartTaskParams( + ybService, + xClusterConfig, + sourceUniverse, + targetUniverse, + restartForm.dbs, + restartForm.bootstrapParams, + false /* dryRun */, + isForceDelete, + drConfig.isHalted() /*isForceBootstrap*/); + } UUID taskUUID = commissioner.submit(TaskType.RestartDrConfig, taskParams); CustomerTask.create( @@ -534,64 +553,91 @@ public Result replaceReplica(UUID customerUUID, UUID drConfigUuid, Http.Request autoFlagUtil.checkPromotedAutoFlagsEquality(sourceUniverse, newTargetUniverse); } - Set tableIds = xClusterConfig.getTableIds(); - - // Add index tables. - Map> mainTableIndexTablesMap = - XClusterConfigTaskBase.getMainTableIndexTablesMap(this.ybService, sourceUniverse, tableIds); - Set indexTableIdSet = - mainTableIndexTablesMap.values().stream().flatMap(List::stream).collect(Collectors.toSet()); - tableIds.addAll(indexTableIdSet); - - log.debug("tableIds are {}", tableIds); - - List sourceTableInfoList = - XClusterConfigTaskBase.getTableInfoList(ybService, sourceUniverse); - List requestedTableInfoList = - XClusterConfigTaskBase.filterTableInfoListByTableIds(sourceTableInfoList, tableIds); + DrConfigTaskParams taskParams; + // Create xCluster config object. + XClusterConfig newTargetXClusterConfig = + drConfig.addXClusterConfig( + sourceUniverse.getUniverseUUID(), + newTargetUniverse.getUniverseUUID(), + xClusterConfig.getType()); - XClusterConfigTaskBase.verifyTablesNotInReplication( - tableIds, sourceUniverse.getUniverseUUID(), newTargetUniverse.getUniverseUUID()); - XClusterConfigController.certsForCdcDirGFlagCheck(sourceUniverse, newTargetUniverse); + try { + if (xClusterConfig.getType() != ConfigType.Db) { + Set tableIds = xClusterConfig.getTableIds(); + + // Add index tables. + Map> mainTableIndexTablesMap = + XClusterConfigTaskBase.getMainTableIndexTablesMap( + this.ybService, sourceUniverse, tableIds); + Set indexTableIdSet = + mainTableIndexTablesMap.values().stream() + .flatMap(List::stream) + .collect(Collectors.toSet()); + tableIds.addAll(indexTableIdSet); + + log.debug("tableIds are {}", tableIds); + + List sourceTableInfoList = + XClusterConfigTaskBase.getTableInfoList(ybService, sourceUniverse); + List requestedTableInfoList = + XClusterConfigTaskBase.filterTableInfoListByTableIds(sourceTableInfoList, tableIds); + + XClusterConfigTaskBase.verifyTablesNotInReplication( + tableIds, sourceUniverse.getUniverseUUID(), newTargetUniverse.getUniverseUUID()); + XClusterConfigController.certsForCdcDirGFlagCheck(sourceUniverse, newTargetUniverse); + + List newTargetTableInfoList = + XClusterConfigTaskBase.getTableInfoList(ybService, newTargetUniverse); + Map sourceTableIdNewTargetTableIdMap = + XClusterConfigTaskBase.getSourceTableIdTargetTableIdMap( + requestedTableInfoList, newTargetTableInfoList); + + BootstrapParams bootstrapParams = + getBootstrapParamsFromRestartBootstrapParams( + replaceReplicaForm.bootstrapParams, tableIds); + XClusterConfigController.xClusterBootstrappingPreChecks( + requestedTableInfoList, + sourceTableInfoList, + newTargetUniverse, + sourceUniverse, + sourceTableIdNewTargetTableIdMap, + ybService, + bootstrapParams, + null /* currentReplicationGroupName */); - List newTargetTableInfoList = - XClusterConfigTaskBase.getTableInfoList(ybService, newTargetUniverse); - Map sourceTableIdNewTargetTableIdMap = - XClusterConfigTaskBase.getSourceTableIdTargetTableIdMap( - requestedTableInfoList, newTargetTableInfoList); + newTargetXClusterConfig.updateTables(tableIds, tableIds /* tableIdsNeedBootstrap */); + newTargetXClusterConfig.updateIndexTablesFromMainTableIndexTablesMap( + mainTableIndexTablesMap); + taskParams = + new DrConfigTaskParams( + drConfig, + xClusterConfig, + newTargetXClusterConfig, + bootstrapParams, + requestedTableInfoList, + mainTableIndexTablesMap, + sourceTableIdNewTargetTableIdMap); + } else { + newTargetXClusterConfig.updateNamespaces(xClusterConfig.getDbIds()); + taskParams = + new DrConfigTaskParams( + drConfig, + xClusterConfig, + newTargetXClusterConfig, + newTargetXClusterConfig.getDbIds(), + Collections.emptyMap()); + } - BootstrapParams bootstrapParams = - getBootstrapParamsFromRestartBootstrapParams(replaceReplicaForm.bootstrapParams, tableIds); - XClusterConfigController.xClusterBootstrappingPreChecks( - requestedTableInfoList, - sourceTableInfoList, - newTargetUniverse, - sourceUniverse, - sourceTableIdNewTargetTableIdMap, - ybService, - bootstrapParams, - null /* currentReplicationGroupName */); - - // Todo: add a dryRun option here. + // Todo: add a dryRun option here. - // Create xCluster config object. - XClusterConfig newTargetXClusterConfig = - drConfig.addXClusterConfig( - sourceUniverse.getUniverseUUID(), newTargetUniverse.getUniverseUUID()); - newTargetXClusterConfig.updateTables(tableIds, tableIds /* tableIdsNeedBootstrap */); - newTargetXClusterConfig.updateIndexTablesFromMainTableIndexTablesMap(mainTableIndexTablesMap); - newTargetXClusterConfig.setSecondary(true); + newTargetXClusterConfig.setSecondary(true); + newTargetXClusterConfig.update(); + } catch (Exception e) { + newTargetXClusterConfig.delete(); + throw e; + } // Submit task to set up xCluster config. - DrConfigTaskParams taskParams = - new DrConfigTaskParams( - drConfig, - xClusterConfig, - newTargetXClusterConfig, - bootstrapParams, - requestedTableInfoList, - mainTableIndexTablesMap, - sourceTableIdNewTargetTableIdMap); UUID taskUUID = commissioner.submit(TaskType.EditDrConfig, taskParams); CustomerTask.create( customer, @@ -771,7 +817,7 @@ public Result switchover(UUID customerUUID, UUID drConfigUuid, Http.Request requ ybService, targetUniverse, xClusterConfig.getReplicationGroupName()) .getDbScopedInfos() .stream() - .map(i -> i.getTargetNamespaceId()) + .map(DbScopedInfoPB::getTargetNamespaceId) .collect(Collectors.toSet())); } catch (Exception e) { throw new PlatformServiceException( @@ -853,55 +899,111 @@ public Result failover(UUID customerUUID, UUID drConfigUuid, Http.Request reques Universe targetUniverse = Universe.getOrBadRequest(xClusterConfig.getTargetUniverseUUID(), customer); + DrConfigTaskParams taskParams; + Set namespaceIdsWithSafetime = failoverForm.namespaceIdSafetimeEpochUsMap.keySet(); + Set namespaceIdsWithoutSafetime; // Todo: Add pre-checks for user's input safetime. + XClusterConfig failoverXClusterConfig = + drConfig.addXClusterConfig( + xClusterConfig.getTargetUniverseUUID(), + xClusterConfig.getSourceUniverseUUID(), + xClusterConfig.getType()); - List targetTableInfoList = - XClusterConfigTaskBase.getTableInfoList(ybService, targetUniverse); - - // Because during failover, the source universe could be down, we should rely on the target - // universe to get the table map between source to target. - Map sourceTableIdTargetTableIdMap = - xClusterUniverseService.getSourceTableIdTargetTableIdMap( - targetUniverse, xClusterConfig.getReplicationGroupName()); - - // All tables must have corresponding tables on the target universe. - Set sourceTableIdsWithNoTableOnTargetUniverse = - sourceTableIdTargetTableIdMap.entrySet().stream() - .filter(entry -> Objects.isNull(entry.getValue())) - .map(Entry::getKey) - .collect(Collectors.toSet()); - if (!sourceTableIdsWithNoTableOnTargetUniverse.isEmpty()) { - throw new PlatformServiceException( - BAD_REQUEST, - String.format( - "The following tables are in replication with no corresponding table on the " - + "target universe: %s. This can happen if the table is dropped without being " - + "removed from replication first. You may fix this issue by running `Reconcile " - + "config with DB` from UI", - sourceTableIdsWithNoTableOnTargetUniverse)); + try { + if (xClusterConfig.getType() != ConfigType.Db) { + List targetTableInfoList = + XClusterConfigTaskBase.getTableInfoList(ybService, targetUniverse); + + // Because during failover, the source universe could be down, we should rely on the target + // universe to get the table map between source to target. + Map sourceTableIdTargetTableIdMap = + xClusterUniverseService.getSourceTableIdTargetTableIdMap( + targetUniverse, xClusterConfig.getReplicationGroupName()); + + // All tables must have corresponding tables on the target universe. + Set sourceTableIdsWithNoTableOnTargetUniverse = + sourceTableIdTargetTableIdMap.entrySet().stream() + .filter(entry -> Objects.isNull(entry.getValue())) + .map(Entry::getKey) + .collect(Collectors.toSet()); + if (!sourceTableIdsWithNoTableOnTargetUniverse.isEmpty()) { + throw new PlatformServiceException( + BAD_REQUEST, + String.format( + "The following tables are in replication with no corresponding table on the" + + " target universe: %s. This can happen if the table is dropped without" + + " being removed from replication first. You may fix this issue by running" + + " `Reconcile config with DB` from UI", + sourceTableIdsWithNoTableOnTargetUniverse)); + } + + // Use table IDs on the target universe for failover xCluster. + Set tableIds = new HashSet<>(sourceTableIdTargetTableIdMap.values()); + List requestedTableInfoList = + XClusterConfigTaskBase.filterTableInfoListByTableIds(targetTableInfoList, tableIds); + + drSwitchoverFailoverPreChecks( + CustomerTask.TaskType.Failover, + requestedTableInfoList, + targetTableInfoList, + targetUniverse, + sourceUniverse); + Map> mainTableIndexTablesMap = + XClusterConfigTaskBase.getMainTableIndexTablesMap(ybService, targetUniverse, tableIds); + + // Make sure the safetime for all the namespaces is specified. + namespaceIdsWithoutSafetime = + XClusterConfigTaskBase.getNamespaces(requestedTableInfoList).stream() + .map(namespace -> namespace.getId().toStringUtf8()) + .filter(namespaceId -> !namespaceIdsWithSafetime.contains(namespaceId)) + .collect(Collectors.toSet()); + taskParams = + new DrConfigTaskParams( + drConfig, + xClusterConfig, + failoverXClusterConfig, + failoverForm.namespaceIdSafetimeEpochUsMap, + requestedTableInfoList, + mainTableIndexTablesMap); + failoverXClusterConfig.updateTables(tableIds, null /* tableIdsNeedBootstrap */); + failoverXClusterConfig.updateIndexTablesFromMainTableIndexTablesMap( + mainTableIndexTablesMap); + } else { + try { + Set namespacesInReplication = + XClusterConfigTaskBase.getUniverseReplicationInfo( + ybService, targetUniverse, xClusterConfig.getReplicationGroupName()) + .getDbScopedInfos() + .stream() + .map(i -> i.getTargetNamespaceId()) + .collect(Collectors.toSet()); + namespaceIdsWithoutSafetime = + Sets.difference(namespacesInReplication, namespaceIdsWithSafetime); + + failoverXClusterConfig.updateNamespaces(namespacesInReplication); + } catch (Exception e) { + throw new PlatformServiceException( + INTERNAL_SERVER_ERROR, + String.format( + "Failed to get target namespace IDs for group %s", + xClusterConfig.getReplicationGroupName())); + } + + taskParams = + new DrConfigTaskParams( + drConfig, + xClusterConfig, + failoverXClusterConfig, + failoverXClusterConfig.getDbIds(), + failoverForm.namespaceIdSafetimeEpochUsMap); + } + } catch (Exception e) { + failoverXClusterConfig.delete(); + throw e; } - // Use table IDs on the target universe for failover xCluster. - Set tableIds = new HashSet<>(sourceTableIdTargetTableIdMap.values()); - List requestedTableInfoList = - XClusterConfigTaskBase.filterTableInfoListByTableIds(targetTableInfoList, tableIds); - drSwitchoverFailoverPreChecks( - CustomerTask.TaskType.Failover, - requestedTableInfoList, - targetTableInfoList, - targetUniverse, - sourceUniverse); - Map> mainTableIndexTablesMap = - XClusterConfigTaskBase.getMainTableIndexTablesMap(ybService, targetUniverse, tableIds); - - // Make sure the safetime for all the namespaces is specified. - Set namespaceIdsWithSafetime = failoverForm.namespaceIdSafetimeEpochUsMap.keySet(); - Set namespaceIdsWithoutSafetime = - XClusterConfigTaskBase.getNamespaces(requestedTableInfoList).stream() - .map(namespace -> namespace.getId().toStringUtf8()) - .filter(namespaceId -> !namespaceIdsWithSafetime.contains(namespaceId)) - .collect(Collectors.toSet()); if (!namespaceIdsWithoutSafetime.isEmpty()) { + failoverXClusterConfig.delete(); throw new PlatformServiceException( BAD_REQUEST, String.format( @@ -910,25 +1012,10 @@ public Result failover(UUID customerUUID, UUID drConfigUuid, Http.Request reques namespaceIdsWithoutSafetime)); } - XClusterConfig failoverXClusterConfig = - drConfig.addXClusterConfig( - xClusterConfig.getTargetUniverseUUID(), - xClusterConfig.getSourceUniverseUUID(), - xClusterConfig.getType()); - failoverXClusterConfig.updateTables(tableIds, null /* tableIdsNeedBootstrap */); - failoverXClusterConfig.updateIndexTablesFromMainTableIndexTablesMap(mainTableIndexTablesMap); failoverXClusterConfig.setSecondary(true); + failoverXClusterConfig.update(); // Submit task to set up xCluster config. - DrConfigTaskParams taskParams = - new DrConfigTaskParams( - drConfig, - xClusterConfig, - failoverXClusterConfig, - failoverForm.namespaceIdSafetimeEpochUsMap, - requestedTableInfoList, - mainTableIndexTablesMap); - UUID taskUUID = commissioner.submit(TaskType.FailoverDrConfig, taskParams); CustomerTask.create( customer, @@ -1344,32 +1431,6 @@ private void validateBackupRequestParamsForBootstrapping( customerConfigService, backupHelper, bootstrapBackupParams, customerUUID); } - private List getRequestedTableInfoList( - Set dbIds, - List sourceTableInfoList) { - List requestedTableInfoList = - sourceTableInfoList.stream() - .filter( - tableInfo -> - XClusterConfigTaskBase.isXClusterSupported(tableInfo) - && dbIds.contains(tableInfo.getNamespace().getId().toStringUtf8())) - .collect(Collectors.toList()); - Set foundDbIds = - requestedTableInfoList.stream() - .map(tableInfo -> tableInfo.getNamespace().getId().toStringUtf8()) - .collect(Collectors.toSet()); - // Ensure all DB names are found. - if (foundDbIds.size() != dbIds.size()) { - Set missingDbIds = - dbIds.stream().filter(dbId -> !foundDbIds.contains(dbId)).collect(Collectors.toSet()); - throw new IllegalArgumentException( - String.format( - "Some of the DB ids were not found: was %d, found %d, missing dbs: %s", - dbIds.size(), foundDbIds.size(), missingDbIds)); - } - return requestedTableInfoList; - } - private static BootstrapParams getBootstrapParamsFromRestartBootstrapParams( @Nullable XClusterConfigRestartFormData.RestartBootstrapParams restartBootstrapParams, Set tableIds) { diff --git a/managed/src/main/java/com/yugabyte/yw/controllers/SessionController.java b/managed/src/main/java/com/yugabyte/yw/controllers/SessionController.java index c22882d626f5..81e006bc4804 100644 --- a/managed/src/main/java/com/yugabyte/yw/controllers/SessionController.java +++ b/managed/src/main/java/com/yugabyte/yw/controllers/SessionController.java @@ -181,7 +181,9 @@ public static class SessionInfo { @ApiOperation( nickname = "getSessionInfo", - value = "Get current user/customer uuid auth/api token", + value = + "Get current user and customer uuid. This will not generate or return the API token, use" + + " /api_token API for that.", authorizations = @Authorization(AbstractPlatformController.API_KEY_AUTH), response = SessionInfo.class) @With(TokenAuthenticator.class) @@ -193,8 +195,8 @@ public Result getSessionInfo(Http.Request request) { SessionInfo sessionInfo = new SessionInfo( authCookie.isPresent() ? authCookie.get().value() : null, - user.upsertApiToken(), - user.getApiTokenVersion(), + null, + null, cust.getUuid(), user.getUuid()); return withData(sessionInfo); diff --git a/managed/src/main/java/com/yugabyte/yw/controllers/XClusterConfigController.java b/managed/src/main/java/com/yugabyte/yw/controllers/XClusterConfigController.java index 9e32f687d153..faae4b2b633f 100644 --- a/managed/src/main/java/com/yugabyte/yw/controllers/XClusterConfigController.java +++ b/managed/src/main/java/com/yugabyte/yw/controllers/XClusterConfigController.java @@ -911,6 +911,7 @@ static XClusterConfigTaskParams getRestartTaskParams( boolean dryRun, boolean isForceDelete, boolean isForceBootstrap) { + // Add index tables. Map> mainTableIndexTablesMap = XClusterConfigTaskBase.getMainTableIndexTablesMap(ybService, sourceUniverse, tableIds); @@ -963,6 +964,32 @@ static XClusterConfigTaskParams getRestartTaskParams( isForceBootstrap); } + static XClusterConfigTaskParams getDbScopedRestartTaskParams( + YBClientService ybService, + XClusterConfig xClusterConfig, + Universe sourceUniverse, + Universe targetUniverse, + Set dbIds, + RestartBootstrapParams restartBootstrapParams, + boolean dryRun, + boolean isForceDelete, + boolean isForceBootstrap) { + + XClusterConfigCreateFormData.BootstrapParams bootstrapParams = null; + if (restartBootstrapParams != null) { + bootstrapParams = new XClusterConfigCreateFormData.BootstrapParams(); + bootstrapParams.backupRequestParams = restartBootstrapParams.backupRequestParams; + bootstrapParams.tables = new HashSet<>(); + } + + return new XClusterConfigTaskParams( + xClusterConfig, + bootstrapParams, + CollectionUtils.isEmpty(dbIds) ? xClusterConfig.getDbIds() : dbIds, + null, + isForceBootstrap); + } + /** * API that deletes an xCluster replication configuration. * diff --git a/managed/src/main/java/com/yugabyte/yw/forms/XClusterConfigTaskParams.java b/managed/src/main/java/com/yugabyte/yw/forms/XClusterConfigTaskParams.java index cd7f6ffc8d20..4c17e3ccbc6b 100644 --- a/managed/src/main/java/com/yugabyte/yw/forms/XClusterConfigTaskParams.java +++ b/managed/src/main/java/com/yugabyte/yw/forms/XClusterConfigTaskParams.java @@ -85,6 +85,16 @@ public XClusterConfigTaskParams( this.pitrParams = pitrParams; } + public XClusterConfigTaskParams( + XClusterConfig xClusterConfig, + XClusterConfigCreateFormData.BootstrapParams bootstrapParams, + Set dbs, + @Nullable DrConfigCreateForm.PitrParams pitrParams, + boolean isForceBootstrap) { + this(xClusterConfig, bootstrapParams, dbs, pitrParams); + this.isForceBootstrap = isForceBootstrap; + } + /** It is used in the edit method. */ public XClusterConfigTaskParams( XClusterConfig xClusterConfig, diff --git a/managed/src/main/resources/openapi/components/requestBodies/UniverseKubernetesOverridesReq.yaml b/managed/src/main/resources/openapi/components/requestBodies/UniverseKubernetesOverridesReq.yaml new file mode 100644 index 000000000000..4bd04d84f00e --- /dev/null +++ b/managed/src/main/resources/openapi/components/requestBodies/UniverseKubernetesOverridesReq.yaml @@ -0,0 +1,5 @@ +required: true +content: + application/json: + schema: + $ref: "../schemas/UniverseEditKubernetesOverrides.yaml" diff --git a/managed/src/main/resources/openapi/components/schemas/ClusterNodeSpec.yaml b/managed/src/main/resources/openapi/components/schemas/ClusterNodeSpec.yaml index 377542b54f7b..a17ff0c7703b 100644 --- a/managed/src/main/resources/openapi/components/schemas/ClusterNodeSpec.yaml +++ b/managed/src/main/resources/openapi/components/schemas/ClusterNodeSpec.yaml @@ -11,6 +11,6 @@ allOf: description: Used only for a k8s Universe. Required for k8s Universe if instance_type is not specified. Sets custom cpu and memory requests/limits for tserver pods of a cluster. $ref: "./K8SNodeResourceSpec.yaml" az_node_spec: - description: Granular node settings overridden per Availability Zone idetified by AZ uuid. + description: Granular node settings overridden per Availability Zone identified by AZ uuid. additionalProperties: $ref: "./AvailabilityZoneNodeSpec.yaml" diff --git a/managed/src/main/resources/openapi/components/schemas/UniverseEditKubernetesOverrides.yaml b/managed/src/main/resources/openapi/components/schemas/UniverseEditKubernetesOverrides.yaml new file mode 100644 index 000000000000..671deadf289a --- /dev/null +++ b/managed/src/main/resources/openapi/components/schemas/UniverseEditKubernetesOverrides.yaml @@ -0,0 +1,19 @@ +title: UniverseEditKubernetesOverrides +description: | + UniverseEditKubernetesOverrides + + Update all kubernetes overrides on the universe. Part of UniverseKubernetesOverridesReq +type: object +properties: + overrides: + description: Global kubernetes overrides to apply across the entire universe. + type: string + example: |- + tserver: + podLabels: + env: test + az_overrides: + description: Granular kubernetes overrides per Availability Zone identified by AZ uuid. + example: 'az_uuid: "tserver:\n podLabels:\n env: test"' + additionalProperties: + type: string diff --git a/managed/src/main/resources/openapi/paths/_index.yaml b/managed/src/main/resources/openapi/paths/_index.yaml index 0dcf4f7351c3..2f175501ee24 100644 --- a/managed/src/main/resources/openapi/paths/_index.yaml +++ b/managed/src/main/resources/openapi/paths/_index.yaml @@ -938,3 +938,61 @@ checkOnlyPermission: false x-yba-api-since: 2024.2.0.0 x-yba-api-visibility: preview +'/customers/{cUUID}/universes/{uniUUID}/kubernetes-overrides': + parameters: + - name: cUUID + in: path + description: Customer UUID + schema: + type: string + format: uuid + explode: false + style: simple + required: true + - name: uniUUID + in: path + description: Universe UUID + schema: + type: string + format: uuid + explode: false + style: simple + required: true + post: + operationId: editKubernetesOverrides + summary: Edit Kubernetes Helm Overrides + description: | + Update the kubernetes helm override values. This can be used to add custom settings to + kubernetes resources managed by YugabyteDB Anywhere. These override values can apply globally + to a universe or per AZ. + + See https://github.com/yugabyte/charts/blob/master/stable/yugabyte/values.yaml for possible + override options. + tags: + - Universe + requestBody: + $ref: "../components/requestBodies/UniverseKubernetesOverridesReq.yaml" + responses: + '202': + $ref: "../components/responses/YBATaskResp.yaml" + '400': + description: Invalid input + '500': + description: Server error + security: + - apiKeyAuth: [] + x-yba-api-audit: + auditTargetType: Universe + auditTargetId: uniUUID.toString() + auditActionType: UpgradeKubernetesOverrides + taskUuid: obj.getTaskUuid() + x-yba-api-authz: + - requiredPermission: + resourceType: universe + action: UPDATE + resourceLocation: + path: universes + sourceType: endpoint + checkOnlyPermission: false + x-yba-api-since: 2024.2.0.0 + x-yba-api-visibility: preview diff --git a/managed/src/main/resources/openapi/paths/universe.yaml b/managed/src/main/resources/openapi/paths/universe.yaml index 9693e0056b78..9d0c7ff5745d 100644 --- a/managed/src/main/resources/openapi/paths/universe.yaml +++ b/managed/src/main/resources/openapi/paths/universe.yaml @@ -821,3 +821,61 @@ checkOnlyPermission: false x-yba-api-since: 2024.2.0.0 x-yba-api-visibility: preview +'/customers/{cUUID}/universes/{uniUUID}/kubernetes-overrides': + parameters: + - name: cUUID + in: path + description: Customer UUID + schema: + type: string + format: uuid + explode: false + style: simple + required: true + - name: uniUUID + in: path + description: Universe UUID + schema: + type: string + format: uuid + explode: false + style: simple + required: true + post: + operationId: editKubernetesOverrides + summary: Edit Kubernetes Helm Overrides + description: | + Update the kubernetes helm override values. This can be used to add custom settings to + kubernetes resources managed by YugabyteDB Anywhere. These override values can apply globally + to a universe or per AZ. + + See https://github.com/yugabyte/charts/blob/master/stable/yugabyte/values.yaml for possible + override options. + tags: + - Universe + requestBody: + $ref: "../components/requestBodies/UniverseKubernetesOverridesReq.yaml" + responses: + '202': + $ref: "../components/responses/YBATaskResp.yaml" + '400': + description: Invalid input + '500': + description: Server error + security: + - apiKeyAuth: [] + x-yba-api-audit: + auditTargetType: Universe + auditTargetId: uniUUID.toString() + auditActionType: UpgradeKubernetesOverrides + taskUuid: obj.getTaskUuid() + x-yba-api-authz: + - requiredPermission: + resourceType: universe + action: UPDATE + resourceLocation: + path: universes + sourceType: endpoint + checkOnlyPermission: false + x-yba-api-since: 2024.2.0.0 + x-yba-api-visibility: preview diff --git a/managed/src/main/resources/swagger-strict.json b/managed/src/main/resources/swagger-strict.json index 16253e0bd06f..7fb1f51d8f5d 100644 --- a/managed/src/main/resources/swagger-strict.json +++ b/managed/src/main/resources/swagger-strict.json @@ -28556,7 +28556,7 @@ "security" : [ { "apiKeyAuth" : [ ] } ], - "summary" : "Get current user/customer uuid auth/api token", + "summary" : "Get current user and customer uuid. This will not generate or return the API token, use /api_token API for that.", "tags" : [ "Session management" ] } }, diff --git a/managed/src/main/resources/swagger.json b/managed/src/main/resources/swagger.json index 96b94d4b3ab7..564a3235c85e 100644 --- a/managed/src/main/resources/swagger.json +++ b/managed/src/main/resources/swagger.json @@ -30018,7 +30018,7 @@ "security" : [ { "apiKeyAuth" : [ ] } ], - "summary" : "Get current user/customer uuid auth/api token", + "summary" : "Get current user and customer uuid. This will not generate or return the API token, use /api_token API for that.", "tags" : [ "Session management" ] } }, diff --git a/managed/src/test/java/com/yugabyte/yw/api/v2/UniverseApiControllerUpgradeTest.java b/managed/src/test/java/com/yugabyte/yw/api/v2/UniverseApiControllerUpgradeTest.java index 85eb73522fec..d52d3fb047c8 100644 --- a/managed/src/test/java/com/yugabyte/yw/api/v2/UniverseApiControllerUpgradeTest.java +++ b/managed/src/test/java/com/yugabyte/yw/api/v2/UniverseApiControllerUpgradeTest.java @@ -20,6 +20,7 @@ import com.yugabyte.yba.v2.client.api.UniverseApi; import com.yugabyte.yba.v2.client.models.UniverseCertRotateSpec; import com.yugabyte.yba.v2.client.models.UniverseEditEncryptionInTransit; +import com.yugabyte.yba.v2.client.models.UniverseEditKubernetesOverrides; import com.yugabyte.yba.v2.client.models.UniverseRollbackUpgradeReq; import com.yugabyte.yba.v2.client.models.UniverseSoftwareFinalizeImpactedXCluster; import com.yugabyte.yba.v2.client.models.UniverseSoftwareUpgradeFinalize; @@ -36,6 +37,7 @@ import com.yugabyte.yw.controllers.handlers.UpgradeUniverseHandler; import com.yugabyte.yw.forms.CertsRotateParams; import com.yugabyte.yw.forms.FinalizeUpgradeParams; +import com.yugabyte.yw.forms.KubernetesOverridesUpgradeParams; import com.yugabyte.yw.forms.RollbackUpgradeParams; import com.yugabyte.yw.forms.SoftwareUpgradeParams; import com.yugabyte.yw.forms.SystemdUpgradeParams; @@ -50,6 +52,8 @@ import com.yugabyte.yw.models.extended.FinalizeUpgradeInfoResponse; import com.yugabyte.yw.models.extended.SoftwareUpgradeInfoResponse; import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; import java.util.UUID; import org.junit.Before; import org.junit.Test; @@ -379,11 +383,9 @@ public void testV2CertRotation() throws ApiException { .thenReturn(taskUUID); UniverseCertRotateSpec req = new UniverseCertRotateSpec(); req.setRollingUpgrade(true); - ; UUID clientCert = UUID.randomUUID(); UUID nodeCert = UUID.randomUUID(); req.setRootCa(nodeCert); - ; req.setClientRootCa(clientCert); YBATask resp = apiClient.encryptionInTransitCertRotate( @@ -397,4 +399,27 @@ public void testV2CertRotation() throws ApiException { assertEquals(nodeCert, params.rootCA); assertFalse(params.rootAndClientRootCASame); } + + @Test + public void testV2KubernetesOverrides() throws ApiException { + UUID taskUUID = UUID.randomUUID(); + when(mockUpgradeUniverseHandler.upgradeKubernetesOverrides(any(), eq(customer), eq(universe))) + .thenReturn(taskUUID); + UniverseEditKubernetesOverrides req = new UniverseEditKubernetesOverrides(); + req.setOverrides("my_overrides"); + Map azOverrides = new HashMap(); + azOverrides.put("az1", "az1_overrides"); + req.setAzOverrides(azOverrides); + YBATask resp = + apiClient.editKubernetesOverrides(customer.getUuid(), universe.getUniverseUUID(), req); + ArgumentCaptor captor = + ArgumentCaptor.forClass(KubernetesOverridesUpgradeParams.class); + verify(mockUpgradeUniverseHandler) + .upgradeKubernetesOverrides(captor.capture(), eq(customer), eq(universe)); + KubernetesOverridesUpgradeParams params = captor.getValue(); + assertEquals(taskUUID, resp.getTaskUuid()); + assertEquals("my_overrides", params.universeOverrides); + assertTrue(params.azOverrides.containsKey("az1")); + assertEquals("az1_overrides", params.azOverrides.get("az1")); + } } diff --git a/managed/src/test/java/com/yugabyte/yw/controllers/DrConfigControllerTest.java b/managed/src/test/java/com/yugabyte/yw/controllers/DrConfigControllerTest.java index 2954a4482c63..d737cc56ceec 100644 --- a/managed/src/test/java/com/yugabyte/yw/controllers/DrConfigControllerTest.java +++ b/managed/src/test/java/com/yugabyte/yw/controllers/DrConfigControllerTest.java @@ -10,12 +10,14 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static play.inject.Bindings.bind; @@ -23,6 +25,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.yugabyte.yw.commissioner.Commissioner; import com.yugabyte.yw.commissioner.XClusterScheduler; +import com.yugabyte.yw.common.DrConfigStates.State; import com.yugabyte.yw.common.ModelFactory; import com.yugabyte.yw.common.PlatformGuiceApplicationBaseTest; import com.yugabyte.yw.common.PlatformServiceException; @@ -33,11 +36,15 @@ import com.yugabyte.yw.common.gflags.AutoFlagUtil; import com.yugabyte.yw.common.services.YBClientService; import com.yugabyte.yw.forms.DrConfigCreateForm; +import com.yugabyte.yw.forms.DrConfigFailoverForm; +import com.yugabyte.yw.forms.DrConfigReplaceReplicaForm; +import com.yugabyte.yw.forms.DrConfigRestartForm; import com.yugabyte.yw.forms.DrConfigSetDatabasesForm; import com.yugabyte.yw.forms.DrConfigSwitchoverForm; import com.yugabyte.yw.forms.DrConfigTaskParams; import com.yugabyte.yw.forms.XClusterConfigCreateFormData.BootstrapParams.BootstrapBackupParams; import com.yugabyte.yw.forms.XClusterConfigRestartFormData.RestartBootstrapParams; +import com.yugabyte.yw.forms.XClusterConfigTaskParams; import com.yugabyte.yw.metrics.MetricQueryHelper; import com.yugabyte.yw.models.Customer; import com.yugabyte.yw.models.DrConfig; @@ -50,8 +57,10 @@ import com.yugabyte.yw.models.configs.CustomerConfig; import com.yugabyte.yw.models.helpers.TaskType; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.UUID; import org.junit.Before; @@ -358,21 +367,8 @@ public void testCreateDbScopedDisabledFailure() { assertBadRequest(result, "db scoped disaster recovery configs is disabled"); } - @Test - public void testDbScopedSwitchover() throws Exception { - String sourceNamespace = "sourceNamespace"; - DrConfig drConfig = - DrConfig.create( - "test", - sourceUniverse.getUniverseUUID(), - targetUniverse.getUniverseUUID(), - new BootstrapBackupParams(), - Set.of(sourceNamespace)); - drConfig.getActiveXClusterConfig().setStatus(XClusterConfigStatusType.Running); - drConfig.getActiveXClusterConfig().update(); - UUID taskUUID = buildTaskInfo(null, TaskType.SwitchoverDrConfig); - when(mockCommissioner.submit(any(), any())).thenReturn(taskUUID); - String targetNamespace = "targetNamespace"; + private void setupMockGetUniverseReplicationInfo( + DrConfig drConfig, String sourceNamespace, String targetNamespace) throws Exception { GetUniverseReplicationInfoResponse mockResponse = new GetUniverseReplicationInfoResponse( 0, @@ -389,6 +385,24 @@ public void testDbScopedSwitchover() throws Exception { when(mockYBClient.getUniverseReplicationInfo( eq(drConfig.getActiveXClusterConfig().getReplicationGroupName()))) .thenReturn(mockResponse); + } + + @Test + public void testDbScopedSwitchover() throws Exception { + String sourceNamespace = "sourceNamespace"; + DrConfig drConfig = + DrConfig.create( + "test", + sourceUniverse.getUniverseUUID(), + targetUniverse.getUniverseUUID(), + new BootstrapBackupParams(), + Set.of(sourceNamespace)); + drConfig.getActiveXClusterConfig().setStatus(XClusterConfigStatusType.Running); + drConfig.getActiveXClusterConfig().update(); + UUID taskUUID = buildTaskInfo(null, TaskType.SwitchoverDrConfig); + when(mockCommissioner.submit(any(), any())).thenReturn(taskUUID); + String targetNamespace = "targetNamespace"; + setupMockGetUniverseReplicationInfo(drConfig, sourceNamespace, targetNamespace); ListTablesResponse mockListTablesResponse = mock(ListTablesResponse.class); when(mockListTablesResponse.getTableInfoList()).thenReturn(Collections.emptyList()); when(mockYBClient.getTablesList(nullable(String.class), eq(false), nullable(String.class))) @@ -438,4 +452,187 @@ public void testDbScopedSwitchover() throws Exception { assertEquals(XClusterNamespaceConfig.Status.Validated, namespaceConfig.getStatus()); assertTrue(switchoverConfig.getTableDetails().isEmpty()); } + + @Test + public void testDbScopedFailoverFailsWithSafetimeMissing() throws Exception { + String sourceNamespace = "sourceNamespace"; + DrConfig drConfig = + DrConfig.create( + "test", + sourceUniverse.getUniverseUUID(), + targetUniverse.getUniverseUUID(), + new BootstrapBackupParams(), + Set.of(sourceNamespace)); + drConfig.getActiveXClusterConfig().setStatus(XClusterConfigStatusType.Running); + drConfig.getActiveXClusterConfig().update(); + + String targetNamespace = "targetNamespace"; + setupMockGetUniverseReplicationInfo(drConfig, sourceNamespace, targetNamespace); + + DrConfigFailoverForm form = new DrConfigFailoverForm(); + form.primaryUniverseUuid = sourceUniverse.getUniverseUUID(); + form.drReplicaUniverseUuid = targetUniverse.getUniverseUUID(); + form.namespaceIdSafetimeEpochUsMap = new HashMap<>(); + + Result result = + assertPlatformException( + () -> + doRequestWithAuthTokenAndBody( + "POST", + String.format( + "/api/customers/%s/dr_configs/%s/failover", + defaultCustomer.getUuid(), drConfig.getUuid()), + authToken, + Json.toJson(form))); + + assertBadRequest(result, "Safetime must be specified for all the databases"); + assertEquals(1, drConfig.getXClusterConfigs().size()); + } + + @Test + public void testDbScopedFailover() throws Exception { + String sourceNamespace = "sourceNamespace"; + DrConfig drConfig = + DrConfig.create( + "test", + sourceUniverse.getUniverseUUID(), + targetUniverse.getUniverseUUID(), + new BootstrapBackupParams(), + Set.of(sourceNamespace)); + drConfig.getActiveXClusterConfig().setStatus(XClusterConfigStatusType.Running); + drConfig.getActiveXClusterConfig().update(); + UUID taskUUID = buildTaskInfo(null, TaskType.FailoverDrConfig); + when(mockCommissioner.submit(any(), any())).thenReturn(taskUUID); + + String targetNamespace = "targetNamespace"; + setupMockGetUniverseReplicationInfo(drConfig, sourceNamespace, targetNamespace); + + DrConfigFailoverForm form = new DrConfigFailoverForm(); + form.primaryUniverseUuid = sourceUniverse.getUniverseUUID(); + form.drReplicaUniverseUuid = targetUniverse.getUniverseUUID(); + form.namespaceIdSafetimeEpochUsMap = Map.of(targetNamespace, 100L); + + Result result = + doRequestWithAuthTokenAndBody( + "POST", + String.format( + "/api/customers/%s/dr_configs/%s/failover", + defaultCustomer.getUuid(), drConfig.getUuid()), + authToken, + Json.toJson(form)); + + assertOk(result); + verify(mockYBClient) + .getUniverseReplicationInfo( + eq(drConfig.getActiveXClusterConfig().getReplicationGroupName())); + + ArgumentCaptor paramsArgumentCaptor = + ArgumentCaptor.forClass(DrConfigTaskParams.class); + verify(mockCommissioner).submit(eq(TaskType.FailoverDrConfig), paramsArgumentCaptor.capture()); + + DrConfigTaskParams params = paramsArgumentCaptor.getValue(); + assertEquals(drConfig.getUuid(), params.getDrConfig().getUuid()); + assertEquals(1, params.getDbs().size()); + assertEquals(targetNamespace, params.getDbs().iterator().next()); + assertEquals(form.namespaceIdSafetimeEpochUsMap, params.getNamespaceIdSafetimeEpochUsMap()); + assertTrue(params.getMainTableIndexTablesMap().isEmpty()); + assertTrue(params.getTableInfoList().isEmpty()); + assertTrue(params.getSourceTableIdsWithNoTableOnTargetUniverse().isEmpty()); + + XClusterConfig oldXClusterConfig = params.getOldXClusterConfig(); + assertEquals(drConfig.getActiveXClusterConfig().getUuid(), oldXClusterConfig.getUuid()); + + XClusterConfig failoverConfig = params.getXClusterConfig(); + assertEquals(oldXClusterConfig.getType(), failoverConfig.getType()); + drConfig.refresh(); + assertEquals(2, drConfig.getXClusterConfigs().size()); + assertEquals(failoverConfig.getUuid(), drConfig.getFailoverXClusterConfig().getUuid()); + assertEquals(1, failoverConfig.getNamespaces().size()); + XClusterNamespaceConfig namespaceConfig = failoverConfig.getNamespaces().iterator().next(); + assertEquals(targetNamespace, namespaceConfig.getSourceNamespaceId()); + assertEquals(XClusterNamespaceConfig.Status.Validated, namespaceConfig.getStatus()); + assertTrue(failoverConfig.getTableDetails().isEmpty()); + } + + @Test + public void testDbScopedRepair() throws Exception { + String sourceNamespace = "sourceNamespace"; + DrConfig drConfig = + DrConfig.create( + "test", + sourceUniverse.getUniverseUUID(), + targetUniverse.getUniverseUUID(), + new BootstrapBackupParams(), + Set.of(sourceNamespace)); + drConfig.setState(State.Halted); + drConfig.getActiveXClusterConfig().setStatus(XClusterConfigStatusType.Initialized); + drConfig.update(); + UUID taskUUID = buildTaskInfo(null, TaskType.RestartDrConfig); + when(mockCommissioner.submit(any(), any())).thenReturn(taskUUID); + String targetNamespace = "targetNamespace"; + + DrConfigRestartForm form = new DrConfigRestartForm(); + form.dbs = Set.of(sourceNamespace); + + Result result = + doRequestWithAuthTokenAndBody( + "POST", + String.format( + "/api/customers/%s/dr_configs/%s/restart", + defaultCustomer.getUuid(), drConfig.getUuid()), + authToken, + Json.toJson(form)); + + assertOk(result); + ArgumentCaptor paramsArgumentCaptor = + ArgumentCaptor.forClass(XClusterConfigTaskParams.class); + verify(mockCommissioner).submit(eq(TaskType.RestartDrConfig), paramsArgumentCaptor.capture()); + XClusterConfigTaskParams params = paramsArgumentCaptor.getValue(); + assertNull(params.getPitrParams()); + assertEquals(drConfig.getActiveXClusterConfig().getDbIds(), params.getDbs()); + assertTrue(params.isForceBootstrap()); + } + + @Test + public void testDbScopedReplicaReplacement() throws Exception { + Universe newReplica = createUniverse("new replication target"); + DrConfig drConfig = + spy( + DrConfig.create( + "test", + sourceUniverse.getUniverseUUID(), + targetUniverse.getUniverseUUID(), + new BootstrapBackupParams(), + Set.of("sourceNamespace"))); + drConfig.update(); + UUID taskUUID = buildTaskInfo(null, TaskType.EditDrConfig); + when(mockCommissioner.submit(any(), any())).thenReturn(taskUUID); + + DrConfigReplaceReplicaForm form = new DrConfigReplaceReplicaForm(); + form.primaryUniverseUuid = sourceUniverse.getUniverseUUID(); + form.drReplicaUniverseUuid = newReplica.getUniverseUUID(); + + Result result = + doRequestWithAuthTokenAndBody( + "POST", + String.format( + "/api/customers/%s/dr_configs/%s/replace_replica", + defaultCustomer.getUuid(), drConfig.getUuid()), + authToken, + Json.toJson(form)); + + assertOk(result); + ArgumentCaptor paramsArgumentCaptor = + ArgumentCaptor.forClass(XClusterConfigTaskParams.class); + verify(mockCommissioner).submit(eq(TaskType.EditDrConfig), paramsArgumentCaptor.capture()); + XClusterConfigTaskParams params = paramsArgumentCaptor.getValue(); + assertEquals(drConfig.getActiveXClusterConfig().getDbIds(), params.getDbs()); + assertNull(params.getPitrParams()); + + drConfig.refresh(); + XClusterConfig newConfig = drConfig.getFailoverXClusterConfig(); + assertNotNull(newConfig); + assertEquals(newConfig.getDbIds(), drConfig.getActiveXClusterConfig().getDbIds()); + assertTrue(newConfig.getTableIds().isEmpty()); + } } diff --git a/src/postgres/src/backend/commands/ybccmds.c b/src/postgres/src/backend/commands/ybccmds.c index 85d538e417d9..6c4469adfc13 100644 --- a/src/postgres/src/backend/commands/ybccmds.c +++ b/src/postgres/src/backend/commands/ybccmds.c @@ -2026,9 +2026,10 @@ YBCDestroyVirtualWalForCDC() void YBCGetCDCConsistentChanges(const char *stream_id, - YBCPgChangeRecordBatch **record_batch) + YBCPgChangeRecordBatch **record_batch, + YBCTypeEntityProvider type_entity_provider) { - HandleYBStatus(YBCPgGetCDCConsistentChanges(stream_id, record_batch)); + HandleYBStatus(YBCPgGetCDCConsistentChanges(stream_id, record_batch, type_entity_provider)); } void diff --git a/src/postgres/src/backend/parser/gram.y b/src/postgres/src/backend/parser/gram.y index 854fad291392..560786572ca1 100644 --- a/src/postgres/src/backend/parser/gram.y +++ b/src/postgres/src/backend/parser/gram.y @@ -10315,7 +10315,6 @@ RenameStmt: ALTER AGGREGATE aggregate_with_argtypes RENAME TO name } | ALTER TABLE IF_P EXISTS relation_expr RENAME opt_column name TO name { - parser_ybc_not_support(@1, "ALTER TABLE IF EXISTS"); RenameStmt *n = makeNode(RenameStmt); n->renameType = OBJECT_COLUMN; diff --git a/src/postgres/src/backend/replication/logical/yb_virtual_wal_client.c b/src/postgres/src/backend/replication/logical/yb_virtual_wal_client.c index ec28900dd3cb..e5ca04fa56d9 100644 --- a/src/postgres/src/backend/replication/logical/yb_virtual_wal_client.c +++ b/src/postgres/src/backend/replication/logical/yb_virtual_wal_client.c @@ -26,6 +26,7 @@ #include #include "access/xact.h" +#include "catalog/yb_type.h" #include "commands/ybccmds.h" #include "pg_yb_utils.h" #include "replication/slot.h" @@ -241,6 +242,26 @@ InitVirtualWal(List *publication_names) list_free(tables); } +static const YBCPgTypeEntity * +GetDynamicTypeEntity(int attr_num, Oid relid) +{ + bool is_in_txn = IsTransactionOrTransactionBlock(); + if (!is_in_txn) + StartTransactionCommand(); + + Relation rel = RelationIdGetRelation(relid); + if (!RelationIsValid(rel)) + elog(ERROR, "Could not open relation with OID %u", relid); + Oid type_oid = GetTypeId(attr_num, RelationGetDescr(rel)); + RelationClose(rel); + const YBCPgTypeEntity* type_entity = YbDataTypeFromOidMod(attr_num, type_oid); + + if (!is_in_txn) + AbortCurrentTransaction(); + + return type_entity; +} + YBCPgVirtualWalRecord * YBCReadRecord(XLogReaderState *state, List *publication_names, char **errormsg) { @@ -293,7 +314,7 @@ YBCReadRecord(XLogReaderState *state, List *publication_names, char **errormsg) } YBCGetCDCConsistentChanges(MyReplicationSlot->data.yb_stream_id, - &cached_records); + &cached_records, &GetDynamicTypeEntity); cached_records_last_sent_row_idx = 0; YbWalSndTotalTimeInYBDecodeMicros = 0; diff --git a/src/postgres/src/include/commands/ybccmds.h b/src/postgres/src/include/commands/ybccmds.h index f1c139f952d0..164fc43f371d 100644 --- a/src/postgres/src/include/commands/ybccmds.h +++ b/src/postgres/src/include/commands/ybccmds.h @@ -144,7 +144,8 @@ extern void YBCUpdatePublicationTableList(const char *stream_id, extern void YBCDestroyVirtualWalForCDC(); extern void YBCGetCDCConsistentChanges(const char *stream_id, - YBCPgChangeRecordBatch **record_batch); + YBCPgChangeRecordBatch **record_batch, + YBCTypeEntityProvider type_entity_provider); extern void YBCUpdateAndPersistLSN(const char *stream_id, XLogRecPtr restart_lsn_hint, diff --git a/src/postgres/src/test/regress/expected/yb_feature_alter_table.out b/src/postgres/src/test/regress/expected/yb_feature_alter_table.out index d3c8fde3a1d1..728bcd05bc13 100644 --- a/src/postgres/src/test/regress/expected/yb_feature_alter_table.out +++ b/src/postgres/src/test/regress/expected/yb_feature_alter_table.out @@ -254,7 +254,14 @@ ERROR: constraint "checkb2" for table "atacc1" does not exist alter table atacc1 drop constraint if exists checkb3; delete from atacc1 where b = 5; -- test rename -alter table atacc1 rename b to e; +alter table atacc1 rename b to d; -- should fail: d already exists +ERROR: column "d" of relation "atacc1" already exists +alter table atacc1 rename b to f; +alter table atacc1 rename column f to e; +alter table if exists doesnt_exist_tab rename b to f; +NOTICE: relation "doesnt_exist_tab" does not exist, skipping +alter table if exists doesnt_exist_tab rename column f to e; +NOTICE: relation "doesnt_exist_tab" does not exist, skipping select * from atacc1; e | c | d ----+----+---- diff --git a/src/postgres/src/test/regress/expected/yb_pg_alter_table.out b/src/postgres/src/test/regress/expected/yb_pg_alter_table.out index 4001d24ad661..dff82959829d 100644 --- a/src/postgres/src/test/regress/expected/yb_pg_alter_table.out +++ b/src/postgres/src/test/regress/expected/yb_pg_alter_table.out @@ -311,6 +311,33 @@ Check constraints: DROP TABLE constraint_rename_cache; DROP TABLE like_constraint_rename_cache; +-- test inheritance +create table renameColumn (a int); +create table renameColumnChild (b int) inherits (renameColumn); +ERROR: INHERITS not supported yet +LINE 1: create table renameColumnChild (b int) inherits (renameColum... + ^ +HINT: See https://github.com/yugabyte/yugabyte-db/issues/1129. React with thumbs up to raise its priority +/* YB: uncomment when INHERITS is supported +create table renameColumnAnother (c int) inherits (renameColumnChild); + +-- these three should fail +alter table renameColumnChild rename column a to d; +alter table only renameColumnChild rename column a to d; +alter table only renameColumn rename column a to d; +*/ -- YB +-- these should work +alter table renameColumn rename column a to d; +/* YB: uncomment when INHERITS is supported +alter table renameColumnChild rename column b to a; +*/ -- YB +-- these should work +alter table if exists doesnt_exist_tab rename column a to d; +NOTICE: relation "doesnt_exist_tab" does not exist, skipping +alter table if exists doesnt_exist_tab rename column b to a; +NOTICE: relation "doesnt_exist_tab" does not exist, skipping +-- this should work +alter table renameColumn add column w int; -- -- lock levels -- diff --git a/src/postgres/src/test/regress/sql/yb_feature_alter_table.sql b/src/postgres/src/test/regress/sql/yb_feature_alter_table.sql index 171007cb953a..39937d28132f 100644 --- a/src/postgres/src/test/regress/sql/yb_feature_alter_table.sql +++ b/src/postgres/src/test/regress/sql/yb_feature_alter_table.sql @@ -144,7 +144,13 @@ alter table atacc1 drop constraint if exists checkb3; delete from atacc1 where b = 5; -- test rename -alter table atacc1 rename b to e; +alter table atacc1 rename b to d; -- should fail: d already exists +alter table atacc1 rename b to f; +alter table atacc1 rename column f to e; + +alter table if exists doesnt_exist_tab rename b to f; +alter table if exists doesnt_exist_tab rename column f to e; + select * from atacc1; -- try dropping all columns diff --git a/src/postgres/src/test/regress/sql/yb_pg_alter_table.sql b/src/postgres/src/test/regress/sql/yb_pg_alter_table.sql index 13994973a142..065b1f0b0d6c 100644 --- a/src/postgres/src/test/regress/sql/yb_pg_alter_table.sql +++ b/src/postgres/src/test/regress/sql/yb_pg_alter_table.sql @@ -285,6 +285,33 @@ CREATE TABLE like_constraint_rename_cache DROP TABLE constraint_rename_cache; DROP TABLE like_constraint_rename_cache; +-- test inheritance + +create table renameColumn (a int); +create table renameColumnChild (b int) inherits (renameColumn); +/* YB: uncomment when INHERITS is supported +create table renameColumnAnother (c int) inherits (renameColumnChild); + +-- these three should fail +alter table renameColumnChild rename column a to d; +alter table only renameColumnChild rename column a to d; +alter table only renameColumn rename column a to d; +*/ -- YB + +-- these should work +alter table renameColumn rename column a to d; +/* YB: uncomment when INHERITS is supported +alter table renameColumnChild rename column b to a; +*/ -- YB + +-- these should work +alter table if exists doesnt_exist_tab rename column a to d; +alter table if exists doesnt_exist_tab rename column b to a; + +-- this should work +alter table renameColumn add column w int; + + -- -- lock levels -- diff --git a/src/postgres/third-party-extensions/pg_partman/sql/functions/apply_publications.sql b/src/postgres/third-party-extensions/pg_partman/sql/functions/apply_publications.sql index 3c318d82bdef..61392bb85ada 100644 --- a/src/postgres/third-party-extensions/pg_partman/sql/functions/apply_publications.sql +++ b/src/postgres/third-party-extensions/pg_partman/sql/functions/apply_publications.sql @@ -5,6 +5,7 @@ DECLARE v_publications text[]; v_row record; v_sql text; + yb_v_table_exists boolean; BEGIN /* * Function to ATLER PUBLICATION ... ADD TABLE to support logical replication @@ -18,9 +19,23 @@ WHERE c.parent_table = p_parent_table; FOR v_row IN SELECT pubname FROM unnest(v_publications) AS pubname LOOP - v_sql = format('ALTER PUBLICATION %I ADD TABLE %I.%I', v_row.pubname, p_child_schema, p_child_tablename); - RAISE DEBUG '%', v_sql; - EXECUTE v_sql; + + SELECT EXISTS ( + SELECT 1 + FROM pg_publication_rel pr + JOIN pg_class c ON pr.prrelid = c.oid + JOIN pg_namespace n ON c.relnamespace = n.oid + JOIN pg_publication p ON pr.prpubid = p.oid + WHERE c.relname = p_child_tablename + AND n.nspname = p_child_schema + AND p.pubname = v_row.pubname + ) INTO yb_v_table_exists; + + IF NOT yb_v_table_exists THEN + v_sql = format('ALTER PUBLICATION %I ADD TABLE %I.%I', v_row.pubname, p_child_schema, p_child_tablename); + RAISE DEBUG '%', v_sql; + EXECUTE v_sql; + END IF; END LOOP; END; diff --git a/src/postgres/third-party-extensions/pg_partman/sql/functions/create_parent.sql b/src/postgres/third-party-extensions/pg_partman/sql/functions/create_parent.sql index 75c09cea6ee8..567f392656ae 100644 --- a/src/postgres/third-party-extensions/pg_partman/sql/functions/create_parent.sql +++ b/src/postgres/third-party-extensions/pg_partman/sql/functions/create_parent.sql @@ -74,6 +74,7 @@ v_top_datetime_string text; v_top_parent_schema text := split_part(p_parent_table, '.', 1); v_top_parent_table text := split_part(p_parent_table, '.', 2); v_unlogged char; +yb_v_parent_table_default regclass; BEGIN /* @@ -744,7 +745,7 @@ IF p_type = 'native' AND current_setting('server_version_num')::int >= 110000 TH */ -- Same INCLUDING list is used in create_partition_*(). INDEXES is handled when partition is attached if it's supported. - v_sql := v_sql || format(' TABLE %I.%I (LIKE %I.%I INCLUDING DEFAULTS INCLUDING CONSTRAINTS INCLUDING STORAGE INCLUDING COMMENTS ' + v_sql := v_sql || format(' TABLE IF NOT EXISTS %I.%I (LIKE %I.%I INCLUDING DEFAULTS INCLUDING CONSTRAINTS INCLUDING STORAGE INCLUDING COMMENTS ' , v_parent_schema, v_default_partition, v_parent_schema, v_parent_tablename); IF current_setting('server_version_num')::int >= 120000 THEN v_sql := v_sql || ' INCLUDING GENERATED '; @@ -753,7 +754,12 @@ IF p_type = 'native' AND current_setting('server_version_num')::int >= 110000 TH EXECUTE v_sql; v_sql := format('ALTER TABLE %I.%I ATTACH PARTITION %I.%I DEFAULT' , v_parent_schema, v_parent_tablename, v_parent_schema, v_default_partition); - EXECUTE v_sql; + SELECT inhparent::regclass INTO yb_v_parent_table_default + FROM pg_inherits + WHERE inhrelid = (quote_ident(v_parent_schema) || '.' || quote_ident(v_default_partition))::regclass; + IF yb_v_parent_table_default is NULL THEN + EXECUTE v_sql; + END IF; IF p_publications IS NOT NULL THEN -- NOTE: Native publication inheritance is only supported on PG14+ diff --git a/src/postgres/third-party-extensions/pg_partman/sql/functions/create_partition_id.sql b/src/postgres/third-party-extensions/pg_partman/sql/functions/create_partition_id.sql index e4eb825cd83a..0bf15bef6b4b 100644 --- a/src/postgres/third-party-extensions/pg_partman/sql/functions/create_partition_id.sql +++ b/src/postgres/third-party-extensions/pg_partman/sql/functions/create_partition_id.sql @@ -41,12 +41,27 @@ v_sub_id_max bigint; v_sub_id_min bigint; v_template_table text; v_unlogged char; +yb_v_child_tables text[] := '{}'; +yb_v_child_table record; +yb_v_is_child_table_attached boolean; BEGIN /* * Function to create id partitions */ +-- Fetch child tables using pg_inherits +FOR yb_v_child_table IN + SELECT child.relname + FROM pg_inherits + JOIN pg_class parent ON pg_inherits.inhparent = parent.oid + JOIN pg_class child ON pg_inherits.inhrelid = child.oid + WHERE parent.relname = split_part(p_parent_table, '.', 2) +LOOP + -- Append each child table name to the array + yb_v_child_tables := array_append(yb_v_child_tables, yb_v_child_table.relname::text); +END LOOP; + SELECT control , partition_type , partition_interval @@ -114,15 +129,29 @@ FOREACH v_id IN ARRAY p_partition_ids LOOP END IF; v_partition_name := @extschema@.check_name_length(v_parent_tablename, v_id::text, TRUE); + + -- YB: check if child table is already attached + yb_v_is_child_table_attached := v_partition_name = ANY(yb_v_child_tables); + IF yb_v_is_child_table_attached THEN + RAISE NOTICE 'Table % already attached', v_partition_name; + v_partition_created := true; + CONTINUE; + END IF; + -- If child table already exists, skip creation -- Have to check pg_class because if subpartitioned, table will not be in pg_tables SELECT c.relname INTO v_exists FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON c.relnamespace = n.oid WHERE n.nspname = v_parent_schema::name AND c.relname = v_partition_name::name; + /* YB: Don't continue whole loop iteration, there could be + case that child partition was created but not attached due to + previous create_partition_id failed as YB does not support + transactional DDL. IF v_exists IS NOT NULL THEN CONTINUE; END IF; + */ -- Ensure analyze is run if a new partition is created. Otherwise if one isn't, will be false and analyze will be skipped v_analyze := TRUE; @@ -180,8 +209,10 @@ FOREACH v_id IN ARRAY p_partition_ids LOOP END IF; END IF; - RAISE DEBUG 'create_partition_id v_sql: %', v_sql; - EXECUTE v_sql; + IF v_exists IS NULL THEN + RAISE DEBUG 'create_partition_id v_sql: %', v_sql; + EXECUTE v_sql; + END IF; IF v_partition_type = 'native' THEN diff --git a/src/postgres/third-party-extensions/pg_partman/sql/functions/create_partition_time.sql b/src/postgres/third-party-extensions/pg_partman/sql/functions/create_partition_time.sql index 3dde5d3ec304..db8459ca45b9 100644 --- a/src/postgres/third-party-extensions/pg_partman/sql/functions/create_partition_time.sql +++ b/src/postgres/third-party-extensions/pg_partman/sql/functions/create_partition_time.sql @@ -54,12 +54,28 @@ v_time timestamptz; v_partition_type text; v_unlogged char; v_year text; +yb_v_child_table record; +yb_v_child_tables text[] := '{}'; +yb_v_is_child_table_attached boolean; +yb_v_constraint_name text; BEGIN /* * Function to create a child table in a time-based partition set */ +-- Fetch child tables using pg_inherits +FOR yb_v_child_table IN + SELECT child.relname + FROM pg_inherits + JOIN pg_class parent ON pg_inherits.inhparent = parent.oid + JOIN pg_class child ON pg_inherits.inhrelid = child.oid + WHERE parent.relname = split_part(p_parent_table, '.', 2) +LOOP + -- Append each child table name to the array + yb_v_child_tables := array_append(yb_v_child_tables, yb_v_child_table.relname::text); +END LOOP; + SELECT partition_type , control , partition_interval @@ -158,6 +174,15 @@ FOREACH v_time IN ARRAY p_partition_times LOOP -- This suffix generation code is in partition_data_time() as well v_partition_suffix := to_char(v_time, v_datetime_string); v_partition_name := @extschema@.check_name_length(v_parent_tablename, v_partition_suffix, TRUE); + + -- YB: check if child table is already attached + yb_v_is_child_table_attached := v_partition_name = ANY(yb_v_child_tables); + IF yb_v_is_child_table_attached THEN + RAISE NOTICE 'Table % already attached', v_partition_name; + v_partition_created := true; + CONTINUE; + END IF; + -- Check if child exists. SELECT count(*) INTO v_exists FROM pg_catalog.pg_class c @@ -165,9 +190,14 @@ FOREACH v_time IN ARRAY p_partition_times LOOP WHERE n.nspname = v_parent_schema::name AND c.relname = v_partition_name::name; + /* YB: Don't continue whole loop iteration, there could be + case that child partition was created but not attached due to + previous create_partition_time failed as YB does not support + transactional DDL. IF v_exists > 0 THEN CONTINUE; END IF; + */ -- Ensure analyze is run if a new partition is created. Otherwise if one isn't, will be false and analyze will be skipped v_analyze := TRUE; @@ -229,9 +259,10 @@ FOREACH v_time IN ARRAY p_partition_times LOOP END IF; END IF; - RAISE DEBUG 'create_partition_time v_sql: %', v_sql; - EXECUTE v_sql; - + IF v_exists IS NULL THEN + RAISE DEBUG 'create_partition_time v_sql: %', v_sql; + EXECUTE v_sql; + END IF; IF v_partition_type = 'native' THEN @@ -284,13 +315,22 @@ FOREACH v_time IN ARRAY p_partition_times LOOP , EXTRACT('epoch' FROM v_partition_timestamp_end)::bigint * 1000000000); END IF; -- Create secondary, time-based constraint since native's constraint is already integer based - EXECUTE format('ALTER TABLE %I.%I ADD CONSTRAINT %I CHECK (%s >= %L AND %4$s < %6$L)' - , v_parent_schema - , v_partition_name - , v_partition_name||'_partition_check' - , v_partition_expression - , v_partition_timestamp_start - , v_partition_timestamp_end); + -- YB: Check if the constraint already exists + SELECT conname INTO yb_v_constraint_name + FROM pg_constraint + WHERE conname = v_partition_name||'_partition_check' + AND conrelid = (quote_ident(v_parent_schema) || '.' || quote_ident(v_partition_name))::regclass; + + -- YB: If the constraint does not exist, create it + IF yb_v_constraint_name IS NULL THEN + EXECUTE format('ALTER TABLE %I.%I ADD CONSTRAINT %I CHECK (%s >= %L AND %4$s < %6$L)' + , v_parent_schema + , v_partition_name + , v_partition_name||'_partition_check' + , v_partition_expression + , v_partition_timestamp_start + , v_partition_timestamp_end); + END IF; END IF; ELSE -- non-native diff --git a/src/postgres/third-party-extensions/pg_partman/sql/functions/inherit_template_properties.sql b/src/postgres/third-party-extensions/pg_partman/sql/functions/inherit_template_properties.sql index a0183abf88c2..a1fc4362d636 100644 --- a/src/postgres/third-party-extensions/pg_partman/sql/functions/inherit_template_properties.sql +++ b/src/postgres/third-party-extensions/pg_partman/sql/functions/inherit_template_properties.sql @@ -22,6 +22,8 @@ v_template_table text; v_template_tablename name; v_template_tablespace name; v_template_unlogged char; +yb_v_child_index_found boolean := false; +yb_v_child_index_list record; BEGIN /* @@ -100,6 +102,7 @@ IF current_setting('server_version_num')::int >= 100000 THEN ORDER BY 1 LOOP v_dupe_found := false; + yb_v_child_index_found := false; IF current_setting('server_version_num')::int >= 110000 THEN FOR v_parent_index_list IN @@ -140,6 +143,43 @@ IF current_setting('server_version_num')::int >= 100000 THEN CONTINUE; END IF; + -- YB: Check for existing index on child table + FOR yb_v_child_index_list IN + SELECT + array_to_string(regexp_matches(pg_get_indexdef(indexrelid), ' USING .*'),',') AS statement + , i.indisprimary + , ( SELECT array_agg(a.attname ORDER by x.r) + FROM pg_catalog.pg_attribute a + JOIN ( SELECT k, row_number() over () as r + FROM unnest(i.indkey) k ) as x + ON a.attnum = x.k AND a.attrelid = i.indrelid + ) AS indkey_names + FROM pg_catalog.pg_index i + WHERE i.indrelid = ( SELECT oid FROM pg_catalog.pg_class WHERE relname = p_child_tablename AND relnamespace = ( SELECT oid FROM pg_catalog.pg_namespace WHERE nspname = p_child_schema )) + AND i.indisvalid + ORDER BY 1 + LOOP + IF yb_v_child_index_list.indisprimary = v_index_list.indisprimary THEN + IF yb_v_child_index_list.indisprimary THEN + IF yb_v_child_index_list.indkey_names = v_index_list.indkey_names THEN + RAISE DEBUG 'inherit_template_properties: Duplicate primary key found on child table: %', v_index_list.indkey_names; + yb_v_child_index_found := true; + CONTINUE; -- skip creating this index + END IF; + END IF; + END IF; + + IF yb_v_child_index_list.statement = v_index_list.statement THEN + RAISE DEBUG 'inherit_template_properties: Duplicate index found on child table: %', v_index_list.statement; + yb_v_child_index_found := true; + CONTINUE; -- skip creating this index + END IF; + END LOOP; + + IF yb_v_child_index_found THEN + CONTINUE; + END IF; + IF v_index_list.indisprimary THEN v_sql := format('ALTER TABLE %I.%I ADD PRIMARY KEY (%s)' , v_child_schema diff --git a/src/postgres/third-party-extensions/wal2json/.gitignore b/src/postgres/third-party-extensions/wal2json/.gitignore new file mode 100644 index 000000000000..25344d12c0d5 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/.gitignore @@ -0,0 +1,6 @@ +/regression.diffs +/regression.out +/results/ +/wal2json.bc +/wal2json.so +*.o diff --git a/src/postgres/third-party-extensions/wal2json/LICENSE b/src/postgres/third-party-extensions/wal2json/LICENSE new file mode 100644 index 000000000000..e3e82163fc09 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2013-2024, Euler Taveira de Oliveira +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + +* Neither the name of the Euler Taveira de Oliveira nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/postgres/third-party-extensions/wal2json/Makefile b/src/postgres/third-party-extensions/wal2json/Makefile new file mode 100644 index 000000000000..c0effef25d5e --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/Makefile @@ -0,0 +1,37 @@ +MODULES = wal2json + +REGRESS = cmdline insert1 update1 update2 update3 update4 delete1 delete2 \ + delete3 delete4 savepoint specialvalue toast bytea message typmod \ + filtertable selecttable include_timestamp include_lsn include_xids \ + include_domain_data_type truncate type_oid actions position default \ + pk rename_column numeric_data_types_as_string + +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) + +# message API is available in 9.6+ +ifneq (,$(findstring $(MAJORVERSION),9.4 9.5)) +REGRESS := $(filter-out message, $(REGRESS)) +endif + +# truncate API is available in 11+ +ifneq (,$(findstring $(MAJORVERSION),9.4 9.5 9.6 10)) +REGRESS := $(filter-out truncate, $(REGRESS)) +endif + +# actions API is available in 11+ +# this test should be executed in prior versions, however, truncate will fail. +ifneq (,$(findstring $(MAJORVERSION),9.4 9.5 9.6 10)) +REGRESS := $(filter-out actions, $(REGRESS)) +endif + +# make installcheck +# +# It can be run but you need to add the following parameters to +# postgresql.conf: +# +# wal_level = logical +# max_replication_slots = 10 +# +# Also, you should start the server before executing it. diff --git a/src/postgres/third-party-extensions/wal2json/README.md b/src/postgres/third-party-extensions/wal2json/README.md new file mode 100644 index 000000000000..ca791a0516fb --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/README.md @@ -0,0 +1,511 @@ +[![Coverity Scan Build Status](https://scan.coverity.com/projects/4832/badge.svg)](https://scan.coverity.com/projects/wal2json) + +Introduction +============ + +**wal2json** is an output plugin for logical decoding. It means that the plugin have access to tuples produced by INSERT and UPDATE. Also, UPDATE/DELETE old row versions can be accessed depending on the configured replica identity. Changes can be consumed using the streaming protocol (logical replication slots) or by a special SQL API. + +**format version 1** produces a JSON object per transaction. All of the new/old tuples are available in the JSON object. Also, there are options to include properties such as transaction timestamp, schema-qualified, data types, and transaction ids. + +**format version 2** produces a JSON object per tuple. Optional JSON object for beginning and end of transaction. Also, there are a variety of options to include properties. + +Build and Install +================= + +This extension is supported on [those platforms](http://www.postgresql.org/docs/current/static/supported-platforms.html) that PostgreSQL is. The installation steps depend on your operating system. [PostgreSQL yum repository](https://yum.postgresql.org) and [PostgreSQL apt repository](https://wiki.postgresql.org/wiki/Apt) provide wal2json packages. + +In Red Hat/CentOS: + +``` +$ sudo yum install wal2json_16 +``` + +In Debian/Ubuntu: + +``` +$ sudo apt-get install postgresql-16-wal2json +``` + +You can also keep up with the latest fixes and features cloning the Git repository. + +``` +$ git clone https://github.com/eulerto/wal2json.git +``` + +Unix based Operating Systems +---------------------------- + +Before installing **wal2json**, you should have PostgreSQL 9.4+ installed (including the header files). If PostgreSQL is not in your search path, add it. If you are using [PostgreSQL yum repository](https://yum.postgresql.org), install `postgresql16-devel` and add `/usr/pgsql-16/bin` to your search path (yum uses `16, 15, 14, 13, 12, 11, 10, 96 or 95`). If you are using [PostgreSQL apt repository](https://wiki.postgresql.org/wiki/Apt), install `postgresql-server-dev-16` and add `/usr/lib/postgresql/16/bin` to your search path. (apt uses `16, 15, 14, 13, 12, 11, 10, 9.6 or 9.5`). + +If you compile PostgreSQL by yourself and install it in `/home/euler/pg16`: + +``` +$ tar -zxf wal2json-wal2json_2_6.tar.gz +$ cd wal2json-wal2json_2_6 +$ export PATH=/home/euler/pg16/bin:$PATH +$ make +$ make install +``` + +If you are using [PostgreSQL yum repository](https://yum.postgresql.org): + +``` +$ sudo yum install postgresql16-devel +$ tar -zxf wal2json-wal2json_2_6.tar.gz +$ cd wal2json-wal2json_2_6 +$ export PATH=/usr/pgsql-16/bin:$PATH +$ make +$ make install +``` + +If you are using [PostgreSQL apt repository](https://wiki.postgresql.org/wiki/Apt): + +``` +$ sudo apt-get install postgresql-server-dev-16 +$ tar -zxf wal2json-wal2json_2_6.tar.gz +$ cd wal2json-wal2json_2_6 +$ export PATH=/usr/lib/postgresql/16/bin:$PATH +$ make +$ make install +``` + +Windows +------- + +There are several ways to build **wal2json** on Windows. If you are build PostgreSQL too, you can put **wal2json** directory inside contrib, change the contrib Makefile (variable SUBDIRS) and build it following the [Installation from Source Code on Windows](http://www.postgresql.org/docs/current/static/install-windows.html) instructions. However, if you already have PostgreSQL installed, it is also possible to compile **wal2json** out of the tree. Edit `wal2json.vcxproj` file and change `c:\pg\16` to the PostgreSQL prefix directory. The next step is to open this project file in MS Visual Studio and compile it. Final step is to copy `wal2json.dll` to the `pg_config --pkglibdir` directory. + +Configuration +============= + +postgresql.conf +--------------- + +You need to set up at least two parameters at postgresql.conf: + +``` +wal_level = logical +# +# these parameters only need to set in versions 9.4, 9.5 and 9.6 +# default values are ok in version 10 or later +# +max_replication_slots = 10 +max_wal_senders = 10 +``` + +After changing these parameters, a restart is needed. + +Parameters +---------- + +* `include-xids`: add _xid_ to each changeset. Default is _false_. +* `include-timestamp`: add _timestamp_ to each changeset. Default is _false_. +* `include-schemas`: add _schema_ to each change. Default is _true_. +* `include-types`: add _type_ to each change. Default is _true_. +* `include-typmod`: add modifier to types that have it (eg. varchar(20) instead of varchar). Default is _true_. +* `include-type-oids`: add type oids. Default is _false_. +* `include-domain-data-type`: replace domain name with the underlying data type. Default is _false_. +* `include-column-positions`: add column position (_pg_attribute.attnum_). Default is _false_. +* `include-origin`: add origin of a piece of data. Default is _false_. +* `include-not-null`: add _not null_ information as _columnoptionals_. Default is _false_. +* `include-default`: add default expression. Default is _false_. +* `include-pk`: add _primary key_ information as _pk_. Column name and data type is included. Default is _false_. +* `numeric-data-types-as-string`: use string for numeric data types. JSON specification does not recognize `Infinity` and `NaN` as valid numeric values. There might be [potential interoperability problems](https://datatracker.ietf.org/doc/html/rfc7159#section-6) for double precision numbers. Default is _false_. +* `pretty-print`: add spaces and indentation to JSON structures. Default is _false_. +* `write-in-chunks`: write after every change instead of every changeset. Only used when `format-version` is `1`. Default is _false_. +* `include-lsn`: add _nextlsn_ to each changeset. Default is _false_. +* `include-transaction`: emit records denoting the start and end of each transaction. Default is _true_. +* `include-unchanged-toast` (deprecated): Don't use it. It is deprecated. +* `filter-origins`: exclude changes from the specified origins. Default is empty which means that no origin will be filtered. It is a comma separated value. +* `filter-tables`: exclude rows from the specified tables. Default is empty which means that no table will be filtered. It is a comma separated value. The tables should be schema-qualified. `*.foo` means table foo in all schemas and `bar.*` means all tables in schema bar. Special characters (space, single quote, comma, period, asterisk) must be escaped with backslash. Schema and table are case-sensitive. Table `"public"."Foo bar"` should be specified as `public.Foo\ bar`. +* `add-tables`: include only rows from the specified tables. Default is all tables from all schemas. It has the same rules from `filter-tables`. +* `filter-msg-prefixes`: exclude messages if prefix is in the list. Default is empty which means that no message will be filtered. It is a comma separated value. +* `add-msg-prefixes`: include only messages if prefix is in the list. Default is all prefixes. It is a comma separated value. `wal2json` applies `filter-msg-prefixes` before this parameter. +* `format-version`: defines which format to use. Default is _1_. +* `actions`: define which operations will be sent. Default is all actions (insert, update, delete, and truncate). However, if you are using `format-version` 1, truncate is not enabled (backward compatibility). + +Examples +======== + +There are two ways to obtain the changes (JSON objects) from **wal2json** plugin: calling functions via SQL or pg_recvlogical. + +pg_recvlogical +-------------- + +Besides the configuration above, it is necessary to configure a replication connection to use pg_recvlogical. A logical replication connection in version 9.4, 9.5, and 9.6 requires `replication` keyword in the database column. Since version 10, logical replication matches a normal entry with a database name or keywords such as `all`. + +First, add a replication connection rule at pg_hba.conf (9.4, 9.5, and 9.6): + +``` +local replication myuser trust +``` + +If you are using version 10 or later: + +``` +local mydatabase myuser trust +``` + +Also, set max_wal_senders at postgresql.conf: + +``` +max_wal_senders = 1 +``` + +A restart is necessary if you changed max_wal_senders. + +You are ready to try **wal2json**. In one terminal: + +``` +$ pg_recvlogical -d postgres --slot test_slot --create-slot -P wal2json +$ pg_recvlogical -d postgres --slot test_slot --start -o pretty-print=1 -o add-msg-prefixes=wal2json -f - +``` + +In another terminal: + +``` +$ cat /tmp/example1.sql +CREATE TABLE table1_with_pk (a SERIAL, b VARCHAR(30), c TIMESTAMP NOT NULL, PRIMARY KEY(a, c)); +CREATE TABLE table1_without_pk (a SERIAL, b NUMERIC(5,2), c TEXT); + +BEGIN; +INSERT INTO table1_with_pk (b, c) VALUES('Backup and Restore', now()); +INSERT INTO table1_with_pk (b, c) VALUES('Tuning', now()); +INSERT INTO table1_with_pk (b, c) VALUES('Replication', now()); +SELECT pg_logical_emit_message(true, 'wal2json', 'this message will be delivered'); +SELECT pg_logical_emit_message(true, 'pgoutput', 'this message will be filtered'); +DELETE FROM table1_with_pk WHERE a < 3; +SELECT pg_logical_emit_message(false, 'wal2json', 'this non-transactional message will be delivered even if you rollback the transaction'); + +INSERT INTO table1_without_pk (b, c) VALUES(2.34, 'Tapir'); +-- it is not added to stream because there isn't a pk or a replica identity +UPDATE table1_without_pk SET c = 'Anta' WHERE c = 'Tapir'; +COMMIT; + +DROP TABLE table1_with_pk; +DROP TABLE table1_without_pk; + +$ psql -At -f /tmp/example1.sql postgres +CREATE TABLE +CREATE TABLE +BEGIN +INSERT 0 1 +INSERT 0 1 +INSERT 0 1 +3/78BFC828 +3/78BFC880 +DELETE 2 +3/78BFC990 +INSERT 0 1 +UPDATE 1 +COMMIT +DROP TABLE +DROP TABLE +``` + +The output in the first terminal is: + +``` +{ + "change": [ + ] +} +{ + "change": [ + ] +} +{ + "change": [ + { + "kind": "message", + "transactional": false, + "prefix": "wal2json", + "content": "this non-transactional message will be delivered even if you rollback the transaction" + } + ] +} +WARNING: table "table1_without_pk" without primary key or replica identity is nothing +{ + "change": [ + { + "kind": "insert", + "schema": "public", + "table": "table1_with_pk", + "columnnames": ["a", "b", "c"], + "columntypes": ["integer", "character varying(30)", "timestamp without time zone"], + "columnvalues": [1, "Backup and Restore", "2018-03-27 11:58:28.988414"] + } + ,{ + "kind": "insert", + "schema": "public", + "table": "table1_with_pk", + "columnnames": ["a", "b", "c"], + "columntypes": ["integer", "character varying(30)", "timestamp without time zone"], + "columnvalues": [2, "Tuning", "2018-03-27 11:58:28.988414"] + } + ,{ + "kind": "insert", + "schema": "public", + "table": "table1_with_pk", + "columnnames": ["a", "b", "c"], + "columntypes": ["integer", "character varying(30)", "timestamp without time zone"], + "columnvalues": [3, "Replication", "2018-03-27 11:58:28.988414"] + } + ,{ + "kind": "message", + "transactional": true, + "prefix": "wal2json", + "content": "this message will be delivered" + } + ,{ + "kind": "delete", + "schema": "public", + "table": "table1_with_pk", + "oldkeys": { + "keynames": ["a", "c"], + "keytypes": ["integer", "timestamp without time zone"], + "keyvalues": [1, "2018-03-27 11:58:28.988414"] + } + } + ,{ + "kind": "delete", + "schema": "public", + "table": "table1_with_pk", + "oldkeys": { + "keynames": ["a", "c"], + "keytypes": ["integer", "timestamp without time zone"], + "keyvalues": [2, "2018-03-27 11:58:28.988414"] + } + } + ,{ + "kind": "insert", + "schema": "public", + "table": "table1_without_pk", + "columnnames": ["a", "b", "c"], + "columntypes": ["integer", "numeric(5,2)", "text"], + "columnvalues": [1, 2.34, "Tapir"] + } + ] +} +{ + "change": [ + ] +} +{ + "change": [ + ] +} +``` + +Dropping the slot in the first terminal: + +``` +Ctrl+C +$ pg_recvlogical -d postgres --slot test_slot --drop-slot +``` + +SQL functions +------------- + +``` +$ cat /tmp/example2.sql +CREATE TABLE table2_with_pk (a SERIAL, b VARCHAR(30), c TIMESTAMP NOT NULL, PRIMARY KEY(a, c)); +CREATE TABLE table2_without_pk (a SERIAL, b NUMERIC(5,2), c TEXT); + +SELECT 'init' FROM pg_create_logical_replication_slot('test_slot', 'wal2json'); + +BEGIN; +INSERT INTO table2_with_pk (b, c) VALUES('Backup and Restore', now()); +INSERT INTO table2_with_pk (b, c) VALUES('Tuning', now()); +INSERT INTO table2_with_pk (b, c) VALUES('Replication', now()); +SELECT pg_logical_emit_message(true, 'wal2json', 'this message will be delivered'); +SELECT pg_logical_emit_message(true, 'pgoutput', 'this message will be filtered'); +DELETE FROM table2_with_pk WHERE a < 3; +SELECT pg_logical_emit_message(false, 'wal2json', 'this non-transactional message will be delivered even if you rollback the transaction'); + +INSERT INTO table2_without_pk (b, c) VALUES(2.34, 'Tapir'); +-- it is not added to stream because there isn't a pk or a replica identity +UPDATE table2_without_pk SET c = 'Anta' WHERE c = 'Tapir'; +COMMIT; + +SELECT data FROM pg_logical_slot_get_changes('test_slot', NULL, NULL, 'pretty-print', '1', 'add-msg-prefixes', 'wal2json'); +SELECT 'stop' FROM pg_drop_replication_slot('test_slot'); + +DROP TABLE table2_with_pk; +DROP TABLE table2_without_pk; +``` + +The script above produces the output below: + +``` +$ psql -At -f /tmp/example2.sql postgres +CREATE TABLE +CREATE TABLE +init +BEGIN +INSERT 0 1 +INSERT 0 1 +INSERT 0 1 +3/78C2CA50 +3/78C2CAA8 +DELETE 2 +3/78C2CBD8 +INSERT 0 1 +UPDATE 1 +COMMIT +{ + "change": [ + { + "kind": "message", + "transactional": false, + "prefix": "wal2json", + "content": "this non-transactional message will be delivered even if you rollback the transaction" + } + ] +} +psql:/tmp/example2.sql:17: WARNING: table "table2_without_pk" without primary key or replica identity is nothing +{ + "change": [ + { + "kind": "insert", + "schema": "public", + "table": "table2_with_pk", + "columnnames": ["a", "b", "c"], + "columntypes": ["integer", "character varying(30)", "timestamp without time zone"], + "columnvalues": [1, "Backup and Restore", "2018-03-27 12:05:29.914496"] + } + ,{ + "kind": "insert", + "schema": "public", + "table": "table2_with_pk", + "columnnames": ["a", "b", "c"], + "columntypes": ["integer", "character varying(30)", "timestamp without time zone"], + "columnvalues": [2, "Tuning", "2018-03-27 12:05:29.914496"] + } + ,{ + "kind": "insert", + "schema": "public", + "table": "table2_with_pk", + "columnnames": ["a", "b", "c"], + "columntypes": ["integer", "character varying(30)", "timestamp without time zone"], + "columnvalues": [3, "Replication", "2018-03-27 12:05:29.914496"] + } + ,{ + "kind": "message", + "transactional": true, + "prefix": "wal2json", + "content": "this message will be delivered" + } + ,{ + "kind": "delete", + "schema": "public", + "table": "table2_with_pk", + "oldkeys": { + "keynames": ["a", "c"], + "keytypes": ["integer", "timestamp without time zone"], + "keyvalues": [1, "2018-03-27 12:05:29.914496"] + } + } + ,{ + "kind": "delete", + "schema": "public", + "table": "table2_with_pk", + "oldkeys": { + "keynames": ["a", "c"], + "keytypes": ["integer", "timestamp without time zone"], + "keyvalues": [2, "2018-03-27 12:05:29.914496"] + } + } + ,{ + "kind": "insert", + "schema": "public", + "table": "table2_without_pk", + "columnnames": ["a", "b", "c"], + "columntypes": ["integer", "numeric(5,2)", "text"], + "columnvalues": [1, 2.34, "Tapir"] + } + ] +} +stop +DROP TABLE +DROP TABLE +``` + +Let's repeat the same example with `format-version` 2: + +``` +$ cat /tmp/example3.sql +CREATE TABLE table3_with_pk (a SERIAL, b VARCHAR(30), c TIMESTAMP NOT NULL, PRIMARY KEY(a, c)); +CREATE TABLE table3_without_pk (a SERIAL, b NUMERIC(5,2), c TEXT); + +SELECT 'init' FROM pg_create_logical_replication_slot('test_slot', 'wal2json'); + +BEGIN; +INSERT INTO table3_with_pk (b, c) VALUES('Backup and Restore', now()); +INSERT INTO table3_with_pk (b, c) VALUES('Tuning', now()); +INSERT INTO table3_with_pk (b, c) VALUES('Replication', now()); +SELECT pg_logical_emit_message(true, 'wal2json', 'this message will be delivered'); +SELECT pg_logical_emit_message(true, 'pgoutput', 'this message will be filtered'); +DELETE FROM table3_with_pk WHERE a < 3; +SELECT pg_logical_emit_message(false, 'wal2json', 'this non-transactional message will be delivered even if you rollback the transaction'); + +INSERT INTO table3_without_pk (b, c) VALUES(2.34, 'Tapir'); +-- it is not added to stream because there isn't a pk or a replica identity +UPDATE table3_without_pk SET c = 'Anta' WHERE c = 'Tapir'; +COMMIT; + +SELECT data FROM pg_logical_slot_get_changes('test_slot', NULL, NULL, 'format-version', '2', 'add-msg-prefixes', 'wal2json'); +SELECT 'stop' FROM pg_drop_replication_slot('test_slot'); + +DROP TABLE table3_with_pk; +DROP TABLE table3_without_pk; +``` + +The script above produces the output below: + +``` +$ psql -At -f /tmp/example3.sql postgres +CREATE TABLE +CREATE TABLE +init +BEGIN +INSERT 0 1 +INSERT 0 1 +INSERT 0 1 +3/78CB8F30 +3/78CB8F88 +DELETE 2 +3/78CB90B8 +INSERT 0 1 +UPDATE 1 +COMMIT +psql:/tmp/example3.sql:20: WARNING: no tuple identifier for UPDATE in table "public"."table3_without_pk" +{"action":"M","transactional":false,"prefix":"wal2json","content":"this non-transactional message will be delivered even if you rollback the transaction"} +{"action":"B"} +{"action":"I","schema":"public","table":"table3_with_pk","columns":[{"name":"a","type":"integer","value":1},{"name":"b","type":"character varying(30)","value":"Backup and Restore"},{"name":"c","type":"timestamp without time zone","value":"2019-12-29 04:58:34.806671"}]} +{"action":"I","schema":"public","table":"table3_with_pk","columns":[{"name":"a","type":"integer","value":2},{"name":"b","type":"character varying(30)","value":"Tuning"},{"name":"c","type":"timestamp without time zone","value":"2019-12-29 04:58:34.806671"}]} +{"action":"I","schema":"public","table":"table3_with_pk","columns":[{"name":"a","type":"integer","value":3},{"name":"b","type":"character varying(30)","value":"Replication"},{"name":"c","type":"timestamp without time zone","value":"2019-12-29 04:58:34.806671"}]} +{"action":"M","transactional":true,"prefix":"wal2json","content":"this message will be delivered"} +{"action":"D","schema":"public","table":"table3_with_pk","identity":[{"name":"a","type":"integer","value":1},{"name":"c","type":"timestamp without time zone","value":"2019-12-29 04:58:34.806671"}]} +{"action":"D","schema":"public","table":"table3_with_pk","identity":[{"name":"a","type":"integer","value":2},{"name":"c","type":"timestamp without time zone","value":"2019-12-29 04:58:34.806671"}]} +{"action":"I","schema":"public","table":"table3_without_pk","columns":[{"name":"a","type":"integer","value":1},{"name":"b","type":"numeric(5,2)","value":2.34},{"name":"c","type":"text","value":"Tapir"}]} +{"action":"C"} +stop +DROP TABLE +DROP TABLE +``` + +License +======= + +> Copyright (c) 2013-2024, Euler Taveira de Oliveira +> All rights reserved. + +> Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +> Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +> Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +> Neither the name of the Euler Taveira de Oliveira nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/postgres/third-party-extensions/wal2json/expected/actions.out b/src/postgres/third-party-extensions/wal2json/expected/actions.out new file mode 100644 index 000000000000..da2a95d1fdaa --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/actions.out @@ -0,0 +1,133 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +-- actions +CREATE TABLE actions (a integer primary key); +INSERT INTO actions (a) VALUES(1); +UPDATE actions SET a = 2 WHERE a = 1; +DELETE FROM actions WHERE a = 2; +TRUNCATE TABLE actions; +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'actions', 'insert, foo, delete'); +ERROR: could not parse value "foo" for parameter "actions" +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1'); + data +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"change":[]} + {"change":[{"kind":"insert","schema":"public","table":"actions","columnnames":["a"],"columntypes":["integer"],"columnvalues":[1]}]} + {"change":[{"kind":"update","schema":"public","table":"actions","columnnames":["a"],"columntypes":["integer"],"columnvalues":[2],"oldkeys":{"keynames":["a"],"keytypes":["integer"],"keyvalues":[1]}}]} + {"change":[{"kind":"delete","schema":"public","table":"actions","oldkeys":{"keynames":["a"],"keytypes":["integer"],"keyvalues":[2]}}]} + {"change":[]} +(5 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); + data +------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"actions","columns":[{"name":"a","type":"integer","value":1}]} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"actions","columns":[{"name":"a","type":"integer","value":2}],"identity":[{"name":"a","type":"integer","value":1}]} + {"action":"C"} + {"action":"B"} + {"action":"D","schema":"public","table":"actions","identity":[{"name":"a","type":"integer","value":2}]} + {"action":"C"} + {"action":"B"} + {"action":"T","schema":"public","table":"actions"} + {"action":"C"} +(14 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'actions', 'insert'); + data +-------------------------------------------------------------------------------------------------------- + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"actions","columns":[{"name":"a","type":"integer","value":1}]} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} +(11 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'actions', 'update'); + data +------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"actions","columns":[{"name":"a","type":"integer","value":2}],"identity":[{"name":"a","type":"integer","value":1}]} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} +(11 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'actions', 'delete'); + data +--------------------------------------------------------------------------------------------------------- + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"D","schema":"public","table":"actions","identity":[{"name":"a","type":"integer","value":2}]} + {"action":"C"} + {"action":"B"} + {"action":"C"} +(11 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'actions', 'truncate'); + data +---------------------------------------------------- + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"T","schema":"public","table":"actions"} + {"action":"C"} +(11 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'actions', 'update, truncate'); + data +------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"actions","columns":[{"name":"a","type":"integer","value":2}],"identity":[{"name":"a","type":"integer","value":1}]} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"T","schema":"public","table":"actions"} + {"action":"C"} +(12 rows) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + diff --git a/src/postgres/third-party-extensions/wal2json/expected/bytea.out b/src/postgres/third-party-extensions/wal2json/expected/bytea.out new file mode 100644 index 000000000000..7225d93cde38 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/bytea.out @@ -0,0 +1,89 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +SET extra_float_digits = 0; +DROP TABLE IF EXISTS xpto; +DROP SEQUENCE IF EXISTS xpto_rand_seq; +CREATE SEQUENCE xpto_rand_seq START 11 INCREMENT 997; +CREATE TABLE xpto ( +id serial primary key, +rand1 float8 DEFAULT nextval('xpto_rand_seq'), +bincol bytea +); +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +INSERT INTO xpto (bincol) SELECT decode(string_agg(to_char(round(g.i * 0.08122019), 'FM0000'), ''), 'hex') FROM generate_series(500, 5000) g(i); +UPDATE xpto SET rand1 = 123.456 WHERE id = 1; +DELETE FROM xpto WHERE id = 1; +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0'); + data +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "xpto", + + "columnnames": ["id", "rand1", "bincol"], + + "columntypes": ["int4", "float8", "bytea"], + + "columnvalues": [1, 11, "0041004100410041004100410041004100410041004100420042004200420042004200420042004200420042004200420043004300430043004300430043004300430043004300430044004400440044004400440044004400440044004400440045004500450045004500450045004500450045004500450045004600460046004600460046004600460046004600460046004700470047004700470047004700470047004700470047004800480048004800480048004800480048004800480048004800490049004900490049004900490049004900490049004900500050005000500050005000500050005000500050005000510051005100510051005100510051005100510051005100510052005200520052005200520052005200520052005200520053005300530053005300530053005300530053005300530054005400540054005400540054005400540054005400540054005500550055005500550055005500550055005500550055005600560056005600560056005600560056005600560056005700570057005700570057005700570057005700570057005800580058005800580058005800580058005800580058005800590059005900590059005900590059005900590059005900600060006000600060006000600060006000600060006000610061006100610061006100610061006100610061006100610062006200620062006200620062006200620062006200620063006300630063006300630063006300630063006300630064006400640064006400640064006400640064006400640064006500650065006500650065006500650065006500650065006600660066006600660066006600660066006600660066006700670067006700670067006700670067006700670067006700680068006800680068006800680068006800680068006800690069006900690069006900690069006900690069006900700070007000700070007000700070007000700070007000700071007100710071007100710071007100710071007100710072007200720072007200720072007200720072007200720073007300730073007300730073007300730073007300730074007400740074007400740074007400740074007400740074007500750075007500750075007500750075007500750075007600760076007600760076007600760076007600760076007700770077007700770077007700770077007700770077007700780078007800780078007800780078007800780078007800790079007900790079007900790079007900790079007900800080008000800080008000800080008000800080008000800081008100810081008100810081008100810081008100810082008200820082008200820082008200820082008200820083008300830083008300830083008300830083008300830083008400840084008400840084008400840084008400840084008500850085008500850085008500850085008500850085008600860086008600860086008600860086008600860086008600870087008700870087008700870087008700870087008700880088008800880088008800880088008800880088008800890089008900890089008900890089008900890089008900900090009000900090009000900090009000900090009000900091009100910091009100910091009100910091009100910092009200920092009200920092009200920092009200920093009300930093009300930093009300930093009300930093009400940094009400940094009400940094009400940094009500950095009500950095009500950095009500950095009600960096009600960096009600960096009600960096009600970097009700970097009700970097009700970097009700980098009800980098009800980098009800980098009800990099009900990099009900990099009900990099009900990100010001000100010001000100010001000100010001000101010101010101010101010101010101010101010101010102010201020102010201020102010201020102010201020102010301030103010301030103010301030103010301030103010401040104010401040104010401040104010401040104010501050105010501050105010501050105010501050105010601060106010601060106010601060106010601060106010601070107010701070107010701070107010701070107010701080108010801080108010801080108010801080108010801090109010901090109010901090109010901090109010901090110011001100110011001100110011001100110011001100111011101110111011101110111011101110111011101110112011201120112011201120112011201120112011201120112011301130113011301130113011301130113011301130113011401140114011401140114011401140114011401140114011501150115011501150115011501150115011501150115011501160116011601160116011601160116011601160116011601170117011701170117011701170117011701170117011701180118011801180118011801180118011801180118011801190119011901190119011901190119011901190119011901190120012001200120012001200120012001200120012001200121012101210121012101210121012101210121012101210122012201220122012201220122012201220122012201220122012301230123012301230123012301230123012301230123012401240124012401240124012401240124012401240124012501250125012501250125012501250125012501250125012501260126012601260126012601260126012601260126012601270127012701270127012701270127012701270127012701280128012801280128012801280128012801280128012801280129012901290129012901290129012901290129012901290130013001300130013001300130013001300130013001300131013101310131013101310131013101310131013101310131013201320132013201320132013201320132013201320132013301330133013301330133013301330133013301330133013401340134013401340134013401340134013401340134013501350135013501350135013501350135013501350135013501360136013601360136013601360136013601360136013601370137013701370137013701370137013701370137013701380138013801380138013801380138013801380138013801380139013901390139013901390139013901390139013901390140014001400140014001400140014001400140014001400141014101410141014101410141014101410141014101410141014201420142014201420142014201420142014201420142014301430143014301430143014301430143014301430143014401440144014401440144014401440144014401440144014401450145014501450145014501450145014501450145014501460146014601460146014601460146014601460146014601470147014701470147014701470147014701470147014701470148014801480148014801480148014801480148014801480149014901490149014901490149014901490149014901490150015001500150015001500150015001500150015001500151015101510151015101510151015101510151015101510151015201520152015201520152015201520152015201520152015301530153015301530153015301530153015301530153015401540154015401540154015401540154015401540154015401550155015501550155015501550155015501550155015501560156015601560156015601560156015601560156015601570157015701570157015701570157015701570157015701570158015801580158015801580158015801580158015801580159015901590159015901590159015901590159015901590160016001600160016001600160016001600160016001600160016101610161016101610161016101610161016101610161016201620162016201620162016201620162016201620162016301630163016301630163016301630163016301630163016301640164016401640164016401640164016401640164016401650165016501650165016501650165016501650165016501660166016601660166016601660166016601660166016601670167016701670167016701670167016701670167016701670168016801680168016801680168016801680168016801680169016901690169016901690169016901690169016901690170017001700170017001700170017001700170017001700170017101710171017101710171017101710171017101710171017201720172017201720172017201720172017201720172017301730173017301730173017301730173017301730173017301740174017401740174017401740174017401740174017401750175017501750175017501750175017501750175017501760176017601760176017601760176017601760176017601760177017701770177017701770177017701770177017701770178017801780178017801780178017801780178017801780179017901790179017901790179017901790179017901790179018001800180018001800180018001800180018001800180018101810181018101810181018101810181018101810181018201820182018201820182018201820182018201820182018301830183018301830183018301830183018301830183018301840184018401840184018401840184018401840184018401850185018501850185018501850185018501850185018501860186018601860186018601860186018601860186018601860187018701870187018701870187018701870187018701870188018801880188018801880188018801880188018801880189018901890189018901890189018901890189018901890189019001900190019001900190019001900190019001900190019101910191019101910191019101910191019101910191019201920192019201920192019201920192019201920192019201930193019301930193019301930193019301930193019301940194019401940194019401940194019401940194019401950195019501950195019501950195019501950195019501950196019601960196019601960196019601960196019601960197019701970197019701970197019701970197019701970198019801980198019801980198019801980198019801980199019901990199019901990199019901990199019901990199020002000200020002000200020002000200020002000200020102010201020102010201020102010201020102010201020202020202020202020202020202020202020202020202020202030203020302030203020302030203020302030203020302040204020402040204020402040204020402040204020402050205020502050205020502050205020502050205020502050206020602060206020602060206020602060206020602060207020702070207020702070207020702070207020702070208020802080208020802080208020802080208020802080208020902090209020902090209020902090209020902090209021002100210021002100210021002100210021002100210021102110211021102110211021102110211021102110211021102120212021202120212021202120212021202120212021202130213021302130213021302130213021302130213021302140214021402140214021402140214021402140214021402150215021502150215021502150215021502150215021502150216021602160216021602160216021602160216021602160217021702170217021702170217021702170217021702170218021802180218021802180218021802180218021802180218021902190219021902190219021902190219021902190219022002200220022002200220022002200220022002200220022102210221022102210221022102210221022102210221022102220222022202220222022202220222022202220222022202230223022302230223022302230223022302230223022302240224022402240224022402240224022402240224022402240225022502250225022502250225022502250225022502250226022602260226022602260226022602260226022602260227022702270227022702270227022702270227022702270227022802280228022802280228022802280228022802280228022902290229022902290229022902290229022902290229023002300230023002300230023002300230023002300230023102310231023102310231023102310231023102310231023102320232023202320232023202320232023202320232023202330233023302330233023302330233023302330233023302340234023402340234023402340234023402340234023402340235023502350235023502350235023502350235023502350236023602360236023602360236023602360236023602360237023702370237023702370237023702370237023702370237023802380238023802380238023802380238023802380238023902390239023902390239023902390239023902390239024002400240024002400240024002400240024002400240024002410241024102410241024102410241024102410241024102420242024202420242024202420242024202420242024202430243024302430243024302430243024302430243024302430244024402440244024402440244024402440244024402440245024502450245024502450245024502450245024502450246024602460246024602460246024602460246024602460247024702470247024702470247024702470247024702470247024802480248024802480248024802480248024802480248024902490249024902490249024902490249024902490249025002500250025002500250025002500250025002500250025002510251025102510251025102510251025102510251025102520252025202520252025202520252025202520252025202530253025302530253025302530253025302530253025302530254025402540254025402540254025402540254025402540255025502550255025502550255025502550255025502550256025602560256025602560256025602560256025602560256025702570257025702570257025702570257025702570257025802580258025802580258025802580258025802580258025902590259025902590259025902590259025902590259025902600260026002600260026002600260026002600260026002610261026102610261026102610261026102610261026102620262026202620262026202620262026202620262026202630263026302630263026302630263026302630263026302630264026402640264026402640264026402640264026402640265026502650265026502650265026502650265026502650266026602660266026602660266026602660266026602660266026702670267026702670267026702670267026702670267026802680268026802680268026802680268026802680268026902690269026902690269026902690269026902690269026902700270027002700270027002700270027002700270027002710271027102710271027102710271027102710271027102720272027202720272027202720272027202720272027202720273027302730273027302730273027302730273027302730274027402740274027402740274027402740274027402740275027502750275027502750275027502750275027502750275027602760276027602760276027602760276027602760276027702770277027702770277027702770277027702770277027802780278027802780278027802780278027802780278027902790279027902790279027902790279027902790279027902800280028002800280028002800280028002800280028002810281028102810281028102810281028102810281028102820282028202820282028202820282028202820282028202820283028302830283028302830283028302830283028302830284028402840284028402840284028402840284028402840285028502850285028502850285028502850285028502850285028602860286028602860286028602860286028602860286028702870287028702870287028702870287028702870287028802880288028802880288028802880288028802880288028802890289028902890289028902890289028902890289028902900290029002900290029002900290029002900290029002910291029102910291029102910291029102910291029102910292029202920292029202920292029202920292029202920293029302930293029302930293029302930293029302930294029402940294029402940294029402940294029402940295029502950295029502950295029502950295029502950295029602960296029602960296029602960296029602960296029702970297029702970297029702970297029702970297029802980298029802980298029802980298029802980298029802990299029902990299029902990299029902990299029903000300030003000300030003000300030003000300030003010301030103010301030103010301030103010301030103010302030203020302030203020302030203020302030203020303030303030303030303030303030303030303030303030304030403040304030403040304030403040304030403040304030503050305030503050305030503050305030503050305030603060306030603060306030603060306030603060306030703070307030703070307030703070307030703070307030703080308030803080308030803080308030803080308030803090309030903090309030903090309030903090309030903100310031003100310031003100310031003100310031003110311031103110311031103110311031103110311031103110312031203120312031203120312031203120312031203120313031303130313031303130313031303130313031303130314031403140314031403140314031403140314031403140314031503150315031503150315031503150315031503150315031603160316031603160316031603160316031603160316031703170317031703170317031703170317031703170317031703180318031803180318031803180318031803180318031803190319031903190319031903190319031903190319031903200320032003200320032003200320032003200320032003200321032103210321032103210321032103210321032103210322032203220322032203220322032203220322032203220323032303230323032303230323032303230323032303230324032403240324032403240324032403240324032403240324032503250325032503250325032503250325032503250325032603260326032603260326032603260326032603260326032703270327032703270327032703270327032703270327032703280328032803280328032803280328032803280328032803290329032903290329032903290329032903290329032903300330033003300330033003300330033003300330033003300331033103310331033103310331033103310331033103310332033203320332033203320332033203320332033203320333033303330333033303330333033303330333033303330333033403340334033403340334033403340334033403340334033503350335033503350335033503350335033503350335033603360336033603360336033603360336033603360336033603370337033703370337033703370337033703370337033703380338033803380338033803380338033803380338033803390339033903390339033903390339033903390339033903400340034003400340034003400340034003400340034003400341034103410341034103410341034103410341034103410342034203420342034203420342034203420342034203420343034303430343034303430343034303430343034303430343034403440344034403440344034403440344034403440344034503450345034503450345034503450345034503450345034603460346034603460346034603460346034603460346034603470347034703470347034703470347034703470347034703480348034803480348034803480348034803480348034803490349034903490349034903490349034903490349034903490350035003500350035003500350035003500350035003500351035103510351035103510351035103510351035103510352035203520352035203520352035203520352035203520352035303530353035303530353035303530353035303530353035403540354035403540354035403540354035403540354035503550355035503550355035503550355035503550355035603560356035603560356035603560356035603560356035603570357035703570357035703570357035703570357035703580358035803580358035803580358035803580358035803590359035903590359035903590359035903590359035903590360036003600360036003600360036003600360036003600361036103610361036103610361036103610361036103610362036203620362036203620362036203620362036203620362036303630363036303630363036303630363036303630363036403640364036403640364036403640364036403640364036503650365036503650365036503650365036503650365036503660366036603660366036603660366036603660366036603670367036703670367036703670367036703670367036703680368036803680368036803680368036803680368036803680369036903690369036903690369036903690369036903690370037003700370037003700370037003700370037003700371037103710371037103710371037103710371037103710372037203720372037203720372037203720372037203720372037303730373037303730373037303730373037303730373037403740374037403740374037403740374037403740374037503750375037503750375037503750375037503750375037503760376037603760376037603760376037603760376037603770377037703770377037703770377037703770377037703780378037803780378037803780378037803780378037803780379037903790379037903790379037903790379037903790380038003800380038003800380038003800380038003800381038103810381038103810381038103810381038103810381038203820382038203820382038203820382038203820382038303830383038303830383038303830383038303830383038403840384038403840384038403840384038403840384038403850385038503850385038503850385038503850385038503860386038603860386038603860386038603860386038603870387038703870387038703870387038703870387038703880388038803880388038803880388038803880388038803880389038903890389038903890389038903890389038903890390039003900390039003900390039003900390039003900391039103910391039103910391039103910391039103910391039203920392039203920392039203920392039203920392039303930393039303930393039303930393039303930393039403940394039403940394039403940394039403940394039403950395039503950395039503950395039503950395039503960396039603960396039603960396039603960396039603970397039703970397039703970397039703970397039703970398039803980398039803980398039803980398039803980399039903990399039903990399039903990399039903990400040004000400040004000400040004000400040004000400040104010401040104010401040104010401040104010401040204020402040204020402040204020402040204020402040304030403040304030403040304030403040304030403040404040404040404040404040404040404040404040404040404050405040504050405040504050405040504050405040504060406040604060406040604060406"] + + } + + ] + + } + { + + "change": [ + + { + + "kind": "update", + + "schema": "public", + + "table": "xpto", + + "columnnames": ["id", "rand1", "bincol"], + + "columntypes": ["int4", "float8", "bytea"], + + "columnvalues": [1, 123.456, "0041004100410041004100410041004100410041004100420042004200420042004200420042004200420042004200420043004300430043004300430043004300430043004300430044004400440044004400440044004400440044004400440045004500450045004500450045004500450045004500450045004600460046004600460046004600460046004600460046004700470047004700470047004700470047004700470047004800480048004800480048004800480048004800480048004800490049004900490049004900490049004900490049004900500050005000500050005000500050005000500050005000510051005100510051005100510051005100510051005100510052005200520052005200520052005200520052005200520053005300530053005300530053005300530053005300530054005400540054005400540054005400540054005400540054005500550055005500550055005500550055005500550055005600560056005600560056005600560056005600560056005700570057005700570057005700570057005700570057005800580058005800580058005800580058005800580058005800590059005900590059005900590059005900590059005900600060006000600060006000600060006000600060006000610061006100610061006100610061006100610061006100610062006200620062006200620062006200620062006200620063006300630063006300630063006300630063006300630064006400640064006400640064006400640064006400640064006500650065006500650065006500650065006500650065006600660066006600660066006600660066006600660066006700670067006700670067006700670067006700670067006700680068006800680068006800680068006800680068006800690069006900690069006900690069006900690069006900700070007000700070007000700070007000700070007000700071007100710071007100710071007100710071007100710072007200720072007200720072007200720072007200720073007300730073007300730073007300730073007300730074007400740074007400740074007400740074007400740074007500750075007500750075007500750075007500750075007600760076007600760076007600760076007600760076007700770077007700770077007700770077007700770077007700780078007800780078007800780078007800780078007800790079007900790079007900790079007900790079007900800080008000800080008000800080008000800080008000800081008100810081008100810081008100810081008100810082008200820082008200820082008200820082008200820083008300830083008300830083008300830083008300830083008400840084008400840084008400840084008400840084008500850085008500850085008500850085008500850085008600860086008600860086008600860086008600860086008600870087008700870087008700870087008700870087008700880088008800880088008800880088008800880088008800890089008900890089008900890089008900890089008900900090009000900090009000900090009000900090009000900091009100910091009100910091009100910091009100910092009200920092009200920092009200920092009200920093009300930093009300930093009300930093009300930093009400940094009400940094009400940094009400940094009500950095009500950095009500950095009500950095009600960096009600960096009600960096009600960096009600970097009700970097009700970097009700970097009700980098009800980098009800980098009800980098009800990099009900990099009900990099009900990099009900990100010001000100010001000100010001000100010001000101010101010101010101010101010101010101010101010102010201020102010201020102010201020102010201020102010301030103010301030103010301030103010301030103010401040104010401040104010401040104010401040104010501050105010501050105010501050105010501050105010601060106010601060106010601060106010601060106010601070107010701070107010701070107010701070107010701080108010801080108010801080108010801080108010801090109010901090109010901090109010901090109010901090110011001100110011001100110011001100110011001100111011101110111011101110111011101110111011101110112011201120112011201120112011201120112011201120112011301130113011301130113011301130113011301130113011401140114011401140114011401140114011401140114011501150115011501150115011501150115011501150115011501160116011601160116011601160116011601160116011601170117011701170117011701170117011701170117011701180118011801180118011801180118011801180118011801190119011901190119011901190119011901190119011901190120012001200120012001200120012001200120012001200121012101210121012101210121012101210121012101210122012201220122012201220122012201220122012201220122012301230123012301230123012301230123012301230123012401240124012401240124012401240124012401240124012501250125012501250125012501250125012501250125012501260126012601260126012601260126012601260126012601270127012701270127012701270127012701270127012701280128012801280128012801280128012801280128012801280129012901290129012901290129012901290129012901290130013001300130013001300130013001300130013001300131013101310131013101310131013101310131013101310131013201320132013201320132013201320132013201320132013301330133013301330133013301330133013301330133013401340134013401340134013401340134013401340134013501350135013501350135013501350135013501350135013501360136013601360136013601360136013601360136013601370137013701370137013701370137013701370137013701380138013801380138013801380138013801380138013801380139013901390139013901390139013901390139013901390140014001400140014001400140014001400140014001400141014101410141014101410141014101410141014101410141014201420142014201420142014201420142014201420142014301430143014301430143014301430143014301430143014401440144014401440144014401440144014401440144014401450145014501450145014501450145014501450145014501460146014601460146014601460146014601460146014601470147014701470147014701470147014701470147014701470148014801480148014801480148014801480148014801480149014901490149014901490149014901490149014901490150015001500150015001500150015001500150015001500151015101510151015101510151015101510151015101510151015201520152015201520152015201520152015201520152015301530153015301530153015301530153015301530153015401540154015401540154015401540154015401540154015401550155015501550155015501550155015501550155015501560156015601560156015601560156015601560156015601570157015701570157015701570157015701570157015701570158015801580158015801580158015801580158015801580159015901590159015901590159015901590159015901590160016001600160016001600160016001600160016001600160016101610161016101610161016101610161016101610161016201620162016201620162016201620162016201620162016301630163016301630163016301630163016301630163016301640164016401640164016401640164016401640164016401650165016501650165016501650165016501650165016501660166016601660166016601660166016601660166016601670167016701670167016701670167016701670167016701670168016801680168016801680168016801680168016801680169016901690169016901690169016901690169016901690170017001700170017001700170017001700170017001700170017101710171017101710171017101710171017101710171017201720172017201720172017201720172017201720172017301730173017301730173017301730173017301730173017301740174017401740174017401740174017401740174017401750175017501750175017501750175017501750175017501760176017601760176017601760176017601760176017601760177017701770177017701770177017701770177017701770178017801780178017801780178017801780178017801780179017901790179017901790179017901790179017901790179018001800180018001800180018001800180018001800180018101810181018101810181018101810181018101810181018201820182018201820182018201820182018201820182018301830183018301830183018301830183018301830183018301840184018401840184018401840184018401840184018401850185018501850185018501850185018501850185018501860186018601860186018601860186018601860186018601860187018701870187018701870187018701870187018701870188018801880188018801880188018801880188018801880189018901890189018901890189018901890189018901890189019001900190019001900190019001900190019001900190019101910191019101910191019101910191019101910191019201920192019201920192019201920192019201920192019201930193019301930193019301930193019301930193019301940194019401940194019401940194019401940194019401950195019501950195019501950195019501950195019501950196019601960196019601960196019601960196019601960197019701970197019701970197019701970197019701970198019801980198019801980198019801980198019801980199019901990199019901990199019901990199019901990199020002000200020002000200020002000200020002000200020102010201020102010201020102010201020102010201020202020202020202020202020202020202020202020202020202030203020302030203020302030203020302030203020302040204020402040204020402040204020402040204020402050205020502050205020502050205020502050205020502050206020602060206020602060206020602060206020602060207020702070207020702070207020702070207020702070208020802080208020802080208020802080208020802080208020902090209020902090209020902090209020902090209021002100210021002100210021002100210021002100210021102110211021102110211021102110211021102110211021102120212021202120212021202120212021202120212021202130213021302130213021302130213021302130213021302140214021402140214021402140214021402140214021402150215021502150215021502150215021502150215021502150216021602160216021602160216021602160216021602160217021702170217021702170217021702170217021702170218021802180218021802180218021802180218021802180218021902190219021902190219021902190219021902190219022002200220022002200220022002200220022002200220022102210221022102210221022102210221022102210221022102220222022202220222022202220222022202220222022202230223022302230223022302230223022302230223022302240224022402240224022402240224022402240224022402240225022502250225022502250225022502250225022502250226022602260226022602260226022602260226022602260227022702270227022702270227022702270227022702270227022802280228022802280228022802280228022802280228022902290229022902290229022902290229022902290229023002300230023002300230023002300230023002300230023102310231023102310231023102310231023102310231023102320232023202320232023202320232023202320232023202330233023302330233023302330233023302330233023302340234023402340234023402340234023402340234023402340235023502350235023502350235023502350235023502350236023602360236023602360236023602360236023602360237023702370237023702370237023702370237023702370237023802380238023802380238023802380238023802380238023902390239023902390239023902390239023902390239024002400240024002400240024002400240024002400240024002410241024102410241024102410241024102410241024102420242024202420242024202420242024202420242024202430243024302430243024302430243024302430243024302430244024402440244024402440244024402440244024402440245024502450245024502450245024502450245024502450246024602460246024602460246024602460246024602460247024702470247024702470247024702470247024702470247024802480248024802480248024802480248024802480248024902490249024902490249024902490249024902490249025002500250025002500250025002500250025002500250025002510251025102510251025102510251025102510251025102520252025202520252025202520252025202520252025202530253025302530253025302530253025302530253025302530254025402540254025402540254025402540254025402540255025502550255025502550255025502550255025502550256025602560256025602560256025602560256025602560256025702570257025702570257025702570257025702570257025802580258025802580258025802580258025802580258025902590259025902590259025902590259025902590259025902600260026002600260026002600260026002600260026002610261026102610261026102610261026102610261026102620262026202620262026202620262026202620262026202630263026302630263026302630263026302630263026302630264026402640264026402640264026402640264026402640265026502650265026502650265026502650265026502650266026602660266026602660266026602660266026602660266026702670267026702670267026702670267026702670267026802680268026802680268026802680268026802680268026902690269026902690269026902690269026902690269026902700270027002700270027002700270027002700270027002710271027102710271027102710271027102710271027102720272027202720272027202720272027202720272027202720273027302730273027302730273027302730273027302730274027402740274027402740274027402740274027402740275027502750275027502750275027502750275027502750275027602760276027602760276027602760276027602760276027702770277027702770277027702770277027702770277027802780278027802780278027802780278027802780278027902790279027902790279027902790279027902790279027902800280028002800280028002800280028002800280028002810281028102810281028102810281028102810281028102820282028202820282028202820282028202820282028202820283028302830283028302830283028302830283028302830284028402840284028402840284028402840284028402840285028502850285028502850285028502850285028502850285028602860286028602860286028602860286028602860286028702870287028702870287028702870287028702870287028802880288028802880288028802880288028802880288028802890289028902890289028902890289028902890289028902900290029002900290029002900290029002900290029002910291029102910291029102910291029102910291029102910292029202920292029202920292029202920292029202920293029302930293029302930293029302930293029302930294029402940294029402940294029402940294029402940295029502950295029502950295029502950295029502950295029602960296029602960296029602960296029602960296029702970297029702970297029702970297029702970297029802980298029802980298029802980298029802980298029802990299029902990299029902990299029902990299029903000300030003000300030003000300030003000300030003010301030103010301030103010301030103010301030103010302030203020302030203020302030203020302030203020303030303030303030303030303030303030303030303030304030403040304030403040304030403040304030403040304030503050305030503050305030503050305030503050305030603060306030603060306030603060306030603060306030703070307030703070307030703070307030703070307030703080308030803080308030803080308030803080308030803090309030903090309030903090309030903090309030903100310031003100310031003100310031003100310031003110311031103110311031103110311031103110311031103110312031203120312031203120312031203120312031203120313031303130313031303130313031303130313031303130314031403140314031403140314031403140314031403140314031503150315031503150315031503150315031503150315031603160316031603160316031603160316031603160316031703170317031703170317031703170317031703170317031703180318031803180318031803180318031803180318031803190319031903190319031903190319031903190319031903200320032003200320032003200320032003200320032003200321032103210321032103210321032103210321032103210322032203220322032203220322032203220322032203220323032303230323032303230323032303230323032303230324032403240324032403240324032403240324032403240324032503250325032503250325032503250325032503250325032603260326032603260326032603260326032603260326032703270327032703270327032703270327032703270327032703280328032803280328032803280328032803280328032803290329032903290329032903290329032903290329032903300330033003300330033003300330033003300330033003300331033103310331033103310331033103310331033103310332033203320332033203320332033203320332033203320333033303330333033303330333033303330333033303330333033403340334033403340334033403340334033403340334033503350335033503350335033503350335033503350335033603360336033603360336033603360336033603360336033603370337033703370337033703370337033703370337033703380338033803380338033803380338033803380338033803390339033903390339033903390339033903390339033903400340034003400340034003400340034003400340034003400341034103410341034103410341034103410341034103410342034203420342034203420342034203420342034203420343034303430343034303430343034303430343034303430343034403440344034403440344034403440344034403440344034503450345034503450345034503450345034503450345034603460346034603460346034603460346034603460346034603470347034703470347034703470347034703470347034703480348034803480348034803480348034803480348034803490349034903490349034903490349034903490349034903490350035003500350035003500350035003500350035003500351035103510351035103510351035103510351035103510352035203520352035203520352035203520352035203520352035303530353035303530353035303530353035303530353035403540354035403540354035403540354035403540354035503550355035503550355035503550355035503550355035603560356035603560356035603560356035603560356035603570357035703570357035703570357035703570357035703580358035803580358035803580358035803580358035803590359035903590359035903590359035903590359035903590360036003600360036003600360036003600360036003600361036103610361036103610361036103610361036103610362036203620362036203620362036203620362036203620362036303630363036303630363036303630363036303630363036403640364036403640364036403640364036403640364036503650365036503650365036503650365036503650365036503660366036603660366036603660366036603660366036603670367036703670367036703670367036703670367036703680368036803680368036803680368036803680368036803680369036903690369036903690369036903690369036903690370037003700370037003700370037003700370037003700371037103710371037103710371037103710371037103710372037203720372037203720372037203720372037203720372037303730373037303730373037303730373037303730373037403740374037403740374037403740374037403740374037503750375037503750375037503750375037503750375037503760376037603760376037603760376037603760376037603770377037703770377037703770377037703770377037703780378037803780378037803780378037803780378037803780379037903790379037903790379037903790379037903790380038003800380038003800380038003800380038003800381038103810381038103810381038103810381038103810381038203820382038203820382038203820382038203820382038303830383038303830383038303830383038303830383038403840384038403840384038403840384038403840384038403850385038503850385038503850385038503850385038503860386038603860386038603860386038603860386038603870387038703870387038703870387038703870387038703880388038803880388038803880388038803880388038803880389038903890389038903890389038903890389038903890390039003900390039003900390039003900390039003900391039103910391039103910391039103910391039103910391039203920392039203920392039203920392039203920392039303930393039303930393039303930393039303930393039403940394039403940394039403940394039403940394039403950395039503950395039503950395039503950395039503960396039603960396039603960396039603960396039603970397039703970397039703970397039703970397039703970398039803980398039803980398039803980398039803980399039903990399039903990399039903990399039903990400040004000400040004000400040004000400040004000400040104010401040104010401040104010401040104010401040204020402040204020402040204020402040204020402040304030403040304030403040304030403040304030403040404040404040404040404040404040404040404040404040404050405040504050405040504050405040504050405040504060406040604060406040604060406"],+ + "oldkeys": { + + "keynames": ["id"], + + "keytypes": ["int4"], + + "keyvalues": [1] + + } + + } + + ] + + } + { + + "change": [ + + { + + "kind": "delete", + + "schema": "public", + + "table": "xpto", + + "oldkeys": { + + "keynames": ["id"], + + "keytypes": ["int4"], + + "keyvalues": [1] + + } + + } + + ] + + } +(3 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); + data +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"action":"B"} + {"action":"I","schema":"public","table":"xpto","columns":[{"name":"id","type":"integer","value":1},{"name":"rand1","type":"double precision","value":11},{"name":"bincol","type":"bytea","value":"0041004100410041004100410041004100410041004100420042004200420042004200420042004200420042004200420043004300430043004300430043004300430043004300430044004400440044004400440044004400440044004400440045004500450045004500450045004500450045004500450045004600460046004600460046004600460046004600460046004700470047004700470047004700470047004700470047004800480048004800480048004800480048004800480048004800490049004900490049004900490049004900490049004900500050005000500050005000500050005000500050005000510051005100510051005100510051005100510051005100510052005200520052005200520052005200520052005200520053005300530053005300530053005300530053005300530054005400540054005400540054005400540054005400540054005500550055005500550055005500550055005500550055005600560056005600560056005600560056005600560056005700570057005700570057005700570057005700570057005800580058005800580058005800580058005800580058005800590059005900590059005900590059005900590059005900600060006000600060006000600060006000600060006000610061006100610061006100610061006100610061006100610062006200620062006200620062006200620062006200620063006300630063006300630063006300630063006300630064006400640064006400640064006400640064006400640064006500650065006500650065006500650065006500650065006600660066006600660066006600660066006600660066006700670067006700670067006700670067006700670067006700680068006800680068006800680068006800680068006800690069006900690069006900690069006900690069006900700070007000700070007000700070007000700070007000700071007100710071007100710071007100710071007100710072007200720072007200720072007200720072007200720073007300730073007300730073007300730073007300730074007400740074007400740074007400740074007400740074007500750075007500750075007500750075007500750075007600760076007600760076007600760076007600760076007700770077007700770077007700770077007700770077007700780078007800780078007800780078007800780078007800790079007900790079007900790079007900790079007900800080008000800080008000800080008000800080008000800081008100810081008100810081008100810081008100810082008200820082008200820082008200820082008200820083008300830083008300830083008300830083008300830083008400840084008400840084008400840084008400840084008500850085008500850085008500850085008500850085008600860086008600860086008600860086008600860086008600870087008700870087008700870087008700870087008700880088008800880088008800880088008800880088008800890089008900890089008900890089008900890089008900900090009000900090009000900090009000900090009000900091009100910091009100910091009100910091009100910092009200920092009200920092009200920092009200920093009300930093009300930093009300930093009300930093009400940094009400940094009400940094009400940094009500950095009500950095009500950095009500950095009600960096009600960096009600960096009600960096009600970097009700970097009700970097009700970097009700980098009800980098009800980098009800980098009800990099009900990099009900990099009900990099009900990100010001000100010001000100010001000100010001000101010101010101010101010101010101010101010101010102010201020102010201020102010201020102010201020102010301030103010301030103010301030103010301030103010401040104010401040104010401040104010401040104010501050105010501050105010501050105010501050105010601060106010601060106010601060106010601060106010601070107010701070107010701070107010701070107010701080108010801080108010801080108010801080108010801090109010901090109010901090109010901090109010901090110011001100110011001100110011001100110011001100111011101110111011101110111011101110111011101110112011201120112011201120112011201120112011201120112011301130113011301130113011301130113011301130113011401140114011401140114011401140114011401140114011501150115011501150115011501150115011501150115011501160116011601160116011601160116011601160116011601170117011701170117011701170117011701170117011701180118011801180118011801180118011801180118011801190119011901190119011901190119011901190119011901190120012001200120012001200120012001200120012001200121012101210121012101210121012101210121012101210122012201220122012201220122012201220122012201220122012301230123012301230123012301230123012301230123012401240124012401240124012401240124012401240124012501250125012501250125012501250125012501250125012501260126012601260126012601260126012601260126012601270127012701270127012701270127012701270127012701280128012801280128012801280128012801280128012801280129012901290129012901290129012901290129012901290130013001300130013001300130013001300130013001300131013101310131013101310131013101310131013101310131013201320132013201320132013201320132013201320132013301330133013301330133013301330133013301330133013401340134013401340134013401340134013401340134013501350135013501350135013501350135013501350135013501360136013601360136013601360136013601360136013601370137013701370137013701370137013701370137013701380138013801380138013801380138013801380138013801380139013901390139013901390139013901390139013901390140014001400140014001400140014001400140014001400141014101410141014101410141014101410141014101410141014201420142014201420142014201420142014201420142014301430143014301430143014301430143014301430143014401440144014401440144014401440144014401440144014401450145014501450145014501450145014501450145014501460146014601460146014601460146014601460146014601470147014701470147014701470147014701470147014701470148014801480148014801480148014801480148014801480149014901490149014901490149014901490149014901490150015001500150015001500150015001500150015001500151015101510151015101510151015101510151015101510151015201520152015201520152015201520152015201520152015301530153015301530153015301530153015301530153015401540154015401540154015401540154015401540154015401550155015501550155015501550155015501550155015501560156015601560156015601560156015601560156015601570157015701570157015701570157015701570157015701570158015801580158015801580158015801580158015801580159015901590159015901590159015901590159015901590160016001600160016001600160016001600160016001600160016101610161016101610161016101610161016101610161016201620162016201620162016201620162016201620162016301630163016301630163016301630163016301630163016301640164016401640164016401640164016401640164016401650165016501650165016501650165016501650165016501660166016601660166016601660166016601660166016601670167016701670167016701670167016701670167016701670168016801680168016801680168016801680168016801680169016901690169016901690169016901690169016901690170017001700170017001700170017001700170017001700170017101710171017101710171017101710171017101710171017201720172017201720172017201720172017201720172017301730173017301730173017301730173017301730173017301740174017401740174017401740174017401740174017401750175017501750175017501750175017501750175017501760176017601760176017601760176017601760176017601760177017701770177017701770177017701770177017701770178017801780178017801780178017801780178017801780179017901790179017901790179017901790179017901790179018001800180018001800180018001800180018001800180018101810181018101810181018101810181018101810181018201820182018201820182018201820182018201820182018301830183018301830183018301830183018301830183018301840184018401840184018401840184018401840184018401850185018501850185018501850185018501850185018501860186018601860186018601860186018601860186018601860187018701870187018701870187018701870187018701870188018801880188018801880188018801880188018801880189018901890189018901890189018901890189018901890189019001900190019001900190019001900190019001900190019101910191019101910191019101910191019101910191019201920192019201920192019201920192019201920192019201930193019301930193019301930193019301930193019301940194019401940194019401940194019401940194019401950195019501950195019501950195019501950195019501950196019601960196019601960196019601960196019601960197019701970197019701970197019701970197019701970198019801980198019801980198019801980198019801980199019901990199019901990199019901990199019901990199020002000200020002000200020002000200020002000200020102010201020102010201020102010201020102010201020202020202020202020202020202020202020202020202020202030203020302030203020302030203020302030203020302040204020402040204020402040204020402040204020402050205020502050205020502050205020502050205020502050206020602060206020602060206020602060206020602060207020702070207020702070207020702070207020702070208020802080208020802080208020802080208020802080208020902090209020902090209020902090209020902090209021002100210021002100210021002100210021002100210021102110211021102110211021102110211021102110211021102120212021202120212021202120212021202120212021202130213021302130213021302130213021302130213021302140214021402140214021402140214021402140214021402150215021502150215021502150215021502150215021502150216021602160216021602160216021602160216021602160217021702170217021702170217021702170217021702170218021802180218021802180218021802180218021802180218021902190219021902190219021902190219021902190219022002200220022002200220022002200220022002200220022102210221022102210221022102210221022102210221022102220222022202220222022202220222022202220222022202230223022302230223022302230223022302230223022302240224022402240224022402240224022402240224022402240225022502250225022502250225022502250225022502250226022602260226022602260226022602260226022602260227022702270227022702270227022702270227022702270227022802280228022802280228022802280228022802280228022902290229022902290229022902290229022902290229023002300230023002300230023002300230023002300230023102310231023102310231023102310231023102310231023102320232023202320232023202320232023202320232023202330233023302330233023302330233023302330233023302340234023402340234023402340234023402340234023402340235023502350235023502350235023502350235023502350236023602360236023602360236023602360236023602360237023702370237023702370237023702370237023702370237023802380238023802380238023802380238023802380238023902390239023902390239023902390239023902390239024002400240024002400240024002400240024002400240024002410241024102410241024102410241024102410241024102420242024202420242024202420242024202420242024202430243024302430243024302430243024302430243024302430244024402440244024402440244024402440244024402440245024502450245024502450245024502450245024502450246024602460246024602460246024602460246024602460247024702470247024702470247024702470247024702470247024802480248024802480248024802480248024802480248024902490249024902490249024902490249024902490249025002500250025002500250025002500250025002500250025002510251025102510251025102510251025102510251025102520252025202520252025202520252025202520252025202530253025302530253025302530253025302530253025302530254025402540254025402540254025402540254025402540255025502550255025502550255025502550255025502550256025602560256025602560256025602560256025602560256025702570257025702570257025702570257025702570257025802580258025802580258025802580258025802580258025902590259025902590259025902590259025902590259025902600260026002600260026002600260026002600260026002610261026102610261026102610261026102610261026102620262026202620262026202620262026202620262026202630263026302630263026302630263026302630263026302630264026402640264026402640264026402640264026402640265026502650265026502650265026502650265026502650266026602660266026602660266026602660266026602660266026702670267026702670267026702670267026702670267026802680268026802680268026802680268026802680268026902690269026902690269026902690269026902690269026902700270027002700270027002700270027002700270027002710271027102710271027102710271027102710271027102720272027202720272027202720272027202720272027202720273027302730273027302730273027302730273027302730274027402740274027402740274027402740274027402740275027502750275027502750275027502750275027502750275027602760276027602760276027602760276027602760276027702770277027702770277027702770277027702770277027802780278027802780278027802780278027802780278027902790279027902790279027902790279027902790279027902800280028002800280028002800280028002800280028002810281028102810281028102810281028102810281028102820282028202820282028202820282028202820282028202820283028302830283028302830283028302830283028302830284028402840284028402840284028402840284028402840285028502850285028502850285028502850285028502850285028602860286028602860286028602860286028602860286028702870287028702870287028702870287028702870287028802880288028802880288028802880288028802880288028802890289028902890289028902890289028902890289028902900290029002900290029002900290029002900290029002910291029102910291029102910291029102910291029102910292029202920292029202920292029202920292029202920293029302930293029302930293029302930293029302930294029402940294029402940294029402940294029402940295029502950295029502950295029502950295029502950295029602960296029602960296029602960296029602960296029702970297029702970297029702970297029702970297029802980298029802980298029802980298029802980298029802990299029902990299029902990299029902990299029903000300030003000300030003000300030003000300030003010301030103010301030103010301030103010301030103010302030203020302030203020302030203020302030203020303030303030303030303030303030303030303030303030304030403040304030403040304030403040304030403040304030503050305030503050305030503050305030503050305030603060306030603060306030603060306030603060306030703070307030703070307030703070307030703070307030703080308030803080308030803080308030803080308030803090309030903090309030903090309030903090309030903100310031003100310031003100310031003100310031003110311031103110311031103110311031103110311031103110312031203120312031203120312031203120312031203120313031303130313031303130313031303130313031303130314031403140314031403140314031403140314031403140314031503150315031503150315031503150315031503150315031603160316031603160316031603160316031603160316031703170317031703170317031703170317031703170317031703180318031803180318031803180318031803180318031803190319031903190319031903190319031903190319031903200320032003200320032003200320032003200320032003200321032103210321032103210321032103210321032103210322032203220322032203220322032203220322032203220323032303230323032303230323032303230323032303230324032403240324032403240324032403240324032403240324032503250325032503250325032503250325032503250325032603260326032603260326032603260326032603260326032703270327032703270327032703270327032703270327032703280328032803280328032803280328032803280328032803290329032903290329032903290329032903290329032903300330033003300330033003300330033003300330033003300331033103310331033103310331033103310331033103310332033203320332033203320332033203320332033203320333033303330333033303330333033303330333033303330333033403340334033403340334033403340334033403340334033503350335033503350335033503350335033503350335033603360336033603360336033603360336033603360336033603370337033703370337033703370337033703370337033703380338033803380338033803380338033803380338033803390339033903390339033903390339033903390339033903400340034003400340034003400340034003400340034003400341034103410341034103410341034103410341034103410342034203420342034203420342034203420342034203420343034303430343034303430343034303430343034303430343034403440344034403440344034403440344034403440344034503450345034503450345034503450345034503450345034603460346034603460346034603460346034603460346034603470347034703470347034703470347034703470347034703480348034803480348034803480348034803480348034803490349034903490349034903490349034903490349034903490350035003500350035003500350035003500350035003500351035103510351035103510351035103510351035103510352035203520352035203520352035203520352035203520352035303530353035303530353035303530353035303530353035403540354035403540354035403540354035403540354035503550355035503550355035503550355035503550355035603560356035603560356035603560356035603560356035603570357035703570357035703570357035703570357035703580358035803580358035803580358035803580358035803590359035903590359035903590359035903590359035903590360036003600360036003600360036003600360036003600361036103610361036103610361036103610361036103610362036203620362036203620362036203620362036203620362036303630363036303630363036303630363036303630363036403640364036403640364036403640364036403640364036503650365036503650365036503650365036503650365036503660366036603660366036603660366036603660366036603670367036703670367036703670367036703670367036703680368036803680368036803680368036803680368036803680369036903690369036903690369036903690369036903690370037003700370037003700370037003700370037003700371037103710371037103710371037103710371037103710372037203720372037203720372037203720372037203720372037303730373037303730373037303730373037303730373037403740374037403740374037403740374037403740374037503750375037503750375037503750375037503750375037503760376037603760376037603760376037603760376037603770377037703770377037703770377037703770377037703780378037803780378037803780378037803780378037803780379037903790379037903790379037903790379037903790380038003800380038003800380038003800380038003800381038103810381038103810381038103810381038103810381038203820382038203820382038203820382038203820382038303830383038303830383038303830383038303830383038403840384038403840384038403840384038403840384038403850385038503850385038503850385038503850385038503860386038603860386038603860386038603860386038603870387038703870387038703870387038703870387038703880388038803880388038803880388038803880388038803880389038903890389038903890389038903890389038903890390039003900390039003900390039003900390039003900391039103910391039103910391039103910391039103910391039203920392039203920392039203920392039203920392039303930393039303930393039303930393039303930393039403940394039403940394039403940394039403940394039403950395039503950395039503950395039503950395039503960396039603960396039603960396039603960396039603970397039703970397039703970397039703970397039703970398039803980398039803980398039803980398039803980399039903990399039903990399039903990399039903990400040004000400040004000400040004000400040004000400040104010401040104010401040104010401040104010401040204020402040204020402040204020402040204020402040304030403040304030403040304030403040304030403040404040404040404040404040404040404040404040404040404050405040504050405040504050405040504050405040504060406040604060406040604060406"}]} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"xpto","columns":[{"name":"id","type":"integer","value":1},{"name":"rand1","type":"double precision","value":123.456},{"name":"bincol","type":"bytea","value":"0041004100410041004100410041004100410041004100420042004200420042004200420042004200420042004200420043004300430043004300430043004300430043004300430044004400440044004400440044004400440044004400440045004500450045004500450045004500450045004500450045004600460046004600460046004600460046004600460046004700470047004700470047004700470047004700470047004800480048004800480048004800480048004800480048004800490049004900490049004900490049004900490049004900500050005000500050005000500050005000500050005000510051005100510051005100510051005100510051005100510052005200520052005200520052005200520052005200520053005300530053005300530053005300530053005300530054005400540054005400540054005400540054005400540054005500550055005500550055005500550055005500550055005600560056005600560056005600560056005600560056005700570057005700570057005700570057005700570057005800580058005800580058005800580058005800580058005800590059005900590059005900590059005900590059005900600060006000600060006000600060006000600060006000610061006100610061006100610061006100610061006100610062006200620062006200620062006200620062006200620063006300630063006300630063006300630063006300630064006400640064006400640064006400640064006400640064006500650065006500650065006500650065006500650065006600660066006600660066006600660066006600660066006700670067006700670067006700670067006700670067006700680068006800680068006800680068006800680068006800690069006900690069006900690069006900690069006900700070007000700070007000700070007000700070007000700071007100710071007100710071007100710071007100710072007200720072007200720072007200720072007200720073007300730073007300730073007300730073007300730074007400740074007400740074007400740074007400740074007500750075007500750075007500750075007500750075007600760076007600760076007600760076007600760076007700770077007700770077007700770077007700770077007700780078007800780078007800780078007800780078007800790079007900790079007900790079007900790079007900800080008000800080008000800080008000800080008000800081008100810081008100810081008100810081008100810082008200820082008200820082008200820082008200820083008300830083008300830083008300830083008300830083008400840084008400840084008400840084008400840084008500850085008500850085008500850085008500850085008600860086008600860086008600860086008600860086008600870087008700870087008700870087008700870087008700880088008800880088008800880088008800880088008800890089008900890089008900890089008900890089008900900090009000900090009000900090009000900090009000900091009100910091009100910091009100910091009100910092009200920092009200920092009200920092009200920093009300930093009300930093009300930093009300930093009400940094009400940094009400940094009400940094009500950095009500950095009500950095009500950095009600960096009600960096009600960096009600960096009600970097009700970097009700970097009700970097009700980098009800980098009800980098009800980098009800990099009900990099009900990099009900990099009900990100010001000100010001000100010001000100010001000101010101010101010101010101010101010101010101010102010201020102010201020102010201020102010201020102010301030103010301030103010301030103010301030103010401040104010401040104010401040104010401040104010501050105010501050105010501050105010501050105010601060106010601060106010601060106010601060106010601070107010701070107010701070107010701070107010701080108010801080108010801080108010801080108010801090109010901090109010901090109010901090109010901090110011001100110011001100110011001100110011001100111011101110111011101110111011101110111011101110112011201120112011201120112011201120112011201120112011301130113011301130113011301130113011301130113011401140114011401140114011401140114011401140114011501150115011501150115011501150115011501150115011501160116011601160116011601160116011601160116011601170117011701170117011701170117011701170117011701180118011801180118011801180118011801180118011801190119011901190119011901190119011901190119011901190120012001200120012001200120012001200120012001200121012101210121012101210121012101210121012101210122012201220122012201220122012201220122012201220122012301230123012301230123012301230123012301230123012401240124012401240124012401240124012401240124012501250125012501250125012501250125012501250125012501260126012601260126012601260126012601260126012601270127012701270127012701270127012701270127012701280128012801280128012801280128012801280128012801280129012901290129012901290129012901290129012901290130013001300130013001300130013001300130013001300131013101310131013101310131013101310131013101310131013201320132013201320132013201320132013201320132013301330133013301330133013301330133013301330133013401340134013401340134013401340134013401340134013501350135013501350135013501350135013501350135013501360136013601360136013601360136013601360136013601370137013701370137013701370137013701370137013701380138013801380138013801380138013801380138013801380139013901390139013901390139013901390139013901390140014001400140014001400140014001400140014001400141014101410141014101410141014101410141014101410141014201420142014201420142014201420142014201420142014301430143014301430143014301430143014301430143014401440144014401440144014401440144014401440144014401450145014501450145014501450145014501450145014501460146014601460146014601460146014601460146014601470147014701470147014701470147014701470147014701470148014801480148014801480148014801480148014801480149014901490149014901490149014901490149014901490150015001500150015001500150015001500150015001500151015101510151015101510151015101510151015101510151015201520152015201520152015201520152015201520152015301530153015301530153015301530153015301530153015401540154015401540154015401540154015401540154015401550155015501550155015501550155015501550155015501560156015601560156015601560156015601560156015601570157015701570157015701570157015701570157015701570158015801580158015801580158015801580158015801580159015901590159015901590159015901590159015901590160016001600160016001600160016001600160016001600160016101610161016101610161016101610161016101610161016201620162016201620162016201620162016201620162016301630163016301630163016301630163016301630163016301640164016401640164016401640164016401640164016401650165016501650165016501650165016501650165016501660166016601660166016601660166016601660166016601670167016701670167016701670167016701670167016701670168016801680168016801680168016801680168016801680169016901690169016901690169016901690169016901690170017001700170017001700170017001700170017001700170017101710171017101710171017101710171017101710171017201720172017201720172017201720172017201720172017301730173017301730173017301730173017301730173017301740174017401740174017401740174017401740174017401750175017501750175017501750175017501750175017501760176017601760176017601760176017601760176017601760177017701770177017701770177017701770177017701770178017801780178017801780178017801780178017801780179017901790179017901790179017901790179017901790179018001800180018001800180018001800180018001800180018101810181018101810181018101810181018101810181018201820182018201820182018201820182018201820182018301830183018301830183018301830183018301830183018301840184018401840184018401840184018401840184018401850185018501850185018501850185018501850185018501860186018601860186018601860186018601860186018601860187018701870187018701870187018701870187018701870188018801880188018801880188018801880188018801880189018901890189018901890189018901890189018901890189019001900190019001900190019001900190019001900190019101910191019101910191019101910191019101910191019201920192019201920192019201920192019201920192019201930193019301930193019301930193019301930193019301940194019401940194019401940194019401940194019401950195019501950195019501950195019501950195019501950196019601960196019601960196019601960196019601960197019701970197019701970197019701970197019701970198019801980198019801980198019801980198019801980199019901990199019901990199019901990199019901990199020002000200020002000200020002000200020002000200020102010201020102010201020102010201020102010201020202020202020202020202020202020202020202020202020202030203020302030203020302030203020302030203020302040204020402040204020402040204020402040204020402050205020502050205020502050205020502050205020502050206020602060206020602060206020602060206020602060207020702070207020702070207020702070207020702070208020802080208020802080208020802080208020802080208020902090209020902090209020902090209020902090209021002100210021002100210021002100210021002100210021102110211021102110211021102110211021102110211021102120212021202120212021202120212021202120212021202130213021302130213021302130213021302130213021302140214021402140214021402140214021402140214021402150215021502150215021502150215021502150215021502150216021602160216021602160216021602160216021602160217021702170217021702170217021702170217021702170218021802180218021802180218021802180218021802180218021902190219021902190219021902190219021902190219022002200220022002200220022002200220022002200220022102210221022102210221022102210221022102210221022102220222022202220222022202220222022202220222022202230223022302230223022302230223022302230223022302240224022402240224022402240224022402240224022402240225022502250225022502250225022502250225022502250226022602260226022602260226022602260226022602260227022702270227022702270227022702270227022702270227022802280228022802280228022802280228022802280228022902290229022902290229022902290229022902290229023002300230023002300230023002300230023002300230023102310231023102310231023102310231023102310231023102320232023202320232023202320232023202320232023202330233023302330233023302330233023302330233023302340234023402340234023402340234023402340234023402340235023502350235023502350235023502350235023502350236023602360236023602360236023602360236023602360237023702370237023702370237023702370237023702370237023802380238023802380238023802380238023802380238023902390239023902390239023902390239023902390239024002400240024002400240024002400240024002400240024002410241024102410241024102410241024102410241024102420242024202420242024202420242024202420242024202430243024302430243024302430243024302430243024302430244024402440244024402440244024402440244024402440245024502450245024502450245024502450245024502450246024602460246024602460246024602460246024602460247024702470247024702470247024702470247024702470247024802480248024802480248024802480248024802480248024902490249024902490249024902490249024902490249025002500250025002500250025002500250025002500250025002510251025102510251025102510251025102510251025102520252025202520252025202520252025202520252025202530253025302530253025302530253025302530253025302530254025402540254025402540254025402540254025402540255025502550255025502550255025502550255025502550256025602560256025602560256025602560256025602560256025702570257025702570257025702570257025702570257025802580258025802580258025802580258025802580258025902590259025902590259025902590259025902590259025902600260026002600260026002600260026002600260026002610261026102610261026102610261026102610261026102620262026202620262026202620262026202620262026202630263026302630263026302630263026302630263026302630264026402640264026402640264026402640264026402640265026502650265026502650265026502650265026502650266026602660266026602660266026602660266026602660266026702670267026702670267026702670267026702670267026802680268026802680268026802680268026802680268026902690269026902690269026902690269026902690269026902700270027002700270027002700270027002700270027002710271027102710271027102710271027102710271027102720272027202720272027202720272027202720272027202720273027302730273027302730273027302730273027302730274027402740274027402740274027402740274027402740275027502750275027502750275027502750275027502750275027602760276027602760276027602760276027602760276027702770277027702770277027702770277027702770277027802780278027802780278027802780278027802780278027902790279027902790279027902790279027902790279027902800280028002800280028002800280028002800280028002810281028102810281028102810281028102810281028102820282028202820282028202820282028202820282028202820283028302830283028302830283028302830283028302830284028402840284028402840284028402840284028402840285028502850285028502850285028502850285028502850285028602860286028602860286028602860286028602860286028702870287028702870287028702870287028702870287028802880288028802880288028802880288028802880288028802890289028902890289028902890289028902890289028902900290029002900290029002900290029002900290029002910291029102910291029102910291029102910291029102910292029202920292029202920292029202920292029202920293029302930293029302930293029302930293029302930294029402940294029402940294029402940294029402940295029502950295029502950295029502950295029502950295029602960296029602960296029602960296029602960296029702970297029702970297029702970297029702970297029802980298029802980298029802980298029802980298029802990299029902990299029902990299029902990299029903000300030003000300030003000300030003000300030003010301030103010301030103010301030103010301030103010302030203020302030203020302030203020302030203020303030303030303030303030303030303030303030303030304030403040304030403040304030403040304030403040304030503050305030503050305030503050305030503050305030603060306030603060306030603060306030603060306030703070307030703070307030703070307030703070307030703080308030803080308030803080308030803080308030803090309030903090309030903090309030903090309030903100310031003100310031003100310031003100310031003110311031103110311031103110311031103110311031103110312031203120312031203120312031203120312031203120313031303130313031303130313031303130313031303130314031403140314031403140314031403140314031403140314031503150315031503150315031503150315031503150315031603160316031603160316031603160316031603160316031703170317031703170317031703170317031703170317031703180318031803180318031803180318031803180318031803190319031903190319031903190319031903190319031903200320032003200320032003200320032003200320032003200321032103210321032103210321032103210321032103210322032203220322032203220322032203220322032203220323032303230323032303230323032303230323032303230324032403240324032403240324032403240324032403240324032503250325032503250325032503250325032503250325032603260326032603260326032603260326032603260326032703270327032703270327032703270327032703270327032703280328032803280328032803280328032803280328032803290329032903290329032903290329032903290329032903300330033003300330033003300330033003300330033003300331033103310331033103310331033103310331033103310332033203320332033203320332033203320332033203320333033303330333033303330333033303330333033303330333033403340334033403340334033403340334033403340334033503350335033503350335033503350335033503350335033603360336033603360336033603360336033603360336033603370337033703370337033703370337033703370337033703380338033803380338033803380338033803380338033803390339033903390339033903390339033903390339033903400340034003400340034003400340034003400340034003400341034103410341034103410341034103410341034103410342034203420342034203420342034203420342034203420343034303430343034303430343034303430343034303430343034403440344034403440344034403440344034403440344034503450345034503450345034503450345034503450345034603460346034603460346034603460346034603460346034603470347034703470347034703470347034703470347034703480348034803480348034803480348034803480348034803490349034903490349034903490349034903490349034903490350035003500350035003500350035003500350035003500351035103510351035103510351035103510351035103510352035203520352035203520352035203520352035203520352035303530353035303530353035303530353035303530353035403540354035403540354035403540354035403540354035503550355035503550355035503550355035503550355035603560356035603560356035603560356035603560356035603570357035703570357035703570357035703570357035703580358035803580358035803580358035803580358035803590359035903590359035903590359035903590359035903590360036003600360036003600360036003600360036003600361036103610361036103610361036103610361036103610362036203620362036203620362036203620362036203620362036303630363036303630363036303630363036303630363036403640364036403640364036403640364036403640364036503650365036503650365036503650365036503650365036503660366036603660366036603660366036603660366036603670367036703670367036703670367036703670367036703680368036803680368036803680368036803680368036803680369036903690369036903690369036903690369036903690370037003700370037003700370037003700370037003700371037103710371037103710371037103710371037103710372037203720372037203720372037203720372037203720372037303730373037303730373037303730373037303730373037403740374037403740374037403740374037403740374037503750375037503750375037503750375037503750375037503760376037603760376037603760376037603760376037603770377037703770377037703770377037703770377037703780378037803780378037803780378037803780378037803780379037903790379037903790379037903790379037903790380038003800380038003800380038003800380038003800381038103810381038103810381038103810381038103810381038203820382038203820382038203820382038203820382038303830383038303830383038303830383038303830383038403840384038403840384038403840384038403840384038403850385038503850385038503850385038503850385038503860386038603860386038603860386038603860386038603870387038703870387038703870387038703870387038703880388038803880388038803880388038803880388038803880389038903890389038903890389038903890389038903890390039003900390039003900390039003900390039003900391039103910391039103910391039103910391039103910391039203920392039203920392039203920392039203920392039303930393039303930393039303930393039303930393039403940394039403940394039403940394039403940394039403950395039503950395039503950395039503950395039503960396039603960396039603960396039603960396039603970397039703970397039703970397039703970397039703970398039803980398039803980398039803980398039803980399039903990399039903990399039903990399039903990400040004000400040004000400040004000400040004000400040104010401040104010401040104010401040104010401040204020402040204020402040204020402040204020402040304030403040304030403040304030403040304030403040404040404040404040404040404040404040404040404040404050405040504050405040504050405040504050405040504060406040604060406040604060406"}],"identity":[{"name":"id","type":"integer","value":1}]} + {"action":"C"} + {"action":"B"} + {"action":"D","schema":"public","table":"xpto","identity":[{"name":"id","type":"integer","value":1}]} + {"action":"C"} +(9 rows) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + diff --git a/src/postgres/third-party-extensions/wal2json/expected/cmdline.out b/src/postgres/third-party-extensions/wal2json/expected/cmdline.out new file mode 100644 index 000000000000..3cbe0cfdc150 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/cmdline.out @@ -0,0 +1,85 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'nosuchopt', '42'); +ERROR: option "nosuchopt" = "42" is unknown +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-unchanged-toast', '1'); +ERROR: parameter "include-unchanged-toast" was deprecated +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'filter-origins', '16, 27, 123'); + data +------ +(0 rows) + +-- don't include not-null constraint by default +CREATE TABLE table_optional ( +a smallserial, +b integer, +c boolean not null, +PRIMARY KEY(a) +); +INSERT INTO table_optional (b, c) VALUES(NULL, TRUE); +UPDATE table_optional SET b = 123 WHERE a = 1; +DELETE FROM table_optional WHERE a = 1; +DROP TABLE table_optional; +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-xids', '0', 'include-not-null', '1'); + data +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"change":[]} + {"change":[{"kind":"insert","schema":"public","table":"table_optional","columnnames":["a","b","c"],"columntypes":["smallint","integer","boolean"],"columnoptionals":[false,true,false],"columnvalues":[1,null,true]}]} + {"change":[{"kind":"update","schema":"public","table":"table_optional","columnnames":["a","b","c"],"columntypes":["smallint","integer","boolean"],"columnoptionals":[false,true,false],"columnvalues":[1,123,true],"oldkeys":{"keynames":["a"],"keytypes":["smallint"],"keyvalues":[1]}}]} + {"change":[{"kind":"delete","schema":"public","table":"table_optional","oldkeys":{"keynames":["a"],"keytypes":["smallint"],"keyvalues":[1]}}]} + {"change":[]} +(5 rows) + +-- By default don't write in chunks +CREATE TABLE x (); +DROP TABLE x; +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-xids', '0'); + data +--------------- + {"change":[]} + {"change":[]} +(2 rows) + +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-xids', '0', 'write-in-chunks', '1'); + data +------------- + {"change":[ + ]} + {"change":[ + ]} +(4 rows) + +-- By default don't write xids +CREATE TABLE gimmexid (id integer PRIMARY KEY); +INSERT INTO gimmexid values (1); +DROP TABLE gimmexid; +SELECT max(((data::json) -> 'xid')::text::int) < txid_current() FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'include-xids', '1'); + ?column? +---------- + t +(1 row) + +SELECT max(((data::json) -> 'xid')::text::int) + 10 > txid_current() FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'include-xids', '1'); + ?column? +---------- + t +(1 row) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL) where ((data::json) -> 'xid') IS NOT NULL; + data +------ +(0 rows) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + diff --git a/src/postgres/third-party-extensions/wal2json/expected/default.out b/src/postgres/third-party-extensions/wal2json/expected/default.out new file mode 100644 index 000000000000..3619c9c532ec --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/default.out @@ -0,0 +1,95 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +CREATE TABLE w2j_default (a serial, b integer DEFAULT 6, c text DEFAULT 'wal2json', d timestamp DEFAULT '2020-07-12 11:55:30', e integer DEFAULT NULL, f integer, PRIMARY KEY(a)); +CREATE TABLE w2j_truncate (a serial primary key, b text not null); +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +INSERT INTO w2j_default (b, c ,d, e, f) VALUES(2, 'test', '2020-03-01 08:09:00', 80, 10); +INSERT INTO w2j_default DEFAULT VALUES; +UPDATE w2j_default SET b = 3 WHERE a = 1; +INSERT INTO w2j_truncate (b) VALUES('foo@bar.com'); +TRUNCATE w2j_truncate; +INSERT INTO w2j_truncate (b) VALUES('foo@bar.com'); +-- without include-default parameter +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1'); + data +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"change":[{"kind":"insert","schema":"public","table":"w2j_default","columnnames":["a","b","c","d","e","f"],"columntypes":["integer","integer","text","timestamp without time zone","integer","integer"],"columnvalues":[1,2,"test","Sun Mar 01 08:09:00 2020",80,10]}]} + {"change":[{"kind":"insert","schema":"public","table":"w2j_default","columnnames":["a","b","c","d","e","f"],"columntypes":["integer","integer","text","timestamp without time zone","integer","integer"],"columnvalues":[2,6,"wal2json","Sun Jul 12 11:55:30 2020",null,null]}]} + {"change":[{"kind":"update","schema":"public","table":"w2j_default","columnnames":["a","b","c","d","e","f"],"columntypes":["integer","integer","text","timestamp without time zone","integer","integer"],"columnvalues":[1,3,"test","Sun Mar 01 08:09:00 2020",80,10],"oldkeys":{"keynames":["a"],"keytypes":["integer"],"keyvalues":[1]}}]} + {"change":[{"kind":"insert","schema":"public","table":"w2j_truncate","columnnames":["a","b"],"columntypes":["integer","text"],"columnvalues":[1,"foo@bar.com"]}]} + {"change":[]} + {"change":[{"kind":"insert","schema":"public","table":"w2j_truncate","columnnames":["a","b"],"columntypes":["integer","text"],"columnvalues":[2,"foo@bar.com"]}]} +(6 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); + data +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_default","columns":[{"name":"a","type":"integer","value":1},{"name":"b","type":"integer","value":2},{"name":"c","type":"text","value":"test"},{"name":"d","type":"timestamp without time zone","value":"Sun Mar 01 08:09:00 2020"},{"name":"e","type":"integer","value":80},{"name":"f","type":"integer","value":10}]} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_default","columns":[{"name":"a","type":"integer","value":2},{"name":"b","type":"integer","value":6},{"name":"c","type":"text","value":"wal2json"},{"name":"d","type":"timestamp without time zone","value":"Sun Jul 12 11:55:30 2020"},{"name":"e","type":"integer","value":null},{"name":"f","type":"integer","value":null}]} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"w2j_default","columns":[{"name":"a","type":"integer","value":1},{"name":"b","type":"integer","value":3},{"name":"c","type":"text","value":"test"},{"name":"d","type":"timestamp without time zone","value":"Sun Mar 01 08:09:00 2020"},{"name":"e","type":"integer","value":80},{"name":"f","type":"integer","value":10}],"identity":[{"name":"a","type":"integer","value":1}]} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_truncate","columns":[{"name":"a","type":"integer","value":1},{"name":"b","type":"text","value":"foo@bar.com"}]} + {"action":"C"} + {"action":"B"} + {"action":"T","schema":"public","table":"w2j_truncate"} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_truncate","columns":[{"name":"a","type":"integer","value":2},{"name":"b","type":"text","value":"foo@bar.com"}]} + {"action":"C"} +(18 rows) + +-- with include-default parameter +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-default', '1'); + data +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"change":[{"kind":"insert","schema":"public","table":"w2j_default","columnnames":["a","b","c","d","e","f"],"columntypes":["integer","integer","text","timestamp without time zone","integer","integer"],"columndefaults":["nextval('w2j_default_a_seq'::regclass)","6","'wal2json'::text","'Sun Jul 12 11:55:30 2020'::timestamp without time zone",null,null],"columnvalues":[1,2,"test","Sun Mar 01 08:09:00 2020",80,10]}]} + {"change":[{"kind":"insert","schema":"public","table":"w2j_default","columnnames":["a","b","c","d","e","f"],"columntypes":["integer","integer","text","timestamp without time zone","integer","integer"],"columndefaults":["nextval('w2j_default_a_seq'::regclass)","6","'wal2json'::text","'Sun Jul 12 11:55:30 2020'::timestamp without time zone",null,null],"columnvalues":[2,6,"wal2json","Sun Jul 12 11:55:30 2020",null,null]}]} + {"change":[{"kind":"update","schema":"public","table":"w2j_default","columnnames":["a","b","c","d","e","f"],"columntypes":["integer","integer","text","timestamp without time zone","integer","integer"],"columndefaults":["nextval('w2j_default_a_seq'::regclass)","6","'wal2json'::text","'Sun Jul 12 11:55:30 2020'::timestamp without time zone",null,null],"columnvalues":[1,3,"test","Sun Mar 01 08:09:00 2020",80,10],"oldkeys":{"keynames":["a"],"keytypes":["integer"],"keyvalues":[1]}}]} + {"change":[{"kind":"insert","schema":"public","table":"w2j_truncate","columnnames":["a","b"],"columntypes":["integer","text"],"columndefaults":["nextval('w2j_truncate_a_seq'::regclass)",null],"columnvalues":[1,"foo@bar.com"]}]} + {"change":[]} + {"change":[{"kind":"insert","schema":"public","table":"w2j_truncate","columnnames":["a","b"],"columntypes":["integer","text"],"columndefaults":["nextval('w2j_truncate_a_seq'::regclass)",null],"columnvalues":[2,"foo@bar.com"]}]} +(6 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'include-default', '1'); + data +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_default","columns":[{"name":"a","type":"integer","value":1,"default":"nextval('w2j_default_a_seq'::regclass)"},{"name":"b","type":"integer","value":2,"default":"6"},{"name":"c","type":"text","value":"test","default":"'wal2json'::text"},{"name":"d","type":"timestamp without time zone","value":"Sun Mar 01 08:09:00 2020","default":"'Sun Jul 12 11:55:30 2020'::timestamp without time zone"},{"name":"e","type":"integer","value":80,"default":null},{"name":"f","type":"integer","value":10,"default":null}]} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_default","columns":[{"name":"a","type":"integer","value":2,"default":"nextval('w2j_default_a_seq'::regclass)"},{"name":"b","type":"integer","value":6,"default":"6"},{"name":"c","type":"text","value":"wal2json","default":"'wal2json'::text"},{"name":"d","type":"timestamp without time zone","value":"Sun Jul 12 11:55:30 2020","default":"'Sun Jul 12 11:55:30 2020'::timestamp without time zone"},{"name":"e","type":"integer","value":null,"default":null},{"name":"f","type":"integer","value":null,"default":null}]} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"w2j_default","columns":[{"name":"a","type":"integer","value":1,"default":"nextval('w2j_default_a_seq'::regclass)"},{"name":"b","type":"integer","value":3,"default":"6"},{"name":"c","type":"text","value":"test","default":"'wal2json'::text"},{"name":"d","type":"timestamp without time zone","value":"Sun Mar 01 08:09:00 2020","default":"'Sun Jul 12 11:55:30 2020'::timestamp without time zone"},{"name":"e","type":"integer","value":80,"default":null},{"name":"f","type":"integer","value":10,"default":null}],"identity":[{"name":"a","type":"integer","value":1}]} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_truncate","columns":[{"name":"a","type":"integer","value":1,"default":"nextval('w2j_truncate_a_seq'::regclass)"},{"name":"b","type":"text","value":"foo@bar.com","default":null}]} + {"action":"C"} + {"action":"B"} + {"action":"T","schema":"public","table":"w2j_truncate"} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_truncate","columns":[{"name":"a","type":"integer","value":2,"default":"nextval('w2j_truncate_a_seq'::regclass)"},{"name":"b","type":"text","value":"foo@bar.com","default":null}]} + {"action":"C"} +(18 rows) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + +DROP TABLE w2j_default; +DROP TABLE w2j_truncate; diff --git a/src/postgres/third-party-extensions/wal2json/expected/default_2.out b/src/postgres/third-party-extensions/wal2json/expected/default_2.out new file mode 100644 index 000000000000..61ab5e41c4b4 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/default_2.out @@ -0,0 +1,93 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +CREATE TABLE w2j_default (a serial, b integer DEFAULT 6, c text DEFAULT 'wal2json', d timestamp DEFAULT '2020-07-12 11:55:30', e integer DEFAULT NULL, f integer, PRIMARY KEY(a)); +CREATE TABLE w2j_truncate (a serial primary key, b text not null); +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +INSERT INTO w2j_default (b, c ,d, e, f) VALUES(2, 'test', '2020-03-01 08:09:00', 80, 10); +INSERT INTO w2j_default DEFAULT VALUES; +UPDATE w2j_default SET b = 3 WHERE a = 1; +INSERT INTO w2j_truncate (b) VALUES('foo@bar.com'); +TRUNCATE w2j_truncate; +INSERT INTO w2j_truncate (b) VALUES('foo@bar.com'); +-- without include-default parameter +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1'); + data +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"change":[{"kind":"insert","schema":"public","table":"w2j_default","columnnames":["a","b","c","d","e","f"],"columntypes":["integer","integer","text","timestamp without time zone","integer","integer"],"columnvalues":[1,2,"test","Sun Mar 01 08:09:00 2020",80,10]}]} + {"change":[{"kind":"insert","schema":"public","table":"w2j_default","columnnames":["a","b","c","d","e","f"],"columntypes":["integer","integer","text","timestamp without time zone","integer","integer"],"columnvalues":[2,6,"wal2json","Sun Jul 12 11:55:30 2020",null,null]}]} + {"change":[{"kind":"update","schema":"public","table":"w2j_default","columnnames":["a","b","c","d","e","f"],"columntypes":["integer","integer","text","timestamp without time zone","integer","integer"],"columnvalues":[1,3,"test","Sun Mar 01 08:09:00 2020",80,10],"oldkeys":{"keynames":["a"],"keytypes":["integer"],"keyvalues":[1]}}]} + {"change":[{"kind":"insert","schema":"public","table":"w2j_truncate","columnnames":["a","b"],"columntypes":["integer","text"],"columnvalues":[1,"foo@bar.com"]}]} + {"change":[]} + {"change":[{"kind":"insert","schema":"public","table":"w2j_truncate","columnnames":["a","b"],"columntypes":["integer","text"],"columnvalues":[2,"foo@bar.com"]}]} +(6 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); + data +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_default","columns":[{"name":"a","type":"integer","value":1},{"name":"b","type":"integer","value":2},{"name":"c","type":"text","value":"test"},{"name":"d","type":"timestamp without time zone","value":"Sun Mar 01 08:09:00 2020"},{"name":"e","type":"integer","value":80},{"name":"f","type":"integer","value":10}]} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_default","columns":[{"name":"a","type":"integer","value":2},{"name":"b","type":"integer","value":6},{"name":"c","type":"text","value":"wal2json"},{"name":"d","type":"timestamp without time zone","value":"Sun Jul 12 11:55:30 2020"},{"name":"e","type":"integer","value":null},{"name":"f","type":"integer","value":null}]} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"w2j_default","columns":[{"name":"a","type":"integer","value":1},{"name":"b","type":"integer","value":3},{"name":"c","type":"text","value":"test"},{"name":"d","type":"timestamp without time zone","value":"Sun Mar 01 08:09:00 2020"},{"name":"e","type":"integer","value":80},{"name":"f","type":"integer","value":10}],"identity":[{"name":"a","type":"integer","value":1}]} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_truncate","columns":[{"name":"a","type":"integer","value":1},{"name":"b","type":"text","value":"foo@bar.com"}]} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_truncate","columns":[{"name":"a","type":"integer","value":2},{"name":"b","type":"text","value":"foo@bar.com"}]} + {"action":"C"} +(17 rows) + +-- with include-default parameter +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-default', '1'); + data +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"change":[{"kind":"insert","schema":"public","table":"w2j_default","columnnames":["a","b","c","d","e","f"],"columntypes":["integer","integer","text","timestamp without time zone","integer","integer"],"columndefaults":["nextval('w2j_default_a_seq'::regclass)","6","'wal2json'::text","'Sun Jul 12 11:55:30 2020'::timestamp without time zone",null,null],"columnvalues":[1,2,"test","Sun Mar 01 08:09:00 2020",80,10]}]} + {"change":[{"kind":"insert","schema":"public","table":"w2j_default","columnnames":["a","b","c","d","e","f"],"columntypes":["integer","integer","text","timestamp without time zone","integer","integer"],"columndefaults":["nextval('w2j_default_a_seq'::regclass)","6","'wal2json'::text","'Sun Jul 12 11:55:30 2020'::timestamp without time zone",null,null],"columnvalues":[2,6,"wal2json","Sun Jul 12 11:55:30 2020",null,null]}]} + {"change":[{"kind":"update","schema":"public","table":"w2j_default","columnnames":["a","b","c","d","e","f"],"columntypes":["integer","integer","text","timestamp without time zone","integer","integer"],"columndefaults":["nextval('w2j_default_a_seq'::regclass)","6","'wal2json'::text","'Sun Jul 12 11:55:30 2020'::timestamp without time zone",null,null],"columnvalues":[1,3,"test","Sun Mar 01 08:09:00 2020",80,10],"oldkeys":{"keynames":["a"],"keytypes":["integer"],"keyvalues":[1]}}]} + {"change":[{"kind":"insert","schema":"public","table":"w2j_truncate","columnnames":["a","b"],"columntypes":["integer","text"],"columndefaults":["nextval('w2j_truncate_a_seq'::regclass)",null],"columnvalues":[1,"foo@bar.com"]}]} + {"change":[]} + {"change":[{"kind":"insert","schema":"public","table":"w2j_truncate","columnnames":["a","b"],"columntypes":["integer","text"],"columndefaults":["nextval('w2j_truncate_a_seq'::regclass)",null],"columnvalues":[2,"foo@bar.com"]}]} +(6 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'include-default', '1'); + data +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_default","columns":[{"name":"a","type":"integer","value":1,"default":"nextval('w2j_default_a_seq'::regclass)"},{"name":"b","type":"integer","value":2,"default":"6"},{"name":"c","type":"text","value":"test","default":"'wal2json'::text"},{"name":"d","type":"timestamp without time zone","value":"Sun Mar 01 08:09:00 2020","default":"'Sun Jul 12 11:55:30 2020'::timestamp without time zone"},{"name":"e","type":"integer","value":80,"default":null},{"name":"f","type":"integer","value":10,"default":null}]} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_default","columns":[{"name":"a","type":"integer","value":2,"default":"nextval('w2j_default_a_seq'::regclass)"},{"name":"b","type":"integer","value":6,"default":"6"},{"name":"c","type":"text","value":"wal2json","default":"'wal2json'::text"},{"name":"d","type":"timestamp without time zone","value":"Sun Jul 12 11:55:30 2020","default":"'Sun Jul 12 11:55:30 2020'::timestamp without time zone"},{"name":"e","type":"integer","value":null,"default":null},{"name":"f","type":"integer","value":null,"default":null}]} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"w2j_default","columns":[{"name":"a","type":"integer","value":1,"default":"nextval('w2j_default_a_seq'::regclass)"},{"name":"b","type":"integer","value":3,"default":"6"},{"name":"c","type":"text","value":"test","default":"'wal2json'::text"},{"name":"d","type":"timestamp without time zone","value":"Sun Mar 01 08:09:00 2020","default":"'Sun Jul 12 11:55:30 2020'::timestamp without time zone"},{"name":"e","type":"integer","value":80,"default":null},{"name":"f","type":"integer","value":10,"default":null}],"identity":[{"name":"a","type":"integer","value":1}]} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_truncate","columns":[{"name":"a","type":"integer","value":1,"default":"nextval('w2j_truncate_a_seq'::regclass)"},{"name":"b","type":"text","value":"foo@bar.com","default":null}]} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_truncate","columns":[{"name":"a","type":"integer","value":2,"default":"nextval('w2j_truncate_a_seq'::regclass)"},{"name":"b","type":"text","value":"foo@bar.com","default":null}]} + {"action":"C"} +(17 rows) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + +DROP TABLE w2j_default; +DROP TABLE w2j_truncate; diff --git a/src/postgres/third-party-extensions/wal2json/expected/delete1.out b/src/postgres/third-party-extensions/wal2json/expected/delete1.out new file mode 100644 index 000000000000..ba39853ac37b --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/delete1.out @@ -0,0 +1,127 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +DROP TABLE IF EXISTS table_with_pk; +DROP TABLE IF EXISTS table_without_pk; +DROP TABLE IF EXISTS table_with_unique; +CREATE TABLE table_with_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +PRIMARY KEY(b, c, d) +); +CREATE TABLE table_without_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector +); +CREATE TABLE table_with_unique ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3) not null, +f real not null, +g double precision not null, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +UNIQUE(g, n) +); +-- INSERT +INSERT INTO table_with_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_without_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_with_unique (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +-- DELETE: no pk +DELETE FROM table_without_pk WHERE b = 1; +-- DELETE: pk +DELETE FROM table_with_pk WHERE b = 1; +-- DELETE: unique +DELETE FROM table_with_unique WHERE b = 1; +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0'); +WARNING: table "table_without_pk" without primary key or replica identity is nothing +WARNING: table "table_with_unique" without primary key or replica identity is nothing + data +----------------------------------------------------------------------- + { + + "change": [ + + ] + + } + { + + "change": [ + + { + + "kind": "delete", + + "schema": "public", + + "table": "table_with_pk", + + "oldkeys": { + + "keynames": ["b", "c", "d"], + + "keytypes": ["int2", "int4", "int8"],+ + "keyvalues": [1, 2, 3] + + } + + } + + ] + + } + { + + "change": [ + + ] + + } +(3 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); +WARNING: no tuple identifier for DELETE in table "public"."table_without_pk" +WARNING: no tuple identifier for DELETE in table "public"."table_with_unique" + data +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"D","schema":"public","table":"table_with_pk","identity":[{"name":"b","type":"smallint","value":1},{"name":"c","type":"integer","value":2},{"name":"d","type":"bigint","value":3}]} + {"action":"C"} + {"action":"B"} + {"action":"C"} +(7 rows) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + diff --git a/src/postgres/third-party-extensions/wal2json/expected/delete2.out b/src/postgres/third-party-extensions/wal2json/expected/delete2.out new file mode 100644 index 000000000000..5cfc403a011e --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/delete2.out @@ -0,0 +1,158 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +DROP TABLE IF EXISTS table_with_pk; +DROP TABLE IF EXISTS table_without_pk; +DROP TABLE IF EXISTS table_with_unique; +CREATE TABLE table_with_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +PRIMARY KEY(b, c, d) +); +CREATE TABLE table_without_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector +); +CREATE TABLE table_with_unique ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3) not null, +f real not null, +g double precision not null, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +UNIQUE(g, n) +); +-- INSERT +INSERT INTO table_with_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_without_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_with_unique (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +-- DELETE: REPLICA IDENTITY NOTHING +ALTER TABLE table_with_pk REPLICA IDENTITY NOTHING; +DELETE FROM table_with_pk WHERE b = 1; +ALTER TABLE table_with_pk REPLICA IDENTITY DEFAULT; +ALTER TABLE table_without_pk REPLICA IDENTITY NOTHING; +DELETE FROM table_without_pk WHERE b = 1; +ALTER TABLE table_without_pk REPLICA IDENTITY DEFAULT; +ALTER TABLE table_with_unique REPLICA IDENTITY NOTHING; +DELETE FROM table_with_unique WHERE b = 1; +ALTER TABLE table_with_unique REPLICA IDENTITY DEFAULT; +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0'); +WARNING: table "table_with_pk" without primary key or replica identity is nothing +WARNING: table "table_without_pk" without primary key or replica identity is nothing +WARNING: table "table_with_unique" without primary key or replica identity is nothing + data +--------------------- + { + + "change": [+ + ] + + } + { + + "change": [+ + ] + + } + { + + "change": [+ + ] + + } + { + + "change": [+ + ] + + } + { + + "change": [+ + ] + + } + { + + "change": [+ + ] + + } + { + + "change": [+ + ] + + } + { + + "change": [+ + ] + + } + { + + "change": [+ + ] + + } +(9 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); +WARNING: no tuple identifier for DELETE in table "public"."table_with_pk" +WARNING: no tuple identifier for DELETE in table "public"."table_without_pk" +WARNING: no tuple identifier for DELETE in table "public"."table_with_unique" + data +---------------- + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} +(18 rows) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + diff --git a/src/postgres/third-party-extensions/wal2json/expected/delete3.out b/src/postgres/third-party-extensions/wal2json/expected/delete3.out new file mode 100644 index 000000000000..36aa886ce7bd --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/delete3.out @@ -0,0 +1,205 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +SET extra_float_digits = 0; +DROP TABLE IF EXISTS table_with_pk; +DROP TABLE IF EXISTS table_without_pk; +DROP TABLE IF EXISTS table_with_unique; +CREATE TABLE table_with_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +PRIMARY KEY(b, c, d) +); +CREATE TABLE table_without_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector +); +CREATE TABLE table_with_unique ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3) not null, +f real not null, +g double precision not null, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +UNIQUE(g, n) +); +-- INSERT +INSERT INTO table_with_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_with_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(4, 5, 6, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_without_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_with_unique (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +-- DELETE: REPLICA IDENTITY FULL +ALTER TABLE table_with_pk REPLICA IDENTITY FULL; +DELETE FROM table_with_pk WHERE b = 1; +DELETE FROM table_with_pk WHERE n = true; +ALTER TABLE table_with_pk REPLICA IDENTITY DEFAULT; +ALTER TABLE table_without_pk REPLICA IDENTITY FULL; +DELETE FROM table_without_pk WHERE b = 1; +ALTER TABLE table_without_pk REPLICA IDENTITY DEFAULT; +ALTER TABLE table_with_unique REPLICA IDENTITY FULL; +DELETE FROM table_with_unique WHERE b = 1; +ALTER TABLE table_with_unique REPLICA IDENTITY DEFAULT; +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0'); + data +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + { + + "change": [ + + ] + + } + { + + "change": [ + + { + + "kind": "delete", + + "schema": "public", + + "table": "table_with_pk", + + "oldkeys": { + + "keynames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "keytypes": ["int2", "int2", "int4", "int8", "numeric", "float4", "float8", "bpchar", "varchar", "text", "varbit", "timestamp", "date", "bool", "json", "tsvector"], + + "keyvalues": [1, 1, 2, 3, 3.540, 876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"]+ + } + + } + + ] + + } + { + + "change": [ + + { + + "kind": "delete", + + "schema": "public", + + "table": "table_with_pk", + + "oldkeys": { + + "keynames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "keytypes": ["int2", "int2", "int4", "int8", "numeric", "float4", "float8", "bpchar", "varchar", "text", "varbit", "timestamp", "date", "bool", "json", "tsvector"], + + "keyvalues": [2, 4, 5, 6, 3.540, 876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"]+ + } + + } + + ] + + } + { + + "change": [ + + ] + + } + { + + "change": [ + + ] + + } + { + + "change": [ + + { + + "kind": "delete", + + "schema": "public", + + "table": "table_without_pk", + + "oldkeys": { + + "keynames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "keytypes": ["int2", "int2", "int4", "int8", "numeric", "float4", "float8", "bpchar", "varchar", "text", "varbit", "timestamp", "date", "bool", "json", "tsvector"], + + "keyvalues": [1, 1, 2, 3, 3.540, 876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"]+ + } + + } + + ] + + } + { + + "change": [ + + ] + + } + { + + "change": [ + + ] + + } + { + + "change": [ + + { + + "kind": "delete", + + "schema": "public", + + "table": "table_with_unique", + + "oldkeys": { + + "keynames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "keytypes": ["int2", "int2", "int4", "int8", "numeric", "float4", "float8", "bpchar", "varchar", "text", "varbit", "timestamp", "date", "bool", "json", "tsvector"], + + "keyvalues": [1, 1, 2, 3, 3.540, 876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"]+ + } + + } + + ] + + } + { + + "change": [ + + ] + + } +(10 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); + data +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"D","schema":"public","table":"table_with_pk","identity":[{"name":"a","type":"smallint","value":1},{"name":"b","type":"smallint","value":1},{"name":"c","type":"integer","value":2},{"name":"d","type":"bigint","value":3},{"name":"e","type":"numeric(5,3)","value":3.540},{"name":"f","type":"real","value":876.563},{"name":"g","type":"double precision","value":1.23},{"name":"h","type":"character(10)","value":"teste "},{"name":"i","type":"character varying(30)","value":"testando"},{"name":"j","type":"text","value":"um texto longo"},{"name":"k","type":"bit varying(20)","value":"001110010101010"},{"name":"l","type":"timestamp without time zone","value":"Sat Nov 02 17:30:52 2013"},{"name":"m","type":"date","value":"02-04-2013"},{"name":"n","type":"boolean","value":true},{"name":"o","type":"json","value":"{ \"a\": 123 }"},{"name":"p","type":"tsvector","value":"'Old' 'Parr'"}]} + {"action":"C"} + {"action":"B"} + {"action":"D","schema":"public","table":"table_with_pk","identity":[{"name":"a","type":"smallint","value":2},{"name":"b","type":"smallint","value":4},{"name":"c","type":"integer","value":5},{"name":"d","type":"bigint","value":6},{"name":"e","type":"numeric(5,3)","value":3.540},{"name":"f","type":"real","value":876.563},{"name":"g","type":"double precision","value":1.23},{"name":"h","type":"character(10)","value":"teste "},{"name":"i","type":"character varying(30)","value":"testando"},{"name":"j","type":"text","value":"um texto longo"},{"name":"k","type":"bit varying(20)","value":"001110010101010"},{"name":"l","type":"timestamp without time zone","value":"Sat Nov 02 17:30:52 2013"},{"name":"m","type":"date","value":"02-04-2013"},{"name":"n","type":"boolean","value":true},{"name":"o","type":"json","value":"{ \"a\": 123 }"},{"name":"p","type":"tsvector","value":"'Old' 'Parr'"}]} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"D","schema":"public","table":"table_without_pk","identity":[{"name":"a","type":"smallint","value":1},{"name":"b","type":"smallint","value":1},{"name":"c","type":"integer","value":2},{"name":"d","type":"bigint","value":3},{"name":"e","type":"numeric(5,3)","value":3.540},{"name":"f","type":"real","value":876.563},{"name":"g","type":"double precision","value":1.23},{"name":"h","type":"character(10)","value":"teste "},{"name":"i","type":"character varying(30)","value":"testando"},{"name":"j","type":"text","value":"um texto longo"},{"name":"k","type":"bit varying(20)","value":"001110010101010"},{"name":"l","type":"timestamp without time zone","value":"Sat Nov 02 17:30:52 2013"},{"name":"m","type":"date","value":"02-04-2013"},{"name":"n","type":"boolean","value":true},{"name":"o","type":"json","value":"{ \"a\": 123 }"},{"name":"p","type":"tsvector","value":"'Old' 'Parr'"}]} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"D","schema":"public","table":"table_with_unique","identity":[{"name":"a","type":"smallint","value":1},{"name":"b","type":"smallint","value":1},{"name":"c","type":"integer","value":2},{"name":"d","type":"bigint","value":3},{"name":"e","type":"numeric(5,3)","value":3.540},{"name":"f","type":"real","value":876.563},{"name":"g","type":"double precision","value":1.23},{"name":"h","type":"character(10)","value":"teste "},{"name":"i","type":"character varying(30)","value":"testando"},{"name":"j","type":"text","value":"um texto longo"},{"name":"k","type":"bit varying(20)","value":"001110010101010"},{"name":"l","type":"timestamp without time zone","value":"Sat Nov 02 17:30:52 2013"},{"name":"m","type":"date","value":"02-04-2013"},{"name":"n","type":"boolean","value":true},{"name":"o","type":"json","value":"{ \"a\": 123 }"},{"name":"p","type":"tsvector","value":"'Old' 'Parr'"}]} + {"action":"C"} + {"action":"B"} + {"action":"C"} +(24 rows) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + diff --git a/src/postgres/third-party-extensions/wal2json/expected/delete4.out b/src/postgres/third-party-extensions/wal2json/expected/delete4.out new file mode 100644 index 000000000000..a4f4a7ddfac4 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/delete4.out @@ -0,0 +1,99 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +DROP TABLE IF EXISTS table_with_unique; +CREATE TABLE table_with_unique ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3) not null, +f real not null, +g double precision not null, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +UNIQUE(g, n) +); +-- INSERT +INSERT INTO table_with_unique (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', false, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_with_unique (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(4, 5, 6, 3.54, 876.563452345, 4.56, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +-- DELETE: REPLICA IDENTITY INDEX +ALTER TABLE table_with_unique REPLICA IDENTITY USING INDEX table_with_unique_g_n_key; +DELETE FROM table_with_unique WHERE b = 1; +DELETE FROM table_with_unique WHERE n = true; +ALTER TABLE table_with_unique REPLICA IDENTITY DEFAULT; +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0'); + data +----------------------------------------------------------------- + { + + "change": [ + + ] + + } + { + + "change": [ + + { + + "kind": "delete", + + "schema": "public", + + "table": "table_with_unique", + + "oldkeys": { + + "keynames": ["g", "n"], + + "keytypes": ["float8", "bool"],+ + "keyvalues": [1.23, false] + + } + + } + + ] + + } + { + + "change": [ + + { + + "kind": "delete", + + "schema": "public", + + "table": "table_with_unique", + + "oldkeys": { + + "keynames": ["g", "n"], + + "keytypes": ["float8", "bool"],+ + "keyvalues": [4.56, true] + + } + + } + + ] + + } + { + + "change": [ + + ] + + } +(4 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); + data +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"D","schema":"public","table":"table_with_unique","identity":[{"name":"g","type":"double precision","value":1.23},{"name":"n","type":"boolean","value":false}]} + {"action":"C"} + {"action":"B"} + {"action":"D","schema":"public","table":"table_with_unique","identity":[{"name":"g","type":"double precision","value":4.56},{"name":"n","type":"boolean","value":true}]} + {"action":"C"} + {"action":"B"} + {"action":"C"} +(10 rows) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + diff --git a/src/postgres/third-party-extensions/wal2json/expected/filtertable.out b/src/postgres/third-party-extensions/wal2json/expected/filtertable.out new file mode 100644 index 000000000000..2cefb887b5c7 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/filtertable.out @@ -0,0 +1,219 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +DROP TABLE IF EXISTS filter_table_1; +NOTICE: table "filter_table_1" does not exist, skipping +DROP TABLE IF EXISTS filter_table_2; +NOTICE: table "filter_table_2" does not exist, skipping +DROP TABLE IF EXISTS filter_table_3; +NOTICE: table "filter_table_3" does not exist, skipping +DROP TABLE IF EXISTS filter_table_4; +NOTICE: table "filter_table_4" does not exist, skipping +DROP TABLE IF EXISTS "Filter_table_5"; +NOTICE: table "Filter_table_5" does not exist, skipping +DROP TABLE IF EXISTS "filter table_6"; +NOTICE: table "filter table_6" does not exist, skipping +DROP TABLE IF EXISTS "filter.table_7"; +NOTICE: table "filter.table_7" does not exist, skipping +DROP TABLE IF EXISTS "filter,table_8"; +NOTICE: table "filter,table_8" does not exist, skipping +DROP TABLE IF EXISTS "filter""table_9"; +NOTICE: table "filter"table_9" does not exist, skipping +DROP TABLE IF EXISTS " filter_table_10"; +NOTICE: table " filter_table_10" does not exist, skipping +DROP TABLE IF EXISTS "*"; +NOTICE: table "*" does not exist, skipping +DROP SCHEMA IF EXISTS filter_schema_1 CASCADE; +NOTICE: schema "filter_schema_1" does not exist, skipping +DROP SCHEMA IF EXISTS filter_schema_2 CASCADE; +NOTICE: schema "filter_schema_2" does not exist, skipping +DROP SCHEMA IF EXISTS "*" CASCADE; +NOTICE: schema "*" does not exist, skipping +CREATE SCHEMA filter_schema_1; +CREATE SCHEMA filter_schema_2; +CREATE SCHEMA "*"; +CREATE TABLE filter_table_1 (a integer, b text, primary key(a)); +CREATE TABLE filter_schema_1.filter_table_1 (a integer, b text, primary key(a)); +CREATE TABLE filter_schema_1.filter_table_2 (a integer, b text, primary key(a)); +CREATE TABLE filter_schema_2.filter_table_1 (a integer, b text, primary key(a)); +CREATE TABLE filter_schema_2.filter_table_2 (a integer, b text, primary key(a)); +CREATE TABLE filter_schema_2.filter_table_3 (a integer, b text, primary key(a)); +CREATE TABLE filter_table_2 (a integer, b text, primary key(a)); +CREATE TABLE filter_table_3 (a integer, b text, primary key(a)); +CREATE TABLE filter_table_4 (a integer, b text, primary key(a)); +CREATE TABLE "Filter_table_5" (a integer, b text, primary key(a)); +CREATE TABLE "filter table_6" (a integer, b text, primary key(a)); +CREATE TABLE "filter.table_7" (a integer, b text, primary key(a)); +CREATE TABLE "filter,table_8" (a integer, b text, primary key(a)); +CREATE TABLE "filter""table_9" (a integer, b text, primary key(a)); +CREATE TABLE " filter_table_10" (a integer, b text, primary key(a)); +CREATE TABLE "*" (a integer, b text, primary key(a)); +CREATE TABLE "*".filter_table_0 (a integer, b text, primary key(a)); +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +INSERT INTO filter_table_1 (a, b) VALUES(1, 'public.filter_table_1'); +INSERT INTO filter_schema_1.filter_table_1 (a, b) VALUES(1, 'filter_schema_1.filter_table_1'); +INSERT INTO filter_schema_1.filter_table_2 (a, b) VALUES(1, 'filter_schema_1.filter_table_2'); +INSERT INTO filter_schema_2.filter_table_1 (a, b) VALUES(1, 'filter_schema_2.filter_table_1'); +INSERT INTO filter_schema_2.filter_table_2 (a, b) VALUES(1, 'filter_schema_2.filter_table_2'); +INSERT INTO filter_schema_2.filter_table_3 (a, b) VALUES(1, 'filter_schema_2.filter_table_3'); +INSERT INTO filter_table_2 (a, b) VALUES(1, 'public.filter_table_2'); +INSERT INTO filter_table_3 (a, b) VALUES(1, 'public.filter_table_3'); +INSERT INTO filter_table_4 (a, b) VALUES(1, 'public.filter_table_4'); +INSERT INTO "Filter_table_5" (a, b) VALUES(1, 'public.Filter_table_5'); +INSERT INTO "filter table_6" (a, b) VALUES(1, 'public.filter table_6'); +INSERT INTO "filter.table_7" (a, b) VALUES(1, 'public.filter.table_7'); +INSERT INTO "filter,table_8" (a, b) VALUES(1, 'public.filter,table_8'); +INSERT INTO "filter""table_9" (a, b) VALUES(1, 'public.filter"table_9'); +INSERT INTO " filter_table_10" (a, b) VALUES(1, 'public. filter_table_10'); +INSERT INTO "*" (a, b) VALUES(1, 'public.*'); +INSERT INTO "*".filter_table_0 (a, b) VALUES(1, '*.filter_table_0'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'filter-tables', ' foo.bar,*.filter_table_1 ,filter_schema_2.* , public.filter_table_3 , public.Filter_table_5, public.filter\ table_6, public.filter\.table_7 , public.filter\,table_8 , public.filter"table_9, *.\ filter_table_10 , public.\* , \*.filter_table_0 '); + data +------------------------------------------------------------------------------- + { + + "change": [ + + ] + + } + { + + "change": [ + + ] + + } + { + + "change": [ + + { + + "kind": "insert", + + "schema": "filter_schema_1", + + "table": "filter_table_2", + + "columnnames": ["a", "b"], + + "columntypes": ["integer", "text"], + + "columnvalues": [1, "filter_schema_1.filter_table_2"]+ + } + + ] + + } + { + + "change": [ + + ] + + } + { + + "change": [ + + ] + + } + { + + "change": [ + + ] + + } + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "filter_table_2", + + "columnnames": ["a", "b"], + + "columntypes": ["integer", "text"], + + "columnvalues": [1, "public.filter_table_2"] + + } + + ] + + } + { + + "change": [ + + ] + + } + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "filter_table_4", + + "columnnames": ["a", "b"], + + "columntypes": ["integer", "text"], + + "columnvalues": [1, "public.filter_table_4"] + + } + + ] + + } + { + + "change": [ + + ] + + } + { + + "change": [ + + ] + + } + { + + "change": [ + + ] + + } + { + + "change": [ + + ] + + } + { + + "change": [ + + ] + + } + { + + "change": [ + + ] + + } + { + + "change": [ + + ] + + } + { + + "change": [ + + ] + + } +(17 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'filter-tables', ' foo.bar,*.filter_table_1 ,filter_schema_2.* , public.filter_table_3 , public.Filter_table_5, public.filter\ table_6, public.filter\.table_7 , public.filter\,table_8 , public.filter"table_9, *.\ filter_table_10 , public.\* , \*.filter_table_0 '); + data +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"filter_schema_1","table":"filter_table_2","columns":[{"name":"a","type":"integer","value":1},{"name":"b","type":"text","value":"filter_schema_1.filter_table_2"}]} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"filter_table_2","columns":[{"name":"a","type":"integer","value":1},{"name":"b","type":"text","value":"public.filter_table_2"}]} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"filter_table_4","columns":[{"name":"a","type":"integer","value":1},{"name":"b","type":"text","value":"public.filter_table_4"}]} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} +(37 rows) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + diff --git a/src/postgres/third-party-extensions/wal2json/expected/include_domain_data_type.out b/src/postgres/third-party-extensions/wal2json/expected/include_domain_data_type.out new file mode 100644 index 000000000000..7bf55750b46e --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/include_domain_data_type.out @@ -0,0 +1,291 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +SET extra_float_digits = 0; +CREATE DOMAIN "wal2json_DOMAIN_1" AS bigint; +CREATE DOMAIN wal2json_domain_2 AS numeric(5,3); +CREATE DOMAIN wal2json_domain_3 AS varchar(30); +CREATE DOMAIN "wal2json_DOMAIN_4" AS bit varying(20); +CREATE TYPE "wal2json_Type" AS ENUM('a', 'b', 'c'); +CREATE TABLE test_wal2json_5 ( +a smallserial, +b smallint, +c int, +d "wal2json_DOMAIN_1", +e wal2json_domain_2, +f real not null, +g double precision, +h char(10), +i wal2json_domain_3, +j text, +k "wal2json_DOMAIN_4", +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +PRIMARY KEY(b, c, d) +); +CREATE TABLE test_wal2json_6 ( +a integer, +b "wal2json_Type"[], +PRIMARY KEY(a) +); +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +INSERT INTO test_wal2json_5 (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +UPDATE test_wal2json_5 SET f = -f WHERE b = 1; +INSERT INTO test_wal2json_6 (a, b) VALUES(1, array['b', 'c']::"wal2json_Type"[]); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-domain-data-type', '0', 'include-pk', '1'); + data +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "test_wal2json_5", + + "columnnames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "columntypes": ["smallint", "smallint", "integer", "wal2json_DOMAIN_1", "wal2json_domain_2", "real", "double precision", "character(10)", "wal2json_domain_3", "text", "wal2json_DOMAIN_4", "timestamp without time zone", "date", "boolean", "json", "tsvector"],+ + "columnvalues": [1, 1, 2, "3", "3.540", 876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"], + + "pk": { + + "pknames": ["b", "c", "d"], + + "pktypes": ["smallint", "integer", "wal2json_DOMAIN_1"] + + } + + } + + ] + + } + { + + "change": [ + + { + + "kind": "update", + + "schema": "public", + + "table": "test_wal2json_5", + + "columnnames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "columntypes": ["smallint", "smallint", "integer", "wal2json_DOMAIN_1", "wal2json_domain_2", "real", "double precision", "character(10)", "wal2json_domain_3", "text", "wal2json_DOMAIN_4", "timestamp without time zone", "date", "boolean", "json", "tsvector"],+ + "columnvalues": [1, 1, 2, "3", "3.540", -876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"], + + "pk": { + + "pknames": ["b", "c", "d"], + + "pktypes": ["smallint", "integer", "wal2json_DOMAIN_1"] + + }, + + "oldkeys": { + + "keynames": ["b", "c", "d"], + + "keytypes": ["smallint", "integer", "wal2json_DOMAIN_1"], + + "keyvalues": [1, 2, "3"] + + } + + } + + ] + + } + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "test_wal2json_6", + + "columnnames": ["a", "b"], + + "columntypes": ["integer", "\"wal2json_Type\"[]"], + + "columnvalues": [1, "{b,c}"], + + "pk": { + + "pknames": ["a"], + + "pktypes": ["integer"] + + } + + } + + ] + + } +(3 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-domain-data-type', '1', 'include-pk', '1'); + data +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "test_wal2json_5", + + "columnnames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "columntypes": ["smallint", "smallint", "integer", "bigint", "numeric(5,3)", "real", "double precision", "character(10)", "character varying(30)", "text", "bit varying(20)", "timestamp without time zone", "date", "boolean", "json", "tsvector"],+ + "columnvalues": [1, 1, 2, 3, 3.540, 876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"], + + "pk": { + + "pknames": ["b", "c", "d"], + + "pktypes": ["smallint", "integer", "bigint"] + + } + + } + + ] + + } + { + + "change": [ + + { + + "kind": "update", + + "schema": "public", + + "table": "test_wal2json_5", + + "columnnames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "columntypes": ["smallint", "smallint", "integer", "bigint", "numeric(5,3)", "real", "double precision", "character(10)", "character varying(30)", "text", "bit varying(20)", "timestamp without time zone", "date", "boolean", "json", "tsvector"],+ + "columnvalues": [1, 1, 2, 3, 3.540, -876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"], + + "pk": { + + "pknames": ["b", "c", "d"], + + "pktypes": ["smallint", "integer", "bigint"] + + }, + + "oldkeys": { + + "keynames": ["b", "c", "d"], + + "keytypes": ["smallint", "integer", "bigint"], + + "keyvalues": [1, 2, 3] + + } + + } + + ] + + } + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "test_wal2json_6", + + "columnnames": ["a", "b"], + + "columntypes": ["integer", "\"wal2json_Type\"[]"], + + "columnvalues": [1, "{b,c}"], + + "pk": { + + "pknames": ["a"], + + "pktypes": ["integer"] + + } + + } + + ] + + } +(3 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-domain-data-type', '0', 'include-typmod', '0'); + data +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "test_wal2json_5", + + "columnnames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "columntypes": ["int2", "int2", "int4", "wal2json_DOMAIN_1", "wal2json_domain_2", "float4", "float8", "bpchar", "wal2json_domain_3", "text", "wal2json_DOMAIN_4", "timestamp", "date", "bool", "json", "tsvector"],+ + "columnvalues": [1, 1, 2, "3", "3.540", 876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"] + + } + + ] + + } + { + + "change": [ + + { + + "kind": "update", + + "schema": "public", + + "table": "test_wal2json_5", + + "columnnames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "columntypes": ["int2", "int2", "int4", "wal2json_DOMAIN_1", "wal2json_domain_2", "float4", "float8", "bpchar", "wal2json_domain_3", "text", "wal2json_DOMAIN_4", "timestamp", "date", "bool", "json", "tsvector"],+ + "columnvalues": [1, 1, 2, "3", "3.540", -876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"], + + "oldkeys": { + + "keynames": ["b", "c", "d"], + + "keytypes": ["int2", "int4", "wal2json_DOMAIN_1"], + + "keyvalues": [1, 2, "3"] + + } + + } + + ] + + } + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "test_wal2json_6", + + "columnnames": ["a", "b"], + + "columntypes": ["int4", "_wal2json_Type"], + + "columnvalues": [1, "{b,c}"] + + } + + ] + + } +(3 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-domain-data-type', '1', 'include-typmod', '0'); + data +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "test_wal2json_5", + + "columnnames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "columntypes": ["int2", "int2", "int4", "int8", "numeric", "float4", "float8", "bpchar", "varchar", "text", "varbit", "timestamp", "date", "bool", "json", "tsvector"], + + "columnvalues": [1, 1, 2, 3, 3.540, 876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"] + + } + + ] + + } + { + + "change": [ + + { + + "kind": "update", + + "schema": "public", + + "table": "test_wal2json_5", + + "columnnames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "columntypes": ["int2", "int2", "int4", "int8", "numeric", "float4", "float8", "bpchar", "varchar", "text", "varbit", "timestamp", "date", "bool", "json", "tsvector"], + + "columnvalues": [1, 1, 2, 3, 3.540, -876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"],+ + "oldkeys": { + + "keynames": ["b", "c", "d"], + + "keytypes": ["int2", "int4", "int8"], + + "keyvalues": [1, 2, 3] + + } + + } + + ] + + } + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "test_wal2json_6", + + "columnnames": ["a", "b"], + + "columntypes": ["int4", "_wal2json_Type"], + + "columnvalues": [1, "{b,c}"] + + } + + ] + + } +(3 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'include-domain-data-type', '0', 'include-pk', '1'); + data +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"action":"B"} + {"action":"I","schema":"public","table":"test_wal2json_5","columns":[{"name":"a","type":"smallint","value":1},{"name":"b","type":"smallint","value":1},{"name":"c","type":"integer","value":2},{"name":"d","type":"wal2json_DOMAIN_1","value":"3"},{"name":"e","type":"wal2json_domain_2","value":"3.540"},{"name":"f","type":"real","value":876.563},{"name":"g","type":"double precision","value":1.23},{"name":"h","type":"character(10)","value":"teste "},{"name":"i","type":"wal2json_domain_3","value":"testando"},{"name":"j","type":"text","value":"um texto longo"},{"name":"k","type":"wal2json_DOMAIN_4","value":"001110010101010"},{"name":"l","type":"timestamp without time zone","value":"Sat Nov 02 17:30:52 2013"},{"name":"m","type":"date","value":"02-04-2013"},{"name":"n","type":"boolean","value":true},{"name":"o","type":"json","value":"{ \"a\": 123 }"},{"name":"p","type":"tsvector","value":"'Old' 'Parr'"}],"pk":[{"name":"b","type":"smallint"},{"name":"c","type":"integer"},{"name":"d","type":"wal2json_DOMAIN_1"}]} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"test_wal2json_5","columns":[{"name":"a","type":"smallint","value":1},{"name":"b","type":"smallint","value":1},{"name":"c","type":"integer","value":2},{"name":"d","type":"wal2json_DOMAIN_1","value":"3"},{"name":"e","type":"wal2json_domain_2","value":"3.540"},{"name":"f","type":"real","value":-876.563},{"name":"g","type":"double precision","value":1.23},{"name":"h","type":"character(10)","value":"teste "},{"name":"i","type":"wal2json_domain_3","value":"testando"},{"name":"j","type":"text","value":"um texto longo"},{"name":"k","type":"wal2json_DOMAIN_4","value":"001110010101010"},{"name":"l","type":"timestamp without time zone","value":"Sat Nov 02 17:30:52 2013"},{"name":"m","type":"date","value":"02-04-2013"},{"name":"n","type":"boolean","value":true},{"name":"o","type":"json","value":"{ \"a\": 123 }"},{"name":"p","type":"tsvector","value":"'Old' 'Parr'"}],"identity":[{"name":"b","type":"smallint","value":1},{"name":"c","type":"integer","value":2},{"name":"d","type":"wal2json_DOMAIN_1","value":"3"}],"pk":[{"name":"b","type":"smallint"},{"name":"c","type":"integer"},{"name":"d","type":"wal2json_DOMAIN_1"}]} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"test_wal2json_6","columns":[{"name":"a","type":"integer","value":1},{"name":"b","type":"\"wal2json_Type\"[]","value":"{b,c}"}],"pk":[{"name":"a","type":"integer"}]} + {"action":"C"} +(9 rows) + +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '2', 'include-domain-data-type', '1', 'include-pk', '1'); + data +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"action":"B"} + {"action":"I","schema":"public","table":"test_wal2json_5","columns":[{"name":"a","type":"smallint","value":1},{"name":"b","type":"smallint","value":1},{"name":"c","type":"integer","value":2},{"name":"d","type":"bigint","value":"3"},{"name":"e","type":"numeric(5,3)","value":"3.540"},{"name":"f","type":"real","value":876.563},{"name":"g","type":"double precision","value":1.23},{"name":"h","type":"character(10)","value":"teste "},{"name":"i","type":"character varying(30)","value":"testando"},{"name":"j","type":"text","value":"um texto longo"},{"name":"k","type":"bit varying(20)","value":"001110010101010"},{"name":"l","type":"timestamp without time zone","value":"Sat Nov 02 17:30:52 2013"},{"name":"m","type":"date","value":"02-04-2013"},{"name":"n","type":"boolean","value":true},{"name":"o","type":"json","value":"{ \"a\": 123 }"},{"name":"p","type":"tsvector","value":"'Old' 'Parr'"}],"pk":[{"name":"b","type":"smallint"},{"name":"c","type":"integer"},{"name":"d","type":"bigint"}]} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"test_wal2json_5","columns":[{"name":"a","type":"smallint","value":1},{"name":"b","type":"smallint","value":1},{"name":"c","type":"integer","value":2},{"name":"d","type":"bigint","value":"3"},{"name":"e","type":"numeric(5,3)","value":"3.540"},{"name":"f","type":"real","value":-876.563},{"name":"g","type":"double precision","value":1.23},{"name":"h","type":"character(10)","value":"teste "},{"name":"i","type":"character varying(30)","value":"testando"},{"name":"j","type":"text","value":"um texto longo"},{"name":"k","type":"bit varying(20)","value":"001110010101010"},{"name":"l","type":"timestamp without time zone","value":"Sat Nov 02 17:30:52 2013"},{"name":"m","type":"date","value":"02-04-2013"},{"name":"n","type":"boolean","value":true},{"name":"o","type":"json","value":"{ \"a\": 123 }"},{"name":"p","type":"tsvector","value":"'Old' 'Parr'"}],"identity":[{"name":"b","type":"smallint","value":1},{"name":"c","type":"integer","value":2},{"name":"d","type":"bigint","value":"3"}],"pk":[{"name":"b","type":"smallint"},{"name":"c","type":"integer"},{"name":"d","type":"bigint"}]} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"test_wal2json_6","columns":[{"name":"a","type":"integer","value":1},{"name":"b","type":"\"wal2json_Type\"[]","value":"{b,c}"}],"pk":[{"name":"a","type":"integer"}]} + {"action":"C"} +(9 rows) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + +DROP TABLE test_wal2json_5; +DROP TABLE test_wal2json_6; +DROP DOMAIN "wal2json_DOMAIN_1"; +DROP DOMAIN wal2json_domain_2; +DROP DOMAIN wal2json_domain_3; +DROP DOMAIN "wal2json_DOMAIN_4"; +DROP TYPE "wal2json_Type"; diff --git a/src/postgres/third-party-extensions/wal2json/expected/include_lsn.out b/src/postgres/third-party-extensions/wal2json/expected/include_lsn.out new file mode 100644 index 000000000000..7faf0063cdcd --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/include_lsn.out @@ -0,0 +1,42 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +DROP TABLE IF EXISTS tbl; +CREATE TABLE tbl (id int); +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +-- One row should have one record and one nextlsn +INSERT INTO tbl VALUES (1); +SELECT count(*) = 1, count(distinct ((data::json)->'nextlsn')::text) = 1 FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-lsn', '1'); + ?column? | ?column? +----------+---------- + t | t +(1 row) + +-- Two rows should have two records and two nextlsns +INSERT INTO tbl VALUES (2); +INSERT INTO tbl VALUES (3); +SELECT count(*) = 2, count(distinct ((data::json)->'nextlsn')::text) = 2 FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-lsn', '1'); + ?column? | ?column? +----------+---------- + t | t +(1 row) + +-- Two rows in one transaction should have one record and one nextlsn +INSERT INTO tbl VALUES (4), (5); +SELECT count(*) = 1, count(distinct ((data::json)->'nextlsn')::text) = 1 FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-lsn', '1'); + ?column? | ?column? +----------+---------- + t | t +(1 row) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + diff --git a/src/postgres/third-party-extensions/wal2json/expected/include_timestamp.out b/src/postgres/third-party-extensions/wal2json/expected/include_timestamp.out new file mode 100644 index 000000000000..dafbe62c4f0c --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/include_timestamp.out @@ -0,0 +1,43 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +DROP TABLE IF EXISTS tbl; +NOTICE: table "tbl" does not exist, skipping +CREATE TABLE tbl (id int); +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +-- One row should have one record and one timestamp +INSERT INTO tbl VALUES (1); +SELECT count(*) = 1, count(distinct ((data::json)->'timestamp')::text) = 1 FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-timestamp', '1'); + ?column? | ?column? +----------+---------- + t | t +(1 row) + +-- Two rows should have two records and two timestamps +INSERT INTO tbl VALUES (2); +INSERT INTO tbl VALUES (3); +SELECT count(*) = 2, count(distinct ((data::json)->'timestamp')::text) = 2 FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-timestamp', '1'); + ?column? | ?column? +----------+---------- + t | t +(1 row) + +-- Two rows in one transaction should have one record and one timestamp +INSERT INTO tbl VALUES (4), (5); +SELECT count(*) = 1, count(distinct ((data::json)->'timestamp')::text) = 1 FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-timestamp', '1'); + ?column? | ?column? +----------+---------- + t | t +(1 row) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + diff --git a/src/postgres/third-party-extensions/wal2json/expected/include_xids.out b/src/postgres/third-party-extensions/wal2json/expected/include_xids.out new file mode 100644 index 000000000000..241306ff5160 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/include_xids.out @@ -0,0 +1,42 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +DROP TABLE IF EXISTS tbl; +CREATE TABLE tbl (id int); +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +-- One row should have one record and one xids +INSERT INTO tbl VALUES (1); +SELECT count(*) = 1, count(distinct ((data::json)->'xid')::text) = 1 FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-xids', '1'); + ?column? | ?column? +----------+---------- + t | t +(1 row) + +-- Two rows should have two records and two xids +INSERT INTO tbl VALUES (2); +INSERT INTO tbl VALUES (3); +SELECT count(*) = 2, count(distinct ((data::json)->'xid')::text) = 2 FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-xids', '1'); + ?column? | ?column? +----------+---------- + t | t +(1 row) + +-- Two rows in one transaction should have one record and one xid +INSERT INTO tbl VALUES (4), (5); +SELECT count(*) = 2, count(distinct ((data::json)->'xid')::text) = 1 FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-xids', '1'); + ?column? | ?column? +----------+---------- + f | t +(1 row) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + diff --git a/src/postgres/third-party-extensions/wal2json/expected/insert1.out b/src/postgres/third-party-extensions/wal2json/expected/insert1.out new file mode 100644 index 000000000000..fc3657f2b8d9 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/insert1.out @@ -0,0 +1,139 @@ +-- this is the first test (CREATE EXTENSION, no DROP TABLE) +LOAD 'test_decoding'; +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +SET extra_float_digits = 0; +CREATE TABLE table_with_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +PRIMARY KEY(b, c, d) +); +CREATE TABLE table_without_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector +); +CREATE TABLE table_with_unique ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3) not null, +f real not null, +g double precision not null, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +UNIQUE(g, n) +); +CREATE SCHEMA "test ""schema"; +CREATE TABLE "test ""schema"."test "" with 'quotes'" ( + id serial primary key, + "col spaces" int, + "col""quotes" int +); +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +-- INSERT +BEGIN; +INSERT INTO table_with_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_without_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_with_unique (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO "test ""schema"."test "" with 'quotes'" VALUES (1, 2, 3); +COMMIT; +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0'); + data +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "table_with_pk", + + "columnnames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "columntypes": ["int2", "int2", "int4", "int8", "numeric", "float4", "float8", "bpchar", "varchar", "text", "varbit", "timestamp", "date", "bool", "json", "tsvector"], + + "columnvalues": [1, 1, 2, 3, 3.540, 876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"]+ + } + + ,{ + + "kind": "insert", + + "schema": "public", + + "table": "table_without_pk", + + "columnnames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "columntypes": ["int2", "int2", "int4", "int8", "numeric", "float4", "float8", "bpchar", "varchar", "text", "varbit", "timestamp", "date", "bool", "json", "tsvector"], + + "columnvalues": [1, 1, 2, 3, 3.540, 876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"]+ + } + + ,{ + + "kind": "insert", + + "schema": "public", + + "table": "table_with_unique", + + "columnnames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "columntypes": ["int2", "int2", "int4", "int8", "numeric", "float4", "float8", "bpchar", "varchar", "text", "varbit", "timestamp", "date", "bool", "json", "tsvector"], + + "columnvalues": [1, 1, 2, 3, 3.540, 876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"]+ + } + + ,{ + + "kind": "insert", + + "schema": "test \"schema", + + "table": "test \" with 'quotes'", + + "columnnames": ["id", "col spaces", "col\"quotes"], + + "columntypes": ["int4", "int4", "int4"], + + "columnvalues": [1, 2, 3] + + } + + ] + + } +(1 row) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); + data +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"action":"B"} + {"action":"I","schema":"public","table":"table_with_pk","columns":[{"name":"a","type":"smallint","value":1},{"name":"b","type":"smallint","value":1},{"name":"c","type":"integer","value":2},{"name":"d","type":"bigint","value":3},{"name":"e","type":"numeric(5,3)","value":3.540},{"name":"f","type":"real","value":876.563},{"name":"g","type":"double precision","value":1.23},{"name":"h","type":"character(10)","value":"teste "},{"name":"i","type":"character varying(30)","value":"testando"},{"name":"j","type":"text","value":"um texto longo"},{"name":"k","type":"bit varying(20)","value":"001110010101010"},{"name":"l","type":"timestamp without time zone","value":"Sat Nov 02 17:30:52 2013"},{"name":"m","type":"date","value":"02-04-2013"},{"name":"n","type":"boolean","value":true},{"name":"o","type":"json","value":"{ \"a\": 123 }"},{"name":"p","type":"tsvector","value":"'Old' 'Parr'"}]} + {"action":"I","schema":"public","table":"table_without_pk","columns":[{"name":"a","type":"smallint","value":1},{"name":"b","type":"smallint","value":1},{"name":"c","type":"integer","value":2},{"name":"d","type":"bigint","value":3},{"name":"e","type":"numeric(5,3)","value":3.540},{"name":"f","type":"real","value":876.563},{"name":"g","type":"double precision","value":1.23},{"name":"h","type":"character(10)","value":"teste "},{"name":"i","type":"character varying(30)","value":"testando"},{"name":"j","type":"text","value":"um texto longo"},{"name":"k","type":"bit varying(20)","value":"001110010101010"},{"name":"l","type":"timestamp without time zone","value":"Sat Nov 02 17:30:52 2013"},{"name":"m","type":"date","value":"02-04-2013"},{"name":"n","type":"boolean","value":true},{"name":"o","type":"json","value":"{ \"a\": 123 }"},{"name":"p","type":"tsvector","value":"'Old' 'Parr'"}]} + {"action":"I","schema":"public","table":"table_with_unique","columns":[{"name":"a","type":"smallint","value":1},{"name":"b","type":"smallint","value":1},{"name":"c","type":"integer","value":2},{"name":"d","type":"bigint","value":3},{"name":"e","type":"numeric(5,3)","value":3.540},{"name":"f","type":"real","value":876.563},{"name":"g","type":"double precision","value":1.23},{"name":"h","type":"character(10)","value":"teste "},{"name":"i","type":"character varying(30)","value":"testando"},{"name":"j","type":"text","value":"um texto longo"},{"name":"k","type":"bit varying(20)","value":"001110010101010"},{"name":"l","type":"timestamp without time zone","value":"Sat Nov 02 17:30:52 2013"},{"name":"m","type":"date","value":"02-04-2013"},{"name":"n","type":"boolean","value":true},{"name":"o","type":"json","value":"{ \"a\": 123 }"},{"name":"p","type":"tsvector","value":"'Old' 'Parr'"}]} + {"action":"I","schema":"test \"schema","table":"test \" with 'quotes'","columns":[{"name":"id","type":"integer","value":1},{"name":"col spaces","type":"integer","value":2},{"name":"col\"quotes","type":"integer","value":3}]} + {"action":"C"} +(6 rows) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + diff --git a/src/postgres/third-party-extensions/wal2json/expected/message.out b/src/postgres/third-party-extensions/wal2json/expected/message.out new file mode 100644 index 000000000000..e23643741517 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/message.out @@ -0,0 +1,231 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +SELECT 'msg1' FROM pg_logical_emit_message(true, 'wal2json', 'this is a\ message'); + ?column? +---------- + msg1 +(1 row) + +SELECT 'msg2' FROM pg_logical_emit_message(false, 'wal2json', 'this is "another" message'); + ?column? +---------- + msg2 +(1 row) + +SELECT 'msg3' FROM pg_logical_emit_message(false, 'wal2json', E'\\x546170697275732074657272657374726973'::bytea); + ?column? +---------- + msg3 +(1 row) + +SELECT 'msg4' FROM pg_logical_emit_message(false, 'wal2json', E'\\x5072696f646f6e746573206d6178696d7573'::bytea); + ?column? +---------- + msg4 +(1 row) + +SELECT 'msg5' FROM pg_logical_emit_message(false, 'wal2json', E'\\x436172796f6361722062726173696c69656e7365'::bytea); + ?column? +---------- + msg5 +(1 row) + +BEGIN; +SELECT 'msg6' FROM pg_logical_emit_message(true, 'wal2json', 'this message will not be printed'); + ?column? +---------- + msg6 +(1 row) + +SELECT 'msg7' FROM pg_logical_emit_message(false, 'wal2json', 'this message will be printed even if the transaction is rollbacked'); + ?column? +---------- + msg7 +(1 row) + +ROLLBACK; +BEGIN; +SELECT 'msg8' FROM pg_logical_emit_message(true, 'wal2json', 'this is message #1'); + ?column? +---------- + msg8 +(1 row) + +SELECT 'msg9' FROM pg_logical_emit_message(false, 'wal2json', 'this message will be printed before message #1'); + ?column? +---------- + msg9 +(1 row) + +SELECT 'msg10' FROM pg_logical_emit_message(true, 'wal2json', 'this is message #2'); + ?column? +---------- + msg10 +(1 row) + +COMMIT; +SELECT 'msg11' FROM pg_logical_emit_message(true, 'filtered', 'this message will be filtered'); + ?column? +---------- + msg11 +(1 row) + +SELECT 'msg12' FROM pg_logical_emit_message(true, 'added1', 'this message will be printed'); + ?column? +---------- + msg12 +(1 row) + +SELECT 'msg13' FROM pg_logical_emit_message(true, 'added2', 'this message will be filtered'); + ?column? +---------- + msg13 +(1 row) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'filter-msg-prefixes', 'foo, filtered, bar', 'add-msg-prefixes', 'added1, added3, wal2json'); + data +--------------------------------------------------------------------------------------------------------- + { + + "change": [ + + { + + "kind": "message", + + "transactional": true, + + "prefix": "wal2json", + + "content": "this is a\\ message" + + } + + ] + + } + { + + "change": [ + + { + + "kind": "message", + + "transactional": false, + + "prefix": "wal2json", + + "content": "this is \"another\" message" + + } + + ] + + } + { + + "change": [ + + { + + "kind": "message", + + "transactional": false, + + "prefix": "wal2json", + + "content": "Tapirus terrestris" + + } + + ] + + } + { + + "change": [ + + { + + "kind": "message", + + "transactional": false, + + "prefix": "wal2json", + + "content": "Priodontes maximus" + + } + + ] + + } + { + + "change": [ + + { + + "kind": "message", + + "transactional": false, + + "prefix": "wal2json", + + "content": "Caryocar brasiliense" + + } + + ] + + } + { + + "change": [ + + { + + "kind": "message", + + "transactional": false, + + "prefix": "wal2json", + + "content": "this message will be printed even if the transaction is rollbacked"+ + } + + ] + + } + { + + "change": [ + + { + + "kind": "message", + + "transactional": false, + + "prefix": "wal2json", + + "content": "this message will be printed before message #1" + + } + + ] + + } + { + + "change": [ + + { + + "kind": "message", + + "transactional": true, + + "prefix": "wal2json", + + "content": "this is message #1" + + } + + ,{ + + "kind": "message", + + "transactional": true, + + "prefix": "wal2json", + + "content": "this is message #2" + + } + + ] + + } + { + + "change": [ + + ] + + } + { + + "change": [ + + { + + "kind": "message", + + "transactional": true, + + "prefix": "added1", + + "content": "this message will be printed" + + } + + ] + + } + { + + "change": [ + + ] + + } +(11 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'filter-msg-prefixes', 'foo, filtered, bar', 'add-msg-prefixes', 'added1, added3, wal2json'); + data +----------------------------------------------------------------------------------------------------------------------------------------- + {"action":"B"} + {"action":"M","transactional":true,"prefix":"wal2json","content":"this is a\\ message"} + {"action":"C"} + {"action":"M","transactional":false,"prefix":"wal2json","content":"this is \"another\" message"} + {"action":"M","transactional":false,"prefix":"wal2json","content":"Tapirus terrestris"} + {"action":"M","transactional":false,"prefix":"wal2json","content":"Priodontes maximus"} + {"action":"M","transactional":false,"prefix":"wal2json","content":"Caryocar brasiliense"} + {"action":"M","transactional":false,"prefix":"wal2json","content":"this message will be printed even if the transaction is rollbacked"} + {"action":"M","transactional":false,"prefix":"wal2json","content":"this message will be printed before message #1"} + {"action":"B"} + {"action":"M","transactional":true,"prefix":"wal2json","content":"this is message #1"} + {"action":"M","transactional":true,"prefix":"wal2json","content":"this is message #2"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"M","transactional":true,"prefix":"added1","content":"this message will be printed"} + {"action":"C"} + {"action":"B"} + {"action":"C"} +(20 rows) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + diff --git a/src/postgres/third-party-extensions/wal2json/expected/numeric_data_types_as_string.out b/src/postgres/third-party-extensions/wal2json/expected/numeric_data_types_as_string.out new file mode 100644 index 000000000000..cad032e79009 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/numeric_data_types_as_string.out @@ -0,0 +1,187 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +SET extra_float_digits = 0; +CREATE TABLE table_integer (a smallserial, b smallint, c int, d bigint); +CREATE TABLE table_decimal (a real, b double precision, c numeric); +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +BEGIN; +INSERT INTO table_integer (b, c, d) VALUES(32767, 2147483647, 9223372036854775807); +INSERT INTO table_integer (b, c, d) VALUES(-32768, -2147483648, -9223372036854775808); +INSERT INTO table_decimal (a, b) VALUES('Infinity', 'Infinity'); +INSERT INTO table_decimal (a, b) VALUES('-Infinity', '-Infinity'); +INSERT INTO table_decimal (a, b, c) VALUES('NaN', 'NaN', 'NaN'); +INSERT INTO table_decimal (a, b, c) VALUES(123.456, 123456789.012345, 1234567890987654321.1234567890987654321); +INSERT INTO table_decimal (a, b, c) VALUES(-123.456, -123456789.012345, -1234567890987654321.1234567890987654321); +COMMIT; +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'numeric-data-types-as-string', '1'); + data +----------------------------------------------------------------------------------------------------------------------- + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "table_integer", + + "columnnames": ["a", "b", "c", "d"], + + "columntypes": ["smallint", "smallint", "integer", "bigint"], + + "columnvalues": ["1", "32767", "2147483647", "9223372036854775807"] + + } + + ,{ + + "kind": "insert", + + "schema": "public", + + "table": "table_integer", + + "columnnames": ["a", "b", "c", "d"], + + "columntypes": ["smallint", "smallint", "integer", "bigint"], + + "columnvalues": ["2", "-32768", "-2147483648", "-9223372036854775808"] + + } + + ,{ + + "kind": "insert", + + "schema": "public", + + "table": "table_decimal", + + "columnnames": ["a", "b", "c"], + + "columntypes": ["real", "double precision", "numeric"], + + "columnvalues": ["Infinity", "Infinity", null] + + } + + ,{ + + "kind": "insert", + + "schema": "public", + + "table": "table_decimal", + + "columnnames": ["a", "b", "c"], + + "columntypes": ["real", "double precision", "numeric"], + + "columnvalues": ["-Infinity", "-Infinity", null] + + } + + ,{ + + "kind": "insert", + + "schema": "public", + + "table": "table_decimal", + + "columnnames": ["a", "b", "c"], + + "columntypes": ["real", "double precision", "numeric"], + + "columnvalues": ["NaN", "NaN", "NaN"] + + } + + ,{ + + "kind": "insert", + + "schema": "public", + + "table": "table_decimal", + + "columnnames": ["a", "b", "c"], + + "columntypes": ["real", "double precision", "numeric"], + + "columnvalues": ["123.456", "123456789.012345", "1234567890987654321.1234567890987654321"] + + } + + ,{ + + "kind": "insert", + + "schema": "public", + + "table": "table_decimal", + + "columnnames": ["a", "b", "c"], + + "columntypes": ["real", "double precision", "numeric"], + + "columnvalues": ["-123.456", "-123456789.012345", "-1234567890987654321.1234567890987654321"]+ + } + + ] + + } +(1 row) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1'); + data +----------------------------------------------------------------------------------------------------------------- + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "table_integer", + + "columnnames": ["a", "b", "c", "d"], + + "columntypes": ["smallint", "smallint", "integer", "bigint"], + + "columnvalues": [1, 32767, 2147483647, 9223372036854775807] + + } + + ,{ + + "kind": "insert", + + "schema": "public", + + "table": "table_integer", + + "columnnames": ["a", "b", "c", "d"], + + "columntypes": ["smallint", "smallint", "integer", "bigint"], + + "columnvalues": [2, -32768, -2147483648, -9223372036854775808] + + } + + ,{ + + "kind": "insert", + + "schema": "public", + + "table": "table_decimal", + + "columnnames": ["a", "b", "c"], + + "columntypes": ["real", "double precision", "numeric"], + + "columnvalues": [null, null, null] + + } + + ,{ + + "kind": "insert", + + "schema": "public", + + "table": "table_decimal", + + "columnnames": ["a", "b", "c"], + + "columntypes": ["real", "double precision", "numeric"], + + "columnvalues": [null, null, null] + + } + + ,{ + + "kind": "insert", + + "schema": "public", + + "table": "table_decimal", + + "columnnames": ["a", "b", "c"], + + "columntypes": ["real", "double precision", "numeric"], + + "columnvalues": [null, null, null] + + } + + ,{ + + "kind": "insert", + + "schema": "public", + + "table": "table_decimal", + + "columnnames": ["a", "b", "c"], + + "columntypes": ["real", "double precision", "numeric"], + + "columnvalues": [123.456, 123456789.012345, 1234567890987654321.1234567890987654321] + + } + + ,{ + + "kind": "insert", + + "schema": "public", + + "table": "table_decimal", + + "columnnames": ["a", "b", "c"], + + "columntypes": ["real", "double precision", "numeric"], + + "columnvalues": [-123.456, -123456789.012345, -1234567890987654321.1234567890987654321]+ + } + + ] + + } +(1 row) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'numeric-data-types-as-string', '1'); + data +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"action":"B"} + {"action":"I","schema":"public","table":"table_integer","columns":[{"name":"a","type":"smallint","value":"1"},{"name":"b","type":"smallint","value":"32767"},{"name":"c","type":"integer","value":"2147483647"},{"name":"d","type":"bigint","value":"9223372036854775807"}]} + {"action":"I","schema":"public","table":"table_integer","columns":[{"name":"a","type":"smallint","value":"2"},{"name":"b","type":"smallint","value":"-32768"},{"name":"c","type":"integer","value":"-2147483648"},{"name":"d","type":"bigint","value":"-9223372036854775808"}]} + {"action":"I","schema":"public","table":"table_decimal","columns":[{"name":"a","type":"real","value":"Infinity"},{"name":"b","type":"double precision","value":"Infinity"},{"name":"c","type":"numeric","value":null}]} + {"action":"I","schema":"public","table":"table_decimal","columns":[{"name":"a","type":"real","value":"-Infinity"},{"name":"b","type":"double precision","value":"-Infinity"},{"name":"c","type":"numeric","value":null}]} + {"action":"I","schema":"public","table":"table_decimal","columns":[{"name":"a","type":"real","value":"NaN"},{"name":"b","type":"double precision","value":"NaN"},{"name":"c","type":"numeric","value":"NaN"}]} + {"action":"I","schema":"public","table":"table_decimal","columns":[{"name":"a","type":"real","value":"123.456"},{"name":"b","type":"double precision","value":"123456789.012345"},{"name":"c","type":"numeric","value":"1234567890987654321.1234567890987654321"}]} + {"action":"I","schema":"public","table":"table_decimal","columns":[{"name":"a","type":"real","value":"-123.456"},{"name":"b","type":"double precision","value":"-123456789.012345"},{"name":"c","type":"numeric","value":"-1234567890987654321.1234567890987654321"}]} + {"action":"C"} +(9 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); + data +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"action":"B"} + {"action":"I","schema":"public","table":"table_integer","columns":[{"name":"a","type":"smallint","value":1},{"name":"b","type":"smallint","value":32767},{"name":"c","type":"integer","value":2147483647},{"name":"d","type":"bigint","value":9223372036854775807}]} + {"action":"I","schema":"public","table":"table_integer","columns":[{"name":"a","type":"smallint","value":2},{"name":"b","type":"smallint","value":-32768},{"name":"c","type":"integer","value":-2147483648},{"name":"d","type":"bigint","value":-9223372036854775808}]} + {"action":"I","schema":"public","table":"table_decimal","columns":[{"name":"a","type":"real","value":null},{"name":"b","type":"double precision","value":null},{"name":"c","type":"numeric","value":null}]} + {"action":"I","schema":"public","table":"table_decimal","columns":[{"name":"a","type":"real","value":null},{"name":"b","type":"double precision","value":null},{"name":"c","type":"numeric","value":null}]} + {"action":"I","schema":"public","table":"table_decimal","columns":[{"name":"a","type":"real","value":null},{"name":"b","type":"double precision","value":null},{"name":"c","type":"numeric","value":null}]} + {"action":"I","schema":"public","table":"table_decimal","columns":[{"name":"a","type":"real","value":123.456},{"name":"b","type":"double precision","value":123456789.012345},{"name":"c","type":"numeric","value":1234567890987654321.1234567890987654321}]} + {"action":"I","schema":"public","table":"table_decimal","columns":[{"name":"a","type":"real","value":-123.456},{"name":"b","type":"double precision","value":-123456789.012345},{"name":"c","type":"numeric","value":-1234567890987654321.1234567890987654321}]} + {"action":"C"} +(9 rows) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + +DROP TABLE table_integer; +DROP TABLE table_decimal; diff --git a/src/postgres/third-party-extensions/wal2json/expected/pk.out b/src/postgres/third-party-extensions/wal2json/expected/pk.out new file mode 100644 index 000000000000..c999059995ae --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/pk.out @@ -0,0 +1,209 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +SET extra_float_digits = 0; +CREATE TABLE w2j_pk_with_pk ( +a int, +b timestamp, +c text, +d boolean, +e numeric(5,3), +PRIMARY KEY(b, d, e) +); +CREATE TABLE w2j_pk_without_pk ( +a int, +b timestamp, +c text, +d boolean, +e numeric(5,3) +); +CREATE TABLE w2j_pk_with_ri ( +a int NOT NULL, +b timestamp, +c text, +d boolean, +e numeric(5,3), +UNIQUE(a) +); +ALTER TABLE w2j_pk_with_ri REPLICA IDENTITY USING INDEX w2j_pk_with_ri_a_key; +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +INSERT INTO w2j_pk_with_pk (a, b, c, d, e) VALUES(123, '2020-04-26 16:23:59', 'Melanosuchus Niger', true, 4.56); +UPDATE w2j_pk_with_pk SET a = 456, c = 'Panthera Onca', d = false; +DELETE FROM w2j_pk_with_pk; +INSERT INTO w2j_pk_without_pk (a, b, c, d, e) VALUES(123, '2020-04-26 16:23:59', 'Melanosuchus Niger', true, 4.56); +UPDATE w2j_pk_without_pk SET a = 456, c = 'Panthera Onca', d = false; +DELETE FROM w2j_pk_without_pk; +INSERT INTO w2j_pk_with_ri (a, b, c, d, e) VALUES(123, '2020-04-26 16:23:59', 'Inia Araguaiaensis', true, 4.56); +UPDATE w2j_pk_with_ri SET a = 456, c = 'Panthera Onca', d = false; +DELETE FROM w2j_pk_with_ri; +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0', 'include-pk', '1'); +WARNING: table "w2j_pk_without_pk" without primary key or replica identity is nothing +WARNING: table "w2j_pk_without_pk" without primary key or replica identity is nothing + data +--------------------------------------------------------------------------------------------------------------- + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "w2j_pk_with_pk", + + "columnnames": ["a", "b", "c", "d", "e"], + + "columntypes": ["int4", "timestamp", "text", "bool", "numeric"], + + "columnvalues": [123, "Sun Apr 26 16:23:59 2020", "Melanosuchus Niger", true, 4.560],+ + "pk": { + + "pknames": ["b", "d", "e"], + + "pktypes": ["timestamp", "bool", "numeric"] + + } + + } + + ] + + } + { + + "change": [ + + { + + "kind": "update", + + "schema": "public", + + "table": "w2j_pk_with_pk", + + "columnnames": ["a", "b", "c", "d", "e"], + + "columntypes": ["int4", "timestamp", "text", "bool", "numeric"], + + "columnvalues": [456, "Sun Apr 26 16:23:59 2020", "Panthera Onca", false, 4.560], + + "pk": { + + "pknames": ["b", "d", "e"], + + "pktypes": ["timestamp", "bool", "numeric"] + + }, + + "oldkeys": { + + "keynames": ["b", "d", "e"], + + "keytypes": ["timestamp", "bool", "numeric"], + + "keyvalues": ["Sun Apr 26 16:23:59 2020", true, 4.560] + + } + + } + + ] + + } + { + + "change": [ + + { + + "kind": "delete", + + "schema": "public", + + "table": "w2j_pk_with_pk", + + "pk": { + + "pknames": ["b", "d", "e"], + + "pktypes": ["timestamp", "bool", "numeric"] + + }, + + "oldkeys": { + + "keynames": ["b", "d", "e"], + + "keytypes": ["timestamp", "bool", "numeric"], + + "keyvalues": ["Sun Apr 26 16:23:59 2020", false, 4.560] + + } + + } + + ] + + } + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "w2j_pk_without_pk", + + "columnnames": ["a", "b", "c", "d", "e"], + + "columntypes": ["int4", "timestamp", "text", "bool", "numeric"], + + "columnvalues": [123, "Sun Apr 26 16:23:59 2020", "Melanosuchus Niger", true, 4.560] + + } + + ] + + } + { + + "change": [ + + ] + + } + { + + "change": [ + + ] + + } + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "w2j_pk_with_ri", + + "columnnames": ["a", "b", "c", "d", "e"], + + "columntypes": ["int4", "timestamp", "text", "bool", "numeric"], + + "columnvalues": [123, "Sun Apr 26 16:23:59 2020", "Inia Araguaiaensis", true, 4.560] + + } + + ] + + } + { + + "change": [ + + { + + "kind": "update", + + "schema": "public", + + "table": "w2j_pk_with_ri", + + "columnnames": ["a", "b", "c", "d", "e"], + + "columntypes": ["int4", "timestamp", "text", "bool", "numeric"], + + "columnvalues": [456, "Sun Apr 26 16:23:59 2020", "Panthera Onca", false, 4.560], + + "oldkeys": { + + "keynames": ["a"], + + "keytypes": ["int4"], + + "keyvalues": [123] + + } + + } + + ] + + } + { + + "change": [ + + { + + "kind": "delete", + + "schema": "public", + + "table": "w2j_pk_with_ri", + + "oldkeys": { + + "keynames": ["a"], + + "keytypes": ["int4"], + + "keyvalues": [456] + + } + + } + + ] + + } +(9 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'include-pk', '1'); +WARNING: no tuple identifier for UPDATE in table "public"."w2j_pk_without_pk" +WARNING: no tuple identifier for DELETE in table "public"."w2j_pk_without_pk" + data +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_pk_with_pk","columns":[{"name":"a","type":"integer","value":123},{"name":"b","type":"timestamp without time zone","value":"Sun Apr 26 16:23:59 2020"},{"name":"c","type":"text","value":"Melanosuchus Niger"},{"name":"d","type":"boolean","value":true},{"name":"e","type":"numeric(5,3)","value":4.560}],"pk":[{"name":"b","type":"timestamp without time zone"},{"name":"d","type":"boolean"},{"name":"e","type":"numeric(5,3)"}]} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"w2j_pk_with_pk","columns":[{"name":"a","type":"integer","value":456},{"name":"b","type":"timestamp without time zone","value":"Sun Apr 26 16:23:59 2020"},{"name":"c","type":"text","value":"Panthera Onca"},{"name":"d","type":"boolean","value":false},{"name":"e","type":"numeric(5,3)","value":4.560}],"identity":[{"name":"b","type":"timestamp without time zone","value":"Sun Apr 26 16:23:59 2020"},{"name":"d","type":"boolean","value":true},{"name":"e","type":"numeric(5,3)","value":4.560}],"pk":[{"name":"b","type":"timestamp without time zone"},{"name":"d","type":"boolean"},{"name":"e","type":"numeric(5,3)"}]} + {"action":"C"} + {"action":"B"} + {"action":"D","schema":"public","table":"w2j_pk_with_pk","identity":[{"name":"b","type":"timestamp without time zone","value":"Sun Apr 26 16:23:59 2020"},{"name":"d","type":"boolean","value":false},{"name":"e","type":"numeric(5,3)","value":4.560}],"pk":[{"name":"b","type":"timestamp without time zone"},{"name":"d","type":"boolean"},{"name":"e","type":"numeric(5,3)"}]} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_pk_without_pk","columns":[{"name":"a","type":"integer","value":123},{"name":"b","type":"timestamp without time zone","value":"Sun Apr 26 16:23:59 2020"},{"name":"c","type":"text","value":"Melanosuchus Niger"},{"name":"d","type":"boolean","value":true},{"name":"e","type":"numeric(5,3)","value":4.560}],"pk":[]} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_pk_with_ri","columns":[{"name":"a","type":"integer","value":123},{"name":"b","type":"timestamp without time zone","value":"Sun Apr 26 16:23:59 2020"},{"name":"c","type":"text","value":"Inia Araguaiaensis"},{"name":"d","type":"boolean","value":true},{"name":"e","type":"numeric(5,3)","value":4.560}],"pk":[]} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"w2j_pk_with_ri","columns":[{"name":"a","type":"integer","value":456},{"name":"b","type":"timestamp without time zone","value":"Sun Apr 26 16:23:59 2020"},{"name":"c","type":"text","value":"Panthera Onca"},{"name":"d","type":"boolean","value":false},{"name":"e","type":"numeric(5,3)","value":4.560}],"identity":[{"name":"a","type":"integer","value":123}],"pk":[]} + {"action":"C"} + {"action":"B"} + {"action":"D","schema":"public","table":"w2j_pk_with_ri","identity":[{"name":"a","type":"integer","value":456}],"pk":[]} + {"action":"C"} +(25 rows) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + +DROP TABLE w2j_pk_with_pk; +DROP TABLE w2j_pk_without_pk; +DROP TABLE w2j_pk_with_ri; diff --git a/src/postgres/third-party-extensions/wal2json/expected/position.out b/src/postgres/third-party-extensions/wal2json/expected/position.out new file mode 100644 index 000000000000..6f97be572f95 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/position.out @@ -0,0 +1,88 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +CREATE TABLE w2j_position (a integer, b integer, primary key(a)); +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +INSERT INTO w2j_position (a, b) VALUES(1,2); +UPDATE w2j_position SET b = 3 WHERE a = 1; +ALTER TABLE w2j_position ADD COLUMN c integer; +ALTER TABLE w2j_position DROP COLUMN b; +INSERT INTO w2j_position (a, c) VALUES(5,6); +UPDATE w2j_position SET c = 7 WHERE a = 5; +-- without include-column-position parameter +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1'); + data +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + {"change":[{"kind":"insert","schema":"public","table":"w2j_position","columnnames":["a","b"],"columntypes":["integer","integer"],"columnvalues":[1,2]}]} + {"change":[{"kind":"update","schema":"public","table":"w2j_position","columnnames":["a","b"],"columntypes":["integer","integer"],"columnvalues":[1,3],"oldkeys":{"keynames":["a"],"keytypes":["integer"],"keyvalues":[1]}}]} + {"change":[]} + {"change":[]} + {"change":[{"kind":"insert","schema":"public","table":"w2j_position","columnnames":["a","c"],"columntypes":["integer","integer"],"columnvalues":[5,6]}]} + {"change":[{"kind":"update","schema":"public","table":"w2j_position","columnnames":["a","c"],"columntypes":["integer","integer"],"columnvalues":[5,7],"oldkeys":{"keynames":["a"],"keytypes":["integer"],"keyvalues":[5]}}]} +(6 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); + data +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_position","columns":[{"name":"a","type":"integer","value":1},{"name":"b","type":"integer","value":2}]} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"w2j_position","columns":[{"name":"a","type":"integer","value":1},{"name":"b","type":"integer","value":3}],"identity":[{"name":"a","type":"integer","value":1}]} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_position","columns":[{"name":"a","type":"integer","value":5},{"name":"c","type":"integer","value":6}]} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"w2j_position","columns":[{"name":"a","type":"integer","value":5},{"name":"c","type":"integer","value":7}],"identity":[{"name":"a","type":"integer","value":5}]} + {"action":"C"} +(16 rows) + +-- with include-column-position parameter +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-column-positions', '1'); + data +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + {"change":[{"kind":"insert","schema":"public","table":"w2j_position","columnnames":["a","b"],"columntypes":["integer","integer"],"columnpositions":[1,2],"columnvalues":[1,2]}]} + {"change":[{"kind":"update","schema":"public","table":"w2j_position","columnnames":["a","b"],"columntypes":["integer","integer"],"columnpositions":[1,2],"columnvalues":[1,3],"oldkeys":{"keynames":["a"],"keytypes":["integer"],"keyvalues":[1]}}]} + {"change":[]} + {"change":[]} + {"change":[{"kind":"insert","schema":"public","table":"w2j_position","columnnames":["a","c"],"columntypes":["integer","integer"],"columnpositions":[1,3],"columnvalues":[5,6]}]} + {"change":[{"kind":"update","schema":"public","table":"w2j_position","columnnames":["a","c"],"columntypes":["integer","integer"],"columnpositions":[1,3],"columnvalues":[5,7],"oldkeys":{"keynames":["a"],"keytypes":["integer"],"keyvalues":[5]}}]} +(6 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'include-column-positions', '1'); + data +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_position","columns":[{"name":"a","type":"integer","value":1,"position":1},{"name":"b","type":"integer","value":2,"position":2}]} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"w2j_position","columns":[{"name":"a","type":"integer","value":1,"position":1},{"name":"b","type":"integer","value":3,"position":2}],"identity":[{"name":"a","type":"integer","value":1}]} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_position","columns":[{"name":"a","type":"integer","value":5,"position":1},{"name":"c","type":"integer","value":6,"position":3}]} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"w2j_position","columns":[{"name":"a","type":"integer","value":5,"position":1},{"name":"c","type":"integer","value":7,"position":3}],"identity":[{"name":"a","type":"integer","value":5}]} + {"action":"C"} +(16 rows) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + diff --git a/src/postgres/third-party-extensions/wal2json/expected/rename_column.out b/src/postgres/third-party-extensions/wal2json/expected/rename_column.out new file mode 100644 index 000000000000..e2544d6ccaff --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/rename_column.out @@ -0,0 +1,397 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +SET extra_float_digits = 0; +CREATE TABLE w2j_rename_pk ( +a int, +b timestamp, +c text, +d boolean, +e numeric(5,3), +PRIMARY KEY(a, d) +); +CREATE TABLE w2j_rename_ri ( +a int NOT NULL, +b timestamp, +c text, +d boolean NOT NULL, +e numeric(5,3) +); +CREATE UNIQUE INDEX w2j_rename_ri_idx ON w2j_rename_ri (a, d); +ALTER TABLE w2j_rename_ri REPLICA IDENTITY USING INDEX w2j_rename_ri_idx; +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +INSERT INTO w2j_rename_pk (a, b, c, d, e) VALUES(123, '2020-04-26 16:23:59', 'Melanosuchus Niger', true, 4.56); +UPDATE w2j_rename_pk SET e = 8.76 WHERE a = 123; +ALTER TABLE w2j_rename_pk RENAME COLUMN d TO f; +INSERT INTO w2j_rename_pk (a, b, c, f, e) VALUES(456, '2020-12-07 15:56:59', 'Panthera Onca', false, 4.44); +UPDATE w2j_rename_pk SET e = 2.718 WHERE a = 456; +BEGIN; +INSERT INTO w2j_rename_pk (a, b, c, f, e) VALUES(789, '2021-04-04 10:33:04', 'Chrysocyon brachyurus', true, 20.30); +ALTER TABLE w2j_rename_pk RENAME COLUMN a TO g; +INSERT INTO w2j_rename_pk (g, b, c, f, e) VALUES(790, '2020-04-04 10:34:55', 'Myrmecophaga tridactyla', false, 1.8); +UPDATE w2j_rename_pk SET e = 3.1415 WHERE g = 456; +COMMIT; +INSERT INTO w2j_rename_ri (a, b, c, d, e) VALUES(123, '2020-04-26 16:23:59', 'Melanosuchus Niger', true, 4.56); +UPDATE w2j_rename_ri SET e = 8.76 WHERE a = 123; +ALTER TABLE w2j_rename_ri RENAME COLUMN d TO f; +INSERT INTO w2j_rename_ri (a, b, c, f, e) VALUES(456, '2020-12-07 15:56:59', 'Panthera Onca', false, 4.44); +UPDATE w2j_rename_ri SET e = 2.718 WHERE a = 456; +BEGIN; +INSERT INTO w2j_rename_ri (a, b, c, f, e) VALUES(789, '2021-04-04 10:33:04', 'Chrysocyon brachyurus', true, 20.30); +ALTER TABLE w2j_rename_ri RENAME COLUMN a TO g; +INSERT INTO w2j_rename_ri (g, b, c, f, e) VALUES(790, '2020-04-04 10:34:55', 'Myrmecophaga tridactyla', false, 1.8); +UPDATE w2j_rename_ri SET e = 3.1415 WHERE g = 456; +COMMIT; +ALTER TABLE w2j_rename_pk REPLICA IDENTITY FULL; +INSERT INTO w2j_rename_pk (g, b, c, f, e) VALUES(890, '2023-10-31 03:06:00', 'Crypturellus parvirostris', true, 8.90); +UPDATE w2j_rename_pk SET e = 8.91 WHERE g = 890; +DELETE FROM w2j_rename_pk WHERE g = 890; +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0', 'include-pk', '1'); + data +-------------------------------------------------------------------------------------------------------------------------- + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "w2j_rename_pk", + + "columnnames": ["a", "b", "c", "d", "e"], + + "columntypes": ["int4", "timestamp", "text", "bool", "numeric"], + + "columnvalues": [123, "Sun Apr 26 16:23:59 2020", "Melanosuchus Niger", true, 4.560], + + "pk": { + + "pknames": ["a", "d"], + + "pktypes": ["int4", "bool"] + + } + + } + + ] + + } + { + + "change": [ + + { + + "kind": "update", + + "schema": "public", + + "table": "w2j_rename_pk", + + "columnnames": ["a", "b", "c", "d", "e"], + + "columntypes": ["int4", "timestamp", "text", "bool", "numeric"], + + "columnvalues": [123, "Sun Apr 26 16:23:59 2020", "Melanosuchus Niger", true, 8.760], + + "pk": { + + "pknames": ["a", "d"], + + "pktypes": ["int4", "bool"] + + }, + + "oldkeys": { + + "keynames": ["a", "d"], + + "keytypes": ["int4", "bool"], + + "keyvalues": [123, true] + + } + + } + + ] + + } + { + + "change": [ + + ] + + } + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "w2j_rename_pk", + + "columnnames": ["a", "b", "c", "f", "e"], + + "columntypes": ["int4", "timestamp", "text", "bool", "numeric"], + + "columnvalues": [456, "Mon Dec 07 15:56:59 2020", "Panthera Onca", false, 4.440], + + "pk": { + + "pknames": ["a", "f"], + + "pktypes": ["int4", "bool"] + + } + + } + + ] + + } + { + + "change": [ + + { + + "kind": "update", + + "schema": "public", + + "table": "w2j_rename_pk", + + "columnnames": ["a", "b", "c", "f", "e"], + + "columntypes": ["int4", "timestamp", "text", "bool", "numeric"], + + "columnvalues": [456, "Mon Dec 07 15:56:59 2020", "Panthera Onca", false, 2.718], + + "pk": { + + "pknames": ["a", "f"], + + "pktypes": ["int4", "bool"] + + }, + + "oldkeys": { + + "keynames": ["a", "f"], + + "keytypes": ["int4", "bool"], + + "keyvalues": [456, false] + + } + + } + + ] + + } + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "w2j_rename_pk", + + "columnnames": ["a", "b", "c", "f", "e"], + + "columntypes": ["int4", "timestamp", "text", "bool", "numeric"], + + "columnvalues": [789, "Sun Apr 04 10:33:04 2021", "Chrysocyon brachyurus", true, 20.300], + + "pk": { + + "pknames": ["a", "f"], + + "pktypes": ["int4", "bool"] + + } + + } + + ,{ + + "kind": "insert", + + "schema": "public", + + "table": "w2j_rename_pk", + + "columnnames": ["g", "b", "c", "f", "e"], + + "columntypes": ["int4", "timestamp", "text", "bool", "numeric"], + + "columnvalues": [790, "Sat Apr 04 10:34:55 2020", "Myrmecophaga tridactyla", false, 1.800], + + "pk": { + + "pknames": ["g", "f"], + + "pktypes": ["int4", "bool"] + + } + + } + + ,{ + + "kind": "update", + + "schema": "public", + + "table": "w2j_rename_pk", + + "columnnames": ["g", "b", "c", "f", "e"], + + "columntypes": ["int4", "timestamp", "text", "bool", "numeric"], + + "columnvalues": [456, "Mon Dec 07 15:56:59 2020", "Panthera Onca", false, 3.142], + + "pk": { + + "pknames": ["g", "f"], + + "pktypes": ["int4", "bool"] + + }, + + "oldkeys": { + + "keynames": ["g", "f"], + + "keytypes": ["int4", "bool"], + + "keyvalues": [456, false] + + } + + } + + ] + + } + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "w2j_rename_ri", + + "columnnames": ["a", "b", "c", "d", "e"], + + "columntypes": ["int4", "timestamp", "text", "bool", "numeric"], + + "columnvalues": [123, "Sun Apr 26 16:23:59 2020", "Melanosuchus Niger", true, 4.560] + + } + + ] + + } + { + + "change": [ + + { + + "kind": "update", + + "schema": "public", + + "table": "w2j_rename_ri", + + "columnnames": ["a", "b", "c", "d", "e"], + + "columntypes": ["int4", "timestamp", "text", "bool", "numeric"], + + "columnvalues": [123, "Sun Apr 26 16:23:59 2020", "Melanosuchus Niger", true, 8.760], + + "oldkeys": { + + "keynames": ["a", "d"], + + "keytypes": ["int4", "bool"], + + "keyvalues": [123, true] + + } + + } + + ] + + } + { + + "change": [ + + ] + + } + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "w2j_rename_ri", + + "columnnames": ["a", "b", "c", "f", "e"], + + "columntypes": ["int4", "timestamp", "text", "bool", "numeric"], + + "columnvalues": [456, "Mon Dec 07 15:56:59 2020", "Panthera Onca", false, 4.440] + + } + + ] + + } + { + + "change": [ + + { + + "kind": "update", + + "schema": "public", + + "table": "w2j_rename_ri", + + "columnnames": ["a", "b", "c", "f", "e"], + + "columntypes": ["int4", "timestamp", "text", "bool", "numeric"], + + "columnvalues": [456, "Mon Dec 07 15:56:59 2020", "Panthera Onca", false, 2.718], + + "oldkeys": { + + "keynames": ["a", "f"], + + "keytypes": ["int4", "bool"], + + "keyvalues": [456, false] + + } + + } + + ] + + } + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "w2j_rename_ri", + + "columnnames": ["a", "b", "c", "f", "e"], + + "columntypes": ["int4", "timestamp", "text", "bool", "numeric"], + + "columnvalues": [789, "Sun Apr 04 10:33:04 2021", "Chrysocyon brachyurus", true, 20.300] + + } + + ,{ + + "kind": "insert", + + "schema": "public", + + "table": "w2j_rename_ri", + + "columnnames": ["g", "b", "c", "f", "e"], + + "columntypes": ["int4", "timestamp", "text", "bool", "numeric"], + + "columnvalues": [790, "Sat Apr 04 10:34:55 2020", "Myrmecophaga tridactyla", false, 1.800] + + } + + ,{ + + "kind": "update", + + "schema": "public", + + "table": "w2j_rename_ri", + + "columnnames": ["g", "b", "c", "f", "e"], + + "columntypes": ["int4", "timestamp", "text", "bool", "numeric"], + + "columnvalues": [456, "Mon Dec 07 15:56:59 2020", "Panthera Onca", false, 3.142], + + "oldkeys": { + + "keynames": ["g", "f"], + + "keytypes": ["int4", "bool"], + + "keyvalues": [456, false] + + } + + } + + ] + + } + { + + "change": [ + + ] + + } + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "w2j_rename_pk", + + "columnnames": ["g", "b", "c", "f", "e"], + + "columntypes": ["int4", "timestamp", "text", "bool", "numeric"], + + "columnvalues": [890, "Tue Oct 31 03:06:00 2023", "Crypturellus parvirostris", true, 8.900], + + "pk": { + + "pknames": ["g", "f"], + + "pktypes": ["int4", "bool"] + + } + + } + + ] + + } + { + + "change": [ + + { + + "kind": "update", + + "schema": "public", + + "table": "w2j_rename_pk", + + "columnnames": ["g", "b", "c", "f", "e"], + + "columntypes": ["int4", "timestamp", "text", "bool", "numeric"], + + "columnvalues": [890, "Tue Oct 31 03:06:00 2023", "Crypturellus parvirostris", true, 8.910], + + "pk": { + + "pknames": ["g", "f"], + + "pktypes": ["int4", "bool"] + + }, + + "oldkeys": { + + "keynames": ["g", "b", "c", "f", "e"], + + "keytypes": ["int4", "timestamp", "text", "bool", "numeric"], + + "keyvalues": [890, "Tue Oct 31 03:06:00 2023", "Crypturellus parvirostris", true, 8.900]+ + } + + } + + ] + + } + { + + "change": [ + + { + + "kind": "delete", + + "schema": "public", + + "table": "w2j_rename_pk", + + "pk": { + + "pknames": ["g", "f"], + + "pktypes": ["int4", "bool"] + + }, + + "oldkeys": { + + "keynames": ["g", "b", "c", "f", "e"], + + "keytypes": ["int4", "timestamp", "text", "bool", "numeric"], + + "keyvalues": [890, "Tue Oct 31 03:06:00 2023", "Crypturellus parvirostris", true, 8.910]+ + } + + } + + ] + + } +(16 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'include-pk', '1'); + data +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_rename_pk","columns":[{"name":"a","type":"integer","value":123},{"name":"b","type":"timestamp without time zone","value":"Sun Apr 26 16:23:59 2020"},{"name":"c","type":"text","value":"Melanosuchus Niger"},{"name":"d","type":"boolean","value":true},{"name":"e","type":"numeric(5,3)","value":4.560}],"pk":[{"name":"a","type":"integer"},{"name":"d","type":"boolean"}]} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"w2j_rename_pk","columns":[{"name":"a","type":"integer","value":123},{"name":"b","type":"timestamp without time zone","value":"Sun Apr 26 16:23:59 2020"},{"name":"c","type":"text","value":"Melanosuchus Niger"},{"name":"d","type":"boolean","value":true},{"name":"e","type":"numeric(5,3)","value":8.760}],"identity":[{"name":"a","type":"integer","value":123},{"name":"d","type":"boolean","value":true}],"pk":[{"name":"a","type":"integer"},{"name":"d","type":"boolean"}]} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_rename_pk","columns":[{"name":"a","type":"integer","value":456},{"name":"b","type":"timestamp without time zone","value":"Mon Dec 07 15:56:59 2020"},{"name":"c","type":"text","value":"Panthera Onca"},{"name":"f","type":"boolean","value":false},{"name":"e","type":"numeric(5,3)","value":4.440}],"pk":[{"name":"a","type":"integer"},{"name":"f","type":"boolean"}]} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"w2j_rename_pk","columns":[{"name":"a","type":"integer","value":456},{"name":"b","type":"timestamp without time zone","value":"Mon Dec 07 15:56:59 2020"},{"name":"c","type":"text","value":"Panthera Onca"},{"name":"f","type":"boolean","value":false},{"name":"e","type":"numeric(5,3)","value":2.718}],"identity":[{"name":"a","type":"integer","value":456},{"name":"f","type":"boolean","value":false}],"pk":[{"name":"a","type":"integer"},{"name":"f","type":"boolean"}]} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_rename_pk","columns":[{"name":"a","type":"integer","value":789},{"name":"b","type":"timestamp without time zone","value":"Sun Apr 04 10:33:04 2021"},{"name":"c","type":"text","value":"Chrysocyon brachyurus"},{"name":"f","type":"boolean","value":true},{"name":"e","type":"numeric(5,3)","value":20.300}],"pk":[{"name":"a","type":"integer"},{"name":"f","type":"boolean"}]} + {"action":"I","schema":"public","table":"w2j_rename_pk","columns":[{"name":"g","type":"integer","value":790},{"name":"b","type":"timestamp without time zone","value":"Sat Apr 04 10:34:55 2020"},{"name":"c","type":"text","value":"Myrmecophaga tridactyla"},{"name":"f","type":"boolean","value":false},{"name":"e","type":"numeric(5,3)","value":1.800}],"pk":[{"name":"g","type":"integer"},{"name":"f","type":"boolean"}]} + {"action":"U","schema":"public","table":"w2j_rename_pk","columns":[{"name":"g","type":"integer","value":456},{"name":"b","type":"timestamp without time zone","value":"Mon Dec 07 15:56:59 2020"},{"name":"c","type":"text","value":"Panthera Onca"},{"name":"f","type":"boolean","value":false},{"name":"e","type":"numeric(5,3)","value":3.142}],"identity":[{"name":"g","type":"integer","value":456},{"name":"f","type":"boolean","value":false}],"pk":[{"name":"g","type":"integer"},{"name":"f","type":"boolean"}]} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_rename_ri","columns":[{"name":"a","type":"integer","value":123},{"name":"b","type":"timestamp without time zone","value":"Sun Apr 26 16:23:59 2020"},{"name":"c","type":"text","value":"Melanosuchus Niger"},{"name":"d","type":"boolean","value":true},{"name":"e","type":"numeric(5,3)","value":4.560}],"pk":[]} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"w2j_rename_ri","columns":[{"name":"a","type":"integer","value":123},{"name":"b","type":"timestamp without time zone","value":"Sun Apr 26 16:23:59 2020"},{"name":"c","type":"text","value":"Melanosuchus Niger"},{"name":"d","type":"boolean","value":true},{"name":"e","type":"numeric(5,3)","value":8.760}],"identity":[{"name":"a","type":"integer","value":123},{"name":"d","type":"boolean","value":true}],"pk":[]} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_rename_ri","columns":[{"name":"a","type":"integer","value":456},{"name":"b","type":"timestamp without time zone","value":"Mon Dec 07 15:56:59 2020"},{"name":"c","type":"text","value":"Panthera Onca"},{"name":"f","type":"boolean","value":false},{"name":"e","type":"numeric(5,3)","value":4.440}],"pk":[]} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"w2j_rename_ri","columns":[{"name":"a","type":"integer","value":456},{"name":"b","type":"timestamp without time zone","value":"Mon Dec 07 15:56:59 2020"},{"name":"c","type":"text","value":"Panthera Onca"},{"name":"f","type":"boolean","value":false},{"name":"e","type":"numeric(5,3)","value":2.718}],"identity":[{"name":"a","type":"integer","value":456},{"name":"f","type":"boolean","value":false}],"pk":[]} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_rename_ri","columns":[{"name":"a","type":"integer","value":789},{"name":"b","type":"timestamp without time zone","value":"Sun Apr 04 10:33:04 2021"},{"name":"c","type":"text","value":"Chrysocyon brachyurus"},{"name":"f","type":"boolean","value":true},{"name":"e","type":"numeric(5,3)","value":20.300}],"pk":[]} + {"action":"I","schema":"public","table":"w2j_rename_ri","columns":[{"name":"g","type":"integer","value":790},{"name":"b","type":"timestamp without time zone","value":"Sat Apr 04 10:34:55 2020"},{"name":"c","type":"text","value":"Myrmecophaga tridactyla"},{"name":"f","type":"boolean","value":false},{"name":"e","type":"numeric(5,3)","value":1.800}],"pk":[]} + {"action":"U","schema":"public","table":"w2j_rename_ri","columns":[{"name":"g","type":"integer","value":456},{"name":"b","type":"timestamp without time zone","value":"Mon Dec 07 15:56:59 2020"},{"name":"c","type":"text","value":"Panthera Onca"},{"name":"f","type":"boolean","value":false},{"name":"e","type":"numeric(5,3)","value":3.142}],"identity":[{"name":"g","type":"integer","value":456},{"name":"f","type":"boolean","value":false}],"pk":[]} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_rename_pk","columns":[{"name":"g","type":"integer","value":890},{"name":"b","type":"timestamp without time zone","value":"Tue Oct 31 03:06:00 2023"},{"name":"c","type":"text","value":"Crypturellus parvirostris"},{"name":"f","type":"boolean","value":true},{"name":"e","type":"numeric(5,3)","value":8.900}],"pk":[{"name":"g","type":"integer"},{"name":"f","type":"boolean"}]} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"w2j_rename_pk","columns":[{"name":"g","type":"integer","value":890},{"name":"b","type":"timestamp without time zone","value":"Tue Oct 31 03:06:00 2023"},{"name":"c","type":"text","value":"Crypturellus parvirostris"},{"name":"f","type":"boolean","value":true},{"name":"e","type":"numeric(5,3)","value":8.910}],"identity":[{"name":"g","type":"integer","value":890},{"name":"b","type":"timestamp without time zone","value":"Tue Oct 31 03:06:00 2023"},{"name":"c","type":"text","value":"Crypturellus parvirostris"},{"name":"f","type":"boolean","value":true},{"name":"e","type":"numeric(5,3)","value":8.900}],"pk":[{"name":"g","type":"integer"},{"name":"f","type":"boolean"}]} + {"action":"C"} + {"action":"B"} + {"action":"D","schema":"public","table":"w2j_rename_pk","identity":[{"name":"g","type":"integer","value":890},{"name":"b","type":"timestamp without time zone","value":"Tue Oct 31 03:06:00 2023"},{"name":"c","type":"text","value":"Crypturellus parvirostris"},{"name":"f","type":"boolean","value":true},{"name":"e","type":"numeric(5,3)","value":8.910}],"pk":[{"name":"g","type":"integer"},{"name":"f","type":"boolean"}]} + {"action":"C"} +(49 rows) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + +DROP TABLE w2j_rename_pk; +DROP TABLE w2j_rename_ri; diff --git a/src/postgres/third-party-extensions/wal2json/expected/savepoint.out b/src/postgres/third-party-extensions/wal2json/expected/savepoint.out new file mode 100644 index 000000000000..6da5a9ba4d00 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/savepoint.out @@ -0,0 +1,100 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +CREATE TABLE xpto (a SERIAL PRIMARY KEY, b text); +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +INSERT INTO xpto (b) VALUES('john'); +INSERT INTO xpto (b) VALUES('smith'); +INSERT INTO xpto (b) VALUES('robert'); +BEGIN; +INSERT INTO xpto (b) VALUES('marie'); +SAVEPOINT sp1; +INSERT INTO xpto (b) VALUES('ernesto'); +SAVEPOINT sp2; +INSERT INTO xpto (b) VALUES('peter'); -- discard +SAVEPOINT sp3; +INSERT INTO xpto (b) VALUES('albert'); -- discard +ROLLBACK TO SAVEPOINT sp2; +RELEASE SAVEPOINT sp1; +INSERT INTO xpto (b) VALUES('francisco'); +END; +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0'); + data +---------------------------------------------------------- + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "xpto", + + "columnnames": ["a", "b"], + + "columntypes": ["int4", "text"],+ + "columnvalues": [1, "john"] + + } + + ] + + } + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "xpto", + + "columnnames": ["a", "b"], + + "columntypes": ["int4", "text"],+ + "columnvalues": [2, "smith"] + + } + + ] + + } + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "xpto", + + "columnnames": ["a", "b"], + + "columntypes": ["int4", "text"],+ + "columnvalues": [3, "robert"] + + } + + ] + + } + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "xpto", + + "columnnames": ["a", "b"], + + "columntypes": ["int4", "text"],+ + "columnvalues": [4, "marie"] + + } + + ,{ + + "kind": "insert", + + "schema": "public", + + "table": "xpto", + + "columnnames": ["a", "b"], + + "columntypes": ["int4", "text"],+ + "columnvalues": [5, "ernesto"] + + } + + ,{ + + "kind": "insert", + + "schema": "public", + + "table": "xpto", + + "columnnames": ["a", "b"], + + "columntypes": ["int4", "text"],+ + "columnvalues": [8, "francisco"]+ + } + + ] + + } +(4 rows) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + diff --git a/src/postgres/third-party-extensions/wal2json/expected/selecttable.out b/src/postgres/third-party-extensions/wal2json/expected/selecttable.out new file mode 100644 index 000000000000..748239425d48 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/selecttable.out @@ -0,0 +1,156 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +DROP TABLE IF EXISTS select_table_1; +NOTICE: table "select_table_1" does not exist, skipping +DROP TABLE IF EXISTS select_table_2; +NOTICE: table "select_table_2" does not exist, skipping +DROP TABLE IF EXISTS select_table_3; +NOTICE: table "select_table_3" does not exist, skipping +DROP SCHEMA IF EXISTS select_schema_1 CASCADE; +NOTICE: schema "select_schema_1" does not exist, skipping +DROP SCHEMA IF EXISTS select_schema_2 CASCADE; +NOTICE: schema "select_schema_2" does not exist, skipping +CREATE SCHEMA select_schema_1; +CREATE SCHEMA select_schema_2; +CREATE TABLE select_table_1 (a integer, b text, primary key(a)); +CREATE TABLE select_schema_1.select_table_1 (a integer, b text, primary key(a)); +CREATE TABLE select_schema_1.select_table_2 (a integer, b text, primary key(a)); +CREATE TABLE select_schema_2.select_table_1 (a integer, b text, primary key(a)); +CREATE TABLE select_schema_2.select_table_2 (a integer, b text, primary key(a)); +CREATE TABLE select_schema_2.select_table_3 (a integer, b text, primary key(a)); +CREATE TABLE select_table_2 (a integer, b text, primary key(a)); +CREATE TABLE select_table_3 (a integer, b text, primary key(a)); +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +INSERT INTO select_table_1 (a, b) VALUES(1, 'public.select_table_1'); +INSERT INTO select_schema_1.select_table_1 (a, b) VALUES(1, 'select_schema_1.select_table_1'); +INSERT INTO select_schema_1.select_table_2 (a, b) VALUES(1, 'select_schema_1.select_table_2'); +INSERT INTO select_schema_2.select_table_1 (a, b) VALUES(1, 'select_schema_2.select_table_1'); +INSERT INTO select_schema_2.select_table_2 (a, b) VALUES(1, 'select_schema_2.select_table_2'); +INSERT INTO select_schema_2.select_table_3 (a, b) VALUES(1, 'select_schema_2.select_table_3'); +INSERT INTO select_table_2 (a, b) VALUES(1, 'public.select_table_2'); +INSERT INTO select_table_3 (a, b) VALUES(1, 'public.select_table_3'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'add-tables', ' foo.bar,*.select_table_1 ,select_schema_2.* , public.select_table_3 '); + data +------------------------------------------------------------------------------- + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "select_table_1", + + "columnnames": ["a", "b"], + + "columntypes": ["integer", "text"], + + "columnvalues": [1, "public.select_table_1"] + + } + + ] + + } + { + + "change": [ + + { + + "kind": "insert", + + "schema": "select_schema_1", + + "table": "select_table_1", + + "columnnames": ["a", "b"], + + "columntypes": ["integer", "text"], + + "columnvalues": [1, "select_schema_1.select_table_1"]+ + } + + ] + + } + { + + "change": [ + + ] + + } + { + + "change": [ + + { + + "kind": "insert", + + "schema": "select_schema_2", + + "table": "select_table_1", + + "columnnames": ["a", "b"], + + "columntypes": ["integer", "text"], + + "columnvalues": [1, "select_schema_2.select_table_1"]+ + } + + ] + + } + { + + "change": [ + + { + + "kind": "insert", + + "schema": "select_schema_2", + + "table": "select_table_2", + + "columnnames": ["a", "b"], + + "columntypes": ["integer", "text"], + + "columnvalues": [1, "select_schema_2.select_table_2"]+ + } + + ] + + } + { + + "change": [ + + { + + "kind": "insert", + + "schema": "select_schema_2", + + "table": "select_table_3", + + "columnnames": ["a", "b"], + + "columntypes": ["integer", "text"], + + "columnvalues": [1, "select_schema_2.select_table_3"]+ + } + + ] + + } + { + + "change": [ + + ] + + } + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "select_table_3", + + "columnnames": ["a", "b"], + + "columntypes": ["integer", "text"], + + "columnvalues": [1, "public.select_table_3"] + + } + + ] + + } +(8 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'add-tables', ' foo.bar,*.select_table_1 ,select_schema_2.* , public.select_table_3 '); + data +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"action":"B"} + {"action":"I","schema":"public","table":"select_table_1","columns":[{"name":"a","type":"integer","value":1},{"name":"b","type":"text","value":"public.select_table_1"}]} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"select_schema_1","table":"select_table_1","columns":[{"name":"a","type":"integer","value":1},{"name":"b","type":"text","value":"select_schema_1.select_table_1"}]} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"select_schema_2","table":"select_table_1","columns":[{"name":"a","type":"integer","value":1},{"name":"b","type":"text","value":"select_schema_2.select_table_1"}]} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"select_schema_2","table":"select_table_2","columns":[{"name":"a","type":"integer","value":1},{"name":"b","type":"text","value":"select_schema_2.select_table_2"}]} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"select_schema_2","table":"select_table_3","columns":[{"name":"a","type":"integer","value":1},{"name":"b","type":"text","value":"select_schema_2.select_table_3"}]} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"select_table_3","columns":[{"name":"a","type":"integer","value":1},{"name":"b","type":"text","value":"public.select_table_3"}]} + {"action":"C"} +(22 rows) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + + diff --git a/src/postgres/third-party-extensions/wal2json/expected/specialvalue.out b/src/postgres/third-party-extensions/wal2json/expected/specialvalue.out new file mode 100644 index 000000000000..b035da70cd49 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/specialvalue.out @@ -0,0 +1,70 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +DROP TABLE IF EXISTS xpto; +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +CREATE TABLE xpto (a SERIAL PRIMARY KEY, b bool, c varchar(60), d real); +COMMIT; +WARNING: there is no transaction in progress +BEGIN; +INSERT INTO xpto (b, c, d) VALUES('t', 'test1', '+inf'); +INSERT INTO xpto (b, c, d) VALUES('f', 'test2', 'nan'); +INSERT INTO xpto (b, c, d) VALUES(NULL, 'null', '-inf'); +INSERT INTO xpto (b, c, d) VALUES(TRUE, E'valid: '' " \\ / \b \f \n \r \t \u207F \u967F invalid: \\g \\k end', 123.456); +COMMIT; +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0'); + data +------------------------------------------------------------------------------------------------------------------------- + { + + "change": [ + + ] + + } + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "xpto", + + "columnnames": ["a", "b", "c", "d"], + + "columntypes": ["int4", "bool", "varchar", "float4"], + + "columnvalues": [1, true, "test1", null] + + } + + ,{ + + "kind": "insert", + + "schema": "public", + + "table": "xpto", + + "columnnames": ["a", "b", "c", "d"], + + "columntypes": ["int4", "bool", "varchar", "float4"], + + "columnvalues": [2, false, "test2", null] + + } + + ,{ + + "kind": "insert", + + "schema": "public", + + "table": "xpto", + + "columnnames": ["a", "b", "c", "d"], + + "columntypes": ["int4", "bool", "varchar", "float4"], + + "columnvalues": [3, null, "null", null] + + } + + ,{ + + "kind": "insert", + + "schema": "public", + + "table": "xpto", + + "columnnames": ["a", "b", "c", "d"], + + "columntypes": ["int4", "bool", "varchar", "float4"], + + "columnvalues": [4, true, "valid: ' \" \\ / \b \f \n \r \t ⁿ 陿 invalid: \\g \\k end", 123.456]+ + } + + ] + + } +(2 rows) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + diff --git a/src/postgres/third-party-extensions/wal2json/expected/toast.out b/src/postgres/third-party-extensions/wal2json/expected/toast.out new file mode 100644 index 000000000000..e4897a6a27b1 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/toast.out @@ -0,0 +1,132 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +SET extra_float_digits = 0; +DROP TABLE IF EXISTS xpto; +DROP SEQUENCE IF EXISTS xpto_rand_seq; +NOTICE: sequence "xpto_rand_seq" does not exist, skipping +CREATE SEQUENCE xpto_rand_seq START 11 INCREMENT 997; +CREATE TABLE xpto ( +id serial primary key, +toasted_col1 text, +rand1 float8 DEFAULT nextval('xpto_rand_seq'), +toasted_col2 text, +rand2 float8 DEFAULT nextval('xpto_rand_seq') +); +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +-- uncompressed external toast data +INSERT INTO xpto (toasted_col1, toasted_col2) SELECT string_agg(g.i::text, ''), string_agg((g.i*2)::text, '') FROM generate_series(1, 2000) g(i); +-- compressed external toast data +INSERT INTO xpto (toasted_col2) SELECT repeat(string_agg(to_char(g.i, 'FM0000'), ''), 50) FROM generate_series(1, 500) g(i); +-- update of existing column +UPDATE xpto SET toasted_col1 = (SELECT string_agg(g.i::text, '') FROM generate_series(1, 2000) g(i)) WHERE id = 1; +UPDATE xpto SET rand1 = 123.456 WHERE id = 1; +DELETE FROM xpto WHERE id = 1; +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0'); + data +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "xpto", + + "columnnames": ["id", "toasted_col1", "rand1", "toasted_col2", "rand2"], + + "columntypes": ["int4", "text", "float8", "text", "float8"], + + "columnvalues": [1, "12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000", 11, "24681012141618202224262830323436384042444648505254565860626466687072747678808284868890929496981001021041061081101121141161181201221241261281301321341361381401421441461481501521541561581601621641661681701721741761781801821841861881901921941961982002022042062082102122142162182202222242262282302322342362382402422442462482502522542562582602622642662682702722742762782802822842862882902922942962983003023043063083103123143163183203223243263283303323343363383403423443463483503523543563583603623643663683703723743763783803823843863883903923943963984004024044064084104124144164184204224244264284304324344364384404424444464484504524544564584604624644664684704724744764784804824844864884904924944964985005025045065085105125145165185205225245265285305325345365385405425445465485505525545565585605625645665685705725745765785805825845865885905925945965986006026046066086106126146166186206226246266286306326346366386406426446466486506526546566586606626646666686706726746766786806826846866886906926946966987007027047067087107127147167187207227247267287307327347367387407427447467487507527547567587607627647667687707727747767787807827847867887907927947967988008028048068088108128148168188208228248268288308328348368388408428448468488508528548568588608628648668688708728748768788808828848868888908928948968989009029049069089109129149169189209229249269289309329349369389409429449469489509529549569589609629649669689709729749769789809829849869889909929949969981000100210041006100810101012101410161018102010221024102610281030103210341036103810401042104410461048105010521054105610581060106210641066106810701072107410761078108010821084108610881090109210941096109811001102110411061108111011121114111611181120112211241126112811301132113411361138114011421144114611481150115211541156115811601162116411661168117011721174117611781180118211841186118811901192119411961198120012021204120612081210121212141216121812201222122412261228123012321234123612381240124212441246124812501252125412561258126012621264126612681270127212741276127812801282128412861288129012921294129612981300130213041306130813101312131413161318132013221324132613281330133213341336133813401342134413461348135013521354135613581360136213641366136813701372137413761378138013821384138613881390139213941396139814001402140414061408141014121414141614181420142214241426142814301432143414361438144014421444144614481450145214541456145814601462146414661468147014721474147614781480148214841486148814901492149414961498150015021504150615081510151215141516151815201522152415261528153015321534153615381540154215441546154815501552155415561558156015621564156615681570157215741576157815801582158415861588159015921594159615981600160216041606160816101612161416161618162016221624162616281630163216341636163816401642164416461648165016521654165616581660166216641666166816701672167416761678168016821684168616881690169216941696169817001702170417061708171017121714171617181720172217241726172817301732173417361738174017421744174617481750175217541756175817601762176417661768177017721774177617781780178217841786178817901792179417961798180018021804180618081810181218141816181818201822182418261828183018321834183618381840184218441846184818501852185418561858186018621864186618681870187218741876187818801882188418861888189018921894189618981900190219041906190819101912191419161918192019221924192619281930193219341936193819401942194419461948195019521954195619581960196219641966196819701972197419761978198019821984198619881990199219941996199820002002200420062008201020122014201620182020202220242026202820302032203420362038204020422044204620482050205220542056205820602062206420662068207020722074207620782080208220842086208820902092209420962098210021022104210621082110211221142116211821202122212421262128213021322134213621382140214221442146214821502152215421562158216021622164216621682170217221742176217821802182218421862188219021922194219621982200220222042206220822102212221422162218222022222224222622282230223222342236223822402242224422462248225022522254225622582260226222642266226822702272227422762278228022822284228622882290229222942296229823002302230423062308231023122314231623182320232223242326232823302332233423362338234023422344234623482350235223542356235823602362236423662368237023722374237623782380238223842386238823902392239423962398240024022404240624082410241224142416241824202422242424262428243024322434243624382440244224442446244824502452245424562458246024622464246624682470247224742476247824802482248424862488249024922494249624982500250225042506250825102512251425162518252025222524252625282530253225342536253825402542254425462548255025522554255625582560256225642566256825702572257425762578258025822584258625882590259225942596259826002602260426062608261026122614261626182620262226242626262826302632263426362638264026422644264626482650265226542656265826602662266426662668267026722674267626782680268226842686268826902692269426962698270027022704270627082710271227142716271827202722272427262728273027322734273627382740274227442746274827502752275427562758276027622764276627682770277227742776277827802782278427862788279027922794279627982800280228042806280828102812281428162818282028222824282628282830283228342836283828402842284428462848285028522854285628582860286228642866286828702872287428762878288028822884288628882890289228942896289829002902290429062908291029122914291629182920292229242926292829302932293429362938294029422944294629482950295229542956295829602962296429662968297029722974297629782980298229842986298829902992299429962998300030023004300630083010301230143016301830203022302430263028303030323034303630383040304230443046304830503052305430563058306030623064306630683070307230743076307830803082308430863088309030923094309630983100310231043106310831103112311431163118312031223124312631283130313231343136313831403142314431463148315031523154315631583160316231643166316831703172317431763178318031823184318631883190319231943196319832003202320432063208321032123214321632183220322232243226322832303232323432363238324032423244324632483250325232543256325832603262326432663268327032723274327632783280328232843286328832903292329432963298330033023304330633083310331233143316331833203322332433263328333033323334333633383340334233443346334833503352335433563358336033623364336633683370337233743376337833803382338433863388339033923394339633983400340234043406340834103412341434163418342034223424342634283430343234343436343834403442344434463448345034523454345634583460346234643466346834703472347434763478348034823484348634883490349234943496349835003502350435063508351035123514351635183520352235243526352835303532353435363538354035423544354635483550355235543556355835603562356435663568357035723574357635783580358235843586358835903592359435963598360036023604360636083610361236143616361836203622362436263628363036323634363636383640364236443646364836503652365436563658366036623664366636683670367236743676367836803682368436863688369036923694369636983700370237043706370837103712371437163718372037223724372637283730373237343736373837403742374437463748375037523754375637583760376237643766376837703772377437763778378037823784378637883790379237943796379838003802380438063808381038123814381638183820382238243826382838303832383438363838384038423844384638483850385238543856385838603862386438663868387038723874387638783880388238843886388838903892389438963898390039023904390639083910391239143916391839203922392439263928393039323934393639383940394239443946394839503952395439563958396039623964396639683970397239743976397839803982398439863988399039923994399639984000", 1008] + + } + + ] + + } + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "xpto", + + "columnnames": ["id", "toasted_col1", "rand1", "toasted_col2", "rand2"], + + "columntypes": ["int4", "text", "float8", "text", "float8"], + + "columnvalues": [2, null, 2005, "0001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500", 3002]+ + } + + ] + + } + { + + "change": [ + + { + + "kind": "update", + + "schema": "public", + + "table": "xpto", + + "columnnames": ["id", "toasted_col1", "rand1", "rand2"], + + "columntypes": ["int4", "text", "float8", "float8"], + + "columnvalues": [1, "12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000", 11, 1008], + + "oldkeys": { + + "keynames": ["id"], + + "keytypes": ["int4"], + + "keyvalues": [1] + + } + + } + + ] + + } + { + + "change": [ + + { + + "kind": "update", + + "schema": "public", + + "table": "xpto", + + "columnnames": ["id", "rand1", "rand2"], + + "columntypes": ["int4", "float8", "float8"], + + "columnvalues": [1, 123.456, 1008], + + "oldkeys": { + + "keynames": ["id"], + + "keytypes": ["int4"], + + "keyvalues": [1] + + } + + } + + ] + + } + { + + "change": [ + + { + + "kind": "delete", + + "schema": "public", + + "table": "xpto", + + "oldkeys": { + + "keynames": ["id"], + + "keytypes": ["int4"], + + "keyvalues": [1] + + } + + } + + ] + + } +(5 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); + data +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + {"action":"B"} + {"action":"I","schema":"public","table":"xpto","columns":[{"name":"id","type":"integer","value":1},{"name":"toasted_col1","type":"text","value":"12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000"},{"name":"rand1","type":"double precision","value":11},{"name":"toasted_col2","type":"text","value":"24681012141618202224262830323436384042444648505254565860626466687072747678808284868890929496981001021041061081101121141161181201221241261281301321341361381401421441461481501521541561581601621641661681701721741761781801821841861881901921941961982002022042062082102122142162182202222242262282302322342362382402422442462482502522542562582602622642662682702722742762782802822842862882902922942962983003023043063083103123143163183203223243263283303323343363383403423443463483503523543563583603623643663683703723743763783803823843863883903923943963984004024044064084104124144164184204224244264284304324344364384404424444464484504524544564584604624644664684704724744764784804824844864884904924944964985005025045065085105125145165185205225245265285305325345365385405425445465485505525545565585605625645665685705725745765785805825845865885905925945965986006026046066086106126146166186206226246266286306326346366386406426446466486506526546566586606626646666686706726746766786806826846866886906926946966987007027047067087107127147167187207227247267287307327347367387407427447467487507527547567587607627647667687707727747767787807827847867887907927947967988008028048068088108128148168188208228248268288308328348368388408428448468488508528548568588608628648668688708728748768788808828848868888908928948968989009029049069089109129149169189209229249269289309329349369389409429449469489509529549569589609629649669689709729749769789809829849869889909929949969981000100210041006100810101012101410161018102010221024102610281030103210341036103810401042104410461048105010521054105610581060106210641066106810701072107410761078108010821084108610881090109210941096109811001102110411061108111011121114111611181120112211241126112811301132113411361138114011421144114611481150115211541156115811601162116411661168117011721174117611781180118211841186118811901192119411961198120012021204120612081210121212141216121812201222122412261228123012321234123612381240124212441246124812501252125412561258126012621264126612681270127212741276127812801282128412861288129012921294129612981300130213041306130813101312131413161318132013221324132613281330133213341336133813401342134413461348135013521354135613581360136213641366136813701372137413761378138013821384138613881390139213941396139814001402140414061408141014121414141614181420142214241426142814301432143414361438144014421444144614481450145214541456145814601462146414661468147014721474147614781480148214841486148814901492149414961498150015021504150615081510151215141516151815201522152415261528153015321534153615381540154215441546154815501552155415561558156015621564156615681570157215741576157815801582158415861588159015921594159615981600160216041606160816101612161416161618162016221624162616281630163216341636163816401642164416461648165016521654165616581660166216641666166816701672167416761678168016821684168616881690169216941696169817001702170417061708171017121714171617181720172217241726172817301732173417361738174017421744174617481750175217541756175817601762176417661768177017721774177617781780178217841786178817901792179417961798180018021804180618081810181218141816181818201822182418261828183018321834183618381840184218441846184818501852185418561858186018621864186618681870187218741876187818801882188418861888189018921894189618981900190219041906190819101912191419161918192019221924192619281930193219341936193819401942194419461948195019521954195619581960196219641966196819701972197419761978198019821984198619881990199219941996199820002002200420062008201020122014201620182020202220242026202820302032203420362038204020422044204620482050205220542056205820602062206420662068207020722074207620782080208220842086208820902092209420962098210021022104210621082110211221142116211821202122212421262128213021322134213621382140214221442146214821502152215421562158216021622164216621682170217221742176217821802182218421862188219021922194219621982200220222042206220822102212221422162218222022222224222622282230223222342236223822402242224422462248225022522254225622582260226222642266226822702272227422762278228022822284228622882290229222942296229823002302230423062308231023122314231623182320232223242326232823302332233423362338234023422344234623482350235223542356235823602362236423662368237023722374237623782380238223842386238823902392239423962398240024022404240624082410241224142416241824202422242424262428243024322434243624382440244224442446244824502452245424562458246024622464246624682470247224742476247824802482248424862488249024922494249624982500250225042506250825102512251425162518252025222524252625282530253225342536253825402542254425462548255025522554255625582560256225642566256825702572257425762578258025822584258625882590259225942596259826002602260426062608261026122614261626182620262226242626262826302632263426362638264026422644264626482650265226542656265826602662266426662668267026722674267626782680268226842686268826902692269426962698270027022704270627082710271227142716271827202722272427262728273027322734273627382740274227442746274827502752275427562758276027622764276627682770277227742776277827802782278427862788279027922794279627982800280228042806280828102812281428162818282028222824282628282830283228342836283828402842284428462848285028522854285628582860286228642866286828702872287428762878288028822884288628882890289228942896289829002902290429062908291029122914291629182920292229242926292829302932293429362938294029422944294629482950295229542956295829602962296429662968297029722974297629782980298229842986298829902992299429962998300030023004300630083010301230143016301830203022302430263028303030323034303630383040304230443046304830503052305430563058306030623064306630683070307230743076307830803082308430863088309030923094309630983100310231043106310831103112311431163118312031223124312631283130313231343136313831403142314431463148315031523154315631583160316231643166316831703172317431763178318031823184318631883190319231943196319832003202320432063208321032123214321632183220322232243226322832303232323432363238324032423244324632483250325232543256325832603262326432663268327032723274327632783280328232843286328832903292329432963298330033023304330633083310331233143316331833203322332433263328333033323334333633383340334233443346334833503352335433563358336033623364336633683370337233743376337833803382338433863388339033923394339633983400340234043406340834103412341434163418342034223424342634283430343234343436343834403442344434463448345034523454345634583460346234643466346834703472347434763478348034823484348634883490349234943496349835003502350435063508351035123514351635183520352235243526352835303532353435363538354035423544354635483550355235543556355835603562356435663568357035723574357635783580358235843586358835903592359435963598360036023604360636083610361236143616361836203622362436263628363036323634363636383640364236443646364836503652365436563658366036623664366636683670367236743676367836803682368436863688369036923694369636983700370237043706370837103712371437163718372037223724372637283730373237343736373837403742374437463748375037523754375637583760376237643766376837703772377437763778378037823784378637883790379237943796379838003802380438063808381038123814381638183820382238243826382838303832383438363838384038423844384638483850385238543856385838603862386438663868387038723874387638783880388238843886388838903892389438963898390039023904390639083910391239143916391839203922392439263928393039323934393639383940394239443946394839503952395439563958396039623964396639683970397239743976397839803982398439863988399039923994399639984000"},{"name":"rand2","type":"double precision","value":1008}]} + {"action":"C"} + {"action":"B"} + {"action":"I","schema":"public","table":"xpto","columns":[{"name":"id","type":"integer","value":2},{"name":"toasted_col1","type":"text","value":null},{"name":"rand1","type":"double precision","value":2005},{"name":"toasted_col2","type":"text","value":"0001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500000100020003000400050006000700080009001000110012001300140015001600170018001900200021002200230024002500260027002800290030003100320033003400350036003700380039004000410042004300440045004600470048004900500051005200530054005500560057005800590060006100620063006400650066006700680069007000710072007300740075007600770078007900800081008200830084008500860087008800890090009100920093009400950096009700980099010001010102010301040105010601070108010901100111011201130114011501160117011801190120012101220123012401250126012701280129013001310132013301340135013601370138013901400141014201430144014501460147014801490150015101520153015401550156015701580159016001610162016301640165016601670168016901700171017201730174017501760177017801790180018101820183018401850186018701880189019001910192019301940195019601970198019902000201020202030204020502060207020802090210021102120213021402150216021702180219022002210222022302240225022602270228022902300231023202330234023502360237023802390240024102420243024402450246024702480249025002510252025302540255025602570258025902600261026202630264026502660267026802690270027102720273027402750276027702780279028002810282028302840285028602870288028902900291029202930294029502960297029802990300030103020303030403050306030703080309031003110312031303140315031603170318031903200321032203230324032503260327032803290330033103320333033403350336033703380339034003410342034303440345034603470348034903500351035203530354035503560357035803590360036103620363036403650366036703680369037003710372037303740375037603770378037903800381038203830384038503860387038803890390039103920393039403950396039703980399040004010402040304040405040604070408040904100411041204130414041504160417041804190420042104220423042404250426042704280429043004310432043304340435043604370438043904400441044204430444044504460447044804490450045104520453045404550456045704580459046004610462046304640465046604670468046904700471047204730474047504760477047804790480048104820483048404850486048704880489049004910492049304940495049604970498049905000001000200030004000500060007000800090010001100120013001400150016001700180019002000210022002300240025002600270028002900300031003200330034003500360037003800390040004100420043004400450046004700480049005000510052005300540055005600570058005900600061006200630064006500660067006800690070007100720073007400750076007700780079008000810082008300840085008600870088008900900091009200930094009500960097009800990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050000010002000300040005000600070008000900100011001200130014001500160017001800190020002100220023002400250026002700280029003000310032003300340035003600370038003900400041004200430044004500460047004800490050005100520053005400550056005700580059006000610062006300640065006600670068006900700071007200730074007500760077007800790080008100820083008400850086008700880089009000910092009300940095009600970098009901000101010201030104010501060107010801090110011101120113011401150116011701180119012001210122012301240125012601270128012901300131013201330134013501360137013801390140014101420143014401450146014701480149015001510152015301540155015601570158015901600161016201630164016501660167016801690170017101720173017401750176017701780179018001810182018301840185018601870188018901900191019201930194019501960197019801990200020102020203020402050206020702080209021002110212021302140215021602170218021902200221022202230224022502260227022802290230023102320233023402350236023702380239024002410242024302440245024602470248024902500251025202530254025502560257025802590260026102620263026402650266026702680269027002710272027302740275027602770278027902800281028202830284028502860287028802890290029102920293029402950296029702980299030003010302030303040305030603070308030903100311031203130314031503160317031803190320032103220323032403250326032703280329033003310332033303340335033603370338033903400341034203430344034503460347034803490350035103520353035403550356035703580359036003610362036303640365036603670368036903700371037203730374037503760377037803790380038103820383038403850386038703880389039003910392039303940395039603970398039904000401040204030404040504060407040804090410041104120413041404150416041704180419042004210422042304240425042604270428042904300431043204330434043504360437043804390440044104420443044404450446044704480449045004510452045304540455045604570458045904600461046204630464046504660467046804690470047104720473047404750476047704780479048004810482048304840485048604870488048904900491049204930494049504960497049804990500"},{"name":"rand2","type":"double precision","value":3002}]} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"xpto","columns":[{"name":"id","type":"integer","value":1},{"name":"toasted_col1","type":"text","value":"12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000"},{"name":"rand1","type":"double precision","value":11},{"name":"rand2","type":"double precision","value":1008}],"identity":[{"name":"id","type":"integer","value":1}]} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"xpto","columns":[{"name":"id","type":"integer","value":1},{"name":"rand1","type":"double precision","value":123.456},{"name":"rand2","type":"double precision","value":1008}],"identity":[{"name":"id","type":"integer","value":1}]} + {"action":"C"} + {"action":"B"} + {"action":"D","schema":"public","table":"xpto","identity":[{"name":"id","type":"integer","value":1}]} + {"action":"C"} +(15 rows) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + diff --git a/src/postgres/third-party-extensions/wal2json/expected/truncate.out b/src/postgres/third-party-extensions/wal2json/expected/truncate.out new file mode 100644 index 000000000000..4d8b965971d5 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/truncate.out @@ -0,0 +1,113 @@ +-- predictability +SET synchronous_commit = on; +SET extra_float_digits = 0; +CREATE TABLE table_truncate_1 (a integer, b text); +CREATE TABLE table_truncate_2 (a integer, b text); +CREATE TABLE table_truncate_3 (a integer, b text); +CREATE TABLE table_truncate_4 (a integer, b text); +CREATE TABLE table_truncate_5 (a integer, b text); +CREATE TABLE table_truncate_6 (a integer, b text); +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +TRUNCATE table_truncate_1; +BEGIN; +TRUNCATE table_truncate_2; +INSERT INTO table_truncate_1 (a, b) VALUES(1, 'test1'); +INSERT INTO table_truncate_3 (a, b) VALUES(2, 'test2'); +TRUNCATE table_truncate_3; +INSERT INTO table_truncate_3 (a, b) VALUES(3, 'test3'); +COMMIT; +BEGIN; +TRUNCATE table_truncate_4; +ROLLBACK; +BEGIN; +TRUNCATE table_truncate_5, table_truncate_6; +COMMIT; +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1'); + data +------------------------------------------------------------- + { + + "change": [ + + ] + + } + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "table_truncate_1", + + "columnnames": ["a", "b"], + + "columntypes": ["integer", "text"],+ + "columnvalues": [1, "test1"] + + } + + ,{ + + "kind": "insert", + + "schema": "public", + + "table": "table_truncate_3", + + "columnnames": ["a", "b"], + + "columntypes": ["integer", "text"],+ + "columnvalues": [2, "test2"] + + } + + ,{ + + "kind": "insert", + + "schema": "public", + + "table": "table_truncate_3", + + "columnnames": ["a", "b"], + + "columntypes": ["integer", "text"],+ + "columnvalues": [3, "test3"] + + } + + ] + + } + { + + "change": [ + + ] + + } +(3 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); + data +------------------------------------------------------------------------------------------------------------------------------------------------------------ + {"action":"B"} + {"action":"T","schema":"public","table":"table_truncate_1"} + {"action":"C"} + {"action":"B"} + {"action":"T","schema":"public","table":"table_truncate_2"} + {"action":"I","schema":"public","table":"table_truncate_1","columns":[{"name":"a","type":"integer","value":1},{"name":"b","type":"text","value":"test1"}]} + {"action":"I","schema":"public","table":"table_truncate_3","columns":[{"name":"a","type":"integer","value":2},{"name":"b","type":"text","value":"test2"}]} + {"action":"T","schema":"public","table":"table_truncate_3"} + {"action":"I","schema":"public","table":"table_truncate_3","columns":[{"name":"a","type":"integer","value":3},{"name":"b","type":"text","value":"test3"}]} + {"action":"C"} + {"action":"B"} + {"action":"T","schema":"public","table":"table_truncate_5"} + {"action":"T","schema":"public","table":"table_truncate_6"} + {"action":"C"} +(14 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'filter-tables', '*.table_truncate_5'); + data +------------------------------------------------------------------------------------------------------------------------------------------------------------ + {"action":"B"} + {"action":"T","schema":"public","table":"table_truncate_1"} + {"action":"C"} + {"action":"B"} + {"action":"T","schema":"public","table":"table_truncate_2"} + {"action":"I","schema":"public","table":"table_truncate_1","columns":[{"name":"a","type":"integer","value":1},{"name":"b","type":"text","value":"test1"}]} + {"action":"I","schema":"public","table":"table_truncate_3","columns":[{"name":"a","type":"integer","value":2},{"name":"b","type":"text","value":"test2"}]} + {"action":"T","schema":"public","table":"table_truncate_3"} + {"action":"I","schema":"public","table":"table_truncate_3","columns":[{"name":"a","type":"integer","value":3},{"name":"b","type":"text","value":"test3"}]} + {"action":"C"} + {"action":"B"} + {"action":"T","schema":"public","table":"table_truncate_6"} + {"action":"C"} +(13 rows) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + diff --git a/src/postgres/third-party-extensions/wal2json/expected/type_oid.out b/src/postgres/third-party-extensions/wal2json/expected/type_oid.out new file mode 100644 index 000000000000..e49343f1f61f --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/type_oid.out @@ -0,0 +1,68 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +DROP TABLE IF EXISTS w2j_type_oid; +NOTICE: table "w2j_type_oid" does not exist, skipping +CREATE TABLE w2j_type_oid (a integer, b boolean, primary key(a)); +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +INSERT INTO w2j_type_oid (a, b) VALUES(1, true); +UPDATE w2j_type_oid SET a = 3; +DELETE FROM w2j_type_oid WHERE a = 3; +-- without include-type-oids parameter +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1'); + data +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"change":[{"kind":"insert","schema":"public","table":"w2j_type_oid","columnnames":["a","b"],"columntypes":["integer","boolean"],"columnvalues":[1,true]}]} + {"change":[{"kind":"update","schema":"public","table":"w2j_type_oid","columnnames":["a","b"],"columntypes":["integer","boolean"],"columnvalues":[3,true],"oldkeys":{"keynames":["a"],"keytypes":["integer"],"keyvalues":[1]}}]} + {"change":[{"kind":"delete","schema":"public","table":"w2j_type_oid","oldkeys":{"keynames":["a"],"keytypes":["integer"],"keyvalues":[3]}}]} +(3 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); + data +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_type_oid","columns":[{"name":"a","type":"integer","value":1},{"name":"b","type":"boolean","value":true}]} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"w2j_type_oid","columns":[{"name":"a","type":"integer","value":3},{"name":"b","type":"boolean","value":true}],"identity":[{"name":"a","type":"integer","value":1}]} + {"action":"C"} + {"action":"B"} + {"action":"D","schema":"public","table":"w2j_type_oid","identity":[{"name":"a","type":"integer","value":3}]} + {"action":"C"} +(9 rows) + +-- with include-type-oids parameter +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-type-oids', '1'); + data +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"change":[{"kind":"insert","schema":"public","table":"w2j_type_oid","columnnames":["a","b"],"columntypes":["integer","boolean"],"columntypeoids":[23,16],"columnvalues":[1,true]}]} + {"change":[{"kind":"update","schema":"public","table":"w2j_type_oid","columnnames":["a","b"],"columntypes":["integer","boolean"],"columntypeoids":[23,16],"columnvalues":[3,true],"oldkeys":{"keynames":["a"],"keytypes":["integer"],"keytypeoids":[23],"keyvalues":[1]}}]} + {"change":[{"kind":"delete","schema":"public","table":"w2j_type_oid","oldkeys":{"keynames":["a"],"keytypes":["integer"],"keytypeoids":[23],"keyvalues":[3]}}]} +(3 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'include-type-oids', '1'); + data +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"action":"B"} + {"action":"I","schema":"public","table":"w2j_type_oid","columns":[{"name":"a","type":"integer","typeoid":23,"value":1},{"name":"b","type":"boolean","typeoid":16,"value":true}]} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"w2j_type_oid","columns":[{"name":"a","type":"integer","typeoid":23,"value":3},{"name":"b","type":"boolean","typeoid":16,"value":true}],"identity":[{"name":"a","type":"integer","typeoid":23,"value":1}]} + {"action":"C"} + {"action":"B"} + {"action":"D","schema":"public","table":"w2j_type_oid","identity":[{"name":"a","type":"integer","typeoid":23,"value":3}]} + {"action":"C"} +(9 rows) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + +DROP TABLE w2j_type_oid; diff --git a/src/postgres/third-party-extensions/wal2json/expected/typmod.out b/src/postgres/third-party-extensions/wal2json/expected/typmod.out new file mode 100644 index 000000000000..59aa910ac863 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/typmod.out @@ -0,0 +1,136 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +SET extra_float_digits = 0; +DROP TABLE IF EXISTS table_with_pk; +CREATE TABLE table_with_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +PRIMARY KEY(b, c, d) +); +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +INSERT INTO table_with_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +UPDATE table_with_pk SET f = -f WHERE b = 1; +-- UPDATE: pk change +DELETE FROM table_with_pk WHERE b = 1; +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1'); + data +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "table_with_pk", + + "columnnames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "columntypes": ["smallint", "smallint", "integer", "bigint", "numeric(5,3)", "real", "double precision", "character(10)", "character varying(30)", "text", "bit varying(20)", "timestamp without time zone", "date", "boolean", "json", "tsvector"],+ + "columnvalues": [1, 1, 2, 3, 3.540, 876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"] + + } + + ] + + } + { + + "change": [ + + { + + "kind": "update", + + "schema": "public", + + "table": "table_with_pk", + + "columnnames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "columntypes": ["smallint", "smallint", "integer", "bigint", "numeric(5,3)", "real", "double precision", "character(10)", "character varying(30)", "text", "bit varying(20)", "timestamp without time zone", "date", "boolean", "json", "tsvector"],+ + "columnvalues": [1, 1, 2, 3, 3.540, -876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"], + + "oldkeys": { + + "keynames": ["b", "c", "d"], + + "keytypes": ["smallint", "integer", "bigint"], + + "keyvalues": [1, 2, 3] + + } + + } + + ] + + } + { + + "change": [ + + { + + "kind": "delete", + + "schema": "public", + + "table": "table_with_pk", + + "oldkeys": { + + "keynames": ["b", "c", "d"], + + "keytypes": ["smallint", "integer", "bigint"], + + "keyvalues": [1, 2, 3] + + } + + } + + ] + + } +(3 rows) + +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0'); + data +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + { + + "change": [ + + { + + "kind": "insert", + + "schema": "public", + + "table": "table_with_pk", + + "columnnames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "columntypes": ["int2", "int2", "int4", "int8", "numeric", "float4", "float8", "bpchar", "varchar", "text", "varbit", "timestamp", "date", "bool", "json", "tsvector"], + + "columnvalues": [1, 1, 2, 3, 3.540, 876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"] + + } + + ] + + } + { + + "change": [ + + { + + "kind": "update", + + "schema": "public", + + "table": "table_with_pk", + + "columnnames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "columntypes": ["int2", "int2", "int4", "int8", "numeric", "float4", "float8", "bpchar", "varchar", "text", "varbit", "timestamp", "date", "bool", "json", "tsvector"], + + "columnvalues": [1, 1, 2, 3, 3.540, -876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"],+ + "oldkeys": { + + "keynames": ["b", "c", "d"], + + "keytypes": ["int2", "int4", "int8"], + + "keyvalues": [1, 2, 3] + + } + + } + + ] + + } + { + + "change": [ + + { + + "kind": "delete", + + "schema": "public", + + "table": "table_with_pk", + + "oldkeys": { + + "keynames": ["b", "c", "d"], + + "keytypes": ["int2", "int4", "int8"], + + "keyvalues": [1, 2, 3] + + } + + } + + ] + + } +(3 rows) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + diff --git a/src/postgres/third-party-extensions/wal2json/expected/update1.out b/src/postgres/third-party-extensions/wal2json/expected/update1.out new file mode 100644 index 000000000000..a5acb255b2dd --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/update1.out @@ -0,0 +1,153 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +SET extra_float_digits = 0; +DROP TABLE IF EXISTS table_with_pk; +DROP TABLE IF EXISTS table_without_pk; +DROP TABLE IF EXISTS table_with_unique; +CREATE TABLE table_with_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +PRIMARY KEY(b, c, d) +); +CREATE TABLE table_without_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector +); +CREATE TABLE table_with_unique ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3) not null, +f real not null, +g double precision not null, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +UNIQUE(g, n) +); +-- INSERT +INSERT INTO table_with_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_without_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_with_unique (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +-- UPDATE: no pk +UPDATE table_without_pk SET f = -f WHERE b = 1; +-- UPDATE: no pk change +UPDATE table_with_pk SET f = -f WHERE b = 1; +-- UPDATE: pk change +UPDATE table_with_pk SET b = -b WHERE b = 1; +-- UPDATE: unique +UPDATE table_with_unique SET n = false WHERE b = 1; +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0'); +WARNING: table "table_without_pk" without primary key or replica identity is nothing +WARNING: table "table_with_unique" without primary key or replica identity is nothing + data +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + { + + "change": [ + + ] + + } + { + + "change": [ + + { + + "kind": "update", + + "schema": "public", + + "table": "table_with_pk", + + "columnnames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "columntypes": ["int2", "int2", "int4", "int8", "numeric", "float4", "float8", "bpchar", "varchar", "text", "varbit", "timestamp", "date", "bool", "json", "tsvector"], + + "columnvalues": [1, 1, 2, 3, 3.540, -876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"], + + "oldkeys": { + + "keynames": ["b", "c", "d"], + + "keytypes": ["int2", "int4", "int8"], + + "keyvalues": [1, 2, 3] + + } + + } + + ] + + } + { + + "change": [ + + { + + "kind": "update", + + "schema": "public", + + "table": "table_with_pk", + + "columnnames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "columntypes": ["int2", "int2", "int4", "int8", "numeric", "float4", "float8", "bpchar", "varchar", "text", "varbit", "timestamp", "date", "bool", "json", "tsvector"], + + "columnvalues": [1, -1, 2, 3, 3.540, -876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"],+ + "oldkeys": { + + "keynames": ["b", "c", "d"], + + "keytypes": ["int2", "int4", "int8"], + + "keyvalues": [1, 2, 3] + + } + + } + + ] + + } + { + + "change": [ + + ] + + } +(4 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); +WARNING: no tuple identifier for UPDATE in table "public"."table_without_pk" +WARNING: no tuple identifier for UPDATE in table "public"."table_with_unique" + data +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"table_with_pk","columns":[{"name":"a","type":"smallint","value":1},{"name":"b","type":"smallint","value":1},{"name":"c","type":"integer","value":2},{"name":"d","type":"bigint","value":3},{"name":"e","type":"numeric(5,3)","value":3.540},{"name":"f","type":"real","value":-876.563},{"name":"g","type":"double precision","value":1.23},{"name":"h","type":"character(10)","value":"teste "},{"name":"i","type":"character varying(30)","value":"testando"},{"name":"j","type":"text","value":"um texto longo"},{"name":"k","type":"bit varying(20)","value":"001110010101010"},{"name":"l","type":"timestamp without time zone","value":"Sat Nov 02 17:30:52 2013"},{"name":"m","type":"date","value":"02-04-2013"},{"name":"n","type":"boolean","value":true},{"name":"o","type":"json","value":"{ \"a\": 123 }"},{"name":"p","type":"tsvector","value":"'Old' 'Parr'"}],"identity":[{"name":"b","type":"smallint","value":1},{"name":"c","type":"integer","value":2},{"name":"d","type":"bigint","value":3}]} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"table_with_pk","columns":[{"name":"a","type":"smallint","value":1},{"name":"b","type":"smallint","value":-1},{"name":"c","type":"integer","value":2},{"name":"d","type":"bigint","value":3},{"name":"e","type":"numeric(5,3)","value":3.540},{"name":"f","type":"real","value":-876.563},{"name":"g","type":"double precision","value":1.23},{"name":"h","type":"character(10)","value":"teste "},{"name":"i","type":"character varying(30)","value":"testando"},{"name":"j","type":"text","value":"um texto longo"},{"name":"k","type":"bit varying(20)","value":"001110010101010"},{"name":"l","type":"timestamp without time zone","value":"Sat Nov 02 17:30:52 2013"},{"name":"m","type":"date","value":"02-04-2013"},{"name":"n","type":"boolean","value":true},{"name":"o","type":"json","value":"{ \"a\": 123 }"},{"name":"p","type":"tsvector","value":"'Old' 'Parr'"}],"identity":[{"name":"b","type":"smallint","value":1},{"name":"c","type":"integer","value":2},{"name":"d","type":"bigint","value":3}]} + {"action":"C"} + {"action":"B"} + {"action":"C"} +(10 rows) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + diff --git a/src/postgres/third-party-extensions/wal2json/expected/update2.out b/src/postgres/third-party-extensions/wal2json/expected/update2.out new file mode 100644 index 000000000000..2bcf5fd6e265 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/update2.out @@ -0,0 +1,158 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +DROP TABLE IF EXISTS table_with_pk; +DROP TABLE IF EXISTS table_without_pk; +DROP TABLE IF EXISTS table_with_unique; +CREATE TABLE table_with_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +PRIMARY KEY(b, c, d) +); +CREATE TABLE table_without_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector +); +CREATE TABLE table_with_unique ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3) not null, +f real not null, +g double precision not null, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +UNIQUE(g, n) +); +-- INSERT +INSERT INTO table_with_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_without_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_with_unique (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +-- UPDATE: REPLICA IDENTITY NOTHING +ALTER TABLE table_with_pk REPLICA IDENTITY NOTHING; +UPDATE table_with_pk SET f = -f WHERE b = 1; +ALTER TABLE table_with_pk REPLICA IDENTITY DEFAULT; +ALTER TABLE table_without_pk REPLICA IDENTITY NOTHING; +UPDATE table_without_pk SET f = -f WHERE b = 1; +ALTER TABLE table_without_pk REPLICA IDENTITY DEFAULT; +ALTER TABLE table_with_unique REPLICA IDENTITY NOTHING; +UPDATE table_with_unique SET f = -f WHERE b = 1; +ALTER TABLE table_with_unique REPLICA IDENTITY DEFAULT; +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0'); +WARNING: table "table_with_pk" without primary key or replica identity is nothing +WARNING: table "table_without_pk" without primary key or replica identity is nothing +WARNING: table "table_with_unique" without primary key or replica identity is nothing + data +--------------------- + { + + "change": [+ + ] + + } + { + + "change": [+ + ] + + } + { + + "change": [+ + ] + + } + { + + "change": [+ + ] + + } + { + + "change": [+ + ] + + } + { + + "change": [+ + ] + + } + { + + "change": [+ + ] + + } + { + + "change": [+ + ] + + } + { + + "change": [+ + ] + + } +(9 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); +WARNING: no tuple identifier for UPDATE in table "public"."table_with_pk" +WARNING: no tuple identifier for UPDATE in table "public"."table_without_pk" +WARNING: no tuple identifier for UPDATE in table "public"."table_with_unique" + data +---------------- + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} +(18 rows) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + diff --git a/src/postgres/third-party-extensions/wal2json/expected/update3.out b/src/postgres/third-party-extensions/wal2json/expected/update3.out new file mode 100644 index 000000000000..463a4ac137ea --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/update3.out @@ -0,0 +1,195 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +SET extra_float_digits = 0; +DROP TABLE IF EXISTS table_with_pk; +DROP TABLE IF EXISTS table_without_pk; +DROP TABLE IF EXISTS table_with_unique; +CREATE TABLE table_with_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +PRIMARY KEY(b, c, d) +); +CREATE TABLE table_without_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector +); +CREATE TABLE table_with_unique ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3) not null, +f real not null, +g double precision not null, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +UNIQUE(g, n) +); +-- INSERT +INSERT INTO table_with_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_without_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_with_unique (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +-- UPDATE: REPLICA IDENTITY FULL +ALTER TABLE table_with_pk REPLICA IDENTITY FULL; +UPDATE table_with_pk SET f = -f WHERE b = 1; +ALTER TABLE table_with_pk REPLICA IDENTITY DEFAULT; +ALTER TABLE table_without_pk REPLICA IDENTITY FULL; +UPDATE table_without_pk SET f = -f WHERE b = 1; +ALTER TABLE table_without_pk REPLICA IDENTITY DEFAULT; +ALTER TABLE table_with_unique REPLICA IDENTITY FULL; +UPDATE table_with_unique SET f = -f WHERE b = 1; +ALTER TABLE table_with_unique REPLICA IDENTITY DEFAULT; +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0'); + data +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + { + + "change": [ + + ] + + } + { + + "change": [ + + { + + "kind": "update", + + "schema": "public", + + "table": "table_with_pk", + + "columnnames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "columntypes": ["int2", "int2", "int4", "int8", "numeric", "float4", "float8", "bpchar", "varchar", "text", "varbit", "timestamp", "date", "bool", "json", "tsvector"], + + "columnvalues": [1, 1, 2, 3, 3.540, -876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"], + + "oldkeys": { + + "keynames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "keytypes": ["int2", "int2", "int4", "int8", "numeric", "float4", "float8", "bpchar", "varchar", "text", "varbit", "timestamp", "date", "bool", "json", "tsvector"], + + "keyvalues": [1, 1, 2, 3, 3.540, 876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"]+ + } + + } + + ] + + } + { + + "change": [ + + ] + + } + { + + "change": [ + + ] + + } + { + + "change": [ + + { + + "kind": "update", + + "schema": "public", + + "table": "table_without_pk", + + "columnnames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "columntypes": ["int2", "int2", "int4", "int8", "numeric", "float4", "float8", "bpchar", "varchar", "text", "varbit", "timestamp", "date", "bool", "json", "tsvector"], + + "columnvalues": [1, 1, 2, 3, 3.540, -876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"], + + "oldkeys": { + + "keynames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "keytypes": ["int2", "int2", "int4", "int8", "numeric", "float4", "float8", "bpchar", "varchar", "text", "varbit", "timestamp", "date", "bool", "json", "tsvector"], + + "keyvalues": [1, 1, 2, 3, 3.540, 876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"]+ + } + + } + + ] + + } + { + + "change": [ + + ] + + } + { + + "change": [ + + ] + + } + { + + "change": [ + + { + + "kind": "update", + + "schema": "public", + + "table": "table_with_unique", + + "columnnames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "columntypes": ["int2", "int2", "int4", "int8", "numeric", "float4", "float8", "bpchar", "varchar", "text", "varbit", "timestamp", "date", "bool", "json", "tsvector"], + + "columnvalues": [1, 1, 2, 3, 3.540, -876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"], + + "oldkeys": { + + "keynames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "keytypes": ["int2", "int2", "int4", "int8", "numeric", "float4", "float8", "bpchar", "varchar", "text", "varbit", "timestamp", "date", "bool", "json", "tsvector"], + + "keyvalues": [1, 1, 2, 3, 3.540, 876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"]+ + } + + } + + ] + + } + { + + "change": [ + + ] + + } +(9 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); + data +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"table_with_pk","columns":[{"name":"a","type":"smallint","value":1},{"name":"b","type":"smallint","value":1},{"name":"c","type":"integer","value":2},{"name":"d","type":"bigint","value":3},{"name":"e","type":"numeric(5,3)","value":3.540},{"name":"f","type":"real","value":-876.563},{"name":"g","type":"double precision","value":1.23},{"name":"h","type":"character(10)","value":"teste "},{"name":"i","type":"character varying(30)","value":"testando"},{"name":"j","type":"text","value":"um texto longo"},{"name":"k","type":"bit varying(20)","value":"001110010101010"},{"name":"l","type":"timestamp without time zone","value":"Sat Nov 02 17:30:52 2013"},{"name":"m","type":"date","value":"02-04-2013"},{"name":"n","type":"boolean","value":true},{"name":"o","type":"json","value":"{ \"a\": 123 }"},{"name":"p","type":"tsvector","value":"'Old' 'Parr'"}],"identity":[{"name":"a","type":"smallint","value":1},{"name":"b","type":"smallint","value":1},{"name":"c","type":"integer","value":2},{"name":"d","type":"bigint","value":3},{"name":"e","type":"numeric(5,3)","value":3.540},{"name":"f","type":"real","value":876.563},{"name":"g","type":"double precision","value":1.23},{"name":"h","type":"character(10)","value":"teste "},{"name":"i","type":"character varying(30)","value":"testando"},{"name":"j","type":"text","value":"um texto longo"},{"name":"k","type":"bit varying(20)","value":"001110010101010"},{"name":"l","type":"timestamp without time zone","value":"Sat Nov 02 17:30:52 2013"},{"name":"m","type":"date","value":"02-04-2013"},{"name":"n","type":"boolean","value":true},{"name":"o","type":"json","value":"{ \"a\": 123 }"},{"name":"p","type":"tsvector","value":"'Old' 'Parr'"}]} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"table_without_pk","columns":[{"name":"a","type":"smallint","value":1},{"name":"b","type":"smallint","value":1},{"name":"c","type":"integer","value":2},{"name":"d","type":"bigint","value":3},{"name":"e","type":"numeric(5,3)","value":3.540},{"name":"f","type":"real","value":-876.563},{"name":"g","type":"double precision","value":1.23},{"name":"h","type":"character(10)","value":"teste "},{"name":"i","type":"character varying(30)","value":"testando"},{"name":"j","type":"text","value":"um texto longo"},{"name":"k","type":"bit varying(20)","value":"001110010101010"},{"name":"l","type":"timestamp without time zone","value":"Sat Nov 02 17:30:52 2013"},{"name":"m","type":"date","value":"02-04-2013"},{"name":"n","type":"boolean","value":true},{"name":"o","type":"json","value":"{ \"a\": 123 }"},{"name":"p","type":"tsvector","value":"'Old' 'Parr'"}],"identity":[{"name":"a","type":"smallint","value":1},{"name":"b","type":"smallint","value":1},{"name":"c","type":"integer","value":2},{"name":"d","type":"bigint","value":3},{"name":"e","type":"numeric(5,3)","value":3.540},{"name":"f","type":"real","value":876.563},{"name":"g","type":"double precision","value":1.23},{"name":"h","type":"character(10)","value":"teste "},{"name":"i","type":"character varying(30)","value":"testando"},{"name":"j","type":"text","value":"um texto longo"},{"name":"k","type":"bit varying(20)","value":"001110010101010"},{"name":"l","type":"timestamp without time zone","value":"Sat Nov 02 17:30:52 2013"},{"name":"m","type":"date","value":"02-04-2013"},{"name":"n","type":"boolean","value":true},{"name":"o","type":"json","value":"{ \"a\": 123 }"},{"name":"p","type":"tsvector","value":"'Old' 'Parr'"}]} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"table_with_unique","columns":[{"name":"a","type":"smallint","value":1},{"name":"b","type":"smallint","value":1},{"name":"c","type":"integer","value":2},{"name":"d","type":"bigint","value":3},{"name":"e","type":"numeric(5,3)","value":3.540},{"name":"f","type":"real","value":-876.563},{"name":"g","type":"double precision","value":1.23},{"name":"h","type":"character(10)","value":"teste "},{"name":"i","type":"character varying(30)","value":"testando"},{"name":"j","type":"text","value":"um texto longo"},{"name":"k","type":"bit varying(20)","value":"001110010101010"},{"name":"l","type":"timestamp without time zone","value":"Sat Nov 02 17:30:52 2013"},{"name":"m","type":"date","value":"02-04-2013"},{"name":"n","type":"boolean","value":true},{"name":"o","type":"json","value":"{ \"a\": 123 }"},{"name":"p","type":"tsvector","value":"'Old' 'Parr'"}],"identity":[{"name":"a","type":"smallint","value":1},{"name":"b","type":"smallint","value":1},{"name":"c","type":"integer","value":2},{"name":"d","type":"bigint","value":3},{"name":"e","type":"numeric(5,3)","value":3.540},{"name":"f","type":"real","value":876.563},{"name":"g","type":"double precision","value":1.23},{"name":"h","type":"character(10)","value":"teste "},{"name":"i","type":"character varying(30)","value":"testando"},{"name":"j","type":"text","value":"um texto longo"},{"name":"k","type":"bit varying(20)","value":"001110010101010"},{"name":"l","type":"timestamp without time zone","value":"Sat Nov 02 17:30:52 2013"},{"name":"m","type":"date","value":"02-04-2013"},{"name":"n","type":"boolean","value":true},{"name":"o","type":"json","value":"{ \"a\": 123 }"},{"name":"p","type":"tsvector","value":"'Old' 'Parr'"}]} + {"action":"C"} + {"action":"B"} + {"action":"C"} +(21 rows) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + diff --git a/src/postgres/third-party-extensions/wal2json/expected/update4.out b/src/postgres/third-party-extensions/wal2json/expected/update4.out new file mode 100644 index 000000000000..c9a4353568d6 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/expected/update4.out @@ -0,0 +1,107 @@ +\set VERBOSITY terse +-- predictability +SET synchronous_commit = on; +SET extra_float_digits = 0; +DROP TABLE IF EXISTS table_with_unique; +CREATE TABLE table_with_unique ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3) not null, +f real not null, +g double precision not null, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +UNIQUE(g, n) +); +-- INSERT +INSERT INTO table_with_unique (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', false, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_with_unique (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(4, 5, 6, 3.54, 876.563452345, 4.56, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + ?column? +---------- + init +(1 row) + +-- UPDATE: REPLICA IDENTITY USING INDEX +ALTER TABLE table_with_unique REPLICA IDENTITY USING INDEX table_with_unique_g_n_key; +-- FIXME não apresenta valor correto de g +UPDATE table_with_unique SET c = -c WHERE b = 1; +UPDATE table_with_unique SET g = -g WHERE n = true; +ALTER TABLE table_with_unique REPLICA IDENTITY DEFAULT; +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0'); + data +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + { + + "change": [ + + ] + + } + { + + "change": [ + + { + + "kind": "update", + + "schema": "public", + + "table": "table_with_unique", + + "columnnames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "columntypes": ["int2", "int2", "int4", "int8", "numeric", "float4", "float8", "bpchar", "varchar", "text", "varbit", "timestamp", "date", "bool", "json", "tsvector"], + + "columnvalues": [1, 1, -2, 3, 3.540, 876.563, 1.23, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", false, "{ \"a\": 123 }", "'Old' 'Parr'"],+ + "oldkeys": { + + "keynames": ["g", "n"], + + "keytypes": ["float8", "bool"], + + "keyvalues": [1.23, false] + + } + + } + + ] + + } + { + + "change": [ + + { + + "kind": "update", + + "schema": "public", + + "table": "table_with_unique", + + "columnnames": ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"], + + "columntypes": ["int2", "int2", "int4", "int8", "numeric", "float4", "float8", "bpchar", "varchar", "text", "varbit", "timestamp", "date", "bool", "json", "tsvector"], + + "columnvalues": [2, 4, 5, 6, 3.540, 876.563, -4.56, "teste ", "testando", "um texto longo", "001110010101010", "Sat Nov 02 17:30:52 2013", "02-04-2013", true, "{ \"a\": 123 }", "'Old' 'Parr'"], + + "oldkeys": { + + "keynames": ["g", "n"], + + "keytypes": ["float8", "bool"], + + "keyvalues": [4.56, true] + + } + + } + + ] + + } + { + + "change": [ + + ] + + } +(4 rows) + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); + data +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + {"action":"B"} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"table_with_unique","columns":[{"name":"a","type":"smallint","value":1},{"name":"b","type":"smallint","value":1},{"name":"c","type":"integer","value":-2},{"name":"d","type":"bigint","value":3},{"name":"e","type":"numeric(5,3)","value":3.540},{"name":"f","type":"real","value":876.563},{"name":"g","type":"double precision","value":1.23},{"name":"h","type":"character(10)","value":"teste "},{"name":"i","type":"character varying(30)","value":"testando"},{"name":"j","type":"text","value":"um texto longo"},{"name":"k","type":"bit varying(20)","value":"001110010101010"},{"name":"l","type":"timestamp without time zone","value":"Sat Nov 02 17:30:52 2013"},{"name":"m","type":"date","value":"02-04-2013"},{"name":"n","type":"boolean","value":false},{"name":"o","type":"json","value":"{ \"a\": 123 }"},{"name":"p","type":"tsvector","value":"'Old' 'Parr'"}],"identity":[{"name":"g","type":"double precision","value":1.23},{"name":"n","type":"boolean","value":false}]} + {"action":"C"} + {"action":"B"} + {"action":"U","schema":"public","table":"table_with_unique","columns":[{"name":"a","type":"smallint","value":2},{"name":"b","type":"smallint","value":4},{"name":"c","type":"integer","value":5},{"name":"d","type":"bigint","value":6},{"name":"e","type":"numeric(5,3)","value":3.540},{"name":"f","type":"real","value":876.563},{"name":"g","type":"double precision","value":-4.56},{"name":"h","type":"character(10)","value":"teste "},{"name":"i","type":"character varying(30)","value":"testando"},{"name":"j","type":"text","value":"um texto longo"},{"name":"k","type":"bit varying(20)","value":"001110010101010"},{"name":"l","type":"timestamp without time zone","value":"Sat Nov 02 17:30:52 2013"},{"name":"m","type":"date","value":"02-04-2013"},{"name":"n","type":"boolean","value":true},{"name":"o","type":"json","value":"{ \"a\": 123 }"},{"name":"p","type":"tsvector","value":"'Old' 'Parr'"}],"identity":[{"name":"g","type":"double precision","value":4.56},{"name":"n","type":"boolean","value":true}]} + {"action":"C"} + {"action":"B"} + {"action":"C"} +(10 rows) + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + ?column? +---------- + stop +(1 row) + diff --git a/src/postgres/third-party-extensions/wal2json/sql/actions.sql b/src/postgres/third-party-extensions/wal2json/sql/actions.sql new file mode 100644 index 000000000000..86745e8d682c --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/actions.sql @@ -0,0 +1,23 @@ +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +-- actions +CREATE TABLE actions (a integer primary key); +INSERT INTO actions (a) VALUES(1); +UPDATE actions SET a = 2 WHERE a = 1; +DELETE FROM actions WHERE a = 2; +TRUNCATE TABLE actions; +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'actions', 'insert, foo, delete'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'actions', 'insert'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'actions', 'update'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'actions', 'delete'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'actions', 'truncate'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'actions', 'update, truncate'); + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/src/postgres/third-party-extensions/wal2json/sql/bytea.sql b/src/postgres/third-party-extensions/wal2json/sql/bytea.sql new file mode 100644 index 000000000000..0be9485185be --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/bytea.sql @@ -0,0 +1,25 @@ +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; +SET extra_float_digits = 0; + +DROP TABLE IF EXISTS xpto; +DROP SEQUENCE IF EXISTS xpto_rand_seq; + +CREATE SEQUENCE xpto_rand_seq START 11 INCREMENT 997; +CREATE TABLE xpto ( +id serial primary key, +rand1 float8 DEFAULT nextval('xpto_rand_seq'), +bincol bytea +); + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +INSERT INTO xpto (bincol) SELECT decode(string_agg(to_char(round(g.i * 0.08122019), 'FM0000'), ''), 'hex') FROM generate_series(500, 5000) g(i); +UPDATE xpto SET rand1 = 123.456 WHERE id = 1; +DELETE FROM xpto WHERE id = 1; + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/src/postgres/third-party-extensions/wal2json/sql/cmdline.sql b/src/postgres/third-party-extensions/wal2json/sql/cmdline.sql new file mode 100644 index 000000000000..7cc4ace134f1 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/cmdline.sql @@ -0,0 +1,42 @@ +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'nosuchopt', '42'); + +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-unchanged-toast', '1'); + +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'filter-origins', '16, 27, 123'); + +-- don't include not-null constraint by default +CREATE TABLE table_optional ( +a smallserial, +b integer, +c boolean not null, +PRIMARY KEY(a) +); +INSERT INTO table_optional (b, c) VALUES(NULL, TRUE); +UPDATE table_optional SET b = 123 WHERE a = 1; +DELETE FROM table_optional WHERE a = 1; +DROP TABLE table_optional; +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-xids', '0', 'include-not-null', '1'); + +-- By default don't write in chunks +CREATE TABLE x (); +DROP TABLE x; +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-xids', '0'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-xids', '0', 'write-in-chunks', '1'); + +-- By default don't write xids +CREATE TABLE gimmexid (id integer PRIMARY KEY); +INSERT INTO gimmexid values (1); +DROP TABLE gimmexid; +SELECT max(((data::json) -> 'xid')::text::int) < txid_current() FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'include-xids', '1'); +SELECT max(((data::json) -> 'xid')::text::int) + 10 > txid_current() FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'include-xids', '1'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL) where ((data::json) -> 'xid') IS NOT NULL; + + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/src/postgres/third-party-extensions/wal2json/sql/default.sql b/src/postgres/third-party-extensions/wal2json/sql/default.sql new file mode 100644 index 000000000000..5b8575996bf2 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/default.sql @@ -0,0 +1,30 @@ +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; + +CREATE TABLE w2j_default (a serial, b integer DEFAULT 6, c text DEFAULT 'wal2json', d timestamp DEFAULT '2020-07-12 11:55:30', e integer DEFAULT NULL, f integer, PRIMARY KEY(a)); +CREATE TABLE w2j_truncate (a serial primary key, b text not null); + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +INSERT INTO w2j_default (b, c ,d, e, f) VALUES(2, 'test', '2020-03-01 08:09:00', 80, 10); +INSERT INTO w2j_default DEFAULT VALUES; +UPDATE w2j_default SET b = 3 WHERE a = 1; + +INSERT INTO w2j_truncate (b) VALUES('foo@bar.com'); +TRUNCATE w2j_truncate; +INSERT INTO w2j_truncate (b) VALUES('foo@bar.com'); + +-- without include-default parameter +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); + +-- with include-default parameter +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-default', '1'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'include-default', '1'); + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + +DROP TABLE w2j_default; +DROP TABLE w2j_truncate; diff --git a/src/postgres/third-party-extensions/wal2json/sql/delete1.sql b/src/postgres/third-party-extensions/wal2json/sql/delete1.sql new file mode 100644 index 000000000000..ae1354370afc --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/delete1.sql @@ -0,0 +1,87 @@ +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; + +DROP TABLE IF EXISTS table_with_pk; +DROP TABLE IF EXISTS table_without_pk; +DROP TABLE IF EXISTS table_with_unique; + +CREATE TABLE table_with_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +PRIMARY KEY(b, c, d) +); + +CREATE TABLE table_without_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector +); + +CREATE TABLE table_with_unique ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3) not null, +f real not null, +g double precision not null, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +UNIQUE(g, n) +); + +-- INSERT +INSERT INTO table_with_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_without_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_with_unique (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +-- DELETE: no pk +DELETE FROM table_without_pk WHERE b = 1; + +-- DELETE: pk +DELETE FROM table_with_pk WHERE b = 1; + +-- DELETE: unique +DELETE FROM table_with_unique WHERE b = 1; + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/src/postgres/third-party-extensions/wal2json/sql/delete2.sql b/src/postgres/third-party-extensions/wal2json/sql/delete2.sql new file mode 100644 index 000000000000..00235747602c --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/delete2.sql @@ -0,0 +1,91 @@ +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; + +DROP TABLE IF EXISTS table_with_pk; +DROP TABLE IF EXISTS table_without_pk; +DROP TABLE IF EXISTS table_with_unique; + +CREATE TABLE table_with_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +PRIMARY KEY(b, c, d) +); + +CREATE TABLE table_without_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector +); + +CREATE TABLE table_with_unique ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3) not null, +f real not null, +g double precision not null, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +UNIQUE(g, n) +); + +-- INSERT +INSERT INTO table_with_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_without_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_with_unique (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +-- DELETE: REPLICA IDENTITY NOTHING +ALTER TABLE table_with_pk REPLICA IDENTITY NOTHING; +DELETE FROM table_with_pk WHERE b = 1; +ALTER TABLE table_with_pk REPLICA IDENTITY DEFAULT; + +ALTER TABLE table_without_pk REPLICA IDENTITY NOTHING; +DELETE FROM table_without_pk WHERE b = 1; +ALTER TABLE table_without_pk REPLICA IDENTITY DEFAULT; + +ALTER TABLE table_with_unique REPLICA IDENTITY NOTHING; +DELETE FROM table_with_unique WHERE b = 1; +ALTER TABLE table_with_unique REPLICA IDENTITY DEFAULT; + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/src/postgres/third-party-extensions/wal2json/sql/delete3.sql b/src/postgres/third-party-extensions/wal2json/sql/delete3.sql new file mode 100644 index 000000000000..8c696e46ed65 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/delete3.sql @@ -0,0 +1,94 @@ +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; +SET extra_float_digits = 0; + +DROP TABLE IF EXISTS table_with_pk; +DROP TABLE IF EXISTS table_without_pk; +DROP TABLE IF EXISTS table_with_unique; + +CREATE TABLE table_with_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +PRIMARY KEY(b, c, d) +); + +CREATE TABLE table_without_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector +); + +CREATE TABLE table_with_unique ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3) not null, +f real not null, +g double precision not null, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +UNIQUE(g, n) +); + +-- INSERT +INSERT INTO table_with_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_with_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(4, 5, 6, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_without_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_with_unique (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +-- DELETE: REPLICA IDENTITY FULL +ALTER TABLE table_with_pk REPLICA IDENTITY FULL; +DELETE FROM table_with_pk WHERE b = 1; +DELETE FROM table_with_pk WHERE n = true; +ALTER TABLE table_with_pk REPLICA IDENTITY DEFAULT; + +ALTER TABLE table_without_pk REPLICA IDENTITY FULL; +DELETE FROM table_without_pk WHERE b = 1; +ALTER TABLE table_without_pk REPLICA IDENTITY DEFAULT; + +ALTER TABLE table_with_unique REPLICA IDENTITY FULL; +DELETE FROM table_with_unique WHERE b = 1; +ALTER TABLE table_with_unique REPLICA IDENTITY DEFAULT; + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/src/postgres/third-party-extensions/wal2json/sql/delete4.sql b/src/postgres/third-party-extensions/wal2json/sql/delete4.sql new file mode 100644 index 000000000000..20eebee3aef4 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/delete4.sql @@ -0,0 +1,42 @@ +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; + +DROP TABLE IF EXISTS table_with_unique; + +CREATE TABLE table_with_unique ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3) not null, +f real not null, +g double precision not null, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +UNIQUE(g, n) +); + +-- INSERT +INSERT INTO table_with_unique (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', false, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_with_unique (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(4, 5, 6, 3.54, 876.563452345, 4.56, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +-- DELETE: REPLICA IDENTITY INDEX +ALTER TABLE table_with_unique REPLICA IDENTITY USING INDEX table_with_unique_g_n_key; +DELETE FROM table_with_unique WHERE b = 1; +DELETE FROM table_with_unique WHERE n = true; +ALTER TABLE table_with_unique REPLICA IDENTITY DEFAULT; + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/src/postgres/third-party-extensions/wal2json/sql/filtertable.sql b/src/postgres/third-party-extensions/wal2json/sql/filtertable.sql new file mode 100644 index 000000000000..9ebd9bf529d4 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/filtertable.sql @@ -0,0 +1,65 @@ +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; + +DROP TABLE IF EXISTS filter_table_1; +DROP TABLE IF EXISTS filter_table_2; +DROP TABLE IF EXISTS filter_table_3; +DROP TABLE IF EXISTS filter_table_4; +DROP TABLE IF EXISTS "Filter_table_5"; +DROP TABLE IF EXISTS "filter table_6"; +DROP TABLE IF EXISTS "filter.table_7"; +DROP TABLE IF EXISTS "filter,table_8"; +DROP TABLE IF EXISTS "filter""table_9"; +DROP TABLE IF EXISTS " filter_table_10"; +DROP TABLE IF EXISTS "*"; +DROP SCHEMA IF EXISTS filter_schema_1 CASCADE; +DROP SCHEMA IF EXISTS filter_schema_2 CASCADE; +DROP SCHEMA IF EXISTS "*" CASCADE; + +CREATE SCHEMA filter_schema_1; +CREATE SCHEMA filter_schema_2; +CREATE SCHEMA "*"; + +CREATE TABLE filter_table_1 (a integer, b text, primary key(a)); +CREATE TABLE filter_schema_1.filter_table_1 (a integer, b text, primary key(a)); +CREATE TABLE filter_schema_1.filter_table_2 (a integer, b text, primary key(a)); +CREATE TABLE filter_schema_2.filter_table_1 (a integer, b text, primary key(a)); +CREATE TABLE filter_schema_2.filter_table_2 (a integer, b text, primary key(a)); +CREATE TABLE filter_schema_2.filter_table_3 (a integer, b text, primary key(a)); +CREATE TABLE filter_table_2 (a integer, b text, primary key(a)); +CREATE TABLE filter_table_3 (a integer, b text, primary key(a)); +CREATE TABLE filter_table_4 (a integer, b text, primary key(a)); +CREATE TABLE "Filter_table_5" (a integer, b text, primary key(a)); +CREATE TABLE "filter table_6" (a integer, b text, primary key(a)); +CREATE TABLE "filter.table_7" (a integer, b text, primary key(a)); +CREATE TABLE "filter,table_8" (a integer, b text, primary key(a)); +CREATE TABLE "filter""table_9" (a integer, b text, primary key(a)); +CREATE TABLE " filter_table_10" (a integer, b text, primary key(a)); +CREATE TABLE "*" (a integer, b text, primary key(a)); +CREATE TABLE "*".filter_table_0 (a integer, b text, primary key(a)); + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +INSERT INTO filter_table_1 (a, b) VALUES(1, 'public.filter_table_1'); +INSERT INTO filter_schema_1.filter_table_1 (a, b) VALUES(1, 'filter_schema_1.filter_table_1'); +INSERT INTO filter_schema_1.filter_table_2 (a, b) VALUES(1, 'filter_schema_1.filter_table_2'); +INSERT INTO filter_schema_2.filter_table_1 (a, b) VALUES(1, 'filter_schema_2.filter_table_1'); +INSERT INTO filter_schema_2.filter_table_2 (a, b) VALUES(1, 'filter_schema_2.filter_table_2'); +INSERT INTO filter_schema_2.filter_table_3 (a, b) VALUES(1, 'filter_schema_2.filter_table_3'); +INSERT INTO filter_table_2 (a, b) VALUES(1, 'public.filter_table_2'); +INSERT INTO filter_table_3 (a, b) VALUES(1, 'public.filter_table_3'); +INSERT INTO filter_table_4 (a, b) VALUES(1, 'public.filter_table_4'); +INSERT INTO "Filter_table_5" (a, b) VALUES(1, 'public.Filter_table_5'); +INSERT INTO "filter table_6" (a, b) VALUES(1, 'public.filter table_6'); +INSERT INTO "filter.table_7" (a, b) VALUES(1, 'public.filter.table_7'); +INSERT INTO "filter,table_8" (a, b) VALUES(1, 'public.filter,table_8'); +INSERT INTO "filter""table_9" (a, b) VALUES(1, 'public.filter"table_9'); +INSERT INTO " filter_table_10" (a, b) VALUES(1, 'public. filter_table_10'); +INSERT INTO "*" (a, b) VALUES(1, 'public.*'); +INSERT INTO "*".filter_table_0 (a, b) VALUES(1, '*.filter_table_0'); + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'filter-tables', ' foo.bar,*.filter_table_1 ,filter_schema_2.* , public.filter_table_3 , public.Filter_table_5, public.filter\ table_6, public.filter\.table_7 , public.filter\,table_8 , public.filter"table_9, *.\ filter_table_10 , public.\* , \*.filter_table_0 '); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'filter-tables', ' foo.bar,*.filter_table_1 ,filter_schema_2.* , public.filter_table_3 , public.Filter_table_5, public.filter\ table_6, public.filter\.table_7 , public.filter\,table_8 , public.filter"table_9, *.\ filter_table_10 , public.\* , \*.filter_table_0 '); +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/src/postgres/third-party-extensions/wal2json/sql/include_domain_data_type.sql b/src/postgres/third-party-extensions/wal2json/sql/include_domain_data_type.sql new file mode 100644 index 000000000000..ee3e5bad5e1e --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/include_domain_data_type.sql @@ -0,0 +1,62 @@ +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; +SET extra_float_digits = 0; + +CREATE DOMAIN "wal2json_DOMAIN_1" AS bigint; +CREATE DOMAIN wal2json_domain_2 AS numeric(5,3); +CREATE DOMAIN wal2json_domain_3 AS varchar(30); +CREATE DOMAIN "wal2json_DOMAIN_4" AS bit varying(20); + +CREATE TYPE "wal2json_Type" AS ENUM('a', 'b', 'c'); + +CREATE TABLE test_wal2json_5 ( +a smallserial, +b smallint, +c int, +d "wal2json_DOMAIN_1", +e wal2json_domain_2, +f real not null, +g double precision, +h char(10), +i wal2json_domain_3, +j text, +k "wal2json_DOMAIN_4", +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +PRIMARY KEY(b, c, d) +); + +CREATE TABLE test_wal2json_6 ( +a integer, +b "wal2json_Type"[], +PRIMARY KEY(a) +); + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +INSERT INTO test_wal2json_5 (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); + +UPDATE test_wal2json_5 SET f = -f WHERE b = 1; + +INSERT INTO test_wal2json_6 (a, b) VALUES(1, array['b', 'c']::"wal2json_Type"[]); + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-domain-data-type', '0', 'include-pk', '1'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-domain-data-type', '1', 'include-pk', '1'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-domain-data-type', '0', 'include-typmod', '0'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-domain-data-type', '1', 'include-typmod', '0'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'include-domain-data-type', '0', 'include-pk', '1'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '2', 'include-domain-data-type', '1', 'include-pk', '1'); +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + +DROP TABLE test_wal2json_5; +DROP TABLE test_wal2json_6; +DROP DOMAIN "wal2json_DOMAIN_1"; +DROP DOMAIN wal2json_domain_2; +DROP DOMAIN wal2json_domain_3; +DROP DOMAIN "wal2json_DOMAIN_4"; +DROP TYPE "wal2json_Type"; diff --git a/src/postgres/third-party-extensions/wal2json/sql/include_lsn.sql b/src/postgres/third-party-extensions/wal2json/sql/include_lsn.sql new file mode 100644 index 000000000000..3a9bb8d62d41 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/include_lsn.sql @@ -0,0 +1,25 @@ +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; + +DROP TABLE IF EXISTS tbl; +CREATE TABLE tbl (id int); + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +-- One row should have one record and one nextlsn +INSERT INTO tbl VALUES (1); +SELECT count(*) = 1, count(distinct ((data::json)->'nextlsn')::text) = 1 FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-lsn', '1'); + +-- Two rows should have two records and two nextlsns +INSERT INTO tbl VALUES (2); +INSERT INTO tbl VALUES (3); +SELECT count(*) = 2, count(distinct ((data::json)->'nextlsn')::text) = 2 FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-lsn', '1'); + +-- Two rows in one transaction should have one record and one nextlsn +INSERT INTO tbl VALUES (4), (5); +SELECT count(*) = 1, count(distinct ((data::json)->'nextlsn')::text) = 1 FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-lsn', '1'); + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + diff --git a/src/postgres/third-party-extensions/wal2json/sql/include_timestamp.sql b/src/postgres/third-party-extensions/wal2json/sql/include_timestamp.sql new file mode 100644 index 000000000000..efa1e90bffe4 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/include_timestamp.sql @@ -0,0 +1,25 @@ +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; + +DROP TABLE IF EXISTS tbl; +CREATE TABLE tbl (id int); + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +-- One row should have one record and one timestamp +INSERT INTO tbl VALUES (1); +SELECT count(*) = 1, count(distinct ((data::json)->'timestamp')::text) = 1 FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-timestamp', '1'); + +-- Two rows should have two records and two timestamps +INSERT INTO tbl VALUES (2); +INSERT INTO tbl VALUES (3); +SELECT count(*) = 2, count(distinct ((data::json)->'timestamp')::text) = 2 FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-timestamp', '1'); + +-- Two rows in one transaction should have one record and one timestamp +INSERT INTO tbl VALUES (4), (5); +SELECT count(*) = 1, count(distinct ((data::json)->'timestamp')::text) = 1 FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-timestamp', '1'); + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + diff --git a/src/postgres/third-party-extensions/wal2json/sql/include_xids.sql b/src/postgres/third-party-extensions/wal2json/sql/include_xids.sql new file mode 100644 index 000000000000..110b6346f766 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/include_xids.sql @@ -0,0 +1,25 @@ +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; + +DROP TABLE IF EXISTS tbl; +CREATE TABLE tbl (id int); + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +-- One row should have one record and one xids +INSERT INTO tbl VALUES (1); +SELECT count(*) = 1, count(distinct ((data::json)->'xid')::text) = 1 FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-xids', '1'); + +-- Two rows should have two records and two xids +INSERT INTO tbl VALUES (2); +INSERT INTO tbl VALUES (3); +SELECT count(*) = 2, count(distinct ((data::json)->'xid')::text) = 2 FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-xids', '1'); + +-- Two rows in one transaction should have one record and one xid +INSERT INTO tbl VALUES (4), (5); +SELECT count(*) = 2, count(distinct ((data::json)->'xid')::text) = 1 FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-xids', '1'); + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + diff --git a/src/postgres/third-party-extensions/wal2json/sql/insert1.sql b/src/postgres/third-party-extensions/wal2json/sql/insert1.sql new file mode 100644 index 000000000000..fbb514a24af3 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/insert1.sql @@ -0,0 +1,89 @@ +-- this is the first test (CREATE EXTENSION, no DROP TABLE) +LOAD 'test_decoding'; + +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; +SET extra_float_digits = 0; + +CREATE TABLE table_with_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +PRIMARY KEY(b, c, d) +); + +CREATE TABLE table_without_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector +); + +CREATE TABLE table_with_unique ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3) not null, +f real not null, +g double precision not null, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +UNIQUE(g, n) +); + +CREATE SCHEMA "test ""schema"; + +CREATE TABLE "test ""schema"."test "" with 'quotes'" ( + id serial primary key, + "col spaces" int, + "col""quotes" int +); + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +-- INSERT +BEGIN; +INSERT INTO table_with_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_without_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_with_unique (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO "test ""schema"."test "" with 'quotes'" VALUES (1, 2, 3); +COMMIT; + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/src/postgres/third-party-extensions/wal2json/sql/message.sql b/src/postgres/third-party-extensions/wal2json/sql/message.sql new file mode 100644 index 000000000000..b762a8ae101d --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/message.sql @@ -0,0 +1,33 @@ +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +SELECT 'msg1' FROM pg_logical_emit_message(true, 'wal2json', 'this is a\ message'); +SELECT 'msg2' FROM pg_logical_emit_message(false, 'wal2json', 'this is "another" message'); + +SELECT 'msg3' FROM pg_logical_emit_message(false, 'wal2json', E'\\x546170697275732074657272657374726973'::bytea); +SELECT 'msg4' FROM pg_logical_emit_message(false, 'wal2json', E'\\x5072696f646f6e746573206d6178696d7573'::bytea); +SELECT 'msg5' FROM pg_logical_emit_message(false, 'wal2json', E'\\x436172796f6361722062726173696c69656e7365'::bytea); + +BEGIN; +SELECT 'msg6' FROM pg_logical_emit_message(true, 'wal2json', 'this message will not be printed'); +SELECT 'msg7' FROM pg_logical_emit_message(false, 'wal2json', 'this message will be printed even if the transaction is rollbacked'); +ROLLBACK; + +BEGIN; +SELECT 'msg8' FROM pg_logical_emit_message(true, 'wal2json', 'this is message #1'); +SELECT 'msg9' FROM pg_logical_emit_message(false, 'wal2json', 'this message will be printed before message #1'); +SELECT 'msg10' FROM pg_logical_emit_message(true, 'wal2json', 'this is message #2'); +COMMIT; + +SELECT 'msg11' FROM pg_logical_emit_message(true, 'filtered', 'this message will be filtered'); +SELECT 'msg12' FROM pg_logical_emit_message(true, 'added1', 'this message will be printed'); +SELECT 'msg13' FROM pg_logical_emit_message(true, 'added2', 'this message will be filtered'); + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'filter-msg-prefixes', 'foo, filtered, bar', 'add-msg-prefixes', 'added1, added3, wal2json'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'filter-msg-prefixes', 'foo, filtered, bar', 'add-msg-prefixes', 'added1, added3, wal2json'); + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/src/postgres/third-party-extensions/wal2json/sql/numeric_data_types_as_string.sql b/src/postgres/third-party-extensions/wal2json/sql/numeric_data_types_as_string.sql new file mode 100644 index 000000000000..9a06cadfaa6d --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/numeric_data_types_as_string.sql @@ -0,0 +1,33 @@ +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; +SET extra_float_digits = 0; + + + +CREATE TABLE table_integer (a smallserial, b smallint, c int, d bigint); +CREATE TABLE table_decimal (a real, b double precision, c numeric); + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +BEGIN; +INSERT INTO table_integer (b, c, d) VALUES(32767, 2147483647, 9223372036854775807); +INSERT INTO table_integer (b, c, d) VALUES(-32768, -2147483648, -9223372036854775808); + +INSERT INTO table_decimal (a, b) VALUES('Infinity', 'Infinity'); +INSERT INTO table_decimal (a, b) VALUES('-Infinity', '-Infinity'); +INSERT INTO table_decimal (a, b, c) VALUES('NaN', 'NaN', 'NaN'); +INSERT INTO table_decimal (a, b, c) VALUES(123.456, 123456789.012345, 1234567890987654321.1234567890987654321); +INSERT INTO table_decimal (a, b, c) VALUES(-123.456, -123456789.012345, -1234567890987654321.1234567890987654321); +COMMIT; + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'numeric-data-types-as-string', '1'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'numeric-data-types-as-string', '1'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + +DROP TABLE table_integer; +DROP TABLE table_decimal; diff --git a/src/postgres/third-party-extensions/wal2json/sql/pk.sql b/src/postgres/third-party-extensions/wal2json/sql/pk.sql new file mode 100644 index 000000000000..160454f15f67 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/pk.sql @@ -0,0 +1,54 @@ +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; +SET extra_float_digits = 0; + +CREATE TABLE w2j_pk_with_pk ( +a int, +b timestamp, +c text, +d boolean, +e numeric(5,3), +PRIMARY KEY(b, d, e) +); + +CREATE TABLE w2j_pk_without_pk ( +a int, +b timestamp, +c text, +d boolean, +e numeric(5,3) +); + +CREATE TABLE w2j_pk_with_ri ( +a int NOT NULL, +b timestamp, +c text, +d boolean, +e numeric(5,3), +UNIQUE(a) +); +ALTER TABLE w2j_pk_with_ri REPLICA IDENTITY USING INDEX w2j_pk_with_ri_a_key; + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +INSERT INTO w2j_pk_with_pk (a, b, c, d, e) VALUES(123, '2020-04-26 16:23:59', 'Melanosuchus Niger', true, 4.56); +UPDATE w2j_pk_with_pk SET a = 456, c = 'Panthera Onca', d = false; +DELETE FROM w2j_pk_with_pk; + +INSERT INTO w2j_pk_without_pk (a, b, c, d, e) VALUES(123, '2020-04-26 16:23:59', 'Melanosuchus Niger', true, 4.56); +UPDATE w2j_pk_without_pk SET a = 456, c = 'Panthera Onca', d = false; +DELETE FROM w2j_pk_without_pk; + +INSERT INTO w2j_pk_with_ri (a, b, c, d, e) VALUES(123, '2020-04-26 16:23:59', 'Inia Araguaiaensis', true, 4.56); +UPDATE w2j_pk_with_ri SET a = 456, c = 'Panthera Onca', d = false; +DELETE FROM w2j_pk_with_ri; + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0', 'include-pk', '1'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'include-pk', '1'); +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + +DROP TABLE w2j_pk_with_pk; +DROP TABLE w2j_pk_without_pk; +DROP TABLE w2j_pk_with_ri; diff --git a/src/postgres/third-party-extensions/wal2json/sql/position.sql b/src/postgres/third-party-extensions/wal2json/sql/position.sql new file mode 100644 index 000000000000..ef984c3622ec --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/position.sql @@ -0,0 +1,25 @@ +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; + +CREATE TABLE w2j_position (a integer, b integer, primary key(a)); + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +INSERT INTO w2j_position (a, b) VALUES(1,2); +UPDATE w2j_position SET b = 3 WHERE a = 1; +ALTER TABLE w2j_position ADD COLUMN c integer; +ALTER TABLE w2j_position DROP COLUMN b; +INSERT INTO w2j_position (a, c) VALUES(5,6); +UPDATE w2j_position SET c = 7 WHERE a = 5; + +-- without include-column-position parameter +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); + +-- with include-column-position parameter +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-column-positions', '1'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'include-column-positions', '1'); + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/src/postgres/third-party-extensions/wal2json/sql/rename_column.sql b/src/postgres/third-party-extensions/wal2json/sql/rename_column.sql new file mode 100644 index 000000000000..0101ab41c3c4 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/rename_column.sql @@ -0,0 +1,69 @@ +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; +SET extra_float_digits = 0; + +CREATE TABLE w2j_rename_pk ( +a int, +b timestamp, +c text, +d boolean, +e numeric(5,3), +PRIMARY KEY(a, d) +); + +CREATE TABLE w2j_rename_ri ( +a int NOT NULL, +b timestamp, +c text, +d boolean NOT NULL, +e numeric(5,3) +); +CREATE UNIQUE INDEX w2j_rename_ri_idx ON w2j_rename_ri (a, d); +ALTER TABLE w2j_rename_ri REPLICA IDENTITY USING INDEX w2j_rename_ri_idx; + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +INSERT INTO w2j_rename_pk (a, b, c, d, e) VALUES(123, '2020-04-26 16:23:59', 'Melanosuchus Niger', true, 4.56); +UPDATE w2j_rename_pk SET e = 8.76 WHERE a = 123; + +ALTER TABLE w2j_rename_pk RENAME COLUMN d TO f; + +INSERT INTO w2j_rename_pk (a, b, c, f, e) VALUES(456, '2020-12-07 15:56:59', 'Panthera Onca', false, 4.44); +UPDATE w2j_rename_pk SET e = 2.718 WHERE a = 456; + +BEGIN; +INSERT INTO w2j_rename_pk (a, b, c, f, e) VALUES(789, '2021-04-04 10:33:04', 'Chrysocyon brachyurus', true, 20.30); +ALTER TABLE w2j_rename_pk RENAME COLUMN a TO g; +INSERT INTO w2j_rename_pk (g, b, c, f, e) VALUES(790, '2020-04-04 10:34:55', 'Myrmecophaga tridactyla', false, 1.8); +UPDATE w2j_rename_pk SET e = 3.1415 WHERE g = 456; +COMMIT; + +INSERT INTO w2j_rename_ri (a, b, c, d, e) VALUES(123, '2020-04-26 16:23:59', 'Melanosuchus Niger', true, 4.56); +UPDATE w2j_rename_ri SET e = 8.76 WHERE a = 123; + +ALTER TABLE w2j_rename_ri RENAME COLUMN d TO f; + +INSERT INTO w2j_rename_ri (a, b, c, f, e) VALUES(456, '2020-12-07 15:56:59', 'Panthera Onca', false, 4.44); +UPDATE w2j_rename_ri SET e = 2.718 WHERE a = 456; + +BEGIN; +INSERT INTO w2j_rename_ri (a, b, c, f, e) VALUES(789, '2021-04-04 10:33:04', 'Chrysocyon brachyurus', true, 20.30); +ALTER TABLE w2j_rename_ri RENAME COLUMN a TO g; +INSERT INTO w2j_rename_ri (g, b, c, f, e) VALUES(790, '2020-04-04 10:34:55', 'Myrmecophaga tridactyla', false, 1.8); +UPDATE w2j_rename_ri SET e = 3.1415 WHERE g = 456; +COMMIT; + +ALTER TABLE w2j_rename_pk REPLICA IDENTITY FULL; +INSERT INTO w2j_rename_pk (g, b, c, f, e) VALUES(890, '2023-10-31 03:06:00', 'Crypturellus parvirostris', true, 8.90); +UPDATE w2j_rename_pk SET e = 8.91 WHERE g = 890; +DELETE FROM w2j_rename_pk WHERE g = 890; + + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0', 'include-pk', '1'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'include-pk', '1'); +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + +DROP TABLE w2j_rename_pk; +DROP TABLE w2j_rename_ri; diff --git a/src/postgres/third-party-extensions/wal2json/sql/savepoint.sql b/src/postgres/third-party-extensions/wal2json/sql/savepoint.sql new file mode 100644 index 000000000000..78789ea9951f --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/savepoint.sql @@ -0,0 +1,28 @@ +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; + +CREATE TABLE xpto (a SERIAL PRIMARY KEY, b text); + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +INSERT INTO xpto (b) VALUES('john'); +INSERT INTO xpto (b) VALUES('smith'); +INSERT INTO xpto (b) VALUES('robert'); + +BEGIN; +INSERT INTO xpto (b) VALUES('marie'); +SAVEPOINT sp1; +INSERT INTO xpto (b) VALUES('ernesto'); +SAVEPOINT sp2; +INSERT INTO xpto (b) VALUES('peter'); -- discard +SAVEPOINT sp3; +INSERT INTO xpto (b) VALUES('albert'); -- discard +ROLLBACK TO SAVEPOINT sp2; +RELEASE SAVEPOINT sp1; +INSERT INTO xpto (b) VALUES('francisco'); +END; + +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0'); +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/src/postgres/third-party-extensions/wal2json/sql/selecttable.sql b/src/postgres/third-party-extensions/wal2json/sql/selecttable.sql new file mode 100644 index 000000000000..64fcd0e40c78 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/selecttable.sql @@ -0,0 +1,38 @@ +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; + +DROP TABLE IF EXISTS select_table_1; +DROP TABLE IF EXISTS select_table_2; +DROP TABLE IF EXISTS select_table_3; +DROP SCHEMA IF EXISTS select_schema_1 CASCADE; +DROP SCHEMA IF EXISTS select_schema_2 CASCADE; + +CREATE SCHEMA select_schema_1; +CREATE SCHEMA select_schema_2; + +CREATE TABLE select_table_1 (a integer, b text, primary key(a)); +CREATE TABLE select_schema_1.select_table_1 (a integer, b text, primary key(a)); +CREATE TABLE select_schema_1.select_table_2 (a integer, b text, primary key(a)); +CREATE TABLE select_schema_2.select_table_1 (a integer, b text, primary key(a)); +CREATE TABLE select_schema_2.select_table_2 (a integer, b text, primary key(a)); +CREATE TABLE select_schema_2.select_table_3 (a integer, b text, primary key(a)); +CREATE TABLE select_table_2 (a integer, b text, primary key(a)); +CREATE TABLE select_table_3 (a integer, b text, primary key(a)); + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +INSERT INTO select_table_1 (a, b) VALUES(1, 'public.select_table_1'); +INSERT INTO select_schema_1.select_table_1 (a, b) VALUES(1, 'select_schema_1.select_table_1'); +INSERT INTO select_schema_1.select_table_2 (a, b) VALUES(1, 'select_schema_1.select_table_2'); +INSERT INTO select_schema_2.select_table_1 (a, b) VALUES(1, 'select_schema_2.select_table_1'); +INSERT INTO select_schema_2.select_table_2 (a, b) VALUES(1, 'select_schema_2.select_table_2'); +INSERT INTO select_schema_2.select_table_3 (a, b) VALUES(1, 'select_schema_2.select_table_3'); +INSERT INTO select_table_2 (a, b) VALUES(1, 'public.select_table_2'); +INSERT INTO select_table_3 (a, b) VALUES(1, 'public.select_table_3'); + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'add-tables', ' foo.bar,*.select_table_1 ,select_schema_2.* , public.select_table_3 '); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'add-tables', ' foo.bar,*.select_table_1 ,select_schema_2.* , public.select_table_3 '); +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + diff --git a/src/postgres/third-party-extensions/wal2json/sql/specialvalue.sql b/src/postgres/third-party-extensions/wal2json/sql/specialvalue.sql new file mode 100644 index 000000000000..3c65bd3058ce --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/specialvalue.sql @@ -0,0 +1,21 @@ +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; + +DROP TABLE IF EXISTS xpto; + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +CREATE TABLE xpto (a SERIAL PRIMARY KEY, b bool, c varchar(60), d real); +COMMIT; + +BEGIN; +INSERT INTO xpto (b, c, d) VALUES('t', 'test1', '+inf'); +INSERT INTO xpto (b, c, d) VALUES('f', 'test2', 'nan'); +INSERT INTO xpto (b, c, d) VALUES(NULL, 'null', '-inf'); +INSERT INTO xpto (b, c, d) VALUES(TRUE, E'valid: '' " \\ / \b \f \n \r \t \u207F \u967F invalid: \\g \\k end', 123.456); +COMMIT; + +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0'); +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/src/postgres/third-party-extensions/wal2json/sql/toast.sql b/src/postgres/third-party-extensions/wal2json/sql/toast.sql new file mode 100644 index 000000000000..5c96a341b55c --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/toast.sql @@ -0,0 +1,36 @@ +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; +SET extra_float_digits = 0; + +DROP TABLE IF EXISTS xpto; +DROP SEQUENCE IF EXISTS xpto_rand_seq; + +CREATE SEQUENCE xpto_rand_seq START 11 INCREMENT 997; +CREATE TABLE xpto ( +id serial primary key, +toasted_col1 text, +rand1 float8 DEFAULT nextval('xpto_rand_seq'), +toasted_col2 text, +rand2 float8 DEFAULT nextval('xpto_rand_seq') +); + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +-- uncompressed external toast data +INSERT INTO xpto (toasted_col1, toasted_col2) SELECT string_agg(g.i::text, ''), string_agg((g.i*2)::text, '') FROM generate_series(1, 2000) g(i); + +-- compressed external toast data +INSERT INTO xpto (toasted_col2) SELECT repeat(string_agg(to_char(g.i, 'FM0000'), ''), 50) FROM generate_series(1, 500) g(i); + +-- update of existing column +UPDATE xpto SET toasted_col1 = (SELECT string_agg(g.i::text, '') FROM generate_series(1, 2000) g(i)) WHERE id = 1; + +UPDATE xpto SET rand1 = 123.456 WHERE id = 1; + +DELETE FROM xpto WHERE id = 1; + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/src/postgres/third-party-extensions/wal2json/sql/truncate.sql b/src/postgres/third-party-extensions/wal2json/sql/truncate.sql new file mode 100644 index 000000000000..0accc3b5a143 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/truncate.sql @@ -0,0 +1,35 @@ +-- predictability +SET synchronous_commit = on; +SET extra_float_digits = 0; + +CREATE TABLE table_truncate_1 (a integer, b text); +CREATE TABLE table_truncate_2 (a integer, b text); +CREATE TABLE table_truncate_3 (a integer, b text); +CREATE TABLE table_truncate_4 (a integer, b text); +CREATE TABLE table_truncate_5 (a integer, b text); +CREATE TABLE table_truncate_6 (a integer, b text); + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +TRUNCATE table_truncate_1; + +BEGIN; +TRUNCATE table_truncate_2; +INSERT INTO table_truncate_1 (a, b) VALUES(1, 'test1'); +INSERT INTO table_truncate_3 (a, b) VALUES(2, 'test2'); +TRUNCATE table_truncate_3; +INSERT INTO table_truncate_3 (a, b) VALUES(3, 'test3'); +COMMIT; + +BEGIN; +TRUNCATE table_truncate_4; +ROLLBACK; + +BEGIN; +TRUNCATE table_truncate_5, table_truncate_6; +COMMIT; + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'filter-tables', '*.table_truncate_5'); +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/src/postgres/third-party-extensions/wal2json/sql/type_oid.sql b/src/postgres/third-party-extensions/wal2json/sql/type_oid.sql new file mode 100644 index 000000000000..5249e6a5b967 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/type_oid.sql @@ -0,0 +1,25 @@ +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; + +DROP TABLE IF EXISTS w2j_type_oid; +CREATE TABLE w2j_type_oid (a integer, b boolean, primary key(a)); + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +INSERT INTO w2j_type_oid (a, b) VALUES(1, true); +UPDATE w2j_type_oid SET a = 3; +DELETE FROM w2j_type_oid WHERE a = 3; + +-- without include-type-oids parameter +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); + +-- with include-type-oids parameter +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'include-type-oids', '1'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2', 'include-type-oids', '1'); + +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); + +DROP TABLE w2j_type_oid; diff --git a/src/postgres/third-party-extensions/wal2json/sql/typmod.sql b/src/postgres/third-party-extensions/wal2json/sql/typmod.sql new file mode 100644 index 000000000000..dc4141eb7bde --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/typmod.sql @@ -0,0 +1,40 @@ +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; +SET extra_float_digits = 0; + +DROP TABLE IF EXISTS table_with_pk; + +CREATE TABLE table_with_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +PRIMARY KEY(b, c, d) +); + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +INSERT INTO table_with_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); + +UPDATE table_with_pk SET f = -f WHERE b = 1; + +-- UPDATE: pk change +DELETE FROM table_with_pk WHERE b = 1; + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1'); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0'); +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/src/postgres/third-party-extensions/wal2json/sql/update1.sql b/src/postgres/third-party-extensions/wal2json/sql/update1.sql new file mode 100644 index 000000000000..062390e2ea1e --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/update1.sql @@ -0,0 +1,91 @@ +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; +SET extra_float_digits = 0; + +DROP TABLE IF EXISTS table_with_pk; +DROP TABLE IF EXISTS table_without_pk; +DROP TABLE IF EXISTS table_with_unique; + +CREATE TABLE table_with_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +PRIMARY KEY(b, c, d) +); + +CREATE TABLE table_without_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector +); + +CREATE TABLE table_with_unique ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3) not null, +f real not null, +g double precision not null, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +UNIQUE(g, n) +); + +-- INSERT +INSERT INTO table_with_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_without_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_with_unique (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +-- UPDATE: no pk +UPDATE table_without_pk SET f = -f WHERE b = 1; + +-- UPDATE: no pk change +UPDATE table_with_pk SET f = -f WHERE b = 1; + +-- UPDATE: pk change +UPDATE table_with_pk SET b = -b WHERE b = 1; + +-- UPDATE: unique +UPDATE table_with_unique SET n = false WHERE b = 1; + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/src/postgres/third-party-extensions/wal2json/sql/update2.sql b/src/postgres/third-party-extensions/wal2json/sql/update2.sql new file mode 100644 index 000000000000..3d3a12279d2a --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/update2.sql @@ -0,0 +1,91 @@ +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; + +DROP TABLE IF EXISTS table_with_pk; +DROP TABLE IF EXISTS table_without_pk; +DROP TABLE IF EXISTS table_with_unique; + +CREATE TABLE table_with_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +PRIMARY KEY(b, c, d) +); + +CREATE TABLE table_without_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector +); + +CREATE TABLE table_with_unique ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3) not null, +f real not null, +g double precision not null, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +UNIQUE(g, n) +); + +-- INSERT +INSERT INTO table_with_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_without_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_with_unique (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +-- UPDATE: REPLICA IDENTITY NOTHING +ALTER TABLE table_with_pk REPLICA IDENTITY NOTHING; +UPDATE table_with_pk SET f = -f WHERE b = 1; +ALTER TABLE table_with_pk REPLICA IDENTITY DEFAULT; + +ALTER TABLE table_without_pk REPLICA IDENTITY NOTHING; +UPDATE table_without_pk SET f = -f WHERE b = 1; +ALTER TABLE table_without_pk REPLICA IDENTITY DEFAULT; + +ALTER TABLE table_with_unique REPLICA IDENTITY NOTHING; +UPDATE table_with_unique SET f = -f WHERE b = 1; +ALTER TABLE table_with_unique REPLICA IDENTITY DEFAULT; + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/src/postgres/third-party-extensions/wal2json/sql/update3.sql b/src/postgres/third-party-extensions/wal2json/sql/update3.sql new file mode 100644 index 000000000000..d476c99d8903 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/update3.sql @@ -0,0 +1,92 @@ +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; +SET extra_float_digits = 0; + +DROP TABLE IF EXISTS table_with_pk; +DROP TABLE IF EXISTS table_without_pk; +DROP TABLE IF EXISTS table_with_unique; + +CREATE TABLE table_with_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +PRIMARY KEY(b, c, d) +); + +CREATE TABLE table_without_pk ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3), +f real not null, +g double precision, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector +); + +CREATE TABLE table_with_unique ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3) not null, +f real not null, +g double precision not null, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +UNIQUE(g, n) +); + +-- INSERT +INSERT INTO table_with_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_without_pk (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_with_unique (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +-- UPDATE: REPLICA IDENTITY FULL +ALTER TABLE table_with_pk REPLICA IDENTITY FULL; +UPDATE table_with_pk SET f = -f WHERE b = 1; +ALTER TABLE table_with_pk REPLICA IDENTITY DEFAULT; + +ALTER TABLE table_without_pk REPLICA IDENTITY FULL; +UPDATE table_without_pk SET f = -f WHERE b = 1; +ALTER TABLE table_without_pk REPLICA IDENTITY DEFAULT; + +ALTER TABLE table_with_unique REPLICA IDENTITY FULL; +UPDATE table_with_unique SET f = -f WHERE b = 1; +ALTER TABLE table_with_unique REPLICA IDENTITY DEFAULT; + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/src/postgres/third-party-extensions/wal2json/sql/update4.sql b/src/postgres/third-party-extensions/wal2json/sql/update4.sql new file mode 100644 index 000000000000..5d18ce80aef8 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/sql/update4.sql @@ -0,0 +1,44 @@ +\set VERBOSITY terse + +-- predictability +SET synchronous_commit = on; +SET extra_float_digits = 0; + +DROP TABLE IF EXISTS table_with_unique; + +CREATE TABLE table_with_unique ( +a smallserial, +b smallint, +c int, +d bigint, +e numeric(5,3) not null, +f real not null, +g double precision not null, +h char(10), +i varchar(30), +j text, +k bit varying(20), +l timestamp, +m date, +n boolean not null, +o json, +p tsvector, +UNIQUE(g, n) +); + +-- INSERT +INSERT INTO table_with_unique (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(1, 2, 3, 3.54, 876.563452345, 1.23, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', false, '{ "a": 123 }', 'Old Old Parr'::tsvector); +INSERT INTO table_with_unique (b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) VALUES(4, 5, 6, 3.54, 876.563452345, 4.56, 'teste', 'testando', 'um texto longo', B'001110010101010', '2013-11-02 17:30:52', '2013-02-04', true, '{ "a": 123 }', 'Old Old Parr'::tsvector); + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'wal2json'); + +-- UPDATE: REPLICA IDENTITY USING INDEX +ALTER TABLE table_with_unique REPLICA IDENTITY USING INDEX table_with_unique_g_n_key; +-- FIXME não apresenta valor correto de g +UPDATE table_with_unique SET c = -c WHERE b = 1; +UPDATE table_with_unique SET g = -g WHERE n = true; +ALTER TABLE table_with_unique REPLICA IDENTITY DEFAULT; + +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '1', 'pretty-print', '1', 'include-typmod', '0'); +SELECT data FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'format-version', '2'); +SELECT 'stop' FROM pg_drop_replication_slot('regression_slot'); diff --git a/src/postgres/third-party-extensions/wal2json/wal2json.c b/src/postgres/third-party-extensions/wal2json/wal2json.c new file mode 100644 index 000000000000..0c6295dcbe54 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/wal2json.c @@ -0,0 +1,3330 @@ +/*------------------------------------------------------------------------- + * + * wal2json.c + * JSON output plugin for changeset extraction + * + * Copyright (c) 2013-2024, Euler Taveira de Oliveira + * + * IDENTIFICATION + * contrib/wal2json/wal2json.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "access/genam.h" +#include "access/heapam.h" +#include "access/sysattr.h" +#include "catalog/indexing.h" +#include "catalog/pg_attrdef.h" +#include "catalog/pg_type.h" + +#include "replication/logical.h" +#if PG_VERSION_NUM >= 90500 +#include "replication/origin.h" +#endif + +#include "utils/builtins.h" +#include "utils/fmgroids.h" +#include "utils/guc.h" +#include "utils/json.h" +#include "utils/lsyscache.h" +#include "utils/memutils.h" +#include "utils/pg_lsn.h" +#include "utils/rel.h" +#include "utils/syscache.h" + +#define WAL2JSON_VERSION "2.6" +#define WAL2JSON_VERSION_NUM 206 + +#define WAL2JSON_FORMAT_VERSION 2 +#define WAL2JSON_FORMAT_MIN_VERSION 1 + +PG_MODULE_MAGIC; + +extern void _PG_init(void); +extern void PGDLLEXPORT _PG_output_plugin_init(OutputPluginCallbacks *cb); + +typedef struct +{ + bool insert; + bool update; + bool delete; + bool truncate; +} JsonAction; + +typedef struct +{ + MemoryContext context; + bool include_transaction; /* BEGIN and COMMIT objects (v2) */ + bool include_xids; /* include transaction ids */ + bool include_timestamp; /* include transaction timestamp */ + bool include_origin; /* replication origin */ + bool include_schemas; /* qualify tables */ + bool include_types; /* include data types */ + bool include_type_oids; /* include data type oids */ + bool include_typmod; /* include typmod in types */ + bool include_domain_data_type; /* include underlying data type of the domain */ + bool include_column_positions; /* include column numbers */ + bool include_not_null; /* include not-null constraints */ + bool include_default; /* include default expressions */ + bool include_pk; /* include primary key */ + + bool pretty_print; /* pretty-print JSON? */ + bool write_in_chunks; /* write in chunks? (v1) */ + bool numeric_data_types_as_string; /* use strings for numeric data types */ + + JsonAction actions; /* output only these actions */ + + List *filter_origins; /* filter out origins */ + List *filter_tables; /* filter out tables */ + List *add_tables; /* add only these tables */ + List *filter_msg_prefixes; /* filter by message prefixes */ + List *add_msg_prefixes; /* add only messages with these prefixes */ + + int format_version; /* support different formats */ + + /* + * LSN pointing to the end of commit record + 1 (txn->end_lsn) + * It is useful for tools that wants a position to restart from. + */ + bool include_lsn; /* include LSNs */ + + uint64 nr_changes; /* # of passes in pg_decode_change() */ + /* FIXME replace with txn->nentries */ + + /* pretty print */ + char ht[2]; /* horizontal tab, if pretty print */ + char nl[2]; /* new line, if pretty print */ + char sp[2]; /* space, if pretty print */ +} JsonDecodingData; + +typedef enum +{ + PGOUTPUTJSON_CHANGE, + PGOUTPUTJSON_IDENTITY, + PGOUTPUTJSON_PK +} PGOutputJsonKind; + +typedef struct SelectTable +{ + char *schemaname; + char *tablename; + bool allschemas; /* true means any schema */ + bool alltables; /* true means any table */ +} SelectTable; + +/* These must be available to pg_dlsym() */ +static void pg_decode_startup(LogicalDecodingContext *ctx, OutputPluginOptions *opt, bool is_init); +static void pg_decode_shutdown(LogicalDecodingContext *ctx); +static void pg_decode_begin_txn(LogicalDecodingContext *ctx, + ReorderBufferTXN *txn); +static void pg_decode_commit_txn(LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, XLogRecPtr commit_lsn); +static void pg_decode_change(LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, Relation rel, + ReorderBufferChange *change); +#if PG_VERSION_NUM >= 90500 +static bool pg_filter_by_origin(LogicalDecodingContext *ctx, RepOriginId origin_id); +#endif +#if PG_VERSION_NUM >= 90600 +static void pg_decode_message(LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, XLogRecPtr lsn, + bool transactional, const char *prefix, + Size content_size, const char *content); +#endif +#if PG_VERSION_NUM >= 110000 +static void pg_decode_truncate(LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, int n, Relation relations[], + ReorderBufferChange *change); +#endif + +static void columns_to_stringinfo(LogicalDecodingContext *ctx, TupleDesc tupdesc, HeapTuple tuple, bool addcomma, Relation relation); +static void tuple_to_stringinfo(LogicalDecodingContext *ctx, TupleDesc tupdesc, HeapTuple tuple, Bitmapset *bs, bool replident, bool addcomma, Relation relation); +static void pk_to_stringinfo(LogicalDecodingContext *ctx, TupleDesc tupdesc, HeapTuple tuple, Bitmapset *bs, bool addcomma); +static void identity_to_stringinfo(LogicalDecodingContext *ctx, TupleDesc tupdesc, HeapTuple tuple, Bitmapset *bs); +static bool parse_table_identifier(List *qualified_tables, char separator, List **select_tables); +static bool string_to_SelectTable(char *rawstring, char separator, List **select_tables); +static bool split_string_to_list(char *rawstring, char separator, List **sl); +static bool split_string_to_oid_list(char *rawstring, char separator, List **sl); + +static bool pg_filter_by_action(int change_type, JsonAction actions); +static bool pg_filter_by_table(List *filter_tables, char *schemaname, char *tablename); +static bool pg_add_by_table(List *add_tables, char *schemaname, char *tablename); + +/* version 1 */ +static void pg_decode_begin_txn_v1(LogicalDecodingContext *ctx, + ReorderBufferTXN *txn); +static void pg_decode_commit_txn_v1(LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, XLogRecPtr commit_lsn); +static void pg_decode_change_v1(LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, Relation rel, + ReorderBufferChange *change); +#if PG_VERSION_NUM >= 90600 +static void pg_decode_message_v1(LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, XLogRecPtr lsn, + bool transactional, const char *prefix, + Size content_size, const char *content); +#endif +#if PG_VERSION_NUM >= 110000 +static void pg_decode_truncate_v1(LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, int n, Relation relations[], + ReorderBufferChange *change); +#endif + +/* version 2 */ +static void pg_decode_begin_txn_v2(LogicalDecodingContext *ctx, + ReorderBufferTXN *txn); +static void pg_decode_commit_txn_v2(LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, XLogRecPtr commit_lsn); +static void pg_decode_write_value(LogicalDecodingContext *ctx, Datum value, bool isnull, Oid typid); +static void pg_decode_write_tuple(LogicalDecodingContext *ctx, Relation relation, HeapTuple tuple, PGOutputJsonKind kind); +static void pg_decode_write_change(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, Relation relation, ReorderBufferChange *change); +static void pg_decode_change_v2(LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, Relation rel, + ReorderBufferChange *change); +#if PG_VERSION_NUM >= 90600 +static void pg_decode_message_v2(LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, XLogRecPtr lsn, + bool transactional, const char *prefix, + Size content_size, const char *content); +#endif +#if PG_VERSION_NUM >= 110000 +static void pg_decode_truncate_v2(LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, int n, Relation relations[], + ReorderBufferChange *change); +#endif + +/* + * Backward compatibility. + * + * This macro is only available in 9.6+. + */ +#if PG_VERSION_NUM < 90600 +#ifdef USE_FLOAT8_BYVAL +#define UInt64GetDatum(X) ((Datum) (X)) +#else +#define UInt64GetDatum(X) Int64GetDatum((int64) (X)) +#endif +#endif + +#if PG_VERSION_NUM >= 150000 && PG_VERSION_NUM < 160000 +static void update_replication_progress(LogicalDecodingContext *ctx, bool skipped_xact); +#elif PG_VERSION_NUM >= 100000 && PG_VERSION_NUM < 150000 +static void update_replication_progress(LogicalDecodingContext *ctx); +#endif + +void +_PG_init(void) +{ +} + +/* Specify output plugin callbacks */ +void +_PG_output_plugin_init(OutputPluginCallbacks *cb) +{ + AssertVariableIsOfType(&_PG_output_plugin_init, LogicalOutputPluginInit); + + cb->startup_cb = pg_decode_startup; + cb->begin_cb = pg_decode_begin_txn; + cb->change_cb = pg_decode_change; + cb->commit_cb = pg_decode_commit_txn; + cb->shutdown_cb = pg_decode_shutdown; +#if PG_VERSION_NUM >= 90500 + cb->filter_by_origin_cb = pg_filter_by_origin; +#endif +#if PG_VERSION_NUM >= 90600 + cb->message_cb = pg_decode_message; +#endif +#if PG_VERSION_NUM >= 110000 + cb->truncate_cb = pg_decode_truncate; +#endif +} + +/* Initialize this plugin */ +static void +pg_decode_startup(LogicalDecodingContext *ctx, OutputPluginOptions *opt, bool is_init) +{ + ListCell *option; + JsonDecodingData *data; + SelectTable *t; + + data = palloc0(sizeof(JsonDecodingData)); + data->context = AllocSetContextCreate(TopMemoryContext, + "wal2json output context", +#if PG_VERSION_NUM >= 90600 + ALLOCSET_DEFAULT_SIZES +#else + ALLOCSET_DEFAULT_MINSIZE, + ALLOCSET_DEFAULT_INITSIZE, + ALLOCSET_DEFAULT_MAXSIZE +#endif + ); + data->include_transaction = true; + data->include_xids = false; + data->include_timestamp = false; + data->include_pk = false; + data->include_origin = false; + data->include_schemas = true; + data->include_types = true; + data->include_type_oids = false; + data->include_typmod = true; + data->include_domain_data_type = false; + data->include_column_positions = false; + data->numeric_data_types_as_string = false; + data->pretty_print = false; + data->write_in_chunks = false; + data->include_lsn = false; + data->include_not_null = false; + data->include_default = false; + data->filter_origins = NIL; + data->filter_tables = NIL; + data->filter_msg_prefixes = NIL; + data->add_msg_prefixes = NIL; + + data->format_version = 1; + + /* default actions */ + if (WAL2JSON_FORMAT_VERSION == 1) + { + data->actions.insert = true; + data->actions.update = true; + data->actions.delete = true; + data->actions.truncate = false; /* backward compatibility */ + } + else + { + data->actions.insert = true; + data->actions.update = true; + data->actions.delete = true; + data->actions.truncate = true; + } + + /* pretty print */ + data->ht[0] = '\0'; + data->nl[0] = '\0'; + data->sp[0] = '\0'; + + /* add all tables in all schemas by default */ + t = palloc0(sizeof(SelectTable)); + t->allschemas = true; + t->alltables = true; + data->add_tables = lappend(data->add_tables, t); + + data->nr_changes = 0; + + ctx->output_plugin_private = data; + + opt->output_type = OUTPUT_PLUGIN_TEXTUAL_OUTPUT; + + foreach(option, ctx->output_plugin_options) + { + DefElem *elem = lfirst(option); + + Assert(elem->arg == NULL || IsA(elem->arg, String)); + + if (strcmp(elem->defname, "include-transaction") == 0) + { + /* if option value is NULL then assume that value is true */ + if (elem->arg == NULL) + data->include_transaction = true; + else if (!parse_bool(strVal(elem->arg), &data->include_transaction)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("could not parse value \"%s\" for parameter \"%s\"", + strVal(elem->arg), elem->defname))); + } + else if (strcmp(elem->defname, "include-xids") == 0) + { + /* If option does not provide a value, it means its value is true */ + if (elem->arg == NULL) + { + elog(DEBUG1, "include-xids argument is null"); + data->include_xids = true; + } + else if (!parse_bool(strVal(elem->arg), &data->include_xids)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("could not parse value \"%s\" for parameter \"%s\"", + strVal(elem->arg), elem->defname))); + } + else if (strcmp(elem->defname, "include-timestamp") == 0) + { + if (elem->arg == NULL) + { + elog(DEBUG1, "include-timestamp argument is null"); + data->include_timestamp = true; + } + else if (!parse_bool(strVal(elem->arg), &data->include_timestamp)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("could not parse value \"%s\" for parameter \"%s\"", + strVal(elem->arg), elem->defname))); + } + else if (strcmp(elem->defname, "include-pk") == 0) + { + if (elem->arg == NULL) + { + elog(DEBUG1, "include-pk argument is null"); + data->include_pk = true; + } + else if (!parse_bool(strVal(elem->arg), &data->include_pk)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("could not parse value \"%s\" for parameter \"%s\"", + strVal(elem->arg), elem->defname))); + } + else if (strcmp(elem->defname, "include-origin") == 0) + { + if (elem->arg == NULL) + { + elog(DEBUG1, "include-origin argument is null"); + data->include_origin = true; + } + else if (!parse_bool(strVal(elem->arg), &data->include_origin)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("could not parse value \"%s\" for parameter \"%s\"", + strVal(elem->arg), elem->defname))); + } + else if (strcmp(elem->defname, "include-schemas") == 0) + { + if (elem->arg == NULL) + { + elog(DEBUG1, "include-schemas argument is null"); + data->include_schemas = true; + } + else if (!parse_bool(strVal(elem->arg), &data->include_schemas)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("could not parse value \"%s\" for parameter \"%s\"", + strVal(elem->arg), elem->defname))); + } + else if (strcmp(elem->defname, "include-types") == 0) + { + if (elem->arg == NULL) + { + elog(DEBUG1, "include-types argument is null"); + data->include_types = true; + } + else if (!parse_bool(strVal(elem->arg), &data->include_types)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("could not parse value \"%s\" for parameter \"%s\"", + strVal(elem->arg), elem->defname))); + } + else if (strcmp(elem->defname, "include-type-oids") == 0) + { + if (elem->arg == NULL) + { + elog(DEBUG1, "include-type-oids argument is null"); + data->include_type_oids = true; + } + else if (!parse_bool(strVal(elem->arg), &data->include_type_oids)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("could not parse value \"%s\" for parameter \"%s\"", + strVal(elem->arg), elem->defname))); + } + else if (strcmp(elem->defname, "include-typmod") == 0) + { + if (elem->arg == NULL) + { + elog(DEBUG1, "include-typmod argument is null"); + data->include_typmod = true; + } + else if (!parse_bool(strVal(elem->arg), &data->include_typmod)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("could not parse value \"%s\" for parameter \"%s\"", + strVal(elem->arg), elem->defname))); + } + else if (strcmp(elem->defname, "include-domain-data-type") == 0) + { + if (elem->arg == NULL) + { + elog(DEBUG1, "include-types argument is null"); + data->include_domain_data_type = true; + } + else if (!parse_bool(strVal(elem->arg), &data->include_domain_data_type)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("could not parse value \"%s\" for parameter \"%s\"", + strVal(elem->arg), elem->defname))); + } + else if (strcmp(elem->defname, "include-column-positions") == 0) + { + if (elem->arg == NULL) + { + elog(DEBUG1, "include-column-positions argument is null"); + data->include_column_positions = true; + } + else if (!parse_bool(strVal(elem->arg), &data->include_column_positions)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("could not parse value \"%s\" for parameter \"%s\"", + strVal(elem->arg), elem->defname))); + } + else if (strcmp(elem->defname, "include-not-null") == 0) + { + if (elem->arg == NULL) + { + elog(DEBUG1, "include-not-null argument is null"); + data->include_not_null = true; + } + else if (!parse_bool(strVal(elem->arg), &data->include_not_null)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("could not parse value \"%s\" for parameter \"%s\"", + strVal(elem->arg), elem->defname))); + } + else if (strcmp(elem->defname, "include-default") == 0) + { + if (elem->arg == NULL) + { + elog(DEBUG1, "include-default argument is null"); + data->include_default = true; + } + else if (!parse_bool(strVal(elem->arg), &data->include_default)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("could not parse value \"%s\" for parameter \"%s\"", + strVal(elem->arg), elem->defname))); + } + else if (strcmp(elem->defname, "numeric-data-types-as-string") == 0) + { + if (elem->arg == NULL) + { + elog(DEBUG1, "numeric-data-types-as-string argument is null"); + data->numeric_data_types_as_string = true; + } + else if (!parse_bool(strVal(elem->arg), &data->numeric_data_types_as_string)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("could not parse value \"%s\" for parameter \"%s\"", + strVal(elem->arg), elem->defname))); + } + else if (strcmp(elem->defname, "pretty-print") == 0) + { + if (elem->arg == NULL) + { + elog(DEBUG1, "pretty-print argument is null"); + data->pretty_print = true; + } + else if (!parse_bool(strVal(elem->arg), &data->pretty_print)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("could not parse value \"%s\" for parameter \"%s\"", + strVal(elem->arg), elem->defname))); + + if (data->pretty_print) + { + data->ht[0] = '\t'; + data->nl[0] = '\n'; + data->sp[0] = ' '; + } + } + else if (strcmp(elem->defname, "write-in-chunks") == 0) + { + if (elem->arg == NULL) + { + elog(DEBUG1, "write-in-chunks argument is null"); + data->write_in_chunks = true; + } + else if (!parse_bool(strVal(elem->arg), &data->write_in_chunks)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("could not parse value \"%s\" for parameter \"%s\"", + strVal(elem->arg), elem->defname))); + } + else if (strcmp(elem->defname, "include-lsn") == 0) + { + if (elem->arg == NULL) + { + elog(DEBUG1, "include-lsn argument is null"); + data->include_lsn = true; + } + else if (!parse_bool(strVal(elem->arg), &data->include_lsn)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("could not parse value \"%s\" for parameter \"%s\"", + strVal(elem->arg), elem->defname))); + } + else if (strcmp(elem->defname, "include-unchanged-toast") == 0) + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_NAME), + errmsg("parameter \"%s\" was deprecated", elem->defname))); + } + else if (strcmp(elem->defname, "actions") == 0) + { + char *rawstr; + + if (elem->arg == NULL) + { + elog(DEBUG1, "actions argument is null"); + /* argument null means default; nothing to do here */ + } + else + { + List *selected_actions = NIL; + ListCell *lc; + + rawstr = pstrdup(strVal(elem->arg)); + if (!split_string_to_list(rawstr, ',', &selected_actions)) + { + pfree(rawstr); + ereport(ERROR, + (errcode(ERRCODE_INVALID_NAME), + errmsg("could not parse value \"%s\" for parameter \"%s\"", + strVal(elem->arg), elem->defname))); + } + + data->actions.insert = false; + data->actions.update = false; + data->actions.delete = false; + data->actions.truncate = false; + + foreach(lc, selected_actions) + { + char *p = lfirst(lc); + + if (strcmp(p, "insert") == 0) + data->actions.insert = true; + else if (strcmp(p, "update") == 0) + data->actions.update = true; + else if (strcmp(p, "delete") == 0) + data->actions.delete = true; + else if (strcmp(p, "truncate") == 0) + data->actions.truncate = true; + else + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("could not parse value \"%s\" for parameter \"%s\"", + p, elem->defname))); + } + + pfree(rawstr); + list_free(selected_actions); + } + } + else if (strcmp(elem->defname, "filter-origins") == 0) + { + char *rawstr; + + if (elem->arg == NULL) + { + elog(DEBUG1, "filter-origins argument is null"); + data->filter_origins = NIL; + } + else + { + rawstr = pstrdup(strVal(elem->arg)); + if (!split_string_to_oid_list(rawstr, ',', &data->filter_origins)) + { + pfree(rawstr); + ereport(ERROR, + (errcode(ERRCODE_INVALID_NAME), + errmsg("could not parse value \"%s\" for parameter \"%s\"", + strVal(elem->arg), elem->defname))); + } + pfree(rawstr); + } + } + else if (strcmp(elem->defname, "filter-tables") == 0) + { + char *rawstr; + + if (elem->arg == NULL) + { + elog(DEBUG1, "filter-tables argument is null"); + data->filter_tables = NIL; + } + else + { + rawstr = pstrdup(strVal(elem->arg)); + if (!string_to_SelectTable(rawstr, ',', &data->filter_tables)) + { + pfree(rawstr); + ereport(ERROR, + (errcode(ERRCODE_INVALID_NAME), + errmsg("could not parse value \"%s\" for parameter \"%s\"", + strVal(elem->arg), elem->defname))); + } + pfree(rawstr); + } + } + else if (strcmp(elem->defname, "add-tables") == 0) + { + char *rawstr; + + /* + * If this parameter is specified, remove 'all tables in all + * schemas' value from list. + */ + list_free_deep(data->add_tables); + data->add_tables = NIL; + + if (elem->arg == NULL) + { + elog(DEBUG1, "add-tables argument is null"); + data->add_tables = NIL; + } + else + { + rawstr = pstrdup(strVal(elem->arg)); + if (!string_to_SelectTable(rawstr, ',', &data->add_tables)) + { + pfree(rawstr); + ereport(ERROR, + (errcode(ERRCODE_INVALID_NAME), + errmsg("could not parse value \"%s\" for parameter \"%s\"", + strVal(elem->arg), elem->defname))); + } + pfree(rawstr); + } + } + else if (strcmp(elem->defname, "filter-msg-prefixes") == 0) + { + char *rawstr; + + if (elem->arg == NULL) + { + elog(DEBUG1, "filter-msg-prefixes argument is null"); + data->filter_msg_prefixes = NIL; + } + else + { + rawstr = pstrdup(strVal(elem->arg)); + if (!split_string_to_list(rawstr, ',', &data->filter_msg_prefixes)) + { + pfree(rawstr); + ereport(ERROR, + (errcode(ERRCODE_INVALID_NAME), + errmsg("could not parse value \"%s\" for parameter \"%s\"", + strVal(elem->arg), elem->defname))); + } + pfree(rawstr); + } + } + else if (strcmp(elem->defname, "add-msg-prefixes") == 0) + { + char *rawstr; + + if (elem->arg == NULL) + { + elog(DEBUG1, "add-msg-prefixes argument is null"); + data->add_msg_prefixes = NIL; + } + else + { + rawstr = pstrdup(strVal(elem->arg)); + if (!split_string_to_list(rawstr, ',', &data->add_msg_prefixes)) + { + pfree(rawstr); + ereport(ERROR, + (errcode(ERRCODE_INVALID_NAME), + errmsg("could not parse value \"%s\" for parameter \"%s\"", + strVal(elem->arg), elem->defname))); + } + pfree(rawstr); + } + } + else if (strcmp(elem->defname, "format-version") == 0) + { + if (elem->arg == NULL) + { + elog(DEBUG1, "format-version argument is null"); + data->format_version = WAL2JSON_FORMAT_VERSION; + } + else if (!parse_int(strVal(elem->arg), &data->format_version, 0, NULL)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("could not parse value \"%s\" for parameter \"%s\"", + strVal(elem->arg), elem->defname))); + + if (data->format_version > WAL2JSON_FORMAT_VERSION) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("client sent format_version=%d but we only support format %d or lower", + data->format_version, WAL2JSON_FORMAT_VERSION))); + + if (data->format_version < WAL2JSON_FORMAT_MIN_VERSION) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("client sent format_version=%d but we only support format %d or higher", + data->format_version, WAL2JSON_FORMAT_MIN_VERSION))); + } + else + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("option \"%s\" = \"%s\" is unknown", + elem->defname, + elem->arg ? strVal(elem->arg) : "(null)"))); + } + } + + elog(DEBUG2, "format version: %d", data->format_version); +} + +/* cleanup this plugin's resources */ +static void +pg_decode_shutdown(LogicalDecodingContext *ctx) +{ + JsonDecodingData *data = ctx->output_plugin_private; + + /* cleanup our own resources via memory context reset */ + MemoryContextDelete(data->context); +} + +#if PG_VERSION_NUM >= 90500 +static bool +pg_filter_by_origin(LogicalDecodingContext *ctx, RepOriginId origin_id) +{ + JsonDecodingData *data = ctx->output_plugin_private; + + elog(DEBUG3, "origin: %u", origin_id); + + /* changes produced locally are never filtered */ + if (origin_id == InvalidRepOriginId) + return false; + + /* Filter origins, if available */ + if (list_length(data->filter_origins) > 0 && list_member_oid(data->filter_origins, origin_id)) + { + elog(DEBUG2, "origin \"%u\" was filtered out", origin_id); + return true; + } + + /* + * There isn't a list of origins to filter or origin is not contained in + * the filter list hence forward to all subscribers. + */ + return false; +} +#endif + +/* BEGIN callback */ +static void +pg_decode_begin_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn) +{ + JsonDecodingData *data = ctx->output_plugin_private; + + if (data->format_version == 2) + pg_decode_begin_txn_v2(ctx, txn); + else if (data->format_version == 1) + pg_decode_begin_txn_v1(ctx, txn); + else + elog(ERROR, "format version %d is not supported", data->format_version); +} + +static void +pg_decode_begin_txn_v1(LogicalDecodingContext *ctx, ReorderBufferTXN *txn) +{ + JsonDecodingData *data = ctx->output_plugin_private; + + data->nr_changes = 0; + + /* Transaction starts */ + OutputPluginPrepareWrite(ctx, true); + + appendStringInfo(ctx->out, "{%s", data->nl); + + if (data->include_xids) + appendStringInfo(ctx->out, "%s\"xid\":%s%u,%s", data->ht, data->sp, txn->xid, data->nl); + + if (data->include_lsn) + { + char *lsn_str = DatumGetCString(DirectFunctionCall1(pg_lsn_out, UInt64GetDatum(txn->end_lsn))); + + appendStringInfo(ctx->out, "%s\"nextlsn\":%s\"%s\",%s", data->ht, data->sp, lsn_str, data->nl); + + pfree(lsn_str); + } + +#if PG_VERSION_NUM >= 150000 + if (data->include_timestamp) + appendStringInfo(ctx->out, "%s\"timestamp\":%s\"%s\",%s", data->ht, data->sp, timestamptz_to_str(txn->xact_time.commit_time), data->nl); +#else + if (data->include_timestamp) + appendStringInfo(ctx->out, "%s\"timestamp\":%s\"%s\",%s", data->ht, data->sp, timestamptz_to_str(txn->commit_time), data->nl); +#endif + +#if PG_VERSION_NUM >= 90500 + if (data->include_origin) + appendStringInfo(ctx->out, "%s\"origin\":%s%u,%s", data->ht, data->sp, txn->origin_id, data->nl); +#endif + + appendStringInfo(ctx->out, "%s\"change\":%s[", data->ht, data->sp); + + if (data->write_in_chunks) + OutputPluginWrite(ctx, true); +} + +static void +pg_decode_begin_txn_v2(LogicalDecodingContext *ctx, ReorderBufferTXN *txn) +{ + JsonDecodingData *data = ctx->output_plugin_private; + + /* don't include BEGIN object */ + if (!data->include_transaction) + return; + + OutputPluginPrepareWrite(ctx, true); + appendStringInfoString(ctx->out, "{\"action\":\"B\""); + if (data->include_xids) + appendStringInfo(ctx->out, ",\"xid\":%u", txn->xid); + +#if PG_VERSION_NUM >= 150000 + if (data->include_timestamp) + appendStringInfo(ctx->out, ",\"timestamp\":\"%s\"", timestamptz_to_str(txn->xact_time.commit_time)); +#else + if (data->include_timestamp) + appendStringInfo(ctx->out, ",\"timestamp\":\"%s\"", timestamptz_to_str(txn->commit_time)); +#endif + +#if PG_VERSION_NUM >= 90500 + if (data->include_origin) + appendStringInfo(ctx->out, ",\"origin\":%u", txn->origin_id); +#endif + + if (data->include_lsn) + { + char *lsn_str = DatumGetCString(DirectFunctionCall1(pg_lsn_out, UInt64GetDatum(txn->final_lsn))); + appendStringInfo(ctx->out, ",\"lsn\":\"%s\"", lsn_str); + pfree(lsn_str); + + lsn_str = DatumGetCString(DirectFunctionCall1(pg_lsn_out, UInt64GetDatum(txn->end_lsn))); + appendStringInfo(ctx->out, ",\"nextlsn\":\"%s\"", lsn_str); + pfree(lsn_str); + } + + appendStringInfoChar(ctx->out, '}'); + OutputPluginWrite(ctx, true); +} + +/* COMMIT callback */ +static void +pg_decode_commit_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, + XLogRecPtr commit_lsn) +{ + JsonDecodingData *data = ctx->output_plugin_private; + + /* + * Some older minor versions from back branches (10 to 14) calls + * OutputPluginUpdateProgress(). That's before the fix + * f95d53eded55ecbf037f6416ced6af29a2c3caca. After that, + * update_replication_progress() function is used for back branches. In + * version 15, update_replication_progress() changes the signature to + * support skipped transactions. In version 16, + * OutputPluginUpdateProgress() is back because a proper fix was added into + * logical decoding. + */ +#if PG_VERSION_NUM >= 160000 + OutputPluginUpdateProgress(ctx, false); /* XXX change 2nd param when skipped empty transaction is supported */ +#elif PG_VERSION_NUM >= 150000 && PG_VERSION_NUM < 160000 + update_replication_progress(ctx, false); /* XXX change 2nd param when skipped empty transaction is supported */ +#elif PG_VERSION_NUM >= 140004 && PG_VERSION_NUM < 150000 + update_replication_progress(ctx); +#elif PG_VERSION_NUM >= 130008 && PG_VERSION_NUM < 140000 + update_replication_progress(ctx); +#elif PG_VERSION_NUM >= 120012 && PG_VERSION_NUM < 130000 + update_replication_progress(ctx); +#elif PG_VERSION_NUM >= 110017 && PG_VERSION_NUM < 120000 + update_replication_progress(ctx); +#elif PG_VERSION_NUM >= 100022 && PG_VERSION_NUM < 110000 + update_replication_progress(ctx); +#elif PG_VERSION_NUM >= 140000 && PG_VERSION_NUM < 140004 + OutputPluginUpdateProgress(ctx); +#elif PG_VERSION_NUM >= 130000 && PG_VERSION_NUM < 130008 + OutputPluginUpdateProgress(ctx); +#elif PG_VERSION_NUM >= 120000 && PG_VERSION_NUM < 120012 + OutputPluginUpdateProgress(ctx); +#elif PG_VERSION_NUM >= 110000 && PG_VERSION_NUM < 110017 + OutputPluginUpdateProgress(ctx); +#elif PG_VERSION_NUM >= 100000 && PG_VERSION_NUM < 100022 + OutputPluginUpdateProgress(ctx); +#endif + + elog(DEBUG2, "my change counter: " UINT64_FORMAT " ; # of changes: " UINT64_FORMAT " ; # of changes in memory: " UINT64_FORMAT, data->nr_changes, txn->nentries, txn->nentries_mem); + elog(DEBUG2, "# of subxacts: %d", txn->nsubtxns); + + if (data->format_version == 2) + pg_decode_commit_txn_v2(ctx, txn, commit_lsn); + else if (data->format_version == 1) + pg_decode_commit_txn_v1(ctx, txn, commit_lsn); + else + elog(ERROR, "format version %d is not supported", data->format_version); +} + +static void +pg_decode_commit_txn_v1(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, + XLogRecPtr commit_lsn) +{ + JsonDecodingData *data = ctx->output_plugin_private; + + /* Transaction ends */ + if (data->write_in_chunks) + OutputPluginPrepareWrite(ctx, true); + + /* if we don't write in chunks, we need a newline here */ + if (!data->write_in_chunks) + appendStringInfo(ctx->out, "%s", data->nl); + + appendStringInfo(ctx->out, "%s]%s}", data->ht, data->nl); + + OutputPluginWrite(ctx, true); +} + +static void +pg_decode_commit_txn_v2(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, + XLogRecPtr commit_lsn) +{ + JsonDecodingData *data = ctx->output_plugin_private; + + /* don't include COMMIT object */ + if (!data->include_transaction) + return; + + OutputPluginPrepareWrite(ctx, true); + appendStringInfoString(ctx->out, "{\"action\":\"C\""); + if (data->include_xids) + appendStringInfo(ctx->out, ",\"xid\":%u", txn->xid); + +#if PG_VERSION_NUM >= 150000 + if (data->include_timestamp) + appendStringInfo(ctx->out, ",\"timestamp\":\"%s\"", timestamptz_to_str(txn->xact_time.commit_time)); +#else + if (data->include_timestamp) + appendStringInfo(ctx->out, ",\"timestamp\":\"%s\"", timestamptz_to_str(txn->commit_time)); +#endif + +#if PG_VERSION_NUM >= 90500 + if (data->include_origin) + appendStringInfo(ctx->out, ",\"origin\":%u", txn->origin_id); +#endif + + if (data->include_lsn) + { + char *lsn_str = DatumGetCString(DirectFunctionCall1(pg_lsn_out, UInt64GetDatum(commit_lsn))); + appendStringInfo(ctx->out, ",\"lsn\":\"%s\"", lsn_str); + pfree(lsn_str); + + lsn_str = DatumGetCString(DirectFunctionCall1(pg_lsn_out, UInt64GetDatum(txn->end_lsn))); + appendStringInfo(ctx->out, ",\"nextlsn\":\"%s\"", lsn_str); + pfree(lsn_str); + } + + appendStringInfoChar(ctx->out, '}'); + OutputPluginWrite(ctx, true); +} + +/* + * Accumulate tuple information and stores it at the end + * + * replident: is this tuple a replica identity? + */ +static void +tuple_to_stringinfo(LogicalDecodingContext *ctx, TupleDesc tupdesc, HeapTuple tuple, Bitmapset *bs, bool replident, bool addcomma, Relation relation) +{ + JsonDecodingData *data; + int natt; + + StringInfoData colnames; + StringInfoData coltypes; + StringInfoData coltypeoids; + StringInfoData colpositions; + StringInfoData colnotnulls; + StringInfoData coldefaults; + StringInfoData colvalues; + char comma[3] = ""; + + Relation defrel = NULL; + + data = ctx->output_plugin_private; + + initStringInfo(&colnames); + initStringInfo(&coltypes); + if (data->include_type_oids) + initStringInfo(&coltypeoids); + if (data->include_column_positions) + initStringInfo(&colpositions); + if (data->include_not_null) + initStringInfo(&colnotnulls); + if (data->include_default) + initStringInfo(&coldefaults); + initStringInfo(&colvalues); + + /* + * If replident is true, it will output info about replica identity. In this + * case, there are special JSON objects for it. Otherwise, it will print new + * tuple data. + */ + if (replident) + { + appendStringInfo(&colnames, "%s%s%s\"oldkeys\":%s{%s", data->ht, data->ht, data->ht, data->sp, data->nl); + appendStringInfo(&colnames, "%s%s%s%s\"keynames\":%s[", data->ht, data->ht, data->ht, data->ht, data->sp); + appendStringInfo(&coltypes, "%s%s%s%s\"keytypes\":%s[", data->ht, data->ht, data->ht, data->ht, data->sp); + if (data->include_type_oids) + appendStringInfo(&coltypeoids, "%s%s%s%s\"keytypeoids\":%s[", data->ht, data->ht, data->ht, data->ht, data->sp); + appendStringInfo(&colvalues, "%s%s%s%s\"keyvalues\":%s[", data->ht, data->ht, data->ht, data->ht, data->sp); + } + else + { + appendStringInfo(&colnames, "%s%s%s\"columnnames\":%s[", data->ht, data->ht, data->ht, data->sp); + appendStringInfo(&coltypes, "%s%s%s\"columntypes\":%s[", data->ht, data->ht, data->ht, data->sp); + if (data->include_type_oids) + appendStringInfo(&coltypeoids, "%s%s%s\"columntypeoids\":%s[", data->ht, data->ht, data->ht, data->sp); + if (data->include_column_positions) + appendStringInfo(&colpositions, "%s%s%s\"columnpositions\":%s[", data->ht, data->ht, data->ht, data->sp); + if (data->include_not_null) + appendStringInfo(&colnotnulls, "%s%s%s\"columnoptionals\":%s[", data->ht, data->ht, data->ht, data->sp); + if (data->include_default) + appendStringInfo(&coldefaults, "%s%s%s\"columndefaults\":%s[", data->ht, data->ht, data->ht, data->sp); + appendStringInfo(&colvalues, "%s%s%s\"columnvalues\":%s[", data->ht, data->ht, data->ht, data->sp); + } + + if (!replident && data->include_default) + { +#if PG_VERSION_NUM >= 120000 + defrel = table_open(AttrDefaultRelationId, AccessShareLock); +#else + defrel = heap_open(AttrDefaultRelationId, AccessShareLock); +#endif + } + + /* Print column information (name, type, value) */ + for (natt = 0; natt < tupdesc->natts; natt++) + { + Form_pg_attribute attr; /* the attribute itself */ + Oid typid; /* type of current attribute */ + HeapTuple type_tuple; /* information about a type */ + Oid typoutput; /* output function */ + bool typisvarlena; + Datum origval; /* possibly toasted Datum */ + Datum val; /* definitely detoasted Datum */ + char *outputstr = NULL; + bool isnull; /* column is null? */ + + /* + * Commit d34a74dd064af959acd9040446925d9d53dff15b introduced + * TupleDescAttr() in back branches. If the version supports + * this macro, use it. Version 10 and later already support it. + */ +#if (PG_VERSION_NUM >= 90600 && PG_VERSION_NUM < 90605) || (PG_VERSION_NUM >= 90500 && PG_VERSION_NUM < 90509) || (PG_VERSION_NUM >= 90400 && PG_VERSION_NUM < 90414) + attr = tupdesc->attrs[natt]; +#else + attr = TupleDescAttr(tupdesc, natt); +#endif + + elog(DEBUG1, "attribute \"%s\" (%d/%d)", NameStr(attr->attname), natt, tupdesc->natts); + + /* Do not print dropped or system columns */ + if (attr->attisdropped || attr->attnum < 0) + continue; + + /* Replica identity column? */ + if (bs != NULL && !bms_is_member(attr->attnum - FirstLowInvalidHeapAttributeNumber, bs)) + continue; + + /* Get Datum from tuple */ + origval = heap_getattr(tuple, natt + 1, tupdesc, &isnull); + + /* Skip nulls iif printing key/identity */ + if (isnull && replident) + continue; + + typid = attr->atttypid; + + /* Figure out type name */ + type_tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid)); + if (!HeapTupleIsValid(type_tuple)) + elog(ERROR, "cache lookup failed for type %u", typid); + + /* Get information needed for printing values of a type */ + getTypeOutputInfo(typid, &typoutput, &typisvarlena); + + /* XXX Unchanged TOAST Datum does not need to be output */ + if (!isnull && typisvarlena && VARATT_IS_EXTERNAL_ONDISK(origval)) + { + elog(DEBUG1, "column \"%s\" has an unchanged TOAST", NameStr(attr->attname)); + continue; + } + + /* Accumulate each column info */ + appendStringInfo(&colnames, "%s", comma); + escape_json(&colnames, NameStr(attr->attname)); + + if (data->include_types) + { + char *type_str; + int len; + Form_pg_type type_form = (Form_pg_type) GETSTRUCT(type_tuple); + + /* + * It is a domain. Replace domain name with base data type if + * include_domain_data_type is enabled. + */ + if (type_form->typtype == TYPTYPE_DOMAIN && data->include_domain_data_type) + { + typid = type_form->typbasetype; + if (data->include_typmod) + { + getTypeOutputInfo(typid, &typoutput, &typisvarlena); + type_str = format_type_with_typemod(type_form->typbasetype, type_form->typtypmod); + } + else + { + /* + * Since we are not using a format function, grab base type + * name from Form_pg_type. + */ + type_tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid)); + if (!HeapTupleIsValid(type_tuple)) + elog(ERROR, "cache lookup failed for type %u", typid); + type_form = (Form_pg_type) GETSTRUCT(type_tuple); + type_str = pstrdup(NameStr(type_form->typname)); + } + } + else + { + if (data->include_typmod) + type_str = TextDatumGetCString(DirectFunctionCall2(format_type, attr->atttypid, attr->atttypmod)); + else + type_str = pstrdup(NameStr(type_form->typname)); + } + + appendStringInfo(&coltypes, "%s", comma); + /* + * format_type() returns a quoted identifier, if + * required. In this case, it doesn't need to enclose the type name + * in double quotes. However, if it is an array type, it should + * escape it because the brackets are outside the double quotes. + */ + len = strlen(type_str); + if (type_str[0] == '"' && type_str[len - 1] != ']') + appendStringInfo(&coltypes, "%s", type_str); + else + escape_json(&coltypes, type_str); + + pfree(type_str); + + /* oldkeys doesn't print not-null constraints */ + if (!replident && data->include_not_null) + { + if (attr->attnotnull) + appendStringInfo(&colnotnulls, "%sfalse", comma); + else + appendStringInfo(&colnotnulls, "%strue", comma); + } + } + + if (data->include_type_oids) + appendStringInfo(&coltypeoids, "%s%u", comma, typid); + + ReleaseSysCache(type_tuple); + + if (!replident && data->include_column_positions) + appendStringInfo(&colpositions, "%s%d", comma, attr->attnum); + + /* + * Print default for columns. + */ + if (!replident && data->include_default) + { +#if PG_VERSION_NUM >= 120000 + if (attr->atthasdef && attr->attgenerated == '\0') +#else + if (attr->atthasdef) +#endif + { + ScanKeyData scankeys[2]; + SysScanDesc scan; + HeapTuple def_tuple; + Datum def_value; + bool attisnull; + char *result; + + ScanKeyInit(&scankeys[0], + Anum_pg_attrdef_adrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(relation->rd_id)); + ScanKeyInit(&scankeys[1], + Anum_pg_attrdef_adnum, + BTEqualStrategyNumber, F_INT2EQ, + Int16GetDatum(attr->attnum)); + + scan = systable_beginscan(defrel, AttrDefaultIndexId, true, + NULL, 2, scankeys); + + def_tuple = systable_getnext(scan); + if (HeapTupleIsValid(def_tuple)) + { + def_value = fastgetattr(def_tuple, Anum_pg_attrdef_adbin, defrel->rd_att, &attisnull); + + if (!attisnull) + { + result = TextDatumGetCString(DirectFunctionCall2(pg_get_expr, + def_value, + ObjectIdGetDatum(relation->rd_id))); + + appendStringInfo(&coldefaults, "%s\"%s\"", comma, result); + pfree(result); + } + else + { + /* + * null means that default was not set. Is it possible? + * atthasdef shouldn't be set. + */ + appendStringInfo(&coldefaults, "%snull", comma); + } + } + + systable_endscan(scan); + } + else + { + /* + * no DEFAULT clause implicitly means that the default is NULL + */ + appendStringInfo(&coldefaults, "%snull", comma); + } + } + + if (isnull) + { + appendStringInfo(&colvalues, "%snull", comma); + } + else + { + if (typisvarlena) + val = PointerGetDatum(PG_DETOAST_DATUM(origval)); + else + val = origval; + + /* Finally got the value */ + outputstr = OidOutputFunctionCall(typoutput, val); + + /* + * Data types are printed with quotes unless they are number, true, + * false, null, an array or an object. + * + * The NaN and Infinity are not valid JSON symbols. Hence, + * regardless of sign they are represented as the string null. + * + * Exception to this is when data->numeric_data_types_as_string is + * true. In this case, numbers (including NaN and Infinity values) + * are printed with quotes. + */ + switch (typid) + { + case INT2OID: + case INT4OID: + case INT8OID: + case OIDOID: + case FLOAT4OID: + case FLOAT8OID: + case NUMERICOID: + if (data->numeric_data_types_as_string) { + if (strspn(outputstr, "0123456789+-eE.") == strlen(outputstr) || + pg_strncasecmp(outputstr, "NaN", 3) == 0 || + pg_strncasecmp(outputstr, "Infinity", 8) == 0 || + pg_strncasecmp(outputstr, "-Infinity", 9) == 0) { + appendStringInfo(&colvalues, "%s", comma); + escape_json(&colvalues, outputstr); + } else { + elog(ERROR, "%s is not a number", outputstr); + } + } + else if (pg_strncasecmp(outputstr, "NaN", 3) == 0 || + pg_strncasecmp(outputstr, "Infinity", 8) == 0 || + pg_strncasecmp(outputstr, "-Infinity", 9) == 0) + { + appendStringInfo(&colvalues, "%snull", comma); + elog(DEBUG1, "attribute \"%s\" is special: %s", NameStr(attr->attname), outputstr); + } + else if (strspn(outputstr, "0123456789+-eE.") == strlen(outputstr)) + appendStringInfo(&colvalues, "%s%s", comma, outputstr); + else + elog(ERROR, "%s is not a number", outputstr); + break; + case BOOLOID: + if (strcmp(outputstr, "t") == 0) + appendStringInfo(&colvalues, "%strue", comma); + else + appendStringInfo(&colvalues, "%sfalse", comma); + break; + case BYTEAOID: + appendStringInfo(&colvalues, "%s", comma); + /* string is "\x54617069727573", start after "\x" */ + escape_json(&colvalues, (outputstr + 2)); + break; + default: + appendStringInfo(&colvalues, "%s", comma); + escape_json(&colvalues, outputstr); + break; + } + } + + /* The first column does not have comma */ + if (strcmp(comma, "") == 0) + snprintf(comma, 3, ",%s", data->sp); + } + + if (!replident && data->include_default) + { +#if PG_VERSION_NUM >= 120000 + table_close(defrel, AccessShareLock); +#else + heap_close(defrel, AccessShareLock); +#endif + } + + /* Column info ends */ + if (replident) + { + appendStringInfo(&colnames, "],%s", data->nl); + if (data->include_types) + appendStringInfo(&coltypes, "],%s", data->nl); + if (data->include_type_oids) + appendStringInfo(&coltypeoids, "],%s", data->nl); + appendStringInfo(&colvalues, "]%s", data->nl); + appendStringInfo(&colvalues, "%s%s%s}%s", data->ht, data->ht, data->ht, data->nl); + } + else + { + appendStringInfo(&colnames, "],%s", data->nl); + if (data->include_types) + appendStringInfo(&coltypes, "],%s", data->nl); + if (data->include_type_oids) + appendStringInfo(&coltypeoids, "],%s", data->nl); + if (data->include_column_positions) + appendStringInfo(&colpositions, "],%s", data->nl); + if (data->include_not_null) + appendStringInfo(&colnotnulls, "],%s", data->nl); + if (data->include_default) + appendStringInfo(&coldefaults, "],%s", data->nl); + if (addcomma) + appendStringInfo(&colvalues, "],%s", data->nl); + else + appendStringInfo(&colvalues, "]%s", data->nl); + } + + /* Print data */ + appendStringInfoString(ctx->out, colnames.data); + if (data->include_types) + appendStringInfoString(ctx->out, coltypes.data); + if (data->include_type_oids) + appendStringInfoString(ctx->out, coltypeoids.data); + if (data->include_column_positions) + appendStringInfoString(ctx->out, colpositions.data); + if (data->include_not_null) + appendStringInfoString(ctx->out, colnotnulls.data); + if (data->include_default) + appendStringInfoString(ctx->out, coldefaults.data); + appendStringInfoString(ctx->out, colvalues.data); + + pfree(colnames.data); + pfree(coltypes.data); + if (data->include_type_oids) + pfree(coltypeoids.data); + if (data->include_column_positions) + pfree(colpositions.data); + if (data->include_not_null) + pfree(colnotnulls.data); + if (data->include_default) + pfree(coldefaults.data); + pfree(colvalues.data); +} + +/* Print columns information */ +static void +columns_to_stringinfo(LogicalDecodingContext *ctx, TupleDesc tupdesc, HeapTuple tuple, bool addcomma, Relation relation) +{ + tuple_to_stringinfo(ctx, tupdesc, tuple, NULL, false, addcomma, relation); +} + +/* Print replica identity information */ +static void +identity_to_stringinfo(LogicalDecodingContext *ctx, TupleDesc tupdesc, HeapTuple tuple, Bitmapset *bs) +{ + /* Last parameter does not matter */ + tuple_to_stringinfo(ctx, tupdesc, tuple, bs, true, false, NULL); +} + +/* Print primary key information */ +static void +pk_to_stringinfo(LogicalDecodingContext *ctx, TupleDesc tupdesc, HeapTuple tuple, Bitmapset *bs, bool addcomma) +{ + JsonDecodingData *data; + int natt; + char comma[3] = ""; + + StringInfoData pknames; + StringInfoData pktypes; + + data = ctx->output_plugin_private; + + initStringInfo(&pknames); + initStringInfo(&pktypes); + + appendStringInfo(&pknames, "%s%s%s\"pk\":%s{%s", data->ht, data->ht, data->ht, data->sp, data->nl); + appendStringInfo(&pknames, "%s%s%s%s\"pknames\":%s[", data->ht, data->ht, data->ht, data->ht, data->sp); + appendStringInfo(&pktypes, "%s%s%s%s\"pktypes\":%s[", data->ht, data->ht, data->ht, data->ht, data->sp); + + /* Print column information (name, type, value) */ + for (natt = 0; natt < tupdesc->natts; natt++) + { + Form_pg_attribute attr; /* the attribute itself */ + Oid typid; /* type of current attribute */ + HeapTuple type_tuple; /* information about a type */ + + /* + * Commit d34a74dd064af959acd9040446925d9d53dff15b introduced + * TupleDescAttr() in back branches. If the version supports + * this macro, use it. Version 10 and later already support it. + */ +#if (PG_VERSION_NUM >= 90600 && PG_VERSION_NUM < 90605) || (PG_VERSION_NUM >= 90500 && PG_VERSION_NUM < 90509) || (PG_VERSION_NUM >= 90400 && PG_VERSION_NUM < 90414) + attr = tupdesc->attrs[natt]; +#else + attr = TupleDescAttr(tupdesc, natt); +#endif + + /* Do not print dropped or system columns */ + if (attr->attisdropped || attr->attnum < 0) + continue; + + /* Primary key column? */ + if (bs != NULL && !bms_is_member(attr->attnum - FirstLowInvalidHeapAttributeNumber, bs)) + continue; + + typid = attr->atttypid; + + /* Figure out type name */ + type_tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid)); + if (!HeapTupleIsValid(type_tuple)) + elog(ERROR, "cache lookup failed for type %u", typid); + + /* Accumulate each column info */ + appendStringInfo(&pknames, "%s", comma); + escape_json(&pknames, NameStr(attr->attname)); + + if (data->include_types) + { + char *type_str; + Form_pg_type type_form = (Form_pg_type) GETSTRUCT(type_tuple); + + /* + * It is a domain. Replace domain name with base data type if + * include_domain_data_type is enabled. + */ + if (type_form->typtype == TYPTYPE_DOMAIN && data->include_domain_data_type) + { + typid = type_form->typbasetype; + if (data->include_typmod) + { + type_str = format_type_with_typemod(type_form->typbasetype, type_form->typtypmod); + } + else + { + /* + * Since we are not using a format function, grab base type + * name from Form_pg_type. + */ + type_tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid)); + if (!HeapTupleIsValid(type_tuple)) + elog(ERROR, "cache lookup failed for type %u", typid); + type_form = (Form_pg_type) GETSTRUCT(type_tuple); + type_str = pstrdup(NameStr(type_form->typname)); + } + } + else + { + if (data->include_typmod) + type_str = TextDatumGetCString(DirectFunctionCall2(format_type, attr->atttypid, attr->atttypmod)); + else + type_str = pstrdup(NameStr(type_form->typname)); + } + + appendStringInfo(&pktypes, "%s", comma); + /* + * format_type() returns a quoted identifier, if + * required. In this case, it doesn't need to enclose the type name + * in double quotes. + */ + if (type_str[0] == '"') + appendStringInfo(&pktypes, "%s", type_str); + else + escape_json(&pktypes, type_str); + + pfree(type_str); + } + + ReleaseSysCache(type_tuple); + + /* The first column does not have comma */ + if (strcmp(comma, "") == 0) + snprintf(comma, 3, ",%s", data->sp); + } + + appendStringInfo(&pknames, "],%s", data->nl); + appendStringInfo(&pktypes, "]%s", data->nl); + if (addcomma) + appendStringInfo(&pktypes, "%s%s%s},%s", data->ht, data->ht, data->ht, data->nl); + else + appendStringInfo(&pktypes, "%s%s%s}%s", data->ht, data->ht, data->ht, data->nl); + + appendStringInfoString(ctx->out, pknames.data); + appendStringInfoString(ctx->out, pktypes.data); + + pfree(pknames.data); + pfree(pktypes.data); +} + +static bool +pg_filter_by_action(int change_type, JsonAction actions) +{ + if (change_type == REORDER_BUFFER_CHANGE_INSERT && !actions.insert) + { + elog(DEBUG3, "ignore INSERT"); + return true; + } + if (change_type == REORDER_BUFFER_CHANGE_UPDATE && !actions.update) + { + elog(DEBUG3, "ignore UPDATE"); + return true; + } + if (change_type == REORDER_BUFFER_CHANGE_DELETE && !actions.delete) + { + elog(DEBUG3, "ignore DELETE"); + return true; + } + + return false; +} + +static bool +pg_filter_by_table(List *filter_tables, char *schemaname, char *tablename) +{ + if (list_length(filter_tables) > 0) + { + ListCell *lc; + + foreach(lc, filter_tables) + { + SelectTable *t = lfirst(lc); + + if (t->allschemas || strcmp(t->schemaname, schemaname) == 0) + { + if (t->alltables || strcmp(t->tablename, tablename) == 0) + { + elog(DEBUG2, "\"%s\".\"%s\" was filtered out", + ((t->allschemas) ? "*" : t->schemaname), + ((t->alltables) ? "*" : t->tablename)); + return true; + } + } + } + } + + return false; +} + +static bool +pg_add_by_table(List *add_tables, char *schemaname, char *tablename) +{ + if (list_length(add_tables) > 0) + { + ListCell *lc; + + /* all tables in all schemas are added by default */ + foreach(lc, add_tables) + { + SelectTable *t = lfirst(lc); + + if (t->allschemas || strcmp(t->schemaname, schemaname) == 0) + { + if (t->alltables || strcmp(t->tablename, tablename) == 0) + { + elog(DEBUG2, "\"%s\".\"%s\" was added", + ((t->allschemas) ? "*" : t->schemaname), + ((t->alltables) ? "*" : t->tablename)); + return true; + } + } + } + } + + return false; +} + +/* Callback for individual changed tuples */ +static void +pg_decode_change(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, + Relation relation, ReorderBufferChange *change) +{ + JsonDecodingData *data = ctx->output_plugin_private; + +#if PG_VERSION_NUM >= 150000 && PG_VERSION_NUM < 160000 + update_replication_progress(ctx, false); +#elif PG_VERSION_NUM >= 140004 && PG_VERSION_NUM < 150000 + update_replication_progress(ctx); +#elif PG_VERSION_NUM >= 130008 && PG_VERSION_NUM < 140000 + update_replication_progress(ctx); +#elif PG_VERSION_NUM >= 120012 && PG_VERSION_NUM < 130000 + update_replication_progress(ctx); +#elif PG_VERSION_NUM >= 110017 && PG_VERSION_NUM < 120000 + update_replication_progress(ctx); +#elif PG_VERSION_NUM >= 100022 && PG_VERSION_NUM < 110000 + update_replication_progress(ctx); +#endif + + if (data->format_version == 2) + pg_decode_change_v2(ctx, txn, relation, change); + else if (data->format_version == 1) + pg_decode_change_v1(ctx, txn, relation, change); + else + elog(ERROR, "format version %d is not supported", data->format_version); +} + +static void +pg_decode_change_v1(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, + Relation relation, ReorderBufferChange *change) +{ + JsonDecodingData *data; + Form_pg_class class_form; + TupleDesc tupdesc; + MemoryContext old; + + Bitmapset *pkbs = NULL; + Bitmapset *ribs = NULL; + + char *schemaname; + char *tablename; + + AssertVariableIsOfType(&pg_decode_change, LogicalDecodeChangeCB); + + data = ctx->output_plugin_private; + + /* filter changes by action */ + if (pg_filter_by_action(change->action, data->actions)) + return; + + class_form = RelationGetForm(relation); + tupdesc = RelationGetDescr(relation); + + /* Avoid leaking memory by using and resetting our own context */ + old = MemoryContextSwitchTo(data->context); + + /* schema and table names are used for select tables */ + schemaname = get_namespace_name(class_form->relnamespace); + tablename = NameStr(class_form->relname); + + if (data->write_in_chunks) + OutputPluginPrepareWrite(ctx, true); + + /* Make sure rd_replidindex is set */ + RelationGetIndexList(relation); + + /* Filter tables, if available */ + if (pg_filter_by_table(data->filter_tables, schemaname, tablename)) + { + MemoryContextSwitchTo(old); + MemoryContextReset(data->context); + return; + } + + /* Add tables */ + if (!pg_add_by_table(data->add_tables, schemaname, tablename)) + { + MemoryContextSwitchTo(old); + MemoryContextReset(data->context); + return; + } + + switch (change->action) + { + case REORDER_BUFFER_CHANGE_INSERT: + if (change->data.tp.newtuple == NULL) + { + elog(WARNING, "no tuple data for INSERT in table \"%s\"", NameStr(class_form->relname)); + MemoryContextSwitchTo(old); + MemoryContextReset(data->context); + return; + } + break; + case REORDER_BUFFER_CHANGE_UPDATE: + /* + * Bail out iif: + * (i) doesn't have a pk and replica identity is not full; + * (ii) replica identity is nothing. + */ + if (!OidIsValid(relation->rd_replidindex) && relation->rd_rel->relreplident != REPLICA_IDENTITY_FULL) + { + /* FIXME this sentence is imprecise */ + elog(WARNING, "table \"%s\" without primary key or replica identity is nothing", NameStr(class_form->relname)); + MemoryContextSwitchTo(old); + MemoryContextReset(data->context); + return; + } + + if (change->data.tp.newtuple == NULL) + { + elog(WARNING, "no tuple data for UPDATE in table \"%s\"", NameStr(class_form->relname)); + MemoryContextSwitchTo(old); + MemoryContextReset(data->context); + return; + } + break; + case REORDER_BUFFER_CHANGE_DELETE: + /* + * Bail out iif: + * (i) doesn't have a pk and replica identity is not full; + * (ii) replica identity is nothing. + */ + if (!OidIsValid(relation->rd_replidindex) && relation->rd_rel->relreplident != REPLICA_IDENTITY_FULL) + { + /* FIXME this sentence is imprecise */ + elog(WARNING, "table \"%s\" without primary key or replica identity is nothing", NameStr(class_form->relname)); + MemoryContextSwitchTo(old); + MemoryContextReset(data->context); + return; + } + + if (change->data.tp.oldtuple == NULL) + { + elog(WARNING, "no tuple data for DELETE in table \"%s\"", NameStr(class_form->relname)); + MemoryContextSwitchTo(old); + MemoryContextReset(data->context); + return; + } + break; + default: + Assert(false); + } + + /* Change counter */ + data->nr_changes++; + + /* if we don't write in chunks, we need a newline here */ + if (!data->write_in_chunks) + appendStringInfo(ctx->out, "%s", data->nl); + + appendStringInfo(ctx->out, "%s%s", data->ht, data->ht); + + if (data->nr_changes > 1) + appendStringInfoChar(ctx->out, ','); + + appendStringInfo(ctx->out, "{%s", data->nl); + + /* Print change kind */ + switch (change->action) + { + case REORDER_BUFFER_CHANGE_INSERT: + appendStringInfo(ctx->out, "%s%s%s\"kind\":%s\"insert\",%s", data->ht, data->ht, data->ht, data->sp, data->nl); + break; + case REORDER_BUFFER_CHANGE_UPDATE: + appendStringInfo(ctx->out, "%s%s%s\"kind\":%s\"update\",%s", data->ht, data->ht, data->ht, data->sp, data->nl); + break; + case REORDER_BUFFER_CHANGE_DELETE: + appendStringInfo(ctx->out, "%s%s%s\"kind\":%s\"delete\",%s", data->ht, data->ht, data->ht, data->sp, data->nl); + break; + default: + Assert(false); + } + + /* Print table name (possibly) qualified */ + if (data->include_schemas) + { + appendStringInfo(ctx->out, "%s%s%s\"schema\":%s", data->ht, data->ht, data->ht, data->sp); + escape_json(ctx->out, get_namespace_name(class_form->relnamespace)); + appendStringInfo(ctx->out, ",%s", data->nl); + } + appendStringInfo(ctx->out, "%s%s%s\"table\":%s", data->ht, data->ht, data->ht, data->sp); + escape_json(ctx->out, NameStr(class_form->relname)); + appendStringInfo(ctx->out, ",%s", data->nl); + + if (data->include_pk) +#if PG_VERSION_NUM >= 100000 + pkbs = RelationGetIndexAttrBitmap(relation, INDEX_ATTR_BITMAP_PRIMARY_KEY); +#else + pkbs = RelationGetIndexAttrBitmap(relation, INDEX_ATTR_BITMAP_KEY); +#endif + + switch (change->action) + { + case REORDER_BUFFER_CHANGE_INSERT: + /* Print the new tuple */ +#if PG_VERSION_NUM >= 100000 + if (data->include_pk && OidIsValid(relation->rd_pkindex)) +#else + if (data->include_pk && OidIsValid(relation->rd_replidindex) && + relation->rd_rel->relreplident == REPLICA_IDENTITY_DEFAULT) +#endif + { +#if PG_VERSION_NUM >= 170000 + columns_to_stringinfo(ctx, tupdesc, change->data.tp.newtuple, true, relation); + pk_to_stringinfo(ctx, tupdesc, change->data.tp.newtuple, pkbs, false); +#else + columns_to_stringinfo(ctx, tupdesc, &change->data.tp.newtuple->tuple, true, relation); + pk_to_stringinfo(ctx, tupdesc, &change->data.tp.newtuple->tuple, pkbs, false); +#endif + } + else + { +#if PG_VERSION_NUM >= 170000 + columns_to_stringinfo(ctx, tupdesc, change->data.tp.newtuple, false, relation); +#else + columns_to_stringinfo(ctx, tupdesc, &change->data.tp.newtuple->tuple, false, relation); +#endif + } + break; + case REORDER_BUFFER_CHANGE_UPDATE: + /* Print the new tuple */ +#if PG_VERSION_NUM >= 170000 + columns_to_stringinfo(ctx, tupdesc, change->data.tp.newtuple, true, relation); +#else + columns_to_stringinfo(ctx, tupdesc, &change->data.tp.newtuple->tuple, true, relation); +#endif + +#if PG_VERSION_NUM >= 100000 + if (data->include_pk && OidIsValid(relation->rd_pkindex)) +#else + if (data->include_pk && OidIsValid(relation->rd_replidindex) && + relation->rd_rel->relreplident == REPLICA_IDENTITY_DEFAULT) +#endif + { +#if PG_VERSION_NUM >= 170000 + pk_to_stringinfo(ctx, tupdesc, change->data.tp.newtuple, pkbs, true); +#else + pk_to_stringinfo(ctx, tupdesc, &change->data.tp.newtuple->tuple, pkbs, true); +#endif + } + + /* + * The old tuple is available when: + * (i) pk changes; + * (ii) replica identity is full; + * (iii) replica identity is index and indexed column changes. + * + * FIXME if old tuple is not available we must get only the indexed + * columns (the whole tuple is printed). + */ + if (change->data.tp.oldtuple == NULL) + { + elog(DEBUG1, "old tuple is null"); + + ribs = RelationGetIndexAttrBitmap(relation, INDEX_ATTR_BITMAP_IDENTITY_KEY); +#if PG_VERSION_NUM >= 170000 + identity_to_stringinfo(ctx, tupdesc, change->data.tp.newtuple, ribs); +#else + identity_to_stringinfo(ctx, tupdesc, &change->data.tp.newtuple->tuple, ribs); +#endif + } + else + { + elog(DEBUG1, "old tuple is not null"); +#if PG_VERSION_NUM >= 170000 + identity_to_stringinfo(ctx, tupdesc, change->data.tp.oldtuple, NULL); +#else + identity_to_stringinfo(ctx, tupdesc, &change->data.tp.oldtuple->tuple, NULL); +#endif + } + break; + case REORDER_BUFFER_CHANGE_DELETE: +#if PG_VERSION_NUM >= 100000 + if (data->include_pk && OidIsValid(relation->rd_pkindex)) +#else + if (data->include_pk && OidIsValid(relation->rd_replidindex) && + relation->rd_rel->relreplident == REPLICA_IDENTITY_DEFAULT) +#endif + { +#if PG_VERSION_NUM >= 170000 + pk_to_stringinfo(ctx, tupdesc, change->data.tp.oldtuple, pkbs, true); +#else + pk_to_stringinfo(ctx, tupdesc, &change->data.tp.oldtuple->tuple, pkbs, true); +#endif + } + + ribs = RelationGetIndexAttrBitmap(relation, INDEX_ATTR_BITMAP_IDENTITY_KEY); +#if PG_VERSION_NUM >= 170000 + identity_to_stringinfo(ctx, tupdesc, change->data.tp.oldtuple, ribs); +#else + identity_to_stringinfo(ctx, tupdesc, &change->data.tp.oldtuple->tuple, ribs); +#endif + + if (change->data.tp.oldtuple == NULL) + elog(DEBUG1, "old tuple is null"); + else + elog(DEBUG1, "old tuple is not null"); + break; + default: + Assert(false); + } + + bms_free(pkbs); + bms_free(ribs); + + appendStringInfo(ctx->out, "%s%s}", data->ht, data->ht); + + MemoryContextSwitchTo(old); + MemoryContextReset(data->context); + + if (data->write_in_chunks) + OutputPluginWrite(ctx, true); +} + +static void +pg_decode_write_value(LogicalDecodingContext *ctx, Datum value, bool isnull, Oid typid) +{ + JsonDecodingData *data; + Oid typoutfunc; + bool isvarlena; + char *outstr; + + data = ctx->output_plugin_private; + + if (isnull) + { + appendStringInfoString(ctx->out, "null"); + return; + } + + /* get type information and call its output function */ + getTypeOutputInfo(typid, &typoutfunc, &isvarlena); + + /* XXX dead code? check is one level above. */ + if (isvarlena && VARATT_IS_EXTERNAL_ONDISK(value)) + { + elog(DEBUG1, "unchanged TOAST Datum"); + return; + } + + /* if value is varlena, detoast Datum */ + if (isvarlena) + { + Datum detoastedval; + + detoastedval = PointerGetDatum(PG_DETOAST_DATUM(value)); + outstr = OidOutputFunctionCall(typoutfunc, detoastedval); + } + else + { + outstr = OidOutputFunctionCall(typoutfunc, value); + } + + /* + * Data types are printed with quotes unless they are number, true, false, + * null, an array or an object. + * + * The NaN an Infinity are not valid JSON symbols. Hence, regardless of + * sign they are represented as the string null. + * + * Exception to this is when data->numeric_data_types_as_string is + * true. In this case, numbers (including NaN and Infinity values) + * are printed with quotes. + */ + switch (typid) + { + case INT2OID: + case INT4OID: + case INT8OID: + case OIDOID: + case FLOAT4OID: + case FLOAT8OID: + case NUMERICOID: + if (data->numeric_data_types_as_string) { + if (strspn(outstr, "0123456789+-eE.") == strlen(outstr) || + pg_strncasecmp(outstr, "NaN", 3) == 0 || + pg_strncasecmp(outstr, "Infinity", 8) == 0 || + pg_strncasecmp(outstr, "-Infinity", 9) == 0) { + escape_json(ctx->out, outstr); + } else { + elog(ERROR, "%s is not a number", outstr); + } + } + else if (pg_strncasecmp(outstr, "NaN", 3) == 0 || + pg_strncasecmp(outstr, "Infinity", 8) == 0 || + pg_strncasecmp(outstr, "-Infinity", 9) == 0) + { + appendStringInfoString(ctx->out, "null"); + elog(DEBUG1, "special value: %s", outstr); + } + else if (strspn(outstr, "0123456789+-eE.") == strlen(outstr)) + appendStringInfo(ctx->out, "%s", outstr); + else + elog(ERROR, "%s is not a number", outstr); + break; + case BOOLOID: + if (strcmp(outstr, "t") == 0) + appendStringInfoString(ctx->out, "true"); + else + appendStringInfoString(ctx->out, "false"); + break; + case BYTEAOID: + /* string is "\x54617069727573", start after \x */ + escape_json(ctx->out, (outstr + 2)); + break; + default: + escape_json(ctx->out, outstr); + break; + } + + pfree(outstr); +} + +static void +pg_decode_write_tuple(LogicalDecodingContext *ctx, Relation relation, HeapTuple tuple, PGOutputJsonKind kind) +{ + JsonDecodingData *data; + TupleDesc tupdesc; + Relation defrel = NULL; + Bitmapset *bs = NULL; + int i; + Datum *values; + bool *nulls; + bool need_sep = false; + + data = ctx->output_plugin_private; + + tupdesc = RelationGetDescr(relation); + values = (Datum *) palloc(tupdesc->natts * sizeof(Datum)); + nulls = (bool *) palloc(tupdesc->natts * sizeof(bool)); + + /* break down the tuple into fields */ + heap_deform_tuple(tuple, tupdesc, values, nulls); + + /* figure out replica identity columns */ + if (kind == PGOUTPUTJSON_IDENTITY) + { + bs = RelationGetIndexAttrBitmap(relation, INDEX_ATTR_BITMAP_IDENTITY_KEY); + } + else if (kind == PGOUTPUTJSON_PK) + { +#if PG_VERSION_NUM >= 100000 + bs = RelationGetIndexAttrBitmap(relation, INDEX_ATTR_BITMAP_PRIMARY_KEY); +#else + bs = RelationGetIndexAttrBitmap(relation, INDEX_ATTR_BITMAP_KEY); +#endif + } + + /* open pg_attrdef in preparation to get default values from columns */ + if (kind == PGOUTPUTJSON_CHANGE && data->include_default) + { +#if PG_VERSION_NUM >= 120000 + defrel = table_open(AttrDefaultRelationId, AccessShareLock); +#else + defrel = heap_open(AttrDefaultRelationId, AccessShareLock); +#endif + } + + for (i = 0; i < tupdesc->natts; i++) + { + Form_pg_attribute attr; + +#if (PG_VERSION_NUM >= 90600 && PG_VERSION_NUM < 90605) || (PG_VERSION_NUM >= 90500 && PG_VERSION_NUM < 90509) || (PG_VERSION_NUM >= 90400 && PG_VERSION_NUM < 90414) + attr = tupdesc->attrs[i]; +#else + attr = TupleDescAttr(tupdesc, i); +#endif + + /* skip dropped or system columns */ + if (attr->attisdropped || attr->attnum < 0) + continue; + + if (bs != NULL && !bms_is_member(attr->attnum - FirstLowInvalidHeapAttributeNumber, bs)) + continue; + + /* don't send unchanged TOAST Datum */ + if (!nulls[i] && attr->attlen == -1 && VARATT_IS_EXTERNAL_ONDISK(values[i])) + continue; + + if (need_sep) + appendStringInfoChar(ctx->out, ','); + need_sep = true; + + appendStringInfoChar(ctx->out, '{'); + appendStringInfoString(ctx->out, "\"name\":"); + escape_json(ctx->out, NameStr(attr->attname)); + + /* type name (with typmod, if available) */ + if (data->include_types) + { + HeapTuple type_tuple; + Form_pg_type type_form; + char *type_str; + int len; + + type_tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(attr->atttypid)); + type_form = (Form_pg_type) GETSTRUCT(type_tuple); + + /* + * It is a domain. Replace domain name with base data type if + * include_domain_data_type is enabled. + */ + if (type_form->typtype == TYPTYPE_DOMAIN && data->include_domain_data_type) + type_str = format_type_with_typemod(type_form->typbasetype, type_form->typtypmod); + else + type_str = format_type_with_typemod(attr->atttypid, attr->atttypmod); + + appendStringInfoString(ctx->out, ",\"type\":"); + /* + * format_type_with_typemod() returns a quoted identifier, if + * required. In this case, it doesn't need to enclose the type name + * in double quotes. However, if it is an array type, it should + * escape it because the brackets are outside the double quotes. + */ + len = strlen(type_str); + if (type_str[0] == '"' && type_str[len -1] != ']') + appendStringInfo(ctx->out, "%s", type_str); + else + escape_json(ctx->out, type_str); + pfree(type_str); + + ReleaseSysCache(type_tuple); + } + + /* + * Print type oid for columns. + */ + if (data->include_type_oids) + { + appendStringInfoString(ctx->out, ",\"typeoid\":"); + appendStringInfo(ctx->out, "%d", attr->atttypid); + } + + if (kind != PGOUTPUTJSON_PK) + { + appendStringInfoString(ctx->out, ",\"value\":"); + pg_decode_write_value(ctx, values[i], nulls[i], attr->atttypid); + } + + /* + * Print optional for columns. This information is redundant for + * replica identity (index) because all attributes are not null. + */ + if (kind == PGOUTPUTJSON_CHANGE && data->include_not_null) + { + if (attr->attnotnull) + appendStringInfoString(ctx->out, ",\"optional\":false"); + else + appendStringInfoString(ctx->out, ",\"optional\":true"); + } + + /* + * Print position for columns. Positions are only available for new + * tuple (INSERT, UPDATE). + */ + if (kind == PGOUTPUTJSON_CHANGE && data->include_column_positions) + { + appendStringInfoString(ctx->out, ",\"position\":"); + appendStringInfo(ctx->out, "%d", attr->attnum); + } + + /* + * Print default for columns. + */ + if (kind == PGOUTPUTJSON_CHANGE && data->include_default) + { +#if PG_VERSION_NUM >= 120000 + if (attr->atthasdef && attr->attgenerated == '\0') +#else + if (attr->atthasdef) +#endif + { + ScanKeyData scankeys[2]; + SysScanDesc scan; + HeapTuple def_tuple; + Datum def_value; + bool isnull; + char *result; + + ScanKeyInit(&scankeys[0], + Anum_pg_attrdef_adrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(relation->rd_id)); + ScanKeyInit(&scankeys[1], + Anum_pg_attrdef_adnum, + BTEqualStrategyNumber, F_INT2EQ, + Int16GetDatum(attr->attnum)); + + scan = systable_beginscan(defrel, AttrDefaultIndexId, true, + NULL, 2, scankeys); + + def_tuple = systable_getnext(scan); + if (HeapTupleIsValid(def_tuple)) + { + def_value = fastgetattr(def_tuple, Anum_pg_attrdef_adbin, defrel->rd_att, &isnull); + + if (!isnull) + { + result = TextDatumGetCString(DirectFunctionCall2(pg_get_expr, + def_value, + ObjectIdGetDatum(relation->rd_id))); + + appendStringInfoString(ctx->out, ",\"default\":"); + appendStringInfo(ctx->out, "\"%s\"", result); + pfree(result); + } + else + { + /* + * null means that default was not set. Is it possible? + * atthasdef shouldn't be set. + */ + appendStringInfoString(ctx->out, ",\"default\":null"); + } + } + + systable_endscan(scan); + } + else + { + /* + * no DEFAULT clause implicitly means that the default is NULL + */ + appendStringInfoString(ctx->out, ",\"default\":null"); + } + } + + appendStringInfoChar(ctx->out, '}'); + } + + /* close pg_attrdef */ + if (kind == PGOUTPUTJSON_CHANGE && data->include_default) + { +#if PG_VERSION_NUM >= 120000 + table_close(defrel, AccessShareLock); +#else + heap_close(defrel, AccessShareLock); +#endif + } + + bms_free(bs); + + pfree(values); + pfree(nulls); +} + +static void +pg_decode_write_change(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, Relation relation, ReorderBufferChange *change) +{ + JsonDecodingData *data = ctx->output_plugin_private; + + /* make sure rd_pkindex and rd_replidindex are set */ + RelationGetIndexList(relation); + + switch (change->action) + { + case REORDER_BUFFER_CHANGE_INSERT: + if (change->data.tp.newtuple == NULL) + { + elog(WARNING, "no tuple data for INSERT in table \"%s\".\"%s\"", get_namespace_name(RelationGetNamespace(relation)), RelationGetRelationName(relation)); + return; + } + break; + case REORDER_BUFFER_CHANGE_UPDATE: + if (change->data.tp.newtuple == NULL) + { + elog(WARNING, "no tuple data for UPDATE in table \"%s\".\"%s\"", get_namespace_name(RelationGetNamespace(relation)), RelationGetRelationName(relation)); + return; + } + if (change->data.tp.oldtuple == NULL) + { + if (!OidIsValid(relation->rd_replidindex) && relation->rd_rel->relreplident != REPLICA_IDENTITY_FULL) + { + elog(WARNING, "no tuple identifier for UPDATE in table \"%s\".\"%s\"", get_namespace_name(RelationGetNamespace(relation)), RelationGetRelationName(relation)); + return; + } + } + break; + case REORDER_BUFFER_CHANGE_DELETE: + if (change->data.tp.oldtuple == NULL) + { + if (!OidIsValid(relation->rd_replidindex) && relation->rd_rel->relreplident != REPLICA_IDENTITY_FULL) + { + elog(WARNING, "no tuple identifier for DELETE in table \"%s\".\"%s\"", get_namespace_name(RelationGetNamespace(relation)), RelationGetRelationName(relation)); + return; + } + } + break; + default: + Assert(false); + } + + OutputPluginPrepareWrite(ctx, true); + + appendStringInfoChar(ctx->out, '{'); + + switch (change->action) + { + case REORDER_BUFFER_CHANGE_INSERT: + appendStringInfoString(ctx->out, "\"action\":\"I\""); + break; + case REORDER_BUFFER_CHANGE_UPDATE: + appendStringInfoString(ctx->out, "\"action\":\"U\""); + break; + case REORDER_BUFFER_CHANGE_DELETE: + appendStringInfoString(ctx->out, "\"action\":\"D\""); + break; + default: + Assert(false); + } + + if (data->include_xids) + appendStringInfo(ctx->out, ",\"xid\":%u", txn->xid); + +#if PG_VERSION_NUM >= 150000 + if (data->include_timestamp) + appendStringInfo(ctx->out, ",\"timestamp\":\"%s\"", timestamptz_to_str(txn->xact_time.commit_time)); +#else + if (data->include_timestamp) + appendStringInfo(ctx->out, ",\"timestamp\":\"%s\"", timestamptz_to_str(txn->commit_time)); +#endif + +#if PG_VERSION_NUM >= 90500 + if (data->include_origin) + appendStringInfo(ctx->out, ",\"origin\":%u", txn->origin_id); +#endif + + if (data->include_lsn) + { + char *lsn_str = DatumGetCString(DirectFunctionCall1(pg_lsn_out, UInt64GetDatum(change->lsn))); + appendStringInfo(ctx->out, ",\"lsn\":\"%s\"", lsn_str); + pfree(lsn_str); + } + + if (data->include_schemas) + { + appendStringInfo(ctx->out, ",\"schema\":"); + escape_json(ctx->out, get_namespace_name(RelationGetNamespace(relation))); + } + + appendStringInfo(ctx->out, ",\"table\":"); + escape_json(ctx->out, RelationGetRelationName(relation)); + + /* print new tuple (INSERT, UPDATE) */ + if (change->data.tp.newtuple != NULL) + { + appendStringInfoString(ctx->out, ",\"columns\":["); +#if PG_VERSION_NUM >= 170000 + pg_decode_write_tuple(ctx, relation, change->data.tp.newtuple, PGOUTPUTJSON_CHANGE); +#else + pg_decode_write_tuple(ctx, relation, &change->data.tp.newtuple->tuple, PGOUTPUTJSON_CHANGE); +#endif + appendStringInfoChar(ctx->out, ']'); + } + + /* + * Print old tuple (UPDATE, DELETE) + * + * old tuple is available when: + * (1) primary key changes; + * (2) replica identity is index and one of the indexed columns changes; + * (3) replica identity is full. + * + * If old tuple is not available (because (a) primary key does not change + * or (b) replica identity is index and none of indexed columns does not + * change) identity is obtained from new tuple (because it doesn't change). + * + */ + if (change->data.tp.oldtuple != NULL) + { + appendStringInfoString(ctx->out, ",\"identity\":["); +#if PG_VERSION_NUM >= 170000 + pg_decode_write_tuple(ctx, relation, change->data.tp.oldtuple, PGOUTPUTJSON_IDENTITY); +#else + pg_decode_write_tuple(ctx, relation, &change->data.tp.oldtuple->tuple, PGOUTPUTJSON_IDENTITY); +#endif + appendStringInfoChar(ctx->out, ']'); + } + else + { + /* + * Old tuple is not available, however, identity can be obtained from + * new tuple (because it doesn't change). + */ + if (change->action == REORDER_BUFFER_CHANGE_UPDATE) + { + elog(DEBUG2, "old tuple is null on UPDATE"); + + /* + * Before v10, there is not rd_pkindex then rely on REPLICA + * IDENTITY DEFAULT to obtain primary key. + */ +#if PG_VERSION_NUM >= 100000 + if (OidIsValid(relation->rd_pkindex) || OidIsValid(relation->rd_replidindex)) +#else + if (OidIsValid(relation->rd_replidindex)) +#endif + { + elog(DEBUG1, "REPLICA IDENTITY: obtain old tuple using new tuple"); + appendStringInfoString(ctx->out, ",\"identity\":["); +#if PG_VERSION_NUM >= 170000 + pg_decode_write_tuple(ctx, relation, change->data.tp.newtuple, PGOUTPUTJSON_IDENTITY); +#else + pg_decode_write_tuple(ctx, relation, &change->data.tp.newtuple->tuple, PGOUTPUTJSON_IDENTITY); +#endif + appendStringInfoChar(ctx->out, ']'); + } + else + { + /* old tuple is not available and can't be obtained, report it */ + elog(WARNING, "no old tuple data for UPDATE in table \"%s\".\"%s\"", get_namespace_name(RelationGetNamespace(relation)), RelationGetRelationName(relation)); + } + } + + /* old tuple is not available and can't be obtained, report it */ + if (change->action == REORDER_BUFFER_CHANGE_DELETE) + { + elog(WARNING, "no old tuple data for DELETE in table \"%s\".\"%s\"", get_namespace_name(RelationGetNamespace(relation)), RelationGetRelationName(relation)); + } + } + + if (data->include_pk) + { + appendStringInfoString(ctx->out, ",\"pk\":["); +#if PG_VERSION_NUM >= 100000 + if (OidIsValid(relation->rd_pkindex)) +#else + if (OidIsValid(relation->rd_replidindex) && relation->rd_rel->relreplident == REPLICA_IDENTITY_DEFAULT) +#endif + { +#if PG_VERSION_NUM >= 170000 + if (change->data.tp.oldtuple != NULL) + pg_decode_write_tuple(ctx, relation, change->data.tp.oldtuple, PGOUTPUTJSON_PK); + else + pg_decode_write_tuple(ctx, relation, change->data.tp.newtuple, PGOUTPUTJSON_PK); +#else + if (change->data.tp.oldtuple != NULL) + pg_decode_write_tuple(ctx, relation, &change->data.tp.oldtuple->tuple, PGOUTPUTJSON_PK); + else + pg_decode_write_tuple(ctx, relation, &change->data.tp.newtuple->tuple, PGOUTPUTJSON_PK); +#endif + } + appendStringInfoChar(ctx->out, ']'); + } + + appendStringInfoChar(ctx->out, '}'); + + OutputPluginWrite(ctx, true); +} + +static void +pg_decode_change_v2(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, + Relation relation, ReorderBufferChange *change) +{ + JsonDecodingData *data = ctx->output_plugin_private; + MemoryContext old; + + char *schemaname; + char *tablename; + + /* filter changes by action */ + if (pg_filter_by_action(change->action, data->actions)) + return; + + /* avoid leaking memory by using and resetting our own context */ + old = MemoryContextSwitchTo(data->context); + + /* schema and table names are used for chosen tables */ + schemaname = get_namespace_name(RelationGetNamespace(relation)); + tablename = RelationGetRelationName(relation); + + /* Exclude tables, if available */ + if (pg_filter_by_table(data->filter_tables, schemaname, tablename)) + { + MemoryContextSwitchTo(old); + MemoryContextReset(data->context); + return; + } + + /* Add tables */ + if (!pg_add_by_table(data->add_tables, schemaname, tablename)) + { + MemoryContextSwitchTo(old); + MemoryContextReset(data->context); + return; + } + + pg_decode_write_change(ctx, txn, relation, change); + + MemoryContextSwitchTo(old); + MemoryContextReset(data->context); +} + +#if PG_VERSION_NUM >= 90600 +/* Callback for generic logical decoding messages */ +static void +pg_decode_message(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, + XLogRecPtr lsn, bool transactional, const char *prefix, Size + content_size, const char *content) +{ + JsonDecodingData *data = ctx->output_plugin_private; + +#if PG_VERSION_NUM >= 150000 && PG_VERSION_NUM < 160000 + update_replication_progress(ctx, false); +#elif PG_VERSION_NUM >= 140004 && PG_VERSION_NUM < 150000 + update_replication_progress(ctx); +#elif PG_VERSION_NUM >= 130008 && PG_VERSION_NUM < 140000 + update_replication_progress(ctx); +#elif PG_VERSION_NUM >= 120012 && PG_VERSION_NUM < 130000 + update_replication_progress(ctx); +#elif PG_VERSION_NUM >= 110017 && PG_VERSION_NUM < 120000 + update_replication_progress(ctx); +#elif PG_VERSION_NUM >= 100022 && PG_VERSION_NUM < 110000 + update_replication_progress(ctx); +#endif + + /* Filter message prefixes, if available */ + if (list_length(data->filter_msg_prefixes) > 0) + { + ListCell *lc; + + foreach(lc, data->filter_msg_prefixes) + { + char *p = lfirst(lc); + + if (strcmp(p, prefix) == 0) + { + elog(DEBUG2, "message prefix \"%s\" was filtered out", p); + return; + } + } + } + + /* Add messages by prefix */ + if (list_length(data->add_msg_prefixes) > 0) + { + ListCell *lc; + bool skip = true; + + foreach(lc, data->add_msg_prefixes) + { + char *p = lfirst(lc); + + if (strcmp(p, prefix) == 0) + skip = false; + } + + if (skip) + { + elog(DEBUG2, "message prefix \"%s\" was skipped", prefix); + return; + } + } + + if (data->format_version == 2) + pg_decode_message_v2(ctx, txn, lsn, transactional, prefix, content_size, content); + else if (data->format_version == 1) + pg_decode_message_v1(ctx, txn, lsn, transactional, prefix, content_size, content); + else + elog(ERROR, "format version %d is not supported", data->format_version); +} + +static void +pg_decode_message_v1(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, + XLogRecPtr lsn, bool transactional, const char *prefix, Size + content_size, const char *content) +{ + JsonDecodingData *data; + MemoryContext old; + char *content_str; + + data = ctx->output_plugin_private; + + /* Avoid leaking memory by using and resetting our own context */ + old = MemoryContextSwitchTo(data->context); + + /* + * write immediately iif (i) write-in-chunks=1 or (ii) non-transactional + * messages. + */ + if (data->write_in_chunks || !transactional) + OutputPluginPrepareWrite(ctx, true); + + /* + * increment counter only for transactional messages because + * non-transactional message has only one object. + */ + if (transactional) + data->nr_changes++; + + /* if we don't write in chunks, we need a newline here */ + if (!data->write_in_chunks && transactional) + appendStringInfo(ctx->out, "%s", data->nl); + + /* build a complete JSON object for non-transactional message */ + if (!transactional) + appendStringInfo(ctx->out, "{%s%s\"change\":%s[%s", data->nl, data->ht, data->sp, data->nl); + + appendStringInfo(ctx->out, "%s%s", data->ht, data->ht); + + /* + * Non-transactional message contains only one object. Comma is not + * required. Avoid printing a comma for non-transactional messages that was + * provided in a transaction. + */ + if (transactional && data->nr_changes > 1) + appendStringInfoChar(ctx->out, ','); + + appendStringInfo(ctx->out, "{%s%s%s%s\"kind\":%s\"message\",%s", data->nl, data->ht, data->ht, data->ht, data->sp, data->nl); + + if (transactional) + appendStringInfo(ctx->out, "%s%s%s\"transactional\":%strue,%s", data->ht, data->ht, data->ht, data->sp, data->nl); + else + appendStringInfo(ctx->out, "%s%s%s\"transactional\":%sfalse,%s", data->ht, data->ht, data->ht, data->sp, data->nl); + + appendStringInfo(ctx->out, "%s%s%s\"prefix\":%s", data->ht, data->ht, data->ht, data->sp); + escape_json(ctx->out, prefix); + appendStringInfo(ctx->out, ",%s%s%s%s\"content\":%s", data->nl, data->ht, data->ht, data->ht, data->sp); + + content_str = (char *) palloc0((content_size + 1) * sizeof(char)); + strncpy(content_str, content, content_size); + escape_json(ctx->out, content_str); + pfree(content_str); + + appendStringInfo(ctx->out, "%s%s%s}", data->nl, data->ht, data->ht); + + /* build a complete JSON object for non-transactional message */ + if (!transactional) + appendStringInfo(ctx->out, "%s%s]%s}", data->nl, data->ht, data->nl); + + MemoryContextSwitchTo(old); + MemoryContextReset(data->context); + + if (data->write_in_chunks || !transactional) + OutputPluginWrite(ctx, true); +} + +static void +pg_decode_message_v2(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, + XLogRecPtr lsn, bool transactional, const char *prefix, Size + content_size, const char *content) +{ + JsonDecodingData *data = ctx->output_plugin_private; + MemoryContext old; + char *content_str; + + /* Avoid leaking memory by using and resetting our own context */ + old = MemoryContextSwitchTo(data->context); + + OutputPluginPrepareWrite(ctx, true); + appendStringInfoChar(ctx->out, '{'); + appendStringInfoString(ctx->out, "\"action\":\"M\""); + + if (data->include_xids) + { + /* + * Non-transactional messages can have no xid, hence, assigns null in + * this case. Assigns null for xid in non-transactional messages + * because in some cases there isn't an assigned xid. + * This same logic is valid for timestamp and origin. + */ + if (transactional) + appendStringInfo(ctx->out, ",\"xid\":%u", txn->xid); + else + appendStringInfoString(ctx->out, ",\"xid\":null"); + } + + if (data->include_timestamp) + { +#if PG_VERSION_NUM >= 150000 + if (transactional) + appendStringInfo(ctx->out, ",\"timestamp\":\"%s\"", timestamptz_to_str(txn->xact_time.commit_time)); +#else + if (transactional) + appendStringInfo(ctx->out, ",\"timestamp\":\"%s\"", timestamptz_to_str(txn->commit_time)); +#endif + else + appendStringInfoString(ctx->out, ",\"timestamp\":null"); + } + + if (data->include_origin) + { + if (transactional) + appendStringInfo(ctx->out, ",\"origin\":%u", txn->origin_id); + else + appendStringInfo(ctx->out, ",\"origin\":null"); + } + + if (data->include_lsn) + { + char *lsn_str = DatumGetCString(DirectFunctionCall1(pg_lsn_out, UInt64GetDatum(lsn))); + appendStringInfo(ctx->out, ",\"lsn\":\"%s\"", lsn_str); + pfree(lsn_str); + } + + if (transactional) + appendStringInfoString(ctx->out, ",\"transactional\":true"); + else + appendStringInfoString(ctx->out, ",\"transactional\":false"); + + appendStringInfoString(ctx->out, ",\"prefix\":"); + escape_json(ctx->out, prefix); + + appendStringInfoString(ctx->out, ",\"content\":"); + content_str = (char *) palloc0((content_size + 1) * sizeof(char)); + strncpy(content_str, content, content_size); + escape_json(ctx->out, content_str); + pfree(content_str); + + appendStringInfoChar(ctx->out, '}'); + OutputPluginWrite(ctx, true); + + MemoryContextSwitchTo(old); + MemoryContextReset(data->context); +} +#endif + +#if PG_VERSION_NUM >= 110000 +/* Callback for TRUNCATE command */ +static void pg_decode_truncate(LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, int n, Relation relations[], + ReorderBufferChange *change) +{ + JsonDecodingData *data = ctx->output_plugin_private; + + /* + * For back branches (10 to 15), update_replication_progress() should be called here. + * FIXME call OutputPluginUpdateProgress() for old minor versions? + */ +#if PG_VERSION_NUM >= 150000 && PG_VERSION_NUM < 160000 + update_replication_progress(ctx, false); +#elif PG_VERSION_NUM >= 140004 && PG_VERSION_NUM < 150000 + update_replication_progress(ctx); +#elif PG_VERSION_NUM >= 130008 && PG_VERSION_NUM < 140000 + update_replication_progress(ctx); +#elif PG_VERSION_NUM >= 120012 && PG_VERSION_NUM < 130000 + update_replication_progress(ctx); +#elif PG_VERSION_NUM >= 110017 && PG_VERSION_NUM < 120000 + update_replication_progress(ctx); +#endif + + if (data->format_version == 2) + pg_decode_truncate_v2(ctx, txn, n, relations, change); + else if (data->format_version == 1) + pg_decode_truncate_v1(ctx, txn, n, relations, change); + else + elog(ERROR, "format version %d is not supported", data->format_version); +} + +static void pg_decode_truncate_v1(LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, int n, Relation relations[], + ReorderBufferChange *change) +{ +#ifdef _NOT_USED + JsonDecodingData *data; + MemoryContext old; + int i; + + data = ctx->output_plugin_private; + + if (!data->actions.truncate) + { + elog(DEBUG3, "ignore TRUNCATE"); + return; + } + + /* Avoid leaking memory by using and resetting our own context */ + old = MemoryContextSwitchTo(data->context); + + /* Exclude tables, if available */ + if (pg_filter_by_table(data->filter_tables, schemaname, tablename)) + { + MemoryContextSwitchTo(old); + MemoryContextReset(data->context); + continue; + } + + /* Add tables */ + if (!pg_add_by_table(data->add_tables, schemaname, tablename)) + { + MemoryContextSwitchTo(old); + MemoryContextReset(data->context); + continue; + } + + if (data->write_in_chunks) + OutputPluginPrepareWrite(ctx, true); + + /* + * increment counter only for transactional messages because + * non-transactional message has only one object. + */ + data->nr_changes++; + + /* if we don't write in chunks, we need a newline here */ + if (!data->write_in_chunks) + appendStringInfo(ctx->out, "%s", data->nl); + + appendStringInfo(ctx->out, "%s%s", data->ht, data->ht); + + if (data->nr_changes > 1) + appendStringInfoChar(ctx->out, ','); + + appendStringInfo(ctx->out, "{%s%s%s%s\"kind\":%s\"truncate\",%s", data->nl, data->ht, data->ht, data->ht, data->sp, data->nl); + + if (data->include_xids) + appendStringInfo(ctx->out, "%s%s%s\"xid\":%s%u,%s", data->ht, data->ht, data->ht, data->sp, txn->xid, data->nl); + +#if PG_VERSION_NUM >= 150000 + if (data->include_timestamp) + appendStringInfo(ctx->out, "%s%s%s\"timestamp\":%s\"%s\",%s", data->ht, data->ht, data->ht, data->sp, timestamptz_to_str(txn->xact_time.commit_time), data->nl); +#else + if (data->include_timestamp) + appendStringInfo(ctx->out, "%s%s%s\"timestamp\":%s\"%s\",%s", data->ht, data->ht, data->ht, data->sp, timestamptz_to_str(txn->commit_time), data->nl); +#endif + + if (data->include_origin) + appendStringInfo(ctx->out, "%s%s%s\"origin\":%s%u,%s", data->ht, data->ht, data->ht, data->sp, txn->origin_id, data->nl); + + if (data->include_lsn) + { + char *lsn_str = DatumGetCString(DirectFunctionCall1(pg_lsn_out, UInt64GetDatum(change->lsn))); + appendStringInfo(ctx->out, "%s%s%s\"lsn\":%s\"%s\",%s", data->ht, data->ht, data->ht, data->sp, lsn_str, data->nl); + pfree(lsn_str); + } + + for (i = 0; i < n; i++) + { + if (data->include_schemas) + { + appendStringInfo(ctx->out, "%s%s%s\"schema\":%s", data->ht, data->ht, data->ht, data->sp); + escape_json(ctx->out, get_namespace_name(RelationGetNamespace(relations[i]))); + appendStringInfo(ctx->out, ",%s", data->nl); + } + + appendStringInfo(ctx->out, "%s%s%s\"table\":%s", data->ht, data->ht, data->ht, data->sp); + escape_json(ctx->out, RelationGetRelationName(relations[i])); + } + + appendStringInfo(ctx->out, "%s%s%s}", data->nl, data->ht, data->ht); + + MemoryContextSwitchTo(old); + MemoryContextReset(data->context); + + if (data->write_in_chunks) + OutputPluginWrite(ctx, true); +#endif +} + +static void pg_decode_truncate_v2(LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, int n, Relation relations[], + ReorderBufferChange *change) +{ + JsonDecodingData *data = ctx->output_plugin_private; + MemoryContext old; + int i; + + if (!data->actions.truncate) + { + elog(DEBUG3, "ignore TRUNCATE"); + return; + } + + /* avoid leaking memory by using and resetting our own context */ + old = MemoryContextSwitchTo(data->context); + + for (i = 0; i < n; i++) + { + char *schemaname; + char *tablename; + + /* schema and table names are used for chosen tables */ + schemaname = get_namespace_name(RelationGetNamespace(relations[i])); + tablename = RelationGetRelationName(relations[i]); + + /* Exclude tables, if available */ + if (pg_filter_by_table(data->filter_tables, schemaname, tablename)) + { + MemoryContextSwitchTo(old); + MemoryContextReset(data->context); + continue; + } + + /* Add tables */ + if (!pg_add_by_table(data->add_tables, schemaname, tablename)) + { + MemoryContextSwitchTo(old); + MemoryContextReset(data->context); + continue; + } + + OutputPluginPrepareWrite(ctx, true); + appendStringInfoChar(ctx->out, '{'); + appendStringInfoString(ctx->out, "\"action\":\"T\""); + + if (data->include_xids) + appendStringInfo(ctx->out, ",\"xid\":%u", txn->xid); + +#if PG_VERSION_NUM >= 150000 + if (data->include_timestamp) + appendStringInfo(ctx->out, ",\"timestamp\":\"%s\"", timestamptz_to_str(txn->xact_time.commit_time)); +#else + if (data->include_timestamp) + appendStringInfo(ctx->out, ",\"timestamp\":\"%s\"", timestamptz_to_str(txn->commit_time)); +#endif + + if (data->include_origin) + appendStringInfo(ctx->out, ",\"origin\":%u", txn->origin_id); + + if (data->include_lsn) + { + char *lsn_str = DatumGetCString(DirectFunctionCall1(pg_lsn_out, UInt64GetDatum(change->lsn))); + appendStringInfo(ctx->out, ",\"lsn\":\"%s\"", lsn_str); + pfree(lsn_str); + } + + if (data->include_schemas) + { + appendStringInfo(ctx->out, ",\"schema\":"); + escape_json(ctx->out, schemaname); + } + + appendStringInfo(ctx->out, ",\"table\":"); + escape_json(ctx->out, tablename); + + appendStringInfoChar(ctx->out, '}'); + OutputPluginWrite(ctx, true); + } + + MemoryContextSwitchTo(old); + MemoryContextReset(data->context); +} +#endif + +static bool +parse_table_identifier(List *qualified_tables, char separator, List **select_tables) +{ + ListCell *lc; + + foreach(lc, qualified_tables) + { + char *str = lfirst(lc); + char *startp; + char *nextp; + int len; + SelectTable *t = palloc0(sizeof(SelectTable)); + + /* + * Detect a special character that means all schemas. There could be a + * schema named "*" thus this test should be before we remove the + * escape character. + */ + if (str[0] == '*' && str[1] == '.') + t->allschemas = true; + else + t->allschemas = false; + + startp = nextp = str; + while (*nextp && *nextp != separator) + { + /* remove escape character */ + if (*nextp == '\\') + memmove(nextp, nextp + 1, strlen(nextp)); + nextp++; + } + len = nextp - startp; + + /* if separator was not found, schema was not informed */ + if (*nextp == '\0') + { + pfree(t); + return false; + } + else + { + /* schema name */ + t->schemaname = (char *) palloc0((len + 1) * sizeof(char)); + strncpy(t->schemaname, startp, len); + + nextp++; /* jump separator */ + startp = nextp; /* start new identifier (table name) */ + + /* + * Detect a special character that means all tables. There could be + * a table named "*" thus this test should be before that we remove + * the escape character. + */ + if (startp[0] == '*' && startp[1] == '\0') + t->alltables = true; + else + t->alltables = false; + + while (*nextp) + { + /* remove escape character */ + if (*nextp == '\\') + memmove(nextp, nextp + 1, strlen(nextp)); + nextp++; + } + len = nextp - startp; + + /* table name */ + t->tablename = (char *) palloc0((len + 1) * sizeof(char)); + strncpy(t->tablename, startp, len); + } + + *select_tables = lappend(*select_tables, t); + } + + return true; +} + +static bool +string_to_SelectTable(char *rawstring, char separator, List **select_tables) +{ + char *nextp; + bool done = false; + List *qualified_tables = NIL; + + nextp = rawstring; + + while (isspace(*nextp)) + nextp++; /* skip leading whitespace */ + + if (*nextp == '\0') + return true; /* allow empty string */ + + /* At the top of the loop, we are at start of a new identifier. */ + do + { + char *curname; + char *endp; + char *qname; + + curname = nextp; + while (*nextp && *nextp != separator && !isspace(*nextp)) + { + if (*nextp == '\\') + nextp++; /* ignore next character because of escape */ + nextp++; + } + endp = nextp; + if (curname == nextp) + return false; /* empty unquoted name not allowed */ + + while (isspace(*nextp)) + nextp++; /* skip trailing whitespace */ + + if (*nextp == separator) + { + nextp++; + while (isspace(*nextp)) + nextp++; /* skip leading whitespace for next */ + /* we expect another name, so done remains false */ + } + else if (*nextp == '\0') + done = true; + else + return false; /* invalid syntax */ + + /* Now safe to overwrite separator with a null */ + *endp = '\0'; + + /* + * Finished isolating current name --- add it to list + */ + qname = pstrdup(curname); + qualified_tables = lappend(qualified_tables, qname); + + /* Loop back if we didn't reach end of string */ + } while (!done); + + if (!parse_table_identifier(qualified_tables, '.', select_tables)) + return false; + + list_free_deep(qualified_tables); + + return true; +} + +static bool +split_string_to_list(char *rawstring, char separator, List **sl) +{ + char *nextp; + bool done = false; + + nextp = rawstring; + + while (isspace(*nextp)) + nextp++; /* skip leading whitespace */ + + if (*nextp == '\0') + return true; /* allow empty string */ + + /* At the top of the loop, we are at start of a new identifier. */ + do + { + char *curname; + char *endp; + char *pname; + + curname = nextp; + while (*nextp && *nextp != separator && !isspace(*nextp)) + { + if (*nextp == '\\') + nextp++; /* ignore next character because of escape */ + nextp++; + } + endp = nextp; + if (curname == nextp) + return false; /* empty unquoted name not allowed */ + + while (isspace(*nextp)) + nextp++; /* skip trailing whitespace */ + + if (*nextp == separator) + { + nextp++; + while (isspace(*nextp)) + nextp++; /* skip leading whitespace for next */ + /* we expect another name, so done remains false */ + } + else if (*nextp == '\0') + done = true; + else + return false; /* invalid syntax */ + + /* Now safe to overwrite separator with a null */ + *endp = '\0'; + + /* + * Finished isolating current name --- add it to list + */ + pname = pstrdup(curname); + *sl = lappend(*sl, pname); + + /* Loop back if we didn't reach end of string */ + } while (!done); + + return true; +} + +/* + * Convert a string into a list of Oids + */ +static bool +split_string_to_oid_list(char *rawstring, char separator, List **sl) +{ + char *nextp; + bool done = false; + + nextp = rawstring; + + while (isspace(*nextp)) + nextp++; /* skip leading whitespace */ + + if (*nextp == '\0') + return true; /* allow empty string */ + + /* At the top of the loop, we are at start of a new identifier. */ + do + { + char *tok; + char *endp; + Oid originid; + + tok = nextp; + while (*nextp && *nextp != separator && !isspace(*nextp)) + { + if (*nextp == '\\') + nextp++; /* ignore next character because of escape */ + nextp++; + } + endp = nextp; + + while (isspace(*nextp)) + nextp++; /* skip trailing whitespace */ + + if (*nextp == separator) + { + nextp++; + while (isspace(*nextp)) + nextp++; /* skip leading whitespace for next */ + /* we expect another name, so done remains false */ + } + else if (*nextp == '\0') + done = true; + else + return false; /* invalid syntax */ + + /* Now safe to overwrite separator with a null */ + *endp = '\0'; + + /* + * Finished isolating origin id --- add it to list + */ + originid = (Oid) atoi(tok); + *sl = lappend_oid(*sl, originid); + + /* Loop back if we didn't reach end of string */ + } while (!done); + + return true; +} + +/* + * Try to update progress and send a keepalive message if too many changes were + * processed. + * + * For a large transaction, if we don't send any change to the downstream for a + * long time (exceeds the wal_receiver_timeout of standby) then it can timeout. + * This can happen when all or most of the changes are not published. + * + * Copied from Postgres commit f95d53eded55ecbf037f6416ced6af29a2c3caca + */ +#if PG_VERSION_NUM >= 150000 && PG_VERSION_NUM < 160000 +static void +update_replication_progress(LogicalDecodingContext *ctx, bool skipped_xact) +{ + static int changes_count = 0; + + /* + * We don't want to try sending a keepalive message after processing each + * change as that can have overhead. Tests revealed that there is no + * noticeable overhead in doing it after continuously processing 100 or so + * changes. + */ +#define CHANGES_THRESHOLD 100 + + /* + * If we are at the end of transaction LSN, update progress tracking. + * Otherwise, after continuously processing CHANGES_THRESHOLD changes, we + * try to send a keepalive message if required. + */ + if (ctx->end_xact || ++changes_count >= CHANGES_THRESHOLD) + { + OutputPluginUpdateProgress(ctx, skipped_xact); + changes_count = 0; + } +} +#elif PG_VERSION_NUM >= 100000 && PG_VERSION_NUM < 150000 +static void +update_replication_progress(LogicalDecodingContext *ctx) +{ + static int changes_count = 0; + + /* + * We don't want to try sending a keepalive message after processing each + * change as that can have overhead. Tests revealed that there is no + * noticeable overhead in doing it after continuously processing 100 or so + * changes. + */ +#define CHANGES_THRESHOLD 100 + + /* + * If we are at the end of transaction LSN, update progress tracking. + * Otherwise, after continuously processing CHANGES_THRESHOLD changes, we + * try to send a keepalive message if required. + */ + if (ctx->end_xact || ++changes_count >= CHANGES_THRESHOLD) + { + OutputPluginUpdateProgress(ctx); + changes_count = 0; + } +} +#endif diff --git a/src/postgres/third-party-extensions/wal2json/wal2json.sln b/src/postgres/third-party-extensions/wal2json/wal2json.sln new file mode 100644 index 000000000000..203a006dead6 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/wal2json.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.9.34728.123 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wal2json", "wal2json.vcxproj", "{D10508A0-6575-4EE9-9AD9-4BC161A5E934}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D10508A0-6575-4EE9-9AD9-4BC161A5E934}.Debug|x64.ActiveCfg = Debug|x64 + {D10508A0-6575-4EE9-9AD9-4BC161A5E934}.Debug|x64.Build.0 = Debug|x64 + {D10508A0-6575-4EE9-9AD9-4BC161A5E934}.Debug|x86.ActiveCfg = Debug|Win32 + {D10508A0-6575-4EE9-9AD9-4BC161A5E934}.Debug|x86.Build.0 = Debug|Win32 + {D10508A0-6575-4EE9-9AD9-4BC161A5E934}.Release|x64.ActiveCfg = Release|x64 + {D10508A0-6575-4EE9-9AD9-4BC161A5E934}.Release|x64.Build.0 = Release|x64 + {D10508A0-6575-4EE9-9AD9-4BC161A5E934}.Release|x86.ActiveCfg = Release|Win32 + {D10508A0-6575-4EE9-9AD9-4BC161A5E934}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {542A3CD9-759C-4DB6-B7CD-8E51866EFCC0} + EndGlobalSection +EndGlobal diff --git a/src/postgres/third-party-extensions/wal2json/wal2json.vcxproj b/src/postgres/third-party-extensions/wal2json/wal2json.vcxproj new file mode 100644 index 000000000000..09933e349846 --- /dev/null +++ b/src/postgres/third-party-extensions/wal2json/wal2json.vcxproj @@ -0,0 +1,96 @@ + + + + + Debug + x64 + + + Release + x64 + + + + 17.0 + {185AF5B6-C04A-4710-8330-18A4416BD225} + Win32Proj + 10.0 + + + + DynamicLibrary + true + v143 + + + DynamicLibrary + false + v143 + + + + + + + + + + + + + + + false + + + false + + + + C:\pg\16\include\server\port\win32_msvc;C:\pg\16\include\server\port\win32;C:\pg\16\include\server;C:\pg\16\include;%(AdditionalIncludeDirectories) + WIN32;_WINDOWS;__WINDOWS__;__WIN32__;WIN32_STACK_RLIMIT=4194304;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_DEBUG;DEBUG=1%(PreprocessorDefinitions) + false + MultiThreadedDebugDLL + 4018;4244;4273;4102;4090;4267;%(DisableSpecificWarnings) + /MP %(AdditionalOptions) + Default + + + .\x64\Debug\wal2json.dll + C:\pg\16\lib;%(AdditionalLibraryDirectories) + postgres.lib;libpgcommon.lib;libpgport.lib;%(AdditionalDependencies) + MachineX64 + /ignore:4197 %(AdditionalOptions) + + + false + + + + + C:\pg\16\include\server\port\win32_msvc;C:\pg\16\include\server\port\win32;C:\pg\16\include\server;C:\pg\16\include;%(AdditionalIncludeDirectories) + WIN32;_WINDOWS;__WINDOWS__;__WIN32__;EXEC_BACKEND;WIN32_STACK_RLIMIT=4194304;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_DEBUG;DEBUG=1%(PreprocessorDefinitions) + false + MultiThreadedDebugDLL + 4018;4244;4273;4102;4090;4267;%(DisableSpecificWarnings) + /MP %(AdditionalOptions) + Default + + + .\x64\Release\wal2json.dll + C:\pg\16\lib;%(AdditionalLibraryDirectories) + postgres.lib;libpgcommon.lib;libpgport.lib;%(AdditionalDependencies) + MachineX64 + /ignore:4197 %(AdditionalOptions) + + + false + + + + + + + + + diff --git a/src/yb/cdc/cdcsdk_producer.cc b/src/yb/cdc/cdcsdk_producer.cc index b361ebfc16eb..629a854125c1 100644 --- a/src/yb/cdc/cdcsdk_producer.cc +++ b/src/yb/cdc/cdcsdk_producer.cc @@ -168,6 +168,7 @@ Status AddColumnToMap( // send NULL values to the walsender. This is needed to be able to differentiate between NULL // and Omitted values. if (request_source == CDCSDKRequestSource::WALSENDER) { + cdc_datum_message->set_col_attr_num(col_schema.order()); cdc_datum_message->set_column_type(col_schema.pg_type_oid()); cdc_datum_message->mutable_pg_ql_value()->CopyFrom(ql_value); return Status::OK(); diff --git a/src/yb/common/common.proto b/src/yb/common/common.proto index ffb7e59a729d..ee604b8ba84a 100644 --- a/src/yb/common/common.proto +++ b/src/yb/common/common.proto @@ -639,6 +639,8 @@ message DatumMessagePB { // The Walsender does the conversion from QLValuePB to the PG datum. QLValuePB pg_ql_value = 15; } + // This is applicable only for YSQL table columns. + optional int32 col_attr_num = 16; } message PgDatumPB { diff --git a/src/yb/integration-tests/cdcsdk_ysql-test.cc b/src/yb/integration-tests/cdcsdk_ysql-test.cc index 177c292e375b..62ec0102c0e8 100644 --- a/src/yb/integration-tests/cdcsdk_ysql-test.cc +++ b/src/yb/integration-tests/cdcsdk_ysql-test.cc @@ -8613,19 +8613,6 @@ TEST_F(CDCSDKYsqlTest, TestNonEligibleTableShouldNotGetAddedToConsistentSnapshot TestNonEligibleTableShouldNotGetAddedToCDCStream(/* create_consistent_snapshot_stream */ true); } -TEST_F(CDCSDKYsqlTest, TestTablesWithEnumArrayColumnShouldNotGetAddedToStream) { - ASSERT_OK(SetUpWithParams(1, 1, false, false)); - auto conn = ASSERT_RESULT(test_cluster_.ConnectToDB(kNamespaceName)); - - ASSERT_OK(conn.Execute("CREATE TYPE \"enum_type\" AS ENUM('a', 'b', 'c');")); - ASSERT_OK(conn.Execute("CREATE TABLE test_table (a int primary key, b \"enum_type\"[])")); - auto stream_id = ASSERT_RESULT(CreateDBStream()); - - auto stream = ASSERT_RESULT(GetCDCStream(stream_id)); - // The table with enum array column will not be added to the stream. - ASSERT_EQ(stream.stream().table_id_size(), 0); -} - void CDCSDKYsqlTest::TestDisableOfDynamicTableAdditionOnCDCStream( bool use_consistent_snapshot_stream) { ANNOTATE_UNPROTECTED_WRITE(FLAGS_yb_enable_cdc_consistent_snapshot_streams) = diff --git a/src/yb/master/master_xrepl-test.cc b/src/yb/master/master_xrepl-test.cc index c3fbefb7de64..0f6a1966a3d1 100644 --- a/src/yb/master/master_xrepl-test.cc +++ b/src/yb/master/master_xrepl-test.cc @@ -556,7 +556,6 @@ TEST_F(MasterTestXRepl, YB_DISABLE_TEST_IN_TSAN(TestCDCStreamCreationWithOldReco CreateCDCStreamRequestPB req; CreateCDCStreamResponsePB resp; req.set_namespace_id(ns_id); - req.set_cdcsdk_ysql_replication_slot_name(kPgReplicationSlotName); AddKeyValueToCreateCDCStreamRequestOption(&req, cdc::kIdType, cdc::kNamespaceId); AddKeyValueToCreateCDCStreamRequestOption( &req, cdc::kSourceType, CDCRequestSource_Name(cdc::CDCRequestSource::CDCSDK)); @@ -574,7 +573,8 @@ TEST_F(MasterTestXRepl, TestCreateCDCStreamForNamespaceInvalidDuplicationSlotNam auto ns_id = create_namespace_resp.id(); for (auto i = 0; i < num_tables; ++i) { - ASSERT_OK(CreatePgsqlTable(ns_id, Format("cdc_table_$0", i), kTableIds[i], kTableSchema)); + ASSERT_OK( + CreatePgsqlTable(ns_id, Format("cdc_table_$0", i), kTableIds[i], kTableSchemaWithTypeOids)); } ASSERT_RESULT( @@ -644,7 +644,8 @@ TEST_F(MasterTestXRepl, TestCreateCDCStreamForNamespaceLimitReached) { auto ns_id = create_namespace_resp.id(); for (auto i = 0; i < num_tables; ++i) { - ASSERT_OK(CreatePgsqlTable(ns_id, Format("cdc_table_$0", i), kTableIds[i], kTableSchema)); + ASSERT_OK( + CreatePgsqlTable(ns_id, Format("cdc_table_$0", i), kTableIds[i], kTableSchemaWithTypeOids)); } ASSERT_RESULT( @@ -791,7 +792,8 @@ TEST_F(MasterTestXRepl, TestCreateDropCDCStreamWithReplicationSlotName) { ASSERT_OK(CreatePgsqlNamespace(kNamespaceName, kPgsqlNamespaceId, &create_namespace_resp)); auto ns_id = create_namespace_resp.id(); for (auto i = 0; i < num_tables; ++i) { - ASSERT_OK(CreatePgsqlTable(ns_id, Format("cdc_table_$0", i), kTableIds[i], kTableSchema)); + ASSERT_OK( + CreatePgsqlTable(ns_id, Format("cdc_table_$0", i), kTableIds[i], kTableSchemaWithTypeOids)); } // Create and Delete CDC stream with replication slot name in quick succession. @@ -845,9 +847,9 @@ TEST_F(MasterTestXRepl, TestListCDCStreamsCDCSDKWithReplicationSlot) { auto ns_id2 = create_namespace_resp.id(); // 2 tables in cdc_namespace and 1 table in cdc_namespace2 - ASSERT_OK(CreatePgsqlTable(ns_id, "cdc_table_1", kTableIds[0], kTableSchema)); - ASSERT_OK(CreatePgsqlTable(ns_id, "cdc_table_2", kTableIds[1], kTableSchema)); - ASSERT_OK(CreatePgsqlTable(ns_id2, "cdc_table_3", kTableIds[2], kTableSchema)); + ASSERT_OK(CreatePgsqlTable(ns_id, "cdc_table_1", kTableIds[0], kTableSchemaWithTypeOids)); + ASSERT_OK(CreatePgsqlTable(ns_id, "cdc_table_2", kTableIds[1], kTableSchemaWithTypeOids)); + ASSERT_OK(CreatePgsqlTable(ns_id2, "cdc_table_3", kTableIds[2], kTableSchemaWithTypeOids)); auto stream_id = ASSERT_RESULT( CreateCDCStreamForNamespace(ns_id, kPgReplicationSlotName, kPgReplicationSlotPgOutput)); @@ -1134,7 +1136,8 @@ TEST_F(MasterTestXRepl, DropNamespaceWithLiveCDCStream) { auto ns_id = create_namespace_resp.id(); for (auto i = 0; i < num_tables; ++i) { - ASSERT_OK(CreatePgsqlTable(ns_id, Format("cdc_table_$0", i), kTableIds[i], kTableSchema)); + ASSERT_OK( + CreatePgsqlTable(ns_id, Format("cdc_table_$0", i), kTableIds[i], kTableSchemaWithTypeOids)); } ASSERT_RESULT( CreateCDCStreamForNamespace(ns_id, kPgReplicationSlotName, kPgReplicationSlotPgOutput)); diff --git a/src/yb/master/xrepl_catalog_manager.cc b/src/yb/master/xrepl_catalog_manager.cc index 40f079ba43f3..b23dd192fdd7 100644 --- a/src/yb/master/xrepl_catalog_manager.cc +++ b/src/yb/master/xrepl_catalog_manager.cc @@ -1930,7 +1930,6 @@ bool CatalogManager::IsTableEligibleForCDCSDKStream( const TableInfoPtr& table_info, const std::optional& schema) const { if (schema.has_value()) { bool has_pk = true; - bool has_invalid_pg_typeoid = false; for (const auto& col : schema->columns()) { if (col.order() == static_cast(PgSystemAttrNum::kYBRowId)) { // ybrowid column is added for tables that don't have user-specified primary key. @@ -1939,19 +1938,16 @@ bool CatalogManager::IsTableEligibleForCDCSDKStream( has_pk = false; break; } - if (col.pg_type_oid() == 0) { - has_invalid_pg_typeoid = true; - } } - if (!has_pk || has_invalid_pg_typeoid) { - if (FLAGS_TEST_cdcsdk_add_indexes_to_stream) { - // allow adding user created indexes to CDC stream. - if (IsUserIndexUnlocked(*table_info)) { - return true; - } - } + + if (!has_pk) { return false; } + + // Allow adding user created indexes to CDC stream. + if (FLAGS_TEST_cdcsdk_add_indexes_to_stream && IsUserIndexUnlocked(*table_info)) { + return true; + } } if (IsMatviewTable(*table_info)) { diff --git a/src/yb/yql/pggate/ybc_pggate.cc b/src/yb/yql/pggate/ybc_pggate.cc index 1455b0ddff95..37420f453925 100644 --- a/src/yb/yql/pggate/ybc_pggate.cc +++ b/src/yb/yql/pggate/ybc_pggate.cc @@ -400,6 +400,14 @@ std::string HumanReadableTableType(yb::TableType table_type) { FATAL_INVALID_ENUM_VALUE(yb::TableType, table_type); } +const YBCPgTypeEntity* GetTypeEntity( + int pg_type_oid, int attr_num, YBCPgOid table_oid, YBCTypeEntityProvider type_entity_provider) { + + // TODO(23239): Optimize the lookup of type entities for dynamic types. + return pg_type_oid == kPgInvalidOid ? (*type_entity_provider)(attr_num, table_oid) + : pgapi->FindTypeEntity(pg_type_oid); +} + } // namespace //-------------------------------------------------------------------------------------------------- @@ -2422,7 +2430,9 @@ YBCPgRowMessageAction GetRowMessageAction(yb::cdc::RowMessage row_message_pb) { } YBCStatus YBCPgGetCDCConsistentChanges( - const char *stream_id, YBCPgChangeRecordBatch **record_batch) { + const char* stream_id, + YBCPgChangeRecordBatch** record_batch, + YBCTypeEntityProvider type_entity_provider) { const auto result = pgapi->GetConsistentChangesForCDC(std::string(stream_id)); if (!result.ok()) { return ToYBCStatus(result.status()); @@ -2481,6 +2491,10 @@ YBCStatus YBCPgGetCDCConsistentChanges( old_tuple_idx++; } + const auto table_oid = row_message_pb.has_table_id() + ? PgObjectId(row_message_pb.table_id()).object_oid + : kPgInvalidOid; + auto col_count = narrow_cast(col_name_idx_map.size()); YBCPgDatumMessage *cols = nullptr; if (col_count > 0) { @@ -2498,8 +2512,10 @@ YBCStatus YBCPgGetCDCConsistentChanges( if (!before_op_is_omitted) { const auto old_datum_pb = &row_message_pb.old_tuple(static_cast(col_idxs.second.first)); - const auto *type_entity = - pgapi->FindTypeEntity(static_cast(old_datum_pb->column_type())); + DCHECK(table_oid != kPgInvalidOid); + const auto* type_entity = GetTypeEntity( + static_cast(old_datum_pb->column_type()), old_datum_pb->col_attr_num(), + table_oid, type_entity_provider); auto s = PBToDatum( type_entity, type_attrs, old_datum_pb->pg_ql_value(), &before_op_datum, &before_op_is_null); @@ -2515,8 +2531,10 @@ YBCStatus YBCPgGetCDCConsistentChanges( if (!after_op_is_omitted) { const auto new_datum_pb = &row_message_pb.new_tuple(static_cast(col_idxs.second.second)); - const auto *type_entity = - pgapi->FindTypeEntity(static_cast(new_datum_pb->column_type())); + DCHECK(table_oid != kPgInvalidOid); + const auto* type_entity = GetTypeEntity( + static_cast(new_datum_pb->column_type()), new_datum_pb->col_attr_num(), + table_oid, type_entity_provider); auto s = PBToDatum( type_entity, type_attrs, new_datum_pb->pg_ql_value(), &after_op_datum, &after_op_is_null); @@ -2536,12 +2554,6 @@ YBCStatus YBCPgGetCDCConsistentChanges( } } - // Only present for DML records. - YBCPgOid table_oid = kPgInvalidOid; - if (row_message_pb.has_table_id()) { - auto table_id = PgObjectId(row_message_pb.table_id()); - table_oid = table_id.object_oid; - } new (&resp_rows[row_idx]) YBCPgRowMessage{ .col_count = col_count, diff --git a/src/yb/yql/pggate/ybc_pggate.h b/src/yb/yql/pggate/ybc_pggate.h index 291c039d6b49..a1cb7a5da894 100644 --- a/src/yb/yql/pggate/ybc_pggate.h +++ b/src/yb/yql/pggate/ybc_pggate.h @@ -25,6 +25,7 @@ extern "C" { typedef void (*YBCAshAcquireBufferLock)(bool); typedef YBCAshSample* (*YBCAshGetNextCircularBufferSlot)(); +typedef const YBCPgTypeEntity* (*YBCTypeEntityProvider)(int, YBCPgOid); typedef void * SliceVector; typedef const void * ConstSliceVector; @@ -875,7 +876,8 @@ YBCStatus YBCPgUpdatePublicationTableList( YBCStatus YBCPgDestroyVirtualWalForCDC(); YBCStatus YBCPgGetCDCConsistentChanges(const char *stream_id, - YBCPgChangeRecordBatch **record_batch); + YBCPgChangeRecordBatch **record_batch, + YBCTypeEntityProvider type_entity_provider); YBCStatus YBCPgUpdateAndPersistLSN( const char* stream_id, YBCPgXLogRecPtr restart_lsn_hint, YBCPgXLogRecPtr confirmed_flush,