1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-29 23:43:17 +03:00

Add an at-least-marginally-plausible method of estimating the number

of groups produced by GROUP BY.  This improves the accuracy of planning
estimates for grouped subselects, and is needed to check whether a
hashed aggregation plan risks memory overflow.
This commit is contained in:
Tom Lane
2002-11-19 23:22:00 +00:00
parent 54cb1db6cf
commit b60be3f2f8
11 changed files with 454 additions and 75 deletions

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.75 2002/09/04 20:31:21 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.76 2002/11/19 23:21:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -784,6 +784,71 @@ process_implied_equality(Query *root, Node *item1, Node *item2,
pull_varnos((Node *) clause));
}
/*
* vars_known_equal
* Detect whether two Vars are known equal due to equijoin clauses.
*
* This is not completely accurate since we avoid adding redundant restriction
* clauses to individual base rels (see qual_is_redundant). However, after
* the implied-equality-deduction phase, it is complete for Vars of different
* rels; that's sufficient for planned uses.
*/
bool
vars_known_equal(Query *root, Var *var1, Var *var2)
{
Index irel1;
Index irel2;
RelOptInfo *rel1;
List *restrictlist;
List *itm;
/*
* Would need more work here if we wanted to check for known equality
* of general clauses: there might be multiple base rels involved.
*/
Assert(IsA(var1, Var));
irel1 = var1->varno;
Assert(IsA(var2, Var));
irel2 = var2->varno;
/*
* If both vars belong to same rel, we need to look at that rel's
* baserestrictinfo list. If different rels, each will have a
* joininfo node for the other, and we can scan either list.
*/
rel1 = find_base_rel(root, irel1);
if (irel1 == irel2)
restrictlist = rel1->baserestrictinfo;
else
{
JoinInfo *joininfo = find_joininfo_node(rel1,
makeListi1(irel2));
restrictlist = joininfo->jinfo_restrictinfo;
}
/*
* Scan to see if equality is known.
*/
foreach(itm, restrictlist)
{
RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(itm);
Node *left,
*right;
if (restrictinfo->mergejoinoperator == InvalidOid)
continue; /* ignore non-mergejoinable clauses */
/* We now know the restrictinfo clause is a binary opclause */
left = (Node *) get_leftop(restrictinfo->clause);
right = (Node *) get_rightop(restrictinfo->clause);
if ((equal(var1, left) && equal(var2, right)) ||
(equal(var2, left) && equal(var1, right)))
return true; /* found a matching clause */
}
return false;
}
/*
* qual_is_redundant
* Detect whether an implied-equality qual that turns out to be a