diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 6c1b35fbe1e6085e1112c78d08ddb5238dc9b0e7..c819f2231e5df61068c1d468f21d3c6f9719b1d2 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 <wctype.h>
 #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;
 }