diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index f46a848d42499da44f145a6a0d3a132cd55f6488..12ee1c28f17328b254a3441dfddcb1d11e4796e3 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -6,7 +6,7 @@
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.21 1997/01/10 17:46:33 momjian Exp $
+ *    $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.22 1997/03/12 20:47:32 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -102,13 +102,15 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
     Relation rel;
     extern char *UserName;    /* defined in global.c */
     const AclMode required_access = from ? ACL_WR : ACL_RD;
+    int result;
 
     rel = heap_openr(relname);
     if (rel == NULL) elog(WARN, "COPY command failed.  Class %s "
                           "does not exist.", relname);
-    
-    if (!pg_aclcheck(relname, UserName, required_access))
-        elog(WARN, "%s %s", relname, ACL_NO_PRIV_WARNING);
+
+    result = pg_aclcheck(relname, UserName, required_access);
+    if(result != ACLCHECK_OK)
+        elog(WARN, "%s: %s", relname, aclcheck_error_strings[result]);
         /* Above should not return */
     else if (!superuser() && !pipe)
         elog(WARN, "You must have Postgres superuser privilege to do a COPY "
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 11c8f91a8d40591231cf69a73eb4a88f4b3d814d..cff5081c3744ee13adc6973654684133cd76719a 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -26,7 +26,7 @@
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.10 1997/01/22 05:26:27 vadim Exp $
+ *    $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.11 1997/03/12 20:47:41 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -289,7 +289,7 @@ ExecCheckPerms(CmdType operation,
     HeapTuple htp;
     List *lp;
     List *qvars, *tvars;
-    int32 ok = 1;
+    int32 ok = 1, aclcheck_result = -1;
     char *opstr;
     NameData rname;
     char *userName;
@@ -317,21 +317,21 @@ ExecCheckPerms(CmdType operation,
 	    if (intMember(resultRelation, qvars) ||
 		intMember(resultRelation, tvars)) {
 		/* result relation is scanned */
-		ok = CHECK(ACL_RD);
+		ok = ((aclcheck_result = CHECK(ACL_RD)) == ACLCHECK_OK);
 		opstr = "read";
 		if (!ok)
 		    break;
 	    }
 	    switch (operation) {
 	    case CMD_INSERT:
-		ok = CHECK(ACL_AP) ||
-		    CHECK(ACL_WR);
+		ok = ((aclcheck_result = CHECK(ACL_AP)) == ACLCHECK_OK) ||
+		     ((aclcheck_result = CHECK(ACL_WR)) == ACLCHECK_OK);
 		opstr = "append";
 		break;
 	    case CMD_NOTIFY: /* what does this mean?? -- jw, 1/6/94 */
 	    case CMD_DELETE:
 	    case CMD_UPDATE:
-		ok = CHECK(ACL_WR);
+		ok = ((aclcheck_result = CHECK(ACL_WR)) == ACLCHECK_OK);
 		opstr = "write";
 		break;
 	    default:
@@ -340,7 +340,7 @@ ExecCheckPerms(CmdType operation,
 	    }
 	} else {
 	    /* XXX NOTIFY?? */
-	    ok = CHECK(ACL_RD);
+	    ok = ((aclcheck_result = CHECK(ACL_RD)) == ACLCHECK_OK);
 	    opstr = "read";
 	}
 	if (!ok)
@@ -352,7 +352,7 @@ ExecCheckPerms(CmdType operation,
 	elog(WARN, "%s on \"%-.*s\": permission denied", opstr, 
 	     NAMEDATALEN, rname.data);
 */	    
-	elog(WARN, "%s %s", rname.data, ACL_NO_PRIV_WARNING);
+	elog(WARN, "%s: %s", rname.data, aclcheck_error_strings[aclcheck_result]);
     }
 }
 
diff --git a/src/backend/parser/parse_query.c b/src/backend/parser/parse_query.c
index 398685bed4adcabfffc195fe0e42f7a93c796a11..2411e264974c69823ef7f37bea291e91a7c4a4dc 100644
--- a/src/backend/parser/parse_query.c
+++ b/src/backend/parser/parse_query.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/backend/parser/Attic/parse_query.c,v 1.14 1997/02/14 23:02:29 momjian Exp $
+ *    $Header: /cvsroot/pgsql/src/backend/parser/Attic/parse_query.c,v 1.15 1997/03/12 20:47:57 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -133,7 +133,7 @@ addRangeTableEntry(ParseState *pstate,
     relation = heap_openr(relname);
     if (relation == NULL) {
 	elog(WARN,"%s: %s",
-	     relname, ACL_NO_PRIV_WARNING);
+	     relname, aclcheck_error_strings[ACLCHECK_NO_CLASS]);
     }
 
     /*
diff --git a/src/backend/tcop/aclchk.c b/src/backend/tcop/aclchk.c
index b58a750343c7bd63cc0649340a5dede5c7dfb0d9..20748e16c6a720f9e87b1831b9a0fd545549f04b 100644
--- a/src/backend/tcop/aclchk.c
+++ b/src/backend/tcop/aclchk.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/backend/tcop/Attic/aclchk.c,v 1.6 1997/01/23 19:33:31 scrappy Exp $
+ *    $Header: /cvsroot/pgsql/src/backend/tcop/Attic/aclchk.c,v 1.7 1997/03/12 20:48:17 scrappy Exp $
  *
  * NOTES
  *    See acl.h.
@@ -17,7 +17,7 @@
 #include <string.h>
 #include "postgres.h"
 
-#include "utils/acl.h"		/* where declarations for this file goes */
+#include "utils/acl.h"		/* where declarations for this file go */
 #include "access/heapam.h"
 #include "access/htup.h"
 #include "access/tupmacs.h"
@@ -55,6 +55,15 @@
 #define	Name_pg_group			"pggroup"
 #endif
 
+/* warning messages, now more explicit. */
+/* should correspond to the order of the ACLCHK_* result codes above. */
+char *aclcheck_error_strings[] = {
+  "No error.",
+  "Permission denied.",
+  "Table does not exist.",
+  "Must be table owner."
+};
+
 #ifdef ACLDEBUG_TRACE
 static
 dumpacl(Acl *acl)
@@ -268,10 +277,10 @@ aclcheck(Acl *acl, AclId id, AclIdType idtype, AclMode mode)
      * the system never creates an empty ACL.
      */
     if (num < 1) {
-#ifdef ACLDEBUG_TRACE
+#ifdef ACLDEBUG_TRACE || 1
 	elog(DEBUG, "aclcheck: zero-length ACL, returning 1");
 #endif
-	return(1);
+	return ACLCHECK_OK;
     }
 
     switch (idtype) {
@@ -284,7 +293,7 @@ aclcheck(Acl *acl, AclId id, AclIdType idtype, AclMode mode)
 		elog(DEBUG, "aclcheck: found %d/%d",
 		     aip->ai_id, aip->ai_mode);
 #endif
-		return((aip->ai_mode & mode) ? 1 : 0);
+		return((aip->ai_mode & mode) ? ACLCHECK_OK : ACLCHECK_NO_PRIV);
 	    }
 	}
 	for (found_group = 0;
@@ -304,7 +313,7 @@ aclcheck(Acl *acl, AclId id, AclIdType idtype, AclMode mode)
 		    elog(DEBUG, "aclcheck: found %d/%d",
 			 aip->ai_id, aip->ai_mode);
 #endif
-		    return(0);
+		    return ACLCHECK_NO_PRIV;
 		}
 #endif
 	    }
