]> granicus.if.org Git - postgresql/blob - src/backend/utils/adt/formatting.c
Fix typos in comments.
[postgresql] / src / backend / utils / adt / formatting.c
1 /* -----------------------------------------------------------------------
2  * formatting.c
3  *
4  * src/backend/utils/adt/formatting.c
5  *
6  *
7  *       Portions Copyright (c) 1999-2017, PostgreSQL Global Development Group
8  *
9  *
10  *       TO_CHAR(); TO_TIMESTAMP(); TO_DATE(); TO_NUMBER();
11  *
12  *       The PostgreSQL routines for a timestamp/int/float/numeric formatting,
13  *       inspired by the Oracle TO_CHAR() / TO_DATE() / TO_NUMBER() routines.
14  *
15  *
16  *       Cache & Memory:
17  *      Routines use (itself) internal cache for format pictures.
18  *
19  *      The cache uses a static buffer and is persistent across transactions.  If
20  *      the format-picture is bigger than the cache buffer, the parser is called
21  *      always.
22  *
23  *       NOTE for Number version:
24  *      All in this version is implemented as keywords ( => not used
25  *      suffixes), because a format picture is for *one* item (number)
26  *      only. It not is as a timestamp version, where each keyword (can)
27  *      has suffix.
28  *
29  *       NOTE for Timestamp routines:
30  *      In this module the POSIX 'struct tm' type is *not* used, but rather
31  *      PgSQL type, which has tm_mon based on one (*non* zero) and
32  *      year *not* based on 1900, but is used full year number.
33  *      Module supports AD / BC / AM / PM.
34  *
35  *      Supported types for to_char():
36  *
37  *              Timestamp, Numeric, int4, int8, float4, float8
38  *
39  *      Supported types for reverse conversion:
40  *
41  *              Timestamp       - to_timestamp()
42  *              Date            - to_date()
43  *              Numeric         - to_number()
44  *
45  *
46  *      Karel Zak
47  *
48  * TODO
49  *      - better number building (formatting) / parsing, now it isn't
50  *                ideal code
51  *      - use Assert()
52  *      - add support for abstime
53  *      - add support for roman number to standard number conversion
54  *      - add support for number spelling
55  *      - add support for string to string formatting (we must be better
56  *        than Oracle :-),
57  *              to_char('Hello', 'X X X X X') -> 'H e l l o'
58  *
59  * -----------------------------------------------------------------------
60  */
61
62 #ifdef DEBUG_TO_FROM_CHAR
63 #define DEBUG_elog_output       DEBUG3
64 #endif
65
66 #include "postgres.h"
67
68 #include <ctype.h>
69 #include <unistd.h>
70 #include <math.h>
71 #include <float.h>
72 #include <limits.h>
73
74 /*
75  * towlower() and friends should be in <wctype.h>, but some pre-C99 systems
76  * declare them in <wchar.h>.
77  */
78 #ifdef HAVE_WCHAR_H
79 #include <wchar.h>
80 #endif
81 #ifdef HAVE_WCTYPE_H
82 #include <wctype.h>
83 #endif
84
85 #include "catalog/pg_collation.h"
86 #include "mb/pg_wchar.h"
87 #include "utils/builtins.h"
88 #include "utils/date.h"
89 #include "utils/datetime.h"
90 #include "utils/formatting.h"
91 #include "utils/int8.h"
92 #include "utils/numeric.h"
93 #include "utils/pg_locale.h"
94
95 /* ----------
96  * Routines type
97  * ----------
98  */
99 #define DCH_TYPE                1               /* DATE-TIME version    */
100 #define NUM_TYPE                2               /* NUMBER version       */
101
102 /* ----------
103  * KeyWord Index (ascii from position 32 (' ') to 126 (~))
104  * ----------
105  */
106 #define KeyWord_INDEX_SIZE              ('~' - ' ')
107 #define KeyWord_INDEX_FILTER(_c)        ((_c) <= ' ' || (_c) >= '~' ? 0 : 1)
108
109 /* ----------
110  * Maximal length of one node
111  * ----------
112  */
113 #define DCH_MAX_ITEM_SIZ           12           /* max localized day name               */
114 #define NUM_MAX_ITEM_SIZ                8               /* roman number (RN has 15 chars)       */
115
116 /* ----------
117  * More is in float.c
118  * ----------
119  */
120 #define MAXFLOATWIDTH   60
121 #define MAXDOUBLEWIDTH  500
122
123
124 /* ----------
125  * Format parser structs
126  * ----------
127  */
128 typedef struct
129 {
130         char       *name;                       /* suffix string                */
131         int                     len,                    /* suffix length                */
132                                 id,                             /* used in node->suffix */
133                                 type;                   /* prefix / postfix                     */
134 } KeySuffix;
135
136 /* ----------
137  * FromCharDateMode
138  * ----------
139  *
140  * This value is used to nominate one of several distinct (and mutually
141  * exclusive) date conventions that a keyword can belong to.
142  */
143 typedef enum
144 {
145         FROM_CHAR_DATE_NONE = 0,        /* Value does not affect date mode. */
146         FROM_CHAR_DATE_GREGORIAN,       /* Gregorian (day, month, year) style date */
147         FROM_CHAR_DATE_ISOWEEK          /* ISO 8601 week date */
148 } FromCharDateMode;
149
150 typedef struct FormatNode FormatNode;
151
152 typedef struct
153 {
154         const char *name;
155         int                     len;
156         int                     id;
157         bool            is_digit;
158         FromCharDateMode date_mode;
159 } KeyWord;
160
161 struct FormatNode
162 {
163         int                     type;                   /* node type                    */
164         const KeyWord *key;                     /* if node type is KEYWORD      */
165         char            character;              /* if node type is CHAR         */
166         int                     suffix;                 /* keyword suffix               */
167 };
168
169 #define NODE_TYPE_END           1
170 #define NODE_TYPE_ACTION        2
171 #define NODE_TYPE_CHAR          3
172
173 #define SUFFTYPE_PREFIX         1
174 #define SUFFTYPE_POSTFIX        2
175
176 #define CLOCK_24_HOUR           0
177 #define CLOCK_12_HOUR           1
178
179
180 /* ----------
181  * Full months
182  * ----------
183  */
184 static const char *const months_full[] = {
185         "January", "February", "March", "April", "May", "June", "July",
186         "August", "September", "October", "November", "December", NULL
187 };
188
189 static const char *const days_short[] = {
190         "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL
191 };
192
193 /* ----------
194  * AD / BC
195  * ----------
196  *      There is no 0 AD.  Years go from 1 BC to 1 AD, so we make it
197  *      positive and map year == -1 to year zero, and shift all negative
198  *      years up one.  For interval years, we just return the year.
199  */
200 #define ADJUST_YEAR(year, is_interval)  ((is_interval) ? (year) : ((year) <= 0 ? -((year) - 1) : (year)))
201
202 #define A_D_STR         "A.D."
203 #define a_d_STR         "a.d."
204 #define AD_STR          "AD"
205 #define ad_STR          "ad"
206
207 #define B_C_STR         "B.C."
208 #define b_c_STR         "b.c."
209 #define BC_STR          "BC"
210 #define bc_STR          "bc"
211
212 /*
213  * AD / BC strings for seq_search.
214  *
215  * These are given in two variants, a long form with periods and a standard
216  * form without.
217  *
218  * The array is laid out such that matches for AD have an even index, and
219  * matches for BC have an odd index.  So the boolean value for BC is given by
220  * taking the array index of the match, modulo 2.
221  */
222 static const char *const adbc_strings[] = {ad_STR, bc_STR, AD_STR, BC_STR, NULL};
223 static const char *const adbc_strings_long[] = {a_d_STR, b_c_STR, A_D_STR, B_C_STR, NULL};
224
225 /* ----------
226  * AM / PM
227  * ----------
228  */
229 #define A_M_STR         "A.M."
230 #define a_m_STR         "a.m."
231 #define AM_STR          "AM"
232 #define am_STR          "am"
233
234 #define P_M_STR         "P.M."
235 #define p_m_STR         "p.m."
236 #define PM_STR          "PM"
237 #define pm_STR          "pm"
238
239 /*
240  * AM / PM strings for seq_search.
241  *
242  * These are given in two variants, a long form with periods and a standard
243  * form without.
244  *
245  * The array is laid out such that matches for AM have an even index, and
246  * matches for PM have an odd index.  So the boolean value for PM is given by
247  * taking the array index of the match, modulo 2.
248  */
249 static const char *const ampm_strings[] = {am_STR, pm_STR, AM_STR, PM_STR, NULL};
250 static const char *const ampm_strings_long[] = {a_m_STR, p_m_STR, A_M_STR, P_M_STR, NULL};
251
252 /* ----------
253  * Months in roman-numeral
254  * (Must be in reverse order for seq_search (in FROM_CHAR), because
255  *      'VIII' must have higher precedence than 'V')
256  * ----------
257  */
258 static const char *const rm_months_upper[] =
259 {"XII", "XI", "X", "IX", "VIII", "VII", "VI", "V", "IV", "III", "II", "I", NULL};
260
261 static const char *const rm_months_lower[] =
262 {"xii", "xi", "x", "ix", "viii", "vii", "vi", "v", "iv", "iii", "ii", "i", NULL};
263
264 /* ----------
265  * Roman numbers
266  * ----------
267  */
268 static const char *const rm1[] = {"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", NULL};
269 static const char *const rm10[] = {"X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC", NULL};
270 static const char *const rm100[] = {"C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM", NULL};
271
272 /* ----------
273  * Ordinal postfixes
274  * ----------
275  */
276 static const char *const numTH[] = {"ST", "ND", "RD", "TH", NULL};
277 static const char *const numth[] = {"st", "nd", "rd", "th", NULL};
278
279 /* ----------
280  * Flags & Options:
281  * ----------
282  */
283 #define ONE_UPPER               1               /* Name */
284 #define ALL_UPPER               2               /* NAME */
285 #define ALL_LOWER               3               /* name */
286
287 #define FULL_SIZ                0
288
289 #define MAX_MONTH_LEN   9
290 #define MAX_MON_LEN             3
291 #define MAX_DAY_LEN             9
292 #define MAX_DY_LEN              3
293 #define MAX_RM_LEN              4
294
295 #define TH_UPPER                1
296 #define TH_LOWER                2
297
298 /* ----------
299  * Number description struct
300  * ----------
301  */
302 typedef struct
303 {
304         int                     pre,                    /* (count) numbers before decimal */
305                                 post,                   /* (count) numbers after decimal  */
306                                 lsign,                  /* want locales sign              */
307                                 flag,                   /* number parameters              */
308                                 pre_lsign_num,  /* tmp value for lsign            */
309                                 multi,                  /* multiplier for 'V'             */
310                                 zero_start,             /* position of first zero         */
311                                 zero_end,               /* position of last zero          */
312                                 need_locale;    /* needs it locale                */
313 } NUMDesc;
314
315 /* ----------
316  * Flags for NUMBER version
317  * ----------
318  */
319 #define NUM_F_DECIMAL           (1 << 1)
320 #define NUM_F_LDECIMAL          (1 << 2)
321 #define NUM_F_ZERO                      (1 << 3)
322 #define NUM_F_BLANK                     (1 << 4)
323 #define NUM_F_FILLMODE          (1 << 5)
324 #define NUM_F_LSIGN                     (1 << 6)
325 #define NUM_F_BRACKET           (1 << 7)
326 #define NUM_F_MINUS                     (1 << 8)
327 #define NUM_F_PLUS                      (1 << 9)
328 #define NUM_F_ROMAN                     (1 << 10)
329 #define NUM_F_MULTI                     (1 << 11)
330 #define NUM_F_PLUS_POST         (1 << 12)
331 #define NUM_F_MINUS_POST        (1 << 13)
332 #define NUM_F_EEEE                      (1 << 14)
333
334 #define NUM_LSIGN_PRE   (-1)
335 #define NUM_LSIGN_POST  1
336 #define NUM_LSIGN_NONE  0
337
338 /* ----------
339  * Tests
340  * ----------
341  */
342 #define IS_DECIMAL(_f)  ((_f)->flag & NUM_F_DECIMAL)
343 #define IS_LDECIMAL(_f) ((_f)->flag & NUM_F_LDECIMAL)
344 #define IS_ZERO(_f) ((_f)->flag & NUM_F_ZERO)
345 #define IS_BLANK(_f)    ((_f)->flag & NUM_F_BLANK)
346 #define IS_FILLMODE(_f) ((_f)->flag & NUM_F_FILLMODE)
347 #define IS_BRACKET(_f)  ((_f)->flag & NUM_F_BRACKET)
348 #define IS_MINUS(_f)    ((_f)->flag & NUM_F_MINUS)
349 #define IS_LSIGN(_f)    ((_f)->flag & NUM_F_LSIGN)
350 #define IS_PLUS(_f) ((_f)->flag & NUM_F_PLUS)
351 #define IS_ROMAN(_f)    ((_f)->flag & NUM_F_ROMAN)
352 #define IS_MULTI(_f)    ((_f)->flag & NUM_F_MULTI)
353 #define IS_EEEE(_f)             ((_f)->flag & NUM_F_EEEE)
354
355 /* ----------
356  * Format picture cache
357  *
358  * We will cache datetime format pictures up to DCH_CACHE_SIZE bytes long;
359  * likewise number format pictures up to NUM_CACHE_SIZE bytes long.
360  *
361  * For simplicity, the cache entries are fixed-size, so they allow for the
362  * worst case of a FormatNode for each byte in the picture string.
363  *
364  * The max number of entries in the caches is DCH_CACHE_ENTRIES
365  * resp. NUM_CACHE_ENTRIES.
366  * ----------
367  */
368 #define NUM_CACHE_SIZE          64
369 #define NUM_CACHE_ENTRIES       20
370 #define DCH_CACHE_SIZE          128
371 #define DCH_CACHE_ENTRIES       20
372
373 typedef struct
374 {
375         FormatNode      format[DCH_CACHE_SIZE + 1];
376         char            str[DCH_CACHE_SIZE + 1];
377         bool            valid;
378         int                     age;
379 } DCHCacheEntry;
380
381 typedef struct
382 {
383         FormatNode      format[NUM_CACHE_SIZE + 1];
384         char            str[NUM_CACHE_SIZE + 1];
385         bool            valid;
386         int                     age;
387         NUMDesc         Num;
388 } NUMCacheEntry;
389
390 /* global cache for date/time format pictures */
391 static DCHCacheEntry DCHCache[DCH_CACHE_ENTRIES];
392 static int      n_DCHCache = 0;         /* current number of entries */
393 static int      DCHCounter = 0;         /* aging-event counter */
394
395 /* global cache for number format pictures */
396 static NUMCacheEntry NUMCache[NUM_CACHE_ENTRIES];
397 static int      n_NUMCache = 0;         /* current number of entries */
398 static int      NUMCounter = 0;         /* aging-event counter */
399
400 /* ----------
401  * For char->date/time conversion
402  * ----------
403  */
404 typedef struct
405 {
406         FromCharDateMode mode;
407         int                     hh,
408                                 pm,
409                                 mi,
410                                 ss,
411                                 ssss,
412                                 d,                              /* stored as 1-7, Sunday = 1, 0 means missing */
413                                 dd,
414                                 ddd,
415                                 mm,
416                                 ms,
417                                 year,
418                                 bc,
419                                 ww,
420                                 w,
421                                 cc,
422                                 j,
423                                 us,
424                                 yysz,                   /* is it YY or YYYY ? */
425                                 clock;                  /* 12 or 24 hour clock? */
426 } TmFromChar;
427
428 #define ZERO_tmfc(_X) memset(_X, 0, sizeof(TmFromChar))
429
430 /* ----------
431  * Debug
432  * ----------
433  */
434 #ifdef DEBUG_TO_FROM_CHAR
435 #define DEBUG_TMFC(_X) \
436                 elog(DEBUG_elog_output, "TMFC:\nmode %d\nhh %d\npm %d\nmi %d\nss %d\nssss %d\nd %d\ndd %d\nddd %d\nmm %d\nms: %d\nyear %d\nbc %d\nww %d\nw %d\ncc %d\nj %d\nus: %d\nyysz: %d\nclock: %d", \
437                         (_X)->mode, (_X)->hh, (_X)->pm, (_X)->mi, (_X)->ss, (_X)->ssss, \
438                         (_X)->d, (_X)->dd, (_X)->ddd, (_X)->mm, (_X)->ms, (_X)->year, \
439                         (_X)->bc, (_X)->ww, (_X)->w, (_X)->cc, (_X)->j, (_X)->us, \
440                         (_X)->yysz, (_X)->clock);
441 #define DEBUG_TM(_X) \
442                 elog(DEBUG_elog_output, "TM:\nsec %d\nyear %d\nmin %d\nwday %d\nhour %d\nyday %d\nmday %d\nnisdst %d\nmon %d\n",\
443                         (_X)->tm_sec, (_X)->tm_year,\
444                         (_X)->tm_min, (_X)->tm_wday, (_X)->tm_hour, (_X)->tm_yday,\
445                         (_X)->tm_mday, (_X)->tm_isdst, (_X)->tm_mon)
446 #else
447 #define DEBUG_TMFC(_X)
448 #define DEBUG_TM(_X)
449 #endif
450
451 /* ----------
452  * Datetime to char conversion
453  * ----------
454  */
455 typedef struct TmToChar
456 {
457         struct pg_tm tm;                        /* classic 'tm' struct */
458         fsec_t          fsec;                   /* fractional seconds */
459         const char *tzn;                        /* timezone */
460 } TmToChar;
461
462 #define tmtcTm(_X)      (&(_X)->tm)
463 #define tmtcTzn(_X) ((_X)->tzn)
464 #define tmtcFsec(_X)    ((_X)->fsec)
465
466 #define ZERO_tm(_X) \
467 do {    \
468         (_X)->tm_sec  = (_X)->tm_year = (_X)->tm_min = (_X)->tm_wday = \
469         (_X)->tm_hour = (_X)->tm_yday = (_X)->tm_isdst = 0; \
470         (_X)->tm_mday = (_X)->tm_mon  = 1; \
471 } while(0)
472
473 #define ZERO_tmtc(_X) \
474 do { \
475         ZERO_tm( tmtcTm(_X) ); \
476         tmtcFsec(_X) = 0; \
477         tmtcTzn(_X) = NULL; \
478 } while(0)
479
480 /*
481  *      to_char(time) appears to to_char() as an interval, so this check
482  *      is really for interval and time data types.
483  */
484 #define INVALID_FOR_INTERVAL  \
485 do { \
486         if (is_interval) \
487                 ereport(ERROR, \
488                                 (errcode(ERRCODE_INVALID_DATETIME_FORMAT), \
489                                  errmsg("invalid format specification for an interval value"), \
490                                  errhint("Intervals are not tied to specific calendar dates."))); \
491 } while(0)
492
493 /*****************************************************************************
494  *                      KeyWord definitions
495  *****************************************************************************/
496
497 /* ----------
498  * Suffixes:
499  * ----------
500  */
501 #define DCH_S_FM        0x01
502 #define DCH_S_TH        0x02
503 #define DCH_S_th        0x04
504 #define DCH_S_SP        0x08
505 #define DCH_S_TM        0x10
506
507 /* ----------
508  * Suffix tests
509  * ----------
510  */
511 #define S_THth(_s)      ((((_s) & DCH_S_TH) || ((_s) & DCH_S_th)) ? 1 : 0)
512 #define S_TH(_s)        (((_s) & DCH_S_TH) ? 1 : 0)
513 #define S_th(_s)        (((_s) & DCH_S_th) ? 1 : 0)
514 #define S_TH_TYPE(_s)   (((_s) & DCH_S_TH) ? TH_UPPER : TH_LOWER)
515
516 /* Oracle toggles FM behavior, we don't; see docs. */
517 #define S_FM(_s)        (((_s) & DCH_S_FM) ? 1 : 0)
518 #define S_SP(_s)        (((_s) & DCH_S_SP) ? 1 : 0)
519 #define S_TM(_s)        (((_s) & DCH_S_TM) ? 1 : 0)
520
521 /* ----------
522  * Suffixes definition for DATE-TIME TO/FROM CHAR
523  * ----------
524  */
525 #define TM_SUFFIX_LEN   2
526
527 static const KeySuffix DCH_suff[] = {
528         {"FM", 2, DCH_S_FM, SUFFTYPE_PREFIX},
529         {"fm", 2, DCH_S_FM, SUFFTYPE_PREFIX},
530         {"TM", TM_SUFFIX_LEN, DCH_S_TM, SUFFTYPE_PREFIX},
531         {"tm", 2, DCH_S_TM, SUFFTYPE_PREFIX},
532         {"TH", 2, DCH_S_TH, SUFFTYPE_POSTFIX},
533         {"th", 2, DCH_S_th, SUFFTYPE_POSTFIX},
534         {"SP", 2, DCH_S_SP, SUFFTYPE_POSTFIX},
535         /* last */
536         {NULL, 0, 0, 0}
537 };
538
539
540 /* ----------
541  * Format-pictures (KeyWord).
542  *
543  * The KeyWord field; alphabetic sorted, *BUT* strings alike is sorted
544  *                complicated -to-> easy:
545  *
546  *      (example: "DDD","DD","Day","D" )
547  *
548  * (this specific sort needs the algorithm for sequential search for strings,
549  * which not has exact end; -> How keyword is in "HH12blabla" ? - "HH"
550  * or "HH12"? You must first try "HH12", because "HH" is in string, but
551  * it is not good.
552  *
553  * (!)
554  *       - Position for the keyword is similar as position in the enum DCH/NUM_poz.
555  * (!)
556  *
557  * For fast search is used the 'int index[]', index is ascii table from position
558  * 32 (' ') to 126 (~), in this index is DCH_ / NUM_ enums for each ASCII
559  * position or -1 if char is not used in the KeyWord. Search example for
560  * string "MM":
561  *      1)      see in index to index['M' - 32],
562  *      2)      take keywords position (enum DCH_MI) from index
563  *      3)      run sequential search in keywords[] from this position
564  *
565  * ----------
566  */
567
568 typedef enum
569 {
570         DCH_A_D,
571         DCH_A_M,
572         DCH_AD,
573         DCH_AM,
574         DCH_B_C,
575         DCH_BC,
576         DCH_CC,
577         DCH_DAY,
578         DCH_DDD,
579         DCH_DD,
580         DCH_DY,
581         DCH_Day,
582         DCH_Dy,
583         DCH_D,
584         DCH_FX,                                         /* global suffix */
585         DCH_HH24,
586         DCH_HH12,
587         DCH_HH,
588         DCH_IDDD,
589         DCH_ID,
590         DCH_IW,
591         DCH_IYYY,
592         DCH_IYY,
593         DCH_IY,
594         DCH_I,
595         DCH_J,
596         DCH_MI,
597         DCH_MM,
598         DCH_MONTH,
599         DCH_MON,
600         DCH_MS,
601         DCH_Month,
602         DCH_Mon,
603         DCH_OF,
604         DCH_P_M,
605         DCH_PM,
606         DCH_Q,
607         DCH_RM,
608         DCH_SSSS,
609         DCH_SS,
610         DCH_TZ,
611         DCH_US,
612         DCH_WW,
613         DCH_W,
614         DCH_Y_YYY,
615         DCH_YYYY,
616         DCH_YYY,
617         DCH_YY,
618         DCH_Y,
619         DCH_a_d,
620         DCH_a_m,
621         DCH_ad,
622         DCH_am,
623         DCH_b_c,
624         DCH_bc,
625         DCH_cc,
626         DCH_day,
627         DCH_ddd,
628         DCH_dd,
629         DCH_dy,
630         DCH_d,
631         DCH_fx,
632         DCH_hh24,
633         DCH_hh12,
634         DCH_hh,
635         DCH_iddd,
636         DCH_id,
637         DCH_iw,
638         DCH_iyyy,
639         DCH_iyy,
640         DCH_iy,
641         DCH_i,
642         DCH_j,
643         DCH_mi,
644         DCH_mm,
645         DCH_month,
646         DCH_mon,
647         DCH_ms,
648         DCH_p_m,
649         DCH_pm,
650         DCH_q,
651         DCH_rm,
652         DCH_ssss,
653         DCH_ss,
654         DCH_tz,
655         DCH_us,
656         DCH_ww,
657         DCH_w,
658         DCH_y_yyy,
659         DCH_yyyy,
660         DCH_yyy,
661         DCH_yy,
662         DCH_y,
663
664         /* last */
665         _DCH_last_
666 }       DCH_poz;
667
668 typedef enum
669 {
670         NUM_COMMA,
671         NUM_DEC,
672         NUM_0,
673         NUM_9,
674         NUM_B,
675         NUM_C,
676         NUM_D,
677         NUM_E,
678         NUM_FM,
679         NUM_G,
680         NUM_L,
681         NUM_MI,
682         NUM_PL,
683         NUM_PR,
684         NUM_RN,
685         NUM_SG,
686         NUM_SP,
687         NUM_S,
688         NUM_TH,
689         NUM_V,
690         NUM_b,
691         NUM_c,
692         NUM_d,
693         NUM_e,
694         NUM_fm,
695         NUM_g,
696         NUM_l,
697         NUM_mi,
698         NUM_pl,
699         NUM_pr,
700         NUM_rn,
701         NUM_sg,
702         NUM_sp,
703         NUM_s,
704         NUM_th,
705         NUM_v,
706
707         /* last */
708         _NUM_last_
709 }       NUM_poz;
710
711 /* ----------
712  * KeyWords for DATE-TIME version
713  * ----------
714  */
715 static const KeyWord DCH_keywords[] = {
716 /*      name, len, id, is_digit, date_mode */
717         {"A.D.", 4, DCH_A_D, FALSE, FROM_CHAR_DATE_NONE},       /* A */
718         {"A.M.", 4, DCH_A_M, FALSE, FROM_CHAR_DATE_NONE},
719         {"AD", 2, DCH_AD, FALSE, FROM_CHAR_DATE_NONE},
720         {"AM", 2, DCH_AM, FALSE, FROM_CHAR_DATE_NONE},
721         {"B.C.", 4, DCH_B_C, FALSE, FROM_CHAR_DATE_NONE},       /* B */
722         {"BC", 2, DCH_BC, FALSE, FROM_CHAR_DATE_NONE},
723         {"CC", 2, DCH_CC, TRUE, FROM_CHAR_DATE_NONE},           /* C */
724         {"DAY", 3, DCH_DAY, FALSE, FROM_CHAR_DATE_NONE},        /* D */
725         {"DDD", 3, DCH_DDD, TRUE, FROM_CHAR_DATE_GREGORIAN},
726         {"DD", 2, DCH_DD, TRUE, FROM_CHAR_DATE_GREGORIAN},
727         {"DY", 2, DCH_DY, FALSE, FROM_CHAR_DATE_NONE},
728         {"Day", 3, DCH_Day, FALSE, FROM_CHAR_DATE_NONE},
729         {"Dy", 2, DCH_Dy, FALSE, FROM_CHAR_DATE_NONE},
730         {"D", 1, DCH_D, TRUE, FROM_CHAR_DATE_GREGORIAN},
731         {"FX", 2, DCH_FX, FALSE, FROM_CHAR_DATE_NONE},          /* F */
732         {"HH24", 4, DCH_HH24, TRUE, FROM_CHAR_DATE_NONE},       /* H */
733         {"HH12", 4, DCH_HH12, TRUE, FROM_CHAR_DATE_NONE},
734         {"HH", 2, DCH_HH, TRUE, FROM_CHAR_DATE_NONE},
735         {"IDDD", 4, DCH_IDDD, TRUE, FROM_CHAR_DATE_ISOWEEK},            /* I */
736         {"ID", 2, DCH_ID, TRUE, FROM_CHAR_DATE_ISOWEEK},
737         {"IW", 2, DCH_IW, TRUE, FROM_CHAR_DATE_ISOWEEK},
738         {"IYYY", 4, DCH_IYYY, TRUE, FROM_CHAR_DATE_ISOWEEK},
739         {"IYY", 3, DCH_IYY, TRUE, FROM_CHAR_DATE_ISOWEEK},
740         {"IY", 2, DCH_IY, TRUE, FROM_CHAR_DATE_ISOWEEK},
741         {"I", 1, DCH_I, TRUE, FROM_CHAR_DATE_ISOWEEK},
742         {"J", 1, DCH_J, TRUE, FROM_CHAR_DATE_NONE}, /* J */
743         {"MI", 2, DCH_MI, TRUE, FROM_CHAR_DATE_NONE},           /* M */
744         {"MM", 2, DCH_MM, TRUE, FROM_CHAR_DATE_GREGORIAN},
745         {"MONTH", 5, DCH_MONTH, FALSE, FROM_CHAR_DATE_GREGORIAN},
746         {"MON", 3, DCH_MON, FALSE, FROM_CHAR_DATE_GREGORIAN},
747         {"MS", 2, DCH_MS, TRUE, FROM_CHAR_DATE_NONE},
748         {"Month", 5, DCH_Month, FALSE, FROM_CHAR_DATE_GREGORIAN},
749         {"Mon", 3, DCH_Mon, FALSE, FROM_CHAR_DATE_GREGORIAN},
750         {"OF", 2, DCH_OF, FALSE, FROM_CHAR_DATE_NONE},          /* O */
751         {"P.M.", 4, DCH_P_M, FALSE, FROM_CHAR_DATE_NONE},       /* P */
752         {"PM", 2, DCH_PM, FALSE, FROM_CHAR_DATE_NONE},
753         {"Q", 1, DCH_Q, TRUE, FROM_CHAR_DATE_NONE}, /* Q */
754         {"RM", 2, DCH_RM, FALSE, FROM_CHAR_DATE_GREGORIAN}, /* R */
755         {"SSSS", 4, DCH_SSSS, TRUE, FROM_CHAR_DATE_NONE},       /* S */
756         {"SS", 2, DCH_SS, TRUE, FROM_CHAR_DATE_NONE},
757         {"TZ", 2, DCH_TZ, FALSE, FROM_CHAR_DATE_NONE},          /* T */
758         {"US", 2, DCH_US, TRUE, FROM_CHAR_DATE_NONE},           /* U */
759         {"WW", 2, DCH_WW, TRUE, FROM_CHAR_DATE_GREGORIAN},      /* W */
760         {"W", 1, DCH_W, TRUE, FROM_CHAR_DATE_GREGORIAN},
761         {"Y,YYY", 5, DCH_Y_YYY, TRUE, FROM_CHAR_DATE_GREGORIAN},        /* Y */
762         {"YYYY", 4, DCH_YYYY, TRUE, FROM_CHAR_DATE_GREGORIAN},
763         {"YYY", 3, DCH_YYY, TRUE, FROM_CHAR_DATE_GREGORIAN},
764         {"YY", 2, DCH_YY, TRUE, FROM_CHAR_DATE_GREGORIAN},
765         {"Y", 1, DCH_Y, TRUE, FROM_CHAR_DATE_GREGORIAN},
766         {"a.d.", 4, DCH_a_d, FALSE, FROM_CHAR_DATE_NONE},       /* a */
767         {"a.m.", 4, DCH_a_m, FALSE, FROM_CHAR_DATE_NONE},
768         {"ad", 2, DCH_ad, FALSE, FROM_CHAR_DATE_NONE},
769         {"am", 2, DCH_am, FALSE, FROM_CHAR_DATE_NONE},
770         {"b.c.", 4, DCH_b_c, FALSE, FROM_CHAR_DATE_NONE},       /* b */
771         {"bc", 2, DCH_bc, FALSE, FROM_CHAR_DATE_NONE},
772         {"cc", 2, DCH_CC, TRUE, FROM_CHAR_DATE_NONE},           /* c */
773         {"day", 3, DCH_day, FALSE, FROM_CHAR_DATE_NONE},        /* d */
774         {"ddd", 3, DCH_DDD, TRUE, FROM_CHAR_DATE_GREGORIAN},
775         {"dd", 2, DCH_DD, TRUE, FROM_CHAR_DATE_GREGORIAN},
776         {"dy", 2, DCH_dy, FALSE, FROM_CHAR_DATE_NONE},
777         {"d", 1, DCH_D, TRUE, FROM_CHAR_DATE_GREGORIAN},
778         {"fx", 2, DCH_FX, FALSE, FROM_CHAR_DATE_NONE},          /* f */
779         {"hh24", 4, DCH_HH24, TRUE, FROM_CHAR_DATE_NONE},       /* h */
780         {"hh12", 4, DCH_HH12, TRUE, FROM_CHAR_DATE_NONE},
781         {"hh", 2, DCH_HH, TRUE, FROM_CHAR_DATE_NONE},
782         {"iddd", 4, DCH_IDDD, TRUE, FROM_CHAR_DATE_ISOWEEK},            /* i */
783         {"id", 2, DCH_ID, TRUE, FROM_CHAR_DATE_ISOWEEK},
784         {"iw", 2, DCH_IW, TRUE, FROM_CHAR_DATE_ISOWEEK},
785         {"iyyy", 4, DCH_IYYY, TRUE, FROM_CHAR_DATE_ISOWEEK},
786         {"iyy", 3, DCH_IYY, TRUE, FROM_CHAR_DATE_ISOWEEK},
787         {"iy", 2, DCH_IY, TRUE, FROM_CHAR_DATE_ISOWEEK},
788         {"i", 1, DCH_I, TRUE, FROM_CHAR_DATE_ISOWEEK},
789         {"j", 1, DCH_J, TRUE, FROM_CHAR_DATE_NONE}, /* j */
790         {"mi", 2, DCH_MI, TRUE, FROM_CHAR_DATE_NONE},           /* m */
791         {"mm", 2, DCH_MM, TRUE, FROM_CHAR_DATE_GREGORIAN},
792         {"month", 5, DCH_month, FALSE, FROM_CHAR_DATE_GREGORIAN},
793         {"mon", 3, DCH_mon, FALSE, FROM_CHAR_DATE_GREGORIAN},
794         {"ms", 2, DCH_MS, TRUE, FROM_CHAR_DATE_NONE},
795         {"p.m.", 4, DCH_p_m, FALSE, FROM_CHAR_DATE_NONE},       /* p */
796         {"pm", 2, DCH_pm, FALSE, FROM_CHAR_DATE_NONE},
797         {"q", 1, DCH_Q, TRUE, FROM_CHAR_DATE_NONE}, /* q */
798         {"rm", 2, DCH_rm, FALSE, FROM_CHAR_DATE_GREGORIAN}, /* r */
799         {"ssss", 4, DCH_SSSS, TRUE, FROM_CHAR_DATE_NONE},       /* s */
800         {"ss", 2, DCH_SS, TRUE, FROM_CHAR_DATE_NONE},
801         {"tz", 2, DCH_tz, FALSE, FROM_CHAR_DATE_NONE},          /* t */
802         {"us", 2, DCH_US, TRUE, FROM_CHAR_DATE_NONE},           /* u */
803         {"ww", 2, DCH_WW, TRUE, FROM_CHAR_DATE_GREGORIAN},      /* w */
804         {"w", 1, DCH_W, TRUE, FROM_CHAR_DATE_GREGORIAN},
805         {"y,yyy", 5, DCH_Y_YYY, TRUE, FROM_CHAR_DATE_GREGORIAN},        /* y */
806         {"yyyy", 4, DCH_YYYY, TRUE, FROM_CHAR_DATE_GREGORIAN},
807         {"yyy", 3, DCH_YYY, TRUE, FROM_CHAR_DATE_GREGORIAN},
808         {"yy", 2, DCH_YY, TRUE, FROM_CHAR_DATE_GREGORIAN},
809         {"y", 1, DCH_Y, TRUE, FROM_CHAR_DATE_GREGORIAN},
810
811         /* last */
812         {NULL, 0, 0, 0, 0}
813 };
814
815 /* ----------
816  * KeyWords for NUMBER version
817  *
818  * The is_digit and date_mode fields are not relevant here.
819  * ----------
820  */
821 static const KeyWord NUM_keywords[] = {
822 /*      name, len, id                   is in Index */
823         {",", 1, NUM_COMMA},            /* , */
824         {".", 1, NUM_DEC},                      /* . */
825         {"0", 1, NUM_0},                        /* 0 */
826         {"9", 1, NUM_9},                        /* 9 */
827         {"B", 1, NUM_B},                        /* B */
828         {"C", 1, NUM_C},                        /* C */
829         {"D", 1, NUM_D},                        /* D */
830         {"EEEE", 4, NUM_E},                     /* E */
831         {"FM", 2, NUM_FM},                      /* F */
832         {"G", 1, NUM_G},                        /* G */
833         {"L", 1, NUM_L},                        /* L */
834         {"MI", 2, NUM_MI},                      /* M */
835         {"PL", 2, NUM_PL},                      /* P */
836         {"PR", 2, NUM_PR},
837         {"RN", 2, NUM_RN},                      /* R */
838         {"SG", 2, NUM_SG},                      /* S */
839         {"SP", 2, NUM_SP},
840         {"S", 1, NUM_S},
841         {"TH", 2, NUM_TH},                      /* T */
842         {"V", 1, NUM_V},                        /* V */
843         {"b", 1, NUM_B},                        /* b */
844         {"c", 1, NUM_C},                        /* c */
845         {"d", 1, NUM_D},                        /* d */
846         {"eeee", 4, NUM_E},                     /* e */
847         {"fm", 2, NUM_FM},                      /* f */
848         {"g", 1, NUM_G},                        /* g */
849         {"l", 1, NUM_L},                        /* l */
850         {"mi", 2, NUM_MI},                      /* m */
851         {"pl", 2, NUM_PL},                      /* p */
852         {"pr", 2, NUM_PR},
853         {"rn", 2, NUM_rn},                      /* r */
854         {"sg", 2, NUM_SG},                      /* s */
855         {"sp", 2, NUM_SP},
856         {"s", 1, NUM_S},
857         {"th", 2, NUM_th},                      /* t */
858         {"v", 1, NUM_V},                        /* v */
859
860         /* last */
861         {NULL, 0, 0}
862 };
863
864
865 /* ----------
866  * KeyWords index for DATE-TIME version
867  * ----------
868  */
869 static const int DCH_index[KeyWord_INDEX_SIZE] = {
870 /*
871 0       1       2       3       4       5       6       7       8       9
872 */
873         /*---- first 0..31 chars are skipped ----*/
874
875         -1, -1, -1, -1, -1, -1, -1, -1,
876         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
877         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
878         -1, -1, -1, -1, -1, DCH_A_D, DCH_B_C, DCH_CC, DCH_DAY, -1,
879         DCH_FX, -1, DCH_HH24, DCH_IDDD, DCH_J, -1, -1, DCH_MI, -1, DCH_OF,
880         DCH_P_M, DCH_Q, DCH_RM, DCH_SSSS, DCH_TZ, DCH_US, -1, DCH_WW, -1, DCH_Y_YYY,
881         -1, -1, -1, -1, -1, -1, -1, DCH_a_d, DCH_b_c, DCH_cc,
882         DCH_day, -1, DCH_fx, -1, DCH_hh24, DCH_iddd, DCH_j, -1, -1, DCH_mi,
883         -1, -1, DCH_p_m, DCH_q, DCH_rm, DCH_ssss, DCH_tz, DCH_us, -1, DCH_ww,
884         -1, DCH_y_yyy, -1, -1, -1, -1
885
886         /*---- chars over 126 are skipped ----*/
887 };
888
889 /* ----------
890  * KeyWords index for NUMBER version
891  * ----------
892  */
893 static const int NUM_index[KeyWord_INDEX_SIZE] = {
894 /*
895 0       1       2       3       4       5       6       7       8       9
896 */
897         /*---- first 0..31 chars are skipped ----*/
898
899         -1, -1, -1, -1, -1, -1, -1, -1,
900         -1, -1, -1, -1, NUM_COMMA, -1, NUM_DEC, -1, NUM_0, -1,
901         -1, -1, -1, -1, -1, -1, -1, NUM_9, -1, -1,
902         -1, -1, -1, -1, -1, -1, NUM_B, NUM_C, NUM_D, NUM_E,
903         NUM_FM, NUM_G, -1, -1, -1, -1, NUM_L, NUM_MI, -1, -1,
904         NUM_PL, -1, NUM_RN, NUM_SG, NUM_TH, -1, NUM_V, -1, -1, -1,
905         -1, -1, -1, -1, -1, -1, -1, -1, NUM_b, NUM_c,
906         NUM_d, NUM_e, NUM_fm, NUM_g, -1, -1, -1, -1, NUM_l, NUM_mi,
907         -1, -1, NUM_pl, -1, NUM_rn, NUM_sg, NUM_th, -1, NUM_v, -1,
908         -1, -1, -1, -1, -1, -1
909
910         /*---- chars over 126 are skipped ----*/
911 };
912
913 /* ----------
914  * Number processor struct
915  * ----------
916  */
917 typedef struct NUMProc
918 {
919         bool            is_to_char;
920         NUMDesc    *Num;                        /* number description           */
921
922         int                     sign,                   /* '-' or '+'                   */
923                                 sign_wrote,             /* was sign write               */
924                                 num_count,              /* number of write digits       */
925                                 num_in,                 /* is inside number             */
926                                 num_curr,               /* current position in number   */
927                                 out_pre_spaces, /* spaces before first digit    */
928
929                                 read_dec,               /* to_number - was read dec. point      */
930                                 read_post,              /* to_number - number of dec. digit */
931                                 read_pre;               /* to_number - number non-dec. digit */
932
933         char       *number,                     /* string with number   */
934                            *number_p,           /* pointer to current number position */
935                            *inout,                      /* in / out buffer      */
936                            *inout_p,            /* pointer to current inout position */
937                            *last_relevant,      /* last relevant number after decimal point */
938
939                            *L_negative_sign,    /* Locale */
940                            *L_positive_sign,
941                            *decimal,
942                            *L_thousands_sep,
943                            *L_currency_symbol;
944 } NUMProc;
945
946
947 /* ----------
948  * Functions
949  * ----------
950  */
951 static const KeyWord *index_seq_search(const char *str, const KeyWord *kw,
952                                  const int *index);
953 static const KeySuffix *suff_search(const char *str, const KeySuffix *suf, int type);
954 static void NUMDesc_prepare(NUMDesc *num, FormatNode *n);
955 static void parse_format(FormatNode *node, const char *str, const KeyWord *kw,
956                          const KeySuffix *suf, const int *index, int ver, NUMDesc *Num);
957
958 static void DCH_to_char(FormatNode *node, bool is_interval,
959                         TmToChar *in, char *out, Oid collid);
960 static void DCH_from_char(FormatNode *node, char *in, TmFromChar *out);
961
962 #ifdef DEBUG_TO_FROM_CHAR
963 static void dump_index(const KeyWord *k, const int *index);
964 static void dump_node(FormatNode *node, int max);
965 #endif
966
967 static const char *get_th(char *num, int type);
968 static char *str_numth(char *dest, char *num, int type);
969 static int      adjust_partial_year_to_2020(int year);
970 static int      strspace_len(char *str);
971 static void from_char_set_mode(TmFromChar *tmfc, const FromCharDateMode mode);
972 static void from_char_set_int(int *dest, const int value, const FormatNode *node);
973 static int      from_char_parse_int_len(int *dest, char **src, const int len, FormatNode *node);
974 static int      from_char_parse_int(int *dest, char **src, FormatNode *node);
975 static int      seq_search(char *name, const char *const * array, int type, int max, int *len);
976 static int      from_char_seq_search(int *dest, char **src, const char *const * array, int type, int max, FormatNode *node);
977 static void do_to_timestamp(text *date_txt, text *fmt,
978                                 struct pg_tm * tm, fsec_t *fsec);
979 static char *fill_str(char *str, int c, int max);
980 static FormatNode *NUM_cache(int len, NUMDesc *Num, text *pars_str, bool *shouldFree);
981 static char *int_to_roman(int number);
982 static void NUM_prepare_locale(NUMProc *Np);
983 static char *get_last_relevant_decnum(char *num);
984 static void NUM_numpart_from_char(NUMProc *Np, int id, int input_len);
985 static void NUM_numpart_to_char(NUMProc *Np, int id);
986 static char *NUM_processor(FormatNode *node, NUMDesc *Num, char *inout,
987                    char *number, int from_char_input_len, int to_char_out_pre_spaces,
988                           int sign, bool is_to_char, Oid collid);
989 static DCHCacheEntry *DCH_cache_getnew(const char *str);
990 static DCHCacheEntry *DCH_cache_search(const char *str);
991 static DCHCacheEntry *DCH_cache_fetch(const char *str);
992 static NUMCacheEntry *NUM_cache_getnew(const char *str);
993 static NUMCacheEntry *NUM_cache_search(const char *str);
994 static NUMCacheEntry *NUM_cache_fetch(const char *str);
995
996
997 /* ----------
998  * Fast sequential search, use index for data selection which
999  * go to seq. cycle (it is very fast for unwanted strings)
1000  * (can't be used binary search in format parsing)
1001  * ----------
1002  */
1003 static const KeyWord *
1004 index_seq_search(const char *str, const KeyWord *kw, const int *index)
1005 {
1006         int                     poz;
1007
1008         if (!KeyWord_INDEX_FILTER(*str))
1009                 return NULL;
1010
1011         if ((poz = *(index + (*str - ' '))) > -1)
1012         {
1013                 const KeyWord *k = kw + poz;
1014
1015                 do
1016                 {
1017                         if (strncmp(str, k->name, k->len) == 0)
1018                                 return k;
1019                         k++;
1020                         if (!k->name)
1021                                 return NULL;
1022                 } while (*str == *k->name);
1023         }
1024         return NULL;
1025 }
1026
1027 static const KeySuffix *
1028 suff_search(const char *str, const KeySuffix *suf, int type)
1029 {
1030         const KeySuffix *s;
1031
1032         for (s = suf; s->name != NULL; s++)
1033         {
1034                 if (s->type != type)
1035                         continue;
1036
1037                 if (strncmp(str, s->name, s->len) == 0)
1038                         return s;
1039         }
1040         return NULL;
1041 }
1042
1043 /* ----------
1044  * Prepare NUMDesc (number description struct) via FormatNode struct
1045  * ----------
1046  */
1047 static void
1048 NUMDesc_prepare(NUMDesc *num, FormatNode *n)
1049 {
1050         if (n->type != NODE_TYPE_ACTION)
1051                 return;
1052
1053         if (IS_EEEE(num) && n->key->id != NUM_E)
1054                 ereport(ERROR,
1055                                 (errcode(ERRCODE_SYNTAX_ERROR),
1056                                  errmsg("\"EEEE\" must be the last pattern used")));
1057
1058         switch (n->key->id)
1059         {
1060                 case NUM_9:
1061                         if (IS_BRACKET(num))
1062                                 ereport(ERROR,
1063                                                 (errcode(ERRCODE_SYNTAX_ERROR),
1064                                                  errmsg("\"9\" must be ahead of \"PR\"")));
1065                         if (IS_MULTI(num))
1066                         {
1067                                 ++num->multi;
1068                                 break;
1069                         }
1070                         if (IS_DECIMAL(num))
1071                                 ++num->post;
1072                         else
1073                                 ++num->pre;
1074                         break;
1075
1076                 case NUM_0:
1077                         if (IS_BRACKET(num))
1078                                 ereport(ERROR,
1079                                                 (errcode(ERRCODE_SYNTAX_ERROR),
1080                                                  errmsg("\"0\" must be ahead of \"PR\"")));
1081                         if (!IS_ZERO(num) && !IS_DECIMAL(num))
1082                         {
1083                                 num->flag |= NUM_F_ZERO;
1084                                 num->zero_start = num->pre + 1;
1085                         }
1086                         if (!IS_DECIMAL(num))
1087                                 ++num->pre;
1088                         else
1089                                 ++num->post;
1090
1091                         num->zero_end = num->pre + num->post;
1092                         break;
1093
1094                 case NUM_B:
1095                         if (num->pre == 0 && num->post == 0 && (!IS_ZERO(num)))
1096                                 num->flag |= NUM_F_BLANK;
1097                         break;
1098
1099                 case NUM_D:
1100                         num->flag |= NUM_F_LDECIMAL;
1101                         num->need_locale = TRUE;
1102                         /* FALLTHROUGH */
1103                 case NUM_DEC:
1104                         if (IS_DECIMAL(num))
1105                                 ereport(ERROR,
1106                                                 (errcode(ERRCODE_SYNTAX_ERROR),
1107                                                  errmsg("multiple decimal points")));
1108                         if (IS_MULTI(num))
1109                                 ereport(ERROR,
1110                                                 (errcode(ERRCODE_SYNTAX_ERROR),
1111                                          errmsg("cannot use \"V\" and decimal point together")));
1112                         num->flag |= NUM_F_DECIMAL;
1113                         break;
1114
1115                 case NUM_FM:
1116                         num->flag |= NUM_F_FILLMODE;
1117                         break;
1118
1119                 case NUM_S:
1120                         if (IS_LSIGN(num))
1121                                 ereport(ERROR,
1122                                                 (errcode(ERRCODE_SYNTAX_ERROR),
1123                                                  errmsg("cannot use \"S\" twice")));
1124                         if (IS_PLUS(num) || IS_MINUS(num) || IS_BRACKET(num))
1125                                 ereport(ERROR,
1126                                                 (errcode(ERRCODE_SYNTAX_ERROR),
1127                                                  errmsg("cannot use \"S\" and \"PL\"/\"MI\"/\"SG\"/\"PR\" together")));
1128                         if (!IS_DECIMAL(num))
1129                         {
1130                                 num->lsign = NUM_LSIGN_PRE;
1131                                 num->pre_lsign_num = num->pre;
1132                                 num->need_locale = TRUE;
1133                                 num->flag |= NUM_F_LSIGN;
1134                         }
1135                         else if (num->lsign == NUM_LSIGN_NONE)
1136                         {
1137                                 num->lsign = NUM_LSIGN_POST;
1138                                 num->need_locale = TRUE;
1139                                 num->flag |= NUM_F_LSIGN;
1140                         }
1141                         break;
1142
1143                 case NUM_MI:
1144                         if (IS_LSIGN(num))
1145                                 ereport(ERROR,
1146                                                 (errcode(ERRCODE_SYNTAX_ERROR),
1147                                                  errmsg("cannot use \"S\" and \"MI\" together")));
1148                         num->flag |= NUM_F_MINUS;
1149                         if (IS_DECIMAL(num))
1150                                 num->flag |= NUM_F_MINUS_POST;
1151                         break;
1152
1153                 case NUM_PL:
1154                         if (IS_LSIGN(num))
1155                                 ereport(ERROR,
1156                                                 (errcode(ERRCODE_SYNTAX_ERROR),
1157                                                  errmsg("cannot use \"S\" and \"PL\" together")));
1158                         num->flag |= NUM_F_PLUS;
1159                         if (IS_DECIMAL(num))
1160                                 num->flag |= NUM_F_PLUS_POST;
1161                         break;
1162
1163                 case NUM_SG:
1164                         if (IS_LSIGN(num))
1165                                 ereport(ERROR,
1166                                                 (errcode(ERRCODE_SYNTAX_ERROR),
1167                                                  errmsg("cannot use \"S\" and \"SG\" together")));
1168                         num->flag |= NUM_F_MINUS;
1169                         num->flag |= NUM_F_PLUS;
1170                         break;
1171
1172                 case NUM_PR:
1173                         if (IS_LSIGN(num) || IS_PLUS(num) || IS_MINUS(num))
1174                                 ereport(ERROR,
1175                                                 (errcode(ERRCODE_SYNTAX_ERROR),
1176                                                  errmsg("cannot use \"PR\" and \"S\"/\"PL\"/\"MI\"/\"SG\" together")));
1177                         num->flag |= NUM_F_BRACKET;
1178                         break;
1179
1180                 case NUM_rn:
1181                 case NUM_RN:
1182                         num->flag |= NUM_F_ROMAN;
1183                         break;
1184
1185                 case NUM_L:
1186                 case NUM_G:
1187                         num->need_locale = TRUE;
1188                         break;
1189
1190                 case NUM_V:
1191                         if (IS_DECIMAL(num))
1192                                 ereport(ERROR,
1193                                                 (errcode(ERRCODE_SYNTAX_ERROR),
1194                                          errmsg("cannot use \"V\" and decimal point together")));
1195                         num->flag |= NUM_F_MULTI;
1196                         break;
1197
1198                 case NUM_E:
1199                         if (IS_EEEE(num))
1200                                 ereport(ERROR,
1201                                                 (errcode(ERRCODE_SYNTAX_ERROR),
1202                                                  errmsg("cannot use \"EEEE\" twice")));
1203                         if (IS_BLANK(num) || IS_FILLMODE(num) || IS_LSIGN(num) ||
1204                                 IS_BRACKET(num) || IS_MINUS(num) || IS_PLUS(num) ||
1205                                 IS_ROMAN(num) || IS_MULTI(num))
1206                                 ereport(ERROR,
1207                                                 (errcode(ERRCODE_SYNTAX_ERROR),
1208                                            errmsg("\"EEEE\" is incompatible with other formats"),
1209                                                  errdetail("\"EEEE\" may only be used together with digit and decimal point patterns.")));
1210                         num->flag |= NUM_F_EEEE;
1211                         break;
1212         }
1213 }
1214
1215 /* ----------
1216  * Format parser, search small keywords and keyword's suffixes, and make
1217  * format-node tree.
1218  *
1219  * for DATE-TIME & NUMBER version
1220  * ----------
1221  */
1222 static void
1223 parse_format(FormatNode *node, const char *str, const KeyWord *kw,
1224                          const KeySuffix *suf, const int *index, int ver, NUMDesc *Num)
1225 {
1226         const KeySuffix *s;
1227         FormatNode *n;
1228         int                     node_set = 0,
1229                                 suffix,
1230                                 last = 0;
1231
1232 #ifdef DEBUG_TO_FROM_CHAR
1233         elog(DEBUG_elog_output, "to_char/number(): run parser");
1234 #endif
1235
1236         n = node;
1237
1238         while (*str)
1239         {
1240                 suffix = 0;
1241
1242                 /*
1243                  * Prefix
1244                  */
1245                 if (ver == DCH_TYPE && (s = suff_search(str, suf, SUFFTYPE_PREFIX)) != NULL)
1246                 {
1247                         suffix |= s->id;
1248                         if (s->len)
1249                                 str += s->len;
1250                 }
1251
1252                 /*
1253                  * Keyword
1254                  */
1255                 if (*str && (n->key = index_seq_search(str, kw, index)) != NULL)
1256                 {
1257                         n->type = NODE_TYPE_ACTION;
1258                         n->suffix = 0;
1259                         node_set = 1;
1260                         if (n->key->len)
1261                                 str += n->key->len;
1262
1263                         /*
1264                          * NUM version: Prepare global NUMDesc struct
1265                          */
1266                         if (ver == NUM_TYPE)
1267                                 NUMDesc_prepare(Num, n);
1268
1269                         /*
1270                          * Postfix
1271                          */
1272                         if (ver == DCH_TYPE && *str && (s = suff_search(str, suf, SUFFTYPE_POSTFIX)) != NULL)
1273                         {
1274                                 suffix |= s->id;
1275                                 if (s->len)
1276                                         str += s->len;
1277                         }
1278                 }
1279                 else if (*str)
1280                 {
1281                         /*
1282                          * Special characters '\' and '"'
1283                          */
1284                         if (*str == '"' && last != '\\')
1285                         {
1286                                 int                     x = 0;
1287
1288                                 while (*(++str))
1289                                 {
1290                                         if (*str == '"' && x != '\\')
1291                                         {
1292                                                 str++;
1293                                                 break;
1294                                         }
1295                                         else if (*str == '\\' && x != '\\')
1296                                         {
1297                                                 x = '\\';
1298                                                 continue;
1299                                         }
1300                                         n->type = NODE_TYPE_CHAR;
1301                                         n->character = *str;
1302                                         n->key = NULL;
1303                                         n->suffix = 0;
1304                                         ++n;
1305                                         x = *str;
1306                                 }
1307                                 node_set = 0;
1308                                 suffix = 0;
1309                                 last = 0;
1310                         }
1311                         else if (*str && *str == '\\' && last != '\\' && *(str + 1) == '"')
1312                         {
1313                                 last = *str;
1314                                 str++;
1315                         }
1316                         else if (*str)
1317                         {
1318                                 n->type = NODE_TYPE_CHAR;
1319                                 n->character = *str;
1320                                 n->key = NULL;
1321                                 node_set = 1;
1322                                 last = 0;
1323                                 str++;
1324                         }
1325                 }
1326
1327                 /* end */
1328                 if (node_set)
1329                 {
1330                         if (n->type == NODE_TYPE_ACTION)
1331                                 n->suffix = suffix;
1332                         ++n;
1333
1334                         n->suffix = 0;
1335                         node_set = 0;
1336                 }
1337         }
1338
1339         n->type = NODE_TYPE_END;
1340         n->suffix = 0;
1341 }
1342
1343 /* ----------
1344  * DEBUG: Dump the FormatNode Tree (debug)
1345  * ----------
1346  */
1347 #ifdef DEBUG_TO_FROM_CHAR
1348
1349 #define DUMP_THth(_suf) (S_TH(_suf) ? "TH" : (S_th(_suf) ? "th" : " "))
1350 #define DUMP_FM(_suf)   (S_FM(_suf) ? "FM" : " ")
1351
1352 static void
1353 dump_node(FormatNode *node, int max)
1354 {
1355         FormatNode *n;
1356         int                     a;
1357
1358         elog(DEBUG_elog_output, "to_from-char(): DUMP FORMAT");
1359
1360         for (a = 0, n = node; a <= max; n++, a++)
1361         {
1362                 if (n->type == NODE_TYPE_ACTION)
1363                         elog(DEBUG_elog_output, "%d:\t NODE_TYPE_ACTION '%s'\t(%s,%s)",
1364                                  a, n->key->name, DUMP_THth(n->suffix), DUMP_FM(n->suffix));
1365                 else if (n->type == NODE_TYPE_CHAR)
1366                         elog(DEBUG_elog_output, "%d:\t NODE_TYPE_CHAR '%c'", a, n->character);
1367                 else if (n->type == NODE_TYPE_END)
1368                 {
1369                         elog(DEBUG_elog_output, "%d:\t NODE_TYPE_END", a);
1370                         return;
1371                 }
1372                 else
1373                         elog(DEBUG_elog_output, "%d:\t unknown NODE!", a);
1374         }
1375 }
1376 #endif   /* DEBUG */
1377
1378 /*****************************************************************************
1379  *                      Private utils
1380  *****************************************************************************/
1381
1382 /* ----------
1383  * Return ST/ND/RD/TH for simple (1..9) numbers
1384  * type --> 0 upper, 1 lower
1385  * ----------
1386  */
1387 static const char *
1388 get_th(char *num, int type)
1389 {
1390         int                     len = strlen(num),
1391                                 last,
1392                                 seclast;
1393
1394         last = *(num + (len - 1));
1395         if (!isdigit((unsigned char) last))
1396                 ereport(ERROR,
1397                                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1398                                  errmsg("\"%s\" is not a number", num)));
1399
1400         /*
1401          * All "teens" (<x>1[0-9]) get 'TH/th', while <x>[02-9][123] still get
1402          * 'ST/st', 'ND/nd', 'RD/rd', respectively
1403          */
1404         if ((len > 1) && ((seclast = num[len - 2]) == '1'))
1405                 last = 0;
1406
1407         switch (last)
1408         {
1409                 case '1':
1410                         if (type == TH_UPPER)
1411                                 return numTH[0];
1412                         return numth[0];
1413                 case '2':
1414                         if (type == TH_UPPER)
1415                                 return numTH[1];
1416                         return numth[1];
1417                 case '3':
1418                         if (type == TH_UPPER)
1419                                 return numTH[2];
1420                         return numth[2];
1421                 default:
1422                         if (type == TH_UPPER)
1423                                 return numTH[3];
1424                         return numth[3];
1425         }
1426 }
1427
1428 /* ----------
1429  * Convert string-number to ordinal string-number
1430  * type --> 0 upper, 1 lower
1431  * ----------
1432  */
1433 static char *
1434 str_numth(char *dest, char *num, int type)
1435 {
1436         if (dest != num)
1437                 strcpy(dest, num);
1438         strcat(dest, get_th(num, type));
1439         return dest;
1440 }
1441
1442 /*****************************************************************************
1443  *                      upper/lower/initcap functions
1444  *****************************************************************************/
1445
1446 /*
1447  * If the system provides the needed functions for wide-character manipulation
1448  * (which are all standardized by C99), then we implement upper/lower/initcap
1449  * using wide-character functions, if necessary.  Otherwise we use the
1450  * traditional <ctype.h> functions, which of course will not work as desired
1451  * in multibyte character sets.  Note that in either case we are effectively
1452  * assuming that the database character encoding matches the encoding implied
1453  * by LC_CTYPE.
1454  *
1455  * If the system provides locale_t and associated functions (which are
1456  * standardized by Open Group's XBD), we can support collations that are
1457  * neither default nor C.  The code is written to handle both combinations
1458  * of have-wide-characters and have-locale_t, though it's rather unlikely
1459  * a platform would have the latter without the former.
1460  */
1461
1462 /*
1463  * collation-aware, wide-character-aware lower function
1464  *
1465  * We pass the number of bytes so we can pass varlena and char*
1466  * to this function.  The result is a palloc'd, null-terminated string.
1467  */
1468 char *
1469 str_tolower(const char *buff, size_t nbytes, Oid collid)
1470 {
1471         char       *result;
1472
1473         if (!buff)
1474                 return NULL;
1475
1476         /* C/POSIX collations use this path regardless of database encoding */
1477         if (lc_ctype_is_c(collid))
1478         {
1479                 result = asc_tolower(buff, nbytes);
1480         }
1481 #ifdef USE_WIDE_UPPER_LOWER
1482         else if (pg_database_encoding_max_length() > 1)
1483         {
1484                 pg_locale_t mylocale = 0;
1485                 wchar_t    *workspace;
1486                 size_t          curr_char;
1487                 size_t          result_size;
1488
1489                 if (collid != DEFAULT_COLLATION_OID)
1490                 {
1491                         if (!OidIsValid(collid))
1492                         {
1493                                 /*
1494                                  * This typically means that the parser could not resolve a
1495                                  * conflict of implicit collations, so report it that way.
1496                                  */
1497                                 ereport(ERROR,
1498                                                 (errcode(ERRCODE_INDETERMINATE_COLLATION),
1499                                                  errmsg("could not determine which collation to use for lower() function"),
1500                                                  errhint("Use the COLLATE clause to set the collation explicitly.")));
1501                         }
1502                         mylocale = pg_newlocale_from_collation(collid);
1503                 }
1504
1505                 /* Overflow paranoia */
1506                 if ((nbytes + 1) > (INT_MAX / sizeof(wchar_t)))
1507                         ereport(ERROR,
1508                                         (errcode(ERRCODE_OUT_OF_MEMORY),
1509                                          errmsg("out of memory")));
1510
1511                 /* Output workspace cannot have more codes than input bytes */
1512                 workspace = (wchar_t *) palloc((nbytes + 1) * sizeof(wchar_t));
1513
1514                 char2wchar(workspace, nbytes + 1, buff, nbytes, mylocale);
1515
1516                 for (curr_char = 0; workspace[curr_char] != 0; curr_char++)
1517                 {
1518 #ifdef HAVE_LOCALE_T
1519                         if (mylocale)
1520                                 workspace[curr_char] = towlower_l(workspace[curr_char], mylocale);
1521                         else
1522 #endif
1523                                 workspace[curr_char] = towlower(workspace[curr_char]);
1524                 }
1525
1526                 /* Make result large enough; case change might change number of bytes */
1527                 result_size = curr_char * pg_database_encoding_max_length() + 1;
1528                 result = palloc(result_size);
1529
1530                 wchar2char(result, workspace, result_size, mylocale);
1531                 pfree(workspace);
1532         }
1533 #endif   /* USE_WIDE_UPPER_LOWER */
1534         else
1535         {
1536 #ifdef HAVE_LOCALE_T
1537                 pg_locale_t mylocale = 0;
1538 #endif
1539                 char       *p;
1540
1541                 if (collid != DEFAULT_COLLATION_OID)
1542                 {
1543                         if (!OidIsValid(collid))
1544                         {
1545                                 /*
1546                                  * This typically means that the parser could not resolve a
1547                                  * conflict of implicit collations, so report it that way.
1548                                  */
1549                                 ereport(ERROR,
1550                                                 (errcode(ERRCODE_INDETERMINATE_COLLATION),
1551                                                  errmsg("could not determine which collation to use for lower() function"),
1552                                                  errhint("Use the COLLATE clause to set the collation explicitly.")));
1553                         }
1554 #ifdef HAVE_LOCALE_T
1555                         mylocale = pg_newlocale_from_collation(collid);
1556 #endif
1557                 }
1558
1559                 result = pnstrdup(buff, nbytes);
1560
1561                 /*
1562                  * Note: we assume that tolower_l() will not be so broken as to need
1563                  * an isupper_l() guard test.  When using the default collation, we
1564                  * apply the traditional Postgres behavior that forces ASCII-style
1565                  * treatment of I/i, but in non-default collations you get exactly
1566                  * what the collation says.
1567                  */
1568                 for (p = result; *p; p++)
1569                 {
1570 #ifdef HAVE_LOCALE_T
1571                         if (mylocale)
1572                                 *p = tolower_l((unsigned char) *p, mylocale);
1573                         else
1574 #endif
1575                                 *p = pg_tolower((unsigned char) *p);
1576                 }
1577         }
1578
1579         return result;
1580 }
1581
1582 /*
1583  * collation-aware, wide-character-aware upper function
1584  *
1585  * We pass the number of bytes so we can pass varlena and char*
1586  * to this function.  The result is a palloc'd, null-terminated string.
1587  */
1588 char *
1589 str_toupper(const char *buff, size_t nbytes, Oid collid)
1590 {
1591         char       *result;
1592
1593         if (!buff)
1594                 return NULL;
1595
1596         /* C/POSIX collations use this path regardless of database encoding */
1597         if (lc_ctype_is_c(collid))
1598         {
1599                 result = asc_toupper(buff, nbytes);
1600         }
1601 #ifdef USE_WIDE_UPPER_LOWER
1602         else if (pg_database_encoding_max_length() > 1)
1603         {
1604                 pg_locale_t mylocale = 0;
1605                 wchar_t    *workspace;
1606                 size_t          curr_char;
1607                 size_t          result_size;
1608
1609                 if (collid != DEFAULT_COLLATION_OID)
1610                 {
1611                         if (!OidIsValid(collid))
1612                         {
1613                                 /*
1614                                  * This typically means that the parser could not resolve a
1615                                  * conflict of implicit collations, so report it that way.
1616                                  */
1617                                 ereport(ERROR,
1618                                                 (errcode(ERRCODE_INDETERMINATE_COLLATION),
1619                                                  errmsg("could not determine which collation to use for upper() function"),
1620                                                  errhint("Use the COLLATE clause to set the collation explicitly.")));
1621                         }
1622                         mylocale = pg_newlocale_from_collation(collid);
1623                 }
1624
1625                 /* Overflow paranoia */
1626                 if ((nbytes + 1) > (INT_MAX / sizeof(wchar_t)))
1627                         ereport(ERROR,
1628                                         (errcode(ERRCODE_OUT_OF_MEMORY),
1629                                          errmsg("out of memory")));
1630
1631                 /* Output workspace cannot have more codes than input bytes */
1632                 workspace = (wchar_t *) palloc((nbytes + 1) * sizeof(wchar_t));
1633
1634                 char2wchar(workspace, nbytes + 1, buff, nbytes, mylocale);
1635
1636                 for (curr_char = 0; workspace[curr_char] != 0; curr_char++)
1637                 {
1638 #ifdef HAVE_LOCALE_T
1639                         if (mylocale)
1640                                 workspace[curr_char] = towupper_l(workspace[curr_char], mylocale);
1641                         else
1642 #endif
1643                                 workspace[curr_char] = towupper(workspace[curr_char]);
1644                 }
1645
1646                 /* Make result large enough; case change might change number of bytes */
1647                 result_size = curr_char * pg_database_encoding_max_length() + 1;
1648                 result = palloc(result_size);
1649
1650                 wchar2char(result, workspace, result_size, mylocale);
1651                 pfree(workspace);
1652         }
1653 #endif   /* USE_WIDE_UPPER_LOWER */
1654         else
1655         {
1656 #ifdef HAVE_LOCALE_T
1657                 pg_locale_t mylocale = 0;
1658 #endif
1659                 char       *p;
1660
1661                 if (collid != DEFAULT_COLLATION_OID)
1662                 {
1663                         if (!OidIsValid(collid))
1664                         {
1665                                 /*
1666                                  * This typically means that the parser could not resolve a
1667                                  * conflict of implicit collations, so report it that way.
1668                                  */
1669                                 ereport(ERROR,
1670                                                 (errcode(ERRCODE_INDETERMINATE_COLLATION),
1671                                                  errmsg("could not determine which collation to use for upper() function"),
1672                                                  errhint("Use the COLLATE clause to set the collation explicitly.")));
1673                         }
1674 #ifdef HAVE_LOCALE_T
1675                         mylocale = pg_newlocale_from_collation(collid);
1676 #endif
1677                 }
1678
1679                 result = pnstrdup(buff, nbytes);
1680
1681                 /*
1682                  * Note: we assume that toupper_l() will not be so broken as to need
1683                  * an islower_l() guard test.  When using the default collation, we
1684                  * apply the traditional Postgres behavior that forces ASCII-style
1685                  * treatment of I/i, but in non-default collations you get exactly
1686                  * what the collation says.
1687                  */
1688                 for (p = result; *p; p++)
1689                 {
1690 #ifdef HAVE_LOCALE_T
1691                         if (mylocale)
1692                                 *p = toupper_l((unsigned char) *p, mylocale);
1693                         else
1694 #endif
1695                                 *p = pg_toupper((unsigned char) *p);
1696                 }
1697         }
1698
1699         return result;
1700 }
1701
1702 /*
1703  * collation-aware, wide-character-aware initcap function
1704  *
1705  * We pass the number of bytes so we can pass varlena and char*
1706  * to this function.  The result is a palloc'd, null-terminated string.
1707  */
1708 char *
1709 str_initcap(const char *buff, size_t nbytes, Oid collid)
1710 {
1711         char       *result;
1712         int                     wasalnum = false;
1713
1714         if (!buff)
1715                 return NULL;
1716
1717         /* C/POSIX collations use this path regardless of database encoding */
1718         if (lc_ctype_is_c(collid))
1719         {
1720                 result = asc_initcap(buff, nbytes);
1721         }
1722 #ifdef USE_WIDE_UPPER_LOWER
1723         else if (pg_database_encoding_max_length() > 1)
1724         {
1725                 pg_locale_t mylocale = 0;
1726                 wchar_t    *workspace;
1727                 size_t          curr_char;
1728                 size_t          result_size;
1729
1730                 if (collid != DEFAULT_COLLATION_OID)
1731                 {
1732                         if (!OidIsValid(collid))
1733                         {
1734                                 /*
1735                                  * This typically means that the parser could not resolve a
1736                                  * conflict of implicit collations, so report it that way.
1737                                  */
1738                                 ereport(ERROR,
1739                                                 (errcode(ERRCODE_INDETERMINATE_COLLATION),
1740                                                  errmsg("could not determine which collation to use for initcap() function"),
1741                                                  errhint("Use the COLLATE clause to set the collation explicitly.")));
1742                         }
1743                         mylocale = pg_newlocale_from_collation(collid);
1744                 }
1745
1746                 /* Overflow paranoia */
1747                 if ((nbytes + 1) > (INT_MAX / sizeof(wchar_t)))
1748                         ereport(ERROR,
1749                                         (errcode(ERRCODE_OUT_OF_MEMORY),
1750                                          errmsg("out of memory")));
1751
1752                 /* Output workspace cannot have more codes than input bytes */
1753                 workspace = (wchar_t *) palloc((nbytes + 1) * sizeof(wchar_t));
1754
1755                 char2wchar(workspace, nbytes + 1, buff, nbytes, mylocale);
1756
1757                 for (curr_char = 0; workspace[curr_char] != 0; curr_char++)
1758                 {
1759 #ifdef HAVE_LOCALE_T
1760                         if (mylocale)
1761                         {
1762                                 if (wasalnum)
1763                                         workspace[curr_char] = towlower_l(workspace[curr_char], mylocale);
1764                                 else
1765                                         workspace[curr_char] = towupper_l(workspace[curr_char], mylocale);
1766                                 wasalnum = iswalnum_l(workspace[curr_char], mylocale);
1767                         }
1768                         else
1769 #endif
1770                         {
1771                                 if (wasalnum)
1772                                         workspace[curr_char] = towlower(workspace[curr_char]);
1773                                 else
1774                                         workspace[curr_char] = towupper(workspace[curr_char]);
1775                                 wasalnum = iswalnum(workspace[curr_char]);
1776                         }
1777                 }
1778
1779                 /* Make result large enough; case change might change number of bytes */
1780                 result_size = curr_char * pg_database_encoding_max_length() + 1;
1781                 result = palloc(result_size);
1782
1783                 wchar2char(result, workspace, result_size, mylocale);
1784                 pfree(workspace);
1785         }
1786 #endif   /* USE_WIDE_UPPER_LOWER */
1787         else
1788         {
1789 #ifdef HAVE_LOCALE_T
1790                 pg_locale_t mylocale = 0;
1791 #endif
1792                 char       *p;
1793
1794                 if (collid != DEFAULT_COLLATION_OID)
1795                 {
1796                         if (!OidIsValid(collid))
1797                         {
1798                                 /*
1799                                  * This typically means that the parser could not resolve a
1800                                  * conflict of implicit collations, so report it that way.
1801                                  */
1802                                 ereport(ERROR,
1803                                                 (errcode(ERRCODE_INDETERMINATE_COLLATION),
1804                                                  errmsg("could not determine which collation to use for initcap() function"),
1805                                                  errhint("Use the COLLATE clause to set the collation explicitly.")));
1806                         }
1807 #ifdef HAVE_LOCALE_T
1808                         mylocale = pg_newlocale_from_collation(collid);
1809 #endif
1810                 }
1811
1812                 result = pnstrdup(buff, nbytes);
1813
1814                 /*
1815                  * Note: we assume that toupper_l()/tolower_l() will not be so broken
1816                  * as to need guard tests.  When using the default collation, we apply
1817                  * the traditional Postgres behavior that forces ASCII-style treatment
1818                  * of I/i, but in non-default collations you get exactly what the
1819                  * collation says.
1820                  */
1821                 for (p = result; *p; p++)
1822                 {
1823 #ifdef HAVE_LOCALE_T
1824                         if (mylocale)
1825                         {
1826                                 if (wasalnum)
1827                                         *p = tolower_l((unsigned char) *p, mylocale);
1828                                 else
1829                                         *p = toupper_l((unsigned char) *p, mylocale);
1830                                 wasalnum = isalnum_l((unsigned char) *p, mylocale);
1831                         }
1832                         else
1833 #endif
1834                         {
1835                                 if (wasalnum)
1836                                         *p = pg_tolower((unsigned char) *p);
1837                                 else
1838                                         *p = pg_toupper((unsigned char) *p);
1839                                 wasalnum = isalnum((unsigned char) *p);
1840                         }
1841                 }
1842         }
1843
1844         return result;
1845 }
1846
1847 /*
1848  * ASCII-only lower function
1849  *
1850  * We pass the number of bytes so we can pass varlena and char*
1851  * to this function.  The result is a palloc'd, null-terminated string.
1852  */
1853 char *
1854 asc_tolower(const char *buff, size_t nbytes)
1855 {
1856         char       *result;
1857         char       *p;
1858
1859         if (!buff)
1860                 return NULL;
1861
1862         result = pnstrdup(buff, nbytes);
1863
1864         for (p = result; *p; p++)
1865                 *p = pg_ascii_tolower((unsigned char) *p);
1866
1867         return result;
1868 }
1869
1870 /*
1871  * ASCII-only upper function
1872  *
1873  * We pass the number of bytes so we can pass varlena and char*
1874  * to this function.  The result is a palloc'd, null-terminated string.
1875  */
1876 char *
1877 asc_toupper(const char *buff, size_t nbytes)
1878 {
1879         char       *result;
1880         char       *p;
1881
1882         if (!buff)
1883                 return NULL;
1884
1885         result = pnstrdup(buff, nbytes);
1886
1887         for (p = result; *p; p++)
1888                 *p = pg_ascii_toupper((unsigned char) *p);
1889
1890         return result;
1891 }
1892
1893 /*
1894  * ASCII-only initcap function
1895  *
1896  * We pass the number of bytes so we can pass varlena and char*
1897  * to this function.  The result is a palloc'd, null-terminated string.
1898  */
1899 char *
1900 asc_initcap(const char *buff, size_t nbytes)
1901 {
1902         char       *result;
1903         char       *p;
1904         int                     wasalnum = false;
1905
1906         if (!buff)
1907                 return NULL;
1908
1909         result = pnstrdup(buff, nbytes);
1910
1911         for (p = result; *p; p++)
1912         {
1913                 char            c;
1914
1915                 if (wasalnum)
1916                         *p = c = pg_ascii_tolower((unsigned char) *p);
1917                 else
1918                         *p = c = pg_ascii_toupper((unsigned char) *p);
1919                 /* we don't trust isalnum() here */
1920                 wasalnum = ((c >= 'A' && c <= 'Z') ||
1921                                         (c >= 'a' && c <= 'z') ||
1922                                         (c >= '0' && c <= '9'));
1923         }
1924
1925         return result;
1926 }
1927
1928 /* convenience routines for when the input is null-terminated */
1929
1930 static char *
1931 str_tolower_z(const char *buff, Oid collid)
1932 {
1933         return str_tolower(buff, strlen(buff), collid);
1934 }
1935
1936 static char *
1937 str_toupper_z(const char *buff, Oid collid)
1938 {
1939         return str_toupper(buff, strlen(buff), collid);
1940 }
1941
1942 static char *
1943 str_initcap_z(const char *buff, Oid collid)
1944 {
1945         return str_initcap(buff, strlen(buff), collid);
1946 }
1947
1948 static char *
1949 asc_tolower_z(const char *buff)
1950 {
1951         return asc_tolower(buff, strlen(buff));
1952 }
1953
1954 static char *
1955 asc_toupper_z(const char *buff)
1956 {
1957         return asc_toupper(buff, strlen(buff));
1958 }
1959
1960 /* asc_initcap_z is not currently needed */
1961
1962
1963 /* ----------
1964  * Skip TM / th in FROM_CHAR
1965  *
1966  * If S_THth is on, skip two chars, assuming there are two available
1967  * ----------
1968  */
1969 #define SKIP_THth(ptr, _suf) \
1970         do { \
1971                 if (S_THth(_suf)) \
1972                 { \
1973                         if (*(ptr)) (ptr)++; \
1974                         if (*(ptr)) (ptr)++; \
1975                 } \
1976         } while (0)
1977
1978
1979 #ifdef DEBUG_TO_FROM_CHAR
1980 /* -----------
1981  * DEBUG: Call for debug and for index checking; (Show ASCII char
1982  * and defined keyword for each used position
1983  * ----------
1984  */
1985 static void
1986 dump_index(const KeyWord *k, const int *index)
1987 {
1988         int                     i,
1989                                 count = 0,
1990                                 free_i = 0;
1991
1992         elog(DEBUG_elog_output, "TO-FROM_CHAR: Dump KeyWord Index:");
1993
1994         for (i = 0; i < KeyWord_INDEX_SIZE; i++)
1995         {
1996                 if (index[i] != -1)
1997                 {
1998                         elog(DEBUG_elog_output, "\t%c: %s, ", i + 32, k[index[i]].name);
1999                         count++;
2000                 }
2001                 else
2002                 {
2003                         free_i++;
2004                         elog(DEBUG_elog_output, "\t(%d) %c %d", i, i + 32, index[i]);
2005                 }
2006         }
2007         elog(DEBUG_elog_output, "\n\t\tUsed positions: %d,\n\t\tFree positions: %d",
2008                  count, free_i);
2009 }
2010 #endif   /* DEBUG */
2011
2012 /* ----------
2013  * Return TRUE if next format picture is not digit value
2014  * ----------
2015  */
2016 static bool
2017 is_next_separator(FormatNode *n)
2018 {
2019         if (n->type == NODE_TYPE_END)
2020                 return FALSE;
2021
2022         if (n->type == NODE_TYPE_ACTION && S_THth(n->suffix))
2023                 return TRUE;
2024
2025         /*
2026          * Next node
2027          */
2028         n++;
2029
2030         /* end of format string is treated like a non-digit separator */
2031         if (n->type == NODE_TYPE_END)
2032                 return TRUE;
2033
2034         if (n->type == NODE_TYPE_ACTION)
2035         {
2036                 if (n->key->is_digit)
2037                         return FALSE;
2038
2039                 return TRUE;
2040         }
2041         else if (isdigit((unsigned char) n->character))
2042                 return FALSE;
2043
2044         return TRUE;                            /* some non-digit input (separator) */
2045 }
2046
2047
2048 static int
2049 adjust_partial_year_to_2020(int year)
2050 {
2051         /*
2052          * Adjust all dates toward 2020; this is effectively what happens when we
2053          * assume '70' is 1970 and '69' is 2069.
2054          */
2055         /* Force 0-69 into the 2000's */
2056         if (year < 70)
2057                 return year + 2000;
2058         /* Force 70-99 into the 1900's */
2059         else if (year < 100)
2060                 return year + 1900;
2061         /* Force 100-519 into the 2000's */
2062         else if (year < 520)
2063                 return year + 2000;
2064         /* Force 520-999 into the 1000's */
2065         else if (year < 1000)
2066                 return year + 1000;
2067         else
2068                 return year;
2069 }
2070
2071
2072 static int
2073 strspace_len(char *str)
2074 {
2075         int                     len = 0;
2076
2077         while (*str && isspace((unsigned char) *str))
2078         {
2079                 str++;
2080                 len++;
2081         }
2082         return len;
2083 }
2084
2085 /*
2086  * Set the date mode of a from-char conversion.
2087  *
2088  * Puke if the date mode has already been set, and the caller attempts to set
2089  * it to a conflicting mode.
2090  */
2091 static void
2092 from_char_set_mode(TmFromChar *tmfc, const FromCharDateMode mode)
2093 {
2094         if (mode != FROM_CHAR_DATE_NONE)
2095         {
2096                 if (tmfc->mode == FROM_CHAR_DATE_NONE)
2097                         tmfc->mode = mode;
2098                 else if (tmfc->mode != mode)
2099                         ereport(ERROR,
2100                                         (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
2101                                          errmsg("invalid combination of date conventions"),
2102                                          errhint("Do not mix Gregorian and ISO week date "
2103                                                          "conventions in a formatting template.")));
2104         }
2105 }
2106
2107 /*
2108  * Set the integer pointed to by 'dest' to the given value.
2109  *
2110  * Puke if the destination integer has previously been set to some other
2111  * non-zero value.
2112  */
2113 static void
2114 from_char_set_int(int *dest, const int value, const FormatNode *node)
2115 {
2116         if (*dest != 0 && *dest != value)
2117                 ereport(ERROR,
2118                                 (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
2119                    errmsg("conflicting values for \"%s\" field in formatting string",
2120                                   node->key->name),
2121                                  errdetail("This value contradicts a previous setting for "
2122                                                    "the same field type.")));
2123         *dest = value;
2124 }
2125
2126 /*
2127  * Read a single integer from the source string, into the int pointed to by
2128  * 'dest'. If 'dest' is NULL, the result is discarded.
2129  *
2130  * In fixed-width mode (the node does not have the FM suffix), consume at most
2131  * 'len' characters.  However, any leading whitespace isn't counted in 'len'.
2132  *
2133  * We use strtol() to recover the integer value from the source string, in
2134  * accordance with the given FormatNode.
2135  *
2136  * If the conversion completes successfully, src will have been advanced to
2137  * point at the character immediately following the last character used in the
2138  * conversion.
2139  *
2140  * Return the number of characters consumed.
2141  *
2142  * Note that from_char_parse_int() provides a more convenient wrapper where
2143  * the length of the field is the same as the length of the format keyword (as
2144  * with DD and MI).
2145  */
2146 static int
2147 from_char_parse_int_len(int *dest, char **src, const int len, FormatNode *node)
2148 {
2149         long            result;
2150         char            copy[DCH_MAX_ITEM_SIZ + 1];
2151         char       *init = *src;
2152         int                     used;
2153
2154         /*
2155          * Skip any whitespace before parsing the integer.
2156          */
2157         *src += strspace_len(*src);
2158
2159         Assert(len <= DCH_MAX_ITEM_SIZ);
2160         used = (int) strlcpy(copy, *src, len + 1);
2161
2162         if (S_FM(node->suffix) || is_next_separator(node))
2163         {
2164                 /*
2165                  * This node is in Fill Mode, or the next node is known to be a
2166                  * non-digit value, so we just slurp as many characters as we can get.
2167                  */
2168                 errno = 0;
2169                 result = strtol(init, src, 10);
2170         }
2171         else
2172         {
2173                 /*
2174                  * We need to pull exactly the number of characters given in 'len' out
2175                  * of the string, and convert those.
2176                  */
2177                 char       *last;
2178
2179                 if (used < len)
2180                         ereport(ERROR,
2181                                         (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
2182                                 errmsg("source string too short for \"%s\" formatting field",
2183                                            node->key->name),
2184                                          errdetail("Field requires %d characters, but only %d "
2185                                                            "remain.",
2186                                                            len, used),
2187                                          errhint("If your source string is not fixed-width, try "
2188                                                          "using the \"FM\" modifier.")));
2189
2190                 errno = 0;
2191                 result = strtol(copy, &last, 10);
2192                 used = last - copy;
2193
2194                 if (used > 0 && used < len)
2195                         ereport(ERROR,
2196                                         (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
2197                                          errmsg("invalid value \"%s\" for \"%s\"",
2198                                                         copy, node->key->name),
2199                                          errdetail("Field requires %d characters, but only %d "
2200                                                            "could be parsed.", len, used),
2201                                          errhint("If your source string is not fixed-width, try "
2202                                                          "using the \"FM\" modifier.")));
2203
2204                 *src += used;
2205         }
2206
2207         if (*src == init)
2208                 ereport(ERROR,
2209                                 (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
2210                                  errmsg("invalid value \"%s\" for \"%s\"",
2211                                                 copy, node->key->name),
2212                                  errdetail("Value must be an integer.")));
2213
2214         if (errno == ERANGE || result < INT_MIN || result > INT_MAX)
2215                 ereport(ERROR,
2216                                 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2217                                  errmsg("value for \"%s\" in source string is out of range",
2218                                                 node->key->name),
2219                                  errdetail("Value must be in the range %d to %d.",
2220                                                    INT_MIN, INT_MAX)));
2221
2222         if (dest != NULL)
2223                 from_char_set_int(dest, (int) result, node);
2224         return *src - init;
2225 }
2226
2227 /*
2228  * Call from_char_parse_int_len(), using the length of the format keyword as
2229  * the expected length of the field.
2230  *
2231  * Don't call this function if the field differs in length from the format
2232  * keyword (as with HH24; the keyword length is 4, but the field length is 2).
2233  * In such cases, call from_char_parse_int_len() instead to specify the
2234  * required length explicitly.
2235  */
2236 static int
2237 from_char_parse_int(int *dest, char **src, FormatNode *node)
2238 {
2239         return from_char_parse_int_len(dest, src, node->key->len, node);
2240 }
2241
2242 /* ----------
2243  * Sequential search with to upper/lower conversion
2244  * ----------
2245  */
2246 static int
2247 seq_search(char *name, const char *const * array, int type, int max, int *len)
2248 {
2249         const char *p;
2250         const char *const * a;
2251         char       *n;
2252         int                     last,
2253                                 i;
2254
2255         *len = 0;
2256
2257         if (!*name)
2258                 return -1;
2259
2260         /* set first char */
2261         if (type == ONE_UPPER || type == ALL_UPPER)
2262                 *name = pg_toupper((unsigned char) *name);
2263         else if (type == ALL_LOWER)
2264                 *name = pg_tolower((unsigned char) *name);
2265
2266         for (last = 0, a = array; *a != NULL; a++)
2267         {
2268                 /* compare first chars */
2269                 if (*name != **a)
2270                         continue;
2271
2272                 for (i = 1, p = *a + 1, n = name + 1;; n++, p++, i++)
2273                 {
2274                         /* search fragment (max) only */
2275                         if (max && i == max)
2276                         {
2277                                 *len = i;
2278                                 return a - array;
2279                         }
2280                         /* full size */
2281                         if (*p == '\0')
2282                         {
2283                                 *len = i;
2284                                 return a - array;
2285                         }
2286                         /* Not found in array 'a' */
2287                         if (*n == '\0')
2288                                 break;
2289
2290                         /*
2291                          * Convert (but convert new chars only)
2292                          */
2293                         if (i > last)
2294                         {
2295                                 if (type == ONE_UPPER || type == ALL_LOWER)
2296                                         *n = pg_tolower((unsigned char) *n);
2297                                 else if (type == ALL_UPPER)
2298                                         *n = pg_toupper((unsigned char) *n);
2299                                 last = i;
2300                         }
2301
2302 #ifdef DEBUG_TO_FROM_CHAR
2303                         elog(DEBUG_elog_output, "N: %c, P: %c, A: %s (%s)",
2304                                  *n, *p, *a, name);
2305 #endif
2306                         if (*n != *p)
2307                                 break;
2308                 }
2309         }
2310
2311         return -1;
2312 }
2313
2314 /*
2315  * Perform a sequential search in 'array' for text matching the first 'max'
2316  * characters of the source string.
2317  *
2318  * If a match is found, copy the array index of the match into the integer
2319  * pointed to by 'dest', advance 'src' to the end of the part of the string
2320  * which matched, and return the number of characters consumed.
2321  *
2322  * If the string doesn't match, throw an error.
2323  */
2324 static int
2325 from_char_seq_search(int *dest, char **src, const char *const * array, int type, int max,
2326                                          FormatNode *node)
2327 {
2328         int                     len;
2329
2330         *dest = seq_search(*src, array, type, max, &len);
2331         if (len <= 0)
2332         {
2333                 char            copy[DCH_MAX_ITEM_SIZ + 1];
2334
2335                 Assert(max <= DCH_MAX_ITEM_SIZ);
2336                 strlcpy(copy, *src, max + 1);
2337
2338                 ereport(ERROR,
2339                                 (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
2340                                  errmsg("invalid value \"%s\" for \"%s\"",
2341                                                 copy, node->key->name),
2342                                  errdetail("The given value did not match any of the allowed "
2343                                                    "values for this field.")));
2344         }
2345         *src += len;
2346         return len;
2347 }
2348
2349 /* ----------
2350  * Process a TmToChar struct as denoted by a list of FormatNodes.
2351  * The formatted data is written to the string pointed to by 'out'.
2352  * ----------
2353  */
2354 static void
2355 DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid collid)
2356 {
2357         FormatNode *n;
2358         char       *s;
2359         struct pg_tm *tm = &in->tm;
2360         int                     i;
2361
2362         /* cache localized days and months */
2363         cache_locale_time();
2364
2365         s = out;
2366         for (n = node; n->type != NODE_TYPE_END; n++)
2367         {
2368                 if (n->type != NODE_TYPE_ACTION)
2369                 {
2370                         *s = n->character;
2371                         s++;
2372                         continue;
2373                 }
2374
2375                 switch (n->key->id)
2376                 {
2377                         case DCH_A_M:
2378                         case DCH_P_M:
2379                                 strcpy(s, (tm->tm_hour % HOURS_PER_DAY >= HOURS_PER_DAY / 2)
2380                                            ? P_M_STR : A_M_STR);
2381                                 s += strlen(s);
2382                                 break;
2383                         case DCH_AM:
2384                         case DCH_PM:
2385                                 strcpy(s, (tm->tm_hour % HOURS_PER_DAY >= HOURS_PER_DAY / 2)
2386                                            ? PM_STR : AM_STR);
2387                                 s += strlen(s);
2388                                 break;
2389                         case DCH_a_m:
2390                         case DCH_p_m:
2391                                 strcpy(s, (tm->tm_hour % HOURS_PER_DAY >= HOURS_PER_DAY / 2)
2392                                            ? p_m_STR : a_m_STR);
2393                                 s += strlen(s);
2394                                 break;
2395                         case DCH_am:
2396                         case DCH_pm:
2397                                 strcpy(s, (tm->tm_hour % HOURS_PER_DAY >= HOURS_PER_DAY / 2)
2398                                            ? pm_STR : am_STR);
2399                                 s += strlen(s);
2400                                 break;
2401                         case DCH_HH:
2402                         case DCH_HH12:
2403
2404                                 /*
2405                                  * display time as shown on a 12-hour clock, even for
2406                                  * intervals
2407                                  */
2408                                 sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : (tm->tm_hour >= 0) ? 2 : 3,
2409                                  tm->tm_hour % (HOURS_PER_DAY / 2) == 0 ? HOURS_PER_DAY / 2 :
2410                                                 tm->tm_hour % (HOURS_PER_DAY / 2));
2411                                 if (S_THth(n->suffix))
2412                                         str_numth(s, s, S_TH_TYPE(n->suffix));
2413                                 s += strlen(s);
2414                                 break;
2415                         case DCH_HH24:
2416                                 sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : (tm->tm_hour >= 0) ? 2 : 3,
2417                                                 tm->tm_hour);
2418                                 if (S_THth(n->suffix))
2419                                         str_numth(s, s, S_TH_TYPE(n->suffix));
2420                                 s += strlen(s);
2421                                 break;
2422                         case DCH_MI:
2423                                 sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : (tm->tm_min >= 0) ? 2 : 3,
2424                                                 tm->tm_min);
2425                                 if (S_THth(n->suffix))
2426                                         str_numth(s, s, S_TH_TYPE(n->suffix));
2427                                 s += strlen(s);
2428                                 break;
2429                         case DCH_SS:
2430                                 sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : (tm->tm_sec >= 0) ? 2 : 3,
2431                                                 tm->tm_sec);
2432                                 if (S_THth(n->suffix))
2433                                         str_numth(s, s, S_TH_TYPE(n->suffix));
2434                                 s += strlen(s);
2435                                 break;
2436                         case DCH_MS:            /* millisecond */
2437 #ifdef HAVE_INT64_TIMESTAMP
2438                                 sprintf(s, "%03d", (int) (in->fsec / INT64CONST(1000)));
2439 #else
2440                                 /* No rint() because we can't overflow and we might print US */
2441                                 sprintf(s, "%03d", (int) (in->fsec * 1000));
2442 #endif
2443                                 if (S_THth(n->suffix))
2444                                         str_numth(s, s, S_TH_TYPE(n->suffix));
2445                                 s += strlen(s);
2446                                 break;
2447                         case DCH_US:            /* microsecond */
2448 #ifdef HAVE_INT64_TIMESTAMP
2449                                 sprintf(s, "%06d", (int) in->fsec);
2450 #else
2451                                 /* don't use rint() because we can't overflow 1000 */
2452                                 sprintf(s, "%06d", (int) (in->fsec * 1000000));
2453 #endif
2454                                 if (S_THth(n->suffix))
2455                                         str_numth(s, s, S_TH_TYPE(n->suffix));
2456                                 s += strlen(s);
2457                                 break;
2458                         case DCH_SSSS:
2459                                 sprintf(s, "%d", tm->tm_hour * SECS_PER_HOUR +
2460                                                 tm->tm_min * SECS_PER_MINUTE +
2461                                                 tm->tm_sec);
2462                                 if (S_THth(n->suffix))
2463                                         str_numth(s, s, S_TH_TYPE(n->suffix));
2464                                 s += strlen(s);
2465                                 break;
2466                         case DCH_tz:
2467                                 INVALID_FOR_INTERVAL;
2468                                 if (tmtcTzn(in))
2469                                 {
2470                                         /* We assume here that timezone names aren't localized */
2471                                         char       *p = asc_tolower_z(tmtcTzn(in));
2472
2473                                         strcpy(s, p);
2474                                         pfree(p);
2475                                         s += strlen(s);
2476                                 }
2477                                 break;
2478                         case DCH_TZ:
2479                                 INVALID_FOR_INTERVAL;
2480                                 if (tmtcTzn(in))
2481                                 {
2482                                         strcpy(s, tmtcTzn(in));
2483                                         s += strlen(s);
2484                                 }
2485                                 break;
2486                         case DCH_OF:
2487                                 INVALID_FOR_INTERVAL;
2488                                 sprintf(s, "%c%0*d",
2489                                                 (tm->tm_gmtoff >= 0) ? '+' : '-',
2490                                                 S_FM(n->suffix) ? 0 : 2,
2491                                                 abs((int) tm->tm_gmtoff) / SECS_PER_HOUR);
2492                                 s += strlen(s);
2493                                 if (abs((int) tm->tm_gmtoff) % SECS_PER_HOUR != 0)
2494                                 {
2495                                         sprintf(s, ":%02d",
2496                                                         (abs((int) tm->tm_gmtoff) % SECS_PER_HOUR) / SECS_PER_MINUTE);
2497                                         s += strlen(s);
2498                                 }
2499                                 break;
2500                         case DCH_A_D:
2501                         case DCH_B_C:
2502                                 INVALID_FOR_INTERVAL;
2503                                 strcpy(s, (tm->tm_year <= 0 ? B_C_STR : A_D_STR));
2504                                 s += strlen(s);
2505                                 break;
2506                         case DCH_AD:
2507                         case DCH_BC:
2508                                 INVALID_FOR_INTERVAL;
2509                                 strcpy(s, (tm->tm_year <= 0 ? BC_STR : AD_STR));
2510                                 s += strlen(s);
2511                                 break;
2512                         case DCH_a_d:
2513                         case DCH_b_c:
2514                                 INVALID_FOR_INTERVAL;
2515                                 strcpy(s, (tm->tm_year <= 0 ? b_c_STR : a_d_STR));
2516                                 s += strlen(s);
2517                                 break;
2518                         case DCH_ad:
2519                         case DCH_bc:
2520                                 INVALID_FOR_INTERVAL;
2521                                 strcpy(s, (tm->tm_year <= 0 ? bc_STR : ad_STR));
2522                                 s += strlen(s);
2523                                 break;
2524                         case DCH_MONTH:
2525                                 INVALID_FOR_INTERVAL;
2526                                 if (!tm->tm_mon)
2527                                         break;
2528                                 if (S_TM(n->suffix))
2529                                 {
2530                                         char       *str = str_toupper_z(localized_full_months[tm->tm_mon - 1], collid);
2531
2532                                         if (strlen(str) <= (n->key->len + TM_SUFFIX_LEN) * DCH_MAX_ITEM_SIZ)
2533                                                 strcpy(s, str);
2534                                         else
2535                                                 ereport(ERROR,
2536                                                                 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2537                                                   errmsg("localized string format value too long")));
2538                                 }
2539                                 else
2540                                         sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9,
2541                                                         asc_toupper_z(months_full[tm->tm_mon - 1]));
2542                                 s += strlen(s);
2543                                 break;
2544                         case DCH_Month:
2545                                 INVALID_FOR_INTERVAL;
2546                                 if (!tm->tm_mon)
2547                                         break;
2548                                 if (S_TM(n->suffix))
2549                                 {
2550                                         char       *str = str_initcap_z(localized_full_months[tm->tm_mon - 1], collid);
2551
2552                                         if (strlen(str) <= (n->key->len + TM_SUFFIX_LEN) * DCH_MAX_ITEM_SIZ)
2553                                                 strcpy(s, str);
2554                                         else
2555                                                 ereport(ERROR,
2556                                                                 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2557                                                   errmsg("localized string format value too long")));
2558                                 }
2559                                 else
2560                                         sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9,
2561                                                         months_full[tm->tm_mon - 1]);
2562                                 s += strlen(s);
2563                                 break;
2564                         case DCH_month:
2565                                 INVALID_FOR_INTERVAL;
2566                                 if (!tm->tm_mon)
2567                                         break;
2568                                 if (S_TM(n->suffix))
2569                                 {
2570                                         char       *str = str_tolower_z(localized_full_months[tm->tm_mon - 1], collid);
2571
2572                                         if (strlen(str) <= (n->key->len + TM_SUFFIX_LEN) * DCH_MAX_ITEM_SIZ)
2573                                                 strcpy(s, str);
2574                                         else
2575                                                 ereport(ERROR,
2576                                                                 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2577                                                   errmsg("localized string format value too long")));
2578                                 }
2579                                 else
2580                                         sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9,
2581                                                         asc_tolower_z(months_full[tm->tm_mon - 1]));
2582                                 s += strlen(s);
2583                                 break;
2584                         case DCH_MON:
2585                                 INVALID_FOR_INTERVAL;
2586                                 if (!tm->tm_mon)
2587                                         break;
2588                                 if (S_TM(n->suffix))
2589                                 {
2590                                         char       *str = str_toupper_z(localized_abbrev_months[tm->tm_mon - 1], collid);
2591
2592                                         if (strlen(str) <= (n->key->len + TM_SUFFIX_LEN) * DCH_MAX_ITEM_SIZ)
2593                                                 strcpy(s, str);
2594                                         else
2595                                                 ereport(ERROR,
2596                                                                 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2597                                                   errmsg("localized string format value too long")));
2598                                 }
2599                                 else
2600                                         strcpy(s, asc_toupper_z(months[tm->tm_mon - 1]));
2601                                 s += strlen(s);
2602                                 break;
2603                         case DCH_Mon:
2604                                 INVALID_FOR_INTERVAL;
2605                                 if (!tm->tm_mon)
2606                                         break;
2607                                 if (S_TM(n->suffix))
2608                                 {
2609                                         char       *str = str_initcap_z(localized_abbrev_months[tm->tm_mon - 1], collid);
2610
2611                                         if (strlen(str) <= (n->key->len + TM_SUFFIX_LEN) * DCH_MAX_ITEM_SIZ)
2612                                                 strcpy(s, str);
2613                                         else
2614                                                 ereport(ERROR,
2615                                                                 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2616                                                   errmsg("localized string format value too long")));
2617                                 }
2618                                 else
2619                                         strcpy(s, months[tm->tm_mon - 1]);
2620                                 s += strlen(s);
2621                                 break;
2622                         case DCH_mon:
2623                                 INVALID_FOR_INTERVAL;
2624                                 if (!tm->tm_mon)
2625                                         break;
2626                                 if (S_TM(n->suffix))
2627                                 {
2628                                         char       *str = str_tolower_z(localized_abbrev_months[tm->tm_mon - 1], collid);
2629
2630                                         if (strlen(str) <= (n->key->len + TM_SUFFIX_LEN) * DCH_MAX_ITEM_SIZ)
2631                                                 strcpy(s, str);
2632                                         else
2633                                                 ereport(ERROR,
2634                                                                 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2635                                                   errmsg("localized string format value too long")));
2636                                 }
2637                                 else
2638                                         strcpy(s, asc_tolower_z(months[tm->tm_mon - 1]));
2639                                 s += strlen(s);
2640                                 break;
2641                         case DCH_MM:
2642                                 sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : (tm->tm_mon >= 0) ? 2 : 3,
2643                                                 tm->tm_mon);
2644                                 if (S_THth(n->suffix))
2645                                         str_numth(s, s, S_TH_TYPE(n->suffix));
2646                                 s += strlen(s);
2647                                 break;
2648                         case DCH_DAY:
2649                                 INVALID_FOR_INTERVAL;
2650                                 if (S_TM(n->suffix))
2651                                 {
2652                                         char       *str = str_toupper_z(localized_full_days[tm->tm_wday], collid);
2653
2654                                         if (strlen(str) <= (n->key->len + TM_SUFFIX_LEN) * DCH_MAX_ITEM_SIZ)
2655                                                 strcpy(s, str);
2656                                         else
2657                                                 ereport(ERROR,
2658                                                                 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2659                                                   errmsg("localized string format value too long")));
2660                                 }
2661                                 else
2662                                         sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9,
2663                                                         asc_toupper_z(days[tm->tm_wday]));
2664                                 s += strlen(s);
2665                                 break;
2666                         case DCH_Day:
2667                                 INVALID_FOR_INTERVAL;
2668                                 if (S_TM(n->suffix))
2669                                 {
2670                                         char       *str = str_initcap_z(localized_full_days[tm->tm_wday], collid);
2671
2672                                         if (strlen(str) <= (n->key->len + TM_SUFFIX_LEN) * DCH_MAX_ITEM_SIZ)
2673                                                 strcpy(s, str);
2674                                         else
2675                                                 ereport(ERROR,
2676                                                                 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2677                                                   errmsg("localized string format value too long")));
2678                                 }
2679                                 else
2680                                         sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9,
2681                                                         days[tm->tm_wday]);
2682                                 s += strlen(s);
2683                                 break;
2684                         case DCH_day:
2685                                 INVALID_FOR_INTERVAL;
2686                                 if (S_TM(n->suffix))
2687                                 {
2688                                         char       *str = str_tolower_z(localized_full_days[tm->tm_wday], collid);
2689
2690                                         if (strlen(str) <= (n->key->len + TM_SUFFIX_LEN) * DCH_MAX_ITEM_SIZ)
2691                                                 strcpy(s, str);
2692                                         else
2693                                                 ereport(ERROR,
2694                                                                 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2695                                                   errmsg("localized string format value too long")));
2696                                 }
2697                                 else
2698                                         sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9,
2699                                                         asc_tolower_z(days[tm->tm_wday]));
2700                                 s += strlen(s);
2701                                 break;
2702                         case DCH_DY:
2703                                 INVALID_FOR_INTERVAL;
2704                                 if (S_TM(n->suffix))
2705                                 {
2706                                         char       *str = str_toupper_z(localized_abbrev_days[tm->tm_wday], collid);
2707
2708                                         if (strlen(str) <= (n->key->len + TM_SUFFIX_LEN) * DCH_MAX_ITEM_SIZ)
2709                                                 strcpy(s, str);
2710                                         else
2711                                                 ereport(ERROR,
2712                                                                 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2713                                                   errmsg("localized string format value too long")));
2714                                 }
2715                                 else
2716                                         strcpy(s, asc_toupper_z(days_short[tm->tm_wday]));
2717                                 s += strlen(s);
2718                                 break;
2719                         case DCH_Dy:
2720                                 INVALID_FOR_INTERVAL;
2721                                 if (S_TM(n->suffix))
2722                                 {
2723                                         char       *str = str_initcap_z(localized_abbrev_days[tm->tm_wday], collid);
2724
2725                                         if (strlen(str) <= (n->key->len + TM_SUFFIX_LEN) * DCH_MAX_ITEM_SIZ)
2726                                                 strcpy(s, str);
2727                                         else
2728                                                 ereport(ERROR,
2729                                                                 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2730                                                   errmsg("localized string format value too long")));
2731                                 }
2732                                 else
2733                                         strcpy(s, days_short[tm->tm_wday]);
2734                                 s += strlen(s);
2735                                 break;
2736                         case DCH_dy:
2737                                 INVALID_FOR_INTERVAL;
2738                                 if (S_TM(n->suffix))
2739                                 {
2740                                         char       *str = str_tolower_z(localized_abbrev_days[tm->tm_wday], collid);
2741
2742                                         if (strlen(str) <= (n->key->len + TM_SUFFIX_LEN) * DCH_MAX_ITEM_SIZ)
2743                                                 strcpy(s, str);
2744                                         else
2745                                                 ereport(ERROR,
2746                                                                 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2747                                                   errmsg("localized string format value too long")));
2748                                 }
2749                                 else
2750                                         strcpy(s, asc_tolower_z(days_short[tm->tm_wday]));
2751                                 s += strlen(s);
2752                                 break;
2753                         case DCH_DDD:
2754                         case DCH_IDDD:
2755                                 sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : 3,
2756                                                 (n->key->id == DCH_DDD) ?
2757                                                 tm->tm_yday :
2758                                           date2isoyearday(tm->tm_year, tm->tm_mon, tm->tm_mday));
2759                                 if (S_THth(n->suffix))
2760                                         str_numth(s, s, S_TH_TYPE(n->suffix));
2761                                 s += strlen(s);
2762                                 break;
2763                         case DCH_DD:
2764                                 sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : 2, tm->tm_mday);
2765                                 if (S_THth(n->suffix))
2766                                         str_numth(s, s, S_TH_TYPE(n->suffix));
2767                                 s += strlen(s);
2768                                 break;
2769                         case DCH_D:
2770                                 INVALID_FOR_INTERVAL;
2771                                 sprintf(s, "%d", tm->tm_wday + 1);
2772                                 if (S_THth(n->suffix))
2773                                         str_numth(s, s, S_TH_TYPE(n->suffix));
2774                                 s += strlen(s);
2775                                 break;
2776                         case DCH_ID:
2777                                 INVALID_FOR_INTERVAL;
2778                                 sprintf(s, "%d", (tm->tm_wday == 0) ? 7 : tm->tm_wday);
2779                                 if (S_THth(n->suffix))
2780                                         str_numth(s, s, S_TH_TYPE(n->suffix));
2781                                 s += strlen(s);
2782                                 break;
2783                         case DCH_WW:
2784                                 sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : 2,
2785                                                 (tm->tm_yday - 1) / 7 + 1);
2786                                 if (S_THth(n->suffix))
2787                                         str_numth(s, s, S_TH_TYPE(n->suffix));
2788                                 s += strlen(s);
2789                                 break;
2790                         case DCH_IW:
2791                                 sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : 2,
2792                                                 date2isoweek(tm->tm_year, tm->tm_mon, tm->tm_mday));
2793                                 if (S_THth(n->suffix))
2794                                         str_numth(s, s, S_TH_TYPE(n->suffix));
2795                                 s += strlen(s);
2796                                 break;
2797                         case DCH_Q:
2798                                 if (!tm->tm_mon)
2799                                         break;
2800                                 sprintf(s, "%d", (tm->tm_mon - 1) / 3 + 1);
2801                                 if (S_THth(n->suffix))
2802                                         str_numth(s, s, S_TH_TYPE(n->suffix));
2803                                 s += strlen(s);
2804                                 break;
2805                         case DCH_CC:
2806                                 if (is_interval)        /* straight calculation */
2807                                         i = tm->tm_year / 100;
2808                                 else
2809                                 {
2810                                         if (tm->tm_year > 0)
2811                                                 /* Century 20 == 1901 - 2000 */
2812                                                 i = (tm->tm_year - 1) / 100 + 1;
2813                                         else
2814                                                 /* Century 6BC == 600BC - 501BC */
2815                                                 i = tm->tm_year / 100 - 1;
2816                                 }
2817                                 if (i <= 99 && i >= -99)
2818                                         sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : (i >= 0) ? 2 : 3, i);
2819                                 else
2820                                         sprintf(s, "%d", i);
2821                                 if (S_THth(n->suffix))
2822                                         str_numth(s, s, S_TH_TYPE(n->suffix));
2823                                 s += strlen(s);
2824                                 break;
2825                         case DCH_Y_YYY:
2826                                 i = ADJUST_YEAR(tm->tm_year, is_interval) / 1000;
2827                                 sprintf(s, "%d,%03d", i,
2828                                                 ADJUST_YEAR(tm->tm_year, is_interval) - (i * 1000));
2829                                 if (S_THth(n->suffix))
2830                                         str_numth(s, s, S_TH_TYPE(n->suffix));
2831                                 s += strlen(s);
2832                                 break;
2833                         case DCH_YYYY:
2834                         case DCH_IYYY:
2835                                 sprintf(s, "%0*d",
2836                                                 S_FM(n->suffix) ? 0 :
2837                                                 (ADJUST_YEAR(tm->tm_year, is_interval) >= 0) ? 4 : 5,
2838                                                 (n->key->id == DCH_YYYY ?
2839                                                  ADJUST_YEAR(tm->tm_year, is_interval) :
2840                                                  ADJUST_YEAR(date2isoyear(tm->tm_year,
2841                                                                                                   tm->tm_mon,
2842                                                                                                   tm->tm_mday),
2843                                                                          is_interval)));
2844                                 if (S_THth(n->suffix))
2845                                         str_numth(s, s, S_TH_TYPE(n->suffix));
2846                                 s += strlen(s);
2847                                 break;
2848                         case DCH_YYY:
2849                         case DCH_IYY:
2850                                 sprintf(s, "%0*d",
2851                                                 S_FM(n->suffix) ? 0 :
2852                                                 (ADJUST_YEAR(tm->tm_year, is_interval) >= 0) ? 3 : 4,
2853                                                 (n->key->id == DCH_YYY ?
2854                                                  ADJUST_YEAR(tm->tm_year, is_interval) :
2855                                                  ADJUST_YEAR(date2isoyear(tm->tm_year,
2856                                                                                                   tm->tm_mon,
2857                                                                                                   tm->tm_mday),
2858                                                                          is_interval)) % 1000);
2859                                 if (S_THth(n->suffix))
2860                                         str_numth(s, s, S_TH_TYPE(n->suffix));
2861                                 s += strlen(s);
2862                                 break;
2863                         case DCH_YY:
2864                         case DCH_IY:
2865                                 sprintf(s, "%0*d",
2866                                                 S_FM(n->suffix) ? 0 :
2867                                                 (ADJUST_YEAR(tm->tm_year, is_interval) >= 0) ? 2 : 3,
2868                                                 (n->key->id == DCH_YY ?
2869                                                  ADJUST_YEAR(tm->tm_year, is_interval) :
2870                                                  ADJUST_YEAR(date2isoyear(tm->tm_year,
2871                                                                                                   tm->tm_mon,
2872                                                                                                   tm->tm_mday),
2873                                                                          is_interval)) % 100);
2874                                 if (S_THth(n->suffix))
2875                                         str_numth(s, s, S_TH_TYPE(n->suffix));
2876                                 s += strlen(s);
2877                                 break;
2878                         case DCH_Y:
2879                         case DCH_I:
2880                                 sprintf(s, "%1d",
2881                                                 (n->key->id == DCH_Y ?
2882                                                  ADJUST_YEAR(tm->tm_year, is_interval) :
2883                                                  ADJUST_YEAR(date2isoyear(tm->tm_year,
2884                                                                                                   tm->tm_mon,
2885                                                                                                   tm->tm_mday),
2886                                                                          is_interval)) % 10);
2887                                 if (S_THth(n->suffix))
2888                                         str_numth(s, s, S_TH_TYPE(n->suffix));
2889                                 s += strlen(s);
2890                                 break;
2891                         case DCH_RM:
2892                                 if (!tm->tm_mon)
2893                                         break;
2894                                 sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -4,
2895                                                 rm_months_upper[MONTHS_PER_YEAR - tm->tm_mon]);
2896                                 s += strlen(s);
2897                                 break;
2898                         case DCH_rm:
2899                                 if (!tm->tm_mon)
2900                                         break;
2901                                 sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -4,
2902                                                 rm_months_lower[MONTHS_PER_YEAR - tm->tm_mon]);
2903                                 s += strlen(s);
2904                                 break;
2905                         case DCH_W:
2906                                 sprintf(s, "%d", (tm->tm_mday - 1) / 7 + 1);
2907                                 if (S_THth(n->suffix))
2908                                         str_numth(s, s, S_TH_TYPE(n->suffix));
2909                                 s += strlen(s);
2910                                 break;
2911                         case DCH_J:
2912                                 sprintf(s, "%d", date2j(tm->tm_year, tm->tm_mon, tm->tm_mday));
2913                                 if (S_THth(n->suffix))
2914                                         str_numth(s, s, S_TH_TYPE(n->suffix));
2915                                 s += strlen(s);
2916                                 break;
2917                 }
2918         }
2919
2920         *s = '\0';
2921 }
2922
2923 /* ----------
2924  * Process a string as denoted by a list of FormatNodes.
2925  * The TmFromChar struct pointed to by 'out' is populated with the results.
2926  *
2927  * Note: we currently don't have any to_interval() function, so there
2928  * is no need here for INVALID_FOR_INTERVAL checks.
2929  * ----------
2930  */
2931 static void
2932 DCH_from_char(FormatNode *node, char *in, TmFromChar *out)
2933 {
2934         FormatNode *n;
2935         char       *s;
2936         int                     len,
2937                                 value;
2938         bool            fx_mode = false;
2939
2940         for (n = node, s = in; n->type != NODE_TYPE_END && *s != '\0'; n++)
2941         {
2942                 if (n->type != NODE_TYPE_ACTION)
2943                 {
2944                         /*
2945                          * Separator, so consume one character from input string.  Notice
2946                          * we don't insist that the consumed character match the format's
2947                          * character.
2948                          */
2949                         s++;
2950                         continue;
2951                 }
2952
2953                 /* Ignore spaces before fields when not in FX (fixed width) mode */
2954                 if (!fx_mode && n->key->id != DCH_FX)
2955                 {
2956                         while (*s != '\0' && isspace((unsigned char) *s))
2957                                 s++;
2958                 }
2959
2960                 from_char_set_mode(out, n->key->date_mode);
2961
2962                 switch (n->key->id)
2963                 {
2964                         case DCH_FX:
2965                                 fx_mode = true;
2966                                 break;
2967                         case DCH_A_M:
2968                         case DCH_P_M:
2969                         case DCH_a_m:
2970                         case DCH_p_m:
2971                                 from_char_seq_search(&value, &s, ampm_strings_long,
2972                                                                          ALL_UPPER, n->key->len, n);
2973                                 from_char_set_int(&out->pm, value % 2, n);
2974                                 out->clock = CLOCK_12_HOUR;
2975                                 break;
2976                         case DCH_AM:
2977                         case DCH_PM:
2978                         case DCH_am:
2979                         case DCH_pm:
2980                                 from_char_seq_search(&value, &s, ampm_strings,
2981                                                                          ALL_UPPER, n->key->len, n);
2982                                 from_char_set_int(&out->pm, value % 2, n);
2983                                 out->clock = CLOCK_12_HOUR;
2984                                 break;
2985                         case DCH_HH:
2986                         case DCH_HH12:
2987                                 from_char_parse_int_len(&out->hh, &s, 2, n);
2988                                 out->clock = CLOCK_12_HOUR;
2989                                 SKIP_THth(s, n->suffix);
2990                                 break;
2991                         case DCH_HH24:
2992                                 from_char_parse_int_len(&out->hh, &s, 2, n);
2993                                 SKIP_THth(s, n->suffix);
2994                                 break;
2995                         case DCH_MI:
2996                                 from_char_parse_int(&out->mi, &s, n);
2997                                 SKIP_THth(s, n->suffix);
2998                                 break;
2999                         case DCH_SS:
3000                                 from_char_parse_int(&out->ss, &s, n);
3001                                 SKIP_THth(s, n->suffix);
3002                                 break;
3003                         case DCH_MS:            /* millisecond */
3004                                 len = from_char_parse_int_len(&out->ms, &s, 3, n);
3005
3006                                 /*
3007                                  * 25 is 0.25 and 250 is 0.25 too; 025 is 0.025 and not 0.25
3008                                  */
3009                                 out->ms *= len == 1 ? 100 :
3010                                         len == 2 ? 10 : 1;
3011
3012                                 SKIP_THth(s, n->suffix);
3013                                 break;
3014                         case DCH_US:            /* microsecond */
3015                                 len = from_char_parse_int_len(&out->us, &s, 6, n);
3016
3017                                 out->us *= len == 1 ? 100000 :
3018                                         len == 2 ? 10000 :
3019                                         len == 3 ? 1000 :
3020                                         len == 4 ? 100 :
3021                                         len == 5 ? 10 : 1;
3022
3023                                 SKIP_THth(s, n->suffix);
3024                                 break;
3025                         case DCH_SSSS:
3026                                 from_char_parse_int(&out->ssss, &s, n);
3027                                 SKIP_THth(s, n->suffix);
3028                                 break;
3029                         case DCH_tz:
3030                         case DCH_TZ:
3031                         case DCH_OF:
3032                                 ereport(ERROR,
3033                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3034                                                  errmsg("\"TZ\"/\"tz\"/\"OF\" format patterns are not supported in to_date")));
3035                         case DCH_A_D:
3036                         case DCH_B_C:
3037                         case DCH_a_d:
3038                         case DCH_b_c:
3039                                 from_char_seq_search(&value, &s, adbc_strings_long,
3040                                                                          ALL_UPPER, n->key->len, n);
3041                                 from_char_set_int(&out->bc, value % 2, n);
3042                                 break;
3043                         case DCH_AD:
3044                         case DCH_BC:
3045                         case DCH_ad:
3046                         case DCH_bc:
3047                                 from_char_seq_search(&value, &s, adbc_strings,
3048                                                                          ALL_UPPER, n->key->len, n);
3049                                 from_char_set_int(&out->bc, value % 2, n);
3050                                 break;
3051                         case DCH_MONTH:
3052                         case DCH_Month:
3053                         case DCH_month:
3054                                 from_char_seq_search(&value, &s, months_full, ONE_UPPER,
3055                                                                          MAX_MONTH_LEN, n);
3056                                 from_char_set_int(&out->mm, value + 1, n);
3057                                 break;
3058                         case DCH_MON:
3059                         case DCH_Mon:
3060                         case DCH_mon:
3061                                 from_char_seq_search(&value, &s, months, ONE_UPPER,
3062                                                                          MAX_MON_LEN, n);
3063                                 from_char_set_int(&out->mm, value + 1, n);
3064                                 break;
3065                         case DCH_MM:
3066                                 from_char_parse_int(&out->mm, &s, n);
3067                                 SKIP_THth(s, n->suffix);
3068                                 break;
3069                         case DCH_DAY:
3070                         case DCH_Day:
3071                         case DCH_day:
3072                                 from_char_seq_search(&value, &s, days, ONE_UPPER,
3073                                                                          MAX_DAY_LEN, n);
3074                                 from_char_set_int(&out->d, value, n);
3075                                 out->d++;
3076                                 break;
3077                         case DCH_DY:
3078                         case DCH_Dy:
3079                         case DCH_dy:
3080                                 from_char_seq_search(&value, &s, days, ONE_UPPER,
3081                                                                          MAX_DY_LEN, n);
3082                                 from_char_set_int(&out->d, value, n);
3083                                 out->d++;
3084                                 break;
3085                         case DCH_DDD:
3086                                 from_char_parse_int(&out->ddd, &s, n);
3087                                 SKIP_THth(s, n->suffix);
3088                                 break;
3089                         case DCH_IDDD:
3090                                 from_char_parse_int_len(&out->ddd, &s, 3, n);
3091                                 SKIP_THth(s, n->suffix);
3092                                 break;
3093                         case DCH_DD:
3094                                 from_char_parse_int(&out->dd, &s, n);
3095                                 SKIP_THth(s, n->suffix);
3096                                 break;
3097                         case DCH_D:
3098                                 from_char_parse_int(&out->d, &s, n);
3099                                 SKIP_THth(s, n->suffix);
3100                                 break;
3101                         case DCH_ID:
3102                                 from_char_parse_int_len(&out->d, &s, 1, n);
3103                                 /* Shift numbering to match Gregorian where Sunday = 1 */
3104                                 if (++out->d > 7)
3105                                         out->d = 1;
3106                                 SKIP_THth(s, n->suffix);
3107                                 break;
3108                         case DCH_WW:
3109                         case DCH_IW:
3110                                 from_char_parse_int(&out->ww, &s, n);
3111                                 SKIP_THth(s, n->suffix);
3112                                 break;
3113                         case DCH_Q:
3114
3115                                 /*
3116                                  * We ignore 'Q' when converting to date because it is unclear
3117                                  * which date in the quarter to use, and some people specify
3118                                  * both quarter and month, so if it was honored it might
3119                                  * conflict with the supplied month. That is also why we don't
3120                                  * throw an error.
3121                                  *
3122                                  * We still parse the source string for an integer, but it
3123                                  * isn't stored anywhere in 'out'.
3124                                  */
3125                                 from_char_parse_int((int *) NULL, &s, n);
3126                                 SKIP_THth(s, n->suffix);
3127                                 break;
3128                         case DCH_CC:
3129                                 from_char_parse_int(&out->cc, &s, n);
3130                                 SKIP_THth(s, n->suffix);
3131                                 break;
3132                         case DCH_Y_YYY:
3133                                 {
3134                                         int                     matched,
3135                                                                 years,
3136                                                                 millennia,
3137                                                                 nch;
3138
3139                                         matched = sscanf(s, "%d,%03d%n", &millennia, &years, &nch);
3140                                         if (matched < 2)
3141                                                 ereport(ERROR,
3142                                                                 (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
3143                                                           errmsg("invalid input string for \"Y,YYY\"")));
3144                                         years += (millennia * 1000);
3145                                         from_char_set_int(&out->year, years, n);
3146                                         out->yysz = 4;
3147                                         s += nch;
3148                                         SKIP_THth(s, n->suffix);
3149                                 }
3150                                 break;
3151                         case DCH_YYYY:
3152                         case DCH_IYYY:
3153                                 from_char_parse_int(&out->year, &s, n);
3154                                 out->yysz = 4;
3155                                 SKIP_THth(s, n->suffix);
3156                                 break;
3157                         case DCH_YYY:
3158                         case DCH_IYY:
3159                                 if (from_char_parse_int(&out->year, &s, n) < 4)
3160                                         out->year = adjust_partial_year_to_2020(out->year);
3161                                 out->yysz = 3;
3162                                 SKIP_THth(s, n->suffix);
3163                                 break;
3164                         case DCH_YY:
3165                         case DCH_IY:
3166                                 if (from_char_parse_int(&out->year, &s, n) < 4)
3167                                         out->year = adjust_partial_year_to_2020(out->year);
3168                                 out->yysz = 2;
3169                                 SKIP_THth(s, n->suffix);
3170                                 break;
3171                         case DCH_Y:
3172                         case DCH_I:
3173                                 if (from_char_parse_int(&out->year, &s, n) < 4)
3174                                         out->year = adjust_partial_year_to_2020(out->year);
3175                                 out->yysz = 1;
3176                                 SKIP_THth(s, n->suffix);
3177                                 break;
3178                         case DCH_RM:
3179                                 from_char_seq_search(&value, &s, rm_months_upper,
3180                                                                          ALL_UPPER, MAX_RM_LEN, n);
3181                                 from_char_set_int(&out->mm, MONTHS_PER_YEAR - value, n);
3182                                 break;
3183                         case DCH_rm:
3184                                 from_char_seq_search(&value, &s, rm_months_lower,
3185                                                                          ALL_LOWER, MAX_RM_LEN, n);
3186                                 from_char_set_int(&out->mm, MONTHS_PER_YEAR - value, n);
3187                                 break;
3188                         case DCH_W:
3189                                 from_char_parse_int(&out->w, &s, n);
3190                                 SKIP_THth(s, n->suffix);
3191                                 break;
3192                         case DCH_J:
3193                                 from_char_parse_int(&out->j, &s, n);
3194                                 SKIP_THth(s, n->suffix);
3195                                 break;
3196                 }
3197         }
3198 }
3199
3200 /* select a DCHCacheEntry to hold the given format picture */
3201 static DCHCacheEntry *
3202 DCH_cache_getnew(const char *str)
3203 {
3204         DCHCacheEntry *ent;
3205
3206         /* counter overflow check - paranoia? */
3207         if (DCHCounter >= (INT_MAX - DCH_CACHE_ENTRIES))
3208         {
3209                 DCHCounter = 0;
3210
3211                 for (ent = DCHCache; ent < (DCHCache + DCH_CACHE_ENTRIES); ent++)
3212                         ent->age = (++DCHCounter);
3213         }
3214
3215         /*
3216          * If cache is full, remove oldest entry (or recycle first not-valid one)
3217          */
3218         if (n_DCHCache >= DCH_CACHE_ENTRIES)
3219         {
3220                 DCHCacheEntry *old = DCHCache + 0;
3221
3222 #ifdef DEBUG_TO_FROM_CHAR
3223                 elog(DEBUG_elog_output, "cache is full (%d)", n_DCHCache);
3224 #endif
3225                 if (old->valid)
3226                 {
3227                         for (ent = DCHCache + 1; ent < (DCHCache + DCH_CACHE_ENTRIES); ent++)
3228                         {
3229                                 if (!ent->valid)
3230                                 {
3231                                         old = ent;
3232                                         break;
3233                                 }
3234                                 if (ent->age < old->age)
3235                                         old = ent;
3236                         }
3237                 }
3238 #ifdef DEBUG_TO_FROM_CHAR
3239                 elog(DEBUG_elog_output, "OLD: '%s' AGE: %d", old->str, old->age);
3240 #endif
3241                 old->valid = false;
3242                 StrNCpy(old->str, str, DCH_CACHE_SIZE + 1);
3243                 old->age = (++DCHCounter);
3244                 /* caller is expected to fill format, then set valid */
3245                 return old;
3246         }
3247         else
3248         {
3249 #ifdef DEBUG_TO_FROM_CHAR
3250                 elog(DEBUG_elog_output, "NEW (%d)", n_DCHCache);
3251 #endif
3252                 ent = DCHCache + n_DCHCache;
3253                 ent->valid = false;
3254                 StrNCpy(ent->str, str, DCH_CACHE_SIZE + 1);
3255                 ent->age = (++DCHCounter);
3256                 /* caller is expected to fill format, then set valid */
3257                 ++n_DCHCache;
3258                 return ent;
3259         }
3260 }
3261
3262 /* look for an existing DCHCacheEntry matching the given format picture */
3263 static DCHCacheEntry *
3264 DCH_cache_search(const char *str)
3265 {
3266         int                     i;
3267         DCHCacheEntry *ent;
3268
3269         /* counter overflow check - paranoia? */
3270         if (DCHCounter >= (INT_MAX - DCH_CACHE_ENTRIES))
3271         {
3272                 DCHCounter = 0;
3273
3274                 for (ent = DCHCache; ent < (DCHCache + DCH_CACHE_ENTRIES); ent++)
3275                         ent->age = (++DCHCounter);
3276         }
3277
3278         for (i = 0, ent = DCHCache; i < n_DCHCache; i++, ent++)
3279         {
3280                 if (ent->valid && strcmp(ent->str, str) == 0)
3281                 {
3282                         ent->age = (++DCHCounter);
3283                         return ent;
3284                 }
3285         }
3286
3287         return NULL;
3288 }
3289
3290 /* Find or create a DCHCacheEntry for the given format picture */
3291 static DCHCacheEntry *
3292 DCH_cache_fetch(const char *str)
3293 {
3294         DCHCacheEntry *ent;
3295
3296         if ((ent = DCH_cache_search(str)) == NULL)
3297         {
3298                 /*
3299                  * Not in the cache, must run parser and save a new format-picture to
3300                  * the cache.  Do not mark the cache entry valid until parsing
3301                  * succeeds.
3302                  */
3303                 ent = DCH_cache_getnew(str);
3304
3305                 parse_format(ent->format, str, DCH_keywords,
3306                                          DCH_suff, DCH_index, DCH_TYPE, NULL);
3307
3308                 ent->valid = true;
3309         }
3310         return ent;
3311 }
3312
3313 /*
3314  * Format a date/time or interval into a string according to fmt.
3315  * We parse fmt into a list of FormatNodes.  This is then passed to DCH_to_char
3316  * for formatting.
3317  */
3318 static text *
3319 datetime_to_char_body(TmToChar *tmtc, text *fmt, bool is_interval, Oid collid)
3320 {
3321         FormatNode *format;
3322         char       *fmt_str,
3323                            *result;
3324         bool            incache;
3325         int                     fmt_len;
3326         text       *res;
3327
3328         /*
3329          * Convert fmt to C string
3330          */
3331         fmt_str = text_to_cstring(fmt);
3332         fmt_len = strlen(fmt_str);
3333
3334         /*
3335          * Allocate workspace for result as C string
3336          */
3337         result = palloc((fmt_len * DCH_MAX_ITEM_SIZ) + 1);
3338         *result = '\0';
3339
3340         if (fmt_len > DCH_CACHE_SIZE)
3341         {
3342                 /*
3343                  * Allocate new memory if format picture is bigger than static cache
3344                  * and do not use cache (call parser always)
3345                  */
3346                 incache = FALSE;
3347
3348                 format = (FormatNode *) palloc((fmt_len + 1) * sizeof(FormatNode));
3349
3350                 parse_format(format, fmt_str, DCH_keywords,
3351                                          DCH_suff, DCH_index, DCH_TYPE, NULL);
3352         }
3353         else
3354         {
3355                 /*
3356                  * Use cache buffers
3357                  */
3358                 DCHCacheEntry *ent = DCH_cache_fetch(fmt_str);
3359
3360                 incache = TRUE;
3361                 format = ent->format;
3362         }
3363
3364         /* The real work is here */
3365         DCH_to_char(format, is_interval, tmtc, result, collid);
3366
3367         if (!incache)
3368                 pfree(format);
3369
3370         pfree(fmt_str);
3371
3372         /* convert C-string result to TEXT format */
3373         res = cstring_to_text(result);
3374
3375         pfree(result);
3376         return res;
3377 }
3378
3379 /****************************************************************************
3380  *                              Public routines
3381  ***************************************************************************/
3382
3383 /* -------------------
3384  * TIMESTAMP to_char()
3385  * -------------------
3386  */
3387 Datum
3388 timestamp_to_char(PG_FUNCTION_ARGS)
3389 {
3390         Timestamp       dt = PG_GETARG_TIMESTAMP(0);
3391         text       *fmt = PG_GETARG_TEXT_P(1),
3392                            *res;
3393         TmToChar        tmtc;
3394         struct pg_tm *tm;
3395         int                     thisdate;
3396
3397         if ((VARSIZE(fmt) - VARHDRSZ) <= 0 || TIMESTAMP_NOT_FINITE(dt))
3398                 PG_RETURN_NULL();
3399
3400         ZERO_tmtc(&tmtc);
3401         tm = tmtcTm(&tmtc);
3402
3403         if (timestamp2tm(dt, NULL, tm, &tmtcFsec(&tmtc), NULL, NULL) != 0)
3404                 ereport(ERROR,
3405                                 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3406                                  errmsg("timestamp out of range")));
3407
3408         thisdate = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday);
3409         tm->tm_wday = (thisdate + 1) % 7;
3410         tm->tm_yday = thisdate - date2j(tm->tm_year, 1, 1) + 1;
3411
3412         if (!(res = datetime_to_char_body(&tmtc, fmt, false, PG_GET_COLLATION())))
3413                 PG_RETURN_NULL();
3414
3415         PG_RETURN_TEXT_P(res);
3416 }
3417
3418 Datum
3419 timestamptz_to_char(PG_FUNCTION_ARGS)
3420 {
3421         TimestampTz dt = PG_GETARG_TIMESTAMP(0);
3422         text       *fmt = PG_GETARG_TEXT_P(1),
3423                            *res;
3424         TmToChar        tmtc;
3425         int                     tz;
3426         struct pg_tm *tm;
3427         int                     thisdate;
3428
3429         if ((VARSIZE(fmt) - VARHDRSZ) <= 0 || TIMESTAMP_NOT_FINITE(dt))
3430                 PG_RETURN_NULL();
3431
3432         ZERO_tmtc(&tmtc);
3433         tm = tmtcTm(&tmtc);
3434
3435         if (timestamp2tm(dt, &tz, tm, &tmtcFsec(&tmtc), &tmtcTzn(&tmtc), NULL) != 0)
3436                 ereport(ERROR,
3437                                 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3438                                  errmsg("timestamp out of range")));
3439
3440         thisdate = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday);
3441         tm->tm_wday = (thisdate + 1) % 7;
3442         tm->tm_yday = thisdate - date2j(tm->tm_year, 1, 1) + 1;
3443
3444         if (!(res = datetime_to_char_body(&tmtc, fmt, false, PG_GET_COLLATION())))
3445                 PG_RETURN_NULL();
3446
3447         PG_RETURN_TEXT_P(res);
3448 }
3449
3450
3451 /* -------------------
3452  * INTERVAL to_char()
3453  * -------------------
3454  */
3455 Datum
3456 interval_to_char(PG_FUNCTION_ARGS)
3457 {
3458         Interval   *it = PG_GETARG_INTERVAL_P(0);
3459         text       *fmt = PG_GETARG_TEXT_P(1),
3460                            *res;
3461         TmToChar        tmtc;
3462         struct pg_tm *tm;
3463
3464         if ((VARSIZE(fmt) - VARHDRSZ) <= 0)
3465                 PG_RETURN_NULL();
3466
3467         ZERO_tmtc(&tmtc);
3468         tm = tmtcTm(&tmtc);
3469
3470         if (interval2tm(*it, tm, &tmtcFsec(&tmtc)) != 0)
3471                 PG_RETURN_NULL();
3472
3473         /* wday is meaningless, yday approximates the total span in days */
3474         tm->tm_yday = (tm->tm_year * MONTHS_PER_YEAR + tm->tm_mon) * DAYS_PER_MONTH + tm->tm_mday;
3475
3476         if (!(res = datetime_to_char_body(&tmtc, fmt, true, PG_GET_COLLATION())))
3477                 PG_RETURN_NULL();
3478
3479         PG_RETURN_TEXT_P(res);
3480 }
3481
3482 /* ---------------------
3483  * TO_TIMESTAMP()
3484  *
3485  * Make Timestamp from date_str which is formatted at argument 'fmt'
3486  * ( to_timestamp is reverse to_char() )
3487  * ---------------------
3488  */
3489 Datum
3490 to_timestamp(PG_FUNCTION_ARGS)
3491 {
3492         text       *date_txt = PG_GETARG_TEXT_P(0);
3493         text       *fmt = PG_GETARG_TEXT_P(1);
3494         Timestamp       result;
3495         int                     tz;
3496         struct pg_tm tm;
3497         fsec_t          fsec;
3498
3499         do_to_timestamp(date_txt, fmt, &tm, &fsec);
3500
3501         tz = DetermineTimeZoneOffset(&tm, session_timezone);
3502
3503         if (tm2timestamp(&tm, fsec, &tz, &result) != 0)
3504                 ereport(ERROR,
3505                                 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3506                                  errmsg("timestamp out of range")));
3507
3508         PG_RETURN_TIMESTAMP(result);
3509 }
3510
3511 /* ----------
3512  * TO_DATE
3513  *      Make Date from date_str which is formated at argument 'fmt'
3514  * ----------
3515  */
3516 Datum
3517 to_date(PG_FUNCTION_ARGS)
3518 {
3519         text       *date_txt = PG_GETARG_TEXT_P(0);
3520         text       *fmt = PG_GETARG_TEXT_P(1);
3521         DateADT         result;
3522         struct pg_tm tm;
3523         fsec_t          fsec;
3524
3525         do_to_timestamp(date_txt, fmt, &tm, &fsec);
3526
3527         /* Prevent overflow in Julian-day routines */
3528         if (!IS_VALID_JULIAN(tm.tm_year, tm.tm_mon, tm.tm_mday))
3529                 ereport(ERROR,
3530                                 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3531                                  errmsg("date out of range: \"%s\"",
3532                                                 text_to_cstring(date_txt))));
3533
3534         result = date2j(tm.tm_year, tm.tm_mon, tm.tm_mday) - POSTGRES_EPOCH_JDATE;
3535
3536         /* Now check for just-out-of-range dates */
3537         if (!IS_VALID_DATE(result))
3538                 ereport(ERROR,
3539                                 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3540                                  errmsg("date out of range: \"%s\"",
3541                                                 text_to_cstring(date_txt))));
3542
3543         PG_RETURN_DATEADT(result);
3544 }
3545
3546 /*
3547  * do_to_timestamp: shared code for to_timestamp and to_date
3548  *
3549  * Parse the 'date_txt' according to 'fmt', return results as a struct pg_tm
3550  * and fractional seconds.
3551  *
3552  * We parse 'fmt' into a list of FormatNodes, which is then passed to
3553  * DCH_from_char to populate a TmFromChar with the parsed contents of
3554  * 'date_txt'.
3555  *
3556  * The TmFromChar is then analysed and converted into the final results in
3557  * struct 'tm' and 'fsec'.
3558  */
3559 static void
3560 do_to_timestamp(text *date_txt, text *fmt,
3561                                 struct pg_tm * tm, fsec_t *fsec)
3562 {
3563         FormatNode *format;
3564         TmFromChar      tmfc;
3565         int                     fmt_len;
3566         char       *date_str;
3567         int                     fmask;
3568
3569         date_str = text_to_cstring(date_txt);
3570
3571         ZERO_tmfc(&tmfc);
3572         ZERO_tm(tm);
3573         *fsec = 0;
3574         fmask = 0;                                      /* bit mask for ValidateDate() */
3575
3576         fmt_len = VARSIZE_ANY_EXHDR(fmt);
3577
3578         if (fmt_len)
3579         {
3580                 char       *fmt_str;
3581                 bool            incache;
3582
3583                 fmt_str = text_to_cstring(fmt);
3584
3585                 if (fmt_len > DCH_CACHE_SIZE)
3586                 {
3587                         /*
3588                          * Allocate new memory if format picture is bigger than static
3589                          * cache and do not use cache (call parser always)
3590                          */
3591                         incache = FALSE;
3592
3593                         format = (FormatNode *) palloc((fmt_len + 1) * sizeof(FormatNode));
3594
3595                         parse_format(format, fmt_str, DCH_keywords,
3596                                                  DCH_suff, DCH_index, DCH_TYPE, NULL);
3597                 }
3598                 else
3599                 {
3600                         /*
3601                          * Use cache buffers
3602                          */
3603                         DCHCacheEntry *ent = DCH_cache_fetch(fmt_str);
3604
3605                         incache = TRUE;
3606                         format = ent->format;
3607                 }
3608
3609 #ifdef DEBUG_TO_FROM_CHAR
3610                 /* dump_node(format, fmt_len); */
3611                 /* dump_index(DCH_keywords, DCH_index); */
3612 #endif
3613
3614                 DCH_from_char(format, date_str, &tmfc);
3615
3616                 pfree(fmt_str);
3617                 if (!incache)
3618                         pfree(format);
3619         }
3620
3621         DEBUG_TMFC(&tmfc);
3622
3623         /*
3624          * Convert to_date/to_timestamp input fields to standard 'tm'
3625          */
3626         if (tmfc.ssss)
3627         {
3628                 int                     x = tmfc.ssss;
3629
3630                 tm->tm_hour = x / SECS_PER_HOUR;
3631                 x %= SECS_PER_HOUR;
3632                 tm->tm_min = x / SECS_PER_MINUTE;
3633                 x %= SECS_PER_MINUTE;
3634                 tm->tm_sec = x;
3635         }
3636
3637         if (tmfc.ss)
3638                 tm->tm_sec = tmfc.ss;
3639         if (tmfc.mi)
3640                 tm->tm_min = tmfc.mi;
3641         if (tmfc.hh)
3642                 tm->tm_hour = tmfc.hh;
3643
3644         if (tmfc.clock == CLOCK_12_HOUR)
3645         {
3646                 if (tm->tm_hour < 1 || tm->tm_hour > HOURS_PER_DAY / 2)
3647                         ereport(ERROR,
3648                                         (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
3649                                          errmsg("hour \"%d\" is invalid for the 12-hour clock",
3650                                                         tm->tm_hour),
3651                                          errhint("Use the 24-hour clock, or give an hour between 1 and 12.")));
3652
3653                 if (tmfc.pm && tm->tm_hour < HOURS_PER_DAY / 2)
3654                         tm->tm_hour += HOURS_PER_DAY / 2;
3655                 else if (!tmfc.pm && tm->tm_hour == HOURS_PER_DAY / 2)
3656                         tm->tm_hour = 0;
3657         }
3658
3659         if (tmfc.year)
3660         {
3661                 /*
3662                  * If CC and YY (or Y) are provided, use YY as 2 low-order digits for
3663                  * the year in the given century.  Keep in mind that the 21st century
3664                  * AD runs from 2001-2100, not 2000-2099; 6th century BC runs from
3665                  * 600BC to 501BC.
3666                  */
3667                 if (tmfc.cc && tmfc.yysz <= 2)
3668                 {
3669                         if (tmfc.bc)
3670                                 tmfc.cc = -tmfc.cc;
3671                         tm->tm_year = tmfc.year % 100;
3672                         if (tm->tm_year)
3673                         {
3674                                 if (tmfc.cc >= 0)
3675                                         tm->tm_year += (tmfc.cc - 1) * 100;
3676                                 else
3677                                         tm->tm_year = (tmfc.cc + 1) * 100 - tm->tm_year + 1;
3678                         }
3679                         else
3680                         {
3681                                 /* find century year for dates ending in "00" */
3682                                 tm->tm_year = tmfc.cc * 100 + ((tmfc.cc >= 0) ? 0 : 1);
3683                         }
3684                 }
3685                 else
3686                 {
3687                         /* If a 4-digit year is provided, we use that and ignore CC. */
3688                         tm->tm_year = tmfc.year;
3689                         if (tmfc.bc && tm->tm_year > 0)
3690                                 tm->tm_year = -(tm->tm_year - 1);
3691                 }
3692                 fmask |= DTK_M(YEAR);
3693         }
3694         else if (tmfc.cc)
3695         {
3696                 /* use first year of century */
3697                 if (tmfc.bc)
3698                         tmfc.cc = -tmfc.cc;
3699                 if (tmfc.cc >= 0)
3700                         /* +1 because 21st century started in 2001 */
3701                         tm->tm_year = (tmfc.cc - 1) * 100 + 1;
3702                 else
3703                         /* +1 because year == 599 is 600 BC */
3704                         tm->tm_year = tmfc.cc * 100 + 1;
3705                 fmask |= DTK_M(YEAR);
3706         }
3707
3708         if (tmfc.j)
3709         {
3710                 j2date(tmfc.j, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
3711                 fmask |= DTK_DATE_M;
3712         }
3713
3714         if (tmfc.ww)
3715         {
3716                 if (tmfc.mode == FROM_CHAR_DATE_ISOWEEK)
3717                 {
3718                         /*
3719                          * If tmfc.d is not set, then the date is left at the beginning of
3720                          * the ISO week (Monday).
3721                          */
3722                         if (tmfc.d)
3723                                 isoweekdate2date(tmfc.ww, tmfc.d, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
3724                         else
3725                                 isoweek2date(tmfc.ww, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
3726                         fmask |= DTK_DATE_M;
3727                 }
3728                 else
3729                         tmfc.ddd = (tmfc.ww - 1) * 7 + 1;
3730         }
3731
3732         if (tmfc.w)
3733                 tmfc.dd = (tmfc.w - 1) * 7 + 1;
3734         if (tmfc.dd)
3735         {
3736                 tm->tm_mday = tmfc.dd;
3737                 fmask |= DTK_M(DAY);
3738         }
3739         if (tmfc.mm)
3740         {
3741                 tm->tm_mon = tmfc.mm;
3742                 fmask |= DTK_M(MONTH);
3743         }
3744
3745         if (tmfc.ddd && (tm->tm_mon <= 1 || tm->tm_mday <= 1))
3746         {
3747                 /*
3748                  * The month and day field have not been set, so we use the
3749                  * day-of-year field to populate them.  Depending on the date mode,
3750                  * this field may be interpreted as a Gregorian day-of-year, or an ISO
3751                  * week date day-of-year.
3752                  */
3753
3754                 if (!tm->tm_year && !tmfc.bc)
3755                         ereport(ERROR,
3756                                         (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
3757                         errmsg("cannot calculate day of year without year information")));
3758
3759                 if (tmfc.mode == FROM_CHAR_DATE_ISOWEEK)
3760                 {
3761                         int                     j0;             /* zeroth day of the ISO year, in Julian */
3762
3763                         j0 = isoweek2j(tm->tm_year, 1) - 1;
3764
3765                         j2date(j0 + tmfc.ddd, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
3766                         fmask |= DTK_DATE_M;
3767                 }
3768                 else
3769                 {
3770                         const int  *y;
3771                         int                     i;
3772
3773                         static const int ysum[2][13] = {
3774                                 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},
3775                         {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}};
3776
3777                         y = ysum[isleap(tm->tm_year)];
3778
3779                         for (i = 1; i <= MONTHS_PER_YEAR; i++)
3780                         {
3781                                 if (tmfc.ddd <= y[i])
3782                                         break;
3783                         }
3784                         if (tm->tm_mon <= 1)
3785                                 tm->tm_mon = i;
3786
3787                         if (tm->tm_mday <= 1)
3788                                 tm->tm_mday = tmfc.ddd - y[i - 1];
3789
3790                         fmask |= DTK_M(MONTH) | DTK_M(DAY);
3791                 }
3792         }
3793
3794 #ifdef HAVE_INT64_TIMESTAMP
3795         if (tmfc.ms)
3796                 *fsec += tmfc.ms * 1000;
3797         if (tmfc.us)
3798                 *fsec += tmfc.us;
3799 #else
3800         if (tmfc.ms)
3801                 *fsec += (double) tmfc.ms / 1000;
3802         if (tmfc.us)
3803                 *fsec += (double) tmfc.us / 1000000;
3804 #endif
3805
3806         /* Range-check date fields according to bit mask computed above */
3807         if (fmask != 0)
3808         {
3809                 /* We already dealt with AD/BC, so pass isjulian = true */
3810                 int                     dterr = ValidateDate(fmask, true, false, false, tm);
3811
3812                 if (dterr != 0)
3813                 {
3814                         /*
3815                          * Force the error to be DTERR_FIELD_OVERFLOW even if ValidateDate
3816                          * said DTERR_MD_FIELD_OVERFLOW, because we don't want to print an
3817                          * irrelevant hint about datestyle.
3818                          */
3819                         DateTimeParseError(DTERR_FIELD_OVERFLOW, date_str, "timestamp");
3820                 }
3821         }
3822
3823         /* Range-check time fields too */
3824         if (tm->tm_hour < 0 || tm->tm_hour >= HOURS_PER_DAY ||
3825                 tm->tm_min < 0 || tm->tm_min >= MINS_PER_HOUR ||
3826                 tm->tm_sec < 0 || tm->tm_sec >= SECS_PER_MINUTE ||
3827 #ifdef HAVE_INT64_TIMESTAMP
3828                 *fsec < INT64CONST(0) || *fsec >= USECS_PER_SEC
3829 #else
3830                 *fsec < 0 || *fsec >= 1
3831 #endif
3832                 )
3833                 DateTimeParseError(DTERR_FIELD_OVERFLOW, date_str, "timestamp");
3834
3835         DEBUG_TM(tm);
3836
3837         pfree(date_str);
3838 }
3839
3840
3841 /**********************************************************************
3842  *      the NUMBER version part
3843  *********************************************************************/
3844
3845
3846 static char *
3847 fill_str(char *str, int c, int max)
3848 {
3849         memset(str, c, max);
3850         *(str + max) = '\0';
3851         return str;
3852 }
3853
3854 #define zeroize_NUM(_n) \
3855 do { \
3856         (_n)->flag              = 0;    \
3857         (_n)->lsign             = 0;    \
3858         (_n)->pre               = 0;    \
3859         (_n)->post              = 0;    \
3860         (_n)->pre_lsign_num = 0;        \
3861         (_n)->need_locale       = 0;    \
3862         (_n)->multi             = 0;    \
3863         (_n)->zero_start        = 0;    \
3864         (_n)->zero_end          = 0;    \
3865 } while(0)
3866
3867 /* select a NUMCacheEntry to hold the given format picture */
3868 static NUMCacheEntry *
3869 NUM_cache_getnew(const char *str)
3870 {
3871         NUMCacheEntry *ent;
3872
3873         /* counter overflow check - paranoia? */
3874         if (NUMCounter >= (INT_MAX - NUM_CACHE_ENTRIES))
3875         {
3876                 NUMCounter = 0;
3877
3878                 for (ent = NUMCache; ent < (NUMCache + NUM_CACHE_ENTRIES); ent++)
3879                         ent->age = (++NUMCounter);
3880         }
3881
3882         /*
3883          * If cache is full, remove oldest entry (or recycle first not-valid one)
3884          */
3885         if (n_NUMCache >= NUM_CACHE_ENTRIES)
3886         {
3887                 NUMCacheEntry *old = NUMCache + 0;
3888
3889 #ifdef DEBUG_TO_FROM_CHAR
3890                 elog(DEBUG_elog_output, "Cache is full (%d)", n_NUMCache);
3891 #endif
3892                 if (old->valid)
3893                 {
3894                         for (ent = NUMCache + 1; ent < (NUMCache + NUM_CACHE_ENTRIES); ent++)
3895                         {
3896                                 if (!ent->valid)
3897                                 {
3898                                         old = ent;
3899                                         break;
3900                                 }
3901                                 if (ent->age < old->age)
3902                                         old = ent;
3903                         }
3904                 }
3905 #ifdef DEBUG_TO_FROM_CHAR
3906                 elog(DEBUG_elog_output, "OLD: \"%s\" AGE: %d", old->str, old->age);
3907 #endif
3908                 old->valid = false;
3909                 StrNCpy(old->str, str, NUM_CACHE_SIZE + 1);
3910                 old->age = (++NUMCounter);
3911                 /* caller is expected to fill format and Num, then set valid */
3912                 return old;
3913         }
3914         else
3915         {
3916 #ifdef DEBUG_TO_FROM_CHAR
3917                 elog(DEBUG_elog_output, "NEW (%d)", n_NUMCache);
3918 #endif
3919                 ent = NUMCache + n_NUMCache;
3920                 ent->valid = false;
3921                 StrNCpy(ent->str, str, NUM_CACHE_SIZE + 1);
3922                 ent->age = (++NUMCounter);
3923                 /* caller is expected to fill format and Num, then set valid */
3924                 ++n_NUMCache;
3925                 return ent;
3926         }
3927 }
3928
3929 /* look for an existing NUMCacheEntry matching the given format picture */
3930 static NUMCacheEntry *
3931 NUM_cache_search(const char *str)
3932 {
3933         int                     i;
3934         NUMCacheEntry *ent;
3935
3936         /* counter overflow check - paranoia? */
3937         if (NUMCounter >= (INT_MAX - NUM_CACHE_ENTRIES))
3938         {
3939                 NUMCounter = 0;
3940
3941                 for (ent = NUMCache; ent < (NUMCache + NUM_CACHE_ENTRIES); ent++)
3942                         ent->age = (++NUMCounter);
3943         }
3944
3945         for (i = 0, ent = NUMCache; i < n_NUMCache; i++, ent++)
3946         {
3947                 if (ent->valid && strcmp(ent->str, str) == 0)
3948                 {
3949                         ent->age = (++NUMCounter);
3950                         return ent;
3951                 }
3952         }
3953
3954         return NULL;
3955 }
3956
3957 /* Find or create a NUMCacheEntry for the given format picture */
3958 static NUMCacheEntry *
3959 NUM_cache_fetch(const char *str)
3960 {
3961         NUMCacheEntry *ent;
3962
3963         if ((ent = NUM_cache_search(str)) == NULL)
3964         {
3965                 /*
3966                  * Not in the cache, must run parser and save a new format-picture to
3967                  * the cache.  Do not mark the cache entry valid until parsing
3968                  * succeeds.
3969                  */
3970                 ent = NUM_cache_getnew(str);
3971
3972                 zeroize_NUM(&ent->Num);
3973
3974                 parse_format(ent->format, str, NUM_keywords,
3975                                          NULL, NUM_index, NUM_TYPE, &ent->Num);
3976
3977                 ent->valid = true;
3978         }
3979         return ent;
3980 }
3981
3982 /* ----------
3983  * Cache routine for NUM to_char version
3984  * ----------
3985  */
3986 static FormatNode *
3987 NUM_cache(int len, NUMDesc *Num, text *pars_str, bool *shouldFree)
3988 {
3989         FormatNode *format = NULL;
3990         char       *str;
3991
3992         str = text_to_cstring(pars_str);
3993
3994         if (len > NUM_CACHE_SIZE)
3995         {
3996                 /*
3997                  * Allocate new memory if format picture is bigger than static cache
3998                  * and do not use cache (call parser always)
3999                  */
4000                 format = (FormatNode *) palloc((len + 1) * sizeof(FormatNode));
4001
4002                 *shouldFree = true;
4003
4004                 zeroize_NUM(Num);
4005
4006                 parse_format(format, str, NUM_keywords,
4007                                          NULL, NUM_index, NUM_TYPE, Num);
4008         }
4009         else
4010         {
4011                 /*
4012                  * Use cache buffers
4013                  */
4014                 NUMCacheEntry *ent = NUM_cache_fetch(str);
4015
4016                 *shouldFree = false;
4017
4018                 format = ent->format;
4019
4020                 /*
4021                  * Copy cache to used struct
4022                  */
4023                 Num->flag = ent->Num.flag;
4024                 Num->lsign = ent->Num.lsign;
4025                 Num->pre = ent->Num.pre;
4026                 Num->post = ent->Num.post;
4027                 Num->pre_lsign_num = ent->Num.pre_lsign_num;
4028                 Num->need_locale = ent->Num.need_locale;
4029                 Num->multi = ent->Num.multi;
4030                 Num->zero_start = ent->Num.zero_start;
4031                 Num->zero_end = ent->Num.zero_end;
4032         }
4033
4034 #ifdef DEBUG_TO_FROM_CHAR
4035         /* dump_node(format, len); */
4036         dump_index(NUM_keywords, NUM_index);
4037 #endif
4038
4039         pfree(str);
4040         return format;
4041 }
4042
4043
4044 static char *
4045 int_to_roman(int number)
4046 {
4047         int                     len = 0,
4048                                 num = 0;
4049         char       *p = NULL,
4050                            *result,
4051                                 numstr[5];
4052
4053         result = (char *) palloc(16);
4054         *result = '\0';
4055
4056         if (number > 3999 || number < 1)
4057         {
4058                 fill_str(result, '#', 15);
4059                 return result;
4060         }
4061         len = snprintf(numstr, sizeof(numstr), "%d", number);
4062
4063         for (p = numstr; *p != '\0'; p++, --len)
4064         {
4065                 num = *p - 49;                  /* 48 ascii + 1 */
4066                 if (num < 0)
4067                         continue;
4068
4069                 if (len > 3)
4070                 {
4071                         while (num-- != -1)
4072                                 strcat(result, "M");
4073                 }
4074                 else
4075                 {
4076                         if (len == 3)
4077                                 strcat(result, rm100[num]);
4078                         else if (len == 2)
4079                                 strcat(result, rm10[num]);
4080                         else if (len == 1)
4081                                 strcat(result, rm1[num]);
4082                 }
4083         }
4084         return result;
4085 }
4086
4087
4088
4089 /* ----------
4090  * Locale
4091  * ----------
4092  */
4093 static void
4094 NUM_prepare_locale(NUMProc *Np)
4095 {
4096         if (Np->Num->need_locale)
4097         {
4098                 struct lconv *lconv;
4099
4100                 /*
4101                  * Get locales
4102                  */
4103                 lconv = PGLC_localeconv();
4104
4105                 /*
4106                  * Positive / Negative number sign
4107                  */
4108                 if (lconv->negative_sign && *lconv->negative_sign)
4109                         Np->L_negative_sign = lconv->negative_sign;
4110                 else
4111                         Np->L_negative_sign = "-";
4112
4113                 if (lconv->positive_sign && *lconv->positive_sign)
4114                         Np->L_positive_sign = lconv->positive_sign;
4115                 else
4116                         Np->L_positive_sign = "+";
4117
4118                 /*
4119                  * Number decimal point
4120                  */
4121                 if (lconv->decimal_point && *lconv->decimal_point)
4122                         Np->decimal = lconv->decimal_point;
4123
4124                 else
4125                         Np->decimal = ".";
4126
4127                 if (!IS_LDECIMAL(Np->Num))
4128                         Np->decimal = ".";
4129
4130                 /*
4131                  * Number thousands separator
4132                  *
4133                  * Some locales (e.g. broken glibc pt_BR), have a comma for decimal,
4134                  * but "" for thousands_sep, so we set the thousands_sep too.
4135                  * http://archives.postgresql.org/pgsql-hackers/2007-11/msg00772.php
4136                  */
4137                 if (lconv->thousands_sep && *lconv->thousands_sep)
4138                         Np->L_thousands_sep = lconv->thousands_sep;
4139                 /* Make sure thousands separator doesn't match decimal point symbol. */
4140                 else if (strcmp(Np->decimal, ",") !=0)
4141                         Np->L_thousands_sep = ",";
4142                 else
4143                         Np->L_thousands_sep = ".";
4144
4145                 /*
4146                  * Currency symbol
4147                  */
4148                 if (lconv->currency_symbol && *lconv->currency_symbol)
4149                         Np->L_currency_symbol = lconv->currency_symbol;
4150                 else
4151                         Np->L_currency_symbol = " ";
4152         }
4153         else
4154         {
4155                 /*
4156                  * Default values
4157                  */
4158                 Np->L_negative_sign = "-";
4159                 Np->L_positive_sign = "+";
4160                 Np->decimal = ".";
4161
4162                 Np->L_thousands_sep = ",";
4163                 Np->L_currency_symbol = " ";
4164         }
4165 }
4166
4167 /* ----------
4168  * Return pointer of last relevant number after decimal point
4169  *      12.0500 --> last relevant is '5'
4170  *      12.0000 --> last relevant is '.'
4171  * If there is no decimal point, return NULL (which will result in same
4172  * behavior as if FM hadn't been specified).
4173  * ----------
4174  */
4175 static char *
4176 get_last_relevant_decnum(char *num)
4177 {
4178         char       *result,
4179                            *p = strchr(num, '.');
4180
4181 #ifdef DEBUG_TO_FROM_CHAR
4182         elog(DEBUG_elog_output, "get_last_relevant_decnum()");
4183 #endif
4184
4185         if (!p)
4186                 return NULL;
4187
4188         result = p;
4189
4190         while (*(++p))
4191         {
4192                 if (*p != '0')
4193                         result = p;
4194         }
4195
4196         return result;
4197 }
4198
4199 /* ----------
4200  * Number extraction for TO_NUMBER()
4201  * ----------
4202  */
4203 static void
4204 NUM_numpart_from_char(NUMProc *Np, int id, int input_len)
4205 {
4206         bool            isread = FALSE;
4207
4208 #ifdef DEBUG_TO_FROM_CHAR
4209         elog(DEBUG_elog_output, " --- scan start --- id=%s",
4210                  (id == NUM_0 || id == NUM_9) ? "NUM_0/9" : id == NUM_DEC ? "NUM_DEC" : "???");
4211 #endif
4212
4213 #define OVERLOAD_TEST   (Np->inout_p >= Np->inout + input_len)
4214 #define AMOUNT_TEST(_s) (input_len-(Np->inout_p-Np->inout) >= _s)
4215
4216         if (OVERLOAD_TEST)
4217                 return;
4218
4219         if (*Np->inout_p == ' ')
4220                 Np->inout_p++;
4221
4222         if (OVERLOAD_TEST)
4223                 return;
4224
4225         /*
4226          * read sign before number
4227          */
4228         if (*Np->number == ' ' && (id == NUM_0 || id == NUM_9) &&
4229                 (Np->read_pre + Np->read_post) == 0)
4230         {
4231 #ifdef DEBUG_TO_FROM_CHAR
4232                 elog(DEBUG_elog_output, "Try read sign (%c), locale positive: %s, negative: %s",
4233                          *Np->inout_p, Np->L_positive_sign, Np->L_negative_sign);
4234 #endif
4235
4236                 /*
4237                  * locale sign
4238                  */
4239                 if (IS_LSIGN(Np->Num) && Np->Num->lsign == NUM_LSIGN_PRE)
4240                 {
4241                         int                     x = 0;
4242
4243 #ifdef DEBUG_TO_FROM_CHAR
4244                         elog(DEBUG_elog_output, "Try read locale pre-sign (%c)", *Np->inout_p);
4245 #endif
4246                         if ((x = strlen(Np->L_negative_sign)) &&
4247                                 AMOUNT_TEST(x) &&
4248                                 strncmp(Np->inout_p, Np->L_negative_sign, x) == 0)
4249                         {
4250                                 Np->inout_p += x;
4251                                 *Np->number = '-';
4252                         }
4253                         else if ((x = strlen(Np->L_positive_sign)) &&
4254                                          AMOUNT_TEST(x) &&
4255                                          strncmp(Np->inout_p, Np->L_positive_sign, x) == 0)
4256                         {
4257                                 Np->inout_p += x;
4258                                 *Np->number = '+';
4259                         }
4260                 }
4261                 else
4262                 {
4263 #ifdef DEBUG_TO_FROM_CHAR
4264                         elog(DEBUG_elog_output, "Try read simple sign (%c)", *Np->inout_p);
4265 #endif
4266
4267                         /*
4268                          * simple + - < >
4269                          */
4270                         if (*Np->inout_p == '-' || (IS_BRACKET(Np->Num) &&
4271                                                                                 *Np->inout_p == '<'))
4272                         {
4273                                 *Np->number = '-';              /* set - */
4274                                 Np->inout_p++;
4275                         }
4276                         else if (*Np->inout_p == '+')
4277                         {
4278                                 *Np->number = '+';              /* set + */
4279                                 Np->inout_p++;
4280                         }
4281                 }
4282         }
4283
4284         if (OVERLOAD_TEST)
4285                 return;
4286
4287 #ifdef DEBUG_TO_FROM_CHAR
4288         elog(DEBUG_elog_output, "Scan for numbers (%c), current number: '%s'", *Np->inout_p, Np->number);
4289 #endif
4290
4291         /*
4292          * read digit or decimal point
4293          */
4294         if (isdigit((unsigned char) *Np->inout_p))
4295         {
4296                 if (Np->read_dec && Np->read_post == Np->Num->post)
4297                         return;
4298
4299                 *Np->number_p = *Np->inout_p;
4300                 Np->number_p++;
4301
4302                 if (Np->read_dec)
4303                         Np->read_post++;
4304                 else
4305                         Np->read_pre++;
4306
4307                 isread = TRUE;
4308
4309 #ifdef DEBUG_TO_FROM_CHAR
4310                 elog(DEBUG_elog_output, "Read digit (%c)", *Np->inout_p);
4311 #endif
4312         }
4313         else if (IS_DECIMAL(Np->Num) && Np->read_dec == FALSE)
4314         {
4315                 /*
4316                  * We need not test IS_LDECIMAL(Np->Num) explicitly here, because
4317                  * Np->decimal is always just "." if we don't have a D format token.
4318                  * So we just unconditionally match to Np->decimal.
4319                  */
4320                 int                     x = strlen(Np->decimal);
4321
4322 #ifdef DEBUG_TO_FROM_CHAR
4323                 elog(DEBUG_elog_output, "Try read decimal point (%c)",
4324                          *Np->inout_p);
4325 #endif
4326                 if (x && AMOUNT_TEST(x) && strncmp(Np->inout_p, Np->decimal, x) == 0)
4327                 {
4328                         Np->inout_p += x - 1;
4329                         *Np->number_p = '.';
4330                         Np->number_p++;
4331                         Np->read_dec = TRUE;
4332                         isread = TRUE;
4333                 }
4334         }
4335
4336         if (OVERLOAD_TEST)
4337                 return;
4338
4339         /*
4340          * Read sign behind "last" number
4341          *
4342          * We need sign detection because determine exact position of post-sign is
4343          * difficult:
4344          *
4345          * FM9999.9999999S         -> 123.001- 9.9S                        -> .5- FM9.999999MI ->
4346          * 5.01-
4347          */
4348         if (*Np->number == ' ' && Np->read_pre + Np->read_post > 0)
4349         {
4350                 /*
4351                  * locale sign (NUM_S) is always anchored behind a last number, if: -
4352                  * locale sign expected - last read char was NUM_0/9 or NUM_DEC - and
4353                  * next char is not digit
4354                  */
4355                 if (IS_LSIGN(Np->Num) && isread &&
4356                         (Np->inout_p + 1) < Np->inout + input_len &&
4357                         !isdigit((unsigned char) *(Np->inout_p + 1)))
4358                 {
4359                         int                     x;
4360                         char       *tmp = Np->inout_p++;
4361
4362 #ifdef DEBUG_TO_FROM_CHAR
4363                         elog(DEBUG_elog_output, "Try read locale post-sign (%c)", *Np->inout_p);
4364 #endif
4365                         if ((x = strlen(Np->L_negative_sign)) &&
4366                                 AMOUNT_TEST(x) &&
4367                                 strncmp(Np->inout_p, Np->L_negative_sign, x) == 0)
4368                         {
4369                                 Np->inout_p += x - 1;   /* -1 .. NUM_processor() do inout_p++ */
4370                                 *Np->number = '-';
4371                         }
4372                         else if ((x = strlen(Np->L_positive_sign)) &&
4373                                          AMOUNT_TEST(x) &&
4374                                          strncmp(Np->inout_p, Np->L_positive_sign, x) == 0)
4375                         {
4376                                 Np->inout_p += x - 1;   /* -1 .. NUM_processor() do inout_p++ */
4377                                 *Np->number = '+';
4378                         }
4379                         if (*Np->number == ' ')
4380                                 /* no sign read */
4381                                 Np->inout_p = tmp;
4382                 }
4383
4384                 /*
4385                  * try read non-locale sign, it's happen only if format is not exact
4386                  * and we cannot determine sign position of MI/PL/SG, an example:
4387                  *
4388                  * FM9.999999MI                    -> 5.01-
4389                  *
4390                  * if (.... && IS_LSIGN(Np->Num)==FALSE) prevents read wrong formats
4391                  * like to_number('1 -', '9S') where sign is not anchored to last
4392                  * number.
4393                  */
4394                 else if (isread == FALSE && IS_LSIGN(Np->Num) == FALSE &&
4395                                  (IS_PLUS(Np->Num) || IS_MINUS(Np->Num)))
4396                 {
4397 #ifdef DEBUG_TO_FROM_CHAR
4398                         elog(DEBUG_elog_output, "Try read simple post-sign (%c)", *Np->inout_p);
4399 #endif
4400
4401                         /*
4402                          * simple + -
4403                          */
4404                         if (*Np->inout_p == '-' || *Np->inout_p == '+')
4405                                 /* NUM_processor() do inout_p++ */
4406                                 *Np->number = *Np->inout_p;
4407                 }
4408         }
4409 }
4410
4411 #define IS_PREDEC_SPACE(_n) \
4412                 (IS_ZERO((_n)->Num)==FALSE && \
4413                  (_n)->number == (_n)->number_p && \
4414                  *(_n)->number == '0' && \
4415                                  (_n)->Num->post != 0)
4416
4417 /* ----------
4418  * Add digit or sign to number-string
4419  * ----------
4420  */
4421 static void
4422 NUM_numpart_to_char(NUMProc *Np, int id)
4423 {
4424         int                     end;
4425
4426         if (IS_ROMAN(Np->Num))
4427                 return;
4428
4429         /* Note: in this elog() output not set '\0' in 'inout' */
4430
4431 #ifdef DEBUG_TO_FROM_CHAR
4432
4433         /*
4434          * Np->num_curr is number of current item in format-picture, it is not
4435          * current position in inout!
4436          */
4437         elog(DEBUG_elog_output,
4438                  "SIGN_WROTE: %d, CURRENT: %d, NUMBER_P: \"%s\", INOUT: \"%s\"",
4439                  Np->sign_wrote,
4440                  Np->num_curr,
4441                  Np->number_p,
4442                  Np->inout);
4443 #endif
4444         Np->num_in = FALSE;
4445
4446         /*
4447          * Write sign if real number will write to output Note: IS_PREDEC_SPACE()
4448          * handle "9.9" --> " .1"
4449          */
4450         if (Np->sign_wrote == FALSE &&
4451                 (Np->num_curr >= Np->out_pre_spaces || (IS_ZERO(Np->Num) && Np->Num->zero_start == Np->num_curr)) &&
4452                 (IS_PREDEC_SPACE(Np) == FALSE || (Np->last_relevant && *Np->last_relevant == '.')))
4453         {
4454                 if (IS_LSIGN(Np->Num))
4455                 {
4456                         if (Np->Num->lsign == NUM_LSIGN_PRE)
4457                         {
4458                                 if (Np->sign == '-')
4459                                         strcpy(Np->inout_p, Np->L_negative_sign);
4460                                 else
4461                                         strcpy(Np->inout_p, Np->L_positive_sign);
4462                                 Np->inout_p += strlen(Np->inout_p);
4463                                 Np->sign_wrote = TRUE;
4464                         }
4465                 }
4466                 else if (IS_BRACKET(Np->Num))
4467                 {
4468                         *Np->inout_p = Np->sign == '+' ? ' ' : '<';
4469                         ++Np->inout_p;
4470                         Np->sign_wrote = TRUE;
4471                 }
4472                 else if (Np->sign == '+')
4473                 {
4474                         if (!IS_FILLMODE(Np->Num))
4475                         {
4476                                 *Np->inout_p = ' ';             /* Write + */
4477                                 ++Np->inout_p;
4478                         }
4479                         Np->sign_wrote = TRUE;
4480                 }
4481                 else if (Np->sign == '-')
4482                 {                                               /* Write - */
4483                         *Np->inout_p = '-';
4484                         ++Np->inout_p;
4485                         Np->sign_wrote = TRUE;
4486                 }
4487         }
4488
4489
4490         /*
4491          * digits / FM / Zero / Dec. point
4492          */
4493         if (id == NUM_9 || id == NUM_0 || id == NUM_D || id == NUM_DEC)
4494         {
4495                 if (Np->num_curr < Np->out_pre_spaces &&
4496                         (Np->Num->zero_start > Np->num_curr || !IS_ZERO(Np->Num)))
4497                 {
4498                         /*
4499                          * Write blank space
4500                          */
4501                         if (!IS_FILLMODE(Np->Num))
4502                         {
4503                                 *Np->inout_p = ' ';             /* Write ' ' */
4504                                 ++Np->inout_p;
4505                         }
4506                 }
4507                 else if (IS_ZERO(Np->Num) &&
4508                                  Np->num_curr < Np->out_pre_spaces &&
4509                                  Np->Num->zero_start <= Np->num_curr)
4510                 {
4511                         /*
4512                          * Write ZERO
4513                          */
4514                         *Np->inout_p = '0'; /* Write '0' */
4515                         ++Np->inout_p;
4516                         Np->num_in = TRUE;
4517                 }
4518                 else
4519                 {
4520                         /*
4521                          * Write Decimal point
4522                          */
4523                         if (*Np->number_p == '.')
4524                         {
4525                                 if (!Np->last_relevant || *Np->last_relevant != '.')
4526                                 {
4527                                         strcpy(Np->inout_p, Np->decimal);       /* Write DEC/D */
4528                                         Np->inout_p += strlen(Np->inout_p);
4529                                 }
4530
4531                                 /*
4532                                  * Ora 'n' -- FM9.9 --> 'n.'
4533                                  */
4534                                 else if (IS_FILLMODE(Np->Num) &&
4535                                                  Np->last_relevant && *Np->last_relevant == '.')
4536                                 {
4537                                         strcpy(Np->inout_p, Np->decimal);       /* Write DEC/D */
4538                                         Np->inout_p += strlen(Np->inout_p);
4539                                 }
4540                         }
4541                         else
4542                         {
4543                                 /*
4544                                  * Write Digits
4545                                  */
4546                                 if (Np->last_relevant && Np->number_p > Np->last_relevant &&
4547                                         id != NUM_0)
4548                                         ;
4549
4550                                 /*
4551                                  * '0.1' -- 9.9 --> '  .1'
4552                                  */
4553                                 else if (IS_PREDEC_SPACE(Np))
4554                                 {
4555                                         if (!IS_FILLMODE(Np->Num))
4556                                         {
4557                                                 *Np->inout_p = ' ';
4558                                                 ++Np->inout_p;
4559                                         }
4560
4561                                         /*
4562                                          * '0' -- FM9.9 --> '0.'
4563                                          */
4564                                         else if (Np->last_relevant && *Np->last_relevant == '.')
4565                                         {
4566                                                 *Np->inout_p = '0';
4567                                                 ++Np->inout_p;
4568                                         }
4569                                 }
4570                                 else
4571                                 {
4572                                         *Np->inout_p = *Np->number_p;           /* Write DIGIT */
4573                                         ++Np->inout_p;
4574                                         Np->num_in = TRUE;
4575                                 }
4576                         }
4577                         /* do no exceed string length */
4578                         if (*Np->number_p)
4579                                 ++Np->number_p;
4580                 }
4581
4582                 end = Np->num_count + (Np->out_pre_spaces ? 1 : 0) + (IS_DECIMAL(Np->Num) ? 1 : 0);
4583
4584                 if (Np->last_relevant && Np->last_relevant == Np->number_p)
4585                         end = Np->num_curr;
4586
4587                 if (Np->num_curr + 1 == end)
4588                 {
4589                         if (Np->sign_wrote == TRUE && IS_BRACKET(Np->Num))
4590                         {
4591                                 *Np->inout_p = Np->sign == '+' ? ' ' : '>';
4592                                 ++Np->inout_p;
4593                         }
4594                         else if (IS_LSIGN(Np->Num) && Np->Num->lsign == NUM_LSIGN_POST)
4595                         {
4596                                 if (Np->sign == '-')
4597                                         strcpy(Np->inout_p, Np->L_negative_sign);
4598                                 else
4599                                         strcpy(Np->inout_p, Np->L_positive_sign);
4600                                 Np->inout_p += strlen(Np->inout_p);
4601                         }
4602                 }
4603         }
4604
4605         ++Np->num_curr;
4606 }
4607
4608 static char *
4609 NUM_processor(FormatNode *node, NUMDesc *Num, char *inout,
4610                    char *number, int from_char_input_len, int to_char_out_pre_spaces,
4611                           int sign, bool is_to_char, Oid collid)
4612 {
4613         FormatNode *n;
4614         NUMProc         _Np,
4615                            *Np = &_Np;
4616
4617         MemSet(Np, 0, sizeof(NUMProc));
4618
4619         Np->Num = Num;
4620         Np->is_to_char = is_to_char;
4621         Np->number = number;
4622         Np->inout = inout;
4623         Np->last_relevant = NULL;
4624         Np->read_post = 0;
4625         Np->read_pre = 0;
4626         Np->read_dec = FALSE;
4627
4628         if (Np->Num->zero_start)
4629                 --Np->Num->zero_start;
4630
4631         if (IS_EEEE(Np->Num))
4632         {
4633                 if (!Np->is_to_char)
4634                         ereport(ERROR,
4635                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4636                                          errmsg("\"EEEE\" not supported for input")));
4637                 return strcpy(inout, number);
4638         }
4639
4640         /*
4641          * Roman correction
4642          */
4643         if (IS_ROMAN(Np->Num))
4644         {
4645                 if (!Np->is_to_char)
4646                         ereport(ERROR,
4647                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4648                                          errmsg("\"RN\" not supported for input")));
4649
4650                 Np->Num->lsign = Np->Num->pre_lsign_num = Np->Num->post =
4651                         Np->Num->pre = Np->out_pre_spaces = Np->sign = 0;
4652
4653                 if (IS_FILLMODE(Np->Num))
4654                 {
4655                         Np->Num->flag = 0;
4656                         Np->Num->flag |= NUM_F_FILLMODE;
4657                 }
4658                 else
4659                         Np->Num->flag = 0;
4660                 Np->Num->flag |= NUM_F_ROMAN;
4661         }
4662
4663         /*
4664          * Sign
4665          */
4666         if (is_to_char)
4667         {
4668                 Np->sign = sign;
4669
4670                 /* MI/PL/SG - write sign itself and not in number */
4671                 if (IS_PLUS(Np->Num) || IS_MINUS(Np->Num))
4672                 {
4673                         if (IS_PLUS(Np->Num) && IS_MINUS(Np->Num) == FALSE)
4674                                 Np->sign_wrote = FALSE; /* need sign */
4675                         else
4676                                 Np->sign_wrote = TRUE;  /* needn't sign */
4677                 }
4678                 else
4679                 {
4680                         if (Np->sign != '-')
4681                         {
4682                                 if (IS_BRACKET(Np->Num) && IS_FILLMODE(Np->Num))
4683                                         Np->Num->flag &= ~NUM_F_BRACKET;
4684                                 if (IS_MINUS(Np->Num))
4685                                         Np->Num->flag &= ~NUM_F_MINUS;
4686                         }
4687                         else if (Np->sign != '+' && IS_PLUS(Np->Num))
4688                                 Np->Num->flag &= ~NUM_F_PLUS;
4689
4690                         if (Np->sign == '+' && IS_FILLMODE(Np->Num) && IS_LSIGN(Np->Num) == FALSE)
4691                                 Np->sign_wrote = TRUE;  /* needn't sign */
4692                         else
4693                                 Np->sign_wrote = FALSE; /* need sign */
4694
4695                         if (Np->Num->lsign == NUM_LSIGN_PRE && Np->Num->pre == Np->Num->pre_lsign_num)
4696                                 Np->Num->lsign = NUM_LSIGN_POST;
4697                 }
4698         }
4699         else
4700                 Np->sign = FALSE;
4701
4702         /*
4703          * Count
4704          */
4705         Np->num_count = Np->Num->post + Np->Num->pre - 1;
4706
4707         if (is_to_char)
4708         {
4709                 Np->out_pre_spaces = to_char_out_pre_spaces;
4710
4711                 if (IS_FILLMODE(Np->Num) && IS_DECIMAL(Np->Num))
4712                 {
4713                         Np->last_relevant = get_last_relevant_decnum(Np->number);
4714
4715                         /*
4716                          * If any '0' specifiers are present, make sure we don't strip
4717                          * those digits.
4718                          */
4719                         if (Np->last_relevant && Np->Num->zero_end > Np->out_pre_spaces)
4720                         {
4721                                 char       *last_zero;
4722
4723                                 last_zero = Np->number + (Np->Num->zero_end - Np->out_pre_spaces);
4724                                 if (Np->last_relevant < last_zero)
4725                                         Np->last_relevant = last_zero;
4726                         }
4727                 }
4728
4729                 if (Np->sign_wrote == FALSE && Np->out_pre_spaces == 0)
4730                         ++Np->num_count;
4731         }
4732         else
4733         {
4734                 Np->out_pre_spaces = 0;
4735                 *Np->number = ' ';              /* sign space */
4736                 *(Np->number + 1) = '\0';
4737         }
4738
4739         Np->num_in = 0;
4740         Np->num_curr = 0;
4741
4742 #ifdef DEBUG_TO_FROM_CHAR
4743         elog(DEBUG_elog_output,
4744                  "\n\tSIGN: '%c'\n\tNUM: '%s'\n\tPRE: %d\n\tPOST: %d\n\tNUM_COUNT: %d\n\tNUM_PRE: %d\n\tSIGN_WROTE: %s\n\tZERO: %s\n\tZERO_START: %d\n\tZERO_END: %d\n\tLAST_RELEVANT: %s\n\tBRACKET: %s\n\tPLUS: %s\n\tMINUS: %s\n\tFILLMODE: %s\n\tROMAN: %s\n\tEEEE: %s",
4745                  Np->sign,
4746                  Np->number,
4747                  Np->Num->pre,
4748                  Np->Num->post,
4749                  Np->num_count,
4750                  Np->out_pre_spaces,
4751                  Np->sign_wrote ? "Yes" : "No",
4752                  IS_ZERO(Np->Num) ? "Yes" : "No",
4753                  Np->Num->zero_start,
4754                  Np->Num->zero_end,
4755                  Np->last_relevant ? Np->last_relevant : "<not set>",
4756                  IS_BRACKET(Np->Num) ? "Yes" : "No",
4757                  IS_PLUS(Np->Num) ? "Yes" : "No",
4758                  IS_MINUS(Np->Num) ? "Yes" : "No",
4759                  IS_FILLMODE(Np->Num) ? "Yes" : "No",
4760                  IS_ROMAN(Np->Num) ? "Yes" : "No",
4761                  IS_EEEE(Np->Num) ? "Yes" : "No"
4762                 );
4763 #endif
4764
4765         /*
4766          * Locale
4767          */
4768         NUM_prepare_locale(Np);
4769
4770         /*
4771          * Processor direct cycle
4772          */
4773         if (Np->is_to_char)
4774                 Np->number_p = Np->number;
4775         else
4776                 Np->number_p = Np->number + 1;  /* first char is space for sign */
4777
4778         for (n = node, Np->inout_p = Np->inout; n->type != NODE_TYPE_END; n++)
4779         {
4780                 if (!Np->is_to_char)
4781                 {
4782                         /*
4783                          * Check non-string inout end
4784                          */
4785                         if (Np->inout_p >= Np->inout + from_char_input_len)
4786                                 break;
4787                 }
4788
4789                 /*
4790                  * Format pictures actions
4791                  */
4792                 if (n->type == NODE_TYPE_ACTION)
4793                 {
4794                         /*
4795                          * Create/reading digit/zero/blank/sing
4796                          *
4797                          * 'NUM_S' note: The locale sign is anchored to number and we
4798                          * read/write it when we work with first or last number
4799                          * (NUM_0/NUM_9). This is reason why NUM_S missing in follow
4800                          * switch().
4801                          */
4802                         switch (n->key->id)
4803                         {
4804                                 case NUM_9:
4805                                 case NUM_0:
4806                                 case NUM_DEC:
4807                                 case NUM_D:
4808                                         if (Np->is_to_char)
4809                                         {
4810                                                 NUM_numpart_to_char(Np, n->key->id);
4811                                                 continue;               /* for() */
4812                                         }
4813                                         else
4814                                         {
4815                                                 NUM_numpart_from_char(Np, n->key->id, from_char_input_len);
4816                                                 break;  /* switch() case: */
4817                                         }
4818
4819                                 case NUM_COMMA:
4820                                         if (Np->is_to_char)
4821                                         {
4822                                                 if (!Np->num_in)
4823                                                 {
4824                                                         if (IS_FILLMODE(Np->Num))
4825                                                                 continue;
4826                                                         else
4827                                                                 *Np->inout_p = ' ';
4828                                                 }
4829                                                 else
4830                                                         *Np->inout_p = ',';
4831                                         }
4832                                         else
4833                                         {
4834                                                 if (!Np->num_in)
4835                                                 {
4836                                                         if (IS_FILLMODE(Np->Num))
4837                                                                 continue;
4838                                                 }
4839                                         }
4840                                         break;
4841
4842                                 case NUM_G:
4843                                         if (Np->is_to_char)
4844                                         {
4845                                                 if (!Np->num_in)
4846                                                 {
4847                                                         if (IS_FILLMODE(Np->Num))
4848                                                                 continue;
4849                                                         else
4850                                                         {
4851                                                                 int                     x = strlen(Np->L_thousands_sep);
4852
4853                                                                 memset(Np->inout_p, ' ', x);
4854                                                                 Np->inout_p += x - 1;
4855                                                         }
4856                                                 }
4857                                                 else
4858                                                 {
4859                                                         strcpy(Np->inout_p, Np->L_thousands_sep);
4860                                                         Np->inout_p += strlen(Np->inout_p) - 1;
4861                                                 }
4862                                         }
4863                                         else
4864                                         {
4865                                                 if (!Np->num_in)
4866                                                 {
4867                                                         if (IS_FILLMODE(Np->Num))
4868                                                                 continue;
4869                                                 }
4870                                                 Np->inout_p += strlen(Np->L_thousands_sep) - 1;
4871                                         }
4872                                         break;
4873
4874                                 case NUM_L:
4875                                         if (Np->is_to_char)
4876                                         {
4877                                                 strcpy(Np->inout_p, Np->L_currency_symbol);
4878                                                 Np->inout_p += strlen(Np->inout_p) - 1;
4879                                         }
4880                                         else
4881                                                 Np->inout_p += strlen(Np->L_currency_symbol) - 1;
4882                                         break;
4883
4884                                 case NUM_RN:
4885                                         if (IS_FILLMODE(Np->Num))
4886                                         {
4887                                                 strcpy(Np->inout_p, Np->number_p);
4888                                                 Np->inout_p += strlen(Np->inout_p) - 1;
4889                                         }
4890                                         else
4891                                         {
4892                                                 sprintf(Np->inout_p, "%15s", Np->number_p);
4893                                                 Np->inout_p += strlen(Np->inout_p) - 1;
4894                                         }
4895                                         break;
4896
4897                                 case NUM_rn:
4898                                         if (IS_FILLMODE(Np->Num))
4899                                         {
4900                                                 strcpy(Np->inout_p, asc_tolower_z(Np->number_p));
4901                                                 Np->inout_p += strlen(Np->inout_p) - 1;
4902                                         }
4903                                         else
4904                                         {
4905                                                 sprintf(Np->inout_p, "%15s", asc_tolower_z(Np->number_p));
4906                                                 Np->inout_p += strlen(Np->inout_p) - 1;
4907                                         }
4908                                         break;
4909
4910                                 case NUM_th:
4911                                         if (IS_ROMAN(Np->Num) || *Np->number == '#' ||
4912                                                 Np->sign == '-' || IS_DECIMAL(Np->Num))
4913                                                 continue;
4914
4915                                         if (Np->is_to_char)
4916                                                 strcpy(Np->inout_p, get_th(Np->number, TH_LOWER));
4917                                         Np->inout_p += 1;
4918                                         break;
4919
4920                                 case NUM_TH:
4921                                         if (IS_ROMAN(Np->Num) || *Np->number == '#' ||
4922                                                 Np->sign == '-' || IS_DECIMAL(Np->Num))
4923                                                 continue;
4924
4925                                         if (Np->is_to_char)
4926                                                 strcpy(Np->inout_p, get_th(Np->number, TH_UPPER));
4927                                         Np->inout_p += 1;
4928                                         break;
4929
4930                                 case NUM_MI:
4931                                         if (Np->is_to_char)
4932                                         {
4933                                                 if (Np->sign == '-')
4934                                                         *Np->inout_p = '-';
4935                                                 else if (IS_FILLMODE(Np->Num))
4936                                                         continue;
4937                                                 else
4938                                                         *Np->inout_p = ' ';
4939                                         }
4940                                         else
4941                                         {
4942                                                 if (*Np->inout_p == '-')
4943                                                         *Np->number = '-';
4944                                         }
4945                                         break;
4946
4947                                 case NUM_PL:
4948                                         if (Np->is_to_char)
4949                                         {
4950                                                 if (Np->sign == '+')
4951                                                         *Np->inout_p = '+';
4952                                                 else if (IS_FILLMODE(Np->Num))
4953                                                         continue;
4954                                                 else
4955                                                         *Np->inout_p = ' ';
4956                                         }
4957                                         else
4958                                         {
4959                                                 if (*Np->inout_p == '+')
4960                                                         *Np->number = '+';
4961                                         }
4962                                         break;
4963
4964                                 case NUM_SG:
4965                                         if (Np->is_to_char)
4966                                                 *Np->inout_p = Np->sign;
4967
4968                                         else
4969                                         {
4970                                                 if (*Np->inout_p == '-')
4971                                                         *Np->number = '-';
4972                                                 else if (*Np->inout_p == '+')
4973                                                         *Np->number = '+';
4974                                         }
4975                                         break;
4976
4977
4978                                 default:
4979                                         continue;
4980                                         break;
4981                         }
4982                 }
4983                 else
4984                 {
4985                         /*
4986                          * Remove to output char from input in TO_CHAR
4987                          */
4988                         if (Np->is_to_char)
4989                                 *Np->inout_p = n->character;
4990                 }
4991                 Np->inout_p++;
4992         }
4993
4994         if (Np->is_to_char)
4995         {
4996                 *Np->inout_p = '\0';
4997                 return Np->inout;
4998         }
4999         else
5000         {
5001                 if (*(Np->number_p - 1) == '.')
5002                         *(Np->number_p - 1) = '\0';
5003                 else
5004                         *Np->number_p = '\0';
5005
5006                 /*
5007                  * Correction - precision of dec. number
5008                  */
5009                 Np->Num->post = Np->read_post;
5010
5011 #ifdef DEBUG_TO_FROM_CHAR
5012                 elog(DEBUG_elog_output, "TO_NUMBER (number): '%s'", Np->number);
5013 #endif
5014                 return Np->number;
5015         }
5016 }
5017
5018 /* ----------
5019  * MACRO: Start part of NUM - for all NUM's to_char variants
5020  *      (sorry, but I hate copy same code - macro is better..)
5021  * ----------
5022  */
5023 #define NUM_TOCHAR_prepare \
5024 do { \
5025         int len = VARSIZE_ANY_EXHDR(fmt); \
5026         if (len <= 0 || len >= (INT_MAX-VARHDRSZ)/NUM_MAX_ITEM_SIZ)             \
5027                 PG_RETURN_TEXT_P(cstring_to_text("")); \
5028         result  = (text *) palloc0((len * NUM_MAX_ITEM_SIZ) + 1 + VARHDRSZ);    \
5029         format  = NUM_cache(len, &Num, fmt, &shouldFree);               \
5030 } while (0)
5031
5032 /* ----------
5033  * MACRO: Finish part of NUM
5034  * ----------
5035  */
5036 #define NUM_TOCHAR_finish \
5037 do { \
5038         int             len; \
5039                                                                         \
5040         NUM_processor(format, &Num, VARDATA(result), numstr, 0, out_pre_spaces, sign, true, PG_GET_COLLATION()); \
5041                                                                         \
5042         if (shouldFree)                                 \
5043                 pfree(format);                          \
5044                                                                         \
5045         /*                                                              \
5046          * Convert null-terminated representation of result to standard text. \
5047          * The result is usually much bigger than it needs to be, but there \
5048          * seems little point in realloc'ing it smaller. \
5049          */                                                             \
5050         len = strlen(VARDATA(result));  \
5051         SET_VARSIZE(result, len + VARHDRSZ); \
5052 } while (0)
5053
5054 /* -------------------
5055  * NUMERIC to_number() (convert string to numeric)
5056  * -------------------
5057  */
5058 Datum
5059 numeric_to_number(PG_FUNCTION_ARGS)
5060 {
5061         text       *value = PG_GETARG_TEXT_P(0);
5062         text       *fmt = PG_GETARG_TEXT_P(1);
5063         NUMDesc         Num;
5064         Datum           result;
5065         FormatNode *format;
5066         char       *numstr;
5067         bool            shouldFree;
5068         int                     len = 0;
5069         int                     scale,
5070                                 precision;
5071
5072         len = VARSIZE(fmt) - VARHDRSZ;
5073
5074         if (len <= 0 || len >= INT_MAX / NUM_MAX_ITEM_SIZ)
5075                 PG_RETURN_NULL();
5076
5077         format = NUM_cache(len, &Num, fmt, &shouldFree);
5078
5079         numstr = (char *) palloc((len * NUM_MAX_ITEM_SIZ) + 1);
5080
5081         NUM_processor(format, &Num, VARDATA(value), numstr,
5082                                   VARSIZE(value) - VARHDRSZ, 0, 0, false, PG_GET_COLLATION());
5083
5084         scale = Num.post;
5085         precision = Num.pre + Num.multi + scale;
5086
5087         if (shouldFree)
5088                 pfree(format);
5089
5090         result = DirectFunctionCall3(numeric_in,
5091                                                                  CStringGetDatum(numstr),
5092                                                                  ObjectIdGetDatum(InvalidOid),
5093                                           Int32GetDatum(((precision << 16) | scale) + VARHDRSZ));
5094
5095         if (IS_MULTI(&Num))
5096         {
5097                 Numeric         x;
5098                 Numeric         a = DatumGetNumeric(DirectFunctionCall1(int4_numeric,
5099                                                                                                                  Int32GetDatum(10)));
5100                 Numeric         b = DatumGetNumeric(DirectFunctionCall1(int4_numeric,
5101                                                                                                  Int32GetDatum(-Num.multi)));
5102
5103                 x = DatumGetNumeric(DirectFunctionCall2(numeric_power,
5104                                                                                                 NumericGetDatum(a),
5105                                                                                                 NumericGetDatum(b)));
5106                 result = DirectFunctionCall2(numeric_mul,
5107                                                                          result,
5108                                                                          NumericGetDatum(x));
5109         }
5110
5111         pfree(numstr);
5112         return result;
5113 }
5114
5115 /* ------------------
5116  * NUMERIC to_char()
5117  * ------------------
5118  */
5119 Datum
5120 numeric_to_char(PG_FUNCTION_ARGS)
5121 {
5122         Numeric         value = PG_GETARG_NUMERIC(0);
5123         text       *fmt = PG_GETARG_TEXT_P(1);
5124         NUMDesc         Num;
5125         FormatNode *format;
5126         text       *result;
5127         bool            shouldFree;
5128         int                     out_pre_spaces = 0,
5129                                 sign = 0;
5130         char       *numstr,
5131                            *orgnum,
5132                            *p;
5133         Numeric         x;
5134
5135         NUM_TOCHAR_prepare;
5136
5137         /*
5138          * On DateType depend part (numeric)
5139          */
5140         if (IS_ROMAN(&Num))
5141         {
5142                 x = DatumGetNumeric(DirectFunctionCall2(numeric_round,
5143                                                                                                 NumericGetDatum(value),
5144                                                                                                 Int32GetDatum(0)));
5145                 numstr = orgnum =
5146                         int_to_roman(DatumGetInt32(DirectFunctionCall1(numeric_int4,
5147                                                                                                            NumericGetDatum(x))));
5148         }
5149         else if (IS_EEEE(&Num))
5150         {
5151                 orgnum = numeric_out_sci(value, Num.post);
5152
5153                 /*
5154                  * numeric_out_sci() does not emit a sign for positive numbers.  We
5155                  * need to add a space in this case so that positive and negative
5156                  * numbers are aligned.  We also have to do the right thing for NaN.
5157                  */
5158                 if (strcmp(orgnum, "NaN") == 0)
5159                 {
5160                         /*
5161                          * Allow 6 characters for the leading sign, the decimal point,
5162                          * "e", the exponent's sign and two exponent digits.
5163                          */
5164                         numstr = (char *) palloc(Num.pre + Num.post + 7);
5165                         fill_str(numstr, '#', Num.pre + Num.post + 6);
5166                         *numstr = ' ';
5167                         *(numstr + Num.pre + 1) = '.';
5168                 }
5169                 else if (*orgnum != '-')
5170                 {
5171                         numstr = (char *) palloc(strlen(orgnum) + 2);
5172                         *numstr = ' ';
5173                         strcpy(numstr + 1, orgnum);
5174                 }
5175                 else
5176                 {
5177                         numstr = orgnum;
5178                 }
5179         }
5180         else
5181         {
5182                 int                     numstr_pre_len;
5183                 Numeric         val = value;
5184
5185                 if (IS_MULTI(&Num))
5186                 {
5187                         Numeric         a = DatumGetNumeric(DirectFunctionCall1(int4_numeric,
5188                                                                                                                  Int32GetDatum(10)));
5189                         Numeric         b = DatumGetNumeric(DirectFunctionCall1(int4_numeric,
5190                                                                                                   Int32GetDatum(Num.multi)));
5191
5192                         x = DatumGetNumeric(DirectFunctionCall2(numeric_power,
5193                                                                                                         NumericGetDatum(a),
5194                                                                                                         NumericGetDatum(b)));
5195                         val = DatumGetNumeric(DirectFunctionCall2(numeric_mul,
5196                                                                                                           NumericGetDatum(value),
5197                                                                                                           NumericGetDatum(x)));
5198                         Num.pre += Num.multi;
5199                 }
5200
5201                 x = DatumGetNumeric(DirectFunctionCall2(numeric_round,
5202                                                                                                 NumericGetDatum(val),
5203                                                                                                 Int32GetDatum(Num.post)));
5204                 orgnum = DatumGetCString(DirectFunctionCall1(numeric_out,
5205                                                                                                          NumericGetDatum(x)));
5206
5207                 if (*orgnum == '-')
5208                 {
5209                         sign = '-';
5210                         numstr = orgnum + 1;
5211                 }
5212                 else
5213                 {
5214                         sign = '+';
5215                         numstr = orgnum;
5216                 }
5217
5218                 if ((p = strchr(numstr, '.')))
5219                         numstr_pre_len = p - numstr;
5220                 else
5221                         numstr_pre_len = strlen(numstr);
5222
5223                 /* needs padding? */
5224                 if (numstr_pre_len < Num.pre)
5225                         out_pre_spaces = Num.pre - numstr_pre_len;
5226                 /* overflowed prefix digit format? */
5227                 else if (numstr_pre_len > Num.pre)
5228                 {
5229                         numstr = (char *) palloc(Num.pre + Num.post + 2);
5230                         fill_str(numstr, '#', Num.pre + Num.post + 1);
5231                         *(numstr + Num.pre) = '.';
5232                 }
5233         }
5234
5235         NUM_TOCHAR_finish;
5236         PG_RETURN_TEXT_P(result);
5237 }
5238
5239 /* ---------------
5240  * INT4 to_char()
5241  * ---------------
5242  */
5243 Datum
5244 int4_to_char(PG_FUNCTION_ARGS)
5245 {
5246         int32           value = PG_GETARG_INT32(0);
5247         text       *fmt = PG_GETARG_TEXT_P(1);
5248         NUMDesc         Num;
5249         FormatNode *format;
5250         text       *result;
5251         bool            shouldFree;
5252         int                     out_pre_spaces = 0,
5253                                 sign = 0;
5254         char       *numstr,
5255                            *orgnum;
5256
5257         NUM_TOCHAR_prepare;
5258
5259         /*
5260          * On DateType depend part (int32)
5261          */
5262         if (IS_ROMAN(&Num))
5263                 numstr = orgnum = int_to_roman(value);
5264         else if (IS_EEEE(&Num))
5265         {
5266                 /* we can do it easily because float8 won't lose any precision */
5267                 float8          val = (float8) value;
5268
5269                 orgnum = (char *) palloc(MAXDOUBLEWIDTH + 1);
5270                 snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%+.*e", Num.post, val);
5271
5272                 /*
5273                  * Swap a leading positive sign for a space.
5274                  */
5275                 if (*orgnum == '+')
5276                         *orgnum = ' ';
5277
5278                 numstr = orgnum;
5279         }
5280         else
5281         {
5282                 int                     numstr_pre_len;
5283
5284                 if (IS_MULTI(&Num))
5285                 {
5286                         orgnum = DatumGetCString(DirectFunctionCall1(int4out,
5287                                                                                                                  Int32GetDatum(value * ((int32) pow((double) 10, (double) Num.multi)))));
5288                         Num.pre += Num.multi;
5289                 }
5290                 else
5291                 {
5292                         orgnum = DatumGetCString(DirectFunctionCall1(int4out,
5293                                                                                                           Int32GetDatum(value)));
5294                 }
5295
5296                 if (*orgnum == '-')
5297                 {
5298                         sign = '-';
5299                         orgnum++;
5300                 }
5301                 else
5302                         sign = '+';
5303
5304                 numstr_pre_len = strlen(orgnum);
5305
5306                 /* post-decimal digits?  Pad out with zeros. */
5307                 if (Num.post)
5308                 {
5309                         numstr = (char *) palloc(numstr_pre_len + Num.post + 2);
5310                         strcpy(numstr, orgnum);
5311                         *(numstr + numstr_pre_len) = '.';
5312                         memset(numstr + numstr_pre_len + 1, '0', Num.post);
5313                         *(numstr + numstr_pre_len + Num.post + 1) = '\0';
5314                 }
5315                 else
5316                         numstr = orgnum;
5317
5318                 /* needs padding? */
5319                 if (numstr_pre_len < Num.pre)
5320                         out_pre_spaces = Num.pre - numstr_pre_len;
5321                 /* overflowed prefix digit format? */
5322                 else if (numstr_pre_len > Num.pre)
5323                 {
5324                         numstr = (char *) palloc(Num.pre + Num.post + 2);
5325                         fill_str(numstr, '#', Num.pre + Num.post + 1);
5326                         *(numstr + Num.pre) = '.';
5327                 }
5328         }
5329
5330         NUM_TOCHAR_finish;
5331         PG_RETURN_TEXT_P(result);
5332 }
5333
5334 /* ---------------
5335  * INT8 to_char()
5336  * ---------------
5337  */
5338 Datum
5339 int8_to_char(PG_FUNCTION_ARGS)
5340 {
5341         int64           value = PG_GETARG_INT64(0);
5342         text       *fmt = PG_GETARG_TEXT_P(1);
5343         NUMDesc         Num;
5344         FormatNode *format;
5345         text       *result;
5346         bool            shouldFree;
5347         int                     out_pre_spaces = 0,
5348                                 sign = 0;
5349         char       *numstr,
5350                            *orgnum;
5351
5352         NUM_TOCHAR_prepare;
5353
5354         /*
5355          * On DateType depend part (int32)
5356          */
5357         if (IS_ROMAN(&Num))
5358         {
5359                 /* Currently don't support int8 conversion to roman... */
5360                 numstr = orgnum = int_to_roman(DatumGetInt32(
5361                                                   DirectFunctionCall1(int84, Int64GetDatum(value))));
5362         }
5363         else if (IS_EEEE(&Num))
5364         {
5365                 /* to avoid loss of precision, must go via numeric not float8 */
5366                 Numeric         val;
5367
5368                 val = DatumGetNumeric(DirectFunctionCall1(int8_numeric,
5369                                                                                                   Int64GetDatum(value)));
5370                 orgnum = numeric_out_sci(val, Num.post);
5371
5372                 /*
5373                  * numeric_out_sci() does not emit a sign for positive numbers.  We
5374                  * need to add a space in this case so that positive and negative
5375                  * numbers are aligned.  We don't have to worry about NaN here.
5376                  */
5377                 if (*orgnum != '-')
5378                 {
5379                         numstr = (char *) palloc(strlen(orgnum) + 2);
5380                         *numstr = ' ';
5381                         strcpy(numstr + 1, orgnum);
5382                 }
5383                 else
5384                 {
5385                         numstr = orgnum;
5386                 }
5387         }
5388         else
5389         {
5390                 int                     numstr_pre_len;
5391
5392                 if (IS_MULTI(&Num))
5393                 {
5394                         double          multi = pow((double) 10, (double) Num.multi);
5395
5396                         value = DatumGetInt64(DirectFunctionCall2(int8mul,
5397                                                                                                           Int64GetDatum(value),
5398                                                                                                    DirectFunctionCall1(dtoi8,
5399                                                                                                         Float8GetDatum(multi))));
5400                         Num.pre += Num.multi;
5401                 }
5402
5403                 orgnum = DatumGetCString(DirectFunctionCall1(int8out,
5404                                                                                                          Int64GetDatum(value)));
5405
5406                 if (*orgnum == '-')
5407                 {
5408                         sign = '-';
5409                         orgnum++;
5410                 }
5411                 else
5412                         sign = '+';
5413
5414                 numstr_pre_len = strlen(orgnum);
5415
5416                 /* post-decimal digits?  Pad out with zeros. */
5417                 if (Num.post)
5418                 {
5419                         numstr = (char *) palloc(numstr_pre_len + Num.post + 2);
5420                         strcpy(numstr, orgnum);
5421                         *(numstr + numstr_pre_len) = '.';
5422                         memset(numstr + numstr_pre_len + 1, '0', Num.post);
5423                         *(numstr + numstr_pre_len + Num.post + 1) = '\0';
5424                 }
5425                 else
5426                         numstr = orgnum;
5427
5428                 /* needs padding? */
5429                 if (numstr_pre_len < Num.pre)
5430                         out_pre_spaces = Num.pre - numstr_pre_len;
5431                 /* overflowed prefix digit format? */
5432                 else if (numstr_pre_len > Num.pre)
5433                 {
5434                         numstr = (char *) palloc(Num.pre + Num.post + 2);
5435                         fill_str(numstr, '#', Num.pre + Num.post + 1);
5436                         *(numstr + Num.pre) = '.';
5437                 }
5438         }
5439
5440         NUM_TOCHAR_finish;
5441         PG_RETURN_TEXT_P(result);
5442 }
5443
5444 /* -----------------
5445  * FLOAT4 to_char()
5446  * -----------------
5447  */
5448 Datum
5449 float4_to_char(PG_FUNCTION_ARGS)
5450 {
5451         float4          value = PG_GETARG_FLOAT4(0);
5452         text       *fmt = PG_GETARG_TEXT_P(1);
5453         NUMDesc         Num;
5454         FormatNode *format;
5455         text       *result;
5456         bool            shouldFree;
5457         int                     out_pre_spaces = 0,
5458                                 sign = 0;
5459         char       *numstr,
5460                            *orgnum,
5461                            *p;
5462
5463         NUM_TOCHAR_prepare;
5464
5465         if (IS_ROMAN(&Num))
5466                 numstr = orgnum = int_to_roman((int) rint(value));
5467         else if (IS_EEEE(&Num))
5468         {
5469                 numstr = orgnum = (char *) palloc(MAXDOUBLEWIDTH + 1);
5470                 if (isnan(value) || is_infinite(value))
5471                 {
5472                         /*
5473                          * Allow 6 characters for the leading sign, the decimal point,
5474                          * "e", the exponent's sign and two exponent digits.
5475                          */
5476                         numstr = (char *) palloc(Num.pre + Num.post + 7);
5477                         fill_str(numstr, '#', Num.pre + Num.post + 6);
5478                         *numstr = ' ';
5479                         *(numstr + Num.pre + 1) = '.';
5480                 }
5481                 else
5482                 {
5483                         snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%+.*e", Num.post, value);
5484
5485                         /*
5486                          * Swap a leading positive sign for a space.
5487                          */
5488                         if (*orgnum == '+')
5489                                 *orgnum = ' ';
5490
5491                         numstr = orgnum;
5492                 }
5493         }
5494         else
5495         {
5496                 float4          val = value;
5497                 int                     numstr_pre_len;
5498
5499                 if (IS_MULTI(&Num))
5500                 {
5501                         float           multi = pow((double) 10, (double) Num.multi);
5502
5503                         val = value * multi;
5504                         Num.pre += Num.multi;
5505                 }
5506
5507                 orgnum = (char *) palloc(MAXFLOATWIDTH + 1);
5508                 snprintf(orgnum, MAXFLOATWIDTH + 1, "%.0f", fabs(val));
5509                 numstr_pre_len = strlen(orgnum);
5510
5511                 /* adjust post digits to fit max float digits */
5512                 if (numstr_pre_len >= FLT_DIG)
5513                         Num.post = 0;
5514                 else if (numstr_pre_len + Num.post > FLT_DIG)
5515                         Num.post = FLT_DIG - numstr_pre_len;
5516                 snprintf(orgnum, MAXFLOATWIDTH + 1, "%.*f", Num.post, val);
5517
5518                 if (*orgnum == '-')
5519                 {                                               /* < 0 */
5520                         sign = '-';
5521                         numstr = orgnum + 1;
5522                 }
5523                 else
5524                 {
5525                         sign = '+';
5526                         numstr = orgnum;
5527                 }
5528
5529                 if ((p = strchr(numstr, '.')))
5530                         numstr_pre_len = p - numstr;
5531                 else
5532                         numstr_pre_len = strlen(numstr);
5533
5534                 /* needs padding? */
5535                 if (numstr_pre_len < Num.pre)
5536                         out_pre_spaces = Num.pre - numstr_pre_len;
5537                 /* overflowed prefix digit format? */
5538                 else if (numstr_pre_len > Num.pre)
5539                 {
5540                         numstr = (char *) palloc(Num.pre + Num.post + 2);
5541                         fill_str(numstr, '#', Num.pre + Num.post + 1);
5542                         *(numstr + Num.pre) = '.';
5543                 }
5544         }
5545
5546         NUM_TOCHAR_finish;
5547         PG_RETURN_TEXT_P(result);
5548 }
5549
5550 /* -----------------
5551  * FLOAT8 to_char()
5552  * -----------------
5553  */
5554 Datum
5555 float8_to_char(PG_FUNCTION_ARGS)
5556 {
5557         float8          value = PG_GETARG_FLOAT8(0);
5558         text       *fmt = PG_GETARG_TEXT_P(1);
5559         NUMDesc         Num;
5560         FormatNode *format;
5561         text       *result;
5562         bool            shouldFree;
5563         int                     out_pre_spaces = 0,
5564                                 sign = 0;
5565         char       *numstr,
5566                            *orgnum,
5567                            *p;
5568
5569         NUM_TOCHAR_prepare;
5570
5571         if (IS_ROMAN(&Num))
5572                 numstr = orgnum = int_to_roman((int) rint(value));
5573         else if (IS_EEEE(&Num))
5574         {
5575                 numstr = orgnum = (char *) palloc(MAXDOUBLEWIDTH + 1);
5576                 if (isnan(value) || is_infinite(value))
5577                 {
5578                         /*
5579                          * Allow 6 characters for the leading sign, the decimal point,
5580                          * "e", the exponent's sign and two exponent digits.
5581                          */
5582                         numstr = (char *) palloc(Num.pre + Num.post + 7);
5583                         fill_str(numstr, '#', Num.pre + Num.post + 6);
5584                         *numstr = ' ';
5585                         *(numstr + Num.pre + 1) = '.';
5586                 }
5587                 else
5588                 {
5589                         snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%+.*e", Num.post, value);
5590
5591                         /*
5592                          * Swap a leading positive sign for a space.
5593                          */
5594                         if (*orgnum == '+')
5595                                 *orgnum = ' ';
5596
5597                         numstr = orgnum;
5598                 }
5599         }
5600         else
5601         {
5602                 float8          val = value;
5603                 int                     numstr_pre_len;
5604
5605                 if (IS_MULTI(&Num))
5606                 {
5607                         double          multi = pow((double) 10, (double) Num.multi);
5608
5609                         val = value * multi;
5610                         Num.pre += Num.multi;
5611                 }
5612                 orgnum = (char *) palloc(MAXDOUBLEWIDTH + 1);
5613                 numstr_pre_len = snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%.0f", fabs(val));
5614
5615                 /* adjust post digits to fit max double digits */
5616                 if (numstr_pre_len >= DBL_DIG)
5617                         Num.post = 0;
5618                 else if (numstr_pre_len + Num.post > DBL_DIG)
5619                         Num.post = DBL_DIG - numstr_pre_len;
5620                 snprintf(orgnum, MAXDOUBLEWIDTH + 1, "%.*f", Num.post, val);
5621
5622                 if (*orgnum == '-')
5623                 {                                               /* < 0 */
5624                         sign = '-';
5625                         numstr = orgnum + 1;
5626                 }
5627                 else
5628                 {
5629                         sign = '+';
5630                         numstr = orgnum;
5631                 }
5632
5633                 if ((p = strchr(numstr, '.')))
5634                         numstr_pre_len = p - numstr;
5635                 else
5636                         numstr_pre_len = strlen(numstr);
5637
5638                 /* needs padding? */
5639                 if (numstr_pre_len < Num.pre)
5640                         out_pre_spaces = Num.pre - numstr_pre_len;
5641                 /* overflowed prefix digit format? */
5642                 else if (numstr_pre_len > Num.pre)
5643                 {
5644                         numstr = (char *) palloc(Num.pre + Num.post + 2);
5645                         fill_str(numstr, '#', Num.pre + Num.post + 1);
5646                         *(numstr + Num.pre) = '.';
5647                 }
5648         }
5649
5650         NUM_TOCHAR_finish;
5651         PG_RETURN_TEXT_P(result);
5652 }