Fix memory leak in IndexScan node with reordering
authorAlexander Korotkov <[email protected]>
Mon, 14 Feb 2022 00:26:55 +0000 (03:26 +0300)
committerAlexander Korotkov <[email protected]>
Mon, 14 Feb 2022 01:17:04 +0000 (04:17 +0300)
Fix ExecReScanIndexScan() to free the referenced tuples while emptying the
priority queue.  Backpatch to all supported versions.

Discussion: https://postgr.es/m/CAHqSB9gECMENBQmpbv5rvmT3HTaORmMK3Ukg73DsX5H7EJV7jw%40mail.gmail.com
Author: Aliaksandr Kalenik
Reviewed-by: Tom Lane, Alexander Korotkov
Backpatch-through: 10

src/backend/executor/nodeIndexscan.c
src/test/regress/expected/create_index.out
src/test/regress/sql/create_index.sql

index a91f135be7a9a1b66512decff8c8375a44411df8..90b2699a96be915bc3eb091ade356e47d053c2c0 100644 (file)
@@ -574,8 +574,12 @@ ExecReScanIndexScan(IndexScanState *node)
    /* flush the reorder queue */
    if (node->iss_ReorderQueue)
    {
+       HeapTuple   tuple;
        while (!pairingheap_is_empty(node->iss_ReorderQueue))
-           reorderqueue_pop(node);
+       {
+           tuple = reorderqueue_pop(node);
+           heap_freetuple(tuple);
+       }
    }
 
    /* reset index scan */
index 1cc475abb0648b623732bbb9804e79befe66b7a1..d55aec3a1d0fff1beab00ad961ac6e2d2ac0eadc 100644 (file)
@@ -588,6 +588,33 @@ SELECT circle_center(f1), round(radius(f1)) as radius FROM gcircle_tbl ORDER BY
  (751.5,2655)   |     20
 (10 rows)
 
+EXPLAIN (COSTS OFF)
+SELECT point(x,x), (SELECT f1 FROM gpolygon_tbl ORDER BY f1 <-> point(x,x) LIMIT 1) as c FROM generate_series(0,10,1) x;
+                                         QUERY PLAN                                         
+--------------------------------------------------------------------------------------------
+ Function Scan on generate_series x
+   SubPlan 1
+     ->  Limit
+           ->  Index Scan using ggpolygonind on gpolygon_tbl
+                 Order By: (f1 <-> point((x.x)::double precision, (x.x)::double precision))
+(5 rows)
+
+SELECT point(x,x), (SELECT f1 FROM gpolygon_tbl ORDER BY f1 <-> point(x,x) LIMIT 1) as c FROM generate_series(0,10,1) x;
+  point  |                     c                     
+---------+-------------------------------------------
+ (0,0)   | ((240,359),(240,455),(337,455),(337,359))
+ (1,1)   | ((240,359),(240,455),(337,455),(337,359))
+ (2,2)   | ((240,359),(240,455),(337,455),(337,359))
+ (3,3)   | ((240,359),(240,455),(337,455),(337,359))
+ (4,4)   | ((240,359),(240,455),(337,455),(337,359))
+ (5,5)   | ((240,359),(240,455),(337,455),(337,359))
+ (6,6)   | ((240,359),(240,455),(337,455),(337,359))
+ (7,7)   | ((240,359),(240,455),(337,455),(337,359))
+ (8,8)   | ((240,359),(240,455),(337,455),(337,359))
+ (9,9)   | ((240,359),(240,455),(337,455),(337,359))
+ (10,10) | ((240,359),(240,455),(337,455),(337,359))
+(11 rows)
+
 -- Now check the results from bitmap indexscan
 SET enable_seqscan = OFF;
 SET enable_indexscan = OFF;
index a06c98074b881c9b8e3cf2600165776dd4c8aa43..d8fded3d930ae68e5016b163273e145824e7127a 100644 (file)
@@ -239,6 +239,10 @@ EXPLAIN (COSTS OFF)
 SELECT circle_center(f1), round(radius(f1)) as radius FROM gcircle_tbl ORDER BY f1 <-> '(200,300)'::point LIMIT 10;
 SELECT circle_center(f1), round(radius(f1)) as radius FROM gcircle_tbl ORDER BY f1 <-> '(200,300)'::point LIMIT 10;
 
+EXPLAIN (COSTS OFF)
+SELECT point(x,x), (SELECT f1 FROM gpolygon_tbl ORDER BY f1 <-> point(x,x) LIMIT 1) as c FROM generate_series(0,10,1) x;
+SELECT point(x,x), (SELECT f1 FROM gpolygon_tbl ORDER BY f1 <-> point(x,x) LIMIT 1) as c FROM generate_series(0,10,1) x;
+
 -- Now check the results from bitmap indexscan
 SET enable_seqscan = OFF;
 SET enable_indexscan = OFF;