Agg/Aggreg cleanup and datetime.sql patch.
This commit is contained in:
parent
247b3f9054
commit
1401f63dd1
src
backend
executor
nodes
optimizer/plan
rewrite
utils/adt
include/optimizer
test/regress/sql
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.40 1999/01/24 00:28:18 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.41 1999/01/25 18:02:13 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -67,7 +67,7 @@ bool execConstByVal;
|
|||||||
int execConstLen;
|
int execConstLen;
|
||||||
|
|
||||||
/* static functions decls */
|
/* static functions decls */
|
||||||
static Datum ExecEvalAggref(Aggref *agg, ExprContext *econtext, bool *isNull);
|
static Datum ExecEvalAggref(Aggref *aggref, ExprContext *econtext, bool *isNull);
|
||||||
static Datum ExecEvalArrayRef(ArrayRef *arrayRef, ExprContext *econtext,
|
static Datum ExecEvalArrayRef(ArrayRef *arrayRef, ExprContext *econtext,
|
||||||
bool *isNull, bool *isDone);
|
bool *isNull, bool *isDone);
|
||||||
static Datum ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull);
|
static Datum ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull);
|
||||||
@ -192,10 +192,10 @@ ExecEvalArrayRef(ArrayRef *arrayRef,
|
|||||||
* ----------------------------------------------------------------
|
* ----------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
static Datum
|
static Datum
|
||||||
ExecEvalAggref(Aggref *agg, ExprContext *econtext, bool *isNull)
|
ExecEvalAggref(Aggref *aggref, ExprContext *econtext, bool *isNull)
|
||||||
{
|
{
|
||||||
*isNull = econtext->ecxt_nulls[agg->aggno];
|
*isNull = econtext->ecxt_nulls[aggref->aggno];
|
||||||
return econtext->ecxt_values[agg->aggno];
|
return econtext->ecxt_values[aggref->aggno];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------
|
/* ----------------------------------------------------------------
|
||||||
|
@ -45,7 +45,7 @@ typedef struct AggFuncInfo
|
|||||||
FmgrInfo finalfn;
|
FmgrInfo finalfn;
|
||||||
} AggFuncInfo;
|
} 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;
|
AggState *aggstate;
|
||||||
EState *estate;
|
EState *estate;
|
||||||
Aggref **aggregates;
|
|
||||||
Plan *outerPlan;
|
Plan *outerPlan;
|
||||||
int i,
|
int aggno,
|
||||||
nagg;
|
nagg;
|
||||||
Datum *value1,
|
Datum *value1,
|
||||||
*value2;
|
*value2;
|
||||||
@ -123,7 +122,6 @@ ExecAgg(Agg *node)
|
|||||||
*/
|
*/
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
|
||||||
aggstate = node->aggstate;
|
aggstate = node->aggstate;
|
||||||
if (aggstate->agg_done)
|
if (aggstate->agg_done)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -133,17 +131,6 @@ ExecAgg(Agg *node)
|
|||||||
|
|
||||||
nagg = length(node->aggs);
|
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;
|
value1 = node->aggstate->csstate.cstate.cs_ExprContext->ecxt_values;
|
||||||
nulls = node->aggstate->csstate.cstate.cs_ExprContext->ecxt_nulls;
|
nulls = node->aggstate->csstate.cstate.cs_ExprContext->ecxt_nulls;
|
||||||
|
|
||||||
@ -161,9 +148,10 @@ ExecAgg(Agg *node)
|
|||||||
|
|
||||||
projInfo = aggstate->csstate.cstate.cs_ProjInfo;
|
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;
|
char *aggname;
|
||||||
HeapTuple aggTuple;
|
HeapTuple aggTuple;
|
||||||
Form_pg_aggregate aggp;
|
Form_pg_aggregate aggp;
|
||||||
@ -171,22 +159,20 @@ ExecAgg(Agg *node)
|
|||||||
xfn2_oid,
|
xfn2_oid,
|
||||||
finalfn_oid;
|
finalfn_oid;
|
||||||
|
|
||||||
agg = aggregates[i];
|
|
||||||
|
|
||||||
/* ---------------------
|
/* ---------------------
|
||||||
* find transfer functions of all the aggregates and initialize
|
* find transfer functions of all the aggregates and initialize
|
||||||
* their initial values
|
* their initial values
|
||||||
* ---------------------
|
* ---------------------
|
||||||
*/
|
*/
|
||||||
aggname = agg->aggname;
|
aggname = aggref->aggname;
|
||||||
aggTuple = SearchSysCacheTuple(AGGNAME,
|
aggTuple = SearchSysCacheTuple(AGGNAME,
|
||||||
PointerGetDatum(aggname),
|
PointerGetDatum(aggname),
|
||||||
ObjectIdGetDatum(agg->basetype),
|
ObjectIdGetDatum(aggref->basetype),
|
||||||
0, 0);
|
0, 0);
|
||||||
if (!HeapTupleIsValid(aggTuple))
|
if (!HeapTupleIsValid(aggTuple))
|
||||||
elog(ERROR, "ExecAgg: cache lookup failed for aggregate \"%s\"(%s)",
|
elog(ERROR, "ExecAgg: cache lookup failed for aggregate \"%s\"(%s)",
|
||||||
aggname,
|
aggname,
|
||||||
typeidTypeName(agg->basetype));
|
typeidTypeName(aggref->basetype));
|
||||||
aggp = (Form_pg_aggregate) GETSTRUCT(aggTuple);
|
aggp = (Form_pg_aggregate) GETSTRUCT(aggTuple);
|
||||||
|
|
||||||
xfn1_oid = aggp->aggtransfn1;
|
xfn1_oid = aggp->aggtransfn1;
|
||||||
@ -195,15 +181,15 @@ ExecAgg(Agg *node)
|
|||||||
|
|
||||||
if (OidIsValid(finalfn_oid))
|
if (OidIsValid(finalfn_oid))
|
||||||
{
|
{
|
||||||
fmgr_info(finalfn_oid, &aggFuncInfo[i].finalfn);
|
fmgr_info(finalfn_oid, &aggFuncInfo[aggno].finalfn);
|
||||||
aggFuncInfo[i].finalfn_oid = finalfn_oid;
|
aggFuncInfo[aggno].finalfn_oid = finalfn_oid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (OidIsValid(xfn2_oid))
|
if (OidIsValid(xfn2_oid))
|
||||||
{
|
{
|
||||||
fmgr_info(xfn2_oid, &aggFuncInfo[i].xfn2);
|
fmgr_info(xfn2_oid, &aggFuncInfo[aggno].xfn2);
|
||||||
aggFuncInfo[i].xfn2_oid = xfn2_oid;
|
aggFuncInfo[aggno].xfn2_oid = xfn2_oid;
|
||||||
value2[i] = (Datum) AggNameGetInitVal((char *) aggname,
|
value2[aggno] = (Datum) AggNameGetInitVal((char *) aggname,
|
||||||
aggp->aggbasetype,
|
aggp->aggbasetype,
|
||||||
2,
|
2,
|
||||||
&isNull2);
|
&isNull2);
|
||||||
@ -219,9 +205,9 @@ ExecAgg(Agg *node)
|
|||||||
|
|
||||||
if (OidIsValid(xfn1_oid))
|
if (OidIsValid(xfn1_oid))
|
||||||
{
|
{
|
||||||
fmgr_info(xfn1_oid, &aggFuncInfo[i].xfn1);
|
fmgr_info(xfn1_oid, &aggFuncInfo[aggno].xfn1);
|
||||||
aggFuncInfo[i].xfn1_oid = xfn1_oid;
|
aggFuncInfo[aggno].xfn1_oid = xfn1_oid;
|
||||||
value1[i] = (Datum) AggNameGetInitVal((char *) aggname,
|
value1[aggno] = (Datum) AggNameGetInitVal((char *) aggname,
|
||||||
aggp->aggbasetype,
|
aggp->aggbasetype,
|
||||||
1,
|
1,
|
||||||
&isNull1);
|
&isNull1);
|
||||||
@ -236,10 +222,11 @@ ExecAgg(Agg *node)
|
|||||||
*/
|
*/
|
||||||
if (isNull1)
|
if (isNull1)
|
||||||
{
|
{
|
||||||
noInitValue[i] = 1;
|
noInitValue[aggno] = 1;
|
||||||
nulls[i] = 1;
|
nulls[aggno] = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
aggno++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
@ -271,53 +258,55 @@ ExecAgg(Agg *node)
|
|||||||
|
|
||||||
/* initially, set all the values to NULL */
|
/* initially, set all the values to NULL */
|
||||||
null_array = palloc(tupType->natts);
|
null_array = palloc(tupType->natts);
|
||||||
for (i = 0; i < tupType->natts; i++)
|
for (aggno = 0; aggno < tupType->natts; aggno++)
|
||||||
null_array[i] = 'n';
|
null_array[aggno] = 'n';
|
||||||
oneTuple = heap_formtuple(tupType, tupValue, null_array);
|
oneTuple = heap_formtuple(tupType, tupValue, null_array);
|
||||||
pfree(null_array);
|
pfree(null_array);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < nagg; i++)
|
aggno = 0;
|
||||||
|
foreach(alist, node->aggs)
|
||||||
{
|
{
|
||||||
|
Aggref *aggref = lfirst(alist);
|
||||||
AttrNumber attnum;
|
AttrNumber attnum;
|
||||||
int2 attlen = 0;
|
int2 attlen = 0;
|
||||||
Datum newVal = (Datum) NULL;
|
Datum newVal = (Datum) NULL;
|
||||||
AggFuncInfo *aggfns = &aggFuncInfo[i];
|
AggFuncInfo *aggfns = &aggFuncInfo[aggno];
|
||||||
Datum args[2];
|
Datum args[2];
|
||||||
Node *tagnode = NULL;
|
Node *tagnode = NULL;
|
||||||
|
|
||||||
switch (nodeTag(aggregates[i]->target))
|
switch (nodeTag(aggref->target))
|
||||||
{
|
{
|
||||||
case T_Var:
|
case T_Var:
|
||||||
tagnode = NULL;
|
tagnode = NULL;
|
||||||
newVal = aggGetAttr(outerslot,
|
newVal = aggGetAttr(outerslot,
|
||||||
aggregates[i],
|
aggref,
|
||||||
&isNull);
|
&isNull);
|
||||||
break;
|
break;
|
||||||
case T_Expr:
|
case T_Expr:
|
||||||
tagnode = ((Expr *) aggregates[i]->target)->oper;
|
tagnode = ((Expr *) aggref->target)->oper;
|
||||||
econtext->ecxt_scantuple = outerslot;
|
econtext->ecxt_scantuple = outerslot;
|
||||||
newVal = ExecEvalExpr(aggregates[i]->target, econtext,
|
newVal = ExecEvalExpr(aggref->target, econtext,
|
||||||
&isNull, &isDone);
|
&isNull, &isDone);
|
||||||
break;
|
break;
|
||||||
case T_Const:
|
case T_Const:
|
||||||
tagnode = NULL;
|
tagnode = NULL;
|
||||||
econtext->ecxt_scantuple = outerslot;
|
econtext->ecxt_scantuple = outerslot;
|
||||||
newVal = ExecEvalExpr(aggregates[i]->target, econtext,
|
newVal = ExecEvalExpr(aggref->target, econtext,
|
||||||
&isNull, &isDone);
|
&isNull, &isDone);
|
||||||
break;
|
break;
|
||||||
default:
|
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 */
|
continue; /* ignore this tuple for this agg */
|
||||||
|
|
||||||
if (aggfns->xfn1.fn_addr != NULL)
|
if (aggfns->xfn1.fn_addr != NULL)
|
||||||
{
|
{
|
||||||
if (noInitValue[i])
|
if (noInitValue[aggno])
|
||||||
{
|
{
|
||||||
int byVal = 0;
|
int byVal = 0;
|
||||||
|
|
||||||
@ -333,10 +322,10 @@ ExecAgg(Agg *node)
|
|||||||
* came will be freed on the next iteration of the
|
* came will be freed on the next iteration of the
|
||||||
* scan
|
* scan
|
||||||
*/
|
*/
|
||||||
switch (nodeTag(aggregates[i]->target))
|
switch (nodeTag(aggref->target))
|
||||||
{
|
{
|
||||||
case T_Var:
|
case T_Var:
|
||||||
attnum = ((Var *) aggregates[i]->target)->varattno;
|
attnum = ((Var *) aggref->target)->varattno;
|
||||||
attlen = outerslot->ttc_tupleDescriptor->attrs[attnum - 1]->attlen;
|
attlen = outerslot->ttc_tupleDescriptor->attrs[attnum - 1]->attlen;
|
||||||
byVal = outerslot->ttc_tupleDescriptor->attrs[attnum - 1]->attbyval;
|
byVal = outerslot->ttc_tupleDescriptor->attrs[attnum - 1]->attbyval;
|
||||||
|
|
||||||
@ -355,35 +344,34 @@ ExecAgg(Agg *node)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case T_Const:
|
case T_Const:
|
||||||
attlen = ((Const *) aggregates[i]->target)->constlen;
|
attlen = ((Const *) aggref->target)->constlen;
|
||||||
byVal = ((Const *) aggregates[i]->target)->constbyval;
|
byVal = ((Const *) aggref->target)->constbyval;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
elog(ERROR, "ExecAgg: Bad Agg->Target for Agg %d", i);
|
elog(ERROR, "ExecAgg: Bad Agg->Target for Agg %d", aggno);
|
||||||
}
|
}
|
||||||
if (attlen == -1)
|
if (attlen == -1)
|
||||||
{
|
{
|
||||||
/* variable length */
|
/* variable length */
|
||||||
attlen = VARSIZE((struct varlena *) newVal);
|
attlen = VARSIZE((struct varlena *) newVal);
|
||||||
}
|
}
|
||||||
value1[i] = (Datum) palloc(attlen);
|
value1[aggno] = (Datum) palloc(attlen);
|
||||||
if (byVal)
|
if (byVal)
|
||||||
value1[i] = newVal;
|
value1[aggno] = newVal;
|
||||||
else
|
else
|
||||||
memmove((char *) (value1[i]), (char *) newVal, attlen);
|
memmove((char *) (value1[aggno]), (char *) newVal, attlen);
|
||||||
noInitValue[i] = 0;
|
noInitValue[aggno] = 0;
|
||||||
nulls[i] = 0;
|
nulls[aggno] = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* apply the transition functions.
|
* apply the transition functions.
|
||||||
*/
|
*/
|
||||||
args[0] = value1[i];
|
args[0] = value1[aggno];
|
||||||
args[1] = newVal;
|
args[1] = newVal;
|
||||||
value1[i] =
|
value1[aggno] =
|
||||||
(Datum) fmgr_c(&aggfns->xfn1,
|
(Datum) fmgr_c(&aggfns->xfn1,
|
||||||
(FmgrValues *) args,
|
(FmgrValues *) args,
|
||||||
&isNull1);
|
&isNull1);
|
||||||
@ -393,13 +381,14 @@ ExecAgg(Agg *node)
|
|||||||
|
|
||||||
if (aggfns->xfn2.fn_addr != NULL)
|
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,
|
(Datum) fmgr_c(&aggfns->xfn2,
|
||||||
(FmgrValues *) &xfn2_val, &isNull2);
|
(FmgrValues *) &xfn2_val, &isNull2);
|
||||||
Assert(!isNull2);
|
Assert(!isNull2);
|
||||||
}
|
}
|
||||||
|
aggno++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -417,12 +406,14 @@ ExecAgg(Agg *node)
|
|||||||
* finalize the aggregate (if necessary), and get the resultant value
|
* 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];
|
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)
|
if (aggfns->finalfn.fn_nargs > 1)
|
||||||
{
|
{
|
||||||
args[0] = (char *) value1[i];
|
args[0] = (char *) value1[aggno];
|
||||||
args[1] = (char *) value2[i];
|
args[1] = (char *) value2[aggno];
|
||||||
}
|
}
|
||||||
else if (aggfns->xfn1.fn_addr != NULL)
|
else if (aggfns->xfn1.fn_addr != NULL)
|
||||||
args[0] = (char *) value1[i];
|
args[0] = (char *) value1[aggno];
|
||||||
else if (aggfns->xfn2.fn_addr != NULL)
|
else if (aggfns->xfn2.fn_addr != NULL)
|
||||||
args[0] = (char *) value2[i];
|
args[0] = (char *) value2[aggno];
|
||||||
else
|
else
|
||||||
elog(NOTICE, "ExecAgg: no valid transition functions??");
|
elog(NOTICE, "ExecAgg: no valid transition functions??");
|
||||||
value1[i] = (Datum) fmgr_c(&aggfns->finalfn,
|
value1[aggno] = (Datum) fmgr_c(&aggfns->finalfn,
|
||||||
(FmgrValues *) args, &(nulls[i]));
|
(FmgrValues *) args, &(nulls[aggno]));
|
||||||
}
|
}
|
||||||
else if (aggfns->xfn1.fn_addr != NULL)
|
else if (aggfns->xfn1.fn_addr != NULL)
|
||||||
{
|
{
|
||||||
@ -456,9 +447,10 @@ ExecAgg(Agg *node)
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
else if (aggfns->xfn2.fn_addr != NULL)
|
else if (aggfns->xfn2.fn_addr != NULL)
|
||||||
value1[i] = value2[i];
|
value1[aggno] = value2[aggno];
|
||||||
else
|
else
|
||||||
elog(ERROR, "ExecAgg: no valid transition functions??");
|
elog(ERROR, "ExecAgg: no valid transition functions??");
|
||||||
|
aggno++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -494,11 +486,12 @@ ExecAgg(Agg *node)
|
|||||||
if(node->plan.qual != NULL){
|
if(node->plan.qual != NULL){
|
||||||
qual_result = ExecQual(fix_opids(node->plan.qual), econtext);
|
qual_result = ExecQual(fix_opids(node->plan.qual), econtext);
|
||||||
}
|
}
|
||||||
|
else qual_result = false;
|
||||||
|
|
||||||
if (oneTuple)
|
if (oneTuple)
|
||||||
pfree(oneTuple);
|
pfree(oneTuple);
|
||||||
}
|
}
|
||||||
while ((node->plan.qual != NULL) && (qual_result != true));
|
while (node->plan.qual != NULL && qual_result != true);
|
||||||
|
|
||||||
return resultSlot;
|
return resultSlot;
|
||||||
}
|
}
|
||||||
@ -516,7 +509,7 @@ ExecInitAgg(Agg *node, EState *estate, Plan *parent)
|
|||||||
AggState *aggstate;
|
AggState *aggstate;
|
||||||
Plan *outerPlan;
|
Plan *outerPlan;
|
||||||
ExprContext *econtext;
|
ExprContext *econtext;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* assign the node's execution state
|
* assign the node's execution state
|
||||||
*/
|
*/
|
||||||
@ -528,7 +521,7 @@ ExecInitAgg(Agg *node, EState *estate, Plan *parent)
|
|||||||
aggstate = makeNode(AggState);
|
aggstate = makeNode(AggState);
|
||||||
node->aggstate = aggstate;
|
node->aggstate = aggstate;
|
||||||
aggstate->agg_done = FALSE;
|
aggstate->agg_done = FALSE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* assign node's base id and create expression context
|
* assign node's base id and create expression context
|
||||||
*/
|
*/
|
||||||
@ -628,7 +621,7 @@ ExecEndAgg(Agg *node)
|
|||||||
*/
|
*/
|
||||||
static Datum
|
static Datum
|
||||||
aggGetAttr(TupleTableSlot *slot,
|
aggGetAttr(TupleTableSlot *slot,
|
||||||
Aggref *agg,
|
Aggref *aggref,
|
||||||
bool *isNull)
|
bool *isNull)
|
||||||
{
|
{
|
||||||
Datum result;
|
Datum result;
|
||||||
@ -645,7 +638,7 @@ aggGetAttr(TupleTableSlot *slot,
|
|||||||
tuple_type = slot->ttc_tupleDescriptor;
|
tuple_type = slot->ttc_tupleDescriptor;
|
||||||
buffer = slot->ttc_buffer;
|
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
|
* If the attribute number is invalid, then we are supposed to return
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.54 1999/01/24 00:28:19 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.55 1999/01/25 18:02:14 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -506,7 +506,7 @@ _copyAgg(Agg *from)
|
|||||||
|
|
||||||
CopyPlanFields((Plan *) from, (Plan *) newnode);
|
CopyPlanFields((Plan *) from, (Plan *) newnode);
|
||||||
|
|
||||||
newnode->aggs = set_agg_tlist_references(newnode);
|
newnode->aggs = get_agg_tlist_references(newnode);
|
||||||
Node_Copy(from, newnode, aggstate);
|
Node_Copy(from, newnode, aggstate);
|
||||||
|
|
||||||
return newnode;
|
return newnode;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.37 1999/01/25 12:01:04 vadim Exp $
|
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.38 1999/01/25 18:02:15 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -249,7 +249,7 @@ union_planner(Query *parse)
|
|||||||
{
|
{
|
||||||
int old_length=0, new_length=0;
|
int old_length=0, new_length=0;
|
||||||
|
|
||||||
/* Create the AGG node but use 'tlist' not 'new_tlist' as target list because we
|
/* Create the Agg node but use 'tlist' not 'new_tlist' as target list because we
|
||||||
* don't want the additional attributes (only used for the havingQual, see above)
|
* don't want the additional attributes (only used for the havingQual, see above)
|
||||||
* to show up in the result */
|
* to show up in the result */
|
||||||
result_plan = (Plan *) make_agg(tlist, result_plan);
|
result_plan = (Plan *) make_agg(tlist, result_plan);
|
||||||
@ -259,7 +259,7 @@ union_planner(Query *parse)
|
|||||||
* the result tuple of the subplans.
|
* the result tuple of the subplans.
|
||||||
*/
|
*/
|
||||||
((Agg *) result_plan)->aggs =
|
((Agg *) result_plan)->aggs =
|
||||||
set_agg_tlist_references((Agg *) result_plan);
|
get_agg_tlist_references((Agg *) result_plan);
|
||||||
|
|
||||||
|
|
||||||
/***S*H***/
|
/***S*H***/
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.32 1999/01/24 00:28:20 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.33 1999/01/25 18:02:18 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -700,7 +700,7 @@ OperandIsInner(Node *opnd, int inner_relid)
|
|||||||
|
|
||||||
/*---------------------------------------------------------
|
/*---------------------------------------------------------
|
||||||
*
|
*
|
||||||
* set_agg_tlist_references -
|
* get_agg_tlist_references -
|
||||||
* changes the target list of an Agg node so that it points to
|
* changes the target list of an Agg node so that it points to
|
||||||
* the tuples returned by its left tree subplan.
|
* the tuples returned by its left tree subplan.
|
||||||
*
|
*
|
||||||
@ -708,7 +708,7 @@ OperandIsInner(Node *opnd, int inner_relid)
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
List *
|
List *
|
||||||
set_agg_tlist_references(Agg *aggNode)
|
get_agg_tlist_references(Agg *aggNode)
|
||||||
{
|
{
|
||||||
List *aggTargetList;
|
List *aggTargetList;
|
||||||
List *subplanTargetList;
|
List *subplanTargetList;
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/rewrite/Attic/locks.c,v 1.15 1999/01/24 00:28:30 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/rewrite/Attic/locks.c,v 1.16 1999/01/25 18:02:18 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -68,9 +68,9 @@ nodeThisLockWasTriggered(Node *node, int varno, AttrNumber attnum,
|
|||||||
break;
|
break;
|
||||||
case T_Aggref:
|
case T_Aggref:
|
||||||
{
|
{
|
||||||
Aggref *agg = (Aggref *) node;
|
Aggref *aggref = (Aggref *) node;
|
||||||
|
|
||||||
return nodeThisLockWasTriggered(agg->target, varno, attnum,
|
return nodeThisLockWasTriggered(aggref->target, varno, attnum,
|
||||||
sublevels_up);
|
sublevels_up);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.31 1999/01/25 12:01:14 vadim Exp $
|
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.32 1999/01/25 18:02:20 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -162,10 +162,10 @@ rangeTableEntry_used(Node *node, int rt_index, int sublevels_up)
|
|||||||
|
|
||||||
case T_Aggref:
|
case T_Aggref:
|
||||||
{
|
{
|
||||||
Aggref *agg = (Aggref *)node;
|
Aggref *aggref = (Aggref *)node;
|
||||||
|
|
||||||
return rangeTableEntry_used(
|
return rangeTableEntry_used(
|
||||||
(Node *)(agg->target),
|
(Node *)(aggref->target),
|
||||||
rt_index,
|
rt_index,
|
||||||
sublevels_up);
|
sublevels_up);
|
||||||
}
|
}
|
||||||
@ -398,10 +398,10 @@ attribute_used(Node *node, int rt_index, int attno, int sublevels_up)
|
|||||||
|
|
||||||
case T_Aggref:
|
case T_Aggref:
|
||||||
{
|
{
|
||||||
Aggref *agg = (Aggref *)node;
|
Aggref *aggref = (Aggref *)node;
|
||||||
|
|
||||||
return attribute_used(
|
return attribute_used(
|
||||||
(Node *)(agg->target),
|
(Node *)(aggref->target),
|
||||||
rt_index,
|
rt_index,
|
||||||
attno,
|
attno,
|
||||||
sublevels_up);
|
sublevels_up);
|
||||||
@ -607,10 +607,10 @@ modifyAggrefUplevel(Node *node)
|
|||||||
|
|
||||||
case T_Aggref:
|
case T_Aggref:
|
||||||
{
|
{
|
||||||
Aggref *agg = (Aggref *)node;
|
Aggref *aggref = (Aggref *)node;
|
||||||
|
|
||||||
modifyAggrefUplevel(
|
modifyAggrefUplevel(
|
||||||
(Node *)(agg->target));
|
(Node *)(aggref->target));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -743,10 +743,10 @@ modifyAggrefChangeVarnodes(Node **nodePtr, int rt_index, int new_index, int subl
|
|||||||
|
|
||||||
case T_Aggref:
|
case T_Aggref:
|
||||||
{
|
{
|
||||||
Aggref *agg = (Aggref *)node;
|
Aggref *aggref = (Aggref *)node;
|
||||||
|
|
||||||
modifyAggrefChangeVarnodes(
|
modifyAggrefChangeVarnodes(
|
||||||
(Node **)(&(agg->target)),
|
(Node **)(&(aggref->target)),
|
||||||
rt_index,
|
rt_index,
|
||||||
new_index,
|
new_index,
|
||||||
sublevels_up);
|
sublevels_up);
|
||||||
@ -933,12 +933,12 @@ modifyAggrefDropQual(Node **nodePtr, Node *orignode, Expr *expr)
|
|||||||
|
|
||||||
case T_Aggref:
|
case T_Aggref:
|
||||||
{
|
{
|
||||||
Aggref *agg = (Aggref *)node;
|
Aggref *aggref = (Aggref *)node;
|
||||||
Aggref *oagg = (Aggref *)orignode;
|
Aggref *oaggref = (Aggref *)orignode;
|
||||||
|
|
||||||
modifyAggrefDropQual(
|
modifyAggrefDropQual(
|
||||||
(Node **)(&(agg->target)),
|
(Node **)(&(aggref->target)),
|
||||||
(Node *)(oagg->target),
|
(Node *)(oaggref->target),
|
||||||
expr);
|
expr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1378,10 +1378,10 @@ apply_RIR_adjust_sublevel(Node *node, int sublevels_up)
|
|||||||
|
|
||||||
case T_Aggref:
|
case T_Aggref:
|
||||||
{
|
{
|
||||||
Aggref *agg = (Aggref *)node;
|
Aggref *aggref = (Aggref *)node;
|
||||||
|
|
||||||
apply_RIR_adjust_sublevel(
|
apply_RIR_adjust_sublevel(
|
||||||
(Node *)(agg->target),
|
(Node *)(aggref->target),
|
||||||
sublevels_up);
|
sublevels_up);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1527,10 +1527,10 @@ apply_RIR_view(Node **nodePtr, int rt_index, RangeTblEntry *rte, List *tlist, in
|
|||||||
|
|
||||||
case T_Aggref:
|
case T_Aggref:
|
||||||
{
|
{
|
||||||
Aggref *agg = (Aggref *)node;
|
Aggref *aggref = (Aggref *)node;
|
||||||
|
|
||||||
apply_RIR_view(
|
apply_RIR_view(
|
||||||
(Node **)(&(agg->target)),
|
(Node **)(&(aggref->target)),
|
||||||
rt_index,
|
rt_index,
|
||||||
rte,
|
rte,
|
||||||
tlist,
|
tlist,
|
||||||
@ -1928,10 +1928,10 @@ fireRIRonSubselect(Node *node)
|
|||||||
|
|
||||||
case T_Aggref:
|
case T_Aggref:
|
||||||
{
|
{
|
||||||
Aggref *agg = (Aggref *)node;
|
Aggref *aggref = (Aggref *)node;
|
||||||
|
|
||||||
fireRIRonSubselect(
|
fireRIRonSubselect(
|
||||||
(Node *)(agg->target));
|
(Node *)(aggref->target));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.25 1999/01/24 00:28:31 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.26 1999/01/25 18:02:22 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -55,10 +55,10 @@ OffsetVarNodes(Node *node, int offset, int sublevels_up)
|
|||||||
|
|
||||||
case T_Aggref:
|
case T_Aggref:
|
||||||
{
|
{
|
||||||
Aggref *agg = (Aggref *)node;
|
Aggref *aggref = (Aggref *)node;
|
||||||
|
|
||||||
OffsetVarNodes(
|
OffsetVarNodes(
|
||||||
(Node *)(agg->target),
|
(Node *)(aggref->target),
|
||||||
offset,
|
offset,
|
||||||
sublevels_up);
|
sublevels_up);
|
||||||
}
|
}
|
||||||
@ -273,10 +273,10 @@ ChangeVarNodes(Node *node, int rt_index, int new_index, int sublevels_up)
|
|||||||
|
|
||||||
case T_Aggref:
|
case T_Aggref:
|
||||||
{
|
{
|
||||||
Aggref *agg = (Aggref *)node;
|
Aggref *aggref = (Aggref *)node;
|
||||||
|
|
||||||
ChangeVarNodes(
|
ChangeVarNodes(
|
||||||
(Node *)(agg->target),
|
(Node *)(aggref->target),
|
||||||
rt_index,
|
rt_index,
|
||||||
new_index,
|
new_index,
|
||||||
sublevels_up);
|
sublevels_up);
|
||||||
@ -748,9 +748,9 @@ nodeHandleRIRAttributeRule(Node **nodePtr,
|
|||||||
break;
|
break;
|
||||||
case T_Aggref:
|
case T_Aggref:
|
||||||
{
|
{
|
||||||
Aggref *agg = (Aggref *) node;
|
Aggref *aggref = (Aggref *) node;
|
||||||
|
|
||||||
nodeHandleRIRAttributeRule(&agg->target, rtable, targetlist,
|
nodeHandleRIRAttributeRule(&aggref->target, rtable, targetlist,
|
||||||
rt_index, attr_num, modified, badsql,
|
rt_index, attr_num, modified, badsql,
|
||||||
sublevels_up);
|
sublevels_up);
|
||||||
}
|
}
|
||||||
@ -913,9 +913,9 @@ nodeHandleViewRule(Node **nodePtr,
|
|||||||
break;
|
break;
|
||||||
case T_Aggref:
|
case T_Aggref:
|
||||||
{
|
{
|
||||||
Aggref *agg = (Aggref *) node;
|
Aggref *aggref = (Aggref *) node;
|
||||||
|
|
||||||
nodeHandleViewRule(&(agg->target), rtable, targetlist,
|
nodeHandleViewRule(&(aggref->target), rtable, targetlist,
|
||||||
rt_index, modified, sublevels_up);
|
rt_index, modified, sublevels_up);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* out of it's tuple
|
* out of it's tuple
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.7 1999/01/24 00:28:32 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.8 1999/01/25 18:02:23 momjian Exp $
|
||||||
*
|
*
|
||||||
* This software is copyrighted by Jan Wieck - Hamburg.
|
* This software is copyrighted by Jan Wieck - Hamburg.
|
||||||
*
|
*
|
||||||
@ -1247,13 +1247,13 @@ get_rule_expr(QryHier *qh, int rt_index, Node *node, bool varprefix)
|
|||||||
|
|
||||||
case T_Aggref:
|
case T_Aggref:
|
||||||
{
|
{
|
||||||
Aggref *agg = (Aggref *) node;
|
Aggref *aggref = (Aggref *) node;
|
||||||
|
|
||||||
strcat(buf, "\"");
|
strcat(buf, "\"");
|
||||||
strcat(buf, agg->aggname);
|
strcat(buf, aggref->aggname);
|
||||||
strcat(buf, "\"(");
|
strcat(buf, "\"(");
|
||||||
strcat(buf, get_rule_expr(qh, rt_index,
|
strcat(buf, get_rule_expr(qh, rt_index,
|
||||||
(Node *) (agg->target), varprefix));
|
(Node *) (aggref->target), varprefix));
|
||||||
strcat(buf, ")");
|
strcat(buf, ")");
|
||||||
return pstrdup(buf);
|
return pstrdup(buf);
|
||||||
}
|
}
|
||||||
@ -1729,10 +1729,10 @@ check_if_rte_used(int rt_index, Node *node, int sup)
|
|||||||
|
|
||||||
case T_Aggref:
|
case T_Aggref:
|
||||||
{
|
{
|
||||||
Aggref *agg = (Aggref *) node;
|
Aggref *aggref = (Aggref *) node;
|
||||||
|
|
||||||
return check_if_rte_used(rt_index,
|
return check_if_rte_used(rt_index,
|
||||||
(Node *) (agg->target), sup);
|
(Node *) (aggref->target), sup);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: planmain.h,v 1.17 1998/10/08 18:30:34 momjian Exp $
|
* $Id: planmain.h,v 1.18 1999/01/25 18:02:28 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -54,7 +54,7 @@ extern List *join_references(List *clauses, List *outer_tlist,
|
|||||||
List *inner_tlist);
|
List *inner_tlist);
|
||||||
extern List *index_outerjoin_references(List *inner_indxqual,
|
extern List *index_outerjoin_references(List *inner_indxqual,
|
||||||
List *outer_tlist, Index inner_relid);
|
List *outer_tlist, Index inner_relid);
|
||||||
extern List *set_agg_tlist_references(Agg *aggNode);
|
extern List *get_agg_tlist_references(Agg *aggNode);
|
||||||
extern void set_agg_agglist_references(Agg *aggNode);
|
extern void set_agg_agglist_references(Agg *aggNode);
|
||||||
extern void del_agg_tlist_references(List *tlist);
|
extern void del_agg_tlist_references(List *tlist);
|
||||||
extern List *check_having_qual_for_aggs(Node *clause,
|
extern List *check_having_qual_for_aggs(Node *clause,
|
||||||
|
@ -10,6 +10,9 @@ SELECT ('tomorrow'::datetime = ('yesterday'::datetime + '2 days'::timespan)) as
|
|||||||
SELECT ('current'::datetime = 'now'::datetime) as "True";
|
SELECT ('current'::datetime = 'now'::datetime) as "True";
|
||||||
SELECT ('now'::datetime - 'current'::datetime) AS "ZeroSecs";
|
SELECT ('now'::datetime - 'current'::datetime) AS "ZeroSecs";
|
||||||
|
|
||||||
|
SET DateStyle = 'Postgres,noneuropean';
|
||||||
|
SELECT datetime('1994-01-01', '11:00') AS "Jan_01_1994_11am";
|
||||||
|
|
||||||
CREATE TABLE DATETIME_TBL( d1 datetime);
|
CREATE TABLE DATETIME_TBL( d1 datetime);
|
||||||
|
|
||||||
INSERT INTO DATETIME_TBL VALUES ('current');
|
INSERT INTO DATETIME_TBL VALUES ('current');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user