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

Commit547df0c

Browse files
author
Thomas G. Lockhart
committed
Support alternate storage scheme of 64-bit integer for date/time types.
Use "--enable-integer-datetimes" in configuration to use this rather than the original float8 storage. I would recommend the integer-based storage for any platform on which it is available. We perhaps should make this the default for the production release.Change timezone(timestamptz) results to return timestamp rather than a character string. Formerly, we didn't have a way to represent timestamps with an explicit time zone other than freezing the info into a string. Now, we can reasonably omit the explicit time zone from the result and return a timestamp with values appropriate for the specified time zone. Much cleaner, and if you need the time zone in the result you can put it into a character string pretty easily anyway.Allow fractional seconds in date/time types even for dates prior to 1BC.Limit timestamp data types to 6 decimal places of precision. Just right for a micro-second storage of int8 date/time types, and reduces the number of places ad-hoc rounding was occuring for the float8-based types.Use lookup tables for precision/rounding calculations for timestamp and interval types. Formerly used pow() to calculate the desired value but with a more limited range there is no reason to not type in a lookup table. Should be *much* better performance, though formerly there were some optimizations to help minimize the number of times pow() was called.Define a HAVE_INT64_TIMESTAMP variable. Based on the configure option "--enable-integer-datetimes" and the existing internal INT64_IS_BUSTED.Add explicit date/interval operators and functions for addition and subtraction. Formerly relied on implicit type promotion from date to timestamp with time zone.Change timezone conversion functions for the timetz type from "timetz()" to "timezone()". This is consistant with other time zone coersion functions for other types.Bump the catalog version to 200204201.Fix up regression tests to reflect changes in fractional seconds representation for date/times in BC eras.All regression tests pass on my Linux box.
1 parent3fab493 commit547df0c

File tree

21 files changed

+1653
-550
lines changed

21 files changed

+1653
-550
lines changed

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

Lines changed: 457 additions & 53 deletions
Large diffs are not rendered by default.

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

Lines changed: 371 additions & 185 deletions
Large diffs are not rendered by default.

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

Lines changed: 18 additions & 3 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.52 2002/04/03 05:39:29 petere Exp $
4+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.53 2002/04/21 19:48:12 thomas Exp $
55
*
66
*
77
* Portions Copyright (c) 1999-2000, PostgreSQL Global Development Group
@@ -410,7 +410,7 @@ typedef struct
410410
typedefstructTmToChar
411411
{
412412
structtmtm;/* classic 'tm' struct */
413-
doublefsec;/*milliseconds */
413+
fsec_tfsec;/*fractional seconds */
414414
char*tzn;/* timezone */
415415
}TmToChar;
416416

@@ -1831,7 +1831,11 @@ dch_time(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
18311831
caseDCH_MS:/* millisecond */
18321832
if (flag==TO_CHAR)
18331833
{
1834+
#ifdefHAVE_INT64_TIMESTAMP
1835+
sprintf(inout,"%03d", (int) (tmtc->fsec /INT64CONST(1000)));
1836+
#else
18341837
sprintf(inout,"%03d", (int)rint(tmtc->fsec*1000));
1838+
#endif
18351839
if (S_THth(suf))
18361840
str_numth(p_inout,inout,S_TH_TYPE(suf));
18371841
if (S_THth(suf))
@@ -1874,7 +1878,11 @@ dch_time(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
18741878
caseDCH_US:/* microsecond */
18751879
if (flag==TO_CHAR)
18761880
{
1881+
#ifdefHAVE_INT64_TIMESTAMP
1882+
sprintf(inout,"%06d", (int)tmtc->fsec);
1883+
#else
18771884
sprintf(inout,"%06d", (int)rint(tmtc->fsec*1000000));
1885+
#endif
18781886
if (S_THth(suf))
18791887
str_numth(p_inout,inout,S_TH_TYPE(suf));
18801888
if (S_THth(suf))
@@ -2868,7 +2876,7 @@ to_timestamp(PG_FUNCTION_ARGS)
28682876
date_len,
28692877
tz=0;
28702878
structtmtm;
2871-
doublefsec=0;
2879+
fsec_tfsec=0;
28722880

28732881
ZERO_tm(&tm);
28742882
ZERO_tmfc(&tmfc);
@@ -3071,10 +3079,17 @@ to_timestamp(PG_FUNCTION_ARGS)
30713079
tm.tm_yday-y[i-1];
30723080
}
30733081

3082+
#ifdefHAVE_INT64_TIMESTAMP
3083+
if (tmfc.ms)
3084+
fsec+=tmfc.ms*1000;
3085+
if (tmfc.us)
3086+
fsec+=tmfc.us;
3087+
#else
30743088
if (tmfc.ms)
30753089
fsec+= (double)tmfc.ms /1000;
30763090
if (tmfc.us)
30773091
fsec+= (double)tmfc.us /1000000;
3092+
#endif
30783093

30793094
/* -------------------------------------------------------------- */
30803095

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/int8.c,v 1.37 2002/02/23 01:01:30 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/int8.c,v 1.38 2002/04/21 19:48:12 thomas Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -23,6 +23,7 @@
2323

2424
/* this should be set in pg_config.h, but just in case it wasn't: */
2525
#ifndefINT64_FORMAT
26+
#warning "Broken pg_config.h should have defined INT64_FORMAT"
2627
#defineINT64_FORMAT "%ld"
2728
#endif
2829

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

Lines changed: 49 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.92 2002/03/06 06:10:13 momjian Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.93 2002/04/21 19:48:12 thomas Exp $
1313
*
1414
* NOTES
1515
*
@@ -76,34 +76,13 @@
7676
AbsoluteTimeGetDatum(t1), \
7777
AbsoluteTimeGetDatum(t2))) ? (t2) : (t1))
7878

