diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 0b6a44cbce0932de8bb4a30a1117badd4a64c872..654ee5849b16108310c90268da7c5b76c1f1dfb4 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -1129,9 +1129,7 @@ set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel, /* * It's possible that constraint exclusion proved the subquery empty. If * so, it's convenient to turn it back into a dummy path so that we will - * recognize appropriate optimizations at this query level. (But see - * create_append_plan in createplan.c, which has to reverse this - * substitution.) + * recognize appropriate optimizations at this level. */ if (is_dummy_plan(rel->subplan)) { diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 42f58bd5c7c824468fe1cd96dfbb49a155456cca..99412b6e0783d46250c1e364031e95c2c006efd4 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -664,49 +664,30 @@ static Plan * create_append_plan(PlannerInfo *root, AppendPath *best_path) { Append *plan; - RelOptInfo *rel = best_path->path.parent; - List *tlist = build_relation_tlist(rel); + List *tlist = build_relation_tlist(best_path->path.parent); List *subplans = NIL; ListCell *subpaths; /* - * The subpaths list could be empty, if every child was proven empty by - * constraint exclusion. In that case generate a dummy plan that returns - * no rows. + * It is possible for the subplans list to contain only one entry, or even + * no entries. Handle these cases specially. * - * Note that an AppendPath with no members is also generated in certain - * cases where there was no appending construct at all, but we know the - * relation is empty (see set_dummy_rel_pathlist). + * XXX ideally, if there's just one entry, we'd not bother to generate an + * Append node but just return the single child. At the moment this does + * not work because the varno of the child scan plan won't match the + * parent-rel Vars it'll be asked to emit. */ if (best_path->subpaths == NIL) { - /* - * If this is a dummy path for a subquery, we have to wrap the - * subquery's original plan in a SubqueryScan so that setrefs.c will - * do the right things. (In particular, it must pull up the - * subquery's rangetable so that the executor will apply permissions - * checks to those rels at runtime.) - */ - if (rel->rtekind == RTE_SUBQUERY) - { - Assert(is_dummy_plan(rel->subplan)); - return (Plan *) make_subqueryscan(tlist, - NIL, - rel->relid, - rel->subplan); - } - else - { - /* Generate a Result plan with constant-FALSE gating qual */ - return (Plan *) make_result(root, - tlist, - (Node *) list_make1(makeBoolConst(false, - false)), - NULL); - } + /* Generate a Result plan with constant-FALSE gating qual */ + return (Plan *) make_result(root, + tlist, + (Node *) list_make1(makeBoolConst(false, + false)), + NULL); } - /* Build the plan for each child */ + /* Normal case with multiple subpaths */ foreach(subpaths, best_path->subpaths) { Path *subpath = (Path *) lfirst(subpaths); @@ -714,13 +695,6 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path) subplans = lappend(subplans, create_plan_recurse(root, subpath)); } - /* - * XXX ideally, if there's just one child, we'd not bother to generate an - * Append node but just return the single child. At the moment this does - * not work because the varno of the child scan plan won't match the - * parent-rel Vars it'll be asked to emit. - */ - plan = make_append(subplans, tlist); return (Plan *) plan; diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out index 68afecc91f7760b9d7fbc50f58dfd59b2b70ea46..e8930cb2eb58543e45a0924a1c1a1fe846fe0ced 100644 --- a/src/test/regress/expected/privileges.out +++ b/src/test/regress/expected/privileges.out @@ -198,8 +198,6 @@ CREATE VIEW atestv1 AS SELECT * FROM atest1; -- ok /* The next *should* fail, but it's not implemented that way yet. */ CREATE VIEW atestv2 AS SELECT * FROM atest2; CREATE VIEW atestv3 AS SELECT * FROM atest3; -- ok -/* Empty view is a corner case that failed in 9.2. */ -CREATE VIEW atestv0 AS SELECT 0 as x WHERE false; -- ok SELECT * FROM atestv1; -- ok a | b ---+----- @@ -226,8 +224,6 @@ SELECT * FROM atestv3; -- ok -----+-----+------- (0 rows) -SELECT * FROM atestv0; -- fail -ERROR: permission denied for relation atestv0 CREATE VIEW atestv4 AS SELECT * FROM atestv3; -- nested view SELECT * FROM atestv4; -- ok one | two | three @@ -1390,7 +1386,6 @@ drop table dep_priv_test; drop sequence x_seq; DROP FUNCTION testfunc2(int); DROP FUNCTION testfunc4(boolean); -DROP VIEW atestv0; DROP VIEW atestv1; DROP VIEW atestv2; -- this should cascade to drop atestv4 diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql index 6ac3378a8d003e8204b1bc1fd3e85b046cd7fd2c..d4d328e649f7244dd8cb520058849221aab40edf 100644 --- a/src/test/regress/sql/privileges.sql +++ b/src/test/regress/sql/privileges.sql @@ -147,8 +147,6 @@ CREATE VIEW atestv1 AS SELECT * FROM atest1; -- ok /* The next *should* fail, but it's not implemented that way yet. */ CREATE VIEW atestv2 AS SELECT * FROM atest2; CREATE VIEW atestv3 AS SELECT * FROM atest3; -- ok -/* Empty view is a corner case that failed in 9.2. */ -CREATE VIEW atestv0 AS SELECT 0 as x WHERE false; -- ok SELECT * FROM atestv1; -- ok SELECT * FROM atestv2; -- fail @@ -160,7 +158,6 @@ SET SESSION AUTHORIZATION regressuser4; SELECT * FROM atestv1; -- ok SELECT * FROM atestv2; -- fail SELECT * FROM atestv3; -- ok -SELECT * FROM atestv0; -- fail CREATE VIEW atestv4 AS SELECT * FROM atestv3; -- nested view SELECT * FROM atestv4; -- ok @@ -831,7 +828,6 @@ drop sequence x_seq; DROP FUNCTION testfunc2(int); DROP FUNCTION testfunc4(boolean); -DROP VIEW atestv0; DROP VIEW atestv1; DROP VIEW atestv2; -- this should cascade to drop atestv4