Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita17f2d7

Browse files
committed
Refactor code so that to_date() does not call to_timestamp() and then
perform a timestamp-to-date coercion. Instead both routines share asubroutine that delivers the parsing result as a struct tm. This avoidsproblems with timezone dependency of to_date's result, and should beat least marginally faster too.
1 parent4b02f3c commita17f2d7

File tree

1 file changed

+98
-76
lines changed

1 file changed

+98
-76
lines changed

‎src/backend/utils/adt/formatting.c

Lines changed: 98 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* -----------------------------------------------------------------------
22
* formatting.c
33
*
4-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.66 2003/08/04 23:59:38 tgl Exp $
4+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.67 2003/08/25 16:13:27 tgl Exp $
55
*
66
*
77
* Portions Copyright (c) 1999-2003, PostgreSQL Global Development Group
@@ -880,6 +880,8 @@ static intseq_search(char *name, char **array, int type, int max, int *len);
880880
staticintdch_global(intarg,char*inout,intsuf,intflag,FormatNode*node,void*data);
881881
staticintdch_time(intarg,char*inout,intsuf,intflag,FormatNode*node,void*data);
882882
staticintdch_date(intarg,char*inout,intsuf,intflag,FormatNode*node,void*data);
883+
staticvoiddo_to_timestamp(text*date_txt,text*fmt,
884+
structtm*tm,fsec_t*fsec);
883885
staticchar*fill_str(char*str,intc,intmax);
884886
staticFormatNode*NUM_cache(intlen,NUMDesc*Num,char*pars_str,bool*shouldFree);
885887
staticchar*int_to_roman(intnumber);
@@ -2901,21 +2903,65 @@ to_timestamp(PG_FUNCTION_ARGS)
29012903
{
29022904
text*date_txt=PG_GETARG_TEXT_P(0);
29032905
text*fmt=PG_GETARG_TEXT_P(1);
2904-
29052906
Timestampresult;
2907+
inttz;
2908+
structtmtm;
2909+
fsec_tfsec;
2910+
2911+
do_to_timestamp(date_txt,fmt,&tm,&fsec);
2912+
2913+
tz=DetermineLocalTimeZone(&tm);
2914+
2915+
if (tm2timestamp(&tm,fsec,&tz,&result)!=0)
2916+
ereport(ERROR,
2917+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2918+
errmsg("timestamp out of range")));
2919+
2920+
PG_RETURN_TIMESTAMP(result);
2921+
}
2922+
2923+
/* ----------
2924+
* TO_DATE
2925+
*Make Date from date_str which is formated at argument 'fmt'
2926+
* ----------
2927+
*/
2928+
Datum
2929+
to_date(PG_FUNCTION_ARGS)
2930+
{
2931+
text*date_txt=PG_GETARG_TEXT_P(0);
2932+
text*fmt=PG_GETARG_TEXT_P(1);
2933+
DateADTresult;
2934+
structtmtm;
2935+
fsec_tfsec;
2936+
2937+
do_to_timestamp(date_txt,fmt,&tm,&fsec);
2938+
2939+
result=date2j(tm.tm_year,tm.tm_mon,tm.tm_mday)-POSTGRES_EPOCH_JDATE;
2940+
2941+
PG_RETURN_DATEADT(result);
2942+
}
2943+
2944+
/*
2945+
* do_to_timestamp: shared code for to_timestamp and to_date
2946+
*
2947+
* Parse the 'date_txt' according to 'fmt', return results as a struct tm
2948+
* and fractional seconds.
2949+
*/
2950+
staticvoid
2951+
do_to_timestamp(text*date_txt,text*fmt,
2952+
structtm*tm,fsec_t*fsec)
2953+
{
29062954
FormatNode*format;
29072955
TmFromChartmfc;
2908-
29092956
boolincache;
29102957
char*str;
29112958
char*date_str;
29122959
intlen,
2913-
date_len,
2914-
tz=0;
2915-
structtmtm;
2916-
fsec_tfsec=0;
2960+
date_len;
2961+
2962+
ZERO_tm(tm);
2963+
*fsec=0;
29172964

2918-
ZERO_tm(&tm);
29192965
ZERO_tmfc(&tmfc);
29202966

29212967
len=VARSIZE(fmt)-VARHDRSZ;
@@ -3004,15 +3050,15 @@ to_timestamp(PG_FUNCTION_ARGS)
30043050
{
30053051
intx=tmfc.ssss;
30063052

3007-
tm.tm_hour=x /3600;
3053+
tm->tm_hour=x /3600;
30083054
x %=3600;
3009-
tm.tm_min=x /60;
3055+
tm->tm_min=x /60;
30103056
x %=60;
3011-
tm.tm_sec=x;
3057+
tm->tm_sec=x;
30123058
}
30133059

30143060
if (tmfc.cc)
3015-
tm.tm_year= (tmfc.cc-1)*100;
3061+
tm->tm_year= (tmfc.cc-1)*100;
30163062

30173063
if (tmfc.ww)
30183064
tmfc.ddd= (tmfc.ww-1)*7+1;
@@ -3021,79 +3067,79 @@ to_timestamp(PG_FUNCTION_ARGS)
30213067
tmfc.dd= (tmfc.w-1)*7+1;
30223068

30233069
if (tmfc.ss)
3024-
tm.tm_sec=tmfc.ss;
3070+
tm->tm_sec=tmfc.ss;
30253071
if (tmfc.mi)
3026-
tm.tm_min=tmfc.mi;
3072+
tm->tm_min=tmfc.mi;
30273073
if (tmfc.hh)
3028-
tm.tm_hour=tmfc.hh;
3074+
tm->tm_hour=tmfc.hh;
30293075

30303076
if (tmfc.pm||tmfc.am)
30313077
{
3032-
if (tm.tm_hour<1||tm.tm_hour>12)
3078+
if (tm->tm_hour<1||tm->tm_hour>12)
30333079
ereport(ERROR,
30343080
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
30353081
errmsg("AM/PM hour must be between 1 and 12")));
30363082

3037-
if (tmfc.pm&&tm.tm_hour<12)
3038-
tm.tm_hour+=12;
3083+
if (tmfc.pm&&tm->tm_hour<12)
3084+
tm->tm_hour+=12;
30393085

3040-
elseif (tmfc.am&&tm.tm_hour==12)
3041-
tm.tm_hour=0;
3086+
elseif (tmfc.am&&tm->tm_hour==12)
3087+
tm->tm_hour=0;
30423088
}
30433089

