11/* -----------------------------------------------------------------------
22 * formatting.c
33 *
4- * $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.154 2009/02/07 14:16:45 momjian Exp $
4+ * $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.155 2009/03/12 00:53:25 tgl Exp $
55 *
66 *
77 * Portions Copyright (c) 1999-2009, PostgreSQL Global Development Group
@@ -392,12 +392,10 @@ static intDCHCounter = 0;
392392
393393/* global cache for --- number part */
394394static NUMCacheEntry NUMCache [NUM_CACHE_FIELDS + 1 ];
395- static NUMCacheEntry * last_NUMCacheEntry ;
396395
397396static int n_NUMCache = 0 ;/* number of entries */
398397static int NUMCounter = 0 ;
399-
400- #define MAX_INT32 (2147483600)
398+ static NUMCacheEntry * last_NUMCacheEntry = NUMCache + 0 ;
401399
402400/* ----------
403401 * For char->date/time conversion
@@ -2765,10 +2763,10 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out)
27652763static DCHCacheEntry *
27662764DCH_cache_getnew (char * str )
27672765{
2768- DCHCacheEntry * ent = NULL ;
2766+ DCHCacheEntry * ent ;
27692767
2770- /* counteroverload check - paranoia? */
2771- if (DCHCounter + DCH_CACHE_FIELDS >= MAX_INT32 )
2768+ /* counteroverflow check - paranoia? */
2769+ if (DCHCounter >= ( INT_MAX - DCH_CACHE_FIELDS - 1 ) )
27722770{
27732771DCHCounter = 0 ;
27742772
@@ -2777,7 +2775,7 @@ DCH_cache_getnew(char *str)
27772775}
27782776
27792777/*
2780- *Cache is full - needs removeany older entry
2778+ *If cache is full, removeoldest entry
27812779 */
27822780if (n_DCHCache > DCH_CACHE_FIELDS )
27832781{
@@ -2786,7 +2784,7 @@ DCH_cache_getnew(char *str)
27862784#ifdef DEBUG_TO_FROM_CHAR
27872785elog (DEBUG_elog_output ,"cache is full (%d)" ,n_DCHCache );
27882786#endif
2789- for (ent = DCHCache ;ent <= (DCHCache + DCH_CACHE_FIELDS );ent ++ )
2787+ for (ent = DCHCache + 1 ;ent <= (DCHCache + DCH_CACHE_FIELDS );ent ++ )
27902788{
27912789if (ent -> age < old -> age )
27922790old = ent ;
@@ -2811,35 +2809,30 @@ DCH_cache_getnew(char *str)
28112809++ n_DCHCache ;
28122810return ent ;
28132811}
2814-
2815- return NULL ;/* never */
28162812}
28172813
28182814static DCHCacheEntry *
28192815DCH_cache_search (char * str )
28202816{
2821- int i = 0 ;
2817+ int i ;
28222818DCHCacheEntry * ent ;
28232819
2824- /* counteroverload check - paranoia? */
2825- if (DCHCounter + DCH_CACHE_FIELDS >= MAX_INT32 )
2820+ /* counteroverflow check - paranoia? */
2821+ if (DCHCounter >= ( INT_MAX - DCH_CACHE_FIELDS - 1 ) )
28262822{
28272823DCHCounter = 0 ;
28282824
28292825for (ent = DCHCache ;ent <= (DCHCache + DCH_CACHE_FIELDS );ent ++ )
28302826ent -> age = (++ DCHCounter );
28312827}
28322828
2833- for (ent = DCHCache ; ent <= ( DCHCache + DCH_CACHE_FIELDS ); ent ++ )
2829+ for (i = 0 , ent = DCHCache ; i < n_DCHCache ; i ++ , ent ++ )
28342830{
2835- if (i == n_DCHCache )
2836- break ;
28372831if (strcmp (ent -> str ,str )== 0 )
28382832{
28392833ent -> age = (++ DCHCounter );
28402834return ent ;
28412835}
2842- i ++ ;
28432836}
28442837
28452838return NULL ;
@@ -3371,10 +3364,10 @@ do { \
33713364static NUMCacheEntry *
33723365NUM_cache_getnew (char * str )
33733366{
3374- NUMCacheEntry * ent = NULL ;
3367+ NUMCacheEntry * ent ;
33753368
3376- /* counteroverload check - paranoia? */
3377- if (NUMCounter + NUM_CACHE_FIELDS >= MAX_INT32 )
3369+ /* counteroverflow check - paranoia? */
3370+ if (NUMCounter >= ( INT_MAX - NUM_CACHE_FIELDS - 1 ) )
33783371{
33793372NUMCounter = 0 ;
33803373
@@ -3383,7 +3376,7 @@ NUM_cache_getnew(char *str)
33833376}
33843377
33853378/*
3386- *Cache is full - needs removeany older entry
3379+ *If cache is full, removeoldest entry
33873380 */
33883381if (n_NUMCache > NUM_CACHE_FIELDS )
33893382{
@@ -3392,13 +3385,13 @@ NUM_cache_getnew(char *str)
33923385#ifdef DEBUG_TO_FROM_CHAR
33933386elog (DEBUG_elog_output ,"Cache is full (%d)" ,n_NUMCache );
33943387#endif
3395-
33963388for (ent = NUMCache ;ent <= (NUMCache + NUM_CACHE_FIELDS );ent ++ )
33973389{
33983390/*
3399- * entry removed via NUM_cache_remove() can be used here
3391+ * entry removed via NUM_cache_remove() can be used here,
3392+ * which is why it's worth scanning first entry again
34003393 */
3401- if (* ent -> str == '\0' )
3394+ if (ent -> str [ 0 ] == '\0' )
34023395{
34033396old = ent ;
34043397break ;
@@ -3412,7 +3405,6 @@ NUM_cache_getnew(char *str)
34123405StrNCpy (old -> str ,str ,NUM_CACHE_SIZE + 1 );
34133406/* old->format fill parser */
34143407old -> age = (++ NUMCounter );
3415-
34163408ent = old ;
34173409}
34183410else
@@ -3430,35 +3422,32 @@ NUM_cache_getnew(char *str)
34303422zeroize_NUM (& ent -> Num );
34313423
34323424last_NUMCacheEntry = ent ;
3433- return ent ;/* never */
3425+ return ent ;
34343426}
34353427
34363428static NUMCacheEntry *
34373429NUM_cache_search (char * str )
34383430{
3439- int i = 0 ;
3431+ int i ;
34403432NUMCacheEntry * ent ;
34413433
3442- /* counteroverload check - paranoia? */
3443- if (NUMCounter + NUM_CACHE_FIELDS >= MAX_INT32 )
3434+ /* counteroverflow check - paranoia? */
3435+ if (NUMCounter >= ( INT_MAX - NUM_CACHE_FIELDS - 1 ) )
34443436{
34453437NUMCounter = 0 ;
34463438
34473439for (ent = NUMCache ;ent <= (NUMCache + NUM_CACHE_FIELDS );ent ++ )
34483440ent -> age = (++ NUMCounter );
34493441}
34503442
3451- for (ent = NUMCache ; ent <= ( NUMCache + NUM_CACHE_FIELDS ); ent ++ )
3443+ for (i = 0 , ent = NUMCache ; i < n_NUMCache ; i ++ , ent ++ )
34523444{
3453- if (i == n_NUMCache )
3454- break ;
34553445if (strcmp (ent -> str ,str )== 0 )
34563446{
34573447ent -> age = (++ NUMCounter );
34583448last_NUMCacheEntry = ent ;
34593449return ent ;
34603450}
3461- i ++ ;
34623451}
34633452
34643453return NULL ;
@@ -3470,7 +3459,7 @@ NUM_cache_remove(NUMCacheEntry *ent)
34703459#ifdef DEBUG_TO_FROM_CHAR
34713460elog (DEBUG_elog_output ,"REMOVING ENTRY (%s)" ,ent -> str );
34723461#endif
3473- * ent -> str = '\0' ;
3462+ ent -> str [ 0 ] = '\0' ;
34743463ent -> age = 0 ;
34753464}
34763465