diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c index 122dc38db56..5a4dea89ac5 100644 --- a/src/backend/access/gist/gistget.c +++ b/src/backend/access/gist/gistget.c @@ -375,6 +375,7 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances, } so->nPageData = so->curPageData = 0; + scan->xs_hitup = NULL; /* might point into pageDataCxt */ if (so->pageDataCxt) MemoryContextReset(so->pageDataCxt); @@ -642,6 +643,7 @@ gistgettuple(IndexScanDesc scan, ScanDirection dir) so->firstCall = false; so->curPageData = so->nPageData = 0; + scan->xs_hitup = NULL; if (so->pageDataCxt) MemoryContextReset(so->pageDataCxt); @@ -766,6 +768,7 @@ gistgetbitmap(IndexScanDesc scan, TIDBitmap *tbm) /* Begin the scan by processing the root page */ so->curPageData = so->nPageData = 0; + scan->xs_hitup = NULL; if (so->pageDataCxt) MemoryContextReset(so->pageDataCxt); diff --git a/src/backend/access/gist/gistscan.c b/src/backend/access/gist/gistscan.c index 81ff8fc8b6e..058544e2ae2 100644 --- a/src/backend/access/gist/gistscan.c +++ b/src/backend/access/gist/gistscan.c @@ -313,6 +313,9 @@ gistrescan(IndexScanDesc scan, ScanKey key, int nkeys, if (!first_time) pfree(fn_extras); } + + /* any previous xs_hitup will have been pfree'd in context resets above */ + scan->xs_hitup = NULL; } void diff --git a/src/test/regress/expected/gist.out b/src/test/regress/expected/gist.out index c7181b0397e..91f99981409 100644 --- a/src/test/regress/expected/gist.out +++ b/src/test/regress/expected/gist.out @@ -114,6 +114,40 @@ order by point(0.101, 0.101) <-> p; (0.5,0.5) (11 rows) +-- Check case with multiple rescans (bug #14641) +explain (costs off) +select p from + (values (box(point(0,0), point(0.5,0.5))), + (box(point(0.5,0.5), point(0.75,0.75))), + (box(point(0.8,0.8), point(1.0,1.0)))) as v(bb) +cross join lateral + (select p from gist_tbl where p <@ bb order by p <-> bb[0] limit 2) ss; + QUERY PLAN +-------------------------------------------------------------------- + Nested Loop + -> Values Scan on "*VALUES*" + -> Limit + -> Index Only Scan using gist_tbl_point_index on gist_tbl + Index Cond: (p <@ "*VALUES*".column1) + Order By: (p <-> ("*VALUES*".column1)[0]) +(6 rows) + +select p from + (values (box(point(0,0), point(0.5,0.5))), + (box(point(0.5,0.5), point(0.75,0.75))), + (box(point(0.8,0.8), point(1.0,1.0)))) as v(bb) +cross join lateral + (select p from gist_tbl where p <@ bb order by p <-> bb[0] limit 2) ss; + p +------------- + (0.5,0.5) + (0.45,0.45) + (0.75,0.75) + (0.7,0.7) + (1,1) + (0.95,0.95) +(6 rows) + drop index gist_tbl_point_index; -- Test index-only scan with box opclass create index gist_tbl_box_index on gist_tbl using gist (b); diff --git a/src/test/regress/sql/gist.sql b/src/test/regress/sql/gist.sql index 9d4ff1e97e9..49126fd466d 100644 --- a/src/test/regress/sql/gist.sql +++ b/src/test/regress/sql/gist.sql @@ -69,6 +69,22 @@ order by point(0.101, 0.101) <-> p; select p from gist_tbl where p <@ box(point(0,0), point(0.5, 0.5)) order by point(0.101, 0.101) <-> p; +-- Check case with multiple rescans (bug #14641) +explain (costs off) +select p from + (values (box(point(0,0), point(0.5,0.5))), + (box(point(0.5,0.5), point(0.75,0.75))), + (box(point(0.8,0.8), point(1.0,1.0)))) as v(bb) +cross join lateral + (select p from gist_tbl where p <@ bb order by p <-> bb[0] limit 2) ss; + +select p from + (values (box(point(0,0), point(0.5,0.5))), + (box(point(0.5,0.5), point(0.75,0.75))), + (box(point(0.8,0.8), point(1.0,1.0)))) as v(bb) +cross join lateral + (select p from gist_tbl where p <@ bb order by p <-> bb[0] limit 2) ss; + drop index gist_tbl_point_index; -- Test index-only scan with box opclass