@@ -313,7 +322,7 @@ aclcheck(Acl *acl, AclId id, AclIdType idtype, AclMode mode)
 #ifdef ACLDEBUG_TRACE
 	    elog(DEBUG,"aclcheck: all groups ok");
 #endif
-	    return(1);
+	    return ACLCHECK_OK;
 	}
 	break;
     case ACL_IDTYPE_GID:
@@ -329,7 +338,7 @@ aclcheck(Acl *acl, AclId id, AclIdType idtype, AclMode mode)
 		elog(DEBUG, "aclcheck: found %d/%d",
 		     aip->ai_id, aip->ai_mode);
 #endif
-		return((aip->ai_mode & mode) ? 1 : 0);
+		return((aip->ai_mode & mode) ? ACLCHECK_OK : ACLCHECK_NO_PRIV);
 	    }
 	}
 	break;
@@ -343,7 +352,7 @@ aclcheck(Acl *acl, AclId id, AclIdType idtype, AclMode mode)
 #ifdef ACLDEBUG_TRACE
     elog(DEBUG, "aclcheck: using world=%d", aidat->ai_mode);
 #endif
-    return((aidat->ai_mode & mode) ? 1 : 0);
+    return((aidat->ai_mode & mode) ? ACLCHECK_OK : ACLCHECK_NO_PRIV);
 }
 
 int32
