Skip to content

Commit 58fdca2

Browse files
committed
plpgsql: make WHEN OTHERS distinct from WHEN SQLSTATE '00000'.
The catchall exception condition OTHERS was represented as sqlerrstate == 0, which was a poor choice because that comes out the same as SQLSTATE '00000'. While we don't issue that as an error code ourselves, there isn't anything particularly stopping users from doing so. Use -1 instead, which can't match any allowed SQLSTATE string. While at it, invent a macro PLPGSQL_OTHERS to use instead of a hard-coded magic number. While this seems like a bug fix, I'm inclined not to back-patch. It seems barely possible that someone has written code like this and would be annoyed by changing the behavior in a minor release. Reported-by: David Fiedler <david.fido.fiedler@gmail.com> Author: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://postgr.es/m/CAHjN70-=H5EpTOuZVbC8mPvRS5EfZ4MY2=OUdVDWoyGvKhb+Rw@mail.gmail.com
1 parent 9a2e2a2 commit 58fdca2

File tree

3 files changed

+6
-7
lines changed

3 files changed

+6
-7
lines changed

src/pl/plpgsql/src/pl_comp.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2273,14 +2273,10 @@ plpgsql_parse_err_condition(char *condname)
22732273
* here.
22742274
*/
22752275

2276-
/*
2277-
* OTHERS is represented as code 0 (which would map to '00000', but we
2278-
* have no need to represent that as an exception condition).
2279-
*/
22802276
if (strcmp(condname, "others") == 0)
22812277
{
22822278
new = palloc(sizeof(PLpgSQL_condition));
2283-
new->sqlerrstate = 0;
2279+
new->sqlerrstate = PLPGSQL_OTHERS;
22842280
new->condname = condname;
22852281
new->next = NULL;
22862282
return new;

src/pl/plpgsql/src/pl_exec.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1603,7 +1603,7 @@ exception_matches_conditions(ErrorData *edata, PLpgSQL_condition *cond)
16031603
* assert-failure. If you're foolish enough, you can match those
16041604
* explicitly.
16051605
*/
1606-
if (sqlerrstate == 0)
1606+
if (sqlerrstate == PLPGSQL_OTHERS)
16071607
{
16081608
if (edata->sqlerrcode != ERRCODE_QUERY_CANCELED &&
16091609
edata->sqlerrcode != ERRCODE_ASSERT_FAILURE)

src/pl/plpgsql/src/plpgsql.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,11 +490,14 @@ typedef struct PLpgSQL_stmt
490490
*/
491491
typedef struct PLpgSQL_condition
492492
{
493-
int sqlerrstate; /* SQLSTATE code */
493+
int sqlerrstate; /* SQLSTATE code, or PLPGSQL_OTHERS */
494494
char *condname; /* condition name (for debugging) */
495495
struct PLpgSQL_condition *next;
496496
} PLpgSQL_condition;
497497

498+
/* This value mustn't match any possible output of MAKE_SQLSTATE() */
499+
#define PLPGSQL_OTHERS (-1)
500+
498501
/*
499502
* EXCEPTION block
500503
*/

0 commit comments

Comments
 (0)