diff -Naur pgsql.virg/src/backend/utils/adt/acl.c pgsql.dev/src/backend/utils/adt/acl.c
--- pgsql.virg/src/backend/utils/adt/acl.c	Sat Jun  9 23:21:55 2001
+++ pgsql.dev/src/backend/utils/adt/acl.c	Sun Jun 10 02:10:34 2001
@@ -31,6 +31,12 @@
 static bool aclitemeq(const AclItem *a1, const AclItem *a2);
 static bool aclitemgt(const AclItem *a1, const AclItem *a2);
 
+AclMode convert_priv_string(text *priv_type_text);
+bool has_table_privilege_cname_cname(char *username, char *relname, text *priv_type_text);
+bool has_table_privilege_id_cname(Oid usesysid, char *relname, text *priv_type_text);
+bool has_table_privilege_cname_id(char *username, Oid reloid, text *priv_type_text);
+static char *get_Name(text *relin);
+
 #define ACL_IDTYPE_GID_KEYWORD	"group"
 #define ACL_IDTYPE_UID_KEYWORD	"user"
 
@@ -709,4 +715,753 @@
 	ret = pstrdup(str.data);
 	pfree(str.data);
 	return ret;
+}
+
+
+/*
+ * has_table_privilege_tname_tname
+ *		Check user privileges on a relation given
+ *		text usename, text relname, and text priv name.
+ *
+ * RETURNS
+ *		a boolean value
+ *		't' indicating user has the privilege
+ *		'f' indicating user does not have the privilege
+ */
+Datum
+has_table_privilege_tname_tname(PG_FUNCTION_ARGS)
+{
+	text		*username_text;
+	char		*username;
+	text		*relname_text;
+	char		*relname;
+	text		*priv_type_text;
+	bool		result;
+
+	username_text = PG_GETARG_TEXT_P(0);
+	relname_text = PG_GETARG_TEXT_P(1);
+	priv_type_text = PG_GETARG_TEXT_P(2);
+
+	/* 
+	 * Convert username and relname 'text' pattern to null-terminated string
+	 */
+	username = get_Name(username_text);
+	relname = get_Name(relname_text);
+
+	/*
+	 * Make use of has_table_privilege_cname_cname.
+	 * It accepts the arguments we now have.
+	 */
+	result = has_table_privilege_cname_cname(username, relname, priv_type_text);
+
+	PG_RETURN_BOOL(result);
+
+}
+
+
+/*
+ * has_table_privilege_tname_name
+ *		Check user privileges on a relation given
+ *		text usename, name relname, and text priv name.
+ *
+ * RETURNS
+ *		a boolean value
+ *		't' indicating user has the privilege
+ *		'f' indicating user does not have the privilege
+ */
+Datum
+has_table_privilege_tname_name(PG_FUNCTION_ARGS)
+{
+	text		*username_text;
+	char		*username;
+	Name		relname_name;
+	char		*relname;
+	text		*priv_type_text;
+	bool		result;
+
+	username_text = PG_GETARG_TEXT_P(0);
+	relname_name = PG_GETARG_NAME(1);
+	priv_type_text = PG_GETARG_TEXT_P(2);
+
+	/* 
+	 * Convert username 'text' pattern to null-terminated string
+	 */
+	username = get_Name(username_text);
+
+	/* 
+	 * Convert relname 'name' pattern to null-terminated string
+	 */
+	relname = DatumGetCString(DirectFunctionCall1(nameout, PointerGetDatum(relname_name)));
+
+	/*
+	 * Make use of has_table_privilege_cname_cname.
+	 * It accepts the arguments we now have.
+	 */
+	result = has_table_privilege_cname_cname(username, relname, priv_type_text);
+
+	PG_RETURN_BOOL(result);
+
+}
+
+
+/*
+ * has_table_privilege_name_tname
+ *		Check user privileges on a relation given
+ *		name usename, text relname, and text priv name.
+ *
+ * RETURNS
+ *		a boolean value
+ *		't' indicating user has the privilege
+ *		'f' indicating user does not have the privilege
+ */
+Datum
+has_table_privilege_name_tname(PG_FUNCTION_ARGS)
+{
+	Name		username_name;
+	char		*username;
+	text		*relname_text;
+	char		*relname;
+	text		*priv_type_text;
+	bool		result;
+
+	username_name = PG_GETARG_NAME(0);
+	relname_text = PG_GETARG_TEXT_P(1);
+	priv_type_text = PG_GETARG_TEXT_P(2);
+
+	/* 
+	 * Convert username 'name' pattern to null-terminated string
+	 */
+	username = DatumGetCString(DirectFunctionCall1(nameout, PointerGetDatum(username_name)));
+
+	/* 
+	 * Convert relname 'text' pattern to null-terminated string
+	 */
+	relname = get_Name(relname_text);
+
+	/*
+	 * Make use of has_table_privilege_cname_cname.
+	 * It accepts the arguments we now have.
+	 */
+	result = has_table_privilege_cname_cname(username, relname, priv_type_text);
+
+	PG_RETURN_BOOL(result);
+
+}
+
+
+/*
+ * has_table_privilege_name_name
+ *		Check user privileges on a relation given
+ *		name usename, name relname, and text priv name.
+ *
+ * RETURNS
+ *		a boolean value
+ *		't' indicating user has the privilege
+ *		'f' indicating user does not have the privilege
+ */
+Datum
+has_table_privilege_name_name(PG_FUNCTION_ARGS)
+{
+	Name		username_name;
+	char		*username;
+	Name		relname_name;
+	char		*relname;
+	text		*priv_type_text;
+	bool		result;
+
+	username_name = PG_GETARG_NAME(0);
+	relname_name = PG_GETARG_NAME(1);
+	priv_type_text = PG_GETARG_TEXT_P(2);
+
+	/* 
+	 * Convert username and relname 'name' pattern to null-terminated string
+	 */
+	username = DatumGetCString(DirectFunctionCall1(nameout, PointerGetDatum(username_name)));
+	relname = DatumGetCString(DirectFunctionCall1(nameout, PointerGetDatum(relname_name)));
+
+	/*
+	 * Make use of has_table_privilege_cname_cname.
+	 * It accepts the arguments we now have.
+	 */
+	result = has_table_privilege_cname_cname(username, relname, priv_type_text);
+
+	PG_RETURN_BOOL(result);
+
+}
+
+
+/*
+ * has_table_privilege_tname
+ *		Check user privileges on a relation given
+ *		text relname and text priv name.
+ *		current_user is assumed
+ *
+ * RETURNS
+ *		a boolean value
+ *		't' indicating user has the privilege
+ *		'f' indicating user does not have the privilege
+ */
+Datum
+has_table_privilege_tname(PG_FUNCTION_ARGS)
+{
+	Oid			usesysid = (Oid) -1;
+	text		*relname_text;
+	char		*relname;
+	text		*priv_type_text;
+	bool		result;
+
+	relname_text = PG_GETARG_TEXT_P(0);
+	priv_type_text = PG_GETARG_TEXT_P(1);
+
+	usesysid = GetUserId();
+
+	/* 
+	 * Convert relname 'text' pattern to null-terminated string
+	 */
+	relname = get_Name(relname_text);
+
+	/*
+	 * Make use of has_table_privilege_id_cname.
+	 * It accepts the arguments we now have.
+	 */
+	result = has_table_privilege_id_cname(usesysid, relname, priv_type_text);
+
+	PG_RETURN_BOOL(result);
+
+}
+
+/*
+ * has_table_privilege_name
+ *		Check user privileges on a relation given
+ *		name relname and text priv name.
+ *		current_user is assumed
+ *
+ * RETURNS
+ *		a boolean value
+ *		't' indicating user has the privilege
+ *		'f' indicating user does not have the privilege
+ */
+Datum
+has_table_privilege_name(PG_FUNCTION_ARGS)
+{
+	Oid			usesysid = (Oid) -1;
+	Name		relname_name;
+	char		*relname;
+	text		*priv_type_text;
+	bool		result;
+
+	relname_name = PG_GETARG_NAME(0);
+	priv_type_text = PG_GETARG_TEXT_P(1);
+
+	usesysid = GetUserId();
+
+	/* 
+	 * Convert relname 'Name' pattern to null-terminated string
+	 */
+	relname = DatumGetCString(DirectFunctionCall1(nameout, PointerGetDatum(relname_name)));
+
+	/*
+	 * Make use of has_table_privilege_id_cname.
+	 * It accepts the arguments we now have.
+	 */
+	result = has_table_privilege_id_cname(usesysid, relname, priv_type_text);
+
+	PG_RETURN_BOOL(result);
+
+}
+
+
+/*
+ * has_table_privilege_tname_id
+ *		Check user privileges on a relation given
+ *		text usename, rel oid, and text priv name.
+ *
+ * RETURNS
+ *		a boolean value
+ *		't' indicating user has the privilege
+ *		'f' indicating user does not have the privilege
+ */
+Datum
+has_table_privilege_tname_id(PG_FUNCTION_ARGS)
+{
+	text		*username_text;
+	char		*username;
+	Oid			reloid = 0;
+	text		*priv_type_text;
+	bool		result;
+
+	username_text = PG_GETARG_TEXT_P(0);
+	reloid = PG_GETARG_OID(1);
+	priv_type_text = PG_GETARG_TEXT_P(2);
+
+	/* 
+	 * Convert username 'text' pattern to null-terminated string
+	 */
+	username = get_Name(username_text);
+
+	/*
+	 * Make use of has_table_privilege_cname_id.
+	 * It accepts the arguments we now have.
+	 */
+	result = has_table_privilege_cname_id(username, reloid, priv_type_text);
+
+	PG_RETURN_BOOL(result);
+
+}
+
+
+/*
+ * has_table_privilege_name_id
+ *		Check user privileges on a relation given
+ *		name usename, rel oid, and text priv name.
+ *
+ * RETURNS
+ *		a boolean value
+ *		't' indicating user has the privilege
+ *		'f' indicating user does not have the privilege
+ */
+Datum
+has_table_privilege_name_id(PG_FUNCTION_ARGS)
+{
+	Name		username_name;
+	char		*username;
+	Oid			reloid = 0;
+	text		*priv_type_text = NULL;
+	bool		result;
+
+	username_name = PG_GETARG_NAME(0);
+	reloid = PG_GETARG_OID(1);
+	priv_type_text = PG_GETARG_TEXT_P(2);
+
+	/* 
+	 * Convert username 'name' pattern to null-terminated string
+	 */
+	username = DatumGetCString(DirectFunctionCall1(nameout, PointerGetDatum(username_name)));
+
+	/*
+	 * Make use of has_table_privilege_cname_id.
+	 * It accepts the arguments we now have.
+	 */
+	result = has_table_privilege_cname_id(username, reloid, priv_type_text);
+
+	PG_RETURN_BOOL(result);
+
+}
+
+
+/*
+ * has_table_privilege_id
+ *		Check user privileges on a relation given
+ *		rel oid, and text priv name.
+ *		current_user is assumed
+ *
+ * RETURNS
+ *		a boolean value
+ *		't' indicating user has the privilege
+ *		'f' indicating user does not have the privilege
+ */
+Datum
+has_table_privilege_id(PG_FUNCTION_ARGS)
+{
+	char		*username;
+	Oid			reloid = 0;
+	text		*priv_type_text;
+	bool		result;
+
+	reloid = PG_GETARG_OID(0);
+	priv_type_text = PG_GETARG_TEXT_P(1);
+	username = GetUserName(GetUserId());
+
+	/*
+	 * Make use of has_table_privilege_cname_id.
+	 * It accepts the arguments we now have.
+	 */
+	result = has_table_privilege_cname_id(username, reloid, priv_type_text);
+
+	PG_RETURN_BOOL(result);
+
+}
+
+
+/*
+ * has_table_privilege_id_tname
+ *		Check user privileges on a relation given
+ *		usesysid, text relname, and priv name.
+ *
+ * RETURNS
+ *		a boolean value
+ *		't' indicating user has the privilege
+ *		'f' indicating user does not have the privilege
+ */
+Datum
+has_table_privilege_id_tname(PG_FUNCTION_ARGS)
+{
+	Oid			usesysid;
+	text		*relname_text;
+	char		*relname;
+	text		*priv_type_text;
+	bool		result;
+
+	usesysid = PG_GETARG_OID(0);
+	relname_text = PG_GETARG_TEXT_P(1);
+	priv_type_text = PG_GETARG_TEXT_P(2);
+
+	/* 
+	 * Convert relname 'text' pattern to null-terminated string
+	 */
+	relname = get_Name(relname_text);
+
+	/*
+	 * Make use of has_table_privilege_id_cname.
+	 * It accepts the arguments we now have.
+	 */
+	result = has_table_privilege_id_cname(usesysid, relname, priv_type_text);
+
+	PG_RETURN_BOOL(result);
+
+}
+
+
+/*
+ * has_table_privilege_id_name
+ *		Check user privileges on a relation given
+ *		usesysid, name relname, and priv name.
+ *
+ * RETURNS
+ *		a boolean value
+ *		't' indicating user has the privilege
+ *		'f' indicating user does not have the privilege
+ */
+Datum
+has_table_privilege_id_name(PG_FUNCTION_ARGS)
+{
+	Oid			usesysid;
+	Name		relname_name;
+	char		*relname;
+	text		*priv_type_text;
+	bool		result;
+
+	usesysid = PG_GETARG_OID(0);
+	relname_name = PG_GETARG_NAME(1);
+	priv_type_text = PG_GETARG_TEXT_P(2);
+
+	/* 
+	 * Convert relname 'name' pattern to null-terminated string
+	 */
+	relname = DatumGetCString(DirectFunctionCall1(nameout, PointerGetDatum(relname_name)));
+
+	/*
+	 * Make use of has_table_privilege_id_cname.
+	 * It accepts the arguments we now have.
+	 */
+	result = has_table_privilege_id_cname(usesysid, relname, priv_type_text);
+
+	PG_RETURN_BOOL(result);
+
+}
+
+
+/*
+ * has_table_privilege_id_id
+ *		Check user privileges on a relation given
+ *		usesysid, rel oid, and priv name.
+ *
+ * RETURNS
+ *		a boolean value
+ *		't' indicating user has the privilege
+ *		'f' indicating user does not have the privilege
+ */
+Datum
+has_table_privilege_id_id(PG_FUNCTION_ARGS)
+{
+	Oid			usesysid;
+	Oid			reloid;
+	char		*relname;
+	text		*priv_type_text;
+	HeapTuple	tuple;
+	AclMode		mode;
+	int32		result;
+
+
+	usesysid = PG_GETARG_OID(0);
+	reloid = PG_GETARG_OID(1);
+	priv_type_text = PG_GETARG_TEXT_P(2);
+
+	/*
+	 * Lookup relname based on rel oid
+	 */
+	tuple = SearchSysCache(RELOID, ObjectIdGetDatum(reloid), 0, 0, 0);
+	if (!HeapTupleIsValid(tuple)) {
+		elog(ERROR, "has_table_privilege: invalid relation oid %d", (int) reloid);
+	}
+
+	relname = NameStr(((Form_pg_class) GETSTRUCT(tuple))->relname);
+
+	ReleaseSysCache(tuple);
+
+	/* 
+	 * Convert priv_type_text to an AclMode
+	 */
+	mode = convert_priv_string(priv_type_text);
+
+	/* 
+	 * Finally, check for the privilege
+	 */
+	result = pg_aclcheck(relname, usesysid, mode);
+
+	if (result == ACLCHECK_OK) {
+		PG_RETURN_BOOL(TRUE);
+	} else {
+		PG_RETURN_BOOL(FALSE);
+	}
+
+}
+
+/*
+ *		Internal functions.
+ */
+
+/*
+ * convert_priv_string
+ *		Internal function.
+ *		Return mode from priv_type string
+ *
+ * RETURNS
+ *		AclMode
+ */
+
+AclMode
+convert_priv_string(text *priv_type_text)
+{
+	char	*priv_type = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(priv_type_text)));
+
+	/*
+	 * Return mode from priv_type string
+	 */
+	if (strcasecmp(priv_type, "SELECT") == 0)
+		return ACL_SELECT;
+
+	if (strcasecmp(priv_type, "INSERT") == 0)
+		return ACL_INSERT;
+
+	if (strcasecmp(priv_type, "UPDATE") == 0)
+		return ACL_UPDATE;
+
+	if (strcasecmp(priv_type, "DELETE") == 0)
+		return ACL_DELETE;
+
+	if (strcasecmp(priv_type, "RULE") == 0)
+		return ACL_RULE;
+
+	if (strcasecmp(priv_type, "REFERENCES") == 0)
+		return ACL_REFERENCES;
+
+	if (strcasecmp(priv_type, "TRIGGER") == 0)
+		return ACL_TRIGGER;
+
+	elog(ERROR, "has_table_privilege: invalid privilege type %s", priv_type);
+	/*
+	 * We should never get here, but stop the compiler from complaining
+	 */
+	return ACL_NO;
+
+}
+
+/*
+ * has_table_privilege_cname_cname
+ *		Check user privileges on a relation given
+ *		char *usename, char *relname, and text priv name.
+ *
+ * RETURNS
+ *		a boolean value
+ *		't' indicating user has the privilege
+ *		'f' indicating user does not have the privilege
+ */
+bool
+has_table_privilege_cname_cname(char *username, char *relname, text *priv_type_text)
+{
+
+	Oid			usesysid = (Oid) -1;
+	HeapTuple	tuple;
+	bool		result;
+
+	/*
+	 * Lookup userid based on username
+	 */
+
+	tuple = SearchSysCache(SHADOWNAME, NameGetDatum(username), 0, 0, 0);
+	if (!HeapTupleIsValid(tuple)) {
+		elog(ERROR, "has_table_privilege: invalid user name %s", (char *) username);
+	}
+
+	usesysid = (Oid) ((Form_pg_shadow) GETSTRUCT(tuple))->usesysid;
+	ReleaseSysCache(tuple);
+
+	/*
+	 * Make use of has_table_privilege_id_cname.
+	 * It accepts the arguments we now have.
+	 */
+	result = has_table_privilege_id_cname(usesysid, relname, priv_type_text);
+
+	return result;
+
+}
+
+
+/*
+ * has_table_privilege_cname_id
+ *		Check user privileges on a relation given
+ *		char *usename, rel oid, and text priv name.
+ *
+ * RETURNS
+ *		a boolean value
+ *		't' indicating user has the privilege
+ *		'f' indicating user does not have the privilege
+ */
+bool
+has_table_privilege_cname_id(char *username, Oid reloid, text *priv_type_text)
+{
+	Oid			usesysid = (Oid) -1;
+	char		*relname = NULL;
+	HeapTuple	tuple;
+	bool		result;
+
+	/*
+	 * Lookup userid based on username
+	 */
+
+	tuple = SearchSysCache(SHADOWNAME, NameGetDatum(username), 0, 0, 0);
+	if (!HeapTupleIsValid(tuple)) {
+		elog(ERROR, "has_table_privilege: invalid user name %s", (char *) username);
+	}
+
+	usesysid = (Oid) ((Form_pg_shadow) GETSTRUCT(tuple))->usesysid;
+
+	ReleaseSysCache(tuple);
+
+	/*
+	 * Lookup relname based on rel oid
+	 */
+	tuple = SearchSysCache(RELOID, ObjectIdGetDatum(reloid), 0, 0, 0);
+	if (!HeapTupleIsValid(tuple)) {
+		elog(ERROR, "has_table_privilege: invalid relation oid %d", (int) reloid);
+	}
+
+	relname = NameStr(((Form_pg_class) GETSTRUCT(tuple))->relname);
+
+	ReleaseSysCache(tuple);
+
+	/*
+	 * Make use of has_table_privilege_id_cname.
+	 * It accepts the arguments we now have.
+	 */
+	result = has_table_privilege_id_cname(usesysid, relname, priv_type_text);
+
+	return result;
+
+}
+
+
+/*
+ * has_table_privilege_id_cname
+ *		Check user privileges on a relation given
+ *		usesysid, char *relname, and text priv name.
+ *
+ * RETURNS
+ *		a boolean value
+ *		't' indicating user has the privilege
+ *		'f' indicating user does not have the privilege
+ */
+bool
+has_table_privilege_id_cname(Oid usesysid, char *relname, text *priv_type_text)
+{
+
+	HeapTuple	tuple;
+	AclMode		mode;
+	int32		result;
+
+	/*
+	 * Check relname is valid.
+	 * This is needed to deal with the case when usename is a superuser
+	 * in which case pg_aclcheck simply returns ACLCHECK_OK
+	 * without validating relname
+	 */
+	tuple = SearchSysCache(RELNAME, PointerGetDatum(relname), 0, 0, 0);
+
+	if (!HeapTupleIsValid(tuple)) {
+		elog(ERROR, "has_table_privilege: invalid relname %s", relname);
+	}
+	ReleaseSysCache(tuple);
+
+	/* 
+	 * Convert priv_type_text to an AclMode
+	 */
+	mode = convert_priv_string(priv_type_text);
+
+	/* 
+	 * Finally, check for the privilege
+	 */
+	result = pg_aclcheck(relname, usesysid, mode);
+
+	if (result == ACLCHECK_OK) {
+		return TRUE;
+	} else {
+		return FALSE;
+	}
+
+}
+
+
+/*
+ * Given a 'text' relname parameter to a function, extract the actual
+ * relname.  We downcase the name if it's not double-quoted,
+ * and truncate it if it's too long.
+ *
+ * This is a kluge, really --- should be able to write, e.g. nextval(seqrel).
+ */
+static char *
+get_Name(text *relin)
+{
+	char	   *rawname = DatumGetCString(DirectFunctionCall1(textout,
+												PointerGetDatum(relin)));
+	int			rawlen = strlen(rawname);
+	char	   *relname;
+
+	if (rawlen >= 2 &&
+		rawname[0] == '\"' && rawname[rawlen - 1] == '\"')
+	{
+		/* strip off quotes, keep case */
+		rawname[rawlen - 1] = '\0';
+		relname = pstrdup(rawname + 1);
+		pfree(rawname);
+	}
+	else
+	{
+		relname = rawname;
+
+		/*
+		 * It's important that this match the identifier downcasing code
+		 * used by backend/parser/scan.l.
+		 */
+		for (; *rawname; rawname++)
+		{
+			if (isupper((unsigned char) *rawname))
+				*rawname = tolower((unsigned char) *rawname);
+		}
+	}
+
+	/* Truncate name if it's overlength; again, should match scan.l */
+	if (strlen(relname) >= NAMEDATALEN)
+	{
+#ifdef MULTIBYTE
+		int len;
+
+		len = pg_mbcliplen(relname, i, NAMEDATALEN-1);
+		relname[len] = '\0';
+#else
+		relname[NAMEDATALEN-1] = '\0';
+#endif
+	}
+
+	return relname;
 }
