mirror of
https://github.com/postgres/postgres.git
synced 2025-11-10 17:42:29 +03:00
Revise union_planner and associated routines to clean up breakage
from EXCEPT/HAVING patch. Cases involving nontrivial GROUP BY expressions now work again. Also, the code is at least somewhat better documented...
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.17 1999/02/22 05:26:27 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.18 1999/05/03 00:38:44 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -68,43 +68,31 @@ pull_varnos(Node *me)
|
||||
|
||||
/*
|
||||
* contain_var_clause
|
||||
* Recursively find var nodes from a clause by pulling vars from the
|
||||
* left and right operands of the clause.
|
||||
* Recursively scan a clause to discover whether it contains any Var nodes.
|
||||
*
|
||||
* Returns true if any varnode found.
|
||||
*/
|
||||
bool
|
||||
contain_var_clause(Node *clause)
|
||||
{
|
||||
List *temp;
|
||||
|
||||
if (clause == NULL)
|
||||
return FALSE;
|
||||
else if (IsA(clause, Var))
|
||||
return TRUE;
|
||||
else if (IsA(clause, Iter))
|
||||
return contain_var_clause(((Iter *) clause)->iterexpr);
|
||||
else if (single_node(clause))
|
||||
return FALSE;
|
||||
else if (or_clause(clause) || and_clause(clause) || is_funcclause(clause))
|
||||
{
|
||||
List *temp;
|
||||
|
||||
foreach(temp, ((Expr *) clause)->args)
|
||||
{
|
||||
if (contain_var_clause(lfirst(temp)))
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
else if (IsA(clause, Iter))
|
||||
return contain_var_clause(((Iter *) clause)->iterexpr);
|
||||
else if (is_subplan(clause))
|
||||
{
|
||||
List *temp;
|
||||
|
||||
foreach(temp, ((Expr *) clause)->args)
|
||||
{
|
||||
if (contain_var_clause(lfirst(temp)))
|
||||
return TRUE;
|
||||
}
|
||||
/* Ok - check left sides of Oper-s */
|
||||
/* Also check left sides of Oper-s */
|
||||
foreach(temp, ((SubPlan *) ((Expr *) clause)->oper)->sublink->oper)
|
||||
{
|
||||
if (contain_var_clause(lfirst(((Expr *) lfirst(temp))->args)))
|
||||
@@ -112,10 +100,24 @@ contain_var_clause(Node *clause)
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
else if (IsA(clause, Expr))
|
||||
{
|
||||
/*
|
||||
* Recursively scan the arguments of an expression.
|
||||
* NOTE: this must come after is_subplan() case since
|
||||
* subplan is a kind of Expr node.
|
||||
*/
|
||||
foreach(temp, ((Expr *) clause)->args)
|
||||
{
|
||||
if (contain_var_clause(lfirst(temp)))
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
else if (IsA(clause, Aggref))
|
||||
return contain_var_clause(((Aggref *) clause)->target);
|
||||
else if (IsA(clause, ArrayRef))
|
||||
{
|
||||
List *temp;
|
||||
|
||||
foreach(temp, ((ArrayRef *) clause)->refupperindexpr)
|
||||
{
|
||||
if (contain_var_clause(lfirst(temp)))
|
||||
@@ -132,19 +134,11 @@ contain_var_clause(Node *clause)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
else if (not_clause(clause))
|
||||
return contain_var_clause((Node *) get_notclausearg((Expr *) clause));
|
||||
else if (is_opclause(clause))
|
||||
return (contain_var_clause((Node *) get_leftop((Expr *) clause)) ||
|
||||
contain_var_clause((Node *) get_rightop((Expr *) clause)));
|
||||
else if (case_clause(clause))
|
||||
{
|
||||
List *args;
|
||||
CaseWhen *when;
|
||||
|
||||
foreach(args, ((CaseExpr *) clause)->args)
|
||||
foreach(temp, ((CaseExpr *) clause)->args)
|
||||
{
|
||||
when = lfirst(args);
|
||||
CaseWhen *when = (CaseWhen *) lfirst(temp);
|
||||
if (contain_var_clause(when->expr))
|
||||
return TRUE;
|
||||
if (contain_var_clause(when->result))
|
||||
@@ -152,6 +146,11 @@ contain_var_clause(Node *clause)
|
||||
}
|
||||
return (contain_var_clause(((CaseExpr *) clause)->defresult));
|
||||
}
|
||||
else
|
||||
{
|
||||
elog(ERROR, "contain_var_clause: Cannot handle node type %d",
|
||||
nodeTag(clause));
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@@ -161,45 +160,46 @@ contain_var_clause(Node *clause)
|
||||
* Recursively pulls all var nodes from a clause by pulling vars from the
|
||||
* left and right operands of the clause.
|
||||
*
|
||||
* Returns list of varnodes found.
|
||||
* Returns list of varnodes found. Note the varnodes themselves are not
|
||||
* copied, only referenced.
|
||||
*/
|
||||
List *
|
||||
pull_var_clause(Node *clause)
|
||||
{
|
||||
List *retval = NIL;
|
||||
List *temp;
|
||||
|
||||
if (clause == NULL)
|
||||
return NIL;
|
||||
else if (IsA(clause, Var))
|
||||
retval = lcons(clause, NIL);
|
||||
else if (IsA(clause, Iter))
|
||||
retval = pull_var_clause(((Iter *) clause)->iterexpr);
|
||||
else if (single_node(clause))
|
||||
retval = NIL;
|
||||
else if (or_clause(clause) || and_clause(clause) || is_funcclause(clause))
|
||||
{
|
||||
List *temp;
|
||||
|
||||
foreach(temp, ((Expr *) clause)->args)
|
||||
retval = nconc(retval, pull_var_clause(lfirst(temp)));
|
||||
}
|
||||
else if (IsA(clause, Iter))
|
||||
retval = pull_var_clause(((Iter *) clause)->iterexpr);
|
||||
else if (is_subplan(clause))
|
||||
{
|
||||
List *temp;
|
||||
|
||||
foreach(temp, ((Expr *) clause)->args)
|
||||
retval = nconc(retval, pull_var_clause(lfirst(temp)));
|
||||
/* Ok - get Var-s from left sides of Oper-s */
|
||||
/* Also get Var-s from left sides of Oper-s */
|
||||
foreach(temp, ((SubPlan *) ((Expr *) clause)->oper)->sublink->oper)
|
||||
retval = nconc(retval,
|
||||
pull_var_clause(lfirst(((Expr *) lfirst(temp))->args)));
|
||||
}
|
||||
else if (IsA(clause, Expr))
|
||||
{
|
||||
/*
|
||||
* Recursively scan the arguments of an expression.
|
||||
* NOTE: this must come after is_subplan() case since
|
||||
* subplan is a kind of Expr node.
|
||||
*/
|
||||
foreach(temp, ((Expr *) clause)->args)
|
||||
retval = nconc(retval, pull_var_clause(lfirst(temp)));
|
||||
}
|
||||
else if (IsA(clause, Aggref))
|
||||
retval = pull_var_clause(((Aggref *) clause)->target);
|
||||
else if (IsA(clause, ArrayRef))
|
||||
{
|
||||
List *temp;
|
||||
|
||||
foreach(temp, ((ArrayRef *) clause)->refupperindexpr)
|
||||
retval = nconc(retval, pull_var_clause(lfirst(temp)));
|
||||
foreach(temp, ((ArrayRef *) clause)->reflowerindexpr)
|
||||
@@ -209,25 +209,21 @@ pull_var_clause(Node *clause)
|
||||
retval = nconc(retval,
|
||||
pull_var_clause(((ArrayRef *) clause)->refassgnexpr));
|
||||
}
|
||||
else if (not_clause(clause))
|
||||
retval = pull_var_clause((Node *) get_notclausearg((Expr *) clause));
|
||||
else if (is_opclause(clause))
|
||||
retval = nconc(pull_var_clause((Node *) get_leftop((Expr *) clause)),
|
||||
pull_var_clause((Node *) get_rightop((Expr *) clause)));
|
||||
else if (case_clause(clause))
|
||||
{
|
||||
List *temp;
|
||||
|
||||
foreach(temp, ((CaseExpr *) clause)->args)
|
||||
{
|
||||
retval = nconc(retval, pull_var_clause(((CaseWhen *) lfirst(temp))->expr));
|
||||
retval = nconc(retval, pull_var_clause(((CaseWhen *) lfirst(temp))->result));
|
||||
CaseWhen *when = (CaseWhen *) lfirst(temp);
|
||||
retval = nconc(retval, pull_var_clause(when->expr));
|
||||
retval = nconc(retval, pull_var_clause(when->result));
|
||||
}
|
||||
|
||||
retval = nconc(retval, pull_var_clause(((CaseExpr *) clause)->defresult));
|
||||
}
|
||||
else
|
||||
retval = NIL;
|
||||
{
|
||||
elog(ERROR, "pull_var_clause: Cannot handle node type %d",
|
||||
nodeTag(clause));
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user