11/* -----------------------------------------------------------------------
22 * formatting.c
33 *
4- * $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.67 2003/08/25 16:13:27 tgl Exp $
4+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.68 2003/09/03 14:59:41 tgl Exp $
55 *
66 *
77 * Portions Copyright (c) 1999-2003, PostgreSQL Global Development Group
@@ -1294,6 +1294,16 @@ DCH_processor(FormatNode *node, char *inout, int flag, void *data)
12941294
12951295for (n = node ,s = inout ;n -> type != NODE_TYPE_END ;n ++ )
12961296{
1297+ if (flag == FROM_CHAR && * s == '\0' )
1298+ /*
1299+ * The input string is shorter than format picture,
1300+ * so it's good time to break this loop...
1301+ *
1302+ * Note: this isn't relevant for TO_CHAR mode, beacuse
1303+ * it use 'inout' allocated by format picture length.
1304+ */
1305+ break ;
1306+
12971307if (n -> type == NODE_TYPE_ACTION )
12981308{
12991309int len ;
@@ -1328,9 +1338,8 @@ DCH_processor(FormatNode *node, char *inout, int flag, void *data)
13281338}
13291339}
13301340}
1331-
1341+
13321342++ s ;/* ! */
1333-
13341343}
13351344
13361345if (flag == TO_CHAR )
@@ -2715,10 +2724,10 @@ datetime_to_char_body(TmToChar *tmtc, text *fmt)
27152724{
27162725FormatNode * format ;
27172726struct tm * tm = NULL ;
2718- char * str_fmt ,
2719- * result ;
2720- bool incache ;
2721- int len = VARSIZE (fmt )- VARHDRSZ ;
2727+ char * fmt_str ,
2728+ * result ;
2729+ bool incache ;
2730+ int fmt_len = VARSIZE (fmt )- VARHDRSZ ;
27222731
27232732tm = tmtcTm (tmtc );
27242733tm -> tm_wday = (date2j (tm -> tm_year ,tm -> tm_mon ,tm -> tm_mday )+ 1 ) %7 ;
@@ -2727,29 +2736,28 @@ datetime_to_char_body(TmToChar *tmtc, text *fmt)
27272736/*
27282737 * Convert fmt to C string
27292738 */
2730- str_fmt = (char * )palloc (len + 1 );
2731- memcpy (str_fmt ,VARDATA (fmt ),len );
2732- * (str_fmt + len )= '\0' ;
2739+ fmt_str = (char * )palloc (fmt_len + 1 );
2740+ memcpy (fmt_str ,VARDATA (fmt ),fmt_len );
2741+ * (fmt_str + fmt_len )= '\0' ;
27332742
27342743/*
27352744 * Allocate result
27362745 */
2737- result = palloc ((len * DCH_MAX_ITEM_SIZ )+ 1 );
2746+ result = palloc ((fmt_len * DCH_MAX_ITEM_SIZ )+ 1 );
27382747
27392748/*
27402749 * Allocate new memory if format picture is bigger than static cache
2741- * and not use cache (call parser always) - incache=FALSE show this
2742- * variant
2750+ * and not use cache (call parser always)
27432751 */
2744- if (len > DCH_CACHE_SIZE )
2752+ if (fmt_len > DCH_CACHE_SIZE )
27452753{
2746- format = (FormatNode * )palloc ((len + 1 )* sizeof (FormatNode ));
2754+ format = (FormatNode * )palloc ((fmt_len + 1 )* sizeof (FormatNode ));
27472755incache = FALSE;
27482756
2749- parse_format (format ,str_fmt ,DCH_keywords ,
2757+ parse_format (format ,fmt_str ,DCH_keywords ,
27502758DCH_suff ,DCH_index ,DCH_TYPE ,NULL );
27512759
2752- (format + len )-> type = NODE_TYPE_END ;/* Paranoia? */
2760+ (format + fmt_len )-> type = NODE_TYPE_END ;/* Paranoia? */
27532761
27542762}
27552763else
@@ -2758,25 +2766,24 @@ datetime_to_char_body(TmToChar *tmtc, text *fmt)
27582766 * Use cache buffers
27592767 */
27602768DCHCacheEntry * ent ;
2761-
27622769incache = TRUE;
27632770
2764- if ((ent = DCH_cache_search (str_fmt ))== NULL )
2771+ if ((ent = DCH_cache_search (fmt_str ))== NULL )
27652772{
27662773
2767- ent = DCH_cache_getnew (str_fmt );
2774+ ent = DCH_cache_getnew (fmt_str );
27682775
27692776/*
27702777 * Not in the cache, must run parser and save a new
27712778 * format-picture to the cache.
27722779 */
2773- parse_format (ent -> format ,str_fmt ,DCH_keywords ,
2780+ parse_format (ent -> format ,fmt_str ,DCH_keywords ,
27742781DCH_suff ,DCH_index ,DCH_TYPE ,NULL );
27752782
2776- (ent -> format + len )-> type = NODE_TYPE_END ;/* Paranoia? */
2783+ (ent -> format + fmt_len )-> type = NODE_TYPE_END ;/* Paranoia? */
27772784
27782785#ifdef DEBUG_TO_FROM_CHAR
2779- /* dump_node(ent->format,len ); */
2786+ /* dump_node(ent->format,fmt_len ); */
27802787/* dump_index(DCH_keywords, DCH_index); */
27812788#endif
27822789}
@@ -2788,22 +2795,27 @@ datetime_to_char_body(TmToChar *tmtc, text *fmt)
27882795if (!incache )
27892796pfree (format );
27902797
2791- pfree (str_fmt );
2798+ pfree (fmt_str );
27922799
27932800/*
27942801 * for result is allocated max memory, which current format-picture
27952802 * needs, now it allocate result with real size
27962803 */
2797- if (!(len = strlen (result )))
2798- pfree (result );
2799- else
2804+ if (result && * result )
28002805{
2801- text * res = (text * )palloc (len + 1 + VARHDRSZ );
2806+ int len = strlen (result );
2807+
2808+ if (len )
2809+ {
2810+ text * res = (text * )palloc (len + 1 + VARHDRSZ );
28022811
2803- memcpy (VARDATA (res ),result ,len );
2804- VARATT_SIZEP (res )= len + VARHDRSZ ;
2805- return res ;
2812+ memcpy (VARDATA (res ),result ,len );
2813+ VARATT_SIZEP (res )= len + VARHDRSZ ;
2814+ pfree (result );
2815+ return res ;
2816+ }
28062817}
2818+ pfree (result );
28072819return NULL ;
28082820}
28092821
@@ -2953,64 +2965,63 @@ do_to_timestamp(text *date_txt, text *fmt,
29532965{
29542966FormatNode * format ;
29552967TmFromChar tmfc ;
2956- bool incache ;
2957- char * str ;
2958- char * date_str ;
2959- int len ,
2960- date_len ;
2968+ int fmt_len ;
29612969
29622970ZERO_tm (tm );
29632971* fsec = 0 ;
29642972
29652973ZERO_tmfc (& tmfc );
29662974
2967- len = VARSIZE (fmt )- VARHDRSZ ;
2975+ fmt_len = VARSIZE (fmt )- VARHDRSZ ;
29682976
2969- if (len )
2977+ if (fmt_len )
29702978{
2971- str = (char * )palloc (len + 1 );
2972- memcpy (str ,VARDATA (fmt ),len );
2973- * (str + len )= '\0' ;
2979+ int date_len ;
2980+ char * fmt_str ;
2981+ char * date_str ;
2982+ bool incache ;
2983+
2984+ fmt_str = (char * )palloc (fmt_len + 1 );
2985+ memcpy (fmt_str ,VARDATA (fmt ),fmt_len );
2986+ * (fmt_str + fmt_len )= '\0' ;
29742987
29752988/*
29762989 * Allocate new memory if format picture is bigger than static
2977- * cache and not use cache (call parser always) - incache=FALSE
2978- * show this variant
2990+ * cache and not use cache (call parser always)
29792991 */
2980- if (len > DCH_CACHE_SIZE )
2992+ if (fmt_len > DCH_CACHE_SIZE )
29812993{
2982- format = (FormatNode * )palloc ((len + 1 )* sizeof (FormatNode ));
2994+ format = (FormatNode * )palloc ((fmt_len + 1 )* sizeof (FormatNode ));
29832995incache = FALSE;
29842996
2985- parse_format (format ,str ,DCH_keywords ,
2997+ parse_format (format ,fmt_str ,DCH_keywords ,
29862998DCH_suff ,DCH_index ,DCH_TYPE ,NULL );
29872999
2988- (format + len )-> type = NODE_TYPE_END ;/* Paranoia? */
3000+ (format + fmt_len )-> type = NODE_TYPE_END ;/* Paranoia? */
29893001}
29903002else
29913003{
29923004/*
29933005 * Use cache buffers
29943006 */
29953007DCHCacheEntry * ent ;
3008+ incache = TRUE;
29963009
2997- incache = 0 ;
2998-
2999- if ((ent = DCH_cache_search (str ))== NULL )
3010+ if ((ent = DCH_cache_search (fmt_str ))== NULL )
30003011{
30013012
3002- ent = DCH_cache_getnew (str );
3013+ ent = DCH_cache_getnew (fmt_str );
30033014
30043015/*
30053016 * Not in the cache, must run parser and save a new
30063017 * format-picture to the cache.
30073018 */
3008- parse_format (ent -> format ,str ,DCH_keywords ,
3019+ parse_format (ent -> format ,fmt_str ,DCH_keywords ,
30093020DCH_suff ,DCH_index ,DCH_TYPE ,NULL );
30103021
3011- (ent -> format + len )-> type = NODE_TYPE_END ;/* Paranoia? */
3022+ (ent -> format + fmt_len )-> type = NODE_TYPE_END ;/* Paranoia? */
30123023#ifdef DEBUG_TO_FROM_CHAR
3013- /* dump_node(ent->format,len ); */
3024+ /* dump_node(ent->format,fmt_len ); */
30143025/* dump_index(DCH_keywords, DCH_index); */
30153026#endif
30163027}
@@ -3021,7 +3032,7 @@ do_to_timestamp(text *date_txt, text *fmt,
30213032 * Call action for each node in FormatNode tree
30223033 */
30233034#ifdef DEBUG_TO_FROM_CHAR
3024- /* dump_node(format,len ); */
3035+ /* dump_node(format,fmt_len ); */
30253036#endif
30263037
30273038/*
@@ -3035,8 +3046,8 @@ do_to_timestamp(text *date_txt, text *fmt,
30353046DCH_processor (format ,date_str ,FROM_CHAR , (void * )& tmfc );
30363047
30373048pfree (date_str );
3038- pfree (str );
3039- if (incache )
3049+ pfree (fmt_str );
3050+ if (! incache )
30403051pfree (format );
30413052}
30423053