diff -Naur pgsql.virg/src/include/catalog/pg_proc.h pgsql.dev/src/include/catalog/pg_proc.h
--- pgsql.virg/src/include/catalog/pg_proc.h	Sun Jun 10 01:59:22 2001
+++ pgsql.dev/src/include/catalog/pg_proc.h	Sat Jun  9 20:44:39 2001
@@ -2627,6 +2627,35 @@
 DATA(insert OID = 1915 (  numeric_uplus	   PGUID 12 f t t t 1 f 1700 "1700" 100 0 0 100  numeric_uplus - ));
 DESCR("unary plus");
 
+DATA(insert OID = 1920 (  has_table_privilege		   PGUID 12 f t f t 3 f 16 "25 25 25" 100 0 0 100	has_table_privilege_tname_tname - ));
+DESCR("user privilege on relation by text username, text relname");
+DATA(insert OID = 1921 (  has_table_privilege		   PGUID 12 f t f t 3 f 16 "25 19 25" 100 0 0 100	has_table_privilege_tname_name - ));
+DESCR("user privilege on relation by text username, name relname");
+DATA(insert OID = 1922 (  has_table_privilege		   PGUID 12 f t f t 3 f 16 "19 25 25" 100 0 0 100	has_table_privilege_name_tname - ));
+DESCR("user privilege on relation by name username, text relname");
+DATA(insert OID = 1923 (  has_table_privilege		   PGUID 12 f t f t 3 f 16 "19 19 25" 100 0 0 100	has_table_privilege_name_name - ));
+DESCR("user privilege on relation by name username, name relname");
+DATA(insert OID = 1924 (  has_table_privilege		   PGUID 12 f t f t 2 f 16 "25 25" 100 0 0 100	has_table_privilege_tname - ));
+DESCR("current user privilege on relation by text relname");
+DATA(insert OID = 1925 (  has_table_privilege		   PGUID 12 f t f t 2 f 16 "19 25" 100 0 0 100	has_table_privilege_name - ));
+DESCR("current user privilege on relation by name relname");
+
+DATA(insert OID = 1926 (  has_table_privilege		   PGUID 12 f t f t 3 f 16 "25 26 25" 100 0 0 100	has_table_privilege_tname_id - ));
+DESCR("user privilege on relation by text username, rel oid");
+DATA(insert OID = 1927 (  has_table_privilege		   PGUID 12 f t f t 3 f 16 "19 26 25" 100 0 0 100	has_table_privilege_name_id - ));
+DESCR("user privilege on relation by text username, rel oid");
+DATA(insert OID = 1928 (  has_table_privilege		   PGUID 12 f t f t 2 f 16 "26 25" 100 0 0 100	has_table_privilege_id - ));
+DESCR("current user privilege on relation by rel oid");
+
+DATA(insert OID = 1929 (  has_table_privilege		   PGUID 12 f t f t 3 f 16 "26 25 25" 100 0 0 100	has_table_privilege_id_tname - ));
+DESCR("user privilege on relation by usesysid, relname");
+DATA(insert OID = 1930 (  has_table_privilege		   PGUID 12 f t f t 3 f 16 "26 19 25" 100 0 0 100	has_table_privilege_id_name - ));
+DESCR("user privilege on relation by usesysid, relname");
+
+DATA(insert OID = 1931 (  has_table_privilege		   PGUID 12 f t f t 3 f 16 "26 26 25" 100 0 0 100	has_table_privilege_id_id - ));
+DESCR("user privilege on relation by usesysid, rel oid");
+
+
 /*
  * prototypes for functions pg_proc.c
  */
