Index: doc/src/sgml/ref/grant.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/ref/grant.sgml,v
retrieving revision 1.50
diff -c -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	11 Jan 2006 22:40:11 -0000
***************
*** 25,30 ****
--- 25,35 ----
      ON [ TABLE ] tablename [, ...]
      TO { username | GROUP groupname | PUBLIC } [, ...] [ WITH GRANT OPTION ]
  
+ GRANT { { USAGE | SELECT | UPDATE }
+     [,...] | ALL [ PRIVILEGES ] }
+     ON SEQUENCE sequencename [, ...]
+     TO { username | GROUP groupname | PUBLIC } [, ...] [ WITH GRANT OPTION ]
+ 
  GRANT { { CREATE | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }
      ON DATABASE dbname [, ...]
      TO { username | GROUP groupname | PUBLIC } [, ...] [ WITH GRANT OPTION ]
***************
*** 260,265 ****
--- 265,274 ----
         also met).  Essentially this allows the grantee to look up>
         objects within the schema.
        
+       
+        For sequences, this privilege allows the use of the
+        currval and nextval functions.
+       
       
      
  
***************
*** 511,517 ****
  
     
      The RULE privilege, and privileges on
!     databases, tablespaces, schemas, languages, and sequences are
      PostgreSQL extensions.
     
   
--- 520,526 ----
  
     
      The RULE privilege, and privileges on
!     databases, tablespaces, schemas, and languages are
      PostgreSQL extensions.
     
   
Index: doc/src/sgml/ref/revoke.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/ref/revoke.sgml,v
retrieving revision 1.35
diff -c -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	11 Jan 2006 22:40:11 -0000
***************
*** 28,33 ****
--- 28,40 ----
      [ CASCADE | RESTRICT ]
  
  REVOKE [ GRANT OPTION FOR ]
+     { { USAGE | SELECT | UPDATE }
+     [,...] | ALL [ PRIVILEGES ] }
+     ON SEQUENCE sequencename [, ...]
+     FROM { username | GROUP groupname | PUBLIC } [, ...]
+     [ CASCADE | RESTRICT ]
+ 
+ REVOKE [ GRANT OPTION FOR ]
      { { CREATE | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }
      ON DATABASE dbname [, ...]
      FROM { username | GROUP groupname | PUBLIC } [, ...]
Index: src/backend/catalog/aclchk.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v
retrieving revision 1.123
diff -c -c -r1.123 aclchk.c
*** src/backend/catalog/aclchk.c	1 Dec 2005 02:03:00 -0000	1.123
--- src/backend/catalog/aclchk.c	11 Jan 2006 22:40:12 -0000
***************
*** 164,169 ****
--- 164,172 ----
  		case ACL_KIND_CLASS:
  			whole_mask = ACL_ALL_RIGHTS_RELATION;
  			break;
+ 		case ACL_KIND_SEQUENCE:
+ 			whole_mask = ACL_ALL_RIGHTS_SEQUENCE;
+ 			break;
  		case ACL_KIND_DATABASE:
  			whole_mask = ACL_ALL_RIGHTS_DATABASE;
  			break;
***************
*** 212,233 ****
  		if (this_privileges == 0)
  			ereport(WARNING,
  					(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
! 					 errmsg("no privileges were granted")));
  		else if (!all_privs && this_privileges != privileges)
  			ereport(WARNING,
  					(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
! 					 errmsg("not all privileges were granted")));
  	}
  	else
  	{
  		if (this_privileges == 0)
  			ereport(WARNING,
  					(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
! 					 errmsg("no privileges could be revoked")));
  		else if (!all_privs && this_privileges != privileges)
  			ereport(WARNING,
  					(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
! 					 errmsg("not all privileges could be revoked")));
  	}
  
  	return this_privileges;
--- 215,236 ----
  		if (this_privileges == 0)
  			ereport(WARNING,
  					(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
! 					 errmsg("no privileges were granted for \"%s\"", objname)));
  		else if (!all_privs && this_privileges != privileges)
  			ereport(WARNING,
  					(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED),
! 					 errmsg("not all privileges were granted for \"%s\"", objname)));
  	}
  	else
  	{
  		if (this_privileges == 0)
  			ereport(WARNING,
  					(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
! 					 errmsg("no privileges could be revoked for \"%s\"", objname)));
  		else if (!all_privs && this_privileges != privileges)
  			ereport(WARNING,
  					(errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED),
! 					 errmsg("not all privileges could be revoked for \"%s\"", objname)));
  	}
  
  	return this_privileges;
***************
*** 282,290 ****
  	 */
  	switch (stmt->objtype)
  	{
  		case ACL_OBJECT_RELATION:
! 			all_privileges = ACL_ALL_RIGHTS_RELATION;
! 			errormsg = _("invalid privilege type %s for table");
  			break;
  		case ACL_OBJECT_DATABASE:
  			all_privileges = ACL_ALL_RIGHTS_DATABASE;
--- 285,302 ----
  	 */
  	switch (stmt->objtype)
  	{
+ 		/*
+ 		 *	Because this might be a sequence, we test both relation
+ 		 *	and sequence bits, and later do a more limited test
+ 		 *	when we know the object type.
+ 		 */
  		case ACL_OBJECT_RELATION:
! 			all_privileges = ACL_ALL_RIGHTS_RELATION | ACL_ALL_RIGHTS_SEQUENCE;
! 			errormsg = _("invalid privilege type %s for relation");
! 			break;
! 		case ACL_OBJECT_SEQUENCE:
! 			all_privileges = ACL_ALL_RIGHTS_SEQUENCE;
! 			errormsg = _("invalid privilege type %s for sequence");
  			break;
  		case ACL_OBJECT_DATABASE:
  			all_privileges = ACL_ALL_RIGHTS_DATABASE;
***************
*** 327,332 ****
--- 339,345 ----
  	{
  		istmt.all_privs = false;
  		istmt.privileges = ACL_NO_RIGHTS;
+ 
  		foreach(cell, stmt->privileges)
  		{
  			char	   *privname = strVal(lfirst(cell));
***************
*** 356,361 ****
--- 369,375 ----
  	switch (istmt->objtype)
  	{
  		case ACL_OBJECT_RELATION:
+ 		case ACL_OBJECT_SEQUENCE:
  			ExecGrant_Relation(istmt);
  			break;
  		case ACL_OBJECT_DATABASE:
***************
*** 395,400 ****
--- 409,415 ----
  	switch (objtype)
  	{
  		case ACL_OBJECT_RELATION:
+ 		case ACL_OBJECT_SEQUENCE:
  			foreach(cell, objnames)
  			{
  				Oid			relOid;
***************
*** 523,537 ****
  	return objects;
  }
  
  static void
  ExecGrant_Relation(InternalGrant *istmt)
  {
  	Relation	relation;
  	ListCell   *cell;
  
- 	if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
- 		istmt->privileges = ACL_ALL_RIGHTS_RELATION;
- 
  	relation = heap_open(RelationRelationId, RowExclusiveLock);
  
  	foreach(cell, istmt->objects)
--- 538,552 ----
  	return objects;
  }
  
+ /*
+  *	This processes both sequences and non-sequences.
+  */
  static void
  ExecGrant_Relation(InternalGrant *istmt)
  {
  	Relation	relation;
  	ListCell   *cell;
  
  	relation = heap_open(RelationRelationId, RowExclusiveLock);
  
  	foreach(cell, istmt->objects)
***************
*** 577,582 ****
--- 592,660 ----
  					 errmsg("\"%s\" is a composite type",
  							NameStr(pg_class_tuple->relname))));
  
+ 		/* Used GRANT SEQUENCE on a non-sequence? */
+ 		if (istmt->objtype == ACL_OBJECT_SEQUENCE &&
+ 			pg_class_tuple->relkind != RELKIND_SEQUENCE)
+ 			ereport(ERROR,
+ 					(errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ 					 errmsg("\"%s\" is not a sequence",
+ 							NameStr(pg_class_tuple->relname))));
+ 
+ 		/* Adjust the default permissions based on whether it is a sequence */
+ 		if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
+ 		{
+ 			if (pg_class_tuple->relkind == RELKIND_SEQUENCE)
+ 				this_privileges = ACL_ALL_RIGHTS_SEQUENCE;
+ 			else
+ 				this_privileges = ACL_ALL_RIGHTS_RELATION;
+ 		}
+ 		else
+ 			this_privileges = istmt->privileges;
+ 		
+ 		/*
+ 		 *	The GRANT TABLE syntax can be used for sequences and
+ 		 *	non-sequences, so we have to look at the relkind to
+ 		 *	determine the supported permissions.  The OR of
+ 		 *	table and sequence permissions were already checked.
+ 		 */
+ 		if (istmt->objtype == ACL_OBJECT_RELATION)
+ 		{
+ 			if (pg_class_tuple->relkind == RELKIND_SEQUENCE)
+ 			{
+ 				/*
+ 				 *	For backward compatibility, throw just a warning
+ 				 *	for invalid sequence permissions when using the
+ 				 *	non-sequence GRANT syntax is used.
+ 				 */
+ 				if (this_privileges & ~((AclMode) ACL_ALL_RIGHTS_SEQUENCE))
+ 				{
+ 					/*
+ 					 *	Mention the object name because the user needs to
+ 					 *	know which operations succeeded.  This is required
+ 					 *	because WARNING allows the command to continue.
+ 					 */
+ 					ereport(WARNING,
+ 							(errcode(ERRCODE_INVALID_GRANT_OPERATION),
+ 							 errmsg("sequence \"%s\" only supports USAGE, SELECT, and UPDATE",
+ 									NameStr(pg_class_tuple->relname))));
+ 					this_privileges &= (AclMode) ACL_ALL_RIGHTS_SEQUENCE;
+ 				}
+ 			}
+ 			else
+ 			{
+ 				if (this_privileges & ~((AclMode) ACL_ALL_RIGHTS_RELATION))
+ 					/*
+ 					 *	USAGE is the only permission supported by sequences
+ 					 *	but not by non-sequences.  Don't mention the object
+ 					 *	name because we didn't in the combined TABLE |
+ 					 *	SEQUENCE check.
+ 					 */
+ 					ereport(ERROR,
+ 							(errcode(ERRCODE_INVALID_GRANT_OPERATION),
+ 							 errmsg("invalid privilege type USAGE for table")));
+ 			}
+ 		}
+ 
  		/*
  		 * Get owner ID and working copy of existing ACL. If there's no ACL,
  		 * substitute the proper default.
***************
*** 585,596 ****
  		aclDatum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relacl,
  								   &isNull);
  		if (isNull)
! 			old_acl = acldefault(ACL_OBJECT_RELATION, ownerId);
  		else
  			old_acl = DatumGetAclPCopy(aclDatum);
  
  		/* Determine ID to do the grant as, and available grant options */
! 		select_best_grantor(GetUserId(), istmt->privileges,
  							old_acl, ownerId,
  							&grantorId, &avail_goptions);
  
--- 663,676 ----
  		aclDatum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relacl,
  								   &isNull);
  		if (isNull)
! 			old_acl = acldefault(pg_class_tuple->relkind == RELKIND_SEQUENCE ?
! 								 ACL_OBJECT_SEQUENCE : ACL_OBJECT_RELATION,
! 								 ownerId);
  		else
  			old_acl = DatumGetAclPCopy(aclDatum);
  
  		/* Determine ID to do the grant as, and available grant options */
! 		select_best_grantor(GetUserId(), this_privileges,
  							old_acl, ownerId,
  							&grantorId, &avail_goptions);
  
***************
*** 600,607 ****
  		 */
  		this_privileges =
  			restrict_and_check_grant(istmt->is_grant, avail_goptions,
! 									 istmt->all_privs, istmt->privileges,
! 									 relOid, grantorId, ACL_KIND_CLASS,
  									 NameStr(pg_class_tuple->relname));
  
  		/*
--- 680,689 ----
  		 */
  		this_privileges =
  			restrict_and_check_grant(istmt->is_grant, avail_goptions,
! 									 istmt->all_privs, this_privileges,
! 									 relOid, grantorId,
! 									 pg_class_tuple->relkind == RELKIND_SEQUENCE
! 										? ACL_KIND_SEQUENCE : ACL_KIND_CLASS,
  									 NameStr(pg_class_tuple->relname));
  
  		/*
***************
*** 1336,1341 ****
--- 1418,1425 ----
  {
  	/* ACL_KIND_CLASS */
  	gettext_noop("permission denied for relation %s"),
+ 	/* ACL_KIND_SEQUENCE */
+ 	gettext_noop("permission denied for sequence %s"),
  	/* ACL_KIND_DATABASE */
  	gettext_noop("permission denied for database %s"),
  	/* ACL_KIND_PROC */
***************
*** 1360,1365 ****
--- 1444,1451 ----
  {
  	/* ACL_KIND_CLASS */
  	gettext_noop("must be owner of relation %s"),
+ 	/* ACL_KIND_SEQUENCE */
+ 	gettext_noop("must be owner of sequence %s"),
  	/* ACL_KIND_DATABASE */
  	gettext_noop("must be owner of database %s"),
  	/* ACL_KIND_PROC */
***************
*** 1439,1444 ****
--- 1525,1531 ----
  	switch (objkind)
  	{
  		case ACL_KIND_CLASS:
+ 		case ACL_KIND_SEQUENCE:
  			return pg_class_aclmask(table_oid, roleid, mask, how);
  		case ACL_KIND_DATABASE:
  			return pg_database_aclmask(table_oid, roleid, mask, how);
***************
*** 1500,1508 ****
  	 *
  	 * As of 7.4 we have some updatable system views; those shouldn't be
  	 * 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) &&
--- 1587,1595 ----
  	 *
  	 * As of 7.4 we have some updatable system views; those shouldn't be
  	 * protected in this way.  Assume the view rules can take care of
! 	 * themselves.  ACL_USAGE is if we ever have system sequences.
  	 */
! 	if ((mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE | ACL_USAGE)) &&
  		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);
  	}
  
  	/*
--- 1598,1604 ----
  #ifdef ACLDEBUG
  		elog(DEBUG2, "permission denied for system catalog update");
  #endif
! 		mask &= ~(ACL_INSERT | ACL_UPDATE | ACL_DELETE | ACL_USAGE);
  	}
  
  	/*
***************
*** 1536,1542 ****
  	if (isNull)
  	{
  		/* No ACL, so build default ACL */
! 		acl = acldefault(ACL_OBJECT_RELATION, ownerId);
  		aclDatum = (Datum) 0;
  	}
  	else
--- 1623,1631 ----
  	if (isNull)
  	{
  		/* No ACL, so build default ACL */
! 		acl = acldefault(classForm->relkind == RELKIND_SEQUENCE ?
! 							ACL_OBJECT_SEQUENCE : ACL_OBJECT_RELATION,
! 						 ownerId);
  		aclDatum = (Datum) 0;
  	}
  	else
Index: src/backend/catalog/pg_shdepend.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/catalog/pg_shdepend.c,v
retrieving revision 1.6
diff -c -c -r1.6 pg_shdepend.c
*** src/backend/catalog/pg_shdepend.c	1 Dec 2005 02:03:00 -0000	1.6
--- src/backend/catalog/pg_shdepend.c	11 Jan 2006 22:40:12 -0000
***************
*** 1133,1140 ****
  					switch (sdepForm->classid)
  					{
  						case RelationRelationId:
! 							istmt.objtype = ACL_OBJECT_RELATION;
  							break;
  						case DatabaseRelationId:
  							istmt.objtype = ACL_OBJECT_DATABASE;
  							break;
--- 1133,1157 ----
  					switch (sdepForm->classid)
  					{
  						case RelationRelationId:
! 						{
! 							/* is it a sequence or non-sequence? */
! 							Form_pg_class pg_class_tuple;
! 							HeapTuple	tuple;
! 
! 							tuple = SearchSysCache(RELOID,
! 								ObjectIdGetDatum(sdepForm->objid),
! 								0, 0, 0);
! 							if (!HeapTupleIsValid(tuple))
! 								elog(ERROR, "cache lookup failed for relation %u",
! 											sdepForm->objid);
! 							pg_class_tuple = (Form_pg_class) GETSTRUCT(tuple);
! 							if (pg_class_tuple->relkind == RELKIND_SEQUENCE)
! 								istmt.objtype = ACL_OBJECT_SEQUENCE;
! 							else
! 								istmt.objtype = ACL_OBJECT_RELATION;
! 							ReleaseSysCache(tuple);
  							break;
+ 						}
  						case DatabaseRelationId:
  							istmt.objtype = ACL_OBJECT_DATABASE;
  							break;
Index: src/backend/commands/sequence.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/commands/sequence.c,v
retrieving revision 1.126
diff -c -c -r1.126 sequence.c
*** src/backend/commands/sequence.c	22 Nov 2005 18:17:09 -0000	1.126
--- src/backend/commands/sequence.c	11 Jan 2006 22:40:13 -0000
***************
*** 422,428 ****
  	/* open and AccessShareLock sequence */
  	init_sequence(relid, &elm, &seqrel);
  
! 	if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_UPDATE) != ACLCHECK_OK)
  		ereport(ERROR,
  				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
  				 errmsg("permission denied for sequence %s",
--- 422,429 ----
  	/* open and AccessShareLock sequence */
  	init_sequence(relid, &elm, &seqrel);
  
! 	if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_USAGE) != ACLCHECK_OK &&
! 		pg_class_aclcheck(elm->relid, GetUserId(), ACL_UPDATE) != ACLCHECK_OK)
  		ereport(ERROR,
  				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
  				 errmsg("permission denied for sequence %s",
***************
*** 613,619 ****
  	/* open and AccessShareLock sequence */
  	init_sequence(relid, &elm, &seqrel);
  
! 	if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_SELECT) != ACLCHECK_OK)
  		ereport(ERROR,
  				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
  				 errmsg("permission denied for sequence %s",
--- 614,621 ----
  	/* open and AccessShareLock sequence */
  	init_sequence(relid, &elm, &seqrel);
  
! 	if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_SELECT) != ACLCHECK_OK &&
! 		pg_class_aclcheck(elm->relid, GetUserId(), ACL_USAGE) != ACLCHECK_OK)
  		ereport(ERROR,
  				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
  				 errmsg("permission denied for sequence %s",
***************
*** 657,663 ****
  	/* nextval() must have already been called for this sequence */
  	Assert(last_used_seq->increment != 0);
  
! 	if (pg_class_aclcheck(last_used_seq->relid, GetUserId(), ACL_SELECT) != ACLCHECK_OK)
  		ereport(ERROR,
  				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
  				 errmsg("permission denied for sequence %s",
--- 659,666 ----
  	/* nextval() must have already been called for this sequence */
  	Assert(last_used_seq->increment != 0);
  
! 	if (pg_class_aclcheck(last_used_seq->relid, GetUserId(), ACL_SELECT) != ACLCHECK_OK &&
! 		pg_class_aclcheck(last_used_seq->relid, GetUserId(), ACL_USAGE) != ACLCHECK_OK)
  		ereport(ERROR,
  				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
  				 errmsg("permission denied for sequence %s",
Index: src/backend/parser/gram.y
===================================================================
RCS file: /cvsroot/pgsql/src/backend/parser/gram.y,v
retrieving revision 2.521
diff -c -c -r2.521 gram.y
*** src/backend/parser/gram.y	29 Dec 2005 04:53:18 -0000	2.521
--- src/backend/parser/gram.y	11 Jan 2006 22:40:20 -0000
***************
*** 3322,3327 ****
--- 3322,3334 ----
  					n->objs = $2;
  					$$ = n;
  				}
+ 			| SEQUENCE qualified_name_list
+ 				{
+ 					PrivTarget *n = makeNode(PrivTarget);
+ 					n->objtype = ACL_OBJECT_SEQUENCE;
+ 					n->objs = $2;
+ 					$$ = n;
+ 				}
  			| FUNCTION function_with_argtypes_list
  				{
  					PrivTarget *n = makeNode(PrivTarget);
Index: src/backend/utils/adt/acl.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v
retrieving revision 1.129
diff -c -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	11 Jan 2006 22:40:25 -0000
***************
*** 545,550 ****
--- 545,554 ----
  			world_default = ACL_NO_RIGHTS;
  			owner_default = ACL_ALL_RIGHTS_RELATION;
  			break;
+ 		case ACL_OBJECT_SEQUENCE:
+ 			world_default = ACL_NO_RIGHTS;
+ 			owner_default = ACL_ALL_RIGHTS_SEQUENCE;
+ 			break;
  		case ACL_OBJECT_DATABASE:
  			world_default = ACL_CREATE_TEMP;	/* not NO_RIGHTS! */
  			owner_default = ACL_ALL_RIGHTS_DATABASE;
Index: src/bin/pg_dump/dumputils.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/pg_dump/dumputils.c,v
retrieving revision 1.24
diff -c -c -r1.24 dumputils.c
*** src/bin/pg_dump/dumputils.c	11 Jan 2006 21:24:30 -0000	1.24
--- src/bin/pg_dump/dumputils.c	11 Jan 2006 22:40:30 -0000
***************
*** 22,29 ****
  #define supports_grant_options(version) ((version) >= 70400)
  
  static bool parseAclItem(const char *item, const char *type, const char *name,
! 			 int remoteVersion,
! 			 PQExpBuffer grantee, PQExpBuffer grantor,
  			 PQExpBuffer privs, PQExpBuffer privswgo);
  static char *copyAclUserName(PQExpBuffer output, char *input);
  static void AddAcl(PQExpBuffer aclbuf, const char *keyword);
--- 22,28 ----
  #define supports_grant_options(version) ((version) >= 70400)
  
  static bool parseAclItem(const char *item, const char *type, const char *name,
! 			 int remoteVersion, PQExpBuffer grantee, PQExpBuffer grantor,
  			 PQExpBuffer privs, PQExpBuffer privswgo);
  static char *copyAclUserName(PQExpBuffer output, char *input);
  static void AddAcl(PQExpBuffer aclbuf, const char *keyword);
***************
*** 326,332 ****
   *
   *	name: the object name, in the form to use in the commands (already quoted)
   *	type: the object type (as seen in GRANT command: must be one of
!  *		TABLE, FUNCTION, LANGUAGE, SCHEMA, DATABASE, or TABLESPACE)
   *	acls: the ACL string fetched from the database
   *	owner: username of object owner (will be passed through fmtId); can be
   *		NULL or empty string to indicate "no owner known"
--- 325,331 ----
   *
   *	name: the object name, in the form to use in the commands (already quoted)
   *	type: the object type (as seen in GRANT command: must be one of
!  *		TABLE, SEQUENCE, FUNCTION, LANGUAGE, SCHEMA, DATABASE, or TABLESPACE)
   *	acls: the ACL string fetched from the database
   *	owner: username of object owner (will be passed through fmtId); can be
   *		NULL or empty string to indicate "no owner known"
***************
*** 515,522 ****
   */
  static bool
  parseAclItem(const char *item, const char *type, const char *name,
! 			 int remoteVersion,
! 			 PQExpBuffer grantee, PQExpBuffer grantor,
  			 PQExpBuffer privs, PQExpBuffer privswgo)
  {
  	char	   *buf;
--- 514,520 ----
   */
  static bool
  parseAclItem(const char *item, const char *type, const char *name,
! 			 int remoteVersion, PQExpBuffer grantee, PQExpBuffer grantor,
  			 PQExpBuffer privs, PQExpBuffer privswgo)
  {
  	char	   *buf;
***************
*** 547,552 ****
--- 545,551 ----
  
  	/* privilege codes */
  #define CONVERT_PRIV(code, keywd) \
+ do { \
  	if ((pos = strchr(eqpos + 1, code))) \
  	{ \
  		if (*(pos + 1) == '*') \
***************
*** 561,576 ****
  		} \
  	} \
  	else \
! 		all_with_go = all_without_go = false
  
  	resetPQExpBuffer(privs);
  	resetPQExpBuffer(privswgo);
  
! 	if (strcmp(type, "TABLE") == 0)
  	{
  		CONVERT_PRIV('a', "INSERT");
  		CONVERT_PRIV('r', "SELECT");
  		CONVERT_PRIV('R', "RULE");
  
  		if (remoteVersion >= 70200)
  		{
--- 560,578 ----
  		} \
  	} \
  	else \
! 		all_with_go = all_without_go = false; \
! } while (0)
  
  	resetPQExpBuffer(privs);
  	resetPQExpBuffer(privswgo);
  
! 	if (strcmp(type, "TABLE") == 0 || strcmp(type, "SEQUENCE") == 0)
  	{
  		CONVERT_PRIV('a', "INSERT");
  		CONVERT_PRIV('r', "SELECT");
  		CONVERT_PRIV('R', "RULE");
+ 		if (strcmp(type, "SEQUENCE") == 0)
+ 			CONVERT_PRIV('U', "USAGE");
  
  		if (remoteVersion >= 70200)
  		{
Index: src/bin/pg_dump/pg_backup_archiver.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v
retrieving revision 1.118
diff -c -c -r1.118 pg_backup_archiver.c
*** src/bin/pg_dump/pg_backup_archiver.c	22 Nov 2005 18:17:28 -0000	1.118
--- src/bin/pg_dump/pg_backup_archiver.c	11 Jan 2006 22:40:31 -0000
***************
*** 1889,1895 ****
  			if (strcmp(ropt->schemaNames, te->namespace) != 0)
  				return 0;
  		}
! 		if ((strcmp(te->desc, "TABLE") == 0) || (strcmp(te->desc, "TABLE DATA") == 0))
  		{
  			if (!ropt->selTable)
  				return 0;
--- 1889,1896 ----
  			if (strcmp(ropt->schemaNames, te->namespace) != 0)
  				return 0;
  		}
! 		if (strcmp(te->desc, "TABLE") == 0 ||
! 			strcmp(te->desc, "TABLE DATA") == 0)
  		{
  			if (!ropt->selTable)
  				return 0;
***************
*** 2276,2283 ****
  	const char *type = te->desc;
  
  	/* Use ALTER TABLE for views and sequences */
! 	if (strcmp(type, "VIEW") == 0 ||
! 		strcmp(type, "SEQUENCE") == 0)
  		type = "TABLE";
  
  	/* objects named by a schema and name */
--- 2277,2283 ----
  	const char *type = te->desc;
  
  	/* Use ALTER TABLE for views and sequences */
! 	if (strcmp(type, "VIEW") == 0 || strcmp(type, "SEQUENCE") == 0)
  		type = "TABLE";
  
  	/* objects named by a schema and name */
Index: src/bin/pg_dump/pg_dump.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v
retrieving revision 1.426
diff -c -c -r1.426 pg_dump.c
*** src/bin/pg_dump/pg_dump.c	9 Jan 2006 21:16:17 -0000	1.426
--- src/bin/pg_dump/pg_dump.c	11 Jan 2006 22:40:36 -0000
***************
*** 6788,6794 ****
  
  		/* Handle the ACL here */
  		namecopy = strdup(fmtId(tbinfo->dobj.name));
! 		dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId, "TABLE",
  				namecopy, tbinfo->dobj.name,
  				tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
  				tbinfo->relacl);
--- 6788,6804 ----
  
  		/* Handle the ACL here */
  		namecopy = strdup(fmtId(tbinfo->dobj.name));
! 		dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
! 				/*
! 				 *	Use GRANT SEQUENCE only when dumping a >= 8.2 database
! 				 *	because it supports the USAGE permission.
! 				 *	>= 8.2 databases still supports GRANT TABLE for loading
! 				 *	sequences from previous versions.  It issues warnings
! 				 *	for invalid permissions.
! 				 */
! 				(tbinfo->relkind == RELKIND_SEQUENCE &&
! 				 fout->remoteVersion >= 80200)
! 					? "SEQUENCE" : "TABLE",
  				namecopy, tbinfo->dobj.name,
  				tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
  				tbinfo->relacl);
Index: src/include/nodes/parsenodes.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/nodes/parsenodes.h,v
retrieving revision 1.298
diff -c -c -r1.298 parsenodes.h
*** src/include/nodes/parsenodes.h	7 Dec 2005 15:20:55 -0000	1.298
--- src/include/nodes/parsenodes.h	11 Jan 2006 22:40:38 -0000
***************
*** 884,890 ****
   */
  typedef enum GrantObjectType
  {
! 	ACL_OBJECT_RELATION,		/* table, view, sequence */
  	ACL_OBJECT_DATABASE,		/* database */
  	ACL_OBJECT_FUNCTION,		/* function */
  	ACL_OBJECT_LANGUAGE,		/* procedural language */
--- 884,891 ----
   */
  typedef enum GrantObjectType
  {
! 	ACL_OBJECT_RELATION,		/* table, view */
! 	ACL_OBJECT_SEQUENCE,		/* sequence */
  	ACL_OBJECT_DATABASE,		/* database */
  	ACL_OBJECT_FUNCTION,		/* function */
  	ACL_OBJECT_LANGUAGE,		/* procedural language */
Index: src/include/utils/acl.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/utils/acl.h,v
retrieving revision 1.91
diff -c -c -r1.91 acl.h
*** src/include/utils/acl.h	1 Dec 2005 02:03:01 -0000	1.91
--- src/include/utils/acl.h	11 Jan 2006 22:40:38 -0000
***************
*** 143,148 ****
--- 143,149 ----
   * Bitmasks defining "all rights" for each supported object type
   */
  #define ACL_ALL_RIGHTS_RELATION		(ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_DELETE|ACL_RULE|ACL_REFERENCES|ACL_TRIGGER)
+ #define ACL_ALL_RIGHTS_SEQUENCE		(ACL_USAGE|ACL_SELECT|ACL_UPDATE)
  #define ACL_ALL_RIGHTS_DATABASE		(ACL_CREATE|ACL_CREATE_TEMP)
  #define ACL_ALL_RIGHTS_FUNCTION		(ACL_EXECUTE)
  #define ACL_ALL_RIGHTS_LANGUAGE		(ACL_USAGE)
***************
*** 169,174 ****
--- 170,176 ----
  typedef enum AclObjectKind
  {
  	ACL_KIND_CLASS,				/* pg_class */
+ 	ACL_KIND_SEQUENCE,			/* pg_sequence */
  	ACL_KIND_DATABASE,			/* pg_database */
  	ACL_KIND_PROC,				/* pg_proc */
  	ACL_KIND_OPER,				/* pg_operator */
Index: src/test/regress/expected/privileges.out
===================================================================
RCS file: /cvsroot/pgsql/src/test/regress/expected/privileges.out,v
retrieving revision 1.32
diff -c -c -r1.32 privileges.out
*** src/test/regress/expected/privileges.out	15 Aug 2005 02:40:30 -0000	1.32
--- src/test/regress/expected/privileges.out	11 Jan 2006 22:40:39 -0000
***************
*** 90,96 ****
  COPY atest2 FROM stdin; -- fail
  ERROR:  permission denied for relation atest2
  GRANT ALL ON atest1 TO PUBLIC; -- fail
! WARNING:  no privileges were granted
  -- checks in subquery, both ok
  SELECT * FROM atest1 WHERE ( b IN ( SELECT col1 FROM atest2 ) );
   a | b 
--- 90,96 ----
  COPY atest2 FROM stdin; -- fail
  ERROR:  permission denied for relation atest2
  GRANT ALL ON atest1 TO PUBLIC; -- fail
! WARNING:  no privileges were granted for "atest1"
  -- checks in subquery, both ok
  SELECT * FROM atest1 WHERE ( b IN ( SELECT col1 FROM atest2 ) );
   a | b 
***************
*** 227,233 ****
  HINT:  Only superusers may use untrusted languages.
  SET SESSION AUTHORIZATION regressuser1;
  GRANT USAGE ON LANGUAGE sql TO regressuser2; -- fail
! WARNING:  no privileges were granted
  CREATE FUNCTION testfunc1(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql;
  CREATE FUNCTION testfunc2(int) RETURNS int AS 'select 3 * $1;' LANGUAGE sql;
  REVOKE ALL ON FUNCTION testfunc1(int), testfunc2(int) FROM PUBLIC;
--- 227,233 ----
  HINT:  Only superusers may use untrusted languages.
  SET SESSION AUTHORIZATION regressuser1;
  GRANT USAGE ON LANGUAGE sql TO regressuser2; -- fail
! WARNING:  no privileges were granted for "sql"
  CREATE FUNCTION testfunc1(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql;
  CREATE FUNCTION testfunc2(int) RETURNS int AS 'select 3 * $1;' LANGUAGE sql;
  REVOKE ALL ON FUNCTION testfunc1(int), testfunc2(int) FROM PUBLIC;
***************
*** 551,557 ****
  SET SESSION AUTHORIZATION regressuser2;
  GRANT SELECT ON atest4 TO regressuser3;
  GRANT UPDATE ON atest4 TO regressuser3; -- fail
! WARNING:  no privileges were granted
  SET SESSION AUTHORIZATION regressuser1;
  REVOKE SELECT ON atest4 FROM regressuser3; -- does nothing
  SELECT has_table_privilege('regressuser3', 'atest4', 'SELECT'); -- true
--- 551,557 ----
  SET SESSION AUTHORIZATION regressuser2;
  GRANT SELECT ON atest4 TO regressuser3;
  GRANT UPDATE ON atest4 TO regressuser3; -- fail
! WARNING:  no privileges were granted for "atest4"
  SET SESSION AUTHORIZATION regressuser1;
  REVOKE SELECT ON atest4 FROM regressuser3; -- does nothing
  SELECT has_table_privilege('regressuser3', 'atest4', 'SELECT'); -- true