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