@@ -1387,11 +1387,11 @@ EXECUTE format('UPDATE tbl SET %I = $1 WHERE key = $2', colname)
13871387 command, which has the form:
13881388
13891389<synopsis>
1390- GET DIAGNOSTICS <replaceable>variable</replaceable> = <replaceable>item</replaceable> <optional> , ... </optional>;
1390+ GET<optional> CURRENT </optional> DIAGNOSTICS <replaceable>variable</replaceable> = <replaceable>item</replaceable> <optional> , ... </optional>;
13911391</synopsis>
13921392
13931393 This command allows retrieval of system status indicators. Each
1394- <replaceable>item</replaceable> is a key word identifying astate
1394+ <replaceable>item</replaceable> is a key word identifying astatus
13951395 value to be assigned to the specified variable (which should be
13961396 of the right data type to receive it). The currently available
13971397 status items are <varname>ROW_COUNT</>, the number of rows
@@ -2522,16 +2522,6 @@ END;
25222522 </para>
25232523 </tip>
25242524
2525- <para>
2526- Within an exception handler, the <varname>SQLSTATE</varname>
2527- variable contains the error code that corresponds to the
2528- exception that was raised (refer to <xref
2529- linkend="errcodes-table"> for a list of possible error
2530- codes). The <varname>SQLERRM</varname> variable contains the
2531- error message associated with the exception. These variables are
2532- undefined outside exception handlers.
2533- </para>
2534-
25352525 <example id="plpgsql-upsert-example">
25362526 <title>Exceptions with <command>UPDATE</>/<command>INSERT</></title>
25372527 <para>
@@ -2568,11 +2558,112 @@ LANGUAGE plpgsql;
25682558SELECT merge_db(1, 'david');
25692559SELECT merge_db(1, 'dennis');
25702560</programlisting>
2571- This example assumes the <literal>unique_violation</> error is caused by
2572- the <command>INSERT</>, and not by an <command>INSERT</> trigger function
2573- on the table.
2561+
2562+ This coding assumes the <literal>unique_violation</> error is caused by
2563+ the <command>INSERT</>, and not by, say, an <command>INSERT</> in a
2564+ trigger function on the table. More safety could be had by using the
2565+ features discussed next to check that the trapped error was the one
2566+ expected.
25742567 </para>
25752568 </example>
2569+
2570+ <sect3 id="plpgsql-exception-diagnostics">
2571+ <title>Obtaining information about an error</title>
2572+
2573+ <para>
2574+ Exception handlers frequently need to identify the specific error that
2575+ occurred. There are two ways to get information about the current
2576+ exception in <application>PL/pgSQL</>: special variables and the
2577+ <command>GET STACKED DIAGNOSTICS</command> command.
2578+ </para>
2579+
2580+ <para>
2581+ Within an exception handler, the special variable
2582+ <varname>SQLSTATE</varname> contains the error code that corresponds to
2583+ the exception that was raised (refer to <xref linkend="errcodes-table">
2584+ for a list of possible error codes). The special variable
2585+ <varname>SQLERRM</varname> contains the error message associated with the
2586+ exception. These variables are undefined outside exception handlers.
2587+ </para>
2588+
2589+ <para>
2590+ Within an exception handler, one may also retrieve
2591+ information about the current exception by using the
2592+ <command>GET STACKED DIAGNOSTICS</command> command, which has the form:
2593+
2594+ <synopsis>
2595+ GET STACKED DIAGNOSTICS <replaceable>variable</replaceable> = <replaceable>item</replaceable> <optional> , ... </optional>;
2596+ </synopsis>
2597+
2598+ Each <replaceable>item</replaceable> is a key word identifying a status
2599+ value to be assigned to the specified variable (which should be
2600+ of the right data type to receive it). The currently available
2601+ status items are:
2602+
2603+ <table id="plpgsql-exception-diagnostics-values">
2604+ <title>Error diagnostics values</title>
2605+ <tgroup cols="3">
2606+ <thead>
2607+ <row>
2608+ <entry>Name</entry>
2609+ <entry>Type</entry>
2610+ <entry>Description</entry>
2611+ </row>
2612+ </thead>
2613+ <tbody>
2614+ <row>
2615+ <entry><literal>RETURNED_SQLSTATE</literal></entry>
2616+ <entry>text</entry>
2617+ <entry>the SQLSTATE error code of the exception</entry>
2618+ </row>
2619+ <row>
2620+ <entry><literal>MESSAGE_TEXT</literal></entry>
2621+ <entry>text</entry>
2622+ <entry>the text of the exception's primary message</entry>
2623+ </row>
2624+ <row>
2625+ <entry><literal>PG_EXCEPTION_DETAIL</literal></entry>
2626+ <entry>text</entry>
2627+ <entry>the text of the exception's detail message, if any</entry>
2628+ </row>
2629+ <row>
2630+ <entry><literal>PG_EXCEPTION_HINT</literal></entry>
2631+ <entry>text</entry>
2632+ <entry>the text of the exception's hint message, if any</entry>
2633+ </row>
2634+ <row>
2635+ <entry><literal>PG_EXCEPTION_CONTEXT</literal></entry>
2636+ <entry>text</entry>
2637+ <entry>line(s) of text describing the call stack</entry>
2638+ </row>
2639+ </tbody>
2640+ </tgroup>
2641+ </table>
2642+ </para>
2643+
2644+ <para>
2645+ If the exception did not set a value for an item, an empty string
2646+ will be returned.
2647+ </para>
2648+
2649+ <para>
2650+ Here is an example:
2651+ <programlisting>
2652+ DECLARE
2653+ text_var1 text;
2654+ text_var2 text;
2655+ text_var3 text;
2656+ BEGIN
2657+ -- some processing which might cause an exception
2658+ ...
2659+ EXCEPTION WHEN OTHERS THEN
2660+ GET STACKED DIAGNOSTICS text_var1 = MESSAGE_TEXT,
2661+ text_var2 = PG_EXCEPTION_DETAIL,
2662+ text_var3 = PG_EXCEPTION_HINT;
2663+ END;
2664+ </programlisting>
2665+ </para>
2666+ </sect3>
25762667 </sect2>
25772668 </sect1>
25782669