Tom Lane <t...@sss.pgh.pa.us> Wednesday 23 February 2011 22:30:04
> =?utf-8?q?Rados=C5=82aw_Smogura?= <rsmog...@softperience.eu> writes:
> > Here is extended version, has version field (N_ACL_RIGHTS*2) and reserved
> > mask, as well definition is more general then def of PGSQL. In any way it
> > require that rights mades bit array.
> 
> You're going in quite the wrong direction here.  The consensus as I
> understood it was that we should just use the text representation in
> binary mode too, rather than inventing a separate representation that's
> going to put a whole new set of constraints on what can happen to the
> internal representation.  The proposal you have here has no redeeming
> social value whatever, because nobody cares about the I/O efficiency
> for aclitem (and even if anyone did, you've made no case that this would
> actually be more efficient to use on the client side).
> 
>                       regards, tom lane

Look at it. Pass call to in/out.

Regards,
Radek
diff --git a/.gitignore b/.gitignore
index 1be11e8..0d594f9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,3 +17,5 @@ objfiles.txt
 /GNUmakefile
 /config.log
 /config.status
+/nbproject/private/
+/nbproject
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
index 691ba3b..fa151cd 100644
--- a/src/backend/utils/adt/acl.c
+++ b/src/backend/utils/adt/acl.c
@@ -33,6 +33,7 @@
 #include "utils/lsyscache.h"
 #include "utils/memutils.h"
 #include "utils/syscache.h"
+#include "libpq/pqformat.h"
 
 
 typedef struct
@@ -77,7 +78,8 @@ static const char *getid(const char *s, char *n);
 static void putid(char *p, const char *s);
 static Acl *allocacl(int n);
 static void check_acl(const Acl *acl);
-static const char *aclparse(const char *s, AclItem *aip);
+static const char *aclparse(const char *s, AclItem *aip, bool binary);
+static Datum aclitem_common_in_recv(const char* s, bool binary);
 static bool aclitem_match(const AclItem *a1, const AclItem *a2);
 static int	aclitemComparator(const void *arg1, const void *arg2);
 static void check_circularity(const Acl *old_acl, const AclItem *mod_aip,
@@ -222,6 +224,8 @@ putid(char *p, const char *s)
  *
  *		This routine is called by the parser as well as aclitemin(), hence
  *		the added generality.
+ * 
+ * @param binary if we parse for binary mode or text mode
  *
  * RETURNS:
  *		the string position in 's' immediately following the ACL
@@ -230,7 +234,7 @@ putid(char *p, const char *s)
  *		  UID/GID, id type identifier and mode type values.
  */
 static const char *
-aclparse(const char *s, AclItem *aip)
+aclparse(const char *s, AclItem *aip, bool binary)
 {
 	AclMode		privs,
 				goption,
@@ -249,20 +253,20 @@ aclparse(const char *s, AclItem *aip)
 		/* we just read a keyword, not a name */
 		if (strcmp(name, "group") != 0 && strcmp(name, "user") != 0)
 			ereport(ERROR,
-					(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+					(errcode((binary ? ERRCODE_INVALID_BINARY_REPRESENTATION : ERRCODE_INVALID_TEXT_REPRESENTATION)),
 					 errmsg("unrecognized key word: \"%s\"", name),
 					 errhint("ACL key word must be \"group\" or \"user\".")));
 		s = getid(s, name);		/* move s to the name beyond the keyword */
 		if (name[0] == '\0')
 			ereport(ERROR,
-					(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+					(errcode((binary ? ERRCODE_INVALID_BINARY_REPRESENTATION : ERRCODE_INVALID_TEXT_REPRESENTATION)),
 					 errmsg("missing name"),
 					 errhint("A name must follow the \"group\" or \"user\" key word.")));
 	}
 
 	if (*s != '=')
 		ereport(ERROR,
-				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+				(errcode((binary ? ERRCODE_INVALID_BINARY_REPRESENTATION : ERRCODE_INVALID_TEXT_REPRESENTATION)),
 				 errmsg("missing \"=\" sign")));
 
 	privs = goption = ACL_NO_RIGHTS;
@@ -315,7 +319,7 @@ aclparse(const char *s, AclItem *aip)
 				break;
 			default:
 				ereport(ERROR,
-						(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+						(errcode((binary ? ERRCODE_INVALID_BINARY_REPRESENTATION : ERRCODE_INVALID_TEXT_REPRESENTATION)),
 					  errmsg("invalid mode character: must be one of \"%s\"",
 							 ACL_ALL_RIGHTS_STR)));
 		}
@@ -337,7 +341,7 @@ aclparse(const char *s, AclItem *aip)
 		s = getid(s + 1, name2);
 		if (name2[0] == '\0')
 			ereport(ERROR,
-					(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+					(errcode((binary ? ERRCODE_INVALID_BINARY_REPRESENTATION : ERRCODE_INVALID_TEXT_REPRESENTATION)),
 					 errmsg("a name must follow the \"/\" sign")));
 		aip->ai_grantor = get_role_oid(name2, false);
 	}
@@ -548,6 +552,22 @@ check_acl(const Acl *acl)
 				 errmsg("ACL arrays must not contain null values")));
 }
 
