aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/executor/nodeBitmapHeapscan.c12
-rw-r--r--src/backend/nodes/tidbitmap.c2
-rw-r--r--src/test/regress/expected/join.out35
-rw-r--r--src/test/regress/sql/join.sql17
4 files changed, 61 insertions, 5 deletions
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index a7cbaf1660e..928c94cab6a 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -572,9 +572,11 @@ ExecReScanBitmapHeapScan(BitmapHeapScanState *node)
if (scan)
{
/*
- * End iteration on iterators saved in scan descriptor.
+ * End iteration on iterators saved in scan descriptor if they have
+ * not already been cleaned up.
*/
- tbm_end_iterate(&scan->st.rs_tbmiterator);
+ if (!tbm_exhausted(&scan->st.rs_tbmiterator))
+ tbm_end_iterate(&scan->st.rs_tbmiterator);
/* rescan to release any page pin */
table_rescan(node->ss.ss_currentScanDesc, NULL);
@@ -654,9 +656,11 @@ ExecEndBitmapHeapScan(BitmapHeapScanState *node)
if (scanDesc)
{
/*
- * End iteration on iterators saved in scan descriptor.
+ * End iteration on iterators saved in scan descriptor if they have
+ * not already been cleaned up.
*/
- tbm_end_iterate(&scanDesc->st.rs_tbmiterator);
+ if (!tbm_exhausted(&scanDesc->st.rs_tbmiterator))
+ tbm_end_iterate(&scanDesc->st.rs_tbmiterator);
/*
* close table scan
diff --git a/src/backend/nodes/tidbitmap.c b/src/backend/nodes/tidbitmap.c
index 687d6f17636..63316d5d655 100644
--- a/src/backend/nodes/tidbitmap.c
+++ b/src/backend/nodes/tidbitmap.c
@@ -1594,7 +1594,7 @@ tbm_begin_iterate(TIDBitmap *tbm, dsa_area *dsa, dsa_pointer dsp)
void
tbm_end_iterate(TBMIterator *iterator)
{
- Assert(iterator);
+ Assert(iterator && !tbm_exhausted(iterator));
if (iterator->shared)
tbm_end_shared_iterate(iterator->i.shared_iterator);
diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out
index 55d44a9bcee..0c9b312eafd 100644
--- a/src/test/regress/expected/join.out
+++ b/src/test/regress/expected/join.out
@@ -8182,3 +8182,38 @@ SELECT t1.a FROM skip_fetch t1 LEFT JOIN skip_fetch t2 ON t2.a = 1 WHERE t2.a IS
RESET enable_indexonlyscan;
RESET enable_seqscan;
+-- Test BitmapHeapScan with a rescan releases resources correctly
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+CREATE TEMP TABLE rescan_bhs (a INT);
+INSERT INTO rescan_bhs VALUES (1), (2);
+CREATE INDEX ON rescan_bhs (a);
+EXPLAIN (COSTS OFF)
+SELECT * FROM rescan_bhs t1 LEFT JOIN rescan_bhs t2 ON t1.a IN
+ (SELECT a FROM rescan_bhs t3 WHERE t2.a > 1);
+ QUERY PLAN
+-----------------------------------------------------------
+ Nested Loop Left Join
+ Join Filter: (ANY (t1.a = (SubPlan 1).col1))
+ -> Bitmap Heap Scan on rescan_bhs t1
+ -> Bitmap Index Scan on rescan_bhs_a_idx
+ -> Materialize
+ -> Bitmap Heap Scan on rescan_bhs t2
+ -> Bitmap Index Scan on rescan_bhs_a_idx
+ SubPlan 1
+ -> Result
+ One-Time Filter: (t2.a > 1)
+ -> Bitmap Heap Scan on rescan_bhs t3
+ -> Bitmap Index Scan on rescan_bhs_a_idx
+(12 rows)
+
+SELECT * FROM rescan_bhs t1 LEFT JOIN rescan_bhs t2 ON t1.a IN
+ (SELECT a FROM rescan_bhs t3 WHERE t2.a > 1);
+ a | a
+---+---
+ 1 | 2
+ 2 | 2
+(2 rows)
+
+RESET enable_seqscan;
+RESET enable_indexscan;
diff --git a/src/test/regress/sql/join.sql b/src/test/regress/sql/join.sql
index d6f49f281b7..8cfc1053cb7 100644
--- a/src/test/regress/sql/join.sql
+++ b/src/test/regress/sql/join.sql
@@ -3016,3 +3016,20 @@ SELECT t1.a FROM skip_fetch t1 LEFT JOIN skip_fetch t2 ON t2.a = 1 WHERE t2.a IS
RESET enable_indexonlyscan;
RESET enable_seqscan;
+
+-- Test BitmapHeapScan with a rescan releases resources correctly
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+
+CREATE TEMP TABLE rescan_bhs (a INT);
+INSERT INTO rescan_bhs VALUES (1), (2);
+CREATE INDEX ON rescan_bhs (a);
+
+EXPLAIN (COSTS OFF)
+SELECT * FROM rescan_bhs t1 LEFT JOIN rescan_bhs t2 ON t1.a IN
+ (SELECT a FROM rescan_bhs t3 WHERE t2.a > 1);
+SELECT * FROM rescan_bhs t1 LEFT JOIN rescan_bhs t2 ON t1.a IN
+ (SELECT a FROM rescan_bhs t3 WHERE t2.a > 1);
+
+RESET enable_seqscan;
+RESET enable_indexscan;