From c892643a3c4645450e3f84d2e2266a4e46340d28 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 16 Jun 2006 23:29:27 +0000 Subject: [PATCH] Code review for SELECT INTO STRICT patch: use saner choices of error SQLSTATEs, fix some documentation problems. --- doc/src/sgml/errcodes.sgml | 14 ++++++++++- doc/src/sgml/plpgsql.sgml | 43 +++++++++++++++++++-------------- src/include/utils/errcodes.h | 4 ++- src/pl/plpgsql/src/gram.y | 4 +-- src/pl/plpgsql/src/pl_exec.c | 6 ++--- src/pl/plpgsql/src/plerrcodes.h | 20 +++++++-------- src/pl/plpgsql/src/scan.l | 4 +-- 7 files changed, 57 insertions(+), 38 deletions(-) diff --git a/doc/src/sgml/errcodes.sgml b/doc/src/sgml/errcodes.sgml index b5617c9850..bf06cfaf5e 100644 --- a/doc/src/sgml/errcodes.sgml +++ b/doc/src/sgml/errcodes.sgml @@ -1,4 +1,4 @@ - + <productname>PostgreSQL</productname> Error Codes @@ -1344,6 +1344,18 @@ raise_exception + +P0002 +NO DATA FOUND +no_data_found + + + +P0003 +TOO MANY ROWS +too_many_rows + + Class XX — Internal Error diff --git a/doc/src/sgml/plpgsql.sgml b/doc/src/sgml/plpgsql.sgml index 1f09b9e99c..ac5b2b4cfc 100644 --- a/doc/src/sgml/plpgsql.sgml +++ b/doc/src/sgml/plpgsql.sgml @@ -1,4 +1,4 @@ - + <application>PL/pgSQL</application> - <acronym>SQL</acronym> Procedural Language @@ -1076,8 +1076,8 @@ tax := subtotal * 0.06; - The result of a SELECT command yielding multiple columns (but - only one row) can be assigned to a record variable, row-type + The result of a SELECT 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: @@ -1126,23 +1126,24 @@ SELECT INTO STRICT target target will be set to the first row returned by the query, or if the query returned no rows, null values are assigned. (Note that the first row is not - well-defined unless you've used ORDER BY.) - You can check the special FOUND variable to - determine if any rows were found: + well-defined unless you've used ORDER BY.) Any result rows + after the first row are discarded. + You can check the special FOUND variable (see + ) to + determine whether a row was returned: -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; - - If the STRICT option is specified, a query must + If the STRICT option is specified, the query must return exactly one row or a run-time error will be thrown, either NO_DATA_FOUND (no rows) or 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: BEGIN; @@ -1154,11 +1155,17 @@ BEGIN; RAISE EXCEPTION 'employee % not unique', myname; END; - Only SELECT INTO STRICT allows you to check if more - than one row was retrieved. SELECT INTO STRICT - matches Oracle's PL/SQL SELECT INTO behavior. + Successful execution of SELECT INTO STRICT + always sets FOUND to true. + + + SELECT INTO STRICT matches the behavior of + Oracle PL/SQL's SELECT INTO statement. + + + @@ -1987,7 +1994,7 @@ END LOOP label ; the loop. If the BY clause isn't specified the iteration step is 1 otherwise it's the value specified in the BY clause. If REVERSE is specified then the step value is - considered negative. + considered negative. @@ -2764,7 +2771,7 @@ RAISE EXCEPTION 'Nonexistent ID --> %', user_id; Data type name; the name of the table that caused the trigger invocation. This is now deprecated, and could disappear in a future - release. Use TG_TABLE_NAME instead. + release. Use TG_TABLE_NAME instead. @@ -2774,7 +2781,7 @@ RAISE EXCEPTION 'Nonexistent ID --> %', user_id; Data type name; the name of the table that - caused the trigger invocation. + caused the trigger invocation. @@ -2784,7 +2791,7 @@ RAISE EXCEPTION 'Nonexistent ID --> %', user_id; Data type name; the name of the schema of the - table that caused the trigger invocation. + table that caused the trigger invocation. diff --git a/src/include/utils/errcodes.h b/src/include/utils/errcodes.h index fc59a32fb9..8ba809d2ee 100644 --- a/src/include/utils/errcodes.h +++ b/src/include/utils/errcodes.h @@ -11,7 +11,7 @@ * * 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 @@ /* 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 21a0bd6541..4ced4402eb 100644 --- a/src/pl/plpgsql/src/gram.y +++ b/src/pl/plpgsql/src/gram.y @@ -9,7 +9,7 @@ * * * 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, %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 e74dcac231..4188fe1eb1 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -8,7 +8,7 @@ * * * 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) { 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 fedd4d0c7e..478bf3b080 100644 --- a/src/pl/plpgsql/src/plerrcodes.h +++ b/src/pl/plpgsql/src/plerrcodes.h @@ -9,7 +9,7 @@ * * 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 $ * *------------------------------------------------------------------------- */ @@ -711,6 +711,14 @@ "raise_exception", ERRCODE_RAISE_EXCEPTION }, +{ + "no_data_found", ERRCODE_NO_DATA_FOUND +}, + +{ + "too_many_rows", ERRCODE_TOO_MANY_ROWS +}, + { "internal_error", ERRCODE_INTERNAL_ERROR }, @@ -722,13 +730,3 @@ { "index_corrupted", ERRCODE_INDEX_CORRUPTED }, - -{ - "no_data_found", ERRCODE_NO_DATA -}, - -{ - "too_many_rows", ERRCODE_CARDINALITY_VIOLATION -}, - - diff --git a/src/pl/plpgsql/src/scan.l b/src/pl/plpgsql/src/scan.l index 1dca30a566..7220949063 100644 --- a/src/pl/plpgsql/src/scan.l +++ b/src/pl/plpgsql/src/scan.l @@ -9,7 +9,7 @@ * * * 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; } 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; }