30443090
switch (tmfc.q)
30453091
{
30463092
case1:
3047-
tm.tm_mday=1;
3048-
tm.tm_mon=1;
3093+
tm->tm_mday=1;
3094+
tm->tm_mon=1;
30493095
break;
30503096
case2:
3051-
tm.tm_mday=1;
3052-
tm.tm_mon=4;
3097+
tm->tm_mday=1;
3098+
tm->tm_mon=4;
30533099
break;
30543100
case3:
3055-
tm.tm_mday=1;
3056-
tm.tm_mon=7;
3101+
tm->tm_mday=1;
3102+
tm->tm_mon=7;
30573103
break;
30583104
case4:
3059-
tm.tm_mday=1;
3060-
tm.tm_mon=10;
3105+
tm->tm_mday=1;
3106+
tm->tm_mon=10;
30613107
break;
30623108
}
30633109

30643110
if (tmfc.year)
3065-
tm.tm_year=tmfc.year;
3111+
tm->tm_year=tmfc.year;
30663112

30673113
if (tmfc.bc)
30683114
{
3069-
if (tm.tm_year>0)
3070-
tm.tm_year=-(tm.tm_year-1);
3115+
if (tm->tm_year>0)
3116+
tm->tm_year=-(tm->tm_year-1);
30713117
else
30723118
ereport(ERROR,
30733119
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
30743120
errmsg("inconsistent use of year %04d and \"BC\"",
3075-
tm.tm_year)));
3121+
tm->tm_year)));
30763122
}
30773123

30783124
if (tmfc.j)
3079-
j2date(tmfc.j,&tm.tm_year,&tm.tm_mon,&tm.tm_mday);
3125+
j2date(tmfc.j,&tm->tm_year,&tm->tm_mon,&tm->tm_mday);
30803126

30813127
if (tmfc.iw)
3082-
isoweek2date(tmfc.iw,&tm.tm_year,&tm.tm_mon,&tm.tm_mday);
3128+
isoweek2date(tmfc.iw,&tm->tm_year,&tm->tm_mon,&tm->tm_mday);
30833129