79-
#ifdefNOT_USED
80-
staticchar*unit_tab[]= {
81-
"second","seconds","minute","minutes",
82-
"hour","hours","day","days","week","weeks",
83-
"month","months","year","years"};
84-
85-
#defineUNITMAXLEN 7/* max length of a unit name */
86-
#defineNUNITS 14/* number of different units */
87-
88-
/* table of seconds per unit (month = 30 days, year = 365 days) */
89-
staticintsec_tab[]= {
90-
1,1,60,60,
91-
3600,3600,86400,86400,604800,604800,
92-
2592000,2592000,31536000,31536000};
93-
#endif
9479

9580
/*
9681
* Function prototypes -- internal to this file only
9782
*/
9883

9984
staticAbsoluteTimetm2abstime(structtm*tm,inttz);
10085
staticvoidreltime2tm(RelativeTimetime,structtm*tm);
101-
102-
#ifdefNOT_USED
103-
staticintcorrect_unit(char*unit,int*unptr);
104-
staticintcorrect_dir(char*direction,int*signptr);
105-
#endif
106-
10786
staticintistinterval(char*i_string,
10887
AbsoluteTime*i_start,
10988
AbsoluteTime*i_end);
@@ -177,7 +156,7 @@ GetCurrentAbsoluteTime(void)
177156
}/* GetCurrentAbsoluteTime() */
178157

179158

