Home Explore Blog CI



postgresql

35th chunk of `doc/src/sgml/queries.sgml`
ec741ce99ee67d2c9076fa007f4f4a9c8f498c79a9e3df050000000100000f05
 query.  Such a statement will be executed nonetheless.
    A not-particularly-useful example is:

<programlisting>
WITH t AS (
    DELETE FROM foo
)
DELETE FROM bar;
</programlisting>

    This example would remove all rows from tables <structname>foo</structname> and
    <structname>bar</structname>.  The number of affected rows reported to the client
    would only include rows removed from <structname>bar</structname>.
   </para>

   <para>
    Recursive self-references in data-modifying statements are not
    allowed.  In some cases it is possible to work around this limitation by
    referring to the output of a recursive <literal>WITH</literal>, for example:

<programlisting>
WITH RECURSIVE included_parts(sub_part, part) AS (
    SELECT sub_part, part FROM parts WHERE part = 'our_product'
  UNION ALL
    SELECT p.sub_part, p.part
    FROM included_parts pr, parts p
    WHERE p.part = pr.sub_part
)
DELETE FROM parts
  WHERE part IN (SELECT part FROM included_parts);
</programlisting>

    This query would remove all direct and indirect subparts of a product.
   </para>

   <para>
    Data-modifying statements in <literal>WITH</literal> are executed exactly once,
    and always to completion, independently of whether the primary query
    reads all (or indeed any) of their output.  Notice that this is different
    from the rule for <command>SELECT</command> in <literal>WITH</literal>: as stated in the
    previous section, execution of a <command>SELECT</command> is carried only as far
    as the primary query demands its output.
   </para>

   <para>
    The sub-statements in <literal>WITH</literal> are executed concurrently with
    each other and with the main query.  Therefore, when using data-modifying
    statements in <literal>WITH</literal>, the order in which the specified updates
    actually happen is unpredictable.  All the statements are executed with
    the same <firstterm>snapshot</firstterm> (see <xref linkend="mvcc"/>), so they
    cannot <quote>see</quote> one another's effects on the target tables.  This
    alleviates the effects of the unpredictability of the actual order of row
    updates, and means that <literal>RETURNING</literal> data is the only way to
    communicate changes between different <literal>WITH</literal> sub-statements and
    the main query.  An example of this is that in

<programlisting>
WITH t AS (
    UPDATE products SET price = price * 1.05
    RETURNING *
)
SELECT * FROM products;
</programlisting>

    the outer <command>SELECT</command> would return the original prices before the
    action of the <command>UPDATE</command>, while in

<programlisting>
WITH t AS (
    UPDATE products SET price = price * 1.05
    RETURNING *
)
SELECT * FROM t;
</programlisting>

    the outer <command>SELECT</command> would return the updated data.
   </para>

   <para>
    Trying to update the same row twice in a single statement is not
    supported.  Only one of the modifications takes place, but it is not easy
    (and sometimes not possible) to reliably predict which one.  This also
    applies to deleting a row that was already updated in the same statement:
    only the update is performed.  Therefore you should generally avoid trying
    to modify a single row twice in a single statement.  In particular avoid
    writing <literal>WITH</literal> sub-statements that could affect the same rows
    changed by the main statement or a sibling sub-statement.  The effects
    of such a statement will not be predictable.
   </para>

   <para>
    At present, any table used as the target of a data-modifying statement in
    <literal>WITH</literal> must not have a conditional rule, nor an <literal>ALSO</literal>
    rule, nor an <literal>INSTEAD</literal> rule that expands to multiple statements.
   </para>

  </sect2>

 </sect1>

</chapter>

Title: Data-Modifying Statements in WITH Clauses: Execution and Limitations
Summary
This section discusses the behavior and limitations of data-modifying statements in WITH clauses. It explains that these statements are executed exactly once, regardless of whether the primary query uses their output. The text emphasizes that the execution order of WITH sub-statements is unpredictable, as they run concurrently with each other and the main query. All statements use the same snapshot, preventing them from seeing each other's effects on target tables. The section warns against updating the same row twice in a single statement, as the outcome is unpredictable. It also notes that tables used as targets in data-modifying WITH statements must not have conditional rules, ALSO rules, or INSTEAD rules that expand to multiple statements. Examples are provided to illustrate these concepts, including how to use RETURNING data to communicate changes between WITH sub-statements and the main query.