📄 rewritemanip.c
字号:
/*------------------------------------------------------------------------- * * rewriteManip.c * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION * $Header: /usr/local/cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.32 1999/05/26 12:55:48 momjian Exp $ * *------------------------------------------------------------------------- */#include <string.h>#include "postgres.h"#include "nodes/pg_list.h"#include "utils/elog.h"#include "nodes/nodes.h"#include "nodes/relation.h"#include "nodes/primnodes.h"#include "parser/parsetree.h" /* for getrelid() */#include "utils/lsyscache.h"#include "utils/builtins.h"#include "rewrite/rewriteHandler.h"#include "rewrite/rewriteManip.h"#include "rewrite/rewriteSupport.h"#include "rewrite/locks.h"#include "nodes/plannodes.h"#include "optimizer/clauses.h"static void ResolveNew(RewriteInfo *info, List *targetlist, Node **node, int sublevels_up);/* * OffsetVarnodes - */voidOffsetVarNodes(Node *node, int offset, int sublevels_up){ if (node == NULL) return; switch (nodeTag(node)) { case T_TargetEntry: { TargetEntry *tle = (TargetEntry *) node; OffsetVarNodes( (Node *) (tle->expr), offset, sublevels_up); } break; case T_Aggref: { Aggref *aggref = (Aggref *) node; OffsetVarNodes( (Node *) (aggref->target), offset, sublevels_up); } break; case T_GroupClause: break; case T_Expr: { Expr *exp = (Expr *) node; OffsetVarNodes( (Node *) (exp->args), offset, sublevels_up); } break; case T_Iter: { Iter *iter = (Iter *) node; OffsetVarNodes( (Node *) (iter->iterexpr), offset, sublevels_up); } break; case T_ArrayRef: { ArrayRef *ref = (ArrayRef *) node; OffsetVarNodes( (Node *) (ref->refupperindexpr), offset, sublevels_up); OffsetVarNodes( (Node *) (ref->reflowerindexpr), offset, sublevels_up); OffsetVarNodes( (Node *) (ref->refexpr), offset, sublevels_up); OffsetVarNodes( (Node *) (ref->refassgnexpr), offset, sublevels_up); } break; case T_Var: { Var *var = (Var *) node; if (var->varlevelsup == sublevels_up) { var->varno += offset; var->varnoold += offset; } } break; case T_Param: break; case T_Const: break; case T_List: { List *l; foreach(l, (List *) node) OffsetVarNodes( (Node *) lfirst(l), offset, sublevels_up); } break; case T_SubLink: { SubLink *sub = (SubLink *) node; List *tmp_oper, *tmp_lefthand; /* * We also have to adapt the variables used in * sub->lefthand and sub->oper */ OffsetVarNodes( (Node *) (sub->lefthand), offset, sublevels_up); OffsetVarNodes( (Node *) (sub->subselect), offset, sublevels_up + 1); /***S*I***/ /* * Make sure the first argument of sub->oper points to the * same var as sub->lefthand does otherwise we will run * into troubles using aggregates (aggno will not be set * correctly) */ tmp_lefthand = sub->lefthand; foreach(tmp_oper, sub->oper) { lfirst(((Expr *) lfirst(tmp_oper))->args) = lfirst(tmp_lefthand); tmp_lefthand = lnext(tmp_lefthand); } } break; case T_Query: { Query *qry = (Query *) node; OffsetVarNodes( (Node *) (qry->targetList), offset, sublevels_up); OffsetVarNodes( (Node *) (qry->qual), offset, sublevels_up); OffsetVarNodes( (Node *) (qry->havingQual), offset, sublevels_up); } break; case T_CaseExpr: { CaseExpr *exp = (CaseExpr *) node; OffsetVarNodes( (Node *) (exp->args), offset, sublevels_up); OffsetVarNodes( (Node *) (exp->defresult), offset, sublevels_up); } break; case T_CaseWhen: { CaseWhen *exp = (CaseWhen *) node; OffsetVarNodes( (Node *) (exp->expr), offset, sublevels_up); OffsetVarNodes( (Node *) (exp->result), offset, sublevels_up); } break; default: elog(NOTICE, "unknown node tag %d in OffsetVarNodes()", nodeTag(node)); elog(NOTICE, "Node is: %s", nodeToString(node)); break; }}/* * ChangeVarNodes - */voidChangeVarNodes(Node *node, int rt_index, int new_index, int sublevels_up){ if (node == NULL) return; switch (nodeTag(node)) { case T_TargetEntry: { TargetEntry *tle = (TargetEntry *) node; ChangeVarNodes( (Node *) (tle->expr), rt_index, new_index, sublevels_up); } break; case T_Aggref: { Aggref *aggref = (Aggref *) node; ChangeVarNodes( (Node *) (aggref->target), rt_index, new_index, sublevels_up); } break; case T_GroupClause: break; case T_Expr: { Expr *exp = (Expr *) node; ChangeVarNodes( (Node *) (exp->args), rt_index, new_index, sublevels_up); } break; case T_Iter: { Iter *iter = (Iter *) node; ChangeVarNodes( (Node *) (iter->iterexpr), rt_index, new_index, sublevels_up); } break; case T_ArrayRef: { ArrayRef *ref = (ArrayRef *) node; ChangeVarNodes( (Node *) (ref->refupperindexpr), rt_index, new_index, sublevels_up); ChangeVarNodes( (Node *) (ref->reflowerindexpr), rt_index, new_index, sublevels_up); ChangeVarNodes( (Node *) (ref->refexpr), rt_index, new_index, sublevels_up); ChangeVarNodes( (Node *) (ref->refassgnexpr), rt_index, new_index, sublevels_up); } break; case T_Var: { Var *var = (Var *) node; if (var->varlevelsup == sublevels_up && var->varno == rt_index) { var->varno = new_index; var->varnoold = new_index; } } break; case T_Param: break; case T_Const: break; case T_List: { List *l; foreach(l, (List *) node) ChangeVarNodes( (Node *) lfirst(l), rt_index, new_index, sublevels_up); } break; case T_SubLink: { SubLink *sub = (SubLink *) node; List *tmp_oper, *tmp_lefthand; ChangeVarNodes( (Node *) (sub->lefthand), rt_index, new_index, sublevels_up); ChangeVarNodes( (Node *) (sub->subselect), rt_index, new_index, sublevels_up + 1); /***S*I***/ /* * Make sure the first argument of sub->oper points to the * same var as sub->lefthand does otherwise we will run * into troubles using aggregates (aggno will not be set * correctly) */ tmp_lefthand = sub->lefthand; foreach(tmp_oper, sub->oper) { lfirst(((Expr *) lfirst(tmp_oper))->args) = lfirst(tmp_lefthand); tmp_lefthand = lnext(tmp_lefthand); } } break; case T_Query: { Query *qry = (Query *) node; ChangeVarNodes( (Node *) (qry->targetList), rt_index, new_index, sublevels_up); ChangeVarNodes( (Node *) (qry->qual), rt_index, new_index, sublevels_up); ChangeVarNodes( (Node *) (qry->havingQual), rt_index, new_index, sublevels_up); } break; case T_CaseExpr: { CaseExpr *exp = (CaseExpr *) node; ChangeVarNodes( (Node *) (exp->args), rt_index, new_index, sublevels_up); ChangeVarNodes( (Node *) (exp->defresult), rt_index, new_index, sublevels_up); } break; case T_CaseWhen: { CaseWhen *exp = (CaseWhen *) node; ChangeVarNodes( (Node *) (exp->expr), rt_index, new_index, sublevels_up); ChangeVarNodes( (Node *) (exp->result), rt_index, new_index, sublevels_up); } break; default: elog(NOTICE, "unknown node tag %d in ChangeVarNodes()", nodeTag(node)); elog(NOTICE, "Node is: %s", nodeToString(node)); break; }}voidAddQual(Query *parsetree, Node *qual){ Node *copy, *old; if (qual == NULL) return; /***S*I***/ /* INTERSECT want's the original, but we need to copy - Jan */ /* copy = qual; */ copy = copyObject(qual); old = parsetree->qual; if (old == NULL) parsetree->qual = copy; else parsetree->qual = (Node *) make_andclause(makeList(parsetree->qual, copy, -1));}/* Adds the given havingQual to the one already contained in the parsetree just as * AddQual does for the normal 'where' qual */voidAddHavingQual(Query *parsetree, Node *havingQual){ Node *copy, *old; if (havingQual == NULL) return; /***S*I***/ /* INTERSECT want's the original, but we need to copy - Jan */ /* copy = havingQual; */ copy = copyObject(havingQual); old = parsetree->havingQual; if (old == NULL) parsetree->havingQual = copy; else parsetree->havingQual = (Node *) make_andclause(makeList(parsetree->havingQual, copy, -1));}#ifdef NOT_USEDvoidAddNotHavingQual(Query *parsetree, Node *havingQual){ Node *copy; if (havingQual == NULL) return; /***S*I***/ /* INTERSECT want's the original, but we need to copy - Jan */ /* copy = (Node *) make_notclause((Expr *)havingQual); */ copy = (Node *) make_notclause((Expr *) copyObject(havingQual)); AddHavingQual(parsetree, copy);}#endifvoidAddNotQual(Query *parsetree, Node *qual){ Node *copy; if (qual == NULL) return; /***S*I***/ /* INTERSECT want's the original, but we need to copy - Jan */ /* copy = (Node *) make_notclause((Expr *)qual); */ copy = (Node *) make_notclause((Expr *) copyObject(qual)); AddQual(parsetree, copy);}voidAddGroupClause(Query *parsetree, List *group_by, List *tlist){ List *l; List *tl; GroupClause *groupclause; TargetEntry *tle; int new_resno; new_resno = length(parsetree->targetList); foreach(l, group_by) { groupclause = (GroupClause *) copyObject(lfirst(l)); tle = NULL; foreach(tl, tlist) { if (((TargetEntry *) lfirst(tl))->resdom->resgroupref ==
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -