diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c index 20f695cee4e..1a69d40a715 100644 --- a/src/backend/access/gist/gistget.c +++ b/src/backend/access/gist/gistget.c @@ -302,6 +302,7 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances, } so->nPageData = so->curPageData = 0; + scan->xs_itup = NULL; /* might point into pageDataCxt */ if (so->pageDataCxt) MemoryContextReset(so->pageDataCxt); @@ -552,6 +553,7 @@ gistgettuple(PG_FUNCTION_ARGS) so->firstCall = false; so->curPageData = so->nPageData = 0; + scan->xs_itup = NULL; if (so->pageDataCxt) MemoryContextReset(so->pageDataCxt); @@ -629,6 +631,7 @@ gistgetbitmap(PG_FUNCTION_ARGS) /* Begin the scan by processing the root page */ so->curPageData = so->nPageData = 0; + scan->xs_itup = NULL; if (so->pageDataCxt) MemoryContextReset(so->pageDataCxt); diff --git a/src/backend/access/gist/gistscan.c b/src/backend/access/gist/gistscan.c index 62f1fdd8da2..cde9e794967 100644 --- a/src/backend/access/gist/gistscan.c +++ b/src/backend/access/gist/gistscan.c @@ -318,6 +318,9 @@ gistrescan(PG_FUNCTION_ARGS) pfree(fn_extras); } + /* any previous xs_itup will have been pfree'd in context resets above */ + scan->xs_itup = NULL; + PG_RETURN_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