1
0
mirror of https://github.com/postgres/postgres.git synced 2025-09-02 04:21:28 +03:00

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...
This commit is contained in:
Tom Lane
2000-07-17 03:05:41 +00:00
parent 139f19c302
commit bec98a31c5
55 changed files with 1949 additions and 1813 deletions

View File

@@ -22,7 +22,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.158 2000/07/11 13:07:17 momjian Exp $
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.159 2000/07/17 03:05:20 tgl Exp $
*
* Modifications - 6/10/96 - dave@bensoft.com - version 1.13.dhb
*
@@ -1421,22 +1421,16 @@ clearAggInfo(AggInfo *agginfo, int numArgs)
free(agginfo[i].oid);
if (agginfo[i].aggname)
free(agginfo[i].aggname);
if (agginfo[i].aggtransfn1)
free(agginfo[i].aggtransfn1);
if (agginfo[i].aggtransfn2)
free(agginfo[i].aggtransfn2);
if (agginfo[i].aggtransfn)
free(agginfo[i].aggtransfn);
if (agginfo[i].aggfinalfn)
free(agginfo[i].aggfinalfn);
if (agginfo[i].aggtranstype1)
free(agginfo[i].aggtranstype1);
if (agginfo[i].aggtranstype)
free(agginfo[i].aggtranstype);
if (agginfo[i].aggbasetype)
free(agginfo[i].aggbasetype);
if (agginfo[i].aggtranstype2)
free(agginfo[i].aggtranstype2);
if (agginfo[i].agginitval1)
free(agginfo[i].agginitval1);
if (agginfo[i].agginitval2)
free(agginfo[i].agginitval2);
if (agginfo[i].agginitval)
free(agginfo[i].agginitval);
if (agginfo[i].usename)
free(agginfo[i].usename);
}
@@ -1463,22 +1457,19 @@ getAggregates(int *numAggs)
int i_oid;
int i_aggname;
int i_aggtransfn1;
int i_aggtransfn2;
int i_aggtransfn;
int i_aggfinalfn;
int i_aggtranstype1;
int i_aggtranstype;
int i_aggbasetype;
int i_aggtranstype2;
int i_agginitval1;
int i_agginitval2;
int i_agginitval;
int i_usename;
/* find all user-defined aggregates */
appendPQExpBuffer(query,
"SELECT pg_aggregate.oid, aggname, aggtransfn1, aggtransfn2, "
"aggfinalfn, aggtranstype1, aggbasetype, aggtranstype2, "
"agginitval1, agginitval2, usename from pg_aggregate, pg_user "
"SELECT pg_aggregate.oid, aggname, aggtransfn, "
"aggfinalfn, aggtranstype, aggbasetype, "
"agginitval, usename from pg_aggregate, pg_user "
"where aggowner = usesysid");
res = PQexec(g_conn, query->data);
@@ -1497,28 +1488,22 @@ getAggregates(int *numAggs)
i_oid = PQfnumber(res, "oid");
i_aggname = PQfnumber(res, "aggname");
i_aggtransfn1 = PQfnumber(res, "aggtransfn1");
i_aggtransfn2 = PQfnumber(res, "aggtransfn2");
i_aggtransfn = PQfnumber(res, "aggtransfn");
i_aggfinalfn = PQfnumber(res, "aggfinalfn");
i_aggtranstype1 = PQfnumber(res, "aggtranstype1");
i_aggtranstype = PQfnumber(res, "aggtranstype");
i_aggbasetype = PQfnumber(res, "aggbasetype");
i_aggtranstype2 = PQfnumber(res, "aggtranstype2");
i_agginitval1 = PQfnumber(res, "agginitval1");
i_agginitval2 = PQfnumber(res, "agginitval2");
i_agginitval = PQfnumber(res, "agginitval");
i_usename = PQfnumber(res, "usename");
for (i = 0; i < ntups; i++)
{
agginfo[i].oid = strdup(PQgetvalue(res, i, i_oid));
agginfo[i].aggname = strdup(PQgetvalue(res, i, i_aggname));
agginfo[i].aggtransfn1 = strdup(PQgetvalue(res, i, i_aggtransfn1));
agginfo[i].aggtransfn2 = strdup(PQgetvalue(res, i, i_aggtransfn2));
agginfo[i].aggtransfn = strdup(PQgetvalue(res, i, i_aggtransfn));
agginfo[i].aggfinalfn = strdup(PQgetvalue(res, i, i_aggfinalfn));
agginfo[i].aggtranstype1 = strdup(PQgetvalue(res, i, i_aggtranstype1));
agginfo[i].aggtranstype = strdup(PQgetvalue(res, i, i_aggtranstype));
agginfo[i].aggbasetype = strdup(PQgetvalue(res, i, i_aggbasetype));
agginfo[i].aggtranstype2 = strdup(PQgetvalue(res, i, i_aggtranstype2));
agginfo[i].agginitval1 = strdup(PQgetvalue(res, i, i_agginitval1));
agginfo[i].agginitval2 = strdup(PQgetvalue(res, i, i_agginitval2));
agginfo[i].agginitval = strdup(PQgetvalue(res, i, i_agginitval));
agginfo[i].usename = strdup(PQgetvalue(res, i, i_usename));
}
@@ -2902,69 +2887,32 @@ dumpAggs(Archive *fout, AggInfo *agginfo, int numAggs,
PQExpBuffer q = createPQExpBuffer();
PQExpBuffer delq = createPQExpBuffer();
PQExpBuffer aggSig = createPQExpBuffer();
PQExpBuffer sfunc1 = createPQExpBuffer();
PQExpBuffer sfunc2 = createPQExpBuffer();
PQExpBuffer basetype = createPQExpBuffer();
PQExpBuffer finalfunc = createPQExpBuffer();
char comma1[2],
comma2[2];
PQExpBuffer details = createPQExpBuffer();
for (i = 0; i < numAggs; i++)
{
resetPQExpBuffer(sfunc1);
resetPQExpBuffer(sfunc2);
resetPQExpBuffer(basetype);
resetPQExpBuffer(finalfunc);
resetPQExpBuffer(details);
/* skip all the builtin oids */
if (atoi(agginfo[i].oid) < g_last_builtin_oid)
continue;
appendPQExpBuffer(basetype,
appendPQExpBuffer(details,
"BASETYPE = %s, ",
fmtId(findTypeByOid(tinfo, numTypes, agginfo[i].aggbasetype), false));
if (!(strcmp(agginfo[i].aggtransfn1, "-") == 0))
{
appendPQExpBuffer(sfunc1,
"SFUNC1 = %s, STYPE1 = %s",
agginfo[i].aggtransfn1,
fmtId(findTypeByOid(tinfo, numTypes, agginfo[i].aggtranstype1), false));
if (agginfo[i].agginitval1)
appendPQExpBuffer(sfunc1, ", INITCOND1 = '%s'",
agginfo[i].agginitval1);
appendPQExpBuffer(details,
"SFUNC = %s, STYPE = %s",
agginfo[i].aggtransfn,
fmtId(findTypeByOid(tinfo, numTypes, agginfo[i].aggtranstype), false));
}
if (!(strcmp(agginfo[i].aggtransfn2, "-") == 0))
{
appendPQExpBuffer(sfunc2,
"SFUNC2 = %s, STYPE2 = %s",
agginfo[i].aggtransfn2,
fmtId(findTypeByOid(tinfo, numTypes, agginfo[i].aggtranstype2), false));
if (agginfo[i].agginitval2)
appendPQExpBuffer(sfunc2, ", INITCOND2 = '%s'",
agginfo[i].agginitval2);
}
if (agginfo[i].agginitval)
appendPQExpBuffer(details, ", INITCOND = '%s'",
agginfo[i].agginitval);
if (!(strcmp(agginfo[i].aggfinalfn, "-") == 0))
appendPQExpBuffer(finalfunc, "FINALFUNC = %s", agginfo[i].aggfinalfn);
if (sfunc1->data[0] != '\0' && sfunc2->data[0] != '\0')
{
comma1[0] = ',';
comma1[1] = '\0';
}
else
comma1[0] = '\0';
if (finalfunc->data[0] != '\0' && (sfunc1->data[0] != '\0' || sfunc2->data[0] != '\0'))
{
comma2[0] = ',';
comma2[1] = '\0';
}
else
comma2[0] = '\0';
appendPQExpBuffer(details, ", FINALFUNC = %s",
agginfo[i].aggfinalfn);
resetPQExpBuffer(aggSig);
appendPQExpBuffer(aggSig, "%s %s", agginfo[i].aggname,
@@ -2974,14 +2922,9 @@ dumpAggs(Archive *fout, AggInfo *agginfo, int numAggs,
appendPQExpBuffer(delq, "DROP AGGREGATE %s;\n", aggSig->data);
resetPQExpBuffer(q);
appendPQExpBuffer(q, "CREATE AGGREGATE %s ( %s %s%s %s%s %s );\n",
appendPQExpBuffer(q, "CREATE AGGREGATE %s ( %s );\n",
agginfo[i].aggname,
basetype->data,
sfunc1->data,
comma1,
sfunc2->data,
comma2,
finalfunc->data);
details->data);
ArchiveEntry(fout, agginfo[i].oid, aggSig->data, "AGGREGATE", NULL,
q->data, delq->data, agginfo[i].usename, NULL, NULL);