From d8665787b75ae562bff761df067eb56fcf670700 Mon Sep 17 00:00:00 2001 From: WanYixian Date: Thu, 7 Nov 2024 15:51:25 +0800 Subject: [PATCH 1/2] Update subscription.mdx --- delivery/subscription.mdx | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/delivery/subscription.mdx b/delivery/subscription.mdx index 1b0aeefb..8e7d3049 100644 --- a/delivery/subscription.mdx +++ b/delivery/subscription.mdx @@ -83,33 +83,39 @@ If you specify `FULL` instead of the `since_clause`, the subscription cursor sta FETCH from cursor function is currently only supported in the PSQL simple query mode. If you are using components like JDBC that default to the extended query mode, please manually set the mode to simple query mode. -#### FETCH NEXT FROM cursor +#### Non-blocking data fetch -After creating a subscription cursor, you can fetch the data by the `FETCH NEXT FROM cursor_name` command. Then you will see a result like below: +```sql +FETCH NEXT/n FROM cursor_name; +``` + +Fetch the next row or up to N rows from the cursor. If fewer than N rows are available, it will return whatever is available immediately without waiting. This also means that if there are no rows available (i.e., the latest data has been reached), an empty result will be returned immediately. ```sql FETCH NEXT FROM cur; ----RESULT -t1.v1 | t1.v2 | t1.v3 | t1.op | rw_timestamp +t1.v1 | t1.v2 | t1.v3 | t1.op | rw_timestamp -------+-------+-------+--------------+--------------- - 1 | 1 | 1 | UpdateDelete | 1715669376304 + 1 | 1 | 1 | UpdateDelete | 1715669376304 (1 row) ``` -The `op` column in the result stands for the change operations. It has four options: `insert`, `update_insert`, `delete`, and `update_delete`. For a single UPDATE statement, the subscription log will contain two separate rows: one with `update_insert` and another with `update_delete`. This is because RisingWave treats an UPDATE as a delete of the old value followed by an insert of the new value. As for `rw_timestamp`, it corresponds to the Unix timestamp in milliseconds when the data was written. +In the example above, the `op` column in the result indicates the type of change operations. There are four options: `insert`, `update_insert`, `delete`, and `update_delete`. For a single UPDATE statement, the subscription log will contain two separate rows: one with `update_insert` and another with `update_delete`. This is because RisingWave treats an UPDATE as a delete of the old value followed by an insert of the new value. As for `rw_timestamp`, it corresponds to the Unix timestamp in milliseconds when the data was written. + +#### Blocking data fetch -Note that each time `FETCH NEXT FROM cursor_name` is called, it will return one row of incremental data from the subscribed table. It does not return all the incremental data at once, but requires the user to repeatedly call this statement to fetch the data. +```sql +FETCH NEXT/n FROM cursor_name WITH (timeout = 'xx'); +``` -This method is non-blocking. Even if the current table has no new incremental data, `FETCH NEXT FROM cursor_name` will not block, but will return an empty row. When new incremental data is generated, calling this statement again will return the latest row of data. +Fetch up to N rows from the cursor with a specified timeout. The `timeout` value should be a string in the interval format. In this case, the fetch statement will return when either N rows have been fetched or the timeout occurs. If the timeout occurs, whatever has been read up to that point will be returned. Here are two scenarios to trigger the timeout: -#### FETCH n FROM cursor +1. The cursor has reached the latest data and has been waiting too long for new data to arrive. -You also can fetch multiple rows at once from the cursor using the `FETCH n FROM cursor_name` command. `n` is the number of rows to fetch. +2. At least N rows are available for the cursor to read, but retrieving all of them takes an extended period. -```sql -FETCH n FROM cursor_name; -``` +To avoid polling for new data frequently with the non-blocking `FETCH`, you can set a longer timeout to simulate a scenario where you want the `FETCH` to block until new data arrives. #### Order of the fetched data From b86f71bc3ac95c81c6e50bf2ec790615ec96eb0e Mon Sep 17 00:00:00 2001 From: WanYixian Date: Mon, 11 Nov 2024 11:25:22 +0800 Subject: [PATCH 2/2] feedback from review --- delivery/subscription.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/delivery/subscription.mdx b/delivery/subscription.mdx index 8e7d3049..8902cf9e 100644 --- a/delivery/subscription.mdx +++ b/delivery/subscription.mdx @@ -80,7 +80,7 @@ If you specify `FULL` instead of the `since_clause`, the subscription cursor sta **NOTE** -FETCH from cursor function is currently only supported in the PSQL simple query mode. If you are using components like JDBC that default to the extended query mode, please manually set the mode to simple query mode. +FETCH from cursor function is supported in the PSQL simple query mode and extended mode. #### Non-blocking data fetch @@ -101,12 +101,12 @@ t1.v1 | t1.v2 | t1.v3 | t1.op | rw_timestamp (1 row) ``` -In the example above, the `op` column in the result indicates the type of change operations. There are four options: `insert`, `update_insert`, `delete`, and `update_delete`. For a single UPDATE statement, the subscription log will contain two separate rows: one with `update_insert` and another with `update_delete`. This is because RisingWave treats an UPDATE as a delete of the old value followed by an insert of the new value. As for `rw_timestamp`, it corresponds to the Unix timestamp in milliseconds when the data was written. +In the example above, the `op` column in the result indicates the type of change operations. There are four options: `Insert`, `UpdateInsert`, `Delete`, and `UpdateDelete`. For a single UPDATE statement, the subscription log will contain two separate rows: one with `UpdateInsert` and another with `UpdateDelete`. This is because RisingWave treats an UPDATE as a delete of the old value followed by an insert of the new value. As for `rw_timestamp`, it corresponds to the Unix timestamp in milliseconds when the data was written. #### Blocking data fetch ```sql -FETCH NEXT/n FROM cursor_name WITH (timeout = 'xx'); +FETCH NEXT/n FROM cursor_name WITH (timeout = '1s'); ``` Fetch up to N rows from the cursor with a specified timeout. The `timeout` value should be a string in the interval format. In this case, the fetch statement will return when either N rows have been fetched or the timeout occurs. If the timeout occurs, whatever has been read up to that point will be returned. Here are two scenarios to trigger the timeout: