Home Explore Blog CI



postgresql

8th chunk of `doc/src/sgml/rules.sgml`
66476d37e015b9badc4daaf222a4cc7a47571377ec4dc1e90000000100000fa3
 entries in the top query (in this example there
    are no more), and it will recursively check the range-table entries in
    the added subquery to see if any of them reference views.  (But it
    won't expand <literal>old</literal> or <literal>new</literal> &mdash; otherwise we'd have infinite recursion!)
    In this example, there are no rewrite rules for <literal>shoelace_data</literal> or <literal>unit</literal>,
    so rewriting is complete and the above is the final result given to
    the planner.
</para>

<para>
    Now we want to write a query that finds out for which shoes currently in the store
    we have the matching shoelaces (color and length) and where the
    total number of exactly matching pairs is greater than or equal to two.

<programlisting>
SELECT * FROM shoe_ready WHERE total_avail &gt;= 2;

 shoename | sh_avail | sl_name | sl_avail | total_avail
----------+----------+---------+----------+-------------
 sh1      |        2 | sl1     |        5 |           2
 sh3      |        4 | sl7     |        7 |           4
(2 rows)
</programlisting>
</para>

<para>
    The output of the parser this time is the query tree:

<programlisting>
SELECT shoe_ready.shoename, shoe_ready.sh_avail,
       shoe_ready.sl_name, shoe_ready.sl_avail,
       shoe_ready.total_avail
  FROM shoe_ready shoe_ready
 WHERE shoe_ready.total_avail &gt;= 2;
</programlisting>

    The first rule applied will be the one for the
    <literal>shoe_ready</literal> view and it results in the
    query tree:

<programlisting>
SELECT shoe_ready.shoename, shoe_ready.sh_avail,
       shoe_ready.sl_name, shoe_ready.sl_avail,
       shoe_ready.total_avail
  FROM (SELECT rsh.shoename,
               rsh.sh_avail,
               rsl.sl_name,
               rsl.sl_avail,
               least(rsh.sh_avail, rsl.sl_avail) AS total_avail
          FROM shoe rsh, shoelace rsl
         WHERE rsl.sl_color = rsh.slcolor
           AND rsl.sl_len_cm &gt;= rsh.slminlen_cm
           AND rsl.sl_len_cm &lt;= rsh.slmaxlen_cm) shoe_ready
 WHERE shoe_ready.total_avail &gt;= 2;
</programlisting>

    Similarly, the rules for <literal>shoe</literal> and
    <literal>shoelace</literal> are substituted into the range table of
    the subquery, leading to a three-level final query tree:

<programlisting>
SELECT shoe_ready.shoename, shoe_ready.sh_avail,
       shoe_ready.sl_name, shoe_ready.sl_avail,
       shoe_ready.total_avail
  FROM (SELECT rsh.shoename,
               rsh.sh_avail,
               rsl.sl_name,
               rsl.sl_avail,
               least(rsh.sh_avail, rsl.sl_avail) AS total_avail
          FROM (SELECT sh.shoename,
                       sh.sh_avail,
                       sh.slcolor,
                       sh.slminlen,
                       sh.slminlen * un.un_fact AS slminlen_cm,
                       sh.slmaxlen,
                       sh.slmaxlen * un.un_fact AS slmaxlen_cm,
                       sh.slunit
                  FROM shoe_data sh, unit un
                 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 &gt;= rsh.slminlen_cm
           AND rsl.sl_len_cm &lt;= rsh.slmaxlen_cm) shoe_ready
 WHERE shoe_ready.total_avail &gt; 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: Query Rewriting with Nested Views
Summary
This section demonstrates how the rule system in PostgreSQL rewrites queries that reference nested views, using the example of the shoe_ready view. It shows how the rewriter applies rules recursively to expand the views into subqueries, and how the final query tree is optimized by the planner to collapse the subqueries into a single-level query tree.