Home Explore Blog CI



postgresql

9th chunk of `doc/src/sgml/rules.sgml`
3047890388df049f34a96445acb99d5284bc9a647da8a99c0000000100000fa1
     WHERE sh.slunit = un.un_name) rsh,
               (SELECT s.sl_name,
                       s.sl_avail,
                       s.sl_color,
                       s.sl_len,
                       s.sl_unit,
                       s.sl_len * u.un_fact AS sl_len_cm
                  FROM shoelace_data s, unit u
                 WHERE s.sl_unit = u.un_name) rsl
         WHERE rsl.sl_color = rsh.slcolor
           AND rsl.sl_len_cm >= rsh.slminlen_cm
           AND rsl.sl_len_cm <= rsh.slmaxlen_cm) shoe_ready
 WHERE shoe_ready.total_avail > 2;
</programlisting>
   </para>

   <para>
    This might look inefficient, but the planner will collapse this into a
    single-level query tree by <quote>pulling up</quote> the subqueries,
    and then it will plan the joins just as if we'd written them out
    manually.  So collapsing the query tree is an optimization that the
    rewrite system doesn't have to concern itself with.
   </para>
</sect2>

<sect2 id="rules-views-non-select">
<title>View Rules in Non-<command>SELECT</command> Statements</title>

<para>
    Two details of the query tree aren't touched in the description of
    view rules above. These are the command type and the result relation.
    In fact, the command type is not needed by view rules, but the result
    relation may affect the way in which the query rewriter works, because
    special care needs to be taken if the result relation is a view.
</para>

<para>
    There are only a few differences between a query tree for a
    <command>SELECT</command> and one for any other
    command. Obviously, they have a different command type and for a
    command other than a <command>SELECT</command>, the result
    relation points to the range-table entry where the result should
    go.  Everything else is absolutely the same.  So having two tables
    <literal>t1</literal> and <literal>t2</literal> with columns <literal>a</literal> and
    <literal>b</literal>, the query trees for the two statements:

<programlisting>
SELECT t2.b FROM t1, t2 WHERE t1.a = t2.a;

UPDATE t1 SET b = t2.b FROM t2 WHERE t1.a = t2.a;
</programlisting>

    are nearly identical.  In particular:

    <itemizedlist>
        <listitem>
        <para>
            The range tables contain entries for the tables <literal>t1</literal> and <literal>t2</literal>.
        </para>
        </listitem>

        <listitem>
        <para>
            The target lists contain one variable that points to column
            <literal>b</literal> of the range table entry for table <literal>t2</literal>.
        </para>
        </listitem>

        <listitem>
        <para>
            The qualification expressions compare the columns <literal>a</literal> of both
            range-table entries for equality.
        </para>
        </listitem>

        <listitem>
        <para>
            The join trees show a simple join between <literal>t1</literal> and <literal>t2</literal>.
        </para>
        </listitem>
    </itemizedlist>
   </para>

   <para>
    The consequence is, that both query trees result in similar
    execution plans: They are both joins over the two tables. For the
    <command>UPDATE</command> the missing columns from <literal>t1</literal> are added to
    the target list by the planner and the final query tree will read
    as:

<programlisting>
UPDATE t1 SET a = t1.a, b = t2.b FROM t2 WHERE t1.a = t2.a;
</programlisting>

    and thus the executor run over the join will produce exactly the
    same result set as:

<programlisting>
SELECT t1.a, t2.b FROM t1, t2 WHERE t1.a = t2.a;
</programlisting>

    But there is a little problem in
    <command>UPDATE</command>: the part of the executor plan that does
    the join does not care what the results from the join are
    meant for. It just produces a result set of rows. The fact that
    one is a <command>SELECT</command> command and the other is an
    <command>UPDATE</command> is handled higher up in the executor, where
    it knows

Title: View Rules in Non-SELECT Statements
Summary
This section discusses how view rules are applied in non-SELECT statements, such as UPDATE commands. It explains that the query tree for a non-SELECT statement is similar to that of a SELECT statement, with the main difference being the command type and the result relation. The section also highlights the challenges of handling UPDATE commands, where the executor plan must be modified to include all columns of the updated table, not just the ones specified in the UPDATE statement.