1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-12 05:01:15 +03:00

OK, folks, here is the pgindent output.

This commit is contained in:
Bruce Momjian
1998-09-01 04:40:42 +00:00
parent af74855a60
commit fa1a8d6a97
574 changed files with 26509 additions and 24033 deletions

View File

@@ -109,388 +109,397 @@ ExecAgg(Agg *node)
bool isNull = FALSE,
isNull1 = FALSE,
isNull2 = FALSE;
bool qual_result;
bool qual_result;
/* ---------------------
* get state info from node
* ---------------------
*/
/* We loop retrieving groups until we find one matching node->plan.qual */
do {
aggstate = node->aggstate;
if (aggstate->agg_done)
return NULL;
estate = node->plan.state;
econtext = aggstate->csstate.cstate.cs_ExprContext;
nagg = length(node->aggs);
aggregates = (Aggreg **) palloc(sizeof(Aggreg *) * 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;
value2 = (Datum *) palloc(sizeof(Datum) * nagg);
MemSet(value2, 0, sizeof(Datum) * nagg);
aggFuncInfo = (AggFuncInfo *) palloc(sizeof(AggFuncInfo) * nagg);
MemSet(aggFuncInfo, 0, sizeof(AggFuncInfo) * nagg);
noInitValue = (int *) palloc(sizeof(int) * nagg);
MemSet(noInitValue, 0, sizeof(noInitValue) * nagg);
outerPlan = outerPlan(node);
oneTuple = NULL;
projInfo = aggstate->csstate.cstate.cs_ProjInfo;
for (i = 0; i < nagg; i++)
{
Aggreg *agg;
char *aggname;
HeapTuple aggTuple;
Form_pg_aggregate aggp;
Oid xfn1_oid,
xfn2_oid,
finalfn_oid;
agg = aggregates[i];
/* ---------------------
* find transfer functions of all the aggregates and initialize
* their initial values
* ---------------------
*/
aggname = agg->aggname;
aggTuple = SearchSysCacheTuple(AGGNAME,
PointerGetDatum(aggname),
ObjectIdGetDatum(agg->basetype),
0, 0);
if (!HeapTupleIsValid(aggTuple))
elog(ERROR, "ExecAgg: cache lookup failed for aggregate \"%s\"(%s)",
aggname,
typeidTypeName(agg->basetype));
aggp = (Form_pg_aggregate) GETSTRUCT(aggTuple);
xfn1_oid = aggp->aggtransfn1;
xfn2_oid = aggp->aggtransfn2;
finalfn_oid = aggp->aggfinalfn;
if (OidIsValid(finalfn_oid))
{
fmgr_info(finalfn_oid, &aggFuncInfo[i].finalfn);
aggFuncInfo[i].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,
aggp->aggbasetype,
2,
&isNull2);
/* ------------------------------------------
* If there is a second transition function, its initial
* value must exist -- as it does not depend on data values,
* we have no other way of determining an initial value.
* ------------------------------------------
*/
if (isNull2)
elog(ERROR, "ExecAgg: agginitval2 is null");
}
if (OidIsValid(xfn1_oid))
{
fmgr_info(xfn1_oid, &aggFuncInfo[i].xfn1);
aggFuncInfo[i].xfn1_oid = xfn1_oid;
value1[i] = (Datum) AggNameGetInitVal((char *) aggname,
aggp->aggbasetype,
1,
&isNull1);
/* ------------------------------------------
* If the initial value for the first transition function
* doesn't exist in the pg_aggregate table then we let
* the first value returned from the outer procNode become
* the initial value. (This is useful for aggregates like
* max{} and min{}.)
* ------------------------------------------
*/
if (isNull1)
{
noInitValue[i] = 1;
nulls[i] = 1;
}
}
}
/* ----------------
* for each tuple from the the outer plan, apply all the aggregates
* ----------------
/*
* We loop retrieving groups until we find one matching
* node->plan.qual
*/
for (;;)
do
{
HeapTuple outerTuple = NULL;
TupleTableSlot *outerslot;
isNull = isNull1 = isNull2 = 0;
outerslot = ExecProcNode(outerPlan, (Plan *) node);
if (outerslot)
outerTuple = outerslot->val;
if (!HeapTupleIsValid(outerTuple))
aggstate = node->aggstate;
if (aggstate->agg_done)
return NULL;
estate = node->plan.state;
econtext = aggstate->csstate.cstate.cs_ExprContext;
nagg = length(node->aggs);
aggregates = (Aggreg **) palloc(sizeof(Aggreg *) * nagg);
/* take List* and make it an array that can be quickly indexed */
alist = node->aggs;
for (i = 0; i < nagg; i++)
{
/*
* when the outerplan doesn't return a single tuple, create a
* dummy heaptuple anyway because we still need to return a
* valid aggregate value. The value returned will be the
* initial values of the transition functions
*/
if (nTuplesAgged == 0)
{
TupleDesc tupType;
Datum *tupValue;
char *null_array;
tupType = aggstate->csstate.css_ScanTupleSlot->ttc_tupleDescriptor;
tupValue = projInfo->pi_tupValue;
/* initially, set all the values to NULL */
null_array = palloc(tupType->natts);
for (i = 0; i < tupType->natts; i++)
null_array[i] = 'n';
oneTuple = heap_formtuple(tupType, tupValue, null_array);
pfree(null_array);
}
break;
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;
value2 = (Datum *) palloc(sizeof(Datum) * nagg);
MemSet(value2, 0, sizeof(Datum) * nagg);
aggFuncInfo = (AggFuncInfo *) palloc(sizeof(AggFuncInfo) * nagg);
MemSet(aggFuncInfo, 0, sizeof(AggFuncInfo) * nagg);
noInitValue = (int *) palloc(sizeof(int) * nagg);
MemSet(noInitValue, 0, sizeof(noInitValue) * nagg);
outerPlan = outerPlan(node);
oneTuple = NULL;
projInfo = aggstate->csstate.cstate.cs_ProjInfo;
for (i = 0; i < nagg; i++)
{
AttrNumber attnum;
int2 attlen = 0;
Datum newVal = (Datum) NULL;
AggFuncInfo *aggfns = &aggFuncInfo[i];
Datum args[2];
Node *tagnode = NULL;
Aggreg *agg;
char *aggname;
HeapTuple aggTuple;
Form_pg_aggregate aggp;
Oid xfn1_oid,
xfn2_oid,
finalfn_oid;
switch (nodeTag(aggregates[i]->target))
agg = aggregates[i];
/* ---------------------
* find transfer functions of all the aggregates and initialize
* their initial values
* ---------------------
*/
aggname = agg->aggname;
aggTuple = SearchSysCacheTuple(AGGNAME,
PointerGetDatum(aggname),
ObjectIdGetDatum(agg->basetype),
0, 0);
if (!HeapTupleIsValid(aggTuple))
elog(ERROR, "ExecAgg: cache lookup failed for aggregate \"%s\"(%s)",
aggname,
typeidTypeName(agg->basetype));
aggp = (Form_pg_aggregate) GETSTRUCT(aggTuple);
xfn1_oid = aggp->aggtransfn1;
xfn2_oid = aggp->aggtransfn2;
finalfn_oid = aggp->aggfinalfn;
if (OidIsValid(finalfn_oid))
{
case T_Var:
tagnode = NULL;
newVal = aggGetAttr(outerslot,
aggregates[i],
&isNull);
break;
case T_Expr:
tagnode = ((Expr *) aggregates[i]->target)->oper;
econtext->ecxt_scantuple = outerslot;
newVal = ExecEvalExpr(aggregates[i]->target, econtext,
&isNull, &isDone);
break;
case T_Const:
tagnode = NULL;
econtext->ecxt_scantuple = outerslot;
newVal = ExecEvalExpr(aggregates[i]->target, econtext,
&isNull, &isDone);
break;
default:
elog(ERROR, "ExecAgg: Bad Agg->Target for Agg %d", i);
fmgr_info(finalfn_oid, &aggFuncInfo[i].finalfn);
aggFuncInfo[i].finalfn_oid = finalfn_oid;
}
if (isNull && !aggregates[i]->usenulls)
continue; /* ignore this tuple for this agg */
if (aggfns->xfn1.fn_addr != NULL)
if (OidIsValid(xfn2_oid))
{
if (noInitValue[i])
fmgr_info(xfn2_oid, &aggFuncInfo[i].xfn2);
aggFuncInfo[i].xfn2_oid = xfn2_oid;
value2[i] = (Datum) AggNameGetInitVal((char *) aggname,
aggp->aggbasetype,
2,
&isNull2);
/* ------------------------------------------
* If there is a second transition function, its initial
* value must exist -- as it does not depend on data values,
* we have no other way of determining an initial value.
* ------------------------------------------
*/
if (isNull2)
elog(ERROR, "ExecAgg: agginitval2 is null");
}
if (OidIsValid(xfn1_oid))
{
fmgr_info(xfn1_oid, &aggFuncInfo[i].xfn1);
aggFuncInfo[i].xfn1_oid = xfn1_oid;
value1[i] = (Datum) AggNameGetInitVal((char *) aggname,
aggp->aggbasetype,
1,
&isNull1);
/* ------------------------------------------
* If the initial value for the first transition function
* doesn't exist in the pg_aggregate table then we let
* the first value returned from the outer procNode become
* the initial value. (This is useful for aggregates like
* max{} and min{}.)
* ------------------------------------------
*/
if (isNull1)
{
int byVal = 0;
noInitValue[i] = 1;
nulls[i] = 1;
}
}
}
/*
* value1 and value2 has not been initialized. This is
* the first non-NULL value. We use it as the initial
* value.
*/
/* ----------------
* for each tuple from the the outer plan, apply all the aggregates
* ----------------
*/
for (;;)
{
HeapTuple outerTuple = NULL;
TupleTableSlot *outerslot;
/*
* but we can't just use it straight, we have to make
* a copy of it since the tuple from which it came
* will be freed on the next iteration of the scan
*/
switch (nodeTag(aggregates[i]->target))
isNull = isNull1 = isNull2 = 0;
outerslot = ExecProcNode(outerPlan, (Plan *) node);
if (outerslot)
outerTuple = outerslot->val;
if (!HeapTupleIsValid(outerTuple))
{
/*
* when the outerplan doesn't return a single tuple,
* create a dummy heaptuple anyway because we still need
* to return a valid aggregate value. The value returned
* will be the initial values of the transition functions
*/
if (nTuplesAgged == 0)
{
TupleDesc tupType;
Datum *tupValue;
char *null_array;
tupType = aggstate->csstate.css_ScanTupleSlot->ttc_tupleDescriptor;
tupValue = projInfo->pi_tupValue;
/* initially, set all the values to NULL */
null_array = palloc(tupType->natts);
for (i = 0; i < tupType->natts; i++)
null_array[i] = 'n';
oneTuple = heap_formtuple(tupType, tupValue, null_array);
pfree(null_array);
}
break;
}
for (i = 0; i < nagg; i++)
{
AttrNumber attnum;
int2 attlen = 0;
Datum newVal = (Datum) NULL;
AggFuncInfo *aggfns = &aggFuncInfo[i];
Datum args[2];
Node *tagnode = NULL;
switch (nodeTag(aggregates[i]->target))
{
case T_Var:
tagnode = NULL;
newVal = aggGetAttr(outerslot,
aggregates[i],
&isNull);
break;
case T_Expr:
tagnode = ((Expr *) aggregates[i]->target)->oper;
econtext->ecxt_scantuple = outerslot;
newVal = ExecEvalExpr(aggregates[i]->target, econtext,
&isNull, &isDone);
break;
case T_Const:
tagnode = NULL;
econtext->ecxt_scantuple = outerslot;
newVal = ExecEvalExpr(aggregates[i]->target, econtext,
&isNull, &isDone);
break;
default:
elog(ERROR, "ExecAgg: Bad Agg->Target for Agg %d", i);
}
if (isNull && !aggregates[i]->usenulls)
continue; /* ignore this tuple for this agg */
if (aggfns->xfn1.fn_addr != NULL)
{
if (noInitValue[i])
{
case T_Var:
attnum = ((Var *) aggregates[i]->target)->varattno;
attlen = outerslot->ttc_tupleDescriptor->attrs[attnum - 1]->attlen;
byVal = outerslot->ttc_tupleDescriptor->attrs[attnum - 1]->attbyval;
int byVal = 0;
break;
case T_Expr:
{
FunctionCachePtr fcache_ptr;
/*
* value1 and value2 has not been initialized.
* This is the first non-NULL value. We use it as
* the initial value.
*/
if (nodeTag(tagnode) == T_Func)
fcache_ptr = ((Func *) tagnode)->func_fcache;
else
fcache_ptr = ((Oper *) tagnode)->op_fcache;
attlen = fcache_ptr->typlen;
byVal = fcache_ptr->typbyval;
/*
* but we can't just use it straight, we have to
* make a copy of it since the tuple from which it
* came will be freed on the next iteration of the
* scan
*/
switch (nodeTag(aggregates[i]->target))
{
case T_Var:
attnum = ((Var *) aggregates[i]->target)->varattno;
attlen = outerslot->ttc_tupleDescriptor->attrs[attnum - 1]->attlen;
byVal = outerslot->ttc_tupleDescriptor->attrs[attnum - 1]->attbyval;
break;
}
case T_Const:
attlen = ((Const *) aggregates[i]->target)->constlen;
byVal = ((Const *) aggregates[i]->target)->constbyval;
case T_Expr:
{
FunctionCachePtr fcache_ptr;
break;
default:
elog(ERROR, "ExecAgg: Bad Agg->Target for Agg %d", i);
if (nodeTag(tagnode) == T_Func)
fcache_ptr = ((Func *) tagnode)->func_fcache;
else
fcache_ptr = ((Oper *) tagnode)->op_fcache;
attlen = fcache_ptr->typlen;
byVal = fcache_ptr->typbyval;
break;
}
case T_Const:
attlen = ((Const *) aggregates[i]->target)->constlen;
byVal = ((Const *) aggregates[i]->target)->constbyval;
break;
default:
elog(ERROR, "ExecAgg: Bad Agg->Target for Agg %d", i);
}
if (attlen == -1)
{
/* variable length */
attlen = VARSIZE((struct varlena *) newVal);
}
value1[i] = (Datum) palloc(attlen);
if (byVal)
value1[i] = newVal;
else
memmove((char *) (value1[i]), (char *) newVal, attlen);
noInitValue[i] = 0;
nulls[i] = 0;
}
if (attlen == -1)
{
/* variable length */
attlen = VARSIZE((struct varlena *) newVal);
}
value1[i] = (Datum) palloc(attlen);
if (byVal)
value1[i] = newVal;
else
memmove((char *) (value1[i]), (char *) newVal, attlen);
noInitValue[i] = 0;
nulls[i] = 0;
{
/*
* apply the transition functions.
*/
args[0] = value1[i];
args[1] = newVal;
value1[i] =
(Datum) fmgr_c(&aggfns->xfn1,
(FmgrValues *) args,
&isNull1);
Assert(!isNull1);
}
}
else
if (aggfns->xfn2.fn_addr != NULL)
{
Datum xfn2_val = value2[i];
/*
* apply the transition functions.
*/
args[0] = value1[i];
args[1] = newVal;
value1[i] =
(Datum) fmgr_c(&aggfns->xfn1,
(FmgrValues *) args,
&isNull1);
Assert(!isNull1);
value2[i] =
(Datum) fmgr_c(&aggfns->xfn2,
(FmgrValues *) &xfn2_val, &isNull2);
Assert(!isNull2);
}
}
if (aggfns->xfn2.fn_addr != NULL)
{
Datum xfn2_val = value2[i];
/*
* keep this for the projection (we only need one of these -
* all the tuples we aggregate over share the same group
* column)
*/
if (!oneTuple)
oneTuple = heap_copytuple(outerslot->val);
value2[i] =
(Datum) fmgr_c(&aggfns->xfn2,
(FmgrValues *) &xfn2_val, &isNull2);
Assert(!isNull2);
nTuplesAgged++;
}
/* --------------
* finalize the aggregate (if necessary), and get the resultant value
* --------------
*/
for (i = 0; i < nagg; i++)
{
char *args[2];
AggFuncInfo *aggfns = &aggFuncInfo[i];
if (noInitValue[i])
{
/*
* No values found for this agg; return current state.
* This seems to fix behavior for avg() aggregate. -tgl
* 12/96
*/
}
else if (aggfns->finalfn.fn_addr != NULL && nTuplesAgged > 0)
{
if (aggfns->finalfn.fn_nargs > 1)
{
args[0] = (char *) value1[i];
args[1] = (char *) value2[i];
}
else if (aggfns->xfn1.fn_addr != NULL)
args[0] = (char *) value1[i];
else if (aggfns->xfn2.fn_addr != NULL)
args[0] = (char *) value2[i];
else
elog(NOTICE, "ExecAgg: no valid transition functions??");
value1[i] = (Datum) fmgr_c(&aggfns->finalfn,
(FmgrValues *) args, &(nulls[i]));
}
else if (aggfns->xfn1.fn_addr != NULL)
{
/*
* value in the right place, ignore. (If you remove this
* case, fix the else part. -ay 2/95)
*/
}
else if (aggfns->xfn2.fn_addr != NULL)
value1[i] = value2[i];
else
elog(ERROR, "ExecAgg: no valid transition functions??");
}
/*
* keep this for the projection (we only need one of these - all
* the tuples we aggregate over share the same group column)
* whether the aggregation is done depends on whether we are doing
* aggregation over groups or the entire table
*/
if (!oneTuple)
oneTuple = heap_copytuple(outerslot->val);
nTuplesAgged++;
}
/* --------------
* finalize the aggregate (if necessary), and get the resultant value
* --------------
*/
for (i = 0; i < nagg; i++)
{
char *args[2];
AggFuncInfo *aggfns = &aggFuncInfo[i];
if (noInitValue[i])
if (nodeTag(outerPlan) == T_Group)
{
/*
* No values found for this agg; return current state. This
* seems to fix behavior for avg() aggregate. -tgl 12/96
*/
/* aggregation over groups */
aggstate->agg_done = ((Group *) outerPlan)->grpstate->grp_done;
}
else if (aggfns->finalfn.fn_addr != NULL && nTuplesAgged > 0)
{
if (aggfns->finalfn.fn_nargs > 1)
{
args[0] = (char *) value1[i];
args[1] = (char *) value2[i];
}
else if (aggfns->xfn1.fn_addr != NULL)
args[0] = (char *) value1[i];
else if (aggfns->xfn2.fn_addr != NULL)
args[0] = (char *) value2[i];
else
elog(NOTICE, "ExecAgg: no valid transition functions??");
value1[i] = (Datum) fmgr_c(&aggfns->finalfn,
(FmgrValues *) args, &(nulls[i]));
}
else if (aggfns->xfn1.fn_addr != NULL)
{
/*
* value in the right place, ignore. (If you remove this case,
* fix the else part. -ay 2/95)
*/
}
else if (aggfns->xfn2.fn_addr != NULL)
value1[i] = value2[i];
else
elog(ERROR, "ExecAgg: no valid transition functions??");
aggstate->agg_done = TRUE;
/* ----------------
* form a projection tuple, store it in the result tuple
* slot and return it.
* ----------------
*/
ExecStoreTuple(oneTuple,
aggstate->csstate.css_ScanTupleSlot,
InvalidBuffer,
false);
econtext->ecxt_scantuple = aggstate->csstate.css_ScanTupleSlot;
resultSlot = ExecProject(projInfo, &isDone);
/*
* As long as the retrieved group does not match the
* qualifications it is ignored and the next group is fetched
*/
qual_result = ExecQual(fix_opids(node->plan.qual), econtext);
if (oneTuple)
pfree(oneTuple);
}
/*
* whether the aggregation is done depends on whether we are doing
* aggregation over groups or the entire table
*/
if (nodeTag(outerPlan) == T_Group)
{
/* aggregation over groups */
aggstate->agg_done = ((Group *) outerPlan)->grpstate->grp_done;
}
else
aggstate->agg_done = TRUE;
/* ----------------
* form a projection tuple, store it in the result tuple
* slot and return it.
* ----------------
*/
ExecStoreTuple(oneTuple,
aggstate->csstate.css_ScanTupleSlot,
InvalidBuffer,
false);
econtext->ecxt_scantuple = aggstate->csstate.css_ScanTupleSlot;
resultSlot = ExecProject(projInfo, &isDone);
/* As long as the retrieved group does not match the qualifications it is ignored and
* the next group is fetched */
qual_result=ExecQual(fix_opids(node->plan.qual),econtext);
if (oneTuple)
pfree(oneTuple);
}
while((node->plan.qual!=NULL) && (qual_result!=true));
while ((node->plan.qual != NULL) && (qual_result != true));
return resultSlot;
}