diff options
author | Bruce Momjian <bruce@momjian.us> | 1999-01-25 18:02:28 +0000 |
---|---|---|
committer | Bruce Momjian <bruce@momjian.us> | 1999-01-25 18:02:28 +0000 |
commit | 1401f63dd15fbc073775fb0279c3b7153ef95f66 (patch) | |
tree | b9d5715647146f87c8f9f46425cacf8fdef6eebb /src/backend/executor/nodeAgg.c | |
parent | 247b3f905484f8488da91ead600afc85508b112d (diff) | |
download | postgresql-1401f63dd15fbc073775fb0279c3b7153ef95f66.tar.gz postgresql-1401f63dd15fbc073775fb0279c3b7153ef95f66.zip |
Agg/Aggreg cleanup and datetime.sql patch.
Diffstat (limited to 'src/backend/executor/nodeAgg.c')
-rw-r--r-- | src/backend/executor/nodeAgg.c | 141 |
1 files changed, 67 insertions, 74 deletions
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c index a20ef4baa6f..03d0041b640 100644 --- a/src/backend/executor/nodeAgg.c +++ b/src/backend/executor/nodeAgg.c @@ -45,7 +45,7 @@ typedef struct AggFuncInfo FmgrInfo finalfn; } AggFuncInfo; -static Datum aggGetAttr(TupleTableSlot *tuple, Aggref *agg, bool *isNull); +static Datum aggGetAttr(TupleTableSlot *tuple, Aggref *aggref, bool *isNull); /* --------------------------------------- @@ -90,9 +90,8 @@ ExecAgg(Agg *node) { AggState *aggstate; EState *estate; - Aggref **aggregates; Plan *outerPlan; - int i, + int aggno, nagg; Datum *value1, *value2; @@ -123,7 +122,6 @@ ExecAgg(Agg *node) */ do { - aggstate = node->aggstate; if (aggstate->agg_done) return NULL; @@ -133,17 +131,6 @@ ExecAgg(Agg *node) nagg = length(node->aggs); - aggregates = (Aggref **) palloc(sizeof(Aggref *) * nagg); - - /* take List* and make it an array that can be quickly indexed */ - alist = node->aggs; - for (i = 0; i < nagg; i++) - { - aggregates[i] = lfirst(alist); - aggregates[i]->aggno = i; - alist = lnext(alist); - } - value1 = node->aggstate->csstate.cstate.cs_ExprContext->ecxt_values; nulls = node->aggstate->csstate.cstate.cs_ExprContext->ecxt_nulls; @@ -161,9 +148,10 @@ ExecAgg(Agg *node) projInfo = aggstate->csstate.cstate.cs_ProjInfo; - for (i = 0; i < nagg; i++) + aggno = 0; + foreach(alist, node->aggs) { - Aggref *agg; + Aggref *aggref = lfirst(alist); char *aggname; HeapTuple aggTuple; Form_pg_aggregate aggp; @@ -171,22 +159,20 @@ ExecAgg(Agg *node) xfn2_oid, finalfn_oid; - agg = aggregates[i]; - /* --------------------- * find transfer functions of all the aggregates and initialize * their initial values * --------------------- */ - aggname = agg->aggname; + aggname = aggref->aggname; aggTuple = SearchSysCacheTuple(AGGNAME, PointerGetDatum(aggname), - ObjectIdGetDatum(agg->basetype), + ObjectIdGetDatum(aggref->basetype), 0, 0); if (!HeapTupleIsValid(aggTuple)) elog(ERROR, "ExecAgg: cache lookup failed for aggregate \"%s\"(%s)", aggname, - typeidTypeName(agg->basetype)); + typeidTypeName(aggref->basetype)); aggp = (Form_pg_aggregate) GETSTRUCT(aggTuple); xfn1_oid = aggp->aggtransfn1; @@ -195,15 +181,15 @@ ExecAgg(Agg *node) if (OidIsValid(finalfn_oid)) { - fmgr_info(finalfn_oid, &aggFuncInfo[i].finalfn); - aggFuncInfo[i].finalfn_oid = finalfn_oid; + fmgr_info(finalfn_oid, &aggFuncInfo[aggno].finalfn); + aggFuncInfo[aggno].finalfn_oid = finalfn_oid; } if (OidIsValid(xfn2_oid)) { - fmgr_info(xfn2_oid, &aggFuncInfo[i].xfn2); - aggFuncInfo[i].xfn2_oid = xfn2_oid; - value2[i] = (Datum) AggNameGetInitVal((char *) aggname, + fmgr_info(xfn2_oid, &aggFuncInfo[aggno].xfn2); + aggFuncInfo[aggno].xfn2_oid = xfn2_oid; + value2[aggno] = (Datum) AggNameGetInitVal((char *) aggname, aggp->aggbasetype, 2, &isNull2); @@ -219,9 +205,9 @@ ExecAgg(Agg *node) if (OidIsValid(xfn1_oid)) { - fmgr_info(xfn1_oid, &aggFuncInfo[i].xfn1); - aggFuncInfo[i].xfn1_oid = xfn1_oid; - value1[i] = (Datum) AggNameGetInitVal((char *) aggname, + fmgr_info(xfn1_oid, &aggFuncInfo[aggno].xfn1); + aggFuncInfo[aggno].xfn1_oid = xfn1_oid; + value1[aggno] = (Datum) AggNameGetInitVal((char *) aggname, aggp->aggbasetype, 1, &isNull1); @@ -236,10 +222,11 @@ ExecAgg(Agg *node) */ if (isNull1) { - noInitValue[i] = 1; - nulls[i] = 1; + noInitValue[aggno] = 1; + nulls[aggno] = 1; } } + aggno++; } /* ---------------- @@ -271,53 +258,55 @@ ExecAgg(Agg *node) /* initially, set all the values to NULL */ null_array = palloc(tupType->natts); - for (i = 0; i < tupType->natts; i++) - null_array[i] = 'n'; + for (aggno = 0; aggno < tupType->natts; aggno++) + null_array[aggno] = 'n'; oneTuple = heap_formtuple(tupType, tupValue, null_array); pfree(null_array); } break; } - for (i = 0; i < nagg; i++) + aggno = 0; + foreach(alist, node->aggs) { + Aggref *aggref = lfirst(alist); AttrNumber attnum; int2 attlen = 0; Datum newVal = (Datum) NULL; - AggFuncInfo *aggfns = &aggFuncInfo[i]; + AggFuncInfo *aggfns = &aggFuncInfo[aggno]; Datum args[2]; Node *tagnode = NULL; - switch (nodeTag(aggregates[i]->target)) + switch (nodeTag(aggref->target)) { case T_Var: tagnode = NULL; newVal = aggGetAttr(outerslot, - aggregates[i], + aggref, &isNull); break; case T_Expr: - tagnode = ((Expr *) aggregates[i]->target)->oper; + tagnode = ((Expr *) aggref->target)->oper; econtext->ecxt_scantuple = outerslot; - newVal = ExecEvalExpr(aggregates[i]->target, econtext, + newVal = ExecEvalExpr(aggref->target, econtext, &isNull, &isDone); break; case T_Const: tagnode = NULL; econtext->ecxt_scantuple = outerslot; - newVal = ExecEvalExpr(aggregates[i]->target, econtext, + newVal = ExecEvalExpr(aggref->target, econtext, &isNull, &isDone); break; default: - elog(ERROR, "ExecAgg: Bad Agg->Target for Agg %d", i); + elog(ERROR, "ExecAgg: Bad Agg->Target for Agg %d", aggno); } - if (isNull && !aggregates[i]->usenulls) + if (isNull && !aggref->usenulls) continue; /* ignore this tuple for this agg */ if (aggfns->xfn1.fn_addr != NULL) { - if (noInitValue[i]) + if (noInitValue[aggno]) { int byVal = 0; @@ -333,10 +322,10 @@ ExecAgg(Agg *node) * came will be freed on the next iteration of the * scan */ - switch (nodeTag(aggregates[i]->target)) + switch (nodeTag(aggref->target)) { case T_Var: - attnum = ((Var *) aggregates[i]->target)->varattno; + attnum = ((Var *) aggref->target)->varattno; attlen = outerslot->ttc_tupleDescriptor->attrs[attnum - 1]->attlen; byVal = outerslot->ttc_tupleDescriptor->attrs[attnum - 1]->attbyval; @@ -355,35 +344,34 @@ ExecAgg(Agg *node) break; } case T_Const: - attlen = ((Const *) aggregates[i]->target)->constlen; - byVal = ((Const *) aggregates[i]->target)->constbyval; + attlen = ((Const *) aggref->target)->constlen; + byVal = ((Const *) aggref->target)->constbyval; break; default: - elog(ERROR, "ExecAgg: Bad Agg->Target for Agg %d", i); + elog(ERROR, "ExecAgg: Bad Agg->Target for Agg %d", aggno); } if (attlen == -1) { /* variable length */ attlen = VARSIZE((struct varlena *) newVal); } - value1[i] = (Datum) palloc(attlen); + value1[aggno] = (Datum) palloc(attlen); if (byVal) - value1[i] = newVal; + value1[aggno] = newVal; else - memmove((char *) (value1[i]), (char *) newVal, attlen); - noInitValue[i] = 0; - nulls[i] = 0; + memmove((char *) (value1[aggno]), (char *) newVal, attlen); + noInitValue[aggno] = 0; + nulls[aggno] = 0; } else { - /* * apply the transition functions. */ - args[0] = value1[i]; + args[0] = value1[aggno]; args[1] = newVal; - value1[i] = + value1[aggno] = (Datum) fmgr_c(&aggfns->xfn1, (FmgrValues *) args, &isNull1); @@ -393,13 +381,14 @@ ExecAgg(Agg *node) if (aggfns->xfn2.fn_addr != NULL) { - Datum xfn2_val = value2[i]; + Datum xfn2_val = value2[aggno]; - value2[i] = + value2[aggno] = (Datum) fmgr_c(&aggfns->xfn2, (FmgrValues *) &xfn2_val, &isNull2); Assert(!isNull2); } + aggno++; } /* @@ -417,12 +406,14 @@ ExecAgg(Agg *node) * finalize the aggregate (if necessary), and get the resultant value * -------------- */ - for (i = 0; i < nagg; i++) + + aggno = 0; + foreach(alist, node->aggs) { char *args[2]; - AggFuncInfo *aggfns = &aggFuncInfo[i]; + AggFuncInfo *aggfns = &aggFuncInfo[aggno]; - if (noInitValue[i]) + if (noInitValue[aggno]) { /* @@ -435,17 +426,17 @@ ExecAgg(Agg *node) { if (aggfns->finalfn.fn_nargs > 1) { - args[0] = (char *) value1[i]; - args[1] = (char *) value2[i]; + args[0] = (char *) value1[aggno]; + args[1] = (char *) value2[aggno]; } else if (aggfns->xfn1.fn_addr != NULL) - args[0] = (char *) value1[i]; + args[0] = (char *) value1[aggno]; else if (aggfns->xfn2.fn_addr != NULL) - args[0] = (char *) value2[i]; + args[0] = (char *) value2[aggno]; else elog(NOTICE, "ExecAgg: no valid transition functions??"); - value1[i] = (Datum) fmgr_c(&aggfns->finalfn, - (FmgrValues *) args, &(nulls[i])); + value1[aggno] = (Datum) fmgr_c(&aggfns->finalfn, + (FmgrValues *) args, &(nulls[aggno])); } else if (aggfns->xfn1.fn_addr != NULL) { @@ -456,9 +447,10 @@ ExecAgg(Agg *node) */ } else if (aggfns->xfn2.fn_addr != NULL) - value1[i] = value2[i]; + value1[aggno] = value2[aggno]; else elog(ERROR, "ExecAgg: no valid transition functions??"); + aggno++; } /* @@ -494,11 +486,12 @@ ExecAgg(Agg *node) if(node->plan.qual != NULL){ qual_result = ExecQual(fix_opids(node->plan.qual), econtext); } + else qual_result = false; if (oneTuple) pfree(oneTuple); } - while ((node->plan.qual != NULL) && (qual_result != true)); + while (node->plan.qual != NULL && qual_result != true); return resultSlot; } @@ -516,7 +509,7 @@ ExecInitAgg(Agg *node, EState *estate, Plan *parent) AggState *aggstate; Plan *outerPlan; ExprContext *econtext; - + /* * assign the node's execution state */ @@ -528,7 +521,7 @@ ExecInitAgg(Agg *node, EState *estate, Plan *parent) aggstate = makeNode(AggState); node->aggstate = aggstate; aggstate->agg_done = FALSE; - + /* * assign node's base id and create expression context */ @@ -628,7 +621,7 @@ ExecEndAgg(Agg *node) */ static Datum aggGetAttr(TupleTableSlot *slot, - Aggref *agg, + Aggref *aggref, bool *isNull) { Datum result; @@ -645,7 +638,7 @@ aggGetAttr(TupleTableSlot *slot, tuple_type = slot->ttc_tupleDescriptor; buffer = slot->ttc_buffer; - attnum = ((Var *) agg->target)->varattno; + attnum = ((Var *) aggref->target)->varattno; /* * If the attribute number is invalid, then we are supposed to return |