+static
+Datum aclitem_common_in_recv(const char* s, bool binary)
+{
+    AclItem    *aip;
+
+    aip = (AclItem *) palloc(sizeof(AclItem));
+    s = aclparse(s, aip, binary);
+    while (isspace((unsigned char) *s))
+            ++s;
+    if (*s)
+            ereport(ERROR,
+                            (errcode((binary ? ERRCODE_INVALID_BINARY_REPRESENTATION : ERRCODE_INVALID_TEXT_REPRESENTATION)),
+                       errmsg("extra garbage at the end of the ACL specification")));
+
+    PG_RETURN_ACLITEM_P(aip);
+}
 /*
  * aclitemin
  *		Allocates storage for, and fills in, a new AclItem given a string
@@ -559,19 +579,9 @@ check_acl(const Acl *acl)
 Datum
 aclitemin(PG_FUNCTION_ARGS)
 {
-	const char *s = PG_GETARG_CSTRING(0);
-	AclItem    *aip;
-
-	aip = (AclItem *) palloc(sizeof(AclItem));
-	s = aclparse(s, aip);
-	while (isspace((unsigned char) *s))
-		++s;
-	if (*s)
-		ereport(ERROR,
-				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
-			   errmsg("extra garbage at the end of the ACL specification")));
-
-	PG_RETURN_ACLITEM_P(aip);
+        const char *s = PG_GETARG_CSTRING(0);
+        
+        PG_RETURN_ACLITEM_P(aclitem_common_in_recv(s, false));
 }
 
 /*
@@ -644,6 +654,35 @@ aclitemout(PG_FUNCTION_ARGS)
 	PG_RETURN_CSTRING(out);
 }
 
+/** Pass call to {@link aclitem_common_in_recv} */
+Datum
+aclitemrecv(PG_FUNCTION_ARGS) {
+    StringInfo	buf = (StringInfo) PG_GETARG_POINTER(0);
+    char       *str;
+    int		nbytes;
+    AclItem    *out;
+    
+    str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
+    out = (AclItem*) aclitem_common_in_recv(str, true);
+    pfree(str);
+    
+    PG_RETURN_ACLITEM_P(out);
+}
+
+/** Pass call to {@link aclitemout}. */
+Datum
+aclitemsend(PG_FUNCTION_ARGS)
+{
+        StringInfoData  buf;
+        const char      *aclText;
+        
+        pq_begintypsend(&buf);        
+        aclText = (const char*) aclitemout(fcinfo);
+        pq_sendtext(&buf, aclText, strlen(aclText));
+
+	PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
+}
+
 /*
  * aclitem_match
  *		Two AclItems are considered to match iff they have the same
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 8c940bb..c56d8f8 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -4230,6 +4230,10 @@ DATA(insert OID = 3120 (  void_recv			   PGNSP PGUID 12 1 0 0 f f f t f i 1 0 22
 DESCR("I/O");
 DATA(insert OID = 3121 (  void_send			   PGNSP PGUID 12 1 0 0 f f f t f i 1 0 17 "2278" _null_ _null_ _null_ _null_	void_send _null_ _null_ _null_ ));
 DESCR("I/O");
+DATA(insert OID = 3122 (  aclitemrecv			   PGNSP PGUID 12 1 0 0 f f f t f i 1 0 1033 "2281" _null_ _null_ _null_ _null_ aclitemrecv _null_ _null_ _null_ ));
+DESCR("I/O");
+DATA(insert OID = 3123 (  aclitemsend			   PGNSP PGUID 12 1 0 0 f f f t f i 1 0 17 "1033" _null_ _null_ _null_ _null_	aclitemsend _null_ _null_ _null_ ));
+DESCR("I/O");
 
 /* System-view support functions with pretty-print option */
 DATA(insert OID = 2504 (  pg_get_ruledef	   PGNSP PGUID 12 1 0 0 f f f t f s 2 0 25 "26 16" _null_ _null_ _null_ _null_	pg_get_ruledef_ext _null_ _null_ _null_ ));
diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h
index 9baed6c..f89ed44 100644
--- a/src/include/catalog/pg_type.h
+++ b/src/include/catalog/pg_type.h
@@ -462,7 +462,7 @@ DATA(insert OID = 1023 (  _abstime	 PGNSP PGUID -1 f b A f t \054 0 702 0 array_
 DATA(insert OID = 1024 (  _reltime	 PGNSP PGUID -1 f b A f t \054 0 703 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ ));
 DATA(insert OID = 1025 (  _tinterval PGNSP PGUID -1 f b A f t \054 0 704 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ ));
 DATA(insert OID = 1027 (  _polygon	 PGNSP PGUID -1 f b A f t \054 0 604 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ ));
-DATA(insert OID = 1033 (  aclitem	 PGNSP PGUID 12 f b U f t \054 0 0 1034 aclitemin aclitemout - - - - - i p f 0 -1 0 0 _null_ _null_ ));
+DATA(insert OID = 1033 (  aclitem	 PGNSP PGUID 12 f b U f t \054 0 0 1034 aclitemin aclitemout aclitemrecv aclitemsend - - - i p f 0 -1 0 0 _null_ _null_ ));
 DESCR("access control list");
 #define ACLITEMOID		1033
 DATA(insert OID = 1034 (  _aclitem	 PGNSP PGUID -1 f b A f t \054 0 1033 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ ));
diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h
index 1e9cf7f..1ca959d 100644
--- a/src/include/utils/acl.h
+++ b/src/include/utils/acl.h
@@ -239,6 +239,8 @@ extern void initialize_acl(void);
  */
 extern Datum aclitemin(PG_FUNCTION_ARGS);
 extern Datum aclitemout(PG_FUNCTION_ARGS);
+extern Datum aclitemrecv(PG_FUNCTION_ARGS);
+extern Datum aclitemsend(PG_FUNCTION_ARGS);
 extern Datum aclinsert(PG_FUNCTION_ARGS);
 extern Datum aclremove(PG_FUNCTION_ARGS);
 extern Datum aclcontains(PG_FUNCTION_ARGS);
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to