Commit c892643a authored by Tom Lane's avatar Tom Lane

Code review for SELECT INTO STRICT patch: use saner choices of error

SQLSTATEs, fix some documentation problems.
parent 3ba3e6c8
<!-- $PostgreSQL: pgsql/doc/src/sgml/errcodes.sgml,v 1.19 2006/06/16 22:41:45 tgl Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/errcodes.sgml,v 1.20 2006/06/16 23:29:26 tgl Exp $ -->
<appendix id="errcodes-appendix"> <appendix id="errcodes-appendix">
<title><productname>PostgreSQL</productname> Error Codes</title> <title><productname>PostgreSQL</productname> Error Codes</title>
...@@ -1344,6 +1344,18 @@ ...@@ -1344,6 +1344,18 @@
<entry>raise_exception</entry> <entry>raise_exception</entry>
</row> </row>
<row>
<entry><literal>P0002</literal></entry>
<entry>NO DATA FOUND</entry>
<entry>no_data_found</entry>
</row>
<row>
<entry><literal>P0003</literal></entry>
<entry>TOO MANY ROWS</entry>
<entry>too_many_rows</entry>
</row>
<row> <row>
<entry spanname="span13"><emphasis role="bold">Class XX &mdash; Internal Error</></entry> <entry spanname="span13"><emphasis role="bold">Class XX &mdash; Internal Error</></entry>
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.96 2006/06/15 18:02:22 momjian Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.97 2006/06/16 23:29:26 tgl Exp $ -->
<chapter id="plpgsql"> <chapter id="plpgsql">
<title><application>PL/pgSQL</application> - <acronym>SQL</acronym> Procedural Language</title> <title><application>PL/pgSQL</application> - <acronym>SQL</acronym> Procedural Language</title>
...@@ -1076,8 +1076,8 @@ tax := subtotal * 0.06; ...@@ -1076,8 +1076,8 @@ tax := subtotal * 0.06;
</indexterm> </indexterm>
<para> <para>
The result of a <command>SELECT</command> command yielding multiple columns (but The result of a <command>SELECT</command> command yielding multiple
only one row) can be assigned to a record variable, row-type columns (but only one row) can be assigned to a record variable, row-type
variable, or list of scalar variables. This is done by: variable, or list of scalar variables. This is done by:
<synopsis> <synopsis>
...@@ -1126,23 +1126,24 @@ SELECT INTO <optional>STRICT</optional> <replaceable>target</replaceable> <repla ...@@ -1126,23 +1126,24 @@ SELECT INTO <optional>STRICT</optional> <replaceable>target</replaceable> <repla
<replaceable>target</replaceable> will be set to the first row <replaceable>target</replaceable> will be set to the first row
returned by the query, or if the query returned no rows, returned by the query, or if the query returned no rows,
null values are assigned. (Note that <quote>the first row</> is not null values are assigned. (Note that <quote>the first row</> is not
well-defined unless you've used <literal>ORDER BY</>.) well-defined unless you've used <literal>ORDER BY</>.) Any result rows
You can check the special <literal>FOUND</literal> variable to after the first row are discarded.
determine if any rows were found: You can check the special <literal>FOUND</literal> variable (see
<xref linkend="plpgsql-statements-diagnostics">) to
determine whether a row was returned:
<programlisting> <programlisting>
SELECT INTO STRICT myrec * FROM emp WHERE empname = myname; SELECT INTO myrec * FROM emp WHERE empname = myname;
IF NOT FOUND THEN IF NOT FOUND THEN
RAISE EXCEPTION 'employee % not found', myname; RAISE EXCEPTION 'employee % not found', myname;
END IF; END IF;
</programlisting> </programlisting>
<para> If the <literal>STRICT</literal> option is specified, the query must
If the <literal>STRICT</literal> option is specified, a query must
return exactly one row or a run-time error will be thrown, either return exactly one row or a run-time error will be thrown, either
<literal>NO_DATA_FOUND</> (no rows) or <literal>TOO_MANY_ROWS</> <literal>NO_DATA_FOUND</> (no rows) or <literal>TOO_MANY_ROWS</>
(more than one row). You can must use exception blocks to determine (more than one row). You can use an exception block if you wish
the number of rows generated by the query: to catch the error, for example:
<programlisting> <programlisting>
BEGIN; BEGIN;
...@@ -1154,10 +1155,16 @@ BEGIN; ...@@ -1154,10 +1155,16 @@ BEGIN;
RAISE EXCEPTION 'employee % not unique', myname; RAISE EXCEPTION 'employee % not unique', myname;
END; END;
</programlisting> </programlisting>
Only <command>SELECT INTO STRICT</command> allows you to check if more Successful execution of <command>SELECT INTO STRICT</command>
than one row was retrieved. <command>SELECT INTO STRICT</command> always sets <literal>FOUND</literal> to true.
matches Oracle's PL/SQL <command>SELECT INTO</command> behavior. </para>
<note>
<para>
<command>SELECT INTO STRICT</command> matches the behavior of
Oracle PL/SQL's <command>SELECT INTO</command> statement.
</para> </para>
</note>
</sect2> </sect2>
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* Copyright (c) 2003-2006, PostgreSQL Global Development Group * Copyright (c) 2003-2006, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/include/utils/errcodes.h,v 1.19 2006/03/05 15:59:07 momjian Exp $ * $PostgreSQL: pgsql/src/include/utils/errcodes.h,v 1.20 2006/06/16 23:29:26 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -331,6 +331,8 @@ ...@@ -331,6 +331,8 @@
/* Class P0 - PL/pgSQL Error (PostgreSQL-specific error class) */ /* Class P0 - PL/pgSQL Error (PostgreSQL-specific error class) */
#define ERRCODE_PLPGSQL_ERROR MAKE_SQLSTATE('P','0', '0','0','0') #define ERRCODE_PLPGSQL_ERROR MAKE_SQLSTATE('P','0', '0','0','0')
#define ERRCODE_RAISE_EXCEPTION MAKE_SQLSTATE('P','0', '0','0','1') #define ERRCODE_RAISE_EXCEPTION MAKE_SQLSTATE('P','0', '0','0','1')
#define ERRCODE_NO_DATA_FOUND MAKE_SQLSTATE('P','0', '0','0','2')
#define ERRCODE_TOO_MANY_ROWS MAKE_SQLSTATE('P','0', '0','0','3')
/* Class XX - Internal Error (PostgreSQL-specific error class) */ /* Class XX - Internal Error (PostgreSQL-specific error class) */
/* (this is for "can't-happen" conditions and software bugs) */ /* (this is for "can't-happen" conditions and software bugs) */
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.92 2006/06/15 18:02:22 momjian Exp $ * $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.93 2006/06/16 23:29:26 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -157,7 +157,6 @@ static void check_labels(const char *start_label, ...@@ -157,7 +157,6 @@ static void check_labels(const char *start_label,
%token K_ELSE %token K_ELSE
%token K_ELSIF %token K_ELSIF
%token K_END %token K_END
%token K_STRICT
%token K_EXCEPTION %token K_EXCEPTION
%token K_EXECUTE %token K_EXECUTE
%token K_EXIT %token K_EXIT
...@@ -187,6 +186,7 @@ static void check_labels(const char *start_label, ...@@ -187,6 +186,7 @@ static void check_labels(const char *start_label,
%token K_RETURN_NEXT %token K_RETURN_NEXT
%token K_REVERSE %token K_REVERSE
%token K_SELECT %token K_SELECT
%token K_STRICT
%token K_THEN %token K_THEN
%token K_TO %token K_TO
%token K_TYPE %token K_TYPE
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.172 2006/06/16 18:42:23 tgl Exp $ * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.173 2006/06/16 23:29:27 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1721,7 +1721,7 @@ exec_stmt_select(PLpgSQL_execstate *estate, PLpgSQL_stmt_select *stmt) ...@@ -1721,7 +1721,7 @@ exec_stmt_select(PLpgSQL_execstate *estate, PLpgSQL_stmt_select *stmt)
{ {
if (stmt->strict) if (stmt->strict)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_NO_DATA), (errcode(ERRCODE_NO_DATA_FOUND),
errmsg("query returned no rows"))); errmsg("query returned no rows")));
/* set the target to NULL(s) */ /* set the target to NULL(s) */
...@@ -1732,7 +1732,7 @@ exec_stmt_select(PLpgSQL_execstate *estate, PLpgSQL_stmt_select *stmt) ...@@ -1732,7 +1732,7 @@ exec_stmt_select(PLpgSQL_execstate *estate, PLpgSQL_stmt_select *stmt)
if (n > 1 && stmt->strict) if (n > 1 && stmt->strict)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_CARDINALITY_VIOLATION), (errcode(ERRCODE_TOO_MANY_ROWS),
errmsg("query returned more than one row"))); errmsg("query returned more than one row")));
/* /*
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* Copyright (c) 2003-2006, PostgreSQL Global Development Group * Copyright (c) 2003-2006, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/pl/plpgsql/src/plerrcodes.h,v 1.8 2006/06/15 18:02:22 momjian Exp $ * $PostgreSQL: pgsql/src/pl/plpgsql/src/plerrcodes.h,v 1.9 2006/06/16 23:29:27 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -712,23 +712,21 @@ ...@@ -712,23 +712,21 @@
}, },
{ {
"internal_error", ERRCODE_INTERNAL_ERROR "no_data_found", ERRCODE_NO_DATA_FOUND
}, },
{ {
"data_corrupted", ERRCODE_DATA_CORRUPTED "too_many_rows", ERRCODE_TOO_MANY_ROWS
}, },
{ {
"index_corrupted", ERRCODE_INDEX_CORRUPTED "internal_error", ERRCODE_INTERNAL_ERROR
}, },
{ {
"no_data_found", ERRCODE_NO_DATA "data_corrupted", ERRCODE_DATA_CORRUPTED
}, },
{ {
"too_many_rows", ERRCODE_CARDINALITY_VIOLATION "index_corrupted", ERRCODE_INDEX_CORRUPTED
}, },
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/pl/plpgsql/src/scan.l,v 1.51 2006/06/15 18:02:22 momjian Exp $ * $PostgreSQL: pgsql/src/pl/plpgsql/src/scan.l,v 1.52 2006/06/16 23:29:27 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -129,7 +129,6 @@ else { return K_ELSE; } ...@@ -129,7 +129,6 @@ else { return K_ELSE; }
elseif { return K_ELSIF; } elseif { return K_ELSIF; }
elsif { return K_ELSIF; } elsif { return K_ELSIF; }
end { return K_END; } end { return K_END; }
strict { return K_STRICT; }
exception { return K_EXCEPTION; } exception { return K_EXCEPTION; }
execute { return K_EXECUTE; } execute { return K_EXECUTE; }
exit { return K_EXIT; } exit { return K_EXIT; }
...@@ -158,6 +157,7 @@ return { return K_RETURN; } ...@@ -158,6 +157,7 @@ return { return K_RETURN; }
reverse { return K_REVERSE; } reverse { return K_REVERSE; }
row_count { return K_ROW_COUNT; } row_count { return K_ROW_COUNT; }
select { return K_SELECT; } select { return K_SELECT; }
strict { return K_STRICT; }
then { return K_THEN; } then { return K_THEN; }
to { return K_TO; } to { return K_TO; }
type { return K_TYPE; } type { return K_TYPE; }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment