PostgreSQL Source Code git master
Loading...
Searching...
No Matches
timestamp.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * timestamp.c
4 * Functions for the built-in SQL types "timestamp" and "interval".
5 *
6 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/backend/utils/adt/timestamp.c
12 *
13 *-------------------------------------------------------------------------
14 */
15
16#include "postgres.h"
17
18#include <ctype.h>
19#include <math.h>
20#include <limits.h>
21#include <sys/time.h>
22
23#include "access/xact.h"
24#include "catalog/pg_type.h"
25#include "common/int.h"
26#include "common/int128.h"
27#include "funcapi.h"
28#include "libpq/pqformat.h"
29#include "miscadmin.h"
30#include "nodes/nodeFuncs.h"
31#include "nodes/supportnodes.h"
32#include "optimizer/optimizer.h"
33#include "parser/scansup.h"
34#include "utils/array.h"
35#include "utils/builtins.h"
36#include "utils/date.h"
37#include "utils/datetime.h"
38#include "utils/float.h"
39#include "utils/numeric.h"
40#include "utils/skipsupport.h"
41#include "utils/sortsupport.h"
42
43
44/* Set at postmaster start */
46
47/* Set at configuration reload */
49
57
66
67/*
68 * The transition datatype for interval aggregates is declared as internal.
69 * It's a pointer to an IntervalAggState allocated in the aggregate context.
70 */
71typedef struct IntervalAggState
72{
73 int64 N; /* count of finite intervals processed */
74 Interval sumX; /* sum of finite intervals processed */
75 /* These counts are *not* included in N! Use IA_TOTAL_COUNT() as needed */
76 int64 pInfcount; /* count of +infinity intervals */
77 int64 nInfcount; /* count of -infinity intervals */
79
80#define IA_TOTAL_COUNT(ia) \
81 ((ia)->N + (ia)->pInfcount + (ia)->nInfcount)
82
83static TimeOffset time2t(const int hour, const int min, const int sec, const fsec_t fsec);
86 Node *escontext);
89
90static void EncodeSpecialInterval(const Interval *interval, char *str);
92
93/* common code for timestamptypmodin and timestamptztypmodin */
94static int32
96{
97 int32 *tl;
98 int n;
99
101
102 /*
103 * we're not too tense about good error message here because grammar
104 * shouldn't allow wrong number of modifiers for TIMESTAMP
105 */
106 if (n != 1)
109 errmsg("invalid type modifier")));
110
112}
113
114/* exported so parse_expr.c can use it */
115int32
117{
118 if (typmod < 0)
121 errmsg("TIMESTAMP(%d)%s precision must not be negative",
122 typmod, (istz ? " WITH TIME ZONE" : ""))));
123 if (typmod > MAX_TIMESTAMP_PRECISION)
124 {
127 errmsg("TIMESTAMP(%d)%s precision reduced to maximum allowed, %d",
128 typmod, (istz ? " WITH TIME ZONE" : ""),
131 }
132
133 return typmod;
134}
135
136/* common code for timestamptypmodout and timestamptztypmodout */
137static char *
139{
140 const char *tz = istz ? " with time zone" : " without time zone";
141
142 if (typmod >= 0)
143 return psprintf("(%d)%s", (int) typmod, tz);
144 else
145 return pstrdup(tz);
146}
147
148
149/*****************************************************************************
150 * USER I/O ROUTINES *
151 *****************************************************************************/
152
153/*
154 * timestamp_in()
155 * Convert a string to internal form.
156 */
157Datum
159{
160 char *str = PG_GETARG_CSTRING(0);
161#ifdef NOT_USED
162 Oid typelem = PG_GETARG_OID(1);
163#endif
164 int32 typmod = PG_GETARG_INT32(2);
165 Node *escontext = fcinfo->context;
167 fsec_t fsec;
168 struct pg_tm tt,
169 *tm = &tt;
170 int tz;
171 int dtype;
172 int nf;
173 int dterr;
174 char *field[MAXDATEFIELDS];
175 int ftype[MAXDATEFIELDS];
177 DateTimeErrorExtra extra;
178
180 field, ftype, MAXDATEFIELDS, &nf);
181 if (dterr == 0)
182 dterr = DecodeDateTime(field, ftype, nf,
183 &dtype, tm, &fsec, &tz, &extra);
184 if (dterr != 0)
185 {
186 DateTimeParseError(dterr, &extra, str, "timestamp", escontext);
188 }
189
190 switch (dtype)
191 {
192 case DTK_DATE:
193 if (tm2timestamp(tm, fsec, NULL, &result) != 0)
194 ereturn(escontext, (Datum) 0,
196 errmsg("timestamp out of range: \"%s\"", str)));
197 break;
198
199 case DTK_EPOCH:
201 break;
202
203 case DTK_LATE:
205 break;
206
207 case DTK_EARLY:
209 break;
210
211 default:
212 elog(ERROR, "unexpected dtype %d while parsing timestamp \"%s\"",
213 dtype, str);
215 }
216
217 AdjustTimestampForTypmod(&result, typmod, escontext);
218
220}
221
222/*
223 * timestamp_out()
224 * Convert a timestamp to external form.
225 */
226Datum
228{
230 char *result;
231 struct pg_tm tt,
232 *tm = &tt;
233 fsec_t fsec;
234 char buf[MAXDATELEN + 1];
235
238 else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) == 0)
239 EncodeDateTime(tm, fsec, false, 0, NULL, DateStyle, buf);
240 else
243 errmsg("timestamp out of range")));
244
245 result = pstrdup(buf);
247}
248
249/*
250 * timestamp_recv - converts external binary format to timestamp
251 */
252Datum
254{
256
257#ifdef NOT_USED
258 Oid typelem = PG_GETARG_OID(1);
259#endif
260 int32 typmod = PG_GETARG_INT32(2);
262 struct pg_tm tt,
263 *tm = &tt;
264 fsec_t fsec;
265
267
268 /* range check: see if timestamp_out would like it */
270 /* ok */ ;
271 else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0 ||
275 errmsg("timestamp out of range")));
276
278
280}
281
282/*
283 * timestamp_send - converts timestamp to binary format
284 */
285Datum
295
296Datum
303
304Datum
311
312
313/*
314 * timestamp_support()
315 *
316 * Planner support function for the timestamp_scale() and timestamptz_scale()
317 * length coercion functions (we need not distinguish them here).
318 */
319Datum
334
335/*
336 * timestamp_scale()
337 * Adjust time type for specified scale factor.
338 * Used by PostgreSQL type system to stuff columns.
339 */
340Datum
342{
344 int32 typmod = PG_GETARG_INT32(1);
346
348
349 if (!AdjustTimestampForTypmod(&result, typmod, fcinfo->context))
351
353}
354
355/*
356 * AdjustTimestampForTypmod --- round off a timestamp to suit given typmod
357 * Works for either timestamp or timestamptz.
358 *
359 * Returns true on success, false on failure (if escontext points to an
360 * ErrorSaveContext; otherwise errors are thrown).
361 */
362bool
364{
365 static const int64 TimestampScales[MAX_TIMESTAMP_PRECISION + 1] = {
366 INT64CONST(1000000),
367 INT64CONST(100000),
368 INT64CONST(10000),
369 INT64CONST(1000),
370 INT64CONST(100),
371 INT64CONST(10),
372 INT64CONST(1)
373 };
374
376 INT64CONST(500000),
377 INT64CONST(50000),
378 INT64CONST(5000),
379 INT64CONST(500),
380 INT64CONST(50),
381 INT64CONST(5),
382 INT64CONST(0)
383 };
384
385 if (!TIMESTAMP_NOT_FINITE(*time)
386 && (typmod != -1) && (typmod != MAX_TIMESTAMP_PRECISION))
387 {
389 ereturn(escontext, false,
391 errmsg("timestamp(%d) precision must be between %d and %d",
392 typmod, 0, MAX_TIMESTAMP_PRECISION)));
393
394 if (*time >= INT64CONST(0))
395 {
396 *time = ((*time + TimestampOffsets[typmod]) / TimestampScales[typmod]) *
397 TimestampScales[typmod];
398 }
399 else
400 {
401 *time = -((((-*time) + TimestampOffsets[typmod]) / TimestampScales[typmod])
402 * TimestampScales[typmod]);
403 }
404 }
405
406 return true;
407}
408
409/*
410 * timestamptz_in()
411 * Convert a string to internal form.
412 */
413Datum
415{
416 char *str = PG_GETARG_CSTRING(0);
417#ifdef NOT_USED
418 Oid typelem = PG_GETARG_OID(1);
419#endif
420 int32 typmod = PG_GETARG_INT32(2);
421 Node *escontext = fcinfo->context;
423 fsec_t fsec;
424 struct pg_tm tt,
425 *tm = &tt;
426 int tz;
427 int dtype;
428 int nf;
429 int dterr;
430 char *field[MAXDATEFIELDS];
431 int ftype[MAXDATEFIELDS];
433 DateTimeErrorExtra extra;
434
436 field, ftype, MAXDATEFIELDS, &nf);
437 if (dterr == 0)
438 dterr = DecodeDateTime(field, ftype, nf,
439 &dtype, tm, &fsec, &tz, &extra);
440 if (dterr != 0)
441 {
442 DateTimeParseError(dterr, &extra, str, "timestamp with time zone",
443 escontext);
445 }
446
447 switch (dtype)
448 {
449 case DTK_DATE:
450 if (tm2timestamp(tm, fsec, &tz, &result) != 0)
451 ereturn(escontext, (Datum) 0,
453 errmsg("timestamp out of range: \"%s\"", str)));
454 break;
455
456 case DTK_EPOCH:
458 break;
459
460 case DTK_LATE:
462 break;
463
464 case DTK_EARLY:
466 break;
467
468 default:
469 elog(ERROR, "unexpected dtype %d while parsing timestamptz \"%s\"",
470 dtype, str);
472 }
473
474 AdjustTimestampForTypmod(&result, typmod, escontext);
475
477}
478
479/*
480 * Try to parse a timezone specification, and return its timezone offset value
481 * if it's acceptable. Otherwise, an error is thrown.
482 *
483 * Note: some code paths update tm->tm_isdst, and some don't; current callers
484 * don't care, so we don't bother being consistent.
485 */
486static int
488{
489 char tzname[TZ_STRLEN_MAX + 1];
490 int dterr;
491 int tz;
492
494
495 /*
496 * Look up the requested timezone. First we try to interpret it as a
497 * numeric timezone specification; if DecodeTimezone decides it doesn't
498 * like the format, we try timezone abbreviations and names.
499 *
500 * Note pg_tzset happily parses numeric input that DecodeTimezone would
501 * reject. To avoid having it accept input that would otherwise be seen
502 * as invalid, it's enough to disallow having a digit in the first
503 * position of our input string.
504 */
505 if (isdigit((unsigned char) *tzname))
508 errmsg("invalid input syntax for type %s: \"%s\"",
509 "numeric time zone", tzname),
510 errhint("Numeric time zones must have \"-\" or \"+\" as first character.")));
511
513 if (dterr != 0)
514 {
515 int type,
516 val;
517 pg_tz *tzp;
518
522 errmsg("numeric time zone \"%s\" out of range", tzname)));
523 else if (dterr != DTERR_BAD_FORMAT)
526 errmsg("time zone \"%s\" not recognized", tzname)));
527
529
531 {
532 /* fixed-offset abbreviation */
533 tz = -val;
534 }
535 else if (type == TZNAME_DYNTZ)
536 {
537 /* dynamic-offset abbreviation, resolve using specified time */
539 }
540 else
541 {
542 /* full zone name */
543 tz = DetermineTimeZoneOffset(tm, tzp);
544 }
545 }
546
547 return tz;
548}
549
550/*
551 * Look up the requested timezone, returning a pg_tz struct.
552 *
553 * This is the same as DecodeTimezoneNameToTz, but starting with a text Datum.
554 */
555static pg_tz *
557{
558 char tzname[TZ_STRLEN_MAX + 1];
559
561
563}
564
565/*
566 * make_timestamp_internal
567 * workhorse for make_timestamp and make_timestamptz
568 */
569static Timestamp
570make_timestamp_internal(int year, int month, int day,
571 int hour, int min, double sec)
572{
573 struct pg_tm tm;
575 TimeOffset time;
576 int dterr;
577 bool bc = false;
579
580 tm.tm_year = year;
581 tm.tm_mon = month;
582 tm.tm_mday = day;
583
584 /* Handle negative years as BC */
585 if (tm.tm_year < 0)
586 {
587 bc = true;
588 tm.tm_year = -tm.tm_year;
589 }
590
591 dterr = ValidateDate(DTK_DATE_M, false, false, bc, &tm);
592
593 if (dterr != 0)
596 errmsg("date field value out of range: %d-%02d-%02d",
597 year, month, day)));
598
602 errmsg("date out of range: %d-%02d-%02d",
603 year, month, day)));
604
606
607 /* Check for time overflow */
608 if (float_time_overflows(hour, min, sec))
611 errmsg("time field value out of range: %d:%02d:%02g",
612 hour, min, sec)));
613
614 /* This should match tm2time */
615 time = (((hour * MINS_PER_HOUR + min) * SECS_PER_MINUTE)
617
622 errmsg("timestamp out of range: %d-%02d-%02d %d:%02d:%02g",
623 year, month, day,
624 hour, min, sec)));
625
626 /* final range check catches just-out-of-range timestamps */
630 errmsg("timestamp out of range: %d-%02d-%02d %d:%02d:%02g",
631 year, month, day,
632 hour, min, sec)));
633
634 return result;
635}
636
637/*
638 * make_timestamp() - timestamp constructor
639 */
640Datum
642{
643 int32 year = PG_GETARG_INT32(0);
644 int32 month = PG_GETARG_INT32(1);
647 int32 min = PG_GETARG_INT32(4);
648 float8 sec = PG_GETARG_FLOAT8(5);
650
651 result = make_timestamp_internal(year, month, mday,
652 hour, min, sec);
653
655}
656
657/*
658 * make_timestamptz() - timestamp with time zone constructor
659 */
660Datum
676
677/*
678 * Construct a timestamp with time zone.
679 * As above, but the time zone is specified as seventh argument.
680 */
681Datum
683{
684 int32 year = PG_GETARG_INT32(0);
685 int32 month = PG_GETARG_INT32(1);
688 int32 min = PG_GETARG_INT32(4);
689 float8 sec = PG_GETARG_FLOAT8(5);
693 struct pg_tm tt;
694 int tz;
695 fsec_t fsec;
696
698 hour, min, sec);
699
700 if (timestamp2tm(timestamp, NULL, &tt, &fsec, NULL, NULL) != 0)
703 errmsg("timestamp out of range")));
704
706
707 result = dt2local(timestamp, -tz);
708
712 errmsg("timestamp out of range")));
713
715}
716
717/*
718 * to_timestamp(double precision)
719 * Convert UNIX epoch to timestamptz.
720 */
721Datum
723{
726
727 /* Deal with NaN and infinite inputs ... */
728 if (isnan(seconds))
731 errmsg("timestamp cannot be NaN")));
732
733 if (isinf(seconds))
734 {
735 if (seconds < 0)
737 else
739 }
740 else
741 {
742 /* Out of range? */
743 if (seconds <
745 || seconds >=
749 errmsg("timestamp out of range: \"%g\"", seconds)));
750
751 /* Convert UNIX epoch to Postgres epoch */
753
755 result = (int64) seconds;
756
757 /* Recheck in case roundoff produces something just out of range */
761 errmsg("timestamp out of range: \"%g\"",
762 PG_GETARG_FLOAT8(0))));
763 }
764
766}
767
768/*
769 * timestamptz_out()
770 * Convert a timestamp to external form.
771 */
772Datum
774{
776 char *result;
777 int tz;
778 struct pg_tm tt,
779 *tm = &tt;
780 fsec_t fsec;
781 const char *tzn;
782 char buf[MAXDATELEN + 1];
783
786 else if (timestamp2tm(dt, &tz, tm, &fsec, &tzn, NULL) == 0)
787 EncodeDateTime(tm, fsec, true, tz, tzn, DateStyle, buf);
788 else
791 errmsg("timestamp out of range")));
792
793 result = pstrdup(buf);
795}
796
797/*
798 * timestamptz_recv - converts external binary format to timestamptz
799 */
800Datum
802{
804
805#ifdef NOT_USED
806 Oid typelem = PG_GETARG_OID(1);
807#endif
808 int32 typmod = PG_GETARG_INT32(2);
810 int tz;
811 struct pg_tm tt,
812 *tm = &tt;
813 fsec_t fsec;
814
816
817 /* range check: see if timestamptz_out would like it */
819 /* ok */ ;
820 else if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0 ||
824 errmsg("timestamp out of range")));
825
827
829}
830
831/*
832 * timestamptz_send - converts timestamptz to binary format
833 */
834Datum
844
845Datum
852
853Datum
860
861
862/*
863 * timestamptz_scale()
864 * Adjust time type for specified scale factor.
865 * Used by PostgreSQL type system to stuff columns.
866 */
867Datum
881
882
883/*
884 * interval_in()
885 * Convert a string to internal form.
886 *
887 * External format(s):
888 * Uses the generic date/time parsing and decoding routines.
889 */
890Datum
892{
893 char *str = PG_GETARG_CSTRING(0);
894#ifdef NOT_USED
895 Oid typelem = PG_GETARG_OID(1);
896#endif
897 int32 typmod = PG_GETARG_INT32(2);
898 Node *escontext = fcinfo->context;
900 struct pg_itm_in tt,
901 *itm_in = &tt;
902 int dtype;
903 int nf;
904 int range;
905 int dterr;
906 char *field[MAXDATEFIELDS];
907 int ftype[MAXDATEFIELDS];
908 char workbuf[256];
909 DateTimeErrorExtra extra;
910
911 itm_in->tm_year = 0;
912 itm_in->tm_mon = 0;
913 itm_in->tm_mday = 0;
914 itm_in->tm_usec = 0;
915
916 if (typmod >= 0)
917 range = INTERVAL_RANGE(typmod);
918 else
920
921 dterr = ParseDateTime(str, workbuf, sizeof(workbuf), field,
922 ftype, MAXDATEFIELDS, &nf);
923 if (dterr == 0)
924 dterr = DecodeInterval(field, ftype, nf, range,
925 &dtype, itm_in);
926
927 /* if those functions think it's a bad format, try ISO8601 style */
928 if (dterr == DTERR_BAD_FORMAT)
930 &dtype, itm_in);
931
932 if (dterr != 0)
933 {
936 DateTimeParseError(dterr, &extra, str, "interval", escontext);
938 }
939
941
942 switch (dtype)
943 {
944 case DTK_DELTA:
945 if (itmin2interval(itm_in, result) != 0)
946 ereturn(escontext, (Datum) 0,
948 errmsg("interval out of range")));
949 break;
950
951 case DTK_LATE:
953 break;
954
955 case DTK_EARLY:
957 break;
958
959 default:
960 elog(ERROR, "unexpected dtype %d while parsing interval \"%s\"",
961 dtype, str);
962 }
963
964 AdjustIntervalForTypmod(result, typmod, escontext);
965
967}
968
969/*
970 * interval_out()
971 * Convert a time span to external form.
972 */
973Datum
975{
977 char *result;
978 struct pg_itm tt,
979 *itm = &tt;
980 char buf[MAXDATELEN + 1];
981
984 else
985 {
988 }
989
990 result = pstrdup(buf);
992}
993
994/*
995 * interval_recv - converts external binary format to interval
996 */
997Datum
999{
1001
1002#ifdef NOT_USED
1003 Oid typelem = PG_GETARG_OID(1);
1004#endif
1005 int32 typmod = PG_GETARG_INT32(2);
1007
1009
1011 interval->day = pq_getmsgint(buf, sizeof(interval->day));
1013
1015
1017}
1018
1019/*
1020 * interval_send - converts interval to binary format
1021 */
1022Datum
1034
1035/*
1036 * The interval typmod stores a "range" in its high 16 bits and a "precision"
1037 * in its low 16 bits. Both contribute to defining the resolution of the
1038 * type. Range addresses resolution granules larger than one second, and
1039 * precision specifies resolution below one second. This representation can
1040 * express all SQL standard resolutions, but we implement them all in terms of
1041 * truncating rightward from some position. Range is a bitmap of permitted
1042 * fields, but only the temporally-smallest such field is significant to our
1043 * calculations. Precision is a count of sub-second decimal places to retain.
1044 * Setting all bits (INTERVAL_FULL_PRECISION) gives the same truncation
1045 * semantics as choosing MAX_INTERVAL_PRECISION.
1046 */
1047Datum
1049{
1051 int32 *tl;
1052 int n;
1053 int32 typmod;
1054
1056
1057 /*
1058 * tl[0] - interval range (fields bitmask) tl[1] - precision (optional)
1059 *
1060 * Note we must validate tl[0] even though it's normally guaranteed
1061 * correct by the grammar --- consider SELECT 'foo'::"interval"(1000).
1062 */
1063 if (n > 0)
1064 {
1065 switch (tl[0])
1066 {
1067 case INTERVAL_MASK(YEAR):
1068 case INTERVAL_MASK(MONTH):
1069 case INTERVAL_MASK(DAY):
1070 case INTERVAL_MASK(HOUR):
1071 case INTERVAL_MASK(MINUTE):
1072 case INTERVAL_MASK(SECOND):
1081 /* all OK */
1082 break;
1083 default:
1084 ereport(ERROR,
1086 errmsg("invalid INTERVAL type modifier")));
1087 }
1088 }
1089
1090 if (n == 1)
1091 {
1092 if (tl[0] != INTERVAL_FULL_RANGE)
1094 else
1095 typmod = -1;
1096 }
1097 else if (n == 2)
1098 {
1099 if (tl[1] < 0)
1100 ereport(ERROR,
1102 errmsg("INTERVAL(%d) precision must not be negative",
1103 tl[1])));
1104 if (tl[1] > MAX_INTERVAL_PRECISION)
1105 {
1108 errmsg("INTERVAL(%d) precision reduced to maximum allowed, %d",
1111 }
1112 else
1113 typmod = INTERVAL_TYPMOD(tl[1], tl[0]);
1114 }
1115 else
1116 {
1117 ereport(ERROR,
1119 errmsg("invalid INTERVAL type modifier")));
1120 typmod = 0; /* keep compiler quiet */
1121 }
1122
1123 PG_RETURN_INT32(typmod);
1124}
1125
1126Datum
1128{
1129 int32 typmod = PG_GETARG_INT32(0);
1130 char *res = (char *) palloc(64);
1131 int fields;
1132 int precision;
1133 const char *fieldstr;
1134
1135 if (typmod < 0)
1136 {
1137 *res = '\0';
1138 PG_RETURN_CSTRING(res);
1139 }
1140
1141 fields = INTERVAL_RANGE(typmod);
1142 precision = INTERVAL_PRECISION(typmod);
1143
1144 switch (fields)
1145 {
1146 case INTERVAL_MASK(YEAR):
1147 fieldstr = " year";
1148 break;
1149 case INTERVAL_MASK(MONTH):
1150 fieldstr = " month";
1151 break;
1152 case INTERVAL_MASK(DAY):
1153 fieldstr = " day";
1154 break;
1155 case INTERVAL_MASK(HOUR):
1156 fieldstr = " hour";
1157 break;
1158 case INTERVAL_MASK(MINUTE):
1159 fieldstr = " minute";
1160 break;
1161 case INTERVAL_MASK(SECOND):
1162 fieldstr = " second";
1163 break;
1165 fieldstr = " year to month";
1166 break;
1168 fieldstr = " day to hour";
1169 break;
1171 fieldstr = " day to minute";
1172 break;
1174 fieldstr = " day to second";
1175 break;
1177 fieldstr = " hour to minute";
1178 break;
1180 fieldstr = " hour to second";
1181 break;
1183 fieldstr = " minute to second";
1184 break;
1186 fieldstr = "";
1187 break;
1188 default:
1189 elog(ERROR, "invalid INTERVAL typmod: 0x%x", typmod);
1190 fieldstr = "";
1191 break;
1192 }
1193
1194 if (precision != INTERVAL_FULL_PRECISION)
1195 snprintf(res, 64, "%s(%d)", fieldstr, precision);
1196 else
1197 snprintf(res, 64, "%s", fieldstr);
1198
1199 PG_RETURN_CSTRING(res);
1200}
1201
1202/*
1203 * Given an interval typmod value, return a code for the least-significant
1204 * field that the typmod allows to be nonzero, for instance given
1205 * INTERVAL DAY TO HOUR we want to identify "hour".
1206 *
1207 * The results should be ordered by field significance, which means
1208 * we can't use the dt.h macros YEAR etc, because for some odd reason
1209 * they aren't ordered that way. Instead, arbitrarily represent
1210 * SECOND = 0, MINUTE = 1, HOUR = 2, DAY = 3, MONTH = 4, YEAR = 5.
1211 */
1212static int
1214{
1215 if (typmod < 0)
1216 return 0; /* SECOND */
1217
1218 switch (INTERVAL_RANGE(typmod))
1219 {
1220 case INTERVAL_MASK(YEAR):
1221 return 5; /* YEAR */
1222 case INTERVAL_MASK(MONTH):
1223 return 4; /* MONTH */
1224 case INTERVAL_MASK(DAY):
1225 return 3; /* DAY */
1226 case INTERVAL_MASK(HOUR):
1227 return 2; /* HOUR */
1228 case INTERVAL_MASK(MINUTE):
1229 return 1; /* MINUTE */
1230 case INTERVAL_MASK(SECOND):
1231 return 0; /* SECOND */
1233 return 4; /* MONTH */
1235 return 2; /* HOUR */
1237 return 1; /* MINUTE */
1239 return 0; /* SECOND */
1241 return 1; /* MINUTE */
1243 return 0; /* SECOND */
1245 return 0; /* SECOND */
1247 return 0; /* SECOND */
1248 default:
1249 elog(ERROR, "invalid INTERVAL typmod: 0x%x", typmod);
1250 break;
1251 }
1252 return 0; /* can't get here, but keep compiler quiet */
1253}
1254
1255
1256/*
1257 * interval_support()
1258 *
1259 * Planner support function for interval_scale().
1260 *
1261 * Flatten superfluous calls to interval_scale(). The interval typmod is
1262 * complex to permit accepting and regurgitating all SQL standard variations.
1263 * For truncation purposes, it boils down to a single, simple granularity.
1264 */
1265Datum
1267{
1269 Node *ret = NULL;
1270
1272 {
1274 FuncExpr *expr = req->fcall;
1275 Node *typmod;
1276
1277 Assert(list_length(expr->args) >= 2);
1278
1279 typmod = (Node *) lsecond(expr->args);
1280
1281 if (IsA(typmod, Const) && !((Const *) typmod)->constisnull)
1282 {
1283 Node *source = (Node *) linitial(expr->args);
1285 bool noop;
1286
1287 if (new_typmod < 0)
1288 noop = true;
1289 else
1290 {
1292 int old_least_field;
1293 int new_least_field;
1294 int old_precis;
1295 int new_precis;
1296
1299 if (old_typmod < 0)
1301 else
1304
1305 /*
1306 * Cast is a no-op if least field stays the same or decreases
1307 * while precision stays the same or increases. But
1308 * precision, which is to say, sub-second precision, only
1309 * affects ranges that include SECOND.
1310 */
1312 (old_least_field > 0 /* SECOND */ ||
1315 }
1316 if (noop)
1318 }
1319 }
1320
1321 PG_RETURN_POINTER(ret);
1322}
1323
1324/*
1325 * interval_scale()
1326 * Adjust interval type for specified fields.
1327 * Used by PostgreSQL type system to stuff columns.
1328 */
1329Datum
1331{
1333 int32 typmod = PG_GETARG_INT32(1);
1335
1337 *result = *interval;
1338
1339 if (!AdjustIntervalForTypmod(result, typmod, fcinfo->context))
1341
1343}
1344
1345/*
1346 * Adjust interval for specified precision, in both YEAR to SECOND
1347 * range and sub-second precision.
1348 *
1349 * Returns true on success, false on failure (if escontext points to an
1350 * ErrorSaveContext; otherwise errors are thrown).
1351 */
1352static bool
1354 Node *escontext)
1355{
1356 static const int64 IntervalScales[MAX_INTERVAL_PRECISION + 1] = {
1357 INT64CONST(1000000),
1358 INT64CONST(100000),
1359 INT64CONST(10000),
1360 INT64CONST(1000),
1361 INT64CONST(100),
1362 INT64CONST(10),
1363 INT64CONST(1)
1364 };
1365
1366 static const int64 IntervalOffsets[MAX_INTERVAL_PRECISION + 1] = {
1367 INT64CONST(500000),
1368 INT64CONST(50000),
1369 INT64CONST(5000),
1370 INT64CONST(500),
1371 INT64CONST(50),
1372 INT64CONST(5),
1373 INT64CONST(0)
1374 };
1375
1376 /* Typmod has no effect on infinite intervals */
1378 return true;
1379
1380 /*
1381 * Unspecified range and precision? Then not necessary to adjust. Setting
1382 * typmod to -1 is the convention for all data types.
1383 */
1384 if (typmod >= 0)
1385 {
1386 int range = INTERVAL_RANGE(typmod);
1387 int precision = INTERVAL_PRECISION(typmod);
1388
1389 /*
1390 * Our interpretation of intervals with a limited set of fields is
1391 * that fields to the right of the last one specified are zeroed out,
1392 * but those to the left of it remain valid. Thus for example there
1393 * is no operational difference between INTERVAL YEAR TO MONTH and
1394 * INTERVAL MONTH. In some cases we could meaningfully enforce that
1395 * higher-order fields are zero; for example INTERVAL DAY could reject
1396 * nonzero "month" field. However that seems a bit pointless when we
1397 * can't do it consistently. (We cannot enforce a range limit on the
1398 * highest expected field, since we do not have any equivalent of
1399 * SQL's <interval leading field precision>.) If we ever decide to
1400 * revisit this, interval_support will likely require adjusting.
1401 *
1402 * Note: before PG 8.4 we interpreted a limited set of fields as
1403 * actually causing a "modulo" operation on a given value, potentially
1404 * losing high-order as well as low-order information. But there is
1405 * no support for such behavior in the standard, and it seems fairly
1406 * undesirable on data consistency grounds anyway. Now we only
1407 * perform truncation or rounding of low-order fields.
1408 */
1410 {
1411 /* Do nothing... */
1412 }
1413 else if (range == INTERVAL_MASK(YEAR))
1414 {
1416 interval->day = 0;
1417 interval->time = 0;
1418 }
1419 else if (range == INTERVAL_MASK(MONTH))
1420 {
1421 interval->day = 0;
1422 interval->time = 0;
1423 }
1424 /* YEAR TO MONTH */
1425 else if (range == (INTERVAL_MASK(YEAR) | INTERVAL_MASK(MONTH)))
1426 {
1427 interval->day = 0;
1428 interval->time = 0;
1429 }
1430 else if (range == INTERVAL_MASK(DAY))
1431 {
1432 interval->time = 0;
1433 }
1434 else if (range == INTERVAL_MASK(HOUR))
1435 {
1438 }
1439 else if (range == INTERVAL_MASK(MINUTE))
1440 {
1443 }
1444 else if (range == INTERVAL_MASK(SECOND))
1445 {
1446 /* fractional-second rounding will be dealt with below */
1447 }
1448 /* DAY TO HOUR */
1449 else if (range == (INTERVAL_MASK(DAY) |
1451 {
1454 }
1455 /* DAY TO MINUTE */
1456 else if (range == (INTERVAL_MASK(DAY) |
1459 {
1462 }
1463 /* DAY TO SECOND */
1464 else if (range == (INTERVAL_MASK(DAY) |
1468 {
1469 /* fractional-second rounding will be dealt with below */
1470 }
1471 /* HOUR TO MINUTE */
1472 else if (range == (INTERVAL_MASK(HOUR) |
1474 {
1477 }
1478 /* HOUR TO SECOND */
1479 else if (range == (INTERVAL_MASK(HOUR) |
1482 {
1483 /* fractional-second rounding will be dealt with below */
1484 }
1485 /* MINUTE TO SECOND */
1486 else if (range == (INTERVAL_MASK(MINUTE) |
1488 {
1489 /* fractional-second rounding will be dealt with below */
1490 }
1491 else
1492 elog(ERROR, "unrecognized interval typmod: %d", typmod);
1493
1494 /* Need to adjust sub-second precision? */
1495 if (precision != INTERVAL_FULL_PRECISION)
1496 {
1498 ereturn(escontext, false,
1500 errmsg("interval(%d) precision must be between %d and %d",
1501 precision, 0, MAX_INTERVAL_PRECISION)));
1502
1503 if (interval->time >= INT64CONST(0))
1504 {
1506 IntervalOffsets[precision],
1507 &interval->time))
1508 ereturn(escontext, false,
1510 errmsg("interval out of range")));
1511 interval->time -= interval->time % IntervalScales[precision];
1512 }
1513 else
1514 {
1516 IntervalOffsets[precision],
1517 &interval->time))
1518 ereturn(escontext, false,
1520 errmsg("interval out of range")));
1521 interval->time -= interval->time % IntervalScales[precision];
1522 }
1523 }
1524 }
1525
1526 return true;
1527}
1528
1529/*
1530 * make_interval - numeric Interval constructor
1531 */
1532Datum
1534{
1541 double secs = PG_GETARG_FLOAT8(6);
1543
1544 /*
1545 * Reject out-of-range inputs. We reject any input values that cause
1546 * integer overflow of the corresponding interval fields.
1547 */
1548 if (isinf(secs) || isnan(secs))
1549 goto out_of_range;
1550
1552
1553 /* years and months -> months */
1555 pg_add_s32_overflow(result->month, months, &result->month))
1556 goto out_of_range;
1557
1558 /* weeks and days -> days */
1560 pg_add_s32_overflow(result->day, days, &result->day))
1561 goto out_of_range;
1562
1563 /* hours and mins -> usecs (cannot overflow 64-bit) */
1565
1566 /* secs -> usecs */
1568 if (!FLOAT8_FITS_IN_INT64(secs) ||
1569 pg_add_s64_overflow(result->time, (int64) secs, &result->time))
1570 goto out_of_range;
1571
1572 /* make sure that the result is finite */
1574 goto out_of_range;
1575
1577
1579 ereport(ERROR,
1581 errmsg("interval out of range"));
1582
1583 PG_RETURN_NULL(); /* keep compiler quiet */
1584}
1585
1586/*
1587 * EncodeSpecialTimestamp()
1588 * Convert reserved timestamp data type to string.
1589 */
1590void
1592{
1594 strcpy(str, EARLY);
1595 else if (TIMESTAMP_IS_NOEND(dt))
1596 strcpy(str, LATE);
1597 else /* shouldn't happen */
1598 elog(ERROR, "invalid argument for EncodeSpecialTimestamp");
1599}
1600
1601static void
1603{
1605 strcpy(str, EARLY);
1606 else if (INTERVAL_IS_NOEND(interval))
1607 strcpy(str, LATE);
1608 else /* shouldn't happen */
1609 elog(ERROR, "invalid argument for EncodeSpecialInterval");
1610}
1611
1612Datum
1617
1618Datum
1623
1624Datum
1629
1630Datum
1635
1636Datum
1641
1642/*
1643 * GetCurrentTimestamp -- get the current operating system time
1644 *
1645 * Result is in the form of a TimestampTz value, and is expressed to the
1646 * full precision of the gettimeofday() syscall
1647 */
1650{
1652 struct timeval tp;
1653
1654 gettimeofday(&tp, NULL);
1655
1656 result = (TimestampTz) tp.tv_sec -
1658 result = (result * USECS_PER_SEC) + tp.tv_usec;
1659
1660 return result;
1661}
1662
1663/*
1664 * GetSQLCurrentTimestamp -- implements CURRENT_TIMESTAMP, CURRENT_TIMESTAMP(n)
1665 */
1668{
1669 TimestampTz ts;
1670
1672 if (typmod >= 0)
1673 AdjustTimestampForTypmod(&ts, typmod, NULL);
1674 return ts;
1675}
1676
1677/*
1678 * GetSQLLocalTimestamp -- implements LOCALTIMESTAMP, LOCALTIMESTAMP(n)
1679 */
1682{
1683 Timestamp ts;
1684
1686 if (typmod >= 0)
1687 AdjustTimestampForTypmod(&ts, typmod, NULL);
1688 return ts;
1689}
1690
1691/*
1692 * timeofday(*) -- returns the current time as a text.
1693 */
1694Datum
1696{
1697 struct timeval tp;
1698 pg_time_t tt;
1699 struct pg_tm *tm;
1700 char part1[128];
1701 char part2[128];
1702 char buf[128 + 128 + 10];
1703
1704 gettimeofday(&tp, NULL);
1705 tt = (pg_time_t) tp.tv_sec;
1707
1708 pg_strftime(part1, sizeof(part1), "%a %b %d %H:%M:%S", tm);
1709 pg_strftime(part2, sizeof(part2), "%Y %Z", tm);
1710 snprintf(buf, sizeof(buf), "%s.%06d %s", part1, (int) tp.tv_usec, part2);
1711
1713}
1714
1715/*
1716 * TimestampDifference -- convert the difference between two timestamps
1717 * into integer seconds and microseconds
1718 *
1719 * This is typically used to calculate a wait timeout for select(2),
1720 * which explains the otherwise-odd choice of output format.
1721 *
1722 * Both inputs must be ordinary finite timestamps (in current usage,
1723 * they'll be results from GetCurrentTimestamp()).
1724 *
1725 * We expect start_time <= stop_time. If not, we return zeros,
1726 * since then we're already past the previously determined stop_time.
1727 */
1728void
1730 long *secs, int *microsecs)
1731{
1733
1734 if (diff <= 0)
1735 {
1736 *secs = 0;
1737 *microsecs = 0;
1738 }
1739 else
1740 {
1741 *secs = (long) (diff / USECS_PER_SEC);
1743 }
1744}
1745
1746/*
1747 * TimestampDifferenceMilliseconds -- convert the difference between two
1748 * timestamps into integer milliseconds
1749 *
1750 * This is typically used to calculate a wait timeout for WaitLatch()
1751 * or a related function. The choice of "long" as the result type
1752 * is to harmonize with that; furthermore, we clamp the result to at most
1753 * INT_MAX milliseconds, because that's all that WaitLatch() allows.
1754 *
1755 * We expect start_time <= stop_time. If not, we return zero,
1756 * since then we're already past the previously determined stop_time.
1757 *
1758 * Subtracting finite and infinite timestamps works correctly, returning
1759 * zero or INT_MAX as appropriate.
1760 *
1761 * Note we round up any fractional millisecond, since waiting for just
1762 * less than the intended timeout is undesirable.
1763 */
1764long
1766{
1768
1769 /* Deal with zero or negative elapsed time quickly. */
1770 if (start_time >= stop_time)
1771 return 0;
1772 /* To not fail with timestamp infinities, we must detect overflow. */
1774 return (long) INT_MAX;
1775 if (diff >= (INT_MAX * INT64CONST(1000) - 999))
1776 return (long) INT_MAX;
1777 else
1778 return (long) ((diff + 999) / 1000);
1779}
1780
1781/*
1782 * TimestampDifferenceExceeds -- report whether the difference between two
1783 * timestamps is >= a threshold (expressed in milliseconds)
1784 *
1785 * Both inputs must be ordinary finite timestamps (in current usage,
1786 * they'll be results from GetCurrentTimestamp()).
1787 */
1788bool
1797
1798/*
1799 * Check if the difference between two timestamps is >= a given
1800 * threshold (expressed in seconds).
1801 */
1802bool
1805 int threshold_sec)
1806{
1807 long secs;
1808 int usecs;
1809
1810 /* Calculate the difference in seconds */
1812
1813 return (secs >= threshold_sec);
1814}
1815
1816/*
1817 * Convert a time_t to TimestampTz.
1818 *
1819 * We do not use time_t internally in Postgres, but this is provided for use
1820 * by functions that need to interpret, say, a stat(2) result.
1821 *
1822 * To avoid having the function's ABI vary depending on the width of time_t,
1823 * we declare the argument as pg_time_t, which is cast-compatible with
1824 * time_t but always 64 bits wide (unless the platform has no 64-bit type).
1825 * This detail should be invisible to callers, at least at source code level.
1826 */
1838
1839/*
1840 * Convert a TimestampTz to time_t.
1841 *
1842 * This too is just marginally useful, but some places need it.
1843 *
1844 * To avoid having the function's ABI vary depending on the width of time_t,
1845 * we declare the result as pg_time_t, which is cast-compatible with
1846 * time_t but always 64 bits wide (unless the platform has no 64-bit type).
1847 * This detail should be invisible to callers, at least at source code level.
1848 */
1859
1860/*
1861 * Produce a C-string representation of a TimestampTz.
1862 *
1863 * This is mostly for use in emitting messages. The primary difference
1864 * from timestamptz_out is that we force the output format to ISO. Note
1865 * also that the result is in a static buffer, not pstrdup'd.
1866 *
1867 * See also pg_strftime.
1868 */
1869const char *
1871{
1872 static char buf[MAXDATELEN + 1];
1873 int tz;
1874 struct pg_tm tt,
1875 *tm = &tt;
1876 fsec_t fsec;
1877 const char *tzn;
1878
1879 if (TIMESTAMP_NOT_FINITE(t))
1881 else if (timestamp2tm(t, &tz, tm, &fsec, &tzn, NULL) == 0)
1882 EncodeDateTime(tm, fsec, true, tz, tzn, USE_ISO_DATES, buf);
1883 else
1884 strlcpy(buf, "(timestamp out of range)", sizeof(buf));
1885
1886 return buf;
1887}
1888
1889
1890void
1891dt2time(Timestamp jd, int *hour, int *min, int *sec, fsec_t *fsec)
1892{
1893 TimeOffset time;
1894
1895 time = jd;
1896
1897 *hour = time / USECS_PER_HOUR;
1898 time -= (*hour) * USECS_PER_HOUR;
1899 *min = time / USECS_PER_MINUTE;
1900 time -= (*min) * USECS_PER_MINUTE;
1901 *sec = time / USECS_PER_SEC;
1902 *fsec = time - (*sec * USECS_PER_SEC);
1903} /* dt2time() */
1904
1905
1906/*
1907 * timestamp2tm() - Convert timestamp data type to POSIX time structure.
1908 *
1909 * Note that year is _not_ 1900-based, but is an explicit full value.
1910 * Also, month is one-based, _not_ zero-based.
1911 * Returns:
1912 * 0 on success
1913 * -1 on out of range
1914 *
1915 * If attimezone is NULL, the global timezone setting will be used.
1916 */
1917int
1918timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
1919{
1921 Timestamp time;
1923
1924 /* Use session timezone if caller asks for default */
1925 if (attimezone == NULL)
1926 attimezone = session_timezone;
1927
1928 time = dt;
1929 TMODULO(time, date, USECS_PER_DAY);
1930
1931 if (time < INT64CONST(0))
1932 {
1933 time += USECS_PER_DAY;
1934 date -= 1;
1935 }
1936
1937 /* add offset to go from J2000 back to standard Julian date */
1939
1940 /* Julian day routine does not work for negative Julian days */
1942 return -1;
1943
1944 j2date((int) date, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
1945 dt2time(time, &tm->tm_hour, &tm->tm_min, &tm->tm_sec, fsec);
1946
1947 /* Done if no TZ conversion wanted */
1948 if (tzp == NULL)
1949 {
1950 tm->tm_isdst = -1;
1951 tm->tm_gmtoff = 0;
1952 tm->tm_zone = NULL;
1953 if (tzn != NULL)
1954 *tzn = NULL;
1955 return 0;
1956 }
1957
1958 /*
1959 * If the time falls within the range of pg_time_t, use pg_localtime() to
1960 * rotate to the local time zone.
1961 *
1962 * First, convert to an integral timestamp, avoiding possibly
1963 * platform-specific roundoff-in-wrong-direction errors, and adjust to
1964 * Unix epoch. Then see if we can convert to pg_time_t without loss. This
1965 * coding avoids hardwiring any assumptions about the width of pg_time_t,
1966 * so it should behave sanely on machines without int64.
1967 */
1968 dt = (dt - *fsec) / USECS_PER_SEC +
1970 utime = (pg_time_t) dt;
1971 if ((Timestamp) utime == dt)
1972 {
1973 struct pg_tm *tx = pg_localtime(&utime, attimezone);
1974
1975 tm->tm_year = tx->tm_year + 1900;
1976 tm->tm_mon = tx->tm_mon + 1;
1977 tm->tm_mday = tx->tm_mday;
1978 tm->tm_hour = tx->tm_hour;
1979 tm->tm_min = tx->tm_min;
1980 tm->tm_sec = tx->tm_sec;
1981 tm->tm_isdst = tx->tm_isdst;
1982 tm->tm_gmtoff = tx->tm_gmtoff;
1983 tm->tm_zone = tx->tm_zone;
1984 *tzp = -tm->tm_gmtoff;
1985 if (tzn != NULL)
1986 *tzn = tm->tm_zone;
1987 }
1988 else
1989 {
1990 /*
1991 * When out of range of pg_time_t, treat as GMT
1992 */
1993 *tzp = 0;
1994 /* Mark this as *no* time zone available */
1995 tm->tm_isdst = -1;
1996 tm->tm_gmtoff = 0;
1997 tm->tm_zone = NULL;
1998 if (tzn != NULL)
1999 *tzn = NULL;
2000 }
2001
2002 return 0;
2003}
2004
2005
2006/*
2007 * tm2timestamp()
2008 * Convert a tm structure to a timestamp data type.
2009 * Note that year is _not_ 1900-based, but is an explicit full value.
2010 * Also, month is one-based, _not_ zero-based.
2011 *
2012 * Returns -1 on failure (value out of range).
2013 */
2014int
2015tm2timestamp(struct pg_tm *tm, fsec_t fsec, int *tzp, Timestamp *result)
2016{
2018 TimeOffset time;
2019
2020 /* Prevent overflow in Julian-day routines */
2022 {
2023 *result = 0; /* keep compiler quiet */
2024 return -1;
2025 }
2026
2028 time = time2t(tm->tm_hour, tm->tm_min, tm->tm_sec, fsec);
2029
2032 {
2033 *result = 0; /* keep compiler quiet */
2034 return -1;
2035 }
2036 if (tzp != NULL)
2037 *result = dt2local(*result, -(*tzp));
2038
2039 /* final range check catches just-out-of-range timestamps */
2041 {
2042 *result = 0; /* keep compiler quiet */
2043 return -1;
2044 }
2045
2046 return 0;
2047}
2048
2049
2050/*
2051 * interval2itm()
2052 * Convert an Interval to a pg_itm structure.
2053 * Note: overflow is not possible, because the pg_itm fields are
2054 * wide enough for all possible conversion results.
2055 */
2056void
2058{
2059 TimeOffset time;
2061
2062 itm->tm_year = span.month / MONTHS_PER_YEAR;
2063 itm->tm_mon = span.month % MONTHS_PER_YEAR;
2064 itm->tm_mday = span.day;
2065 time = span.time;
2066
2067 tfrac = time / USECS_PER_HOUR;
2068 time -= tfrac * USECS_PER_HOUR;
2069 itm->tm_hour = tfrac;
2070 tfrac = time / USECS_PER_MINUTE;
2071 time -= tfrac * USECS_PER_MINUTE;
2072 itm->tm_min = (int) tfrac;
2073 tfrac = time / USECS_PER_SEC;
2074 time -= tfrac * USECS_PER_SEC;
2075 itm->tm_sec = (int) tfrac;
2076 itm->tm_usec = (int) time;
2077}
2078
2079/*
2080 * itm2interval()
2081 * Convert a pg_itm structure to an Interval.
2082 * Returns 0 if OK, -1 on overflow.
2083 *
2084 * This is for use in computations expected to produce finite results. Any
2085 * inputs that lead to infinite results are treated as overflows.
2086 */
2087int
2089{
2090 int64 total_months = (int64) itm->tm_year * MONTHS_PER_YEAR + itm->tm_mon;
2091
2093 return -1;
2094 span->month = (int32) total_months;
2095 span->day = itm->tm_mday;
2097 &span->time))
2098 return -1;
2099 /* tm_min, tm_sec are 32 bits, so intermediate products can't overflow */
2100 if (pg_add_s64_overflow(span->time, itm->tm_min * USECS_PER_MINUTE,
2101 &span->time))
2102 return -1;
2103 if (pg_add_s64_overflow(span->time, itm->tm_sec * USECS_PER_SEC,
2104 &span->time))
2105 return -1;
2106 if (pg_add_s64_overflow(span->time, itm->tm_usec,
2107 &span->time))
2108 return -1;
2110 return -1;
2111 return 0;
2112}
2113
2114/*
2115 * itmin2interval()
2116 * Convert a pg_itm_in structure to an Interval.
2117 * Returns 0 if OK, -1 on overflow.
2118 *
2119 * Note: if the result is infinite, it is not treated as an overflow. This
2120 * avoids any dump/reload hazards from pre-17 databases that do not support
2121 * infinite intervals, but do allow finite intervals with all fields set to
2122 * INT_MIN/INT_MAX (outside the documented range). Such intervals will be
2123 * silently converted to +/-infinity. This may not be ideal, but seems
2124 * preferable to failure, and ought to be pretty unlikely in practice.
2125 */
2126int
2128{
2129 int64 total_months = (int64) itm_in->tm_year * MONTHS_PER_YEAR + itm_in->tm_mon;
2130
2132 return -1;
2133 span->month = (int32) total_months;
2134 span->day = itm_in->tm_mday;
2135 span->time = itm_in->tm_usec;
2136 return 0;
2137}
2138
2139static TimeOffset
2140time2t(const int hour, const int min, const int sec, const fsec_t fsec)
2141{
2142 return (((((hour * MINS_PER_HOUR) + min) * SECS_PER_MINUTE) + sec) * USECS_PER_SEC) + fsec;
2143}
2144
2145static Timestamp
2147{
2148 dt -= (timezone * USECS_PER_SEC);
2149 return dt;
2150}
2151
2152
2153/*****************************************************************************
2154 * PUBLIC ROUTINES *
2155 *****************************************************************************/
2156
2157
2158Datum
2165
2166Datum
2173
2174
2175/*----------------------------------------------------------
2176 * Relational operators for timestamp.
2177 *---------------------------------------------------------*/
2178
2179void
2181{
2182 struct pg_tm *t0;
2183 pg_time_t epoch = 0;
2184
2185 t0 = pg_gmtime(&epoch);
2186
2187 if (t0 == NULL)
2188 elog(ERROR, "could not convert epoch to timestamp: %m");
2189
2190 tm->tm_year = t0->tm_year;
2191 tm->tm_mon = t0->tm_mon;
2192 tm->tm_mday = t0->tm_mday;
2193 tm->tm_hour = t0->tm_hour;
2194 tm->tm_min = t0->tm_min;
2195 tm->tm_sec = t0->tm_sec;
2196
2197 tm->tm_year += 1900;
2198 tm->tm_mon++;
2199}
2200
2203{
2204 Timestamp dt;
2205 struct pg_tm tt,
2206 *tm = &tt;
2207
2209 /* we don't bother to test for failure ... */
2210 tm2timestamp(tm, 0, NULL, &dt);
2211
2212 return dt;
2213} /* SetEpochTimestamp() */
2214
2215/*
2216 * We are currently sharing some code between timestamp and timestamptz.
2217 * The comparison functions are among them. - thomas 2001-09-25
2218 *
2219 * timestamp_relop - is timestamp1 relop timestamp2
2220 */
2221int
2223{
2224 return (dt1 < dt2) ? -1 : ((dt1 > dt2) ? 1 : 0);
2225}
2226
2227Datum
2235
2236Datum
2244
2245Datum
2253
2254Datum
2262
2263Datum
2271
2272Datum
2280
2281Datum
2289
2290Datum
2298
2299/* note: this is used for timestamptz also */
2300static Datum
2302{
2304
2305 if (texisting == PG_INT64_MIN)
2306 {
2307 /* return value is undefined */
2308 *underflow = true;
2309 return (Datum) 0;
2310 }
2311
2312 *underflow = false;
2313 return TimestampGetDatum(texisting - 1);
2314}
2315
2316/* note: this is used for timestamptz also */
2317static Datum
2319{
2321
2322 if (texisting == PG_INT64_MAX)
2323 {
2324 /* return value is undefined */
2325 *overflow = true;
2326 return (Datum) 0;
2327 }
2328
2329 *overflow = false;
2330 return TimestampGetDatum(texisting + 1);
2331}
2332
2333Datum
2345
2346Datum
2348{
2349 return hashint8(fcinfo);
2350}
2351
2352Datum
2357
2358Datum
2360{
2361 return hashint8(fcinfo);
2362}
2363
2364Datum
2369
2370/*
2371 * Cross-type comparison functions for timestamp vs timestamptz
2372 */
2373
2374int32
2376{
2379
2381 if (escontext.error_occurred)
2382 {
2384 {
2385 /* dt1 is larger than any finite timestamp, but less than infinity */
2386 return TIMESTAMP_IS_NOEND(dt2) ? -1 : +1;
2387 }
2389 {
2390 /* dt1 is less than any finite timestamp, but more than -infinity */
2391 return TIMESTAMP_IS_NOBEGIN(dt2) ? +1 : -1;
2392 }
2393 }
2394
2396}
2397
2398Datum
2406
2407Datum
2415
2416Datum
2424
2425Datum
2433
2434Datum
2442
2443Datum
2451
2452Datum
2460
2461Datum
2469
2470Datum
2478
2479Datum
2487
2488Datum
2496
2497Datum
2505
2506Datum
2514
2515Datum
2523
2524
2525/*
2526 * interval_relop - is interval1 relop interval2
2527 *
2528 * Interval comparison is based on converting interval values to a linear
2529 * representation expressed in the units of the time field (microseconds,
2530 * in the case of integer timestamps) with days assumed to be always 24 hours
2531 * and months assumed to be always 30 days. To avoid overflow, we need a
2532 * wider-than-int64 datatype for the linear representation, so use INT128.
2533 */
2534
2535static inline INT128
2537{
2538 INT128 span;
2539 int64 days;
2540
2541 /*
2542 * Combine the month and day fields into an integral number of days.
2543 * Because the inputs are int32, int64 arithmetic suffices here.
2544 */
2545 days = interval->month * INT64CONST(30);
2546 days += interval->day;
2547
2548 /* Widen time field to 128 bits */
2550
2551 /* Scale up days to microseconds, forming a 128-bit product */
2553
2554 return span;
2555}
2556
2557static int
2565
2566static int
2574
2575Datum
2583
2584Datum
2592
2593Datum
2601
2602Datum
2610
2611Datum
2619
2620Datum
2628
2629Datum
2637
2638/*
2639 * Hashing for intervals
2640 *
2641 * We must produce equal hashvals for values that interval_cmp_internal()
2642 * considers equal. So, compute the net span the same way it does,
2643 * and then hash that.
2644 */
2645Datum
2647{
2650 int64 span64;
2651
2652 /*
2653 * Use only the least significant 64 bits for hashing. The upper 64 bits
2654 * seldom add any useful information, and besides we must do it like this
2655 * for compatibility with hashes calculated before use of INT128 was
2656 * introduced.
2657 */
2659
2661}
2662
2663Datum
2676
2677/*
2678 * overlaps_timestamp() --- implements the SQL OVERLAPS operator.
2679 *
2680 * Algorithm is per SQL spec. This is much harder than you'd think
2681 * because the spec requires us to deliver a non-null answer in some cases
2682 * where some of the inputs are null.
2683 */
2684Datum
2686{
2687 /*
2688 * The arguments are Timestamps, but we leave them as generic Datums to
2689 * avoid unnecessary conversions between value and reference forms --- not
2690 * to mention possible dereferences of null pointers.
2691 */
2696 bool ts1IsNull = PG_ARGISNULL(0);
2697 bool te1IsNull = PG_ARGISNULL(1);
2698 bool ts2IsNull = PG_ARGISNULL(2);
2699 bool te2IsNull = PG_ARGISNULL(3);
2700
2701#define TIMESTAMP_GT(t1,t2) \
2702 DatumGetBool(DirectFunctionCall2(timestamp_gt,t1,t2))
2703#define TIMESTAMP_LT(t1,t2) \
2704 DatumGetBool(DirectFunctionCall2(timestamp_lt,t1,t2))
2705
2706 /*
2707 * If both endpoints of interval 1 are null, the result is null (unknown).
2708 * If just one endpoint is null, take ts1 as the non-null one. Otherwise,
2709 * take ts1 as the lesser endpoint.
2710 */
2711 if (ts1IsNull)
2712 {
2713 if (te1IsNull)
2715 /* swap null for non-null */
2716 ts1 = te1;
2717 te1IsNull = true;
2718 }
2719 else if (!te1IsNull)
2720 {
2721 if (TIMESTAMP_GT(ts1, te1))
2722 {
2723 Datum tt = ts1;
2724
2725 ts1 = te1;
2726 te1 = tt;
2727 }
2728 }
2729
2730 /* Likewise for interval 2. */
2731 if (ts2IsNull)
2732 {
2733 if (te2IsNull)
2735 /* swap null for non-null */
2736 ts2 = te2;
2737 te2IsNull = true;
2738 }
2739 else if (!te2IsNull)
2740 {
2741 if (TIMESTAMP_GT(ts2, te2))
2742 {
2743 Datum tt = ts2;
2744
2745 ts2 = te2;
2746 te2 = tt;
2747 }
2748 }
2749
2750 /*
2751 * At this point neither ts1 nor ts2 is null, so we can consider three
2752 * cases: ts1 > ts2, ts1 < ts2, ts1 = ts2
2753 */
2754 if (TIMESTAMP_GT(ts1, ts2))
2755 {
2756 /*
2757 * This case is ts1 < te2 OR te1 < te2, which may look redundant but
2758 * in the presence of nulls it's not quite completely so.
2759 */
2760 if (te2IsNull)
2762 if (TIMESTAMP_LT(ts1, te2))
2763 PG_RETURN_BOOL(true);
2764 if (te1IsNull)
2766
2767 /*
2768 * If te1 is not null then we had ts1 <= te1 above, and we just found
2769 * ts1 >= te2, hence te1 >= te2.
2770 */
2771 PG_RETURN_BOOL(false);
2772 }
2773 else if (TIMESTAMP_LT(ts1, ts2))
2774 {
2775 /* This case is ts2 < te1 OR te2 < te1 */
2776 if (te1IsNull)
2778 if (TIMESTAMP_LT(ts2, te1))
2779 PG_RETURN_BOOL(true);
2780 if (te2IsNull)
2782
2783 /*
2784 * If te2 is not null then we had ts2 <= te2 above, and we just found
2785 * ts2 >= te1, hence te2 >= te1.
2786 */
2787 PG_RETURN_BOOL(false);
2788 }
2789 else
2790 {
2791 /*
2792 * For ts1 = ts2 the spec says te1 <> te2 OR te1 = te2, which is a
2793 * rather silly way of saying "true if both are non-null, else null".
2794 */
2795 if (te1IsNull || te2IsNull)
2797 PG_RETURN_BOOL(true);
2798 }
2799
2800#undef TIMESTAMP_GT
2801#undef TIMESTAMP_LT
2802}
2803
2804
2805/*----------------------------------------------------------
2806 * "Arithmetic" operators on date/times.
2807 *---------------------------------------------------------*/
2808
2809Datum
2811{
2815
2816 /* use timestamp_cmp_internal to be sure this agrees with comparisons */
2817 if (timestamp_cmp_internal(dt1, dt2) < 0)
2818 result = dt1;
2819 else
2820 result = dt2;
2822}
2823
2824Datum
2837
2838
2839Datum
2841{
2845
2847
2848 /*
2849 * Handle infinities.
2850 *
2851 * We treat anything that amounts to "infinity - infinity" as an error,
2852 * since the interval type has nothing equivalent to NaN.
2853 */
2855 {
2857 {
2859 ereport(ERROR,
2861 errmsg("interval out of range")));
2862 else
2864 }
2865 else if (TIMESTAMP_IS_NOEND(dt1))
2866 {
2868 ereport(ERROR,
2870 errmsg("interval out of range")));
2871 else
2873 }
2874 else if (TIMESTAMP_IS_NOBEGIN(dt2))
2876 else /* TIMESTAMP_IS_NOEND(dt2) */
2878
2880 }
2881
2882 if (unlikely(pg_sub_s64_overflow(dt1, dt2, &result->time)))
2883 ereport(ERROR,
2885 errmsg("interval out of range")));
2886
2887 result->month = 0;
2888 result->day = 0;
2889
2890 /*----------
2891 * This is wrong, but removing it breaks a lot of regression tests.
2892 * For example:
2893 *
2894 * test=> SET timezone = 'EST5EDT';
2895 * test=> SELECT
2896 * test-> ('2005-10-30 13:22:00-05'::timestamptz -
2897 * test(> '2005-10-29 13:22:00-04'::timestamptz);
2898 * ?column?
2899 * ----------------
2900 * 1 day 01:00:00
2901 * (1 row)
2902 *
2903 * so adding that to the first timestamp gets:
2904 *
2905 * test=> SELECT
2906 * test-> ('2005-10-29 13:22:00-04'::timestamptz +
2907 * test(> ('2005-10-30 13:22:00-05'::timestamptz -
2908 * test(> '2005-10-29 13:22:00-04'::timestamptz)) at time zone 'EST';
2909 * timezone
2910 * --------------------
2911 * 2005-10-30 14:22:00
2912 * (1 row)
2913 *----------
2914 */
2917
2919}
2920
2921/*
2922 * interval_justify_interval()
2923 *
2924 * Adjust interval so 'month', 'day', and 'time' portions are within
2925 * customary bounds. Specifically:
2926 *
2927 * 0 <= abs(time) < 24 hours
2928 * 0 <= abs(day) < 30 days
2929 *
2930 * Also, the sign bit on all three fields is made equal, so either
2931 * all three fields are negative or all are positive.
2932 */
2933Datum
2935{
2940
2942 result->month = span->month;
2943 result->day = span->day;
2944 result->time = span->time;
2945
2946 /* do nothing for infinite intervals */
2949
2950 /* pre-justify days if it might prevent overflow */
2951 if ((result->day > 0 && result->time > 0) ||
2952 (result->day < 0 && result->time < 0))
2953 {
2956 if (pg_add_s32_overflow(result->month, wholemonth, &result->month))
2957 ereport(ERROR,
2959 errmsg("interval out of range")));
2960 }
2961
2962 /*
2963 * Since TimeOffset is int64, abs(wholeday) can't exceed about 1.07e8. If
2964 * we pre-justified then abs(result->day) is less than DAYS_PER_MONTH, so
2965 * this addition can't overflow. If we didn't pre-justify, then day and
2966 * time are of different signs, so it still can't overflow.
2967 */
2969 result->day += wholeday;
2970
2973 if (pg_add_s32_overflow(result->month, wholemonth, &result->month))
2974 ereport(ERROR,
2976 errmsg("interval out of range")));
2977
2978 if (result->month > 0 &&
2979 (result->day < 0 || (result->day == 0 && result->time < 0)))
2980 {
2981 result->day += DAYS_PER_MONTH;
2982 result->month--;
2983 }
2984 else if (result->month < 0 &&
2985 (result->day > 0 || (result->day == 0 && result->time > 0)))
2986 {
2987 result->day -= DAYS_PER_MONTH;
2988 result->month++;
2989 }
2990
2991 if (result->day > 0 && result->time < 0)
2992 {
2993 result->time += USECS_PER_DAY;
2994 result->day--;
2995 }
2996 else if (result->day < 0 && result->time > 0)
2997 {
2998 result->time -= USECS_PER_DAY;
2999 result->day++;
3000 }
3001
3003}
3004
3005/*
3006 * interval_justify_hours()
3007 *
3008 * Adjust interval so 'time' contains less than a whole day, adding
3009 * the excess to 'day'. This is useful for
3010 * situations (such as non-TZ) where '1 day' = '24 hours' is valid,
3011 * e.g. interval subtraction and division.
3012 */
3013Datum
3015{
3019
3021 result->month = span->month;
3022 result->day = span->day;
3023 result->time = span->time;
3024
3025 /* do nothing for infinite intervals */
3028
3030 if (pg_add_s32_overflow(result->day, wholeday, &result->day))
3031 ereport(ERROR,
3033 errmsg("interval out of range")));
3034
3035 if (result->day > 0 && result->time < 0)
3036 {
3037 result->time += USECS_PER_DAY;
3038 result->day--;
3039 }
3040 else if (result->day < 0 && result->time > 0)
3041 {
3042 result->time -= USECS_PER_DAY;
3043 result->day++;
3044 }
3045
3047}
3048
3049/*
3050 * interval_justify_days()
3051 *
3052 * Adjust interval so 'day' contains less than 30 days, adding
3053 * the excess to 'month'.
3054 */
3055Datum
3057{
3061
3063 result->month = span->month;
3064 result->day = span->day;
3065 result->time = span->time;
3066
3067 /* do nothing for infinite intervals */
3070
3073 if (pg_add_s32_overflow(result->month, wholemonth, &result->month))
3074 ereport(ERROR,
3076 errmsg("interval out of range")));
3077
3078 if (result->month > 0 && result->day < 0)
3079 {
3080 result->day += DAYS_PER_MONTH;
3081 result->month--;
3082 }
3083 else if (result->month < 0 && result->day > 0)
3084 {
3085 result->day -= DAYS_PER_MONTH;
3086 result->month++;
3087 }
3088
3090}
3091
3092/*
3093 * timestamp_pl_interval()
3094 * Add an interval to a timestamp data type.
3095 * Note that interval has provisions for qualitative year/month and day
3096 * units, so try to do the right thing with them.
3097 * To add a month, increment the month, and use the same day of month.
3098 * Then, if the next month has fewer days, set the day of month
3099 * to the last day of month.
3100 * To add a day, increment the mday, and use the same time of day.
3101 * Lastly, add in the "quantitative time".
3102 */
3103Datum
3105{
3109
3110 /*
3111 * Handle infinities.
3112 *
3113 * We treat anything that amounts to "infinity - infinity" as an error,
3114 * since the timestamp type has nothing equivalent to NaN.
3115 */
3117 {
3119 ereport(ERROR,
3121 errmsg("timestamp out of range")));
3122 else
3124 }
3125 else if (INTERVAL_IS_NOEND(span))
3126 {
3128 ereport(ERROR,
3130 errmsg("timestamp out of range")));
3131 else
3133 }
3135 result = timestamp;
3136 else
3137 {
3138 if (span->month != 0)
3139 {
3140 struct pg_tm tt,
3141 *tm = &tt;
3142 fsec_t fsec;
3143
3144 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
3145 ereport(ERROR,
3147 errmsg("timestamp out of range")));
3148
3149 if (pg_add_s32_overflow(tm->tm_mon, span->month, &tm->tm_mon))
3150 ereport(ERROR,
3152 errmsg("timestamp out of range")));
3153 if (tm->tm_mon > MONTHS_PER_YEAR)
3154 {
3155 tm->tm_year += (tm->tm_mon - 1) / MONTHS_PER_YEAR;
3156 tm->tm_mon = ((tm->tm_mon - 1) % MONTHS_PER_YEAR) + 1;
3157 }
3158 else if (tm->tm_mon < 1)
3159 {
3160 tm->tm_year += tm->tm_mon / MONTHS_PER_YEAR - 1;
3162 }
3163
3164 /* adjust for end of month boundary problems... */
3165 if (tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1])
3166 tm->tm_mday = (day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]);
3167
3168 if (tm2timestamp(tm, fsec, NULL, &timestamp) != 0)
3169 ereport(ERROR,
3171 errmsg("timestamp out of range")));
3172 }
3173
3174 if (span->day != 0)
3175 {
3176 struct pg_tm tt,
3177 *tm = &tt;
3178 fsec_t fsec;
3179 int julian;
3180
3181 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
3182 ereport(ERROR,
3184 errmsg("timestamp out of range")));
3185
3186 /*
3187 * Add days by converting to and from Julian. We need an overflow
3188 * check here since j2date expects a non-negative integer input.
3189 */
3191 if (pg_add_s32_overflow(julian, span->day, &julian) ||
3192 julian < 0)
3193 ereport(ERROR,
3195 errmsg("timestamp out of range")));
3197
3198 if (tm2timestamp(tm, fsec, NULL, &timestamp) != 0)
3199 ereport(ERROR,
3201 errmsg("timestamp out of range")));
3202 }
3203
3205 ereport(ERROR,
3207 errmsg("timestamp out of range")));
3208
3210 ereport(ERROR,
3212 errmsg("timestamp out of range")));
3213
3214 result = timestamp;
3215 }
3216
3218}
3219
3220Datum
3233
3234
3235/*
3236 * timestamptz_pl_interval_internal()
3237 * Add an interval to a timestamptz, in the given (or session) timezone.
3238 *
3239 * Note that interval has provisions for qualitative year/month and day
3240 * units, so try to do the right thing with them.
3241 * To add a month, increment the month, and use the same day of month.
3242 * Then, if the next month has fewer days, set the day of month
3243 * to the last day of month.
3244 * To add a day, increment the mday, and use the same time of day.
3245 * Lastly, add in the "quantitative time".
3246 */
3247static TimestampTz
3249 Interval *span,
3250 pg_tz *attimezone)
3251{
3253 int tz;
3254
3255 /*
3256 * Handle infinities.
3257 *
3258 * We treat anything that amounts to "infinity - infinity" as an error,
3259 * since the timestamptz type has nothing equivalent to NaN.
3260 */
3262 {
3264 ereport(ERROR,
3266 errmsg("timestamp out of range")));
3267 else
3269 }
3270 else if (INTERVAL_IS_NOEND(span))
3271 {
3273 ereport(ERROR,
3275 errmsg("timestamp out of range")));
3276 else
3278 }
3280 result = timestamp;
3281 else
3282 {
3283 /* Use session timezone if caller asks for default */
3284 if (attimezone == NULL)
3285 attimezone = session_timezone;
3286
3287 if (span->month != 0)
3288 {
3289 struct pg_tm tt,
3290 *tm = &tt;
3291 fsec_t fsec;
3292
3293 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, attimezone) != 0)
3294 ereport(ERROR,
3296 errmsg("timestamp out of range")));
3297
3298 if (pg_add_s32_overflow(tm->tm_mon, span->month, &tm->tm_mon))
3299 ereport(ERROR,
3301 errmsg("timestamp out of range")));
3302 if (tm->tm_mon > MONTHS_PER_YEAR)
3303 {
3304 tm->tm_year += (tm->tm_mon - 1) / MONTHS_PER_YEAR;
3305 tm->tm_mon = ((tm->tm_mon - 1) % MONTHS_PER_YEAR) + 1;
3306 }
3307 else if (tm->tm_mon < 1)
3308 {
3309 tm->tm_year += tm->tm_mon / MONTHS_PER_YEAR - 1;
3311 }
3312
3313 /* adjust for end of month boundary problems... */
3314 if (tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1])
3315 tm->tm_mday = (day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]);
3316
3317 tz = DetermineTimeZoneOffset(tm, attimezone);
3318
3319 if (tm2timestamp(tm, fsec, &tz, &timestamp) != 0)
3320 ereport(ERROR,
3322 errmsg("timestamp out of range")));
3323 }
3324
3325 if (span->day != 0)
3326 {
3327 struct pg_tm tt,
3328 *tm = &tt;
3329 fsec_t fsec;
3330 int julian;
3331
3332 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, attimezone) != 0)
3333 ereport(ERROR,
3335 errmsg("timestamp out of range")));
3336
3337 /*
3338 * Add days by converting to and from Julian. We need an overflow
3339 * check here since j2date expects a non-negative integer input.
3340 * In practice though, it will give correct answers for small
3341 * negative Julian dates; we should allow -1 to avoid
3342 * timezone-dependent failures, as discussed in timestamp.h.
3343 */
3345 if (pg_add_s32_overflow(julian, span->day, &julian) ||
3346 julian < -1)
3347 ereport(ERROR,
3349 errmsg("timestamp out of range")));
3351
3352 tz = DetermineTimeZoneOffset(tm, attimezone);
3353
3354 if (tm2timestamp(tm, fsec, &tz, &timestamp) != 0)
3355 ereport(ERROR,
3357 errmsg("timestamp out of range")));
3358 }
3359
3361 ereport(ERROR,
3363 errmsg("timestamp out of range")));
3364
3366 ereport(ERROR,
3368 errmsg("timestamp out of range")));
3369
3370 result = timestamp;
3371 }
3372
3373 return result;
3374}
3375
3376/*
3377 * timestamptz_mi_interval_internal()
3378 * As above, but subtract the interval.
3379 */
3380static TimestampTz
3391
3392/*
3393 * timestamptz_pl_interval()
3394 * Add an interval to a timestamptz, in the session timezone.
3395 */
3396Datum
3404
3405Datum
3413
3414/*
3415 * timestamptz_pl_interval_at_zone()
3416 * Add an interval to a timestamptz, in the specified timezone.
3417 */
3418Datum
3428
3429Datum
3439
3440/*
3441 * interval_um_internal()
3442 * Negate an interval.
3443 */
3444static void
3446{
3449 else if (INTERVAL_IS_NOEND(interval))
3451 else
3452 {
3453 /* Negate each field, guarding against overflow */
3455 pg_sub_s32_overflow(0, interval->day, &result->day) ||
3456 pg_sub_s32_overflow(0, interval->month, &result->month) ||
3458 ereport(ERROR,
3460 errmsg("interval out of range")));
3461 }
3462}
3463
3464Datum
3475
3476
3477Datum
3479{
3483
3484 /* use interval_cmp_internal to be sure this agrees with comparisons */
3486 result = interval1;
3487 else
3488 result = interval2;
3490}
3491
3492Datum
3505
3506static void
3508{
3511
3512 if (pg_add_s32_overflow(span1->month, span2->month, &result->month) ||
3513 pg_add_s32_overflow(span1->day, span2->day, &result->day) ||
3514 pg_add_s64_overflow(span1->time, span2->time, &result->time) ||
3516 ereport(ERROR,
3518 errmsg("interval out of range")));
3519}
3520
3521Datum
3523{
3527
3529
3530 /*
3531 * Handle infinities.
3532 *
3533 * We treat anything that amounts to "infinity - infinity" as an error,
3534 * since the interval type has nothing equivalent to NaN.
3535 */
3537 {
3539 ereport(ERROR,
3541 errmsg("interval out of range")));
3542 else
3544 }
3545 else if (INTERVAL_IS_NOEND(span1))
3546 {
3548 ereport(ERROR,
3550 errmsg("interval out of range")));
3551 else
3553 }
3554 else if (INTERVAL_NOT_FINITE(span2))
3555 memcpy(result, span2, sizeof(Interval));
3556 else
3558
3560}
3561
3562static void
3564{
3567
3568 if (pg_sub_s32_overflow(span1->month, span2->month, &result->month) ||
3569 pg_sub_s32_overflow(span1->day, span2->day, &result->day) ||
3570 pg_sub_s64_overflow(span1->time, span2->time, &result->time) ||
3572 ereport(ERROR,
3574 errmsg("interval out of range")));
3575}
3576
3577Datum
3579{
3583
3585
3586 /*
3587 * Handle infinities.
3588 *
3589 * We treat anything that amounts to "infinity - infinity" as an error,
3590 * since the interval type has nothing equivalent to NaN.
3591 */
3593 {
3595 ereport(ERROR,
3597 errmsg("interval out of range")));
3598 else
3600 }
3601 else if (INTERVAL_IS_NOEND(span1))
3602 {
3604 ereport(ERROR,
3606 errmsg("interval out of range")));
3607 else
3609 }
3610 else if (INTERVAL_IS_NOBEGIN(span2))
3612 else if (INTERVAL_IS_NOEND(span2))
3614 else
3616
3618}
3619
3620/*
3621 * There is no interval_abs(): it is unclear what value to return:
3622 * http://archives.postgresql.org/pgsql-general/2009-10/msg01031.php
3623 * http://archives.postgresql.org/pgsql-general/2009-11/msg00041.php
3624 */
3625
3626Datum
3628{
3631 double month_remainder_days,
3634 int32 orig_month = span->month,
3635 orig_day = span->day;
3637
3639
3640 /*
3641 * Handle NaN and infinities.
3642 *
3643 * We treat "0 * infinity" and "infinity * 0" as errors, since the
3644 * interval type has nothing equivalent to NaN.
3645 */
3646 if (isnan(factor))
3647 goto out_of_range;
3648
3650 {
3651 if (factor == 0.0)
3652 goto out_of_range;
3653
3654 if (factor < 0.0)
3656 else
3657 memcpy(result, span, sizeof(Interval));
3658
3660 }
3661 if (isinf(factor))
3662 {
3663 int isign = interval_sign(span);
3664
3665 if (isign == 0)
3666 goto out_of_range;
3667
3668 if (factor * isign < 0)
3670 else
3672
3674 }
3675
3676 result_double = span->month * factor;
3678 goto out_of_range;
3679 result->month = (int32) result_double;
3680
3681 result_double = span->day * factor;
3683 goto out_of_range;
3684 result->day = (int32) result_double;
3685
3686 /*
3687 * The above correctly handles the whole-number part of the month and day
3688 * products, but we have to do something with any fractional part
3689 * resulting when the factor is non-integral. We cascade the fractions
3690 * down to lower units using the conversion factors DAYS_PER_MONTH and
3691 * SECS_PER_DAY. Note we do NOT cascade up, since we are not forced to do
3692 * so by the representation. The user can choose to cascade up later,
3693 * using justify_hours and/or justify_days.
3694 */
3695
3696 /*
3697 * Fractional months full days into days.
3698 *
3699 * Floating point calculation are inherently imprecise, so these
3700 * calculations are crafted to produce the most reliable result possible.
3701 * TSROUND() is needed to more accurately produce whole numbers where
3702 * appropriate.
3703 */
3706 sec_remainder = (orig_day * factor - result->day +
3709
3710 /*
3711 * Might have 24:00:00 hours due to rounding, or >24 hours because of time
3712 * cascade from months and days. It might still be >24 if the combination
3713 * of cascade and the seconds factor operation itself.
3714 */
3716 {
3717 if (pg_add_s32_overflow(result->day,
3718 (int) (sec_remainder / SECS_PER_DAY),
3719 &result->day))
3720 goto out_of_range;
3722 }
3723
3724 /* cascade units down */
3726 &result->day))
3727 goto out_of_range;
3730 goto out_of_range;
3731 result->time = (int64) result_double;
3732
3734 goto out_of_range;
3735
3737
3739 ereport(ERROR,
3741 errmsg("interval out of range"));
3742
3743 PG_RETURN_NULL(); /* keep compiler quiet */
3744}
3745
3746Datum
3748{
3749 /* Args are float8 and Interval *, but leave them as generic Datum */
3752
3754}
3755
3756Datum
3758{
3761 double month_remainder_days,
3764 int32 orig_month = span->month,
3765 orig_day = span->day;
3767
3769
3770 if (factor == 0.0)
3771 ereport(ERROR,
3773 errmsg("division by zero")));
3774
3775 /*
3776 * Handle NaN and infinities.
3777 *
3778 * We treat "infinity / infinity" as an error, since the interval type has
3779 * nothing equivalent to NaN. Otherwise, dividing by infinity is handled
3780 * by the regular division code, causing all fields to be set to zero.
3781 */
3782 if (isnan(factor))
3783 goto out_of_range;
3784
3786 {
3787 if (isinf(factor))
3788 goto out_of_range;
3789
3790 if (factor < 0.0)
3792 else
3793 memcpy(result, span, sizeof(Interval));
3794
3796 }
3797
3798 result_double = span->month / factor;
3800 goto out_of_range;
3801 result->month = (int32) result_double;
3802
3803 result_double = span->day / factor;
3805 goto out_of_range;
3806 result->day = (int32) result_double;
3807
3808 /*
3809 * Fractional months full days into days. See comment in interval_mul().
3810 */
3813 sec_remainder = (orig_day / factor - result->day +
3817 {
3818 if (pg_add_s32_overflow(result->day,
3819 (int) (sec_remainder / SECS_PER_DAY),
3820 &result->day))
3821 goto out_of_range;
3823 }
3824
3825 /* cascade units down */
3827 &result->day))
3828 goto out_of_range;
3831 goto out_of_range;
3832 result->time = (int64) result_double;
3833
3835 goto out_of_range;
3836
3838
3840 ereport(ERROR,
3842 errmsg("interval out of range"));
3843
3844 PG_RETURN_NULL(); /* keep compiler quiet */
3845}
3846
3847
3848/*
3849 * in_range support functions for timestamps and intervals.
3850 *
3851 * Per SQL spec, we support these with interval as the offset type.
3852 * The spec's restriction that the offset not be negative is a bit hard to
3853 * decipher for intervals, but we choose to interpret it the same as our
3854 * interval comparison operators would.
3855 */
3856
3857Datum
3859{
3862 Interval *offset = PG_GETARG_INTERVAL_P(2);
3863 bool sub = PG_GETARG_BOOL(3);
3864 bool less = PG_GETARG_BOOL(4);
3865 TimestampTz sum;
3866
3867 if (interval_sign(offset) < 0)
3868 ereport(ERROR,
3870 errmsg("invalid preceding or following size in window function")));
3871
3872 /*
3873 * Deal with cases where both base and offset are infinite, and computing
3874 * base +/- offset would cause an error. As for float and numeric types,
3875 * we assume that all values infinitely precede +infinity and infinitely
3876 * follow -infinity. See in_range_float8_float8() for reasoning.
3877 */
3878 if (INTERVAL_IS_NOEND(offset) &&
3879 (sub ? TIMESTAMP_IS_NOEND(base) : TIMESTAMP_IS_NOBEGIN(base)))
3880 PG_RETURN_BOOL(true);
3881
3882 /* We don't currently bother to avoid overflow hazards here */
3883 if (sub)
3884 sum = timestamptz_mi_interval_internal(base, offset, NULL);
3885 else
3886 sum = timestamptz_pl_interval_internal(base, offset, NULL);
3887
3888 if (less)
3889 PG_RETURN_BOOL(val <= sum);
3890 else
3891 PG_RETURN_BOOL(val >= sum);
3892}
3893
3894Datum
3896{
3899 Interval *offset = PG_GETARG_INTERVAL_P(2);
3900 bool sub = PG_GETARG_BOOL(3);
3901 bool less = PG_GETARG_BOOL(4);
3902 Timestamp sum;
3903
3904 if (interval_sign(offset) < 0)
3905 ereport(ERROR,
3907 errmsg("invalid preceding or following size in window function")));
3908
3909 /*
3910 * Deal with cases where both base and offset are infinite, and computing
3911 * base +/- offset would cause an error. As for float and numeric types,
3912 * we assume that all values infinitely precede +infinity and infinitely
3913 * follow -infinity. See in_range_float8_float8() for reasoning.
3914 */
3915 if (INTERVAL_IS_NOEND(offset) &&
3916 (sub ? TIMESTAMP_IS_NOEND(base) : TIMESTAMP_IS_NOBEGIN(base)))
3917 PG_RETURN_BOOL(true);
3918
3919 /* We don't currently bother to avoid overflow hazards here */
3920 if (sub)
3922 TimestampGetDatum(base),
3923 IntervalPGetDatum(offset)));
3924 else
3926 TimestampGetDatum(base),
3927 IntervalPGetDatum(offset)));
3928
3929 if (less)
3930 PG_RETURN_BOOL(val <= sum);
3931 else
3932 PG_RETURN_BOOL(val >= sum);
3933}
3934
3935Datum
3937{
3939 Interval *base = PG_GETARG_INTERVAL_P(1);
3940 Interval *offset = PG_GETARG_INTERVAL_P(2);
3941 bool sub = PG_GETARG_BOOL(3);
3942 bool less = PG_GETARG_BOOL(4);
3943 Interval *sum;
3944
3945 if (interval_sign(offset) < 0)
3946 ereport(ERROR,
3948 errmsg("invalid preceding or following size in window function")));
3949
3950 /*
3951 * Deal with cases where both base and offset are infinite, and computing
3952 * base +/- offset would cause an error. As for float and numeric types,
3953 * we assume that all values infinitely precede +infinity and infinitely
3954 * follow -infinity. See in_range_float8_float8() for reasoning.
3955 */
3956 if (INTERVAL_IS_NOEND(offset) &&
3957 (sub ? INTERVAL_IS_NOEND(base) : INTERVAL_IS_NOBEGIN(base)))
3958 PG_RETURN_BOOL(true);
3959
3960 /* We don't currently bother to avoid overflow hazards here */
3961 if (sub)
3963 IntervalPGetDatum(base),
3964 IntervalPGetDatum(offset)));
3965 else
3967 IntervalPGetDatum(base),
3968 IntervalPGetDatum(offset)));
3969
3970 if (less)
3972 else
3974}
3975
3976
3977/*
3978 * Prepare state data for an interval aggregate function, that needs to compute
3979 * sum and count, in the aggregate's memory context.
3980 *
3981 * The function is used when the state data needs to be allocated in aggregate's
3982 * context. When the state data needs to be allocated in the current memory
3983 * context, we use palloc0 directly e.g. interval_avg_deserialize().
3984 */
3985static IntervalAggState *
3987{
3989 MemoryContext agg_context;
3991
3992 if (!AggCheckCallContext(fcinfo, &agg_context))
3993 elog(ERROR, "aggregate function called in non-aggregate context");
3994
3995 old_context = MemoryContextSwitchTo(agg_context);
3996
3998
4000
4001 return state;
4002}
4003
4004/*
4005 * Accumulate a new input value for interval aggregate functions.
4006 */
4007static void
4009{
4010 /* Infinite inputs are counted separately, and do not affect "N" */
4012 {
4013 state->nInfcount++;
4014 return;
4015 }
4016
4018 {
4019 state->pInfcount++;
4020 return;
4021 }
4022
4023 finite_interval_pl(&state->sumX, newval, &state->sumX);
4024 state->N++;
4025}
4026
4027/*
4028 * Remove the given interval value from the aggregated state.
4029 */
4030static void
4032{
4033 /* Infinite inputs are counted separately, and do not affect "N" */
4035 {
4036 state->nInfcount--;
4037 return;
4038 }
4039
4041 {
4042 state->pInfcount--;
4043 return;
4044 }
4045
4046 /* Handle the to-be-discarded finite value. */
4047 state->N--;
4048 if (state->N > 0)
4049 finite_interval_mi(&state->sumX, newval, &state->sumX);
4050 else
4051 {
4052 /* All values discarded, reset the state */
4053 Assert(state->N == 0);
4054 memset(&state->sumX, 0, sizeof(state->sumX));
4055 }
4056}
4057
4058/*
4059 * Transition function for sum() and avg() interval aggregates.
4060 */
4061Datum
4063{
4065
4067
4068 /* Create the state data on the first call */
4069 if (state == NULL)
4070 state = makeIntervalAggState(fcinfo);
4071
4072 if (!PG_ARGISNULL(1))
4074
4076}
4077
4078/*
4079 * Combine function for sum() and avg() interval aggregates.
4080 *
4081 * Combine the given internal aggregate states and place the combination in
4082 * the first argument.
4083 */
4084Datum
4086{
4089
4092
4093 if (state2 == NULL)
4095
4096 if (state1 == NULL)
4097 {
4098 /* manually copy all fields from state2 to state1 */
4099 state1 = makeIntervalAggState(fcinfo);
4100
4101 state1->N = state2->N;
4102 state1->pInfcount = state2->pInfcount;
4103 state1->nInfcount = state2->nInfcount;
4104
4105 state1->sumX.day = state2->sumX.day;
4106 state1->sumX.month = state2->sumX.month;
4107 state1->sumX.time = state2->sumX.time;
4108
4110 }
4111
4112 state1->N += state2->N;
4113 state1->pInfcount += state2->pInfcount;
4114 state1->nInfcount += state2->nInfcount;
4115
4116 /* Accumulate finite interval values, if any. */
4117 if (state2->N > 0)
4118 finite_interval_pl(&state1->sumX, &state2->sumX, &state1->sumX);
4119
4121}
4122
4123/*
4124 * interval_avg_serialize
4125 * Serialize IntervalAggState for interval aggregates.
4126 */
4127Datum
4129{
4132 bytea *result;
4133
4134 /* Ensure we disallow calling when not in aggregate context */
4135 if (!AggCheckCallContext(fcinfo, NULL))
4136 elog(ERROR, "aggregate function called in non-aggregate context");
4137
4139
4141
4142 /* N */
4143 pq_sendint64(&buf, state->N);
4144
4145 /* sumX */
4146 pq_sendint64(&buf, state->sumX.time);
4147 pq_sendint32(&buf, state->sumX.day);
4148 pq_sendint32(&buf, state->sumX.month);
4149
4150 /* pInfcount */
4151 pq_sendint64(&buf, state->pInfcount);
4152
4153 /* nInfcount */
4154 pq_sendint64(&buf, state->nInfcount);
4155
4157
4159}
4160
4161/*
4162 * interval_avg_deserialize
4163 * Deserialize bytea into IntervalAggState for interval aggregates.
4164 */
4165Datum
4167{
4168 bytea *sstate;
4171
4172 if (!AggCheckCallContext(fcinfo, NULL))
4173 elog(ERROR, "aggregate function called in non-aggregate context");
4174
4175 sstate = PG_GETARG_BYTEA_PP(0);
4176
4177 /*
4178 * Initialize a StringInfo so that we can "receive" it using the standard
4179 * recv-function infrastructure.
4180 */
4182 VARSIZE_ANY_EXHDR(sstate));
4183
4185
4186 /* N */
4187 result->N = pq_getmsgint64(&buf);
4188
4189 /* sumX */
4190 result->sumX.time = pq_getmsgint64(&buf);
4191 result->sumX.day = pq_getmsgint(&buf, 4);
4192 result->sumX.month = pq_getmsgint(&buf, 4);
4193
4194 /* pInfcount */
4195 result->pInfcount = pq_getmsgint64(&buf);
4196
4197 /* nInfcount */
4198 result->nInfcount = pq_getmsgint64(&buf);
4199
4200 pq_getmsgend(&buf);
4201
4203}
4204
4205/*
4206 * Inverse transition function for sum() and avg() interval aggregates.
4207 */
4208Datum
4210{
4212
4214
4215 /* Should not get here with no state */
4216 if (state == NULL)
4217 elog(ERROR, "interval_avg_accum_inv called with NULL state");
4218
4219 if (!PG_ARGISNULL(1))
4221
4223}
4224
4225/* avg(interval) aggregate final function */
4226Datum
4228{
4230
4232
4233 /* If there were no non-null inputs, return NULL */
4234 if (state == NULL || IA_TOTAL_COUNT(state) == 0)
4236
4237 /*
4238 * Aggregating infinities that all have the same sign produces infinity
4239 * with that sign. Aggregating infinities with different signs results in
4240 * an error.
4241 */
4242 if (state->pInfcount > 0 || state->nInfcount > 0)
4243 {
4245
4246 if (state->pInfcount > 0 && state->nInfcount > 0)
4247 ereport(ERROR,
4249 errmsg("interval out of range")));
4250
4252 if (state->pInfcount > 0)
4254 else
4256
4258 }
4259
4261 IntervalPGetDatum(&state->sumX),
4262 Float8GetDatum((double) state->N));
4263}
4264
4265/* sum(interval) aggregate final function */
4266Datum
4268{
4271
4273
4274 /* If there were no non-null inputs, return NULL */
4275 if (state == NULL || IA_TOTAL_COUNT(state) == 0)
4277
4278 /*
4279 * Aggregating infinities that all have the same sign produces infinity
4280 * with that sign. Aggregating infinities with different signs results in
4281 * an error.
4282 */
4283 if (state->pInfcount > 0 && state->nInfcount > 0)
4284 ereport(ERROR,
4286 errmsg("interval out of range")));
4287
4289
4290 if (state->pInfcount > 0)
4292 else if (state->nInfcount > 0)
4294 else
4295 memcpy(result, &state->sumX, sizeof(Interval));
4296
4298}
4299
4300/*
4301 * timestamp_age()
4302 * Calculate time difference while retaining year/month fields.
4303 * Note that this does not result in an accurate absolute time span
4304 * since year and month are out of context once the arithmetic
4305 * is done.
4306 */
4307Datum
4309{
4313 fsec_t fsec1,
4314 fsec2;
4315 struct pg_itm tt,
4316 *tm = &tt;
4317 struct pg_tm tt1,
4318 *tm1 = &tt1;
4319 struct pg_tm tt2,
4320 *tm2 = &tt2;
4321
4323
4324 /*
4325 * Handle infinities.
4326 *
4327 * We treat anything that amounts to "infinity - infinity" as an error,
4328 * since the interval type has nothing equivalent to NaN.
4329 */
4331 {
4333 ereport(ERROR,
4335 errmsg("interval out of range")));
4336 else
4338 }
4339 else if (TIMESTAMP_IS_NOEND(dt1))
4340 {
4342 ereport(ERROR,
4344 errmsg("interval out of range")));
4345 else
4347 }
4348 else if (TIMESTAMP_IS_NOBEGIN(dt2))
4350 else if (TIMESTAMP_IS_NOEND(dt2))
4352 else if (timestamp2tm(dt1, NULL, tm1, &fsec1, NULL, NULL) == 0 &&
4353 timestamp2tm(dt2, NULL, tm2, &fsec2, NULL, NULL) == 0)
4354 {
4355 /* form the symbolic difference */
4356 tm->tm_usec = fsec1 - fsec2;
4357 tm->tm_sec = tm1->tm_sec - tm2->tm_sec;
4358 tm->tm_min = tm1->tm_min - tm2->tm_min;
4359 tm->tm_hour = tm1->tm_hour - tm2->tm_hour;
4360 tm->tm_mday = tm1->tm_mday - tm2->tm_mday;
4361 tm->tm_mon = tm1->tm_mon - tm2->tm_mon;
4362 tm->tm_year = tm1->tm_year - tm2->tm_year;
4363
4364 /* flip sign if necessary... */
4365 if (dt1 < dt2)
4366 {
4367 tm->tm_usec = -tm->tm_usec;
4368 tm->tm_sec = -tm->tm_sec;
4369 tm->tm_min = -tm->tm_min;
4370 tm->tm_hour = -tm->tm_hour;
4371 tm->tm_mday = -tm->tm_mday;
4372 tm->tm_mon = -tm->tm_mon;
4373 tm->tm_year = -tm->tm_year;
4374 }
4375
4376 /* propagate any negative fields into the next higher field */
4377 while (tm->tm_usec < 0)
4378 {
4379 tm->tm_usec += USECS_PER_SEC;
4380 tm->tm_sec--;
4381 }
4382
4383 while (tm->tm_sec < 0)
4384 {
4386 tm->tm_min--;
4387 }
4388
4389 while (tm->tm_min < 0)
4390 {
4392 tm->tm_hour--;
4393 }
4394
4395 while (tm->tm_hour < 0)
4396 {
4398 tm->tm_mday--;
4399 }
4400
4401 while (tm->tm_mday < 0)
4402 {
4403 if (dt1 < dt2)
4404 {
4405 tm->tm_mday += day_tab[isleap(tm1->tm_year)][tm1->tm_mon - 1];
4406 tm->tm_mon--;
4407 }
4408 else
4409 {
4410 tm->tm_mday += day_tab[isleap(tm2->tm_year)][tm2->tm_mon - 1];
4411 tm->tm_mon--;
4412 }
4413 }
4414
4415 while (tm->tm_mon < 0)
4416 {
4418 tm->tm_year--;
4419 }
4420
4421 /* recover sign if necessary... */
4422 if (dt1 < dt2)
4423 {
4424 tm->tm_usec = -tm->tm_usec;
4425 tm->tm_sec = -tm->tm_sec;
4426 tm->tm_min = -tm->tm_min;
4427 tm->tm_hour = -tm->tm_hour;
4428 tm->tm_mday = -tm->tm_mday;
4429 tm->tm_mon = -tm->tm_mon;
4430 tm->tm_year = -tm->tm_year;
4431 }
4432
4433 if (itm2interval(tm, result) != 0)
4434 ereport(ERROR,
4436 errmsg("interval out of range")));
4437 }
4438 else
4439 ereport(ERROR,
4441 errmsg("timestamp out of range")));
4442
4444}
4445
4446
4447/*
4448 * timestamptz_age()
4449 * Calculate time difference while retaining year/month fields.
4450 * Note that this does not result in an accurate absolute time span
4451 * since year and month are out of context once the arithmetic
4452 * is done.
4453 */
4454Datum
4456{
4460 fsec_t fsec1,
4461 fsec2;
4462 struct pg_itm tt,
4463 *tm = &tt;
4464 struct pg_tm tt1,
4465 *tm1 = &tt1;
4466 struct pg_tm tt2,
4467 *tm2 = &tt2;
4468 int tz1;
4469 int tz2;
4470
4472
4473 /*
4474 * Handle infinities.
4475 *
4476 * We treat anything that amounts to "infinity - infinity" as an error,
4477 * since the interval type has nothing equivalent to NaN.
4478 */
4480 {
4482 ereport(ERROR,
4484 errmsg("interval out of range")));
4485 else
4487 }
4488 else if (TIMESTAMP_IS_NOEND(dt1))
4489 {
4491 ereport(ERROR,
4493 errmsg("interval out of range")));
4494 else
4496 }
4497 else if (TIMESTAMP_IS_NOBEGIN(dt2))
4499 else if (TIMESTAMP_IS_NOEND(dt2))
4501 else if (timestamp2tm(dt1, &tz1, tm1, &fsec1, NULL, NULL) == 0 &&
4502 timestamp2tm(dt2, &tz2, tm2, &fsec2, NULL, NULL) == 0)
4503 {
4504 /* form the symbolic difference */
4505 tm->tm_usec = fsec1 - fsec2;
4506 tm->tm_sec = tm1->tm_sec - tm2->tm_sec;
4507 tm->tm_min = tm1->tm_min - tm2->tm_min;
4508 tm->tm_hour = tm1->tm_hour - tm2->tm_hour;
4509 tm->tm_mday = tm1->tm_mday - tm2->tm_mday;
4510 tm->tm_mon = tm1->tm_mon - tm2->tm_mon;
4511 tm->tm_year = tm1->tm_year - tm2->tm_year;
4512
4513 /* flip sign if necessary... */
4514 if (dt1 < dt2)
4515 {
4516 tm->tm_usec = -tm->tm_usec;
4517 tm->tm_sec = -tm->tm_sec;
4518 tm->tm_min = -tm->tm_min;
4519 tm->tm_hour = -tm->tm_hour;
4520 tm->tm_mday = -tm->tm_mday;
4521 tm->tm_mon = -tm->tm_mon;
4522 tm->tm_year = -tm->tm_year;
4523 }
4524
4525 /* propagate any negative fields into the next higher field */
4526 while (tm->tm_usec < 0)
4527 {
4528 tm->tm_usec += USECS_PER_SEC;
4529 tm->tm_sec--;
4530 }
4531
4532 while (tm->tm_sec < 0)
4533 {
4535 tm->tm_min--;
4536 }
4537
4538 while (tm->tm_min < 0)
4539 {
4541 tm->tm_hour--;
4542 }
4543
4544 while (tm->tm_hour < 0)
4545 {
4547 tm->tm_mday--;
4548 }
4549
4550 while (tm->tm_mday < 0)
4551 {
4552 if (dt1 < dt2)
4553 {
4554 tm->tm_mday += day_tab[isleap(tm1->tm_year)][tm1->tm_mon - 1];
4555 tm->tm_mon--;
4556 }
4557 else
4558 {
4559 tm->tm_mday += day_tab[isleap(tm2->tm_year)][tm2->tm_mon - 1];
4560 tm->tm_mon--;
4561 }
4562 }
4563
4564 while (tm->tm_mon < 0)
4565 {
4567 tm->tm_year--;
4568 }
4569
4570 /*
4571 * Note: we deliberately ignore any difference between tz1 and tz2.
4572 */
4573
4574 /* recover sign if necessary... */
4575 if (dt1 < dt2)
4576 {
4577 tm->tm_usec = -tm->tm_usec;
4578 tm->tm_sec = -tm->tm_sec;
4579 tm->tm_min = -tm->tm_min;
4580 tm->tm_hour = -tm->tm_hour;
4581 tm->tm_mday = -tm->tm_mday;
4582 tm->tm_mon = -tm->tm_mon;
4583 tm->tm_year = -tm->tm_year;
4584 }
4585
4586 if (itm2interval(tm, result) != 0)
4587 ereport(ERROR,
4589 errmsg("interval out of range")));
4590 }
4591 else
4592 ereport(ERROR,
4594 errmsg("timestamp out of range")));
4595
4597}
4598
4599
4600/*----------------------------------------------------------
4601 * Conversion operators.
4602 *---------------------------------------------------------*/
4603
4604
4605/*
4606 * timestamp_bin()
4607 * Bin timestamp into specified interval.
4608 */
4609Datum
4611{
4614 Timestamp origin = PG_GETARG_TIMESTAMP(2);
4617 tm_diff,
4618 tm_modulo,
4619 tm_delta;
4620
4623
4624 if (TIMESTAMP_NOT_FINITE(origin))
4625 ereport(ERROR,
4627 errmsg("origin out of range")));
4628
4630 ereport(ERROR,
4632 errmsg("timestamps cannot be binned into infinite intervals")));
4633
4634 if (stride->month != 0)
4635 ereport(ERROR,
4637 errmsg("timestamps cannot be binned into intervals containing months or years")));
4638
4641 ereport(ERROR,
4643 errmsg("interval out of range")));
4644
4645 if (stride_usecs <= 0)
4646 ereport(ERROR,
4648 errmsg("stride must be greater than zero")));
4649
4651 ereport(ERROR,
4653 errmsg("interval out of range")));
4654
4655 /* These calculations cannot overflow */
4658 result = origin + tm_delta;
4659
4660 /*
4661 * We want to round towards -infinity, not 0, when tm_diff is negative and
4662 * not a multiple of stride_usecs. This adjustment *can* cause overflow,
4663 * since the result might now be out of the range origin .. timestamp.
4664 */
4665 if (tm_modulo < 0)
4666 {
4669 ereport(ERROR,
4671 errmsg("timestamp out of range")));
4672 }
4673
4675}
4676
4677/*
4678 * timestamp_trunc()
4679 * Truncate timestamp to specified units.
4680 */
4681Datum
4683{
4687 int type,
4688 val;
4689 char *lowunits;
4690 fsec_t fsec;
4691 struct pg_tm tt,
4692 *tm = &tt;
4693
4696 false);
4697
4698 type = DecodeUnits(0, lowunits, &val);
4699
4700 if (type == UNITS)
4701 {
4703 {
4704 /*
4705 * Errors thrown here for invalid units should exactly match those
4706 * below, else there will be unexpected discrepancies between
4707 * finite- and infinite-input cases.
4708 */
4709 switch (val)
4710 {
4711 case DTK_WEEK:
4712 case DTK_MILLENNIUM:
4713 case DTK_CENTURY:
4714 case DTK_DECADE:
4715 case DTK_YEAR:
4716 case DTK_QUARTER:
4717 case DTK_MONTH:
4718 case DTK_DAY:
4719 case DTK_HOUR:
4720 case DTK_MINUTE:
4721 case DTK_SECOND:
4722 case DTK_MILLISEC:
4723 case DTK_MICROSEC:
4725 break;
4726 default:
4727 ereport(ERROR,
4729 errmsg("unit \"%s\" not supported for type %s",
4731 result = 0;
4732 }
4733 }
4734
4735 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
4736 ereport(ERROR,
4738 errmsg("timestamp out of range")));
4739
4740 switch (val)
4741 {
4742 case DTK_WEEK:
4743 {
4744 int woy;
4745
4747
4748 /*
4749 * If it is week 52/53 and the month is January, then the
4750 * week must belong to the previous year. Also, some
4751 * December dates belong to the next year.
4752 */
4753 if (woy >= 52 && tm->tm_mon == 1)
4754 --tm->tm_year;
4756 ++tm->tm_year;
4757 isoweek2date(woy, &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
4758 tm->tm_hour = 0;
4759 tm->tm_min = 0;
4760 tm->tm_sec = 0;
4761 fsec = 0;
4762 break;
4763 }
4764 case DTK_MILLENNIUM:
4765 /* see comments in timestamptz_trunc */
4766 if (tm->tm_year > 0)
4767 tm->tm_year = ((tm->tm_year + 999) / 1000) * 1000 - 999;
4768 else
4769 tm->tm_year = -((999 - (tm->tm_year - 1)) / 1000) * 1000 + 1;
4771 case DTK_CENTURY:
4772 /* see comments in timestamptz_trunc */
4773 if (tm->tm_year > 0)
4774 tm->tm_year = ((tm->tm_year + 99) / 100) * 100 - 99;
4775 else
4776 tm->tm_year = -((99 - (tm->tm_year - 1)) / 100) * 100 + 1;
4778 case DTK_DECADE:
4779 /* see comments in timestamptz_trunc */
4780 if (val != DTK_MILLENNIUM && val != DTK_CENTURY)
4781 {
4782 if (tm->tm_year > 0)
4783 tm->tm_year = (tm->tm_year / 10) * 10;
4784 else
4785 tm->tm_year = -((8 - (tm->tm_year - 1)) / 10) * 10;
4786 }
4788 case DTK_YEAR:
4789 tm->tm_mon = 1;
4791 case DTK_QUARTER:
4792 tm->tm_mon = (3 * ((tm->tm_mon - 1) / 3)) + 1;
4794 case DTK_MONTH:
4795 tm->tm_mday = 1;
4797 case DTK_DAY:
4798 tm->tm_hour = 0;
4800 case DTK_HOUR:
4801 tm->tm_min = 0;
4803 case DTK_MINUTE:
4804 tm->tm_sec = 0;
4806 case DTK_SECOND:
4807 fsec = 0;
4808 break;
4809
4810 case DTK_MILLISEC:
4811 fsec = (fsec / 1000) * 1000;
4812 break;
4813
4814 case DTK_MICROSEC:
4815 break;
4816
4817 default:
4818 ereport(ERROR,
4820 errmsg("unit \"%s\" not supported for type %s",
4822 result = 0;
4823 }
4824
4825 if (tm2timestamp(tm, fsec, NULL, &result) != 0)
4826 ereport(ERROR,
4828 errmsg("timestamp out of range")));
4829 }
4830 else
4831 {
4832 ereport(ERROR,
4834 errmsg("unit \"%s\" not recognized for type %s",
4836 result = 0;
4837 }
4838
4840}
4841
4842/*
4843 * timestamptz_bin()
4844 * Bin timestamptz into specified interval using specified origin.
4845 */
4846Datum
4848{
4854 tm_diff,
4855 tm_modulo,
4856 tm_delta;
4857
4860
4861 if (TIMESTAMP_NOT_FINITE(origin))
4862 ereport(ERROR,
4864 errmsg("origin out of range")));
4865
4867 ereport(ERROR,
4869 errmsg("timestamps cannot be binned into infinite intervals")));
4870
4871 if (stride->month != 0)
4872 ereport(ERROR,
4874 errmsg("timestamps cannot be binned into intervals containing months or years")));
4875
4878 ereport(ERROR,
4880 errmsg("interval out of range")));
4881
4882 if (stride_usecs <= 0)
4883 ereport(ERROR,
4885 errmsg("stride must be greater than zero")));
4886
4888 ereport(ERROR,
4890 errmsg("interval out of range")));
4891
4892 /* These calculations cannot overflow */
4895 result = origin + tm_delta;
4896
4897 /*
4898 * We want to round towards -infinity, not 0, when tm_diff is negative and
4899 * not a multiple of stride_usecs. This adjustment *can* cause overflow,
4900 * since the result might now be out of the range origin .. timestamp.
4901 */
4902 if (tm_modulo < 0)
4903 {
4906 ereport(ERROR,
4908 errmsg("timestamp out of range")));
4909 }
4910
4912}
4913
4914/*
4915 * Common code for timestamptz_trunc() and timestamptz_trunc_zone().
4916 *
4917 * tzp identifies the zone to truncate with respect to. We assume
4918 * infinite timestamps have already been rejected.
4919 */
4920static TimestampTz
4922{
4924 int tz;
4925 int type,
4926 val;
4927 bool redotz = false;
4928 char *lowunits;
4929 fsec_t fsec;
4930 struct pg_tm tt,
4931 *tm = &tt;
4932
4935 false);
4936
4937 type = DecodeUnits(0, lowunits, &val);
4938
4939 if (type == UNITS)
4940 {
4942 {
4943 /*
4944 * Errors thrown here for invalid units should exactly match those
4945 * below, else there will be unexpected discrepancies between
4946 * finite- and infinite-input cases.
4947 */
4948 switch (val)
4949 {
4950 case DTK_WEEK:
4951 case DTK_MILLENNIUM:
4952 case DTK_CENTURY:
4953 case DTK_DECADE:
4954 case DTK_YEAR:
4955 case DTK_QUARTER:
4956 case DTK_MONTH:
4957 case DTK_DAY:
4958 case DTK_HOUR:
4959 case DTK_MINUTE:
4960 case DTK_SECOND:
4961 case DTK_MILLISEC:
4962 case DTK_MICROSEC:
4963 return timestamp;
4964 break;
4965
4966 default:
4967 ereport(ERROR,
4969 errmsg("unit \"%s\" not supported for type %s",
4971 result = 0;
4972 }
4973 }
4974
4975 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, tzp) != 0)
4976 ereport(ERROR,
4978 errmsg("timestamp out of range")));
4979
4980 switch (val)
4981 {
4982 case DTK_WEEK:
4983 {
4984 int woy;
4985
4987
4988 /*
4989 * If it is week 52/53 and the month is January, then the
4990 * week must belong to the previous year. Also, some
4991 * December dates belong to the next year.
4992 */
4993 if (woy >= 52 && tm->tm_mon == 1)
4994 --tm->tm_year;
4996 ++tm->tm_year;
4997 isoweek2date(woy, &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
4998 tm->tm_hour = 0;
4999 tm->tm_min = 0;
5000 tm->tm_sec = 0;
5001 fsec = 0;
5002 redotz = true;
5003 break;
5004 }
5005 /* one may consider DTK_THOUSAND and DTK_HUNDRED... */
5006 case DTK_MILLENNIUM:
5007
5008 /*
5009 * truncating to the millennium? what is this supposed to
5010 * mean? let us put the first year of the millennium... i.e.
5011 * -1000, 1, 1001, 2001...
5012 */
5013 if (tm->tm_year > 0)
5014 tm->tm_year = ((tm->tm_year + 999) / 1000) * 1000 - 999;
5015 else
5016 tm->tm_year = -((999 - (tm->tm_year - 1)) / 1000) * 1000 + 1;
5018 case DTK_CENTURY:
5019 /* truncating to the century? as above: -100, 1, 101... */
5020 if (tm->tm_year > 0)
5021 tm->tm_year = ((tm->tm_year + 99) / 100) * 100 - 99;
5022 else
5023 tm->tm_year = -((99 - (tm->tm_year - 1)) / 100) * 100 + 1;
5025 case DTK_DECADE:
5026
5027 /*
5028 * truncating to the decade? first year of the decade. must
5029 * not be applied if year was truncated before!
5030 */
5031 if (val != DTK_MILLENNIUM && val != DTK_CENTURY)
5032 {
5033 if (tm->tm_year > 0)
5034 tm->tm_year = (tm->tm_year / 10) * 10;
5035 else
5036 tm->tm_year = -((8 - (tm->tm_year - 1)) / 10) * 10;
5037 }
5039 case DTK_YEAR:
5040 tm->tm_mon = 1;
5042 case DTK_QUARTER:
5043 tm->tm_mon = (3 * ((tm->tm_mon - 1) / 3)) + 1;
5045 case DTK_MONTH:
5046 tm->tm_mday = 1;
5048 case DTK_DAY:
5049 tm->tm_hour = 0;
5050 redotz = true; /* for all cases >= DAY */
5052 case DTK_HOUR:
5053 tm->tm_min = 0;
5055 case DTK_MINUTE:
5056 tm->tm_sec = 0;
5058 case DTK_SECOND:
5059 fsec = 0;
5060 break;
5061 case DTK_MILLISEC:
5062 fsec = (fsec / 1000) * 1000;
5063 break;
5064 case DTK_MICROSEC:
5065 break;
5066
5067 default:
5068 ereport(ERROR,
5070 errmsg("unit \"%s\" not supported for type %s",
5072 result = 0;
5073 }
5074
5075 if (redotz)
5076 tz = DetermineTimeZoneOffset(tm, tzp);
5077
5078 if (tm2timestamp(tm, fsec, &tz, &result) != 0)
5079 ereport(ERROR,
5081 errmsg("timestamp out of range")));
5082 }
5083 else
5084 {
5085 ereport(ERROR,
5087 errmsg("unit \"%s\" not recognized for type %s",
5089 result = 0;
5090 }
5091
5092 return result;
5093}
5094
5095/*
5096 * timestamptz_trunc()
5097 * Truncate timestamptz to specified units in session timezone.
5098 */
5099Datum
5110
5111/*
5112 * timestamptz_trunc_zone()
5113 * Truncate timestamptz to specified units in specified timezone.
5114 */
5115Datum
5117{
5122 pg_tz *tzp;
5123
5124 /*
5125 * Look up the requested timezone.
5126 */
5127 tzp = lookup_timezone(zone);
5128
5130
5132}
5133
5134/*
5135 * interval_trunc()
5136 * Extract specified field from interval.
5137 */
5138Datum
5140{
5144 int type,
5145 val;
5146 char *lowunits;
5147 struct pg_itm tt,
5148 *tm = &tt;
5149
5151
5154 false);
5155
5156 type = DecodeUnits(0, lowunits, &val);
5157
5158 if (type == UNITS)
5159 {
5161 {
5162 /*
5163 * Errors thrown here for invalid units should exactly match those
5164 * below, else there will be unexpected discrepancies between
5165 * finite- and infinite-input cases.
5166 */
5167 switch (val)
5168 {
5169 case DTK_MILLENNIUM:
5170 case DTK_CENTURY:
5171 case DTK_DECADE:
5172 case DTK_YEAR:
5173 case DTK_QUARTER:
5174 case DTK_MONTH:
5175 case DTK_DAY:
5176 case DTK_HOUR:
5177 case DTK_MINUTE:
5178 case DTK_SECOND:
5179 case DTK_MILLISEC:
5180 case DTK_MICROSEC:
5181 memcpy(result, interval, sizeof(Interval));
5183 break;
5184
5185 default:
5186 ereport(ERROR,
5188 errmsg("unit \"%s\" not supported for type %s",
5190 (val == DTK_WEEK) ? errdetail("Months usually have fractional weeks.") : 0));
5191 result = NULL;
5192 }
5193 }
5194
5196 switch (val)
5197 {
5198 case DTK_MILLENNIUM:
5199 /* caution: C division may have negative remainder */
5200 tm->tm_year = (tm->tm_year / 1000) * 1000;
5202 case DTK_CENTURY:
5203 /* caution: C division may have negative remainder */
5204 tm->tm_year = (tm->tm_year / 100) * 100;
5206 case DTK_DECADE:
5207 /* caution: C division may have negative remainder */
5208 tm->tm_year = (tm->tm_year / 10) * 10;
5210 case DTK_YEAR:
5211 tm->tm_mon = 0;
5213 case DTK_QUARTER:
5214 tm->tm_mon = 3 * (tm->tm_mon / 3);
5216 case DTK_MONTH:
5217 tm->tm_mday = 0;
5219 case DTK_DAY:
5220 tm->tm_hour = 0;
5222 case DTK_HOUR:
5223 tm->tm_min = 0;
5225 case DTK_MINUTE:
5226 tm->tm_sec = 0;
5228 case DTK_SECOND:
5229 tm->tm_usec = 0;
5230 break;
5231 case DTK_MILLISEC:
5232 tm->tm_usec = (tm->tm_usec / 1000) * 1000;
5233 break;
5234 case DTK_MICROSEC:
5235 break;
5236
5237 default:
5238 ereport(ERROR,
5240 errmsg("unit \"%s\" not supported for type %s",
5242 (val == DTK_WEEK) ? errdetail("Months usually have fractional weeks.") : 0));
5243 }
5244
5245 if (itm2interval(tm, result) != 0)
5246 ereport(ERROR,
5248 errmsg("interval out of range")));
5249 }
5250 else
5251 {
5252 ereport(ERROR,
5254 errmsg("unit \"%s\" not recognized for type %s",
5256 }
5257
5259}
5260
5261/*
5262 * isoweek2j()
5263 *
5264 * Return the Julian day which corresponds to the first day (Monday) of the given ISO 8601 year and week.
5265 * Julian days are used to convert between ISO week dates and Gregorian dates.
5266 *
5267 * XXX: This function has integer overflow hazards, but restructuring it to
5268 * work with the soft-error handling that its callers do is likely more
5269 * trouble than it's worth.
5270 */
5271int
5272isoweek2j(int year, int week)
5273{
5274 int day0,
5275 day4;
5276
5277 /* fourth day of current year */
5278 day4 = date2j(year, 1, 4);
5279
5280 /* day0 == offset to first day of week (Monday) */
5281 day0 = j2day(day4 - 1);
5282
5283 return ((week - 1) * 7) + (day4 - day0);
5284}
5285
5286/*
5287 * isoweek2date()
5288 * Convert ISO week of year number to date.
5289 * The year field must be specified with the ISO year!
5290 * karel 2000/08/07
5291 */
5292void
5293isoweek2date(int woy, int *year, int *mon, int *mday)
5294{
5295 j2date(isoweek2j(*year, woy), year, mon, mday);
5296}
5297
5298/*
5299 * isoweekdate2date()
5300 *
5301 * Convert an ISO 8601 week date (ISO year, ISO week) into a Gregorian date.
5302 * Gregorian day of week sent so weekday strings can be supplied.
5303 * Populates year, mon, and mday with the correct Gregorian values.
5304 * year must be passed in as the ISO year.
5305 */
5306void
5307isoweekdate2date(int isoweek, int wday, int *year, int *mon, int *mday)
5308{
5309 int jday;
5310
5311 jday = isoweek2j(*year, isoweek);
5312 /* convert Gregorian week start (Sunday=1) to ISO week start (Monday=1) */
5313 if (wday > 1)
5314 jday += wday - 2;
5315 else
5316 jday += 6;
5317 j2date(jday, year, mon, mday);
5318}
5319
5320/*
5321 * date2isoweek()
5322 *
5323 * Returns ISO week number of year.
5324 */
5325int
5326date2isoweek(int year, int mon, int mday)
5327{
5328 int day0,
5329 day4,
5330 dayn,
5331 week;
5332
5333 /* current day */
5334 dayn = date2j(year, mon, mday);
5335
5336 /* fourth day of current year */
5337 day4 = date2j(year, 1, 4);
5338
5339 /* day0 == offset to first day of week (Monday) */
5340 day0 = j2day(day4 - 1);
5341
5342 /*
5343 * We need the first week containing a Thursday, otherwise this day falls
5344 * into the previous year for purposes of counting weeks
5345 */
5346 if (dayn < day4 - day0)
5347 {
5348 day4 = date2j(year - 1, 1, 4);
5349
5350 /* day0 == offset to first day of week (Monday) */
5351 day0 = j2day(day4 - 1);
5352 }
5353
5354 week = (dayn - (day4 - day0)) / 7 + 1;
5355
5356 /*
5357 * Sometimes the last few days in a year will fall into the first week of
5358 * the next year, so check for this.
5359 */
5360 if (week >= 52)
5361 {
5362 day4 = date2j(year + 1, 1, 4);
5363
5364 /* day0 == offset to first day of week (Monday) */
5365 day0 = j2day(day4 - 1);
5366
5367 if (dayn >= day4 - day0)
5368 week = (dayn - (day4 - day0)) / 7 + 1;
5369 }
5370
5371 return week;
5372}
5373
5374
5375/*
5376 * date2isoyear()
5377 *
5378 * Returns ISO 8601 year number.
5379 * Note: zero or negative results follow the year-zero-exists convention.
5380 */
5381int
5382date2isoyear(int year, int mon, int mday)
5383{
5384 int day0,
5385 day4,
5386 dayn,
5387 week;
5388
5389 /* current day */
5390 dayn = date2j(year, mon, mday);
5391
5392 /* fourth day of current year */
5393 day4 = date2j(year, 1, 4);
5394
5395 /* day0 == offset to first day of week (Monday) */
5396 day0 = j2day(day4 - 1);
5397
5398 /*
5399 * We need the first week containing a Thursday, otherwise this day falls
5400 * into the previous year for purposes of counting weeks
5401 */
5402 if (dayn < day4 - day0)
5403 {
5404 day4 = date2j(year - 1, 1, 4);
5405
5406 /* day0 == offset to first day of week (Monday) */
5407 day0 = j2day(day4 - 1);
5408
5409 year--;
5410 }
5411
5412 week = (dayn - (day4 - day0)) / 7 + 1;
5413
5414 /*
5415 * Sometimes the last few days in a year will fall into the first week of
5416 * the next year, so check for this.
5417 */
5418 if (week >= 52)
5419 {
5420 day4 = date2j(year + 1, 1, 4);
5421
5422 /* day0 == offset to first day of week (Monday) */
5423 day0 = j2day(day4 - 1);
5424
5425 if (dayn >= day4 - day0)
5426 year++;
5427 }
5428
5429 return year;
5430}
5431
5432
5433/*
5434 * date2isoyearday()
5435 *
5436 * Returns the ISO 8601 day-of-year, given a Gregorian year, month and day.
5437 * Possible return values are 1 through 371 (364 in non-leap years).
5438 */
5439int
5440date2isoyearday(int year, int mon, int mday)
5441{
5442 return date2j(year, mon, mday) - isoweek2j(date2isoyear(year, mon, mday), 1) + 1;
5443}
5444
5445/*
5446 * NonFiniteTimestampTzPart
5447 *
5448 * Used by timestamp_part and timestamptz_part when extracting from infinite
5449 * timestamp[tz]. Returns +/-Infinity if that is the appropriate result,
5450 * otherwise returns zero (which should be taken as meaning to return NULL).
5451 *
5452 * Errors thrown here for invalid units should exactly match those that
5453 * would be thrown in the calling functions, else there will be unexpected
5454 * discrepancies between finite- and infinite-input cases.
5455 */
5456static float8
5458 bool isNegative, bool isTz)
5459{
5460 if ((type != UNITS) && (type != RESERV))
5461 ereport(ERROR,
5463 errmsg("unit \"%s\" not recognized for type %s",
5464 lowunits,
5466
5467 switch (unit)
5468 {
5469 /* Oscillating units */
5470 case DTK_MICROSEC:
5471 case DTK_MILLISEC:
5472 case DTK_SECOND:
5473 case DTK_MINUTE:
5474 case DTK_HOUR:
5475 case DTK_DAY:
5476 case DTK_MONTH:
5477 case DTK_QUARTER:
5478 case DTK_WEEK:
5479 case DTK_DOW:
5480 case DTK_ISODOW:
5481 case DTK_DOY:
5482 case DTK_TZ:
5483 case DTK_TZ_MINUTE:
5484 case DTK_TZ_HOUR:
5485 return 0.0;
5486
5487 /* Monotonically-increasing units */
5488 case DTK_YEAR:
5489 case DTK_DECADE:
5490 case DTK_CENTURY:
5491 case DTK_MILLENNIUM:
5492 case DTK_JULIAN:
5493 case DTK_ISOYEAR:
5494 case DTK_EPOCH:
5495 if (isNegative)
5496 return -get_float8_infinity();
5497 else
5498 return get_float8_infinity();
5499
5500 default:
5501 ereport(ERROR,
5503 errmsg("unit \"%s\" not supported for type %s",
5504 lowunits,
5506 return 0.0; /* keep compiler quiet */
5507 }
5508}
5509
5510/*
5511 * timestamp_part() and extract_timestamp()
5512 * Extract specified field from timestamp.
5513 */
5514static Datum
5516{
5521 int type,
5522 val;
5523 char *lowunits;
5524 fsec_t fsec;
5525 struct pg_tm tt,
5526 *tm = &tt;
5527
5530 false);
5531
5532 type = DecodeUnits(0, lowunits, &val);
5533 if (type == UNKNOWN_FIELD)
5535
5537 {
5540 false);
5541
5542 if (r != 0.0)
5543 {
5544 if (retnumeric)
5545 {
5546 if (r < 0)
5548 CStringGetDatum("-Infinity"),
5550 Int32GetDatum(-1));
5551 else if (r > 0)
5553 CStringGetDatum("Infinity"),
5555 Int32GetDatum(-1));
5556 }
5557 else
5559 }
5560 else
5562 }
5563
5564 if (type == UNITS)
5565 {
5566 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
5567 ereport(ERROR,
5569 errmsg("timestamp out of range")));
5570
5571 switch (val)
5572 {
5573 case DTK_MICROSEC:
5574 intresult = tm->tm_sec * INT64CONST(1000000) + fsec;
5575 break;
5576
5577 case DTK_MILLISEC:
5578 if (retnumeric)
5579 /*---
5580 * tm->tm_sec * 1000 + fsec / 1000
5581 * = (tm->tm_sec * 1'000'000 + fsec) / 1000
5582 */
5584 else
5585 PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + fsec / 1000.0);
5586 break;
5587
5588 case DTK_SECOND:
5589 if (retnumeric)
5590 /*---
5591 * tm->tm_sec + fsec / 1'000'000
5592 * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
5593 */
5595 else
5596 PG_RETURN_FLOAT8(tm->tm_sec + fsec / 1000000.0);
5597 break;
5598
5599 case DTK_MINUTE:
5600 intresult = tm->tm_min;
5601 break;
5602
5603 case DTK_HOUR:
5604 intresult = tm->tm_hour;
5605 break;
5606
5607 case DTK_DAY:
5608 intresult = tm->tm_mday;
5609 break;
5610
5611 case DTK_MONTH:
5612 intresult = tm->tm_mon;
5613 break;
5614
5615 case DTK_QUARTER:
5616 intresult = (tm->tm_mon - 1) / 3 + 1;
5617 break;
5618
5619 case DTK_WEEK:
5621 break;
5622
5623 case DTK_YEAR:
5624 if (tm->tm_year > 0)
5625 intresult = tm->tm_year;
5626 else
5627 /* there is no year 0, just 1 BC and 1 AD */
5628 intresult = tm->tm_year - 1;
5629 break;
5630
5631 case DTK_DECADE:
5632
5633 /*
5634 * what is a decade wrt dates? let us assume that decade 199
5635 * is 1990 thru 1999... decade 0 starts on year 1 BC, and -1
5636 * is 11 BC thru 2 BC...
5637 */
5638 if (tm->tm_year >= 0)
5639 intresult = tm->tm_year / 10;
5640 else
5641 intresult = -((8 - (tm->tm_year - 1)) / 10);
5642 break;
5643
5644 case DTK_CENTURY:
5645
5646 /* ----
5647 * centuries AD, c>0: year in [ (c-1)* 100 + 1 : c*100 ]
5648 * centuries BC, c<0: year in [ c*100 : (c+1) * 100 - 1]
5649 * there is no number 0 century.
5650 * ----
5651 */
5652 if (tm->tm_year > 0)
5653 intresult = (tm->tm_year + 99) / 100;
5654 else
5655 /* caution: C division may have negative remainder */
5656 intresult = -((99 - (tm->tm_year - 1)) / 100);
5657 break;
5658
5659 case DTK_MILLENNIUM:
5660 /* see comments above. */
5661 if (tm->tm_year > 0)
5662 intresult = (tm->tm_year + 999) / 1000;
5663 else
5664 intresult = -((999 - (tm->tm_year - 1)) / 1000);
5665 break;
5666
5667 case DTK_JULIAN:
5668 if (retnumeric)
5672 NULL),
5673 NULL));
5674 else
5677 tm->tm_sec + (fsec / 1000000.0)) / (double) SECS_PER_DAY);
5678 break;
5679
5680 case DTK_ISOYEAR:
5682 /* Adjust BC years */
5683 if (intresult <= 0)
5684 intresult -= 1;
5685 break;
5686
5687 case DTK_DOW:
5688 case DTK_ISODOW:
5690 if (val == DTK_ISODOW && intresult == 0)
5691 intresult = 7;
5692 break;
5693
5694 case DTK_DOY:
5696 - date2j(tm->tm_year, 1, 1) + 1);
5697 break;
5698
5699 case DTK_TZ:
5700 case DTK_TZ_MINUTE:
5701 case DTK_TZ_HOUR:
5702 default:
5703 ereport(ERROR,
5705 errmsg("unit \"%s\" not supported for type %s",
5707 intresult = 0;
5708 }
5709 }
5710 else if (type == RESERV)
5711 {
5712 switch (val)
5713 {
5714 case DTK_EPOCH:
5716 /* (timestamp - epoch) / 1000000 */
5717 if (retnumeric)
5718 {
5720
5721 if (timestamp < (PG_INT64_MAX + epoch))
5723 else
5724 {
5727 NULL),
5728 int64_to_numeric(1000000),
5729 NULL);
5732 Int32GetDatum(6)));
5733 }
5735 }
5736 else
5737 {
5738 float8 result;
5739
5740 /* try to avoid precision loss in subtraction */
5741 if (timestamp < (PG_INT64_MAX + epoch))
5742 result = (timestamp - epoch) / 1000000.0;
5743 else
5744 result = ((float8) timestamp - epoch) / 1000000.0;
5746 }
5747 break;
5748
5749 default:
5750 ereport(ERROR,
5752 errmsg("unit \"%s\" not supported for type %s",
5754 intresult = 0;
5755 }
5756 }
5757 else
5758 {
5759 ereport(ERROR,
5761 errmsg("unit \"%s\" not recognized for type %s",
5763 intresult = 0;
5764 }
5765
5766 if (retnumeric)
5768 else
5770}
5771
5772Datum
5774{
5775 return timestamp_part_common(fcinfo, false);
5776}
5777
5778Datum
5780{
5781 return timestamp_part_common(fcinfo, true);
5782}
5783
5784/*
5785 * timestamptz_part() and extract_timestamptz()
5786 * Extract specified field from timestamp with time zone.
5787 */
5788static Datum
5790{
5795 int tz;
5796 int type,
5797 val;
5798 char *lowunits;
5799 fsec_t fsec;
5800 struct pg_tm tt,
5801 *tm = &tt;
5802
5805 false);
5806
5807 type = DecodeUnits(0, lowunits, &val);
5808 if (type == UNKNOWN_FIELD)
5810
5812 {
5815 true);
5816
5817 if (r != 0.0)
5818 {
5819 if (retnumeric)
5820 {
5821 if (r < 0)
5823 CStringGetDatum("-Infinity"),
5825 Int32GetDatum(-1));
5826 else if (r > 0)
5828 CStringGetDatum("Infinity"),
5830 Int32GetDatum(-1));
5831 }
5832 else
5834 }
5835 else
5837 }
5838
5839 if (type == UNITS)
5840 {
5841 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
5842 ereport(ERROR,
5844 errmsg("timestamp out of range")));
5845
5846 switch (val)
5847 {
5848 case DTK_TZ:
5849 intresult = -tz;
5850 break;
5851
5852 case DTK_TZ_MINUTE:
5854 break;
5855
5856 case DTK_TZ_HOUR:
5857 intresult = -tz / SECS_PER_HOUR;
5858 break;
5859
5860 case DTK_MICROSEC:
5861 intresult = tm->tm_sec * INT64CONST(1000000) + fsec;
5862 break;
5863
5864 case DTK_MILLISEC:
5865 if (retnumeric)
5866 /*---
5867 * tm->tm_sec * 1000 + fsec / 1000
5868 * = (tm->tm_sec * 1'000'000 + fsec) / 1000
5869 */
5871 else
5872 PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + fsec / 1000.0);
5873 break;
5874
5875 case DTK_SECOND:
5876 if (retnumeric)
5877 /*---
5878 * tm->tm_sec + fsec / 1'000'000
5879 * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
5880 */
5882 else
5883 PG_RETURN_FLOAT8(tm->tm_sec + fsec / 1000000.0);
5884 break;
5885
5886 case DTK_MINUTE:
5887 intresult = tm->tm_min;
5888 break;
5889
5890 case DTK_HOUR:
5891 intresult = tm->tm_hour;
5892 break;
5893
5894 case DTK_DAY:
5895 intresult = tm->tm_mday;
5896 break;
5897
5898 case DTK_MONTH:
5899 intresult = tm->tm_mon;
5900 break;
5901
5902 case DTK_QUARTER:
5903 intresult = (tm->tm_mon - 1) / 3 + 1;
5904 break;
5905
5906 case DTK_WEEK:
5908 break;
5909
5910 case DTK_YEAR:
5911 if (tm->tm_year > 0)
5912 intresult = tm->tm_year;
5913 else
5914 /* there is no year 0, just 1 BC and 1 AD */
5915 intresult = tm->tm_year - 1;
5916 break;
5917
5918 case DTK_DECADE:
5919 /* see comments in timestamp_part */
5920 if (tm->tm_year > 0)
5921 intresult = tm->tm_year / 10;
5922 else
5923 intresult = -((8 - (tm->tm_year - 1)) / 10);
5924 break;
5925
5926 case DTK_CENTURY:
5927 /* see comments in timestamp_part */
5928 if (tm->tm_year > 0)
5929 intresult = (tm->tm_year + 99) / 100;
5930 else
5931 intresult = -((99 - (tm->tm_year - 1)) / 100);
5932 break;
5933
5934 case DTK_MILLENNIUM:
5935 /* see comments in timestamp_part */
5936 if (tm->tm_year > 0)
5937 intresult = (tm->tm_year + 999) / 1000;
5938 else
5939 intresult = -((999 - (tm->tm_year - 1)) / 1000);
5940 break;
5941
5942 case DTK_JULIAN:
5943 if (retnumeric)
5947 NULL),
5948 NULL));
5949 else
5952 tm->tm_sec + (fsec / 1000000.0)) / (double) SECS_PER_DAY);
5953 break;
5954
5955 case DTK_ISOYEAR:
5957 /* Adjust BC years */
5958 if (intresult <= 0)
5959 intresult -= 1;
5960 break;
5961
5962 case DTK_DOW:
5963 case DTK_ISODOW:
5965 if (val == DTK_ISODOW && intresult == 0)
5966 intresult = 7;
5967 break;
5968
5969 case DTK_DOY:
5971 - date2j(tm->tm_year, 1, 1) + 1);
5972 break;
5973
5974 default:
5975 ereport(ERROR,
5977 errmsg("unit \"%s\" not supported for type %s",
5979 intresult = 0;
5980 }
5981 }
5982 else if (type == RESERV)
5983 {
5984 switch (val)
5985 {
5986 case DTK_EPOCH:
5988 /* (timestamp - epoch) / 1000000 */
5989 if (retnumeric)
5990 {
5992
5993 if (timestamp < (PG_INT64_MAX + epoch))
5995 else
5996 {
5999 NULL),
6000 int64_to_numeric(1000000),
6001 NULL);
6004 Int32GetDatum(6)));
6005 }
6007 }
6008 else
6009 {
6010 float8 result;
6011
6012 /* try to avoid precision loss in subtraction */
6013 if (timestamp < (PG_INT64_MAX + epoch))
6014 result = (timestamp - epoch) / 1000000.0;
6015 else
6016 result = ((float8) timestamp - epoch) / 1000000.0;
6018 }
6019 break;
6020
6021 default:
6022 ereport(ERROR,
6024 errmsg("unit \"%s\" not supported for type %s",
6026 intresult = 0;
6027 }
6028 }
6029 else
6030 {
6031 ereport(ERROR,
6033 errmsg("unit \"%s\" not recognized for type %s",
6035
6036 intresult = 0;
6037 }
6038
6039 if (retnumeric)
6041 else
6043}
6044
6045Datum
6047{
6048 return timestamptz_part_common(fcinfo, false);
6049}
6050
6051Datum
6053{
6054 return timestamptz_part_common(fcinfo, true);
6055}
6056
6057/*
6058 * NonFiniteIntervalPart
6059 *
6060 * Used by interval_part when extracting from infinite interval. Returns
6061 * +/-Infinity if that is the appropriate result, otherwise returns zero
6062 * (which should be taken as meaning to return NULL).
6063 *
6064 * Errors thrown here for invalid units should exactly match those that
6065 * would be thrown in the calling functions, else there will be unexpected
6066 * discrepancies between finite- and infinite-input cases.
6067 */
6068static float8
6070{
6071 if ((type != UNITS) && (type != RESERV))
6072 ereport(ERROR,
6074 errmsg("unit \"%s\" not recognized for type %s",
6076
6077 switch (unit)
6078 {
6079 /* Oscillating units */
6080 case DTK_MICROSEC:
6081 case DTK_MILLISEC:
6082 case DTK_SECOND:
6083 case DTK_MINUTE:
6084 case DTK_WEEK:
6085 case DTK_MONTH:
6086 case DTK_QUARTER:
6087 return 0.0;
6088
6089 /* Monotonically-increasing units */
6090 case DTK_HOUR:
6091 case DTK_DAY:
6092 case DTK_YEAR:
6093 case DTK_DECADE:
6094 case DTK_CENTURY:
6095 case DTK_MILLENNIUM:
6096 case DTK_EPOCH:
6097 if (isNegative)
6098 return -get_float8_infinity();
6099 else
6100 return get_float8_infinity();
6101
6102 default:
6103 ereport(ERROR,
6105 errmsg("unit \"%s\" not supported for type %s",
6107 return 0.0; /* keep compiler quiet */
6108 }
6109}
6110
6111/*
6112 * interval_part() and extract_interval()
6113 * Extract specified field from interval.
6114 */
6115static Datum
6117{
6121 int type,
6122 val;
6123 char *lowunits;
6124 struct pg_itm tt,
6125 *tm = &tt;
6126
6129 false);
6130
6131 type = DecodeUnits(0, lowunits, &val);
6132 if (type == UNKNOWN_FIELD)
6134
6136 {
6139
6140 if (r != 0.0)
6141 {
6142 if (retnumeric)
6143 {
6144 if (r < 0)
6146 CStringGetDatum("-Infinity"),
6148 Int32GetDatum(-1));
6149 else if (r > 0)
6151 CStringGetDatum("Infinity"),
6153 Int32GetDatum(-1));
6154 }
6155 else
6157 }
6158 else
6160 }
6161
6162 if (type == UNITS)
6163 {
6165 switch (val)
6166 {
6167 case DTK_MICROSEC:
6168 intresult = tm->tm_sec * INT64CONST(1000000) + tm->tm_usec;
6169 break;
6170
6171 case DTK_MILLISEC:
6172 if (retnumeric)
6173 /*---
6174 * tm->tm_sec * 1000 + fsec / 1000
6175 * = (tm->tm_sec * 1'000'000 + fsec) / 1000
6176 */
6178 else
6179 PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + tm->tm_usec / 1000.0);
6180 break;
6181
6182 case DTK_SECOND:
6183 if (retnumeric)
6184 /*---
6185 * tm->tm_sec + fsec / 1'000'000
6186 * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
6187 */
6189 else
6190 PG_RETURN_FLOAT8(tm->tm_sec + tm->tm_usec / 1000000.0);
6191 break;
6192
6193 case DTK_MINUTE:
6194 intresult = tm->tm_min;
6195 break;
6196
6197 case DTK_HOUR:
6198 intresult = tm->tm_hour;
6199 break;
6200
6201 case DTK_DAY:
6202 intresult = tm->tm_mday;
6203 break;
6204
6205 case DTK_WEEK:
6206 intresult = tm->tm_mday / 7;
6207 break;
6208
6209 case DTK_MONTH:
6210 intresult = tm->tm_mon;
6211 break;
6212
6213 case DTK_QUARTER:
6214
6215 /*
6216 * We want to maintain the rule that a field extracted from a
6217 * negative interval is the negative of the field's value for
6218 * the sign-reversed interval. The broken-down tm_year and
6219 * tm_mon aren't very helpful for that, so work from
6220 * interval->month.
6221 */
6222 if (interval->month >= 0)
6223 intresult = (tm->tm_mon / 3) + 1;
6224 else
6225 intresult = -(((-interval->month % MONTHS_PER_YEAR) / 3) + 1);
6226 break;
6227
6228 case DTK_YEAR:
6229 intresult = tm->tm_year;
6230 break;
6231
6232 case DTK_DECADE:
6233 /* caution: C division may have negative remainder */
6234 intresult = tm->tm_year / 10;
6235 break;
6236
6237 case DTK_CENTURY:
6238 /* caution: C division may have negative remainder */
6239 intresult = tm->tm_year / 100;
6240 break;
6241
6242 case DTK_MILLENNIUM:
6243 /* caution: C division may have negative remainder */
6244 intresult = tm->tm_year / 1000;
6245 break;
6246
6247 default:
6248 ereport(ERROR,
6250 errmsg("unit \"%s\" not supported for type %s",
6252 intresult = 0;
6253 }
6254 }
6255 else if (type == RESERV && val == DTK_EPOCH)
6256 {
6257 if (retnumeric)
6258 {
6261 int64 val;
6262
6263 /*
6264 * To do this calculation in integer arithmetic even though
6265 * DAYS_PER_YEAR is fractional, multiply everything by 4 and then
6266 * divide by 4 again at the end. This relies on DAYS_PER_YEAR
6267 * being a multiple of 0.25 and on SECS_PER_DAY being a multiple
6268 * of 4.
6269 */
6272 (int64) 4 * interval->day) * (SECS_PER_DAY / 4);
6273
6274 /*---
6275 * result = secs_from_day_month + interval->time / 1'000'000
6276 * = (secs_from_day_month * 1'000'000 + interval->time) / 1'000'000
6277 */
6278
6279 /*
6280 * Try the computation inside int64; if it overflows, do it in
6281 * numeric (slower). This overflow happens around 10^9 days, so
6282 * not common in practice.
6283 */
6284 if (!pg_mul_s64_overflow(secs_from_day_month, 1000000, &val) &&
6287 else
6288 result =
6291 NULL);
6292
6294 }
6295 else
6296 {
6297 float8 result;
6298
6299 result = interval->time / 1000000.0;
6302 result += ((double) SECS_PER_DAY) * interval->day;
6303
6305 }
6306 }
6307 else
6308 {
6309 ereport(ERROR,
6311 errmsg("unit \"%s\" not recognized for type %s",
6313 intresult = 0;
6314 }
6315
6316 if (retnumeric)
6318 else
6320}
6321
6322Datum
6324{
6325 return interval_part_common(fcinfo, false);
6326}
6327
6328Datum
6330{
6331 return interval_part_common(fcinfo, true);
6332}
6333
6334
6335/*
6336 * timestamp_zone()
6337 * Encode timestamp type with specified time zone.
6338 * This function is just timestamp2timestamptz() except instead of
6339 * shifting to the global timezone, we shift to the specified timezone.
6340 * This is different from the other AT TIME ZONE cases because instead
6341 * of shifting _to_ a new time zone, it sets the time to _be_ the
6342 * specified timezone.
6343 */
6344Datum
6346{
6350 int tz;
6351 char tzname[TZ_STRLEN_MAX + 1];
6352 int type,
6353 val;
6354 pg_tz *tzp;
6355 struct pg_tm tm;
6356 fsec_t fsec;
6357
6360
6361 /*
6362 * Look up the requested timezone.
6363 */
6365
6366 type = DecodeTimezoneName(tzname, &val, &tzp);
6367
6369 {
6370 /* fixed-offset abbreviation */
6371 tz = val;
6372 result = dt2local(timestamp, tz);
6373 }
6374 else if (type == TZNAME_DYNTZ)
6375 {
6376 /* dynamic-offset abbreviation, resolve using specified time */
6377 if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, tzp) != 0)
6378 ereport(ERROR,
6380 errmsg("timestamp out of range")));
6382 result = dt2local(timestamp, tz);
6383 }
6384 else
6385 {
6386 /* full zone name, rotate to that zone */
6387 if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, tzp) != 0)
6388 ereport(ERROR,
6390 errmsg("timestamp out of range")));
6391 tz = DetermineTimeZoneOffset(&tm, tzp);
6392 if (tm2timestamp(&tm, fsec, &tz, &result) != 0)
6393 ereport(ERROR,
6395 errmsg("timestamp out of range")));
6396 }
6397
6399 ereport(ERROR,
6401 errmsg("timestamp out of range")));
6402
6404}
6405
6406/*
6407 * timestamp_izone()
6408 * Encode timestamp type with specified time interval as time zone.
6409 */
6410Datum
6412{
6416 int tz;
6417
6420
6422 ereport(ERROR,
6424 errmsg("interval time zone \"%s\" must be finite",
6426 PointerGetDatum(zone))))));
6427
6428 if (zone->month != 0 || zone->day != 0)
6429 ereport(ERROR,
6431 errmsg("interval time zone \"%s\" must not include months or days",
6433 PointerGetDatum(zone))))));
6434
6435 tz = zone->time / USECS_PER_SEC;
6436
6437 result = dt2local(timestamp, tz);
6438
6440 ereport(ERROR,
6442 errmsg("timestamp out of range")));
6443
6445} /* timestamp_izone() */
6446
6447/*
6448 * TimestampTimestampTzRequiresRewrite()
6449 *
6450 * Returns false if the TimeZone GUC setting causes timestamp_timestamptz and
6451 * timestamptz_timestamp to be no-ops, where the return value has the same
6452 * bits as the argument. Since project convention is to assume a GUC changes
6453 * no more often than STABLE functions change, the answer is valid that long.
6454 */
6455bool
6457{
6458 long offset;
6459
6460 if (pg_get_timezone_offset(session_timezone, &offset) && offset == 0)
6461 return false;
6462 return true;
6463}
6464
6465/*
6466 * timestamp_timestamptz()
6467 * Convert local timestamp to timestamp at GMT
6468 */
6469Datum
6481
6482/*
6483 * Convert timestamp to timestamp with time zone.
6484 *
6485 * If the timestamp is finite but out of the valid range for timestamptz,
6486 * error handling proceeds based on escontext.
6487 *
6488 * If escontext is NULL, we throw an out-of-range error (hard error).
6489 * If escontext is not NULL, we return NOBEGIN or NOEND for lower bound or
6490 * upper bound overflow, respectively, and record a soft error.
6491 */
6494{
6496 struct pg_tm tt,
6497 *tm = &tt;
6498 fsec_t fsec;
6499 int tz;
6500
6502 return timestamp;
6503
6504 /* timestamp2tm should not fail on valid timestamps, but cope */
6505 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) == 0)
6506 {
6508
6509 result = dt2local(timestamp, -tz);
6510
6512 return result;
6513 }
6514
6515 if (timestamp < 0)
6517 else
6519
6520 ereturn(escontext, result,
6522 errmsg("timestamp out of range")));
6523}
6524
6525/*
6526 * Promote timestamp to timestamptz, throwing error for overflow.
6527 */
6528static TimestampTz
6533
6534/*
6535 * timestamptz_timestamp()
6536 * Convert timestamp at GMT to local timestamp
6537 */
6538Datum
6550
6551/*
6552 * Convert timestamptz to timestamp, throwing error for overflow.
6553 */
6554static Timestamp
6559
6560/*
6561 * Convert timestamp with time zone to timestamp.
6562 *
6563 * If the timestamptz is finite but out of the valid range for timestamp,
6564 * error handling proceeds based on escontext.
6565 *
6566 * If escontext is NULL, we throw an out-of-range error (hard error).
6567 * If escontext is not NULL, we return NOBEGIN or NOEND for lower bound or
6568 * upper bound overflow, respectively, and record a soft error.
6569 */
6572{
6574 struct pg_tm tt,
6575 *tm = &tt;
6576 fsec_t fsec;
6577 int tz;
6578
6580 result = timestamp;
6581 else
6582 {
6583 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
6584 {
6585 if (timestamp < 0)
6587 else
6589
6590 ereturn(escontext, result,
6592 errmsg("timestamp out of range")));
6593 }
6594 if (tm2timestamp(tm, fsec, NULL, &result) != 0)
6595 {
6596 if (timestamp < 0)
6598 else
6600
6601 ereturn(escontext, result,
6603 errmsg("timestamp out of range")));
6604 }
6605 }
6606 return result;
6607}
6608
6609/*
6610 * timestamptz_zone()
6611 * Evaluate timestamp with time zone type at the specified time zone.
6612 * Returns a timestamp without time zone.
6613 */
6614Datum
6616{
6620 int tz;
6621 char tzname[TZ_STRLEN_MAX + 1];
6622 int type,
6623 val;
6624 pg_tz *tzp;
6625
6628
6629 /*
6630 * Look up the requested timezone.
6631 */
6633
6634 type = DecodeTimezoneName(tzname, &val, &tzp);
6635
6637 {
6638 /* fixed-offset abbreviation */
6639 tz = -val;
6640 result = dt2local(timestamp, tz);
6641 }
6642 else if (type == TZNAME_DYNTZ)
6643 {
6644 /* dynamic-offset abbreviation, resolve using specified time */
6645 int isdst;
6646
6648 result = dt2local(timestamp, tz);
6649 }
6650 else
6651 {
6652 /* full zone name, rotate from that zone */
6653 struct pg_tm tm;
6654 fsec_t fsec;
6655
6656 if (timestamp2tm(timestamp, &tz, &tm, &fsec, NULL, tzp) != 0)
6657 ereport(ERROR,
6659 errmsg("timestamp out of range")));
6660 if (tm2timestamp(&tm, fsec, NULL, &result) != 0)
6661 ereport(ERROR,
6663 errmsg("timestamp out of range")));
6664 }
6665
6667 ereport(ERROR,
6669 errmsg("timestamp out of range")));
6670
6672}
6673
6674/*
6675 * timestamptz_izone()
6676 * Encode timestamp with time zone type with specified time interval as time zone.
6677 * Returns a timestamp without time zone.
6678 */
6679Datum
6681{
6685 int tz;
6686
6689
6691 ereport(ERROR,
6693 errmsg("interval time zone \"%s\" must be finite",
6695 PointerGetDatum(zone))))));
6696
6697 if (zone->month != 0 || zone->day != 0)
6698 ereport(ERROR,
6700 errmsg("interval time zone \"%s\" must not include months or days",
6702 PointerGetDatum(zone))))));
6703
6704 tz = -(zone->time / USECS_PER_SEC);
6705
6706 result = dt2local(timestamp, tz);
6707
6709 ereport(ERROR,
6711 errmsg("timestamp out of range")));
6712
6714}
6715
6716/*
6717 * generate_series_timestamp()
6718 * Generate the set of timestamps from start to finish by step
6719 */
6720Datum
6722{
6726
6727 /* stuff done only on the first call of the function */
6728 if (SRF_IS_FIRSTCALL())
6729 {
6731 Timestamp finish = PG_GETARG_TIMESTAMP(1);
6732 Interval *step = PG_GETARG_INTERVAL_P(2);
6733 MemoryContext oldcontext;
6734
6735 /* create a function context for cross-call persistence */
6737
6738 /*
6739 * switch to memory context appropriate for multiple function calls
6740 */
6741 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
6742
6743 /* allocate memory for user context */
6745
6746 /*
6747 * Use fctx to keep state from call to call. Seed current with the
6748 * original start value
6749 */
6750 fctx->current = start;
6751 fctx->finish = finish;
6752 fctx->step = *step;
6753
6754 /* Determine sign of the interval */
6755 fctx->step_sign = interval_sign(&fctx->step);
6756
6757 if (fctx->step_sign == 0)
6758 ereport(ERROR,
6760 errmsg("step size cannot equal zero")));
6761
6762 if (INTERVAL_NOT_FINITE((&fctx->step)))
6763 ereport(ERROR,
6765 errmsg("step size cannot be infinite")));
6766
6767 funcctx->user_fctx = fctx;
6768 MemoryContextSwitchTo(oldcontext);
6769 }
6770
6771 /* stuff done on every call of the function */
6773
6774 /*
6775 * get the saved state and use current as the result for this iteration
6776 */
6777 fctx = funcctx->user_fctx;
6778 result = fctx->current;
6779
6780 if (fctx->step_sign > 0 ?
6781 timestamp_cmp_internal(result, fctx->finish) <= 0 :
6782 timestamp_cmp_internal(result, fctx->finish) >= 0)
6783 {
6784 /* increment current in preparation for next iteration */
6786 TimestampGetDatum(fctx->current),
6787 PointerGetDatum(&fctx->step)));
6788
6789 /* do when there is more left to send */
6791 }
6792 else
6793 {
6794 /* do when there is no more left */
6796 }
6797}
6798
6799/*
6800 * generate_series_timestamptz()
6801 * Generate the set of timestamps from start to finish by step,
6802 * doing arithmetic in the specified or session timezone.
6803 */
6804static Datum
6806{
6810
6811 /* stuff done only on the first call of the function */
6812 if (SRF_IS_FIRSTCALL())
6813 {
6816 Interval *step = PG_GETARG_INTERVAL_P(2);
6817 text *zone = (PG_NARGS() == 4) ? PG_GETARG_TEXT_PP(3) : NULL;
6818 MemoryContext oldcontext;
6819
6820 /* create a function context for cross-call persistence */
6822
6823 /*
6824 * switch to memory context appropriate for multiple function calls
6825 */
6826 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
6827
6828 /* allocate memory for user context */
6830
6831 /*
6832 * Use fctx to keep state from call to call. Seed current with the
6833 * original start value
6834 */
6835 fctx->current = start;
6836 fctx->finish = finish;
6837 fctx->step = *step;
6838 fctx->attimezone = zone ? lookup_timezone(zone) : session_timezone;
6839
6840 /* Determine sign of the interval */
6841 fctx->step_sign = interval_sign(&fctx->step);
6842
6843 if (fctx->step_sign == 0)
6844 ereport(ERROR,
6846 errmsg("step size cannot equal zero")));
6847
6848 if (INTERVAL_NOT_FINITE((&fctx->step)))
6849 ereport(ERROR,
6851 errmsg("step size cannot be infinite")));
6852
6853 funcctx->user_fctx = fctx;
6854 MemoryContextSwitchTo(oldcontext);
6855 }
6856
6857 /* stuff done on every call of the function */
6859
6860 /*
6861 * get the saved state and use current as the result for this iteration
6862 */
6863 fctx = funcctx->user_fctx;
6864 result = fctx->current;
6865
6866 if (fctx->step_sign > 0 ?
6867 timestamp_cmp_internal(result, fctx->finish) <= 0 :
6868 timestamp_cmp_internal(result, fctx->finish) >= 0)
6869 {
6870 /* increment current in preparation for next iteration */
6871 fctx->current = timestamptz_pl_interval_internal(fctx->current,
6872 &fctx->step,
6873 fctx->attimezone);
6874
6875 /* do when there is more left to send */
6877 }
6878 else
6879 {
6880 /* do when there is no more left */
6882 }
6883}
6884
6885Datum
6890
6891Datum
6896
6897/*
6898 * Planner support function for generate_series(timestamp, timestamp, interval)
6899 */
6900Datum
6902{
6904 Node *ret = NULL;
6905
6907 {
6908 /* Try to estimate the number of rows returned */
6910
6911 if (is_funcclause(req->node)) /* be paranoid */
6912 {
6913 List *args = ((FuncExpr *) req->node)->args;
6914 Node *arg1,
6915 *arg2,
6916 *arg3;
6917
6918 /* We can use estimated argument values here */
6920 arg2 = estimate_expression_value(req->root, lsecond(args));
6921 arg3 = estimate_expression_value(req->root, lthird(args));
6922
6923 /*
6924 * If any argument is constant NULL, we can safely assume that
6925 * zero rows are returned. Otherwise, if they're all non-NULL
6926 * constants, we can calculate the number of rows that will be
6927 * returned.
6928 */
6929 if ((IsA(arg1, Const) && ((Const *) arg1)->constisnull) ||
6930 (IsA(arg2, Const) && ((Const *) arg2)->constisnull) ||
6931 (IsA(arg3, Const) && ((Const *) arg3)->constisnull))
6932 {
6933 req->rows = 0;
6934 ret = (Node *) req;
6935 }
6936 else if (IsA(arg1, Const) && IsA(arg2, Const) && IsA(arg3, Const))
6937 {
6939 finish;
6940 Interval *step;
6941 Datum diff;
6942 double dstep;
6943 int64 dummy;
6944
6946 finish = DatumGetTimestamp(((Const *) arg2)->constvalue);
6947 step = DatumGetIntervalP(((Const *) arg3)->constvalue);
6948
6949 /*
6950 * Perform some prechecks which could cause timestamp_mi to
6951 * raise an ERROR. It's much better to just return some
6952 * default estimate than error out in a support function.
6953 */
6955 !pg_sub_s64_overflow(finish, start, &dummy))
6956 {
6958 TimestampGetDatum(finish),
6960
6961#define INTERVAL_TO_MICROSECONDS(i) ((((double) (i)->month * DAYS_PER_MONTH + (i)->day)) * USECS_PER_DAY + (i)->time)
6962
6964
6965 /* This equation works for either sign of step */
6966 if (dstep != 0.0)
6967 {
6970
6971 req->rows = floor(ddiff / dstep + 1.0);
6972 ret = (Node *) req;
6973 }
6974#undef INTERVAL_TO_MICROSECONDS
6975 }
6976 }
6977 }
6978 }
6979
6980 PG_RETURN_POINTER(ret);
6981}
6982
6983
6984/*
6985 * timestamp_at_local()
6986 * timestamptz_at_local()
6987 *
6988 * The regression tests do not like two functions with the same proargs and
6989 * prosrc but different proname, but the grammar for AT LOCAL needs an
6990 * overloaded name to handle both types of timestamp, so we make simple
6991 * wrappers for it.
6992 */
6993Datum
6998
6999Datum
#define PG_GETARG_ARRAYTYPE_P(n)
Definition array.h:263
int32 * ArrayGetIntegerTypmods(ArrayType *arr, int *n)
Definition arrayutils.c:233
const int day_tab[2][13]
Definition datetime.c:76
Node * TemporalSimplify(int32 max_precis, Node *node)
Definition datetime.c:4995
pg_tz * DecodeTimezoneNameToTz(const char *tzname)
Definition datetime.c:3365
int DetermineTimeZoneAbbrevOffsetTS(TimestampTz ts, const char *abbr, pg_tz *tzp, int *isdst)
Definition datetime.c:1810
int DecodeUnits(int field, const char *lowtoken, int *val)
Definition datetime.c:4196
int j2day(int date)
Definition datetime.c:355
int ParseDateTime(const char *timestr, char *workbuf, size_t buflen, char **field, int *ftype, int maxfields, int *numfields)
Definition datetime.c:775
void EncodeInterval(struct pg_itm *itm, int style, char *str)
Definition datetime.c:4740
int DetermineTimeZoneOffset(struct pg_tm *tm, pg_tz *tzp)
Definition datetime.c:1608
void DateTimeParseError(int dterr, DateTimeErrorExtra *extra, const char *str, const char *datatype, Node *escontext)
Definition datetime.c:4241
int DecodeInterval(char **field, int *ftype, int nf, int range, int *dtype, struct pg_itm_in *itm_in)
Definition datetime.c:3511
int DecodeISO8601Interval(char *str, int *dtype, struct pg_itm_in *itm_in)
Definition datetime.c:3977
int ValidateDate(int fmask, bool isjulian, bool is2digits, bool bc, struct pg_tm *tm)
Definition datetime.c:2573
int DecodeSpecial(int field, const char *lowtoken, int *val)
Definition datetime.c:3266
void j2date(int jd, int *year, int *month, int *day)
Definition datetime.c:322
void EncodeDateTime(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str)
Definition datetime.c:4496
int DecodeTimezone(const char *str, int *tzp)
Definition datetime.c:3075
const char *const months[]
Definition datetime.c:82
int DecodeDateTime(char **field, int *ftype, int nf, int *dtype, struct pg_tm *tm, fsec_t *fsec, int *tzp, DateTimeErrorExtra *extra)
Definition datetime.c:1000
int date2j(int year, int month, int day)
Definition datetime.c:297
const char *const days[]
Definition datetime.c:85
int DecodeTimezoneName(const char *tzname, int *offset, pg_tz **tz)
Definition datetime.c:3309
int DetermineTimeZoneAbbrevOffset(struct pg_tm *tm, const char *abbr, pg_tz *tzp)
Definition datetime.c:1771
Datum numeric_round(PG_FUNCTION_ARGS)
Definition numeric.c:1528
Numeric int64_to_numeric(int64 val)
Definition numeric.c:4264
Numeric numeric_add_safe(Numeric num1, Numeric num2, Node *escontext)
Definition numeric.c:2883
Numeric int64_div_fast_to_numeric(int64 val1, int log10val2)
Definition numeric.c:4285
Numeric numeric_div_safe(Numeric num1, Numeric num2, Node *escontext)
Definition numeric.c:3157
Numeric numeric_sub_safe(Numeric num1, Numeric num2, Node *escontext)
Definition numeric.c:2959
Datum numeric_in(PG_FUNCTION_ARGS)
Definition numeric.c:626
void dt2time(Timestamp jd, int *hour, int *min, int *sec, fsec_t *fsec)
Definition timestamp.c:1891
Datum interval_out(PG_FUNCTION_ARGS)
Definition timestamp.c:974
Datum interval_justify_hours(PG_FUNCTION_ARGS)
Definition timestamp.c:3014
Datum make_timestamptz_at_timezone(PG_FUNCTION_ARGS)
Definition timestamp.c:682
int timestamp_cmp_internal(Timestamp dt1, Timestamp dt2)
Definition timestamp.c:2222
long TimestampDifferenceMilliseconds(TimestampTz start_time, TimestampTz stop_time)
Definition timestamp.c:1765
void isoweek2date(int woy, int *year, int *mon, int *mday)
Definition timestamp.c:5293
Datum in_range_timestamp_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3895
void GetEpochTime(struct pg_tm *tm)
Definition timestamp.c:2180
Datum generate_series_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:6886
static float8 NonFiniteTimestampTzPart(int type, int unit, char *lowunits, bool isNegative, bool isTz)
Definition timestamp.c:5457
static INT128 interval_cmp_value(const Interval *interval)
Definition timestamp.c:2536
Datum interval_trunc(PG_FUNCTION_ARGS)
Definition timestamp.c:5139
Datum overlaps_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:2685
Datum extract_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:5779
Datum timestamptypmodout(PG_FUNCTION_ARGS)
Definition timestamp.c:305
Datum interval_gt(PG_FUNCTION_ARGS)
Definition timestamp.c:2603
Datum interval_avg_accum(PG_FUNCTION_ARGS)
Definition timestamp.c:4062
int itmin2interval(struct pg_itm_in *itm_in, Interval *span)
Definition timestamp.c:2127
Datum interval_justify_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:2934
static void finite_interval_mi(const Interval *span1, const Interval *span2, Interval *result)
Definition timestamp.c:3563
Datum timestamptz_part(PG_FUNCTION_ARGS)
Definition timestamp.c:6046
int isoweek2j(int year, int week)
Definition timestamp.c:5272
Datum clock_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:1625
Datum timestamptz_pl_interval_at_zone(PG_FUNCTION_ARGS)
Definition timestamp.c:3419
Datum timestamp_pl_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3104
Datum interval_le(PG_FUNCTION_ARGS)
Definition timestamp.c:2612
Datum interval_avg_serialize(PG_FUNCTION_ARGS)
Definition timestamp.c:4128
Datum interval_mi(PG_FUNCTION_ARGS)
Definition timestamp.c:3578
TimestampTz time_t_to_timestamptz(pg_time_t tm)
Definition timestamp.c:1828
Datum timestamp_le_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:2435
Datum interval_lt(PG_FUNCTION_ARGS)
Definition timestamp.c:2594
Datum timestamp_larger(PG_FUNCTION_ARGS)
Definition timestamp.c:2825
static Datum timestamptz_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition timestamp.c:5789
Datum timestamptz_izone(PG_FUNCTION_ARGS)
Definition timestamp.c:6680
Datum timestamp_cmp_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:2453
static bool AdjustIntervalForTypmod(Interval *interval, int32 typmod, Node *escontext)
Definition timestamp.c:1353
Datum timestamp_part(PG_FUNCTION_ARGS)
Definition timestamp.c:5773
Datum timestamptz_eq_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:2462
Datum interval_hash(PG_FUNCTION_ARGS)
Definition timestamp.c:2646
Datum timestamptztypmodout(PG_FUNCTION_ARGS)
Definition timestamp.c:854
int date2isoweek(int year, int mon, int mday)
Definition timestamp.c:5326
Datum timestamptz_pl_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3397
Datum timestamp_cmp(PG_FUNCTION_ARGS)
Definition timestamp.c:2282
static TimestampTz timestamptz_trunc_internal(text *units, TimestampTz timestamp, pg_tz *tzp)
Definition timestamp.c:4921
Datum timestamp_bin(PG_FUNCTION_ARGS)
Definition timestamp.c:4610
Datum timestamp_zone(PG_FUNCTION_ARGS)
Definition timestamp.c:6345
static pg_tz * lookup_timezone(text *zone)
Definition timestamp.c:556
static TimestampTz timestamp2timestamptz(Timestamp timestamp)
Definition timestamp.c:6529
Datum interval_finite(PG_FUNCTION_ARGS)
Definition timestamp.c:2167
Datum timestamptz_ne_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:2471
Datum timestamptz_lt_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:2480
Datum timestamp_sortsupport(PG_FUNCTION_ARGS)
Definition timestamp.c:2291
Datum timestamp_mi_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3221
Datum timestamptypmodin(PG_FUNCTION_ARGS)
Definition timestamp.c:297
bool AdjustTimestampForTypmod(Timestamp *time, int32 typmod, Node *escontext)
Definition timestamp.c:363
Datum timestamptz_ge_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:2507
Datum timestamp_smaller(PG_FUNCTION_ARGS)
Definition timestamp.c:2810
Datum interval_justify_days(PG_FUNCTION_ARGS)
Definition timestamp.c:3056
TimestampTz timestamp2timestamptz_safe(Timestamp timestamp, Node *escontext)
Definition timestamp.c:6493
Datum timestamp_ge(PG_FUNCTION_ARGS)
Definition timestamp.c:2273
Datum interval_avg_accum_inv(PG_FUNCTION_ARGS)
Definition timestamp.c:4209
Datum generate_series_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:6721
int date2isoyearday(int year, int mon, int mday)
Definition timestamp.c:5440
Datum timestamptz_cmp_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:2516
Datum timestamp_ge_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:2444
static Timestamp timestamptz2timestamp(TimestampTz timestamp)
Definition timestamp.c:6555
void TimestampDifference(TimestampTz start_time, TimestampTz stop_time, long *secs, int *microsecs)
Definition timestamp.c:1729
static void do_interval_accum(IntervalAggState *state, Interval *newval)
Definition timestamp.c:4008
Datum timestamp_scale(PG_FUNCTION_ARGS)
Definition timestamp.c:341
Datum timestamptz_scale(PG_FUNCTION_ARGS)
Definition timestamp.c:868
Datum make_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:661
bool TimestampDifferenceExceedsSeconds(TimestampTz start_time, TimestampTz stop_time, int threshold_sec)
Definition timestamp.c:1803
bool TimestampTimestampTzRequiresRewrite(void)
Definition timestamp.c:6456
Datum timestamp_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:6470
Datum timestamp_recv(PG_FUNCTION_ARGS)
Definition timestamp.c:253
Datum timestamp_lt(PG_FUNCTION_ARGS)
Definition timestamp.c:2246
Datum timestamptz_trunc(PG_FUNCTION_ARGS)
Definition timestamp.c:5100
Datum timestamptz_zone(PG_FUNCTION_ARGS)
Definition timestamp.c:6615
static void finite_interval_pl(const Interval *span1, const Interval *span2, Interval *result)
Definition timestamp.c:3507
void isoweekdate2date(int isoweek, int wday, int *year, int *mon, int *mday)
Definition timestamp.c:5307
int32 timestamp_cmp_timestamptz_internal(Timestamp timestampVal, TimestampTz dt2)
Definition timestamp.c:2375
Datum timestamptz_gt_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:2489
Datum timestamptz_hash_extended(PG_FUNCTION_ARGS)
Definition timestamp.c:2365
bool TimestampDifferenceExceeds(TimestampTz start_time, TimestampTz stop_time, int msec)
Definition timestamp.c:1789
static int32 anytimestamp_typmodin(bool istz, ArrayType *ta)
Definition timestamp.c:95
Datum generate_series_timestamp_support(PG_FUNCTION_ARGS)
Definition timestamp.c:6901
Datum interval_cmp(PG_FUNCTION_ARGS)
Definition timestamp.c:2630
Datum interval_sum(PG_FUNCTION_ARGS)
Definition timestamp.c:4267
Datum timestamp_hash_extended(PG_FUNCTION_ARGS)
Definition timestamp.c:2353
Datum timestamptz_le_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:2498
Datum interval_pl(PG_FUNCTION_ARGS)
Definition timestamp.c:3522
Datum interval_um(PG_FUNCTION_ARGS)
Definition timestamp.c:3465
Datum timestamp_skipsupport(PG_FUNCTION_ARGS)
Definition timestamp.c:2334
static float8 NonFiniteIntervalPart(int type, int unit, char *lowunits, bool isNegative)
Definition timestamp.c:6069
void EncodeSpecialTimestamp(Timestamp dt, char *str)
Definition timestamp.c:1591
Datum make_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:1533
static char * anytimestamp_typmodout(bool istz, int32 typmod)
Definition timestamp.c:138
Datum interval_ge(PG_FUNCTION_ARGS)
Definition timestamp.c:2621
static Timestamp make_timestamp_internal(int year, int month, int day, int hour, int min, double sec)
Definition timestamp.c:570
Datum timestamp_gt_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:2426
Datum timestamp_in(PG_FUNCTION_ARGS)
Definition timestamp.c:158
Datum timestamp_le(PG_FUNCTION_ARGS)
Definition timestamp.c:2264
Datum interval_ne(PG_FUNCTION_ARGS)
Definition timestamp.c:2585
Datum timestamptz_hash(PG_FUNCTION_ARGS)
Definition timestamp.c:2359
Datum interval_in(PG_FUNCTION_ARGS)
Definition timestamp.c:891
static Timestamp dt2local(Timestamp dt, int timezone)
Definition timestamp.c:2146
static Datum interval_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition timestamp.c:6116
TimestampTz PgReloadTime
Definition timestamp.c:48
Datum timestamp_ne_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:2408
Datum interval_hash_extended(PG_FUNCTION_ARGS)
Definition timestamp.c:2664
Datum timestamptz_mi_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3406
Datum timestamp_age(PG_FUNCTION_ARGS)
Definition timestamp.c:4308
Datum interval_smaller(PG_FUNCTION_ARGS)
Definition timestamp.c:3478
static void EncodeSpecialInterval(const Interval *interval, char *str)
Definition timestamp.c:1602
Datum timestamptz_mi_interval_at_zone(PG_FUNCTION_ARGS)
Definition timestamp.c:3430
Datum interval_support(PG_FUNCTION_ARGS)
Definition timestamp.c:1266
Datum timestamptz_in(PG_FUNCTION_ARGS)
Definition timestamp.c:414
static int intervaltypmodleastfield(int32 typmod)
Definition timestamp.c:1213
int32 anytimestamp_typmod_check(bool istz, int32 typmod)
Definition timestamp.c:116
Datum extract_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:6052
Datum pg_postmaster_start_time(PG_FUNCTION_ARGS)
Definition timestamp.c:1631
TimestampTz GetCurrentTimestamp(void)
Definition timestamp.c:1649
static TimeOffset time2t(const int hour, const int min, const int sec, const fsec_t fsec)
Definition timestamp.c:2140
Datum interval_part(PG_FUNCTION_ARGS)
Definition timestamp.c:6323
Datum pg_conf_load_time(PG_FUNCTION_ARGS)
Definition timestamp.c:1637
Datum in_range_interval_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3936
#define IA_TOTAL_COUNT(ia)
Definition timestamp.c:80
const char * timestamptz_to_str(TimestampTz t)
Definition timestamp.c:1870
Datum interval_eq(PG_FUNCTION_ARGS)
Definition timestamp.c:2576
static Datum timestamp_increment(Relation rel, Datum existing, bool *overflow)
Definition timestamp.c:2318
Timestamp GetSQLLocalTimestamp(int32 typmod)
Definition timestamp.c:1681
Datum timestamp_finite(PG_FUNCTION_ARGS)
Definition timestamp.c:2159
static TimestampTz timestamptz_mi_interval_internal(TimestampTz timestamp, Interval *span, pg_tz *attimezone)
Definition timestamp.c:3381
Datum timestamp_trunc(PG_FUNCTION_ARGS)
Definition timestamp.c:4682
Datum mul_d_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3747
Datum timestamptztypmodin(PG_FUNCTION_ARGS)
Definition timestamp.c:846
Datum interval_avg(PG_FUNCTION_ARGS)
Definition timestamp.c:4227
TimestampTz PgStartTime
Definition timestamp.c:45
Datum timestamp_send(PG_FUNCTION_ARGS)
Definition timestamp.c:286
Datum timestamptz_send(PG_FUNCTION_ARGS)
Definition timestamp.c:835
Datum timestamptz_recv(PG_FUNCTION_ARGS)
Definition timestamp.c:801
Datum interval_scale(PG_FUNCTION_ARGS)
Definition timestamp.c:1330
static Datum timestamp_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition timestamp.c:5515
Datum interval_larger(PG_FUNCTION_ARGS)
Definition timestamp.c:3493
Datum timestamp_gt(PG_FUNCTION_ARGS)
Definition timestamp.c:2255
static IntervalAggState * makeIntervalAggState(FunctionCallInfo fcinfo)
Definition timestamp.c:3986
Datum timestamptz_bin(PG_FUNCTION_ARGS)
Definition timestamp.c:4847
Datum timestamptz_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:6539
Datum timestamp_mi(PG_FUNCTION_ARGS)
Definition timestamp.c:2840
Datum timestamptz_at_local(PG_FUNCTION_ARGS)
Definition timestamp.c:7000
Datum interval_send(PG_FUNCTION_ARGS)
Definition timestamp.c:1023
Datum intervaltypmodin(PG_FUNCTION_ARGS)
Definition timestamp.c:1048
#define TIMESTAMP_GT(t1, t2)
Datum timestamp_lt_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:2417
Datum timestamptz_out(PG_FUNCTION_ARGS)
Definition timestamp.c:773
static void interval_um_internal(const Interval *interval, Interval *result)
Definition timestamp.c:3445
Datum timestamp_hash(PG_FUNCTION_ARGS)
Definition timestamp.c:2347
Datum timestamp_out(PG_FUNCTION_ARGS)
Definition timestamp.c:227
Datum timestamp_support(PG_FUNCTION_ARGS)
Definition timestamp.c:320
void interval2itm(Interval span, struct pg_itm *itm)
Definition timestamp.c:2057
Datum float8_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:722
Datum now(PG_FUNCTION_ARGS)
Definition timestamp.c:1613
Datum interval_avg_deserialize(PG_FUNCTION_ARGS)
Definition timestamp.c:4166
Datum timestamp_ne(PG_FUNCTION_ARGS)
Definition timestamp.c:2237
static int interval_cmp_internal(const Interval *interval1, const Interval *interval2)
Definition timestamp.c:2558
Datum interval_recv(PG_FUNCTION_ARGS)
Definition timestamp.c:998
#define INTERVAL_TO_MICROSECONDS(i)
Datum statement_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:1619
Datum timestamptz_age(PG_FUNCTION_ARGS)
Definition timestamp.c:4455
Datum interval_mul(PG_FUNCTION_ARGS)
Definition timestamp.c:3627
Datum interval_div(PG_FUNCTION_ARGS)
Definition timestamp.c:3757
Datum timestamptz_trunc_zone(PG_FUNCTION_ARGS)
Definition timestamp.c:5116
Datum timestamp_eq_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:2399
static TimestampTz timestamptz_pl_interval_internal(TimestampTz timestamp, Interval *span, pg_tz *attimezone)
Definition timestamp.c:3248
static Datum generate_series_timestamptz_internal(FunctionCallInfo fcinfo)
Definition timestamp.c:6805
int itm2interval(struct pg_itm *itm, Interval *span)
Definition timestamp.c:2088
pg_time_t timestamptz_to_time_t(TimestampTz t)
Definition timestamp.c:1850
Datum make_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:641
Datum intervaltypmodout(PG_FUNCTION_ARGS)
Definition timestamp.c:1127
static int interval_sign(const Interval *interval)
Definition timestamp.c:2567
static void do_interval_discard(IntervalAggState *state, Interval *newval)
Definition timestamp.c:4031
Datum timeofday(PG_FUNCTION_ARGS)
Definition timestamp.c:1695
Datum generate_series_timestamptz_at_zone(PG_FUNCTION_ARGS)
Definition timestamp.c:6892
int date2isoyear(int year, int mon, int mday)
Definition timestamp.c:5382
Timestamp timestamptz2timestamp_safe(TimestampTz timestamp, Node *escontext)
Definition timestamp.c:6571
Datum timestamp_izone(PG_FUNCTION_ARGS)
Definition timestamp.c:6411
static Datum timestamp_decrement(Relation rel, Datum existing, bool *underflow)
Definition timestamp.c:2301
static int parse_sane_timezone(struct pg_tm *tm, text *zone)
Definition timestamp.c:487
Datum timestamp_at_local(PG_FUNCTION_ARGS)
Definition timestamp.c:6994
TimestampTz GetSQLCurrentTimestamp(int32 typmod)
Definition timestamp.c:1667
Datum in_range_timestamptz_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3858
Datum interval_avg_combine(PG_FUNCTION_ARGS)
Definition timestamp.c:4085
Datum extract_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:6329
Datum timestamp_eq(PG_FUNCTION_ARGS)
Definition timestamp.c:2228
#define TIMESTAMP_LT(t1, t2)
#define INT64CONST(x)
Definition c.h:630
#define FLOAT8_FITS_IN_INT32(num)
Definition c.h:1177
#define Assert(condition)
Definition c.h:943
int64_t int64
Definition c.h:621
double float8
Definition c.h:714
#define FLOAT8_FITS_IN_INT64(num)
Definition c.h:1179
int32_t int32
Definition c.h:620
#define PG_INT64_MAX
Definition c.h:676
#define PG_INT64_MIN
Definition c.h:675
#define unlikely(x)
Definition c.h:438
#define pg_fallthrough
Definition c.h:161
uint32 result
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
Node * estimate_expression_value(PlannerInfo *root, Node *node)
Definition clauses.c:2641
int64 Timestamp
Definition timestamp.h:38
#define DATETIME_MIN_JULIAN
Definition timestamp.h:251
#define INTERVAL_NOEND(i)
Definition timestamp.h:185
int64 TimestampTz
Definition timestamp.h:39
#define SECS_PER_HOUR
Definition timestamp.h:127
#define MAX_TIMESTAMP_PRECISION
Definition timestamp.h:92
int32 fsec_t
Definition timestamp.h:41
#define INTERVAL_NOT_FINITE(i)
Definition timestamp.h:195
#define TIMESTAMP_NOBEGIN(j)
Definition timestamp.h:159
#define USECS_PER_HOUR
Definition timestamp.h:132
#define TIMESTAMP_END_JULIAN
Definition timestamp.h:253
#define MONTHS_PER_YEAR
Definition timestamp.h:108
#define MINS_PER_HOUR
Definition timestamp.h:129
#define IS_VALID_JULIAN(y, m, d)
Definition timestamp.h:227
#define INTERVAL_NOBEGIN(i)
Definition timestamp.h:175
#define INTERVAL_IS_NOBEGIN(i)
Definition timestamp.h:182
#define IS_VALID_TIMESTAMP(t)
Definition timestamp.h:267
#define MAX_INTERVAL_PRECISION
Definition timestamp.h:93
#define SECS_PER_MINUTE
Definition timestamp.h:128
#define USECS_PER_DAY
Definition timestamp.h:131
#define USECS_PER_SEC
Definition timestamp.h:134
#define HOURS_PER_DAY
Definition timestamp.h:118
#define INTERVAL_IS_NOEND(i)
Definition timestamp.h:192
#define TIMESTAMP_IS_NOEND(j)
Definition timestamp.h:167
#define USECS_PER_MINUTE
Definition timestamp.h:133
#define DAYS_PER_YEAR
Definition timestamp.h:107
#define DAYS_PER_WEEK
Definition timestamp.h:117
#define TIMESTAMP_IS_NOBEGIN(j)
Definition timestamp.h:162
#define DAYS_PER_MONTH
Definition timestamp.h:116
#define UNIX_EPOCH_JDATE
Definition timestamp.h:234
#define TIMESTAMP_NOT_FINITE(j)
Definition timestamp.h:169
#define TSROUND(j)
Definition timestamp.h:100
#define SECS_PER_DAY
Definition timestamp.h:126
#define POSTGRES_EPOCH_JDATE
Definition timestamp.h:235
#define TIMESTAMP_NOEND(j)
Definition timestamp.h:164
int64 TimeOffset
Definition timestamp.h:40
bool float_time_overflows(int hour, int min, double sec)
Definition date.c:1555
int errcode(int sqlerrcode)
Definition elog.c:875
#define ereturn(context, dummy_value,...)
Definition elog.h:280
int errhint(const char *fmt,...) pg_attribute_printf(1
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define WARNING
Definition elog.h:37
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
#define ereport(elevel,...)
Definition elog.h:152
struct SortSupportData * SortSupport
Definition execnodes.h:61
#define palloc_object(type)
Definition fe_memutils.h:89
#define palloc0_object(type)
Definition fe_memutils.h:90
static float8 float8_mul(const float8 val1, const float8 val2)
Definition float.h:192
static float8 get_float8_infinity(void)
Definition float.h:68
#define PG_RETURN_VOID()
Definition fmgr.h:350
#define PG_GETARG_OID(n)
Definition fmgr.h:275
#define PG_GETARG_BYTEA_PP(n)
Definition fmgr.h:309
#define PG_GETARG_TEXT_PP(n)
Definition fmgr.h:310
#define PG_RETURN_BYTEA_P(x)
Definition fmgr.h:373
#define DirectFunctionCall2(func, arg1, arg2)
Definition fmgr.h:690
#define PG_GETARG_FLOAT8(n)
Definition fmgr.h:283
#define PG_RETURN_FLOAT8(x)
Definition fmgr.h:369
#define PG_GETARG_POINTER(n)
Definition fmgr.h:277
#define PG_RETURN_CSTRING(x)
Definition fmgr.h:364
#define PG_ARGISNULL(n)
Definition fmgr.h:209
#define DirectFunctionCall1(func, arg1)
Definition fmgr.h:688
#define PG_GETARG_DATUM(n)
Definition fmgr.h:268
#define PG_NARGS()
Definition fmgr.h:203
#define PG_GETARG_CSTRING(n)
Definition fmgr.h:278
#define PG_RETURN_NULL()
Definition fmgr.h:346
#define PG_RETURN_TEXT_P(x)
Definition fmgr.h:374
#define PG_RETURN_INT32(x)
Definition fmgr.h:355
#define PG_GETARG_INT32(n)
Definition fmgr.h:269
#define PG_GETARG_BOOL(n)
Definition fmgr.h:274
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition fmgr.h:692
#define PG_RETURN_POINTER(x)
Definition fmgr.h:363
#define PG_FUNCTION_ARGS
Definition fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition fmgr.h:360
char * format_type_be(Oid type_oid)
#define SRF_IS_FIRSTCALL()
Definition funcapi.h:304
#define SRF_PERCALL_SETUP()
Definition funcapi.h:308
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition funcapi.h:310
#define SRF_FIRSTCALL_INIT()
Definition funcapi.h:306
#define SRF_RETURN_DONE(_funcctx)
Definition funcapi.h:328
int DateStyle
Definition globals.c:127
int IntervalStyle
Definition globals.c:129
#define newval
return str start
const char * str
Datum hashint8extended(PG_FUNCTION_ARGS)
Definition hashfunc.c:104
Datum hashint8(PG_FUNCTION_ARGS)
Definition hashfunc.c:84
#define MAXDATEFIELDS
Definition datetime.h:202
#define DTK_EPOCH
Definition datetime.h:152
#define TMODULO(t, q, u)
Definition datetime.h:250
#define UNKNOWN_FIELD
Definition datetime.h:124
#define DTK_DECADE
Definition datetime.h:168
#define DTK_SECOND
Definition datetime.h:160
#define DTERR_INTERVAL_OVERFLOW
Definition datetime.h:287
#define DTK_QUARTER
Definition datetime.h:166
#define DTK_JULIAN
Definition datetime.h:173
#define MONTH
Definition datetime.h:91
#define DTK_DELTA
Definition datetime.h:159
#define DTK_TZ_HOUR
Definition datetime.h:177
#define HOUR
Definition datetime.h:100
#define DTK_TZ_MINUTE
Definition datetime.h:178
#define DAY
Definition datetime.h:93
#define DTK_LATE
Definition datetime.h:151
#define YEAR
Definition datetime.h:92
#define DTK_DATE
Definition datetime.h:144
#define DTK_CENTURY
Definition datetime.h:169
#define DTK_ISODOW
Definition datetime.h:180
#define DTK_DAY
Definition datetime.h:163
#define RESERV
Definition datetime.h:90
#define DTERR_BAD_FORMAT
Definition datetime.h:284
#define DTK_DATE_M
Definition datetime.h:191
#define DTK_MILLENNIUM
Definition datetime.h:170
#define DTK_EARLY
Definition datetime.h:150
#define DTK_ISOYEAR
Definition datetime.h:179
#define MAXDATELEN
Definition datetime.h:200
#define SECOND
Definition datetime.h:102
#define isleap(y)
Definition datetime.h:273
#define DTK_DOY
Definition datetime.h:176
#define DTK_TZ
Definition datetime.h:146
#define TZNAME_FIXED_OFFSET
Definition datetime.h:301
#define TZNAME_DYNTZ
Definition datetime.h:302
#define DTERR_TZDISP_OVERFLOW
Definition datetime.h:288
#define EARLY
Definition datetime.h:39
#define DTK_HOUR
Definition datetime.h:162
#define DTK_WEEK
Definition datetime.h:164
#define MINUTE
Definition datetime.h:101
#define LATE
Definition datetime.h:40
#define DTK_MICROSEC
Definition datetime.h:172
#define DTK_DOW
Definition datetime.h:175
#define DTK_YEAR
Definition datetime.h:167
#define DTK_MILLISEC
Definition datetime.h:171
#define DTK_MONTH
Definition datetime.h:165
#define DTERR_FIELD_OVERFLOW
Definition datetime.h:285
#define DTK_MINUTE
Definition datetime.h:161
#define UNITS
Definition datetime.h:107
long val
Definition informix.c:689
static int int128_compare(INT128 x, INT128 y)
Definition int128.h:425
static INT128 int64_to_int128(int64 v)
Definition int128.h:450
static int64 int128_to_int64(INT128 val)
Definition int128.h:468
static void int128_add_int64_mul_int64(INT128 *i128, int64 x, int64 y)
Definition int128.h:203
static bool pg_mul_s64_overflow(int64 a, int64 b, int64 *result)
Definition int.h:293
static bool pg_sub_s64_overflow(int64 a, int64 b, int64 *result)
Definition int.h:262
static bool pg_mul_s32_overflow(int32 a, int32 b, int32 *result)
Definition int.h:187
static bool pg_sub_s32_overflow(int32 a, int32 b, int32 *result)
Definition int.h:169
static bool pg_add_s64_overflow(int64 a, int64 b, int64 *result)
Definition int.h:235
static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)
Definition int.h:151
static int timestamp2tm(timestamp dt, int *tzp, struct tm *tm, fsec_t *fsec, const char **tzn)
Definition timestamp.c:90
static timestamp SetEpochTimestamp(void)
Definition timestamp.c:63
int tm2timestamp(struct tm *tm, fsec_t fsec, int *tzp, timestamp *result)
Definition timestamp.c:38
static struct pg_tm tm
Definition localtime.c:104
char * pstrdup(const char *in)
Definition mcxt.c:1910
void * palloc(Size size)
Definition mcxt.c:1390
#define USE_ISO_DATES
Definition miscadmin.h:240
#define SOFT_ERROR_OCCURRED(escontext)
Definition miscnodes.h:53
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition nodeAgg.c:4609
int32 exprTypmod(const Node *expr)
Definition nodeFuncs.c:304
Node * relabel_to_typmod(Node *expr, int32 typmod)
Definition nodeFuncs.c:694
static bool is_funcclause(const void *clause)
Definition nodeFuncs.h:69
#define IsA(nodeptr, _type_)
Definition nodes.h:164
static Numeric DatumGetNumeric(Datum X)
Definition numeric.h:64
#define PG_RETURN_NUMERIC(x)
Definition numeric.h:83
static Datum NumericGetDatum(Numeric X)
Definition numeric.h:76
static char * errmsg
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:138
static time_t start_time
Definition pg_ctl.c:96
static int list_length(const List *l)
Definition pg_list.h:152
#define lthird(l)
Definition pg_list.h:188
#define linitial(l)
Definition pg_list.h:178
#define lsecond(l)
Definition pg_list.h:183
static rewind_source * source
Definition pg_rewind.c:89
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define TZ_STRLEN_MAX
Definition pgtime.h:54
bool pg_get_timezone_offset(const pg_tz *tz, long int *gmtoff)
Definition localtime.c:1968
PGDLLIMPORT pg_tz * session_timezone
Definition pgtz.c:28
int64 pg_time_t
Definition pgtime.h:23
size_t pg_strftime(char *s, size_t maxsize, const char *format, const struct pg_tm *t)
Definition strftime.c:135
struct pg_tm * pg_localtime(const pg_time_t *timep, const pg_tz *tz)
Definition localtime.c:1347
struct pg_tm * pg_gmtime(const pg_time_t *timep)
Definition localtime.c:1392
long date
Definition pgtypes_date.h:9
int64 timestamp
#define snprintf
Definition port.h:261
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition strlcpy.c:45
#define Int64GetDatumFast(X)
Definition postgres.h:538
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
static char * DatumGetCString(Datum X)
Definition postgres.h:365
uint64_t Datum
Definition postgres.h:70
static Datum Float8GetDatum(float8 X)
Definition postgres.h:515
static Datum CStringGetDatum(const char *X)
Definition postgres.h:383
static Datum Int32GetDatum(int32 X)
Definition postgres.h:212
static int32 DatumGetInt32(Datum X)
Definition postgres.h:202
#define PointerGetDatum(X)
Definition postgres.h:354
#define InvalidOid
unsigned int Oid
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition pqformat.c:414
void pq_getmsgend(StringInfo msg)
Definition pqformat.c:634
void pq_begintypsend(StringInfo buf)
Definition pqformat.c:325
int64 pq_getmsgint64(StringInfo msg)
Definition pqformat.c:452
bytea * pq_endtypsend(StringInfo buf)
Definition pqformat.c:345
static void pq_sendint32(StringInfo buf, uint32 i)
Definition pqformat.h:144
static void pq_sendint64(StringInfo buf, uint64 i)
Definition pqformat.h:152
static int fb(int x)
char * psprintf(const char *fmt,...)
Definition psprintf.c:43
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
char * downcase_truncate_identifier(const char *ident, int len, bool warn)
Definition scansup.c:38
struct SkipSupportData * SkipSupport
Definition skipsupport.h:50
struct StringInfoData * StringInfo
Definition string.h:15
static void initReadOnlyStringInfo(StringInfo str, char *data, int len)
Definition stringinfo.h:157
List * args
Definition primnodes.h:801
Interval sumX
Definition timestamp.c:74
Definition pg_list.h:54
Definition nodes.h:135
SkipSupportIncDec decrement
Definition skipsupport.h:91
SkipSupportIncDec increment
Definition skipsupport.h:92
int(* comparator)(Datum x, Datum y, SortSupport ssup)
Definition pgtime.h:35
int tm_hour
Definition pgtime.h:38
int tm_mday
Definition pgtime.h:39
int tm_mon
Definition pgtime.h:40
int tm_min
Definition pgtime.h:37
const char * tm_zone
Definition pgtime.h:46
int tm_sec
Definition pgtime.h:36
int tm_isdst
Definition pgtime.h:44
long int tm_gmtoff
Definition pgtime.h:45
int tm_year
Definition pgtime.h:41
Definition pgtz.h:66
Definition c.h:776
Definition zic.c:101
int ssup_datum_signed_cmp(Datum x, Datum y, SortSupport ssup)
Definition tuplesort.c:3461
#define INTERVAL_FULL_RANGE
Definition timestamp.h:76
#define timestamptz_cmp_internal(dt1, dt2)
Definition timestamp.h:143
#define INTERVAL_PRECISION(t)
Definition timestamp.h:81
static Datum TimestampTzGetDatum(TimestampTz X)
Definition timestamp.h:52
#define INTERVAL_RANGE(t)
Definition timestamp.h:82
static Datum TimestampGetDatum(Timestamp X)
Definition timestamp.h:46
#define PG_GETARG_TIMESTAMP(n)
Definition timestamp.h:63
static Datum IntervalPGetDatum(const Interval *X)
Definition timestamp.h:58
#define PG_RETURN_TIMESTAMP(x)
Definition timestamp.h:67
#define PG_GETARG_INTERVAL_P(n)
Definition timestamp.h:65
#define PG_GETARG_TIMESTAMPTZ(n)
Definition timestamp.h:64
#define PG_RETURN_TIMESTAMPTZ(x)
Definition timestamp.h:68
static Interval * DatumGetIntervalP(Datum X)
Definition timestamp.h:40
#define PG_RETURN_INTERVAL_P(x)
Definition timestamp.h:69
#define INTERVAL_TYPMOD(p, r)
Definition timestamp.h:80
#define INTERVAL_MASK(b)
Definition timestamp.h:73
static Timestamp DatumGetTimestamp(Datum X)
Definition timestamp.h:28
#define INTERVAL_FULL_PRECISION
Definition timestamp.h:78
static Size VARSIZE_ANY_EXHDR(const void *PTR)
Definition varatt.h:472
static char * VARDATA_ANY(const void *PTR)
Definition varatt.h:486
text * cstring_to_text(const char *s)
Definition varlena.c:184
void text_to_cstring_buffer(const text *src, char *dst, size_t dst_len)
Definition varlena.c:248
const char * type
static const unsigned __int64 epoch
int gettimeofday(struct timeval *tp, void *tzp)
TimestampTz GetCurrentStatementStartTimestamp(void)
Definition xact.c:881
TimestampTz GetCurrentTransactionStartTimestamp(void)
Definition xact.c:872