diff -Naur pgsql.virg/src/include/utils/acl.h pgsql.dev/src/include/utils/acl.h
--- pgsql.virg/src/include/utils/acl.h	Sun Jun 10 01:59:24 2001
+++ pgsql.dev/src/include/utils/acl.h	Sun Jun 10 00:47:42 2001
@@ -193,6 +193,22 @@
 extern Datum aclcontains(PG_FUNCTION_ARGS);
 extern void ExecuteChangeACLStmt(ChangeACLStmt *stmt);
 
+extern Datum has_table_privilege_tname_tname(PG_FUNCTION_ARGS);
+extern Datum has_table_privilege_tname_name(PG_FUNCTION_ARGS);
+extern Datum has_table_privilege_name_tname(PG_FUNCTION_ARGS);
+extern Datum has_table_privilege_name_name(PG_FUNCTION_ARGS);
+extern Datum has_table_privilege_tname(PG_FUNCTION_ARGS);
+extern Datum has_table_privilege_name(PG_FUNCTION_ARGS);
+
+extern Datum has_table_privilege_tname_id(PG_FUNCTION_ARGS);
+extern Datum has_table_privilege_name_id(PG_FUNCTION_ARGS);
+extern Datum has_table_privilege_id(PG_FUNCTION_ARGS);
+
+extern Datum has_table_privilege_id_tname(PG_FUNCTION_ARGS);
+extern Datum has_table_privilege_id_name(PG_FUNCTION_ARGS);
+
+extern Datum has_table_privilege_id_id(PG_FUNCTION_ARGS);
+
 /*
  * prototypes for functions in aclchk.c
  */
