/*------------------------------------------------------------------------- * * 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.7 1997/12/22 05:42:16 momjian Exp $ * *------------------------------------------------------------------------- */ #include #include "postgres.h" #include #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) || and_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) || and_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); }