summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2006-06-16 23:29:27 +0000
committerTom Lane2006-06-16 23:29:27 +0000
commit37ff6227ba1cb595e6ee906a22fdd5cefc1c2ca2 (patch)
tree933d008b5702faeaff21d68a72ecebe32d67bce8
parent8d6d1dddf8a0f38f447287bd4ae8f3d2ae7b8764 (diff)
Code review for SELECT INTO STRICT patch: use saner choices of error
SQLSTATEs, fix some documentation problems.
-rw-r--r--doc/src/sgml/errcodes.sgml12
-rw-r--r--doc/src/sgml/plpgsql.sgml41
-rw-r--r--src/include/utils/errcodes.h2
-rw-r--r--src/pl/plpgsql/src/gram.y2
-rw-r--r--src/pl/plpgsql/src/pl_exec.c4
-rw-r--r--src/pl/plpgsql/src/plerrcodes.h12
-rw-r--r--src/pl/plpgsql/src/scan.l2
7 files changed, 47 insertions, 28 deletions
diff --git a/doc/src/sgml/errcodes.sgml b/doc/src/sgml/errcodes.sgml
index fc7c8fb649..76c6579468 100644
--- a/doc/src/sgml/errcodes.sgml
+++ b/doc/src/sgml/errcodes.sgml
@@ -1344,6 +1344,18 @@
<entry>raise_exception</entry>
</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>
<entry spanname="span13"><emphasis role="bold">Class XX &mdash; Internal Error</></entry>
diff --git a/doc/src/sgml/plpgsql.sgml b/doc/src/sgml/plpgsql.sgml
index a5c1a18dff..ef76a83688 100644
--- a/doc/src/sgml/plpgsql.sgml
+++ b/doc/src/sgml/plpgsql.sgml
@@ -1076,8 +1076,8 @@ tax := subtotal * 0.06;
</indexterm>
<para>
- The result of a <command>SELECT</command> command yielding multiple columns (but
- only one row) can be assigned to a record variable, row-type
+ The result of a <command>SELECT</command> command yielding multiple
+ columns (but only one row) can be assigned to a record variable, row-type
variable, or list of scalar variables. This is done by:
<synopsis>
@@ -1126,23 +1126,24 @@ SELECT INTO <optional>STRICT</optional> <replaceable>target</replaceable> <repla
<replaceable>target</replaceable> will be set to the first row
returned by the query, or if the query returned no rows,
null values are assigned. (Note that <quote>the first row</> is not
- well-defined unless you've used <literal>ORDER BY</>.)
- You can check the special <literal>FOUND</literal> variable to
- determine if any rows were found:
+ well-defined unless you've used <literal>ORDER BY</>.) Any result rows
+ after the first row are discarded.
+ You can check the special <literal>FOUND</literal> variable (see
+ <xref linkend="plpgsql-statements-diagnostics">) to
+ determine whether a row was returned:
<programlisting>
-SELECT INTO STRICT myrec * FROM emp WHERE empname = myname;
+SELECT INTO myrec * FROM emp WHERE empname = myname;
IF NOT FOUND THEN
RAISE EXCEPTION 'employee % not found', myname;
END IF;
</programlisting>
- <para>
- If the <literal>STRICT</literal> option is specified, a query must
+ If the <literal>STRICT</literal> option is specified, the query must
return exactly one row or a run-time error will be thrown, either
<literal>NO_DATA_FOUND</> (no rows) or <literal>TOO_MANY_ROWS</>
- (more than one row). You can must use exception blocks to determine
- the number of rows generated by the query:
+ (more than one row). You can use an exception block if you wish
+ to catch the error, for example:
<programlisting>
BEGIN;
@@ -1154,11 +1155,17 @@ BEGIN;
RAISE EXCEPTION 'employee % not unique', myname;
END;
</programlisting>
- Only <command>SELECT INTO STRICT</command> allows you to check if more
- than one row was retrieved. <command>SELECT INTO STRICT</command>
- matches Oracle's PL/SQL <command>SELECT INTO</command> behavior.
+ Successful execution of <command>SELECT INTO STRICT</command>
+ always sets <literal>FOUND</literal> to true.
</para>
+ <note>
+ <para>
+ <command>SELECT INTO STRICT</command> matches the behavior of
+ Oracle PL/SQL's <command>SELECT INTO</command> statement.
+ </para>
+ </note>
+
</sect2>
<sect2 id="plpgsql-statements-perform">
@@ -1987,7 +1994,7 @@ END LOOP <optional> <replaceable>label</replaceable> </optional>;
the loop. If the <literal>BY</> clause isn't specified the iteration
step is 1 otherwise it's the value specified in the <literal>BY</>
clause. If <literal>REVERSE</> is specified then the step value is
- considered negative.
+ considered negative.
</para>
<para>
@@ -2764,7 +2771,7 @@ RAISE EXCEPTION 'Nonexistent ID --> %', user_id;
<para>
Data type <type>name</type>; the name of the table that caused the trigger
invocation. This is now deprecated, and could disappear in a future
- release. Use <literal>TG_TABLE_NAME</> instead.
+ release. Use <literal>TG_TABLE_NAME</> instead.
</para>
</listitem>
</varlistentry>
@@ -2774,7 +2781,7 @@ RAISE EXCEPTION 'Nonexistent ID --> %', user_id;
<listitem>
<para>
Data type <type>name</type>; the name of the table that
- caused the trigger invocation.
+ caused the trigger invocation.
</para>
</listitem>
</varlistentry>
@@ -2784,7 +2791,7 @@ RAISE EXCEPTION 'Nonexistent ID --> %', user_id;
<listitem>
<para>
Data type <type>name</type>; the name of the schema of the
- table that caused the trigger invocation.
+ table that caused the trigger invocation.
</para>
</listitem>
</varlistentry>
diff --git a/src/include/utils/errcodes.h b/src/include/utils/errcodes.h
index d84a2e7ed2..3ac8c041bf 100644
--- a/src/include/utils/errcodes.h
+++ b/src/include/utils/errcodes.h
@@ -331,6 +331,8 @@
/* Class P0 - PL/pgSQL Error (PostgreSQL-specific error class) */
#define ERRCODE_PLPGSQL_ERROR MAKE_SQLSTATE('P','0', '0','0','0')
#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) */
/* (this is for "can't-happen" conditions and software bugs) */
diff --git a/src/pl/plpgsql/src/gram.y b/src/pl/plpgsql/src/gram.y
index 75f69b9c6b..4f1ea52cae 100644
--- a/src/pl/plpgsql/src/gram.y
+++ b/src/pl/plpgsql/src/gram.y
@@ -157,7 +157,6 @@ static void check_labels(const char *start_label,
%token K_ELSE
%token K_ELSIF
%token K_END
-%token K_STRICT
%token K_EXCEPTION
%token K_EXECUTE
%token K_EXIT
@@ -187,6 +186,7 @@ static void check_labels(const char *start_label,
%token K_RETURN_NEXT
%token K_REVERSE
%token K_SELECT
+%token K_STRICT
%token K_THEN
%token K_TO
%token K_TYPE
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index 2640397fe2..be72029322 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -1721,7 +1721,7 @@ exec_stmt_select(PLpgSQL_execstate *estate, PLpgSQL_stmt_select *stmt)
{
if (stmt->strict)
ereport(ERROR,
- (errcode(ERRCODE_NO_DATA),
+ (errcode(ERRCODE_NO_DATA_FOUND),
errmsg("query returned no rows")));
/* set the target to NULL(s) */
@@ -1732,7 +1732,7 @@ exec_stmt_select(PLpgSQL_execstate *estate, PLpgSQL_stmt_select *stmt)
if (n > 1 && stmt->strict)
ereport(ERROR,
- (errcode(ERRCODE_CARDINALITY_VIOLATION),
+ (errcode(ERRCODE_TOO_MANY_ROWS),
errmsg("query returned more than one row")));
/*
diff --git a/src/pl/plpgsql/src/plerrcodes.h b/src/pl/plpgsql/src/plerrcodes.h
index f0de298d12..2e5fa9bb96 100644
--- a/src/pl/plpgsql/src/plerrcodes.h
+++ b/src/pl/plpgsql/src/plerrcodes.h
@@ -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
},
-
-
diff --git a/src/pl/plpgsql/src/scan.l b/src/pl/plpgsql/src/scan.l
index e7b9a2319d..a04361eb11 100644
--- a/src/pl/plpgsql/src/scan.l
+++ b/src/pl/plpgsql/src/scan.l
@@ -129,7 +129,6 @@ else { return K_ELSE; }
elseif { return K_ELSIF; }
elsif { return K_ELSIF; }
end { return K_END; }
-strict { return K_STRICT; }
exception { return K_EXCEPTION; }
execute { return K_EXECUTE; }
exit { return K_EXIT; }
@@ -158,6 +157,7 @@ return { return K_RETURN; }
reverse { return K_REVERSE; }
row_count { return K_ROW_COUNT; }
select { return K_SELECT; }
+strict { return K_STRICT; }
then { return K_THEN; }
to { return K_TO; }
type { return K_TYPE; }