Add support for privileges on types

This adds support for the more or less SQL-conforming USAGE privilege
on types and domains.  The intent is to be able restrict which users
can create dependencies on types, which restricts the way in which
owners can alter types.

reviewed by Yeb Havinga
This commit is contained in:
Peter Eisentraut 2011-12-20 00:05:19 +02:00
parent 05e992e90e
commit 729205571e
41 changed files with 1249 additions and 201 deletions

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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">

View File

@ -42,6 +42,10 @@ GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] }
ON DATABASE <replaceable>database_name</replaceable> [, ...]
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>
@ -335,6 +343,15 @@ GRANT <replaceable class="PARAMETER">role_name</replaceable> [, ...] TO <replace
For sequences, this privilege allows the use of the
<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.
@ -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>

View File

@ -1048,7 +1048,7 @@ testdb=&gt;
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=&gt;
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.

View File

@ -50,6 +50,12 @@ REVOKE [ GRANT OPTION FOR ]
FROM { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]
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> [, ...]
@ -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 ]

View File

@ -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);

View File

@ -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);
@ -3971,6 +4152,80 @@ pg_foreign_server_aclmask(Oid srv_oid, Oid roleid,
return result;
}
/*
* 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
*
@ -4204,6 +4459,18 @@ pg_foreign_server_aclcheck(Oid srv_oid, Oid roleid, AclMode mode)
return ACLCHECK_NO_PRIV;
}
/*
* 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).
*/
@ -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;
}

View File

@ -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;

View File

@ -71,6 +71,7 @@ AggregateCreate(const char *aggName,
int i;
ObjectAddress myself,
referenced;
AclResult aclresult;
/* sanity checks (caller should have caught these) */
if (!aggName)
@ -200,6 +201,28 @@ AggregateCreate(const char *aggName,
false, -1);
}
/*
* 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.)

View File

@ -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.
*

View File

@ -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;

View File

@ -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
*/

View File

@ -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);

View File

@ -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
*/

View File

@ -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

View File

@ -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; }
;

View File

@ -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 */
@ -4126,6 +4133,206 @@ convert_tablespace_priv_string(text *priv_type_text)
return convert_any_priv_string(priv_type_text, tablespace_priv_map);
}
/*
* 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.

View File

@ -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"

View File

@ -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

View File

@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 201112191
#define CATALOG_VERSION_NO 201112192
#endif

View File

@ -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("");

View File

@ -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 */

View File

@ -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_ ));

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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(*)