@@ -370,7 +379,7 @@ pg_aclcheck(char *relname, char *usename, AclMode mode)
 	   pg_database table, there is still additional permissions checking
 	   in dbcommands.c */
 	if (mode & ACL_AP)
-	    return (1);
+	    return ACLCHECK_OK;
     }
 
     /*
@@ -383,7 +392,7 @@ pg_aclcheck(char *relname, char *usename, AclMode mode)
 	!((Form_pg_user) GETSTRUCT(htp))->usecatupd) {
 	elog(DEBUG, "pg_aclcheck: catalog update to \"%-.*s\": permission denied",
 	     NAMEDATALEN, relname);
-	return(0);
+	return ACLCHECK_NO_PRIV;
     }
 	
     /*
@@ -394,7 +403,7 @@ pg_aclcheck(char *relname, char *usename, AclMode mode)
 	elog(DEBUG, "pg_aclcheck: \"%-.*s\" is superuser",
 	     NAMEDATALEN, usename);
 #endif
-	return(1);
+	return ACLCHECK_OK;
     }
 	
 #ifndef ACLDEBUG
@@ -403,7 +412,7 @@ pg_aclcheck(char *relname, char *usename, AclMode mode)
     if (!HeapTupleIsValid(htp)) {
 	elog(WARN, "pg_aclcheck: class \"%-.*s\" not found",
 	     NAMEDATALEN, relname);
-	return(1);
+	/* an elog(WARN) kills us, so no need to return anything. */
     }
     if (!heap_attisnull(htp, Anum_pg_class_relacl)) {
 	relation = heap_openr(RelationRelationName);
@@ -436,7 +445,7 @@ pg_aclcheck(char *relname, char *usename, AclMode mode)
 	if (!RelationIsValid(relation)) {
 	    elog(NOTICE, "pg_checkacl: could not open \"%-.*s\"??",
 		 RelationRelationName);
-	    return(1);
+	    return ACLCHECK_NO_CLASS;
 	}
 	fmgr_info(NameEqualRegProcedure,
 		  &relkey[0].sk_func,
@@ -494,8 +503,8 @@ pg_ownercheck(char *usename,
     switch (cacheid) {
     case OPROID:
 	if (!HeapTupleIsValid(htp))
-	    elog(WARN, "pg_ownercheck: operator %d not found",
-		 (int) value);
+	    elog(WARN, "pg_ownercheck: operator %ld not found",
+		 PointerGetDatum(value));
 	owner_id = ((OperatorTupleForm) GETSTRUCT(htp))->oprowner;
 	break;
     case PRONAME:
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 693dadc8346096cd82dfc360f93a2a6709790b64..065d01457cc0feb0de0896162367608461d868f1 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.11 1997/01/16 14:56:21 momjian Exp $
+ *    $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.12 1997/03/12 20:48:27 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -381,10 +381,13 @@ ProcessUtility(Node *parsetree,
     case T_RuleStmt:            /* CREATE RULE */
 	{
 	    RuleStmt *stmt = (RuleStmt *)parsetree;
+	    int aclcheck_result;
+
 #ifndef NO_SECURITY
 	    relname = stmt->object->relname;
-	    if (!pg_aclcheck(relname, userName, ACL_RU))
-		elog(WARN, "%s %s", relname, ACL_NO_PRIV_WARNING);	
+	    aclcheck_result = pg_aclcheck(relname, userName, ACL_RU);
+	    if(aclcheck_result != ACLCHECK_OK)
+		elog(WARN, "%s: %s", relname, aclcheck_error_strings[aclcheck_result]);	
 #endif
 	    commandTag = "CREATE";
 	    CHECK_IF_ABORTED();
@@ -423,19 +426,21 @@ ProcessUtility(Node *parsetree,
 			 relname);
 #ifndef NO_SECURITY
 		if (!pg_ownercheck(userName, relname, RELNAME))
-		    elog(WARN, "you do not own class \"%s\"",
-			 relname);
+		    elog(WARN, "%s: %s", relationName, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
 #endif
 		RemoveIndex(relname);
 		break;
 	    case RULE:
 		{
 		    char *rulename = stmt->name;
+		    int aclcheck_result;
 #ifndef NO_SECURITY
 		
 		    relationName = RewriteGetRuleEventRel(rulename);
-		    if (!pg_aclcheck(relationName, userName, ACL_RU))
-			elog(WARN, "%s %s", relationName, ACL_NO_PRIV_WARNING);
+		    aclcheck_result = pg_aclcheck(relationName, userName, ACL_RU);
+		    if(aclcheck_result != ACLCHECK_OK) {
+		        elog(WARN, "%s: %s", relationName, aclcheck_error_strings[aclcheck_result]);
+		    }
 #endif
 		    RemoveRewriteRule(rulename);
 		}
@@ -457,7 +462,7 @@ ProcessUtility(Node *parsetree,
 		    ruleName = MakeRetrieveViewRuleName(viewName);
 		    relationName = RewriteGetRuleEventRel(ruleName);
 		    if (!pg_ownercheck(userName, relationName, RELNAME))
-			elog(WARN, "%s %s", relationName, ACL_NO_PRIV_WARNING);
+			elog(WARN, "%s: %s", relationName, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
 		    pfree(ruleName);
 #endif
 		    RemoveView(viewName);
diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h
index 978950150413f85b1c3c795d433929b1387c992e..bc4473d37d7dce500aa0b92364bf363b673c5e06 100644
--- a/src/include/utils/acl.h
+++ b/src/include/utils/acl.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: acl.h,v 1.4 1996/11/10 03:06:14 momjian Exp $
+ * $Id: acl.h,v 1.5 1997/03/12 20:48:48 scrappy Exp $
  *
  * NOTES
  *    For backward-compatability purposes we have to allow there
@@ -111,10 +111,14 @@ typedef ArrayType IdList;
 #define	ACL_MODE_WR_CHR		'w'
 #define	ACL_MODE_RU_CHR		'R'
 
-/* we use this warning string both for non-existent tables and
-   insufficient privilege so non-privileged users cannot ascertain whether 
-   the class exists or not */
-#define ACL_NO_PRIV_WARNING "Either no such class or insufficient privilege"
+/* result codes for pg_aclcheck */
+#define ACLCHECK_OK               0
+#define ACLCHECK_NO_PRIV          1
+#define ACLCHECK_NO_CLASS         2
+#define ACLCHECK_NOT_OWNER        3
+
+/* warning messages.  set these in aclchk.c. */
+extern char *aclcheck_error_strings[];
 
 /*
  * Enable ACL execution tracing and table dumps