diff options
41 files changed, 1249 insertions, 201 deletions
diff --git a/doc/src/sgml/information_schema.sgml b/doc/src/sgml/information_schema.sgml index 92d2f647190..d8e42e4f630 100644 --- a/doc/src/sgml/information_schema.sgml +++ b/doc/src/sgml/information_schema.sgml @@ -284,6 +284,8 @@ the attributes of composite data types defined in the database. (Note that the view does not give information about table columns, which are sometimes called attributes in PostgreSQL contexts.) + Only those attributes are shown that the current user has access to (by way + of being the owner of or having some privilege on the type). </para> <table> @@ -1915,8 +1917,10 @@ <title><literal>domain_constraints</literal></title> <para> - The view <literal>domain_constraints</literal> contains all - constraints belonging to domains defined in the current database. + The view <literal>domain_constraints</literal> contains all constraints + belonging to domains defined in the current database. Only those domains + are shown that the current user has access to (by way of being the owner or + having some privilege). </para> <table> @@ -2052,8 +2056,9 @@ <title><literal>domains</literal></title> <para> - The view <literal>domains</literal> contains all domains defined in - the current database. + The view <literal>domains</literal> contains all domains defined in the + current database. Only those domains are shown that the current user has + access to (by way of being the owner or having some privilege). </para> <table> @@ -5778,15 +5783,13 @@ ORDER BY c.ordinal_position; <title><literal>udt_privileges</literal></title> <para> - The view <literal>udt_privileges</literal> is intended to identify - <literal>USAGE</literal> privileges granted on user-defined types - to a currently enabled role or by a currently enabled role. Since - data types do not have real privileges - in <productname>PostgreSQL</productname>, this view shows implicit - non-grantable <literal>USAGE</literal> privileges granted by the - owner to <literal>PUBLIC</literal> for all types, including - built-in ones (except domains, - see <xref linkend="infoschema-usage-privileges"> for that). + The view <literal>udt_privileges</literal> identifies + <literal>USAGE</literal> privileges granted on user-defined types to a + currently enabled role or by a currently enabled role. There is one row for + each combination of column, grantor, and grantee. This view shows only + composite types (see under <xref linkend="infoschema-user-defined-types"> + for why); see + <xref linkend="infoschema-usage-privileges"> for domain privileges. </para> <table> @@ -5861,10 +5864,10 @@ ORDER BY c.ordinal_position; </para> <para> - Since collations and domains do not have real privileges + Since collations do not have real privileges in <productname>PostgreSQL</productname>, this view shows implicit non-grantable <literal>USAGE</literal> privileges granted by the - owner to <literal>PUBLIC</literal> for all collations and domains. The other + owner to <literal>PUBLIC</literal> for all collations. The other object types, however, show real privileges. </para> @@ -5940,6 +5943,8 @@ ORDER BY c.ordinal_position; <para> The view <literal>user_defined_types</literal> currently contains all composite types defined in the current database. + Only those types are shown that the current user has access to (by way + of being the owner or having some privilege). </para> <para> diff --git a/doc/src/sgml/ref/alter_default_privileges.sgml b/doc/src/sgml/ref/alter_default_privileges.sgml index f7b52ef9d1a..b5c8bb3a36b 100644 --- a/doc/src/sgml/ref/alter_default_privileges.sgml +++ b/doc/src/sgml/ref/alter_default_privileges.sgml @@ -42,6 +42,10 @@ GRANT { EXECUTE | ALL [ PRIVILEGES ] } ON FUNCTIONS TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ] +GRANT { USAGE | ALL [ PRIVILEGES ] } + ON TYPES + TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ] + REVOKE [ GRANT OPTION FOR ] { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER } [, ...] | ALL [ PRIVILEGES ] } @@ -61,6 +65,12 @@ REVOKE [ GRANT OPTION FOR ] ON FUNCTIONS FROM { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ CASCADE | RESTRICT ] + +REVOKE [ GRANT OPTION FOR ] + { USAGE | ALL [ PRIVILEGES ] } + ON TYPES + FROM { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] + [ CASCADE | RESTRICT ] </synopsis> </refsynopsisdiv> @@ -72,7 +82,7 @@ REVOKE [ GRANT OPTION FOR ] that will be applied to objects created in the future. (It does not affect privileges assigned to already-existing objects.) Currently, only the privileges for tables (including views and foreign tables), - sequences, and functions can be altered. + sequences, functions, and types (including domains) can be altered. </para> <para> diff --git a/doc/src/sgml/ref/alter_foreign_table.sgml b/doc/src/sgml/ref/alter_foreign_table.sgml index 5c7a86fe87f..99e8e906d28 100644 --- a/doc/src/sgml/ref/alter_foreign_table.sgml +++ b/doc/src/sgml/ref/alter_foreign_table.sgml @@ -157,6 +157,8 @@ ALTER FOREIGN TABLE <replaceable class="PARAMETER">name</replaceable> the table's schema. (These restrictions enforce that altering the owner doesn't do anything you couldn't do by dropping and recreating the table. However, a superuser can alter ownership of any table anyway.) + To add a column or alter a column type, you must also + have <literal>USAGE</literal> privilege on the data type. </para> </refsect1> diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_table.sgml index 3b111a4c2b9..1976f6dcede 100644 --- a/doc/src/sgml/ref/alter_table.sgml +++ b/doc/src/sgml/ref/alter_table.sgml @@ -594,6 +594,9 @@ ALTER TABLE <replaceable class="PARAMETER">name</replaceable> the table's schema. (These restrictions enforce that altering the owner doesn't do anything you couldn't do by dropping and recreating the table. However, a superuser can alter ownership of any table anyway.) + To add a column or alter a column type or use the <literal>OF</literal> + clause, you must also have <literal>USAGE</literal> privilege on the data + type. </para> </refsect1> diff --git a/doc/src/sgml/ref/alter_type.sgml b/doc/src/sgml/ref/alter_type.sgml index a81fe6c340c..6386085a608 100644 --- a/doc/src/sgml/ref/alter_type.sgml +++ b/doc/src/sgml/ref/alter_type.sgml @@ -156,6 +156,8 @@ ALTER TYPE <replaceable class="PARAMETER">name</replaceable> ADD VALUE <replacea the type's schema. (These restrictions enforce that altering the owner doesn't do anything you couldn't do by dropping and recreating the type. However, a superuser can alter ownership of any type anyway.) + To add an attribute or alter an attribute type, you must also + have <literal>USAGE</literal> privilege on the data type. </para> </refsect1> diff --git a/doc/src/sgml/ref/create_aggregate.sgml b/doc/src/sgml/ref/create_aggregate.sgml index 7c2e1a9e738..d5e4e272fce 100644 --- a/doc/src/sgml/ref/create_aggregate.sgml +++ b/doc/src/sgml/ref/create_aggregate.sgml @@ -163,6 +163,13 @@ SELECT col FROM tab ORDER BY col USING sortop LIMIT 1; than</quote> or <quote>greater than</quote> strategy member of a B-tree index operator class. </para> + + <para> + To be able to create an aggregate function, you must + have <literal>USAGE</literal> privilege on the argument types, the state + type, and the return type, as well as <literal>EXECUTE</literal> privilege + on the transition and final functions. + </para> </refsect1> <refsect1> diff --git a/doc/src/sgml/ref/create_cast.sgml b/doc/src/sgml/ref/create_cast.sgml index c0039edf752..964cbf4d41a 100644 --- a/doc/src/sgml/ref/create_cast.sgml +++ b/doc/src/sgml/ref/create_cast.sgml @@ -159,10 +159,11 @@ SELECT CAST ( 2 AS numeric ) + 4.0; </note> <para> - To be able to create a cast, you must own the source or the target - data type. To create a binary-coercible cast, you must be superuser. - (This restriction is made because an erroneous binary-coercible cast - conversion can easily crash the server.) + To be able to create a cast, you must own the source or the target data type + and have <literal>USAGE</literal> privilege on the other type. To create a + binary-coercible cast, you must be superuser. (This restriction is made + because an erroneous binary-coercible cast conversion can easily crash the + server.) </para> </refsect1> diff --git a/doc/src/sgml/ref/create_domain.sgml b/doc/src/sgml/ref/create_domain.sgml index 0f901d78ee9..49db069f895 100644 --- a/doc/src/sgml/ref/create_domain.sgml +++ b/doc/src/sgml/ref/create_domain.sgml @@ -59,6 +59,11 @@ CREATE DOMAIN <replaceable class="parameter">name</replaceable> [ AS ] <replacea Define a domain rather than setting up each table's constraint individually. </para> + + <para> + To be able to create a domain, you must have <literal>USAGE</literal> + privilege on the underlying type. + </para> </refsect1> <refsect1> diff --git a/doc/src/sgml/ref/create_foreign_table.sgml b/doc/src/sgml/ref/create_foreign_table.sgml index 7f1cc4264db..2113d001b08 100644 --- a/doc/src/sgml/ref/create_foreign_table.sgml +++ b/doc/src/sgml/ref/create_foreign_table.sgml @@ -52,6 +52,11 @@ CREATE FOREIGN TABLE [ IF NOT EXISTS ] <replaceable class="PARAMETER">table_name the foreign table. Therefore, foreign tables cannot have the same name as any existing data type in the same schema. </para> + + <para> + To be able to create a table, you must have <literal>USAGE</literal> + privilege on all column types. + </para> </refsect1> <refsect1> diff --git a/doc/src/sgml/ref/create_function.sgml b/doc/src/sgml/ref/create_function.sgml index a617f965427..2a87130356e 100644 --- a/doc/src/sgml/ref/create_function.sgml +++ b/doc/src/sgml/ref/create_function.sgml @@ -92,6 +92,11 @@ CREATE [ OR REPLACE ] FUNCTION <para> The user that creates the function becomes the owner of the function. </para> + + <para> + To be able to create a function, you must have <literal>USAGE</literal> + privilege on the argument types and the return type. + </para> </refsect1> <refsect1> diff --git a/doc/src/sgml/ref/create_operator.sgml b/doc/src/sgml/ref/create_operator.sgml index 28b5e7e0da2..dd33f065afc 100644 --- a/doc/src/sgml/ref/create_operator.sgml +++ b/doc/src/sgml/ref/create_operator.sgml @@ -103,6 +103,13 @@ CREATE OPERATOR <replaceable>name</replaceable> ( The other clauses specify optional operator optimization clauses. Their meaning is detailed in <xref linkend="xoper-optimization">. </para> + + <para> + To be able to create an operator, you must have <literal>USAGE</literal> + privilege on the argument types and the return type, as well + as <literal>EXECUTE</literal> privilege on the underlying function. If a + commutator or negator operator is specified, you must own these operators. + </para> </refsect1> <refsect1> diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index d7b0fcf73a6..30e41540479 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -124,6 +124,12 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI a column constraint is only a notational convenience for use when the constraint only affects one column. </para> + + <para> + To be able to create a table, you must have <literal>USAGE</literal> + privilege on all column types or the type in the <literal>OF</literal> + clause, respectively. + </para> </refsect1> <refsect1> diff --git a/doc/src/sgml/ref/create_type.sgml b/doc/src/sgml/ref/create_type.sgml index 3308ee72eaf..7d87a67b3f1 100644 --- a/doc/src/sgml/ref/create_type.sgml +++ b/doc/src/sgml/ref/create_type.sgml @@ -104,6 +104,11 @@ CREATE TYPE <replaceable class="parameter">name</replaceable> A stand-alone composite type is useful, for example, as the argument or return type of a function. </para> + + <para> + To be able to create a composite type, you must + have <literal>USAGE</literal> privilege on all attribute types. + </para> </refsect2> <refsect2 id="SQL-CREATETYPE-enum"> diff --git a/doc/src/sgml/ref/grant.sgml b/doc/src/sgml/ref/grant.sgml index aa9bbcbdab9..51dd2e05e75 100644 --- a/doc/src/sgml/ref/grant.sgml +++ b/doc/src/sgml/ref/grant.sgml @@ -43,6 +43,10 @@ GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] } TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ] GRANT { USAGE | ALL [ PRIVILEGES ] } + ON DOMAIN <replaceable>domain_name</replaceable> [, ...] + TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ] + +GRANT { USAGE | ALL [ PRIVILEGES ] } ON FOREIGN DATA WRAPPER <replaceable>fdw_name</replaceable> [, ...] TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ] @@ -71,6 +75,10 @@ GRANT { CREATE | ALL [ PRIVILEGES ] } ON TABLESPACE <replaceable>tablespace_name</replaceable> [, ...] TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ] +GRANT { USAGE | ALL [ PRIVILEGES ] } + ON TYPE <replaceable>type_name</replaceable> [, ...] + TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ] + GRANT <replaceable class="PARAMETER">role_name</replaceable> [, ...] TO <replaceable class="PARAMETER">role_name</replaceable> [, ...] [ WITH ADMIN OPTION ] </synopsis> </refsynopsisdiv> @@ -336,6 +344,15 @@ GRANT <replaceable class="PARAMETER">role_name</replaceable> [, ...] TO <replace <function>currval</function> and <function>nextval</function> functions. </para> <para> + For types and domains, this privilege allow the use of the type or + domain in the creation of tables, functions, and other schema objects. + (Note that it does not control general <quote>usage</quote> of the type, + such as values of the type appearing in queries. It only prevents + objects from being created that depend on the type. The main purpose of + the privilege is controlling which users create dependencies on a type, + which could prevent the owner from changing the type later.) + </para> + <para> For foreign-data wrappers, this privilege enables the grantee to create new servers using that foreign-data wrapper. </para> @@ -616,7 +633,7 @@ GRANT admins TO joe; <para> The SQL standard provides for a <literal>USAGE</literal> privilege on other kinds of objects: character sets, collations, - translations, domains. + translations. </para> <para> diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml index f97929b1fc9..a9b1ed2699d 100644 --- a/doc/src/sgml/ref/psql-ref.sgml +++ b/doc/src/sgml/ref/psql-ref.sgml @@ -1048,7 +1048,7 @@ testdb=> pattern or the <literal>S</literal> modifier to include system objects. If <literal>+</literal> is appended to the command name, each object - is listed with its associated description. + is listed with its associated permissions and description. </para> </listitem> </varlistentry> @@ -1387,8 +1387,8 @@ testdb=> If <replaceable class="parameter">pattern</replaceable> is specified, only types whose names match the pattern are listed. If <literal>+</literal> is appended to the command name, each type is - listed with its internal name and size, as well as its allowed values - if it is an <type>enum</> type. + listed with its internal name and size, its allowed values + if it is an <type>enum</> type, and its associated permissions. By default, only user-created objects are shown; supply a pattern or the <literal>S</literal> modifier to include system objects. diff --git a/doc/src/sgml/ref/revoke.sgml b/doc/src/sgml/ref/revoke.sgml index 3229e4bcc71..a390375c174 100644 --- a/doc/src/sgml/ref/revoke.sgml +++ b/doc/src/sgml/ref/revoke.sgml @@ -52,6 +52,12 @@ REVOKE [ GRANT OPTION FOR ] REVOKE [ GRANT OPTION FOR ] { USAGE | ALL [ PRIVILEGES ] } + ON DOMAIN <replaceable>domain_name</replaceable> [, ...] + FROM { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] + [ CASCADE | RESTRICT ] + +REVOKE [ GRANT OPTION FOR ] + { USAGE | ALL [ PRIVILEGES ] } ON FOREIGN DATA WRAPPER <replaceable>fdw_name</replaceable> [, ...] FROM { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ CASCADE | RESTRICT ] @@ -93,6 +99,12 @@ REVOKE [ GRANT OPTION FOR ] FROM { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ CASCADE | RESTRICT ] +REVOKE [ GRANT OPTION FOR ] + { USAGE | ALL [ PRIVILEGES ] } + ON TYPE <replaceable>type_name</replaceable> [, ...] + FROM { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] + [ CASCADE | RESTRICT ] + REVOKE [ ADMIN OPTION FOR ] <replaceable class="PARAMETER">role_name</replaceable> [, ...] FROM <replaceable class="PARAMETER">role_name</replaceable> [, ...] [ CASCADE | RESTRICT ] diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c index 9e931df4b14..ee404867fe3 100644 --- a/src/backend/access/common/tupdesc.c +++ b/src/backend/access/common/tupdesc.c @@ -20,7 +20,9 @@ #include "postgres.h" #include "catalog/pg_type.h" +#include "miscadmin.h" #include "parser/parse_type.h" +#include "utils/acl.h" #include "utils/builtins.h" #include "utils/resowner.h" #include "utils/syscache.h" @@ -557,6 +559,7 @@ BuildDescForRelation(List *schema) foreach(l, schema) { ColumnDef *entry = lfirst(l); + AclResult aclresult; /* * for each entry in the list, get the name and type information from @@ -567,6 +570,12 @@ BuildDescForRelation(List *schema) attname = entry->colname; typenameTypeIdAndMod(NULL, entry->typeName, &atttypid, &atttypmod); + + aclresult = pg_type_aclcheck(atttypid, GetUserId(), ACL_USAGE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, ACL_KIND_TYPE, + format_type_be(atttypid)); + attcollation = GetColumnDefCollation(NULL, entry, atttypid); attdim = list_length(entry->typeName->arrayBounds); diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index 60c0b8a5b23..505a611a7dd 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -49,7 +49,9 @@ #include "commands/tablespace.h" #include "foreign/foreign.h" #include "miscadmin.h" +#include "nodes/makefuncs.h" #include "parser/parse_func.h" +#include "parser/parse_type.h" #include "utils/acl.h" #include "utils/builtins.h" #include "utils/fmgroids.h" @@ -113,6 +115,7 @@ static void ExecGrant_Language(InternalGrant *grantStmt); static void ExecGrant_Largeobject(InternalGrant *grantStmt); static void ExecGrant_Namespace(InternalGrant *grantStmt); static void ExecGrant_Tablespace(InternalGrant *grantStmt); +static void ExecGrant_Type(InternalGrant *grantStmt); static void SetDefaultACLsInSchemas(InternalDefaultACL *iacls, List *nspnames); static void SetDefaultACL(InternalDefaultACL *iacls); @@ -274,6 +277,9 @@ restrict_and_check_grant(bool is_grant, AclMode avail_goptions, bool all_privs, case ACL_KIND_FOREIGN_SERVER: whole_mask = ACL_ALL_RIGHTS_FOREIGN_SERVER; break; + case ACL_KIND_TYPE: + whole_mask = ACL_ALL_RIGHTS_TYPE; + break; default: elog(ERROR, "unrecognized object kind: %d", objkind); /* not reached, but keep compiler quiet */ @@ -449,6 +455,10 @@ ExecuteGrantStmt(GrantStmt *stmt) all_privileges = ACL_ALL_RIGHTS_DATABASE; errormsg = gettext_noop("invalid privilege type %s for database"); break; + case ACL_OBJECT_DOMAIN: + all_privileges = ACL_ALL_RIGHTS_TYPE; + errormsg = gettext_noop("invalid privilege type %s for domain"); + break; case ACL_OBJECT_FUNCTION: all_privileges = ACL_ALL_RIGHTS_FUNCTION; errormsg = gettext_noop("invalid privilege type %s for function"); @@ -469,6 +479,10 @@ ExecuteGrantStmt(GrantStmt *stmt) all_privileges = ACL_ALL_RIGHTS_TABLESPACE; errormsg = gettext_noop("invalid privilege type %s for tablespace"); break; + case ACL_OBJECT_TYPE: + all_privileges = ACL_ALL_RIGHTS_TYPE; + errormsg = gettext_noop("invalid privilege type %s for type"); + break; case ACL_OBJECT_FDW: all_privileges = ACL_ALL_RIGHTS_FDW; errormsg = gettext_noop("invalid privilege type %s for foreign-data wrapper"); @@ -552,6 +566,10 @@ ExecGrantStmt_oids(InternalGrant *istmt) case ACL_OBJECT_DATABASE: ExecGrant_Database(istmt); break; + case ACL_OBJECT_DOMAIN: + case ACL_OBJECT_TYPE: + ExecGrant_Type(istmt); + break; case ACL_OBJECT_FDW: ExecGrant_Fdw(istmt); break; @@ -620,6 +638,17 @@ objectNamesToOids(GrantObjectType objtype, List *objnames) objects = lappend_oid(objects, dbid); } break; + case ACL_OBJECT_DOMAIN: + case ACL_OBJECT_TYPE: + foreach(cell, objnames) + { + List *typname = (List *) lfirst(cell); + Oid oid; + + oid = typenameTypeId(NULL, makeTypeNameFromNameList(typname)); + objects = lappend_oid(objects, oid); + } + break; case ACL_OBJECT_FUNCTION: foreach(cell, objnames) { @@ -903,6 +932,10 @@ ExecAlterDefaultPrivilegesStmt(AlterDefaultPrivilegesStmt *stmt) all_privileges = ACL_ALL_RIGHTS_FUNCTION; errormsg = gettext_noop("invalid privilege type %s for function"); break; + case ACL_OBJECT_TYPE: + all_privileges = ACL_ALL_RIGHTS_TYPE; + errormsg = gettext_noop("invalid privilege type %s for type"); + break; default: elog(ERROR, "unrecognized GrantStmt.objtype: %d", (int) action->objtype); @@ -1085,6 +1118,12 @@ SetDefaultACL(InternalDefaultACL *iacls) this_privileges = ACL_ALL_RIGHTS_FUNCTION; break; + case ACL_OBJECT_TYPE: + objtype = DEFACLOBJ_TYPE; + if (iacls->all_privs && this_privileges == ACL_NO_RIGHTS) + this_privileges = ACL_ALL_RIGHTS_TYPE; + break; + default: elog(ERROR, "unrecognized objtype: %d", (int) iacls->objtype); @@ -1334,6 +1373,9 @@ RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid) case DatabaseRelationId: istmt.objtype = ACL_OBJECT_DATABASE; break; + case TypeRelationId: + istmt.objtype = ACL_OBJECT_TYPE; + break; case ProcedureRelationId: istmt.objtype = ACL_OBJECT_FUNCTION; break; @@ -2987,6 +3029,143 @@ ExecGrant_Tablespace(InternalGrant *istmt) heap_close(relation, RowExclusiveLock); } +static void +ExecGrant_Type(InternalGrant *istmt) +{ + Relation relation; + ListCell *cell; + + if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS) + istmt->privileges = ACL_ALL_RIGHTS_TYPE; + + relation = heap_open(TypeRelationId, RowExclusiveLock); + + foreach(cell, istmt->objects) + { + Oid typId = lfirst_oid(cell); + Form_pg_type pg_type_tuple; + Datum aclDatum; + bool isNull; + AclMode avail_goptions; + AclMode this_privileges; + Acl *old_acl; + Acl *new_acl; + Oid grantorId; + Oid ownerId; + HeapTuple newtuple; + Datum values[Natts_pg_type]; + bool nulls[Natts_pg_type]; + bool replaces[Natts_pg_type]; + int noldmembers; + int nnewmembers; + Oid *oldmembers; + Oid *newmembers; + HeapTuple tuple; + + /* Search syscache for pg_type */ + tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typId)); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "cache lookup failed for type %u", typId); + + pg_type_tuple = (Form_pg_type) GETSTRUCT(tuple); + + if (pg_type_tuple->typelem != 0 && pg_type_tuple->typlen == -1) + ereport(ERROR, + (errcode(ERRCODE_INVALID_GRANT_OPERATION), + errmsg("cannot set privileges of array types"), + errhint("Set the privileges of the element type instead."))); + + /* Used GRANT DOMAIN on a non-domain? */ + if (istmt->objtype == ACL_OBJECT_DOMAIN && + pg_type_tuple->typtype != TYPTYPE_DOMAIN) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is not a domain", + NameStr(pg_type_tuple->typname)))); + + /* + * Get owner ID and working copy of existing ACL. If there's no ACL, + * substitute the proper default. + */ + ownerId = pg_type_tuple->typowner; + aclDatum = heap_getattr(tuple, Anum_pg_type_typacl, + RelationGetDescr(relation), &isNull); + if (isNull) + { + old_acl = acldefault(istmt->objtype, ownerId); + /* There are no old member roles according to the catalogs */ + noldmembers = 0; + oldmembers = NULL; + } + else + { + old_acl = DatumGetAclPCopy(aclDatum); + /* Get the roles mentioned in the existing ACL */ + noldmembers = aclmembers(old_acl, &oldmembers); + } + + /* Determine ID to do the grant as, and available grant options */ + select_best_grantor(GetUserId(), istmt->privileges, + old_acl, ownerId, + &grantorId, &avail_goptions); + + /* + * Restrict the privileges to what we can actually grant, and emit the + * standards-mandated warning and error messages. + */ + this_privileges = + restrict_and_check_grant(istmt->is_grant, avail_goptions, + istmt->all_privs, istmt->privileges, + typId, grantorId, ACL_KIND_TYPE, + NameStr(pg_type_tuple->typname), + 0, NULL); + + /* + * Generate new ACL. + */ + new_acl = merge_acl_with_grant(old_acl, istmt->is_grant, + istmt->grant_option, istmt->behavior, + istmt->grantees, this_privileges, + grantorId, ownerId); + + /* + * We need the members of both old and new ACLs so we can correct the + * shared dependency information. + */ + nnewmembers = aclmembers(new_acl, &newmembers); + + /* finished building new ACL value, now insert it */ + MemSet(values, 0, sizeof(values)); + MemSet(nulls, false, sizeof(nulls)); + MemSet(replaces, false, sizeof(replaces)); + + replaces[Anum_pg_type_typacl - 1] = true; + values[Anum_pg_type_typacl - 1] = PointerGetDatum(new_acl); + + newtuple = heap_modify_tuple(tuple, RelationGetDescr(relation), values, + nulls, replaces); + + simple_heap_update(relation, &newtuple->t_self, newtuple); + + /* keep the catalog indexes up to date */ + CatalogUpdateIndexes(relation, newtuple); + + /* Update the shared dependency ACL info */ + updateAclDependencies(TypeRelationId, typId, 0, + ownerId, + noldmembers, oldmembers, + nnewmembers, newmembers); + + ReleaseSysCache(tuple); + pfree(new_acl); + + /* prevent error when processing duplicate objects */ + CommandCounterIncrement(); + } + + heap_close(relation, RowExclusiveLock); +} + static AclMode string_to_privilege(const char *privname) @@ -3263,6 +3442,8 @@ pg_aclmask(AclObjectKind objkind, Oid table_oid, AttrNumber attnum, Oid roleid, return pg_foreign_data_wrapper_aclmask(table_oid, roleid, mask, how); case ACL_KIND_FOREIGN_SERVER: return pg_foreign_server_aclmask(table_oid, roleid, mask, how); + case ACL_KIND_TYPE: + return pg_type_aclmask(table_oid, roleid, mask, how); default: elog(ERROR, "unrecognized objkind: %d", (int) objkind); @@ -3972,6 +4153,80 @@ pg_foreign_server_aclmask(Oid srv_oid, Oid roleid, } /* + * Exported routine for examining a user's privileges for a type. + */ +AclMode +pg_type_aclmask(Oid type_oid, Oid roleid, AclMode mask, AclMaskHow how) +{ + AclMode result; + HeapTuple tuple; + Datum aclDatum; + bool isNull; + Acl *acl; + Oid ownerId; + + Form_pg_type typeForm; + + /* Bypass permission checks for superusers */ + if (superuser_arg(roleid)) + return mask; + + /* + * Must get the type's tuple from pg_type + */ + tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type_oid)); + if (!HeapTupleIsValid(tuple)) + ereport(ERROR, + (errmsg("type with OID %u does not exist", + type_oid))); + typeForm = (Form_pg_type) GETSTRUCT(tuple); + + /* "True" array types don't manage permissions of their own */ + if (typeForm->typelem != 0 && typeForm->typlen == -1) + { + Oid elttype_oid = typeForm->typelem; + + ReleaseSysCache(tuple); + + tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(elttype_oid)); + if (!HeapTupleIsValid(tuple)) + ereport(ERROR, + (errmsg("type with OID %u does not exist", + type_oid))); + typeForm = (Form_pg_type) GETSTRUCT(tuple); + } + + /* + * Normal case: get the type's ACL from pg_type + */ + ownerId = typeForm->typowner; + + aclDatum = SysCacheGetAttr(TYPEOID, tuple, + Anum_pg_type_typacl, &isNull); + if (isNull) + { + /* No ACL, so build default ACL */ + acl = acldefault(ACL_OBJECT_TYPE, ownerId); + aclDatum = (Datum) 0; + } + else + { + /* detoast rel's ACL if necessary */ + acl = DatumGetAclP(aclDatum); + } + + result = aclmask(acl, roleid, ownerId, mask, how); + + /* if we have a detoasted copy, free it */ + if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) + pfree(acl); + + ReleaseSysCache(tuple); + + return result; +} + +/* * Exported routine for checking a user's access privileges to a column * * Returns ACLCHECK_OK if the user has any of the privileges identified by @@ -4205,6 +4460,18 @@ pg_foreign_server_aclcheck(Oid srv_oid, Oid roleid, AclMode mode) } /* + * Exported routine for checking a user's access privileges to a type + */ +AclResult +pg_type_aclcheck(Oid type_oid, Oid roleid, AclMode mode) +{ + if (pg_type_aclmask(type_oid, roleid, mode, ACLMASK_ANY) != 0) + return ACLCHECK_OK; + else + return ACLCHECK_NO_PRIV; +} + +/* * Ownership check for a relation (specified by OID). */ bool @@ -4813,6 +5080,10 @@ get_user_default_acl(GrantObjectType objtype, Oid ownerId, Oid nsp_oid) defaclobjtype = DEFACLOBJ_FUNCTION; break; + case ACL_OBJECT_TYPE: + defaclobjtype = DEFACLOBJ_TYPE; + break; + default: return NULL; } diff --git a/src/backend/catalog/information_schema.sql b/src/backend/catalog/information_schema.sql index 5ce7924b24e..b60409f3ca2 100644 --- a/src/backend/catalog/information_schema.sql +++ b/src/backend/catalog/information_schema.sql @@ -357,7 +357,9 @@ CREATE VIEW attributes AS ON a.attcollation = co.oid AND (nco.nspname, co.collname) <> ('pg_catalog', 'default') WHERE a.attnum > 0 AND NOT a.attisdropped - AND c.relkind in ('c'); + AND c.relkind in ('c') + AND (pg_has_role(c.relowner, 'USAGE') + OR has_type_privilege(c.reltype, 'USAGE')); GRANT SELECT ON attributes TO PUBLIC; @@ -868,7 +870,9 @@ CREATE VIEW domain_constraints AS FROM pg_namespace rs, pg_namespace n, pg_constraint con, pg_type t WHERE rs.oid = con.connamespace AND n.oid = t.typnamespace - AND t.oid = con.contypid; + AND t.oid = con.contypid + AND (pg_has_role(t.typowner, 'USAGE') + OR has_type_privilege(t.oid, 'USAGE')); GRANT SELECT ON domain_constraints TO PUBLIC; @@ -978,7 +982,8 @@ CREATE VIEW domains AS LEFT JOIN (pg_collation co JOIN pg_namespace nco ON (co.collnamespace = nco.oid)) ON t.typcollation = co.oid AND (nco.nspname, co.collname) <> ('pg_catalog', 'default') - ; + WHERE (pg_has_role(t.typowner, 'USAGE') + OR has_type_privilege(t.oid, 'USAGE')); GRANT SELECT ON domains TO PUBLIC; @@ -2024,20 +2029,38 @@ GRANT SELECT ON triggers TO PUBLIC; */ CREATE VIEW udt_privileges AS - SELECT CAST(null AS sql_identifier) AS grantor, - CAST('PUBLIC' AS sql_identifier) AS grantee, + SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor, + CAST(grantee.rolname AS sql_identifier) AS grantee, CAST(current_database() AS sql_identifier) AS udt_catalog, CAST(n.nspname AS sql_identifier) AS udt_schema, CAST(t.typname AS sql_identifier) AS udt_name, CAST('TYPE USAGE' AS character_data) AS privilege_type, -- sic - CAST('NO' AS yes_or_no) AS is_grantable + CAST( + CASE WHEN + -- object owner always has grant options + pg_has_role(grantee.oid, t.typowner, 'USAGE') + OR t.grantable + THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable - FROM pg_authid u, pg_namespace n, pg_type t + FROM ( + SELECT oid, typname, typnamespace, typtype, typowner, (aclexplode(typacl)).* FROM pg_type + ) AS t (oid, typname, typnamespace, typtype, typowner, grantor, grantee, prtype, grantable), + pg_namespace n, + pg_authid u_grantor, + ( + SELECT oid, rolname FROM pg_authid + UNION ALL + SELECT 0::oid, 'PUBLIC' + ) AS grantee (oid, rolname) - WHERE u.oid = t.typowner - AND n.oid = t.typnamespace - AND t.typtype <> 'd' - AND NOT (t.typelem <> 0 AND t.typlen = -1); + WHERE t.typnamespace = n.oid + AND t.typtype = 'c' + AND t.grantee = grantee.oid + AND t.grantor = u_grantor.oid + AND t.prtype IN ('USAGE') + AND (pg_has_role(u_grantor.oid, 'USAGE') + OR pg_has_role(grantee.oid, 'USAGE') + OR grantee.rolname = 'PUBLIC'); GRANT SELECT ON udt_privileges TO PUBLIC; @@ -2091,23 +2114,39 @@ CREATE VIEW usage_privileges AS UNION ALL /* domains */ - -- Domains have no real privileges, so we represent all domains with implicit usage privilege here. - SELECT CAST(u.rolname AS sql_identifier) AS grantor, - CAST('PUBLIC' AS sql_identifier) AS grantee, + SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor, + CAST(grantee.rolname AS sql_identifier) AS grantee, CAST(current_database() AS sql_identifier) AS object_catalog, CAST(n.nspname AS sql_identifier) AS object_schema, CAST(t.typname AS sql_identifier) AS object_name, CAST('DOMAIN' AS character_data) AS object_type, CAST('USAGE' AS character_data) AS privilege_type, - CAST('NO' AS yes_or_no) AS is_grantable + CAST( + CASE WHEN + -- object owner always has grant options + pg_has_role(grantee.oid, t.typowner, 'USAGE') + OR t.grantable + THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable - FROM pg_authid u, + FROM ( + SELECT oid, typname, typnamespace, typtype, typowner, (aclexplode(typacl)).* FROM pg_type + ) AS t (oid, typname, typnamespace, typtype, typowner, grantor, grantee, prtype, grantable), pg_namespace n, - pg_type t + pg_authid u_grantor, + ( + SELECT oid, rolname FROM pg_authid + UNION ALL + SELECT 0::oid, 'PUBLIC' + ) AS grantee (oid, rolname) - WHERE u.oid = t.typowner - AND t.typnamespace = n.oid + WHERE t.typnamespace = n.oid AND t.typtype = 'd' + AND t.grantee = grantee.oid + AND t.grantor = u_grantor.oid + AND t.prtype IN ('USAGE') + AND (pg_has_role(u_grantor.oid, 'USAGE') + OR pg_has_role(grantee.oid, 'USAGE') + OR grantee.rolname = 'PUBLIC') UNION ALL @@ -2237,10 +2276,13 @@ CREATE VIEW user_defined_types AS CAST(null AS sql_identifier) AS source_dtd_identifier, CAST(null AS sql_identifier) AS ref_dtd_identifier - FROM pg_namespace n, pg_class c + FROM pg_namespace n, pg_class c, pg_type t WHERE n.oid = c.relnamespace - AND c.relkind = 'c'; + AND t.typrelid = c.oid + AND c.relkind = 'c' + AND (pg_has_role(t.typowner, 'USAGE') + OR has_type_privilege(t.oid, 'USAGE')); GRANT SELECT ON user_defined_types TO PUBLIC; diff --git a/src/backend/catalog/pg_aggregate.c b/src/backend/catalog/pg_aggregate.c index 86e8c6bddf2..b106c92983c 100644 --- a/src/backend/catalog/pg_aggregate.c +++ b/src/backend/catalog/pg_aggregate.c @@ -71,6 +71,7 @@ AggregateCreate(const char *aggName, int i; ObjectAddress myself, referenced; + AclResult aclresult; /* sanity checks (caller should have caught these) */ if (!aggName) @@ -201,6 +202,28 @@ AggregateCreate(const char *aggName, } /* + * permission checks on used types + */ + for (i = 0; i < numArgs; i++) + { + aclresult = pg_type_aclcheck(aggArgTypes[i], GetUserId(), ACL_USAGE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, ACL_KIND_TYPE, + format_type_be(aggArgTypes[i])); + } + + aclresult = pg_type_aclcheck(aggTransType, GetUserId(), ACL_USAGE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, ACL_KIND_TYPE, + format_type_be(aggTransType)); + + aclresult = pg_type_aclcheck(finaltype, GetUserId(), ACL_USAGE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, ACL_KIND_TYPE, + format_type_be(finaltype)); + + + /* * Everything looks okay. Try to create the pg_proc entry for the * aggregate. (This could fail if there's already a conflicting entry.) */ diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c index 21d1ef303d7..50f384816b4 100644 --- a/src/backend/catalog/pg_type.c +++ b/src/backend/catalog/pg_type.c @@ -117,6 +117,7 @@ TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId) values[Anum_pg_type_typcollation - 1] = ObjectIdGetDatum(InvalidOid); nulls[Anum_pg_type_typdefaultbin - 1] = true; nulls[Anum_pg_type_typdefault - 1] = true; + nulls[Anum_pg_type_typacl - 1] = true; /* * create a new type tuple @@ -224,6 +225,7 @@ TypeCreate(Oid newTypeOid, Datum values[Natts_pg_type]; NameData name; int i; + Acl *typacl = NULL; /* * We assume that the caller validated the arguments individually, but did @@ -369,6 +371,13 @@ TypeCreate(Oid newTypeOid, else nulls[Anum_pg_type_typdefault - 1] = true; + typacl = get_user_default_acl(ACL_OBJECT_TYPE, ownerId, + typeNamespace); + if (typacl != NULL) + values[Anum_pg_type_typacl - 1] = PointerGetDatum(typacl); + else + nulls[Anum_pg_type_typacl - 1] = true; + /* * open pg_type and prepare to insert or update a row. * diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index 45fdfee2175..cc4ddc6006c 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -87,9 +87,11 @@ compute_return_type(TypeName *returnType, Oid languageOid, { Oid rettype; Type typtup; + AclResult aclresult; typtup = LookupTypeName(NULL, returnType, NULL); + if (typtup) { if (!((Form_pg_type) GETSTRUCT(typtup))->typisdefined) @@ -150,6 +152,11 @@ compute_return_type(TypeName *returnType, Oid languageOid, Assert(OidIsValid(rettype)); } + aclresult = pg_type_aclcheck(rettype, GetUserId(), ACL_USAGE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, ACL_KIND_TYPE, + format_type_be(rettype)); + *prorettype_p = rettype; *returnsSet_p = returnType->setof; } @@ -207,6 +214,7 @@ examine_parameter_list(List *parameters, Oid languageOid, bool isinput = false; Oid toid; Type typtup; + AclResult aclresult; typtup = LookupTypeName(NULL, t, NULL); if (typtup) @@ -237,6 +245,11 @@ examine_parameter_list(List *parameters, Oid languageOid, toid = InvalidOid; /* keep compiler quiet */ } + aclresult = pg_type_aclcheck(toid, GetUserId(), ACL_USAGE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, ACL_KIND_TYPE, + format_type_be(toid)); + if (t->setof) ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), @@ -1429,6 +1442,7 @@ CreateCast(CreateCastStmt *stmt) bool nulls[Natts_pg_cast]; ObjectAddress myself, referenced; + AclResult aclresult; sourcetypeid = typenameTypeId(NULL, stmt->sourcetype); targettypeid = typenameTypeId(NULL, stmt->targettype); @@ -1457,6 +1471,16 @@ CreateCast(CreateCastStmt *stmt) format_type_be(sourcetypeid), format_type_be(targettypeid)))); + aclresult = pg_type_aclcheck(sourcetypeid, GetUserId(), ACL_USAGE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, ACL_KIND_TYPE, + format_type_be(sourcetypeid)); + + aclresult = pg_type_aclcheck(targettypeid, GetUserId(), ACL_USAGE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, ACL_KIND_TYPE, + format_type_be(targettypeid)); + /* Detemine the cast method */ if (stmt->func != NULL) castmethod = COERCION_METHOD_FUNCTION; diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c index 1e6c5ce2ad7..0fdf0803134 100644 --- a/src/backend/commands/operatorcmds.c +++ b/src/backend/commands/operatorcmds.c @@ -45,6 +45,7 @@ #include "parser/parse_func.h" #include "parser/parse_oper.h" #include "parser/parse_type.h" +#include "utils/builtins.h" #include "utils/lsyscache.h" #include "utils/rel.h" #include "utils/syscache.h" @@ -73,6 +74,7 @@ DefineOperator(List *names, List *parameters) TypeName *typeName2 = NULL; /* second type name */ Oid typeId1 = InvalidOid; /* types converted to OID */ Oid typeId2 = InvalidOid; + Oid rettype; List *commutatorName = NIL; /* optional commutator operator name */ List *negatorName = NIL; /* optional negator operator name */ List *restrictionName = NIL; /* optional restrict. sel. procedure */ @@ -175,6 +177,22 @@ DefineOperator(List *names, List *parameters) (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), errmsg("at least one of leftarg or rightarg must be specified"))); + if (typeName1) + { + aclresult = pg_type_aclcheck(typeId1, GetUserId(), ACL_USAGE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, ACL_KIND_TYPE, + format_type_be(typeId1)); + } + + if (typeName2) + { + aclresult = pg_type_aclcheck(typeId2, GetUserId(), ACL_USAGE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, ACL_KIND_TYPE, + format_type_be(typeId2)); + } + /* * Look up the operator's underlying function. */ @@ -206,6 +224,12 @@ DefineOperator(List *names, List *parameters) aclcheck_error(aclresult, ACL_KIND_PROC, NameListToString(functionName)); + rettype = get_func_rettype(functionOid); + aclresult = pg_type_aclcheck(rettype, GetUserId(), ACL_USAGE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, ACL_KIND_TYPE, + format_type_be(rettype)); + /* * Look up restriction estimator if specified */ diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 00b6cb9d50d..61689b13386 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -506,7 +506,16 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId) (void) heap_reloptions(relkind, reloptions, true); if (stmt->ofTypename) + { + AclResult aclresult; + ofTypeId = typenameTypeId(NULL, stmt->ofTypename); + + aclresult = pg_type_aclcheck(ofTypeId, GetUserId(), ACL_USAGE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, ACL_KIND_TYPE, + format_type_be(ofTypeId)); + } else ofTypeId = InvalidOid; @@ -4326,6 +4335,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, Expr *defval; List *children; ListCell *child; + AclResult aclresult; /* At top level, permission check was done in ATPrepCmd, else do it */ if (recursing) @@ -4429,6 +4439,12 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, typeTuple = typenameType(NULL, colDef->typeName, &typmod); tform = (Form_pg_type) GETSTRUCT(typeTuple); typeOid = HeapTupleGetOid(typeTuple); + + aclresult = pg_type_aclcheck(typeOid, GetUserId(), ACL_USAGE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, ACL_KIND_TYPE, + format_type_be(typeOid)); + collOid = GetColumnDefCollation(NULL, colDef, typeOid); /* make sure datatype is legal for a column */ @@ -6973,6 +6989,7 @@ ATPrepAlterColumnType(List **wqueue, Oid targetcollid; NewColumnValue *newval; ParseState *pstate = make_parsestate(NULL); + AclResult aclresult; if (rel->rd_rel->reloftype && !recursing) ereport(ERROR, @@ -7006,6 +7023,11 @@ ATPrepAlterColumnType(List **wqueue, /* Look up the target type */ typenameTypeIdAndMod(NULL, typeName, &targettype, &targettypmod); + aclresult = pg_type_aclcheck(targettype, GetUserId(), ACL_USAGE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, ACL_KIND_TYPE, + format_type_be(targettype)); + /* And the collation */ targetcollid = GetColumnDefCollation(NULL, def, targettype); diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index eda43d826fa..ea8f7f099a2 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -756,6 +756,11 @@ DefineDomain(CreateDomainStmt *stmt) errmsg("\"%s\" is not a valid base type for a domain", TypeNameToString(stmt->typeName)))); + aclresult = pg_type_aclcheck(basetypeoid, GetUserId(), ACL_USAGE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, ACL_KIND_TYPE, + format_type_be(basetypeoid)); + /* * Identify the collation if any */ diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 3dbd80d53bc..0cbe93c5c91 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -2490,6 +2490,21 @@ OpenIntoRel(QueryDesc *queryDesc) (errcode(ERRCODE_INVALID_TABLE_DEFINITION), errmsg("ON COMMIT can only be used on temporary tables"))); + { + AclResult aclresult; + int i; + + for (i = 0; i < intoTupDesc->natts; i++) + { + Oid atttypid = intoTupDesc->attrs[i]->atttypid; + + aclresult = pg_type_aclcheck(atttypid, GetUserId(), ACL_USAGE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, ACL_KIND_TYPE, + format_type_be(atttypid)); + } + } + /* * If a column name list was specified in CREATE TABLE AS, override the * column names derived from the query. (Too few column names are OK, too diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index c3e0ee1877d..e0ff49f048a 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -558,7 +558,7 @@ static void processCASbits(int cas_bits, int location, const char *constrType, TABLE TABLES TABLESPACE TEMP TEMPLATE TEMPORARY TEXT_P THEN TIME TIMESTAMP TO TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P - TRUNCATE TRUSTED TYPE_P + TRUNCATE TRUSTED TYPE_P TYPES_P UNBOUNDED UNCOMMITTED UNENCRYPTED UNION UNIQUE UNKNOWN UNLISTEN UNLOGGED UNTIL UPDATE USER USING @@ -5434,6 +5434,14 @@ privilege_target: n->objs = $2; $$ = n; } + | DOMAIN_P any_name_list + { + PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_OBJECT; + n->objtype = ACL_OBJECT_DOMAIN; + n->objs = $2; + $$ = n; + } | LANGUAGE name_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); @@ -5466,6 +5474,14 @@ privilege_target: n->objs = $2; $$ = n; } + | TYPE_P any_name_list + { + PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_OBJECT; + n->objtype = ACL_OBJECT_TYPE; + n->objs = $2; + $$ = n; + } | ALL TABLES IN_P SCHEMA name_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); @@ -5680,6 +5696,7 @@ defacl_privilege_target: TABLES { $$ = ACL_OBJECT_RELATION; } | FUNCTIONS { $$ = ACL_OBJECT_FUNCTION; } | SEQUENCES { $$ = ACL_OBJECT_SEQUENCE; } + | TYPES_P { $$ = ACL_OBJECT_TYPE; } ; diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c index 48fb673df25..59587c68cae 100644 --- a/src/backend/utils/adt/acl.c +++ b/src/backend/utils/adt/acl.c @@ -109,6 +109,8 @@ static Oid convert_server_name(text *servername); static AclMode convert_server_priv_string(text *priv_type_text); static Oid convert_tablespace_name(text *tablespacename); static AclMode convert_tablespace_priv_string(text *priv_type_text); +static Oid convert_type_name(text *typename); +static AclMode convert_type_priv_string(text *priv_type_text); static AclMode convert_role_priv_string(text *priv_type_text); static AclResult pg_role_aclcheck(Oid role_oid, Oid roleid, AclMode mode); @@ -782,6 +784,11 @@ acldefault(GrantObjectType objtype, Oid ownerId) world_default = ACL_NO_RIGHTS; owner_default = ACL_ALL_RIGHTS_FOREIGN_SERVER; break; + case ACL_OBJECT_DOMAIN: + case ACL_OBJECT_TYPE: + world_default = ACL_USAGE; + owner_default = ACL_ALL_RIGHTS_TYPE; + break; default: elog(ERROR, "unrecognized objtype: %d", (int) objtype); world_default = ACL_NO_RIGHTS; /* keep compiler quiet */ @@ -4127,6 +4134,206 @@ convert_tablespace_priv_string(text *priv_type_text) } /* + * has_type_privilege variants + * These are all named "has_type_privilege" at the SQL level. + * They take various combinations of type name, type OID, + * user name, user OID, or implicit user = current_user. + * + * The result is a boolean value: true if user has the indicated + * privilege, false if not, or NULL if object doesn't exist. + */ + +/* + * has_type_privilege_name_name + * Check user privileges on a type given + * name username, text typename, and text priv name. + */ +Datum +has_type_privilege_name_name(PG_FUNCTION_ARGS) +{ + Name username = PG_GETARG_NAME(0); + text *typename = PG_GETARG_TEXT_P(1); + text *priv_type_text = PG_GETARG_TEXT_P(2); + Oid roleid; + Oid typeoid; + AclMode mode; + AclResult aclresult; + + roleid = get_role_oid_or_public(NameStr(*username)); + typeoid = convert_type_name(typename); + mode = convert_type_priv_string(priv_type_text); + + aclresult = pg_type_aclcheck(typeoid, roleid, mode); + + PG_RETURN_BOOL(aclresult == ACLCHECK_OK); +} + +/* + * has_type_privilege_name + * Check user privileges on a type given + * text typename and text priv name. + * current_user is assumed + */ +Datum +has_type_privilege_name(PG_FUNCTION_ARGS) +{ + text *typename = PG_GETARG_TEXT_P(0); + text *priv_type_text = PG_GETARG_TEXT_P(1); + Oid roleid; + Oid typeoid; + AclMode mode; + AclResult aclresult; + + roleid = GetUserId(); + typeoid = convert_type_name(typename); + mode = convert_type_priv_string(priv_type_text); + + aclresult = pg_type_aclcheck(typeoid, roleid, mode); + + PG_RETURN_BOOL(aclresult == ACLCHECK_OK); +} + +/* + * has_type_privilege_name_id + * Check user privileges on a type given + * name usename, type oid, and text priv name. + */ +Datum +has_type_privilege_name_id(PG_FUNCTION_ARGS) +{ + Name username = PG_GETARG_NAME(0); + Oid typeoid = PG_GETARG_OID(1); + text *priv_type_text = PG_GETARG_TEXT_P(2); + Oid roleid; + AclMode mode; + AclResult aclresult; + + roleid = get_role_oid_or_public(NameStr(*username)); + mode = convert_type_priv_string(priv_type_text); + + if (!SearchSysCacheExists1(TYPEOID, ObjectIdGetDatum(typeoid))) + PG_RETURN_NULL(); + + aclresult = pg_type_aclcheck(typeoid, roleid, mode); + + PG_RETURN_BOOL(aclresult == ACLCHECK_OK); +} + +/* + * has_type_privilege_id + * Check user privileges on a type given + * type oid, and text priv name. + * current_user is assumed + */ +Datum +has_type_privilege_id(PG_FUNCTION_ARGS) +{ + Oid typeoid = PG_GETARG_OID(0); + text *priv_type_text = PG_GETARG_TEXT_P(1); + Oid roleid; + AclMode mode; + AclResult aclresult; + + roleid = GetUserId(); + mode = convert_type_priv_string(priv_type_text); + + if (!SearchSysCacheExists1(TYPEOID, ObjectIdGetDatum(typeoid))) + PG_RETURN_NULL(); + + aclresult = pg_type_aclcheck(typeoid, roleid, mode); + + PG_RETURN_BOOL(aclresult == ACLCHECK_OK); +} + +/* + * has_type_privilege_id_name + * Check user privileges on a type given + * roleid, text typename, and text priv name. + */ +Datum +has_type_privilege_id_name(PG_FUNCTION_ARGS) +{ + Oid roleid = PG_GETARG_OID(0); + text *typename = PG_GETARG_TEXT_P(1); + text *priv_type_text = PG_GETARG_TEXT_P(2); + Oid typeoid; + AclMode mode; + AclResult aclresult; + + typeoid = convert_type_name(typename); + mode = convert_type_priv_string(priv_type_text); + + aclresult = pg_type_aclcheck(typeoid, roleid, mode); + + PG_RETURN_BOOL(aclresult == ACLCHECK_OK); +} + +/* + * has_type_privilege_id_id + * Check user privileges on a type given + * roleid, type oid, and text priv name. + */ +Datum +has_type_privilege_id_id(PG_FUNCTION_ARGS) +{ + Oid roleid = PG_GETARG_OID(0); + Oid typeoid = PG_GETARG_OID(1); + text *priv_type_text = PG_GETARG_TEXT_P(2); + AclMode mode; + AclResult aclresult; + + mode = convert_type_priv_string(priv_type_text); + + if (!SearchSysCacheExists1(TYPEOID, ObjectIdGetDatum(typeoid))) + PG_RETURN_NULL(); + + aclresult = pg_type_aclcheck(typeoid, roleid, mode); + + PG_RETURN_BOOL(aclresult == ACLCHECK_OK); +} + +/* + * Support routines for has_type_privilege family. + */ + +/* + * Given a type name expressed as a string, look it up and return Oid + */ +static Oid +convert_type_name(text *typename) +{ + char *typname = text_to_cstring(typename); + Oid oid; + + oid = DatumGetObjectId(DirectFunctionCall1(regtypein, + CStringGetDatum(typname))); + + if (!OidIsValid(oid)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("type \"%s\" does not exist", typname))); + + return oid; +} + +/* + * convert_type_priv_string + * Convert text string to AclMode value. + */ +static AclMode +convert_type_priv_string(text *priv_type_text) +{ + static const priv_map type_priv_map[] = { + {"USAGE", ACL_USAGE}, + {"USAGE WITH GRANT OPTION", ACL_GRANT_OPTION_FOR(ACL_USAGE)}, + {NULL, 0} + }; + + return convert_any_priv_string(priv_type_text, type_priv_map); +} + + +/* * pg_has_role variants * These are all named "pg_has_role" at the SQL level. * They take various combinations of role name, role OID, diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index b6aeae22e5d..095a2a891df 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -504,6 +504,11 @@ describeTypes(const char *pattern, bool verbose, bool showSystem) " ) AS \"%s\",\n", gettext_noop("Elements")); } + if (verbose && pset.sversion >= 90200) + { + printACLColumn(&buf, "t.typacl"); + appendPQExpBuffer(&buf, ",\n "); + } appendPQExpBuffer(&buf, " pg_catalog.obj_description(t.oid, 'pg_type') as \"%s\"\n", @@ -2813,9 +2818,16 @@ listDomains(const char *pattern, bool verbose, bool showSystem) gettext_noop("Check")); if (verbose) + { + if (pset.sversion >= 90200) + { + appendPQExpBuffer(&buf, ",\n "); + printACLColumn(&buf, "t.typacl"); + } appendPQExpBuffer(&buf, ",\n d.description as \"%s\"", gettext_noop("Description")); + } appendPQExpBuffer(&buf, "\nFROM pg_catalog.pg_type t\n" diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index bb0fa09f3ea..473706246d0 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -2241,13 +2241,15 @@ psql_completion(char *text, int start, int end) pg_strcasecmp(prev_wd, "ON") == 0) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvf, " UNION SELECT 'DATABASE'" + " UNION SELECT 'DOMAIN'" " UNION SELECT 'FOREIGN DATA WRAPPER'" " UNION SELECT 'FOREIGN SERVER'" " UNION SELECT 'FUNCTION'" " UNION SELECT 'LANGUAGE'" " UNION SELECT 'LARGE OBJECT'" " UNION SELECT 'SCHEMA'" - " UNION SELECT 'TABLESPACE'"); + " UNION SELECT 'TABLESPACE'" + " UNION SELECT 'TYPE'"); else if ((pg_strcasecmp(prev4_wd, "GRANT") == 0 || pg_strcasecmp(prev4_wd, "REVOKE") == 0) && pg_strcasecmp(prev2_wd, "ON") == 0 && @@ -2266,6 +2268,8 @@ psql_completion(char *text, int start, int end) { if (pg_strcasecmp(prev_wd, "DATABASE") == 0) COMPLETE_WITH_QUERY(Query_for_list_of_databases); + else if (pg_strcasecmp(prev_wd, "DOMAIN") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains, NULL); else if (pg_strcasecmp(prev_wd, "FUNCTION") == 0) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions, NULL); else if (pg_strcasecmp(prev_wd, "LANGUAGE") == 0) @@ -2274,6 +2278,8 @@ psql_completion(char *text, int start, int end) COMPLETE_WITH_QUERY(Query_for_list_of_schemas); else if (pg_strcasecmp(prev_wd, "TABLESPACE") == 0) COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces); + else if (pg_strcasecmp(prev_wd, "TYPE") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes, NULL); else if (pg_strcasecmp(prev4_wd, "GRANT") == 0) COMPLETE_WITH_CONST("TO"); else diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 1b6eaafc7b7..a7f2be41ca0 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 201112191 +#define CATALOG_VERSION_NO 201112192 #endif diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h index 06120e481e8..c767740744f 100644 --- a/src/include/catalog/pg_class.h +++ b/src/include/catalog/pg_class.h @@ -133,7 +133,7 @@ typedef FormData_pg_class *Form_pg_class; */ /* Note: "3" in the relfrozenxid column stands for FirstNormalTransactionId */ -DATA(insert OID = 1247 ( pg_type PGNSP 71 0 PGUID 0 0 0 0 0 0 0 0 f f p r 29 0 t f f f f 3 _null_ _null_ )); +DATA(insert OID = 1247 ( pg_type PGNSP 71 0 PGUID 0 0 0 0 0 0 0 0 f f p r 30 0 t f f f f 3 _null_ _null_ )); DESCR(""); DATA(insert OID = 1249 ( pg_attribute PGNSP 75 0 PGUID 0 0 0 0 0 0 0 0 f f p r 21 0 f f f f f 3 _null_ _null_ )); DESCR(""); diff --git a/src/include/catalog/pg_default_acl.h b/src/include/catalog/pg_default_acl.h index 96e9f0c4c6d..eacd92b0dab 100644 --- a/src/include/catalog/pg_default_acl.h +++ b/src/include/catalog/pg_default_acl.h @@ -71,5 +71,6 @@ typedef FormData_pg_default_acl *Form_pg_default_acl; #define DEFACLOBJ_RELATION 'r' /* table, view */ #define DEFACLOBJ_SEQUENCE 'S' /* sequence */ #define DEFACLOBJ_FUNCTION 'f' /* function */ +#define DEFACLOBJ_TYPE 'T' /* type */ #endif /* PG_DEFAULT_ACL_H */ diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 60e9feb2e32..ffe07279726 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -3311,6 +3311,19 @@ DESCR("current user privilege on server by server name"); DATA(insert OID = 3011 ( has_server_privilege PGNSP PGUID 12 1 0 0 0 f f f t f s 2 0 16 "26 25" _null_ _null_ _null_ _null_ has_server_privilege_id _null_ _null_ _null_ )); DESCR("current user privilege on server by server oid"); +DATA(insert OID = 3138 ( has_type_privilege PGNSP PGUID 12 1 0 0 0 f f f t f s 3 0 16 "19 25 25" _null_ _null_ _null_ _null_ has_type_privilege_name_name _null_ _null_ _null_ )); +DESCR("user privilege on type by username, type name"); +DATA(insert OID = 3139 ( has_type_privilege PGNSP PGUID 12 1 0 0 0 f f f t f s 3 0 16 "19 26 25" _null_ _null_ _null_ _null_ has_type_privilege_name_id _null_ _null_ _null_ )); +DESCR("user privilege on type by username, type oid"); +DATA(insert OID = 3140 ( has_type_privilege PGNSP PGUID 12 1 0 0 0 f f f t f s 3 0 16 "26 25 25" _null_ _null_ _null_ _null_ has_type_privilege_id_name _null_ _null_ _null_ )); +DESCR("user privilege on type by user oid, type name"); +DATA(insert OID = 3141 ( has_type_privilege PGNSP PGUID 12 1 0 0 0 f f f t f s 3 0 16 "26 26 25" _null_ _null_ _null_ _null_ has_type_privilege_id_id _null_ _null_ _null_ )); +DESCR("user privilege on type by user oid, type oid"); +DATA(insert OID = 3142 ( has_type_privilege PGNSP PGUID 12 1 0 0 0 f f f t f s 2 0 16 "25 25" _null_ _null_ _null_ _null_ has_type_privilege_name _null_ _null_ _null_ )); +DESCR("current user privilege on type by type name"); +DATA(insert OID = 3143 ( has_type_privilege PGNSP PGUID 12 1 0 0 0 f f f t f s 2 0 16 "26 25" _null_ _null_ _null_ _null_ has_type_privilege_id _null_ _null_ _null_ )); +DESCR("current user privilege on type by type oid"); + DATA(insert OID = 2705 ( pg_has_role PGNSP PGUID 12 1 0 0 0 f f f t f s 3 0 16 "19 19 25" _null_ _null_ _null_ _null_ pg_has_role_name_name _null_ _null_ _null_ )); DESCR("user privilege on role by username, role name"); DATA(insert OID = 2706 ( pg_has_role PGNSP PGUID 12 1 0 0 0 f f f t f s 3 0 16 "19 26 25" _null_ _null_ _null_ _null_ pg_has_role_name_id _null_ _null_ _null_ )); diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h index 406241a0dad..051d98dc37a 100644 --- a/src/include/catalog/pg_type.h +++ b/src/include/catalog/pg_type.h @@ -217,6 +217,10 @@ CATALOG(pg_type,1247) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71) BKI_SCHEMA_MACRO */ text typdefault; /* VARIABLE LENGTH FIELD */ + /* + * Access permissions + */ + aclitem typacl[1]; /* VARIABLE LENGTH FIELD */ } FormData_pg_type; /* ---------------- @@ -230,7 +234,7 @@ typedef FormData_pg_type *Form_pg_type; * compiler constants for pg_type * ---------------- */ -#define Natts_pg_type 29 +#define Natts_pg_type 30 #define Anum_pg_type_typname 1 #define Anum_pg_type_typnamespace 2 #define Anum_pg_type_typowner 3 @@ -260,6 +264,7 @@ typedef FormData_pg_type *Form_pg_type; #define Anum_pg_type_typcollation 27 #define Anum_pg_type_typdefaultbin 28 #define Anum_pg_type_typdefault 29 +#define Anum_pg_type_typacl 30 /* ---------------- @@ -276,87 +281,87 @@ typedef FormData_pg_type *Form_pg_type; */ /* OIDS 1 - 99 */ -DATA(insert OID = 16 ( bool PGNSP PGUID 1 t b B t t \054 0 0 1000 boolin boolout boolrecv boolsend - - - c p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 16 ( bool PGNSP PGUID 1 t b B t t \054 0 0 1000 boolin boolout boolrecv boolsend - - - c p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("boolean, 'true'/'false'"); #define BOOLOID 16 -DATA(insert OID = 17 ( bytea PGNSP PGUID -1 f b U f t \054 0 0 1001 byteain byteaout bytearecv byteasend - - - i x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 17 ( bytea PGNSP PGUID -1 f b U f t \054 0 0 1001 byteain byteaout bytearecv byteasend - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("variable-length string, binary values escaped"); #define BYTEAOID 17 -DATA(insert OID = 18 ( char PGNSP PGUID 1 t b S f t \054 0 0 1002 charin charout charrecv charsend - - - c p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 18 ( char PGNSP PGUID 1 t b S f t \054 0 0 1002 charin charout charrecv charsend - - - c p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("single character"); #define CHAROID 18 -DATA(insert OID = 19 ( name PGNSP PGUID NAMEDATALEN f b S f t \054 0 18 1003 namein nameout namerecv namesend - - - c p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 19 ( name PGNSP PGUID NAMEDATALEN f b S f t \054 0 18 1003 namein nameout namerecv namesend - - - c p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("63-character type for storing system identifiers"); #define NAMEOID 19 -DATA(insert OID = 20 ( int8 PGNSP PGUID 8 FLOAT8PASSBYVAL b N f t \054 0 0 1016 int8in int8out int8recv int8send - - - d p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 20 ( int8 PGNSP PGUID 8 FLOAT8PASSBYVAL b N f t \054 0 0 1016 int8in int8out int8recv int8send - - - d p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("~18 digit integer, 8-byte storage"); #define INT8OID 20 -DATA(insert OID = 21 ( int2 PGNSP PGUID 2 t b N f t \054 0 0 1005 int2in int2out int2recv int2send - - - s p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 21 ( int2 PGNSP PGUID 2 t b N f t \054 0 0 1005 int2in int2out int2recv int2send - - - s p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("-32 thousand to 32 thousand, 2-byte storage"); #define INT2OID 21 -DATA(insert OID = 22 ( int2vector PGNSP PGUID -1 f b A f t \054 0 21 1006 int2vectorin int2vectorout int2vectorrecv int2vectorsend - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 22 ( int2vector PGNSP PGUID -1 f b A f t \054 0 21 1006 int2vectorin int2vectorout int2vectorrecv int2vectorsend - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("array of int2, used in system tables"); #define INT2VECTOROID 22 -DATA(insert OID = 23 ( int4 PGNSP PGUID 4 t b N f t \054 0 0 1007 int4in int4out int4recv int4send - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 23 ( int4 PGNSP PGUID 4 t b N f t \054 0 0 1007 int4in int4out int4recv int4send - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("-2 billion to 2 billion integer, 4-byte storage"); #define INT4OID 23 -DATA(insert OID = 24 ( regproc PGNSP PGUID 4 t b N f t \054 0 0 1008 regprocin regprocout regprocrecv regprocsend - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 24 ( regproc PGNSP PGUID 4 t b N f t \054 0 0 1008 regprocin regprocout regprocrecv regprocsend - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("registered procedure"); #define REGPROCOID 24 -DATA(insert OID = 25 ( text PGNSP PGUID -1 f b S t t \054 0 0 1009 textin textout textrecv textsend - - - i x f 0 -1 0 100 _null_ _null_ )); +DATA(insert OID = 25 ( text PGNSP PGUID -1 f b S t t \054 0 0 1009 textin textout textrecv textsend - - - i x f 0 -1 0 100 _null_ _null_ _null_ )); DESCR("variable-length string, no limit specified"); #define TEXTOID 25 -DATA(insert OID = 26 ( oid PGNSP PGUID 4 t b N t t \054 0 0 1028 oidin oidout oidrecv oidsend - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 26 ( oid PGNSP PGUID 4 t b N t t \054 0 0 1028 oidin oidout oidrecv oidsend - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("object identifier(oid), maximum 4 billion"); #define OIDOID 26 -DATA(insert OID = 27 ( tid PGNSP PGUID 6 f b U f t \054 0 0 1010 tidin tidout tidrecv tidsend - - - s p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 27 ( tid PGNSP PGUID 6 f b U f t \054 0 0 1010 tidin tidout tidrecv tidsend - - - s p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("(block, offset), physical location of tuple"); #define TIDOID 27 -DATA(insert OID = 28 ( xid PGNSP PGUID 4 t b U f t \054 0 0 1011 xidin xidout xidrecv xidsend - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 28 ( xid PGNSP PGUID 4 t b U f t \054 0 0 1011 xidin xidout xidrecv xidsend - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("transaction id"); #define XIDOID 28 -DATA(insert OID = 29 ( cid PGNSP PGUID 4 t b U f t \054 0 0 1012 cidin cidout cidrecv cidsend - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 29 ( cid PGNSP PGUID 4 t b U f t \054 0 0 1012 cidin cidout cidrecv cidsend - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("command identifier type, sequence in transaction id"); #define CIDOID 29 -DATA(insert OID = 30 ( oidvector PGNSP PGUID -1 f b A f t \054 0 26 1013 oidvectorin oidvectorout oidvectorrecv oidvectorsend - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 30 ( oidvector PGNSP PGUID -1 f b A f t \054 0 26 1013 oidvectorin oidvectorout oidvectorrecv oidvectorsend - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("array of oids, used in system tables"); #define OIDVECTOROID 30 /* hand-built rowtype entries for bootstrapped catalogs */ /* NB: OIDs assigned here must match the BKI_ROWTYPE_OID declarations */ -DATA(insert OID = 71 ( pg_type PGNSP PGUID -1 f c C f t \054 1247 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 75 ( pg_attribute PGNSP PGUID -1 f c C f t \054 1249 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 81 ( pg_proc PGNSP PGUID -1 f c C f t \054 1255 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 83 ( pg_class PGNSP PGUID -1 f c C f t \054 1259 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 71 ( pg_type PGNSP PGUID -1 f c C f t \054 1247 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 75 ( pg_attribute PGNSP PGUID -1 f c C f t \054 1249 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 81 ( pg_proc PGNSP PGUID -1 f c C f t \054 1255 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 83 ( pg_class PGNSP PGUID -1 f c C f t \054 1259 0 0 record_in record_out record_recv record_send - - - d x f 0 -1 0 0 _null_ _null_ _null_ )); /* OIDS 100 - 199 */ -DATA(insert OID = 142 ( xml PGNSP PGUID -1 f b U f t \054 0 0 143 xml_in xml_out xml_recv xml_send - - - i x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 142 ( xml PGNSP PGUID -1 f b U f t \054 0 0 143 xml_in xml_out xml_recv xml_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("XML content"); #define XMLOID 142 -DATA(insert OID = 143 ( _xml PGNSP PGUID -1 f b A f t \054 0 142 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 143 ( _xml PGNSP PGUID -1 f b A f t \054 0 142 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); -DATA(insert OID = 194 ( pg_node_tree PGNSP PGUID -1 f b S f t \054 0 0 0 pg_node_tree_in pg_node_tree_out pg_node_tree_recv pg_node_tree_send - - - i x f 0 -1 0 100 _null_ _null_ )); +DATA(insert OID = 194 ( pg_node_tree PGNSP PGUID -1 f b S f t \054 0 0 0 pg_node_tree_in pg_node_tree_out pg_node_tree_recv pg_node_tree_send - - - i x f 0 -1 0 100 _null_ _null_ _null_ )); DESCR("string representing an internal node tree"); #define PGNODETREEOID 194 /* OIDS 200 - 299 */ -DATA(insert OID = 210 ( smgr PGNSP PGUID 2 t b U f t \054 0 0 0 smgrin smgrout - - - - - s p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 210 ( smgr PGNSP PGUID 2 t b U f t \054 0 0 0 smgrin smgrout - - - - - s p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("storage manager"); /* OIDS 300 - 399 */ @@ -366,252 +371,252 @@ DESCR("storage manager"); /* OIDS 500 - 599 */ /* OIDS 600 - 699 */ -DATA(insert OID = 600 ( point PGNSP PGUID 16 f b G f t \054 0 701 1017 point_in point_out point_recv point_send - - - d p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 600 ( point PGNSP PGUID 16 f b G f t \054 0 701 1017 point_in point_out point_recv point_send - - - d p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("geometric point '(x, y)'"); #define POINTOID 600 -DATA(insert OID = 601 ( lseg PGNSP PGUID 32 f b G f t \054 0 600 1018 lseg_in lseg_out lseg_recv lseg_send - - - d p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 601 ( lseg PGNSP PGUID 32 f b G f t \054 0 600 1018 lseg_in lseg_out lseg_recv lseg_send - - - d p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("geometric line segment '(pt1,pt2)'"); #define LSEGOID 601 -DATA(insert OID = 602 ( path PGNSP PGUID -1 f b G f t \054 0 0 1019 path_in path_out path_recv path_send - - - d x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 602 ( path PGNSP PGUID -1 f b G f t \054 0 0 1019 path_in path_out path_recv path_send - - - d x f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("geometric path '(pt1,...)'"); #define PATHOID 602 -DATA(insert OID = 603 ( box PGNSP PGUID 32 f b G f t \073 0 600 1020 box_in box_out box_recv box_send - - - d p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 603 ( box PGNSP PGUID 32 f b G f t \073 0 600 1020 box_in box_out box_recv box_send - - - d p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("geometric box '(lower left,upper right)'"); #define BOXOID 603 -DATA(insert OID = 604 ( polygon PGNSP PGUID -1 f b G f t \054 0 0 1027 poly_in poly_out poly_recv poly_send - - - d x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 604 ( polygon PGNSP PGUID -1 f b G f t \054 0 0 1027 poly_in poly_out poly_recv poly_send - - - d x f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("geometric polygon '(pt1,...)'"); #define POLYGONOID 604 -DATA(insert OID = 628 ( line PGNSP PGUID 32 f b G f t \054 0 701 629 line_in line_out line_recv line_send - - - d p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 628 ( line PGNSP PGUID 32 f b G f t \054 0 701 629 line_in line_out line_recv line_send - - - d p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("geometric line (not implemented)"); #define LINEOID 628 -DATA(insert OID = 629 ( _line PGNSP PGUID -1 f b A f t \054 0 628 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 629 ( _line PGNSP PGUID -1 f b A f t \054 0 628 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ _null_ )); DESCR(""); /* OIDS 700 - 799 */ -DATA(insert OID = 700 ( float4 PGNSP PGUID 4 FLOAT4PASSBYVAL b N f t \054 0 0 1021 float4in float4out float4recv float4send - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 700 ( float4 PGNSP PGUID 4 FLOAT4PASSBYVAL b N f t \054 0 0 1021 float4in float4out float4recv float4send - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("single-precision floating point number, 4-byte storage"); #define FLOAT4OID 700 -DATA(insert OID = 701 ( float8 PGNSP PGUID 8 FLOAT8PASSBYVAL b N t t \054 0 0 1022 float8in float8out float8recv float8send - - - d p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 701 ( float8 PGNSP PGUID 8 FLOAT8PASSBYVAL b N t t \054 0 0 1022 float8in float8out float8recv float8send - - - d p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("double-precision floating point number, 8-byte storage"); #define FLOAT8OID 701 -DATA(insert OID = 702 ( abstime PGNSP PGUID 4 t b D f t \054 0 0 1023 abstimein abstimeout abstimerecv abstimesend - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 702 ( abstime PGNSP PGUID 4 t b D f t \054 0 0 1023 abstimein abstimeout abstimerecv abstimesend - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("absolute, limited-range date and time (Unix system time)"); #define ABSTIMEOID 702 -DATA(insert OID = 703 ( reltime PGNSP PGUID 4 t b T f t \054 0 0 1024 reltimein reltimeout reltimerecv reltimesend - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 703 ( reltime PGNSP PGUID 4 t b T f t \054 0 0 1024 reltimein reltimeout reltimerecv reltimesend - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("relative, limited-range time interval (Unix delta time)"); #define RELTIMEOID 703 -DATA(insert OID = 704 ( tinterval PGNSP PGUID 12 f b T f t \054 0 0 1025 tintervalin tintervalout tintervalrecv tintervalsend - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 704 ( tinterval PGNSP PGUID 12 f b T f t \054 0 0 1025 tintervalin tintervalout tintervalrecv tintervalsend - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("(abstime,abstime), time interval"); #define TINTERVALOID 704 -DATA(insert OID = 705 ( unknown PGNSP PGUID -2 f b X f t \054 0 0 0 unknownin unknownout unknownrecv unknownsend - - - c p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 705 ( unknown PGNSP PGUID -2 f b X f t \054 0 0 0 unknownin unknownout unknownrecv unknownsend - - - c p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR(""); #define UNKNOWNOID 705 -DATA(insert OID = 718 ( circle PGNSP PGUID 24 f b G f t \054 0 0 719 circle_in circle_out circle_recv circle_send - - - d p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 718 ( circle PGNSP PGUID 24 f b G f t \054 0 0 719 circle_in circle_out circle_recv circle_send - - - d p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("geometric circle '(center,radius)'"); #define CIRCLEOID 718 -DATA(insert OID = 719 ( _circle PGNSP PGUID -1 f b A f t \054 0 718 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 790 ( money PGNSP PGUID 8 FLOAT8PASSBYVAL b N f t \054 0 0 791 cash_in cash_out cash_recv cash_send - - - d p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 719 ( _circle PGNSP PGUID -1 f b A f t \054 0 718 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 790 ( money PGNSP PGUID 8 FLOAT8PASSBYVAL b N f t \054 0 0 791 cash_in cash_out cash_recv cash_send - - - d p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("monetary amounts, $d,ddd.cc"); #define CASHOID 790 -DATA(insert OID = 791 ( _money PGNSP PGUID -1 f b A f t \054 0 790 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 791 ( _money PGNSP PGUID -1 f b A f t \054 0 790 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ _null_ )); /* OIDS 800 - 899 */ -DATA(insert OID = 829 ( macaddr PGNSP PGUID 6 f b U f t \054 0 0 1040 macaddr_in macaddr_out macaddr_recv macaddr_send - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 829 ( macaddr PGNSP PGUID 6 f b U f t \054 0 0 1040 macaddr_in macaddr_out macaddr_recv macaddr_send - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("XX:XX:XX:XX:XX:XX, MAC address"); #define MACADDROID 829 -DATA(insert OID = 869 ( inet PGNSP PGUID -1 f b I t t \054 0 0 1041 inet_in inet_out inet_recv inet_send - - - i m f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 869 ( inet PGNSP PGUID -1 f b I t t \054 0 0 1041 inet_in inet_out inet_recv inet_send - - - i m f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("IP address/netmask, host address, netmask optional"); #define INETOID 869 -DATA(insert OID = 650 ( cidr PGNSP PGUID -1 f b I f t \054 0 0 651 cidr_in cidr_out cidr_recv cidr_send - - - i m f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 650 ( cidr PGNSP PGUID -1 f b I f t \054 0 0 651 cidr_in cidr_out cidr_recv cidr_send - - - i m f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("network IP address/netmask, network address"); #define CIDROID 650 /* OIDS 900 - 999 */ /* OIDS 1000 - 1099 */ -DATA(insert OID = 1000 ( _bool PGNSP PGUID -1 f b A f t \054 0 16 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 1001 ( _bytea PGNSP PGUID -1 f b A f t \054 0 17 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 1002 ( _char PGNSP PGUID -1 f b A f t \054 0 18 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 1003 ( _name PGNSP PGUID -1 f b A f t \054 0 19 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 1005 ( _int2 PGNSP PGUID -1 f b A f t \054 0 21 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 1006 ( _int2vector PGNSP PGUID -1 f b A f t \054 0 22 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 1007 ( _int4 PGNSP PGUID -1 f b A f t \054 0 23 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 1000 ( _bool PGNSP PGUID -1 f b A f t \054 0 16 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 1001 ( _bytea PGNSP PGUID -1 f b A f t \054 0 17 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 1002 ( _char PGNSP PGUID -1 f b A f t \054 0 18 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 1003 ( _name PGNSP PGUID -1 f b A f t \054 0 19 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 1005 ( _int2 PGNSP PGUID -1 f b A f t \054 0 21 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 1006 ( _int2vector PGNSP PGUID -1 f b A f t \054 0 22 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 1007 ( _int4 PGNSP PGUID -1 f b A f t \054 0 23 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); #define INT4ARRAYOID 1007 -DATA(insert OID = 1008 ( _regproc PGNSP PGUID -1 f b A f t \054 0 24 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 1009 ( _text PGNSP PGUID -1 f b A f t \054 0 25 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 100 _null_ _null_ )); +DATA(insert OID = 1008 ( _regproc PGNSP PGUID -1 f b A f t \054 0 24 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 1009 ( _text PGNSP PGUID -1 f b A f t \054 0 25 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 100 _null_ _null_ _null_ )); #define TEXTARRAYOID 1009 -DATA(insert OID = 1028 ( _oid PGNSP PGUID -1 f b A f t \054 0 26 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 1010 ( _tid PGNSP PGUID -1 f b A f t \054 0 27 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 1011 ( _xid PGNSP PGUID -1 f b A f t \054 0 28 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 1012 ( _cid PGNSP PGUID -1 f b A f t \054 0 29 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 1013 ( _oidvector PGNSP PGUID -1 f b A f t \054 0 30 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 1014 ( _bpchar PGNSP PGUID -1 f b A f t \054 0 1042 0 array_in array_out array_recv array_send bpchartypmodin bpchartypmodout - i x f 0 -1 0 100 _null_ _null_ )); -DATA(insert OID = 1015 ( _varchar PGNSP PGUID -1 f b A f t \054 0 1043 0 array_in array_out array_recv array_send varchartypmodin varchartypmodout - i x f 0 -1 0 100 _null_ _null_ )); -DATA(insert OID = 1016 ( _int8 PGNSP PGUID -1 f b A f t \054 0 20 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 1017 ( _point PGNSP PGUID -1 f b A f t \054 0 600 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 1018 ( _lseg PGNSP PGUID -1 f b A f t \054 0 601 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 1019 ( _path PGNSP PGUID -1 f b A f t \054 0 602 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 1020 ( _box PGNSP PGUID -1 f b A f t \073 0 603 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 1021 ( _float4 PGNSP PGUID -1 f b A f t \054 0 700 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 1028 ( _oid PGNSP PGUID -1 f b A f t \054 0 26 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 1010 ( _tid PGNSP PGUID -1 f b A f t \054 0 27 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 1011 ( _xid PGNSP PGUID -1 f b A f t \054 0 28 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 1012 ( _cid PGNSP PGUID -1 f b A f t \054 0 29 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 1013 ( _oidvector PGNSP PGUID -1 f b A f t \054 0 30 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 1014 ( _bpchar PGNSP PGUID -1 f b A f t \054 0 1042 0 array_in array_out array_recv array_send bpchartypmodin bpchartypmodout - i x f 0 -1 0 100 _null_ _null_ _null_ )); +DATA(insert OID = 1015 ( _varchar PGNSP PGUID -1 f b A f t \054 0 1043 0 array_in array_out array_recv array_send varchartypmodin varchartypmodout - i x f 0 -1 0 100 _null_ _null_ _null_ )); +DATA(insert OID = 1016 ( _int8 PGNSP PGUID -1 f b A f t \054 0 20 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 1017 ( _point PGNSP PGUID -1 f b A f t \054 0 600 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 1018 ( _lseg PGNSP PGUID -1 f b A f t \054 0 601 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 1019 ( _path PGNSP PGUID -1 f b A f t \054 0 602 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 1020 ( _box PGNSP PGUID -1 f b A f t \073 0 603 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 1021 ( _float4 PGNSP PGUID -1 f b A f t \054 0 700 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); #define FLOAT4ARRAYOID 1021 -DATA(insert OID = 1022 ( _float8 PGNSP PGUID -1 f b A f t \054 0 701 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 1023 ( _abstime PGNSP PGUID -1 f b A f t \054 0 702 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); -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 = 1022 ( _float8 PGNSP PGUID -1 f b A f t \054 0 701 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 1023 ( _abstime PGNSP PGUID -1 f b A f t \054 0 702 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); +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_ _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_ _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_ _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_ _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_ )); -DATA(insert OID = 1040 ( _macaddr PGNSP PGUID -1 f b A f t \054 0 829 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 1041 ( _inet PGNSP PGUID -1 f b A f t \054 0 869 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 651 ( _cidr PGNSP PGUID -1 f b A f t \054 0 650 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 1263 ( _cstring PGNSP PGUID -1 f b A f t \054 0 2275 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); +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_ _null_ )); +DATA(insert OID = 1040 ( _macaddr PGNSP PGUID -1 f b A f t \054 0 829 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 1041 ( _inet PGNSP PGUID -1 f b A f t \054 0 869 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 651 ( _cidr PGNSP PGUID -1 f b A f t \054 0 650 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 1263 ( _cstring PGNSP PGUID -1 f b A f t \054 0 2275 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); #define CSTRINGARRAYOID 1263 -DATA(insert OID = 1042 ( bpchar PGNSP PGUID -1 f b S f t \054 0 0 1014 bpcharin bpcharout bpcharrecv bpcharsend bpchartypmodin bpchartypmodout - i x f 0 -1 0 100 _null_ _null_ )); +DATA(insert OID = 1042 ( bpchar PGNSP PGUID -1 f b S f t \054 0 0 1014 bpcharin bpcharout bpcharrecv bpcharsend bpchartypmodin bpchartypmodout - i x f 0 -1 0 100 _null_ _null_ _null_ )); DESCR("char(length), blank-padded string, fixed storage length"); #define BPCHAROID 1042 -DATA(insert OID = 1043 ( varchar PGNSP PGUID -1 f b S f t \054 0 0 1015 varcharin varcharout varcharrecv varcharsend varchartypmodin varchartypmodout - i x f 0 -1 0 100 _null_ _null_ )); +DATA(insert OID = 1043 ( varchar PGNSP PGUID -1 f b S f t \054 0 0 1015 varcharin varcharout varcharrecv varcharsend varchartypmodin varchartypmodout - i x f 0 -1 0 100 _null_ _null_ _null_ )); DESCR("varchar(length), non-blank-padded string, variable storage length"); #define VARCHAROID 1043 -DATA(insert OID = 1082 ( date PGNSP PGUID 4 t b D f t \054 0 0 1182 date_in date_out date_recv date_send - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 1082 ( date PGNSP PGUID 4 t b D f t \054 0 0 1182 date_in date_out date_recv date_send - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("date"); #define DATEOID 1082 -DATA(insert OID = 1083 ( time PGNSP PGUID 8 FLOAT8PASSBYVAL b D f t \054 0 0 1183 time_in time_out time_recv time_send timetypmodin timetypmodout - d p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 1083 ( time PGNSP PGUID 8 FLOAT8PASSBYVAL b D f t \054 0 0 1183 time_in time_out time_recv time_send timetypmodin timetypmodout - d p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("time of day"); #define TIMEOID 1083 /* OIDS 1100 - 1199 */ -DATA(insert OID = 1114 ( timestamp PGNSP PGUID 8 FLOAT8PASSBYVAL b D f t \054 0 0 1115 timestamp_in timestamp_out timestamp_recv timestamp_send timestamptypmodin timestamptypmodout - d p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 1114 ( timestamp PGNSP PGUID 8 FLOAT8PASSBYVAL b D f t \054 0 0 1115 timestamp_in timestamp_out timestamp_recv timestamp_send timestamptypmodin timestamptypmodout - d p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("date and time"); #define TIMESTAMPOID 1114 -DATA(insert OID = 1115 ( _timestamp PGNSP PGUID -1 f b A f t \054 0 1114 0 array_in array_out array_recv array_send timestamptypmodin timestamptypmodout - d x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 1182 ( _date PGNSP PGUID -1 f b A f t \054 0 1082 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 1183 ( _time PGNSP PGUID -1 f b A f t \054 0 1083 0 array_in array_out array_recv array_send timetypmodin timetypmodout - d x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 1184 ( timestamptz PGNSP PGUID 8 FLOAT8PASSBYVAL b D t t \054 0 0 1185 timestamptz_in timestamptz_out timestamptz_recv timestamptz_send timestamptztypmodin timestamptztypmodout - d p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 1115 ( _timestamp PGNSP PGUID -1 f b A f t \054 0 1114 0 array_in array_out array_recv array_send timestamptypmodin timestamptypmodout - d x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 1182 ( _date PGNSP PGUID -1 f b A f t \054 0 1082 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 1183 ( _time PGNSP PGUID -1 f b A f t \054 0 1083 0 array_in array_out array_recv array_send timetypmodin timetypmodout - d x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 1184 ( timestamptz PGNSP PGUID 8 FLOAT8PASSBYVAL b D t t \054 0 0 1185 timestamptz_in timestamptz_out timestamptz_recv timestamptz_send timestamptztypmodin timestamptztypmodout - d p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("date and time with time zone"); #define TIMESTAMPTZOID 1184 -DATA(insert OID = 1185 ( _timestamptz PGNSP PGUID -1 f b A f t \054 0 1184 0 array_in array_out array_recv array_send timestamptztypmodin timestamptztypmodout - d x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 1186 ( interval PGNSP PGUID 16 f b T t t \054 0 0 1187 interval_in interval_out interval_recv interval_send intervaltypmodin intervaltypmodout - d p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 1185 ( _timestamptz PGNSP PGUID -1 f b A f t \054 0 1184 0 array_in array_out array_recv array_send timestamptztypmodin timestamptztypmodout - d x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 1186 ( interval PGNSP PGUID 16 f b T t t \054 0 0 1187 interval_in interval_out interval_recv interval_send intervaltypmodin intervaltypmodout - d p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("@ <number> <units>, time interval"); #define INTERVALOID 1186 -DATA(insert OID = 1187 ( _interval PGNSP PGUID -1 f b A f t \054 0 1186 0 array_in array_out array_recv array_send intervaltypmodin intervaltypmodout - d x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 1187 ( _interval PGNSP PGUID -1 f b A f t \054 0 1186 0 array_in array_out array_recv array_send intervaltypmodin intervaltypmodout - d x f 0 -1 0 0 _null_ _null_ _null_ )); /* OIDS 1200 - 1299 */ -DATA(insert OID = 1231 ( _numeric PGNSP PGUID -1 f b A f t \054 0 1700 0 array_in array_out array_recv array_send numerictypmodin numerictypmodout - i x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 1266 ( timetz PGNSP PGUID 12 f b D f t \054 0 0 1270 timetz_in timetz_out timetz_recv timetz_send timetztypmodin timetztypmodout - d p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 1231 ( _numeric PGNSP PGUID -1 f b A f t \054 0 1700 0 array_in array_out array_recv array_send numerictypmodin numerictypmodout - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 1266 ( timetz PGNSP PGUID 12 f b D f t \054 0 0 1270 timetz_in timetz_out timetz_recv timetz_send timetztypmodin timetztypmodout - d p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("time of day with time zone"); #define TIMETZOID 1266 -DATA(insert OID = 1270 ( _timetz PGNSP PGUID -1 f b A f t \054 0 1266 0 array_in array_out array_recv array_send timetztypmodin timetztypmodout - d x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 1270 ( _timetz PGNSP PGUID -1 f b A f t \054 0 1266 0 array_in array_out array_recv array_send timetztypmodin timetztypmodout - d x f 0 -1 0 0 _null_ _null_ _null_ )); /* OIDS 1500 - 1599 */ -DATA(insert OID = 1560 ( bit PGNSP PGUID -1 f b V f t \054 0 0 1561 bit_in bit_out bit_recv bit_send bittypmodin bittypmodout - i x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 1560 ( bit PGNSP PGUID -1 f b V f t \054 0 0 1561 bit_in bit_out bit_recv bit_send bittypmodin bittypmodout - i x f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("fixed-length bit string"); #define BITOID 1560 -DATA(insert OID = 1561 ( _bit PGNSP PGUID -1 f b A f t \054 0 1560 0 array_in array_out array_recv array_send bittypmodin bittypmodout - i x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 1562 ( varbit PGNSP PGUID -1 f b V t t \054 0 0 1563 varbit_in varbit_out varbit_recv varbit_send varbittypmodin varbittypmodout - i x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 1561 ( _bit PGNSP PGUID -1 f b A f t \054 0 1560 0 array_in array_out array_recv array_send bittypmodin bittypmodout - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 1562 ( varbit PGNSP PGUID -1 f b V t t \054 0 0 1563 varbit_in varbit_out varbit_recv varbit_send varbittypmodin varbittypmodout - i x f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("variable-length bit string"); #define VARBITOID 1562 -DATA(insert OID = 1563 ( _varbit PGNSP PGUID -1 f b A f t \054 0 1562 0 array_in array_out array_recv array_send varbittypmodin varbittypmodout - i x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 1563 ( _varbit PGNSP PGUID -1 f b A f t \054 0 1562 0 array_in array_out array_recv array_send varbittypmodin varbittypmodout - i x f 0 -1 0 0 _null_ _null_ _null_ )); /* OIDS 1600 - 1699 */ /* OIDS 1700 - 1799 */ -DATA(insert OID = 1700 ( numeric PGNSP PGUID -1 f b N f t \054 0 0 1231 numeric_in numeric_out numeric_recv numeric_send numerictypmodin numerictypmodout - i m f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 1700 ( numeric PGNSP PGUID -1 f b N f t \054 0 0 1231 numeric_in numeric_out numeric_recv numeric_send numerictypmodin numerictypmodout - i m f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("numeric(precision, decimal), arbitrary precision number"); #define NUMERICOID 1700 -DATA(insert OID = 1790 ( refcursor PGNSP PGUID -1 f b U f t \054 0 0 2201 textin textout textrecv textsend - - - i x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 1790 ( refcursor PGNSP PGUID -1 f b U f t \054 0 0 2201 textin textout textrecv textsend - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("reference to cursor (portal name)"); #define REFCURSOROID 1790 /* OIDS 2200 - 2299 */ -DATA(insert OID = 2201 ( _refcursor PGNSP PGUID -1 f b A f t \054 0 1790 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 2201 ( _refcursor PGNSP PGUID -1 f b A f t \054 0 1790 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); -DATA(insert OID = 2202 ( regprocedure PGNSP PGUID 4 t b N f t \054 0 0 2207 regprocedurein regprocedureout regprocedurerecv regproceduresend - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 2202 ( regprocedure PGNSP PGUID 4 t b N f t \054 0 0 2207 regprocedurein regprocedureout regprocedurerecv regproceduresend - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("registered procedure (with args)"); #define REGPROCEDUREOID 2202 -DATA(insert OID = 2203 ( regoper PGNSP PGUID 4 t b N f t \054 0 0 2208 regoperin regoperout regoperrecv regopersend - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 2203 ( regoper PGNSP PGUID 4 t b N f t \054 0 0 2208 regoperin regoperout regoperrecv regopersend - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("registered operator"); #define REGOPEROID 2203 -DATA(insert OID = 2204 ( regoperator PGNSP PGUID 4 t b N f t \054 0 0 2209 regoperatorin regoperatorout regoperatorrecv regoperatorsend - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 2204 ( regoperator PGNSP PGUID 4 t b N f t \054 0 0 2209 regoperatorin regoperatorout regoperatorrecv regoperatorsend - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("registered operator (with args)"); #define REGOPERATOROID 2204 -DATA(insert OID = 2205 ( regclass PGNSP PGUID 4 t b N f t \054 0 0 2210 regclassin regclassout regclassrecv regclasssend - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 2205 ( regclass PGNSP PGUID 4 t b N f t \054 0 0 2210 regclassin regclassout regclassrecv regclasssend - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("registered class"); #define REGCLASSOID 2205 -DATA(insert OID = 2206 ( regtype PGNSP PGUID 4 t b N f t \054 0 0 2211 regtypein regtypeout regtyperecv regtypesend - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 2206 ( regtype PGNSP PGUID 4 t b N f t \054 0 0 2211 regtypein regtypeout regtyperecv regtypesend - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("registered type"); #define REGTYPEOID 2206 -DATA(insert OID = 2207 ( _regprocedure PGNSP PGUID -1 f b A f t \054 0 2202 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 2208 ( _regoper PGNSP PGUID -1 f b A f t \054 0 2203 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 2209 ( _regoperator PGNSP PGUID -1 f b A f t \054 0 2204 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 2210 ( _regclass PGNSP PGUID -1 f b A f t \054 0 2205 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 2211 ( _regtype PGNSP PGUID -1 f b A f t \054 0 2206 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 2207 ( _regprocedure PGNSP PGUID -1 f b A f t \054 0 2202 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 2208 ( _regoper PGNSP PGUID -1 f b A f t \054 0 2203 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 2209 ( _regoperator PGNSP PGUID -1 f b A f t \054 0 2204 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 2210 ( _regclass PGNSP PGUID -1 f b A f t \054 0 2205 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 2211 ( _regtype PGNSP PGUID -1 f b A f t \054 0 2206 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); #define REGTYPEARRAYOID 2211 /* uuid */ -DATA(insert OID = 2950 ( uuid PGNSP PGUID 16 f b U f t \054 0 0 2951 uuid_in uuid_out uuid_recv uuid_send - - - c p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 2950 ( uuid PGNSP PGUID 16 f b U f t \054 0 0 2951 uuid_in uuid_out uuid_recv uuid_send - - - c p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("UUID datatype"); -DATA(insert OID = 2951 ( _uuid PGNSP PGUID -1 f b A f t \054 0 2950 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 2951 ( _uuid PGNSP PGUID -1 f b A f t \054 0 2950 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); /* text search */ -DATA(insert OID = 3614 ( tsvector PGNSP PGUID -1 f b U f t \054 0 0 3643 tsvectorin tsvectorout tsvectorrecv tsvectorsend - - ts_typanalyze i x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 3614 ( tsvector PGNSP PGUID -1 f b U f t \054 0 0 3643 tsvectorin tsvectorout tsvectorrecv tsvectorsend - - ts_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("text representation for text search"); #define TSVECTOROID 3614 -DATA(insert OID = 3642 ( gtsvector PGNSP PGUID -1 f b U f t \054 0 0 3644 gtsvectorin gtsvectorout - - - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 3642 ( gtsvector PGNSP PGUID -1 f b U f t \054 0 0 3644 gtsvectorin gtsvectorout - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("GiST index internal text representation for text search"); #define GTSVECTOROID 3642 -DATA(insert OID = 3615 ( tsquery PGNSP PGUID -1 f b U f t \054 0 0 3645 tsqueryin tsqueryout tsqueryrecv tsquerysend - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 3615 ( tsquery PGNSP PGUID -1 f b U f t \054 0 0 3645 tsqueryin tsqueryout tsqueryrecv tsquerysend - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("query representation for text search"); #define TSQUERYOID 3615 -DATA(insert OID = 3734 ( regconfig PGNSP PGUID 4 t b N f t \054 0 0 3735 regconfigin regconfigout regconfigrecv regconfigsend - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 3734 ( regconfig PGNSP PGUID 4 t b N f t \054 0 0 3735 regconfigin regconfigout regconfigrecv regconfigsend - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("registered text search configuration"); #define REGCONFIGOID 3734 -DATA(insert OID = 3769 ( regdictionary PGNSP PGUID 4 t b N f t \054 0 0 3770 regdictionaryin regdictionaryout regdictionaryrecv regdictionarysend - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 3769 ( regdictionary PGNSP PGUID 4 t b N f t \054 0 0 3770 regdictionaryin regdictionaryout regdictionaryrecv regdictionarysend - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("registered text search dictionary"); #define REGDICTIONARYOID 3769 -DATA(insert OID = 3643 ( _tsvector PGNSP PGUID -1 f b A f t \054 0 3614 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 3644 ( _gtsvector PGNSP PGUID -1 f b A f t \054 0 3642 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 3645 ( _tsquery PGNSP PGUID -1 f b A f t \054 0 3615 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 3735 ( _regconfig PGNSP PGUID -1 f b A f t \054 0 3734 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 3770 ( _regdictionary PGNSP PGUID -1 f b A f t \054 0 3769 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 3643 ( _tsvector PGNSP PGUID -1 f b A f t \054 0 3614 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 3644 ( _gtsvector PGNSP PGUID -1 f b A f t \054 0 3642 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 3645 ( _tsquery PGNSP PGUID -1 f b A f t \054 0 3615 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 3735 ( _regconfig PGNSP PGUID -1 f b A f t \054 0 3734 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 3770 ( _regdictionary PGNSP PGUID -1 f b A f t \054 0 3769 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); -DATA(insert OID = 2970 ( txid_snapshot PGNSP PGUID -1 f b U f t \054 0 0 2949 txid_snapshot_in txid_snapshot_out txid_snapshot_recv txid_snapshot_send - - - d x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 2970 ( txid_snapshot PGNSP PGUID -1 f b U f t \054 0 0 2949 txid_snapshot_in txid_snapshot_out txid_snapshot_recv txid_snapshot_send - - - d x f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("txid snapshot"); -DATA(insert OID = 2949 ( _txid_snapshot PGNSP PGUID -1 f b A f t \054 0 2970 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 2949 ( _txid_snapshot PGNSP PGUID -1 f b A f t \054 0 2970 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ _null_ )); /* range types */ -DATA(insert OID = 3904 ( int4range PGNSP PGUID -1 f r R f t \054 0 0 3905 range_in range_out range_recv range_send - - range_typanalyze i x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 3904 ( int4range PGNSP PGUID -1 f r R f t \054 0 0 3905 range_in range_out range_recv range_send - - range_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("range of integers"); #define INT4RANGEOID 3904 -DATA(insert OID = 3905 ( _int4range PGNSP PGUID -1 f b A f t \054 0 3904 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 3906 ( numrange PGNSP PGUID -1 f r R f t \054 0 0 3907 range_in range_out range_recv range_send - - range_typanalyze i x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 3905 ( _int4range PGNSP PGUID -1 f b A f t \054 0 3904 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 3906 ( numrange PGNSP PGUID -1 f r R f t \054 0 0 3907 range_in range_out range_recv range_send - - range_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("range of numerics"); -DATA(insert OID = 3907 ( _numrange PGNSP PGUID -1 f b A f t \054 0 3906 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 3908 ( tsrange PGNSP PGUID -1 f r R f t \054 0 0 3909 range_in range_out range_recv range_send - - range_typanalyze d x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 3907 ( _numrange PGNSP PGUID -1 f b A f t \054 0 3906 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 3908 ( tsrange PGNSP PGUID -1 f r R f t \054 0 0 3909 range_in range_out range_recv range_send - - range_typanalyze d x f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("range of timestamps without time zone"); -DATA(insert OID = 3909 ( _tsrange PGNSP PGUID -1 f b A f t \054 0 3908 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 3910 ( tstzrange PGNSP PGUID -1 f r R f t \054 0 0 3911 range_in range_out range_recv range_send - - range_typanalyze d x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 3909 ( _tsrange PGNSP PGUID -1 f b A f t \054 0 3908 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 3910 ( tstzrange PGNSP PGUID -1 f r R f t \054 0 0 3911 range_in range_out range_recv range_send - - range_typanalyze d x f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("range of timestamps with time zone"); -DATA(insert OID = 3911 ( _tstzrange PGNSP PGUID -1 f b A f t \054 0 3910 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 3912 ( daterange PGNSP PGUID -1 f r R f t \054 0 0 3913 range_in range_out range_recv range_send - - range_typanalyze i x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 3911 ( _tstzrange PGNSP PGUID -1 f b A f t \054 0 3910 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 3912 ( daterange PGNSP PGUID -1 f r R f t \054 0 0 3913 range_in range_out range_recv range_send - - range_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("range of dates"); -DATA(insert OID = 3913 ( _daterange PGNSP PGUID -1 f b A f t \054 0 3912 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ )); -DATA(insert OID = 3926 ( int8range PGNSP PGUID -1 f r R f t \054 0 0 3927 range_in range_out range_recv range_send - - range_typanalyze d x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 3913 ( _daterange PGNSP PGUID -1 f b A f t \054 0 3912 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 3926 ( int8range PGNSP PGUID -1 f r R f t \054 0 0 3927 range_in range_out range_recv range_send - - range_typanalyze d x f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("range of bigints"); -DATA(insert OID = 3927 ( _int8range PGNSP PGUID -1 f b A f t \054 0 3926 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 3927 ( _int8range PGNSP PGUID -1 f b A f t \054 0 3926 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ _null_ )); /* * pseudo-types @@ -626,35 +631,35 @@ DATA(insert OID = 3927 ( _int8range PGNSP PGUID -1 f b A f t \054 0 3926 0 arr * but there is now support for it in records and arrays. Perhaps we should * just treat it as a regular base type? */ -DATA(insert OID = 2249 ( record PGNSP PGUID -1 f p P f t \054 0 0 2287 record_in record_out record_recv record_send - - - d x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 2249 ( record PGNSP PGUID -1 f p P f t \054 0 0 2287 record_in record_out record_recv record_send - - - d x f 0 -1 0 0 _null_ _null_ _null_ )); #define RECORDOID 2249 -DATA(insert OID = 2287 ( _record PGNSP PGUID -1 f p P f t \054 0 2249 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 2287 ( _record PGNSP PGUID -1 f p P f t \054 0 2249 0 array_in array_out array_recv array_send - - - d x f 0 -1 0 0 _null_ _null_ _null_ )); #define RECORDARRAYOID 2287 -DATA(insert OID = 2275 ( cstring PGNSP PGUID -2 f p P f t \054 0 0 1263 cstring_in cstring_out cstring_recv cstring_send - - - c p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 2275 ( cstring PGNSP PGUID -2 f p P f t \054 0 0 1263 cstring_in cstring_out cstring_recv cstring_send - - - c p f 0 -1 0 0 _null_ _null_ _null_ )); #define CSTRINGOID 2275 -DATA(insert OID = 2276 ( any PGNSP PGUID 4 t p P f t \054 0 0 0 any_in any_out - - - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 2276 ( any PGNSP PGUID 4 t p P f t \054 0 0 0 any_in any_out - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); #define ANYOID 2276 -DATA(insert OID = 2277 ( anyarray PGNSP PGUID -1 f p P f t \054 0 0 0 anyarray_in anyarray_out anyarray_recv anyarray_send - - - d x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 2277 ( anyarray PGNSP PGUID -1 f p P f t \054 0 0 0 anyarray_in anyarray_out anyarray_recv anyarray_send - - - d x f 0 -1 0 0 _null_ _null_ _null_ )); #define ANYARRAYOID 2277 -DATA(insert OID = 2278 ( void PGNSP PGUID 4 t p P f t \054 0 0 0 void_in void_out void_recv void_send - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 2278 ( void PGNSP PGUID 4 t p P f t \054 0 0 0 void_in void_out void_recv void_send - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); #define VOIDOID 2278 -DATA(insert OID = 2279 ( trigger PGNSP PGUID 4 t p P f t \054 0 0 0 trigger_in trigger_out - - - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 2279 ( trigger PGNSP PGUID 4 t p P f t \054 0 0 0 trigger_in trigger_out - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); #define TRIGGEROID 2279 -DATA(insert OID = 2280 ( language_handler PGNSP PGUID 4 t p P f t \054 0 0 0 language_handler_in language_handler_out - - - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 2280 ( language_handler PGNSP PGUID 4 t p P f t \054 0 0 0 language_handler_in language_handler_out - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); #define LANGUAGE_HANDLEROID 2280 -DATA(insert OID = 2281 ( internal PGNSP PGUID SIZEOF_POINTER t p P f t \054 0 0 0 internal_in internal_out - - - - - ALIGNOF_POINTER p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 2281 ( internal PGNSP PGUID SIZEOF_POINTER t p P f t \054 0 0 0 internal_in internal_out - - - - - ALIGNOF_POINTER p f 0 -1 0 0 _null_ _null_ _null_ )); #define INTERNALOID 2281 -DATA(insert OID = 2282 ( opaque PGNSP PGUID 4 t p P f t \054 0 0 0 opaque_in opaque_out - - - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 2282 ( opaque PGNSP PGUID 4 t p P f t \054 0 0 0 opaque_in opaque_out - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); #define OPAQUEOID 2282 -DATA(insert OID = 2283 ( anyelement PGNSP PGUID 4 t p P f t \054 0 0 0 anyelement_in anyelement_out - - - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 2283 ( anyelement PGNSP PGUID 4 t p P f t \054 0 0 0 anyelement_in anyelement_out - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); #define ANYELEMENTOID 2283 -DATA(insert OID = 2776 ( anynonarray PGNSP PGUID 4 t p P f t \054 0 0 0 anynonarray_in anynonarray_out - - - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 2776 ( anynonarray PGNSP PGUID 4 t p P f t \054 0 0 0 anynonarray_in anynonarray_out - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); #define ANYNONARRAYOID 2776 -DATA(insert OID = 3500 ( anyenum PGNSP PGUID 4 t p P f t \054 0 0 0 anyenum_in anyenum_out - - - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 3500 ( anyenum PGNSP PGUID 4 t p P f t \054 0 0 0 anyenum_in anyenum_out - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); #define ANYENUMOID 3500 -DATA(insert OID = 3115 ( fdw_handler PGNSP PGUID 4 t p P f t \054 0 0 0 fdw_handler_in fdw_handler_out - - - - - i p f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 3115 ( fdw_handler PGNSP PGUID 4 t p P f t \054 0 0 0 fdw_handler_in fdw_handler_out - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); #define FDW_HANDLEROID 3115 -DATA(insert OID = 3831 ( anyrange PGNSP PGUID -1 f p P f t \054 0 0 0 anyrange_in anyrange_out - - - - - d x f 0 -1 0 0 _null_ _null_ )); +DATA(insert OID = 3831 ( anyrange PGNSP PGUID -1 f p P f t \054 0 0 0 anyrange_in anyrange_out - - - - - d x f 0 -1 0 0 _null_ _null_ _null_ )); #define ANYRANGEOID 3831 diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 9e277c5a1e4..734227366d1 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -1282,13 +1282,15 @@ typedef enum GrantObjectType ACL_OBJECT_RELATION, /* table, view */ ACL_OBJECT_SEQUENCE, /* sequence */ ACL_OBJECT_DATABASE, /* database */ + ACL_OBJECT_DOMAIN, /* domain */ ACL_OBJECT_FDW, /* foreign-data wrapper */ ACL_OBJECT_FOREIGN_SERVER, /* foreign server */ ACL_OBJECT_FUNCTION, /* function */ ACL_OBJECT_LANGUAGE, /* procedural language */ ACL_OBJECT_LARGEOBJECT, /* largeobject */ ACL_OBJECT_NAMESPACE, /* namespace */ - ACL_OBJECT_TABLESPACE /* tablespace */ + ACL_OBJECT_TABLESPACE, /* tablespace */ + ACL_OBJECT_TYPE /* type */ } GrantObjectType; typedef struct GrantStmt diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h index 3d170bc3679..49aefed79da 100644 --- a/src/include/parser/kwlist.h +++ b/src/include/parser/kwlist.h @@ -373,6 +373,7 @@ PG_KEYWORD("true", TRUE_P, RESERVED_KEYWORD) PG_KEYWORD("truncate", TRUNCATE, UNRESERVED_KEYWORD) PG_KEYWORD("trusted", TRUSTED, UNRESERVED_KEYWORD) PG_KEYWORD("type", TYPE_P, UNRESERVED_KEYWORD) +PG_KEYWORD("types", TYPES_P, UNRESERVED_KEYWORD) PG_KEYWORD("unbounded", UNBOUNDED, UNRESERVED_KEYWORD) PG_KEYWORD("uncommitted", UNCOMMITTED, UNRESERVED_KEYWORD) PG_KEYWORD("unencrypted", UNENCRYPTED, UNRESERVED_KEYWORD) diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h index 6b80039f972..f23195192dc 100644 --- a/src/include/utils/acl.h +++ b/src/include/utils/acl.h @@ -155,6 +155,7 @@ typedef ArrayType Acl; #define ACL_ALL_RIGHTS_LARGEOBJECT (ACL_SELECT|ACL_UPDATE) #define ACL_ALL_RIGHTS_NAMESPACE (ACL_USAGE|ACL_CREATE) #define ACL_ALL_RIGHTS_TABLESPACE (ACL_CREATE) +#define ACL_ALL_RIGHTS_TYPE (ACL_USAGE) /* operation codes for pg_*_aclmask */ typedef enum @@ -275,6 +276,8 @@ extern AclMode pg_foreign_data_wrapper_aclmask(Oid fdw_oid, Oid roleid, AclMode mask, AclMaskHow how); extern AclMode pg_foreign_server_aclmask(Oid srv_oid, Oid roleid, AclMode mask, AclMaskHow how); +extern AclMode pg_type_aclmask(Oid type_oid, Oid roleid, + AclMode mask, AclMaskHow how); extern AclResult pg_attribute_aclcheck(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode); @@ -290,6 +293,7 @@ extern AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode); extern AclResult pg_tablespace_aclcheck(Oid spc_oid, Oid roleid, AclMode mode); extern AclResult pg_foreign_data_wrapper_aclcheck(Oid fdw_oid, Oid roleid, AclMode mode); extern AclResult pg_foreign_server_aclcheck(Oid srv_oid, Oid roleid, AclMode mode); +extern AclResult pg_type_aclcheck(Oid type_oid, Oid roleid, AclMode mode); extern void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname); diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index 9c5af5960fd..217cd61c849 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -94,6 +94,12 @@ extern Datum has_tablespace_privilege_id_name(PG_FUNCTION_ARGS); extern Datum has_tablespace_privilege_id_id(PG_FUNCTION_ARGS); extern Datum has_tablespace_privilege_name(PG_FUNCTION_ARGS); extern Datum has_tablespace_privilege_id(PG_FUNCTION_ARGS); +extern Datum has_type_privilege_name_name(PG_FUNCTION_ARGS); +extern Datum has_type_privilege_name_id(PG_FUNCTION_ARGS); +extern Datum has_type_privilege_id_name(PG_FUNCTION_ARGS); +extern Datum has_type_privilege_id_id(PG_FUNCTION_ARGS); +extern Datum has_type_privilege_name(PG_FUNCTION_ARGS); +extern Datum has_type_privilege_id(PG_FUNCTION_ARGS); extern Datum pg_has_role_name_name(PG_FUNCTION_ARGS); extern Datum pg_has_role_name_id(PG_FUNCTION_ARGS); extern Datum pg_has_role_id_name(PG_FUNCTION_ARGS); diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out index 5cda2302fcf..a816cce1b11 100644 --- a/src/test/regress/expected/privileges.out +++ b/src/test/regress/expected/privileges.out @@ -509,6 +509,102 @@ ERROR: must be owner of function testfunc1 DROP FUNCTION testfunc1(int); -- ok -- restore to sanity GRANT ALL PRIVILEGES ON LANGUAGE sql TO PUBLIC; +-- privileges on types +-- switch to superuser +\c - +CREATE TYPE testtype1 AS (a int, b text); +REVOKE USAGE ON TYPE testtype1 FROM PUBLIC; +GRANT USAGE ON TYPE testtype1 TO regressuser2; +GRANT USAGE ON TYPE _testtype1 TO regressuser2; -- fail +ERROR: cannot set privileges of array types +HINT: Set the privileges of the element type instead. +GRANT USAGE ON DOMAIN testtype1 TO regressuser2; -- fail +ERROR: "testtype1" is not a domain +CREATE DOMAIN testdomain1 AS int; +REVOKE USAGE on DOMAIN testdomain1 FROM PUBLIC; +GRANT USAGE ON DOMAIN testdomain1 TO regressuser2; +GRANT USAGE ON TYPE testdomain1 TO regressuser2; -- ok +SET SESSION AUTHORIZATION regressuser1; +-- commands that should fail +CREATE AGGREGATE testagg1a(testdomain1) (sfunc = int4_sum, stype = bigint); +ERROR: permission denied for type testdomain1 +CREATE DOMAIN testdomain2a AS testdomain1; +ERROR: permission denied for type testdomain1 +CREATE DOMAIN testdomain3a AS int; +CREATE FUNCTION castfunc(int) RETURNS testdomain3a AS $$ SELECT $1::testdomain3a $$ LANGUAGE SQL; +CREATE CAST (testdomain1 AS testdomain3a) WITH FUNCTION castfunc(int); +ERROR: permission denied for type testdomain1 +DROP FUNCTION castfunc(int) CASCADE; +DROP DOMAIN testdomain3a; +CREATE FUNCTION testfunc5a(a testdomain1) RETURNS int LANGUAGE SQL AS $$ SELECT $1 $$; +ERROR: permission denied for type testdomain1 +CREATE FUNCTION testfunc6a(b int) RETURNS testdomain1 LANGUAGE SQL AS $$ SELECT $1::testdomain1 $$; +ERROR: permission denied for type testdomain1 +CREATE OPERATOR !+! (PROCEDURE = int4pl, LEFTARG = testdomain1, RIGHTARG = testdomain1); +ERROR: permission denied for type testdomain1 +CREATE TABLE test5a (a int, b testdomain1); +ERROR: permission denied for type testdomain1 +CREATE TABLE test6a OF testtype1; +ERROR: permission denied for type testtype1 +CREATE TABLE test10a (a int[], b testtype1[]); +ERROR: permission denied for type testtype1[] +CREATE TABLE test9a (a int, b int); +ALTER TABLE test9a ADD COLUMN c testdomain1; +ERROR: permission denied for type testdomain1 +ALTER TABLE test9a ALTER COLUMN b TYPE testdomain1; +ERROR: permission denied for type testdomain1 +CREATE TYPE test7a AS (a int, b testdomain1); +ERROR: permission denied for type testdomain1 +CREATE TYPE test8a AS (a int, b int); +ALTER TYPE test8a ADD ATTRIBUTE c testdomain1; +ERROR: permission denied for type testdomain1 +ALTER TYPE test8a ALTER ATTRIBUTE b TYPE testdomain1; +ERROR: permission denied for type testdomain1 +CREATE TABLE test11a AS (SELECT 1::testdomain1 AS a); +ERROR: permission denied for type testdomain1 +REVOKE ALL ON TYPE testtype1 FROM PUBLIC; +ERROR: permission denied for type testtype1 +SET SESSION AUTHORIZATION regressuser2; +-- commands that should succeed +CREATE AGGREGATE testagg1b(testdomain1) (sfunc = int4_sum, stype = bigint); +CREATE DOMAIN testdomain2b AS testdomain1; +CREATE DOMAIN testdomain3b AS int; +CREATE FUNCTION castfunc(int) RETURNS testdomain3b AS $$ SELECT $1::testdomain3b $$ LANGUAGE SQL; +CREATE CAST (testdomain1 AS testdomain3b) WITH FUNCTION castfunc(int); +CREATE FUNCTION testfunc5b(a testdomain1) RETURNS int LANGUAGE SQL AS $$ SELECT $1 $$; +CREATE FUNCTION testfunc6b(b int) RETURNS testdomain1 LANGUAGE SQL AS $$ SELECT $1::testdomain1 $$; +CREATE OPERATOR !! (PROCEDURE = testfunc5b, RIGHTARG = testdomain1); +CREATE TABLE test5b (a int, b testdomain1); +CREATE TABLE test6b OF testtype1; +CREATE TABLE test10b (a int[], b testtype1[]); +CREATE TABLE test9b (a int, b int); +ALTER TABLE test9b ADD COLUMN c testdomain1; +ALTER TABLE test9b ALTER COLUMN b TYPE testdomain1; +CREATE TYPE test7b AS (a int, b testdomain1); +CREATE TYPE test8b AS (a int, b int); +ALTER TYPE test8b ADD ATTRIBUTE c testdomain1; +ALTER TYPE test8b ALTER ATTRIBUTE b TYPE testdomain1; +CREATE TABLE test11b AS (SELECT 1::testdomain1 AS a); +REVOKE ALL ON TYPE testtype1 FROM PUBLIC; +WARNING: no privileges could be revoked for "testtype1" +\c - +DROP AGGREGATE testagg1b(testdomain1); +DROP DOMAIN testdomain2b; +DROP OPERATOR !! (NONE, testdomain1); +DROP FUNCTION testfunc5b(a testdomain1); +DROP FUNCTION testfunc6b(b int); +DROP TABLE test5b; +DROP TABLE test6b; +DROP TABLE test9b; +DROP TABLE test10b; +DROP TYPE test7b; +DROP TYPE test8b; +DROP CAST (testdomain1 AS testdomain3b); +DROP FUNCTION castfunc(int) CASCADE; +DROP DOMAIN testdomain3b; +DROP TABLE test11b; +DROP TYPE testtype1; -- ok +DROP DOMAIN testdomain1; -- ok -- truncate SET SESSION AUTHORIZATION regressuser5; TRUNCATE atest2; -- ok @@ -1144,13 +1240,31 @@ SELECT has_function_privilege('regressuser2', 'testns.foo()', 'EXECUTE'); -- yes (1 row) DROP FUNCTION testns.foo(); +ALTER DEFAULT PRIVILEGES FOR ROLE regressuser1 REVOKE USAGE ON TYPES FROM public; +CREATE DOMAIN testns.testdomain1 AS int; +SELECT has_type_privilege('regressuser2', 'testns.testdomain1', 'USAGE'); -- no + has_type_privilege +-------------------- + f +(1 row) + +ALTER DEFAULT PRIVILEGES IN SCHEMA testns GRANT USAGE ON TYPES to public; +DROP DOMAIN testns.testdomain1; +CREATE DOMAIN testns.testdomain1 AS int; +SELECT has_type_privilege('regressuser2', 'testns.testdomain1', 'USAGE'); -- yes + has_type_privilege +-------------------- + t +(1 row) + +DROP DOMAIN testns.testdomain1; RESET ROLE; SELECT count(*) FROM pg_default_acl d LEFT JOIN pg_namespace n ON defaclnamespace = n.oid WHERE nspname = 'testns'; count ------- - 2 + 3 (1 row) DROP SCHEMA testns CASCADE; diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql index a87ce77aa6b..3dd77a79179 100644 --- a/src/test/regress/sql/privileges.sql +++ b/src/test/regress/sql/privileges.sql @@ -338,6 +338,115 @@ DROP FUNCTION testfunc1(int); -- ok -- restore to sanity GRANT ALL PRIVILEGES ON LANGUAGE sql TO PUBLIC; +-- privileges on types + +-- switch to superuser +\c - + +CREATE TYPE testtype1 AS (a int, b text); +REVOKE USAGE ON TYPE testtype1 FROM PUBLIC; +GRANT USAGE ON TYPE testtype1 TO regressuser2; +GRANT USAGE ON TYPE _testtype1 TO regressuser2; -- fail +GRANT USAGE ON DOMAIN testtype1 TO regressuser2; -- fail + +CREATE DOMAIN testdomain1 AS int; +REVOKE USAGE on DOMAIN testdomain1 FROM PUBLIC; +GRANT USAGE ON DOMAIN testdomain1 TO regressuser2; +GRANT USAGE ON TYPE testdomain1 TO regressuser2; -- ok + +SET SESSION AUTHORIZATION regressuser1; + +-- commands that should fail + +CREATE AGGREGATE testagg1a(testdomain1) (sfunc = int4_sum, stype = bigint); + +CREATE DOMAIN testdomain2a AS testdomain1; + +CREATE DOMAIN testdomain3a AS int; +CREATE FUNCTION castfunc(int) RETURNS testdomain3a AS $$ SELECT $1::testdomain3a $$ LANGUAGE SQL; +CREATE CAST (testdomain1 AS testdomain3a) WITH FUNCTION castfunc(int); +DROP FUNCTION castfunc(int) CASCADE; +DROP DOMAIN testdomain3a; + +CREATE FUNCTION testfunc5a(a testdomain1) RETURNS int LANGUAGE SQL AS $$ SELECT $1 $$; +CREATE FUNCTION testfunc6a(b int) RETURNS testdomain1 LANGUAGE SQL AS $$ SELECT $1::testdomain1 $$; + +CREATE OPERATOR !+! (PROCEDURE = int4pl, LEFTARG = testdomain1, RIGHTARG = testdomain1); + +CREATE TABLE test5a (a int, b testdomain1); +CREATE TABLE test6a OF testtype1; +CREATE TABLE test10a (a int[], b testtype1[]); + +CREATE TABLE test9a (a int, b int); +ALTER TABLE test9a ADD COLUMN c testdomain1; +ALTER TABLE test9a ALTER COLUMN b TYPE testdomain1; + +CREATE TYPE test7a AS (a int, b testdomain1); + +CREATE TYPE test8a AS (a int, b int); +ALTER TYPE test8a ADD ATTRIBUTE c testdomain1; +ALTER TYPE test8a ALTER ATTRIBUTE b TYPE testdomain1; + +CREATE TABLE test11a AS (SELECT 1::testdomain1 AS a); + +REVOKE ALL ON TYPE testtype1 FROM PUBLIC; + +SET SESSION AUTHORIZATION regressuser2; + +-- commands that should succeed + +CREATE AGGREGATE testagg1b(testdomain1) (sfunc = int4_sum, stype = bigint); + +CREATE DOMAIN testdomain2b AS testdomain1; + +CREATE DOMAIN testdomain3b AS int; +CREATE FUNCTION castfunc(int) RETURNS testdomain3b AS $$ SELECT $1::testdomain3b $$ LANGUAGE SQL; +CREATE CAST (testdomain1 AS testdomain3b) WITH FUNCTION castfunc(int); + +CREATE FUNCTION testfunc5b(a testdomain1) RETURNS int LANGUAGE SQL AS $$ SELECT $1 $$; +CREATE FUNCTION testfunc6b(b int) RETURNS testdomain1 LANGUAGE SQL AS $$ SELECT $1::testdomain1 $$; + +CREATE OPERATOR !! (PROCEDURE = testfunc5b, RIGHTARG = testdomain1); + +CREATE TABLE test5b (a int, b testdomain1); +CREATE TABLE test6b OF testtype1; +CREATE TABLE test10b (a int[], b testtype1[]); + +CREATE TABLE test9b (a int, b int); +ALTER TABLE test9b ADD COLUMN c testdomain1; +ALTER TABLE test9b ALTER COLUMN b TYPE testdomain1; + +CREATE TYPE test7b AS (a int, b testdomain1); + +CREATE TYPE test8b AS (a int, b int); +ALTER TYPE test8b ADD ATTRIBUTE c testdomain1; +ALTER TYPE test8b ALTER ATTRIBUTE b TYPE testdomain1; + +CREATE TABLE test11b AS (SELECT 1::testdomain1 AS a); + +REVOKE ALL ON TYPE testtype1 FROM PUBLIC; + +\c - +DROP AGGREGATE testagg1b(testdomain1); +DROP DOMAIN testdomain2b; +DROP OPERATOR !! (NONE, testdomain1); +DROP FUNCTION testfunc5b(a testdomain1); +DROP FUNCTION testfunc6b(b int); +DROP TABLE test5b; +DROP TABLE test6b; +DROP TABLE test9b; +DROP TABLE test10b; +DROP TYPE test7b; +DROP TYPE test8b; +DROP CAST (testdomain1 AS testdomain3b); +DROP FUNCTION castfunc(int) CASCADE; +DROP DOMAIN testdomain3b; +DROP TABLE test11b; + +DROP TYPE testtype1; -- ok +DROP DOMAIN testdomain1; -- ok + + -- truncate SET SESSION AUTHORIZATION regressuser5; TRUNCATE atest2; -- ok @@ -626,6 +735,21 @@ SELECT has_function_privilege('regressuser2', 'testns.foo()', 'EXECUTE'); -- yes DROP FUNCTION testns.foo(); +ALTER DEFAULT PRIVILEGES FOR ROLE regressuser1 REVOKE USAGE ON TYPES FROM public; + +CREATE DOMAIN testns.testdomain1 AS int; + +SELECT has_type_privilege('regressuser2', 'testns.testdomain1', 'USAGE'); -- no + +ALTER DEFAULT PRIVILEGES IN SCHEMA testns GRANT USAGE ON TYPES to public; + +DROP DOMAIN testns.testdomain1; +CREATE DOMAIN testns.testdomain1 AS int; + +SELECT has_type_privilege('regressuser2', 'testns.testdomain1', 'USAGE'); -- yes + +DROP DOMAIN testns.testdomain1; + RESET ROLE; SELECT count(*) |