<literal>INSTEAD OF</literal>
triggers, then the <literal>LOCAL CHECK OPTION</literal> may be used to check
the conditions on the automatically updatable view, but the conditions
on the base view with <literal>INSTEAD OF</literal> triggers will not be
checked (a cascaded check option will not cascade down to a
trigger-updatable view, and any check options defined directly on a
trigger-updatable view will be ignored). If the view or any of its base
relations has an <literal>INSTEAD</literal> rule that causes the
<command>INSERT</command> or <command>UPDATE</command> command to be rewritten, then
all check options will be ignored in the rewritten query, including any
checks from automatically updatable views defined on top of the relation
with the <literal>INSTEAD</literal> rule. <command>MERGE</command> is not
supported if the view or any of its base relations have rules.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Notes</title>
<para>
Use the <link linkend="sql-dropview"><command>DROP VIEW</command></link>
statement to drop views.
</para>
<para>
Be careful that the names and types of the view's columns will be
assigned the way you want. For example:
<programlisting>
CREATE VIEW vista AS SELECT 'Hello World';
</programlisting>
is bad form because the column name defaults to <literal>?column?</literal>;
also, the column data type defaults to <type>text</type>, which might not
be what you wanted. Better style for a string literal in a view's
result is something like:
<programlisting>
CREATE VIEW vista AS SELECT text 'Hello World' AS hello;
</programlisting>
</para>
<para>
By default, access to the underlying base relations referenced in the view
is determined by the permissions of the view owner. In some cases, this
can be used to provide secure but restricted access to the underlying
tables. However, not all views are secure against tampering; see <xref
linkend="rules-privileges"/> for details.
</para>
<para>
If the view has the <literal>security_invoker</literal> property set to
<literal>true</literal>, access to the underlying base relations is
determined by the permissions of the user executing the query, rather than
the view owner. Thus, the user of a security invoker view must have the
relevant permissions on the view and its underlying base relations.
</para>
<para>
If any of the underlying base relations is a security invoker view, it
will be treated as if it had been accessed directly from the original
query. Thus, a security invoker view will always check its underlying
base relations using the permissions of the current user, even if it is
accessed from a view without the <literal>security_invoker</literal>
property.
</para>
<para>
If any of the underlying base relations has
<link linkend="ddl-rowsecurity">row-level security</link> enabled, then
by default, the row-level security policies of the view owner are applied,
and access to any additional relations referred to by those policies is
determined by the permissions of the view owner. However, if the view has
<literal>security_invoker</literal> set to <literal>true</literal>, then
the policies and permissions of the invoking user are used instead, as if
the base relations had been referenced directly from the query using the
view.
</para>
<para>
Functions called in the view are treated the same as if they had been
called directly from the query using the view. Therefore, the user of
a view must have permissions to call all functions used by the view.
Functions in the view are executed with the privileges of the user
executing the query or the function owner, depending on whether the
functions are defined as <literal>SECURITY INVOKER</literal>