Tom Lane <[email protected]> Wednesday 23 February 2011 22:30:04
> =?utf-8?q?Rados=C5=82aw_Smogura?= <[email protected]> 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 ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers