📄 rewritehandler.c
字号:
break; case T_CaseExpr: { /* * We're calling recursively, and this routine knows how * to handle lists so let it do the work to handle the * WHEN clauses... */ modifyAggrefQual( (Node **) (&(((CaseExpr *) node)->args)), parsetree); modifyAggrefQual( (Node **) (&(((CaseExpr *) node)->defresult)), parsetree); } break; case T_CaseWhen: { modifyAggrefQual( (Node **) (&(((CaseWhen *) node)->expr)), parsetree); modifyAggrefQual( (Node **) (&(((CaseWhen *) node)->result)), parsetree); } break; case T_Iter: { Iter *iter = (Iter *) node; modifyAggrefQual( (Node **) (&(iter->iterexpr)), parsetree); } break; case T_ArrayRef: { ArrayRef *ref = (ArrayRef *) node; modifyAggrefQual( (Node **) (&(ref->refupperindexpr)), parsetree); modifyAggrefQual( (Node **) (&(ref->reflowerindexpr)), parsetree); modifyAggrefQual( (Node **) (&(ref->refexpr)), parsetree); modifyAggrefQual( (Node **) (&(ref->refassgnexpr)), parsetree); } break; case T_List: { List *l; foreach(l, (List *) node) modifyAggrefQual( (Node **) (&(lfirst(l))), parsetree); } break; case T_SubLink: { SubLink *sub = (SubLink *) node; modifyAggrefQual( (Node **) (&(sub->subselect)), (Query *) (sub->subselect)); } break; case T_Query: { Query *qry = (Query *) node; modifyAggrefQual( (Node **) (&(qry->qual)), parsetree); modifyAggrefQual( (Node **) (&(qry->havingQual)), parsetree); } break; default: elog(NOTICE, "unknown node tag %d in modifyAggrefQual()", nodeTag(node)); elog(NOTICE, "Node is: %s", nodeToString(node)); break; }}/* * checkQueryHasAggs - * Queries marked hasAggs might not have them any longer after * rewriting. Check it. */static boolcheckQueryHasAggs(Node *node){ return checkQueryHasAggs_walker(node, NULL);}static boolcheckQueryHasAggs_walker(Node *node, void *context){ if (node == NULL) return false; if (IsA(node, Aggref)) return true; /* abort the tree traversal and return true */ return expression_tree_walker(node, checkQueryHasAggs_walker, context);}/* * checkQueryHasSubLink - * Queries marked hasSubLinks might not have them any longer after * rewriting. Check it. */static boolcheckQueryHasSubLink(Node *node){ return checkQueryHasSubLink_walker(node, NULL);}static boolcheckQueryHasSubLink_walker(Node *node, void *context){ if (node == NULL) return false; if (IsA(node, SubLink)) return true; /* abort the tree traversal and return true */ /* Note: we assume the tree has not yet been rewritten by subselect.c, * therefore we will find bare SubLink nodes and not SUBPLAN nodes. */ return expression_tree_walker(node, checkQueryHasSubLink_walker, context);}static Node *FindMatchingTLEntry(List *tlist, char *e_attname){ List *i; foreach(i, tlist) { TargetEntry *tle = lfirst(i); char *resname; resname = tle->resdom->resname; if (!strcmp(e_attname, resname)) return (tle->expr); } return NULL;}static Node *make_null(Oid type){ Const *c = makeNode(Const); c->consttype = type; c->constlen = get_typlen(type); c->constvalue = PointerGetDatum(NULL); c->constisnull = true; c->constbyval = get_typbyval(type); return (Node *) c;}static voidapply_RIR_adjust_sublevel(Node *node, int sublevels_up){ if (node == NULL) return; switch (nodeTag(node)) { case T_TargetEntry: { TargetEntry *tle = (TargetEntry *) node; apply_RIR_adjust_sublevel( (Node *) (tle->expr), sublevels_up); } break; case T_Aggref: { Aggref *aggref = (Aggref *) node; apply_RIR_adjust_sublevel( (Node *) (aggref->target), sublevels_up); } break; case T_GroupClause: break; case T_Expr: { Expr *exp = (Expr *) node; apply_RIR_adjust_sublevel( (Node *) (exp->args), sublevels_up); } break; case T_Iter: { Iter *iter = (Iter *) node; apply_RIR_adjust_sublevel( (Node *) (iter->iterexpr), sublevels_up); } break; case T_ArrayRef: { ArrayRef *ref = (ArrayRef *) node; apply_RIR_adjust_sublevel( (Node *) (ref->refupperindexpr), sublevels_up); apply_RIR_adjust_sublevel( (Node *) (ref->reflowerindexpr), sublevels_up); apply_RIR_adjust_sublevel( (Node *) (ref->refexpr), sublevels_up); apply_RIR_adjust_sublevel( (Node *) (ref->refassgnexpr), sublevels_up); } break; case T_Var: { Var *var = (Var *) node; var->varlevelsup = sublevels_up; } break; case T_Param: break; case T_Const: break; case T_List: { List *l; foreach(l, (List *) node) { apply_RIR_adjust_sublevel( (Node *) lfirst(l), sublevels_up); } } break; case T_CaseExpr: { CaseExpr *exp = (CaseExpr *) node; apply_RIR_adjust_sublevel( (Node *) (exp->args), sublevels_up); apply_RIR_adjust_sublevel( (Node *) (exp->defresult), sublevels_up); } break; case T_CaseWhen: { CaseWhen *exp = (CaseWhen *) node; apply_RIR_adjust_sublevel( (Node *) (exp->expr), sublevels_up); apply_RIR_adjust_sublevel( (Node *) (exp->result), sublevels_up); } break; default: elog(NOTICE, "unknown node tag %d in attribute_used()", nodeTag(node)); elog(NOTICE, "Node is: %s", nodeToString(node)); break; }}static voidapply_RIR_view(Node **nodePtr, int rt_index, RangeTblEntry *rte, List *tlist, int *modified, int sublevels_up){ Node *node = *nodePtr; if (node == NULL) return; switch (nodeTag(node)) { case T_TargetEntry: { TargetEntry *tle = (TargetEntry *) node; apply_RIR_view( (Node **) (&(tle->expr)), rt_index, rte, tlist, modified, sublevels_up); } break; case T_Aggref: { Aggref *aggref = (Aggref *) node; apply_RIR_view( (Node **) (&(aggref->target)), rt_index, rte, tlist, modified, sublevels_up); } break; case T_GroupClause: break; case T_Expr: { Expr *exp = (Expr *) node; apply_RIR_view( (Node **) (&(exp->args)), rt_index, rte, tlist, modified, sublevels_up); } break; case T_Iter: { Iter *iter = (Iter *) node; apply_RIR_view( (Node **) (&(iter->iterexpr)), rt_index, rte, tlist, modified, sublevels_up); } break; case T_ArrayRef: { ArrayRef *ref = (ArrayRef *) node; apply_RIR_view( (Node **) (&(ref->refupperindexpr)), rt_index, rte, tlist, modified, sublevels_up); apply_RIR_view( (Node **) (&(ref->reflowerindexpr)), rt_index, rte, tlist, modified, sublevels_up); apply_RIR_view( (Node **) (&(ref->refexpr)), rt_index, rte, tlist, modified, sublevels_up); apply_RIR_view( (Node **) (&(ref->refassgnexpr)), rt_index, rte, tlist, modified, sublevels_up); } break; case T_Var: { Var *var = (Var *) node; if (var->varlevelsup == sublevels_up && var->varno == rt_index) { Node *exp; if (var->varattno < 0) elog(ERROR, "system column %s not available - %s is a view", get_attname(rte->relid, var->varattno), rte->relname); exp = FindMatchingTLEntry( tlist, get_attname(rte->relid, var->varattno)); if (exp == NULL) { *nodePtr = make_null(var->vartype); return; } exp = copyObject(exp); if (var->varlevelsup > 0) apply_RIR_adjust_sublevel(exp, var->varlevelsup); *nodePtr = exp; *modified = TRUE; } } break; case T_Param: break; case T_Const: break; case T_List: { List *l; foreach(l, (List *) node) apply_RIR_view( (Node **) (&(lfirst(l))), rt_index, rte, tlist, modified, sublevels_up); } break; case T_SubLink: { SubLink *sub = (SubLink *) node; List *tmp_lefthand, *tmp_oper; apply_RIR_view( (Node **) (&(sub->lefthand)), rt_index, rte, tlist, modified, sublevels_up); apply_RIR_view( (Node **) (&(sub->subselect)), rt_index, rte, tlist, modified, sublevels_up + 1); /***S*I***/ 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; apply_RIR_view( (Node **) (&(qry->targetList)), rt_index, rte, tlist, modified, sublevels_up); apply_RIR_view( (Node **) (&(qry->qual)), rt_index, rte, tlist, modified, sublevels_up); apply_RIR_view( (Node **) (&(qry->havingQual)), rt_index, rte, tlist, modified, sublevels_up); } break; case T_CaseExpr: { CaseExpr *exp = (CaseExpr *) node; apply_RIR_view( (Node **) (&(exp->args)), rt_index, rte, tlist, modified, sublevels_up); apply_RIR_view( (Node **) (&(exp->defresult)), rt_index, rte, tlist, modified, sublevels_up); } break; case T_CaseWhen: { CaseWhen *exp = (CaseWhen *) node; apply_RIR_view( (Node **) (&(exp->expr)), rt_index, rte, tlist, modified, sublevels_up); apply_RIR_view( (Node **) (&(exp->result)), rt_index, rte, tlist, modified, sublevels_up); } break; default: elog(NOTICE, "unknown node tag %d in apply_RIR_view()", nodeTag(node)); elog(NOTICE, "Node is: %s", nodeToString(node)); break; }}extern void CheckSelectForUpdate(Query *rule_action); /* in analyze.c */static voidApplyRetrieveRule(Query *parsetree, RewriteRule *rule,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -