Re: doc - add missing documentation for "acldefault"
On 09/24/2018 10:09 AM, Joe Conway wrote: > On 09/24/2018 10:01 AM, Tom Lane wrote: >> Joe Conway writes: >>> Having seen none, committed/pushed. This did not seem worth >>> back-patching, so I only pushed to master. >> >> I don't see anything on gitmaster? > > Hmm, yes, interesting -- I must of messed up my local git repo somehow. > Will try again. This time it seems to have worked. Sorry for the noise earlier :-/ Joe -- Crunchy Data - http://crunchydata.com PostgreSQL Support for Secure Enterprises Consulting, Training, & Open Source Development signature.asc Description: OpenPGP digital signature
Re: doc - add missing documentation for "acldefault"
On 09/24/2018 10:01 AM, Tom Lane wrote: > Joe Conway writes: >> Having seen none, committed/pushed. This did not seem worth >> back-patching, so I only pushed to master. > > I don't see anything on gitmaster? Hmm, yes, interesting -- I must of messed up my local git repo somehow. Will try again. Joe -- Crunchy Data - http://crunchydata.com PostgreSQL Support for Secure Enterprises Consulting, Training, & Open Source Development signature.asc Description: OpenPGP digital signature
Re: doc - add missing documentation for "acldefault"
On 09/21/2018 01:51 PM, Joe Conway wrote: > On 09/19/2018 11:18 AM, Joe Conway wrote: >> On 09/19/2018 10:54 AM, Tom Lane wrote: >>> So maybe what we really need is a table of operators not functions. >> >> Good idea -- I will take a look at that. >> >>> However, I don't object to documenting any function that has its >>> own pg_description string. > > Ok, so the attached version refactors/splits the group into two tables > -- operators and functions. > I also included John Naylor's patch with some minor editorialization. > > Any further comments or complaints? Having seen none, committed/pushed. This did not seem worth back-patching, so I only pushed to master. Joe -- Crunchy Data - http://crunchydata.com PostgreSQL Support for Secure Enterprises Consulting, Training, & Open Source Development signature.asc Description: OpenPGP digital signature
Re: doc - add missing documentation for "acldefault"
On 09/19/2018 11:18 AM, Joe Conway wrote: > On 09/19/2018 10:54 AM, Tom Lane wrote: >> Joe Conway writes: >>> * I do believe aclitemeq() has utility outside internal purposes. >> >> Our normal policy is that we do not document functions that are meant to >> be invoked through operators. The \df output saying that is sufficient: > > > >> I would strongly object to ignoring that policy in just one place. > > Ok, fair enough. > >> Actually, it appears that most of these functions have associated >> operators: >> >> # select oid::regoperator, oprcode from pg_operator where oprright = >> 'aclitem'::regtype; >> oid | oprcode >> ---+- >> +(aclitem[],aclitem) | aclinsert >> -(aclitem[],aclitem) | aclremove >> @>(aclitem[],aclitem) | aclcontains >> =(aclitem,aclitem)| aclitemeq >> ~(aclitem[],aclitem) | aclcontains >> (5 rows) >> >> So maybe what we really need is a table of operators not functions. > > Good idea -- I will take a look at that. > >> However, I don't object to documenting any function that has its >> own pg_description string. Ok, so the attached version refactors/splits the group into two tables -- operators and functions. It drops aclinsert and aclremove entirely due to the fact that they no longer do anything useful, to wit: - Datum aclinsert(PG_FUNCTION_ARGS) { ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("aclinsert is no longer supported"))); PG_RETURN_NULL(); /* keep compiler quiet */ } Datum aclremove(PG_FUNCTION_ARGS) { ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("aclremove is no longer supported"))); PG_RETURN_NULL(); /* keep compiler quiet */ } - I also included John Naylor's patch with some minor editorialization. Any further comments or complaints? Thanks, Joe -- Crunchy Data - http://crunchydata.com PostgreSQL Support for Secure Enterprises Consulting, Training, & Open Source Development diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 4331beb..8ebb1bf 100644 *** a/doc/src/sgml/func.sgml --- b/doc/src/sgml/func.sgml *** SELECT * FROM pg_ls_dir('.') WITH ORDINA *** 15962,15968 ! System Information Functions shows several --- 15962,15968 ! System Information Functions and Operators shows several *** SELECT has_function_privilege('joeuser', *** 16894,16899 --- 16894,17034 + shows the operators +available for the aclitem type, which is the internal +representation of access privileges. An aclitem entry +describes the permissions of a grantee, whether they are grantable +or not, and which grantor granted them. For instance, +calvin=r*w/hobbes specifies that the role +calvin has the grantable privilege +SELECT (r*) and the non-grantable +privilege UPDATE (w), granted by +the role hobbes. An empty grantee stands for +PUBLIC. + + + + aclitem + + + acldefault + + + aclitemeq + + + aclcontains + + + aclexplode + + + makeaclitem + + + + aclitem Operators + + + + Operator + Description + Example + Result + + + + + + = + equal + 'calvin=r*w/hobbes'::aclitem = 'calvin=r*w*/hobbes'::aclitem + f + + + + @ + contains element + '{calvin=r*w/hobbes,hobbes=r*w*/postgres}'::aclitem[] @> 'calvin=r*w/hobbes'::aclitem + t + + + + ~ + contains element + '{calvin=r*w/hobbes,hobbes=r*w*/postgres}'::aclitem[] ~ 'calvin=r*w/hobbes'::aclitem + t + + + + + + + + shows some additional + functions to manage the aclitem type. + + + + aclitem Functions + + + Name Return Type Description + + + +acldefault(type, + ownerId) +aclitem[] +get the hardcoded default access privileges for an object belonging to ownerId + + +aclexplode(aclitem[]) +setof record +get aclitem array as tuples + + +makeaclitem(grantee, grantor, privilege, grantable) +aclitem +build an aclitem from input + + + + + + + acldefault returns the hardcoded default access privileges + for an object of type belonging to role ownerId. + Notice that these are used in the absence of any pg_default_acl + () entry. Default access privileges are described in + and can be overwritten with + . In other words, this function will return + results which may be misleading when the defaults have been
Re: doc - add missing documentation for "acldefault"
On 09/19/2018 12:30 PM, John Naylor wrote: > On 9/19/18, Tom Lane wrote: >> However, I don't object to documenting any function that has its >> own pg_description string. > > Speaking of, that description string seems to have been neglected. > I've attached a remedy for that. Thanks, will take care of it. Joe -- Crunchy Data - http://crunchydata.com PostgreSQL Support for Secure Enterprises Consulting, Training, & Open Source Development signature.asc Description: OpenPGP digital signature
Re: doc - add missing documentation for "acldefault"
On 9/19/18, Tom Lane wrote: > However, I don't object to documenting any function that has its > own pg_description string. Speaking of, that description string seems to have been neglected. I've attached a remedy for that. -John Naylor diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 860571440a..6b7088b9ce 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -2073,7 +2073,7 @@ { oid => '1365', descr => 'make ACL item', proname => 'makeaclitem', prorettype => 'aclitem', proargtypes => 'oid oid text bool', prosrc => 'makeaclitem' }, -{ oid => '3943', descr => 'TODO', +{ oid => '3943', descr => 'show default privileges, for use by the information schema', proname => 'acldefault', prorettype => '_aclitem', proargtypes => 'char oid', prosrc => 'acldefault_sql' }, { oid => '1689',
Re: doc - add missing documentation for "acldefault"
Hello, Our normal policy is that we do not document functions that are meant to be invoked through operators. The \df output saying that is sufficient: The output of \df is one thing, but I was looking at pg online documentation and hoping to find things as well. \dfS returns nearly 3000 results, it is not really pratical unless you already know what you are looking for, eg the name of the function... I would strongly object to ignoring that policy in just one place. Ok, fair enough. Actually, it appears that most of these functions have associated operators: # select oid::regoperator, oprcode from pg_operator where oprright = 'aclitem'::regtype; oid | oprcode ---+- +(aclitem[],aclitem) | aclinsert -(aclitem[],aclitem) | aclremove @>(aclitem[],aclitem) | aclcontains =(aclitem,aclitem)| aclitemeq ~(aclitem[],aclitem) | aclcontains (5 rows) So maybe what we really need is a table of operators not functions. Good idea -- I will take a look at that. My initial complaint is that I did not know that there was an "acldefault" function while I was looking for that kind of thing. ISTM that this one should be kept explicitely in the doc. I'm okay with documenting operators instead of the basic undelying functions and skipping type management (in/out) functions, though. -- Fabien.
Re: doc - add missing documentation for "acldefault"
On 09/19/2018 10:54 AM, Tom Lane wrote: > Joe Conway writes: >> * I do believe aclitemeq() has utility outside internal purposes. > > Our normal policy is that we do not document functions that are meant to > be invoked through operators. The \df output saying that is sufficient: > I would strongly object to ignoring that policy in just one place. Ok, fair enough. > Actually, it appears that most of these functions have associated > operators: > > # select oid::regoperator, oprcode from pg_operator where oprright = > 'aclitem'::regtype; > oid | oprcode > ---+- > +(aclitem[],aclitem) | aclinsert > -(aclitem[],aclitem) | aclremove > @>(aclitem[],aclitem) | aclcontains > =(aclitem,aclitem)| aclitemeq > ~(aclitem[],aclitem) | aclcontains > (5 rows) > > So maybe what we really need is a table of operators not functions. Good idea -- I will take a look at that. > However, I don't object to documenting any function that has its > own pg_description string. Ok. Joe -- Crunchy Data - http://crunchydata.com PostgreSQL Support for Secure Enterprises Consulting, Training, & Open Source Development signature.asc Description: OpenPGP digital signature
Re: doc - add missing documentation for "acldefault"
Joe Conway writes: > * I do believe aclitemeq() has utility outside internal purposes. Our normal policy is that we do not document functions that are meant to be invoked through operators. The \df output saying that is sufficient: # \df+ aclitemeq List of functions Schema | Name| Result data type | Argument data types | Type | Volatility | Parallel | Owner | Security | Access privileges | Language | Source code | Description +---+--+-+--++--+--+--+---+--+-+-- pg_catalog | aclitemeq | boolean | aclitem, aclitem| func | immutable | safe | postgres | invoker | | internal | aclitem_eq | implementation of = operator (1 row) I would strongly object to ignoring that policy in just one place. Actually, it appears that most of these functions have associated operators: # select oid::regoperator, oprcode from pg_operator where oprright = 'aclitem'::regtype; oid | oprcode ---+- +(aclitem[],aclitem) | aclinsert -(aclitem[],aclitem) | aclremove @>(aclitem[],aclitem) | aclcontains =(aclitem,aclitem)| aclitemeq ~(aclitem[],aclitem) | aclcontains (5 rows) So maybe what we really need is a table of operators not functions. However, I don't object to documenting any function that has its own pg_description string. regards, tom lane
Re: doc - add missing documentation for "acldefault"
On 08/03/2018 09:04 AM, Fabien COELHO wrote: > Here is a version of the patch which documents briefly all aclitem-related > functions, in a separate table. I claimed this patch for review and commit. Comments: --- * There is a comment in src/backend/utils/adt/acl.c noting that acldefault is "not documented for general use" which needs adjustment * It makes no sense to me to document purely internal functions, e.g. aclitemin/out. If we are going to do that we should do it universally, which is not true currently, and IMHO makes no sense anyway. * I do believe aclitemeq() has utility outside internal purposes. * The section is incomplete * Interestingly (since that is what started this thread apparently) I found myself questioning whether acldefault() is really worth documenting since the result will be misleading if the defaults have been altered via SQL. --- Attached patch addresses those items and does a bit of reordering and editorialization. If there are no objections I will commit it this way in a day or two. Thanks, Joe -- Crunchy Data - http://crunchydata.com PostgreSQL Support for Secure Enterprises Consulting, Training, & Open Source Development diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 4331beb..cea674e 100644 *** a/doc/src/sgml/func.sgml --- b/doc/src/sgml/func.sgml *** SELECT has_function_privilege('joeuser', *** 16893,16898 --- 16893,17032 be specified by name or by OID. + + shows functions to + manage the aclitem type, the internal representation of access + privileges. + An aclitem entry describes the permissions of a grantee, + whether they are grantable or not, and which grantor granted them. + For instance, calvin=r*w/hobbes tells that + role calvin has + grantable privilege SELECT (r*) + and non-grantable privilege UPDATE (w) + granted by role hobbes. + An empty grantee stands for PUBLIC. + + + + aclitem Management Functions + + + Name Return Type Description + + + +acldefault(type, + ownerId) +aclitem[] +get the hardcoded default access privileges for an object belonging to ownerId + + +aclinsert(aclitem[], aclitem) +aclitem[] +add element aclitem to aclitem[] array + + +aclremove(aclitem[], aclitem) +aclitem[] +remove element aclitem from aclitem[] array + + +aclitemeq(aclitem1, aclitem2) +boolean +test whether two aclitem elements are equal + + +aclcontains(aclitem[], aclitem) +boolean +test whether element aclitem is contained within aclitem[] array + + +aclexplode(aclitem[]) +setof record +get aclitem array as tuples + + +makeaclitem(grantee, grantor, privilege, grantable) +aclitem +build an aclitem from input + + + + + + + aclitem + + + acldefault + + + aclinsert + + + aclremove + + + aclitemeq + + + aclcontains + + + aclexplode + + + makeaclitem + + + + acldefault returns the hardcoded default access privileges + for an object of type belonging to role ownerId. + Notice that these are used in the absence of any pg_default_acl + () entry. Default access privileges are described in + and can be overwritten with + . In other words, this function will return + results which may be misleading when the defaults have been overridden. + Type is a CHAR, use + 'c' for COLUMN, + 'r' for relation-like objects such as TABLE or VIEW, + 's' for SEQUENCE, + 'd' for DATABASE, + 'f' for FUNCTION or PROCEDURE, + 'l' for LANGUAGE, + 'L' for LARGE OBJECT, + 'n' for SCHEMA, + 't' for TABLESPACE, + 'F' for FOREIGN DATA WRAPPER, + 'S' for FOREIGN SERVER, + 'T' for TYPE or DOMAIN. + + + + aclinsert and aclremove + allow to insertion/removal of a privilege described by an + aclitem into/from an array of aclitem. + + + + aclitemeq checks for equality of two + aclitem elements. + + + + aclcontains checks if an aclitem + element is present in an array of aclitem. + + + + aclexplode returns an aclitem array + as a set rows. Output columns are grantor oid, + grantee oid (0 for PUBLIC), + granted privilege as text (SELECT, ...) + and whether the prilivege is grantable as boolean. + makeaclitem performs the inverse operation. + + shows functions that determine whether a certain object is visible in the diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c index a45e093..d5285e2 100644 *** a/src/backend/utils/adt/acl.c ---
Re: doc - add missing documentation for "acldefault"
Here is a version of the patch which documents briefly all aclitem-related functions, in a separate table. -- Fabien.diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index edc9be92a6..c81e5aa1b4 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -16829,6 +16829,151 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); be specified by name or by OID. + + shows functions to +manage the aclitem type, the internal representation of access +privileges. +An aclitem entry describes the permissions of a grantee, +whether they are grantable or not, and which grantor granted them. +For instance, calvin=r*w/hobbes tells that +role calvin has +grantable privilege SELECT (r*) +and non-grantable privilege UPDATE (w) +granted by role hobbes. +An empty grantee stands for PUBLIC. + + + +aclitem Management Functions + + + Name Return Type Description + + + + aclcontains(acls, acl) + boolean + tell whether privilege acl is contained within acls + + + acldefault(type, + oid) + aclitem[] + default hardcoded access privileges for an object belonging to oid + + + aclexplode(acls) + setof record + show aclitem array acls as tuples + + + aclinsert(acls, acl) + aclitem[] + add acl to acls + + + aclitemeq(acl1, acl2) + boolean + tell whether two aclitems are equal + + + aclitemin(cstring) + aclitem + internal aclitem type input function + + + aclitemout(acl) + cstring + internal aclitem type output function + + + aclremove(acls, acl) + aclitem[] + remove acl from acls + + + hash_aclitem(acl) + int + internal aclitem hashing function + + + makeaclitem(grantee, grantor, privilege, grantable) + aclitem + build an aclitem from input + + + + + + +aclitem + + +aclcontains + + +aclinsert + + +aclremove + + +acldefault + + +aclexplode + + +makeaclitem + + + +acldefault returns the hardcoded default access privileges +for an object of type belonging to role oid. +Type is a CHAR, use +'c' for COLUMN, +'r' for relation-like objects such as TABLE or VIEW, +'s' for SEQUENCE, +'d' for DATABASE, +'f' for FUNCTION or PROCEDURE, +'l' for LANGUAGE, +'L' for LARGE OBJECT, +'n' for SCHEMA, +'t' for TABLESPACE, +'F' for FOREIGN DATA WRAPPER, +'S' for FOREIGN SERVER, +'T' for TYPE or DOMAIN. +Default access privileges are described in + and can be overwritten with +. + + + +aclexplode shows a set of record describing +aclitem array acls. +Output columns are grantor oid, +grantee OID (0 for PUBLIC), +granted privilege as text (SELECT, ...) +and whether the prilivege is grantable as boolean. +makeaclitem performs the inverse operation. + + + +aclinsert, aclremove and +aclcontains allow to insert/remove/check whether +a privilege described by an aclitem +into/from/is contained by an array of aclitem. + + + +aclitemin, +aclitemout, +aclitemeq and +hash_aclitem +are internal functions to input, output, compare and hash +an aclitem. + + shows functions that determine whether a certain object is visible in the
Re: doc - add missing documentation for "acldefault"
Hello, However, the point of having hidden and/or undocumented functions fails me: they are hard/impossible to find if you do not know they exist from the start, and if you ever find one you do not know what they do without reading the source code in detail, eg to know what to give arguments to get an answer. At first, we must decide in which cases users will use them. And I don't see such cases. I must to know how to grant privileges, how to revoke them and how to check existing priveleges. All theese tasks documented in GRANT, REVOKE commands and system catalog descriptions. These are end-user needs. There are also other needs, such as devs. I see no reason to make the developer work harder by not providing documentation about available functions. Tom mention the "acldefault" function that I did not know existed, and I have read the doc! So I'm still favorable to documenting all functions:-) Maybe there could be a special section about special/internal functions, separate from functions which are more of interest to the end-user? But for me this is already the purpose of the "System information" sections in the documentation. Maybe there could be another sub-section about aclitem related functions in the "System information" section for these. Your's patch from another thread closes the last hole - describing default privileges in various psql commands. Yep. -- Fabien.
Re: doc - add missing documentation for "acldefault"
On Wed, Aug 01, 2018 at 04:41:44PM +0300, Pavel Luzanov wrote: > postgres=# \df acl* > List of fun > Schema | Name | Result data type | > +-+--+-- > pg_catalog | aclcontains | boolean | aclitem[], aclitem > pg_catalog | acldefault | aclitem[] | "char", oid > pg_catalog | aclexplode | SETOF record | acl aclitem[], OUT grantor > oid, O > pg_catalog | aclinsert | aclitem[] | aclitem[], aclitem > pg_catalog | aclitemeq | boolean | aclitem, aclitem > pg_catalog | aclitemin | aclitem | cstring > pg_catalog | aclitemout | cstring | aclitem > pg_catalog | aclremove | aclitem[] | aclitem[], aclitem Some of them are definitely internal. For example, aclitemin and aclitemout are input and output functions respectively of the aclitem data type. I think they don't need to be documented and shouldn't have "pg_" prefix as they was created to maintenance aclitem data type. -- Arthur Zakirov Postgres Professional: http://www.postgrespro.com Russian Postgres Company
Re: doc - add missing documentation for "acldefault"
Hello Fabien, However, the point of having hidden and/or undocumented functions fails me: they are hard/impossible to find if you do not know they exist from the start, and if you ever find one you do not know what they do without reading the source code in detail, eg to know what to give arguments to get an answer. At first, we must decide in which cases users will use them. And I don't see such cases. I must to know how to grant privileges, how to revoke them and how to check existing priveleges. All theese tasks documented in GRANT, REVOKE commands and system catalog descriptions. Your's patch from another thread closes the last hole - describing default privileges in various psql commands. - Pavel Luzanov Postgres Professional: http://www.postgrespro.com The Russian Postgres Company
Re: doc - add missing documentation for "acldefault"
Hello Pavel, I couldn't find the documentation. Attached patch adds one. Probably this function should have been named pg_*. Too late. I think this is intentionally hidden function, like others started with acl*. Yep, I thought of that. However, the point of having hidden and/or undocumented functions fails me: they are hard/impossible to find if you do not know they exist from the start, and if you ever find one you do not know what they do without reading the source code in detail, eg to know what to give arguments to get an answer. So I assumed that it was more lazyness and could be remedied with a doc patch for the one function I read. Maybe it would make sense to document the others as well, which are more straightforward. Also, that does not explain why they do not use a "pg_" prefix, which is already a way of saying "this is an internal-purpose function". So I would be in favor of prefixing them with pg_: as it is an undocumented feature, there would not be a compatibility break, somehow:-) postgres=# \df acl* List of fun Schema | Name | Result data type | +-+--+-- pg_catalog | aclcontains | boolean | aclitem[], aclitem pg_catalog | acldefault | aclitem[] | "char", oid pg_catalog | aclexplode | SETOF record | acl aclitem[], OUT grantor oid, O pg_catalog | aclinsert | aclitem[] | aclitem[], aclitem pg_catalog | aclitemeq | boolean | aclitem, aclitem pg_catalog | aclitemin | aclitem | cstring pg_catalog | aclitemout | cstring | aclitem pg_catalog | aclremove | aclitem[] | aclitem[], aclitem -- Fabien.
Re: doc - add missing documentation for "acldefault"
Fabien, On 01.08.2018 15:28, Fabien COELHO wrote: I couldn't find the documentation. Attached patch adds one. Probably this function should have been named pg_*. Too late. I think this is intentionally hidden function, like others started with acl*. postgres=# \df acl* List of fun Schema | Name | Result data type | +-+--+-- pg_catalog | aclcontains | boolean | aclitem[], aclitem pg_catalog | acldefault | aclitem[] | "char", oid pg_catalog | aclexplode | SETOF record | acl aclitem[], OUT grantor oid, O pg_catalog | aclinsert | aclitem[] | aclitem[], aclitem pg_catalog | aclitemeq | boolean | aclitem, aclitem pg_catalog | aclitemin | aclitem | cstring pg_catalog | aclitemout | cstring | aclitem pg_catalog | aclremove | aclitem[] | aclitem[], aclitem - Pavel Luzanov Postgres Professional: http://www.postgrespro.com The Russian Postgres Company
doc - add missing documentation for "acldefault"
I couldn't find the documentation. Attached patch adds one. Probably this function should have been named pg_*. Too late. -- Fabien.diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index edc9be92a6..0e5f8b914b 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -16398,6 +16398,12 @@ SET search_path TO schema , sc + + acldefault(type, + oid) + aclitem[] + default hardcoded access privileges for an object belonging to oid + has_any_column_privilege(user, table, @@ -16605,6 +16611,9 @@ SET search_path TO schema , sc + +acldefault + has_any_column_privilege @@ -16648,6 +16657,27 @@ SET search_path TO schema , sc row_security_active + +acldefault returns the hardcoded default access privileges +for an object of type belonging to role oid. +Type is a CHAR, use +'c' for COLUMN, +'r' for relation-like objects such as TABLE or VIEW, +'s' for SEQUENCE, +'d' for DATABASE, +'f' for FUNCTION or PROCEDURE, +'l' for LANGUAGE, +'L' for LARGE OBJECT, +'n' for SCHEMA, +'t' for TABLESPACE, +'F' for FOREIGN DATA WRAPPER, +'S' for FOREIGN SERVER, +'T' for TYPE or DOMAIN. +Default access permissions are described in + and can be overwritten with +. + + has_table_privilege checks whether a user can access a table in a particular way. The user can be