OSDN Git Service

From: Darren King <aixssd!darrenk@abs.net>
authorMarc G. Fournier <scrappy@hub.org>
Thu, 22 May 1997 00:17:24 +0000 (00:17 +0000)
committerMarc G. Fournier <scrappy@hub.org>
Thu, 22 May 1997 00:17:24 +0000 (00:17 +0000)
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.

13 files changed:
src/backend/commands/remove.c
src/backend/parser/catalog_utils.c
src/backend/parser/gram.y
src/backend/tcop/aclchk.c
src/backend/tcop/utility.c
src/include/commands/defrem.h
src/include/nodes/nodes.h
src/include/nodes/parsenodes.h
src/include/parser/catalog_utils.h
src/include/utils/acl.h
src/man/drop_aggregate.l
src/test/regress/sql/destroy.sql
src/test/regress/sql/errors.sql

index 3f57ea7..e3c8bdc 100644 (file)
@@ -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);
index 60a4323..e848b75 100644 (file)
@@ -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)));
+    }
+}
index af65505..db2932a 100644 (file)
@@ -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);
index a60794a..a94d357 100644 (file)
@@ -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);
+}
index ee89e5b..fc5b09b 100644 (file)
@@ -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;
index 4d58291..f47e7a3 100644 (file)
@@ -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 */
index e63e56f..16d50d3 100644 (file)
@@ -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,
index d29e66b..288434c 100644 (file)
@@ -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;
 
index 98b03fe..4be3c7e 100644 (file)
@@ -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 */
index bc4473d..6aa5b72 100644 (file)
@@ -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 */
 
index 7837dcb..740d081 100644 (file)
@@ -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).
index 345af37..4d183f3 100644 (file)
@@ -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;
 
 
 --
index e3a080e..225029e 100644 (file)
@@ -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