diff -Naur pgsql.virg/src/include/utils/builtins.h pgsql.dev/src/include/utils/builtins.h
--- pgsql.virg/src/include/utils/builtins.h	Sun Jun 10 01:59:26 2001
+++ pgsql.dev/src/include/utils/builtins.h	Sat Jun  9 20:34:02 2001
@@ -22,6 +22,24 @@
 /*
  *		Defined in adt/
  */
+
+/* acl.c */
+extern Datum has_table_privilege_tname_tname(PG_FUNCTION_ARGS);
+extern Datum has_table_privilege_tname_name(PG_FUNCTION_ARGS);
+extern Datum has_table_privilege_name_tname(PG_FUNCTION_ARGS);
+extern Datum has_table_privilege_name_name(PG_FUNCTION_ARGS);
+extern Datum has_table_privilege_tname(PG_FUNCTION_ARGS);
+extern Datum has_table_privilege_name(PG_FUNCTION_ARGS);
+
+extern Datum has_table_privilege_tname_id(PG_FUNCTION_ARGS);
+extern Datum has_table_privilege_name_id(PG_FUNCTION_ARGS);
+extern Datum has_table_privilege_id(PG_FUNCTION_ARGS);
+
+extern Datum has_table_privilege_id_tname(PG_FUNCTION_ARGS);
+extern Datum has_table_privilege_id_name(PG_FUNCTION_ARGS);
+
+extern Datum has_table_privilege_id_id(PG_FUNCTION_ARGS);
+
 /* bool.c */
 extern Datum boolin(PG_FUNCTION_ARGS);
 extern Datum boolout(PG_FUNCTION_ARGS);
diff -Naur pgsql.virg/src/test/regress/expected/has_table_priv.out pgsql.dev/src/test/regress/expected/has_table_priv.out
--- pgsql.virg/src/test/regress/expected/has_table_priv.out	Thu Jan  1 00:00:00 1970
+++ pgsql.dev/src/test/regress/expected/has_table_priv.out	Sun Jun 10 00:27:38 2001
@@ -0,0 +1,479 @@
+\connect - postgres
+
+--
+-- user postgres, NULL input
+--
+
+select has_table_privilege(NULL,'pg_shadow','select');
+ has_table_privilege 
+---------------------
+ 
+(1 row)
+
+
+--
+-- user postgres, bad relname
+--
+
+select has_table_privilege('postgres','pg_shad','select');
+ERROR:  has_table_privilege: invalid relname pg_shad
+
+--
+-- user postgres, bad usename
+--
+
+select has_table_privilege('post','pg_shadow','select');
+ERROR:  has_table_privilege: invalid user name post
+
+--
+-- user postgres, bad priv_type
+--
+
+select has_table_privilege('postgres','pg_shadow','sel');
+ERROR:  has_table_privilege: invalid privilege type sel
+
+--
+-- user postgres, bad usesysid
+--
+
+select has_table_privilege(-999999,'pg_shadow','update');
+ERROR:  pg_aclcheck: invalid user id 4293967297
+
+--
+-- user postgres, bad rel oid
+--
+
+select has_table_privilege('postgres',-999999,'rule');
+ERROR:  has_table_privilege: invalid relation oid -999999
+
+--
+-- user postgres, rel pg_shadow
+--
+
+select has_table_privilege('postgres','pg_shadow','select');
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+select has_table_privilege('postgres','pg_shadow','insert');
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+
+select has_table_privilege(t2.usesysid,'pg_shadow','update') from (select usesysid from pg_user where usename = 'postgres') as t2;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+select has_table_privilege(t2.usesysid,'pg_shadow','delete') from (select usesysid from pg_user where usename = 'postgres') as t2;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+
+select has_table_privilege('postgres',t1.oid,'rule') from (select oid from pg_class where relname = 'pg_shadow') as t1;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+select has_table_privilege('postgres',t1.oid,'references') from (select oid from pg_class where relname = 'pg_shadow') as t1;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+
+select has_table_privilege(t2.usesysid,t1.oid,'select') from (select oid from pg_class where relname = 'pg_shadow') as t1,(select usesysid from pg_user where usename = 'postgres') as t2;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+select has_table_privilege(t2.usesysid,t1.oid,'insert') from (select oid from pg_class where relname = 'pg_shadow') as t1,(select usesysid from pg_user where usename = 'postgres') as t2;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+
+select has_table_privilege('pg_shadow','update');
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+select has_table_privilege('pg_shadow','delete');
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+
+select has_table_privilege(t1.oid,'select') from (select oid from pg_class where relname = 'pg_shadow') as t1;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+select has_table_privilege(t1.oid,'trigger') from (select oid from pg_class where relname = 'pg_shadow') as t1;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+
+--
+-- create rel testtable
+--
+
+create table testtable(f1 int, f2 text);
+
+--
+-- user postgres, rel testtable
+--
+
+select has_table_privilege('postgres','TESTtable','select');
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+select has_table_privilege('postgres','TESTtable','insert');
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+
+select has_table_privilege(t2.usesysid,'testtable','update') from (select usesysid from pg_user where usename = 'postgres') as t2;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+select has_table_privilege(t2.usesysid,'testtable','delete') from (select usesysid from pg_user where usename = 'postgres') as t2;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+
+select has_table_privilege('postgres',t1.oid,'rule') from (select oid from pg_class where relname = 'testtable') as t1;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+select has_table_privilege('postgres',t1.oid,'references') from (select oid from pg_class where relname = 'testtable') as t1;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+
+select has_table_privilege(t2.usesysid,t1.oid,'select') from (select oid from pg_class where relname = 'testtable') as t1,(select usesysid from pg_user where usename = 'postgres') as t2;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+select has_table_privilege(t2.usesysid,t1.oid,'insert') from (select oid from pg_class where relname = 'testtable') as t1,(select usesysid from pg_user where usename = 'postgres') as t2;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+
+select has_table_privilege('testtable','update');
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+select has_table_privilege('testtable','delete');
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+
+select has_table_privilege(t1.oid,'rule') from (select oid from pg_class where relname = 'testtable') as t1;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+select has_table_privilege(t1.oid,'trigger') from (select oid from pg_class where relname = 'testtable') as t1;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+
+--
+-- create new user, grant on testtable, and connect
+--
+
+create user foo;
+grant select on testtable to foo;
+grant update on testtable to foo;
+grant rule on testtable to foo;
+\connect - foo
+
+--
+-- user foo, rel pg_shadow
+--
+
+select has_table_privilege('foo','pg_class','select');
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+select has_table_privilege('foo','pg_class','insert');
+ has_table_privilege 
+---------------------
+ f
+(1 row)
+
+
+select has_table_privilege(t2.usesysid,'pg_class','update') from (select usesysid from pg_user where usename = 'foo') as t2;
+ has_table_privilege 
+---------------------
+ f
+(1 row)
+
+select has_table_privilege(t2.usesysid,'pg_class','delete') from (select usesysid from pg_user where usename = 'foo') as t2;
+ has_table_privilege 
+---------------------
+ f
+(1 row)
+
+
+select has_table_privilege('foo',t1.oid,'rule') from (select oid from pg_class where relname = 'pg_class') as t1;
+ has_table_privilege 
+---------------------
+ f
+(1 row)
+
+select has_table_privilege('foo',t1.oid,'references') from (select oid from pg_class where relname = 'pg_class') as t1;
+ has_table_privilege 
+---------------------
+ f
+(1 row)
+
+
+select has_table_privilege(t2.usesysid,t1.oid,'select') from (select oid from pg_class where relname = 'pg_class') as t1,(select usesysid from pg_user where usename = 'foo') as t2;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+select has_table_privilege(t2.usesysid,t1.oid,'insert') from (select oid from pg_class where relname = 'pg_class') as t1,(select usesysid from pg_user where usename = 'foo') as t2;
+ has_table_privilege 
+---------------------
+ f
+(1 row)
+
+
+select has_table_privilege('pg_class','update');
+ has_table_privilege 
+---------------------
+ f
+(1 row)
+
+select has_table_privilege('pg_class','delete');
+ has_table_privilege 
+---------------------
+ f
+(1 row)
+
+
+select has_table_privilege(t1.oid,'select') from (select oid from pg_class where relname = 'pg_class') as t1;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+select has_table_privilege(t1.oid,'trigger') from (select oid from pg_class where relname = 'pg_class') as t1;
+ has_table_privilege 
+---------------------
+ f
+(1 row)
+
+
+--
+-- user foo, rel testtable
+--
+
+select has_table_privilege('foo','testtable','select');
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+select has_table_privilege('foo','testtable','insert');
+ has_table_privilege 
+---------------------
+ f
+(1 row)
+
+
+select has_table_privilege(t2.usesysid,'testtable','update') from (select usesysid from pg_user where usename = 'foo') as t2;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+select has_table_privilege(t2.usesysid,'testtable','delete') from (select usesysid from pg_user where usename = 'foo') as t2;
+ has_table_privilege 
+---------------------
+ f
+(1 row)
+
+
+select has_table_privilege('foo',t1.oid,'rule') from (select oid from pg_class where relname = 'testtable') as t1;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+select has_table_privilege('foo',t1.oid,'references') from (select oid from pg_class where relname = 'testtable') as t1;
+ has_table_privilege 
+---------------------
+ f
+(1 row)
+
+
+select has_table_privilege(t2.usesysid,t1.oid,'select') from (select oid from pg_class where relname = 'testtable') as t1,(select usesysid from pg_user where usename = 'foo') as t2;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+select has_table_privilege(t2.usesysid,t1.oid,'insert') from (select oid from pg_class where relname = 'testtable') as t1,(select usesysid from pg_user where usename = 'foo') as t2;
+ has_table_privilege 
+---------------------
+ f
+(1 row)
+
+
+select has_table_privilege('testtable','update');
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+select has_table_privilege('testtable','delete');
+ has_table_privilege 
+---------------------
+ f
+(1 row)
+
+
+select has_table_privilege(t1.oid,'select') from (select oid from pg_class where relname = 'testtable') as t1;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+select has_table_privilege(t1.oid,'trigger') from (select oid from pg_class where relname = 'testtable') as t1;
+ has_table_privilege 
+---------------------
+ f
+(1 row)
+
+
+--
+-- create rel "Quoted RelName"
+--
+
+\connect - postgres
+create table "Quoted RelName" (f1 int, f2 text);
+
+--
+-- user postgres, rel "Quoted RelName", name based variants
+--
+
+select has_table_privilege('postgres','"Quoted RelName"','select');
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+select has_table_privilege('postgres',t1.relname,'select') from (select relname from pg_class where relname = 'Quoted RelName') as t1;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+select has_table_privilege(t1.usename,'"Quoted RelName"','select') from (select usename from pg_user where usename = 'postgres') as t1;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+select has_table_privilege(t1.usename,t2.relname,'select') from (select usename from pg_user where usename = 'postgres') as t1, (select relname from pg_class where relname = 'Quoted RelName') as t2;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+select has_table_privilege('"Quoted RelName"','select');
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+select has_table_privilege(t1.relname,'select') from (select relname from pg_class where relname = 'Quoted RelName') as t1;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+
+select has_table_privilege('postgres',t1.oid,'rule') from (select oid from pg_class where relname = 'Quoted RelName') as t1;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+select has_table_privilege(t1.usename,t2.oid,'rule') from (select usename from pg_user where usename = 'postgres') as t1, (select oid from pg_class where relname = 'Quoted RelName') as t2;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+select has_table_privilege(t1.oid,'rule') from (select oid from pg_class where relname = 'Quoted RelName') as t1;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+
+select has_table_privilege(t1.usesysid,'"Quoted RelName"','select') from (select usesysid from pg_user where usename = 'postgres') as t1;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+select has_table_privilege(t1.usesysid,t2.relname,'select') from (select usesysid from pg_user where usename = 'postgres') as t1, (select relname from pg_class where relname = 'Quoted RelName') as t2;
+ has_table_privilege 
+---------------------
+ t
+(1 row)
+
+
+--
+-- Clean up
+--
+
+drop user foo;
+drop table testtable;
+drop table "Quoted RelName";
diff -Naur pgsql.virg/src/test/regress/parallel_schedule pgsql.dev/src/test/regress/parallel_schedule
--- pgsql.virg/src/test/regress/parallel_schedule	Sun Jun 10 01:59:42 2001
+++ pgsql.dev/src/test/regress/parallel_schedule	Sat Jun  9 20:08:18 2001
@@ -62,6 +62,7 @@
 test: select_into select_distinct select_distinct_on select_implicit select_having subselect union case join aggregates transactions random portals arrays btree_index hash_index
 
 test: privileges
+test: has_table_priv
 test: misc
 
 # ----------
diff -Naur pgsql.virg/src/test/regress/serial_schedule pgsql.dev/src/test/regress/serial_schedule
--- pgsql.virg/src/test/regress/serial_schedule	Sun Jun 10 01:59:43 2001
+++ pgsql.dev/src/test/regress/serial_schedule	Sat Jun  9 19:50:29 2001
@@ -69,6 +69,7 @@
 test: btree_index
 test: hash_index
 test: privileges
+test: has_table_priv
 test: misc
 test: select_views
 test: alter_table
diff -Naur pgsql.virg/src/test/regress/sql/has_table_priv.sql pgsql.dev/src/test/regress/sql/has_table_priv.sql
--- pgsql.virg/src/test/regress/sql/has_table_priv.sql	Thu Jan  1 00:00:00 1970
+++ pgsql.dev/src/test/regress/sql/has_table_priv.sql	Sun Jun 10 00:59:52 2001
@@ -0,0 +1,174 @@
+\connect - postgres
+
+--
+-- user postgres, NULL input
+--
+
+select has_table_privilege(NULL,'pg_shadow','select');
+
+--
+-- user postgres, bad relname
+--
+
+select has_table_privilege('postgres','pg_shad','select');
+
+--
+-- user postgres, bad usename
+--
+
+select has_table_privilege('post','pg_shadow','select');
+
+--
+-- user postgres, bad priv_type
+--
+
+select has_table_privilege('postgres','pg_shadow','sel');
+
+--
+-- user postgres, bad usesysid
+--
+
+select has_table_privilege(-999999,'pg_shadow','update');
+
+--
+-- user postgres, bad rel oid
+--
+
+select has_table_privilege('postgres',-999999,'rule');
+
+--
+-- user postgres, rel pg_shadow
+--
+
+select has_table_privilege('postgres','pg_shadow','select');
+select has_table_privilege('postgres','pg_shadow','insert');
+
+select has_table_privilege(t2.usesysid,'pg_shadow','update') from (select usesysid from pg_user where usename = 'postgres') as t2;
+select has_table_privilege(t2.usesysid,'pg_shadow','delete') from (select usesysid from pg_user where usename = 'postgres') as t2;
+
+select has_table_privilege('postgres',t1.oid,'rule') from (select oid from pg_class where relname = 'pg_shadow') as t1;
+select has_table_privilege('postgres',t1.oid,'references') from (select oid from pg_class where relname = 'pg_shadow') as t1;
+
+select has_table_privilege(t2.usesysid,t1.oid,'select') from (select oid from pg_class where relname = 'pg_shadow') as t1,(select usesysid from pg_user where usename = 'postgres') as t2;
+select has_table_privilege(t2.usesysid,t1.oid,'insert') from (select oid from pg_class where relname = 'pg_shadow') as t1,(select usesysid from pg_user where usename = 'postgres') as t2;
+
+select has_table_privilege('pg_shadow','update');
+select has_table_privilege('pg_shadow','delete');
+
+select has_table_privilege(t1.oid,'select') from (select oid from pg_class where relname = 'pg_shadow') as t1;
+select has_table_privilege(t1.oid,'trigger') from (select oid from pg_class where relname = 'pg_shadow') as t1;
+
+--
+-- create rel testtable
+--
+
+create table testtable(f1 int, f2 text);
+
+--
+-- user postgres, rel testtable
+--
+
+select has_table_privilege('postgres','TESTtable','select');
+select has_table_privilege('postgres','TESTtable','insert');
+
+select has_table_privilege(t2.usesysid,'testtable','update') from (select usesysid from pg_user where usename = 'postgres') as t2;
+select has_table_privilege(t2.usesysid,'testtable','delete') from (select usesysid from pg_user where usename = 'postgres') as t2;
+
+select has_table_privilege('postgres',t1.oid,'rule') from (select oid from pg_class where relname = 'testtable') as t1;
+select has_table_privilege('postgres',t1.oid,'references') from (select oid from pg_class where relname = 'testtable') as t1;
+
+select has_table_privilege(t2.usesysid,t1.oid,'select') from (select oid from pg_class where relname = 'testtable') as t1,(select usesysid from pg_user where usename = 'postgres') as t2;
+select has_table_privilege(t2.usesysid,t1.oid,'insert') from (select oid from pg_class where relname = 'testtable') as t1,(select usesysid from pg_user where usename = 'postgres') as t2;
+
+select has_table_privilege('testtable','update');
+select has_table_privilege('testtable','delete');
+
+select has_table_privilege(t1.oid,'rule') from (select oid from pg_class where relname = 'testtable') as t1;
+select has_table_privilege(t1.oid,'trigger') from (select oid from pg_class where relname = 'testtable') as t1;
+
+--
+-- create new user, grant on testtable, and connect
+--
+
+create user foo;
+grant select on testtable to foo;
+grant update on testtable to foo;
+grant rule on testtable to foo;
+\connect - foo
+
+--
+-- user foo, rel pg_shadow
+--
+
+select has_table_privilege('foo','pg_class','select');
+select has_table_privilege('foo','pg_class','insert');
+
+select has_table_privilege(t2.usesysid,'pg_class','update') from (select usesysid from pg_user where usename = 'foo') as t2;
+select has_table_privilege(t2.usesysid,'pg_class','delete') from (select usesysid from pg_user where usename = 'foo') as t2;
+
+select has_table_privilege('foo',t1.oid,'rule') from (select oid from pg_class where relname = 'pg_class') as t1;
+select has_table_privilege('foo',t1.oid,'references') from (select oid from pg_class where relname = 'pg_class') as t1;
+
+select has_table_privilege(t2.usesysid,t1.oid,'select') from (select oid from pg_class where relname = 'pg_class') as t1,(select usesysid from pg_user where usename = 'foo') as t2;
+select has_table_privilege(t2.usesysid,t1.oid,'insert') from (select oid from pg_class where relname = 'pg_class') as t1,(select usesysid from pg_user where usename = 'foo') as t2;
+
+select has_table_privilege('pg_class','update');
+select has_table_privilege('pg_class','delete');
+
+select has_table_privilege(t1.oid,'select') from (select oid from pg_class where relname = 'pg_class') as t1;
+select has_table_privilege(t1.oid,'trigger') from (select oid from pg_class where relname = 'pg_class') as t1;
+
+--
+-- user foo, rel testtable
+--
+
+select has_table_privilege('foo','testtable','select');
+select has_table_privilege('foo','testtable','insert');
+
+select has_table_privilege(t2.usesysid,'testtable','update') from (select usesysid from pg_user where usename = 'foo') as t2;
+select has_table_privilege(t2.usesysid,'testtable','delete') from (select usesysid from pg_user where usename = 'foo') as t2;
+
+select has_table_privilege('foo',t1.oid,'rule') from (select oid from pg_class where relname = 'testtable') as t1;
+select has_table_privilege('foo',t1.oid,'references') from (select oid from pg_class where relname = 'testtable') as t1;
+
+select has_table_privilege(t2.usesysid,t1.oid,'select') from (select oid from pg_class where relname = 'testtable') as t1,(select usesysid from pg_user where usename = 'foo') as t2;
+select has_table_privilege(t2.usesysid,t1.oid,'insert') from (select oid from pg_class where relname = 'testtable') as t1,(select usesysid from pg_user where usename = 'foo') as t2;
+
+select has_table_privilege('testtable','update');
+select has_table_privilege('testtable','delete');
+
+select has_table_privilege(t1.oid,'select') from (select oid from pg_class where relname = 'testtable') as t1;
+select has_table_privilege(t1.oid,'trigger') from (select oid from pg_class where relname = 'testtable') as t1;
+
+--
+-- create rel "Quoted RelName"
+--
+
+\connect - postgres
+create table "Quoted RelName" (f1 int, f2 text);
+
+--
+-- user postgres, rel "Quoted RelName", name based variants
+--
+
+select has_table_privilege('postgres','"Quoted RelName"','select');
+select has_table_privilege('postgres',t1.relname,'select') from (select relname from pg_class where relname = 'Quoted RelName') as t1;
+select has_table_privilege(t1.usename,'"Quoted RelName"','select') from (select usename from pg_user where usename = 'postgres') as t1;
+select has_table_privilege(t1.usename,t2.relname,'select') from (select usename from pg_user where usename = 'postgres') as t1, (select relname from pg_class where relname = 'Quoted RelName') as t2;
+select has_table_privilege('"Quoted RelName"','select');
+select has_table_privilege(t1.relname,'select') from (select relname from pg_class where relname = 'Quoted RelName') as t1;
+
+select has_table_privilege('postgres',t1.oid,'rule') from (select oid from pg_class where relname = 'Quoted RelName') as t1;
+select has_table_privilege(t1.usename,t2.oid,'rule') from (select usename from pg_user where usename = 'postgres') as t1, (select oid from pg_class where relname = 'Quoted RelName') as t2;
+select has_table_privilege(t1.oid,'rule') from (select oid from pg_class where relname = 'Quoted RelName') as t1;
+
+select has_table_privilege(t1.usesysid,'"Quoted RelName"','select') from (select usesysid from pg_user where usename = 'postgres') as t1;
+select has_table_privilege(t1.usesysid,t2.relname,'select') from (select usesysid from pg_user where usename = 'postgres') as t1, (select relname from pg_class where relname = 'Quoted RelName') as t2;
+
+--
+-- Clean up
+--
+
+drop user foo;
+drop table testtable;
+drop table "Quoted RelName";
