summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc G. Fournier1997-05-22 00:17:24 +0000
committerMarc G. Fournier1997-05-22 00:17:24 +0000
commit5e7c0a0b9ac226add5029afe0af67409438294bc (patch)
tree3377f3307a5aef00fc2c246070dd984256f6b117
parent021ccf0b8cde8ba2e522f0b3e0ba9c030a136cd6 (diff)
From: Darren King <[email protected]>
Subject: [PATCHES] DROP AGGREGATE patch/fix. Here's a patch that fixes the DROP AGGREGATE command to delete the desired aggregate for a specific type.
-rw-r--r--src/backend/commands/remove.c83
-rw-r--r--src/backend/parser/catalog_utils.c18
-rw-r--r--src/backend/parser/gram.y35
-rw-r--r--src/backend/tcop/aclchk.c43
-rw-r--r--src/backend/tcop/utility.c15
-rw-r--r--src/include/commands/defrem.h4
-rw-r--r--src/include/nodes/nodes.h3
-rw-r--r--src/include/nodes/parsenodes.h16
-rw-r--r--src/include/parser/catalog_utils.h3
-rw-r--r--src/include/utils/acl.h4
-rw-r--r--src/man/drop_aggregate.l8
-rw-r--r--src/test/regress/sql/destroy.sql8
-rw-r--r--src/test/regress/sql/errors.sql11
13 files changed, 202 insertions, 49 deletions
diff --git a/src/backend/commands/remove.c b/src/backend/commands/remove.c
index 3f57ea79bc0..e3c8bdc4692 100644
--- a/src/backend/commands/remove.c
+++ b/src/backend/commands/remove.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.7 1996/11/30 18:06:10 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.8 1997/05/22 00:14:32 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@@ -403,27 +403,78 @@ RemoveFunction(char *functionName, /* function name to be removed */
}
void
-RemoveAggregate(char *aggName)
+RemoveAggregate(char *aggName, char *aggType)
{
- Relation relation;
- HeapScanDesc scan;
- HeapTuple tup;
- ItemPointerData itemPointerData;
- static ScanKeyData key[3] = {
- { 0, Anum_pg_aggregate_aggname, NameEqualRegProcedure }
- };
+ Relation relation;
+ HeapScanDesc scan;
+ HeapTuple tup;
+ ItemPointerData itemPointerData;
+ char *userName;
+ char *typename;
+ Oid basetypeID = InvalidOid;
+ bool defined;
+ ScanKeyData aggregateKey[3];
+
+
+ /*
+ * if a basetype is passed in, then attempt to find an aggregate for that
+ * specific type.
+ *
+ * else if the basetype is blank, then attempt to find an aggregate with a
+ * basetype of zero. This is valid. It means that the aggregate is to apply
+ * to all basetypes. ie, a counter of some sort.
+ *
+ */
+
+ if (aggType) {
+ basetypeID = TypeGet(aggType, &defined);
+ if (!OidIsValid(basetypeID)) {
+ elog(WARN, "RemoveAggregate: type '%s' does not exist", aggType);
+ }
+ } else {
+ basetypeID = 0;
+ }
+
+/*
+#ifndef NO_SECURITY
+*/
+ userName = GetPgUserName();
+ if (!pg_aggr_ownercheck(userName, aggName, basetypeID)) {
+ if (aggType) {
+ elog(WARN, "RemoveAggregate: aggregate '%s' on type '%s': permission denied",
+ aggName, aggType);
+ } else {
+ elog(WARN, "RemoveAggregate: aggregate '%s': permission denied",
+ aggName);
+ }
+ }
+/*
+#endif
+*/
+
+ ScanKeyEntryInitialize(&aggregateKey[0], 0x0,
+ Anum_pg_aggregate_aggname,
+ NameEqualRegProcedure,
+ PointerGetDatum(aggName));
- key[0].sk_argument = PointerGetDatum(aggName);
+ ScanKeyEntryInitialize(&aggregateKey[1], 0x0,
+ Anum_pg_aggregate_aggbasetype,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(basetypeID));
- fmgr_info(key[0].sk_procedure, &key[0].sk_func, &key[0].sk_nargs);
relation = heap_openr(AggregateRelationName);
- scan = heap_beginscan(relation, 0, NowTimeQual, 1, key);
+ scan = heap_beginscan(relation, 0, NowTimeQual, 2, aggregateKey);
tup = heap_getnext(scan, 0, (Buffer *) 0);
if (!HeapTupleIsValid(tup)) {
- heap_endscan(scan);
- heap_close(relation);
- elog(WARN, "RemoveAggregate: aggregate '%s' does not exist",
- aggName);
+ heap_endscan(scan);
+ heap_close(relation);
+ if (aggType) {
+ elog(WARN, "RemoveAggregate: aggregate '%s' for '%s' does not exist",
+ aggName, aggType);
+ } else {
+ elog(WARN, "RemoveAggregate: aggregate '%s' for all types does not exist",
+ aggName);
+ }
}
ItemPointerCopy(&tup->t_ctid, &itemPointerData);
heap_delete(relation, &itemPointerData);
diff --git a/src/backend/parser/catalog_utils.c b/src/backend/parser/catalog_utils.c
index 60a4323949a..e848b75e592 100644
--- a/src/backend/parser/catalog_utils.c
+++ b/src/backend/parser/catalog_utils.c
@@ -6,7 +6,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/Attic/catalog_utils.c,v 1.17 1997/03/02 01:03:00 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/Attic/catalog_utils.c,v 1.18 1997/05/22 00:14:41 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1499,3 +1499,19 @@ func_error(char *caller, char *funcname, int nargs, Oid *argtypes)
elog(WARN, "%s: function %s(%s) does not exist", caller, funcname, p);
}
+/*
+ * Error message when aggregate lookup fails that gives details of the
+ * basetype
+ */
+void
+agg_error(char *caller, char *aggname, Oid basetypeID)
+{
+ /* basetypeID that is Invalid (zero) means aggregate over all types. (count) */
+
+ if (basetypeID == InvalidOid) {
+ elog(WARN, "%s: aggregate '%s' for all types does not exist", caller, aggname);
+ } else {
+ elog(WARN, "%s: aggregate '%s' for '%s' does not exist", caller, aggname,
+ tname(get_id_type(basetypeID)));
+ }
+}
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index af655059462..db2932a77d0 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.32 1997/04/23 06:04:42 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.33 1997/05/22 00:14:52 scrappy Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -104,8 +104,8 @@ static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
ExtendStmt, FetchStmt, GrantStmt,
IndexStmt, MoveStmt, ListenStmt, OptimizableStmt,
ProcedureStmt, PurgeStmt,
- RecipeStmt, RemoveOperStmt, RemoveFuncStmt, RemoveStmt, RenameStmt,
- RevokeStmt, RuleStmt, TransactionStmt, ViewStmt, LoadStmt,
+ RecipeStmt, RemoveAggrStmt, RemoveOperStmt, RemoveFuncStmt, RemoveStmt,
+ RenameStmt, RevokeStmt, RuleStmt, TransactionStmt, ViewStmt, LoadStmt,
CreatedbStmt, DestroydbStmt, VacuumStmt, RetrieveStmt, CursorStmt,
ReplaceStmt, AppendStmt, NotifyStmt, DeleteStmt, ClusterStmt,
ExplainStmt, VariableSetStmt, VariableShowStmt, VariableResetStmt
@@ -113,7 +113,7 @@ static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
%type <str> relation_name, copy_file_name, copy_delimiter, def_name,
database_name, access_method_clause, access_method, attr_name,
class, index_name, name, file_name, recipe_name,
- var_name
+ var_name, aggr_argtype
%type <str> opt_id, opt_portal_name,
before_clause, after_clause, all_Op, MathOp, opt_name, opt_unique,
@@ -126,7 +126,7 @@ static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
%type <list> stmtblock, stmtmulti,
relation_name_list, OptTableElementList,
tableElementList, OptInherit, definition,
- opt_with, def_args, def_name_list, func_argtypes,
+ opt_with, def_args, def_name_list, func_argtypes
oper_argtypes, OptStmtList, OptStmtBlock, OptStmtMulti,
opt_column_list, columnList, opt_va_list, va_list,
sort_clause, sortby_list, index_params, index_list,
@@ -262,6 +262,7 @@ stmt : AddAttrStmt
| ProcedureStmt
| PurgeStmt
| RecipeStmt
+ | RemoveAggrStmt
| RemoveOperStmt
| RemoveFuncStmt
| RemoveStmt
@@ -921,6 +922,8 @@ after_clause: AFTER date { $$ = $2; }
*
* remove function <funcname>
* (REMOVE FUNCTION "funcname" (arg1, arg2, ...))
+ * remove aggregate <aggname>
+ * (REMOVE AGGREGATE "aggname" "aggtype")
* remove operator <opname>
* (REMOVE OPERATOR "opname" (leftoperand_typ rightoperand_typ))
* remove type <typename>
@@ -939,13 +942,25 @@ RemoveStmt: DROP remove_type name
}
;
-remove_type: AGGREGATE { $$ = AGGREGATE; }
- | Type { $$ = P_TYPE; }
- | INDEX { $$ = INDEX; }
- | RULE { $$ = RULE; }
- | VIEW { $$ = VIEW; }
+remove_type: Type { $$ = P_TYPE; }
+ | INDEX { $$ = INDEX; }
+ | RULE { $$ = RULE; }
+ | VIEW { $$ = VIEW; }
;
+RemoveAggrStmt: DROP AGGREGATE name aggr_argtype
+ {
+ RemoveAggrStmt *n = makeNode(RemoveAggrStmt);
+ n->aggname = $3;
+ n->aggtype = $4;
+ $$ = (Node *)n;
+ }
+ ;
+
+aggr_argtype: name { $$ = $1; }
+ | '*' { $$ = NULL; }
+ ;
+
RemoveFuncStmt: DROP FUNCTION name '(' func_argtypes ')'
{
RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
diff --git a/src/backend/tcop/aclchk.c b/src/backend/tcop/aclchk.c
index a60794af085..a94d3579150 100644
--- a/src/backend/tcop/aclchk.c
+++ b/src/backend/tcop/aclchk.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/tcop/Attic/aclchk.c,v 1.9 1997/04/03 21:31:47 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/tcop/Attic/aclchk.c,v 1.10 1997/05/22 00:15:21 scrappy Exp $
*
* NOTES
* See acl.h.
@@ -29,6 +29,7 @@
#include "catalog/catname.h"
#include "catalog/pg_group.h"
#include "catalog/pg_operator.h"
+#include "catalog/pg_aggregate.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_user.h"
#include "utils/syscache.h"
@@ -561,3 +562,43 @@ pg_func_ownercheck(char *usename,
return(user_id == owner_id);
}
+
+int32
+pg_aggr_ownercheck(char *usename,
+ char *aggname,
+ Oid basetypeID)
+{
+ HeapTuple htp;
+ AclId user_id, owner_id;
+
+ htp = SearchSysCacheTuple(USENAME, PointerGetDatum(usename),
+ 0,0,0);
+ if (!HeapTupleIsValid(htp))
+ elog(WARN, "pg_aggr_ownercheck: user \"%-.*s\" not found",
+ NAMEDATALEN, usename);
+ user_id = (AclId) ((Form_pg_user) GETSTRUCT(htp))->usesysid;
+
+ /*
+ * Superusers bypass all permission-checking.
+ */
+ if (((Form_pg_user) GETSTRUCT(htp))->usesuper) {
+#ifdef ACLDEBUG_TRACE
+ elog(DEBUG, "pg_aggr_ownercheck: user \"%-.*s\" is superuser",
+ NAMEDATALEN, usename);
+#endif
+ return(1);
+ }
+
+ htp = SearchSysCacheTuple(AGGNAME,
+ PointerGetDatum(aggname),
+ PointerGetDatum(basetypeID),
+ 0,
+ 0);
+
+ if (!HeapTupleIsValid(htp))
+ agg_error("pg_aggr_ownercheck", aggname, basetypeID);
+
+ owner_id = ((Form_pg_aggregate) GETSTRUCT(htp))->aggowner;
+
+ return(user_id == owner_id);
+}
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index ee89e5b3916..fc5b09b4a1e 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.16 1997/04/23 06:09:33 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.17 1997/05/22 00:15:36 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@@ -440,9 +440,6 @@ ProcessUtility(Node *parsetree,
CHECK_IF_ABORTED();
switch(stmt->removeType) {
- case AGGREGATE:
- RemoveAggregate(stmt->name);
- break;
case INDEX:
relname = stmt->name;
if (IsSystemRelationName(relname))
@@ -496,6 +493,16 @@ ProcessUtility(Node *parsetree,
break;
}
break;
+
+ case T_RemoveAggrStmt:
+ {
+ RemoveAggrStmt *stmt = (RemoveAggrStmt *)parsetree;
+ commandTag = "DROP";
+ CHECK_IF_ABORTED();
+ RemoveAggregate(stmt->aggname, stmt->aggtype);
+ }
+ break;
+
case T_RemoveFuncStmt:
{
RemoveFuncStmt *stmt = (RemoveFuncStmt *)parsetree;
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index 4d582910015..f47e7a343ea 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: defrem.h,v 1.6 1996/11/13 20:51:18 scrappy Exp $
+ * $Id: defrem.h,v 1.7 1997/05/22 00:15:47 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@@ -48,6 +48,6 @@ extern void RemoveFunction(char *functionName, int nargs, List *argNameList);
extern void RemoveOperator(char *operatorName,
char *typeName1, char *typeName2);
extern void RemoveType(char *typeName);
-extern void RemoveAggregate(char *aggName);
+extern void RemoveAggregate(char *aggName, char *aggType);
#endif /* DEFREM_H */
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index e63e56f251d..16d50d3b701 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: nodes.h,v 1.8 1997/04/23 03:17:29 scrappy Exp $
+ * $Id: nodes.h,v 1.9 1997/05/22 00:15:58 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@@ -164,6 +164,7 @@ typedef enum NodeTag {
T_ProcedureStmt,
T_PurgeStmt,
T_RecipeStmt,
+ T_RemoveAggrStmt,
T_RemoveFuncStmt,
T_RemoveOperStmt,
T_RemoveStmt,
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index d29e66bcf53..288434c785b 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: parsenodes.h,v 1.15 1997/04/29 04:28:59 vadim Exp $
+ * $Id: parsenodes.h,v 1.16 1997/05/22 00:16:13 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@@ -272,6 +272,16 @@ typedef struct PurgeStmt {
} PurgeStmt;
/* ----------------------
+ * Drop Aggregate Statement
+ * ----------------------
+ */
+typedef struct RemoveAggrStmt {
+ NodeTag type;
+ char *aggname; /* aggregate to drop */
+ char *aggtype; /* for this type */
+} RemoveAggrStmt;
+
+/* ----------------------
* Drop Function Statement
* ----------------------
*/
@@ -292,12 +302,12 @@ typedef struct RemoveOperStmt {
} RemoveOperStmt;
/* ----------------------
- * Drop {Aggregate|Type|Index|Rule|View} Statement
+ * Drop {Type|Index|Rule|View} Statement
* ----------------------
*/
typedef struct RemoveStmt {
NodeTag type;
- int removeType; /* AGGREGATE|P_TYPE|INDEX|RULE|VIEW */
+ int removeType; /* P_TYPE|INDEX|RULE|VIEW */
char *name; /* name to drop */
} RemoveStmt;
diff --git a/src/include/parser/catalog_utils.h b/src/include/parser/catalog_utils.h
index 98b03fe41aa..4be3c7edec9 100644
--- a/src/include/parser/catalog_utils.h
+++ b/src/include/parser/catalog_utils.h
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: catalog_utils.h,v 1.8 1997/02/07 16:24:12 momjian Exp $
+ * $Id: catalog_utils.h,v 1.9 1997/05/22 00:16:28 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@@ -53,5 +53,6 @@ extern Oid get_typelem(Oid type_id);
extern char FindDelimiter(char *typename);
extern void op_error(char *op, Oid arg1, Oid arg2);
extern void func_error(char *caller, char *funcname, int nargs, Oid *argtypes);
+extern void agg_error(char *caller, char *aggname, Oid basetypeID);
#endif /* CATALOG_UTILS_H */
diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h
index bc4473d37d7..6aa5b72b7f0 100644
--- a/src/include/utils/acl.h
+++ b/src/include/utils/acl.h
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: acl.h,v 1.5 1997/03/12 20:48:48 scrappy Exp $
+ * $Id: acl.h,v 1.6 1997/05/22 00:16:41 scrappy Exp $
*
* NOTES
* For backward-compatability purposes we have to allow there
@@ -161,6 +161,8 @@ extern int32 pg_aclcheck(char *relname, char *usename, AclMode mode);
extern int32 pg_ownercheck(char *usename, char *value, int cacheid);
extern int32 pg_func_ownercheck(char *usename, char *funcname,
int nargs, Oid *arglist);
+extern int32 pg_aggr_ownercheck(char *usename, char *aggname,
+ Oid basetypeID);
#endif /* ACL_H */
diff --git a/src/man/drop_aggregate.l b/src/man/drop_aggregate.l
index 7837dcb328a..740d081c7ab 100644
--- a/src/man/drop_aggregate.l
+++ b/src/man/drop_aggregate.l
@@ -1,12 +1,12 @@
.\" This is -*-nroff-*-
.\" XXX standard disclaimer belongs here....
-.\" $Header: /cvsroot/pgsql/src/man/Attic/drop_aggregate.l,v 1.2 1996/12/11 00:27:38 momjian Exp $
+.\" $Header: /cvsroot/pgsql/src/man/Attic/drop_aggregate.l,v 1.3 1997/05/22 00:16:56 scrappy Exp $
.TH "DROP AGGREGATE" SQL 11/05/95 PostgreSQL PostgreSQL
.SH NAME
drop aggregate \(em remove the definition of an aggregate
.SH SYNOPSIS
.nf
-\fBdrop aggregate\fR aggname
+\fBdrop aggregate\fR aggname aggtype
.fi
.SH DESCRIPTION
.BR "drop aggregate"
@@ -16,9 +16,9 @@ aggregate.
.SH EXAMPLE
.nf
--
---Remove the average aggregate
+--Remove the average aggregate for type int4
--
-drop aggregate avg
+drop aggregate avg int4
.fi
.SH "SEE ALSO"
create aggregate(l).
diff --git a/src/test/regress/sql/destroy.sql b/src/test/regress/sql/destroy.sql
index 345af37c36f..4d183f3de87 100644
--- a/src/test/regress/sql/destroy.sql
+++ b/src/test/regress/sql/destroy.sql
@@ -1,7 +1,7 @@
--
-- destroy.source
--
--- $Header: /cvsroot/pgsql/src/test/regress/sql/Attic/destroy.sql,v 1.2 1997/04/27 04:35:31 scrappy Exp $
+-- $Header: /cvsroot/pgsql/src/test/regress/sql/Attic/destroy.sql,v 1.3 1997/05/22 00:17:15 scrappy Exp $
--
--
@@ -74,11 +74,11 @@ DROP TYPE widget;
--
-- AGGREGATE REMOVAL
--
-DROP AGGREGATE newavg;
+DROP AGGREGATE newavg int4;
-DROP AGGREGATE newsum;
+DROP AGGREGATE newsum int4;
-DROP AGGREGATE newcnt;
+DROP AGGREGATE newcnt int4;
--
diff --git a/src/test/regress/sql/errors.sql b/src/test/regress/sql/errors.sql
index e3a080e02a4..225029e306c 100644
--- a/src/test/regress/sql/errors.sql
+++ b/src/test/regress/sql/errors.sql
@@ -1,7 +1,7 @@
--
-- errors.source
--
--- $Header: /cvsroot/pgsql/src/test/regress/sql/errors.sql,v 1.1 1997/04/27 03:56:21 scrappy Exp $
+-- $Header: /cvsroot/pgsql/src/test/regress/sql/errors.sql,v 1.2 1997/05/22 00:17:24 scrappy Exp $
-- bad in postquel, but ok in postsql
@@ -182,6 +182,15 @@ drop aggregate 314159;
-- no such aggregate
drop aggregate nonesuch;
+-- missing aggregate type
+drop aggregate newcnt1;
+
+-- bad aggregate type
+drop aggregate newcnt nonesuch;
+
+-- no such aggregate for type
+drop aggregate newcnt float4;
+
--
-- REMOVE FUNCTION