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