summaryrefslogtreecommitdiff
path: root/src/backend/catalog
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/catalog')
-rw-r--r--src/backend/catalog/aclchk.c30
-rw-r--r--src/backend/catalog/heap.c4
-rw-r--r--src/backend/catalog/indexing.c4
-rw-r--r--src/backend/catalog/pg_aggregate.c126
-rw-r--r--src/backend/catalog/pg_proc.c69
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] = ' ';