diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c index 6c1b35fbe1..c819f2231e 100644 --- a/src/backend/utils/adt/formatting.c +++ b/src/backend/utils/adt/formatting.c @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------- * formatting.c * - * $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.160 2009/08/10 18:29:26 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.161 2009/08/10 20:16:05 alvherre Exp $ * * * Portions Copyright (c) 1999-2009, PostgreSQL Global Development Group @@ -82,6 +82,7 @@ #include #endif +#include "mb/pg_wchar.h" #include "utils/builtins.h" #include "utils/date.h" #include "utils/datetime.h" @@ -89,7 +90,6 @@ #include "utils/int8.h" #include "utils/numeric.h" #include "utils/pg_locale.h" -#include "mb/pg_wchar.h" /* ---------- * Routines type @@ -1046,24 +1046,24 @@ NUMDesc_prepare(NUMDesc *num, FormatNode *n) if (n->type != NODE_TYPE_ACTION) return; - if (IS_EEEE(num) && n->key->id != NUM_E) + /* + * In case of an error, we need to remove the numeric from the cache. Use + * a PG_TRY block to ensure that this happens. + */ + PG_TRY(); { - NUM_cache_remove(last_NUMCacheEntry); + if (IS_EEEE(num) && n->key->id != NUM_E) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("\"EEEE\" must be the last pattern used"))); - } switch (n->key->id) { case NUM_9: if (IS_BRACKET(num)) - { - NUM_cache_remove(last_NUMCacheEntry); ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("\"9\" must be ahead of \"PR\""))); - } if (IS_MULTI(num)) { ++num->multi; @@ -1077,12 +1077,9 @@ NUMDesc_prepare(NUMDesc *num, FormatNode *n) case NUM_0: if (IS_BRACKET(num)) - { - NUM_cache_remove(last_NUMCacheEntry); ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("\"0\" must be ahead of \"PR\""))); - } if (!IS_ZERO(num) && !IS_DECIMAL(num)) { num->flag |= NUM_F_ZERO; @@ -1106,19 +1103,13 @@ NUMDesc_prepare(NUMDesc *num, FormatNode *n) num->need_locale = TRUE; case NUM_DEC: if (IS_DECIMAL(num)) - { - NUM_cache_remove(last_NUMCacheEntry); ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("multiple decimal points"))); - } if (IS_MULTI(num)) - { - NUM_cache_remove(last_NUMCacheEntry); ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("cannot use \"V\" and decimal point together"))); - } num->flag |= NUM_F_DECIMAL; break; @@ -1128,19 +1119,13 @@ NUMDesc_prepare(NUMDesc *num, FormatNode *n) case NUM_S: if (IS_LSIGN(num)) - { - NUM_cache_remove(last_NUMCacheEntry); ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("cannot use \"S\" twice"))); - } if (IS_PLUS(num) || IS_MINUS(num) || IS_BRACKET(num)) - { - NUM_cache_remove(last_NUMCacheEntry); ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("cannot use \"S\" and \"PL\"/\"MI\"/\"SG\"/\"PR\" together"))); - } if (!IS_DECIMAL(num)) { num->lsign = NUM_LSIGN_PRE; @@ -1158,12 +1143,9 @@ NUMDesc_prepare(NUMDesc *num, FormatNode *n) case NUM_MI: if (IS_LSIGN(num)) - { - NUM_cache_remove(last_NUMCacheEntry); ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("cannot use \"S\" and \"MI\" together"))); - } num->flag |= NUM_F_MINUS; if (IS_DECIMAL(num)) num->flag |= NUM_F_MINUS_POST; @@ -1171,12 +1153,9 @@ NUMDesc_prepare(NUMDesc *num, FormatNode *n) case NUM_PL: if (IS_LSIGN(num)) - { - NUM_cache_remove(last_NUMCacheEntry); ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("cannot use \"S\" and \"PL\" together"))); - } num->flag |= NUM_F_PLUS; if (IS_DECIMAL(num)) num->flag |= NUM_F_PLUS_POST; @@ -1184,24 +1163,18 @@ NUMDesc_prepare(NUMDesc *num, FormatNode *n) case NUM_SG: if (IS_LSIGN(num)) - { - NUM_cache_remove(last_NUMCacheEntry); ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("cannot use \"S\" and \"SG\" together"))); - } num->flag |= NUM_F_MINUS; num->flag |= NUM_F_PLUS; break; case NUM_PR: if (IS_LSIGN(num) || IS_PLUS(num) || IS_MINUS(num)) - { - NUM_cache_remove(last_NUMCacheEntry); ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("cannot use \"PR\" and \"S\"/\"PL\"/\"MI\"/\"SG\" together"))); - } num->flag |= NUM_F_BRACKET; break; @@ -1217,36 +1190,35 @@ NUMDesc_prepare(NUMDesc *num, FormatNode *n) case NUM_V: if (IS_DECIMAL(num)) - { - NUM_cache_remove(last_NUMCacheEntry); ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("cannot use \"V\" and decimal point together"))); - } num->flag |= NUM_F_MULTI; break; case NUM_E: if (IS_EEEE(num)) - { - NUM_cache_remove(last_NUMCacheEntry); ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("cannot use \"EEEE\" twice"))); - } if (IS_BLANK(num) || IS_FILLMODE(num) || IS_LSIGN(num) || IS_BRACKET(num) || IS_MINUS(num) || IS_PLUS(num) || IS_ROMAN(num) || IS_MULTI(num)) - { - NUM_cache_remove(last_NUMCacheEntry); ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("\"EEEE\" is incompatible with other formats"), errdetail("\"EEEE\" may only be used together with digit and decimal point patterns."))); - } num->flag |= NUM_F_EEEE; break; } + } + PG_CATCH(); + { + NUM_cache_remove(last_NUMCacheEntry); + PG_RE_THROW(); + } + PG_END_TRY(); + return; }