From: Tom Lane Date: Sat, 3 Feb 2001 21:17:52 +0000 (+0000) Subject: Fix inappropriate attempt to push down qual clauses into a view that X-Git-Tag: REL7_1~586 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=503f042cd764b18aa0df81d764bc40d0f4e4c24a;p=postgresql Fix inappropriate attempt to push down qual clauses into a view that has UNION/INTERSECT/EXCEPT operations. Per bug report from Ferrier. --- diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index fa4e1dfd90..7d44c4dcfa 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.70 2001/01/24 19:42:57 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/allpaths.c,v 1.71 2001/02/03 21:17:52 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -101,8 +101,6 @@ set_base_rel_pathlists(Query *root) if (rel->issubquery) { /* Subquery --- generate a separate plan for it */ - List *upperrestrictlist; - List *lst; /* * If there are any restriction clauses that have been attached @@ -118,6 +116,11 @@ set_base_rel_pathlists(Query *root) * Currently, we do not push down clauses that contain subselects, * mainly because I'm not sure it will work correctly (the * subplan hasn't yet transformed sublinks to subselects). + * Also, if the subquery contains set ops (UNION/INTERSECT/EXCEPT) + * we do not push down any qual clauses, since the planner doesn't + * support quals at the top level of a setop. (With suitable + * analysis we could try to push the quals down into the component + * queries of the setop, but getting it right is not trivial.) * Non-pushed-down clauses will get evaluated as qpquals of * the SubqueryScan node. * @@ -125,41 +128,48 @@ set_base_rel_pathlists(Query *root) * decision not to push down, because it'd result in a worse * plan? */ - upperrestrictlist = NIL; - foreach(lst, rel->baserestrictinfo) + if (rte->subquery->setOperations == NULL) { - RestrictInfo *rinfo = (RestrictInfo *) lfirst(lst); - Node *clause = (Node *) rinfo->clause; + /* OK to consider pushing down individual quals */ + List *upperrestrictlist = NIL; + List *lst; - if (contain_subplans(clause)) + foreach(lst, rel->baserestrictinfo) { - /* Keep it in the upper query */ - upperrestrictlist = lappend(upperrestrictlist, rinfo); - } - else - { - /* - * We need to replace Vars in the clause (which must - * refer to outputs of the subquery) with copies of the - * subquery's targetlist expressions. Note that at this - * point, any uplevel Vars in the clause should have been - * replaced with Params, so they need no work. - */ - clause = ResolveNew(clause, rti, 0, - rte->subquery->targetList, - CMD_SELECT, 0); - rte->subquery->havingQual = - make_and_qual(rte->subquery->havingQual, - clause); - /* - * We need not change the subquery's hasAggs or - * hasSublinks flags, since we can't be pushing down - * any aggregates that weren't there before, and we - * don't push down subselects at all. - */ + RestrictInfo *rinfo = (RestrictInfo *) lfirst(lst); + Node *clause = (Node *) rinfo->clause; + + if (contain_subplans(clause)) + { + /* Keep it in the upper query */ + upperrestrictlist = lappend(upperrestrictlist, rinfo); + } + else + { + /* + * We need to replace Vars in the clause (which must + * refer to outputs of the subquery) with copies of + * the subquery's targetlist expressions. Note that + * at this point, any uplevel Vars in the clause + * should have been replaced with Params, so they + * need no work. + */ + clause = ResolveNew(clause, rti, 0, + rte->subquery->targetList, + CMD_SELECT, 0); + rte->subquery->havingQual = + make_and_qual(rte->subquery->havingQual, + clause); + /* + * We need not change the subquery's hasAggs or + * hasSublinks flags, since we can't be pushing down + * any aggregates that weren't there before, and we + * don't push down subselects at all. + */ + } } + rel->baserestrictinfo = upperrestrictlist; } - rel->baserestrictinfo = upperrestrictlist; /* Generate the plan for the subquery */ rel->subplan = subquery_planner(rte->subquery,