</table>
<para>
- <function>col_description</function> returns the comment for a table column,
- which is specified by the OID of its table and its column number.
- <function>obj_description</function> cannot be used for table columns since
- columns do not have OIDs of their own.
+ <function>col_description</function> returns the comment for a table
+ column, which is specified by the OID of its table and its column number.
+ (<function>obj_description</function> cannot be used for table columns
+ since columns do not have OIDs of their own.)
</para>
<para>
<function>shobj_description</function> is used just like
<function>obj_description</function> except it is used for retrieving
comments on shared objects. Some system catalogs are global to all
- databases within each cluster and their descriptions are stored globally
- as well.
+ databases within each cluster, and the descriptions for objects in them
+ are stored globally as well.
</para>
<indexterm>
</para>
<para>
- To modify a comment, issue a new <command>COMMENT</> command for the
- same object. Only one comment string is stored for each object.
- To remove a comment, write <literal>NULL</literal> in place of the text
- string.
- Comments are automatically dropped when the object is dropped.
+ Only one comment string is stored for each object, so to modify a comment,
+ issue a new <command>COMMENT</> command for the same object. To remove a
+ comment, write <literal>NULL</literal> in place of the text string.
+ Comments are automatically dropped when their object is dropped.
+ </para>
+
+ <para>
+ For most kinds of object, only the object's owner can set the comment.
+ Roles don't have owners, so the rule for <literal>COMMENT ON ROLE</> is
+ that you must be superuser to comment on a superuser role, or have the
+ <literal>CREATEROLE</> privilege to comment on non-superuser roles.
+ Of course, a superuser can comment on anything.
</para>
<para>
<term><replaceable class="parameter">agg_name</replaceable></term>
<term><replaceable class="parameter">constraint_name</replaceable></term>
<term><replaceable class="parameter">function_name</replaceable></term>
- <term><replaceable class="parameter">op</replaceable></term>
+ <term><replaceable class="parameter">operator_name</replaceable></term>
<term><replaceable class="parameter">rule_name</replaceable></term>
<term><replaceable class="parameter">trigger_name</replaceable></term>
<listitem>
<para>
The name of the object to be commented. Names of tables,
- aggregates, domains, foreign tables, functions, indexes, operators,
- operator classes, operator families, sequences, text search objects,
- types, and views can be schema-qualified.
+ aggregates, collations, conversions, domains, foreign tables, functions,
+ indexes, operators, operator classes, operator families, sequences,
+ text search objects, types, and views can be schema-qualified.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">argmode</replaceable></term>
-
<listitem>
<para>
The mode of a function argument: <literal>IN</>, <literal>OUT</>,
<varlistentry>
<term><replaceable class="parameter">argname</replaceable></term>
-
<listitem>
<para>
The name of a function argument.
<varlistentry>
<term><replaceable class="parameter">argtype</replaceable></term>
-
<listitem>
<para>
The data type(s) of the function's arguments (optionally
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><replaceable class="parameter">left_type</replaceable></term>
+ <term><replaceable class="parameter">right_type</replaceable></term>
+ <listitem>
+ <para>
+ The data type(s) of the operator's arguments (optionally
+ schema-qualified). Write <literal>NONE</> for the missing argument
+ of a prefix or postfix operator.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><literal>PROCEDURAL</literal></term>
-
<listitem>
<para>
This is a noise word.
<title>Notes</title>
<para>
- There is presently no security mechanism for comments: any user
+ There is presently no security mechanism for viewing comments: any user
connected to a database can see all the comments for objects in
- that database (although only superusers can change comments for
- objects that they don't own). For shared objects such as
- databases, roles, and tablespaces comments are stored globally
- and any user connected to any database can see all the comments
+ that database. For shared objects such as
+ databases, roles, and tablespaces, comments are stored globally so any
+ user connected to any database in the cluster can see all the comments
for shared objects. Therefore, don't put security-critical
information in comments.
</para>
COMMENT ON LANGUAGE plpython IS 'Python support for stored procedures';
COMMENT ON LARGE OBJECT 346344 IS 'Planning document';
COMMENT ON OPERATOR ^ (text, text) IS 'Performs intersection of two texts';
-COMMENT ON OPERATOR - (NONE, text) IS 'This is a prefix operator on text';
+COMMENT ON OPERATOR - (NONE, integer) IS 'Unary minus';
COMMENT ON OPERATOR CLASS int4ops USING btree IS '4 byte integer operators for btrees';
COMMENT ON OPERATOR FAMILY integer_ops USING btree IS 'all integer operators for btrees';
COMMENT ON ROLE my_role IS 'Administration group for finance tables';
return has_privs_of_role(roleid, ownerId);
}
+/*
+ * Check whether specified role has CREATEROLE privilege (or is a superuser)
+ *
+ * Note: roles do not have owners per se; instead we use this test in
+ * places where an ownership-like permissions test is needed for a role.
+ * Be sure to apply it to the role trying to do the operation, not the
+ * role being operated on! Also note that this generally should not be
+ * considered enough privilege if the target role is a superuser.
+ * (We don't handle that consideration here because we want to give a
+ * separate error message for such cases, so the caller has to deal with it.)
+ */
+bool
+has_createrole_privilege(Oid roleid)
+{
+ bool result = false;
+ HeapTuple utup;
+
+ /* Superusers bypass all permission checking. */
+ if (superuser_arg(roleid))
+ return true;
+
+ utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid));
+ if (HeapTupleIsValid(utup))
+ {
+ result = ((Form_pg_authid) GETSTRUCT(utup))->rolcreaterole;
+ ReleaseSysCache(utup);
+ }
+ return result;
+}
+
/*
* Fetch pg_default_acl entry for given role, namespace and object type
* (object type must be given in pg_default_acl's encoding).
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TABLESPACE,
NameListToString(objname));
break;
- case OBJECT_ROLE:
- if (!has_privs_of_role(roleid, address.objectId))
- ereport(ERROR,
- (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("must be member of role \"%s\"",
- NameListToString(objname))));
- break;
case OBJECT_TSDICTIONARY:
if (!pg_ts_dict_ownercheck(address.objectId, roleid))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSDICTIONARY,
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSCONFIGURATION,
NameListToString(objname));
break;
+ case OBJECT_ROLE:
+ /*
+ * We treat roles as being "owned" by those with CREATEROLE priv,
+ * except that superusers are only owned by superusers.
+ */
+ if (superuser_arg(address.objectId))
+ {
+ if (!superuser_arg(roleid))
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("must be superuser")));
+ }
+ else
+ {
+ if (!has_createrole_privilege(roleid))
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("must have CREATEROLE privilege")));
+ }
+ break;
case OBJECT_FDW:
case OBJECT_TSPARSER:
case OBJECT_TSTEMPLATE: