mirror of
https://github.com/postgres/postgres.git
synced 2025-11-21 00:42:43 +03:00
8.4 pgindent run, with new combined Linux/FreeBSD/MinGW typedef list
provided by Andrew.
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.65 2009/04/28 21:31:16 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.66 2009/06/11 14:48:59 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -52,16 +52,16 @@ static Node *pull_up_simple_subquery(PlannerInfo *root, Node *jtnode,
|
||||
static Node *pull_up_simple_union_all(PlannerInfo *root, Node *jtnode,
|
||||
RangeTblEntry *rte);
|
||||
static void pull_up_union_leaf_queries(Node *setOp, PlannerInfo *root,
|
||||
int parentRTindex, Query *setOpQuery,
|
||||
int childRToffset);
|
||||
int parentRTindex, Query *setOpQuery,
|
||||
int childRToffset);
|
||||
static void make_setop_translation_list(Query *query, Index newvarno,
|
||||
List **translated_vars);
|
||||
List **translated_vars);
|
||||
static bool is_simple_subquery(Query *subquery);
|
||||
static bool is_simple_union_all(Query *subquery);
|
||||
static bool is_simple_union_all_recurse(Node *setOp, Query *setOpQuery,
|
||||
List *colTypes);
|
||||
static List *insert_targetlist_placeholders(PlannerInfo *root, List *tlist,
|
||||
int varno, bool wrap_non_vars);
|
||||
int varno, bool wrap_non_vars);
|
||||
static bool is_safe_append_member(Query *subquery);
|
||||
static void resolvenew_in_jointree(Node *jtnode, int varno, RangeTblEntry *rte,
|
||||
List *subtlist, List *subtlist_with_phvs,
|
||||
@@ -74,7 +74,7 @@ static void reduce_outer_joins_pass2(Node *jtnode,
|
||||
List *nonnullable_vars,
|
||||
List *forced_null_vars);
|
||||
static void substitute_multiple_relids(Node *node,
|
||||
int varno, Relids subrelids);
|
||||
int varno, Relids subrelids);
|
||||
static void fix_append_rel_relids(List *append_rel_list, int varno,
|
||||
Relids subrelids);
|
||||
static Node *find_jointree_node_for_rel(Node *jtnode, int relid);
|
||||
@@ -87,7 +87,7 @@ static Node *find_jointree_node_for_rel(Node *jtnode, int relid);
|
||||
*
|
||||
* A clause "foo op ANY (sub-SELECT)" can be processed by pulling the
|
||||
* sub-SELECT up to become a rangetable entry and treating the implied
|
||||
* comparisons as quals of a semijoin. However, this optimization *only*
|
||||
* comparisons as quals of a semijoin. However, this optimization *only*
|
||||
* works at the top level of WHERE or a JOIN/ON clause, because we cannot
|
||||
* distinguish whether the ANY ought to return FALSE or NULL in cases
|
||||
* involving NULL inputs. Also, in an outer join's ON clause we can only
|
||||
@@ -104,7 +104,7 @@ static Node *find_jointree_node_for_rel(Node *jtnode, int relid);
|
||||
* transformations if any are found.
|
||||
*
|
||||
* This routine has to run before preprocess_expression(), so the quals
|
||||
* clauses are not yet reduced to implicit-AND format. That means we need
|
||||
* clauses are not yet reduced to implicit-AND format. That means we need
|
||||
* to recursively search through explicit AND clauses, which are
|
||||
* probably only binary ANDs. We stop as soon as we hit a non-AND item.
|
||||
*/
|
||||
@@ -162,8 +162,8 @@ pull_up_sublinks_jointree_recurse(PlannerInfo *root, Node *jtnode,
|
||||
/* First, recurse to process children and collect their relids */
|
||||
foreach(l, f->fromlist)
|
||||
{
|
||||
Node *newchild;
|
||||
Relids childrelids;
|
||||
Node *newchild;
|
||||
Relids childrelids;
|
||||
|
||||
newchild = pull_up_sublinks_jointree_recurse(root,
|
||||
lfirst(l),
|
||||
@@ -181,8 +181,8 @@ pull_up_sublinks_jointree_recurse(PlannerInfo *root, Node *jtnode,
|
||||
|
||||
/*
|
||||
* Note that the result will be either newf, or a stack of JoinExprs
|
||||
* with newf at the base. We rely on subsequent optimization steps
|
||||
* to flatten this and rearrange the joins as needed.
|
||||
* with newf at the base. We rely on subsequent optimization steps to
|
||||
* flatten this and rearrange the joins as needed.
|
||||
*
|
||||
* Although we could include the pulled-up subqueries in the returned
|
||||
* relids, there's no need since upper quals couldn't refer to their
|
||||
@@ -199,8 +199,8 @@ pull_up_sublinks_jointree_recurse(PlannerInfo *root, Node *jtnode,
|
||||
Node *jtlink;
|
||||
|
||||
/*
|
||||
* Make a modifiable copy of join node, but don't bother copying
|
||||
* its subnodes (yet).
|
||||
* Make a modifiable copy of join node, but don't bother copying its
|
||||
* subnodes (yet).
|
||||
*/
|
||||
j = (JoinExpr *) palloc(sizeof(JoinExpr));
|
||||
memcpy(j, jtnode, sizeof(JoinExpr));
|
||||
@@ -214,19 +214,19 @@ pull_up_sublinks_jointree_recurse(PlannerInfo *root, Node *jtnode,
|
||||
|
||||
/*
|
||||
* Now process qual, showing appropriate child relids as available,
|
||||
* and attach any pulled-up jointree items at the right place.
|
||||
* In the inner-join case we put new JoinExprs above the existing one
|
||||
* (much as for a FromExpr-style join). In outer-join cases the
|
||||
* new JoinExprs must go into the nullable side of the outer join.
|
||||
* The point of the available_rels machinations is to ensure that we
|
||||
* only pull up quals for which that's okay.
|
||||
* and attach any pulled-up jointree items at the right place. In the
|
||||
* inner-join case we put new JoinExprs above the existing one (much
|
||||
* as for a FromExpr-style join). In outer-join cases the new
|
||||
* JoinExprs must go into the nullable side of the outer join. The
|
||||
* point of the available_rels machinations is to ensure that we only
|
||||
* pull up quals for which that's okay.
|
||||
*
|
||||
* XXX for the moment, we refrain from pulling up IN/EXISTS clauses
|
||||
* appearing in LEFT or RIGHT join conditions. Although it is
|
||||
* appearing in LEFT or RIGHT join conditions. Although it is
|
||||
* semantically valid to do so under the above conditions, we end up
|
||||
* with a query in which the semijoin or antijoin must be evaluated
|
||||
* below the outer join, which could perform far worse than leaving
|
||||
* it as a sublink that is executed only for row pairs that meet the
|
||||
* below the outer join, which could perform far worse than leaving it
|
||||
* as a sublink that is executed only for row pairs that meet the
|
||||
* other join conditions. Fixing this seems to require considerable
|
||||
* restructuring of the executor, but maybe someday it can happen.
|
||||
*
|
||||
@@ -238,7 +238,7 @@ pull_up_sublinks_jointree_recurse(PlannerInfo *root, Node *jtnode,
|
||||
case JOIN_INNER:
|
||||
j->quals = pull_up_sublinks_qual_recurse(root, j->quals,
|
||||
bms_union(leftrelids,
|
||||
rightrelids),
|
||||
rightrelids),
|
||||
&jtlink);
|
||||
break;
|
||||
case JOIN_LEFT:
|
||||
@@ -267,7 +267,7 @@ pull_up_sublinks_jointree_recurse(PlannerInfo *root, Node *jtnode,
|
||||
/*
|
||||
* Although we could include the pulled-up subqueries in the returned
|
||||
* relids, there's no need since upper quals couldn't refer to their
|
||||
* outputs anyway. But we *do* need to include the join's own rtindex
|
||||
* outputs anyway. But we *do* need to include the join's own rtindex
|
||||
* because we haven't yet collapsed join alias variables, so upper
|
||||
* levels would mistakenly think they couldn't use references to this
|
||||
* join.
|
||||
@@ -416,7 +416,7 @@ inline_set_returning_functions(PlannerInfo *root)
|
||||
|
||||
if (rte->rtekind == RTE_FUNCTION)
|
||||
{
|
||||
Query *funcquery;
|
||||
Query *funcquery;
|
||||
|
||||
/* Check safety of expansion, and expand if possible */
|
||||
funcquery = inline_set_returning_function(root, rte);
|
||||
@@ -495,10 +495,10 @@ pull_up_subqueries(PlannerInfo *root, Node *jtnode,
|
||||
* Alternatively, is it a simple UNION ALL subquery? If so, flatten
|
||||
* into an "append relation".
|
||||
*
|
||||
* It's safe to do this regardless of whether this query is
|
||||
* itself an appendrel member. (If you're thinking we should try to
|
||||
* flatten the two levels of appendrel together, you're right; but we
|
||||
* handle that in set_append_rel_pathlist, not here.)
|
||||
* It's safe to do this regardless of whether this query is itself an
|
||||
* appendrel member. (If you're thinking we should try to flatten the
|
||||
* two levels of appendrel together, you're right; but we handle that
|
||||
* in set_append_rel_pathlist, not here.)
|
||||
*/
|
||||
if (rte->rtekind == RTE_SUBQUERY &&
|
||||
is_simple_union_all(rte->subquery))
|
||||
@@ -637,10 +637,10 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte,
|
||||
* pull_up_subqueries' processing is complete for its jointree and
|
||||
* rangetable.
|
||||
*
|
||||
* Note: we should pass NULL for containing-join info even if we are within
|
||||
* an outer join in the upper query; the lower query starts with a clean
|
||||
* slate for outer-join semantics. Likewise, we say we aren't handling an
|
||||
* appendrel member.
|
||||
* Note: we should pass NULL for containing-join info even if we are
|
||||
* within an outer join in the upper query; the lower query starts with a
|
||||
* clean slate for outer-join semantics. Likewise, we say we aren't
|
||||
* handling an appendrel member.
|
||||
*/
|
||||
subquery->jointree = (FromExpr *)
|
||||
pull_up_subqueries(subroot, (Node *) subquery->jointree, NULL, NULL);
|
||||
@@ -673,8 +673,8 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte,
|
||||
|
||||
/*
|
||||
* Adjust level-0 varnos in subquery so that we can append its rangetable
|
||||
* to upper query's. We have to fix the subquery's append_rel_list
|
||||
* as well.
|
||||
* to upper query's. We have to fix the subquery's append_rel_list as
|
||||
* well.
|
||||
*/
|
||||
rtoffset = list_length(parse->rtable);
|
||||
OffsetVarNodes((Node *) subquery, rtoffset, 0);
|
||||
@@ -691,15 +691,15 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte,
|
||||
* The subquery's targetlist items are now in the appropriate form to
|
||||
* insert into the top query, but if we are under an outer join then
|
||||
* non-nullable items may have to be turned into PlaceHolderVars. If we
|
||||
* are dealing with an appendrel member then anything that's not a
|
||||
* simple Var has to be turned into a PlaceHolderVar.
|
||||
* are dealing with an appendrel member then anything that's not a simple
|
||||
* Var has to be turned into a PlaceHolderVar.
|
||||
*/
|
||||
subtlist = subquery->targetList;
|
||||
if (lowest_outer_join != NULL || containing_appendrel != NULL)
|
||||
subtlist_with_phvs = insert_targetlist_placeholders(root,
|
||||
subtlist,
|
||||
varno,
|
||||
containing_appendrel != NULL);
|
||||
containing_appendrel != NULL);
|
||||
else
|
||||
subtlist_with_phvs = subtlist;
|
||||
|
||||
@@ -709,7 +709,7 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte,
|
||||
* replace any of the jointree structure. (This'd be a lot cleaner if we
|
||||
* could use query_tree_mutator.) We have to use PHVs in the targetList,
|
||||
* returningList, and havingQual, since those are certainly above any
|
||||
* outer join. resolvenew_in_jointree tracks its location in the jointree
|
||||
* outer join. resolvenew_in_jointree tracks its location in the jointree
|
||||
* and uses PHVs or not appropriately.
|
||||
*/
|
||||
parse->targetList = (List *)
|
||||
@@ -730,11 +730,11 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte,
|
||||
subtlist_with_phvs, CMD_SELECT, 0);
|
||||
|
||||
/*
|
||||
* Replace references in the translated_vars lists of appendrels.
|
||||
* When pulling up an appendrel member, we do not need PHVs in the list
|
||||
* of the parent appendrel --- there isn't any outer join between.
|
||||
* Elsewhere, use PHVs for safety. (This analysis could be made tighter
|
||||
* but it seems unlikely to be worth much trouble.)
|
||||
* Replace references in the translated_vars lists of appendrels. When
|
||||
* pulling up an appendrel member, we do not need PHVs in the list of the
|
||||
* parent appendrel --- there isn't any outer join between. Elsewhere, use
|
||||
* PHVs for safety. (This analysis could be made tighter but it seems
|
||||
* unlikely to be worth much trouble.)
|
||||
*/
|
||||
foreach(lc, root->append_rel_list)
|
||||
{
|
||||
@@ -753,9 +753,9 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte,
|
||||
*
|
||||
* You might think that we could avoid using PHVs for alias vars of joins
|
||||
* below lowest_outer_join, but that doesn't work because the alias vars
|
||||
* could be referenced above that join; we need the PHVs to be present
|
||||
* in such references after the alias vars get flattened. (It might be
|
||||
* worth trying to be smarter here, someday.)
|
||||
* could be referenced above that join; we need the PHVs to be present in
|
||||
* such references after the alias vars get flattened. (It might be worth
|
||||
* trying to be smarter here, someday.)
|
||||
*/
|
||||
foreach(lc, parse->rtable)
|
||||
{
|
||||
@@ -789,9 +789,9 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte,
|
||||
* will be adjusted, so having created them with the subquery's varno is
|
||||
* correct.
|
||||
*
|
||||
* Likewise, relids appearing in AppendRelInfo nodes have to be fixed.
|
||||
* We already checked that this won't require introducing multiple
|
||||
* subrelids into the single-slot AppendRelInfo structs.
|
||||
* Likewise, relids appearing in AppendRelInfo nodes have to be fixed. We
|
||||
* already checked that this won't require introducing multiple subrelids
|
||||
* into the single-slot AppendRelInfo structs.
|
||||
*/
|
||||
if (parse->hasSubLinks || root->glob->lastPHId != 0 ||
|
||||
root->append_rel_list)
|
||||
@@ -822,9 +822,10 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte,
|
||||
* Miscellaneous housekeeping.
|
||||
*/
|
||||
parse->hasSubLinks |= subquery->hasSubLinks;
|
||||
|
||||
/*
|
||||
* subquery won't be pulled up if it hasAggs or hasWindowFuncs, so no
|
||||
* work needed on those flags
|
||||
* subquery won't be pulled up if it hasAggs or hasWindowFuncs, so no work
|
||||
* needed on those flags
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -859,10 +860,10 @@ pull_up_simple_union_all(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte)
|
||||
/*
|
||||
* Append child RTEs to parent rtable.
|
||||
*
|
||||
* Upper-level vars in subquery are now one level closer to their
|
||||
* parent than before. We don't have to worry about offsetting
|
||||
* varnos, though, because any such vars must refer to stuff above the
|
||||
* level of the query we are pulling into.
|
||||
* Upper-level vars in subquery are now one level closer to their parent
|
||||
* than before. We don't have to worry about offsetting varnos, though,
|
||||
* because any such vars must refer to stuff above the level of the query
|
||||
* we are pulling into.
|
||||
*/
|
||||
rtable = copyObject(subquery->rtable);
|
||||
IncrementVarSublevelsUp_rtable(rtable, -1, 1);
|
||||
@@ -1049,11 +1050,11 @@ is_simple_subquery(Query *subquery)
|
||||
* query_planner() will correctly generate a Result plan for a jointree
|
||||
* that's totally empty, but I don't think the right things happen if an
|
||||
* empty FromExpr appears lower down in a jointree. It would pose a
|
||||
* problem for the PlaceHolderVar mechanism too, since we'd have no
|
||||
* way to identify where to evaluate a PHV coming out of the subquery.
|
||||
* Not worth working hard on this, just to collapse SubqueryScan/Result
|
||||
* into Result; especially since the SubqueryScan can often be optimized
|
||||
* away by setrefs.c anyway.
|
||||
* problem for the PlaceHolderVar mechanism too, since we'd have no way to
|
||||
* identify where to evaluate a PHV coming out of the subquery. Not worth
|
||||
* working hard on this, just to collapse SubqueryScan/Result into Result;
|
||||
* especially since the SubqueryScan can often be optimized away by
|
||||
* setrefs.c anyway.
|
||||
*/
|
||||
if (subquery->jointree->fromlist == NIL)
|
||||
return false;
|
||||
@@ -1167,8 +1168,8 @@ insert_targetlist_placeholders(PlannerInfo *root, List *tlist,
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple Vars always escape being wrapped. This is common enough
|
||||
* to deserve a fast path even if we aren't doing wrap_non_vars.
|
||||
* Simple Vars always escape being wrapped. This is common enough to
|
||||
* deserve a fast path even if we aren't doing wrap_non_vars.
|
||||
*/
|
||||
if (tle->expr && IsA(tle->expr, Var) &&
|
||||
((Var *) tle->expr)->varlevelsup == 0)
|
||||
@@ -1180,8 +1181,8 @@ insert_targetlist_placeholders(PlannerInfo *root, List *tlist,
|
||||
if (!wrap_non_vars)
|
||||
{
|
||||
/*
|
||||
* If it contains a Var of current level, and does not contain
|
||||
* any non-strict constructs, then it's certainly nullable and we
|
||||
* If it contains a Var of current level, and does not contain any
|
||||
* non-strict constructs, then it's certainly nullable and we
|
||||
* don't need to insert a PlaceHolderVar. (Note: in future maybe
|
||||
* we should insert PlaceHolderVars anyway, when a tlist item is
|
||||
* expensive to evaluate?
|
||||
@@ -1248,7 +1249,7 @@ is_safe_append_member(Query *subquery)
|
||||
* but there's no other way...
|
||||
*
|
||||
* If we are above lowest_outer_join then use subtlist_with_phvs; at or
|
||||
* below it, use subtlist. (When no outer joins are in the picture,
|
||||
* below it, use subtlist. (When no outer joins are in the picture,
|
||||
* these will be the same list.)
|
||||
*/
|
||||
static void
|
||||
@@ -1328,7 +1329,7 @@ resolvenew_in_jointree(Node *jtnode, int varno, RangeTblEntry *rte,
|
||||
* SELECT ... FROM a LEFT JOIN b ON (a.x = b.y) WHERE b.y IS NULL;
|
||||
* If the join clause is strict for b.y, then only null-extended rows could
|
||||
* pass the upper WHERE, and we can conclude that what the query is really
|
||||
* specifying is an anti-semijoin. We change the join type from JOIN_LEFT
|
||||
* specifying is an anti-semijoin. We change the join type from JOIN_LEFT
|
||||
* to JOIN_ANTI. The IS NULL clause then becomes redundant, and must be
|
||||
* removed to prevent bogus selectivity calculations, but we leave it to
|
||||
* distribute_qual_to_rels to get rid of such clauses.
|
||||
@@ -1533,6 +1534,7 @@ reduce_outer_joins_pass2(Node *jtnode,
|
||||
break;
|
||||
case JOIN_SEMI:
|
||||
case JOIN_ANTI:
|
||||
|
||||
/*
|
||||
* These could only have been introduced by pull_up_sublinks,
|
||||
* so there's no way that upper quals could refer to their
|
||||
@@ -1565,14 +1567,14 @@ reduce_outer_joins_pass2(Node *jtnode,
|
||||
}
|
||||
|
||||
/*
|
||||
* See if we can reduce JOIN_LEFT to JOIN_ANTI. This is the case
|
||||
* if the join's own quals are strict for any var that was forced
|
||||
* null by higher qual levels. NOTE: there are other ways that we
|
||||
* could detect an anti-join, in particular if we were to check
|
||||
* whether Vars coming from the RHS must be non-null because of
|
||||
* table constraints. That seems complicated and expensive though
|
||||
* (in particular, one would have to be wary of lower outer joins).
|
||||
* For the moment this seems sufficient.
|
||||
* See if we can reduce JOIN_LEFT to JOIN_ANTI. This is the case if
|
||||
* the join's own quals are strict for any var that was forced null by
|
||||
* higher qual levels. NOTE: there are other ways that we could
|
||||
* detect an anti-join, in particular if we were to check whether Vars
|
||||
* coming from the RHS must be non-null because of table constraints.
|
||||
* That seems complicated and expensive though (in particular, one
|
||||
* would have to be wary of lower outer joins). For the moment this
|
||||
* seems sufficient.
|
||||
*/
|
||||
if (jointype == JOIN_LEFT)
|
||||
{
|
||||
@@ -1582,8 +1584,8 @@ reduce_outer_joins_pass2(Node *jtnode,
|
||||
computed_local_nonnullable_vars = true;
|
||||
|
||||
/*
|
||||
* It's not sufficient to check whether local_nonnullable_vars
|
||||
* and forced_null_vars overlap: we need to know if the overlap
|
||||
* It's not sufficient to check whether local_nonnullable_vars and
|
||||
* forced_null_vars overlap: we need to know if the overlap
|
||||
* includes any RHS variables.
|
||||
*/
|
||||
overlap = list_intersection(local_nonnullable_vars,
|
||||
@@ -1621,11 +1623,11 @@ reduce_outer_joins_pass2(Node *jtnode,
|
||||
* side, because an outer join never eliminates any rows from its
|
||||
* non-nullable side. Also, there is no point in passing upper
|
||||
* constraints into the nullable side, since if there were any
|
||||
* we'd have been able to reduce the join. (In the case of
|
||||
* upper forced-null constraints, we *must not* pass them into
|
||||
* the nullable side --- they either applied here, or not.)
|
||||
* The upshot is that we pass either the local or the upper
|
||||
* constraints, never both, to the children of an outer join.
|
||||
* we'd have been able to reduce the join. (In the case of upper
|
||||
* forced-null constraints, we *must not* pass them into the
|
||||
* nullable side --- they either applied here, or not.) The upshot
|
||||
* is that we pass either the local or the upper constraints,
|
||||
* never both, to the children of an outer join.
|
||||
*
|
||||
* At a FULL join we just punt and pass nothing down --- is it
|
||||
* possible to be smarter?
|
||||
@@ -1640,7 +1642,7 @@ reduce_outer_joins_pass2(Node *jtnode,
|
||||
{
|
||||
/* OK to merge upper and local constraints */
|
||||
local_nonnullable_rels = bms_add_members(local_nonnullable_rels,
|
||||
nonnullable_rels);
|
||||
nonnullable_rels);
|
||||
local_nonnullable_vars = list_concat(local_nonnullable_vars,
|
||||
nonnullable_vars);
|
||||
local_forced_null_vars = list_concat(local_forced_null_vars,
|
||||
@@ -1663,7 +1665,7 @@ reduce_outer_joins_pass2(Node *jtnode,
|
||||
pass_nonnullable_vars = local_nonnullable_vars;
|
||||
pass_forced_null_vars = local_forced_null_vars;
|
||||
}
|
||||
else if (jointype != JOIN_FULL) /* ie, LEFT/SEMI/ANTI */
|
||||
else if (jointype != JOIN_FULL) /* ie, LEFT/SEMI/ANTI */
|
||||
{
|
||||
/* can't pass local constraints to non-nullable side */
|
||||
pass_nonnullable_rels = nonnullable_rels;
|
||||
@@ -1722,7 +1724,7 @@ reduce_outer_joins_pass2(Node *jtnode,
|
||||
* top query could (yet) contain such a reference.
|
||||
*
|
||||
* NOTE: although this has the form of a walker, we cheat and modify the
|
||||
* nodes in-place. This should be OK since the tree was copied by ResolveNew
|
||||
* nodes in-place. This should be OK since the tree was copied by ResolveNew
|
||||
* earlier. Avoid scribbling on the original values of the bitmapsets, though,
|
||||
* because expression_tree_mutator doesn't copy those.
|
||||
*/
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.170 2009/05/12 03:11:01 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.171 2009/06/11 14:48:59 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -97,7 +97,7 @@ static void make_inh_translation_list(Relation oldrelation,
|
||||
Index newvarno,
|
||||
List **translated_vars);
|
||||
static Bitmapset *translate_col_privs(const Bitmapset *parent_privs,
|
||||
List *translated_vars);
|
||||
List *translated_vars);
|
||||
static Node *adjust_appendrel_attrs_mutator(Node *node,
|
||||
AppendRelInfo *context);
|
||||
static Relids adjust_relid_set(Relids relids, Index oldrelid, Index newrelid);
|
||||
@@ -220,9 +220,9 @@ recurse_set_operations(Node *setOp, PlannerInfo *root,
|
||||
&subroot);
|
||||
|
||||
/*
|
||||
* Estimate number of groups if caller wants it. If the subquery
|
||||
* used grouping or aggregation, its output is probably mostly
|
||||
* unique anyway; otherwise do statistical estimation.
|
||||
* Estimate number of groups if caller wants it. If the subquery used
|
||||
* grouping or aggregation, its output is probably mostly unique
|
||||
* anyway; otherwise do statistical estimation.
|
||||
*/
|
||||
if (pNumGroups)
|
||||
{
|
||||
@@ -231,7 +231,7 @@ recurse_set_operations(Node *setOp, PlannerInfo *root,
|
||||
*pNumGroups = subplan->plan_rows;
|
||||
else
|
||||
*pNumGroups = estimate_num_groups(subroot,
|
||||
get_tlist_exprs(subquery->targetList, false),
|
||||
get_tlist_exprs(subquery->targetList, false),
|
||||
subplan->plan_rows);
|
||||
}
|
||||
|
||||
@@ -361,7 +361,7 @@ generate_recursion_plan(SetOperationStmt *setOp, PlannerInfo *root,
|
||||
}
|
||||
else
|
||||
{
|
||||
double dNumGroups;
|
||||
double dNumGroups;
|
||||
|
||||
/* Identify the grouping semantics */
|
||||
groupList = generate_setop_grouplist(setOp, tlist);
|
||||
@@ -374,8 +374,8 @@ generate_recursion_plan(SetOperationStmt *setOp, PlannerInfo *root,
|
||||
errdetail("All column datatypes must be hashable.")));
|
||||
|
||||
/*
|
||||
* For the moment, take the number of distinct groups as equal to
|
||||
* the total input size, ie, the worst case.
|
||||
* For the moment, take the number of distinct groups as equal to the
|
||||
* total input size, ie, the worst case.
|
||||
*/
|
||||
dNumGroups = lplan->plan_rows + rplan->plan_rows * 10;
|
||||
|
||||
@@ -460,9 +460,9 @@ generate_union_plan(SetOperationStmt *op, PlannerInfo *root,
|
||||
plan = make_union_unique(op, plan, root, tuple_fraction, sortClauses);
|
||||
|
||||
/*
|
||||
* Estimate number of groups if caller wants it. For now we just
|
||||
* assume the output is unique --- this is certainly true for the
|
||||
* UNION case, and we want worst-case estimates anyway.
|
||||
* Estimate number of groups if caller wants it. For now we just assume
|
||||
* the output is unique --- this is certainly true for the UNION case, and
|
||||
* we want worst-case estimates anyway.
|
||||
*/
|
||||
if (pNumGroups)
|
||||
*pNumGroups = plan->plan_rows;
|
||||
@@ -555,8 +555,8 @@ generate_nonunion_plan(SetOperationStmt *op, PlannerInfo *root,
|
||||
* Estimate number of distinct groups that we'll need hashtable entries
|
||||
* for; this is the size of the left-hand input for EXCEPT, or the smaller
|
||||
* input for INTERSECT. Also estimate the number of eventual output rows.
|
||||
* In non-ALL cases, we estimate each group produces one output row;
|
||||
* in ALL cases use the relevant relation size. These are worst-case
|
||||
* In non-ALL cases, we estimate each group produces one output row; in
|
||||
* ALL cases use the relevant relation size. These are worst-case
|
||||
* estimates, of course, but we need to be conservative.
|
||||
*/
|
||||
if (op->op == SETOP_EXCEPT)
|
||||
@@ -578,7 +578,7 @@ generate_nonunion_plan(SetOperationStmt *op, PlannerInfo *root,
|
||||
*/
|
||||
use_hash = choose_hashed_setop(root, groupList, plan,
|
||||
dNumGroups, dNumOutputRows, tuple_fraction,
|
||||
(op->op == SETOP_INTERSECT) ? "INTERSECT" : "EXCEPT");
|
||||
(op->op == SETOP_INTERSECT) ? "INTERSECT" : "EXCEPT");
|
||||
|
||||
if (!use_hash)
|
||||
plan = (Plan *) make_sort_from_sortclauses(root, groupList, plan);
|
||||
@@ -687,12 +687,12 @@ make_union_unique(SetOperationStmt *op, Plan *plan,
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX for the moment, take the number of distinct groups as equal to
|
||||
* the total input size, ie, the worst case. This is too conservative,
|
||||
* but we don't want to risk having the hashtable overrun memory; also,
|
||||
* it's not clear how to get a decent estimate of the true size. One
|
||||
* should note as well the propensity of novices to write UNION rather
|
||||
* than UNION ALL even when they don't expect any duplicates...
|
||||
* XXX for the moment, take the number of distinct groups as equal to the
|
||||
* total input size, ie, the worst case. This is too conservative, but we
|
||||
* don't want to risk having the hashtable overrun memory; also, it's not
|
||||
* clear how to get a decent estimate of the true size. One should note
|
||||
* as well the propensity of novices to write UNION rather than UNION ALL
|
||||
* even when they don't expect any duplicates...
|
||||
*/
|
||||
dNumGroups = plan->plan_rows;
|
||||
|
||||
@@ -763,7 +763,7 @@ choose_hashed_setop(PlannerInfo *root, List *groupClauses,
|
||||
else
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
/* translator: %s is UNION, INTERSECT, or EXCEPT */
|
||||
/* translator: %s is UNION, INTERSECT, or EXCEPT */
|
||||
errmsg("could not implement %s", construct),
|
||||
errdetail("Some of the datatypes only support hashing, while others only support sorting.")));
|
||||
|
||||
@@ -1260,16 +1260,16 @@ expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti)
|
||||
appinfos = lappend(appinfos, appinfo);
|
||||
|
||||
/*
|
||||
* Translate the column permissions bitmaps to the child's attnums
|
||||
* (we have to build the translated_vars list before we can do this).
|
||||
* But if this is the parent table, leave copyObject's result alone.
|
||||
* Translate the column permissions bitmaps to the child's attnums (we
|
||||
* have to build the translated_vars list before we can do this). But
|
||||
* if this is the parent table, leave copyObject's result alone.
|
||||
*/
|
||||
if (childOID != parentOID)
|
||||
{
|
||||
childrte->selectedCols = translate_col_privs(rte->selectedCols,
|
||||
appinfo->translated_vars);
|
||||
appinfo->translated_vars);
|
||||
childrte->modifiedCols = translate_col_privs(rte->modifiedCols,
|
||||
appinfo->translated_vars);
|
||||
appinfo->translated_vars);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1420,7 +1420,7 @@ make_inh_translation_list(Relation oldrelation, Relation newrelation,
|
||||
* parent rel's attribute numbering to the child's.
|
||||
*
|
||||
* The only surprise here is that we don't translate a parent whole-row
|
||||
* reference into a child whole-row reference. That would mean requiring
|
||||
* reference into a child whole-row reference. That would mean requiring
|
||||
* permissions on all child columns, which is overly strict, since the
|
||||
* query is really only going to reference the inherited columns. Instead
|
||||
* we set the per-column bits for all inherited columns.
|
||||
@@ -1435,12 +1435,12 @@ translate_col_privs(const Bitmapset *parent_privs,
|
||||
ListCell *lc;
|
||||
|
||||
/* System attributes have the same numbers in all tables */
|
||||
for (attno = FirstLowInvalidHeapAttributeNumber+1; attno < 0; attno++)
|
||||
for (attno = FirstLowInvalidHeapAttributeNumber + 1; attno < 0; attno++)
|
||||
{
|
||||
if (bms_is_member(attno - FirstLowInvalidHeapAttributeNumber,
|
||||
parent_privs))
|
||||
child_privs = bms_add_member(child_privs,
|
||||
attno - FirstLowInvalidHeapAttributeNumber);
|
||||
attno - FirstLowInvalidHeapAttributeNumber);
|
||||
}
|
||||
|
||||
/* Check if parent has whole-row reference */
|
||||
@@ -1451,7 +1451,7 @@ translate_col_privs(const Bitmapset *parent_privs,
|
||||
attno = InvalidAttrNumber;
|
||||
foreach(lc, translated_vars)
|
||||
{
|
||||
Var *var = (Var *) lfirst(lc);
|
||||
Var *var = (Var *) lfirst(lc);
|
||||
|
||||
attno++;
|
||||
if (var == NULL) /* ignore dropped columns */
|
||||
@@ -1461,7 +1461,7 @@ translate_col_privs(const Bitmapset *parent_privs,
|
||||
bms_is_member(attno - FirstLowInvalidHeapAttributeNumber,
|
||||
parent_privs))
|
||||
child_privs = bms_add_member(child_privs,
|
||||
var->varattno - FirstLowInvalidHeapAttributeNumber);
|
||||
var->varattno - FirstLowInvalidHeapAttributeNumber);
|
||||
}
|
||||
|
||||
return child_privs;
|
||||
|
||||
Reference in New Issue
Block a user