Prevent to_char(interval) from dumping core on month-related formats
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 26 Mar 2005 00:42:56 +0000 (00:42 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 26 Mar 2005 00:42:56 +0000 (00:42 +0000)
when a zero-month interval is given.  Per discussion with Karel.

src/backend/utils/adt/formatting.c

index d9422587f4f9ef6f4db2a5fc40bd7bbda0250e16..6525729a39d071289e396b0ceaccd333af5f2b0c 100644 (file)
@@ -1,7 +1,7 @@
 /* -----------------------------------------------------------------------
  * formatting.c
  *
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.49 2002/01/04 15:49:42 thomas Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.49.2.1 2005/03/26 00:42:56 tgl Exp $
  *
  *
  *  Portions Copyright (c) 1999-2000, PostgreSQL Global Development Group
@@ -1991,6 +1991,7 @@ static int
 dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
 {
    char        buff[DCH_CACHE_SIZE],
+               workbuff[32],
               *p_inout;
    int         i,
                len;
@@ -2113,14 +2114,18 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
            }
            break;
        case DCH_MONTH:
-           strcpy(inout, months_full[tm->tm_mon - 1]);
-           sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, str_toupper(inout));
+           if (!tm->tm_mon)
+               return -1;
+           strcpy(workbuff, months_full[tm->tm_mon - 1]);
+           sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, str_toupper(workbuff));
            if (S_FM(suf))
                return strlen(p_inout) - 1;
            else
                return 8;
 
        case DCH_Month:
+           if (!tm->tm_mon)
+               return -1;
            sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, months_full[tm->tm_mon - 1]);
            if (S_FM(suf))
                return strlen(p_inout) - 1;
@@ -2128,6 +2133,8 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
                return 8;
 
        case DCH_month:
+           if (!tm->tm_mon)
+               return -1;
            sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, months_full[tm->tm_mon - 1]);
            *inout = tolower((unsigned char) *inout);
            if (S_FM(suf))
@@ -2136,15 +2143,21 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
                return 8;
 
        case DCH_MON:
+           if (!tm->tm_mon)
+               return -1;
            strcpy(inout, months[tm->tm_mon - 1]);
            inout = str_toupper(inout);
            return 2;
 
        case DCH_Mon:
+           if (!tm->tm_mon)
+               return -1;
            strcpy(inout, months[tm->tm_mon - 1]);
            return 2;
 
        case DCH_mon:
+           if (!tm->tm_mon)
+               return -1;
            strcpy(inout, months[tm->tm_mon - 1]);
            *inout = tolower((unsigned char) *inout);
            return 2;
@@ -2159,7 +2172,6 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
                    return strlen(p_inout) - 1;
                else
                    return 1;
-
            }
            else if (flag == FROM_CHAR)
            {
@@ -2176,8 +2188,8 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
            }
            break;
        case DCH_DAY:
-           strcpy(inout, days[tm->tm_wday]);
-           sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, str_toupper(inout));
+           strcpy(workbuff, days[tm->tm_wday]);
+           sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, str_toupper(workbuff));
            if (S_FM(suf))
                return strlen(p_inout) - 1;
            else
@@ -2319,7 +2331,6 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
                    return strlen(p_inout) - 1;
                else
                    return 1;
-
            }
            else if (flag == FROM_CHAR)
            {
@@ -2338,6 +2349,8 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
        case DCH_Q:
            if (flag == TO_CHAR)
            {
+               if (!tm->tm_mon)
+                   return -1;
                sprintf(inout, "%d", (tm->tm_mon - 1) / 3 + 1);
                if (S_THth(suf))
                {
@@ -2345,7 +2358,6 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
                    return 2;
                }
                return 0;
-
            }
            else if (flag == FROM_CHAR)
            {
@@ -2515,6 +2527,8 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
        case DCH_RM:
            if (flag == TO_CHAR)
            {
+               if (!tm->tm_mon)
+                   return -1;
                sprintf(inout, "%*s", S_FM(suf) ? 0 : -4,
                        rm_months_upper[12 - tm->tm_mon]);
                if (S_FM(suf))
@@ -2536,6 +2550,8 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
        case DCH_rm:
            if (flag == TO_CHAR)
            {
+               if (!tm->tm_mon)
+                   return -1;
                sprintf(inout, "%*s", S_FM(suf) ? 0 : -4,
                        rm_months_lower[12 - tm->tm_mon]);
                if (S_FM(suf))