diff options
Diffstat (limited to 'src/backend/catalog')
| -rw-r--r-- | src/backend/catalog/aclchk.c | 30 | ||||
| -rw-r--r-- | src/backend/catalog/heap.c | 4 | ||||
| -rw-r--r-- | src/backend/catalog/indexing.c | 4 | ||||
| -rw-r--r-- | src/backend/catalog/pg_aggregate.c | 126 | ||||
| -rw-r--r-- | src/backend/catalog/pg_proc.c | 69 |
5 files changed, 73 insertions, 160 deletions
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index 04f98449bd..e440489a34 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.63 2002/04/11 05:32:02 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.64 2002/04/11 19:59:56 tgl Exp $ * * NOTES * See acl.h. @@ -733,7 +733,7 @@ pg_class_aclcheck(Oid table_oid, Oid userid, AclMode mode) Acl *acl; /* - * Validate userid, find out if he is superuser + * Validate userid, find out if he is superuser, also get usecatupd */ tuple = SearchSysCache(SHADOWSYSID, ObjectIdGetDatum(userid), @@ -1035,29 +1035,3 @@ pg_proc_ownercheck(Oid proc_oid, Oid userid) return userid == owner_id; } - -/* - * Ownership check for an aggregate function (specified by OID). - */ -bool -pg_aggr_ownercheck(Oid aggr_oid, Oid userid) -{ - HeapTuple tuple; - AclId owner_id; - - /* Superusers bypass all permission checking. */ - if (superuser_arg(userid)) - return true; - - tuple = SearchSysCache(AGGOID, - ObjectIdGetDatum(aggr_oid), - 0, 0, 0); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "pg_aggr_ownercheck: aggregate %u not found", aggr_oid); - - owner_id = ((Form_pg_aggregate) GETSTRUCT(tuple))->aggowner; - - ReleaseSysCache(tuple); - - return userid == owner_id; -} diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 61688793cf..1d225cc082 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.194 2002/03/31 06:26:29 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.195 2002/04/11 19:59:56 tgl Exp $ * * * INTERFACE ROUTINES @@ -1791,7 +1791,7 @@ cookDefault(ParseState *pstate, if (type_id != atttypid) { if (CoerceTargetExpr(pstate, expr, type_id, - atttypid, atttypmod) == NULL) + atttypid, atttypmod, false) == NULL) elog(ERROR, "Column \"%s\" is of type %s" " but default expression is of type %s" "\n\tYou will need to rewrite or cast the expression", diff --git a/src/backend/catalog/indexing.c b/src/backend/catalog/indexing.c index 7ceed7890d..f0c7ef5a0d 100644 --- a/src/backend/catalog/indexing.c +++ b/src/backend/catalog/indexing.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.87 2002/04/05 00:31:24 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.88 2002/04/11 19:59:57 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -32,7 +32,7 @@ */ char *Name_pg_aggregate_indices[Num_pg_aggregate_indices] = -{AggregateNameTypeIndex, AggregateOidIndex}; +{AggregateFnoidIndex}; char *Name_pg_am_indices[Num_pg_am_indices] = {AmNameIndex, AmOidIndex}; char *Name_pg_amop_indices[Num_pg_amop_indices] = diff --git a/src/backend/catalog/pg_aggregate.c b/src/backend/catalog/pg_aggregate.c index a9f270fccf..951e45c5ff 100644 --- a/src/backend/catalog/pg_aggregate.c +++ b/src/backend/catalog/pg_aggregate.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.43 2002/04/09 20:35:47 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.44 2002/04/11 19:59:57 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -19,15 +19,16 @@ #include "catalog/indexing.h" #include "catalog/namespace.h" #include "catalog/pg_aggregate.h" +#include "catalog/pg_language.h" #include "catalog/pg_proc.h" -#include "catalog/pg_type.h" -#include "miscadmin.h" +#include "optimizer/cost.h" #include "parser/parse_coerce.h" #include "parser/parse_func.h" #include "parser/parse_type.h" #include "utils/builtins.h" #include "utils/syscache.h" + /* * AggregateCreate */ @@ -50,7 +51,7 @@ AggregateCreate(const char *aggName, Oid finaltype; Oid fnArgs[FUNC_MAX_ARGS]; int nargs; - NameData aname; + Oid procOid; TupleDesc tupDesc; int i; @@ -61,15 +62,6 @@ AggregateCreate(const char *aggName, if (!aggtransfnName) elog(ERROR, "aggregate must have a transition function"); - /* make sure there is no existing agg of same name and base type */ - if (SearchSysCacheExists(AGGNAME, - PointerGetDatum(aggName), - ObjectIdGetDatum(aggBaseType), - 0, 0)) - elog(ERROR, - "aggregate function \"%s\" with base type %s already exists", - aggName, typeidTypeName(aggBaseType)); - /* handle transfn */ MemSet(fnArgs, 0, FUNC_MAX_ARGS * sizeof(Oid)); fnArgs[0] = aggTransType; @@ -109,8 +101,8 @@ AggregateCreate(const char *aggName, /* handle finalfn, if supplied */ if (aggfinalfnName) { + MemSet(fnArgs, 0, FUNC_MAX_ARGS * sizeof(Oid)); fnArgs[0] = aggTransType; - fnArgs[1] = 0; finalfn = LookupFuncName(aggfinalfnName, 1, fnArgs); if (!OidIsValid(finalfn)) func_error("AggregateCreate", aggfinalfnName, 1, fnArgs, NULL); @@ -132,21 +124,47 @@ AggregateCreate(const char *aggName, } Assert(OidIsValid(finaltype)); + /* + * Everything looks okay. Try to create the pg_proc entry for the + * aggregate. (This could fail if there's already a conflicting entry.) + */ + MemSet(fnArgs, 0, FUNC_MAX_ARGS * sizeof(Oid)); + fnArgs[0] = aggBaseType; + + procOid = ProcedureCreate(aggName, + aggNamespace, + false, /* no replacement */ + false, /* doesn't return a set */ + finaltype, /* returnType */ + INTERNALlanguageId, /* languageObjectId */ + "aggregate_dummy", /* placeholder proc */ + "-", /* probin */ + true, /* isAgg */ + true, /* (obsolete "trusted") */ + false, /* isImplicit */ + false, /* isStrict (not needed for agg) */ + PROVOLATILE_IMMUTABLE, /* volatility (not needed for agg) */ + BYTE_PCT, /* default cost values */ + PERBYTE_CPU, + PERCALL_CPU, + OUTIN_RATIO, + 1, /* parameterCount */ + fnArgs); /* parameterTypes */ + + /* + * Okay to create the pg_aggregate entry. + */ + /* initialize nulls and values */ for (i = 0; i < Natts_pg_aggregate; i++) { nulls[i] = ' '; values[i] = (Datum) NULL; } - namestrcpy(&aname, aggName); - values[Anum_pg_aggregate_aggname - 1] = NameGetDatum(&aname); - values[Anum_pg_aggregate_aggowner - 1] = Int32GetDatum(GetUserId()); + 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_aggbasetype - 1] = ObjectIdGetDatum(aggBaseType); values[Anum_pg_aggregate_aggtranstype - 1] = ObjectIdGetDatum(aggTransType); - values[Anum_pg_aggregate_aggfinaltype - 1] = ObjectIdGetDatum(finaltype); - if (agginitval) values[Anum_pg_aggregate_agginitval - 1] = DirectFunctionCall1(textin, CStringGetDatum(agginitval)); @@ -155,12 +173,9 @@ AggregateCreate(const char *aggName, aggdesc = heap_openr(AggregateRelationName, RowExclusiveLock); tupDesc = aggdesc->rd_att; - if (!HeapTupleIsValid(tup = heap_formtuple(tupDesc, - values, - nulls))) - elog(ERROR, "AggregateCreate: heap_formtuple failed"); - if (!OidIsValid(heap_insert(aggdesc, tup))) - elog(ERROR, "AggregateCreate: heap_insert failed"); + + tup = heap_formtuple(tupDesc, values, nulls); + heap_insert(aggdesc, tup); if (RelationGetForm(aggdesc)->relhasindex) { @@ -173,62 +188,3 @@ AggregateCreate(const char *aggName, heap_close(aggdesc, RowExclusiveLock); } - -Datum -AggNameGetInitVal(char *aggName, Oid basetype, bool *isNull) -{ - HeapTuple tup; - Oid transtype, - typinput, - typelem; - Datum textInitVal; - char *strInitVal; - Datum initVal; - - Assert(PointerIsValid(aggName)); - Assert(PointerIsValid(isNull)); - - tup = SearchSysCache(AGGNAME, - PointerGetDatum(aggName), - ObjectIdGetDatum(basetype), - 0, 0); - if (!HeapTupleIsValid(tup)) - elog(ERROR, "AggNameGetInitVal: cache lookup failed for aggregate '%s'", - aggName); - transtype = ((Form_pg_aggregate) GETSTRUCT(tup))->aggtranstype; - - /* - * initval is potentially null, so don't try to access it as a struct - * field. Must do it the hard way with SysCacheGetAttr. - */ - textInitVal = SysCacheGetAttr(AGGNAME, tup, - Anum_pg_aggregate_agginitval, - isNull); - if (*isNull) - { - ReleaseSysCache(tup); - return (Datum) 0; - } - - strInitVal = DatumGetCString(DirectFunctionCall1(textout, textInitVal)); - - ReleaseSysCache(tup); - - tup = SearchSysCache(TYPEOID, - ObjectIdGetDatum(transtype), - 0, 0, 0); - if (!HeapTupleIsValid(tup)) - elog(ERROR, "AggNameGetInitVal: cache lookup failed on aggregate transition function return type %u", transtype); - - typinput = ((Form_pg_type) GETSTRUCT(tup))->typinput; - typelem = ((Form_pg_type) GETSTRUCT(tup))->typelem; - ReleaseSysCache(tup); - - initVal = OidFunctionCall3(typinput, - CStringGetDatum(strInitVal), - ObjectIdGetDatum(typelem), - Int32GetDatum(-1)); - - pfree(strInitVal); - return initVal; -} diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c index 8cb89b979c..e9fcdc5d8e 100644 --- a/src/backend/catalog/pg_proc.c +++ b/src/backend/catalog/pg_proc.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.69 2002/04/09 20:35:47 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.70 2002/04/11 19:59:57 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -19,7 +19,6 @@ #include "catalog/indexing.h" #include "catalog/pg_language.h" #include "catalog/pg_proc.h" -#include "catalog/pg_type.h" #include "executor/executor.h" #include "miscadmin.h" #include "parser/parse_coerce.h" @@ -48,24 +47,25 @@ ProcedureCreate(const char *procedureName, Oid languageObjectId, const char *prosrc, const char *probin, + bool isAgg, bool trusted, + bool isImplicit, bool isStrict, char volatility, int32 byte_pct, int32 perbyte_cpu, int32 percall_cpu, int32 outin_ratio, - List *argList) + int parameterCount, + const Oid *parameterTypes) { int i; Relation rel; HeapTuple tup; HeapTuple oldtup; - uint16 parameterCount; char nulls[Natts_pg_proc]; Datum values[Natts_pg_proc]; char replaces[Natts_pg_proc]; - List *x; List *querytree_list; Oid typev[FUNC_MAX_ARGS]; Oid relid; @@ -79,43 +79,14 @@ ProcedureCreate(const char *procedureName, Assert(PointerIsValid(prosrc)); Assert(PointerIsValid(probin)); - parameterCount = 0; - MemSet(typev, 0, FUNC_MAX_ARGS * sizeof(Oid)); - foreach(x, argList) - { - TypeName *t = (TypeName *) lfirst(x); - Oid toid; - - if (parameterCount >= FUNC_MAX_ARGS) - elog(ERROR, "functions cannot have more than %d arguments", - FUNC_MAX_ARGS); - - toid = LookupTypeName(t); - if (OidIsValid(toid)) - { - if (!get_typisdefined(toid)) - elog(WARNING, "Argument type \"%s\" is only a shell", - TypeNameToString(t)); - } - else - { - char *typnam = TypeNameToString(t); - - if (strcmp(typnam, "opaque") == 0) - { - if (languageObjectId == SQLlanguageId) - elog(ERROR, "SQL functions cannot have arguments of type \"opaque\""); - toid = InvalidOid; - } - else - elog(ERROR, "Type \"%s\" does not exist", typnam); - } + if (parameterCount < 0 || parameterCount > FUNC_MAX_ARGS) + elog(ERROR, "functions cannot have more than %d arguments", + FUNC_MAX_ARGS); - if (t->setof) - elog(ERROR, "functions cannot accept set arguments"); - - typev[parameterCount++] = toid; - } + /* Make sure we have a zero-padded param type array */ + MemSet(typev, 0, FUNC_MAX_ARGS * sizeof(Oid)); + if (parameterCount > 0) + memcpy(typev, parameterTypes, parameterCount * sizeof(Oid)); if (languageObjectId == SQLlanguageId) { @@ -248,12 +219,13 @@ ProcedureCreate(const char *procedureName, values[i++] = ObjectIdGetDatum(procNamespace); /* pronamespace */ values[i++] = Int32GetDatum(GetUserId()); /* proowner */ values[i++] = ObjectIdGetDatum(languageObjectId); /* prolang */ - values[i++] = BoolGetDatum(false); /* proisinh (unused) */ + values[i++] = BoolGetDatum(isAgg); /* proisagg */ values[i++] = BoolGetDatum(trusted); /* proistrusted */ + values[i++] = BoolGetDatum(isImplicit); /* proimplicit */ values[i++] = BoolGetDatum(isStrict); /* proisstrict */ + values[i++] = BoolGetDatum(returnsSet); /* proretset */ values[i++] = CharGetDatum(volatility); /* provolatile */ values[i++] = UInt16GetDatum(parameterCount); /* pronargs */ - values[i++] = BoolGetDatum(returnsSet); /* proretset */ values[i++] = ObjectIdGetDatum(returnType); /* prorettype */ values[i++] = PointerGetDatum(typev); /* proargtypes */ values[i++] = Int32GetDatum(byte_pct); /* probyte_pct */ @@ -298,6 +270,17 @@ ProcedureCreate(const char *procedureName, elog(ERROR, "ProcedureCreate: cannot change return type of existing function." "\n\tUse DROP FUNCTION first."); + /* Can't change aggregate status, either */ + if (oldproc->proisagg != isAgg) + { + if (oldproc->proisagg) + elog(ERROR, "function %s is an aggregate", + procedureName); + else + elog(ERROR, "function %s is not an aggregate", + procedureName); + } + /* do not change existing permissions, either */ replaces[Anum_pg_proc_proacl-1] = ' '; |
