11/* -----------------------------------------------------------------------
22 * formatting.c
33 *
4- * $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.160 2009/08/1018:29:26 tgl Exp $
4+ * $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.161 2009/08/1020:16:05 alvherre Exp $
55 *
66 *
77 * Portions Copyright (c) 1999-2009, PostgreSQL Global Development Group
8282#include <wctype.h>
8383#endif
8484
85+ #include "mb/pg_wchar.h"
8586#include "utils/builtins.h"
8687#include "utils/date.h"
8788#include "utils/datetime.h"
8889#include "utils/formatting.h"
8990#include "utils/int8.h"
9091#include "utils/numeric.h"
9192#include "utils/pg_locale.h"
92- #include "mb/pg_wchar.h"
9393
9494/* ----------
9595 * Routines type
@@ -1046,24 +1046,24 @@ NUMDesc_prepare(NUMDesc *num, FormatNode *n)
10461046if (n -> type != NODE_TYPE_ACTION )
10471047return ;
10481048
1049- if (IS_EEEE (num )&& n -> key -> id != NUM_E )
1049+ /*
1050+ * In case of an error, we need to remove the numeric from the cache. Use
1051+ * a PG_TRY block to ensure that this happens.
1052+ */
1053+ PG_TRY ();
10501054{
1051- NUM_cache_remove ( last_NUMCacheEntry );
1055+ if ( IS_EEEE ( num ) && n -> key -> id != NUM_E )
10521056ereport (ERROR ,
10531057(errcode (ERRCODE_SYNTAX_ERROR ),
10541058errmsg ("\"EEEE\" must be the last pattern used" )));
1055- }
10561059
10571060switch (n -> key -> id )
10581061{
10591062case NUM_9 :
10601063if (IS_BRACKET (num ))
1061- {
1062- NUM_cache_remove (last_NUMCacheEntry );
10631064ereport (ERROR ,
10641065(errcode (ERRCODE_SYNTAX_ERROR ),
10651066errmsg ("\"9\" must be ahead of \"PR\"" )));
1066- }
10671067if (IS_MULTI (num ))
10681068{
10691069++ num -> multi ;
@@ -1077,12 +1077,9 @@ NUMDesc_prepare(NUMDesc *num, FormatNode *n)
10771077
10781078case NUM_0 :
10791079if (IS_BRACKET (num ))
1080- {
1081- NUM_cache_remove (last_NUMCacheEntry );
10821080ereport (ERROR ,
10831081(errcode (ERRCODE_SYNTAX_ERROR ),
10841082errmsg ("\"0\" must be ahead of \"PR\"" )));
1085- }
10861083if (!IS_ZERO (num )&& !IS_DECIMAL (num ))
10871084{
10881085num -> flag |=NUM_F_ZERO ;
@@ -1106,19 +1103,13 @@ NUMDesc_prepare(NUMDesc *num, FormatNode *n)
11061103num -> need_locale = TRUE;
11071104case NUM_DEC :
11081105if (IS_DECIMAL (num ))
1109- {
1110- NUM_cache_remove (last_NUMCacheEntry );
11111106ereport (ERROR ,
11121107(errcode (ERRCODE_SYNTAX_ERROR ),
11131108errmsg ("multiple decimal points" )));
1114- }
11151109if (IS_MULTI (num ))
1116- {
1117- NUM_cache_remove (last_NUMCacheEntry );
11181110ereport (ERROR ,
11191111(errcode (ERRCODE_SYNTAX_ERROR ),
11201112errmsg ("cannot use \"V\" and decimal point together" )));
1121- }
11221113num -> flag |=NUM_F_DECIMAL ;
11231114break ;
11241115
@@ -1128,19 +1119,13 @@ NUMDesc_prepare(NUMDesc *num, FormatNode *n)
11281119
11291120case NUM_S :
11301121if (IS_LSIGN (num ))
1131- {
1132- NUM_cache_remove (last_NUMCacheEntry );
11331122ereport (ERROR ,
11341123(errcode (ERRCODE_SYNTAX_ERROR ),
11351124errmsg ("cannot use \"S\" twice" )));
1136- }
11371125if (IS_PLUS (num )|| IS_MINUS (num )|| IS_BRACKET (num ))
1138- {
1139- NUM_cache_remove (last_NUMCacheEntry );
11401126ereport (ERROR ,
11411127(errcode (ERRCODE_SYNTAX_ERROR ),
11421128errmsg ("cannot use \"S\" and \"PL\"/\"MI\"/\"SG\"/\"PR\" together" )));
1143- }
11441129if (!IS_DECIMAL (num ))
11451130{
11461131num -> lsign = NUM_LSIGN_PRE ;
@@ -1158,50 +1143,38 @@ NUMDesc_prepare(NUMDesc *num, FormatNode *n)
11581143
11591144case NUM_MI :
11601145if (IS_LSIGN (num ))
1161- {
1162- NUM_cache_remove (last_NUMCacheEntry );
11631146ereport (ERROR ,
11641147(errcode (ERRCODE_SYNTAX_ERROR ),
11651148errmsg ("cannot use \"S\" and \"MI\" together" )));
1166- }
11671149num -> flag |=NUM_F_MINUS ;
11681150if (IS_DECIMAL (num ))
11691151num -> flag |=NUM_F_MINUS_POST ;
11701152break ;
11711153
11721154case NUM_PL :
11731155if (IS_LSIGN (num ))
1174- {
1175- NUM_cache_remove (last_NUMCacheEntry );
11761156ereport (ERROR ,
11771157(errcode (ERRCODE_SYNTAX_ERROR ),
11781158errmsg ("cannot use \"S\" and \"PL\" together" )));
1179- }
11801159num -> flag |=NUM_F_PLUS ;
11811160if (IS_DECIMAL (num ))
11821161num -> flag |=NUM_F_PLUS_POST ;
11831162break ;
11841163
11851164case NUM_SG :
11861165if (IS_LSIGN (num ))
1187- {
1188- NUM_cache_remove (last_NUMCacheEntry );
11891166ereport (ERROR ,
11901167(errcode (ERRCODE_SYNTAX_ERROR ),
11911168errmsg ("cannot use \"S\" and \"SG\" together" )));
1192- }
11931169num -> flag |=NUM_F_MINUS ;
11941170num -> flag |=NUM_F_PLUS ;
11951171break ;
11961172
11971173case NUM_PR :
11981174if (IS_LSIGN (num )|| IS_PLUS (num )|| IS_MINUS (num ))
1199- {
1200- NUM_cache_remove (last_NUMCacheEntry );
12011175ereport (ERROR ,
12021176(errcode (ERRCODE_SYNTAX_ERROR ),
12031177errmsg ("cannot use \"PR\" and \"S\"/\"PL\"/\"MI\"/\"SG\" together" )));
1204- }
12051178num -> flag |=NUM_F_BRACKET ;
12061179break ;
12071180
@@ -1217,36 +1190,35 @@ NUMDesc_prepare(NUMDesc *num, FormatNode *n)
12171190
12181191case NUM_V :
12191192if (IS_DECIMAL (num ))
1220- {
1221- NUM_cache_remove (last_NUMCacheEntry );
12221193ereport (ERROR ,
12231194(errcode (ERRCODE_SYNTAX_ERROR ),
12241195errmsg ("cannot use \"V\" and decimal point together" )));
1225- }
12261196num -> flag |=NUM_F_MULTI ;
12271197break ;
12281198
12291199case NUM_E :
12301200if (IS_EEEE (num ))
1231- {
1232- NUM_cache_remove (last_NUMCacheEntry );
12331201ereport (ERROR ,
12341202(errcode (ERRCODE_SYNTAX_ERROR ),
12351203errmsg ("cannot use \"EEEE\" twice" )));
1236- }
12371204if (IS_BLANK (num )|| IS_FILLMODE (num )|| IS_LSIGN (num )||
12381205IS_BRACKET (num )|| IS_MINUS (num )|| IS_PLUS (num )||
12391206IS_ROMAN (num )|| IS_MULTI (num ))
1240- {
1241- NUM_cache_remove (last_NUMCacheEntry );
12421207ereport (ERROR ,
12431208(errcode (ERRCODE_SYNTAX_ERROR ),
12441209errmsg ("\"EEEE\" is incompatible with other formats" ),
12451210errdetail ("\"EEEE\" may only be used together with digit and decimal point patterns." )));
1246- }
12471211num -> flag |=NUM_F_EEEE ;
12481212break ;
12491213}
1214+ }
1215+ PG_CATCH ();
1216+ {
1217+ NUM_cache_remove (last_NUMCacheEntry );
1218+ PG_RE_THROW ();
1219+ }
1220+ PG_END_TRY ();
1221+
12501222
12511223return ;
12521224}