Commit efcff3da authored by Bruce Momjian's avatar Bruce Momjian

In the attache is new (correct) version. I add TZ (timezone) support

for
to_char() too.

Karel
parent 61768d8c
...@@ -785,11 +785,11 @@ ...@@ -785,11 +785,11 @@
</row> </row>
<row> <row>
<entry>W</entry> <entry>W</entry>
<entry>week of month</entry> <entry>week of month (1-5) where first week start on the first day of the month</entry>
</row> </row>
<row> <row>
<entry>WW</entry> <entry>WW</entry>
<entry>week number of year</entry> <entry>week number of year (1-53) where first week start on the first day of the year</entry>
</row> </row>
<row> <row>
<entry>CC</entry> <entry>CC</entry>
...@@ -811,6 +811,14 @@ ...@@ -811,6 +811,14 @@
<entry>rm</entry> <entry>rm</entry>
<entry>month in Roman Numerals (I-XII; I=JAN) - lower case</entry> <entry>month in Roman Numerals (I-XII; I=JAN) - lower case</entry>
</row> </row>
<row>
<entry>TZ</entry>
<entry>timezone string - upper case (not supported in the to_timestamp())</entry>
</row>
<row>
<entry>tz</entry>
<entry>timezone string - lower case (not supported in the to_timestamp())</entry>
</row>
</tbody> </tbody>
</tgroup> </tgroup>
</table> </table>
...@@ -871,9 +879,12 @@ ...@@ -871,9 +879,12 @@
<listitem> <listitem>
<para> <para>
<function>to_timestamp</function> and <function>to_date</function> <function>to_timestamp</function> and <function>to_date</function>
skip blank space if the <literal>FX</literal> option is skip multiple blank space in converted string if the <literal>FX</literal> option
not used. <literal>FX</literal> must be specified as the first item is not used. <literal>FX</literal> must be specified as the first item
in the template. in the template; for example
<literal>to_timestamp('2000 JUN','YYYY MON')</literal> is right, but
<literal>to_timestamp('2000 JUN','FXYYYY MON')</literal> returns error,
because to_timestamp() expects one blank space only.
</para> </para>
</listitem> </listitem>
......
/* ----------------------------------------------------------------------- /* -----------------------------------------------------------------------
* formatting.c * formatting.c
* *
* $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.16 2000/07/01 21:27:11 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.17 2000/07/03 16:01:30 momjian Exp $
* *
* *
* Portions Copyright (c) 1999-2000, PostgreSQL, Inc * Portions Copyright (c) 1999-2000, PostgreSQL, Inc
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
* Numeric - to_number() * Numeric - to_number()
* *
* *
* Karel Zak - Zakkr * Karel Zak
* *
* ----------------------------------------------------------------------- * -----------------------------------------------------------------------
*/ */
...@@ -105,8 +105,8 @@ ...@@ -105,8 +105,8 @@
* External (defined in PgSQL dt.c (timestamp utils)) * External (defined in PgSQL dt.c (timestamp utils))
* ---------- * ----------
*/ */
extern char *months[], /* month abbreviation */ extern char *months[], /* month abbreviation */
*days[]; /* full days */ *days[]; /* full days */
/* ---------- /* ----------
* Format parser structs * Format parser structs
...@@ -114,27 +114,27 @@ extern char *months[], /* month abbreviation */ ...@@ -114,27 +114,27 @@ extern char *months[], /* month abbreviation */
*/ */
typedef struct typedef struct
{ {
char *name; /* suffix string */ char *name; /* suffix string */
int len, /* suffix length */ int len, /* suffix length */
id, /* used in node->suffix */ id, /* used in node->suffix */
type; /* prefix / postfix */ type; /* prefix / postfix */
} KeySuffix; } KeySuffix;
typedef struct typedef struct
{ {
char *name; /* keyword */ char *name; /* keyword */
/* action for keyword */ /* action for keyword */
int len, /* keyword length */ int len, /* keyword length */
(*action) (), (*action) (),
id; /* keyword id */ id; /* keyword id */
} KeyWord; } KeyWord;
typedef struct typedef struct
{ {
int type; /* node type */ int type; /* node type */
KeyWord *key; /* if node type is KEYWORD */ KeyWord *key; /* if node type is KEYWORD */
int character, /* if node type is CHAR */ int character, /* if node type is CHAR */
suffix; /* keyword suffix */ suffix; /* keyword suffix */
} FormatNode; } FormatNode;
#define NODE_TYPE_END 1 #define NODE_TYPE_END 1
...@@ -233,21 +233,11 @@ static char *numth[] = {"st", "nd", "rd", "th", NULL}; ...@@ -233,21 +233,11 @@ static char *numth[] = {"st", "nd", "rd", "th", NULL};
#define TH_UPPER 1 #define TH_UPPER 1
#define TH_LOWER 2 #define TH_LOWER 2
#ifdef DEBUG_TO_FROM_CHAR
#define NOTICE_TM {\
elog(DEBUG_elog_output, "TM:\nsec %d\nyear %d\nmin %d\nwday %d\nhour %d\nyday %d\nmday %d\nnisdst %d\nmon %d\n",\
tm->tm_sec, tm->tm_year,\
tm->tm_min, tm->tm_wday, tm->tm_hour, tm->tm_yday,\
tm->tm_mday, tm->tm_isdst,tm->tm_mon);\
}
#endif
/* ---------- /* ----------
* Flags for DCH version * Flags for DCH version
* ---------- * ----------
*/ */
static int DCH_global_flag = 0; static int DCH_global_flag = 0;
#define DCH_F_FX 0x01 #define DCH_F_FX 0x01
...@@ -260,15 +250,15 @@ static int DCH_global_flag = 0; ...@@ -260,15 +250,15 @@ static int DCH_global_flag = 0;
*/ */
typedef struct typedef struct
{ {
int pre, /* (count) numbers before decimal */ int pre, /* (count) numbers before decimal */
post, /* (count) numbers after decimal */ post, /* (count) numbers after decimal */
lsign, /* want locales sign */ lsign, /* want locales sign */
flag, /* number parametrs */ flag, /* number parametrs */
pre_lsign_num, /* tmp value for lsign */ pre_lsign_num, /* tmp value for lsign */
multi, /* multiplier for 'V' */ multi, /* multiplier for 'V' */
zero_start, /* position of first zero */ zero_start, /* position of first zero */
zero_end, /* position of last zero */ zero_end, /* position of last zero */
need_locale; /* needs it locale */ need_locale; /* needs it locale */
} NUMDesc; } NUMDesc;
/* ---------- /* ----------
...@@ -278,14 +268,14 @@ typedef struct ...@@ -278,14 +268,14 @@ typedef struct
#define NUM_F_DECIMAL 0x01 #define NUM_F_DECIMAL 0x01
#define NUM_F_LDECIMAL 0x02 #define NUM_F_LDECIMAL 0x02
#define NUM_F_ZERO 0x04 #define NUM_F_ZERO 0x04
#define NUM_F_BLANK 0x08 #define NUM_F_BLANK 0x08
#define NUM_F_FILLMODE 0x10 #define NUM_F_FILLMODE 0x10
#define NUM_F_LSIGN 0x20 #define NUM_F_LSIGN 0x20
#define NUM_F_BRACKET 0x40 #define NUM_F_BRACKET 0x40
#define NUM_F_MINUS 0x80 #define NUM_F_MINUS 0x80
#define NUM_F_PLUS 0x100 #define NUM_F_PLUS 0x100
#define NUM_F_ROMAN 0x200 #define NUM_F_ROMAN 0x200
#define NUM_F_MULTI 0x400 #define NUM_F_MULTI 0x400
#define NUM_LSIGN_PRE -1 #define NUM_LSIGN_PRE -1
#define NUM_LSIGN_POST 1 #define NUM_LSIGN_POST 1
...@@ -297,20 +287,20 @@ typedef struct ...@@ -297,20 +287,20 @@ typedef struct
*/ */
#define IS_DECIMAL(_f) ((_f)->flag & NUM_F_DECIMAL) #define IS_DECIMAL(_f) ((_f)->flag & NUM_F_DECIMAL)
#define IS_LDECIMAL(_f) ((_f)->flag & NUM_F_LDECIMAL) #define IS_LDECIMAL(_f) ((_f)->flag & NUM_F_LDECIMAL)
#define IS_ZERO(_f) ((_f)->flag & NUM_F_ZERO) #define IS_ZERO(_f) ((_f)->flag & NUM_F_ZERO)
#define IS_BLANK(_f) ((_f)->flag & NUM_F_BLANK) #define IS_BLANK(_f) ((_f)->flag & NUM_F_BLANK)
#define IS_FILLMODE(_f) ((_f)->flag & NUM_F_FILLMODE) #define IS_FILLMODE(_f) ((_f)->flag & NUM_F_FILLMODE)
#define IS_BRACKET(_f) ((_f)->flag & NUM_F_BRACKET) #define IS_BRACKET(_f) ((_f)->flag & NUM_F_BRACKET)
#define IS_MINUS(_f) ((_f)->flag & NUM_F_MINUS) #define IS_MINUS(_f) ((_f)->flag & NUM_F_MINUS)
#define IS_LSIGN(_f) ((_f)->flag & NUM_F_LSIGN) #define IS_LSIGN(_f) ((_f)->flag & NUM_F_LSIGN)
#define IS_PLUS(_f) ((_f)->flag & NUM_F_PLUS) #define IS_PLUS(_f) ((_f)->flag & NUM_F_PLUS)
#define IS_ROMAN(_f) ((_f)->flag & NUM_F_ROMAN) #define IS_ROMAN(_f) ((_f)->flag & NUM_F_ROMAN)
#define IS_MULTI(_f) ((_f)->flag & NUM_F_MULTI) #define IS_MULTI(_f) ((_f)->flag & NUM_F_MULTI)
/* ---------- /* ----------
* Format picture cache * Format picture cache
* (cache size: * (cache size:
* Number part = NUM_CACHE_SIZE * NUM_CACHE_FIELDS * Number part = NUM_CACHE_SIZE * NUM_CACHE_FIELDS
* Date-time part = DCH_CACHE_SIZE * DCH_CACHE_FIELDS * Date-time part = DCH_CACHE_SIZE * DCH_CACHE_FIELDS
* ) * )
* ---------- * ----------
...@@ -324,35 +314,76 @@ typedef struct ...@@ -324,35 +314,76 @@ typedef struct
{ {
FormatNode format[DCH_CACHE_SIZE + 1]; FormatNode format[DCH_CACHE_SIZE + 1];
char str[DCH_CACHE_SIZE + 1]; char str[DCH_CACHE_SIZE + 1];
int age; int age;
} DCHCacheEntry; } DCHCacheEntry;
typedef struct typedef struct
{ {
FormatNode format[NUM_CACHE_SIZE + 1]; FormatNode format[NUM_CACHE_SIZE + 1];
char str[NUM_CACHE_SIZE + 1]; char str[NUM_CACHE_SIZE + 1];
int age; int age;
NUMDesc Num; NUMDesc Num;
} NUMCacheEntry; } NUMCacheEntry;
static DCHCacheEntry DCHCache[DCH_CACHE_FIELDS + 1]; /* global cache for /* global cache for --- date/time part */
* date/time part */ static DCHCacheEntry DCHCache[DCH_CACHE_FIELDS + 1];
static int n_DCHCache = 0; /* number of entries */ static int n_DCHCache = 0; /* number of entries */
static int DCHCounter = 0; static int DCHCounter = 0;
static NUMCacheEntry NUMCache[NUM_CACHE_FIELDS + 1]; /* global cache for /* global cache for --- number part */
* number part */ static NUMCacheEntry NUMCache[NUM_CACHE_FIELDS + 1];
static int n_NUMCache = 0; /* number of entries */ static int n_NUMCache = 0; /* number of entries */
static int NUMCounter = 0; static int NUMCounter = 0;
#define MAX_INT32 (2147483640) #define MAX_INT32 (2147483640)
/* ----------
* For char->date/time conversion
* ----------
*/
typedef struct {
int hh, am, pm, mi, ss, ssss, d, dd, ddd, mm, yyyy, bc, ww, w, cc, q, j;
} TmFromChar;
#define ZERO_tmfc( _X ) \
do { \
(_X)->hh= (_X)->am= (_X)->pm= (_X)->mi= (_X)->ss= (_X)->ssss= \
(_X)->d= (_X)->dd= (_X)->ddd= (_X)->mm= (_X)->yyyy= (_X)->bc= \
(_X)->ww= (_X)->w= (_X)->cc= (_X)->q= (_X)->j= 0; \
} while(0)
#ifdef DEBUG_TO_FROM_CHAR
#define NOTICE_TMFC \
elog(DEBUG_elog_output, "TMFC:\nhh %d\nam %d\npm %d\nmi %d\nss %d\nssss %d\nd %d\ndd %d\nddd %d\nmm %d\nyyyy %d\nbc %d\nww %d\nw %d\ncc %d\nq %d\nj %d", \
tmfc->hh, tmfc->am, tmfc->pm, tmfc->mi, tmfc->ss, \
tmfc->ssss, tmfc->d, tmfc->dd, tmfc->ddd, tmfc->mm, \
tmfc->yyyy, tmfc->bc, tmfc->ww, tmfc->w, tmfc->cc, \
tmfc->q, tmfc->j);
#define NOTICE_TM \
elog(DEBUG_elog_output, "TM:\nsec %d\nyear %d\nmin %d\nwday %d\nhour %d\nyday %d\nmday %d\nnisdst %d\nmon %d\n",\
tm->tm_sec, tm->tm_year,\
tm->tm_min, tm->tm_wday, tm->tm_hour, tm->tm_yday,\
tm->tm_mday, tm->tm_isdst,tm->tm_mon)
#endif
#define ZERO_tm( _X ) \
do { \
(_X)->tm_sec = (_X)->tm_year = (_X)->tm_min = (_X)->tm_wday = \
(_X)->tm_hour = (_X)->tm_yday = (_X)->tm_isdst = 0; \
(_X)->tm_mday = (_X)->tm_mon = 1; \
} while(0)
/* ---------- /* ----------
* Private global-modul definitions * Private global-modul definitions
* ---------- * ----------
*/ */
static struct tm _tm, static struct tm _tm, *tm = &_tm;
*tm = &_tm; static TmFromChar _tmfc, *tmfc = &_tmfc;
static char *tzn;
/* ---------- /* ----------
* Utils * Utils
...@@ -469,6 +500,7 @@ typedef enum ...@@ -469,6 +500,7 @@ typedef enum
DCH_RM, DCH_RM,
DCH_SSSS, DCH_SSSS,
DCH_SS, DCH_SS,
DCH_TZ,
DCH_WW, DCH_WW,
DCH_W, DCH_W,
DCH_Y_YYY, DCH_Y_YYY,
...@@ -503,6 +535,7 @@ typedef enum ...@@ -503,6 +535,7 @@ typedef enum
DCH_rm, DCH_rm,
DCH_ssss, DCH_ssss,
DCH_ss, DCH_ss,
DCH_tz,
DCH_ww, DCH_ww,
DCH_w, DCH_w,
DCH_y_yyy, DCH_y_yyy,
...@@ -595,6 +628,7 @@ static KeyWord DCH_keywords[] = { ...@@ -595,6 +628,7 @@ static KeyWord DCH_keywords[] = {
{"RM", 2, dch_date, DCH_RM},/* R */ {"RM", 2, dch_date, DCH_RM},/* R */
{"SSSS", 4, dch_time, DCH_SSSS}, /* S */ {"SSSS", 4, dch_time, DCH_SSSS}, /* S */
{"SS", 2, dch_time, DCH_SS}, {"SS", 2, dch_time, DCH_SS},
{"TZ", 2, dch_time, DCH_TZ}, /* T */
{"WW", 2, dch_date, DCH_WW},/* W */ {"WW", 2, dch_date, DCH_WW},/* W */
{"W", 1, dch_date, DCH_W}, {"W", 1, dch_date, DCH_W},
{"Y,YYY", 5, dch_date, DCH_Y_YYY}, /* Y */ {"Y,YYY", 5, dch_date, DCH_Y_YYY}, /* Y */
...@@ -629,6 +663,7 @@ static KeyWord DCH_keywords[] = { ...@@ -629,6 +663,7 @@ static KeyWord DCH_keywords[] = {
{"rm", 2, dch_date, DCH_rm},/* r */ {"rm", 2, dch_date, DCH_rm},/* r */
{"ssss", 4, dch_time, DCH_SSSS}, /* s */ {"ssss", 4, dch_time, DCH_SSSS}, /* s */
{"ss", 2, dch_time, DCH_SS}, {"ss", 2, dch_time, DCH_SS},
{"tz", 2, dch_time, DCH_tz}, /* t */
{"ww", 2, dch_date, DCH_WW},/* w */ {"ww", 2, dch_date, DCH_WW},/* w */
{"w", 1, dch_date, DCH_W}, {"w", 1, dch_date, DCH_W},
{"y,yyy", 5, dch_date, DCH_Y_YYY}, /* y */ {"y,yyy", 5, dch_date, DCH_Y_YYY}, /* y */
...@@ -701,10 +736,10 @@ static int DCH_index[KeyWord_INDEX_SIZE] = { ...@@ -701,10 +736,10 @@ static int DCH_index[KeyWord_INDEX_SIZE] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, DCH_A_D, DCH_B_C, DCH_CC, DCH_DAY, -1, -1, -1, -1, -1, -1, DCH_A_D, DCH_B_C, DCH_CC, DCH_DAY, -1,
DCH_FX, -1, DCH_HH24, -1, DCH_J, -1, -1, DCH_MI, -1, -1, DCH_FX, -1, DCH_HH24, -1, DCH_J, -1, -1, DCH_MI, -1, -1,
DCH_P_M, DCH_Q, DCH_RM, DCH_SSSS, -1, -1, -1, DCH_WW, -1, DCH_Y_YYY, DCH_P_M, DCH_Q, DCH_RM, DCH_SSSS, DCH_TZ, -1, -1, DCH_WW, -1, DCH_Y_YYY,
-1, -1, -1, -1, -1, -1, -1, DCH_a_d, DCH_b_c, DCH_cc, -1, -1, -1, -1, -1, -1, -1, DCH_a_d, DCH_b_c, DCH_cc,
DCH_day, -1, DCH_fx, -1, DCH_hh24, -1, DCH_j, -1, -1, DCH_mi, DCH_day, -1, DCH_fx, -1, DCH_hh24, -1, DCH_j, -1, -1, DCH_mi,
-1, -1, DCH_p_m, DCH_q, DCH_rm, DCH_ssss, -1, -1, -1, DCH_ww, -1, -1, DCH_p_m, DCH_q, DCH_rm, DCH_ssss, DCH_tz, -1, -1, DCH_ww,
-1, DCH_y_yyy, -1, -1, -1, -1 -1, DCH_y_yyy, -1, -1, -1, -1
/*---- chars over 126 are skiped ----*/ /*---- chars over 126 are skiped ----*/
...@@ -740,33 +775,32 @@ static int NUM_index[KeyWord_INDEX_SIZE] = { ...@@ -740,33 +775,32 @@ static int NUM_index[KeyWord_INDEX_SIZE] = {
*/ */
typedef struct NUMProc typedef struct NUMProc
{ {
int type; /* FROM_CHAR (TO_NUMBER) or TO_CHAR */ int type; /* FROM_CHAR (TO_NUMBER) or TO_CHAR */
NUMDesc *Num; /* number description */ NUMDesc *Num; /* number description */
int sign, /* '-' or '+' */ int sign, /* '-' or '+' */
sign_wrote, /* was sign write */ sign_wrote, /* was sign write */
sign_pos, /* pre number sign position */ sign_pos, /* pre number sign position */
num_count, /* number of write digits */ num_count, /* number of write digits */
num_in, /* is inside number */ num_in, /* is inside number */
num_curr, /* current position in number */ num_curr, /* current position in number */
num_pre, /* space before first number */ num_pre, /* space before first number */
read_dec, /* to_number - was read dec. point */ read_dec, /* to_number - was read dec. point */
read_post; /* to_number - number of dec. digit */ read_post; /* to_number - number of dec. digit */
char *number, /* string with number */ char *number, /* string with number */
*number_p, /* pointer to current number pozition */ *number_p, /* pointer to current number pozition */
*inout, /* in / out buffer */ *inout, /* in / out buffer */
*inout_p, /* pointer to current inout pozition */ *inout_p, /* pointer to current inout pozition */
*last_relevant, /* last relevant number after decimal *last_relevant, /* last relevant number after decimal point */
* point */
*L_negative_sign,/* Locale */
*L_negative_sign,/* Locale */ *L_positive_sign,
*L_positive_sign, *decimal,
*decimal, *L_thousands_sep,
*L_thousands_sep, *L_currency_symbol;
*L_currency_symbol;
} NUMProc; } NUMProc;
...@@ -1011,11 +1045,11 @@ static void ...@@ -1011,11 +1045,11 @@ static void
parse_format(FormatNode *node, char *str, KeyWord *kw, parse_format(FormatNode *node, char *str, KeyWord *kw,
KeySuffix *suf, int *index, int ver, NUMDesc *Num) KeySuffix *suf, int *index, int ver, NUMDesc *Num)
{ {
KeySuffix *s; KeySuffix *s;
FormatNode *n; FormatNode *n;
int node_set = 0, int node_set = 0,
suffix, suffix,
last = 0; last = 0;
#ifdef DEBUG_TO_FROM_CHAR #ifdef DEBUG_TO_FROM_CHAR
elog(DEBUG_elog_output, "to_char/number(): run parser."); elog(DEBUG_elog_output, "to_char/number(): run parser.");
...@@ -1163,8 +1197,7 @@ DCH_processor(FormatNode *node, char *inout, int flag) ...@@ -1163,8 +1197,7 @@ DCH_processor(FormatNode *node, char *inout, int flag)
{ {
if (n->type == NODE_TYPE_ACTION) if (n->type == NODE_TYPE_ACTION)
{ {
int len;
int len;
/* ---------- /* ----------
* Call node action function * Call node action function
...@@ -1260,8 +1293,8 @@ dump_node(FormatNode *node, int max) ...@@ -1260,8 +1293,8 @@ dump_node(FormatNode *node, int max)
static char * static char *
get_th(char *num, int type) get_th(char *num, int type)
{ {
int len = strlen(num), int len = strlen(num),
last, seclast; last, seclast;
last = *(num + (len - 1)); last = *(num + (len - 1));
if (!isdigit((unsigned char) last)) if (!isdigit((unsigned char) last))
...@@ -1354,35 +1387,6 @@ str_tolower(char *buff) ...@@ -1354,35 +1387,6 @@ str_tolower(char *buff)
return buff; return buff;
} }
/* ----------
* Check if in string is AC or BC (return: 0==none; -1==BC; 1==AC)
* ----------
*/
/************* not used - use AD/BC format pictures instead **********
static int
is_acdc(char *str, int *len)
{
char *p;
for(p=str; *p != '\0'; p++) {
if (isspace(*p))
continue;
if (*(p+1)) {
if (toupper(*p)=='B' && toupper(*(++p))=='C') {
*len += (p - str) +1;
return -1;
} else if (toupper(*p)=='A' && toupper(*(++p))=='C') {
*len += (p - str) +1;
return 1;
}
}
return 0;
}
return 0;
}
******************************/
/* ---------- /* ----------
* Sequential search with to upper/lower conversion * Sequential search with to upper/lower conversion
* ---------- * ----------
...@@ -1390,11 +1394,11 @@ is_acdc(char *str, int *len) ...@@ -1390,11 +1394,11 @@ is_acdc(char *str, int *len)
static int static int
seq_search(char *name, char **array, int type, int max, int *len) seq_search(char *name, char **array, int type, int max, int *len)
{ {
char *p, char *p,
*n, *n,
**a; **a;
int last, int last,
i; i;
*len = 0; *len = 0;
...@@ -1470,9 +1474,9 @@ seq_search(char *name, char **array, int type, int max, int *len) ...@@ -1470,9 +1474,9 @@ seq_search(char *name, char **array, int type, int max, int *len)
static void static void
dump_index(KeyWord *k, int *index) dump_index(KeyWord *k, int *index)
{ {
int i, int i,
count = 0, count = 0,
free_i = 0; free_i = 0;
elog(DEBUG_elog_output, "TO-FROM_CHAR: Dump KeyWord Index:"); elog(DEBUG_elog_output, "TO-FROM_CHAR: Dump KeyWord Index:");
...@@ -1511,14 +1515,15 @@ dch_global(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -1511,14 +1515,15 @@ dch_global(int arg, char *inout, int suf, int flag, FormatNode *node)
{ {
switch (arg) switch (arg)
{ {
case DCH_FX:
case DCH_FX: DCH_global_flag |= DCH_F_FX;
DCH_global_flag |= DCH_F_FX; break;
break;
} }
return -1; return -1;
} }
#define AMPM_ERROR elog(ERROR, "to_timestamp(): bad AM/PM string")
/* ---------- /* ----------
* Master function of TIME for: * Master function of TIME for:
* TO_CHAR - write (inout) formated string * TO_CHAR - write (inout) formated string
...@@ -1532,67 +1537,82 @@ dch_time(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -1532,67 +1537,82 @@ dch_time(int arg, char *inout, int suf, int flag, FormatNode *node)
switch (arg) switch (arg)
{ {
case DCH_A_M:
case DCH_A_M:
case DCH_P_M: case DCH_P_M:
if (flag == TO_CHAR) if (flag == TO_CHAR)
{ {
strcpy(inout, (tm->tm_hour > 13 ? P_M_STR : A_M_STR)); strcpy(inout, ((tm->tm_hour > 11
&& tm->tm_hour < 24) ? P_M_STR : A_M_STR));
return 3; return 3;
} }
else if (flag == FROM_CHAR) else if (flag == FROM_CHAR)
{ {
if (strncmp(inout, P_M_STR, 4) == 0 && tm->tm_hour < 13) if (strncmp(inout, P_M_STR, 4) == 0)
tm->tm_hour += 12; tmfc->pm = TRUE;
else if (strncmp(inout, A_M_STR, 4) == 0)
tmfc->am = TRUE;
else
AMPM_ERROR;
return 3; return 3;
} }
break;
case DCH_AM: case DCH_AM:
case DCH_PM: case DCH_PM:
if (flag == TO_CHAR) if (flag == TO_CHAR)
{ {
strcpy(inout, (tm->tm_hour > 13 ? PM_STR : AM_STR)); strcpy(inout, ((tm->tm_hour > 11
&& tm->tm_hour < 24) ? PM_STR : AM_STR));
return 1; return 1;
} }
else if (flag == FROM_CHAR) else if (flag == FROM_CHAR)
{ {
if (strncmp(inout, PM_STR, 2) == 0 && tm->tm_hour < 13) if (strncmp(inout, PM_STR, 2) == 0)
tm->tm_hour += 12; tmfc->pm = TRUE;
else if (strncmp(inout, AM_STR, 2) == 0)
tmfc->am = TRUE;
else
AMPM_ERROR;
return 1; return 1;
} }
break;
case DCH_a_m: case DCH_a_m:
case DCH_p_m: case DCH_p_m:
if (flag == TO_CHAR) if (flag == TO_CHAR)
{ {
strcpy(inout, (tm->tm_hour > 13 ? p_m_STR : a_m_STR)); strcpy(inout, ((tm->tm_hour > 11
&& tm->tm_hour < 24) ? p_m_STR : a_m_STR));
return 3; return 3;
} }
else if (flag == FROM_CHAR) else if (flag == FROM_CHAR)
{ {
if (strncmp(inout, p_m_STR, 4) == 0 && tm->tm_hour < 13) if (strncmp(inout, p_m_STR, 4) == 0)
tm->tm_hour += 12; tmfc->pm = TRUE;
else if (strncmp(inout, a_m_STR, 4) == 0)
tmfc->am = TRUE;
else
AMPM_ERROR;
return 3; return 3;
} }
break;
case DCH_am: case DCH_am:
case DCH_pm: case DCH_pm:
if (flag == TO_CHAR) if (flag == TO_CHAR)
{ {
strcpy(inout, (tm->tm_hour > 13 ? pm_STR : am_STR)); strcpy(inout, ((tm->tm_hour > 11
&& tm->tm_hour < 24) ? pm_STR : am_STR));
return 1; return 1;
} }
else if (flag == FROM_CHAR) else if (flag == FROM_CHAR)
{ {
if (strncmp(inout, pm_STR, 2) == 0 && tm->tm_hour < 13) if (strncmp(inout, pm_STR, 2) == 0)
tm->tm_hour += 12; tmfc->pm = TRUE;
else if (strncmp(inout, am_STR, 2) == 0)
tmfc->am = TRUE;
else
AMPM_ERROR;
return 1; return 1;
} }
break;
case DCH_HH: case DCH_HH:
case DCH_HH12: case DCH_HH12:
if (flag == TO_CHAR) if (flag == TO_CHAR)
...@@ -1612,16 +1632,16 @@ dch_time(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -1612,16 +1632,16 @@ dch_time(int arg, char *inout, int suf, int flag, FormatNode *node)
{ {
if (S_FM(suf)) if (S_FM(suf))
{ {
sscanf(inout, "%d", &tm->tm_hour); sscanf(inout, "%d", &tmfc->hh);
return int4len((int4) tm->tm_hour) - 1 + SKIP_THth(suf); return int4len((int4) tmfc->hh) - 1 + SKIP_THth(suf);
} }
else else
{ {
sscanf(inout, "%02d", &tm->tm_hour); sscanf(inout, "%02d", &tmfc->hh);
return 1 + SKIP_THth(suf); return 1 + SKIP_THth(suf);
} }
} }
break;
case DCH_HH24: case DCH_HH24:
if (flag == TO_CHAR) if (flag == TO_CHAR)
{ {
...@@ -1638,16 +1658,16 @@ dch_time(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -1638,16 +1658,16 @@ dch_time(int arg, char *inout, int suf, int flag, FormatNode *node)
{ {
if (S_FM(suf)) if (S_FM(suf))
{ {
sscanf(inout, "%d", &tm->tm_hour); sscanf(inout, "%d", &tmfc->hh);
return int4len((int4) tm->tm_hour) - 1 + SKIP_THth(suf); return int4len((int4) tmfc->hh) - 1 + SKIP_THth(suf);
} }
else else
{ {
sscanf(inout, "%02d", &tm->tm_hour); sscanf(inout, "%02d", &tmfc->hh);
return 1 + SKIP_THth(suf); return 1 + SKIP_THth(suf);
} }
} }
break;
case DCH_MI: case DCH_MI:
if (flag == TO_CHAR) if (flag == TO_CHAR)
{ {
...@@ -1664,15 +1684,16 @@ dch_time(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -1664,15 +1684,16 @@ dch_time(int arg, char *inout, int suf, int flag, FormatNode *node)
{ {
if (S_FM(suf)) if (S_FM(suf))
{ {
sscanf(inout, "%d", &tm->tm_min); sscanf(inout, "%d", &tmfc->mi);
return int4len((int4) tm->tm_min) - 1 + SKIP_THth(suf); return int4len((int4) tmfc->mi) - 1 + SKIP_THth(suf);
} }
else else
{ {
sscanf(inout, "%02d", &tm->tm_min); sscanf(inout, "%02d", &tmfc->mi);
return 1 + SKIP_THth(suf); return 1 + SKIP_THth(suf);
} }
} }
break;
case DCH_SS: case DCH_SS:
if (flag == TO_CHAR) if (flag == TO_CHAR)
{ {
...@@ -1689,15 +1710,16 @@ dch_time(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -1689,15 +1710,16 @@ dch_time(int arg, char *inout, int suf, int flag, FormatNode *node)
{ {
if (S_FM(suf)) if (S_FM(suf))
{ {
sscanf(inout, "%d", &tm->tm_sec); sscanf(inout, "%d", &tmfc->ss);
return int4len((int4) tm->tm_sec) - 1 + SKIP_THth(suf); return int4len((int4) tmfc->ss) - 1 + SKIP_THth(suf);
} }
else else
{ {
sscanf(inout, "%02d", &tm->tm_sec); sscanf(inout, "%02d", &tmfc->ss);
return 1 + SKIP_THth(suf); return 1 + SKIP_THth(suf);
} }
} }
break;
case DCH_SSSS: case DCH_SSSS:
if (flag == TO_CHAR) if (flag == TO_CHAR)
{ {
...@@ -1708,31 +1730,59 @@ dch_time(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -1708,31 +1730,59 @@ dch_time(int arg, char *inout, int suf, int flag, FormatNode *node)
str_numth(p_inout, inout, S_TH_TYPE(suf)); str_numth(p_inout, inout, S_TH_TYPE(suf));
return strlen(p_inout) - 1; return strlen(p_inout) - 1;
} }
else if (flag == FROM_CHAR) else if (flag == FROM_CHAR)
elog(ERROR, "to_timestamp(): SSSS is not supported"); {
sscanf(inout, "%d", &tmfc->ssss);
return int4len((int4) tmfc->ssss) - 1 + SKIP_THth(suf);
}
break;
case DCH_tz:
case DCH_TZ:
if (flag == TO_CHAR)
{
int siz = strlen(tzn);
if (arg == DCH_TZ)
strcpy(inout, tzn);
else
{
char *p = palloc(siz);
strcpy(p, tzn);
strcpy(inout, str_tolower(p));
pfree(p);
}
return siz - 1;
}
else if (flag == FROM_CHAR)
{
elog(ERROR, "to_timestamp(): TZ/tz not supported.");
}
} }
return -1; return -1;
} }
#define CHECK_SEQ_SEARCH(_l, _s) { \ #define CHECK_SEQ_SEARCH(_l, _s) \
do { \
if (_l <= 0) { \ if (_l <= 0) { \
elog(ERROR, "to_timestamp(): bad value for %s", _s); \ elog(ERROR, "to_timestamp(): bad value for %s", _s); \
} \ } \
} } while (0)
/* ---------- /* ----------
* Master of DATE for: * Master of DATE for:
* TO_CHAR - write (inout) formated string * TO_CHAR - write (inout) formated string
* FROM_CHAR - scan (inout) string by course of FormatNode * FROM_CHAR - scan (inout) string by course of FormatNode
* ---------- * ----------
*/ */
static int static int
dch_date(int arg, char *inout, int suf, int flag, FormatNode *node) dch_date(int arg, char *inout, int suf, int flag, FormatNode *node)
{ {
char buff[DCH_CACHE_SIZE], char buff[DCH_CACHE_SIZE],
*p_inout; *p_inout;
int i, int i,
len; len;
p_inout = inout; p_inout = inout;
...@@ -1746,10 +1796,8 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -1746,10 +1796,8 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node)
{ {
if (arg == DCH_MONTH || arg == DCH_Month || arg == DCH_month) if (arg == DCH_MONTH || arg == DCH_Month || arg == DCH_month)
{ {
tmfc->mm = seq_search(inout, months_full, ONE_UPPER, FULL_SIZ, &len) +1;
tm->tm_mon = seq_search(inout, months_full, ONE_UPPER, FULL_SIZ, &len);
CHECK_SEQ_SEARCH(len, "MONTH/Month/month"); CHECK_SEQ_SEARCH(len, "MONTH/Month/month");
++tm->tm_mon;
if (S_FM(suf)) if (S_FM(suf))
return len - 1; return len - 1;
else else
...@@ -1758,17 +1806,13 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -1758,17 +1806,13 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node)
} }
else if (arg == DCH_MON || arg == DCH_Mon || arg == DCH_mon) else if (arg == DCH_MON || arg == DCH_Mon || arg == DCH_mon)
{ {
tmfc->mm = seq_search(inout, months, ONE_UPPER, MAX_MON_LEN, &len) +1;
tm->tm_mon = seq_search(inout, months, ONE_UPPER, MAX_MON_LEN, &len);
CHECK_SEQ_SEARCH(len, "MON/Mon/mon"); CHECK_SEQ_SEARCH(len, "MON/Mon/mon");
++tm->tm_mon;
return 2; return 2;
} }
else if (arg == DCH_DAY || arg == DCH_Day || arg == DCH_day) else if (arg == DCH_DAY || arg == DCH_Day || arg == DCH_day)
{ {
tmfc->d = seq_search(inout, days, ONE_UPPER, FULL_SIZ, &len);
tm->tm_wday = seq_search(inout, days, ONE_UPPER, FULL_SIZ, &len);
CHECK_SEQ_SEARCH(len, "DAY/Day/day"); CHECK_SEQ_SEARCH(len, "DAY/Day/day");
if (S_FM(suf)) if (S_FM(suf))
return len - 1; return len - 1;
...@@ -1778,11 +1822,9 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -1778,11 +1822,9 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node)
} }
else if (arg == DCH_DY || arg == DCH_Dy || arg == DCH_dy) else if (arg == DCH_DY || arg == DCH_Dy || arg == DCH_dy)
{ {
tmfc->d = seq_search(inout, days, ONE_UPPER, MAX_DY_LEN, &len);
tm->tm_wday = seq_search(inout, days, ONE_UPPER, MAX_DY_LEN, &len);
CHECK_SEQ_SEARCH(len, "DY/Dy/dy"); CHECK_SEQ_SEARCH(len, "DY/Dy/dy");
return 2; return 2;
} }
} }
...@@ -1799,13 +1841,11 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -1799,13 +1841,11 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node)
} }
else if (flag == FROM_CHAR) else if (flag == FROM_CHAR)
{ {
if (strncmp(inout, B_C_STR, 4) == 0 && tm->tm_year > 0) if (strncmp(inout, B_C_STR, 4) == 0)
tm->tm_year = -(tm->tm_year); tmfc->bc = TRUE;
if (tm->tm_year < 0)
tm->tm_year = tm->tm_year + 1;
return 3; return 3;
} }
break;
case DCH_AD: case DCH_AD:
case DCH_BC: case DCH_BC:
if (flag == TO_CHAR) if (flag == TO_CHAR)
...@@ -1816,13 +1856,11 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -1816,13 +1856,11 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node)
} }
else if (flag == FROM_CHAR) else if (flag == FROM_CHAR)
{ {
if (strncmp(inout, BC_STR, 2) == 0 && tm->tm_year > 0) if (strncmp(inout, BC_STR, 2) == 0)
tm->tm_year = -(tm->tm_year); tmfc->bc = TRUE;
if (tm->tm_year < 0)
tm->tm_year = tm->tm_year + 1;
return 1; return 1;
} }
break;
case DCH_a_d: case DCH_a_d:
case DCH_b_c: case DCH_b_c:
if (flag == TO_CHAR) if (flag == TO_CHAR)
...@@ -1833,13 +1871,11 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -1833,13 +1871,11 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node)
} }
else if (flag == FROM_CHAR) else if (flag == FROM_CHAR)
{ {
if (strncmp(inout, b_c_STR, 4) == 0 && tm->tm_year > 0) if (strncmp(inout, b_c_STR, 4) == 0)
tm->tm_year = -(tm->tm_year); tmfc->bc = TRUE;
if (tm->tm_year < 0)
tm->tm_year = tm->tm_year + 1;
return 3; return 3;
} }
break;
case DCH_ad: case DCH_ad:
case DCH_bc: case DCH_bc:
if (flag == TO_CHAR) if (flag == TO_CHAR)
...@@ -1850,13 +1886,11 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -1850,13 +1886,11 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node)
} }
else if (flag == FROM_CHAR) else if (flag == FROM_CHAR)
{ {
if (strncmp(inout, bc_STR, 2) == 0 && tm->tm_year > 0) if (strncmp(inout, bc_STR, 2) == 0)
tm->tm_year = -(tm->tm_year); tmfc->bc = TRUE;
if (tm->tm_year < 0)
tm->tm_year = tm->tm_year + 1;
return 1; return 1;
} }
break;
case DCH_MONTH: case DCH_MONTH:
strcpy(inout, months_full[tm->tm_mon - 1]); strcpy(inout, months_full[tm->tm_mon - 1]);
sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, str_toupper(inout)); sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, str_toupper(inout));
...@@ -1864,14 +1898,14 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -1864,14 +1898,14 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node)
return strlen(p_inout) - 1; return strlen(p_inout) - 1;
else else
return 8; return 8;
case DCH_Month: case DCH_Month:
sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, months_full[tm->tm_mon - 1]); sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, months_full[tm->tm_mon - 1]);
if (S_FM(suf)) if (S_FM(suf))
return strlen(p_inout) - 1; return strlen(p_inout) - 1;
else else
return 8; return 8;
case DCH_month: case DCH_month:
sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, months_full[tm->tm_mon - 1]); sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, months_full[tm->tm_mon - 1]);
*inout = tolower(*inout); *inout = tolower(*inout);
...@@ -1879,12 +1913,12 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -1879,12 +1913,12 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node)
return strlen(p_inout) - 1; return strlen(p_inout) - 1;
else else
return 8; return 8;
case DCH_MON: case DCH_MON:
strcpy(inout, months[tm->tm_mon - 1]); strcpy(inout, months[tm->tm_mon - 1]);
inout = str_toupper(inout); inout = str_toupper(inout);
return 2; return 2;
case DCH_Mon: case DCH_Mon:
strcpy(inout, months[tm->tm_mon - 1]); strcpy(inout, months[tm->tm_mon - 1]);
return 2; return 2;
...@@ -1910,16 +1944,16 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -1910,16 +1944,16 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node)
{ {
if (S_FM(suf)) if (S_FM(suf))
{ {
sscanf(inout, "%d", &tm->tm_mon); sscanf(inout, "%d", &tmfc->mm);
return int4len((int4) tm->tm_mon) - 1 + SKIP_THth(suf); return int4len((int4) tmfc->mm) - 1 + SKIP_THth(suf);
} }
else else
{ {
sscanf(inout, "%02d", &tm->tm_mon); sscanf(inout, "%02d", &tmfc->mm);
return 1 + SKIP_THth(suf); return 1 + SKIP_THth(suf);
} }
} }
break;
case DCH_DAY: case DCH_DAY:
strcpy(inout, days[tm->tm_wday]); strcpy(inout, days[tm->tm_wday]);
sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, str_toupper(inout)); sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, str_toupper(inout));
...@@ -1973,16 +2007,16 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -1973,16 +2007,16 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node)
{ {
if (S_FM(suf)) if (S_FM(suf))
{ {
sscanf(inout, "%d", &tm->tm_yday); sscanf(inout, "%d", &tmfc->ddd);
return int4len((int4) tm->tm_yday) - 1 + SKIP_THth(suf); return int4len((int4) tmfc->ddd) - 1 + SKIP_THth(suf);
} }
else else
{ {
sscanf(inout, "%03d", &tm->tm_yday); sscanf(inout, "%03d", &tmfc->ddd);
return 2 + SKIP_THth(suf); return 2 + SKIP_THth(suf);
} }
} }
break;
case DCH_DD: case DCH_DD:
if (flag == TO_CHAR) if (flag == TO_CHAR)
{ {
...@@ -1999,15 +2033,16 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -1999,15 +2033,16 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node)
{ {
if (S_FM(suf)) if (S_FM(suf))
{ {
sscanf(inout, "%d", &tm->tm_mday); sscanf(inout, "%d", &tmfc->dd);
return int4len((int4) tm->tm_mday) - 1 + SKIP_THth(suf); return int4len((int4) tmfc->dd) - 1 + SKIP_THth(suf);
} }
else else
{ {
sscanf(inout, "%02d", &tm->tm_mday); sscanf(inout, "%02d", &tmfc->dd);
return 1 + SKIP_THth(suf); return 1 + SKIP_THth(suf);
} }
} }
break;
case DCH_D: case DCH_D:
if (flag == TO_CHAR) if (flag == TO_CHAR)
{ {
...@@ -2021,17 +2056,15 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -2021,17 +2056,15 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node)
} }
else if (flag == FROM_CHAR) else if (flag == FROM_CHAR)
{ {
sscanf(inout, "%1d", &tm->tm_wday); sscanf(inout, "%1d", &tmfc->d);
if (tm->tm_wday)
--tm->tm_wday;
return 0 + SKIP_THth(suf); return 0 + SKIP_THth(suf);
} }
break;
case DCH_WW: case DCH_WW:
if (flag == TO_CHAR) if (flag == TO_CHAR)
{ {
sprintf(inout, "%0*d", S_FM(suf) ? 0 : 2, sprintf(inout, "%0*d", S_FM(suf) ? 0 : 2,
(tm->tm_yday - tm->tm_wday + 7) / 7); (tm->tm_yday-1) / 7 + 1);
if (S_THth(suf)) if (S_THth(suf))
str_numth(p_inout, inout, S_TH_TYPE(suf)); str_numth(p_inout, inout, S_TH_TYPE(suf));
if (S_FM(suf) || S_THth(suf)) if (S_FM(suf) || S_THth(suf))
...@@ -2040,8 +2073,20 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -2040,8 +2073,20 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node)
return 1; return 1;
} }
else if (flag == FROM_CHAR) else if (flag == FROM_CHAR)
elog(ERROR, "to_datatime(): WW is not supported"); {
if (S_FM(suf))
{
sscanf(inout, "%d", &tmfc->ww);
return int4len((int4) tmfc->ww) - 1 + SKIP_THth(suf);
}
else
{
sscanf(inout, "%02d", &tmfc->ww);
return 1 + SKIP_THth(suf);
}
}
break;
case DCH_Q: case DCH_Q:
if (flag == TO_CHAR) if (flag == TO_CHAR)
{ {
...@@ -2055,8 +2100,11 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -2055,8 +2100,11 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node)
} }
else if (flag == FROM_CHAR) else if (flag == FROM_CHAR)
elog(ERROR, "to_datatime(): Q is not supported"); {
sscanf(inout, "%1d", &tmfc->q);
return 0 + SKIP_THth(suf);
}
break;
case DCH_CC: case DCH_CC:
if (flag == TO_CHAR) if (flag == TO_CHAR)
{ {
...@@ -2071,7 +2119,11 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -2071,7 +2119,11 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node)
} }
else if (flag == FROM_CHAR) else if (flag == FROM_CHAR)
elog(ERROR, "to_datatime(): CC is not supported"); {
sscanf(inout, "%d", &tmfc->cc);
return int4len((int4) tmfc->cc) + SKIP_THth(suf) -1;
}
break;
case DCH_Y_YYY: case DCH_Y_YYY:
if (flag == TO_CHAR) if (flag == TO_CHAR)
{ {
...@@ -2079,35 +2131,23 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -2079,35 +2131,23 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node)
sprintf(inout, "%d,%03d", i, YEAR_ABS(tm->tm_year) - (i * 1000)); sprintf(inout, "%d,%03d", i, YEAR_ABS(tm->tm_year) - (i * 1000));
if (S_THth(suf)) if (S_THth(suf))
str_numth(p_inout, inout, S_TH_TYPE(suf)); str_numth(p_inout, inout, S_TH_TYPE(suf));
/*
* if (tm->tm_year < 0) strcat(inout, BC_STR_ORIG);
*/
return strlen(p_inout) - 1; return strlen(p_inout) - 1;
} }
else if (flag == FROM_CHAR) else if (flag == FROM_CHAR)
{ {
int cc, int cc;
yy;
sscanf(inout, "%d,%03d", &cc, &yy); sscanf(inout, "%d,%03d", &cc, &tmfc->yyyy);
tm->tm_year = (cc * 1000) + yy; tmfc->yyyy += (cc * 1000);
if (!S_FM(suf) && tm->tm_year <= 9999 && tm->tm_year >= -9999) if (!S_FM(suf) && tmfc->yyyy <= 9999 && tmfc->yyyy >= -9999)
len = 5; len = 5;
else else
len = int4len((int4) tm->tm_year) + 1; len = int4len((int4) tmfc->yyyy) + 1;
len += SKIP_THth(suf); len += SKIP_THth(suf);
/*
* AC/BC if (is_acdc(inout+len, &len) < 0 && tm->tm_year >
* 0) tm->tm_year = -(tm->tm_year); if (tm->tm_year < 0)
* tm->tm_year = tm->tm_year+1;
*/
return len - 1; return len - 1;
} }
break;
case DCH_YYYY: case DCH_YYYY:
if (flag == TO_CHAR) if (flag == TO_CHAR)
{ {
...@@ -2117,30 +2157,19 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -2117,30 +2157,19 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node)
sprintf(inout, "%d", YEAR_ABS(tm->tm_year)); sprintf(inout, "%d", YEAR_ABS(tm->tm_year));
if (S_THth(suf)) if (S_THth(suf))
str_numth(p_inout, inout, S_TH_TYPE(suf)); str_numth(p_inout, inout, S_TH_TYPE(suf));
/*
* if (tm->tm_year < 0) strcat(inout, BC_STR_ORIG);
*/
return strlen(p_inout) - 1; return strlen(p_inout) - 1;
} }
else if (flag == FROM_CHAR) else if (flag == FROM_CHAR)
{ {
sscanf(inout, "%d", &tm->tm_year); sscanf(inout, "%d", &tmfc->yyyy);
if (!S_FM(suf) && tm->tm_year <= 9999 && tm->tm_year >= -9999) if (!S_FM(suf) && tmfc->yyyy <= 9999 && tmfc->yyyy >= -9999)
len = 4; len = 4;
else else
len = int4len((int4) tm->tm_year); len = int4len((int4) tmfc->yyyy);
len += SKIP_THth(suf); len += SKIP_THth(suf);
/*
* AC/BC if (is_acdc(inout+len, &len) < 0 && tm->tm_year >
* 0) tm->tm_year = -(tm->tm_year); if (tm->tm_year < 0)
* tm->tm_year = tm->tm_year+1;
*/
return len - 1; return len - 1;
} }
break;
case DCH_YYY: case DCH_YYY:
if (flag == TO_CHAR) if (flag == TO_CHAR)
{ {
...@@ -2157,13 +2186,10 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -2157,13 +2186,10 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node)
} }
else if (flag == FROM_CHAR) else if (flag == FROM_CHAR)
{ {
int yy; sscanf(inout, "%03d", &tmfc->yyyy);
sscanf(inout, "%03d", &yy);
tm->tm_year = (tm->tm_year / 1000) * 1000 + yy;
return 2 + SKIP_THth(suf); return 2 + SKIP_THth(suf);
} }
break;
case DCH_YY: case DCH_YY:
if (flag == TO_CHAR) if (flag == TO_CHAR)
{ {
...@@ -2180,13 +2206,10 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -2180,13 +2206,10 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node)
} }
else if (flag == FROM_CHAR) else if (flag == FROM_CHAR)
{ {
int yy; sscanf(inout, "%02d", &tmfc->yyyy);
sscanf(inout, "%02d", &yy);
tm->tm_year = (tm->tm_year / 100) * 100 + yy;
return 1 + SKIP_THth(suf); return 1 + SKIP_THth(suf);
} }
break;
case DCH_Y: case DCH_Y:
if (flag == TO_CHAR) if (flag == TO_CHAR)
{ {
...@@ -2203,13 +2226,10 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -2203,13 +2226,10 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node)
} }
else if (flag == FROM_CHAR) else if (flag == FROM_CHAR)
{ {
int yy; sscanf(inout, "%1d", &tmfc->yyyy);
sscanf(inout, "%1d", &yy);
tm->tm_year = (tm->tm_year / 10) * 10 + yy;
return 0 + SKIP_THth(suf); return 0 + SKIP_THth(suf);
} }
break;
case DCH_RM: case DCH_RM:
if (flag == TO_CHAR) if (flag == TO_CHAR)
{ {
...@@ -2223,15 +2243,14 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -2223,15 +2243,14 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node)
} }
else if (flag == FROM_CHAR) else if (flag == FROM_CHAR)
{ {
tm->tm_mon = 11 - seq_search(inout, rm_months_upper, ALL_UPPER, FULL_SIZ, &len); tmfc->mm = 12 - seq_search(inout, rm_months_upper, ALL_UPPER, FULL_SIZ, &len);
CHECK_SEQ_SEARCH(len, "RM"); CHECK_SEQ_SEARCH(len, "RM");
++tm->tm_mon;
if (S_FM(suf)) if (S_FM(suf))
return len - 1; return len - 1;
else else
return 3; return 3;
} }
break;
case DCH_rm: case DCH_rm:
if (flag == TO_CHAR) if (flag == TO_CHAR)
{ {
...@@ -2245,30 +2264,31 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -2245,30 +2264,31 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node)
} }
else if (flag == FROM_CHAR) else if (flag == FROM_CHAR)
{ {
tm->tm_mon = 11 - seq_search(inout, rm_months_lower, ALL_UPPER, FULL_SIZ, &len); tmfc->mm = 12 - seq_search(inout, rm_months_lower, ALL_UPPER, FULL_SIZ, &len);
CHECK_SEQ_SEARCH(len, "rm"); CHECK_SEQ_SEARCH(len, "rm");
++tm->tm_mon;
if (S_FM(suf)) if (S_FM(suf))
return len - 1; return len - 1;
else else
return 3; return 3;
} }
break;
case DCH_W: case DCH_W:
if (flag == TO_CHAR) if (flag == TO_CHAR)
{ {
sprintf(inout, "%d", (tm->tm_mday - tm->tm_wday + 7) / 7); sprintf(inout, "%d", (tm->tm_mday-1) / 7 + 1);
if (S_THth(suf)) if (S_THth(suf))
{ {
str_numth(p_inout, inout, S_TH_TYPE(suf)); str_numth(p_inout, inout, S_TH_TYPE(suf));
return 2; return 2;
} }
return 0; return 0;
} }
else if (flag == FROM_CHAR) else if (flag == FROM_CHAR)
elog(ERROR, "to_datatime(): W is not supported"); {
sscanf(inout, "%1d", &tmfc->w);
return 0 + SKIP_THth(suf);
}
break;
case DCH_J: case DCH_J:
if (flag == TO_CHAR) if (flag == TO_CHAR)
{ {
...@@ -2278,7 +2298,11 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node) ...@@ -2278,7 +2298,11 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node)
return strlen(p_inout) - 1; return strlen(p_inout) - 1;
} }
else if (flag == FROM_CHAR) else if (flag == FROM_CHAR)
elog(ERROR, "to_datatime(): J is not supported"); {
sscanf(inout, "%d", &tmfc->j);
return int4len((int4) tmfc->j) + SKIP_THth(suf) -1;
}
break;
} }
return -1; return -1;
} }
...@@ -2382,32 +2406,25 @@ Datum ...@@ -2382,32 +2406,25 @@ Datum
timestamp_to_char(PG_FUNCTION_ARGS) timestamp_to_char(PG_FUNCTION_ARGS)
{ {
Timestamp dt = PG_GETARG_TIMESTAMP(0); Timestamp dt = PG_GETARG_TIMESTAMP(0);
text *fmt = PG_GETARG_TEXT_P(1); text *fmt = PG_GETARG_TEXT_P(1);
text *result, text *result,
*result_tmp; *result_tmp;
FormatNode *format;
char *str; FormatNode *format;
char *str;
double fsec; double fsec;
char *tzn; int len = 0,
int len = 0, tz,
tz, flag = 0,
flag = 0, x = 0;
x = 0;
len = VARSIZE(fmt) - VARHDRSZ; len = VARSIZE(fmt) - VARHDRSZ;
if ((!len) || (TIMESTAMP_NOT_FINITE(dt))) if ((!len) || (TIMESTAMP_NOT_FINITE(dt)))
return PointerGetDatum(textin("")); return PointerGetDatum(textin(""));
tm->tm_sec = 0; ZERO_tm(tm);
tm->tm_year = 0; tzn = NULL;
tm->tm_min = 0;
tm->tm_wday = 0;
tm->tm_hour = 0;
tm->tm_yday = 0;
tm->tm_mday = 1;
tm->tm_isdst = 0;
tm->tm_mon = 1;
if (TIMESTAMP_IS_EPOCH(dt)) if (TIMESTAMP_IS_EPOCH(dt))
{ {
...@@ -2446,10 +2463,9 @@ timestamp_to_char(PG_FUNCTION_ARGS) ...@@ -2446,10 +2463,9 @@ timestamp_to_char(PG_FUNCTION_ARGS)
* Allocate new memory if format picture is bigger than static cache * Allocate new memory if format picture is bigger than static cache
* and not use cache (call parser always) - flag=1 show this variant * and not use cache (call parser always) - flag=1 show this variant
* ---------- * ----------
*/ */
if (len > DCH_CACHE_SIZE) if (len > DCH_CACHE_SIZE)
{ {
format = (FormatNode *) palloc((len + 1) * sizeof(FormatNode)); format = (FormatNode *) palloc((len + 1) * sizeof(FormatNode));
flag = 1; flag = 1;
...@@ -2479,9 +2495,9 @@ timestamp_to_char(PG_FUNCTION_ARGS) ...@@ -2479,9 +2495,9 @@ timestamp_to_char(PG_FUNCTION_ARGS)
* Not in the cache, must run parser and save a new * Not in the cache, must run parser and save a new
* format-picture to the cache. * format-picture to the cache.
* ---------- * ----------
*/ */
parse_format(ent->format, str, DCH_keywords, parse_format(ent->format, str, DCH_keywords,
DCH_suff, DCH_index, DCH_TYPE, NULL); DCH_suff, DCH_index, DCH_TYPE, NULL);
(ent->format + len)->type = NODE_TYPE_END; /* Paranoa? */ (ent->format + len)->type = NODE_TYPE_END; /* Paranoa? */
...@@ -2527,25 +2543,18 @@ timestamp_to_char(PG_FUNCTION_ARGS) ...@@ -2527,25 +2543,18 @@ timestamp_to_char(PG_FUNCTION_ARGS)
Datum Datum
to_timestamp(PG_FUNCTION_ARGS) to_timestamp(PG_FUNCTION_ARGS)
{ {
text *date_str = PG_GETARG_TEXT_P(0); text *date_str = PG_GETARG_TEXT_P(0);
text *fmt = PG_GETARG_TEXT_P(1); text *fmt = PG_GETARG_TEXT_P(1);
FormatNode *format; FormatNode *format;
int flag = 0; int flag = 0;
Timestamp result; Timestamp result;
char *str; char *str;
int len = 0, int len = 0,
fsec = 0, fsec = 0,
tz = 0; tz = 0;
tm->tm_sec = 0; ZERO_tm(tm);
tm->tm_year = 0; ZERO_tmfc(tmfc);
tm->tm_min = 0;
tm->tm_wday = 0;
tm->tm_hour = 0;
tm->tm_yday = 0;
tm->tm_mday = 1;
tm->tm_isdst = 0;
tm->tm_mon = 1;
len = VARSIZE(fmt) - VARHDRSZ; len = VARSIZE(fmt) - VARHDRSZ;
...@@ -2564,10 +2573,9 @@ to_timestamp(PG_FUNCTION_ARGS) ...@@ -2564,10 +2573,9 @@ to_timestamp(PG_FUNCTION_ARGS)
* Allocate new memory if format picture is bigger than static cache * Allocate new memory if format picture is bigger than static cache
* and not use cache (call parser always) - flag=1 show this variant * and not use cache (call parser always) - flag=1 show this variant
* ---------- * ----------
*/ */
if (len > DCH_CACHE_SIZE) if (len > DCH_CACHE_SIZE)
{ {
format = (FormatNode *) palloc((len + 1) * sizeof(FormatNode)); format = (FormatNode *) palloc((len + 1) * sizeof(FormatNode));
flag = 1; flag = 1;
...@@ -2625,6 +2633,101 @@ to_timestamp(PG_FUNCTION_ARGS) ...@@ -2625,6 +2633,101 @@ to_timestamp(PG_FUNCTION_ARGS)
pfree(format); pfree(format);
} }
/* --------------------------------------------------------------
* Convert values that user define for FROM_CHAR (to_date/to_timestamp)
* to standard 'tm'
* ----------
*/
#ifdef DEBUG_TO_FROM_CHAR
NOTICE_TMFC;
#endif
if (tmfc->ssss)
{
int x;
if (tmfc->ssss > 3600)
tm->tm_sec = x - ((tm->tm_min = (x = tmfc->ssss -
((tm->tm_hour= tmfc->ssss / 3600) * 3600)) / 60) * 60);
else if (tmfc->ssss > 60)
tm->tm_sec = tmfc->ssss - ((tm->tm_min = tmfc->ssss / 60) * 60);
else
tm->tm_sec = tmfc->ssss;
}
if (tmfc->cc)
tm->tm_year = (tmfc->cc-1) * 100;
if (tmfc->ww)
tmfc->ddd = (tmfc->ww - 1) * 7 + 1;
if (tmfc->w)
tmfc->dd = (tmfc->w - 1) * 7 + 1;
if (tmfc->ss) tm->tm_sec = tmfc->ss;
if (tmfc->mi) tm->tm_min = tmfc->mi;
if (tmfc->hh) tm->tm_hour = tmfc->hh;
if (tmfc->pm || tmfc->am)
{
if (tm->tm_hour < 1 || tm->tm_hour > 12)
elog(ERROR, "to_timestamp(): AM/PM hour must be between 1 and 12");
if (tmfc->pm && tm->tm_hour < 12)
tm->tm_hour += 12;
else if (tmfc->am && tm->tm_hour == 12)
tm->tm_hour = 0;
}
switch (tmfc->q)
{
case 1: tm->tm_mday = 1; tm->tm_mon = 1; break;
case 2: tm->tm_mday = 1; tm->tm_mon = 4; break;
case 3: tm->tm_mday = 1; tm->tm_mon = 7; break;
case 4: tm->tm_mday = 1; tm->tm_mon = 10; break;
}
if (tmfc->j)
j2date(tmfc->j, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
if (tmfc->yyyy)
tm->tm_year = tmfc->yyyy;
if (tmfc->bc && tm->tm_year > 0)
tm->tm_year = -(tm->tm_year);
if (tm->tm_year < 0)
tm->tm_year = tm->tm_year + 1;
if (tmfc->d) tm->tm_wday = tmfc->d;
if (tmfc->dd) tm->tm_mday = tmfc->dd;
if (tmfc->ddd) tm->tm_yday = tmfc->ddd;
if (tmfc->mm) tm->tm_mon = tmfc->mm;
if (tmfc->ddd && (tm->tm_mon <=1 || tm->tm_mday <=1))
{
/* count mday and mon from yday */
int *y, i;
int ysum[2][13] = {
{ 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365, 0 },
{ 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366, 0 }};
if (!tm->tm_year)
elog(ERROR, "to_timestamp() cat't convert yday without year information");
y = ysum[ isleap(tm->tm_year) ];
for (i=0; i <= 11; i++)
{
if (tm->tm_yday < y[i])
break;
}
if (tm->tm_mon <=1)
tm->tm_mon = i+1;
if (tm->tm_mday <=1)
tm->tm_mday = i == 0 ? tm->tm_yday :
tm->tm_yday - y[i-1];
}
/* -------------------------------------------------------------- */
#ifdef DEBUG_TO_FROM_CHAR #ifdef DEBUG_TO_FROM_CHAR
NOTICE_TM; NOTICE_TM;
#endif #endif
...@@ -2703,17 +2806,18 @@ fill_str(char *str, int c, int max) ...@@ -2703,17 +2806,18 @@ fill_str(char *str, int c, int max)
return str; return str;
} }
#define zeroize_NUM(_n) { \ #define zeroize_NUM(_n) \
do { \
(_n)->flag = 0; \ (_n)->flag = 0; \
(_n)->lsign = 0; \ (_n)->lsign = 0; \
(_n)->pre = 0; \ (_n)->pre = 0; \
(_n)->post = 0; \ (_n)->post = 0; \
(_n)->pre_lsign_num = 0; \ (_n)->pre_lsign_num = 0; \
(_n)->need_locale = 0; \ (_n)->need_locale = 0; \
(_n)->multi = 0; \ (_n)->multi = 0; \
(_n)->zero_start = 0; \ (_n)->zero_start = 0; \
(_n)->zero_end = 0; \ (_n)->zero_end = 0; \
} } while(0)
static NUMCacheEntry * static NUMCacheEntry *
NUM_cache_getnew(char *str) NUM_cache_getnew(char *str)
...@@ -2777,7 +2881,7 @@ NUM_cache_getnew(char *str) ...@@ -2777,7 +2881,7 @@ NUM_cache_getnew(char *str)
static NUMCacheEntry * static NUMCacheEntry *
NUM_cache_search(char *str) NUM_cache_search(char *str)
{ {
int i = 0; int i = 0;
NUMCacheEntry *ent; NUMCacheEntry *ent;
/* counter overload check - paranoa? */ /* counter overload check - paranoa? */
...@@ -2899,12 +3003,12 @@ NUM_cache(int len, NUMDesc *Num, char *pars_str, int *flag) ...@@ -2899,12 +3003,12 @@ NUM_cache(int len, NUMDesc *Num, char *pars_str, int *flag)
static char * static char *
int_to_roman(int number) int_to_roman(int number)
{ {
int len = 0, int len = 0,
num = 0, num = 0,
set = 0; set = 0;
char *p = NULL, char *p = NULL,
*result, *result,
numstr[5]; numstr[5];
result = (char *) palloc(16); result = (char *) palloc(16);
*result = '\0'; *result = '\0';
...@@ -3039,7 +3143,7 @@ static char * ...@@ -3039,7 +3143,7 @@ static char *
get_last_relevant_decnum(char *num) get_last_relevant_decnum(char *num)
{ {
char *result, char *result,
*p = strchr(num, '.'); *p = strchr(num, '.');
#ifdef DEBUG_TO_FROM_CHAR #ifdef DEBUG_TO_FROM_CHAR
elog(DEBUG_elog_output, "CALL: get_last_relevant_decnum()"); elog(DEBUG_elog_output, "CALL: get_last_relevant_decnum()");
...@@ -3186,8 +3290,7 @@ NUM_numpart_from_char(NUMProc *Np, int id, int plen) ...@@ -3186,8 +3290,7 @@ NUM_numpart_from_char(NUMProc *Np, int id, int plen)
} }
else else
{ {
int x = strlen(Np->decimal);
int x = strlen(Np->decimal);
#ifdef DEBUG_TO_FROM_CHAR #ifdef DEBUG_TO_FROM_CHAR
elog(DEBUG_elog_output, "Try read locale point (%c).", *Np->inout_p); elog(DEBUG_elog_output, "Try read locale point (%c).", *Np->inout_p);
...@@ -3420,8 +3523,8 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number, ...@@ -3420,8 +3523,8 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
int plen, int sign, int type) int plen, int sign, int type)
{ {
FormatNode *n; FormatNode *n;
NUMProc _Np, NUMProc _Np,
*Np = &_Np; *Np = &_Np;
Np->Num = Num; Np->Num = Num;
Np->type = type; Np->type = type;
...@@ -3506,9 +3609,9 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number, ...@@ -3506,9 +3609,9 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
{ {
if (IS_DECIMAL(Np->Num)) if (IS_DECIMAL(Np->Num))
Np->last_relevant = get_last_relevant_decnum( Np->last_relevant = get_last_relevant_decnum(
Np->number + Np->number +
((Np->Num->zero_end - Np->num_pre > 0) ? ((Np->Num->zero_end - Np->num_pre > 0) ?
Np->Num->zero_end - Np->num_pre : 0)); Np->Num->zero_end - Np->num_pre : 0));
} }
if (!Np->sign_wrote && Np->num_pre == 0) if (!Np->sign_wrote && Np->num_pre == 0)
...@@ -3850,23 +3953,23 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number, ...@@ -3850,23 +3953,23 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
* (sorry, but I hate copy same code - macro is better..) * (sorry, but I hate copy same code - macro is better..)
* ---------- * ----------
*/ */
#define NUM_TOCHAR_prepare { \ #define NUM_TOCHAR_prepare \
\ do { \
len = VARSIZE(fmt) - VARHDRSZ; \ len = VARSIZE(fmt) - VARHDRSZ; \
\ \
if (len <= 0) \ if (len <= 0) \
return PointerGetDatum(textin("")); \ return PointerGetDatum(textin("")); \
\ \
result = (text *) palloc( (len * NUM_MAX_ITEM_SIZ) + 1 + VARHDRSZ); \ result = (text *) palloc( (len * NUM_MAX_ITEM_SIZ) + 1 + VARHDRSZ); \
format = NUM_cache(len, &Num, VARDATA(fmt), &flag); \ format = NUM_cache(len, &Num, VARDATA(fmt), &flag); \
} } while(0)
/* ---------- /* ----------
* MACRO: Finish part of NUM * MACRO: Finish part of NUM
* ---------- * ----------
*/ */
#define NUM_TOCHAR_finish { \ #define NUM_TOCHAR_finish \
\ do { \
NUM_processor(format, &Num, VARDATA(result), \ NUM_processor(format, &Num, VARDATA(result), \
numstr, plen, sign, TO_CHAR); \ numstr, plen, sign, TO_CHAR); \
pfree(orgnum); \ pfree(orgnum); \
...@@ -3879,14 +3982,14 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number, ...@@ -3879,14 +3982,14 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
* needs, now it must be re-allocate to result real size \ * needs, now it must be re-allocate to result real size \
* ---------- \ * ---------- \
*/ \ */ \
len = strlen(VARDATA(result)); \ len = strlen(VARDATA(result)); \
result_tmp = result; \ result_tmp = result; \
result = (text *) palloc( len + 1 + VARHDRSZ); \ result = (text *) palloc( len + 1 + VARHDRSZ); \
\ \
strcpy( VARDATA(result), VARDATA(result_tmp)); \ strcpy( VARDATA(result), VARDATA(result_tmp)); \
VARSIZE(result) = len + VARHDRSZ; \ VARSIZE(result) = len + VARHDRSZ; \
pfree(result_tmp); \ pfree(result_tmp); \
} } while(0)
/* ------------------- /* -------------------
* NUMERIC to_number() (convert string to numeric) * NUMERIC to_number() (convert string to numeric)
...@@ -3895,16 +3998,16 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number, ...@@ -3895,16 +3998,16 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
Datum Datum
numeric_to_number(PG_FUNCTION_ARGS) numeric_to_number(PG_FUNCTION_ARGS)
{ {
text *value = PG_GETARG_TEXT_P(0); text *value = PG_GETARG_TEXT_P(0);
text *fmt = PG_GETARG_TEXT_P(1); text *fmt = PG_GETARG_TEXT_P(1);
NUMDesc Num; NUMDesc Num;
Datum result; Datum result;
FormatNode *format; FormatNode *format;
char *numstr; char *numstr;
int flag = 0; int flag = 0;
int len = 0; int len = 0;
int scale, int scale,
precision; precision;
len = VARSIZE(fmt) - VARHDRSZ; len = VARSIZE(fmt) - VARHDRSZ;
...@@ -3925,9 +4028,9 @@ numeric_to_number(PG_FUNCTION_ARGS) ...@@ -3925,9 +4028,9 @@ numeric_to_number(PG_FUNCTION_ARGS)
pfree(format); pfree(format);
result = DirectFunctionCall3(numeric_in, result = DirectFunctionCall3(numeric_in,
CStringGetDatum(numstr), CStringGetDatum(numstr),
ObjectIdGetDatum(InvalidOid), ObjectIdGetDatum(InvalidOid),
Int32GetDatum(((precision << 16) | scale) + VARHDRSZ)); Int32GetDatum(((precision << 16) | scale) + VARHDRSZ));
pfree(numstr); pfree(numstr);
return result; return result;
} }
...@@ -3939,20 +4042,20 @@ numeric_to_number(PG_FUNCTION_ARGS) ...@@ -3939,20 +4042,20 @@ numeric_to_number(PG_FUNCTION_ARGS)
Datum Datum
numeric_to_char(PG_FUNCTION_ARGS) numeric_to_char(PG_FUNCTION_ARGS)
{ {
Numeric value = PG_GETARG_NUMERIC(0); Numeric value = PG_GETARG_NUMERIC(0);
text *fmt = PG_GETARG_TEXT_P(1); text *fmt = PG_GETARG_TEXT_P(1);
NUMDesc Num; NUMDesc Num;
FormatNode *format; FormatNode *format;
text *result, text *result,
*result_tmp; *result_tmp;
int flag = 0; int flag = 0;
int len = 0, int len = 0,
plen = 0, plen = 0,
sign = 0; sign = 0;
char *numstr, char *numstr,
*orgnum, *orgnum,
*p; *p;
Numeric x; Numeric x;
NUM_TOCHAR_prepare; NUM_TOCHAR_prepare;
...@@ -3963,8 +4066,8 @@ numeric_to_char(PG_FUNCTION_ARGS) ...@@ -3963,8 +4066,8 @@ numeric_to_char(PG_FUNCTION_ARGS)
if (IS_ROMAN(&Num)) if (IS_ROMAN(&Num))
{ {
x = DatumGetNumeric(DirectFunctionCall2(numeric_round, x = DatumGetNumeric(DirectFunctionCall2(numeric_round,
NumericGetDatum(value), NumericGetDatum(value),
Int32GetDatum(0))); Int32GetDatum(0)));
numstr = orgnum = int_to_roman(numeric_int4(x)); numstr = orgnum = int_to_roman(numeric_int4(x));
pfree(x); pfree(x);
} }
...@@ -3975,9 +4078,9 @@ numeric_to_char(PG_FUNCTION_ARGS) ...@@ -3975,9 +4078,9 @@ numeric_to_char(PG_FUNCTION_ARGS)
if (IS_MULTI(&Num)) if (IS_MULTI(&Num))
{ {
Numeric a = DatumGetNumeric(DirectFunctionCall1(int4_numeric, Numeric a = DatumGetNumeric(DirectFunctionCall1(int4_numeric,
Int32GetDatum(10))); Int32GetDatum(10)));
Numeric b = DatumGetNumeric(DirectFunctionCall1(int4_numeric, Numeric b = DatumGetNumeric(DirectFunctionCall1(int4_numeric,
Int32GetDatum(Num.multi))); Int32GetDatum(Num.multi)));
x = numeric_power(a, b); x = numeric_power(a, b);
val = numeric_mul(value, x); val = numeric_mul(value, x);
...@@ -3988,10 +4091,10 @@ numeric_to_char(PG_FUNCTION_ARGS) ...@@ -3988,10 +4091,10 @@ numeric_to_char(PG_FUNCTION_ARGS)
} }
x = DatumGetNumeric(DirectFunctionCall2(numeric_round, x = DatumGetNumeric(DirectFunctionCall2(numeric_round,
NumericGetDatum(val), NumericGetDatum(val),
Int32GetDatum(Num.post))); Int32GetDatum(Num.post)));
orgnum = DatumGetCString(DirectFunctionCall1(numeric_out, orgnum = DatumGetCString(DirectFunctionCall1(numeric_out,
NumericGetDatum(x))); NumericGetDatum(x)));
pfree(x); pfree(x);
if (*orgnum == '-') if (*orgnum == '-')
...@@ -4034,18 +4137,18 @@ numeric_to_char(PG_FUNCTION_ARGS) ...@@ -4034,18 +4137,18 @@ numeric_to_char(PG_FUNCTION_ARGS)
Datum Datum
int4_to_char(PG_FUNCTION_ARGS) int4_to_char(PG_FUNCTION_ARGS)
{ {
int32 value = PG_GETARG_INT32(0); int32 value = PG_GETARG_INT32(0);
text *fmt = PG_GETARG_TEXT_P(1); text *fmt = PG_GETARG_TEXT_P(1);
NUMDesc Num; NUMDesc Num;
FormatNode *format; FormatNode *format;
text *result, text *result,
*result_tmp; *result_tmp;
int flag = 0; int flag = 0;
int len = 0, int len = 0,
plen = 0, plen = 0,
sign = 0; sign = 0;
char *numstr, char *numstr,
*orgnum; *orgnum;
NUM_TOCHAR_prepare; NUM_TOCHAR_prepare;
...@@ -4062,13 +4165,13 @@ int4_to_char(PG_FUNCTION_ARGS) ...@@ -4062,13 +4165,13 @@ int4_to_char(PG_FUNCTION_ARGS)
if (IS_MULTI(&Num)) if (IS_MULTI(&Num))
{ {
orgnum = DatumGetCString(DirectFunctionCall1(int4out, orgnum = DatumGetCString(DirectFunctionCall1(int4out,
Int32GetDatum(value * ((int32) pow((double) 10, (double) Num.multi))))); Int32GetDatum(value * ((int32) pow((double) 10, (double) Num.multi)))));
Num.pre += Num.multi; Num.pre += Num.multi;
} }
else else
{ {
orgnum = DatumGetCString(DirectFunctionCall1(int4out, orgnum = DatumGetCString(DirectFunctionCall1(int4out,
Int32GetDatum(value))); Int32GetDatum(value)));
} }
len = strlen(orgnum); len = strlen(orgnum);
...@@ -4082,7 +4185,7 @@ int4_to_char(PG_FUNCTION_ARGS) ...@@ -4082,7 +4185,7 @@ int4_to_char(PG_FUNCTION_ARGS)
if (Num.post) if (Num.post)
{ {
int i; int i;
numstr = palloc(len + 1 + Num.post); numstr = palloc(len + 1 + Num.post);
strcpy(numstr, orgnum + (*orgnum == '-' ? 1 : 0)); strcpy(numstr, orgnum + (*orgnum == '-' ? 1 : 0));
...@@ -4118,18 +4221,18 @@ int4_to_char(PG_FUNCTION_ARGS) ...@@ -4118,18 +4221,18 @@ int4_to_char(PG_FUNCTION_ARGS)
Datum Datum
int8_to_char(PG_FUNCTION_ARGS) int8_to_char(PG_FUNCTION_ARGS)
{ {
int64 value = PG_GETARG_INT64(0); int64 value = PG_GETARG_INT64(0);
text *fmt = PG_GETARG_TEXT_P(1); text *fmt = PG_GETARG_TEXT_P(1);
NUMDesc Num; NUMDesc Num;
FormatNode *format; FormatNode *format;
text *result, text *result,
*result_tmp; *result_tmp;
int flag = 0; int flag = 0;
int len = 0, int len = 0,
plen = 0, plen = 0,
sign = 0; sign = 0;
char *numstr, char *numstr,
*orgnum; *orgnum;
NUM_TOCHAR_prepare; NUM_TOCHAR_prepare;
...@@ -4150,14 +4253,14 @@ int8_to_char(PG_FUNCTION_ARGS) ...@@ -4150,14 +4253,14 @@ int8_to_char(PG_FUNCTION_ARGS)
double multi = pow((double) 10, (double) Num.multi); double multi = pow((double) 10, (double) Num.multi);
value = DatumGetInt64(DirectFunctionCall2(int8mul, value = DatumGetInt64(DirectFunctionCall2(int8mul,
Int64GetDatum(value), Int64GetDatum(value),
DirectFunctionCall1(dtoi8, DirectFunctionCall1(dtoi8,
Float8GetDatum(multi)))); Float8GetDatum(multi))));
Num.pre += Num.multi; Num.pre += Num.multi;
} }
orgnum = DatumGetCString(DirectFunctionCall1(int8out, orgnum = DatumGetCString(DirectFunctionCall1(int8out,
Int64GetDatum(value))); Int64GetDatum(value)));
len = strlen(orgnum); len = strlen(orgnum);
if (*orgnum == '-') if (*orgnum == '-')
...@@ -4170,7 +4273,7 @@ int8_to_char(PG_FUNCTION_ARGS) ...@@ -4170,7 +4273,7 @@ int8_to_char(PG_FUNCTION_ARGS)
if (Num.post) if (Num.post)
{ {
int i; int i;
numstr = palloc(len + 1 + Num.post); numstr = palloc(len + 1 + Num.post);
strcpy(numstr, orgnum + (*orgnum == '-' ? 1 : 0)); strcpy(numstr, orgnum + (*orgnum == '-' ? 1 : 0));
...@@ -4206,19 +4309,19 @@ int8_to_char(PG_FUNCTION_ARGS) ...@@ -4206,19 +4309,19 @@ int8_to_char(PG_FUNCTION_ARGS)
Datum Datum
float4_to_char(PG_FUNCTION_ARGS) float4_to_char(PG_FUNCTION_ARGS)
{ {
float4 value = PG_GETARG_FLOAT4(0); float4 value = PG_GETARG_FLOAT4(0);
text *fmt = PG_GETARG_TEXT_P(1); text *fmt = PG_GETARG_TEXT_P(1);
NUMDesc Num; NUMDesc Num;
FormatNode *format; FormatNode *format;
text *result, text *result,
*result_tmp; *result_tmp;
int flag = 0; int flag = 0;
int len = 0, int len = 0,
plen = 0, plen = 0,
sign = 0; sign = 0;
char *numstr, char *numstr,
*orgnum, *orgnum,
*p; *p;
NUM_TOCHAR_prepare; NUM_TOCHAR_prepare;
...@@ -4233,7 +4336,7 @@ float4_to_char(PG_FUNCTION_ARGS) ...@@ -4233,7 +4336,7 @@ float4_to_char(PG_FUNCTION_ARGS)
if (IS_MULTI(&Num)) if (IS_MULTI(&Num))
{ {
float multi = pow((double) 10, (double) Num.multi); float multi = pow((double) 10, (double) Num.multi);
val = value * multi; val = value * multi;
Num.pre += Num.multi; Num.pre += Num.multi;
...@@ -4286,19 +4389,19 @@ float4_to_char(PG_FUNCTION_ARGS) ...@@ -4286,19 +4389,19 @@ float4_to_char(PG_FUNCTION_ARGS)
Datum Datum
float8_to_char(PG_FUNCTION_ARGS) float8_to_char(PG_FUNCTION_ARGS)
{ {
float8 value = PG_GETARG_FLOAT8(0); float8 value = PG_GETARG_FLOAT8(0);
text *fmt = PG_GETARG_TEXT_P(1); text *fmt = PG_GETARG_TEXT_P(1);
NUMDesc Num; NUMDesc Num;
FormatNode *format; FormatNode *format;
text *result, text *result,
*result_tmp; *result_tmp;
int flag = 0; int flag = 0;
int len = 0, int len = 0,
plen = 0, plen = 0,
sign = 0; sign = 0;
char *numstr, char *numstr,
*orgnum, *orgnum,
*p; *p;
NUM_TOCHAR_prepare; NUM_TOCHAR_prepare;
...@@ -4313,7 +4416,7 @@ float8_to_char(PG_FUNCTION_ARGS) ...@@ -4313,7 +4416,7 @@ float8_to_char(PG_FUNCTION_ARGS)
if (IS_MULTI(&Num)) if (IS_MULTI(&Num))
{ {
double multi = pow((double) 10, (double) Num.multi); double multi = pow((double) 10, (double) Num.multi);
val = value * multi; val = value * multi;
Num.pre += Num.multi; Num.pre += Num.multi;
......
...@@ -1023,7 +1023,7 @@ SELECT '' AS to_char_3, to_char(d1, 'Y,YYY YYYY YYY YY Y CC Q MM WW DDD DD D J') ...@@ -1023,7 +1023,7 @@ SELECT '' AS to_char_3, to_char(d1, 'Y,YYY YYYY YYY YY Y CC Q MM WW DDD DD D J')
| |
| |
| |
| 1,970 1970 970 70 0 20 1 01 00 001 01 5 2440588 | 1,970 1970 970 70 0 20 1 01 01 001 01 5 2440588
| 1,997 1997 997 97 7 20 1 02 06 041 10 2 2450490 | 1,997 1997 997 97 7 20 1 02 06 041 10 2 2450490
| |
| |
...@@ -1032,8 +1032,8 @@ SELECT '' AS to_char_3, to_char(d1, 'Y,YYY YYYY YYY YY Y CC Q MM WW DDD DD D J') ...@@ -1032,8 +1032,8 @@ SELECT '' AS to_char_3, to_char(d1, 'Y,YYY YYYY YYY YY Y CC Q MM WW DDD DD D J')
| 1,997 1997 997 97 7 20 1 02 06 041 10 2 2450490 | 1,997 1997 997 97 7 20 1 02 06 041 10 2 2450490
| 1,997 1997 997 97 7 20 1 02 06 041 10 2 2450490 | 1,997 1997 997 97 7 20 1 02 06 041 10 2 2450490
| 1,997 1997 997 97 7 20 1 02 06 041 10 2 2450490 | 1,997 1997 997 97 7 20 1 02 06 041 10 2 2450490
| 1,997 1997 997 97 7 20 1 01 00 002 02 5 2450451 | 1,997 1997 997 97 7 20 1 01 01 002 02 5 2450451
| 1,997 1997 997 97 7 20 1 01 00 002 02 5 2450451 | 1,997 1997 997 97 7 20 1 01 01 002 02 5 2450451
| 1,997 1997 997 97 7 20 1 02 06 041 10 2 2450490 | 1,997 1997 997 97 7 20 1 02 06 041 10 2 2450490
| 1,997 1997 997 97 7 20 1 02 06 041 10 2 2450490 | 1,997 1997 997 97 7 20 1 02 06 041 10 2 2450490
| 1,997 1997 997 97 7 20 1 02 06 041 10 2 2450490 | 1,997 1997 997 97 7 20 1 02 06 041 10 2 2450490
...@@ -1058,32 +1058,32 @@ SELECT '' AS to_char_3, to_char(d1, 'Y,YYY YYYY YYY YY Y CC Q MM WW DDD DD D J') ...@@ -1058,32 +1058,32 @@ SELECT '' AS to_char_3, to_char(d1, 'Y,YYY YYYY YYY YY Y CC Q MM WW DDD DD D J')
| 1,997 1997 997 97 7 20 2 06 23 161 10 3 2450610 | 1,997 1997 997 97 7 20 2 06 23 161 10 3 2450610
| 1,997 1997 997 97 7 20 1 02 06 041 10 2 2450490 | 1,997 1997 997 97 7 20 1 02 06 041 10 2 2450490
| 1,997 1997 997 97 7 20 1 02 06 042 11 3 2450491 | 1,997 1997 997 97 7 20 1 02 06 042 11 3 2450491
| 1,997 1997 997 97 7 20 1 02 06 043 12 4 2450492 | 1,997 1997 997 97 7 20 1 02 07 043 12 4 2450492
| 1,997 1997 997 97 7 20 1 02 06 044 13 5 2450493 | 1,997 1997 997 97 7 20 1 02 07 044 13 5 2450493
| 1,997 1997 997 97 7 20 1 02 06 045 14 6 2450494 | 1,997 1997 997 97 7 20 1 02 07 045 14 6 2450494
| 1,997 1997 997 97 7 20 1 02 06 046 15 7 2450495 | 1,997 1997 997 97 7 20 1 02 07 046 15 7 2450495
| 1,997 1997 997 97 7 20 1 02 07 047 16 1 2450496 | 1,997 1997 997 97 7 20 1 02 07 047 16 1 2450496
| 0,097 0097 097 97 7 01 1 02 07 047 16 3 1686042 | 0,097 0097 097 97 7 01 1 02 07 047 16 3 1686042
| 0,097 0097 097 97 7 01 1 02 06 047 16 7 1756536 | 0,097 0097 097 97 7 01 1 02 07 047 16 7 1756536
| 0,597 0597 597 97 7 06 1 02 07 047 16 5 1939157 | 0,597 0597 597 97 7 06 1 02 07 047 16 5 1939157
| 1,097 1097 097 97 7 11 1 02 07 047 16 3 2121778 | 1,097 1097 097 97 7 11 1 02 07 047 16 3 2121778
| 1,697 1697 697 97 7 17 1 02 06 047 16 7 2340924 | 1,697 1697 697 97 7 17 1 02 07 047 16 7 2340924
| 1,797 1797 797 97 7 18 1 02 07 047 16 5 2377448 | 1,797 1797 797 97 7 18 1 02 07 047 16 5 2377448
| 1,897 1897 897 97 7 19 1 02 07 047 16 3 2413972 | 1,897 1897 897 97 7 19 1 02 07 047 16 3 2413972
| 1,997 1997 997 97 7 20 1 02 07 047 16 1 2450496 | 1,997 1997 997 97 7 20 1 02 07 047 16 1 2450496
| 2,097 2097 097 97 7 21 1 02 06 047 16 7 2487021 | 2,097 2097 097 97 7 21 1 02 07 047 16 7 2487021
| 1,996 1996 996 96 6 20 1 02 09 059 28 4 2450142 | 1,996 1996 996 96 6 20 1 02 09 059 28 4 2450142
| 1,996 1996 996 96 6 20 1 02 09 060 29 5 2450143 | 1,996 1996 996 96 6 20 1 02 09 060 29 5 2450143
| 1,996 1996 996 96 6 20 1 03 09 061 01 6 2450144 | 1,996 1996 996 96 6 20 1 03 09 061 01 6 2450144
| 1,996 1996 996 96 6 20 4 12 53 365 30 2 2450448 | 1,996 1996 996 96 6 20 4 12 53 365 30 2 2450448
| 1,996 1996 996 96 6 20 4 12 53 366 31 3 2450449 | 1,996 1996 996 96 6 20 4 12 53 366 31 3 2450449
| 1,997 1997 997 97 7 20 1 01 00 001 01 4 2450450 | 1,997 1997 997 97 7 20 1 01 01 001 01 4 2450450
| 1,997 1997 997 97 7 20 1 02 08 059 28 6 2450508 | 1,997 1997 997 97 7 20 1 02 09 059 28 6 2450508
| 1,997 1997 997 97 7 20 1 03 08 060 01 7 2450509 | 1,997 1997 997 97 7 20 1 03 09 060 01 7 2450509
| 1,997 1997 997 97 7 20 4 12 52 364 30 3 2450813 | 1,997 1997 997 97 7 20 4 12 52 364 30 3 2450813
| 1,997 1997 997 97 7 20 4 12 52 365 31 4 2450814 | 1,997 1997 997 97 7 20 4 12 53 365 31 4 2450814
| 1,999 1999 999 99 9 20 4 12 52 365 31 6 2451544 | 1,999 1999 999 99 9 20 4 12 53 365 31 6 2451544
| 2,000 2000 000 00 0 21 1 01 00 001 01 7 2451545 | 2,000 2000 000 00 0 21 1 01 01 001 01 7 2451545
| 2,000 2000 000 00 0 21 4 12 53 366 31 1 2451910 | 2,000 2000 000 00 0 21 4 12 53 366 31 1 2451910
| 2,001 2001 001 01 1 21 1 01 01 001 01 2 2451911 | 2,001 2001 001 01 1 21 1 01 01 001 01 2 2451911
(66 rows) (66 rows)
...@@ -1096,7 +1096,7 @@ SELECT '' AS to_char_4, to_char(d1, 'FMY,YYY FMYYYY FMYYY FMYY FMY FMCC FMQ FMMM ...@@ -1096,7 +1096,7 @@ SELECT '' AS to_char_4, to_char(d1, 'FMY,YYY FMYYYY FMYYY FMYY FMY FMCC FMQ FMMM
| |
| |
| |
| 1,970 1970 970 70 0 20 1 1 0 1 1 5 2440588 | 1,970 1970 970 70 0 20 1 1 1 1 1 5 2440588
| 1,997 1997 997 97 7 20 1 2 6 41 10 2 2450490 | 1,997 1997 997 97 7 20 1 2 6 41 10 2 2450490
| |
| |
...@@ -1105,8 +1105,8 @@ SELECT '' AS to_char_4, to_char(d1, 'FMY,YYY FMYYYY FMYYY FMYY FMY FMCC FMQ FMMM ...@@ -1105,8 +1105,8 @@ SELECT '' AS to_char_4, to_char(d1, 'FMY,YYY FMYYYY FMYYY FMYY FMY FMCC FMQ FMMM
| 1,997 1997 997 97 7 20 1 2 6 41 10 2 2450490 | 1,997 1997 997 97 7 20 1 2 6 41 10 2 2450490
| 1,997 1997 997 97 7 20 1 2 6 41 10 2 2450490 | 1,997 1997 997 97 7 20 1 2 6 41 10 2 2450490
| 1,997 1997 997 97 7 20 1 2 6 41 10 2 2450490 | 1,997 1997 997 97 7 20 1 2 6 41 10 2 2450490
| 1,997 1997 997 97 7 20 1 1 0 2 2 5 2450451 | 1,997 1997 997 97 7 20 1 1 1 2 2 5 2450451
| 1,997 1997 997 97 7 20 1 1 0 2 2 5 2450451 | 1,997 1997 997 97 7 20 1 1 1 2 2 5 2450451
| 1,997 1997 997 97 7 20 1 2 6 41 10 2 2450490 | 1,997 1997 997 97 7 20 1 2 6 41 10 2 2450490
| 1,997 1997 997 97 7 20 1 2 6 41 10 2 2450490 | 1,997 1997 997 97 7 20 1 2 6 41 10 2 2450490
| 1,997 1997 997 97 7 20 1 2 6 41 10 2 2450490 | 1,997 1997 997 97 7 20 1 2 6 41 10 2 2450490
...@@ -1131,32 +1131,32 @@ SELECT '' AS to_char_4, to_char(d1, 'FMY,YYY FMYYYY FMYYY FMYY FMY FMCC FMQ FMMM ...@@ -1131,32 +1131,32 @@ SELECT '' AS to_char_4, to_char(d1, 'FMY,YYY FMYYYY FMYYY FMYY FMY FMCC FMQ FMMM
| 1,997 1997 997 97 7 20 2 6 23 161 10 3 2450610 | 1,997 1997 997 97 7 20 2 6 23 161 10 3 2450610
| 1,997 1997 997 97 7 20 1 2 6 41 10 2 2450490 | 1,997 1997 997 97 7 20 1 2 6 41 10 2 2450490
| 1,997 1997 997 97 7 20 1 2 6 42 11 3 2450491 | 1,997 1997 997 97 7 20 1 2 6 42 11 3 2450491
| 1,997 1997 997 97 7 20 1 2 6 43 12 4 2450492 | 1,997 1997 997 97 7 20 1 2 7 43 12 4 2450492
| 1,997 1997 997 97 7 20 1 2 6 44 13 5 2450493 | 1,997 1997 997 97 7 20 1 2 7 44 13 5 2450493
| 1,997 1997 997 97 7 20 1 2 6 45 14 6 2450494 | 1,997 1997 997 97 7 20 1 2 7 45 14 6 2450494
| 1,997 1997 997 97 7 20 1 2 6 46 15 7 2450495 | 1,997 1997 997 97 7 20 1 2 7 46 15 7 2450495
| 1,997 1997 997 97 7 20 1 2 7 47 16 1 2450496 | 1,997 1997 997 97 7 20 1 2 7 47 16 1 2450496
| 0,097 97 097 97 7 1 1 2 7 47 16 3 1686042 | 0,097 97 097 97 7 1 1 2 7 47 16 3 1686042
| 0,097 97 097 97 7 1 1 2 6 47 16 7 1756536 | 0,097 97 097 97 7 1 1 2 7 47 16 7 1756536
| 0,597 597 597 97 7 6 1 2 7 47 16 5 1939157 | 0,597 597 597 97 7 6 1 2 7 47 16 5 1939157
| 1,097 1097 097 97 7 11 1 2 7 47 16 3 2121778 | 1,097 1097 097 97 7 11 1 2 7 47 16 3 2121778
| 1,697 1697 697 97 7 17 1 2 6 47 16 7 2340924 | 1,697 1697 697 97 7 17 1 2 7 47 16 7 2340924
| 1,797 1797 797 97 7 18 1 2 7 47 16 5 2377448 | 1,797 1797 797 97 7 18 1 2 7 47 16 5 2377448
| 1,897 1897 897 97 7 19 1 2 7 47 16 3 2413972 | 1,897 1897 897 97 7 19 1 2 7 47 16 3 2413972
| 1,997 1997 997 97 7 20 1 2 7 47 16 1 2450496 | 1,997 1997 997 97 7 20 1 2 7 47 16 1 2450496
| 2,097 2097 097 97 7 21 1 2 6 47 16 7 2487021 | 2,097 2097 097 97 7 21 1 2 7 47 16 7 2487021
| 1,996 1996 996 96 6 20 1 2 9 59 28 4 2450142 | 1,996 1996 996 96 6 20 1 2 9 59 28 4 2450142
| 1,996 1996 996 96 6 20 1 2 9 60 29 5 2450143 | 1,996 1996 996 96 6 20 1 2 9 60 29 5 2450143
| 1,996 1996 996 96 6 20 1 3 9 61 1 6 2450144 | 1,996 1996 996 96 6 20 1 3 9 61 1 6 2450144
| 1,996 1996 996 96 6 20 4 12 53 365 30 2 2450448 | 1,996 1996 996 96 6 20 4 12 53 365 30 2 2450448
| 1,996 1996 996 96 6 20 4 12 53 366 31 3 2450449 | 1,996 1996 996 96 6 20 4 12 53 366 31 3 2450449
| 1,997 1997 997 97 7 20 1 1 0 1 1 4 2450450 | 1,997 1997 997 97 7 20 1 1 1 1 1 4 2450450
| 1,997 1997 997 97 7 20 1 2 8 59 28 6 2450508 | 1,997 1997 997 97 7 20 1 2 9 59 28 6 2450508
| 1,997 1997 997 97 7 20 1 3 8 60 1 7 2450509 | 1,997 1997 997 97 7 20 1 3 9 60 1 7 2450509
| 1,997 1997 997 97 7 20 4 12 52 364 30 3 2450813 | 1,997 1997 997 97 7 20 4 12 52 364 30 3 2450813
| 1,997 1997 997 97 7 20 4 12 52 365 31 4 2450814 | 1,997 1997 997 97 7 20 4 12 53 365 31 4 2450814
| 1,999 1999 999 99 9 20 4 12 52 365 31 6 2451544 | 1,999 1999 999 99 9 20 4 12 53 365 31 6 2451544
| 2,000 2000 000 00 0 21 1 1 0 1 1 7 2451545 | 2,000 2000 000 00 0 21 1 1 1 1 1 7 2451545
| 2,000 2000 000 00 0 21 4 12 53 366 31 1 2451910 | 2,000 2000 000 00 0 21 4 12 53 366 31 1 2451910
| 2,001 2001 001 01 1 21 1 1 1 1 1 2 2451911 | 2,001 2001 001 01 1 21 1 1 1 1 1 2 2451911
(66 rows) (66 rows)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment