You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
postgres/src/backend/optimizer/util/var.c

196 lines
5.0 KiB

/*-------------------------------------------------------------------------
*
* var.c--
* Var node manipulation routines
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.3 1996/11/06 09:29:26 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
#include <sys/types.h>
#include "postgres.h"
#include <nodes/relation.h>
#include "nodes/primnodes.h"
#include "nodes/nodeFuncs.h"
#include "optimizer/internal.h"
#include "optimizer/clauses.h"
#include "optimizer/var.h"
#include "parser/parsetree.h"
/*
* find_varnos
*
* Descends down part of a parsetree (qual or tlist),
*
* XXX assumes varno's are always integers, which shouldn't be true...
* (though it currently is, see primnodes.h)
*/
List *
pull_varnos(Node *me)
{
List *i, *result = NIL;
if (me == NULL)
return (NIL);
switch (nodeTag(me)) {
case T_List:
foreach (i, (List*)me) {
result = nconc(result, pull_varnos(lfirst(i)));
}
break;
case T_ArrayRef:
foreach (i, ((ArrayRef*) me)->refupperindexpr)
result = nconc(result, pull_varnos(lfirst(i)));
foreach (i, ((ArrayRef*) me)->reflowerindexpr)
result = nconc(result, pull_varnos(lfirst(i)));
result = nconc(result, pull_varnos(((ArrayRef*) me)->refassgnexpr));
break;
case T_Var:
result = lconsi(((Var*) me)->varno, NIL);
break;
default:
break;
}
return(result);
}
/*
* contain_var_clause--
* Recursively find var nodes from a clause by pulling vars from the
* left and right operands of the clause.
*
* Returns true if any varnode found.
*/
bool contain_var_clause(Node *clause)
{
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)) {
List *temp;
foreach (temp, ((Expr*)clause)->args) {
if (contain_var_clause(lfirst(temp)))
return TRUE;
}
return FALSE;
} else if (is_funcclause (clause)) {
List *temp;
foreach(temp, ((Expr *)clause)->args) {
if (contain_var_clause(lfirst(temp)))
return TRUE;
}
return FALSE;
} else if (IsA(clause,ArrayRef)) {
List *temp;
foreach(temp, ((ArrayRef*)clause)->refupperindexpr) {
if (contain_var_clause(lfirst(temp)))
return TRUE;
}
foreach(temp, ((ArrayRef*)clause)->reflowerindexpr) {
if (contain_var_clause(lfirst(temp)))
return TRUE;
}
if (contain_var_clause(((ArrayRef*)clause)->refexpr))
return TRUE;
if (contain_var_clause(((ArrayRef*)clause)->refassgnexpr))
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)));
return FALSE;
}
/*
* pull_var_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.
*/
List *
pull_var_clause(Node *clause)
{
List *retval = NIL;
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)) {
List *temp;
foreach (temp, ((Expr*)clause)->args)
retval = nconc(retval, pull_var_clause(lfirst(temp)));
} else if (is_funcclause (clause)) {
List *temp;
foreach(temp, ((Expr *)clause)->args)
retval = nconc (retval,pull_var_clause(lfirst(temp)));
} else if (IsA(clause,Aggreg)) {
retval = pull_var_clause(((Aggreg*)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)
retval = nconc (retval,pull_var_clause(lfirst(temp)));
retval = nconc(retval,
pull_var_clause(((ArrayRef*)clause)->refexpr));
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
retval = NIL;
return (retval);
}
/*
* var_equal
*
* Returns t iff two var nodes correspond to the same attribute.
*/
bool
var_equal(Var *var1, Var *var2)
{
if (IsA (var1,Var) && IsA (var2,Var) &&
(((Var*)var1)->varno == ((Var*)var2)->varno) &&
(((Var*)var1)->vartype == ((Var*)var2)->vartype) &&
(((Var*)var1)->varattno == ((Var*)var2)->varattno)) {
return(true);
} else
return(false);
}