Home Explore Blog CI



postgresql

2nd chunk of `doc/src/sgml/ref/create_rule.sgml`
60c00c90649185ef855d23f43ee966fd83034df01eb63f230000000100000fa5
 <para>
   You can create the illusion of an updatable view by defining
   <literal>ON INSERT</literal>, <literal>ON UPDATE</literal>, and
   <literal>ON DELETE</literal> rules (or any subset of those that's
   sufficient for your purposes) to replace update actions on the view
   with appropriate updates on other tables.  If you want to support
   <command>INSERT RETURNING</command> and so on, then be sure to put a suitable
   <literal>RETURNING</literal> clause into each of these rules.
  </para>

  <para>
   There is a catch if you try to use conditional rules for complex view
   updates: there <emphasis>must</emphasis> be an unconditional
   <literal>INSTEAD</literal> rule for each action you wish to allow
   on the view.  If the rule is conditional, or is not
   <literal>INSTEAD</literal>, then the system will still reject
   attempts to perform the update action, because it thinks it might
   end up trying to perform the action on the dummy table of the view
   in some cases.  If you want to handle all the useful cases in
   conditional rules, add an unconditional <literal>DO
   INSTEAD NOTHING</literal> rule to ensure that the system
   understands it will never be called on to update the dummy table.
   Then make the conditional rules non-<literal>INSTEAD</literal>; in
   the cases where they are applied, they add to the default
   <literal>INSTEAD NOTHING</literal> action.  (This method does not
   currently work to support <literal>RETURNING</literal> queries, however.)
  </para>

  <note>
   <para>
    A view that is simple enough to be automatically updatable (see <xref
    linkend="sql-createview"/>) does not require a user-created rule in
    order to be updatable.  While you can create an explicit rule anyway,
    the automatic update transformation will generally outperform an
    explicit rule.
   </para>

   <para>
    Another alternative worth considering is to use <literal>INSTEAD OF</literal>
    triggers (see <xref linkend="sql-createtrigger"/>) in place of rules.
   </para>
  </note>
 </refsect1>

 <refsect1>
  <title>Parameters</title>

  <variablelist>
   <varlistentry>
    <term><replaceable class="parameter">name</replaceable></term>
    <listitem>
     <para>
      The name of a rule to create.  This must be distinct from the
      name of any other rule for the same table.  Multiple rules on
      the same table and same event type are applied in alphabetical
      name order.
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><replaceable class="parameter">event</replaceable></term>
    <listitem>
     <para>
      The event is one of <literal>SELECT</literal>,
      <literal>INSERT</literal>, <literal>UPDATE</literal>, or
      <literal>DELETE</literal>.  Note that an
      <command>INSERT</command> containing an <literal>ON
      CONFLICT</literal> clause cannot be used on tables that have
      either <literal>INSERT</literal> or <literal>UPDATE</literal>
      rules.  Consider using an updatable view instead.
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><replaceable class="parameter">table_name</replaceable></term>
    <listitem>
     <para>
      The name (optionally schema-qualified) of the table or view the
      rule applies to.
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><replaceable class="parameter">condition</replaceable></term>
    <listitem>
     <para>
      Any <acronym>SQL</acronym> conditional expression (returning
      <type>boolean</type>).  The condition expression cannot refer
      to any tables except <literal>NEW</literal> and <literal>OLD</literal>, and
      cannot contain aggregate functions.
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><option>INSTEAD</option></term>
    <listitem>
     <para><literal>INSTEAD</literal> indicates that the commands should be
      executed <emphasis>instead of</emphasis> the original command.
     </para>
    </listitem>

Title: Conditional Rules, Alternatives to Rules, and Parameters for CREATE RULE
Summary
Conditional rules for complex view updates require an unconditional INSTEAD rule for each allowed action. If using conditional rules, include a 'DO INSTEAD NOTHING' rule to prevent updates to the dummy view table. For simple updatable views, user-created rules aren't necessary as the automatic update transformation is more efficient. Alternatively, consider using INSTEAD OF triggers instead of rules. The parameters for CREATE RULE include the rule name, event (SELECT, INSERT, UPDATE, DELETE), table or view name, and an optional SQL condition. The INSTEAD keyword specifies that the rule's commands replace the original command.