mirror of
https://github.com/postgres/postgres.git
synced 2025-06-26 12:21:12 +03:00
Make acl-related functions safe for TOAST. Mark pg_class.relacl as
compressible but not externally storable (since we're not sure about whether creating a toast relation for pg_class would work).
This commit is contained in:
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.9 2000/07/22 11:18:46 wieck Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.10 2000/07/31 22:39:17 tgl Exp $
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* INTERFACE ROUTINES
|
* INTERFACE ROUTINES
|
||||||
@ -273,7 +273,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
|||||||
|
|
||||||
/* ----------
|
/* ----------
|
||||||
* If the old value is an external stored one, check if it
|
* If the old value is an external stored one, check if it
|
||||||
* has changed so we have to detele it later.
|
* has changed so we have to delete it later.
|
||||||
* ----------
|
* ----------
|
||||||
*/
|
*/
|
||||||
if (!old_isnull && att[i]->attlen == -1 &&
|
if (!old_isnull && att[i]->attlen == -1 &&
|
||||||
@ -336,17 +336,16 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
|||||||
if (att[i]->attlen == -1)
|
if (att[i]->attlen == -1)
|
||||||
{
|
{
|
||||||
/* ----------
|
/* ----------
|
||||||
* If the tables attribute say's PLAIN allways, we
|
* If the table's attribute says PLAIN always, force it so.
|
||||||
* do so below.
|
|
||||||
* ----------
|
* ----------
|
||||||
*/
|
*/
|
||||||
if (att[i]->attstorage == 'p')
|
if (att[i]->attstorage == 'p')
|
||||||
toast_action[i] = 'p';
|
toast_action[i] = 'p';
|
||||||
|
|
||||||
/* ----------
|
/* ----------
|
||||||
* We're running for UPDATE, so any TOASTed value we find
|
* We took care of UPDATE above, so any TOASTed value we find
|
||||||
* still in the tuple must be someone elses we cannot reuse.
|
* still in the tuple must be someone else's we cannot reuse.
|
||||||
* Expand it to plain and eventually toast it again below.
|
* Expand it to plain (and, probably, toast it again below).
|
||||||
* ----------
|
* ----------
|
||||||
*/
|
*/
|
||||||
if (VARATT_IS_EXTENDED(DatumGetPointer(toast_values[i])))
|
if (VARATT_IS_EXTENDED(DatumGetPointer(toast_values[i])))
|
||||||
@ -367,7 +366,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* ----------
|
/* ----------
|
||||||
* Not a variable size attribute, plain storage allways
|
* Not a variable size attribute, plain storage always
|
||||||
* ----------
|
* ----------
|
||||||
*/
|
*/
|
||||||
toast_action[i] = 'p';
|
toast_action[i] = 'p';
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.38 2000/04/12 17:14:55 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.39 2000/07/31 22:39:13 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* See acl.h.
|
* See acl.h.
|
||||||
@ -33,7 +33,8 @@
|
|||||||
#include "utils/acl.h"
|
#include "utils/acl.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
static int32 aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode);
|
static int32 aclcheck(char *relname, Acl *acl, AclId id,
|
||||||
|
AclIdType idtype, AclMode mode);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enable use of user relations in place of real system catalogs.
|
* Enable use of user relations in place of real system catalogs.
|
||||||
@ -68,14 +69,16 @@ char *aclcheck_error_strings[] = {
|
|||||||
static
|
static
|
||||||
dumpacl(Acl *acl)
|
dumpacl(Acl *acl)
|
||||||
{
|
{
|
||||||
unsigned i;
|
int i;
|
||||||
AclItem *aip;
|
AclItem *aip;
|
||||||
|
|
||||||
elog(DEBUG, "acl size = %d, # acls = %d",
|
elog(DEBUG, "acl size = %d, # acls = %d",
|
||||||
ACL_SIZE(acl), ACL_NUM(acl));
|
ACL_SIZE(acl), ACL_NUM(acl));
|
||||||
aip = (AclItem *) ACL_DAT(acl);
|
aip = ACL_DAT(acl);
|
||||||
for (i = 0; i < ACL_NUM(acl); ++i)
|
for (i = 0; i < ACL_NUM(acl); ++i)
|
||||||
elog(DEBUG, " acl[%d]: %s", i, aclitemout(aip + i));
|
elog(DEBUG, " acl[%d]: %s", i,
|
||||||
|
DatumGetCString(DirectFunctionCall1(aclitemout,
|
||||||
|
PointerGetDatum(aip + i))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -89,7 +92,7 @@ ChangeAcl(char *relname,
|
|||||||
unsigned modechg)
|
unsigned modechg)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
Acl *old_acl = (Acl *) NULL,
|
Acl *old_acl,
|
||||||
*new_acl;
|
*new_acl;
|
||||||
Relation relation;
|
Relation relation;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
@ -97,14 +100,12 @@ ChangeAcl(char *relname,
|
|||||||
char nulls[Natts_pg_class];
|
char nulls[Natts_pg_class];
|
||||||
char replaces[Natts_pg_class];
|
char replaces[Natts_pg_class];
|
||||||
Relation idescs[Num_pg_class_indices];
|
Relation idescs[Num_pg_class_indices];
|
||||||
int free_old_acl = 0;
|
bool isNull;
|
||||||
|
bool free_old_acl = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the pg_class tuple matching 'relname' and extract the ACL. If
|
* Find the pg_class tuple matching 'relname' and extract the ACL. If
|
||||||
* there's no ACL, create a default using the pg_class.relowner field.
|
* there's no ACL, create a default using the pg_class.relowner field.
|
||||||
*
|
|
||||||
* We can't use the syscache here, since we need to do a heap_update on
|
|
||||||
* the tuple we find.
|
|
||||||
*/
|
*/
|
||||||
relation = heap_openr(RelationRelationName, RowExclusiveLock);
|
relation = heap_openr(RelationRelationName, RowExclusiveLock);
|
||||||
tuple = SearchSysCacheTuple(RELNAME,
|
tuple = SearchSysCacheTuple(RELNAME,
|
||||||
@ -117,25 +118,37 @@ ChangeAcl(char *relname,
|
|||||||
relname);
|
relname);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!heap_attisnull(tuple, Anum_pg_class_relacl))
|
|
||||||
old_acl = (Acl *) heap_getattr(tuple,
|
old_acl = (Acl *) heap_getattr(tuple,
|
||||||
Anum_pg_class_relacl,
|
Anum_pg_class_relacl,
|
||||||
RelationGetDescr(relation),
|
RelationGetDescr(relation),
|
||||||
(bool *) NULL);
|
&isNull);
|
||||||
if (!old_acl || ACL_NUM(old_acl) < 1)
|
if (isNull)
|
||||||
{
|
{
|
||||||
#ifdef ACLDEBUG_TRACE
|
#ifdef ACLDEBUG_TRACE
|
||||||
elog(DEBUG, "ChangeAcl: using default ACL");
|
elog(DEBUG, "ChangeAcl: using default ACL");
|
||||||
#endif
|
#endif
|
||||||
/* old_acl = acldefault(((Form_pg_class) GETSTRUCT(tuple))->relowner); */
|
|
||||||
old_acl = acldefault(relname);
|
old_acl = acldefault(relname);
|
||||||
free_old_acl = 1;
|
free_old_acl = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Need to detoast the old ACL for modification */
|
||||||
|
old_acl = DatumGetAclP(PointerGetDatum(old_acl));
|
||||||
|
|
||||||
|
if (ACL_NUM(old_acl) < 1)
|
||||||
|
{
|
||||||
|
#ifdef ACLDEBUG_TRACE
|
||||||
|
elog(DEBUG, "ChangeAcl: old ACL has zero length");
|
||||||
|
#endif
|
||||||
|
old_acl = acldefault(relname);
|
||||||
|
free_old_acl = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ACLDEBUG_TRACE
|
#ifdef ACLDEBUG_TRACE
|
||||||
dumpacl(old_acl);
|
dumpacl(old_acl);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
new_acl = aclinsert3(old_acl, mod_aip, modechg);
|
new_acl = aclinsert3(old_acl, mod_aip, modechg);
|
||||||
|
|
||||||
#ifdef ACLDEBUG_TRACE
|
#ifdef ACLDEBUG_TRACE
|
||||||
dumpacl(new_acl);
|
dumpacl(new_acl);
|
||||||
#endif
|
#endif
|
||||||
@ -148,7 +161,7 @@ ChangeAcl(char *relname,
|
|||||||
* anyway */
|
* anyway */
|
||||||
}
|
}
|
||||||
replaces[Anum_pg_class_relacl - 1] = 'r';
|
replaces[Anum_pg_class_relacl - 1] = 'r';
|
||||||
values[Anum_pg_class_relacl - 1] = (Datum) new_acl;
|
values[Anum_pg_class_relacl - 1] = PointerGetDatum(new_acl);
|
||||||
tuple = heap_modifytuple(tuple, relation, values, nulls, replaces);
|
tuple = heap_modifytuple(tuple, relation, values, nulls, replaces);
|
||||||
|
|
||||||
heap_update(relation, &tuple->t_self, tuple, NULL);
|
heap_update(relation, &tuple->t_self, tuple, NULL);
|
||||||
@ -193,20 +206,20 @@ get_groname(AclId grosysid)
|
|||||||
if (HeapTupleIsValid(tuple))
|
if (HeapTupleIsValid(tuple))
|
||||||
name = NameStr(((Form_pg_group) GETSTRUCT(tuple))->groname);
|
name = NameStr(((Form_pg_group) GETSTRUCT(tuple))->groname);
|
||||||
else
|
else
|
||||||
elog(NOTICE, "get_groname: group %d not found", grosysid);
|
elog(NOTICE, "get_groname: group %u not found", grosysid);
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32
|
static bool
|
||||||
in_group(AclId uid, AclId gid)
|
in_group(AclId uid, AclId gid)
|
||||||
{
|
{
|
||||||
Relation relation;
|
Relation relation;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
Acl *tmp;
|
Acl *tmp;
|
||||||
unsigned i,
|
int i,
|
||||||
num;
|
num;
|
||||||
AclId *aidp;
|
AclId *aidp;
|
||||||
int32 found = 0;
|
bool found = false;
|
||||||
|
|
||||||
relation = heap_openr(GroupRelationName, RowExclusiveLock);
|
relation = heap_openr(GroupRelationName, RowExclusiveLock);
|
||||||
tuple = SearchSysCacheTuple(GROSYSID,
|
tuple = SearchSysCacheTuple(GROSYSID,
|
||||||
@ -219,13 +232,15 @@ in_group(AclId uid, AclId gid)
|
|||||||
Anum_pg_group_grolist,
|
Anum_pg_group_grolist,
|
||||||
RelationGetDescr(relation),
|
RelationGetDescr(relation),
|
||||||
(bool *) NULL);
|
(bool *) NULL);
|
||||||
|
/* be sure the IdList is not toasted */
|
||||||
|
tmp = DatumGetIdListP(PointerGetDatum(tmp));
|
||||||
/* XXX make me a function */
|
/* XXX make me a function */
|
||||||
num = IDLIST_NUM(tmp);
|
num = IDLIST_NUM(tmp);
|
||||||
aidp = IDLIST_DAT(tmp);
|
aidp = IDLIST_DAT(tmp);
|
||||||
for (i = 0; i < num; ++i)
|
for (i = 0; i < num; ++i)
|
||||||
if (aidp[i] == uid)
|
if (aidp[i] == uid)
|
||||||
{
|
{
|
||||||
found = 1;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -344,8 +359,7 @@ pg_aclcheck(char *relname, char *usename, AclMode mode)
|
|||||||
{
|
{
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
AclId id;
|
AclId id;
|
||||||
Acl *acl = (Acl *) NULL,
|
Acl *acl = (Acl *) NULL;
|
||||||
*tmp;
|
|
||||||
int32 result;
|
int32 result;
|
||||||
Relation relation;
|
Relation relation;
|
||||||
|
|
||||||
@ -396,12 +410,11 @@ pg_aclcheck(char *relname, char *usename, AclMode mode)
|
|||||||
}
|
}
|
||||||
if (!heap_attisnull(tuple, Anum_pg_class_relacl))
|
if (!heap_attisnull(tuple, Anum_pg_class_relacl))
|
||||||
{
|
{
|
||||||
tmp = (Acl *) heap_getattr(tuple,
|
/* get a detoasted copy of the ACL */
|
||||||
|
acl = DatumGetAclPCopy(heap_getattr(tuple,
|
||||||
Anum_pg_class_relacl,
|
Anum_pg_class_relacl,
|
||||||
RelationGetDescr(relation),
|
RelationGetDescr(relation),
|
||||||
(bool *) NULL);
|
(bool *) NULL));
|
||||||
acl = makeacl(ACL_NUM(tmp));
|
|
||||||
memmove((char *) acl, (char *) tmp, ACL_SIZE(tmp));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -410,13 +423,10 @@ pg_aclcheck(char *relname, char *usename, AclMode mode)
|
|||||||
* if the acl is null, by default the owner can do whatever he
|
* if the acl is null, by default the owner can do whatever he
|
||||||
* wants to with it
|
* wants to with it
|
||||||
*/
|
*/
|
||||||
int4 ownerId;
|
AclId ownerId;
|
||||||
|
|
||||||
ownerId = (int4) heap_getattr(tuple,
|
ownerId = ((Form_pg_class) GETSTRUCT(tuple))->relowner;
|
||||||
Anum_pg_class_relowner,
|
acl = aclownerdefault(relname, ownerId);
|
||||||
RelationGetDescr(relation),
|
|
||||||
(bool *) NULL);
|
|
||||||
acl = aclownerdefault(relname, (AclId) ownerId);
|
|
||||||
}
|
}
|
||||||
heap_close(relation, RowExclusiveLock);
|
heap_close(relation, RowExclusiveLock);
|
||||||
#else
|
#else
|
||||||
@ -427,12 +437,11 @@ pg_aclcheck(char *relname, char *usename, AclMode mode)
|
|||||||
if (HeapTupleIsValid(tuple) &&
|
if (HeapTupleIsValid(tuple) &&
|
||||||
!heap_attisnull(tuple, Anum_pg_class_relacl))
|
!heap_attisnull(tuple, Anum_pg_class_relacl))
|
||||||
{
|
{
|
||||||
tmp = (Acl *) heap_getattr(tuple,
|
/* get a detoasted copy of the ACL */
|
||||||
|
acl = DatumGetAclPCopy(heap_getattr(tuple,
|
||||||
Anum_pg_class_relacl,
|
Anum_pg_class_relacl,
|
||||||
RelationGetDescr(relation),
|
RelationGetDescr(relation),
|
||||||
(bool *) NULL);
|
(bool *) NULL));
|
||||||
acl = makeacl(ACL_NUM(tmp));
|
|
||||||
memmove((char *) acl, (char *) tmp, ACL_SIZE(tmp));
|
|
||||||
}
|
}
|
||||||
heap_close(relation, RowExclusiveLock);
|
heap_close(relation, RowExclusiveLock);
|
||||||
#endif
|
#endif
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.47 2000/06/14 18:17:42 petere Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.48 2000/07/31 22:39:09 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -26,8 +26,8 @@
|
|||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
static char *getid(char *s, char *n);
|
static char *getid(char *s, char *n);
|
||||||
static int32 aclitemeq(AclItem *a1, AclItem *a2);
|
static bool aclitemeq(AclItem *a1, AclItem *a2);
|
||||||
static int32 aclitemgt(AclItem *a1, AclItem *a2);
|
static bool aclitemgt(AclItem *a1, AclItem *a2);
|
||||||
static char *aclparse(char *s, AclItem *aip, unsigned *modechg);
|
static char *aclparse(char *s, AclItem *aip, unsigned *modechg);
|
||||||
|
|
||||||
#define ACL_IDTYPE_GID_KEYWORD "group"
|
#define ACL_IDTYPE_GID_KEYWORD "group"
|
||||||
@ -229,18 +229,14 @@ makeacl(int n)
|
|||||||
* RETURNS:
|
* RETURNS:
|
||||||
* the new AclItem
|
* the new AclItem
|
||||||
*/
|
*/
|
||||||
AclItem *
|
Datum
|
||||||
aclitemin(char *s)
|
aclitemin(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
unsigned modechg;
|
char *s = PG_GETARG_CSTRING(0);
|
||||||
AclItem *aip;
|
AclItem *aip;
|
||||||
|
unsigned modechg;
|
||||||
if (!s)
|
|
||||||
elog(ERROR, "aclitemin: null string");
|
|
||||||
|
|
||||||
aip = (AclItem *) palloc(sizeof(AclItem));
|
aip = (AclItem *) palloc(sizeof(AclItem));
|
||||||
if (!aip)
|
|
||||||
elog(ERROR, "aclitemin: palloc failed");
|
|
||||||
s = aclparse(s, aip, &modechg);
|
s = aclparse(s, aip, &modechg);
|
||||||
if (modechg != ACL_MODECHG_EQL)
|
if (modechg != ACL_MODECHG_EQL)
|
||||||
elog(ERROR, "aclitemin: cannot accept anything but = ACLs");
|
elog(ERROR, "aclitemin: cannot accept anything but = ACLs");
|
||||||
@ -248,7 +244,7 @@ aclitemin(char *s)
|
|||||||
++s;
|
++s;
|
||||||
if (*s)
|
if (*s)
|
||||||
elog(ERROR, "aclitemin: extra garbage at end of specification");
|
elog(ERROR, "aclitemin: extra garbage at end of specification");
|
||||||
return aip;
|
PG_RETURN_ACLITEM_P(aip);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -259,24 +255,17 @@ aclitemin(char *s)
|
|||||||
* RETURNS:
|
* RETURNS:
|
||||||
* the new string
|
* the new string
|
||||||
*/
|
*/
|
||||||
char *
|
Datum
|
||||||
aclitemout(AclItem *aip)
|
aclitemout(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
|
AclItem *aip = PG_GETARG_ACLITEM_P(0);
|
||||||
char *p;
|
char *p;
|
||||||
char *out;
|
char *out;
|
||||||
HeapTuple htup;
|
HeapTuple htup;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
static AclItem default_aclitem = {ACL_ID_WORLD,
|
|
||||||
ACL_IDTYPE_WORLD,
|
|
||||||
ACL_WORLD_DEFAULT};
|
|
||||||
char *tmpname;
|
char *tmpname;
|
||||||
|
|
||||||
if (!aip)
|
|
||||||
aip = &default_aclitem;
|
|
||||||
|
|
||||||
p = out = palloc(strlen("group =arwR ") + 1 + NAMEDATALEN);
|
p = out = palloc(strlen("group =arwR ") + 1 + NAMEDATALEN);
|
||||||
if (!out)
|
|
||||||
elog(ERROR, "aclitemout: palloc failed");
|
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
||||||
switch (aip->ai_idtype)
|
switch (aip->ai_idtype)
|
||||||
@ -319,36 +308,28 @@ aclitemout(AclItem *aip)
|
|||||||
*p++ = ACL_MODE_STR[i];
|
*p++ = ACL_MODE_STR[i];
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
||||||
return out;
|
PG_RETURN_CSTRING(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* aclitemeq
|
* aclitemeq
|
||||||
* aclitemgt
|
* aclitemgt
|
||||||
* AclItem equality and greater-than comparison routines.
|
* AclItem equality and greater-than comparison routines.
|
||||||
* Two AclItems are equal iff they are both NULL or they have the
|
* Two AclItems are equal iff they have the
|
||||||
* same identifier (and identifier type).
|
* same identifier (and identifier type).
|
||||||
*
|
*
|
||||||
* RETURNS:
|
* RETURNS:
|
||||||
* a boolean value indicating = or >
|
* a boolean value indicating = or >
|
||||||
*/
|
*/
|
||||||
static int32
|
static bool
|
||||||
aclitemeq(AclItem *a1, AclItem *a2)
|
aclitemeq(AclItem *a1, AclItem *a2)
|
||||||
{
|
{
|
||||||
if (!a1 && !a2)
|
|
||||||
return 1;
|
|
||||||
if (!a1 || !a2)
|
|
||||||
return 0;
|
|
||||||
return a1->ai_idtype == a2->ai_idtype && a1->ai_id == a2->ai_id;
|
return a1->ai_idtype == a2->ai_idtype && a1->ai_id == a2->ai_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32
|
static bool
|
||||||
aclitemgt(AclItem *a1, AclItem *a2)
|
aclitemgt(AclItem *a1, AclItem *a2)
|
||||||
{
|
{
|
||||||
if (a1 && !a2)
|
|
||||||
return 1;
|
|
||||||
if (!a1 || !a2)
|
|
||||||
return 0;
|
|
||||||
return ((a1->ai_idtype > a2->ai_idtype) ||
|
return ((a1->ai_idtype > a2->ai_idtype) ||
|
||||||
(a1->ai_idtype == a2->ai_idtype && a1->ai_id > a2->ai_id));
|
(a1->ai_idtype == a2->ai_idtype && a1->ai_id > a2->ai_id));
|
||||||
}
|
}
|
||||||
@ -384,25 +365,28 @@ acldefault(char *relname)
|
|||||||
return acl;
|
return acl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add or replace an item in an ACL array.
|
||||||
|
*
|
||||||
|
* NB: caller is responsible for having detoasted the input ACL, if needed.
|
||||||
|
*/
|
||||||
Acl *
|
Acl *
|
||||||
aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
|
aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
|
||||||
{
|
{
|
||||||
Acl *new_acl;
|
Acl *new_acl;
|
||||||
AclItem *old_aip,
|
AclItem *old_aip,
|
||||||
*new_aip;
|
*new_aip;
|
||||||
unsigned src,
|
int src,
|
||||||
dst,
|
dst,
|
||||||
num;
|
num;
|
||||||
|
|
||||||
|
/* These checks for null input are probably dead code, but... */
|
||||||
if (!old_acl || ACL_NUM(old_acl) < 1)
|
if (!old_acl || ACL_NUM(old_acl) < 1)
|
||||||
{
|
old_acl = makeacl(0);
|
||||||
new_acl = makeacl(0);
|
|
||||||
return new_acl;
|
|
||||||
}
|
|
||||||
if (!mod_aip)
|
if (!mod_aip)
|
||||||
{
|
{
|
||||||
new_acl = makeacl(ACL_NUM(old_acl));
|
new_acl = makeacl(ACL_NUM(old_acl));
|
||||||
memmove((char *) new_acl, (char *) old_acl, ACL_SIZE(old_acl));
|
memcpy((char *) new_acl, (char *) old_acl, ACL_SIZE(old_acl));
|
||||||
return new_acl;
|
return new_acl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,7 +406,7 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
|
|||||||
{
|
{
|
||||||
/* modify in-place */
|
/* modify in-place */
|
||||||
new_acl = makeacl(ACL_NUM(old_acl));
|
new_acl = makeacl(ACL_NUM(old_acl));
|
||||||
memmove((char *) new_acl, (char *) old_acl, ACL_SIZE(old_acl));
|
memcpy((char *) new_acl, (char *) old_acl, ACL_SIZE(old_acl));
|
||||||
new_aip = ACL_DAT(new_acl);
|
new_aip = ACL_DAT(new_acl);
|
||||||
src = dst;
|
src = dst;
|
||||||
}
|
}
|
||||||
@ -470,10 +454,8 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
|
|||||||
/*
|
/*
|
||||||
* if the newly added entry has no permissions, delete it from the
|
* if the newly added entry has no permissions, delete it from the
|
||||||
* list. For example, this helps in removing entries for users who no
|
* list. For example, this helps in removing entries for users who no
|
||||||
* longer exists...
|
* longer exist...
|
||||||
*/
|
*/
|
||||||
for (dst = 1; dst < num; dst++)
|
|
||||||
{
|
|
||||||
if (new_aip[dst].ai_mode == 0)
|
if (new_aip[dst].ai_mode == 0)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -487,43 +469,43 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
|
|||||||
ARR_DIMS(new_acl)[0] = num - 1;
|
ARR_DIMS(new_acl)[0] = num - 1;
|
||||||
/* Adjust also the array size because it is used for memmove */
|
/* Adjust also the array size because it is used for memmove */
|
||||||
ARR_SIZE(new_acl) -= sizeof(AclItem);
|
ARR_SIZE(new_acl) -= sizeof(AclItem);
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new_acl;
|
return new_acl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* aclinsert
|
* aclinsert (exported function)
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
Acl *
|
Datum
|
||||||
aclinsert(Acl *old_acl, AclItem *mod_aip)
|
aclinsert(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
return aclinsert3(old_acl, mod_aip, ACL_MODECHG_EQL);
|
Acl *old_acl = PG_GETARG_ACL_P(0);
|
||||||
|
AclItem *mod_aip = PG_GETARG_ACLITEM_P(1);
|
||||||
|
|
||||||
|
PG_RETURN_ACL_P(aclinsert3(old_acl, mod_aip, ACL_MODECHG_EQL));
|
||||||
}
|
}
|
||||||
|
|
||||||
Acl *
|
Datum
|
||||||
aclremove(Acl *old_acl, AclItem *mod_aip)
|
aclremove(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
|
Acl *old_acl = PG_GETARG_ACL_P(0);
|
||||||
|
AclItem *mod_aip = PG_GETARG_ACLITEM_P(1);
|
||||||
Acl *new_acl;
|
Acl *new_acl;
|
||||||
AclItem *old_aip,
|
AclItem *old_aip,
|
||||||
*new_aip;
|
*new_aip;
|
||||||
unsigned dst,
|
int dst,
|
||||||
old_num,
|
old_num,
|
||||||
new_num;
|
new_num;
|
||||||
|
|
||||||
|
/* These checks for null input should be dead code, but... */
|
||||||
if (!old_acl || ACL_NUM(old_acl) < 1)
|
if (!old_acl || ACL_NUM(old_acl) < 1)
|
||||||
{
|
old_acl = makeacl(0);
|
||||||
new_acl = makeacl(0);
|
|
||||||
return new_acl;
|
|
||||||
}
|
|
||||||
if (!mod_aip)
|
if (!mod_aip)
|
||||||
{
|
{
|
||||||
new_acl = makeacl(ACL_NUM(old_acl));
|
new_acl = makeacl(ACL_NUM(old_acl));
|
||||||
memmove((char *) new_acl, (char *) old_acl, ACL_SIZE(old_acl));
|
memcpy((char *) new_acl, (char *) old_acl, ACL_SIZE(old_acl));
|
||||||
return new_acl;
|
PG_RETURN_ACL_P(new_acl);
|
||||||
}
|
}
|
||||||
|
|
||||||
old_num = ACL_NUM(old_acl);
|
old_num = ACL_NUM(old_acl);
|
||||||
@ -534,12 +516,12 @@ aclremove(Acl *old_acl, AclItem *mod_aip)
|
|||||||
if (dst >= old_num)
|
if (dst >= old_num)
|
||||||
{ /* not found or empty */
|
{ /* not found or empty */
|
||||||
new_acl = makeacl(ACL_NUM(old_acl));
|
new_acl = makeacl(ACL_NUM(old_acl));
|
||||||
memmove((char *) new_acl, (char *) old_acl, ACL_SIZE(old_acl));
|
memcpy((char *) new_acl, (char *) old_acl, ACL_SIZE(old_acl));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
new_num = old_num - 1;
|
new_num = old_num - 1;
|
||||||
new_acl = makeacl(ACL_NUM(old_acl) - 1);
|
new_acl = makeacl(new_num);
|
||||||
new_aip = ACL_DAT(new_acl);
|
new_aip = ACL_DAT(new_acl);
|
||||||
if (dst == 0)
|
if (dst == 0)
|
||||||
{ /* start */
|
{ /* start */
|
||||||
@ -561,23 +543,24 @@ aclremove(Acl *old_acl, AclItem *mod_aip)
|
|||||||
(new_num - dst) * sizeof(AclItem));
|
(new_num - dst) * sizeof(AclItem));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new_acl;
|
PG_RETURN_ACL_P(new_acl);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32
|
Datum
|
||||||
aclcontains(Acl *acl, AclItem *aip)
|
aclcontains(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
unsigned i,
|
Acl *acl = PG_GETARG_ACL_P(0);
|
||||||
num;
|
AclItem *aip = PG_GETARG_ACLITEM_P(1);
|
||||||
AclItem *aidat;
|
AclItem *aidat;
|
||||||
|
int i,
|
||||||
|
num;
|
||||||
|
|
||||||
if (!acl || !aip || ((num = ACL_NUM(acl)) < 1))
|
num = ACL_NUM(acl);
|
||||||
return 0;
|
|
||||||
aidat = ACL_DAT(acl);
|
aidat = ACL_DAT(acl);
|
||||||
for (i = 0; i < num; ++i)
|
for (i = 0; i < num; ++i)
|
||||||
if (aclitemeq(aip, aidat + i))
|
if (aclitemeq(aip, aidat + i))
|
||||||
return 1;
|
PG_RETURN_BOOL(true);
|
||||||
return 0;
|
PG_RETURN_BOOL(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parser support routines */
|
/* parser support routines */
|
||||||
@ -638,7 +621,7 @@ aclmakepriv(char *old_privlist, char new_priv)
|
|||||||
* "G" - group
|
* "G" - group
|
||||||
* "U" - user
|
* "U" - user
|
||||||
*
|
*
|
||||||
* concatentates the two strings together with a space in between
|
* concatenates the two strings together with a space in between
|
||||||
*
|
*
|
||||||
* this routine is used in the parser
|
* this routine is used in the parser
|
||||||
*
|
*
|
||||||
@ -649,7 +632,7 @@ aclmakeuser(char *user_type, char *user)
|
|||||||
{
|
{
|
||||||
char *user_list;
|
char *user_list;
|
||||||
|
|
||||||
user_list = palloc(strlen(user) + 3);
|
user_list = palloc(strlen(user_type) + strlen(user) + 2);
|
||||||
sprintf(user_list, "%s %s", user_type, user);
|
sprintf(user_list, "%s %s", user_type, user);
|
||||||
return user_list;
|
return user_list;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: pg_attribute.h,v 1.61 2000/07/03 23:10:05 wieck Exp $
|
* $Id: pg_attribute.h,v 1.62 2000/07/31 22:39:06 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* the genbki.sh script reads this file and generates .bki
|
* the genbki.sh script reads this file and generates .bki
|
||||||
@ -124,15 +124,16 @@ CATALOG(pg_attribute) BOOTSTRAP
|
|||||||
|
|
||||||
char attstorage;
|
char attstorage;
|
||||||
|
|
||||||
/*
|
/*----------
|
||||||
* attstorage tells for VARLENA attributes, what the heap access
|
* attstorage tells for VARLENA attributes, what the heap access
|
||||||
* methods can do to it if a given tuple doesn't fit into a page.
|
* methods can do to it if a given tuple doesn't fit into a page.
|
||||||
* Possible values are 'p': Value must be stored plain allways 'e':
|
* Possible values are
|
||||||
* Value can be stored in "secondary" relation (if relation has
|
* 'p': Value must be stored plain always
|
||||||
* rellongrelid attached) 'c': Value can be stored compressed inline
|
* 'e': Value can be stored in "secondary" relation (if relation
|
||||||
* 'x': Value can be stored compressed inline or in "secondary".
|
* has rellongrelid attached)
|
||||||
*
|
* 'm': Value can be stored compressed inline
|
||||||
* Note: compressed storage
|
* 'x': Value can be stored compressed inline or in "secondary"
|
||||||
|
*----------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool attisset;
|
bool attisset;
|
||||||
@ -439,7 +440,7 @@ DATA(insert OID = 0 ( 1249 tableoid 26 0 4 -7 0 -1 -1 t p f i f f));
|
|||||||
{ 1259, {"relhaspkey"}, 16, 0, 1, 18, 0, -1, -1, '\001', 'p', '\0', 'c', '\0', '\0' }, \
|
{ 1259, {"relhaspkey"}, 16, 0, 1, 18, 0, -1, -1, '\001', 'p', '\0', 'c', '\0', '\0' }, \
|
||||||
{ 1259, {"relhasrules"}, 16, 0, 1, 19, 0, -1, -1, '\001', 'p', '\0', 'c', '\0', '\0' }, \
|
{ 1259, {"relhasrules"}, 16, 0, 1, 19, 0, -1, -1, '\001', 'p', '\0', 'c', '\0', '\0' }, \
|
||||||
{ 1259, {"relhassubclass"},16, 0, 1, 20, 0, -1, -1, '\001', 'p', '\0', 'c', '\0', '\0' }, \
|
{ 1259, {"relhassubclass"},16, 0, 1, 20, 0, -1, -1, '\001', 'p', '\0', 'c', '\0', '\0' }, \
|
||||||
{ 1259, {"relacl"}, 1034, 0, -1, 21, 0, -1, -1, '\0', 'p', '\0', 'i', '\0', '\0' }
|
{ 1259, {"relacl"}, 1034, 0, -1, 21, 0, -1, -1, '\0', 'm', '\0', 'i', '\0', '\0' }
|
||||||
|
|
||||||
DATA(insert OID = 0 ( 1259 relname 19 0 NAMEDATALEN 1 0 -1 -1 f p f i f f));
|
DATA(insert OID = 0 ( 1259 relname 19 0 NAMEDATALEN 1 0 -1 -1 f p f i f f));
|
||||||
DATA(insert OID = 0 ( 1259 reltype 26 0 4 2 0 -1 -1 t p f i f f));
|
DATA(insert OID = 0 ( 1259 reltype 26 0 4 2 0 -1 -1 t p f i f f));
|
||||||
@ -461,7 +462,7 @@ DATA(insert OID = 0 ( 1259 relrefs 21 0 2 17 0 -1 -1 t p f s f f));
|
|||||||
DATA(insert OID = 0 ( 1259 relhaspkey 16 0 1 18 0 -1 -1 t p f c f f));
|
DATA(insert OID = 0 ( 1259 relhaspkey 16 0 1 18 0 -1 -1 t p f c f f));
|
||||||
DATA(insert OID = 0 ( 1259 relhasrules 16 0 1 19 0 -1 -1 t p f c f f));
|
DATA(insert OID = 0 ( 1259 relhasrules 16 0 1 19 0 -1 -1 t p f c f f));
|
||||||
DATA(insert OID = 0 ( 1259 relhassubclass 16 0 1 20 0 -1 -1 t p f c f f));
|
DATA(insert OID = 0 ( 1259 relhassubclass 16 0 1 20 0 -1 -1 t p f c f f));
|
||||||
DATA(insert OID = 0 ( 1259 relacl 1034 0 -1 21 0 -1 -1 f p f i f f));
|
DATA(insert OID = 0 ( 1259 relacl 1034 0 -1 21 0 -1 -1 f m f i f f));
|
||||||
DATA(insert OID = 0 ( 1259 ctid 27 0 6 -1 0 -1 -1 f p f i f f));
|
DATA(insert OID = 0 ( 1259 ctid 27 0 6 -1 0 -1 -1 f p f i f f));
|
||||||
DATA(insert OID = 0 ( 1259 oid 26 0 4 -2 0 -1 -1 t p f i f f));
|
DATA(insert OID = 0 ( 1259 oid 26 0 4 -2 0 -1 -1 t p f i f f));
|
||||||
DATA(insert OID = 0 ( 1259 xmin 28 0 4 -3 0 -1 -1 t p f i f f));
|
DATA(insert OID = 0 ( 1259 xmin 28 0 4 -3 0 -1 -1 t p f i f f));
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: pg_proc.h,v 1.153 2000/07/30 22:14:01 tgl Exp $
|
* $Id: pg_proc.h,v 1.154 2000/07/31 22:39:05 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* The script catalog/genbki.sh reads this file and generates .bki
|
* The script catalog/genbki.sh reads this file and generates .bki
|
||||||
@ -1256,16 +1256,16 @@ DATA(insert OID = 1029 ( nullvalue PGUID 12 f t t f 1 f 16 "0" 100 0 0 100
|
|||||||
DESCR("(internal)");
|
DESCR("(internal)");
|
||||||
DATA(insert OID = 1030 ( nonnullvalue PGUID 12 f t t f 1 f 16 "0" 100 0 0 100 nonnullvalue - ));
|
DATA(insert OID = 1030 ( nonnullvalue PGUID 12 f t t f 1 f 16 "0" 100 0 0 100 nonnullvalue - ));
|
||||||
DESCR("(internal)");
|
DESCR("(internal)");
|
||||||
DATA(insert OID = 1031 ( aclitemin PGUID 11 f t f t 1 f 1033 "0" 100 0 0 100 aclitemin - ));
|
DATA(insert OID = 1031 ( aclitemin PGUID 12 f t f t 1 f 1033 "0" 100 0 0 100 aclitemin - ));
|
||||||
DESCR("(internal)");
|
DESCR("(internal)");
|
||||||
DATA(insert OID = 1032 ( aclitemout PGUID 11 f t f t 1 f 23 "0" 100 0 0 100 aclitemout - ));
|
DATA(insert OID = 1032 ( aclitemout PGUID 12 f t f t 1 f 23 "1033" 100 0 0 100 aclitemout - ));
|
||||||
DESCR("(internal)");
|
DESCR("(internal)");
|
||||||
DATA(insert OID = 1035 ( aclinsert PGUID 11 f t f t 2 f 1034 "1034 1033" 100 0 0 100 aclinsert - ));
|
DATA(insert OID = 1035 ( aclinsert PGUID 12 f t f t 2 f 1034 "1034 1033" 100 0 0 100 aclinsert - ));
|
||||||
DESCR("addition");
|
DESCR("add/update ACL item");
|
||||||
DATA(insert OID = 1036 ( aclremove PGUID 11 f t f t 2 f 1034 "1034 1033" 100 0 0 100 aclremove - ));
|
DATA(insert OID = 1036 ( aclremove PGUID 12 f t f t 2 f 1034 "1034 1033" 100 0 0 100 aclremove - ));
|
||||||
DESCR("subtract");
|
DESCR("remove ACL item");
|
||||||
DATA(insert OID = 1037 ( aclcontains PGUID 11 f t f t 2 f 16 "1034 1033" 100 0 0 100 aclcontains - ));
|
DATA(insert OID = 1037 ( aclcontains PGUID 12 f t f t 2 f 16 "1034 1033" 100 0 0 100 aclcontains - ));
|
||||||
DESCR("matches regex., case-sensitive");
|
DESCR("does ACL contain item?");
|
||||||
DATA(insert OID = 1038 ( seteval PGUID 12 f t f t 1 f 23 "26" 100 0 0 100 seteval - ));
|
DATA(insert OID = 1038 ( seteval PGUID 12 f t f t 1 f 23 "26" 100 0 0 100 seteval - ));
|
||||||
DESCR("");
|
DESCR("");
|
||||||
DATA(insert OID = 1044 ( bpcharin PGUID 12 f t t t 3 f 1042 "0 26 23" 100 0 0 100 bpcharin - ));
|
DATA(insert OID = 1044 ( bpcharin PGUID 12 f t t t 3 f 1042 "0 26 23" 100 0 0 100 bpcharin - ));
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||||
* Portions Copyright (c) 1995, Regents of the University of California
|
* Portions Copyright (c) 1995, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: postgres.h,v 1.43 2000/07/03 23:09:56 wieck Exp $
|
* $Id: postgres.h,v 1.44 2000/07/31 22:39:03 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -46,8 +46,6 @@
|
|||||||
* ----------------------------------------------------------------
|
* ----------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef int4 aclitem;
|
|
||||||
|
|
||||||
#define InvalidOid ((Oid) 0)
|
#define InvalidOid ((Oid) 0)
|
||||||
#define OidIsValid(objectId) ((bool) ((objectId) != InvalidOid))
|
#define OidIsValid(objectId) ((bool) ((objectId) != InvalidOid))
|
||||||
|
|
||||||
@ -57,6 +55,8 @@ typedef Oid RegProcedure;
|
|||||||
|
|
||||||
#define RegProcedureIsValid(p) OidIsValid(p)
|
#define RegProcedureIsValid(p) OidIsValid(p)
|
||||||
|
|
||||||
|
typedef int4 aclitem; /* PHONY definition for catalog use only */
|
||||||
|
|
||||||
/* ----------------------------------------------------------------
|
/* ----------------------------------------------------------------
|
||||||
* Section 2: variable length and array types
|
* Section 2: variable length and array types
|
||||||
* ----------------------------------------------------------------
|
* ----------------------------------------------------------------
|
||||||
|
@ -7,17 +7,16 @@
|
|||||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: acl.h,v 1.25 2000/04/12 17:16:54 momjian Exp $
|
* $Id: acl.h,v 1.26 2000/07/31 22:39:02 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* For backward-compatability purposes we have to allow there
|
* For backward-compatibility purposes we have to allow there
|
||||||
* to be a null ACL in a pg_class tuple. This will be defined as
|
* to be a null ACL in a pg_class tuple. This will be defined as
|
||||||
* meaning "no protection" (i.e., old catalogs get old semantics).
|
* meaning "no protection" (i.e., old catalogs get old semantics).
|
||||||
*
|
*
|
||||||
* The AclItems in an ACL array are currently kept in sorted order.
|
* The AclItems in an ACL array are currently kept in sorted order.
|
||||||
* Things will break hard if you change that without changing the
|
* Things will break hard if you change that without changing the
|
||||||
* code wherever this is included.
|
* code wherever this is included.
|
||||||
*
|
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
#ifndef ACL_H
|
#ifndef ACL_H
|
||||||
@ -78,7 +77,7 @@ typedef struct AclItem
|
|||||||
AclMode ai_mode;
|
AclMode ai_mode;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is actually type 'aclitem', and we want a fixed size for for
|
* This is actually type 'aclitem', and we want a fixed size for
|
||||||
* all platforms, so we pad this with dummies.
|
* all platforms, so we pad this with dummies.
|
||||||
*/
|
*/
|
||||||
char dummy1,
|
char dummy1,
|
||||||
@ -88,22 +87,30 @@ typedef struct AclItem
|
|||||||
/* Note: if the size of AclItem changes,
|
/* Note: if the size of AclItem changes,
|
||||||
change the aclitem typlen in pg_type.h */
|
change the aclitem typlen in pg_type.h */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The value of the first dimension-array element. Since these arrays
|
* Definitions for convenient access to Acl (array of AclItem) and IdList
|
||||||
* always have a lower-bound of 0, this is the same as the number of
|
* (array of AclId). These are standard Postgres arrays, but are restricted
|
||||||
* elements in the array.
|
* to have one dimension. We also ignore the lower bound when reading,
|
||||||
|
* and set it to zero when writing.
|
||||||
|
*
|
||||||
|
* CAUTION: as of Postgres 7.1, these arrays are toastable (just like all
|
||||||
|
* other array types). Therefore, be careful to detoast them with the
|
||||||
|
* macros provided, unless you know for certain that a particular array
|
||||||
|
* can't have been toasted. Presently, we do not provide toast tables for
|
||||||
|
* pg_class or pg_group, so the entries in those tables won't have been
|
||||||
|
* stored externally --- but they could have been compressed!
|
||||||
*/
|
*/
|
||||||
#define ARR_DIM0(a) (((unsigned *) (((char *) a) + sizeof(ArrayType)))[0])
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Acl a one-dimensional POSTGRES array of AclItem
|
* Acl a one-dimensional POSTGRES array of AclItem
|
||||||
*/
|
*/
|
||||||
typedef ArrayType Acl;
|
typedef ArrayType Acl;
|
||||||
|
|
||||||
#define ACL_NUM(ACL) ARR_DIM0(ACL)
|
#define ACL_NUM(ACL) (ARR_DIMS(ACL)[0])
|
||||||
#define ACL_DAT(ACL) ((AclItem *) ARR_DATA_PTR(ACL))
|
#define ACL_DAT(ACL) ((AclItem *) ARR_DATA_PTR(ACL))
|
||||||
#define ACL_N_SIZE(N) \
|
#define ACL_N_SIZE(N) (ARR_OVERHEAD(1) + ((N) * sizeof(AclItem)))
|
||||||
((unsigned) (ARR_OVERHEAD(1) + ((N) * sizeof(AclItem))))
|
|
||||||
#define ACL_SIZE(ACL) ARR_SIZE(ACL)
|
#define ACL_SIZE(ACL) ARR_SIZE(ACL)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -111,12 +118,32 @@ typedef ArrayType Acl;
|
|||||||
*/
|
*/
|
||||||
typedef ArrayType IdList;
|
typedef ArrayType IdList;
|
||||||
|
|
||||||
#define IDLIST_NUM(IDL) ARR_DIM0(IDL)
|
#define IDLIST_NUM(IDL) (ARR_DIMS(IDL)[0])
|
||||||
#define IDLIST_DAT(IDL) ((AclId *) ARR_DATA_PTR(IDL))
|
#define IDLIST_DAT(IDL) ((AclId *) ARR_DATA_PTR(IDL))
|
||||||
#define IDLIST_N_SIZE(N) \
|
#define IDLIST_N_SIZE(N) (ARR_OVERHEAD(1) + ((N) * sizeof(AclId)))
|
||||||
((unsigned) (ARR_OVERHEAD(1) + ((N) * sizeof(AclId))))
|
|
||||||
#define IDLIST_SIZE(IDL) ARR_SIZE(IDL)
|
#define IDLIST_SIZE(IDL) ARR_SIZE(IDL)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fmgr macros for these types
|
||||||
|
*/
|
||||||
|
#define DatumGetAclItemP(X) ((AclItem *) DatumGetPointer(X))
|
||||||
|
#define PG_GETARG_ACLITEM_P(n) DatumGetAclItemP(PG_GETARG_DATUM(n))
|
||||||
|
#define PG_RETURN_ACLITEM_P(x) PG_RETURN_POINTER(x)
|
||||||
|
|
||||||
|
#define DatumGetAclP(X) ((Acl *) PG_DETOAST_DATUM(X))
|
||||||
|
#define DatumGetAclPCopy(X) ((Acl *) PG_DETOAST_DATUM_COPY(X))
|
||||||
|
#define PG_GETARG_ACL_P(n) DatumGetAclP(PG_GETARG_DATUM(n))
|
||||||
|
#define PG_GETARG_ACL_P_COPY(n) DatumGetAclPCopy(PG_GETARG_DATUM(n))
|
||||||
|
#define PG_RETURN_ACL_P(x) PG_RETURN_POINTER(x)
|
||||||
|
|
||||||
|
#define DatumGetIdListP(X) ((IdList *) PG_DETOAST_DATUM(X))
|
||||||
|
#define DatumGetIdListPCopy(X) ((IdList *) PG_DETOAST_DATUM_COPY(X))
|
||||||
|
#define PG_GETARG_IDLIST_P(n) DatumGetIdListP(PG_GETARG_DATUM(n))
|
||||||
|
#define PG_GETARG_IDLIST_P_COPY(n) DatumGetIdListPCopy(PG_GETARG_DATUM(n))
|
||||||
|
#define PG_RETURN_IDLIST_P(x) PG_RETURN_POINTER(x)
|
||||||
|
|
||||||
|
|
||||||
|
/* mode indicators for I/O */
|
||||||
#define ACL_MODECHG_STR "+-=" /* list of valid characters */
|
#define ACL_MODECHG_STR "+-=" /* list of valid characters */
|
||||||
#define ACL_MODECHG_ADD_CHR '+'
|
#define ACL_MODECHG_ADD_CHR '+'
|
||||||
#define ACL_MODECHG_DEL_CHR '-'
|
#define ACL_MODECHG_DEL_CHR '-'
|
||||||
@ -157,11 +184,11 @@ extern ChangeACLStmt *makeAclStmt(char *privs, List *rel_list, char *grantee,
|
|||||||
* exported routines (from acl.c)
|
* exported routines (from acl.c)
|
||||||
*/
|
*/
|
||||||
extern Acl *makeacl(int n);
|
extern Acl *makeacl(int n);
|
||||||
extern AclItem *aclitemin(char *s);
|
extern Datum aclitemin(PG_FUNCTION_ARGS);
|
||||||
extern char *aclitemout(AclItem *aip);
|
extern Datum aclitemout(PG_FUNCTION_ARGS);
|
||||||
extern Acl *aclinsert(Acl *old_acl, AclItem *mod_aip);
|
extern Datum aclinsert(PG_FUNCTION_ARGS);
|
||||||
extern Acl *aclremove(Acl *old_acl, AclItem *mod_aip);
|
extern Datum aclremove(PG_FUNCTION_ARGS);
|
||||||
extern int32 aclcontains(Acl *acl, AclItem *aip);
|
extern Datum aclcontains(PG_FUNCTION_ARGS);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* prototypes for functions in aclchk.c
|
* prototypes for functions in aclchk.c
|
||||||
|
Reference in New Issue
Block a user