diff options
author | Robert Haas <rhaas@postgresql.org> | 2018-04-25 15:14:14 -0400 |
---|---|---|
committer | Robert Haas <rhaas@postgresql.org> | 2018-04-25 15:25:55 -0400 |
commit | dc1057fcd878d5c062c5c4c2b548af2be513b6ab (patch) | |
tree | c59dae4627f13e4172a3caaddc1b714f3b02fe60 /src/backend/optimizer/path/allpaths.c | |
parent | f35f30f74b6abb0a2f47c91c20df606cf166e8ff (diff) | |
download | postgresql-dc1057fcd878d5c062c5c4c2b548af2be513b6ab.tar.gz postgresql-dc1057fcd878d5c062c5c4c2b548af2be513b6ab.zip |
Prevent generation of bogus subquery scan paths.
Commit 0927d2f46ddd4cf7d6bf2cc84b3be923e0aedc52 didn't check that
consider_parallel was set for the target relation or account for
the possibility that required_outer might be non-empty.
To prevent future bugs of this ilk, add some assertions to
add_partial_path and do a bit of future-proofing of the code
recently added to recurse_set_operations.
Report by Andreas Seltenreich. Patch by Jeevan Chalke. Review
by Amit Kapila and by me.
Discussion: http://postgr.es/m/CAM2+6=U+9otsyF2fYB8x_2TBeHTR90itarqW=qAEjN-kHaC7kw@mail.gmail.com
Diffstat (limited to 'src/backend/optimizer/path/allpaths.c')
-rw-r--r-- | src/backend/optimizer/path/allpaths.c | 41 |
1 files changed, 23 insertions, 18 deletions
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 9ed73da0f79..afc663cfd8f 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -2243,26 +2243,31 @@ set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel, pathkeys, required_outer)); } - /* If consider_parallel is false, there should be no partial paths. */ - Assert(sub_final_rel->consider_parallel || - sub_final_rel->partial_pathlist == NIL); - - /* Same for partial paths. */ - foreach(lc, sub_final_rel->partial_pathlist) + /* If outer rel allows parallelism, do same for partial paths. */ + if (rel->consider_parallel && bms_is_empty(required_outer)) { - Path *subpath = (Path *) lfirst(lc); - List *pathkeys; - - /* Convert subpath's pathkeys to outer representation */ - pathkeys = convert_subquery_pathkeys(root, - rel, - subpath->pathkeys, - make_tlist_from_pathtarget(subpath->pathtarget)); + /* If consider_parallel is false, there should be no partial paths. */ + Assert(sub_final_rel->consider_parallel || + sub_final_rel->partial_pathlist == NIL); - /* Generate outer path using this subpath */ - add_partial_path(rel, (Path *) - create_subqueryscan_path(root, rel, subpath, - pathkeys, required_outer)); + /* Same for partial paths. */ + foreach(lc, sub_final_rel->partial_pathlist) + { + Path *subpath = (Path *) lfirst(lc); + List *pathkeys; + + /* Convert subpath's pathkeys to outer representation */ + pathkeys = convert_subquery_pathkeys(root, + rel, + subpath->pathkeys, + make_tlist_from_pathtarget(subpath->pathtarget)); + + /* Generate outer path using this subpath */ + add_partial_path(rel, (Path *) + create_subqueryscan_path(root, rel, subpath, + pathkeys, + required_outer)); + } } } |