expression, there is a
special provision: you must write
<synopsis>
<literal>OPERATOR(</literal><replaceable>schema</replaceable><literal>.</literal><replaceable>operator</replaceable><literal>)</literal>
</synopsis>
This is needed to avoid syntactic ambiguity. An example is:
<programlisting>
SELECT 3 OPERATOR(pg_catalog.+) 4;
</programlisting>
In practice one usually relies on the search path for operators,
so as not to have to write anything so ugly as that.
</para>
</sect2>
<sect2 id="ddl-schemas-priv">
<title>Schemas and Privileges</title>
<indexterm zone="ddl-schemas-priv">
<primary>privilege</primary>
<secondary sortas="schemas">for schemas</secondary>
</indexterm>
<para>
By default, users cannot access any objects in schemas they do not
own. To allow that, the owner of the schema must grant the
<literal>USAGE</literal> privilege on the schema. By default, everyone
has that privilege on the schema <literal>public</literal>. To allow
users to make use of the objects in a schema, additional privileges might
need to be granted, as appropriate for the object.
</para>
<para>
A user can also be allowed to create objects in someone else's schema. To
allow that, the <literal>CREATE</literal> privilege on the schema needs to
be granted. In databases upgraded from
<productname>PostgreSQL</productname> 14 or earlier, everyone has that
privilege on the schema <literal>public</literal>.
Some <link linkend="ddl-schemas-patterns">usage patterns</link> call for
revoking that privilege:
<programlisting>
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
</programlisting>
(The first <quote>public</quote> is the schema, the second
<quote>public</quote> means <quote>every user</quote>. In the
first sense it is an identifier, in the second sense it is a
key word, hence the different capitalization; recall the
guidelines from <xref linkend="sql-syntax-identifiers"/>.)
</para>
</sect2>
<sect2 id="ddl-schemas-catalog">
<title>The System Catalog Schema</title>
<indexterm zone="ddl-schemas-catalog">
<primary>system catalog</primary>
<secondary>schema</secondary>
</indexterm>
<para>
In addition to <literal>public</literal> and user-created schemas, each
database contains a <literal>pg_catalog</literal> schema, which contains
the system tables and all the built-in data types, functions, and
operators. <literal>pg_catalog</literal> is always effectively part of
the search path. If it is not named explicitly in the path then
it is implicitly searched <emphasis>before</emphasis> searching the path's
schemas. This ensures that built-in names will always be
findable. However, you can explicitly place
<literal>pg_catalog</literal> at the end of your search path if you
prefer to have user-defined names override built-in names.
</para>
<para>
Since system table names begin with <literal>pg_</literal>, it is best to
avoid such names to ensure that you won't suffer a conflict if some
future version defines a system table named the same as your
table. (With the default search path, an unqualified reference to
your table name would then be resolved as the system table instead.)
System tables will continue to follow the convention of having
names beginning with <literal>pg_</literal>, so that they will not
conflict with unqualified user-table names so long as users avoid
the <literal>pg_</literal> prefix.
</para>
</sect2>
<sect2 id="ddl-schemas-patterns">
<title>Usage Patterns</title>
<para>
Schemas can be used to organize your data in many ways.
A <firstterm>secure schema usage pattern</firstterm> prevents untrusted
users from changing the behavior of other users' queries. When a database
does not use a secure schema usage pattern, users wishing to securely
query that database would take