diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index a48456714c2cbeb703da9cf48fef99502a6cb2a0..c949ca0e37e12eab4f9d70e41962d232bec38981 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -413,6 +413,18 @@ bring_to_singleQE(PlannerInfo *root, RelOptInfo *rel, List *outer_quals) if (origpath->param_info) continue; + /* + * param_info cannot cover the case that an index path's orderbyclauses + * See github issue: https://github.com/greenplum-db/gpdb/issues/9733 + */ + if (IsA(origpath, IndexPath)) + { + IndexPath *ipath = (IndexPath *) origpath; + if (contains_outer_params((Node *) ipath->indexorderbys, + (void *) root)) + continue; + } + CdbPathLocus_MakeSingleQE(&target_locus, origpath->locus.numsegments); diff --git a/src/test/regress/expected/join_gp.out b/src/test/regress/expected/join_gp.out index 24b60a258598966ef589fe7309bb65afa7ff1c23..4c597e0a1a571b209f5d311677daf45fbc94e6f4 100644 --- a/src/test/regress/expected/join_gp.out +++ b/src/test/regress/expected/join_gp.out @@ -1117,3 +1117,70 @@ NOTICE: prefetch join qual in slice 0 of plannode 2 reset Test_print_prefetch_joinqual; reset optimizer; +-- Github Issue: https://github.com/greenplum-db/gpdb/issues/9733 +-- Previously in the function bring_to_outer_query and +-- bring_to_singleQE it depends on the path->param_info field +-- to determine if the path contains outerParams. This is not +-- enought. The following case would SegFault before because +-- the indexpath's orderby clause contains outerParams. +create table gist_tbl_github9733 (b box, p point, c circle); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause, and no column type is suitable for a distribution key. Creating a NULL policy entry. +insert into gist_tbl_github9733 +select box(point(0.05*i, 0.05*i), point(0.05*i, 0.05*i)), + point(0.05*i, 0.05*i), + circle(point(0.05*i, 0.05*i), 1.0) +from generate_series(0,10000) as i; +vacuum analyze gist_tbl_github9733; +create index gist_tbl_point_index_github9733 on gist_tbl_github9733 using gist (p); +set enable_seqscan=off; +set enable_bitmapscan=off; +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_github9733 where p <@ bb order by p <-> bb[0] limit 2) ss; +ERROR: could not devise a query plan for the given query (pathnode.c:417) +reset enable_seqscan; +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_github9733 where p <@ bb order by p <-> bb[0] limit 2) ss; + QUERY PLAN +------------------------------------------------------------------------------------------- + Nested Loop + -> Values Scan on "*VALUES*" + -> Materialize + -> Subquery Scan on ss + -> Limit + -> Sort + Sort Key: ((gist_tbl_github9733.p <-> ("*VALUES*".column1)[0])) + -> Result + Filter: (gist_tbl_github9733.p <@ "*VALUES*".column1) + -> Materialize + -> Gather Motion 3:1 (slice1; segments: 3) + -> Seq Scan on gist_tbl_github9733 + Optimizer: Postgres query optimizer +(13 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_github9733 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) + +reset enable_bitmapscan; diff --git a/src/test/regress/expected/join_gp_optimizer.out b/src/test/regress/expected/join_gp_optimizer.out index 6e518e38642bd20f73b1ab811c1b497149f16b0b..0f54b6e800639a4944fd45b05112c5098e7cb9a8 100644 --- a/src/test/regress/expected/join_gp_optimizer.out +++ b/src/test/regress/expected/join_gp_optimizer.out @@ -1133,3 +1133,70 @@ NOTICE: prefetch join qual in slice 0 of plannode 2 reset Test_print_prefetch_joinqual; reset optimizer; +-- Github Issue: https://github.com/greenplum-db/gpdb/issues/9733 +-- Previously in the function bring_to_outer_query and +-- bring_to_singleQE it depends on the path->param_info field +-- to determine if the path contains outerParams. This is not +-- enought. The following case would SegFault before because +-- the indexpath's orderby clause contains outerParams. +create table gist_tbl_github9733 (b box, p point, c circle); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause, and no column type is suitable for a distribution key. Creating a NULL policy entry. +insert into gist_tbl_github9733 +select box(point(0.05*i, 0.05*i), point(0.05*i, 0.05*i)), + point(0.05*i, 0.05*i), + circle(point(0.05*i, 0.05*i), 1.0) +from generate_series(0,10000) as i; +vacuum analyze gist_tbl_github9733; +create index gist_tbl_point_index_github9733 on gist_tbl_github9733 using gist (p); +set enable_seqscan=off; +set enable_bitmapscan=off; +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_github9733 where p <@ bb order by p <-> bb[0] limit 2) ss; +ERROR: could not devise a query plan for the given query (pathnode.c:417) +reset enable_seqscan; +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_github9733 where p <@ bb order by p <-> bb[0] limit 2) ss; + QUERY PLAN +------------------------------------------------------------------------------------------- + Nested Loop + -> Values Scan on "*VALUES*" + -> Materialize + -> Subquery Scan on ss + -> Limit + -> Sort + Sort Key: ((gist_tbl_github9733.p <-> ("*VALUES*".column1)[0])) + -> Result + Filter: (gist_tbl_github9733.p <@ "*VALUES*".column1) + -> Materialize + -> Gather Motion 3:1 (slice1; segments: 3) + -> Seq Scan on gist_tbl_github9733 + Optimizer: Postgres query optimizer +(13 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_github9733 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) + +reset enable_bitmapscan; diff --git a/src/test/regress/sql/join_gp.sql b/src/test/regress/sql/join_gp.sql index 06629f32c69febbc4db53b7220cee93431550c1d..6e813f3377df6916851747297b539abe9b41a3c0 100644 --- a/src/test/regress/sql/join_gp.sql +++ b/src/test/regress/sql/join_gp.sql @@ -544,3 +544,45 @@ on t1.b = t2.b and t1.a > any (select sum(b) from t3_test_pretch_join_qual t3 wh reset Test_print_prefetch_joinqual; reset optimizer; + +-- Github Issue: https://github.com/greenplum-db/gpdb/issues/9733 +-- Previously in the function bring_to_outer_query and +-- bring_to_singleQE it depends on the path->param_info field +-- to determine if the path contains outerParams. This is not +-- enought. The following case would SegFault before because +-- the indexpath's orderby clause contains outerParams. +create table gist_tbl_github9733 (b box, p point, c circle); +insert into gist_tbl_github9733 +select box(point(0.05*i, 0.05*i), point(0.05*i, 0.05*i)), + point(0.05*i, 0.05*i), + circle(point(0.05*i, 0.05*i), 1.0) +from generate_series(0,10000) as i; +vacuum analyze gist_tbl_github9733; +create index gist_tbl_point_index_github9733 on gist_tbl_github9733 using gist (p); +set enable_seqscan=off; +set enable_bitmapscan=off; +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_github9733 where p <@ bb order by p <-> bb[0] limit 2) ss; + +reset enable_seqscan; +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_github9733 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_github9733 where p <@ bb order by p <-> bb[0] limit 2) ss; + +reset enable_bitmapscan;