diff options
Diffstat (limited to 'contrib/postgres_fdw')
-rw-r--r-- | contrib/postgres_fdw/expected/postgres_fdw.out | 37 | ||||
-rw-r--r-- | contrib/postgres_fdw/postgres_fdw.c | 14 | ||||
-rw-r--r-- | contrib/postgres_fdw/sql/postgres_fdw.sql | 17 |
3 files changed, 68 insertions, 0 deletions
diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out index 7d6f7d9e3df..b2e02caefe4 100644 --- a/contrib/postgres_fdw/expected/postgres_fdw.out +++ b/contrib/postgres_fdw/expected/postgres_fdw.out @@ -10800,6 +10800,43 @@ DROP TABLE base_tbl1; DROP TABLE base_tbl2; DROP TABLE result_tbl; DROP TABLE join_tbl; +-- Test that an asynchronous fetch is processed before restarting the scan in +-- ReScanForeignScan +CREATE TABLE base_tbl (a int, b int); +INSERT INTO base_tbl VALUES (1, 11), (2, 22), (3, 33); +CREATE FOREIGN TABLE foreign_tbl (b int) + SERVER loopback OPTIONS (table_name 'base_tbl'); +CREATE FOREIGN TABLE foreign_tbl2 () INHERITS (foreign_tbl) + SERVER loopback OPTIONS (table_name 'base_tbl'); +EXPLAIN (VERBOSE, COSTS OFF) +SELECT a FROM base_tbl WHERE a IN (SELECT a FROM foreign_tbl); + QUERY PLAN +----------------------------------------------------------------------------- + Seq Scan on public.base_tbl + Output: base_tbl.a + Filter: (SubPlan 1) + SubPlan 1 + -> Result + Output: base_tbl.a + -> Append + -> Async Foreign Scan on public.foreign_tbl foreign_tbl_1 + Remote SQL: SELECT NULL FROM public.base_tbl + -> Async Foreign Scan on public.foreign_tbl2 foreign_tbl_2 + Remote SQL: SELECT NULL FROM public.base_tbl +(11 rows) + +SELECT a FROM base_tbl WHERE a IN (SELECT a FROM foreign_tbl); + a +--- + 1 + 2 + 3 +(3 rows) + +-- Clean up +DROP FOREIGN TABLE foreign_tbl CASCADE; +NOTICE: drop cascades to foreign table foreign_tbl2 +DROP TABLE base_tbl; ALTER SERVER loopback OPTIONS (DROP async_capable); ALTER SERVER loopback2 OPTIONS (DROP async_capable); -- =================================================================== diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index bf3f3d9e26e..56654844e8f 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -1652,6 +1652,18 @@ postgresReScanForeignScan(ForeignScanState *node) return; /* + * If the node is async-capable, and an asynchronous fetch for it has been + * begun, the asynchronous fetch might not have yet completed. Check if + * the node is async-capable, and an asynchronous fetch for it is still in + * progress; if so, complete the asynchronous fetch before restarting the + * scan. + */ + if (fsstate->async_capable && + fsstate->conn_state->pendingAreq && + fsstate->conn_state->pendingAreq->requestee == (PlanState *) node) + fetch_more_data(node); + + /* * If any internal parameters affecting this node have changed, we'd * better destroy and recreate the cursor. Otherwise, rewinding it should * be good enough. If we've only fetched zero or one batch, we needn't @@ -6999,6 +7011,8 @@ produce_tuple_asynchronously(AsyncRequest *areq, bool fetch) ExecAsyncRequestDone(areq, result); return; } + + /* We must have run out of tuples */ Assert(fsstate->next_tuple >= fsstate->num_tuples); /* Fetch some more tuples, if we've not detected EOF yet */ diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql index 9eb673e3693..e050639b572 100644 --- a/contrib/postgres_fdw/sql/postgres_fdw.sql +++ b/contrib/postgres_fdw/sql/postgres_fdw.sql @@ -3431,6 +3431,23 @@ DROP TABLE base_tbl2; DROP TABLE result_tbl; DROP TABLE join_tbl; +-- Test that an asynchronous fetch is processed before restarting the scan in +-- ReScanForeignScan +CREATE TABLE base_tbl (a int, b int); +INSERT INTO base_tbl VALUES (1, 11), (2, 22), (3, 33); +CREATE FOREIGN TABLE foreign_tbl (b int) + SERVER loopback OPTIONS (table_name 'base_tbl'); +CREATE FOREIGN TABLE foreign_tbl2 () INHERITS (foreign_tbl) + SERVER loopback OPTIONS (table_name 'base_tbl'); + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT a FROM base_tbl WHERE a IN (SELECT a FROM foreign_tbl); +SELECT a FROM base_tbl WHERE a IN (SELECT a FROM foreign_tbl); + +-- Clean up +DROP FOREIGN TABLE foreign_tbl CASCADE; +DROP TABLE base_tbl; + ALTER SERVER loopback OPTIONS (DROP async_capable); ALTER SERVER loopback2 OPTIONS (DROP async_capable); |