1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-10 17:42:29 +03:00

Add aggsortop column to pg_aggregate, so that MIN/MAX optimization can

be supported for all datatypes.  Add CREATE AGGREGATE and pg_dump support
too.  Add specialized min/max aggregates for bpchar, instead of depending
on text's min/max, because otherwise the possible use of bpchar indexes
cannot be recognized.
initdb forced because of catalog changes.
This commit is contained in:
Tom Lane
2005-04-12 04:26:34 +00:00
parent 3803f24379
commit 2e7a68896b
15 changed files with 356 additions and 123 deletions

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/pg_aggregate.c,v 1.72 2005/03/31 22:46:06 tgl Exp $
* $PostgreSQL: pgsql/src/backend/catalog/pg_aggregate.c,v 1.73 2005/04/12 04:26:17 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -26,6 +26,7 @@
#include "optimizer/cost.h"
#include "parser/parse_coerce.h"
#include "parser/parse_func.h"
#include "parser/parse_oper.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
@@ -42,9 +43,10 @@ static Oid lookup_agg_function(List *fnName, int nargs, Oid *input_types,
void
AggregateCreate(const char *aggName,
Oid aggNamespace,
Oid aggBaseType,
List *aggtransfnName,
List *aggfinalfnName,
Oid aggBaseType,
List *aggsortopName,
Oid aggTransType,
const char *agginitval)
{
@@ -55,6 +57,7 @@ AggregateCreate(const char *aggName,
Form_pg_proc proc;
Oid transfn;
Oid finalfn = InvalidOid; /* can be omitted */
Oid sortop = InvalidOid; /* can be omitted */
Oid rettype;
Oid finaltype;
Oid fnArgs[2]; /* we only deal with 1- and 2-arg fns */
@@ -167,6 +170,12 @@ AggregateCreate(const char *aggName,
errdetail("An aggregate returning \"anyarray\" or \"anyelement\" "
"must have one of them as its base type.")));
/* handle sortop, if supplied */
if (aggsortopName)
sortop = LookupOperName(aggsortopName,
aggBaseType, aggBaseType,
false);
/*
* Everything looks okay. Try to create the pg_proc entry for the
* aggregate. (This could fail if there's already a conflicting
@@ -207,6 +216,7 @@ AggregateCreate(const char *aggName,
values[Anum_pg_aggregate_aggfnoid - 1] = ObjectIdGetDatum(procOid);
values[Anum_pg_aggregate_aggtransfn - 1] = ObjectIdGetDatum(transfn);
values[Anum_pg_aggregate_aggfinalfn - 1] = ObjectIdGetDatum(finalfn);
values[Anum_pg_aggregate_aggsortop - 1] = ObjectIdGetDatum(sortop);
values[Anum_pg_aggregate_aggtranstype - 1] = ObjectIdGetDatum(aggTransType);
if (agginitval)
values[Anum_pg_aggregate_agginitval - 1] =
@@ -248,6 +258,15 @@ AggregateCreate(const char *aggName,
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
/* Depends on sort operator, if any */
if (OidIsValid(sortop))
{
referenced.classId = get_system_catalog_relid(OperatorRelationName);
referenced.objectId = sortop;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
}
/*

View File

@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/aggregatecmds.c,v 1.23 2005/03/29 00:16:57 tgl Exp $
* $PostgreSQL: pgsql/src/backend/commands/aggregatecmds.c,v 1.24 2005/04/12 04:26:20 tgl Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
@@ -51,6 +51,7 @@ DefineAggregate(List *names, List *parameters)
AclResult aclresult;
List *transfuncName = NIL;
List *finalfuncName = NIL;
List *sortoperatorName = NIL;
TypeName *baseType = NULL;
TypeName *transType = NULL;
char *initval = NULL;
@@ -81,6 +82,8 @@ DefineAggregate(List *names, List *parameters)
transfuncName = defGetQualifiedName(defel);
else if (pg_strcasecmp(defel->defname, "finalfunc") == 0)
finalfuncName = defGetQualifiedName(defel);
else if (pg_strcasecmp(defel->defname, "sortop") == 0)
sortoperatorName = defGetQualifiedName(defel);
else if (pg_strcasecmp(defel->defname, "basetype") == 0)
baseType = defGetTypeName(defel);
else if (pg_strcasecmp(defel->defname, "stype") == 0)
@@ -143,9 +146,10 @@ DefineAggregate(List *names, List *parameters)
*/
AggregateCreate(aggName, /* aggregate name */
aggNamespace, /* namespace */
baseTypeId, /* type of data being aggregated */
transfuncName, /* step function name */
finalfuncName, /* final function name */
baseTypeId, /* type of data being aggregated */
sortoperatorName, /* sort operator name */
transTypeId, /* transition data type */
initval); /* initial condition */
}

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planagg.c,v 1.1 2005/04/11 23:06:55 tgl Exp $
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planagg.c,v 1.2 2005/04/12 04:26:24 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -542,7 +542,6 @@ replace_aggs_with_params_mutator(Node *node, List **context)
static Oid
fetch_agg_sort_op(Oid aggfnoid)
{
#ifdef NOT_YET
HeapTuple aggTuple;
Form_pg_aggregate aggform;
Oid aggsortop;
@@ -558,18 +557,4 @@ fetch_agg_sort_op(Oid aggfnoid)
ReleaseSysCache(aggTuple);
return aggsortop;
#else
/*
* XXX stub implementation for testing: hardwire a few cases.
*/
if (aggfnoid == 2132) /* min(int4) -> int4lt */
return 97;
if (aggfnoid == 2116) /* max(int4) -> int4gt */
return 521;
if (aggfnoid == 2145) /* min(text) -> text_lt */
return 664;
if (aggfnoid == 2129) /* max(text) -> text_gt */
return 666;
return InvalidOid;
#endif
}

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/varchar.c,v 1.108 2004/12/31 22:01:22 pgsql Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/varchar.c,v 1.109 2005/04/12 04:26:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -687,6 +687,40 @@ bpcharcmp(PG_FUNCTION_ARGS)
PG_RETURN_INT32(cmp);
}
Datum
bpchar_larger(PG_FUNCTION_ARGS)
{
BpChar *arg1 = PG_GETARG_BPCHAR_P(0);
BpChar *arg2 = PG_GETARG_BPCHAR_P(1);
int len1,
len2;
int cmp;
len1 = bcTruelen(arg1);
len2 = bcTruelen(arg2);
cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
PG_RETURN_BPCHAR_P((cmp >= 0) ? arg1 : arg2);
}
Datum
bpchar_smaller(PG_FUNCTION_ARGS)
{
BpChar *arg1 = PG_GETARG_BPCHAR_P(0);
BpChar *arg2 = PG_GETARG_BPCHAR_P(1);
int len1,
len2;
int cmp;
len1 = bcTruelen(arg1);
len2 = bcTruelen(arg2);
cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
PG_RETURN_BPCHAR_P((cmp <= 0) ? arg1 : arg2);
}
/*
* bpchar needs a specialized hash function because we want to ignore