diff -Naur pgsql.virg/src/backend/utils/adt/Makefile pgsql/src/backend/utils/adt/Makefile
--- pgsql.virg/src/backend/utils/adt/Makefile	Thu May 31 04:21:26 2001
+++ pgsql/src/backend/utils/adt/Makefile	Thu May 31 05:51:18 2001
@@ -17,7 +17,7 @@
 
 OBJS = acl.o arrayfuncs.o arrayutils.o bool.o cash.o char.o \
 	date.o datetime.o datum.o float.o format_type.o \
-	geo_ops.o geo_selfuncs.o int.o int8.o like.o \
+	geo_ops.o geo_selfuncs.o has_priv.o int.o int8.o like.o \
 	misc.o nabstime.o name.o not_in.o numeric.o numutils.o \
 	oid.o oracle_compat.o \
 	regexp.o regproc.o ruleutils.o selfuncs.o sets.o \
diff -Naur pgsql.virg/src/backend/utils/adt/has_priv.c pgsql/src/backend/utils/adt/has_priv.c
--- pgsql.virg/src/backend/utils/adt/has_priv.c	Thu Jan  1 00:00:00 1970
+++ pgsql/src/backend/utils/adt/has_priv.c	Fri Jun  1 05:34:49 2001
@@ -0,0 +1,158 @@
+/*
+ * has_priv.c
+ *
+ * Check for user privileges
+ *
+ * Copyright (c) Joseph Conway <joe.conway@mail.com>, 2001;
+ * 
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without a written agreement
+ * is hereby granted, provided that the above copyright notice and this
+ * paragraph and the following two paragraphs appear in all copies.
+ * 
+ * IN NO EVENT SHALL THE AUTHOR OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
+ * LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
+ * DOCUMENTATION, EVEN IF THE AUTHOR OR DISTRIBUTORS HAVE BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ * 
+ * THE AUTHOR AND DISTRIBUTORS SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE AUTHOR AND DISTRIBUTORS HAS NO OBLIGATIONS TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ */
+
+
+#include "utils/has_priv.h"
+
+/*
+ * has_privilege
+ *
+ * Check user privileges on a relation
+ * Returns bool
+ *
+ */
+
+PG_FUNCTION_INFO_V1(has_privilege);
+Datum
+has_privilege(PG_FUNCTION_ARGS)
+{
+	text		*username_text;
+	text		*relname_text;
+	text		*priv_type_text;
+	char		*relname;
+	char		*username;
+	char		*priv_type;
+	AclMode		mode;
+	int32		result;
+	HeapTuple	tuple;
+	Oid			userid;
+
+	if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2))
+	{
+		elog(ERROR, "has_privilege: NULL arguments are not permitted");
+	}
+
+	username_text = PG_GETARG_TEXT_P(0);
+	relname_text = PG_GETARG_TEXT_P(1);
+	priv_type_text = PG_GETARG_TEXT_P(2);
+
+	/* 
+	 * Convert 'text' pattern to null-terminated string
+	 */
+
+	relname = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(relname_text)));
+	username = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(username_text)));
+	priv_type = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(priv_type_text)));
+
+	/*
+	 * Lookup userid based on username
+	 */
+
+	tuple = SearchSysCache(SHADOWNAME, NameGetDatum(username), 0, 0, 0);
+	if (!HeapTupleIsValid(tuple)) {
+		elog(ERROR, "has_privilege: invalid user name %s", (char *) username);
+	}
+
+	userid = ((Form_pg_shadow) GETSTRUCT(tuple))->usesysid;
+
+	ReleaseSysCache(tuple);
+
+	/*
+	 * Verify relname is valid
+	 */
+
+	tuple = SearchSysCache(RELNAME, NameGetDatum(relname), 0, 0, 0);
+	if (!HeapTupleIsValid(tuple)) {
+		elog(ERROR, "has_privilege: invalid relation name %s", (char *) relname);
+	}
+
+	ReleaseSysCache(tuple);
+
+
+	/*
+	 * select = ACL_SELECT
+	 * update = ACL_UPDATE
+	 * delete = ACL_DELETE
+	 * rule = ACL_RULE
+	 * insert = ACL_INSERT
+	 * references = ACL_REFERENCES
+	 * trigger = ACL_TRIGGER
+	 * 
+	 * OLD COMMENTS -- pre REL 7.2
+	 * select = r = (ACL_RD)
+	 * update = w (ACL_WR)
+	 * delete = w (ACL_WR)
+	 * rule = R (ACL_RU)
+	 * insert = a (ACL_AP) or w (ACL_WR)
+	 *
+	 */
+
+
+	if (strcasecmp(priv_type, PRIV_SELECT) == 0) {
+
+		mode = (AclMode) ACL_SELECT;
+
+	} else if (strcasecmp(priv_type, PRIV_INSERT) == 0) {
+
+		mode = (AclMode) ACL_INSERT;
+
+	} else if (strcasecmp(priv_type, PRIV_UPDATE) == 0) {
+
+		mode = (AclMode) ACL_UPDATE;
+
+	} else if (strcasecmp(priv_type, PRIV_DELETE) == 0) {
+
+		mode = (AclMode) ACL_DELETE;
+
+	} else if (strcasecmp(priv_type, PRIV_RULE) == 0) {
+
+		mode = (AclMode) ACL_RULE;
+
+	} else if (strcasecmp(priv_type, PRIV_REFERENCES) == 0) {
+
+		mode = (AclMode) ACL_REFERENCES;
+
+	} else if (strcasecmp(priv_type, PRIV_TRIGGER) == 0) {
+
+		mode = (AclMode) ACL_TRIGGER;
+
+	} else {
+
+		mode = (AclMode) ACL_NO;
+		elog(ERROR, "has_privilege: invalid privilege type %s", (char *) priv_type);
+
+	}
+
+	result = pg_aclcheck(relname, userid, mode);
+
+
+	if (result == 1) {
+		PG_RETURN_BOOL(FALSE);
+	} else {
+		PG_RETURN_BOOL(TRUE);
+	}
+}
+
diff -Naur pgsql.virg/src/include/catalog/pg_proc.h pgsql/src/include/catalog/pg_proc.h
--- pgsql.virg/src/include/catalog/pg_proc.h	Thu May 31 04:21:33 2001
+++ pgsql/src/include/catalog/pg_proc.h	Fri Jun  1 05:52:14 2001
@@ -2614,6 +2614,9 @@
 DATA(insert OID = 1909 (  int8shr		   PGUID 12 f t t t 2 f 20 "20 23" 100 0 0 100	int8shr - ));
 DESCR("binary shift right");
 
