Index: src/backend/utils/adt/formatting.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v retrieving revision 1.94 diff -c -c -r1.94 formatting.c *** src/backend/utils/adt/formatting.c 27 Jul 2005 12:44:09 -0000 1.94 --- src/backend/utils/adt/formatting.c 17 Aug 2005 21:42:02 -0000 *************** *** 136,142 **** const char *name; /* keyword */ int len; /* keyword length */ int (*action) (int arg, char *inout, /* action for keyword */ ! int suf, int flag, FormatNode *node, void *data); int id; /* keyword id */ bool isitdigit; /* is expected output/input digit */ --- 136,142 ---- const char *name; /* keyword */ int len; /* keyword length */ int (*action) (int arg, char *inout, /* action for keyword */ ! int suf, bool is_to_char, FormatNode *node, void *data); int id; /* keyword id */ bool isitdigit; /* is expected output/input digit */ *************** *** 231,239 **** * Flags & Options: * ---------- */ - #define TO_CHAR 1 - #define FROM_CHAR 2 - #define ONE_UPPER 1 /* Name */ #define ALL_UPPER 2 /* NAME */ #define ALL_LOWER 3 /* name */ --- 231,236 ---- *************** *** 250,260 **** * Flags for DCH version * ---------- */ ! static int DCH_global_flag = 0; ! ! #define DCH_F_FX 0x01 ! ! #define IS_FX (DCH_global_flag & DCH_F_FX) /* ---------- --- 247,253 ---- * Flags for DCH version * ---------- */ ! static bool DCH_global_fx = false; /* ---------- *************** *** 440,448 **** * KeyWords definition & action *****************************************************************************/ ! static int dch_global(int arg, char *inout, int suf, int flag, FormatNode *node, void *data); ! static int dch_time(int arg, char *inout, int suf, int flag, FormatNode *node, void *data); ! static int dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data); /* ---------- * Suffixes: --- 433,441 ---- * KeyWords definition & action *****************************************************************************/ ! static int dch_global(int arg, char *inout, int suf, bool is_to_char, FormatNode *node, void *data); ! static int dch_time(int arg, char *inout, int suf, bool is_to_char, FormatNode *node, void *data); ! static int dch_date(int arg, char *inout, int suf, bool is_to_char, FormatNode *node, void *data); /* ---------- * Suffixes: *************** *** 843,850 **** */ typedef struct NUMProc { ! int type; /* FROM_CHAR (TO_NUMBER) or TO_CHAR */ ! NUMDesc *Num; /* number description */ int sign, /* '-' or '+' */ --- 836,842 ---- */ typedef struct NUMProc { ! bool is_to_char; NUMDesc *Num; /* number description */ int sign, /* '-' or '+' */ *************** *** 883,889 **** static void NUMDesc_prepare(NUMDesc *num, FormatNode *n); static void parse_format(FormatNode *node, char *str, const KeyWord *kw, KeySuffix *suf, const int *index, int ver, NUMDesc *Num); ! static char *DCH_processor(FormatNode *node, char *inout, int flag, void *data); #ifdef DEBUG_TO_FROM_CHAR static void dump_index(const KeyWord *k, const int *index); --- 875,881 ---- static void NUMDesc_prepare(NUMDesc *num, FormatNode *n); static void parse_format(FormatNode *node, char *str, const KeyWord *kw, KeySuffix *suf, const int *index, int ver, NUMDesc *Num); ! static char *DCH_processor(FormatNode *node, char *inout, bool is_to_char, void *data); #ifdef DEBUG_TO_FROM_CHAR static void dump_index(const KeyWord *k, const int *index); *************** *** 908,914 **** static void NUM_numpart_from_char(NUMProc *Np, int id, int plen); static void NUM_numpart_to_char(NUMProc *Np, int id); static char *NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number, ! int plen, int sign, int type); static DCHCacheEntry *DCH_cache_search(char *str); static DCHCacheEntry *DCH_cache_getnew(char *str); --- 900,906 ---- static void NUM_numpart_from_char(NUMProc *Np, int id, int plen); static void NUM_numpart_to_char(NUMProc *Np, int id); static char *NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number, ! int plen, int sign, bool is_to_char); static DCHCacheEntry *DCH_cache_search(char *str); static DCHCacheEntry *DCH_cache_getnew(char *str); *************** *** 1298,1304 **** * ---------- */ static char * ! DCH_processor(FormatNode *node, char *inout, int flag, void *data) { FormatNode *n; char *s; --- 1290,1296 ---- * ---------- */ static char * ! DCH_processor(FormatNode *node, char *inout, bool is_to_char, void *data) { FormatNode *n; char *s; *************** *** 1307,1317 **** /* * Zeroing global flags */ ! DCH_global_flag = 0; for (n = node, s = inout; n->type != NODE_TYPE_END; n++) { ! if (flag == FROM_CHAR && *s == '\0') /* * The input string is shorter than format picture, so it's --- 1299,1309 ---- /* * Zeroing global flags */ ! DCH_global_fx = false; for (n = node, s = inout; n->type != NODE_TYPE_END; n++) { ! if (!is_to_char && *s == '\0') /* * The input string is shorter than format picture, so it's *************** *** 1329,1335 **** /* * Call node action function */ ! len = n->key->action(n->key->id, s, n->suffix, flag, n, data); if (len > 0) s += len; else if (len == -1) --- 1321,1327 ---- /* * Call node action function */ ! len = n->key->action(n->key->id, s, n->suffix, is_to_char, n, data); if (len > 0) s += len; else if (len == -1) *************** *** 1341,1366 **** /* * Remove to output char from input in TO_CHAR */ ! if (flag == TO_CHAR) *s = n->character; - else { /* * Skip blank space in FROM_CHAR's input */ ! if (isspace((unsigned char) n->character) && IS_FX == 0) ! { while (*s != '\0' && isspace((unsigned char) *(s + 1))) ++s; - } } } ! ! ++s; /* ! */ } ! if (flag == TO_CHAR) *s = '\0'; return inout; } --- 1333,1354 ---- /* * Remove to output char from input in TO_CHAR */ ! if (is_to_char) *s = n->character; else { /* * Skip blank space in FROM_CHAR's input */ ! if (isspace((unsigned char) n->character) && !DCH_global_fx) while (*s != '\0' && isspace((unsigned char) *(s + 1))) ++s; } } ! ++s; } ! if (is_to_char) *s = '\0'; return inout; } *************** *** 1630,1639 **** * ---------- */ static int ! dch_global(int arg, char *inout, int suf, int flag, FormatNode *node, void *data) { if (arg == DCH_FX) ! DCH_global_flag |= DCH_F_FX; return -1; } --- 1618,1627 ---- * ---------- */ static int ! dch_global(int arg, char *inout, int suf, bool is_to_char, FormatNode *node, void *data) { if (arg == DCH_FX) ! DCH_global_fx = true; return -1; } *************** *** 1696,1709 **** * ---------- */ static int ! dch_time(int arg, char *inout, int suf, int flag, FormatNode *node, void *data) { char *p_inout = inout; struct pg_tm *tm = NULL; TmFromChar *tmfc = NULL; TmToChar *tmtc = NULL; ! if (flag == TO_CHAR) { tmtc = (TmToChar *) data; tm = tmtcTm(tmtc); --- 1684,1697 ---- * ---------- */ static int ! dch_time(int arg, char *inout, int suf, bool is_to_char, FormatNode *node, void *data) { char *p_inout = inout; struct pg_tm *tm = NULL; TmFromChar *tmfc = NULL; TmToChar *tmtc = NULL; ! if (is_to_char) { tmtc = (TmToChar *) data; tm = tmtcTm(tmtc); *************** *** 1715,1727 **** { case DCH_A_M: case DCH_P_M: ! if (flag == TO_CHAR) { strcpy(inout, ((tm->tm_hour > 11 && tm->tm_hour < HOURS_PER_DAY) ? P_M_STR : A_M_STR)); return 3; } ! else if (flag == FROM_CHAR) { if (strncmp(inout, P_M_STR, 4) == 0) tmfc->pm = TRUE; --- 1703,1715 ---- { case DCH_A_M: case DCH_P_M: ! if (is_to_char) { strcpy(inout, ((tm->tm_hour > 11 && tm->tm_hour < HOURS_PER_DAY) ? P_M_STR : A_M_STR)); return 3; } ! else { if (strncmp(inout, P_M_STR, 4) == 0) tmfc->pm = TRUE; *************** *** 1734,1746 **** break; case DCH_AM: case DCH_PM: ! if (flag == TO_CHAR) { strcpy(inout, ((tm->tm_hour > 11 && tm->tm_hour < HOURS_PER_DAY) ? PM_STR : AM_STR)); return 1; } ! else if (flag == FROM_CHAR) { if (strncmp(inout, PM_STR, 2) == 0) tmfc->pm = TRUE; --- 1722,1734 ---- break; case DCH_AM: case DCH_PM: ! if (is_to_char) { strcpy(inout, ((tm->tm_hour > 11 && tm->tm_hour < HOURS_PER_DAY) ? PM_STR : AM_STR)); return 1; } ! else { if (strncmp(inout, PM_STR, 2) == 0) tmfc->pm = TRUE; *************** *** 1753,1765 **** break; case DCH_a_m: case DCH_p_m: ! if (flag == TO_CHAR) { strcpy(inout, ((tm->tm_hour > 11 && tm->tm_hour < HOURS_PER_DAY) ? p_m_STR : a_m_STR)); return 3; } ! else if (flag == FROM_CHAR) { if (strncmp(inout, p_m_STR, 4) == 0) tmfc->pm = TRUE; --- 1741,1753 ---- break; case DCH_a_m: case DCH_p_m: ! if (is_to_char) { strcpy(inout, ((tm->tm_hour > 11 && tm->tm_hour < HOURS_PER_DAY) ? p_m_STR : a_m_STR)); return 3; } ! else { if (strncmp(inout, p_m_STR, 4) == 0) tmfc->pm = TRUE; *************** *** 1772,1784 **** break; case DCH_am: case DCH_pm: ! if (flag == TO_CHAR) { strcpy(inout, ((tm->tm_hour > 11 && tm->tm_hour < HOURS_PER_DAY) ? pm_STR : am_STR)); return 1; } ! else if (flag == FROM_CHAR) { if (strncmp(inout, pm_STR, 2) == 0) tmfc->pm = TRUE; --- 1760,1772 ---- break; case DCH_am: case DCH_pm: ! if (is_to_char) { strcpy(inout, ((tm->tm_hour > 11 && tm->tm_hour < HOURS_PER_DAY) ? pm_STR : am_STR)); return 1; } ! else { if (strncmp(inout, pm_STR, 2) == 0) tmfc->pm = TRUE; *************** *** 1791,1797 **** break; case DCH_HH: case DCH_HH12: ! if (flag == TO_CHAR) { sprintf(inout, "%0*d", S_FM(suf) ? 0 : 2, tm->tm_hour == 0 ? 12 : --- 1779,1785 ---- break; case DCH_HH: case DCH_HH12: ! if (is_to_char) { sprintf(inout, "%0*d", S_FM(suf) ? 0 : 2, tm->tm_hour == 0 ? 12 : *************** *** 1804,1810 **** return 1; } ! else if (flag == FROM_CHAR) { if (S_FM(suf) || is_next_separator(node)) { --- 1792,1798 ---- return 1; } ! else { if (S_FM(suf) || is_next_separator(node)) { *************** *** 1819,1825 **** } break; case DCH_HH24: ! if (flag == TO_CHAR) { sprintf(inout, "%0*d", S_FM(suf) ? 0 : 2, tm->tm_hour); if (S_THth(suf)) --- 1807,1813 ---- } break; case DCH_HH24: ! if (is_to_char) { sprintf(inout, "%0*d", S_FM(suf) ? 0 : 2, tm->tm_hour); if (S_THth(suf)) *************** *** 1830,1836 **** return 1; } ! else if (flag == FROM_CHAR) { if (S_FM(suf) || is_next_separator(node)) { --- 1818,1824 ---- return 1; } ! else { if (S_FM(suf) || is_next_separator(node)) { *************** *** 1845,1851 **** } break; case DCH_MI: ! if (flag == TO_CHAR) { sprintf(inout, "%0*d", S_FM(suf) ? 0 : 2, tm->tm_min); if (S_THth(suf)) --- 1833,1839 ---- } break; case DCH_MI: ! if (is_to_char) { sprintf(inout, "%0*d", S_FM(suf) ? 0 : 2, tm->tm_min); if (S_THth(suf)) *************** *** 1856,1862 **** return 1; } ! else if (flag == FROM_CHAR) { if (S_FM(suf) || is_next_separator(node)) { --- 1844,1850 ---- return 1; } ! else { if (S_FM(suf) || is_next_separator(node)) { *************** *** 1871,1877 **** } break; case DCH_SS: ! if (flag == TO_CHAR) { sprintf(inout, "%0*d", S_FM(suf) ? 0 : 2, tm->tm_sec); if (S_THth(suf)) --- 1859,1865 ---- } break; case DCH_SS: ! if (is_to_char) { sprintf(inout, "%0*d", S_FM(suf) ? 0 : 2, tm->tm_sec); if (S_THth(suf)) *************** *** 1882,1888 **** return 1; } ! else if (flag == FROM_CHAR) { if (S_FM(suf) || is_next_separator(node)) { --- 1870,1876 ---- return 1; } ! else { if (S_FM(suf) || is_next_separator(node)) { *************** *** 1897,1903 **** } break; case DCH_MS: /* millisecond */ ! if (flag == TO_CHAR) { #ifdef HAVE_INT64_TIMESTAMP sprintf(inout, "%03d", (int) (tmtc->fsec / INT64CONST(1000))); --- 1885,1891 ---- } break; case DCH_MS: /* millisecond */ ! if (is_to_char) { #ifdef HAVE_INT64_TIMESTAMP sprintf(inout, "%03d", (int) (tmtc->fsec / INT64CONST(1000))); *************** *** 1912,1918 **** return 2; } ! else if (flag == FROM_CHAR) { int len, x; --- 1900,1906 ---- return 2; } ! else { int len, x; *************** *** 1944,1950 **** } break; case DCH_US: /* microsecond */ ! if (flag == TO_CHAR) { #ifdef HAVE_INT64_TIMESTAMP sprintf(inout, "%06d", (int) tmtc->fsec); --- 1932,1938 ---- } break; case DCH_US: /* microsecond */ ! if (is_to_char) { #ifdef HAVE_INT64_TIMESTAMP sprintf(inout, "%06d", (int) tmtc->fsec); *************** *** 1958,1964 **** else return 5; } ! else if (flag == FROM_CHAR) { int len, x; --- 1946,1952 ---- else return 5; } ! else { int len, x; *************** *** 1989,1995 **** } break; case DCH_SSSS: ! if (flag == TO_CHAR) { sprintf(inout, "%d", tm->tm_hour * SECS_PER_HOUR + tm->tm_min * SECS_PER_MINUTE + --- 1977,1983 ---- } break; case DCH_SSSS: ! if (is_to_char) { sprintf(inout, "%d", tm->tm_hour * SECS_PER_HOUR + tm->tm_min * SECS_PER_MINUTE + *************** *** 1998,2004 **** str_numth(p_inout, inout, S_TH_TYPE(suf)); return strlen(p_inout) - 1; } ! else if (flag == FROM_CHAR) { if (S_FM(suf) || is_next_separator(node)) { --- 1986,1992 ---- str_numth(p_inout, inout, S_TH_TYPE(suf)); return strlen(p_inout) - 1; } ! else { if (S_FM(suf) || is_next_separator(node)) { *************** *** 2014,2020 **** break; case DCH_tz: case DCH_TZ: ! if (flag == TO_CHAR && tmtcTzn(tmtc)) { int siz = strlen(tmtcTzn(tmtc)); --- 2002,2008 ---- break; case DCH_tz: case DCH_TZ: ! if (is_to_char && tmtcTzn(tmtc)) { int siz = strlen(tmtcTzn(tmtc)); *************** *** 2030,2036 **** } return siz - 1; } ! else if (flag == FROM_CHAR) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("\"TZ\"/\"tz\" not supported"))); --- 2018,2024 ---- } return siz - 1; } ! else if (!is_to_char) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("\"TZ\"/\"tz\" not supported"))); *************** *** 2055,2061 **** * ---------- */ static int ! dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data) { char buff[DCH_CACHE_SIZE], workbuff[32], --- 2043,2049 ---- * ---------- */ static int ! dch_date(int arg, char *inout, int suf, bool is_to_char, FormatNode *node, void *data) { char buff[DCH_CACHE_SIZE], workbuff[32], *************** *** 2066,2072 **** TmFromChar *tmfc = NULL; TmToChar *tmtc = NULL; ! if (flag == TO_CHAR) { tmtc = (TmToChar *) data; tm = tmtcTm(tmtc); --- 2054,2060 ---- TmFromChar *tmfc = NULL; TmToChar *tmtc = NULL; ! if (is_to_char) { tmtc = (TmToChar *) data; tm = tmtcTm(tmtc); *************** *** 2081,2087 **** * or "january", all is before search convert to "first-upper". This * convention is used for MONTH, MON, DAY, DY */ ! if (flag == FROM_CHAR) { if (arg == DCH_MONTH || arg == DCH_Month || arg == DCH_month) { --- 2069,2075 ---- * or "january", all is before search convert to "first-upper". This * convention is used for MONTH, MON, DAY, DY */ ! if (!is_to_char) { if (arg == DCH_MONTH || arg == DCH_Month || arg == DCH_month) { *************** *** 2121,2133 **** { case DCH_A_D: case DCH_B_C: ! if (flag == TO_CHAR) { strcpy(inout, (tm->tm_year <= 0 ? B_C_STR : A_D_STR)); return 3; } ! else if (flag == FROM_CHAR) { if (strncmp(inout, B_C_STR, 4) == 0) tmfc->bc = TRUE; --- 2109,2121 ---- { case DCH_A_D: case DCH_B_C: ! if (is_to_char) { strcpy(inout, (tm->tm_year <= 0 ? B_C_STR : A_D_STR)); return 3; } ! else { if (strncmp(inout, B_C_STR, 4) == 0) tmfc->bc = TRUE; *************** *** 2136,2148 **** break; case DCH_AD: case DCH_BC: ! if (flag == TO_CHAR) { strcpy(inout, (tm->tm_year <= 0 ? BC_STR : AD_STR)); return 1; } ! else if (flag == FROM_CHAR) { if (strncmp(inout, BC_STR, 2) == 0) tmfc->bc = TRUE; --- 2124,2136 ---- break; case DCH_AD: case DCH_BC: ! if (is_to_char) { strcpy(inout, (tm->tm_year <= 0 ? BC_STR : AD_STR)); return 1; } ! else { if (strncmp(inout, BC_STR, 2) == 0) tmfc->bc = TRUE; *************** *** 2151,2163 **** break; case DCH_a_d: case DCH_b_c: ! if (flag == TO_CHAR) { strcpy(inout, (tm->tm_year <= 0 ? b_c_STR : a_d_STR)); return 3; } ! else if (flag == FROM_CHAR) { if (strncmp(inout, b_c_STR, 4) == 0) tmfc->bc = TRUE; --- 2139,2151 ---- break; case DCH_a_d: case DCH_b_c: ! if (is_to_char) { strcpy(inout, (tm->tm_year <= 0 ? b_c_STR : a_d_STR)); return 3; } ! else { if (strncmp(inout, b_c_STR, 4) == 0) tmfc->bc = TRUE; *************** *** 2166,2178 **** break; case DCH_ad: case DCH_bc: ! if (flag == TO_CHAR) { strcpy(inout, (tm->tm_year <= 0 ? bc_STR : ad_STR)); return 1; } ! else if (flag == FROM_CHAR) { if (strncmp(inout, bc_STR, 2) == 0) tmfc->bc = TRUE; --- 2154,2166 ---- break; case DCH_ad: case DCH_bc: ! if (is_to_char) { strcpy(inout, (tm->tm_year <= 0 ? bc_STR : ad_STR)); return 1; } ! else { if (strncmp(inout, bc_STR, 2) == 0) tmfc->bc = TRUE; *************** *** 2229,2235 **** return 2; case DCH_MM: ! if (flag == TO_CHAR) { sprintf(inout, "%0*d", S_FM(suf) ? 0 : 2, tm->tm_mon); if (S_THth(suf)) --- 2217,2223 ---- return 2; case DCH_MM: ! if (is_to_char) { sprintf(inout, "%0*d", S_FM(suf) ? 0 : 2, tm->tm_mon); if (S_THth(suf)) *************** *** 2239,2245 **** else return 1; } ! else if (flag == FROM_CHAR) { if (S_FM(suf) || is_next_separator(node)) { --- 2227,2233 ---- else return 1; } ! else { if (S_FM(suf) || is_next_separator(node)) { *************** *** 2291,2297 **** return 2; case DCH_DDD: ! if (flag == TO_CHAR) { sprintf(inout, "%0*d", S_FM(suf) ? 0 : 3, tm->tm_yday); if (S_THth(suf)) --- 2279,2285 ---- return 2; case DCH_DDD: ! if (is_to_char) { sprintf(inout, "%0*d", S_FM(suf) ? 0 : 3, tm->tm_yday); if (S_THth(suf)) *************** *** 2302,2308 **** return 2; } ! else if (flag == FROM_CHAR) { if (S_FM(suf) || is_next_separator(node)) { --- 2290,2296 ---- return 2; } ! else { if (S_FM(suf) || is_next_separator(node)) { *************** *** 2317,2323 **** } break; case DCH_DD: ! if (flag == TO_CHAR) { sprintf(inout, "%0*d", S_FM(suf) ? 0 : 2, tm->tm_mday); if (S_THth(suf)) --- 2305,2311 ---- } break; case DCH_DD: ! if (is_to_char) { sprintf(inout, "%0*d", S_FM(suf) ? 0 : 2, tm->tm_mday); if (S_THth(suf)) *************** *** 2328,2334 **** return 1; } ! else if (flag == FROM_CHAR) { if (S_FM(suf) || is_next_separator(node)) { --- 2316,2322 ---- return 1; } ! else { if (S_FM(suf) || is_next_separator(node)) { *************** *** 2343,2349 **** } break; case DCH_D: ! if (flag == TO_CHAR) { sprintf(inout, "%d", tm->tm_wday + 1); if (S_THth(suf)) --- 2331,2337 ---- } break; case DCH_D: ! if (is_to_char) { sprintf(inout, "%d", tm->tm_wday + 1); if (S_THth(suf)) *************** *** 2353,2366 **** } return 0; } ! else if (flag == FROM_CHAR) { sscanf(inout, "%1d", &tmfc->d); return 0 + SKIP_THth(suf); } break; case DCH_WW: ! if (flag == TO_CHAR) { sprintf(inout, "%0*d", S_FM(suf) ? 0 : 2, (tm->tm_yday - 1) / 7 + 1); --- 2341,2354 ---- } return 0; } ! else { sscanf(inout, "%1d", &tmfc->d); return 0 + SKIP_THth(suf); } break; case DCH_WW: ! if (is_to_char) { sprintf(inout, "%0*d", S_FM(suf) ? 0 : 2, (tm->tm_yday - 1) / 7 + 1); *************** *** 2372,2378 **** return 1; } ! else if (flag == FROM_CHAR) { if (S_FM(suf) || is_next_separator(node)) { --- 2360,2366 ---- return 1; } ! else { if (S_FM(suf) || is_next_separator(node)) { *************** *** 2387,2393 **** } break; case DCH_IW: ! if (flag == TO_CHAR) { sprintf(inout, "%0*d", S_FM(suf) ? 0 : 2, date2isoweek(tm->tm_year, tm->tm_mon, tm->tm_mday)); --- 2375,2381 ---- } break; case DCH_IW: ! if (is_to_char) { sprintf(inout, "%0*d", S_FM(suf) ? 0 : 2, date2isoweek(tm->tm_year, tm->tm_mon, tm->tm_mday)); *************** *** 2398,2404 **** else return 1; } ! else if (flag == FROM_CHAR) { if (S_FM(suf) || is_next_separator(node)) { --- 2386,2392 ---- else return 1; } ! else { if (S_FM(suf) || is_next_separator(node)) { *************** *** 2413,2419 **** } break; case DCH_Q: ! if (flag == TO_CHAR) { if (!tm->tm_mon) return -1; --- 2401,2407 ---- } break; case DCH_Q: ! if (is_to_char) { if (!tm->tm_mon) return -1; *************** *** 2425,2438 **** } return 0; } ! else if (flag == FROM_CHAR) { sscanf(inout, "%1d", &tmfc->q); return 0 + SKIP_THth(suf); } break; case DCH_CC: ! if (flag == TO_CHAR) { i = tm->tm_year / 100 + 1; if (i <= 99 && i >= -99) --- 2413,2426 ---- } return 0; } ! else { sscanf(inout, "%1d", &tmfc->q); return 0 + SKIP_THth(suf); } break; case DCH_CC: ! if (is_to_char) { i = tm->tm_year / 100 + 1; if (i <= 99 && i >= -99) *************** *** 2444,2450 **** return strlen(p_inout) - 1; } ! else if (flag == FROM_CHAR) { if (S_FM(suf) || is_next_separator(node)) { --- 2432,2438 ---- return strlen(p_inout) - 1; } ! else { if (S_FM(suf) || is_next_separator(node)) { *************** *** 2459,2465 **** } break; case DCH_Y_YYY: ! if (flag == TO_CHAR) { i = YEAR_ABS(tm->tm_year) / 1000; sprintf(inout, "%d,%03d", i, YEAR_ABS(tm->tm_year) - (i * 1000)); --- 2447,2453 ---- } break; case DCH_Y_YYY: ! if (is_to_char) { i = YEAR_ABS(tm->tm_year) / 1000; sprintf(inout, "%d,%03d", i, YEAR_ABS(tm->tm_year) - (i * 1000)); *************** *** 2467,2473 **** str_numth(p_inout, inout, S_TH_TYPE(suf)); return strlen(p_inout) - 1; } ! else if (flag == FROM_CHAR) { int cc; --- 2455,2461 ---- str_numth(p_inout, inout, S_TH_TYPE(suf)); return strlen(p_inout) - 1; } ! else { int cc; *************** *** 2479,2485 **** break; case DCH_YYYY: case DCH_IYYY: ! if (flag == TO_CHAR) { if (tm->tm_year <= 9999 && tm->tm_year >= -9998) sprintf(inout, "%0*d", --- 2467,2473 ---- break; case DCH_YYYY: case DCH_IYYY: ! if (is_to_char) { if (tm->tm_year <= 9999 && tm->tm_year >= -9998) sprintf(inout, "%0*d", *************** *** 2502,2508 **** str_numth(p_inout, inout, S_TH_TYPE(suf)); return strlen(p_inout) - 1; } ! else if (flag == FROM_CHAR) { if (S_FM(suf) || is_next_separator(node)) { --- 2490,2496 ---- str_numth(p_inout, inout, S_TH_TYPE(suf)); return strlen(p_inout) - 1; } ! else { if (S_FM(suf) || is_next_separator(node)) { *************** *** 2520,2526 **** break; case DCH_YYY: case DCH_IYY: ! if (flag == TO_CHAR) { snprintf(buff, sizeof(buff), "%03d", arg == DCH_YYY ? --- 2508,2514 ---- break; case DCH_YYY: case DCH_IYY: ! if (is_to_char) { snprintf(buff, sizeof(buff), "%03d", arg == DCH_YYY ? *************** *** 2537,2543 **** return 2; } ! else if (flag == FROM_CHAR) { sscanf(inout, "%03d", &tmfc->year); --- 2525,2531 ---- return 2; } ! else { sscanf(inout, "%03d", &tmfc->year); *************** *** 2555,2561 **** break; case DCH_YY: case DCH_IY: ! if (flag == TO_CHAR) { snprintf(buff, sizeof(buff), "%02d", arg == DCH_YY ? --- 2543,2549 ---- break; case DCH_YY: case DCH_IY: ! if (is_to_char) { snprintf(buff, sizeof(buff), "%02d", arg == DCH_YY ? *************** *** 2572,2578 **** return 1; } ! else if (flag == FROM_CHAR) { sscanf(inout, "%02d", &tmfc->year); --- 2560,2566 ---- return 1; } ! else { sscanf(inout, "%02d", &tmfc->year); *************** *** 2590,2596 **** break; case DCH_Y: case DCH_I: ! if (flag == TO_CHAR) { snprintf(buff, sizeof(buff), "%1d", arg == DCH_Y ? --- 2578,2584 ---- break; case DCH_Y: case DCH_I: ! if (is_to_char) { snprintf(buff, sizeof(buff), "%1d", arg == DCH_Y ? *************** *** 2607,2613 **** return 0; } ! else if (flag == FROM_CHAR) { sscanf(inout, "%1d", &tmfc->year); --- 2595,2601 ---- return 0; } ! else { sscanf(inout, "%1d", &tmfc->year); *************** *** 2620,2626 **** } break; case DCH_RM: ! if (flag == TO_CHAR) { if (!tm->tm_mon) return -1; --- 2608,2614 ---- } break; case DCH_RM: ! if (is_to_char) { if (!tm->tm_mon) return -1; *************** *** 2632,2638 **** return 3; } ! else if (flag == FROM_CHAR) { tmfc->mm = 12 - seq_search(inout, rm_months_upper, ALL_UPPER, FULL_SIZ, &len); CHECK_SEQ_SEARCH(len, "RM"); --- 2620,2626 ---- return 3; } ! else { tmfc->mm = 12 - seq_search(inout, rm_months_upper, ALL_UPPER, FULL_SIZ, &len); CHECK_SEQ_SEARCH(len, "RM"); *************** *** 2643,2649 **** } break; case DCH_rm: ! if (flag == TO_CHAR) { if (!tm->tm_mon) return -1; --- 2631,2637 ---- } break; case DCH_rm: ! if (is_to_char) { if (!tm->tm_mon) return -1; *************** *** 2655,2661 **** return 3; } ! else if (flag == FROM_CHAR) { tmfc->mm = 12 - seq_search(inout, rm_months_lower, ALL_LOWER, FULL_SIZ, &len); CHECK_SEQ_SEARCH(len, "rm"); --- 2643,2649 ---- return 3; } ! else { tmfc->mm = 12 - seq_search(inout, rm_months_lower, ALL_LOWER, FULL_SIZ, &len); CHECK_SEQ_SEARCH(len, "rm"); *************** *** 2666,2672 **** } break; case DCH_W: ! if (flag == TO_CHAR) { sprintf(inout, "%d", (tm->tm_mday - 1) / 7 + 1); if (S_THth(suf)) --- 2654,2660 ---- } break; case DCH_W: ! if (is_to_char) { sprintf(inout, "%d", (tm->tm_mday - 1) / 7 + 1); if (S_THth(suf)) *************** *** 2676,2696 **** } return 0; } ! else if (flag == FROM_CHAR) { sscanf(inout, "%1d", &tmfc->w); return 0 + SKIP_THth(suf); } break; case DCH_J: ! if (flag == TO_CHAR) { sprintf(inout, "%d", date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)); if (S_THth(suf)) str_numth(p_inout, inout, S_TH_TYPE(suf)); return strlen(p_inout) - 1; } ! else if (flag == FROM_CHAR) { sscanf(inout, "%d", &tmfc->j); return strdigits_len(inout) - 1 + SKIP_THth(suf); --- 2664,2684 ---- } return 0; } ! else { sscanf(inout, "%1d", &tmfc->w); return 0 + SKIP_THth(suf); } break; case DCH_J: ! if (is_to_char) { sprintf(inout, "%d", date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)); if (S_THth(suf)) str_numth(p_inout, inout, S_TH_TYPE(suf)); return strlen(p_inout) - 1; } ! else { sscanf(inout, "%d", &tmfc->j); return strdigits_len(inout) - 1 + SKIP_THth(suf); *************** *** 2857,2863 **** format = ent->format; } ! DCH_processor(format, result, TO_CHAR, (void *) tmtc); if (!incache) pfree(format); --- 2845,2851 ---- format = ent->format; } ! DCH_processor(format, result, true, (void *) tmtc); if (!incache) pfree(format); *************** *** 3111,3117 **** memcpy(date_str, VARDATA(date_txt), date_len); *(date_str + date_len) = '\0'; ! DCH_processor(format, date_str, FROM_CHAR, (void *) &tmfc); pfree(date_str); pfree(fmt_str); --- 3099,3105 ---- memcpy(date_str, VARDATA(date_txt), date_len); *(date_str + date_len) = '\0'; ! DCH_processor(format, date_str, false, (void *) &tmfc); pfree(date_str); pfree(fmt_str); *************** *** 4081,4087 **** */ static char * NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number, ! int plen, int sign, int type) { FormatNode *n; NUMProc _Np, --- 4069,4075 ---- */ static char * NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number, ! int plen, int sign, bool is_to_char) { FormatNode *n; NUMProc _Np, *************** *** 4090,4096 **** MemSet(Np, 0, sizeof(NUMProc)); Np->Num = Num; ! Np->type = type; Np->number = number; Np->inout = inout; Np->last_relevant = NULL; --- 4078,4084 ---- MemSet(Np, 0, sizeof(NUMProc)); Np->Num = Num; ! Np->is_to_char = is_to_char; Np->number = number; Np->inout = inout; Np->last_relevant = NULL; *************** *** 4106,4112 **** */ if (IS_ROMAN(Np->Num)) { ! if (Np->type == FROM_CHAR) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("\"RN\" not supported"))); --- 4094,4100 ---- */ if (IS_ROMAN(Np->Num)) { ! if (!Np->is_to_char) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("\"RN\" not supported"))); *************** *** 4127,4135 **** /* * Sign */ ! if (type == FROM_CHAR) ! Np->sign = FALSE; ! else { Np->sign = sign; --- 4115,4121 ---- /* * Sign */ ! if (is_to_char) { Np->sign = sign; *************** *** 4162,4174 **** Np->Num->lsign = NUM_LSIGN_POST; } } /* * Count */ Np->num_count = Np->Num->post + Np->Num->pre - 1; ! if (type == TO_CHAR) { Np->num_pre = plen; --- 4148,4162 ---- Np->Num->lsign = NUM_LSIGN_POST; } } + else + Np->sign = FALSE; /* * Count */ Np->num_count = Np->Num->post + Np->Num->pre - 1; ! if (is_to_char) { Np->num_pre = plen; *************** *** 4224,4238 **** /* * Processor direct cycle */ ! if (Np->type == FROM_CHAR) ! Np->number_p = Np->number + 1; /* first char is space for sign */ ! else if (Np->type == TO_CHAR) Np->number_p = Np->number; for (n = node, Np->inout_p = Np->inout; n->type != NODE_TYPE_END; n++) { ! ! if (Np->type == FROM_CHAR) { /* * Check non-string inout end --- 4212,4225 ---- /* * Processor direct cycle */ ! if (Np->is_to_char) Np->number_p = Np->number; + else + Np->number_p = Np->number + 1; /* first char is space for sign */ for (n = node, Np->inout_p = Np->inout; n->type != NODE_TYPE_END; n++) { ! if (!Np->is_to_char) { /* * Check non-string inout end *************** *** 4261,4267 **** case NUM_0: case NUM_DEC: case NUM_D: ! if (Np->type == TO_CHAR) { NUM_numpart_to_char(Np, n->key->id); continue; /* for() */ --- 4248,4254 ---- case NUM_0: case NUM_DEC: case NUM_D: ! if (Np->is_to_char) { NUM_numpart_to_char(Np, n->key->id); continue; /* for() */ *************** *** 4273,4279 **** } case NUM_COMMA: ! if (Np->type == TO_CHAR) { if (!Np->num_in) { --- 4260,4266 ---- } case NUM_COMMA: ! if (Np->is_to_char) { if (!Np->num_in) { *************** *** 4284,4292 **** } else *Np->inout_p = ','; - } ! else if (Np->type == FROM_CHAR) { if (!Np->num_in) { --- 4271,4278 ---- } else *Np->inout_p = ','; } ! else { if (!Np->num_in) { *************** *** 4297,4303 **** break; case NUM_G: ! if (Np->type == TO_CHAR) { if (!Np->num_in) { --- 4283,4289 ---- break; case NUM_G: ! if (Np->is_to_char) { if (!Np->num_in) { *************** *** 4318,4324 **** } } ! else if (Np->type == FROM_CHAR) { if (!Np->num_in) { --- 4304,4310 ---- } } ! else { if (!Np->num_in) { *************** *** 4330,4342 **** break; case NUM_L: ! if (Np->type == TO_CHAR) { strcpy(Np->inout_p, Np->L_currency_symbol); Np->inout_p += strlen(Np->inout_p) - 1; } ! else if (Np->type == FROM_CHAR) Np->inout_p += strlen(Np->L_currency_symbol) - 1; break; --- 4316,4328 ---- break; case NUM_L: ! if (Np->is_to_char) { strcpy(Np->inout_p, Np->L_currency_symbol); Np->inout_p += strlen(Np->inout_p) - 1; } ! else Np->inout_p += strlen(Np->L_currency_symbol) - 1; break; *************** *** 4371,4377 **** Np->sign == '-' || IS_DECIMAL(Np->Num)) continue; ! if (Np->type == TO_CHAR) strcpy(Np->inout_p, get_th(Np->number, TH_LOWER)); Np->inout_p += 1; break; --- 4357,4363 ---- Np->sign == '-' || IS_DECIMAL(Np->Num)) continue; ! if (Np->is_to_char) strcpy(Np->inout_p, get_th(Np->number, TH_LOWER)); Np->inout_p += 1; break; *************** *** 4381,4393 **** Np->sign == '-' || IS_DECIMAL(Np->Num)) continue; ! if (Np->type == TO_CHAR) strcpy(Np->inout_p, get_th(Np->number, TH_UPPER)); Np->inout_p += 1; break; case NUM_MI: ! if (Np->type == TO_CHAR) { if (Np->sign == '-') *Np->inout_p = '-'; --- 4367,4379 ---- Np->sign == '-' || IS_DECIMAL(Np->Num)) continue; ! if (Np->is_to_char) strcpy(Np->inout_p, get_th(Np->number, TH_UPPER)); Np->inout_p += 1; break; case NUM_MI: ! if (Np->is_to_char) { if (Np->sign == '-') *Np->inout_p = '-'; *************** *** 4397,4403 **** *Np->inout_p = ' '; } ! else if (Np->type == FROM_CHAR) { if (*Np->inout_p == '-') *Np->number = '-'; --- 4383,4389 ---- *Np->inout_p = ' '; } ! else { if (*Np->inout_p == '-') *Np->number = '-'; *************** *** 4405,4411 **** break; case NUM_PL: ! if (Np->type == TO_CHAR) { if (Np->sign == '+') *Np->inout_p = '+'; --- 4391,4397 ---- break; case NUM_PL: ! if (Np->is_to_char) { if (Np->sign == '+') *Np->inout_p = '+'; *************** *** 4415,4421 **** *Np->inout_p = ' '; } ! else if (Np->type == FROM_CHAR) { if (*Np->inout_p == '+') *Np->number = '+'; --- 4401,4407 ---- *Np->inout_p = ' '; } ! else { if (*Np->inout_p == '+') *Np->number = '+'; *************** *** 4423,4432 **** break; case NUM_SG: ! if (Np->type == TO_CHAR) *Np->inout_p = Np->sign; ! else if (Np->type == FROM_CHAR) { if (*Np->inout_p == '-') *Np->number = '-'; --- 4409,4418 ---- break; case NUM_SG: ! if (Np->is_to_char) *Np->inout_p = Np->sign; ! else { if (*Np->inout_p == '-') *Np->number = '-'; *************** *** 4447,4465 **** /* * Remove to output char from input in TO_CHAR */ ! if (Np->type == TO_CHAR) *Np->inout_p = n->character; } Np->inout_p++; } ! if (Np->type == TO_CHAR) { *Np->inout_p = '\0'; return Np->inout; - } ! else if (Np->type == FROM_CHAR) { if (*(Np->number_p - 1) == '.') --- 4433,4450 ---- /* * Remove to output char from input in TO_CHAR */ ! if (Np->is_to_char) *Np->inout_p = n->character; } Np->inout_p++; } ! if (Np->is_to_char) { *Np->inout_p = '\0'; return Np->inout; } ! else { if (*(Np->number_p - 1) == '.') *************** *** 4505,4511 **** #define NUM_TOCHAR_finish \ do { \ NUM_processor(format, &Num, VARDATA(result), \ ! numstr, plen, sign, TO_CHAR); \ pfree(orgnum); \ \ if (shouldFree) \ --- 4490,4496 ---- #define NUM_TOCHAR_finish \ do { \ NUM_processor(format, &Num, VARDATA(result), \ ! numstr, plen, sign, true); \ pfree(orgnum); \ \ if (shouldFree) \ *************** *** 4557,4563 **** numstr = (char *) palloc((len * NUM_MAX_ITEM_SIZ) + 1); NUM_processor(format, &Num, VARDATA(value), numstr, ! VARSIZE(value) - VARHDRSZ, 0, FROM_CHAR); scale = Num.post; precision = Max(0, Num.pre) + scale; --- 4542,4548 ---- numstr = (char *) palloc((len * NUM_MAX_ITEM_SIZ) + 1); NUM_processor(format, &Num, VARDATA(value), numstr, ! VARSIZE(value) - VARHDRSZ, 0, false); scale = Num.post; precision = Max(0, Num.pre) + scale;