180-
/*GetCurrentAbsoluteTime()
159+
/*GetCurrentAbsoluteTimeUsec()
181160
* Get the current system time. Set timezone parameters if not specified elsewhere.
182161
* Define HasCTZSet to allow clients to specify the default timezone.
183162
*
@@ -271,13 +250,17 @@ GetCurrentTime(struct tm * tm)
271250

272251

273252
void
274-
GetCurrentTimeUsec(structtm*tm,double*fsec)
253+
GetCurrentTimeUsec(structtm*tm,fsec_t*fsec)
275254
{
276255
inttz;
277256
intusec;
278257

279258
abstime2tm(GetCurrentTransactionStartTimeUsec(&usec),&tz,tm,NULL);
259+
#ifdefHAVE_INT64_TIMESTAMP
260+
*fsec=usec;
261+
#else
280262
*fsec=usec*1.0e-6;
263+
#endif
281264

282265
return;
283266
}/* GetCurrentTimeUsec() */
@@ -493,7 +476,7 @@ nabstimein(PG_FUNCTION_ARGS)
493476
{
494477
char*str=PG_GETARG_CSTRING(0);
495478
AbsoluteTimeresult;
496-
doublefsec;
479+
fsec_tfsec;
497480
inttz=0;
498481
structtmdate,
499482
*tm=&date;
@@ -713,7 +696,7 @@ timestamp_abstime(PG_FUNCTION_ARGS)
713696
{
714697
Timestamptimestamp=PG_GETARG_TIMESTAMP(0);
715698
AbsoluteTimeresult;
716-
doublefsec;
699+
fsec_tfsec;
717700
inttz;
718701
structtmtt,
719702
*tm=&tt;
@@ -767,7 +750,9 @@ abstime_timestamp(PG_FUNCTION_ARGS)
767750

768751
default:
769752
abstime2tm(abstime,&tz,tm,&tzn);
770-
result=abstime+ ((date2j(1970,1,1)-date2j(2000,1,1))*86400)+tz;
753+
if (tm2timestamp(tm,0,NULL,&result)!=0)
754+
elog(ERROR,"Unable convert ABSTIME to TIMESTAMP"
755+
"\n\tabstime_timestamp() internal error");
771756
break;
772757
};
773758

@@ -783,7 +768,7 @@ timestamptz_abstime(PG_FUNCTION_ARGS)
783768
{
784769
TimestampTztimestamp=PG_GETARG_TIMESTAMP(0);
785770
AbsoluteTimeresult;
786-
doublefsec;
771+
fsec_tfsec;
787772
structtmtt,
788773
*tm=&tt;
789774

@@ -810,6 +795,11 @@ abstime_timestamptz(PG_FUNCTION_ARGS)
810795
{
811796
AbsoluteTimeabstime=PG_GETARG_ABSOLUTETIME(0);
812797
TimestampTzresult;
798+
structtmtt,
799+
*tm=&tt;
800+
inttz;
801+
charzone[MAXDATELEN+1],
802+
*tzn=zone;
813803

814804
switch (abstime)
815805
{
@@ -827,7 +817,10 @@ abstime_timestamptz(PG_FUNCTION_ARGS)
827817
break;
828818

829819
default:
830-
result=abstime+ ((date2j(1970,1,1)-date2j(2000,1,1))*86400);
820+
abstime2tm(abstime,&tz,tm,&tzn);
821+
if (tm2timestamp(tm,0,&tz,&result)!=0)
822+
elog(ERROR,"Unable convert ABSTIME to TIMESTAMP WITH TIME ZONE"
823+
"\n\tabstime_timestamp() internal error");
831824
break;
832825
};
833826

@@ -849,7 +842,7 @@ reltimein(PG_FUNCTION_ARGS)
849842
RelativeTimeresult;
850843
structtmtt,
851844
*tm=&tt;
852-
doublefsec;
845+
fsec_tfsec;
853846
intdtype;
854847
char*field[MAXDATEFIELDS];
855848
intnf,
@@ -860,14 +853,14 @@ reltimein(PG_FUNCTION_ARGS)
860853
elog(ERROR,"Bad (length) reltime external representation '%s'",str);
861854

862855
if ((ParseDateTime(str,lowstr,field,ftype,MAXDATEFIELDS,&nf)!=0)
863-
|| (DecodeDateDelta(field,ftype,nf,&dtype,tm,&fsec)!=0))
856+
|| (DecodeInterval(field,ftype,nf,&dtype,tm,&fsec)!=0))
864857
elog(ERROR,"Bad reltime external representation '%s'",str);
865858

866859
switch (dtype)
867860
{
868861
caseDTK_DELTA:
869862
result= ((((tm->tm_hour*60)+tm->tm_min)*60)+tm->tm_sec);
870-
result+= (((tm->tm_year*365)+ (tm->tm_mon*30)+tm->tm_mday)*(24*60*60));
863+
result+= ((tm->tm_year*36525*864)+ (((tm->tm_mon*30)+tm->tm_mday)*86400));
871864
break;
872865

873866
default:
@@ -893,7 +886,7 @@ reltimeout(PG_FUNCTION_ARGS)
893886
charbuf[MAXDATELEN+1];
894887

895888
reltime2tm(time,tm);
896-
EncodeTimeSpan(tm,0,DateStyle,buf);
889+
EncodeInterval(tm,0,DateStyle,buf);
897890

898891
result=pstrdup(buf);
899892
PG_RETURN_CSTRING(result);
@@ -903,7 +896,7 @@ reltimeout(PG_FUNCTION_ARGS)
903896
staticvoid
904897
reltime2tm(RelativeTimetime,structtm*tm)
905898
{
906-
TMODULO(time,tm->tm_year,31536000);
899+
TMODULO(time,tm->tm_year,31557600);
907900
TMODULO(time,tm->tm_mon,2592000);
908901
TMODULO(time,tm->tm_mday,86400);
909902
TMODULO(time,tm->tm_hour,3600);
@@ -988,7 +981,11 @@ interval_reltime(PG_FUNCTION_ARGS)
988981
RelativeTimetime;
989982
intyear,
990983
month;
984+
#ifdefHAVE_INT64_TIMESTAMP
985+
int64span;
986+
#else
991987
doublespan;
988+
#endif
992989

993990
if (interval->month==0)
994991
{
@@ -1006,7 +1003,13 @@ interval_reltime(PG_FUNCTION_ARGS)
10061003
month=interval->month;
10071004
}
10081005

1009-
span= (((((double)365*year)+ ((double)30*month))*86400)+interval->time);
1006+
#ifdefHAVE_INT64_TIMESTAMP
1007+
span= ((((INT64CONST(365250000)*year)+ (INT64CONST(30000000)*month))
1008+
*INT64CONST(86400))+interval->time);
1009+
span /=INT64CONST(1000000);
1010+
#else
1011+
span= (((((double)365.25*year)+ ((double)30*month))*86400)+interval->time);
1012+
#endif
10101013

10111014
if ((span<INT_MIN)|| (span>INT_MAX))
10121015
time=INVALID_RELTIME;
@@ -1036,10 +1039,19 @@ reltime_interval(PG_FUNCTION_ARGS)
10361039
break;
10371040

10381041
default:
1039-
TMODULO(reltime,year,31536000);
1040-
TMODULO(reltime,month,2592000);
1042+
#ifdefHAVE_INT64_TIMESTAMP
1043+
year= (reltime / (36525*864));
1044+
reltime-= (year* (36525*864));
1045+
month= (reltime / (30*86400));
1046+
reltime-= (month* (30*86400));
1047+
1048+
result->time= (reltime*INT64CONST(1000000));
1049+
#else
1050+
TMODULO(reltime,year, (36525*864));
1051+
TMODULO(reltime,month, (30*86400));
10411052

10421053
result->time=reltime;
1054+
#endif
10431055
result->month= ((12*year)+month);
10441056
break;
10451057
}
@@ -1090,11 +1102,6 @@ timepl(PG_FUNCTION_ARGS)
10901102
AbsoluteTimet1=PG_GETARG_ABSOLUTETIME(0);
10911103
RelativeTimet2=PG_GETARG_RELATIVETIME(1);
10921104

1093-
#if0
1094-
if (t1==CURRENT_ABSTIME)
1095-
t1=GetCurrentTransactionStartTime();
1096-
#endif
1097-
10981105
if (AbsoluteTimeIsReal(t1)&&
10991106
RelativeTimeIsValid(t2)&&
11001107
((t2>0) ? (t1<NOEND_ABSTIME-t2)
@@ -1114,11 +1121,6 @@ timemi(PG_FUNCTION_ARGS)
11141121
AbsoluteTimet1=PG_GETARG_ABSOLUTETIME(0);
11151122
RelativeTimet2=PG_GETARG_RELATIVETIME(1);
11161123

1117-
#if0
1118-
if (t1==CURRENT_ABSTIME)
1119-
t1=GetCurrentTransactionStartTime();
1120-
#endif
1121-
11221124
if (AbsoluteTimeIsReal(t1)&&
11231125
RelativeTimeIsValid(t2)&&
11241126
((t2>0) ? (t1>NOSTART_ABSTIME+t2)

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

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*
1616
*
1717
* IDENTIFICATION
18-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.108 2002/04/16 23:08:11 tgl Exp $
18+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.109 2002/04/21 19:48:13 thomas Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -2427,17 +2427,30 @@ convert_timevalue_to_scalar(Datum value, Oid typid)
24272427
* assumed average month length of 365.25/12.0 days. Not
24282428
* too accurate, but plenty good enough for our purposes.
24292429
*/
2430+
#ifdefHAVE_INT64_TIMESTAMP
2431+
return (interval->time+ (interval->month* ((365.25 /12.0)*86400000000.0)));
2432+
#else
24302433
returninterval->time+
24312434
interval->month* (365.25 /12.0*24.0*60.0*60.0);
2435+
#endif
24322436
}
24332437
caseRELTIMEOID:
2438+
#ifdefHAVE_INT64_TIMESTAMP
2439+
return (DatumGetRelativeTime(value)*1000000.0);
2440+
#else
24342441
returnDatumGetRelativeTime(value);
2442+
#endif
24352443
caseTINTERVALOID:
24362444
{
24372445
TimeIntervalinterval=DatumGetTimeInterval(value);
24382446

2447+
#ifdefHAVE_INT64_TIMESTAMP
2448+
if (interval->status!=0)
2449+
return ((interval->data[1]-interval->data[0])*1000000.0);
2450+
#else
24392451
if (interval->status!=0)
24402452
returninterval->data[1]-interval->data[0];
2453+
#endif
24412454
return0;/* for lack of a better idea */
24422455
}
24432456
caseTIMEOID:
@@ -2447,7 +2460,11 @@ convert_timevalue_to_scalar(Datum value, Oid typid)
24472460
TimeTzADT*timetz=DatumGetTimeTzADTP(value);
24482461

24492462
/* use GMT-equivalent time */
2463+
#ifdefHAVE_INT64_TIMESTAMP
2464+
return (double) (timetz->time+ (timetz->zone*1000000.0));
2465+
#else
24502466
return (double) (timetz->time+timetz->zone);
2467+
#endif
24512468
}
24522469
}
24532470

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp