aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/acl.c757
-rw-r--r--src/include/catalog/pg_proc.h31
-rw-r--r--src/include/utils/acl.h18
-rw-r--r--src/include/utils/builtins.h20
-rw-r--r--src/test/regress/parallel_schedule1
-rw-r--r--src/test/regress/serial_schedule3
6 files changed, 825 insertions, 5 deletions
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
index eeb95430271..14bf6e3c801 100644
--- a/src/backend/utils/adt/acl.c
+++ b/src/backend/utils/adt/acl.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.61 2001/06/09 23:21:55 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.62 2001/06/12 15:58:34 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -31,6 +31,12 @@ static const char *getid(const char *s, char *n);
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"
@@ -710,3 +716,752 @@ makeAclString(const char *privileges, const char *grantee, char grant_or_revoke)
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 --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 1208e686920..cee5017a695 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_proc.h,v 1.189 2001/06/07 00:09:30 momjian Exp $
+ * $Id: pg_proc.h,v 1.190 2001/06/12 15:58:34 momjian Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
@@ -2627,6 +2627,35 @@ DESCR("unary plus");
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 --git a/src/include/utils/acl.h b/src/include/utils/acl.h
index 1cf751fad13..f03d6e2e1b4 100644
--- a/src/include/utils/acl.h
+++ b/src/include/utils/acl.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: acl.h,v 1.34 2001/06/09 23:21:55 petere Exp $
+ * $Id: acl.h,v 1.35 2001/06/12 15:58:34 momjian Exp $
*
* NOTES
* For backward-compatibility purposes we have to allow there
@@ -191,6 +191,22 @@ extern Datum aclcontains(PG_FUNCTION_ARGS);
extern const char *aclparse(const char *s, AclItem *aip, unsigned *modechg);
extern char *makeAclString(const char *privileges, const char *grantee, char grant_or_revoke);
+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 --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index 109d144494a..ea53e503039 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: builtins.h,v 1.150 2001/06/09 22:16:17 tgl Exp $
+ * $Id: builtins.h,v 1.151 2001/06/12 15:58:34 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -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 --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
index 08e97511ac9..7e6f9f6e2e2 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -62,6 +62,7 @@ ignore: random
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 --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule
index afb0090cdad..d559fdaf35f 100644
--- a/src/test/regress/serial_schedule
+++ b/src/test/regress/serial_schedule
@@ -1,4 +1,4 @@
-# $Header: /cvsroot/pgsql/src/test/regress/serial_schedule,v 1.4 2001/05/27 09:59:30 petere Exp $
+# $Header: /cvsroot/pgsql/src/test/regress/serial_schedule,v 1.5 2001/06/12 15:58:34 momjian Exp $
# This should probably be in an order similar to parallel_schedule.
test: boolean
test: char
@@ -69,6 +69,7 @@ test: arrays
test: btree_index
test: hash_index
test: privileges
+test: has_table_priv
test: misc
test: select_views
test: alter_table