diff options
Diffstat (limited to 'src/backend/optimizer/util/var.c')
-rw-r--r-- | src/backend/optimizer/util/var.c | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/src/backend/optimizer/util/var.c b/src/backend/optimizer/util/var.c new file mode 100644 index 00000000000..b4f8436c775 --- /dev/null +++ b/src/backend/optimizer/util/var.c @@ -0,0 +1,189 @@ +/*------------------------------------------------------------------------- + * + * 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.1.1.1 1996/07/09 06:21:39 scrappy Exp $ + * + *------------------------------------------------------------------------- + */ +#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); +} |