1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-03 09:13:20 +03:00
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.
This commit is contained in:
Marc G. Fournier
1997-05-22 00:17:24 +00:00
parent 021ccf0b8c
commit 5e7c0a0b9a
13 changed files with 202 additions and 49 deletions

View 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];
key[0].sk_argument = PointerGetDatum(aggName);
/*
* 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));
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);

View 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)));
}
}

View 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);

View 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);
}

View 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;