From 5e7c0a0b9ac226add5029afe0af67409438294bc Mon Sep 17 00:00:00 2001 From: "Marc G. Fournier" Date: Thu, 22 May 1997 00:17:24 +0000 Subject: [PATCH] From: Darren King 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. --- src/backend/commands/remove.c | 83 ++++++++++++++++++++++++++++++-------- src/backend/parser/catalog_utils.c | 18 ++++++++- src/backend/parser/gram.y | 35 +++++++++++----- src/backend/tcop/aclchk.c | 43 +++++++++++++++++++- src/backend/tcop/utility.c | 15 +++++-- src/include/commands/defrem.h | 4 +- src/include/nodes/nodes.h | 3 +- src/include/nodes/parsenodes.h | 16 ++++++-- src/include/parser/catalog_utils.h | 3 +- src/include/utils/acl.h | 4 +- src/man/drop_aggregate.l | 8 ++-- src/test/regress/sql/destroy.sql | 8 ++-- src/test/regress/sql/errors.sql | 11 ++++- 13 files changed, 202 insertions(+), 49 deletions(-) diff --git a/src/backend/commands/remove.c b/src/backend/commands/remove.c index 3f57ea79bc..e3c8bdc469 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 60a4323949..e848b75e59 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 af65505946..db2932a77d 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 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 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 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 * (REMOVE FUNCTION "funcname" (arg1, arg2, ...)) + * remove aggregate + * (REMOVE AGGREGATE "aggname" "aggtype") * remove operator * (REMOVE OPERATOR "opname" (leftoperand_typ rightoperand_typ)) * remove type @@ -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 a60794af08..a94d357915 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 ee89e5b391..fc5b09b4a1 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 4d58291001..f47e7a343e 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 e63e56f251..16d50d3b70 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 d29e66bcf5..288434c785 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 98b03fe41a..4be3c7edec 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 bc4473d37d..6aa5b72b7f 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 7837dcb328..740d081c7a 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 345af37c36..4d183f3de8 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 e3a080e02a..225029e306 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 -- 2.11.0