diff options
Diffstat (limited to 'src/backend/rewrite/rewriteHandler.c')
-rw-r--r-- | src/backend/rewrite/rewriteHandler.c | 2273 |
1 files changed, 1183 insertions, 1090 deletions
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c index 7769d722992..ed02edddea0 100644 --- a/src/backend/rewrite/rewriteHandler.c +++ b/src/backend/rewrite/rewriteHandler.c @@ -6,7 +6,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.44 1999/05/25 13:16:10 wieck Exp $ + * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.45 1999/05/25 16:10:50 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -147,26 +147,27 @@ rangeTableEntry_used(Node *node, int rt_index, int sublevels_up) if (node == NULL) return FALSE; - switch(nodeTag(node)) { + switch (nodeTag(node)) + { case T_TargetEntry: { - TargetEntry *tle = (TargetEntry *)node; + TargetEntry *tle = (TargetEntry *) node; return rangeTableEntry_used( - (Node *)(tle->expr), - rt_index, - sublevels_up); + (Node *) (tle->expr), + rt_index, + sublevels_up); } break; case T_Aggref: { - Aggref *aggref = (Aggref *)node; + Aggref *aggref = (Aggref *) node; return rangeTableEntry_used( - (Node *)(aggref->target), - rt_index, - sublevels_up); + (Node *) (aggref->target), + rt_index, + sublevels_up); } break; @@ -175,61 +176,61 @@ rangeTableEntry_used(Node *node, int rt_index, int sublevels_up) case T_Expr: { - Expr *exp = (Expr *)node; + Expr *exp = (Expr *) node; return rangeTableEntry_used( - (Node *)(exp->args), - rt_index, - sublevels_up); + (Node *) (exp->args), + rt_index, + sublevels_up); } break; case T_Iter: { - Iter *iter = (Iter *)node; + Iter *iter = (Iter *) node; return rangeTableEntry_used( - (Node *)(iter->iterexpr), - rt_index, - sublevels_up); + (Node *) (iter->iterexpr), + rt_index, + sublevels_up); } break; case T_ArrayRef: { - ArrayRef *ref = (ArrayRef *)node; + ArrayRef *ref = (ArrayRef *) node; if (rangeTableEntry_used( - (Node *)(ref->refupperindexpr), - rt_index, - sublevels_up)) + (Node *) (ref->refupperindexpr), + rt_index, + sublevels_up)) return TRUE; - + if (rangeTableEntry_used( - (Node *)(ref->reflowerindexpr), - rt_index, - sublevels_up)) + (Node *) (ref->reflowerindexpr), + rt_index, + sublevels_up)) return TRUE; - + if (rangeTableEntry_used( - (Node *)(ref->refexpr), - rt_index, - sublevels_up)) + (Node *) (ref->refexpr), + rt_index, + sublevels_up)) return TRUE; - + if (rangeTableEntry_used( - (Node *)(ref->refassgnexpr), - rt_index, - sublevels_up)) + (Node *) (ref->refassgnexpr), + rt_index, + sublevels_up)) return TRUE; - + return FALSE; } break; case T_Var: { - Var *var = (Var *)node; + Var *var = (Var *) node; if (var->varlevelsup == sublevels_up) return var->varno == rt_index; @@ -246,13 +247,14 @@ rangeTableEntry_used(Node *node, int rt_index, int sublevels_up) case T_List: { - List *l; + List *l; - foreach (l, (List *)node) { + foreach(l, (List *) node) + { if (rangeTableEntry_used( - (Node *)lfirst(l), - rt_index, - sublevels_up)) + (Node *) lfirst(l), + rt_index, + sublevels_up)) return TRUE; } return FALSE; @@ -261,18 +263,18 @@ rangeTableEntry_used(Node *node, int rt_index, int sublevels_up) case T_SubLink: { - SubLink *sub = (SubLink *)node; + SubLink *sub = (SubLink *) node; if (rangeTableEntry_used( - (Node *)(sub->lefthand), - rt_index, - sublevels_up)) + (Node *) (sub->lefthand), + rt_index, + sublevels_up)) return TRUE; if (rangeTableEntry_used( - (Node *)(sub->subselect), - rt_index, - sublevels_up + 1)) + (Node *) (sub->subselect), + rt_index, + sublevels_up + 1)) return TRUE; return FALSE; @@ -281,18 +283,18 @@ rangeTableEntry_used(Node *node, int rt_index, int sublevels_up) case T_CaseExpr: { - CaseExpr *exp = (CaseExpr *)node; + CaseExpr *exp = (CaseExpr *) node; if (rangeTableEntry_used( - (Node *)(exp->args), - rt_index, - sublevels_up)) + (Node *) (exp->args), + rt_index, + sublevels_up)) return TRUE; if (rangeTableEntry_used( - (Node *)(exp->defresult), - rt_index, - sublevels_up)) + (Node *) (exp->defresult), + rt_index, + sublevels_up)) return TRUE; return FALSE; @@ -301,18 +303,18 @@ rangeTableEntry_used(Node *node, int rt_index, int sublevels_up) case T_CaseWhen: { - CaseWhen *when = (CaseWhen *)node; + CaseWhen *when = (CaseWhen *) node; if (rangeTableEntry_used( - (Node *)(when->expr), - rt_index, - sublevels_up)) + (Node *) (when->expr), + rt_index, + sublevels_up)) return TRUE; if (rangeTableEntry_used( - (Node *)(when->result), - rt_index, - sublevels_up)) + (Node *) (when->result), + rt_index, + sublevels_up)) return TRUE; return FALSE; @@ -321,24 +323,24 @@ rangeTableEntry_used(Node *node, int rt_index, int sublevels_up) case T_Query: { - Query *qry = (Query *)node; + Query *qry = (Query *) node; if (rangeTableEntry_used( - (Node *)(qry->targetList), - rt_index, - sublevels_up)) + (Node *) (qry->targetList), + rt_index, + sublevels_up)) return TRUE; if (rangeTableEntry_used( - (Node *)(qry->qual), - rt_index, - sublevels_up)) + (Node *) (qry->qual), + rt_index, + sublevels_up)) return TRUE; if (rangeTableEntry_used( - (Node *)(qry->havingQual), - rt_index, - sublevels_up)) + (Node *) (qry->havingQual), + rt_index, + sublevels_up)) return TRUE; return FALSE; @@ -368,28 +370,29 @@ attribute_used(Node *node, int rt_index, int attno, int sublevels_up) if (node == NULL) return FALSE; - switch(nodeTag(node)) { + switch (nodeTag(node)) + { case T_TargetEntry: { - TargetEntry *tle = (TargetEntry *)node; + TargetEntry *tle = (TargetEntry *) node; return attribute_used( - (Node *)(tle->expr), - rt_index, - attno, - sublevels_up); + (Node *) (tle->expr), + rt_index, + attno, + sublevels_up); } break; case T_Aggref: { - Aggref *aggref = (Aggref *)node; + Aggref *aggref = (Aggref *) node; return attribute_used( - (Node *)(aggref->target), - rt_index, - attno, - sublevels_up); + (Node *) (aggref->target), + rt_index, + attno, + sublevels_up); } break; @@ -398,58 +401,58 @@ attribute_used(Node *node, int rt_index, int attno, int sublevels_up) case T_Expr: { - Expr *exp = (Expr *)node; + Expr *exp = (Expr *) node; return attribute_used( - (Node *)(exp->args), - rt_index, - attno, - sublevels_up); + (Node *) (exp->args), + rt_index, + attno, + sublevels_up); } break; case T_Iter: { - Iter *iter = (Iter *)node; + Iter *iter = (Iter *) node; return attribute_used( - (Node *)(iter->iterexpr), - rt_index, - attno, - sublevels_up); + (Node *) (iter->iterexpr), + rt_index, + attno, + sublevels_up); } break; case T_ArrayRef: { - ArrayRef *ref = (ArrayRef *)node; + ArrayRef *ref = (ArrayRef *) node; if (attribute_used( - (Node *)(ref->refupperindexpr), - rt_index, - attno, - sublevels_up)) + (Node *) (ref->refupperindexpr), + rt_index, + attno, + sublevels_up)) return TRUE; if (attribute_used( - (Node *)(ref->reflowerindexpr), - rt_index, - attno, - sublevels_up)) + (Node *) (ref->reflowerindexpr), + rt_index, + attno, + sublevels_up)) return TRUE; if (attribute_used( - (Node *)(ref->refexpr), - rt_index, - attno, - sublevels_up)) + (Node *) (ref->refexpr), + rt_index, + attno, + sublevels_up)) return TRUE; if (attribute_used( - (Node *)(ref->refassgnexpr), - rt_index, - attno, - sublevels_up)) + (Node *) (ref->refassgnexpr), + rt_index, + attno, + sublevels_up)) return TRUE; return FALSE; @@ -458,7 +461,7 @@ attribute_used(Node *node, int rt_index, int attno, int sublevels_up) case T_Var: { - Var *var = (Var *)node; + Var *var = (Var *) node; if (var->varlevelsup == sublevels_up) return var->varno == rt_index; @@ -475,14 +478,15 @@ attribute_used(Node *node, int rt_index, int attno, int sublevels_up) case T_List: { - List *l; + List *l; - foreach (l, (List *)node) { + foreach(l, (List *) node) + { if (attribute_used( - (Node *)lfirst(l), - rt_index, - attno, - sublevels_up)) + (Node *) lfirst(l), + rt_index, + attno, + sublevels_up)) return TRUE; } return FALSE; @@ -491,20 +495,20 @@ attribute_used(Node *node, int rt_index, int attno, int sublevels_up) case T_SubLink: { - SubLink *sub = (SubLink *)node; + SubLink *sub = (SubLink *) node; if (attribute_used( - (Node *)(sub->lefthand), - rt_index, - attno, - sublevels_up)) + (Node *) (sub->lefthand), + rt_index, + attno, + sublevels_up)) return TRUE; if (attribute_used( - (Node *)(sub->subselect), - rt_index, - attno, - sublevels_up + 1)) + (Node *) (sub->subselect), + rt_index, + attno, + sublevels_up + 1)) return TRUE; return FALSE; @@ -513,27 +517,27 @@ attribute_used(Node *node, int rt_index, int attno, int sublevels_up) case T_Query: { - Query *qry = (Query *)node; + Query *qry = (Query *) node; if (attribute_used( - (Node *)(qry->targetList), - rt_index, - attno, - sublevels_up)) + (Node *) (qry->targetList), + rt_index, + attno, + sublevels_up)) return TRUE; if (attribute_used( - (Node *)(qry->qual), - rt_index, - attno, - sublevels_up)) + (Node *) (qry->qual), + rt_index, + attno, + sublevels_up)) return TRUE; if (attribute_used( - (Node *)(qry->havingQual), - rt_index, - attno, - sublevels_up)) + (Node *) (qry->havingQual), + rt_index, + attno, + sublevels_up)) return TRUE; return FALSE; @@ -564,61 +568,62 @@ modifyAggrefUplevel(Node *node) if (node == NULL) return; - switch(nodeTag(node)) { + switch (nodeTag(node)) + { case T_TargetEntry: { - TargetEntry *tle = (TargetEntry *)node; + TargetEntry *tle = (TargetEntry *) node; modifyAggrefUplevel( - (Node *)(tle->expr)); + (Node *) (tle->expr)); } break; case T_Aggref: { - Aggref *aggref = (Aggref *)node; + Aggref *aggref = (Aggref *) node; modifyAggrefUplevel( - (Node *)(aggref->target)); + (Node *) (aggref->target)); } break; case T_Expr: { - Expr *exp = (Expr *)node; + Expr *exp = (Expr *) node; modifyAggrefUplevel( - (Node *)(exp->args)); + (Node *) (exp->args)); } break; case T_Iter: { - Iter *iter = (Iter *)node; + Iter *iter = (Iter *) node; modifyAggrefUplevel( - (Node *)(iter->iterexpr)); + (Node *) (iter->iterexpr)); } break; case T_ArrayRef: { - ArrayRef *ref = (ArrayRef *)node; + ArrayRef *ref = (ArrayRef *) node; modifyAggrefUplevel( - (Node *)(ref->refupperindexpr)); + (Node *) (ref->refupperindexpr)); modifyAggrefUplevel( - (Node *)(ref->reflowerindexpr)); + (Node *) (ref->reflowerindexpr)); modifyAggrefUplevel( - (Node *)(ref->refexpr)); + (Node *) (ref->refexpr)); modifyAggrefUplevel( - (Node *)(ref->refassgnexpr)); + (Node *) (ref->refassgnexpr)); } break; case T_Var: { - Var *var = (Var *)node; + Var *var = (Var *) node; var->varlevelsup++; } @@ -632,41 +637,41 @@ modifyAggrefUplevel(Node *node) case T_List: { - List *l; + List *l; - foreach (l, (List *)node) + foreach(l, (List *) node) modifyAggrefUplevel( - (Node *)lfirst(l)); + (Node *) lfirst(l)); } break; case T_SubLink: { - SubLink *sub = (SubLink *)node; + SubLink *sub = (SubLink *) node; modifyAggrefUplevel( - (Node *)(sub->lefthand)); + (Node *) (sub->lefthand)); modifyAggrefUplevel( - (Node *)(sub->oper)); + (Node *) (sub->oper)); modifyAggrefUplevel( - (Node *)(sub->subselect)); + (Node *) (sub->subselect)); } break; case T_Query: { - Query *qry = (Query *)node; + Query *qry = (Query *) node; modifyAggrefUplevel( - (Node *)(qry->targetList)); + (Node *) (qry->targetList)); modifyAggrefUplevel( - (Node *)(qry->qual)); + (Node *) (qry->qual)); modifyAggrefUplevel( - (Node *)(qry->havingQual)); + (Node *) (qry->havingQual)); } break; @@ -690,33 +695,34 @@ modifyAggrefUplevel(Node *node) static void modifyAggrefChangeVarnodes(Node **nodePtr, int rt_index, int new_index, int sublevels_up) { - Node *node = *nodePtr; + Node *node = *nodePtr; if (node == NULL) return; - switch(nodeTag(node)) { + switch (nodeTag(node)) + { case T_TargetEntry: { - TargetEntry *tle = (TargetEntry *)node; + TargetEntry *tle = (TargetEntry *) node; modifyAggrefChangeVarnodes( - (Node **)(&(tle->expr)), - rt_index, - new_index, - sublevels_up); + (Node **) (&(tle->expr)), + rt_index, + new_index, + sublevels_up); } break; case T_Aggref: { - Aggref *aggref = (Aggref *)node; + Aggref *aggref = (Aggref *) node; modifyAggrefChangeVarnodes( - (Node **)(&(aggref->target)), - rt_index, - new_index, - sublevels_up); + (Node **) (&(aggref->target)), + rt_index, + new_index, + sublevels_up); } break; @@ -725,67 +731,68 @@ modifyAggrefChangeVarnodes(Node **nodePtr, int rt_index, int new_index, int subl case T_Expr: { - Expr *exp = (Expr *)node; + Expr *exp = (Expr *) node; modifyAggrefChangeVarnodes( - (Node **)(&(exp->args)), - rt_index, - new_index, - sublevels_up); + (Node **) (&(exp->args)), + rt_index, + new_index, + sublevels_up); } break; case T_Iter: { - Iter *iter = (Iter *)node; + Iter *iter = (Iter *) node; modifyAggrefChangeVarnodes( - (Node **)(&(iter->iterexpr)), - rt_index, - new_index, - sublevels_up); + (Node **) (&(iter->iterexpr)), + rt_index, + new_index, + sublevels_up); } break; case T_ArrayRef: { - ArrayRef *ref = (ArrayRef *)node; + ArrayRef *ref = (ArrayRef *) node; modifyAggrefChangeVarnodes( - (Node **)(&(ref->refupperindexpr)), - rt_index, - new_index, - sublevels_up); + (Node **) (&(ref->refupperindexpr)), + rt_index, + new_index, + sublevels_up); modifyAggrefChangeVarnodes( - (Node **)(&(ref->reflowerindexpr)), - rt_index, - new_index, - sublevels_up); + (Node **) (&(ref->reflowerindexpr)), + rt_index, + new_index, + sublevels_up); modifyAggrefChangeVarnodes( - (Node **)(&(ref->refexpr)), - rt_index, - new_index, - sublevels_up); + (Node **) (&(ref->refexpr)), + rt_index, + new_index, + sublevels_up); modifyAggrefChangeVarnodes( - (Node **)(&(ref->refassgnexpr)), - rt_index, - new_index, - sublevels_up); + (Node **) (&(ref->refassgnexpr)), + rt_index, + new_index, + sublevels_up); } break; case T_Var: { - Var *var = (Var *)node; + Var *var = (Var *) node; if (var->varlevelsup == sublevels_up && - var->varno == rt_index) { + var->varno == rt_index) + { var = copyObject(var); var->varno = new_index; var->varnoold = new_index; var->varlevelsup = 0; - *nodePtr = (Node *)var; + *nodePtr = (Node *) var; } } break; @@ -798,62 +805,62 @@ modifyAggrefChangeVarnodes(Node **nodePtr, int rt_index, int new_index, int subl case T_List: { - List *l; + List *l; - foreach (l, (List *)node) + foreach(l, (List *) node) modifyAggrefChangeVarnodes( - (Node **)(&lfirst(l)), - rt_index, - new_index, - sublevels_up); + (Node **) (&lfirst(l)), + rt_index, + new_index, + sublevels_up); } break; case T_SubLink: { - SubLink *sub = (SubLink *)node; + SubLink *sub = (SubLink *) node; modifyAggrefChangeVarnodes( - (Node **)(&(sub->lefthand)), - rt_index, - new_index, - sublevels_up); + (Node **) (&(sub->lefthand)), + rt_index, + new_index, + sublevels_up); modifyAggrefChangeVarnodes( - (Node **)(&(sub->oper)), - rt_index, - new_index, - sublevels_up); + (Node **) (&(sub->oper)), + rt_index, + new_index, + sublevels_up); modifyAggrefChangeVarnodes( - (Node **)(&(sub->subselect)), - rt_index, - new_index, - sublevels_up + 1); + (Node **) (&(sub->subselect)), + rt_index, + new_index, + sublevels_up + 1); } break; case T_Query: { - Query *qry = (Query *)node; + Query *qry = (Query *) node; modifyAggrefChangeVarnodes( - (Node **)(&(qry->targetList)), - rt_index, - new_index, - sublevels_up); + (Node **) (&(qry->targetList)), + rt_index, + new_index, + sublevels_up); modifyAggrefChangeVarnodes( - (Node **)(&(qry->qual)), - rt_index, - new_index, - sublevels_up); + (Node **) (&(qry->qual)), + rt_index, + new_index, + sublevels_up); modifyAggrefChangeVarnodes( - (Node **)(&(qry->havingQual)), - rt_index, - new_index, - sublevels_up); + (Node **) (&(qry->havingQual)), + rt_index, + new_index, + sublevels_up); } break; @@ -874,24 +881,25 @@ modifyAggrefChangeVarnodes(Node **nodePtr, int rt_index, int new_index, int subl static void modifyAggrefDropQual(Node **nodePtr, Node *orignode, Expr *expr) { - Node *node = *nodePtr; + Node *node = *nodePtr; if (node == NULL) return; - switch(nodeTag(node)) { + switch (nodeTag(node)) + { case T_Var: break; case T_Aggref: { - Aggref *aggref = (Aggref *)node; - Aggref *oaggref = (Aggref *)orignode; + Aggref *aggref = (Aggref *) node; + Aggref *oaggref = (Aggref *) orignode; modifyAggrefDropQual( - (Node **)(&(aggref->target)), - (Node *)(oaggref->target), - expr); + (Node **) (&(aggref->target)), + (Node *) (oaggref->target), + expr); } break; @@ -906,79 +914,81 @@ modifyAggrefDropQual(Node **nodePtr, Node *orignode, Expr *expr) case T_Expr: { - Expr *this_expr = (Expr *)node; - Expr *orig_expr = (Expr *)orignode; + Expr *this_expr = (Expr *) node; + Expr *orig_expr = (Expr *) orignode; - if (orig_expr == expr) { - Const *ctrue; + if (orig_expr == expr) + { + Const *ctrue; if (expr->typeOid != BOOLOID) elog(ERROR, - "aggregate expression in qualification isn't of type bool"); + "aggregate expression in qualification isn't of type bool"); ctrue = makeNode(Const); ctrue->consttype = BOOLOID; ctrue->constlen = 1; ctrue->constisnull = FALSE; - ctrue->constvalue = (Datum)TRUE; + ctrue->constvalue = (Datum) TRUE; ctrue->constbyval = TRUE; - *nodePtr = (Node *)ctrue; + *nodePtr = (Node *) ctrue; } else modifyAggrefDropQual( - (Node **)(&(this_expr->args)), - (Node *)(orig_expr->args), - expr); + (Node **) (&(this_expr->args)), + (Node *) (orig_expr->args), + expr); } break; case T_Iter: { - Iter *iter = (Iter *)node; - Iter *oiter = (Iter *)orignode; + Iter *iter = (Iter *) node; + Iter *oiter = (Iter *) orignode; modifyAggrefDropQual( - (Node **)(&(iter->iterexpr)), - (Node *)(oiter->iterexpr), - expr); + (Node **) (&(iter->iterexpr)), + (Node *) (oiter->iterexpr), + expr); } break; case T_ArrayRef: { - ArrayRef *ref = (ArrayRef *)node; - ArrayRef *oref = (ArrayRef *)orignode; + ArrayRef *ref = (ArrayRef *) node; + ArrayRef *oref = (ArrayRef *) orignode; modifyAggrefDropQual( - (Node **)(&(ref->refupperindexpr)), - (Node *)(oref->refupperindexpr), - expr); + (Node **) (&(ref->refupperindexpr)), + (Node *) (oref->refupperindexpr), + expr); modifyAggrefDropQual( - (Node **)(&(ref->reflowerindexpr)), - (Node *)(oref->reflowerindexpr), - expr); + (Node **) (&(ref->reflowerindexpr)), + (Node *) (oref->reflowerindexpr), + expr); modifyAggrefDropQual( - (Node **)(&(ref->refexpr)), - (Node *)(oref->refexpr), - expr); + (Node **) (&(ref->refexpr)), + (Node *) (oref->refexpr), + expr); modifyAggrefDropQual( - (Node **)(&(ref->refassgnexpr)), - (Node *)(oref->refassgnexpr), - expr); + (Node **) (&(ref->refassgnexpr)), + (Node *) (oref->refassgnexpr), + expr); } break; case T_List: { - List *l; - List *ol = (List *)orignode; - int li = 0; + List *l; + List *ol = (List *) orignode; + int li = 0; - foreach (l, (List *)node) { + foreach(l, (List *) node) + { modifyAggrefDropQual( - (Node **)(&(lfirst(l))), - (Node *)nth(li, ol), - expr); + (Node **) (&(lfirst(l))), + (Node *) nth(li, ol), + expr); li++; } } @@ -986,30 +996,30 @@ modifyAggrefDropQual(Node **nodePtr, Node *orignode, Expr *expr) case T_SubLink: { - SubLink *sub = (SubLink *)node; - SubLink *osub = (SubLink *)orignode; + SubLink *sub = (SubLink *) node; + SubLink *osub = (SubLink *) orignode; modifyAggrefDropQual( - (Node **)(&(sub->subselect)), - (Node *)(osub->subselect), - expr); + (Node **) (&(sub->subselect)), + (Node *) (osub->subselect), + expr); } break; case T_Query: { - Query *qry = (Query *)node; - Query *oqry = (Query *)orignode; + Query *qry = (Query *) node; + Query *oqry = (Query *) orignode; modifyAggrefDropQual( - (Node **)(&(qry->qual)), - (Node *)(oqry->qual), - expr); + (Node **) (&(qry->qual)), + (Node *) (oqry->qual), + expr); modifyAggrefDropQual( - (Node **)(&(qry->havingQual)), - (Node *)(oqry->havingQual), - expr); + (Node **) (&(qry->havingQual)), + (Node *) (oqry->havingQual), + expr); } break; @@ -1031,15 +1041,15 @@ modifyAggrefDropQual(Node **nodePtr, Node *orignode, Expr *expr) static SubLink * modifyAggrefMakeSublink(Expr *origexp, Query *parsetree) { - SubLink *sublink; - Query *subquery; - Node *subqual; - RangeTblEntry *rte; - Aggref *aggref; - Var *target; - TargetEntry *tle; - Resdom *resdom; - Expr *exp = copyObject(origexp); + SubLink *sublink; + Query *subquery; + Node *subqual; + RangeTblEntry *rte; + Aggref *aggref; + Var *target; + TargetEntry *tle; + Resdom *resdom; + Expr *exp = copyObject(origexp); if (nodeTag(nth(0, exp->args)) == T_Aggref) { @@ -1049,66 +1059,66 @@ modifyAggrefMakeSublink(Expr *origexp, Query *parsetree) elog(ERROR, "rewrite: aggregate column of view must be at rigth side in qual"); } - aggref = (Aggref *)nth(1, exp->args); - target = (Var *)(aggref->target); - rte = (RangeTblEntry *)nth(target->varno - 1, parsetree->rtable); - tle = makeNode(TargetEntry); - resdom = makeNode(Resdom); + aggref = (Aggref *) nth(1, exp->args); + target = (Var *) (aggref->target); + rte = (RangeTblEntry *) nth(target->varno - 1, parsetree->rtable); + tle = makeNode(TargetEntry); + resdom = makeNode(Resdom); aggref->usenulls = TRUE; - resdom->resno = 1; - resdom->restype = ((Oper *)(exp->oper))->opresulttype; + resdom->resno = 1; + resdom->restype = ((Oper *) (exp->oper))->opresulttype; resdom->restypmod = -1; resdom->resname = pstrdup("<noname>"); - resdom->reskey = 0; + resdom->reskey = 0; resdom->reskeyop = 0; - resdom->resjunk = false; + resdom->resjunk = false; - tle->resdom = resdom; - tle->expr = (Node *)aggref; + tle->resdom = resdom; + tle->expr = (Node *) aggref; subqual = copyObject(parsetree->qual); - modifyAggrefDropQual((Node **)&subqual, (Node *)parsetree->qual, origexp); + modifyAggrefDropQual((Node **) &subqual, (Node *) parsetree->qual, origexp); sublink = makeNode(SubLink); - sublink->subLinkType = EXPR_SUBLINK; - sublink->useor = FALSE; - sublink->lefthand = lappend(NIL, copyObject(lfirst(exp->args))); - sublink->oper = lappend(NIL, copyObject(exp)); - sublink->subselect = NULL; - - subquery = makeNode(Query); - sublink->subselect = (Node *)subquery; - - subquery->commandType = CMD_SELECT; - subquery->utilityStmt = NULL; - subquery->resultRelation = 0; - subquery->into = NULL; - subquery->isPortal = FALSE; - subquery->isBinary = FALSE; - subquery->isTemp = FALSE; - subquery->unionall = FALSE; - subquery->uniqueFlag = NULL; - subquery->sortClause = NULL; - subquery->rtable = lappend(NIL, rte); - subquery->targetList = lappend(NIL, tle); - subquery->qual = subqual; - subquery->groupClause = NIL; - subquery->havingQual = NULL; - subquery->hasAggs = TRUE; - subquery->hasSubLinks = FALSE; - subquery->unionClause = NULL; - - - modifyAggrefUplevel((Node *)sublink); - - modifyAggrefChangeVarnodes((Node **)&(sublink->lefthand), target->varno, - 1, target->varlevelsup); - modifyAggrefChangeVarnodes((Node **)&(sublink->oper), target->varno, - 1, target->varlevelsup); - modifyAggrefChangeVarnodes((Node **)&(sublink->subselect), target->varno, - 1, target->varlevelsup); + sublink->subLinkType = EXPR_SUBLINK; + sublink->useor = FALSE; + sublink->lefthand = lappend(NIL, copyObject(lfirst(exp->args))); + sublink->oper = lappend(NIL, copyObject(exp)); + sublink->subselect = NULL; + + subquery = makeNode(Query); + sublink->subselect = (Node *) subquery; + + subquery->commandType = CMD_SELECT; + subquery->utilityStmt = NULL; + subquery->resultRelation = 0; + subquery->into = NULL; + subquery->isPortal = FALSE; + subquery->isBinary = FALSE; + subquery->isTemp = FALSE; + subquery->unionall = FALSE; + subquery->uniqueFlag = NULL; + subquery->sortClause = NULL; + subquery->rtable = lappend(NIL, rte); + subquery->targetList = lappend(NIL, tle); + subquery->qual = subqual; + subquery->groupClause = NIL; + subquery->havingQual = NULL; + subquery->hasAggs = TRUE; + subquery->hasSubLinks = FALSE; + subquery->unionClause = NULL; + + + modifyAggrefUplevel((Node *) sublink); + + modifyAggrefChangeVarnodes((Node **) &(sublink->lefthand), target->varno, + 1, target->varlevelsup); + modifyAggrefChangeVarnodes((Node **) &(sublink->oper), target->varno, + 1, target->varlevelsup); + modifyAggrefChangeVarnodes((Node **) &(sublink->subselect), target->varno, + 1, target->varlevelsup); return sublink; } @@ -1124,12 +1134,13 @@ modifyAggrefMakeSublink(Expr *origexp, Query *parsetree) static void modifyAggrefQual(Node **nodePtr, Query *parsetree) { - Node *node = *nodePtr; + Node *node = *nodePtr; if (node == NULL) return; - switch(nodeTag(node)) { + switch (nodeTag(node)) + { case T_Var: break; @@ -1144,122 +1155,127 @@ modifyAggrefQual(Node **nodePtr, Query *parsetree) case T_Expr: { - Expr *exp = (Expr *)node; - SubLink *sub; + Expr *exp = (Expr *) node; + SubLink *sub; - if (length(exp->args) != 2) { + if (length(exp->args) != 2) + { modifyAggrefQual( - (Node **)(&(exp->args)), - parsetree); + (Node **) (&(exp->args)), + parsetree); break; } if (nodeTag(nth(0, exp->args)) != T_Aggref && - nodeTag(nth(1, exp->args)) != T_Aggref) { + nodeTag(nth(1, exp->args)) != T_Aggref) + { modifyAggrefQual( - (Node **)(&(exp->args)), - parsetree); + (Node **) (&(exp->args)), + parsetree); break; } sub = modifyAggrefMakeSublink(exp, - parsetree); + parsetree); - *nodePtr = (Node *)sub; + *nodePtr = (Node *) sub; parsetree->hasSubLinks = TRUE; } 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... */ + + /* + * 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); + (Node **) (&(((CaseExpr *) node)->args)), + parsetree); modifyAggrefQual( - (Node **)(&(((CaseExpr *)node)->defresult)), - parsetree); + (Node **) (&(((CaseExpr *) node)->defresult)), + parsetree); } break; case T_CaseWhen: { modifyAggrefQual( - (Node **)(&(((CaseWhen *)node)->expr)), - parsetree); + (Node **) (&(((CaseWhen *) node)->expr)), + parsetree); modifyAggrefQual( - (Node **)(&(((CaseWhen *)node)->result)), - parsetree); + (Node **) (&(((CaseWhen *) node)->result)), + parsetree); } break; case T_Iter: { - Iter *iter = (Iter *)node; + Iter *iter = (Iter *) node; modifyAggrefQual( - (Node **)(&(iter->iterexpr)), - parsetree); + (Node **) (&(iter->iterexpr)), + parsetree); } break; case T_ArrayRef: { - ArrayRef *ref = (ArrayRef *)node; + ArrayRef *ref = (ArrayRef *) node; modifyAggrefQual( - (Node **)(&(ref->refupperindexpr)), - parsetree); + (Node **) (&(ref->refupperindexpr)), + parsetree); modifyAggrefQual( - (Node **)(&(ref->reflowerindexpr)), - parsetree); + (Node **) (&(ref->reflowerindexpr)), + parsetree); modifyAggrefQual( - (Node **)(&(ref->refexpr)), - parsetree); + (Node **) (&(ref->refexpr)), + parsetree); modifyAggrefQual( - (Node **)(&(ref->refassgnexpr)), - parsetree); + (Node **) (&(ref->refassgnexpr)), + parsetree); } break; case T_List: { - List *l; + List *l; - foreach (l, (List *)node) + foreach(l, (List *) node) modifyAggrefQual( - (Node **)(&(lfirst(l))), - parsetree); + (Node **) (&(lfirst(l))), + parsetree); } break; case T_SubLink: { - SubLink *sub = (SubLink *)node; + SubLink *sub = (SubLink *) node; modifyAggrefQual( - (Node **)(&(sub->subselect)), - (Query *)(sub->subselect)); + (Node **) (&(sub->subselect)), + (Query *) (sub->subselect)); } break; case T_Query: { - Query *qry = (Query *)node; + Query *qry = (Query *) node; modifyAggrefQual( - (Node **)(&(qry->qual)), - parsetree); + (Node **) (&(qry->qual)), + parsetree); modifyAggrefQual( - (Node **)(&(qry->havingQual)), - parsetree); + (Node **) (&(qry->havingQual)), + parsetree); } break; @@ -1284,12 +1300,13 @@ checkQueryHasAggs(Node *node) if (node == NULL) return FALSE; - switch(nodeTag(node)) { + switch (nodeTag(node)) + { case T_TargetEntry: { - TargetEntry *tle = (TargetEntry *)node; + TargetEntry *tle = (TargetEntry *) node; - return checkQueryHasAggs((Node *)(tle->expr)); + return checkQueryHasAggs((Node *) (tle->expr)); } break; @@ -1298,36 +1315,36 @@ checkQueryHasAggs(Node *node) case T_Expr: { - Expr *exp = (Expr *)node; + Expr *exp = (Expr *) node; - return checkQueryHasAggs((Node *)(exp->args)); + return checkQueryHasAggs((Node *) (exp->args)); } break; case T_Iter: { - Iter *iter = (Iter *)node; + Iter *iter = (Iter *) node; - return checkQueryHasAggs((Node *)(iter->iterexpr)); + return checkQueryHasAggs((Node *) (iter->iterexpr)); } break; case T_ArrayRef: { - ArrayRef *ref = (ArrayRef *)node; + ArrayRef *ref = (ArrayRef *) node; - if (checkQueryHasAggs((Node *)(ref->refupperindexpr))) + if (checkQueryHasAggs((Node *) (ref->refupperindexpr))) return TRUE; - - if (checkQueryHasAggs((Node *)(ref->reflowerindexpr))) + + if (checkQueryHasAggs((Node *) (ref->reflowerindexpr))) return TRUE; - - if (checkQueryHasAggs((Node *)(ref->refexpr))) + + if (checkQueryHasAggs((Node *) (ref->refexpr))) return TRUE; - - if (checkQueryHasAggs((Node *)(ref->refassgnexpr))) + + if (checkQueryHasAggs((Node *) (ref->refassgnexpr))) return TRUE; - + return FALSE; } break; @@ -1343,10 +1360,11 @@ checkQueryHasAggs(Node *node) case T_List: { - List *l; + List *l; - foreach (l, (List *)node) { - if (checkQueryHasAggs((Node *)lfirst(l))) + foreach(l, (List *) node) + { + if (checkQueryHasAggs((Node *) lfirst(l))) return TRUE; } return FALSE; @@ -1355,12 +1373,12 @@ checkQueryHasAggs(Node *node) case T_CaseExpr: { - CaseExpr *exp = (CaseExpr *)node; + CaseExpr *exp = (CaseExpr *) node; - if (checkQueryHasAggs((Node *)(exp->args))) + if (checkQueryHasAggs((Node *) (exp->args))) return TRUE; - if (checkQueryHasAggs((Node *)(exp->defresult))) + if (checkQueryHasAggs((Node *) (exp->defresult))) return TRUE; return FALSE; @@ -1369,12 +1387,12 @@ checkQueryHasAggs(Node *node) case T_CaseWhen: { - CaseWhen *when = (CaseWhen *)node; + CaseWhen *when = (CaseWhen *) node; - if (checkQueryHasAggs((Node *)(when->expr))) + if (checkQueryHasAggs((Node *) (when->expr))) return TRUE; - if (checkQueryHasAggs((Node *)(when->result))) + if (checkQueryHasAggs((Node *) (when->result))) return TRUE; return FALSE; @@ -1404,12 +1422,13 @@ checkQueryHasSubLink(Node *node) if (node == NULL) return FALSE; - switch(nodeTag(node)) { + switch (nodeTag(node)) + { case T_TargetEntry: { - TargetEntry *tle = (TargetEntry *)node; + TargetEntry *tle = (TargetEntry *) node; - return checkQueryHasSubLink((Node *)(tle->expr)); + return checkQueryHasSubLink((Node *) (tle->expr)); } break; @@ -1418,36 +1437,36 @@ checkQueryHasSubLink(Node *node) case T_Expr: { - Expr *exp = (Expr *)node; + Expr *exp = (Expr *) node; - return checkQueryHasSubLink((Node *)(exp->args)); + return checkQueryHasSubLink((Node *) (exp->args)); } break; case T_Iter: { - Iter *iter = (Iter *)node; + Iter *iter = (Iter *) node; - return checkQueryHasSubLink((Node *)(iter->iterexpr)); + return checkQueryHasSubLink((Node *) (iter->iterexpr)); } break; case T_ArrayRef: { - ArrayRef *ref = (ArrayRef *)node; + ArrayRef *ref = (ArrayRef *) node; - if (checkQueryHasSubLink((Node *)(ref->refupperindexpr))) + if (checkQueryHasSubLink((Node *) (ref->refupperindexpr))) return TRUE; - - if (checkQueryHasSubLink((Node *)(ref->reflowerindexpr))) + + if (checkQueryHasSubLink((Node *) (ref->reflowerindexpr))) return TRUE; - - if (checkQueryHasSubLink((Node *)(ref->refexpr))) + + if (checkQueryHasSubLink((Node *) (ref->refexpr))) return TRUE; - - if (checkQueryHasSubLink((Node *)(ref->refassgnexpr))) + + if (checkQueryHasSubLink((Node *) (ref->refassgnexpr))) return TRUE; - + return FALSE; } break; @@ -1463,10 +1482,11 @@ checkQueryHasSubLink(Node *node) case T_List: { - List *l; + List *l; - foreach (l, (List *)node) { - if (checkQueryHasSubLink((Node *)lfirst(l))) + foreach(l, (List *) node) + { + if (checkQueryHasSubLink((Node *) lfirst(l))) return TRUE; } return FALSE; @@ -1475,12 +1495,12 @@ checkQueryHasSubLink(Node *node) case T_CaseExpr: { - CaseExpr *exp = (CaseExpr *)node; + CaseExpr *exp = (CaseExpr *) node; - if (checkQueryHasSubLink((Node *)(exp->args))) + if (checkQueryHasSubLink((Node *) (exp->args))) return TRUE; - if (checkQueryHasSubLink((Node *)(exp->defresult))) + if (checkQueryHasSubLink((Node *) (exp->defresult))) return TRUE; return FALSE; @@ -1489,12 +1509,12 @@ checkQueryHasSubLink(Node *node) case T_CaseWhen: { - CaseWhen *when = (CaseWhen *)node; + CaseWhen *when = (CaseWhen *) node; - if (checkQueryHasSubLink((Node *)(when->expr))) + if (checkQueryHasSubLink((Node *) (when->expr))) return TRUE; - if (checkQueryHasSubLink((Node *)(when->result))) + if (checkQueryHasSubLink((Node *) (when->result))) return TRUE; return FALSE; @@ -1548,30 +1568,31 @@ make_null(Oid type) } -static void +static void apply_RIR_adjust_sublevel(Node *node, int sublevels_up) { if (node == NULL) return; - switch(nodeTag(node)) { + switch (nodeTag(node)) + { case T_TargetEntry: { - TargetEntry *tle = (TargetEntry *)node; + TargetEntry *tle = (TargetEntry *) node; apply_RIR_adjust_sublevel( - (Node *)(tle->expr), - sublevels_up); + (Node *) (tle->expr), + sublevels_up); } break; case T_Aggref: { - Aggref *aggref = (Aggref *)node; + Aggref *aggref = (Aggref *) node; apply_RIR_adjust_sublevel( - (Node *)(aggref->target), - sublevels_up); + (Node *) (aggref->target), + sublevels_up); } break; @@ -1580,49 +1601,49 @@ apply_RIR_adjust_sublevel(Node *node, int sublevels_up) case T_Expr: { - Expr *exp = (Expr *)node; + Expr *exp = (Expr *) node; apply_RIR_adjust_sublevel( - (Node *)(exp->args), - sublevels_up); + (Node *) (exp->args), + sublevels_up); } break; case T_Iter: { - Iter *iter = (Iter *)node; + Iter *iter = (Iter *) node; apply_RIR_adjust_sublevel( - (Node *)(iter->iterexpr), - sublevels_up); + (Node *) (iter->iterexpr), + sublevels_up); } break; case T_ArrayRef: { - ArrayRef *ref = (ArrayRef *)node; + ArrayRef *ref = (ArrayRef *) node; apply_RIR_adjust_sublevel( - (Node *)(ref->refupperindexpr), - sublevels_up); + (Node *) (ref->refupperindexpr), + sublevels_up); apply_RIR_adjust_sublevel( - (Node *)(ref->reflowerindexpr), - sublevels_up); + (Node *) (ref->reflowerindexpr), + sublevels_up); apply_RIR_adjust_sublevel( - (Node *)(ref->refexpr), - sublevels_up); + (Node *) (ref->refexpr), + sublevels_up); apply_RIR_adjust_sublevel( - (Node *)(ref->refassgnexpr), - sublevels_up); + (Node *) (ref->refassgnexpr), + sublevels_up); } break; case T_Var: { - Var *var = (Var *)node; + Var *var = (Var *) node; var->varlevelsup = sublevels_up; } @@ -1636,41 +1657,42 @@ apply_RIR_adjust_sublevel(Node *node, int sublevels_up) case T_List: { - List *l; + List *l; - foreach (l, (List *)node) { + foreach(l, (List *) node) + { apply_RIR_adjust_sublevel( - (Node *)lfirst(l), - sublevels_up); + (Node *) lfirst(l), + sublevels_up); } } break; case T_CaseExpr: { - CaseExpr *exp = (CaseExpr *)node; + CaseExpr *exp = (CaseExpr *) node; apply_RIR_adjust_sublevel( - (Node *)(exp->args), - sublevels_up); + (Node *) (exp->args), + sublevels_up); apply_RIR_adjust_sublevel( - (Node *)(exp->defresult), - sublevels_up); + (Node *) (exp->defresult), + sublevels_up); } break; case T_CaseWhen: { - CaseWhen *exp = (CaseWhen *)node; + CaseWhen *exp = (CaseWhen *) node; apply_RIR_adjust_sublevel( - (Node *)(exp->expr), - sublevels_up); + (Node *) (exp->expr), + sublevels_up); apply_RIR_adjust_sublevel( - (Node *)(exp->result), - sublevels_up); + (Node *) (exp->result), + sublevels_up); } break; @@ -1687,37 +1709,38 @@ apply_RIR_adjust_sublevel(Node *node, int sublevels_up) static void apply_RIR_view(Node **nodePtr, int rt_index, RangeTblEntry *rte, List *tlist, int *modified, int sublevels_up) { - Node *node = *nodePtr; + Node *node = *nodePtr; if (node == NULL) return; - switch(nodeTag(node)) { + switch (nodeTag(node)) + { case T_TargetEntry: { - TargetEntry *tle = (TargetEntry *)node; + TargetEntry *tle = (TargetEntry *) node; apply_RIR_view( - (Node **)(&(tle->expr)), - rt_index, - rte, - tlist, - modified, - sublevels_up); + (Node **) (&(tle->expr)), + rt_index, + rte, + tlist, + modified, + sublevels_up); } break; case T_Aggref: { - Aggref *aggref = (Aggref *)node; + Aggref *aggref = (Aggref *) node; apply_RIR_view( - (Node **)(&(aggref->target)), - rt_index, - rte, - tlist, - modified, - sublevels_up); + (Node **) (&(aggref->target)), + rt_index, + rte, + tlist, + modified, + sublevels_up); } break; @@ -1726,83 +1749,85 @@ apply_RIR_view(Node **nodePtr, int rt_index, RangeTblEntry *rte, List *tlist, in case T_Expr: { - Expr *exp = (Expr *)node; + Expr *exp = (Expr *) node; apply_RIR_view( - (Node **)(&(exp->args)), - rt_index, - rte, - tlist, - modified, - sublevels_up); + (Node **) (&(exp->args)), + rt_index, + rte, + tlist, + modified, + sublevels_up); } break; case T_Iter: { - Iter *iter = (Iter *)node; + Iter *iter = (Iter *) node; apply_RIR_view( - (Node **)(&(iter->iterexpr)), - rt_index, - rte, - tlist, - modified, - sublevels_up); + (Node **) (&(iter->iterexpr)), + rt_index, + rte, + tlist, + modified, + sublevels_up); } break; case T_ArrayRef: { - ArrayRef *ref = (ArrayRef *)node; + ArrayRef *ref = (ArrayRef *) node; apply_RIR_view( - (Node **)(&(ref->refupperindexpr)), - rt_index, - rte, - tlist, - modified, - sublevels_up); + (Node **) (&(ref->refupperindexpr)), + rt_index, + rte, + tlist, + modified, + sublevels_up); apply_RIR_view( - (Node **)(&(ref->reflowerindexpr)), - rt_index, - rte, - tlist, - modified, - sublevels_up); + (Node **) (&(ref->reflowerindexpr)), + rt_index, + rte, + tlist, + modified, + sublevels_up); apply_RIR_view( - (Node **)(&(ref->refexpr)), - rt_index, - rte, - tlist, - modified, - sublevels_up); + (Node **) (&(ref->refexpr)), + rt_index, + rte, + tlist, + modified, + sublevels_up); apply_RIR_view( - (Node **)(&(ref->refassgnexpr)), - rt_index, - rte, - tlist, - modified, - sublevels_up); + (Node **) (&(ref->refassgnexpr)), + rt_index, + rte, + tlist, + modified, + sublevels_up); } break; case T_Var: { - Var *var = (Var *)node; + Var *var = (Var *) node; if (var->varlevelsup == sublevels_up && - var->varno == rt_index) { - Node *exp; + 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)); + tlist, + get_attname(rte->relid, + var->varattno)); - if (exp == NULL) { + if (exp == NULL) + { *nodePtr = make_null(var->vartype); return; } @@ -1824,122 +1849,123 @@ apply_RIR_view(Node **nodePtr, int rt_index, RangeTblEntry *rte, List *tlist, in case T_List: { - List *l; + List *l; - foreach (l, (List *)node) + foreach(l, (List *) node) apply_RIR_view( - (Node **)(&(lfirst(l))), - rt_index, - rte, - tlist, - modified, - sublevels_up); + (Node **) (&(lfirst(l))), + rt_index, + rte, + tlist, + modified, + sublevels_up); } break; case T_SubLink: { - SubLink *sub = (SubLink *)node; - List *tmp_lefthand, *tmp_oper; + SubLink *sub = (SubLink *) node; + List *tmp_lefthand, + *tmp_oper; apply_RIR_view( - (Node **)(&(sub->lefthand)), - rt_index, - rte, - tlist, - modified, - sublevels_up); + (Node **) (&(sub->lefthand)), + rt_index, + rte, + tlist, + modified, + sublevels_up); apply_RIR_view( - (Node **)(&(sub->subselect)), - rt_index, - rte, - tlist, - modified, - sublevels_up + 1); + (Node **) (&(sub->subselect)), + rt_index, + rte, + tlist, + modified, + sublevels_up + 1); /***S*I***/ - tmp_lefthand = sub->lefthand; + tmp_lefthand = sub->lefthand; foreach(tmp_oper, sub->oper) - { - lfirst(((Expr *) lfirst(tmp_oper))->args) = - lfirst(tmp_lefthand); - tmp_lefthand = lnext(tmp_lefthand); - } + { + lfirst(((Expr *) lfirst(tmp_oper))->args) = + lfirst(tmp_lefthand); + tmp_lefthand = lnext(tmp_lefthand); + } } break; case T_Query: { - Query *qry = (Query *)node; + Query *qry = (Query *) node; apply_RIR_view( - (Node **)(&(qry->targetList)), - rt_index, - rte, - tlist, - modified, - sublevels_up); + (Node **) (&(qry->targetList)), + rt_index, + rte, + tlist, + modified, + sublevels_up); apply_RIR_view( - (Node **)(&(qry->qual)), - rt_index, - rte, - tlist, - modified, - sublevels_up); + (Node **) (&(qry->qual)), + rt_index, + rte, + tlist, + modified, + sublevels_up); apply_RIR_view( - (Node **)(&(qry->havingQual)), - rt_index, - rte, - tlist, - modified, - sublevels_up); + (Node **) (&(qry->havingQual)), + rt_index, + rte, + tlist, + modified, + sublevels_up); } break; case T_CaseExpr: { - CaseExpr *exp = (CaseExpr *)node; + CaseExpr *exp = (CaseExpr *) node; apply_RIR_view( - (Node **)(&(exp->args)), - rt_index, - rte, - tlist, - modified, - sublevels_up); + (Node **) (&(exp->args)), + rt_index, + rte, + tlist, + modified, + sublevels_up); apply_RIR_view( - (Node **)(&(exp->defresult)), - rt_index, - rte, - tlist, - modified, - sublevels_up); + (Node **) (&(exp->defresult)), + rt_index, + rte, + tlist, + modified, + sublevels_up); } break; case T_CaseWhen: { - CaseWhen *exp = (CaseWhen *)node; + CaseWhen *exp = (CaseWhen *) node; apply_RIR_view( - (Node **)(&(exp->expr)), - rt_index, - rte, - tlist, - modified, - sublevels_up); + (Node **) (&(exp->expr)), + rt_index, + rte, + tlist, + modified, + sublevels_up); apply_RIR_view( - (Node **)(&(exp->result)), - rt_index, - rte, - tlist, - modified, - sublevels_up); + (Node **) (&(exp->result)), + rt_index, + rte, + tlist, + modified, + sublevels_up); } break; @@ -1950,7 +1976,7 @@ apply_RIR_view(Node **nodePtr, int rt_index, RangeTblEntry *rte, List *tlist, in } } -extern void CheckSelectForUpdate(Query *rule_action); /* in analyze.c */ +extern void CheckSelectForUpdate(Query *rule_action); /* in analyze.c */ static void ApplyRetrieveRule(Query *parsetree, @@ -2000,32 +2026,34 @@ ApplyRetrieveRule(Query *parsetree, parsetree->rtable = rtable; /* FOR UPDATE of view... */ - foreach (l, parsetree->rowMark) + foreach(l, parsetree->rowMark) { - if (((RowMark*)lfirst(l))->rti == rt_index) + if (((RowMark *) lfirst(l))->rti == rt_index) break; } - if (l != NULL) /* oh, hell -:) */ + if (l != NULL) /* oh, hell -:) */ { - RowMark *newrm; + RowMark *newrm; Index rti = 1; List *l2; CheckSelectForUpdate(rule_action); - /* - * We believe that rt_index is VIEW - nothing should be - * marked for VIEW, but ACL check must be done. - * As for real tables of VIEW - their rows must be marked, but - * we have to skip ACL check for them. + + /* + * We believe that rt_index is VIEW - nothing should be marked for + * VIEW, but ACL check must be done. As for real tables of VIEW - + * their rows must be marked, but we have to skip ACL check for + * them. */ - ((RowMark*)lfirst(l))->info &= ~ROW_MARK_FOR_UPDATE; - foreach (l2, rule_action->rtable) + ((RowMark *) lfirst(l))->info &= ~ROW_MARK_FOR_UPDATE; + foreach(l2, rule_action->rtable) { + /* - * RTable of VIEW has two entries of VIEW itself - - * we use relid to skip them. + * RTable of VIEW has two entries of VIEW itself - we use + * relid to skip them. */ - if (relation->rd_id != ((RangeTblEntry*)lfirst(l2))->relid) + if (relation->rd_id != ((RangeTblEntry *) lfirst(l2))->relid) { newrm = makeNode(RowMark); newrm->rti = rti + rt_length; @@ -2038,36 +2066,37 @@ ApplyRetrieveRule(Query *parsetree, } rule_action->rtable = rtable; - OffsetVarNodes((Node *) rule_qual, rt_length, 0); + OffsetVarNodes((Node *) rule_qual, rt_length, 0); OffsetVarNodes((Node *) rule_action, rt_length, 0); - ChangeVarNodes((Node *) rule_qual, + ChangeVarNodes((Node *) rule_qual, PRS2_CURRENT_VARNO + rt_length, rt_index, 0); ChangeVarNodes((Node *) rule_action, PRS2_CURRENT_VARNO + rt_length, rt_index, 0); if (relation_level) { - apply_RIR_view((Node **) &parsetree, rt_index, - (RangeTblEntry *)nth(rt_index - 1, rtable), - rule_action->targetList, modified, 0); - apply_RIR_view((Node **) &rule_action, rt_index, - (RangeTblEntry *)nth(rt_index - 1, rtable), - rule_action->targetList, modified, 0); + apply_RIR_view((Node **) &parsetree, rt_index, + (RangeTblEntry *) nth(rt_index - 1, rtable), + rule_action->targetList, modified, 0); + apply_RIR_view((Node **) &rule_action, rt_index, + (RangeTblEntry *) nth(rt_index - 1, rtable), + rule_action->targetList, modified, 0); } else { - HandleRIRAttributeRule(parsetree, rtable, rule_action->targetList, - rt_index, rule->attrno, modified, &badsql); + HandleRIRAttributeRule(parsetree, rtable, rule_action->targetList, + rt_index, rule->attrno, modified, &badsql); + } + if (*modified && !badsql) + { + AddQual(parsetree, rule_action->qual); + AddGroupClause(parsetree, rule_action->groupClause, + rule_action->targetList); + AddHavingQual(parsetree, rule_action->havingQual); + parsetree->hasAggs = (rule_action->hasAggs || parsetree->hasAggs); + parsetree->hasSubLinks = (rule_action->hasSubLinks || parsetree->hasSubLinks); } - if (*modified && !badsql) { - AddQual(parsetree, rule_action->qual); - AddGroupClause(parsetree, rule_action->groupClause, - rule_action->targetList); - AddHavingQual(parsetree, rule_action->havingQual); - parsetree->hasAggs = (rule_action->hasAggs || parsetree->hasAggs); - parsetree->hasSubLinks = (rule_action->hasSubLinks || parsetree->hasSubLinks); - } } @@ -2077,22 +2106,23 @@ fireRIRonSubselect(Node *node) if (node == NULL) return; - switch(nodeTag(node)) { + switch (nodeTag(node)) + { case T_TargetEntry: { - TargetEntry *tle = (TargetEntry *)node; + TargetEntry *tle = (TargetEntry *) node; fireRIRonSubselect( - (Node *)(tle->expr)); + (Node *) (tle->expr)); } break; case T_Aggref: { - Aggref *aggref = (Aggref *)node; + Aggref *aggref = (Aggref *) node; fireRIRonSubselect( - (Node *)(aggref->target)); + (Node *) (aggref->target)); } break; @@ -2101,34 +2131,34 @@ fireRIRonSubselect(Node *node) case T_Expr: { - Expr *exp = (Expr *)node; + Expr *exp = (Expr *) node; fireRIRonSubselect( - (Node *)(exp->args)); + (Node *) (exp->args)); } break; case T_Iter: { - Iter *iter = (Iter *)node; + Iter *iter = (Iter *) node; fireRIRonSubselect( - (Node *)(iter->iterexpr)); + (Node *) (iter->iterexpr)); } break; case T_ArrayRef: { - ArrayRef *ref = (ArrayRef *)node; + ArrayRef *ref = (ArrayRef *) node; fireRIRonSubselect( - (Node *)(ref->refupperindexpr)); + (Node *) (ref->refupperindexpr)); fireRIRonSubselect( - (Node *)(ref->reflowerindexpr)); + (Node *) (ref->reflowerindexpr)); fireRIRonSubselect( - (Node *)(ref->refexpr)); + (Node *) (ref->refexpr)); fireRIRonSubselect( - (Node *)(ref->refassgnexpr)); + (Node *) (ref->refassgnexpr)); } break; @@ -2143,26 +2173,26 @@ fireRIRonSubselect(Node *node) case T_List: { - List *l; + List *l; - foreach (l, (List *)node) + foreach(l, (List *) node) fireRIRonSubselect( - (Node *)(lfirst(l))); + (Node *) (lfirst(l))); } break; case T_SubLink: { - SubLink *sub = (SubLink *)node; - Query *qry; + SubLink *sub = (SubLink *) node; + Query *qry; fireRIRonSubselect( - (Node *)(sub->lefthand)); + (Node *) (sub->lefthand)); - qry = fireRIRrules((Query *)(sub->subselect)); + qry = fireRIRrules((Query *) (sub->subselect)); fireRIRonSubselect( - (Node *)qry); + (Node *) qry); sub->subselect = (Node *) qry; } @@ -2170,40 +2200,40 @@ fireRIRonSubselect(Node *node) case T_CaseExpr: { - CaseExpr *exp = (CaseExpr *)node; + CaseExpr *exp = (CaseExpr *) node; fireRIRonSubselect( - (Node *)(exp->args)); + (Node *) (exp->args)); fireRIRonSubselect( - (Node *)(exp->defresult)); + (Node *) (exp->defresult)); } break; case T_CaseWhen: { - CaseWhen *exp = (CaseWhen *)node; + CaseWhen *exp = (CaseWhen *) node; fireRIRonSubselect( - (Node *)(exp->expr)); + (Node *) (exp->expr)); fireRIRonSubselect( - (Node *)(exp->result)); + (Node *) (exp->result)); } break; case T_Query: { - Query *qry = (Query *)node; + Query *qry = (Query *) node; fireRIRonSubselect( - (Node *)(qry->targetList)); + (Node *) (qry->targetList)); fireRIRonSubselect( - (Node *)(qry->qual)); + (Node *) (qry->qual)); fireRIRonSubselect( - (Node *)(qry->havingQual)); + (Node *) (qry->havingQual)); } break; @@ -2224,30 +2254,32 @@ fireRIRonSubselect(Node *node) static Query * fireRIRrules(Query *parsetree) { - int rt_index; - RangeTblEntry *rte; + int rt_index; + RangeTblEntry *rte; Relation rel; - List *locks; - RuleLock *rules; - RewriteRule *rule; - RewriteRule RIRonly; - int modified; - int i; - List *l; + List *locks; + RuleLock *rules; + RewriteRule *rule; + RewriteRule RIRonly; + int modified; + int i; + List *l; rt_index = 0; - while(rt_index < length(parsetree->rtable)) { + while (rt_index < length(parsetree->rtable)) + { ++rt_index; rte = nth(rt_index - 1, parsetree->rtable); - if (!rangeTableEntry_used((Node *)parsetree, rt_index, 0)) + if (!rangeTableEntry_used((Node *) parsetree, rt_index, 0)) { + /* * Unused range table entries must not be marked as coming - * from a clause. Otherwise the planner will generate - * joins over relations that in fact shouldn't be scanned - * at all and the result will contain duplicates + * from a clause. Otherwise the planner will generate joins + * over relations that in fact shouldn't be scanned at all and + * the result will contain duplicates * * Jan * @@ -2255,9 +2287,10 @@ fireRIRrules(Query *parsetree) rte->inFromCl = FALSE; continue; } - + rel = heap_openr(rte->relname); - if (rel->rd_rules == NULL) { + if (rel->rd_rules == NULL) + { heap_close(rel); continue; } @@ -2268,15 +2301,16 @@ fireRIRrules(Query *parsetree) /* * Collect the RIR rules that we must apply */ - for (i = 0; i < rules->numLocks; i++) { + for (i = 0; i < rules->numLocks; i++) + { rule = rules->rules[i]; if (rule->event != CMD_SELECT) continue; - + if (rule->attrno > 0 && - !attribute_used((Node *)parsetree, - rt_index, - rule->attrno, 0)) + !attribute_used((Node *) parsetree, + rt_index, + rule->attrno, 0)) continue; locks = lappend(locks, rule); @@ -2290,20 +2324,21 @@ fireRIRrules(Query *parsetree) /* * Now apply them */ - foreach (l, locks) { + foreach(l, locks) + { rule = lfirst(l); - RIRonly.event = rule->event; - RIRonly.attrno = rule->attrno; - RIRonly.qual = rule->qual; - RIRonly.actions = rule->actions; + RIRonly.event = rule->event; + RIRonly.attrno = rule->attrno; + RIRonly.qual = rule->qual; + RIRonly.actions = rule->actions; ApplyRetrieveRule(parsetree, - &RIRonly, - rt_index, - RIRonly.attrno == -1, - rel, - &modified); + &RIRonly, + rt_index, + RIRonly.attrno == -1, + rel, + &modified); } heap_close(rel); @@ -2408,9 +2443,7 @@ fireRules(Query *parsetree, /* choose rule to fire from list of rules */ if (locks == NIL) - { return NIL; - } locks = orderRules(locks); /* real instead rules last */ foreach(i, locks) @@ -2529,9 +2562,7 @@ fireRules(Query *parsetree, rule_action->hasSubLinks = TRUE; } if (!parsetree->hasSubLinks && rule_action->hasSubLinks) - { parsetree->hasSubLinks = TRUE; - } /*-------------------------------------------------- * Step 1: @@ -2581,10 +2612,11 @@ fireRules(Query *parsetree, *-------------------------------------------------- */ info->rule_action->rtable = info->rt; + /* - ProcessRetrieveQuery(info->rule_action, info->rt, - &orig_instead_flag, TRUE); - */ + * ProcessRetrieveQuery(info->rule_action, info->rt, + * &orig_instead_flag, TRUE); + */ /*-------------------------------------------------- * Step 4 @@ -2614,19 +2646,19 @@ static List * RewriteQuery(Query *parsetree, bool *instead_flag, List **qual_products) { CmdType event; - List *product_queries = NIL; - int result_relation = 0; - RangeTblEntry *rt_entry; + List *product_queries = NIL; + int result_relation = 0; + RangeTblEntry *rt_entry; Relation rt_entry_relation = NULL; - RuleLock *rt_entry_locks = NULL; + RuleLock *rt_entry_locks = NULL; Assert(parsetree != NULL); event = parsetree->commandType; /* - * SELECT rules are handled later when we have all the - * queries that should get executed + * SELECT rules are handled later when we have all the queries that + * should get executed */ if (event == CMD_SELECT) return NIL; @@ -2646,8 +2678,7 @@ RewriteQuery(Query *parsetree, bool *instead_flag, List **qual_products) result_relation = parsetree->resultRelation; /* - * the statement is an update, insert or delete - fire rules - * on it. + * the statement is an update, insert or delete - fire rules on it. */ rt_entry = rt_fetch(result_relation, parsetree->rtable); rt_entry_relation = heap_openr(rt_entry->relname); @@ -2659,11 +2690,11 @@ RewriteQuery(Query *parsetree, bool *instead_flag, List **qual_products) List *locks = matchLocks(event, rt_entry_locks, result_relation, parsetree); product_queries = fireRules(parsetree, - result_relation, - event, - instead_flag, - locks, - qual_products); + result_relation, + event, + instead_flag, + locks, + qual_products); } return product_queries; @@ -2805,16 +2836,16 @@ RewritePreprocessQuery(Query *parsetree) static List * BasicQueryRewrite(Query *parsetree) { - List *querylist; - List *results = NIL; - List *l; - Query *query; + List *querylist; + List *results = NIL; + List *l; + Query *query; /* * Step 1 * - * There still seems something broken with the resdom numbers - * so we reassign them first. + * There still seems something broken with the resdom numbers so we + * reassign them first. */ RewritePreprocessQuery(parsetree); @@ -2830,19 +2861,21 @@ BasicQueryRewrite(Query *parsetree) * * Apply all the RIR rules on each query */ - foreach (l, querylist) { - query = fireRIRrules((Query *)lfirst(l)); + foreach(l, querylist) + { + query = fireRIRrules((Query *) lfirst(l)); + /* - * If the query was marked having aggregates, check if - * this is still true after rewriting. This check must get - * expanded when someday aggregates can appear somewhere - * else than in the targetlist or the having qual. + * If the query was marked having aggregates, check if this is + * still true after rewriting. This check must get expanded when + * someday aggregates can appear somewhere else than in the + * targetlist or the having qual. */ if (query->hasAggs) - query->hasAggs = checkQueryHasAggs((Node *)(query->targetList)) - | checkQueryHasAggs((Node *)(query->havingQual)); - query->hasSubLinks = checkQueryHasSubLink((Node *)(query->qual)) - | checkQueryHasSubLink((Node *)(query->havingQual)); + query->hasAggs = checkQueryHasAggs((Node *) (query->targetList)) + | checkQueryHasAggs((Node *) (query->havingQual)); + query->hasSubLinks = checkQueryHasSubLink((Node *) (query->qual)) + | checkQueryHasSubLink((Node *) (query->havingQual)); results = lappend(results, query); } return results; @@ -2866,8 +2899,11 @@ QueryRewrite(Query *parsetree) *rewritten_item; /***S*I***/ - /* Rewrite Union, Intersect and Except Queries - * to normal Union Queries using IN and NOT IN subselects */ + + /* + * Rewrite Union, Intersect and Except Queries to normal Union Queries + * using IN and NOT IN subselects + */ if (parsetree->intersectClause) parsetree = Except_Intersect_Rewrite(parsetree); @@ -2877,16 +2913,16 @@ QueryRewrite(Query *parsetree) /* * Rewrite the UNIONS. */ - foreach (rewritten_item, rewritten) + foreach(rewritten_item, rewritten) { Query *qry = (Query *) lfirst(rewritten_item); List *union_result = NIL; List *union_item; - foreach (union_item, qry->unionClause) + foreach(union_item, qry->unionClause) { union_result = nconc(union_result, - BasicQueryRewrite((Query *) lfirst(union_item))); + BasicQueryRewrite((Query *) lfirst(union_item))); } qry->unionClause = union_result; } @@ -2898,79 +2934,82 @@ QueryRewrite(Query *parsetree) /* This function takes two targetlists as arguments and checks if the * targetlists are compatible (i.e. both select for the same number of * attributes and the types are compatible */ -void check_targetlists_are_compatible(List *prev_target, List *current_target) +void +check_targetlists_are_compatible(List *prev_target, List *current_target) { - List *tl, *next_target; - int prev_len = 0, next_len = 0; + List *tl, + *next_target; + int prev_len = 0, + next_len = 0; - foreach(tl, prev_target) - if (!((TargetEntry *) lfirst(tl))->resdom->resjunk) + foreach(tl, prev_target) + if (!((TargetEntry *) lfirst(tl))->resdom->resjunk) prev_len++; - foreach(next_target, current_target) - if (!((TargetEntry *) lfirst(next_target))->resdom->resjunk) + foreach(next_target, current_target) + if (!((TargetEntry *) lfirst(next_target))->resdom->resjunk) next_len++; - - if (prev_len != next_len) - elog(ERROR,"Each UNION | EXCEPT | INTERSECT query must have the same number of columns."); - - foreach(next_target, current_target) - { - Oid itype; - Oid otype; - - otype = ((TargetEntry *) lfirst(prev_target))->resdom->restype; - itype = ((TargetEntry *) lfirst(next_target))->resdom->restype; - - /* one or both is a NULL column? then don't convert... */ - if (otype == InvalidOid) + + if (prev_len != next_len) + elog(ERROR, "Each UNION | EXCEPT | INTERSECT query must have the same number of columns."); + + foreach(next_target, current_target) { - /* propagate a known type forward, if available */ - if (itype != InvalidOid) - ((TargetEntry *) lfirst(prev_target))->resdom->restype = itype; + Oid itype; + Oid otype; + + otype = ((TargetEntry *) lfirst(prev_target))->resdom->restype; + itype = ((TargetEntry *) lfirst(next_target))->resdom->restype; + + /* one or both is a NULL column? then don't convert... */ + if (otype == InvalidOid) + { + /* propagate a known type forward, if available */ + if (itype != InvalidOid) + ((TargetEntry *) lfirst(prev_target))->resdom->restype = itype; #ifdef NOT_USED - else - { - ((TargetEntry *) lfirst(prev_target))->resdom->restype = UNKNOWNOID; - ((TargetEntry *) lfirst(next_target))->resdom->restype = UNKNOWNOID; - } + else + { + ((TargetEntry *) lfirst(prev_target))->resdom->restype = UNKNOWNOID; + ((TargetEntry *) lfirst(next_target))->resdom->restype = UNKNOWNOID; + } #endif + } + else if (itype == InvalidOid) + { + } + /* they don't match in type? then convert... */ + else if (itype != otype) + { + Node *expr; + + expr = ((TargetEntry *) lfirst(next_target))->expr; + expr = CoerceTargetExpr(NULL, expr, itype, otype); + if (expr == NULL) + { + elog(ERROR, "Unable to transform %s to %s" + "\n\tEach UNION | EXCEPT | INTERSECT clause must have compatible target types", + typeidTypeName(itype), + typeidTypeName(otype)); + } + ((TargetEntry *) lfirst(next_target))->expr = expr; + ((TargetEntry *) lfirst(next_target))->resdom->restype = otype; + } + + /* both are UNKNOWN? then evaluate as text... */ + else if (itype == UNKNOWNOID) + { + ((TargetEntry *) lfirst(next_target))->resdom->restype = TEXTOID; + ((TargetEntry *) lfirst(prev_target))->resdom->restype = TEXTOID; + } + prev_target = lnext(prev_target); } - else if (itype == InvalidOid) - { - } - /* they don't match in type? then convert... */ - else if (itype != otype) - { - Node *expr; - - expr = ((TargetEntry *) lfirst(next_target))->expr; - expr = CoerceTargetExpr(NULL, expr, itype, otype); - if (expr == NULL) - { - elog(ERROR, "Unable to transform %s to %s" - "\n\tEach UNION | EXCEPT | INTERSECT clause must have compatible target types", - typeidTypeName(itype), - typeidTypeName(otype)); - } - ((TargetEntry *) lfirst(next_target))->expr = expr; - ((TargetEntry *) lfirst(next_target))->resdom->restype = otype; - } - - /* both are UNKNOWN? then evaluate as text... */ - else if (itype == UNKNOWNOID) - { - ((TargetEntry *) lfirst(next_target))->resdom->restype = TEXTOID; - ((TargetEntry *) lfirst(prev_target))->resdom->restype = TEXTOID; - } - prev_target = lnext(prev_target); - } } /***S*I***/ /* Rewrites UNION INTERSECT and EXCEPT queries to semantiacally equivalent - * queries that use IN and NOT IN subselects. - * + * queries that use IN and NOT IN subselects. + * * The operator tree is attached to 'intersectClause' (see rule * 'SelectStmt' in gram.y) of the 'parsetree' given as an * argument. First we remember some clauses (the sortClause, the @@ -2983,233 +3022,291 @@ void check_targetlists_are_compatible(List *prev_target, List *current_target) * union list and for every OR we create an IN subselect. (NOT IN * subselects are created for OR NOT nodes). The first entry of the * union list is handed back but before that the remembered clauses - * (sortClause etc) are attached to the new top Node (Note that the + * (sortClause etc) are attached to the new top Node (Note that the * new top Node can differ from the parsetree given as argument because of * the translation to DNF. That's why we have to remember the sortClause or * unique flag!) */ Query * -Except_Intersect_Rewrite (Query *parsetree) +Except_Intersect_Rewrite(Query *parsetree) { - - SubLink *n; - Query *result, *intersect_node; - List *elist, *intersect_list = NIL, *intersect, *intersectClause; - List *union_list = NIL, *sortClause; - List *left_expr, *right_expr, *resnames = NIL; - char *op, *uniqueFlag, *into; - bool isBinary, isPortal, isTemp; - CmdType commandType = CMD_SELECT; - List *rtable_insert = NIL; - - List *prev_target = NIL; - - /* Remember the Resnames of the given parsetree's targetlist - * (these are the resnames of the first Select Statement of - * the query formulated by the user and he wants the columns - * named by these strings. The transformation to DNF can - * cause another Select Statment to be the top one which - * uses other names for its columns. Therefore we remeber - * the original names and attach them to the targetlist - * of the new topmost Node at the end of this function */ - foreach(elist, parsetree->targetList) - { - TargetEntry *tent = (TargetEntry *)lfirst(elist); - - resnames = lappend(resnames, tent->resdom->resname); - } - - /* If the Statement is an INSERT INTO ... (SELECT...) statement - * using UNIONs, INTERSECTs or EXCEPTs and the transformation - * to DNF makes another Node to the top node we have to transform - * the new top node to an INSERT node and the original INSERT node - * to a SELECT node */ - if (parsetree->commandType == CMD_INSERT) - { - parsetree->commandType = CMD_SELECT; - commandType = CMD_INSERT; - parsetree->resultRelation = 0; - - /* The result relation ( = the one to insert into) has to be - * attached to the rtable list of the new top node */ - rtable_insert = nth(length(parsetree->rtable) - 1, parsetree->rtable); - } - - /* Save some items, to be able to attach them to the resulting top node - * at the end of the function */ - sortClause = parsetree->sortClause; - uniqueFlag = parsetree->uniqueFlag; - into = parsetree->into; - isBinary = parsetree->isBinary; - isPortal = parsetree->isPortal; - isTemp = parsetree->isTemp; - - /* The operator tree attached to parsetree->intersectClause is still 'raw' - * ( = the leaf nodes are still SelectStmt nodes instead of Query nodes) - * So step through the tree and transform the nodes using parse_analyze(). - * - * The parsetree (given as an argument to - * Except_Intersect_Rewrite()) has already been transformed and - * transforming it again would cause troubles. So we give the 'raw' - * version (of the cooked parsetree) to the function to - * prevent an additional transformation. Instead we hand back the - * 'cooked' version also given as an argument to - * intersect_tree_analyze() */ - intersectClause = - (List *)intersect_tree_analyze((Node *)parsetree->intersectClause, - (Node *)lfirst(parsetree->unionClause), - (Node *)parsetree); - - /* intersectClause is no longer needed so set it to NIL */ - parsetree->intersectClause = NIL; - /* unionClause will be needed later on but the list it delivered - * is no longer needed, so set it to NIL */ - parsetree->unionClause = NIL; - - /* Transform the operator tree to DNF (remember ANDs and ORs have been exchanged, - * that's why we get DNF by using cnfify) - * - * After the call, explicit ANDs are removed and all AND operands - * are simply items in the intersectClause list */ - intersectClause = cnfify((Expr *)intersectClause, true); - - /* For every entry of the intersectClause list we generate one entry in - * the union_list */ - foreach(intersect, intersectClause) - { - /* for every OR we create an IN subselect and for every OR NOT - * we create a NOT IN subselect, so first extract all the Select - * Query nodes from the tree (that contains only OR or OR NOTs - * any more because we did a transformation to DNF - * - * There must be at least one node that is not negated - * (i.e. just OR and not OR NOT) and this node will be the first - * in the list returned */ - intersect_list = NIL; - create_list((Node *)lfirst(intersect), &intersect_list); - - /* This one will become the Select Query node, all other - * nodes are transformed into subselects under this node! */ - intersect_node = (Query *)lfirst(intersect_list); - intersect_list = lnext(intersect_list); - - /* Check if all Select Statements use the same number of attributes and - * if all corresponding attributes are of the same type */ - if (prev_target) - check_targetlists_are_compatible(prev_target, intersect_node->targetList); - prev_target = intersect_node->targetList; - /* End of check for corresponding targetlists */ - - /* Transform all nodes remaining into subselects and add them to - * the qualifications of the Select Query node */ - while(intersect_list != NIL) { - - n = makeNode(SubLink); - - /* Here we got an OR so transform it to an IN subselect */ - if(IsA(lfirst(intersect_list), Query)) - { - /* Check if all Select Statements use the same number of attributes and - * if all corresponding attributes are of the same type */ - check_targetlists_are_compatible(prev_target, - ((Query *)lfirst(intersect_list))->targetList); - /* End of check for corresponding targetlists */ - - n->subselect = lfirst(intersect_list); - op = "="; - n->subLinkType = ANY_SUBLINK; - n->useor = false; - } - /* Here we got an OR NOT node so transform it to a NOT IN subselect */ - else - { - /* Check if all Select Statements use the same number of attributes and - * if all corresponding attributes are of the same type */ - check_targetlists_are_compatible(prev_target, - ((Query *)lfirst(((Expr *)lfirst(intersect_list))->args))->targetList); - /* End of check for corresponding targetlists */ - - n->subselect = (Node *)lfirst(((Expr *)lfirst(intersect_list))->args); - op = "<>"; - n->subLinkType = ALL_SUBLINK; - n->useor = true; - } - - /* Prepare the lefthand side of the Sublinks: All the entries of the - * targetlist must be (IN) or must not be (NOT IN) the subselect */ - foreach(elist, intersect_node->targetList) - { - Node *expr = lfirst(elist); - TargetEntry *tent = (TargetEntry *)expr; - - n->lefthand = lappend(n->lefthand, tent->expr); - } - - /* The first arguments of oper also have to be created for the - * sublink (they are the same as the lefthand side!) */ - left_expr = n->lefthand; - right_expr = ((Query *)(n->subselect))->targetList; - - foreach(elist, left_expr) - { - Node *lexpr = lfirst(elist); - Node *rexpr = lfirst(right_expr); - TargetEntry *tent = (TargetEntry *) rexpr; - Expr *op_expr; - - op_expr = make_op(op, lexpr, tent->expr); - - n->oper = lappend(n->oper, op_expr); - right_expr = lnext(right_expr); - } - - /* If the Select Query node has aggregates in use - * add all the subselects to the HAVING qual else to - * the WHERE qual */ - if(intersect_node->hasAggs == false) { - AddQual(intersect_node, (Node *)n); + + SubLink *n; + Query *result, + *intersect_node; + List *elist, + *intersect_list = NIL, + *intersect, + *intersectClause; + List *union_list = NIL, + *sortClause; + List *left_expr, + *right_expr, + *resnames = NIL; + char *op, + *uniqueFlag, + *into; + bool isBinary, + isPortal, + isTemp; + CmdType commandType = CMD_SELECT; + List *rtable_insert = NIL; + + List *prev_target = NIL; + + /* + * Remember the Resnames of the given parsetree's targetlist (these + * are the resnames of the first Select Statement of the query + * formulated by the user and he wants the columns named by these + * strings. The transformation to DNF can cause another Select + * Statment to be the top one which uses other names for its columns. + * Therefore we remeber the original names and attach them to the + * targetlist of the new topmost Node at the end of this function + */ + foreach(elist, parsetree->targetList) + { + TargetEntry *tent = (TargetEntry *) lfirst(elist); + + resnames = lappend(resnames, tent->resdom->resname); + } + + /* + * If the Statement is an INSERT INTO ... (SELECT...) statement using + * UNIONs, INTERSECTs or EXCEPTs and the transformation to DNF makes + * another Node to the top node we have to transform the new top node + * to an INSERT node and the original INSERT node to a SELECT node + */ + if (parsetree->commandType == CMD_INSERT) + { + parsetree->commandType = CMD_SELECT; + commandType = CMD_INSERT; + parsetree->resultRelation = 0; + + /* + * The result relation ( = the one to insert into) has to be + * attached to the rtable list of the new top node + */ + rtable_insert = nth(length(parsetree->rtable) - 1, parsetree->rtable); } - else { - AddHavingQual(intersect_node, (Node *)n); - } - - /* Now we got sublinks */ - intersect_node->hasSubLinks = true; - intersect_list = lnext(intersect_list); - } - intersect_node->intersectClause = NIL; - union_list = lappend(union_list, intersect_node); - } - - /* The first entry to union_list is our new top node */ - result = (Query *)lfirst(union_list); - /* attach the rest to unionClause */ - result->unionClause = lnext(union_list); - /* Attach all the items remembered in the beginning of the function */ - result->sortClause = sortClause; - result->uniqueFlag = uniqueFlag; - result->into = into; - result->isPortal = isPortal; - result->isBinary = isBinary; - result->isTemp = isTemp; - - /* The relation to insert into is attached to the range table - * of the new top node */ - if (commandType == CMD_INSERT) - { - result->rtable = lappend(result->rtable, rtable_insert); - result->resultRelation = length(result->rtable); - result->commandType = commandType; - } - /* The resnames of the originally first SelectStatement are - * attached to the new first SelectStatement */ - foreach(elist, result->targetList) - { - TargetEntry *tent = (TargetEntry *)lfirst(elist); - - tent->resdom->resname = lfirst(resnames); - resnames = lnext(resnames); - } - return result; + + /* + * Save some items, to be able to attach them to the resulting top + * node at the end of the function + */ + sortClause = parsetree->sortClause; + uniqueFlag = parsetree->uniqueFlag; + into = parsetree->into; + isBinary = parsetree->isBinary; + isPortal = parsetree->isPortal; + isTemp = parsetree->isTemp; + + /* + * The operator tree attached to parsetree->intersectClause is still + * 'raw' ( = the leaf nodes are still SelectStmt nodes instead of + * Query nodes) So step through the tree and transform the nodes using + * parse_analyze(). + * + * The parsetree (given as an argument to Except_Intersect_Rewrite()) has + * already been transformed and transforming it again would cause + * troubles. So we give the 'raw' version (of the cooked parsetree) + * to the function to prevent an additional transformation. Instead we + * hand back the 'cooked' version also given as an argument to + * intersect_tree_analyze() + */ + intersectClause = + (List *) intersect_tree_analyze((Node *) parsetree->intersectClause, + (Node *) lfirst(parsetree->unionClause), + (Node *) parsetree); + + /* intersectClause is no longer needed so set it to NIL */ + parsetree->intersectClause = NIL; + + /* + * unionClause will be needed later on but the list it delivered is no + * longer needed, so set it to NIL + */ + parsetree->unionClause = NIL; + + /* + * Transform the operator tree to DNF (remember ANDs and ORs have been + * exchanged, that's why we get DNF by using cnfify) + * + * After the call, explicit ANDs are removed and all AND operands are + * simply items in the intersectClause list + */ + intersectClause = cnfify((Expr *) intersectClause, true); + + /* + * For every entry of the intersectClause list we generate one entry + * in the union_list + */ + foreach(intersect, intersectClause) + { + + /* + * for every OR we create an IN subselect and for every OR NOT we + * create a NOT IN subselect, so first extract all the Select + * Query nodes from the tree (that contains only OR or OR NOTs any + * more because we did a transformation to DNF + * + * There must be at least one node that is not negated (i.e. just OR + * and not OR NOT) and this node will be the first in the list + * returned + */ + intersect_list = NIL; + create_list((Node *) lfirst(intersect), &intersect_list); + + /* + * This one will become the Select Query node, all other nodes are + * transformed into subselects under this node! + */ + intersect_node = (Query *) lfirst(intersect_list); + intersect_list = lnext(intersect_list); + + /* + * Check if all Select Statements use the same number of + * attributes and if all corresponding attributes are of the same + * type + */ + if (prev_target) + check_targetlists_are_compatible(prev_target, intersect_node->targetList); + prev_target = intersect_node->targetList; + /* End of check for corresponding targetlists */ + + /* + * Transform all nodes remaining into subselects and add them to + * the qualifications of the Select Query node + */ + while (intersect_list != NIL) + { + + n = makeNode(SubLink); + + /* Here we got an OR so transform it to an IN subselect */ + if (IsA(lfirst(intersect_list), Query)) + { + + /* + * Check if all Select Statements use the same number of + * attributes and if all corresponding attributes are of + * the same type + */ + check_targetlists_are_compatible(prev_target, + ((Query *) lfirst(intersect_list))->targetList); + /* End of check for corresponding targetlists */ + + n->subselect = lfirst(intersect_list); + op = "="; + n->subLinkType = ANY_SUBLINK; + n->useor = false; + } + + /* + * Here we got an OR NOT node so transform it to a NOT IN + * subselect + */ + else + { + + /* + * Check if all Select Statements use the same number of + * attributes and if all corresponding attributes are of + * the same type + */ + check_targetlists_are_compatible(prev_target, + ((Query *) lfirst(((Expr *) lfirst(intersect_list))->args))->targetList); + /* End of check for corresponding targetlists */ + + n->subselect = (Node *) lfirst(((Expr *) lfirst(intersect_list))->args); + op = "<>"; + n->subLinkType = ALL_SUBLINK; + n->useor = true; + } + + /* + * Prepare the lefthand side of the Sublinks: All the entries + * of the targetlist must be (IN) or must not be (NOT IN) the + * subselect + */ + foreach(elist, intersect_node->targetList) + { + Node *expr = lfirst(elist); + TargetEntry *tent = (TargetEntry *) expr; + + n->lefthand = lappend(n->lefthand, tent->expr); + } + + /* + * The first arguments of oper also have to be created for the + * sublink (they are the same as the lefthand side!) + */ + left_expr = n->lefthand; + right_expr = ((Query *) (n->subselect))->targetList; + + foreach(elist, left_expr) + { + Node *lexpr = lfirst(elist); + Node *rexpr = lfirst(right_expr); + TargetEntry *tent = (TargetEntry *) rexpr; + Expr *op_expr; + + op_expr = make_op(op, lexpr, tent->expr); + + n->oper = lappend(n->oper, op_expr); + right_expr = lnext(right_expr); + } + + /* + * If the Select Query node has aggregates in use add all the + * subselects to the HAVING qual else to the WHERE qual + */ + if (intersect_node->hasAggs == false) + AddQual(intersect_node, (Node *) n); + else + AddHavingQual(intersect_node, (Node *) n); + + /* Now we got sublinks */ + intersect_node->hasSubLinks = true; + intersect_list = lnext(intersect_list); + } + intersect_node->intersectClause = NIL; + union_list = lappend(union_list, intersect_node); + } + + /* The first entry to union_list is our new top node */ + result = (Query *) lfirst(union_list); + /* attach the rest to unionClause */ + result->unionClause = lnext(union_list); + /* Attach all the items remembered in the beginning of the function */ + result->sortClause = sortClause; + result->uniqueFlag = uniqueFlag; + result->into = into; + result->isPortal = isPortal; + result->isBinary = isBinary; + result->isTemp = isTemp; + + /* + * The relation to insert into is attached to the range table of the + * new top node + */ + if (commandType == CMD_INSERT) + { + result->rtable = lappend(result->rtable, rtable_insert); + result->resultRelation = length(result->rtable); + result->commandType = commandType; + } + + /* + * The resnames of the originally first SelectStatement are attached + * to the new first SelectStatement + */ + foreach(elist, result->targetList) + { + TargetEntry *tent = (TargetEntry *) lfirst(elist); + + tent->resdom->resname = lfirst(resnames); + resnames = lnext(resnames); + } + return result; } /* Create a list of nodes that are either Query nodes of NOT Expr @@ -3217,74 +3314,70 @@ Except_Intersect_Rewrite (Query *parsetree) * least one non negated Query node. This node is attached to the * beginning of the list */ -void create_list(Node *ptr, List **intersect_list) +void +create_list(Node *ptr, List **intersect_list) { - List *arg; - - if(IsA(ptr,Query)) - { - /* The non negated node is attached at the beginning (lcons) */ - *intersect_list = lcons(ptr, *intersect_list); - return; - } - - if(IsA(ptr,Expr)) - { - if(((Expr *)ptr)->opType == NOT_EXPR) + List *arg; + + if (IsA(ptr, Query)) { - /* negated nodes are appended to the end (lappend) */ - *intersect_list = lappend(*intersect_list, ptr); - return; + /* The non negated node is attached at the beginning (lcons) */ + *intersect_list = lcons(ptr, *intersect_list); + return; } - else + + if (IsA(ptr, Expr)) { - foreach(arg, ((Expr *)ptr)->args) - { - create_list(lfirst(arg), intersect_list); - } - return; + if (((Expr *) ptr)->opType == NOT_EXPR) + { + /* negated nodes are appended to the end (lappend) */ + *intersect_list = lappend(*intersect_list, ptr); + return; + } + else + { + foreach(arg, ((Expr *) ptr)->args) + create_list(lfirst(arg), intersect_list); + return; + } + return; } - return; - } } /* The nodes given in 'tree' are still 'raw' so 'cook' them using parse_analyze(). * The node given in first_select has already been cooked, so don't transform - * it again but return a pointer to the previously cooked version given in 'parsetree' + * it again but return a pointer to the previously cooked version given in 'parsetree' * instead. */ -Node *intersect_tree_analyze(Node *tree, Node *first_select, Node *parsetree) +Node * +intersect_tree_analyze(Node *tree, Node *first_select, Node *parsetree) { - Node *result = (Node *) NIL; - List *arg; + Node *result = (Node *) NIL; + List *arg; if (IsA(tree, SelectStmt)) - { - /* If we get to the tree given in first_select return - * parsetree instead of performing parse_analyze() */ + { + + /* + * If we get to the tree given in first_select return parsetree + * instead of performing parse_analyze() + */ if (tree == first_select) - { result = parsetree; - } else - { - /* transform the 'raw' nodes to 'cooked' Query nodes */ - List *qtree = parse_analyze(lcons(tree, NIL), NULL); + { + /* transform the 'raw' nodes to 'cooked' Query nodes */ + List *qtree = parse_analyze(lcons(tree, NIL), NULL); + result = (Node *) lfirst(qtree); } - } + } - if(IsA(tree,Expr)) - { - /* Call recursively for every argument of the node */ - foreach(arg, ((Expr *)tree)->args) + if (IsA(tree, Expr)) { - lfirst(arg) = intersect_tree_analyze(lfirst(arg), first_select, parsetree); + /* Call recursively for every argument of the node */ + foreach(arg, ((Expr *) tree)->args) + lfirst(arg) = intersect_tree_analyze(lfirst(arg), first_select, parsetree); + result = tree; } - result = tree; - } - return result; + return result; } - - - - |