Index: doc/src/sgml/func.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/func.sgml,v
retrieving revision 1.301
diff -c -r1.301 func.sgml
*** doc/src/sgml/func.sgml 28 Dec 2005 01:29:58 -0000 1.301
--- doc/src/sgml/func.sgml 4 Jan 2006 03:38:01 -0000
***************
*** 8961,8968 ****
The desired access privilege type
is specified by a text string, which must evaluate to one of the
values SELECT, INSERT, UPDATE,
! DELETE, RULE, REFERENCES, or
! TRIGGER. (Case of the string is not significant, however.)
An example is:
SELECT has_table_privilege('myschema.mytable', 'select');
--- 8961,8969 ----
The desired access privilege type
is specified by a text string, which must evaluate to one of the
values SELECT, INSERT, UPDATE,
! DELETE, RULE, REFERENCES,
! TRIGGER, TRUNCATE, VACUUM, or
! ANALYZE. (Case of the string is not significant, however.)
An example is:
SELECT has_table_privilege('myschema.mytable', 'select');
Index: doc/src/sgml/information_schema.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/information_schema.sgml,v
retrieving revision 1.23
diff -c -r1.23 information_schema.sgml
*** doc/src/sgml/information_schema.sgml 8 Dec 2005 20:48:10 -0000 1.23
--- doc/src/sgml/information_schema.sgml 4 Jan 2006 03:38:01 -0000
***************
*** 2395,2401 ****
Type of the privilege: SELECT,
DELETE, INSERT,
UPDATE, REFERENCES,
! RULE, or TRIGGER
--- 2395,2403 ----
Type of the privilege: SELECT,
DELETE, INSERT,
UPDATE, REFERENCES,
! RULE, TRIGGER,
! TRUNCATE, VACUUM, or
! ANALYZE.
***************
*** 3643,3649 ****
Type of the privilege: SELECT,
DELETE, INSERT,
UPDATE, REFERENCES,
! RULE, or TRIGGER
--- 3645,3653 ----
Type of the privilege: SELECT,
DELETE, INSERT,
UPDATE, REFERENCES,
! RULE, TRIGGER,
! TRUNCATE, VACUUM, or
! ANALYZE.
Index: doc/src/sgml/user-manag.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/user-manag.sgml,v
retrieving revision 1.33
diff -c -r1.33 user-manag.sgml
*** doc/src/sgml/user-manag.sgml 20 Oct 2005 19:18:00 -0000 1.33
--- doc/src/sgml/user-manag.sgml 4 Jan 2006 03:38:01 -0000
***************
*** 296,301 ****
--- 296,302 ----
There are several different kinds of privilege: SELECT>,
INSERT>, UPDATE>, DELETE>,
RULE>, REFERENCES>, TRIGGER>,
+ TRUNCATE>, VACUUM>, ANALYZE>,
CREATE>, TEMPORARY>, EXECUTE>,
and USAGE>. For more
information on the different types of privileges supported by
Index: doc/src/sgml/ref/grant.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/ref/grant.sgml,v
retrieving revision 1.50
diff -c -r1.50 grant.sgml
*** doc/src/sgml/ref/grant.sgml 20 Oct 2005 19:18:01 -0000 1.50
--- doc/src/sgml/ref/grant.sgml 4 Jan 2006 03:38:02 -0000
***************
*** 20,26 ****
! GRANT { { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER }
[,...] | ALL [ PRIVILEGES ] }
ON [ TABLE ] tablename [, ...]
TO { username | GROUP groupname | PUBLIC } [, ...] [ WITH GRANT OPTION ]
--- 20,26 ----
! GRANT { { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER | TRUNCATE | VACUUM | ANALYZE }
[,...] | ALL [ PRIVILEGES ] }
ON [ TABLE ] tablename [, ...]
TO { username | GROUP groupname | PUBLIC } [, ...] [ WITH GRANT OPTION ]
***************
*** 205,210 ****
--- 205,243 ----
+ TRUNCATE
+
+
+ Allows the truncation of the specified table. NOTE: This will NOT execute
+ triggers defined on the table. Additionally, this requires locking the table
+ exclusivly because it does not follow normal MVCC rules. See the statement.
+
+
+
+
+
+ VACUUM
+
+
+ Allows the vacuuming of the specified table. Note: This implies ANALYZE
+ rights. See the
+ statement.
+
+
+
+
+
+ ANALYZE
+
+
+ Allows the analyzing of the specified table. See the statement.
+
+
+
+
+
CREATE
***************
*** 402,408 ****
U -- USAGE
C -- CREATE
T -- TEMPORARY
! arwdRxt -- ALL PRIVILEGES (for tables)
* -- grant option for preceding privilege
/yyyy -- user who granted this privilege
--- 435,444 ----
U -- USAGE
C -- CREATE
T -- TEMPORARY
! e -- TRUNCATE
! V -- VACUUM
! A -- ANALYZE
! arwdRxteVA -- ALL PRIVILEGES (for tables)
* -- grant option for preceding privilege
/yyyy -- user who granted this privilege
Index: doc/src/sgml/ref/revoke.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/ref/revoke.sgml,v
retrieving revision 1.35
diff -c -r1.35 revoke.sgml
*** doc/src/sgml/ref/revoke.sgml 20 Oct 2005 19:18:01 -0000 1.35
--- doc/src/sgml/ref/revoke.sgml 4 Jan 2006 03:38:02 -0000
***************
*** 21,27 ****
REVOKE [ GRANT OPTION FOR ]
! { { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER }
[,...] | ALL [ PRIVILEGES ] }
ON [ TABLE ] tablename [, ...]
FROM { username | GROUP groupname | PUBLIC } [, ...]
--- 21,27 ----
REVOKE [ GRANT OPTION FOR ]
! { { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER | TRUNCATE | VACUUM | ANALYZE }
[,...] | ALL [ PRIVILEGES ] }
ON [ TABLE ] tablename [, ...]
FROM { username | GROUP groupname | PUBLIC } [, ...]
Index: src/backend/catalog/aclchk.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/catalog/aclchk.c,v
retrieving revision 1.123
diff -c -r1.123 aclchk.c
*** src/backend/catalog/aclchk.c 1 Dec 2005 02:03:00 -0000 1.123
--- src/backend/catalog/aclchk.c 4 Jan 2006 03:38:02 -0000
***************
*** 1286,1291 ****
--- 1286,1297 ----
return ACL_CREATE_TEMP;
if (strcmp(privname, "temp") == 0)
return ACL_CREATE_TEMP;
+ if (strcmp(privname, "truncate") == 0)
+ return ACL_TRUNCATE;
+ if (strcmp(privname, "vacuum") == 0)
+ return ACL_VACUUM;
+ if (strcmp(privname, "analyze") == 0)
+ return ACL_ANALYZE;
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("unrecognized privilege type \"%s\"", privname)));
***************
*** 1319,1324 ****
--- 1325,1336 ----
return "CREATE";
case ACL_CREATE_TEMP:
return "TEMP";
+ case ACL_TRUNCATE:
+ return "TRUNCATE";
+ case ACL_VACUUM:
+ return "VACUUM";
+ case ACL_ANALYZE:
+ return "ANALYZE";
default:
elog(ERROR, "unrecognized privilege: %d", (int) privilege);
}
***************
*** 1502,1508 ****
* protected in this way. Assume the view rules can take care of
* themselves.
*/
! if ((mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE)) &&
IsSystemClass(classForm) &&
classForm->relkind != RELKIND_VIEW &&
!has_rolcatupdate(roleid) &&
--- 1514,1520 ----
* protected in this way. Assume the view rules can take care of
* themselves.
*/
! if ((mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE)) &&
IsSystemClass(classForm) &&
classForm->relkind != RELKIND_VIEW &&
!has_rolcatupdate(roleid) &&
***************
*** 1511,1517 ****
#ifdef ACLDEBUG
elog(DEBUG2, "permission denied for system catalog update");
#endif
! mask &= ~(ACL_INSERT | ACL_UPDATE | ACL_DELETE);
}
/*
--- 1523,1529 ----
#ifdef ACLDEBUG
elog(DEBUG2, "permission denied for system catalog update");
#endif
! mask &= ~(ACL_INSERT | ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE);
}
/*
Index: src/backend/commands/analyze.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/analyze.c,v
retrieving revision 1.90
diff -c -r1.90 analyze.c
*** src/backend/commands/analyze.c 22 Nov 2005 18:17:08 -0000 1.90
--- src/backend/commands/analyze.c 4 Jan 2006 03:38:02 -0000
***************
*** 112,117 ****
--- 112,118 ----
double totalrows,
totaldeadrows;
HeapTuple *rows;
+ AclResult aclresult;
if (vacstmt->verbose)
elevel = INFO;
***************
*** 146,158 ****
*/
onerel = relation_open(relid, AccessShareLock);
! if (!(pg_class_ownercheck(RelationGetRelid(onerel), GetUserId()) ||
(pg_database_ownercheck(MyDatabaseId, GetUserId()) && !onerel->rd_rel->relisshared)))
{
/* No need for a WARNING if we already complained during VACUUM */
if (!vacstmt->vacuum)
ereport(WARNING,
! (errmsg("skipping \"%s\" --- only table or database owner can analyze it",
RelationGetRelationName(onerel))));
relation_close(onerel, AccessShareLock);
return;
--- 147,160 ----
*/
onerel = relation_open(relid, AccessShareLock);
! aclresult = pg_class_aclcheck(RelationGetRelid(onerel), GetUserId(), ACL_ANALYZE);
! if (!((aclresult == ACLCHECK_OK) ||
(pg_database_ownercheck(MyDatabaseId, GetUserId()) && !onerel->rd_rel->relisshared)))
{
/* No need for a WARNING if we already complained during VACUUM */
if (!vacstmt->vacuum)
ereport(WARNING,
! (errmsg("skipping \"%s\" --- only user with ANALYZE privilege or database owner can analyze it",
RelationGetRelationName(onerel))));
relation_close(onerel, AccessShareLock);
return;
Index: src/backend/commands/tablecmds.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/tablecmds.c,v
retrieving revision 1.176
diff -c -r1.176 tablecmds.c
*** src/backend/commands/tablecmds.c 22 Nov 2005 18:17:09 -0000 1.176
--- src/backend/commands/tablecmds.c 4 Jan 2006 03:38:02 -0000
***************
*** 544,549 ****
--- 544,550 ----
{
RangeVar *rv = lfirst(cell);
Relation rel;
+ AclResult aclresult;
/* Grab exclusive lock in preparation for truncate */
rel = heap_openrv(rv, AccessExclusiveLock);
***************
*** 556,564 ****
RelationGetRelationName(rel))));
/* Permissions checks */
! if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
! aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
! RelationGetRelationName(rel));
if (!allowSystemTableMods && IsSystemRelation(rel))
ereport(ERROR,
--- 557,565 ----
RelationGetRelationName(rel))));
/* Permissions checks */
! aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(), ACL_TRUNCATE);
! if (aclresult != ACLCHECK_OK)
! aclcheck_error(aclresult, ACL_KIND_CLASS, RelationGetRelationName(rel));
if (!allowSystemTableMods && IsSystemRelation(rel))
ereport(ERROR,
Index: src/backend/commands/vacuum.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/vacuum.c,v
retrieving revision 1.319
diff -c -r1.319 vacuum.c
*** src/backend/commands/vacuum.c 22 Nov 2005 18:17:09 -0000 1.319
--- src/backend/commands/vacuum.c 4 Jan 2006 03:38:02 -0000
***************
*** 948,953 ****
--- 948,954 ----
LockRelId onerelid;
Oid toast_relid;
bool result;
+ AclResult aclresult;
/* Begin a transaction for vacuuming this relation */
StartTransactionCommand();
***************
*** 989,1008 ****
/*
* Open the class, get an appropriate lock on it, and check permissions.
*
! * We allow the user to vacuum a table if he is superuser, the table
! * owner, or the database owner (but in the latter case, only if it's not
! * a shared relation). pg_class_ownercheck includes the superuser case.
*
* Note we choose to treat permissions failure as a WARNING and keep
* trying to vacuum the rest of the DB --- is this appropriate?
*/
onerel = relation_open(relid, lmode);
! if (!(pg_class_ownercheck(RelationGetRelid(onerel), GetUserId()) ||
(pg_database_ownercheck(MyDatabaseId, GetUserId()) && !onerel->rd_rel->relisshared)))
{
ereport(WARNING,
! (errmsg("skipping \"%s\" --- only table or database owner can vacuum it",
RelationGetRelationName(onerel))));
relation_close(onerel, lmode);
StrategyHintVacuum(false);
--- 990,1011 ----
/*
* Open the class, get an appropriate lock on it, and check permissions.
*
! * We allow the user to vacuum a table if he is superuser, has the
! * VACUUM permission on the table, or the database owner (but in the
! * latter case, only if it's not a shared relation).
! * pg_class_aclcheck includes the superuser case.
*
* Note we choose to treat permissions failure as a WARNING and keep
* trying to vacuum the rest of the DB --- is this appropriate?
*/
onerel = relation_open(relid, lmode);
! aclresult = pg_class_aclcheck(RelationGetRelid(onerel), GetUserId(), ACL_VACUUM);
! if (!((aclresult == ACLCHECK_OK) ||
(pg_database_ownercheck(MyDatabaseId, GetUserId()) && !onerel->rd_rel->relisshared)))
{
ereport(WARNING,
! (errmsg("skipping \"%s\" --- only user with VACUUM privilege or database owner can vacuum it",
RelationGetRelationName(onerel))));
relation_close(onerel, lmode);
StrategyHintVacuum(false);
Index: src/backend/parser/gram.y
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/parser/gram.y,v
retrieving revision 2.521
diff -c -r2.521 gram.y
*** src/backend/parser/gram.y 29 Dec 2005 04:53:18 -0000 2.521
--- src/backend/parser/gram.y 4 Jan 2006 03:38:02 -0000
***************
*** 3300,3305 ****
--- 3300,3306 ----
privilege: SELECT { $$ = pstrdup($1); }
| REFERENCES { $$ = pstrdup($1); }
| CREATE { $$ = pstrdup($1); }
+ | ANALYZE { $$ = pstrdup($1); }
| ColId { $$ = $1; }
;
Index: src/backend/utils/adt/acl.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/acl.c,v
retrieving revision 1.129
diff -c -r1.129 acl.c
*** src/backend/utils/adt/acl.c 18 Nov 2005 02:38:23 -0000 1.129
--- src/backend/utils/adt/acl.c 4 Jan 2006 03:38:02 -0000
***************
*** 287,292 ****
--- 287,301 ----
case ACL_CREATE_TEMP_CHR:
read = ACL_CREATE_TEMP;
break;
+ case ACL_TRUNCATE_CHR:
+ read = ACL_TRUNCATE;
+ break;
+ case ACL_VACUUM_CHR:
+ read = ACL_VACUUM;
+ break;
+ case ACL_ANALYZE_CHR:
+ read = ACL_ANALYZE;
+ break;
default:
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
***************
*** 1334,1339 ****
--- 1343,1354 ----
return ACL_CREATE_TEMP;
if (pg_strcasecmp(priv_type, "TEMPORARY") == 0)
return ACL_CREATE_TEMP;
+ if (pg_strcasecmp(priv_type, "TRUNCATE") == 0)
+ return ACL_TRUNCATE;
+ if (pg_strcasecmp(priv_type, "VACUUM") == 0)
+ return ACL_VACUUM;
+ if (pg_strcasecmp(priv_type, "ANALYZE") == 0)
+ return ACL_ANALYZE;
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
***************
*** 1559,1564 ****
--- 1574,1594 ----
if (pg_strcasecmp(priv_type, "TRIGGER WITH GRANT OPTION") == 0)
return ACL_GRANT_OPTION_FOR(ACL_TRIGGER);
+ if (pg_strcasecmp(priv_type, "TRUNCATE") == 0)
+ return ACL_TRUNCATE;
+ if (pg_strcasecmp(priv_type, "TRUNCATE WITH GRANT OPTION") == 0)
+ return ACL_GRANT_OPTION_FOR(ACL_TRUNCATE);
+
+ if (pg_strcasecmp(priv_type, "VACUUM") == 0)
+ return ACL_VACUUM;
+ if (pg_strcasecmp(priv_type, "VACUUM WITH GRANT OPTION") == 0)
+ return ACL_GRANT_OPTION_FOR(ACL_VACUUM);
+
+ if (pg_strcasecmp(priv_type, "ANALYZE") == 0)
+ return ACL_ANALYZE;
+ if (pg_strcasecmp(priv_type, "ANALYZE WITH GRANT OPTION") == 0)
+ return ACL_GRANT_OPTION_FOR(ACL_ANALYZE);
+
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("unrecognized privilege type: \"%s\"", priv_type)));
Index: src/bin/pg_dump/dumputils.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/pg_dump/dumputils.c,v
retrieving revision 1.23
diff -c -r1.23 dumputils.c
*** src/bin/pg_dump/dumputils.c 3 Dec 2005 21:06:18 -0000 1.23
--- src/bin/pg_dump/dumputils.c 4 Jan 2006 03:38:02 -0000
***************
*** 580,585 ****
--- 580,588 ----
CONVERT_PRIV('d', "DELETE");
CONVERT_PRIV('x', "REFERENCES");
CONVERT_PRIV('t', "TRIGGER");
+ CONVERT_PRIV('e', "TRUNCATE");
+ CONVERT_PRIV('V', "VACUUM");
+ CONVERT_PRIV('A', "ANALYZE");
}
else
{
Index: src/bin/psql/tab-complete.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/psql/tab-complete.c,v
retrieving revision 1.143
diff -c -r1.143 tab-complete.c
*** src/bin/psql/tab-complete.c 18 Dec 2005 02:17:16 -0000 1.143
--- src/bin/psql/tab-complete.c 4 Jan 2006 03:38:02 -0000
***************
*** 1343,1349 ****
{
static const char *const list_privileg[] =
{"SELECT", "INSERT", "UPDATE", "DELETE", "RULE", "REFERENCES",
! "TRIGGER", "CREATE", "TEMPORARY", "EXECUTE", "USAGE", "ALL", NULL};
COMPLETE_WITH_LIST(list_privileg);
}
--- 1343,1350 ----
{
static const char *const list_privileg[] =
{"SELECT", "INSERT", "UPDATE", "DELETE", "RULE", "REFERENCES",
! "TRIGGER", "TRUNCATE", "VACUUM", "ANALYZE", "CREATE",
! "TEMPORARY", "EXECUTE", "USAGE", "ALL", NULL};
COMPLETE_WITH_LIST(list_privileg);
}
Index: src/include/nodes/parsenodes.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/nodes/parsenodes.h,v
retrieving revision 1.298
diff -c -r1.298 parsenodes.h
*** src/include/nodes/parsenodes.h 7 Dec 2005 15:20:55 -0000 1.298
--- src/include/nodes/parsenodes.h 4 Jan 2006 03:38:02 -0000
***************
*** 47,53 ****
#define ACL_USAGE (1<<8) /* for languages and namespaces */
#define ACL_CREATE (1<<9) /* for namespaces and databases */
#define ACL_CREATE_TEMP (1<<10) /* for databases */
! #define N_ACL_RIGHTS 11 /* 1 plus the last 1<