+DATA(insert OID = 1920 (  has_privilege	   PGUID 12 f t f f 3 f 16 "25 25 25" 100 0 0 100	has_privilege - ));
+DESCR("determine privileges");
+
 /*
  * prototypes for functions pg_proc.c
  */
diff -Naur pgsql.virg/src/include/utils/builtins.h pgsql/src/include/utils/builtins.h
--- pgsql.virg/src/include/utils/builtins.h	Thu May 31 04:21:34 2001
+++ pgsql/src/include/utils/builtins.h	Thu May 31 05:52:23 2001
@@ -608,4 +608,7 @@
 extern Datum quote_ident(PG_FUNCTION_ARGS);
 extern Datum quote_literal(PG_FUNCTION_ARGS);
 
+/* has_priv.c */
+extern Datum has_privilege(PG_FUNCTION_ARGS);
+
 #endif	 /* BUILTINS_H */
diff -Naur pgsql.virg/src/include/utils/has_priv.h pgsql/src/include/utils/has_priv.h
--- pgsql.virg/src/include/utils/has_priv.h	Thu Jan  1 00:00:00 1970
+++ pgsql/src/include/utils/has_priv.h	Fri Jun  1 05:19:49 2001
@@ -0,0 +1,55 @@
+/*
+ * has_priv.h
+ *
+ * Check for user privileges
+ *
+ * Copyright (c) Joseph Conway <joe.conway@mail.com>, 2001;
+ * 
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without a written agreement
+ * is hereby granted, provided that the above copyright notice and this
+ * paragraph and the following two paragraphs appear in all copies.
+ * 
+ * IN NO EVENT SHALL THE AUTHOR OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
+ * LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
+ * DOCUMENTATION, EVEN IF THE AUTHOR OR DISTRIBUTORS HAVE BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ * 
+ * THE AUTHOR AND DISTRIBUTORS SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE AUTHOR AND DISTRIBUTORS HAS NO OBLIGATIONS TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ */
+
+#ifndef HAS_PRIV_H
+#define HAS_PRIV_H
+
+#include <string.h>
+#include <ctype.h>
+#include "postgres.h"
+#include "access/heapam.h"
+#include "fmgr.h"
+#include "utils/acl.h"
+#include "utils/builtins.h"
+#include "utils/syscache.h"
+#include "catalog/pg_shadow.h"
+
+#include "storage/proc.h"
+#include "catalog/catname.h"
+#include "utils/fmgroids.h"
+#include "catalog/pg_database.h"
+
+extern Datum has_privilege(PG_FUNCTION_ARGS);
+
+#define PRIV_INSERT			"INSERT\0"
+#define PRIV_SELECT			"SELECT\0"
+#define PRIV_UPDATE			"UPDATE\0"
+#define PRIV_DELETE			"DELETE\0"
+#define PRIV_RULE			"RULE\0"
+#define PRIV_REFERENCES		"REFERENCES\0"
+#define PRIV_TRIGGER		"TRIGGER\0"
+
+#endif	 /* HAS_PRIV_H */
