<!--
doc/src/sgml/ref/rollback_to.sgml
PostgreSQL documentation
-->

<refentry id="sql-rollback-to">
 <indexterm zone="sql-rollback-to">
  <primary>ROLLBACK TO SAVEPOINT</primary>
 </indexterm>

 <indexterm zone="sql-rollback-to">
  <primary>savepoints</primary>
  <secondary>rolling back</secondary>
 </indexterm>

 <refmeta>
  <refentrytitle>ROLLBACK TO SAVEPOINT</refentrytitle>
  <manvolnum>7</manvolnum>
  <refmiscinfo>SQL - Language Statements</refmiscinfo>
 </refmeta>

 <refnamediv>
  <refname>ROLLBACK TO SAVEPOINT</refname>
  <refpurpose>roll back to a savepoint</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] <replaceable>savepoint_name</replaceable>
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   Roll back all commands that were executed after the savepoint was
   established.  The savepoint remains valid and can be rolled back to
   again later, if needed.
  </para>

  <para>
   <command>ROLLBACK TO SAVEPOINT</command> implicitly destroys all savepoints that
   were established after the named savepoint.
  </para>
 </refsect1>

 <refsect1>
  <title>Parameters</title>

  <variablelist>
   <varlistentry>
    <term><replaceable class="parameter">savepoint_name</replaceable></term>
    <listitem>
     <para>
      The savepoint to roll back to.
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Notes</title>

  <para>
   Use <link linkend="sql-release-savepoint"><command>RELEASE SAVEPOINT</command></link> to destroy a savepoint
   without discarding the effects of commands executed after it was
   established.
  </para>

  <para>
   Specifying a savepoint name that has not been established is an error.
  </para>

  <para>
   Cursors have somewhat non-transactional behavior with respect to
   savepoints.  Any cursor that is opened inside a savepoint will be closed
   when the savepoint is rolled back.  If a previously opened cursor is
   affected by a <command>FETCH</command> or <command>MOVE</command> command inside a
   savepoint that is later rolled back, the cursor remains at the
   position that <command>FETCH</command> left it pointing to (that is, the cursor
   motion caused by <command>FETCH</command> is not rolled back).
   Closing a cursor is not undone by rolling back, either.
   However, other side-effects caused by the cursor's query (such as
   side-effects of volatile functions called by the query) <emphasis>are</emphasis>
   rolled back if they occur during a savepoint that is later rolled back.
   A cursor whose execution causes a transaction to abort is put in a
   cannot-execute state, so while the transaction can be restored using
   <command>ROLLBACK TO SAVEPOINT</command>, the cursor can no longer be used.
  </para>
 </refsect1>

 <refsect1>
  <title>Examples</title>

  <para>
   To undo the effects of the commands executed after <literal>my_savepoint</literal>
   was established:
<programlisting>
ROLLBACK TO SAVEPOINT my_savepoint;
</programlisting>
  </para>

  <para>
   Cursor positions are not affected by savepoint rollback:
<programlisting>
BEGIN;

DECLARE foo CURSOR FOR SELECT 1 UNION SELECT 2;

SAVEPOINT foo;

FETCH 1 FROM foo;
 ?column? 
----------
        1

ROLLBACK TO SAVEPOINT foo;

FETCH 1 FROM foo;
 ?column? 
----------
        2

COMMIT;
</programlisting></para>


 </refsect1>

 <refsect1>
  <title>Compatibility</title>

  <para>
   The <acronym>SQL</acronym> standard specifies that the key word
   <literal>SAVEPOINT</literal> is mandatory, but <productname>PostgreSQL</productname>
   and <productname>Oracle</productname> allow it to be omitted.  SQL allows
   only <literal>WORK</literal>, not <literal>TRANSACTION</literal>, as a noise word
   after <literal>ROLLBACK</literal>.  Also, SQL has an optional clause
   <literal>AND [ NO ] CHAIN</literal> which is not currently supported by
   <productname>PostgreSQL</productname>.  Otherwise, this command conforms to
   the SQL standard.
  </para>
 </refsect1>

 <refsect1>
  <title>See Also</title>

  <simplelist type="inline">
   <member><xref linkend="sql-begin"/></member>
   <member><xref linkend="sql-commit"/></member>
   <member><xref linkend="sql-release-savepoint"/></member>
   <member><xref linkend="sql-rollback"/></member>
   <member><xref linkend="sql-savepoint"/></member>
  </simplelist>
 </refsect1>
</refentry>
