1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +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 * 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 void
RemoveAggregate(char *aggName) RemoveAggregate(char *aggName, char *aggType)
{ {
Relation relation; Relation relation;
HeapScanDesc scan; HeapScanDesc scan;
HeapTuple tup; HeapTuple tup;
ItemPointerData itemPointerData; ItemPointerData itemPointerData;
static ScanKeyData key[3] = { char *userName;
{ 0, Anum_pg_aggregate_aggname, NameEqualRegProcedure } 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); 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); tup = heap_getnext(scan, 0, (Buffer *) 0);
if (!HeapTupleIsValid(tup)) { if (!HeapTupleIsValid(tup)) {
heap_endscan(scan); heap_endscan(scan);
heap_close(relation); heap_close(relation);
elog(WARN, "RemoveAggregate: aggregate '%s' does not exist", if (aggType) {
aggName); 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); ItemPointerCopy(&tup->t_ctid, &itemPointerData);
heap_delete(relation, &itemPointerData); heap_delete(relation, &itemPointerData);

View File

@ -6,7 +6,7 @@
* *
* *
* IDENTIFICATION * 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); 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 * 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 * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
@ -104,8 +104,8 @@ static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
ExtendStmt, FetchStmt, GrantStmt, ExtendStmt, FetchStmt, GrantStmt,
IndexStmt, MoveStmt, ListenStmt, OptimizableStmt, IndexStmt, MoveStmt, ListenStmt, OptimizableStmt,
ProcedureStmt, PurgeStmt, ProcedureStmt, PurgeStmt,
RecipeStmt, RemoveOperStmt, RemoveFuncStmt, RemoveStmt, RenameStmt, RecipeStmt, RemoveAggrStmt, RemoveOperStmt, RemoveFuncStmt, RemoveStmt,
RevokeStmt, RuleStmt, TransactionStmt, ViewStmt, LoadStmt, RenameStmt, RevokeStmt, RuleStmt, TransactionStmt, ViewStmt, LoadStmt,
CreatedbStmt, DestroydbStmt, VacuumStmt, RetrieveStmt, CursorStmt, CreatedbStmt, DestroydbStmt, VacuumStmt, RetrieveStmt, CursorStmt,
ReplaceStmt, AppendStmt, NotifyStmt, DeleteStmt, ClusterStmt, ReplaceStmt, AppendStmt, NotifyStmt, DeleteStmt, ClusterStmt,
ExplainStmt, VariableSetStmt, VariableShowStmt, VariableResetStmt 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, %type <str> relation_name, copy_file_name, copy_delimiter, def_name,
database_name, access_method_clause, access_method, attr_name, database_name, access_method_clause, access_method, attr_name,
class, index_name, name, file_name, recipe_name, class, index_name, name, file_name, recipe_name,
var_name var_name, aggr_argtype
%type <str> opt_id, opt_portal_name, %type <str> opt_id, opt_portal_name,
before_clause, after_clause, all_Op, MathOp, opt_name, opt_unique, 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, %type <list> stmtblock, stmtmulti,
relation_name_list, OptTableElementList, relation_name_list, OptTableElementList,
tableElementList, OptInherit, definition, 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, oper_argtypes, OptStmtList, OptStmtBlock, OptStmtMulti,
opt_column_list, columnList, opt_va_list, va_list, opt_column_list, columnList, opt_va_list, va_list,
sort_clause, sortby_list, index_params, index_list, sort_clause, sortby_list, index_params, index_list,
@ -262,6 +262,7 @@ stmt : AddAttrStmt
| ProcedureStmt | ProcedureStmt
| PurgeStmt | PurgeStmt
| RecipeStmt | RecipeStmt
| RemoveAggrStmt
| RemoveOperStmt | RemoveOperStmt
| RemoveFuncStmt | RemoveFuncStmt
| RemoveStmt | RemoveStmt
@ -921,6 +922,8 @@ after_clause: AFTER date { $$ = $2; }
* *
* remove function <funcname> * remove function <funcname>
* (REMOVE FUNCTION "funcname" (arg1, arg2, ...)) * (REMOVE FUNCTION "funcname" (arg1, arg2, ...))
* remove aggregate <aggname>
* (REMOVE AGGREGATE "aggname" "aggtype")
* remove operator <opname> * remove operator <opname>
* (REMOVE OPERATOR "opname" (leftoperand_typ rightoperand_typ)) * (REMOVE OPERATOR "opname" (leftoperand_typ rightoperand_typ))
* remove type <typename> * remove type <typename>
@ -939,13 +942,25 @@ RemoveStmt: DROP remove_type name
} }
; ;
remove_type: AGGREGATE { $$ = AGGREGATE; } remove_type: Type { $$ = P_TYPE; }
| Type { $$ = P_TYPE; } | INDEX { $$ = INDEX; }
| INDEX { $$ = INDEX; } | RULE { $$ = RULE; }
| RULE { $$ = RULE; } | VIEW { $$ = VIEW; }
| 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: DROP FUNCTION name '(' func_argtypes ')'
{ {
RemoveFuncStmt *n = makeNode(RemoveFuncStmt); RemoveFuncStmt *n = makeNode(RemoveFuncStmt);

View File

@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* See acl.h. * See acl.h.
@ -29,6 +29,7 @@
#include "catalog/catname.h" #include "catalog/catname.h"
#include "catalog/pg_group.h" #include "catalog/pg_group.h"
#include "catalog/pg_operator.h" #include "catalog/pg_operator.h"
#include "catalog/pg_aggregate.h"
#include "catalog/pg_proc.h" #include "catalog/pg_proc.h"
#include "catalog/pg_user.h" #include "catalog/pg_user.h"
#include "utils/syscache.h" #include "utils/syscache.h"
@ -561,3 +562,43 @@ pg_func_ownercheck(char *usename,
return(user_id == owner_id); 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 * 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(); CHECK_IF_ABORTED();
switch(stmt->removeType) { switch(stmt->removeType) {
case AGGREGATE:
RemoveAggregate(stmt->name);
break;
case INDEX: case INDEX:
relname = stmt->name; relname = stmt->name;
if (IsSystemRelationName(relname)) if (IsSystemRelationName(relname))
@ -496,6 +493,16 @@ ProcessUtility(Node *parsetree,
break; break;
} }
break; break;
case T_RemoveAggrStmt:
{
RemoveAggrStmt *stmt = (RemoveAggrStmt *)parsetree;
commandTag = "DROP";
CHECK_IF_ABORTED();
RemoveAggregate(stmt->aggname, stmt->aggtype);
}
break;
case T_RemoveFuncStmt: case T_RemoveFuncStmt:
{ {
RemoveFuncStmt *stmt = (RemoveFuncStmt *)parsetree; RemoveFuncStmt *stmt = (RemoveFuncStmt *)parsetree;

View File

@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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, extern void RemoveOperator(char *operatorName,
char *typeName1, char *typeName2); char *typeName1, char *typeName2);
extern void RemoveType(char *typeName); extern void RemoveType(char *typeName);
extern void RemoveAggregate(char *aggName); extern void RemoveAggregate(char *aggName, char *aggType);
#endif /* DEFREM_H */ #endif /* DEFREM_H */

View File

@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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_ProcedureStmt,
T_PurgeStmt, T_PurgeStmt,
T_RecipeStmt, T_RecipeStmt,
T_RemoveAggrStmt,
T_RemoveFuncStmt, T_RemoveFuncStmt,
T_RemoveOperStmt, T_RemoveOperStmt,
T_RemoveStmt, T_RemoveStmt,

View File

@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -271,6 +271,16 @@ typedef struct PurgeStmt {
char *afterDate; /* purge after this date */ char *afterDate; /* purge after this date */
} PurgeStmt; } PurgeStmt;
/* ----------------------
* Drop Aggregate Statement
* ----------------------
*/
typedef struct RemoveAggrStmt {
NodeTag type;
char *aggname; /* aggregate to drop */
char *aggtype; /* for this type */
} RemoveAggrStmt;
/* ---------------------- /* ----------------------
* Drop Function Statement * Drop Function Statement
* ---------------------- * ----------------------
@ -292,12 +302,12 @@ typedef struct RemoveOperStmt {
} RemoveOperStmt; } RemoveOperStmt;
/* ---------------------- /* ----------------------
* Drop {Aggregate|Type|Index|Rule|View} Statement * Drop {Type|Index|Rule|View} Statement
* ---------------------- * ----------------------
*/ */
typedef struct RemoveStmt { typedef struct RemoveStmt {
NodeTag type; NodeTag type;
int removeType; /* AGGREGATE|P_TYPE|INDEX|RULE|VIEW */ int removeType; /* P_TYPE|INDEX|RULE|VIEW */
char *name; /* name to drop */ char *name; /* name to drop */
} RemoveStmt; } RemoveStmt;

View File

@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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 char FindDelimiter(char *typename);
extern void op_error(char *op, Oid arg1, Oid arg2); extern void op_error(char *op, Oid arg1, Oid arg2);
extern void func_error(char *caller, char *funcname, int nargs, Oid *argtypes); 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 */ #endif /* CATALOG_UTILS_H */

View File

@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* For backward-compatability purposes we have to allow there * 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_ownercheck(char *usename, char *value, int cacheid);
extern int32 pg_func_ownercheck(char *usename, char *funcname, extern int32 pg_func_ownercheck(char *usename, char *funcname,
int nargs, Oid *arglist); int nargs, Oid *arglist);
extern int32 pg_aggr_ownercheck(char *usename, char *aggname,
Oid basetypeID);
#endif /* ACL_H */ #endif /* ACL_H */

View File

@ -1,12 +1,12 @@
.\" This is -*-nroff-*- .\" This is -*-nroff-*-
.\" XXX standard disclaimer belongs here.... .\" 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 .TH "DROP AGGREGATE" SQL 11/05/95 PostgreSQL PostgreSQL
.SH NAME .SH NAME
drop aggregate \(em remove the definition of an aggregate drop aggregate \(em remove the definition of an aggregate
.SH SYNOPSIS .SH SYNOPSIS
.nf .nf
\fBdrop aggregate\fR aggname \fBdrop aggregate\fR aggname aggtype
.fi .fi
.SH DESCRIPTION .SH DESCRIPTION
.BR "drop aggregate" .BR "drop aggregate"
@ -16,9 +16,9 @@ aggregate.
.SH EXAMPLE .SH EXAMPLE
.nf .nf
-- --
--Remove the average aggregate --Remove the average aggregate for type int4
-- --
drop aggregate avg drop aggregate avg int4
.fi .fi
.SH "SEE ALSO" .SH "SEE ALSO"
create aggregate(l). create aggregate(l).

View File

@ -1,7 +1,7 @@
-- --
-- destroy.source -- 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 -- AGGREGATE REMOVAL
-- --
DROP AGGREGATE newavg; DROP AGGREGATE newavg int4;
DROP AGGREGATE newsum; DROP AGGREGATE newsum int4;
DROP AGGREGATE newcnt; DROP AGGREGATE newcnt int4;
-- --

View File

@ -1,7 +1,7 @@
-- --
-- errors.source -- 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 -- bad in postquel, but ok in postsql
@ -182,6 +182,15 @@ drop aggregate 314159;
-- no such aggregate -- no such aggregate
drop aggregate nonesuch; 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 -- REMOVE FUNCTION