30843130
if (tmfc.d)
3085-
tm.tm_wday=tmfc.d;
3131+
tm->tm_wday=tmfc.d;
30863132
if (tmfc.dd)
3087-
tm.tm_mday=tmfc.dd;
3133+
tm->tm_mday=tmfc.dd;
30883134
if (tmfc.ddd)
3089-
tm.tm_yday=tmfc.ddd;
3135+
tm->tm_yday=tmfc.ddd;
30903136
if (tmfc.mm)
3091-
tm.tm_mon=tmfc.mm;
3137+
tm->tm_mon=tmfc.mm;
30923138

30933139
/*
30943140
* we don't ignore DDD
30953141
*/
3096-
if (tmfc.ddd&& (tm.tm_mon <=1||tm.tm_mday <=1))
3142+
if (tmfc.ddd&& (tm->tm_mon <=1||tm->tm_mday <=1))
30973143
{
30983144
/* count mday and mon from yday */
30993145
int*y,
@@ -3103,65 +3149,41 @@ to_timestamp(PG_FUNCTION_ARGS)
31033149
{31,59,90,120,151,181,212,243,273,304,334,365,0},
31043150
{31,60,91,121,152,182,213,244,274,305,335,366,0}};
31053151

3106-
if (!tm.tm_year)
3152+
if (!tm->tm_year)
31073153
ereport(ERROR,
31083154
(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
31093155
errmsg("cannot convert yday without year information")));
31103156

3111-
y=ysum[isleap(tm.tm_year)];
3157+
y=ysum[isleap(tm->tm_year)];
31123158

31133159
for (i=0;i <=11;i++)
31143160
{
3115-
if (tm.tm_yday<y[i])
3161+
if (tm->tm_yday<y[i])
31163162
break;
31173163
}
3118-
if (tm.tm_mon <=1)
3119-
tm.tm_mon=i+1;
3164+
if (tm->tm_mon <=1)
3165+
tm->tm_mon=i+1;
31203166

3121-
if (tm.tm_mday <=1)
3122-
tm.tm_mday=i==0 ?tm.tm_yday :
3123-
tm.tm_yday-y[i-1];
3167+
if (tm->tm_mday <=1)
3168+
tm->tm_mday=i==0 ?tm->tm_yday :
3169+
tm->tm_yday-y[i-1];
31243170
}
31253171

31263172
#ifdefHAVE_INT64_TIMESTAMP
31273173
if (tmfc.ms)
3128-
fsec+=tmfc.ms*1000;
3174+
*fsec+=tmfc.ms*1000;
31293175
if (tmfc.us)
3130-
fsec+=tmfc.us;
3176+
*fsec+=tmfc.us;
31313177
#else
31323178
if (tmfc.ms)
3133-
fsec+= (double)tmfc.ms /1000;
3179+
*fsec+= (double)tmfc.ms /1000;
31343180
if (tmfc.us)
3135-
fsec+= (double)tmfc.us /1000000;
3181+
*fsec+= (double)tmfc.us /1000000;
31363182
#endif
31373183

3138-
/* -------------------------------------------------------------- */
3139-
3140-
DEBUG_TM(&tm);
3141-
tz=DetermineLocalTimeZone(&tm);
3142-
3143-
if (tm2timestamp(&tm,fsec,&tz,&result)!=0)
3144-
ereport(ERROR,
3145-
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3146-
errmsg("timestamp out of range")));
3147-
3148-
PG_RETURN_TIMESTAMP(result);
3184+
DEBUG_TM(tm);
31493185
}
31503186

3151-
/* ----------
3152-
* TO_DATE
3153-
*Make Date from date_str which is formated at argument 'fmt'
3154-
* ----------
3155-
*/
3156-
Datum
3157-
to_date(PG_FUNCTION_ARGS)
3158-
{
3159-
/*
3160-
* Quick hack: since our inputs are just like to_timestamp, hand over
3161-
* the whole input info struct...
3162-
*/
3163-
returnDirectFunctionCall1(timestamptz_date,to_timestamp(fcinfo));
3164-
}
31653187

31663188
/**********************************************************************
31673189
*the NUMBER version part

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp