summaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_agg.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2000-07-17 03:05:41 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2000-07-17 03:05:41 +0000
commitbec98a31c55a4f799b398d01541e68d7c086bb81 (patch)
tree14924bb5da2bc0a0f9bfac1aa5b32256fd996b9c /src/backend/parser/parse_agg.c
parent139f19c30221968e7d3bf64fe303cb41517e4601 (diff)
Revise aggregate functions per earlier discussions in pghackers.
There's now only one transition value and transition function. NULL handling in aggregates is a lot cleaner. Also, use Numeric accumulators instead of integer accumulators for sum/avg on integer datatypes --- this avoids overflow at the cost of being a little slower. Implement VARIANCE() and STDDEV() aggregates in the standard backend. Also, enable new LIKE selectivity estimators by default. Unrelated change, but as long as I had to force initdb anyway...
Diffstat (limited to 'src/backend/parser/parse_agg.c')
-rw-r--r--src/backend/parser/parse_agg.c54
1 files changed, 13 insertions, 41 deletions
diff --git a/src/backend/parser/parse_agg.c b/src/backend/parser/parse_agg.c
index 600371a09f2..bbc8f5c7076 100644
--- a/src/backend/parser/parse_agg.c
+++ b/src/backend/parser/parse_agg.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.38 2000/06/15 03:32:19 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.39 2000/07/17 03:05:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -189,18 +189,16 @@ ParseAgg(ParseState *pstate, char *aggname, Oid basetype,
{
HeapTuple theAggTuple;
Form_pg_aggregate aggform;
- Oid fintype;
- Oid xfn1;
- Oid vartype;
Aggref *aggref;
- bool usenulls = false;
theAggTuple = SearchSysCacheTuple(AGGNAME,
PointerGetDatum(aggname),
ObjectIdGetDatum(basetype),
0, 0);
+ /* shouldn't happen --- caller should have checked already */
if (!HeapTupleIsValid(theAggTuple))
- elog(ERROR, "Aggregate %s does not exist", aggname);
+ agg_error("ParseAgg", aggname, basetype);
+ aggform = (Form_pg_aggregate) GETSTRUCT(theAggTuple);
/*
* There used to be a really ugly hack for count(*) here.
@@ -209,43 +207,18 @@ ParseAgg(ParseState *pstate, char *aggname, Oid basetype,
* does the right thing. (It didn't use to do the right thing,
* because the optimizer had the wrong ideas about semantics of
* queries without explicit variables. Fixed as of Oct 1999 --- tgl.)
- *
- * Since "1" never evaluates as null, we currently have no need of the
- * "usenulls" flag, but it should be kept around; in fact, we should
- * extend the pg_aggregate table to let usenulls be specified as an
- * attribute of user-defined aggregates. In the meantime, usenulls is
- * just always set to "false".
*/
- aggform = (Form_pg_aggregate) GETSTRUCT(theAggTuple);
- fintype = aggform->aggfinaltype;
- xfn1 = aggform->aggtransfn1;
-
- /* only aggregates with transfn1 need a base type */
- if (OidIsValid(xfn1))
- {
- basetype = aggform->aggbasetype;
- vartype = exprType(lfirst(args));
- if ((basetype != vartype)
- && (!IS_BINARY_COMPATIBLE(basetype, vartype)))
- {
- Type tp1,
- tp2;
-
- tp1 = typeidType(basetype);
- tp2 = typeidType(vartype);
- elog(ERROR, "Aggregate type mismatch"
- "\n\t%s() works on %s, not on %s",
- aggname, typeTypeName(tp1), typeTypeName(tp2));
- }
- }
+ /*
+ * We assume caller has already checked that given args are compatible
+ * with the agg's basetype.
+ */
aggref = makeNode(Aggref);
aggref->aggname = pstrdup(aggname);
aggref->basetype = aggform->aggbasetype;
- aggref->aggtype = fintype;
+ aggref->aggtype = aggform->aggfinaltype;
aggref->target = lfirst(args);
- aggref->usenulls = usenulls;
aggref->aggstar = agg_star;
aggref->aggdistinct = agg_distinct;
@@ -268,10 +241,9 @@ agg_error(char *caller, char *aggname, Oid basetypeID)
*/
if (basetypeID == InvalidOid)
- elog(ERROR, "%s: aggregate '%s' for all types does not exist", caller, aggname);
+ elog(ERROR, "%s: aggregate '%s' for all types does not exist",
+ caller, aggname);
else
- {
- elog(ERROR, "%s: aggregate '%s' for '%s' does not exist", caller, aggname,
- typeidTypeName(basetypeID));
- }
+ elog(ERROR, "%s: aggregate '%s' for '%s' does not exist",
+ caller, aggname, typeidTypeName(basetypeID));
}