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 * gcc's -ffast-math switch breaks routines that expect exact results from
45 * expressions like timeval / SECS_PER_HOUR, where timeval is double.
46 */
47#ifdef __FAST_MATH__
48#error -ffast-math is known to break this code
49#endif
50
51/* Set at postmaster start */
53
54/* Set at configuration reload */
56
64
73
74/*
75 * The transition datatype for interval aggregates is declared as internal.
76 * It's a pointer to an IntervalAggState allocated in the aggregate context.
77 */
78typedef struct IntervalAggState
79{
80 int64 N; /* count of finite intervals processed */
81 Interval sumX; /* sum of finite intervals processed */
82 /* These counts are *not* included in N! Use IA_TOTAL_COUNT() as needed */
83 int64 pInfcount; /* count of +infinity intervals */
84 int64 nInfcount; /* count of -infinity intervals */
86
87#define IA_TOTAL_COUNT(ia) \
88 ((ia)->N + (ia)->pInfcount + (ia)->nInfcount)
89
90static TimeOffset time2t(const int hour, const int min, const int sec, const fsec_t fsec);
93 Node *escontext);
96
97static void EncodeSpecialInterval(const Interval *interval, char *str);
98static void interval_um_internal(const Interval *interval, Interval *result);
99
100/* common code for timestamptypmodin and timestamptztypmodin */
101static int32
103{
104 int32 *tl;
105 int n;
106
108
109 /*
110 * we're not too tense about good error message here because grammar
111 * shouldn't allow wrong number of modifiers for TIMESTAMP
112 */
113 if (n != 1)
116 errmsg("invalid type modifier")));
117
119}
120
121/* exported so parse_expr.c can use it */
122int32
124{
125 if (typmod < 0)
128 errmsg("TIMESTAMP(%d)%s precision must not be negative",
129 typmod, (istz ? " WITH TIME ZONE" : ""))));
130 if (typmod > MAX_TIMESTAMP_PRECISION)
131 {
134 errmsg("TIMESTAMP(%d)%s precision reduced to maximum allowed, %d",
135 typmod, (istz ? " WITH TIME ZONE" : ""),
138 }
139
140 return typmod;
141}
142
143/* common code for timestamptypmodout and timestamptztypmodout */
144static char *
146{
147 const char *tz = istz ? " with time zone" : " without time zone";
148
149 if (typmod >= 0)
150 return psprintf("(%d)%s", (int) typmod, tz);
151 else
152 return pstrdup(tz);
153}
154
155
156/*****************************************************************************
157 * USER I/O ROUTINES *
158 *****************************************************************************/
159
160/* timestamp_in()
161 * Convert a string to internal form.
162 */
163Datum
165{
166 char *str = PG_GETARG_CSTRING(0);
167#ifdef NOT_USED
168 Oid typelem = PG_GETARG_OID(1);
169#endif
170 int32 typmod = PG_GETARG_INT32(2);
171 Node *escontext = fcinfo->context;
172 Timestamp result;
173 fsec_t fsec;
174 struct pg_tm tt,
175 *tm = &tt;
176 int tz;
177 int dtype;
178 int nf;
179 int dterr;
180 char *field[MAXDATEFIELDS];
181 int ftype[MAXDATEFIELDS];
183 DateTimeErrorExtra extra;
184
186 field, ftype, MAXDATEFIELDS, &nf);
187 if (dterr == 0)
188 dterr = DecodeDateTime(field, ftype, nf,
189 &dtype, tm, &fsec, &tz, &extra);
190 if (dterr != 0)
191 {
192 DateTimeParseError(dterr, &extra, str, "timestamp", escontext);
194 }
195
196 switch (dtype)
197 {
198 case DTK_DATE:
199 if (tm2timestamp(tm, fsec, NULL, &result) != 0)
200 ereturn(escontext, (Datum) 0,
202 errmsg("timestamp out of range: \"%s\"", str)));
203 break;
204
205 case DTK_EPOCH:
206 result = SetEpochTimestamp();
207 break;
208
209 case DTK_LATE:
210 TIMESTAMP_NOEND(result);
211 break;
212
213 case DTK_EARLY:
214 TIMESTAMP_NOBEGIN(result);
215 break;
216
217 default:
218 elog(ERROR, "unexpected dtype %d while parsing timestamp \"%s\"",
219 dtype, str);
220 TIMESTAMP_NOEND(result);
221 }
222
223 AdjustTimestampForTypmod(&result, typmod, escontext);
224
225 PG_RETURN_TIMESTAMP(result);
226}
227
228/* timestamp_out()
229 * Convert a timestamp to external form.
230 */
231Datum
233{
235 char *result;
236 struct pg_tm tt,
237 *tm = &tt;
238 fsec_t fsec;
239 char buf[MAXDATELEN + 1];
240
243 else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) == 0)
244 EncodeDateTime(tm, fsec, false, 0, NULL, DateStyle, buf);
245 else
248 errmsg("timestamp out of range")));
249
250 result = pstrdup(buf);
251 PG_RETURN_CSTRING(result);
252}
253
254/*
255 * timestamp_recv - converts external binary format to timestamp
256 */
257Datum
259{
261
262#ifdef NOT_USED
263 Oid typelem = PG_GETARG_OID(1);
264#endif
265 int32 typmod = PG_GETARG_INT32(2);
267 struct pg_tm tt,
268 *tm = &tt;
269 fsec_t fsec;
270
272
273 /* range check: see if timestamp_out would like it */
275 /* ok */ ;
276 else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0 ||
280 errmsg("timestamp out of range")));
281
283
285}
286
287/*
288 * timestamp_send - converts timestamp to binary format
289 */
290Datum
300
301Datum
308
309Datum
316
317
318/*
319 * timestamp_support()
320 *
321 * Planner support function for the timestamp_scale() and timestamptz_scale()
322 * length coercion functions (we need not distinguish them here).
323 */
324Datum
339
340/* timestamp_scale()
341 * Adjust time type for specified scale factor.
342 * Used by PostgreSQL type system to stuff columns.
343 */
344Datum
346{
348 int32 typmod = PG_GETARG_INT32(1);
349 Timestamp result;
350
351 result = timestamp;
352
353 AdjustTimestampForTypmod(&result, typmod, NULL);
354
355 PG_RETURN_TIMESTAMP(result);
356}
357
358/*
359 * AdjustTimestampForTypmod --- round off a timestamp to suit given typmod
360 * Works for either timestamp or timestamptz.
361 *
362 * Returns true on success, false on failure (if escontext points to an
363 * ErrorSaveContext; otherwise errors are thrown).
364 */
365bool
367{
368 static const int64 TimestampScales[MAX_TIMESTAMP_PRECISION + 1] = {
369 INT64CONST(1000000),
370 INT64CONST(100000),
371 INT64CONST(10000),
372 INT64CONST(1000),
373 INT64CONST(100),
374 INT64CONST(10),
375 INT64CONST(1)
376 };
377
379 INT64CONST(500000),
380 INT64CONST(50000),
381 INT64CONST(5000),
382 INT64CONST(500),
383 INT64CONST(50),
384 INT64CONST(5),
385 INT64CONST(0)
386 };
387
388 if (!TIMESTAMP_NOT_FINITE(*time)
389 && (typmod != -1) && (typmod != MAX_TIMESTAMP_PRECISION))
390 {
392 ereturn(escontext, false,
394 errmsg("timestamp(%d) precision must be between %d and %d",
395 typmod, 0, MAX_TIMESTAMP_PRECISION)));
396
397 if (*time >= INT64CONST(0))
398 {
399 *time = ((*time + TimestampOffsets[typmod]) / TimestampScales[typmod]) *
400 TimestampScales[typmod];
401 }
402 else
403 {
404 *time = -((((-*time) + TimestampOffsets[typmod]) / TimestampScales[typmod])
405 * TimestampScales[typmod]);
406 }
407 }
408
409 return true;
410}
411
412/* timestamptz_in()
413 * Convert a string to internal form.
414 */
415Datum
417{
418 char *str = PG_GETARG_CSTRING(0);
419#ifdef NOT_USED
420 Oid typelem = PG_GETARG_OID(1);
421#endif
422 int32 typmod = PG_GETARG_INT32(2);
423 Node *escontext = fcinfo->context;
424 TimestampTz result;
425 fsec_t fsec;
426 struct pg_tm tt,
427 *tm = &tt;
428 int tz;
429 int dtype;
430 int nf;
431 int dterr;
432 char *field[MAXDATEFIELDS];
433 int ftype[MAXDATEFIELDS];
435 DateTimeErrorExtra extra;
436
438 field, ftype, MAXDATEFIELDS, &nf);
439 if (dterr == 0)
440 dterr = DecodeDateTime(field, ftype, nf,
441 &dtype, tm, &fsec, &tz, &extra);
442 if (dterr != 0)
443 {
444 DateTimeParseError(dterr, &extra, str, "timestamp with time zone",
445 escontext);
447 }
448
449 switch (dtype)
450 {
451 case DTK_DATE:
452 if (tm2timestamp(tm, fsec, &tz, &result) != 0)
453 ereturn(escontext, (Datum) 0,
455 errmsg("timestamp out of range: \"%s\"", str)));
456 break;
457
458 case DTK_EPOCH:
459 result = SetEpochTimestamp();
460 break;
461
462 case DTK_LATE:
463 TIMESTAMP_NOEND(result);
464 break;
465
466 case DTK_EARLY:
467 TIMESTAMP_NOBEGIN(result);
468 break;
469
470 default:
471 elog(ERROR, "unexpected dtype %d while parsing timestamptz \"%s\"",
472 dtype, str);
473 TIMESTAMP_NOEND(result);
474 }
475
476 AdjustTimestampForTypmod(&result, typmod, escontext);
477
478 PG_RETURN_TIMESTAMPTZ(result);
479}
480
481/*
482 * Try to parse a timezone specification, and return its timezone offset value
483 * if it's acceptable. Otherwise, an error is thrown.
484 *
485 * Note: some code paths update tm->tm_isdst, and some don't; current callers
486 * don't care, so we don't bother being consistent.
487 */
488static int
490{
491 char tzname[TZ_STRLEN_MAX + 1];
492 int dterr;
493 int tz;
494
496
497 /*
498 * Look up the requested timezone. First we try to interpret it as a
499 * numeric timezone specification; if DecodeTimezone decides it doesn't
500 * like the format, we try timezone abbreviations and names.
501 *
502 * Note pg_tzset happily parses numeric input that DecodeTimezone would
503 * reject. To avoid having it accept input that would otherwise be seen
504 * as invalid, it's enough to disallow having a digit in the first
505 * position of our input string.
506 */
507 if (isdigit((unsigned char) *tzname))
510 errmsg("invalid input syntax for type %s: \"%s\"",
511 "numeric time zone", tzname),
512 errhint("Numeric time zones must have \"-\" or \"+\" as first character.")));
513
515 if (dterr != 0)
516 {
517 int type,
518 val;
519 pg_tz *tzp;
520
524 errmsg("numeric time zone \"%s\" out of range", tzname)));
525 else if (dterr != DTERR_BAD_FORMAT)
528 errmsg("time zone \"%s\" not recognized", tzname)));
529
531
533 {
534 /* fixed-offset abbreviation */
535 tz = -val;
536 }
537 else if (type == TZNAME_DYNTZ)
538 {
539 /* dynamic-offset abbreviation, resolve using specified time */
541 }
542 else
543 {
544 /* full zone name */
545 tz = DetermineTimeZoneOffset(tm, tzp);
546 }
547 }
548
549 return tz;
550}
551
552/*
553 * Look up the requested timezone, returning a pg_tz struct.
554 *
555 * This is the same as DecodeTimezoneNameToTz, but starting with a text Datum.
556 */
557static pg_tz *
559{
560 char tzname[TZ_STRLEN_MAX + 1];
561
563
565}
566
567/*
568 * make_timestamp_internal
569 * workhorse for make_timestamp and make_timestamptz
570 */
571static Timestamp
572make_timestamp_internal(int year, int month, int day,
573 int hour, int min, double sec)
574{
575 struct pg_tm tm;
577 TimeOffset time;
578 int dterr;
579 bool bc = false;
580 Timestamp result;
581
582 tm.tm_year = year;
583 tm.tm_mon = month;
584 tm.tm_mday = day;
585
586 /* Handle negative years as BC */
587 if (tm.tm_year < 0)
588 {
589 bc = true;
590 tm.tm_year = -tm.tm_year;
591 }
592
593 dterr = ValidateDate(DTK_DATE_M, false, false, bc, &tm);
594
595 if (dterr != 0)
598 errmsg("date field value out of range: %d-%02d-%02d",
599 year, month, day)));
600
604 errmsg("date out of range: %d-%02d-%02d",
605 year, month, day)));
606
608
609 /* Check for time overflow */
610 if (float_time_overflows(hour, min, sec))
613 errmsg("time field value out of range: %d:%02d:%02g",
614 hour, min, sec)));
615
616 /* This should match tm2time */
617 time = (((hour * MINS_PER_HOUR + min) * SECS_PER_MINUTE)
619
621 pg_add_s64_overflow(result, time, &result)))
624 errmsg("timestamp out of range: %d-%02d-%02d %d:%02d:%02g",
625 year, month, day,
626 hour, min, sec)));
627
628 /* final range check catches just-out-of-range timestamps */
629 if (!IS_VALID_TIMESTAMP(result))
632 errmsg("timestamp out of range: %d-%02d-%02d %d:%02d:%02g",
633 year, month, day,
634 hour, min, sec)));
635
636 return result;
637}
638
639/*
640 * make_timestamp() - timestamp constructor
641 */
642Datum
644{
645 int32 year = PG_GETARG_INT32(0);
646 int32 month = PG_GETARG_INT32(1);
649 int32 min = PG_GETARG_INT32(4);
650 float8 sec = PG_GETARG_FLOAT8(5);
651 Timestamp result;
652
653 result = make_timestamp_internal(year, month, mday,
654 hour, min, sec);
655
656 PG_RETURN_TIMESTAMP(result);
657}
658
659/*
660 * make_timestamptz() - timestamp with time zone constructor
661 */
662Datum
664{
665 int32 year = PG_GETARG_INT32(0);
666 int32 month = PG_GETARG_INT32(1);
669 int32 min = PG_GETARG_INT32(4);
670 float8 sec = PG_GETARG_FLOAT8(5);
671 Timestamp result;
672
673 result = make_timestamp_internal(year, month, mday,
674 hour, min, sec);
675
677}
678
679/*
680 * Construct a timestamp with time zone.
681 * As above, but the time zone is specified as seventh argument.
682 */
683Datum
685{
686 int32 year = PG_GETARG_INT32(0);
687 int32 month = PG_GETARG_INT32(1);
690 int32 min = PG_GETARG_INT32(4);
691 float8 sec = PG_GETARG_FLOAT8(5);
693 TimestampTz result;
695 struct pg_tm tt;
696 int tz;
697 fsec_t fsec;
698
700 hour, min, sec);
701
702 if (timestamp2tm(timestamp, NULL, &tt, &fsec, NULL, NULL) != 0)
705 errmsg("timestamp out of range")));
706
708
709 result = dt2local(timestamp, -tz);
710
711 if (!IS_VALID_TIMESTAMP(result))
714 errmsg("timestamp out of range")));
715
716 PG_RETURN_TIMESTAMPTZ(result);
717}
718
719/*
720 * to_timestamp(double precision)
721 * Convert UNIX epoch to timestamptz.
722 */
723Datum
725{
727 TimestampTz result;
728
729 /* Deal with NaN and infinite inputs ... */
730 if (isnan(seconds))
733 errmsg("timestamp cannot be NaN")));
734
735 if (isinf(seconds))
736 {
737 if (seconds < 0)
738 TIMESTAMP_NOBEGIN(result);
739 else
740 TIMESTAMP_NOEND(result);
741 }
742 else
743 {
744 /* Out of range? */
745 if (seconds <
747 || seconds >=
751 errmsg("timestamp out of range: \"%g\"", seconds)));
752
753 /* Convert UNIX epoch to Postgres epoch */
755
757 result = (int64) seconds;
758
759 /* Recheck in case roundoff produces something just out of range */
760 if (!IS_VALID_TIMESTAMP(result))
763 errmsg("timestamp out of range: \"%g\"",
764 PG_GETARG_FLOAT8(0))));
765 }
766
767 PG_RETURN_TIMESTAMP(result);
768}
769
770/* timestamptz_out()
771 * Convert a timestamp to external form.
772 */
773Datum
775{
777 char *result;
778 int tz;
779 struct pg_tm tt,
780 *tm = &tt;
781 fsec_t fsec;
782 const char *tzn;
783 char buf[MAXDATELEN + 1];
784
787 else if (timestamp2tm(dt, &tz, tm, &fsec, &tzn, NULL) == 0)
788 EncodeDateTime(tm, fsec, true, tz, tzn, DateStyle, buf);
789 else
792 errmsg("timestamp out of range")));
793
794 result = pstrdup(buf);
795 PG_RETURN_CSTRING(result);
796}
797
798/*
799 * timestamptz_recv - converts external binary format to timestamptz
800 */
801Datum
803{
805
806#ifdef NOT_USED
807 Oid typelem = PG_GETARG_OID(1);
808#endif
809 int32 typmod = PG_GETARG_INT32(2);
811 int tz;
812 struct pg_tm tt,
813 *tm = &tt;
814 fsec_t fsec;
815
817
818 /* range check: see if timestamptz_out would like it */
820 /* ok */ ;
821 else if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0 ||
825 errmsg("timestamp out of range")));
826
828
830}
831
832/*
833 * timestamptz_send - converts timestamptz to binary format
834 */
835Datum
845
846Datum
853
854Datum
861
862
863/* timestamptz_scale()
864 * Adjust time type for specified scale factor.
865 * Used by PostgreSQL type system to stuff columns.
866 */
867Datum
869{
871 int32 typmod = PG_GETARG_INT32(1);
872 TimestampTz result;
873
874 result = timestamp;
875
876 AdjustTimestampForTypmod(&result, typmod, NULL);
877
878 PG_RETURN_TIMESTAMPTZ(result);
879}
880
881
882/* interval_in()
883 * Convert a string to internal form.
884 *
885 * External format(s):
886 * Uses the generic date/time parsing and decoding routines.
887 */
888Datum
890{
891 char *str = PG_GETARG_CSTRING(0);
892#ifdef NOT_USED
893 Oid typelem = PG_GETARG_OID(1);
894#endif
895 int32 typmod = PG_GETARG_INT32(2);
896 Node *escontext = fcinfo->context;
897 Interval *result;
898 struct pg_itm_in tt,
899 *itm_in = &tt;
900 int dtype;
901 int nf;
902 int range;
903 int dterr;
904 char *field[MAXDATEFIELDS];
905 int ftype[MAXDATEFIELDS];
906 char workbuf[256];
907 DateTimeErrorExtra extra;
908
909 itm_in->tm_year = 0;
910 itm_in->tm_mon = 0;
911 itm_in->tm_mday = 0;
912 itm_in->tm_usec = 0;
913
914 if (typmod >= 0)
915 range = INTERVAL_RANGE(typmod);
916 else
918
919 dterr = ParseDateTime(str, workbuf, sizeof(workbuf), field,
920 ftype, MAXDATEFIELDS, &nf);
921 if (dterr == 0)
922 dterr = DecodeInterval(field, ftype, nf, range,
923 &dtype, itm_in);
924
925 /* if those functions think it's a bad format, try ISO8601 style */
926 if (dterr == DTERR_BAD_FORMAT)
928 &dtype, itm_in);
929
930 if (dterr != 0)
931 {
934 DateTimeParseError(dterr, &extra, str, "interval", escontext);
936 }
937
938 result = palloc_object(Interval);
939
940 switch (dtype)
941 {
942 case DTK_DELTA:
943 if (itmin2interval(itm_in, result) != 0)
944 ereturn(escontext, (Datum) 0,
946 errmsg("interval out of range")));
947 break;
948
949 case DTK_LATE:
950 INTERVAL_NOEND(result);
951 break;
952
953 case DTK_EARLY:
954 INTERVAL_NOBEGIN(result);
955 break;
956
957 default:
958 elog(ERROR, "unexpected dtype %d while parsing interval \"%s\"",
959 dtype, str);
960 }
961
962 AdjustIntervalForTypmod(result, typmod, escontext);
963
964 PG_RETURN_INTERVAL_P(result);
965}
966
967/* interval_out()
968 * Convert a time span to external form.
969 */
970Datum
972{
974 char *result;
975 struct pg_itm tt,
976 *itm = &tt;
977 char buf[MAXDATELEN + 1];
978
981 else
982 {
985 }
986
987 result = pstrdup(buf);
988 PG_RETURN_CSTRING(result);
989}
990
991/*
992 * interval_recv - converts external binary format to interval
993 */
994Datum
996{
998
999#ifdef NOT_USED
1000 Oid typelem = PG_GETARG_OID(1);
1001#endif
1002 int32 typmod = PG_GETARG_INT32(2);
1004
1006
1008 interval->day = pq_getmsgint(buf, sizeof(interval->day));
1010
1012
1014}
1015
1016/*
1017 * interval_send - converts interval to binary format
1018 */
1019Datum
1031
1032/*
1033 * The interval typmod stores a "range" in its high 16 bits and a "precision"
1034 * in its low 16 bits. Both contribute to defining the resolution of the
1035 * type. Range addresses resolution granules larger than one second, and
1036 * precision specifies resolution below one second. This representation can
1037 * express all SQL standard resolutions, but we implement them all in terms of
1038 * truncating rightward from some position. Range is a bitmap of permitted
1039 * fields, but only the temporally-smallest such field is significant to our
1040 * calculations. Precision is a count of sub-second decimal places to retain.
1041 * Setting all bits (INTERVAL_FULL_PRECISION) gives the same truncation
1042 * semantics as choosing MAX_INTERVAL_PRECISION.
1043 */
1044Datum
1046{
1048 int32 *tl;
1049 int n;
1050 int32 typmod;
1051
1053
1054 /*
1055 * tl[0] - interval range (fields bitmask) tl[1] - precision (optional)
1056 *
1057 * Note we must validate tl[0] even though it's normally guaranteed
1058 * correct by the grammar --- consider SELECT 'foo'::"interval"(1000).
1059 */
1060 if (n > 0)
1061 {
1062 switch (tl[0])
1063 {
1064 case INTERVAL_MASK(YEAR):
1065 case INTERVAL_MASK(MONTH):
1066 case INTERVAL_MASK(DAY):
1067 case INTERVAL_MASK(HOUR):
1068 case INTERVAL_MASK(MINUTE):
1069 case INTERVAL_MASK(SECOND):
1078 /* all OK */
1079 break;
1080 default:
1081 ereport(ERROR,
1083 errmsg("invalid INTERVAL type modifier")));
1084 }
1085 }
1086
1087 if (n == 1)
1088 {
1089 if (tl[0] != INTERVAL_FULL_RANGE)
1091 else
1092 typmod = -1;
1093 }
1094 else if (n == 2)
1095 {
1096 if (tl[1] < 0)
1097 ereport(ERROR,
1099 errmsg("INTERVAL(%d) precision must not be negative",
1100 tl[1])));
1101 if (tl[1] > MAX_INTERVAL_PRECISION)
1102 {
1105 errmsg("INTERVAL(%d) precision reduced to maximum allowed, %d",
1108 }
1109 else
1110 typmod = INTERVAL_TYPMOD(tl[1], tl[0]);
1111 }
1112 else
1113 {
1114 ereport(ERROR,
1116 errmsg("invalid INTERVAL type modifier")));
1117 typmod = 0; /* keep compiler quiet */
1118 }
1119
1120 PG_RETURN_INT32(typmod);
1121}
1122
1123Datum
1125{
1126 int32 typmod = PG_GETARG_INT32(0);
1127 char *res = (char *) palloc(64);
1128 int fields;
1129 int precision;
1130 const char *fieldstr;
1131
1132 if (typmod < 0)
1133 {
1134 *res = '\0';
1135 PG_RETURN_CSTRING(res);
1136 }
1137
1138 fields = INTERVAL_RANGE(typmod);
1139 precision = INTERVAL_PRECISION(typmod);
1140
1141 switch (fields)
1142 {
1143 case INTERVAL_MASK(YEAR):
1144 fieldstr = " year";
1145 break;
1146 case INTERVAL_MASK(MONTH):
1147 fieldstr = " month";
1148 break;
1149 case INTERVAL_MASK(DAY):
1150 fieldstr = " day";
1151 break;
1152 case INTERVAL_MASK(HOUR):
1153 fieldstr = " hour";
1154 break;
1155 case INTERVAL_MASK(MINUTE):
1156 fieldstr = " minute";
1157 break;
1158 case INTERVAL_MASK(SECOND):
1159 fieldstr = " second";
1160 break;
1162 fieldstr = " year to month";
1163 break;
1165 fieldstr = " day to hour";
1166 break;
1168 fieldstr = " day to minute";
1169 break;
1171 fieldstr = " day to second";
1172 break;
1174 fieldstr = " hour to minute";
1175 break;
1177 fieldstr = " hour to second";
1178 break;
1180 fieldstr = " minute to second";
1181 break;
1183 fieldstr = "";
1184 break;
1185 default:
1186 elog(ERROR, "invalid INTERVAL typmod: 0x%x", typmod);
1187 fieldstr = "";
1188 break;
1189 }
1190
1191 if (precision != INTERVAL_FULL_PRECISION)
1192 snprintf(res, 64, "%s(%d)", fieldstr, precision);
1193 else
1194 snprintf(res, 64, "%s", fieldstr);
1195
1196 PG_RETURN_CSTRING(res);
1197}
1198
1199/*
1200 * Given an interval typmod value, return a code for the least-significant
1201 * field that the typmod allows to be nonzero, for instance given
1202 * INTERVAL DAY TO HOUR we want to identify "hour".
1203 *
1204 * The results should be ordered by field significance, which means
1205 * we can't use the dt.h macros YEAR etc, because for some odd reason
1206 * they aren't ordered that way. Instead, arbitrarily represent
1207 * SECOND = 0, MINUTE = 1, HOUR = 2, DAY = 3, MONTH = 4, YEAR = 5.
1208 */
1209static int
1211{
1212 if (typmod < 0)
1213 return 0; /* SECOND */
1214
1215 switch (INTERVAL_RANGE(typmod))
1216 {
1217 case INTERVAL_MASK(YEAR):
1218 return 5; /* YEAR */
1219 case INTERVAL_MASK(MONTH):
1220 return 4; /* MONTH */
1221 case INTERVAL_MASK(DAY):
1222 return 3; /* DAY */
1223 case INTERVAL_MASK(HOUR):
1224 return 2; /* HOUR */
1225 case INTERVAL_MASK(MINUTE):
1226 return 1; /* MINUTE */
1227 case INTERVAL_MASK(SECOND):
1228 return 0; /* SECOND */
1230 return 4; /* MONTH */
1232 return 2; /* HOUR */
1234 return 1; /* MINUTE */
1236 return 0; /* SECOND */
1238 return 1; /* MINUTE */
1240 return 0; /* SECOND */
1242 return 0; /* SECOND */
1244 return 0; /* SECOND */
1245 default:
1246 elog(ERROR, "invalid INTERVAL typmod: 0x%x", typmod);
1247 break;
1248 }
1249 return 0; /* can't get here, but keep compiler quiet */
1250}
1251
1252
1253/*
1254 * interval_support()
1255 *
1256 * Planner support function for interval_scale().
1257 *
1258 * Flatten superfluous calls to interval_scale(). The interval typmod is
1259 * complex to permit accepting and regurgitating all SQL standard variations.
1260 * For truncation purposes, it boils down to a single, simple granularity.
1261 */
1262Datum
1264{
1266 Node *ret = NULL;
1267
1269 {
1271 FuncExpr *expr = req->fcall;
1272 Node *typmod;
1273
1274 Assert(list_length(expr->args) >= 2);
1275
1276 typmod = (Node *) lsecond(expr->args);
1277
1278 if (IsA(typmod, Const) && !((Const *) typmod)->constisnull)
1279 {
1280 Node *source = (Node *) linitial(expr->args);
1282 bool noop;
1283
1284 if (new_typmod < 0)
1285 noop = true;
1286 else
1287 {
1289 int old_least_field;
1290 int new_least_field;
1291 int old_precis;
1292 int new_precis;
1293
1296 if (old_typmod < 0)
1298 else
1301
1302 /*
1303 * Cast is a no-op if least field stays the same or decreases
1304 * while precision stays the same or increases. But
1305 * precision, which is to say, sub-second precision, only
1306 * affects ranges that include SECOND.
1307 */
1309 (old_least_field > 0 /* SECOND */ ||
1312 }
1313 if (noop)
1315 }
1316 }
1317
1318 PG_RETURN_POINTER(ret);
1319}
1320
1321/* interval_scale()
1322 * Adjust interval type for specified fields.
1323 * Used by PostgreSQL type system to stuff columns.
1324 */
1325Datum
1327{
1329 int32 typmod = PG_GETARG_INT32(1);
1330 Interval *result;
1331
1332 result = palloc_object(Interval);
1333 *result = *interval;
1334
1335 AdjustIntervalForTypmod(result, typmod, NULL);
1336
1337 PG_RETURN_INTERVAL_P(result);
1338}
1339
1340/*
1341 * Adjust interval for specified precision, in both YEAR to SECOND
1342 * range and sub-second precision.
1343 *
1344 * Returns true on success, false on failure (if escontext points to an
1345 * ErrorSaveContext; otherwise errors are thrown).
1346 */
1347static bool
1349 Node *escontext)
1350{
1351 static const int64 IntervalScales[MAX_INTERVAL_PRECISION + 1] = {
1352 INT64CONST(1000000),
1353 INT64CONST(100000),
1354 INT64CONST(10000),
1355 INT64CONST(1000),
1356 INT64CONST(100),
1357 INT64CONST(10),
1358 INT64CONST(1)
1359 };
1360
1361 static const int64 IntervalOffsets[MAX_INTERVAL_PRECISION + 1] = {
1362 INT64CONST(500000),
1363 INT64CONST(50000),
1364 INT64CONST(5000),
1365 INT64CONST(500),
1366 INT64CONST(50),
1367 INT64CONST(5),
1368 INT64CONST(0)
1369 };
1370
1371 /* Typmod has no effect on infinite intervals */
1373 return true;
1374
1375 /*
1376 * Unspecified range and precision? Then not necessary to adjust. Setting
1377 * typmod to -1 is the convention for all data types.
1378 */
1379 if (typmod >= 0)
1380 {
1381 int range = INTERVAL_RANGE(typmod);
1382 int precision = INTERVAL_PRECISION(typmod);
1383
1384 /*
1385 * Our interpretation of intervals with a limited set of fields is
1386 * that fields to the right of the last one specified are zeroed out,
1387 * but those to the left of it remain valid. Thus for example there
1388 * is no operational difference between INTERVAL YEAR TO MONTH and
1389 * INTERVAL MONTH. In some cases we could meaningfully enforce that
1390 * higher-order fields are zero; for example INTERVAL DAY could reject
1391 * nonzero "month" field. However that seems a bit pointless when we
1392 * can't do it consistently. (We cannot enforce a range limit on the
1393 * highest expected field, since we do not have any equivalent of
1394 * SQL's <interval leading field precision>.) If we ever decide to
1395 * revisit this, interval_support will likely require adjusting.
1396 *
1397 * Note: before PG 8.4 we interpreted a limited set of fields as
1398 * actually causing a "modulo" operation on a given value, potentially
1399 * losing high-order as well as low-order information. But there is
1400 * no support for such behavior in the standard, and it seems fairly
1401 * undesirable on data consistency grounds anyway. Now we only
1402 * perform truncation or rounding of low-order fields.
1403 */
1405 {
1406 /* Do nothing... */
1407 }
1408 else if (range == INTERVAL_MASK(YEAR))
1409 {
1411 interval->day = 0;
1412 interval->time = 0;
1413 }
1414 else if (range == INTERVAL_MASK(MONTH))
1415 {
1416 interval->day = 0;
1417 interval->time = 0;
1418 }
1419 /* YEAR TO MONTH */
1420 else if (range == (INTERVAL_MASK(YEAR) | INTERVAL_MASK(MONTH)))
1421 {
1422 interval->day = 0;
1423 interval->time = 0;
1424 }
1425 else if (range == INTERVAL_MASK(DAY))
1426 {
1427 interval->time = 0;
1428 }
1429 else if (range == INTERVAL_MASK(HOUR))
1430 {
1433 }
1434 else if (range == INTERVAL_MASK(MINUTE))
1435 {
1438 }
1439 else if (range == INTERVAL_MASK(SECOND))
1440 {
1441 /* fractional-second rounding will be dealt with below */
1442 }
1443 /* DAY TO HOUR */
1444 else if (range == (INTERVAL_MASK(DAY) |
1446 {
1449 }
1450 /* DAY TO MINUTE */
1451 else if (range == (INTERVAL_MASK(DAY) |
1454 {
1457 }
1458 /* DAY TO SECOND */
1459 else if (range == (INTERVAL_MASK(DAY) |
1463 {
1464 /* fractional-second rounding will be dealt with below */
1465 }
1466 /* HOUR TO MINUTE */
1467 else if (range == (INTERVAL_MASK(HOUR) |
1469 {
1472 }
1473 /* HOUR TO SECOND */
1474 else if (range == (INTERVAL_MASK(HOUR) |
1477 {
1478 /* fractional-second rounding will be dealt with below */
1479 }
1480 /* MINUTE TO SECOND */
1481 else if (range == (INTERVAL_MASK(MINUTE) |
1483 {
1484 /* fractional-second rounding will be dealt with below */
1485 }
1486 else
1487 elog(ERROR, "unrecognized interval typmod: %d", typmod);
1488
1489 /* Need to adjust sub-second precision? */
1490 if (precision != INTERVAL_FULL_PRECISION)
1491 {
1493 ereturn(escontext, false,
1495 errmsg("interval(%d) precision must be between %d and %d",
1496 precision, 0, MAX_INTERVAL_PRECISION)));
1497
1498 if (interval->time >= INT64CONST(0))
1499 {
1501 IntervalOffsets[precision],
1502 &interval->time))
1503 ereturn(escontext, false,
1505 errmsg("interval out of range")));
1506 interval->time -= interval->time % IntervalScales[precision];
1507 }
1508 else
1509 {
1511 IntervalOffsets[precision],
1512 &interval->time))
1513 ereturn(escontext, false,
1515 errmsg("interval out of range")));
1516 interval->time -= interval->time % IntervalScales[precision];
1517 }
1518 }
1519 }
1520
1521 return true;
1522}
1523
1524/*
1525 * make_interval - numeric Interval constructor
1526 */
1527Datum
1529{
1536 double secs = PG_GETARG_FLOAT8(6);
1537 Interval *result;
1538
1539 /*
1540 * Reject out-of-range inputs. We reject any input values that cause
1541 * integer overflow of the corresponding interval fields.
1542 */
1543 if (isinf(secs) || isnan(secs))
1544 goto out_of_range;
1545
1546 result = palloc_object(Interval);
1547
1548 /* years and months -> months */
1550 pg_add_s32_overflow(result->month, months, &result->month))
1551 goto out_of_range;
1552
1553 /* weeks and days -> days */
1554 if (pg_mul_s32_overflow(weeks, DAYS_PER_WEEK, &result->day) ||
1555 pg_add_s32_overflow(result->day, days, &result->day))
1556 goto out_of_range;
1557
1558 /* hours and mins -> usecs (cannot overflow 64-bit) */
1560
1561 /* secs -> usecs */
1563 if (!FLOAT8_FITS_IN_INT64(secs) ||
1564 pg_add_s64_overflow(result->time, (int64) secs, &result->time))
1565 goto out_of_range;
1566
1567 /* make sure that the result is finite */
1568 if (INTERVAL_NOT_FINITE(result))
1569 goto out_of_range;
1570
1571 PG_RETURN_INTERVAL_P(result);
1572
1574 ereport(ERROR,
1576 errmsg("interval out of range"));
1577
1578 PG_RETURN_NULL(); /* keep compiler quiet */
1579}
1580
1581/* EncodeSpecialTimestamp()
1582 * Convert reserved timestamp data type to string.
1583 */
1584void
1586{
1588 strcpy(str, EARLY);
1589 else if (TIMESTAMP_IS_NOEND(dt))
1590 strcpy(str, LATE);
1591 else /* shouldn't happen */
1592 elog(ERROR, "invalid argument for EncodeSpecialTimestamp");
1593}
1594
1595static void
1597{
1599 strcpy(str, EARLY);
1600 else if (INTERVAL_IS_NOEND(interval))
1601 strcpy(str, LATE);
1602 else /* shouldn't happen */
1603 elog(ERROR, "invalid argument for EncodeSpecialInterval");
1604}
1605
1606Datum
1611
1612Datum
1617
1618Datum
1623
1624Datum
1629
1630Datum
1635
1636/*
1637 * GetCurrentTimestamp -- get the current operating system time
1638 *
1639 * Result is in the form of a TimestampTz value, and is expressed to the
1640 * full precision of the gettimeofday() syscall
1641 */
1644{
1645 TimestampTz result;
1646 struct timeval tp;
1647
1648 gettimeofday(&tp, NULL);
1649
1650 result = (TimestampTz) tp.tv_sec -
1652 result = (result * USECS_PER_SEC) + tp.tv_usec;
1653
1654 return result;
1655}
1656
1657/*
1658 * GetSQLCurrentTimestamp -- implements CURRENT_TIMESTAMP, CURRENT_TIMESTAMP(n)
1659 */
1662{
1663 TimestampTz ts;
1664
1666 if (typmod >= 0)
1667 AdjustTimestampForTypmod(&ts, typmod, NULL);
1668 return ts;
1669}
1670
1671/*
1672 * GetSQLLocalTimestamp -- implements LOCALTIMESTAMP, LOCALTIMESTAMP(n)
1673 */
1676{
1677 Timestamp ts;
1678
1680 if (typmod >= 0)
1681 AdjustTimestampForTypmod(&ts, typmod, NULL);
1682 return ts;
1683}
1684
1685/*
1686 * timeofday(*) -- returns the current time as a text.
1687 */
1688Datum
1690{
1691 struct timeval tp;
1692 char templ[128];
1693 char buf[128];
1694 pg_time_t tt;
1695
1696 gettimeofday(&tp, NULL);
1697 tt = (pg_time_t) tp.tv_sec;
1698 pg_strftime(templ, sizeof(templ), "%a %b %d %H:%M:%S.%%06d %Y %Z",
1700 snprintf(buf, sizeof(buf), templ, tp.tv_usec);
1701
1703}
1704
1705/*
1706 * TimestampDifference -- convert the difference between two timestamps
1707 * into integer seconds and microseconds
1708 *
1709 * This is typically used to calculate a wait timeout for select(2),
1710 * which explains the otherwise-odd choice of output format.
1711 *
1712 * Both inputs must be ordinary finite timestamps (in current usage,
1713 * they'll be results from GetCurrentTimestamp()).
1714 *
1715 * We expect start_time <= stop_time. If not, we return zeros,
1716 * since then we're already past the previously determined stop_time.
1717 */
1718void
1720 long *secs, int *microsecs)
1721{
1723
1724 if (diff <= 0)
1725 {
1726 *secs = 0;
1727 *microsecs = 0;
1728 }
1729 else
1730 {
1731 *secs = (long) (diff / USECS_PER_SEC);
1733 }
1734}
1735
1736/*
1737 * TimestampDifferenceMilliseconds -- convert the difference between two
1738 * timestamps into integer milliseconds
1739 *
1740 * This is typically used to calculate a wait timeout for WaitLatch()
1741 * or a related function. The choice of "long" as the result type
1742 * is to harmonize with that; furthermore, we clamp the result to at most
1743 * INT_MAX milliseconds, because that's all that WaitLatch() allows.
1744 *
1745 * We expect start_time <= stop_time. If not, we return zero,
1746 * since then we're already past the previously determined stop_time.
1747 *
1748 * Subtracting finite and infinite timestamps works correctly, returning
1749 * zero or INT_MAX as appropriate.
1750 *
1751 * Note we round up any fractional millisecond, since waiting for just
1752 * less than the intended timeout is undesirable.
1753 */
1754long
1756{
1758
1759 /* Deal with zero or negative elapsed time quickly. */
1760 if (start_time >= stop_time)
1761 return 0;
1762 /* To not fail with timestamp infinities, we must detect overflow. */
1764 return (long) INT_MAX;
1765 if (diff >= (INT_MAX * INT64CONST(1000) - 999))
1766 return (long) INT_MAX;
1767 else
1768 return (long) ((diff + 999) / 1000);
1769}
1770
1771/*
1772 * TimestampDifferenceExceeds -- report whether the difference between two
1773 * timestamps is >= a threshold (expressed in milliseconds)
1774 *
1775 * Both inputs must be ordinary finite timestamps (in current usage,
1776 * they'll be results from GetCurrentTimestamp()).
1777 */
1778bool
1787
1788/*
1789 * Check if the difference between two timestamps is >= a given
1790 * threshold (expressed in seconds).
1791 */
1792bool
1795 int threshold_sec)
1796{
1797 long secs;
1798 int usecs;
1799
1800 /* Calculate the difference in seconds */
1802
1803 return (secs >= threshold_sec);
1804}
1805
1806/*
1807 * Convert a time_t to TimestampTz.
1808 *
1809 * We do not use time_t internally in Postgres, but this is provided for use
1810 * by functions that need to interpret, say, a stat(2) result.
1811 *
1812 * To avoid having the function's ABI vary depending on the width of time_t,
1813 * we declare the argument as pg_time_t, which is cast-compatible with
1814 * time_t but always 64 bits wide (unless the platform has no 64-bit type).
1815 * This detail should be invisible to callers, at least at source code level.
1816 */
1819{
1820 TimestampTz result;
1821
1822 result = (TimestampTz) tm -
1824 result *= USECS_PER_SEC;
1825
1826 return result;
1827}
1828
1829/*
1830 * Convert a TimestampTz to time_t.
1831 *
1832 * This too is just marginally useful, but some places need it.
1833 *
1834 * To avoid having the function's ABI vary depending on the width of time_t,
1835 * we declare the result as pg_time_t, which is cast-compatible with
1836 * time_t but always 64 bits wide (unless the platform has no 64-bit type).
1837 * This detail should be invisible to callers, at least at source code level.
1838 */
1841{
1842 pg_time_t result;
1843
1844 result = (pg_time_t) (t / USECS_PER_SEC +
1846
1847 return result;
1848}
1849
1850/*
1851 * Produce a C-string representation of a TimestampTz.
1852 *
1853 * This is mostly for use in emitting messages. The primary difference
1854 * from timestamptz_out is that we force the output format to ISO. Note
1855 * also that the result is in a static buffer, not pstrdup'd.
1856 *
1857 * See also pg_strftime.
1858 */
1859const char *
1861{
1862 static char buf[MAXDATELEN + 1];
1863 int tz;
1864 struct pg_tm tt,
1865 *tm = &tt;
1866 fsec_t fsec;
1867 const char *tzn;
1868
1869 if (TIMESTAMP_NOT_FINITE(t))
1871 else if (timestamp2tm(t, &tz, tm, &fsec, &tzn, NULL) == 0)
1872 EncodeDateTime(tm, fsec, true, tz, tzn, USE_ISO_DATES, buf);
1873 else
1874 strlcpy(buf, "(timestamp out of range)", sizeof(buf));
1875
1876 return buf;
1877}
1878
1879
1880void
1881dt2time(Timestamp jd, int *hour, int *min, int *sec, fsec_t *fsec)
1882{
1883 TimeOffset time;
1884
1885 time = jd;
1886
1887 *hour = time / USECS_PER_HOUR;
1888 time -= (*hour) * USECS_PER_HOUR;
1889 *min = time / USECS_PER_MINUTE;
1890 time -= (*min) * USECS_PER_MINUTE;
1891 *sec = time / USECS_PER_SEC;
1892 *fsec = time - (*sec * USECS_PER_SEC);
1893} /* dt2time() */
1894
1895
1896/*
1897 * timestamp2tm() - Convert timestamp data type to POSIX time structure.
1898 *
1899 * Note that year is _not_ 1900-based, but is an explicit full value.
1900 * Also, month is one-based, _not_ zero-based.
1901 * Returns:
1902 * 0 on success
1903 * -1 on out of range
1904 *
1905 * If attimezone is NULL, the global timezone setting will be used.
1906 */
1907int
1908timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
1909{
1911 Timestamp time;
1913
1914 /* Use session timezone if caller asks for default */
1915 if (attimezone == NULL)
1916 attimezone = session_timezone;
1917
1918 time = dt;
1919 TMODULO(time, date, USECS_PER_DAY);
1920
1921 if (time < INT64CONST(0))
1922 {
1923 time += USECS_PER_DAY;
1924 date -= 1;
1925 }
1926
1927 /* add offset to go from J2000 back to standard Julian date */
1929
1930 /* Julian day routine does not work for negative Julian days */
1932 return -1;
1933
1934 j2date((int) date, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
1935 dt2time(time, &tm->tm_hour, &tm->tm_min, &tm->tm_sec, fsec);
1936
1937 /* Done if no TZ conversion wanted */
1938 if (tzp == NULL)
1939 {
1940 tm->tm_isdst = -1;
1941 tm->tm_gmtoff = 0;
1942 tm->tm_zone = NULL;
1943 if (tzn != NULL)
1944 *tzn = NULL;
1945 return 0;
1946 }
1947
1948 /*
1949 * If the time falls within the range of pg_time_t, use pg_localtime() to
1950 * rotate to the local time zone.
1951 *
1952 * First, convert to an integral timestamp, avoiding possibly
1953 * platform-specific roundoff-in-wrong-direction errors, and adjust to
1954 * Unix epoch. Then see if we can convert to pg_time_t without loss. This
1955 * coding avoids hardwiring any assumptions about the width of pg_time_t,
1956 * so it should behave sanely on machines without int64.
1957 */
1958 dt = (dt - *fsec) / USECS_PER_SEC +
1960 utime = (pg_time_t) dt;
1961 if ((Timestamp) utime == dt)
1962 {
1963 struct pg_tm *tx = pg_localtime(&utime, attimezone);
1964
1965 tm->tm_year = tx->tm_year + 1900;
1966 tm->tm_mon = tx->tm_mon + 1;
1967 tm->tm_mday = tx->tm_mday;
1968 tm->tm_hour = tx->tm_hour;
1969 tm->tm_min = tx->tm_min;
1970 tm->tm_sec = tx->tm_sec;
1971 tm->tm_isdst = tx->tm_isdst;
1972 tm->tm_gmtoff = tx->tm_gmtoff;
1973 tm->tm_zone = tx->tm_zone;
1974 *tzp = -tm->tm_gmtoff;
1975 if (tzn != NULL)
1976 *tzn = tm->tm_zone;
1977 }
1978 else
1979 {
1980 /*
1981 * When out of range of pg_time_t, treat as GMT
1982 */
1983 *tzp = 0;
1984 /* Mark this as *no* time zone available */
1985 tm->tm_isdst = -1;
1986 tm->tm_gmtoff = 0;
1987 tm->tm_zone = NULL;
1988 if (tzn != NULL)
1989 *tzn = NULL;
1990 }
1991
1992 return 0;
1993}
1994
1995
1996/* tm2timestamp()
1997 * Convert a tm structure to a timestamp data type.
1998 * Note that year is _not_ 1900-based, but is an explicit full value.
1999 * Also, month is one-based, _not_ zero-based.
2000 *
2001 * Returns -1 on failure (value out of range).
2002 */
2003int
2004tm2timestamp(struct pg_tm *tm, fsec_t fsec, int *tzp, Timestamp *result)
2005{
2007 TimeOffset time;
2008
2009 /* Prevent overflow in Julian-day routines */
2011 {
2012 *result = 0; /* keep compiler quiet */
2013 return -1;
2014 }
2015
2017 time = time2t(tm->tm_hour, tm->tm_min, tm->tm_sec, fsec);
2018
2020 pg_add_s64_overflow(*result, time, result)))
2021 {
2022 *result = 0; /* keep compiler quiet */
2023 return -1;
2024 }
2025 if (tzp != NULL)
2026 *result = dt2local(*result, -(*tzp));
2027
2028 /* final range check catches just-out-of-range timestamps */
2029 if (!IS_VALID_TIMESTAMP(*result))
2030 {
2031 *result = 0; /* keep compiler quiet */
2032 return -1;
2033 }
2034
2035 return 0;
2036}
2037
2038
2039/* interval2itm()
2040 * Convert an Interval to a pg_itm structure.
2041 * Note: overflow is not possible, because the pg_itm fields are
2042 * wide enough for all possible conversion results.
2043 */
2044void
2046{
2047 TimeOffset time;
2049
2050 itm->tm_year = span.month / MONTHS_PER_YEAR;
2051 itm->tm_mon = span.month % MONTHS_PER_YEAR;
2052 itm->tm_mday = span.day;
2053 time = span.time;
2054
2055 tfrac = time / USECS_PER_HOUR;
2056 time -= tfrac * USECS_PER_HOUR;
2057 itm->tm_hour = tfrac;
2058 tfrac = time / USECS_PER_MINUTE;
2059 time -= tfrac * USECS_PER_MINUTE;
2060 itm->tm_min = (int) tfrac;
2061 tfrac = time / USECS_PER_SEC;
2062 time -= tfrac * USECS_PER_SEC;
2063 itm->tm_sec = (int) tfrac;
2064 itm->tm_usec = (int) time;
2065}
2066
2067/* itm2interval()
2068 * Convert a pg_itm structure to an Interval.
2069 * Returns 0 if OK, -1 on overflow.
2070 *
2071 * This is for use in computations expected to produce finite results. Any
2072 * inputs that lead to infinite results are treated as overflows.
2073 */
2074int
2076{
2077 int64 total_months = (int64) itm->tm_year * MONTHS_PER_YEAR + itm->tm_mon;
2078
2080 return -1;
2081 span->month = (int32) total_months;
2082 span->day = itm->tm_mday;
2084 &span->time))
2085 return -1;
2086 /* tm_min, tm_sec are 32 bits, so intermediate products can't overflow */
2087 if (pg_add_s64_overflow(span->time, itm->tm_min * USECS_PER_MINUTE,
2088 &span->time))
2089 return -1;
2090 if (pg_add_s64_overflow(span->time, itm->tm_sec * USECS_PER_SEC,
2091 &span->time))
2092 return -1;
2093 if (pg_add_s64_overflow(span->time, itm->tm_usec,
2094 &span->time))
2095 return -1;
2097 return -1;
2098 return 0;
2099}
2100
2101/* itmin2interval()
2102 * Convert a pg_itm_in structure to an Interval.
2103 * Returns 0 if OK, -1 on overflow.
2104 *
2105 * Note: if the result is infinite, it is not treated as an overflow. This
2106 * avoids any dump/reload hazards from pre-17 databases that do not support
2107 * infinite intervals, but do allow finite intervals with all fields set to
2108 * INT_MIN/INT_MAX (outside the documented range). Such intervals will be
2109 * silently converted to +/-infinity. This may not be ideal, but seems
2110 * preferable to failure, and ought to be pretty unlikely in practice.
2111 */
2112int
2114{
2115 int64 total_months = (int64) itm_in->tm_year * MONTHS_PER_YEAR + itm_in->tm_mon;
2116
2118 return -1;
2119 span->month = (int32) total_months;
2120 span->day = itm_in->tm_mday;
2121 span->time = itm_in->tm_usec;
2122 return 0;
2123}
2124
2125static TimeOffset
2126time2t(const int hour, const int min, const int sec, const fsec_t fsec)
2127{
2128 return (((((hour * MINS_PER_HOUR) + min) * SECS_PER_MINUTE) + sec) * USECS_PER_SEC) + fsec;
2129}
2130
2131static Timestamp
2133{
2134 dt -= (timezone * USECS_PER_SEC);
2135 return dt;
2136}
2137
2138
2139/*****************************************************************************
2140 * PUBLIC ROUTINES *
2141 *****************************************************************************/
2142
2143
2144Datum
2151
2152Datum
2159
2160
2161/*----------------------------------------------------------
2162 * Relational operators for timestamp.
2163 *---------------------------------------------------------*/
2164
2165void
2167{
2168 struct pg_tm *t0;
2169 pg_time_t epoch = 0;
2170
2171 t0 = pg_gmtime(&epoch);
2172
2173 if (t0 == NULL)
2174 elog(ERROR, "could not convert epoch to timestamp: %m");
2175
2176 tm->tm_year = t0->tm_year;
2177 tm->tm_mon = t0->tm_mon;
2178 tm->tm_mday = t0->tm_mday;
2179 tm->tm_hour = t0->tm_hour;
2180 tm->tm_min = t0->tm_min;
2181 tm->tm_sec = t0->tm_sec;
2182
2183 tm->tm_year += 1900;
2184 tm->tm_mon++;
2185}
2186
2189{
2190 Timestamp dt;
2191 struct pg_tm tt,
2192 *tm = &tt;
2193
2195 /* we don't bother to test for failure ... */
2196 tm2timestamp(tm, 0, NULL, &dt);
2197
2198 return dt;
2199} /* SetEpochTimestamp() */
2200
2201/*
2202 * We are currently sharing some code between timestamp and timestamptz.
2203 * The comparison functions are among them. - thomas 2001-09-25
2204 *
2205 * timestamp_relop - is timestamp1 relop timestamp2
2206 */
2207int
2209{
2210 return (dt1 < dt2) ? -1 : ((dt1 > dt2) ? 1 : 0);
2211}
2212
2213Datum
2221
2222Datum
2230
2231Datum
2239
2240Datum
2248
2249Datum
2257
2258Datum
2266
2267Datum
2275
2276Datum
2284
2285/* note: this is used for timestamptz also */
2286static Datum
2288{
2290
2291 if (texisting == PG_INT64_MIN)
2292 {
2293 /* return value is undefined */
2294 *underflow = true;
2295 return (Datum) 0;
2296 }
2297
2298 *underflow = false;
2299 return TimestampGetDatum(texisting - 1);
2300}
2301
2302/* note: this is used for timestamptz also */
2303static Datum
2305{
2307
2308 if (texisting == PG_INT64_MAX)
2309 {
2310 /* return value is undefined */
2311 *overflow = true;
2312 return (Datum) 0;
2313 }
2314
2315 *overflow = false;
2316 return TimestampGetDatum(texisting + 1);
2317}
2318
2319Datum
2331
2332Datum
2334{
2335 return hashint8(fcinfo);
2336}
2337
2338Datum
2343
2344Datum
2346{
2347 return hashint8(fcinfo);
2348}
2349
2350Datum
2355
2356/*
2357 * Cross-type comparison functions for timestamp vs timestamptz
2358 */
2359
2360int32
2362{
2365
2367 if (escontext.error_occurred)
2368 {
2370 {
2371 /* dt1 is larger than any finite timestamp, but less than infinity */
2372 return TIMESTAMP_IS_NOEND(dt2) ? -1 : +1;
2373 }
2375 {
2376 /* dt1 is less than any finite timestamp, but more than -infinity */
2377 return TIMESTAMP_IS_NOBEGIN(dt2) ? +1 : -1;
2378 }
2379 }
2380
2382}
2383
2384Datum
2392
2393Datum
2401
2402Datum
2410
2411Datum
2419
2420Datum
2428
2429Datum
2437
2438Datum
2446
2447Datum
2455
2456Datum
2464
2465Datum
2473
2474Datum
2482
2483Datum
2491
2492Datum
2500
2501Datum
2509
2510
2511/*
2512 * interval_relop - is interval1 relop interval2
2513 *
2514 * Interval comparison is based on converting interval values to a linear
2515 * representation expressed in the units of the time field (microseconds,
2516 * in the case of integer timestamps) with days assumed to be always 24 hours
2517 * and months assumed to be always 30 days. To avoid overflow, we need a
2518 * wider-than-int64 datatype for the linear representation, so use INT128.
2519 */
2520
2521static inline INT128
2523{
2524 INT128 span;
2525 int64 days;
2526
2527 /*
2528 * Combine the month and day fields into an integral number of days.
2529 * Because the inputs are int32, int64 arithmetic suffices here.
2530 */
2531 days = interval->month * INT64CONST(30);
2532 days += interval->day;
2533
2534 /* Widen time field to 128 bits */
2536
2537 /* Scale up days to microseconds, forming a 128-bit product */
2539
2540 return span;
2541}
2542
2543static int
2551
2552static int
2560
2561Datum
2569
2570Datum
2578
2579Datum
2587
2588Datum
2596
2597Datum
2605
2606Datum
2614
2615Datum
2623
2624/*
2625 * Hashing for intervals
2626 *
2627 * We must produce equal hashvals for values that interval_cmp_internal()
2628 * considers equal. So, compute the net span the same way it does,
2629 * and then hash that.
2630 */
2631Datum
2633{
2636 int64 span64;
2637
2638 /*
2639 * Use only the least significant 64 bits for hashing. The upper 64 bits
2640 * seldom add any useful information, and besides we must do it like this
2641 * for compatibility with hashes calculated before use of INT128 was
2642 * introduced.
2643 */
2645
2647}
2648
2649Datum
2662
2663/* overlaps_timestamp() --- implements the SQL OVERLAPS operator.
2664 *
2665 * Algorithm is per SQL spec. This is much harder than you'd think
2666 * because the spec requires us to deliver a non-null answer in some cases
2667 * where some of the inputs are null.
2668 */
2669Datum
2671{
2672 /*
2673 * The arguments are Timestamps, but we leave them as generic Datums to
2674 * avoid unnecessary conversions between value and reference forms --- not
2675 * to mention possible dereferences of null pointers.
2676 */
2681 bool ts1IsNull = PG_ARGISNULL(0);
2682 bool te1IsNull = PG_ARGISNULL(1);
2683 bool ts2IsNull = PG_ARGISNULL(2);
2684 bool te2IsNull = PG_ARGISNULL(3);
2685
2686#define TIMESTAMP_GT(t1,t2) \
2687 DatumGetBool(DirectFunctionCall2(timestamp_gt,t1,t2))
2688#define TIMESTAMP_LT(t1,t2) \
2689 DatumGetBool(DirectFunctionCall2(timestamp_lt,t1,t2))
2690
2691 /*
2692 * If both endpoints of interval 1 are null, the result is null (unknown).
2693 * If just one endpoint is null, take ts1 as the non-null one. Otherwise,
2694 * take ts1 as the lesser endpoint.
2695 */
2696 if (ts1IsNull)
2697 {
2698 if (te1IsNull)
2700 /* swap null for non-null */
2701 ts1 = te1;
2702 te1IsNull = true;
2703 }
2704 else if (!te1IsNull)
2705 {
2706 if (TIMESTAMP_GT(ts1, te1))
2707 {
2708 Datum tt = ts1;
2709
2710 ts1 = te1;
2711 te1 = tt;
2712 }
2713 }
2714
2715 /* Likewise for interval 2. */
2716 if (ts2IsNull)
2717 {
2718 if (te2IsNull)
2720 /* swap null for non-null */
2721 ts2 = te2;
2722 te2IsNull = true;
2723 }
2724 else if (!te2IsNull)
2725 {
2726 if (TIMESTAMP_GT(ts2, te2))
2727 {
2728 Datum tt = ts2;
2729
2730 ts2 = te2;
2731 te2 = tt;
2732 }
2733 }
2734
2735 /*
2736 * At this point neither ts1 nor ts2 is null, so we can consider three
2737 * cases: ts1 > ts2, ts1 < ts2, ts1 = ts2
2738 */
2739 if (TIMESTAMP_GT(ts1, ts2))
2740 {
2741 /*
2742 * This case is ts1 < te2 OR te1 < te2, which may look redundant but
2743 * in the presence of nulls it's not quite completely so.
2744 */
2745 if (te2IsNull)
2747 if (TIMESTAMP_LT(ts1, te2))
2748 PG_RETURN_BOOL(true);
2749 if (te1IsNull)
2751
2752 /*
2753 * If te1 is not null then we had ts1 <= te1 above, and we just found
2754 * ts1 >= te2, hence te1 >= te2.
2755 */
2756 PG_RETURN_BOOL(false);
2757 }
2758 else if (TIMESTAMP_LT(ts1, ts2))
2759 {
2760 /* This case is ts2 < te1 OR te2 < te1 */
2761 if (te1IsNull)
2763 if (TIMESTAMP_LT(ts2, te1))
2764 PG_RETURN_BOOL(true);
2765 if (te2IsNull)
2767
2768 /*
2769 * If te2 is not null then we had ts2 <= te2 above, and we just found
2770 * ts2 >= te1, hence te2 >= te1.
2771 */
2772 PG_RETURN_BOOL(false);
2773 }
2774 else
2775 {
2776 /*
2777 * For ts1 = ts2 the spec says te1 <> te2 OR te1 = te2, which is a
2778 * rather silly way of saying "true if both are non-null, else null".
2779 */
2780 if (te1IsNull || te2IsNull)
2782 PG_RETURN_BOOL(true);
2783 }
2784
2785#undef TIMESTAMP_GT
2786#undef TIMESTAMP_LT
2787}
2788
2789
2790/*----------------------------------------------------------
2791 * "Arithmetic" operators on date/times.
2792 *---------------------------------------------------------*/
2793
2794Datum
2796{
2799 Timestamp result;
2800
2801 /* use timestamp_cmp_internal to be sure this agrees with comparisons */
2802 if (timestamp_cmp_internal(dt1, dt2) < 0)
2803 result = dt1;
2804 else
2805 result = dt2;
2806 PG_RETURN_TIMESTAMP(result);
2807}
2808
2809Datum
2811{
2814 Timestamp result;
2815
2816 if (timestamp_cmp_internal(dt1, dt2) > 0)
2817 result = dt1;
2818 else
2819 result = dt2;
2820 PG_RETURN_TIMESTAMP(result);
2821}
2822
2823
2824Datum
2826{
2829 Interval *result;
2830
2831 result = palloc_object(Interval);
2832
2833 /*
2834 * Handle infinities.
2835 *
2836 * We treat anything that amounts to "infinity - infinity" as an error,
2837 * since the interval type has nothing equivalent to NaN.
2838 */
2840 {
2842 {
2844 ereport(ERROR,
2846 errmsg("interval out of range")));
2847 else
2848 INTERVAL_NOBEGIN(result);
2849 }
2850 else if (TIMESTAMP_IS_NOEND(dt1))
2851 {
2853 ereport(ERROR,
2855 errmsg("interval out of range")));
2856 else
2857 INTERVAL_NOEND(result);
2858 }
2859 else if (TIMESTAMP_IS_NOBEGIN(dt2))
2860 INTERVAL_NOEND(result);
2861 else /* TIMESTAMP_IS_NOEND(dt2) */
2862 INTERVAL_NOBEGIN(result);
2863
2864 PG_RETURN_INTERVAL_P(result);
2865 }
2866
2867 if (unlikely(pg_sub_s64_overflow(dt1, dt2, &result->time)))
2868 ereport(ERROR,
2870 errmsg("interval out of range")));
2871
2872 result->month = 0;
2873 result->day = 0;
2874
2875 /*----------
2876 * This is wrong, but removing it breaks a lot of regression tests.
2877 * For example:
2878 *
2879 * test=> SET timezone = 'EST5EDT';
2880 * test=> SELECT
2881 * test-> ('2005-10-30 13:22:00-05'::timestamptz -
2882 * test(> '2005-10-29 13:22:00-04'::timestamptz);
2883 * ?column?
2884 * ----------------
2885 * 1 day 01:00:00
2886 * (1 row)
2887 *
2888 * so adding that to the first timestamp gets:
2889 *
2890 * test=> SELECT
2891 * test-> ('2005-10-29 13:22:00-04'::timestamptz +
2892 * test(> ('2005-10-30 13:22:00-05'::timestamptz -
2893 * test(> '2005-10-29 13:22:00-04'::timestamptz)) at time zone 'EST';
2894 * timezone
2895 * --------------------
2896 * 2005-10-30 14:22:00
2897 * (1 row)
2898 *----------
2899 */
2901 IntervalPGetDatum(result)));
2902
2903 PG_RETURN_INTERVAL_P(result);
2904}
2905
2906/*
2907 * interval_justify_interval()
2908 *
2909 * Adjust interval so 'month', 'day', and 'time' portions are within
2910 * customary bounds. Specifically:
2911 *
2912 * 0 <= abs(time) < 24 hours
2913 * 0 <= abs(day) < 30 days
2914 *
2915 * Also, the sign bit on all three fields is made equal, so either
2916 * all three fields are negative or all are positive.
2917 */
2918Datum
2920{
2922 Interval *result;
2925
2926 result = palloc_object(Interval);
2927 result->month = span->month;
2928 result->day = span->day;
2929 result->time = span->time;
2930
2931 /* do nothing for infinite intervals */
2932 if (INTERVAL_NOT_FINITE(result))
2933 PG_RETURN_INTERVAL_P(result);
2934
2935 /* pre-justify days if it might prevent overflow */
2936 if ((result->day > 0 && result->time > 0) ||
2937 (result->day < 0 && result->time < 0))
2938 {
2939 wholemonth = result->day / DAYS_PER_MONTH;
2940 result->day -= wholemonth * DAYS_PER_MONTH;
2941 if (pg_add_s32_overflow(result->month, wholemonth, &result->month))
2942 ereport(ERROR,
2944 errmsg("interval out of range")));
2945 }
2946
2947 /*
2948 * Since TimeOffset is int64, abs(wholeday) can't exceed about 1.07e8. If
2949 * we pre-justified then abs(result->day) is less than DAYS_PER_MONTH, so
2950 * this addition can't overflow. If we didn't pre-justify, then day and
2951 * time are of different signs, so it still can't overflow.
2952 */
2954 result->day += wholeday;
2955
2956 wholemonth = result->day / DAYS_PER_MONTH;
2957 result->day -= wholemonth * DAYS_PER_MONTH;
2958 if (pg_add_s32_overflow(result->month, wholemonth, &result->month))
2959 ereport(ERROR,
2961 errmsg("interval out of range")));
2962
2963 if (result->month > 0 &&
2964 (result->day < 0 || (result->day == 0 && result->time < 0)))
2965 {
2966 result->day += DAYS_PER_MONTH;
2967 result->month--;
2968 }
2969 else if (result->month < 0 &&
2970 (result->day > 0 || (result->day == 0 && result->time > 0)))
2971 {
2972 result->day -= DAYS_PER_MONTH;
2973 result->month++;
2974 }
2975
2976 if (result->day > 0 && result->time < 0)
2977 {
2978 result->time += USECS_PER_DAY;
2979 result->day--;
2980 }
2981 else if (result->day < 0 && result->time > 0)
2982 {
2983 result->time -= USECS_PER_DAY;
2984 result->day++;
2985 }
2986
2987 PG_RETURN_INTERVAL_P(result);
2988}
2989
2990/*
2991 * interval_justify_hours()
2992 *
2993 * Adjust interval so 'time' contains less than a whole day, adding
2994 * the excess to 'day'. This is useful for
2995 * situations (such as non-TZ) where '1 day' = '24 hours' is valid,
2996 * e.g. interval subtraction and division.
2997 */
2998Datum
3000{
3002 Interval *result;
3004
3005 result = palloc_object(Interval);
3006 result->month = span->month;
3007 result->day = span->day;
3008 result->time = span->time;
3009
3010 /* do nothing for infinite intervals */
3011 if (INTERVAL_NOT_FINITE(result))
3012 PG_RETURN_INTERVAL_P(result);
3013
3015 if (pg_add_s32_overflow(result->day, wholeday, &result->day))
3016 ereport(ERROR,
3018 errmsg("interval out of range")));
3019
3020 if (result->day > 0 && result->time < 0)
3021 {
3022 result->time += USECS_PER_DAY;
3023 result->day--;
3024 }
3025 else if (result->day < 0 && result->time > 0)
3026 {
3027 result->time -= USECS_PER_DAY;
3028 result->day++;
3029 }
3030
3031 PG_RETURN_INTERVAL_P(result);
3032}
3033
3034/*
3035 * interval_justify_days()
3036 *
3037 * Adjust interval so 'day' contains less than 30 days, adding
3038 * the excess to 'month'.
3039 */
3040Datum
3042{
3044 Interval *result;
3046
3047 result = palloc_object(Interval);
3048 result->month = span->month;
3049 result->day = span->day;
3050 result->time = span->time;
3051
3052 /* do nothing for infinite intervals */
3053 if (INTERVAL_NOT_FINITE(result))
3054 PG_RETURN_INTERVAL_P(result);
3055
3056 wholemonth = result->day / DAYS_PER_MONTH;
3057 result->day -= wholemonth * DAYS_PER_MONTH;
3058 if (pg_add_s32_overflow(result->month, wholemonth, &result->month))
3059 ereport(ERROR,
3061 errmsg("interval out of range")));
3062
3063 if (result->month > 0 && result->day < 0)
3064 {
3065 result->day += DAYS_PER_MONTH;
3066 result->month--;
3067 }
3068 else if (result->month < 0 && result->day > 0)
3069 {
3070 result->day -= DAYS_PER_MONTH;
3071 result->month++;
3072 }
3073
3074 PG_RETURN_INTERVAL_P(result);
3075}
3076
3077/* timestamp_pl_interval()
3078 * Add an interval to a timestamp data type.
3079 * Note that interval has provisions for qualitative year/month and day
3080 * units, so try to do the right thing with them.
3081 * To add a month, increment the month, and use the same day of month.
3082 * Then, if the next month has fewer days, set the day of month
3083 * to the last day of month.
3084 * To add a day, increment the mday, and use the same time of day.
3085 * Lastly, add in the "quantitative time".
3086 */
3087Datum
3089{
3092 Timestamp result;
3093
3094 /*
3095 * Handle infinities.
3096 *
3097 * We treat anything that amounts to "infinity - infinity" as an error,
3098 * since the timestamp type has nothing equivalent to NaN.
3099 */
3101 {
3103 ereport(ERROR,
3105 errmsg("timestamp out of range")));
3106 else
3107 TIMESTAMP_NOBEGIN(result);
3108 }
3109 else if (INTERVAL_IS_NOEND(span))
3110 {
3112 ereport(ERROR,
3114 errmsg("timestamp out of range")));
3115 else
3116 TIMESTAMP_NOEND(result);
3117 }
3119 result = timestamp;
3120 else
3121 {
3122 if (span->month != 0)
3123 {
3124 struct pg_tm tt,
3125 *tm = &tt;
3126 fsec_t fsec;
3127
3128 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
3129 ereport(ERROR,
3131 errmsg("timestamp out of range")));
3132
3133 if (pg_add_s32_overflow(tm->tm_mon, span->month, &tm->tm_mon))
3134 ereport(ERROR,
3136 errmsg("timestamp out of range")));
3137 if (tm->tm_mon > MONTHS_PER_YEAR)
3138 {
3139 tm->tm_year += (tm->tm_mon - 1) / MONTHS_PER_YEAR;
3140 tm->tm_mon = ((tm->tm_mon - 1) % MONTHS_PER_YEAR) + 1;
3141 }
3142 else if (tm->tm_mon < 1)
3143 {
3144 tm->tm_year += tm->tm_mon / MONTHS_PER_YEAR - 1;
3146 }
3147
3148 /* adjust for end of month boundary problems... */
3149 if (tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1])
3150 tm->tm_mday = (day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]);
3151
3152 if (tm2timestamp(tm, fsec, NULL, &timestamp) != 0)
3153 ereport(ERROR,
3155 errmsg("timestamp out of range")));
3156 }
3157
3158 if (span->day != 0)
3159 {
3160 struct pg_tm tt,
3161 *tm = &tt;
3162 fsec_t fsec;
3163 int julian;
3164
3165 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
3166 ereport(ERROR,
3168 errmsg("timestamp out of range")));
3169
3170 /*
3171 * Add days by converting to and from Julian. We need an overflow
3172 * check here since j2date expects a non-negative integer input.
3173 */
3175 if (pg_add_s32_overflow(julian, span->day, &julian) ||
3176 julian < 0)
3177 ereport(ERROR,
3179 errmsg("timestamp out of range")));
3181
3182 if (tm2timestamp(tm, fsec, NULL, &timestamp) != 0)
3183 ereport(ERROR,
3185 errmsg("timestamp out of range")));
3186 }
3187
3189 ereport(ERROR,
3191 errmsg("timestamp out of range")));
3192
3194 ereport(ERROR,
3196 errmsg("timestamp out of range")));
3197
3198 result = timestamp;
3199 }
3200
3201 PG_RETURN_TIMESTAMP(result);
3202}
3203
3204Datum
3217
3218
3219/* timestamptz_pl_interval_internal()
3220 * Add an interval to a timestamptz, in the given (or session) timezone.
3221 *
3222 * Note that interval has provisions for qualitative year/month and day
3223 * units, so try to do the right thing with them.
3224 * To add a month, increment the month, and use the same day of month.
3225 * Then, if the next month has fewer days, set the day of month
3226 * to the last day of month.
3227 * To add a day, increment the mday, and use the same time of day.
3228 * Lastly, add in the "quantitative time".
3229 */
3230static TimestampTz
3232 Interval *span,
3233 pg_tz *attimezone)
3234{
3235 TimestampTz result;
3236 int tz;
3237
3238 /*
3239 * Handle infinities.
3240 *
3241 * We treat anything that amounts to "infinity - infinity" as an error,
3242 * since the timestamptz type has nothing equivalent to NaN.
3243 */
3245 {
3247 ereport(ERROR,
3249 errmsg("timestamp out of range")));
3250 else
3251 TIMESTAMP_NOBEGIN(result);
3252 }
3253 else if (INTERVAL_IS_NOEND(span))
3254 {
3256 ereport(ERROR,
3258 errmsg("timestamp out of range")));
3259 else
3260 TIMESTAMP_NOEND(result);
3261 }
3263 result = timestamp;
3264 else
3265 {
3266 /* Use session timezone if caller asks for default */
3267 if (attimezone == NULL)
3268 attimezone = session_timezone;
3269
3270 if (span->month != 0)
3271 {
3272 struct pg_tm tt,
3273 *tm = &tt;
3274 fsec_t fsec;
3275
3276 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, attimezone) != 0)
3277 ereport(ERROR,
3279 errmsg("timestamp out of range")));
3280
3281 if (pg_add_s32_overflow(tm->tm_mon, span->month, &tm->tm_mon))
3282 ereport(ERROR,
3284 errmsg("timestamp out of range")));
3285 if (tm->tm_mon > MONTHS_PER_YEAR)
3286 {
3287 tm->tm_year += (tm->tm_mon - 1) / MONTHS_PER_YEAR;
3288 tm->tm_mon = ((tm->tm_mon - 1) % MONTHS_PER_YEAR) + 1;
3289 }
3290 else if (tm->tm_mon < 1)
3291 {
3292 tm->tm_year += tm->tm_mon / MONTHS_PER_YEAR - 1;
3294 }
3295
3296 /* adjust for end of month boundary problems... */
3297 if (tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1])
3298 tm->tm_mday = (day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]);
3299
3300 tz = DetermineTimeZoneOffset(tm, attimezone);
3301
3302 if (tm2timestamp(tm, fsec, &tz, &timestamp) != 0)
3303 ereport(ERROR,
3305 errmsg("timestamp out of range")));
3306 }
3307
3308 if (span->day != 0)
3309 {
3310 struct pg_tm tt,
3311 *tm = &tt;
3312 fsec_t fsec;
3313 int julian;
3314
3315 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, attimezone) != 0)
3316 ereport(ERROR,
3318 errmsg("timestamp out of range")));
3319
3320 /*
3321 * Add days by converting to and from Julian. We need an overflow
3322 * check here since j2date expects a non-negative integer input.
3323 * In practice though, it will give correct answers for small
3324 * negative Julian dates; we should allow -1 to avoid
3325 * timezone-dependent failures, as discussed in timestamp.h.
3326 */
3328 if (pg_add_s32_overflow(julian, span->day, &julian) ||
3329 julian < -1)
3330 ereport(ERROR,
3332 errmsg("timestamp out of range")));
3334
3335 tz = DetermineTimeZoneOffset(tm, attimezone);
3336
3337 if (tm2timestamp(tm, fsec, &tz, &timestamp) != 0)
3338 ereport(ERROR,
3340 errmsg("timestamp out of range")));
3341 }
3342
3344 ereport(ERROR,
3346 errmsg("timestamp out of range")));
3347
3349 ereport(ERROR,
3351 errmsg("timestamp out of range")));
3352
3353 result = timestamp;
3354 }
3355
3356 return result;
3357}
3358
3359/* timestamptz_mi_interval_internal()
3360 * As above, but subtract the interval.
3361 */
3362static TimestampTz
3373
3374/* timestamptz_pl_interval()
3375 * Add an interval to a timestamptz, in the session timezone.
3376 */
3377Datum
3385
3386Datum
3394
3395/* timestamptz_pl_interval_at_zone()
3396 * Add an interval to a timestamptz, in the specified timezone.
3397 */
3398Datum
3408
3409Datum
3419
3420/* interval_um_internal()
3421 * Negate an interval.
3422 */
3423static void
3425{
3427 INTERVAL_NOEND(result);
3428 else if (INTERVAL_IS_NOEND(interval))
3429 INTERVAL_NOBEGIN(result);
3430 else
3431 {
3432 /* Negate each field, guarding against overflow */
3433 if (pg_sub_s64_overflow(INT64CONST(0), interval->time, &result->time) ||
3434 pg_sub_s32_overflow(0, interval->day, &result->day) ||
3435 pg_sub_s32_overflow(0, interval->month, &result->month) ||
3436 INTERVAL_NOT_FINITE(result))
3437 ereport(ERROR,
3439 errmsg("interval out of range")));
3440 }
3441}
3442
3443Datum
3445{
3447 Interval *result;
3448
3449 result = palloc_object(Interval);
3451
3452 PG_RETURN_INTERVAL_P(result);
3453}
3454
3455
3456Datum
3458{
3461 Interval *result;
3462
3463 /* use interval_cmp_internal to be sure this agrees with comparisons */
3465 result = interval1;
3466 else
3467 result = interval2;
3468 PG_RETURN_INTERVAL_P(result);
3469}
3470
3471Datum
3473{
3476 Interval *result;
3477
3479 result = interval1;
3480 else
3481 result = interval2;
3482 PG_RETURN_INTERVAL_P(result);
3483}
3484
3485static void
3487{
3490
3491 if (pg_add_s32_overflow(span1->month, span2->month, &result->month) ||
3492 pg_add_s32_overflow(span1->day, span2->day, &result->day) ||
3493 pg_add_s64_overflow(span1->time, span2->time, &result->time) ||
3494 INTERVAL_NOT_FINITE(result))
3495 ereport(ERROR,
3497 errmsg("interval out of range")));
3498}
3499
3500Datum
3502{
3505 Interval *result;
3506
3507 result = palloc_object(Interval);
3508
3509 /*
3510 * Handle infinities.
3511 *
3512 * We treat anything that amounts to "infinity - infinity" as an error,
3513 * since the interval type has nothing equivalent to NaN.
3514 */
3516 {
3518 ereport(ERROR,
3520 errmsg("interval out of range")));
3521 else
3522 INTERVAL_NOBEGIN(result);
3523 }
3524 else if (INTERVAL_IS_NOEND(span1))
3525 {
3527 ereport(ERROR,
3529 errmsg("interval out of range")));
3530 else
3531 INTERVAL_NOEND(result);
3532 }
3533 else if (INTERVAL_NOT_FINITE(span2))
3534 memcpy(result, span2, sizeof(Interval));
3535 else
3536 finite_interval_pl(span1, span2, result);
3537
3538 PG_RETURN_INTERVAL_P(result);
3539}
3540
3541static void
3543{
3546
3547 if (pg_sub_s32_overflow(span1->month, span2->month, &result->month) ||
3548 pg_sub_s32_overflow(span1->day, span2->day, &result->day) ||
3549 pg_sub_s64_overflow(span1->time, span2->time, &result->time) ||
3550 INTERVAL_NOT_FINITE(result))
3551 ereport(ERROR,
3553 errmsg("interval out of range")));
3554}
3555
3556Datum
3558{
3561 Interval *result;
3562
3563 result = palloc_object(Interval);
3564
3565 /*
3566 * Handle infinities.
3567 *
3568 * We treat anything that amounts to "infinity - infinity" as an error,
3569 * since the interval type has nothing equivalent to NaN.
3570 */
3572 {
3574 ereport(ERROR,
3576 errmsg("interval out of range")));
3577 else
3578 INTERVAL_NOBEGIN(result);
3579 }
3580 else if (INTERVAL_IS_NOEND(span1))
3581 {
3583 ereport(ERROR,
3585 errmsg("interval out of range")));
3586 else
3587 INTERVAL_NOEND(result);
3588 }
3589 else if (INTERVAL_IS_NOBEGIN(span2))
3590 INTERVAL_NOEND(result);
3591 else if (INTERVAL_IS_NOEND(span2))
3592 INTERVAL_NOBEGIN(result);
3593 else
3594 finite_interval_mi(span1, span2, result);
3595
3596 PG_RETURN_INTERVAL_P(result);
3597}
3598
3599/*
3600 * There is no interval_abs(): it is unclear what value to return:
3601 * http://archives.postgresql.org/pgsql-general/2009-10/msg01031.php
3602 * http://archives.postgresql.org/pgsql-general/2009-11/msg00041.php
3603 */
3604
3605Datum
3607{
3610 double month_remainder_days,
3613 int32 orig_month = span->month,
3614 orig_day = span->day;
3615 Interval *result;
3616
3617 result = palloc_object(Interval);
3618
3619 /*
3620 * Handle NaN and infinities.
3621 *
3622 * We treat "0 * infinity" and "infinity * 0" as errors, since the
3623 * interval type has nothing equivalent to NaN.
3624 */
3625 if (isnan(factor))
3626 goto out_of_range;
3627
3629 {
3630 if (factor == 0.0)
3631 goto out_of_range;
3632
3633 if (factor < 0.0)
3634 interval_um_internal(span, result);
3635 else
3636 memcpy(result, span, sizeof(Interval));
3637
3638 PG_RETURN_INTERVAL_P(result);
3639 }
3640 if (isinf(factor))
3641 {
3642 int isign = interval_sign(span);
3643
3644 if (isign == 0)
3645 goto out_of_range;
3646
3647 if (factor * isign < 0)
3648 INTERVAL_NOBEGIN(result);
3649 else
3650 INTERVAL_NOEND(result);
3651
3652 PG_RETURN_INTERVAL_P(result);
3653 }
3654
3655 result_double = span->month * factor;
3657 goto out_of_range;
3658 result->month = (int32) result_double;
3659
3660 result_double = span->day * factor;
3662 goto out_of_range;
3663 result->day = (int32) result_double;
3664
3665 /*
3666 * The above correctly handles the whole-number part of the month and day
3667 * products, but we have to do something with any fractional part
3668 * resulting when the factor is non-integral. We cascade the fractions
3669 * down to lower units using the conversion factors DAYS_PER_MONTH and
3670 * SECS_PER_DAY. Note we do NOT cascade up, since we are not forced to do
3671 * so by the representation. The user can choose to cascade up later,
3672 * using justify_hours and/or justify_days.
3673 */
3674
3675 /*
3676 * Fractional months full days into days.
3677 *
3678 * Floating point calculation are inherently imprecise, so these
3679 * calculations are crafted to produce the most reliable result possible.
3680 * TSROUND() is needed to more accurately produce whole numbers where
3681 * appropriate.
3682 */
3685 sec_remainder = (orig_day * factor - result->day +
3688
3689 /*
3690 * Might have 24:00:00 hours due to rounding, or >24 hours because of time
3691 * cascade from months and days. It might still be >24 if the combination
3692 * of cascade and the seconds factor operation itself.
3693 */
3695 {
3696 if (pg_add_s32_overflow(result->day,
3697 (int) (sec_remainder / SECS_PER_DAY),
3698 &result->day))
3699 goto out_of_range;
3701 }
3702
3703 /* cascade units down */
3705 &result->day))
3706 goto out_of_range;
3709 goto out_of_range;
3710 result->time = (int64) result_double;
3711
3712 if (INTERVAL_NOT_FINITE(result))
3713 goto out_of_range;
3714
3715 PG_RETURN_INTERVAL_P(result);
3716
3718 ereport(ERROR,
3720 errmsg("interval out of range"));
3721
3722 PG_RETURN_NULL(); /* keep compiler quiet */
3723}
3724
3725Datum
3727{
3728 /* Args are float8 and Interval *, but leave them as generic Datum */
3731
3733}
3734
3735Datum
3737{
3740 double month_remainder_days,
3743 int32 orig_month = span->month,
3744 orig_day = span->day;
3745 Interval *result;
3746
3747 result = palloc_object(Interval);
3748
3749 if (factor == 0.0)
3750 ereport(ERROR,
3752 errmsg("division by zero")));
3753
3754 /*
3755 * Handle NaN and infinities.
3756 *
3757 * We treat "infinity / infinity" as an error, since the interval type has
3758 * nothing equivalent to NaN. Otherwise, dividing by infinity is handled
3759 * by the regular division code, causing all fields to be set to zero.
3760 */
3761 if (isnan(factor))
3762 goto out_of_range;
3763
3765 {
3766 if (isinf(factor))
3767 goto out_of_range;
3768
3769 if (factor < 0.0)
3770 interval_um_internal(span, result);
3771 else
3772 memcpy(result, span, sizeof(Interval));
3773
3774 PG_RETURN_INTERVAL_P(result);
3775 }
3776
3777 result_double = span->month / factor;
3779 goto out_of_range;
3780 result->month = (int32) result_double;
3781
3782 result_double = span->day / factor;
3784 goto out_of_range;
3785 result->day = (int32) result_double;
3786
3787 /*
3788 * Fractional months full days into days. See comment in interval_mul().
3789 */
3792 sec_remainder = (orig_day / factor - result->day +
3796 {
3797 if (pg_add_s32_overflow(result->day,
3798 (int) (sec_remainder / SECS_PER_DAY),
3799 &result->day))
3800 goto out_of_range;
3802 }
3803
3804 /* cascade units down */
3806 &result->day))
3807 goto out_of_range;
3810 goto out_of_range;
3811 result->time = (int64) result_double;
3812
3813 if (INTERVAL_NOT_FINITE(result))
3814 goto out_of_range;
3815
3816 PG_RETURN_INTERVAL_P(result);
3817
3819 ereport(ERROR,
3821 errmsg("interval out of range"));
3822
3823 PG_RETURN_NULL(); /* keep compiler quiet */
3824}
3825
3826
3827/*
3828 * in_range support functions for timestamps and intervals.
3829 *
3830 * Per SQL spec, we support these with interval as the offset type.
3831 * The spec's restriction that the offset not be negative is a bit hard to
3832 * decipher for intervals, but we choose to interpret it the same as our
3833 * interval comparison operators would.
3834 */
3835
3836Datum
3838{
3841 Interval *offset = PG_GETARG_INTERVAL_P(2);
3842 bool sub = PG_GETARG_BOOL(3);
3843 bool less = PG_GETARG_BOOL(4);
3844 TimestampTz sum;
3845
3846 if (interval_sign(offset) < 0)
3847 ereport(ERROR,
3849 errmsg("invalid preceding or following size in window function")));
3850
3851 /*
3852 * Deal with cases where both base and offset are infinite, and computing
3853 * base +/- offset would cause an error. As for float and numeric types,
3854 * we assume that all values infinitely precede +infinity and infinitely
3855 * follow -infinity. See in_range_float8_float8() for reasoning.
3856 */
3857 if (INTERVAL_IS_NOEND(offset) &&
3858 (sub ? TIMESTAMP_IS_NOEND(base) : TIMESTAMP_IS_NOBEGIN(base)))
3859 PG_RETURN_BOOL(true);
3860
3861 /* We don't currently bother to avoid overflow hazards here */
3862 if (sub)
3863 sum = timestamptz_mi_interval_internal(base, offset, NULL);
3864 else
3865 sum = timestamptz_pl_interval_internal(base, offset, NULL);
3866
3867 if (less)
3868 PG_RETURN_BOOL(val <= sum);
3869 else
3870 PG_RETURN_BOOL(val >= sum);
3871}
3872
3873Datum
3875{
3878 Interval *offset = PG_GETARG_INTERVAL_P(2);
3879 bool sub = PG_GETARG_BOOL(3);
3880 bool less = PG_GETARG_BOOL(4);
3881 Timestamp sum;
3882
3883 if (interval_sign(offset) < 0)
3884 ereport(ERROR,
3886 errmsg("invalid preceding or following size in window function")));
3887
3888 /*
3889 * Deal with cases where both base and offset are infinite, and computing
3890 * base +/- offset would cause an error. As for float and numeric types,
3891 * we assume that all values infinitely precede +infinity and infinitely
3892 * follow -infinity. See in_range_float8_float8() for reasoning.
3893 */
3894 if (INTERVAL_IS_NOEND(offset) &&
3895 (sub ? TIMESTAMP_IS_NOEND(base) : TIMESTAMP_IS_NOBEGIN(base)))
3896 PG_RETURN_BOOL(true);
3897
3898 /* We don't currently bother to avoid overflow hazards here */
3899 if (sub)
3901 TimestampGetDatum(base),
3902 IntervalPGetDatum(offset)));
3903 else
3905 TimestampGetDatum(base),
3906 IntervalPGetDatum(offset)));
3907
3908 if (less)
3909 PG_RETURN_BOOL(val <= sum);
3910 else
3911 PG_RETURN_BOOL(val >= sum);
3912}
3913
3914Datum
3916{
3918 Interval *base = PG_GETARG_INTERVAL_P(1);
3919 Interval *offset = PG_GETARG_INTERVAL_P(2);
3920 bool sub = PG_GETARG_BOOL(3);
3921 bool less = PG_GETARG_BOOL(4);
3922 Interval *sum;
3923
3924 if (interval_sign(offset) < 0)
3925 ereport(ERROR,
3927 errmsg("invalid preceding or following size in window function")));
3928
3929 /*
3930 * Deal with cases where both base and offset are infinite, and computing
3931 * base +/- offset would cause an error. As for float and numeric types,
3932 * we assume that all values infinitely precede +infinity and infinitely
3933 * follow -infinity. See in_range_float8_float8() for reasoning.
3934 */
3935 if (INTERVAL_IS_NOEND(offset) &&
3936 (sub ? INTERVAL_IS_NOEND(base) : INTERVAL_IS_NOBEGIN(base)))
3937 PG_RETURN_BOOL(true);
3938
3939 /* We don't currently bother to avoid overflow hazards here */
3940 if (sub)
3942 IntervalPGetDatum(base),
3943 IntervalPGetDatum(offset)));
3944 else
3946 IntervalPGetDatum(base),
3947 IntervalPGetDatum(offset)));
3948
3949 if (less)
3951 else
3953}
3954
3955
3956/*
3957 * Prepare state data for an interval aggregate function, that needs to compute
3958 * sum and count, in the aggregate's memory context.
3959 *
3960 * The function is used when the state data needs to be allocated in aggregate's
3961 * context. When the state data needs to be allocated in the current memory
3962 * context, we use palloc0 directly e.g. interval_avg_deserialize().
3963 */
3964static IntervalAggState *
3966{
3968 MemoryContext agg_context;
3970
3971 if (!AggCheckCallContext(fcinfo, &agg_context))
3972 elog(ERROR, "aggregate function called in non-aggregate context");
3973
3974 old_context = MemoryContextSwitchTo(agg_context);
3975
3977
3979
3980 return state;
3981}
3982
3983/*
3984 * Accumulate a new input value for interval aggregate functions.
3985 */
3986static void
3988{
3989 /* Infinite inputs are counted separately, and do not affect "N" */
3991 {
3992 state->nInfcount++;
3993 return;
3994 }
3995
3997 {
3998 state->pInfcount++;
3999 return;
4000 }
4001
4002 finite_interval_pl(&state->sumX, newval, &state->sumX);
4003 state->N++;
4004}
4005
4006/*
4007 * Remove the given interval value from the aggregated state.
4008 */
4009static void
4011{
4012 /* Infinite inputs are counted separately, and do not affect "N" */
4014 {
4015 state->nInfcount--;
4016 return;
4017 }
4018
4020 {
4021 state->pInfcount--;
4022 return;
4023 }
4024
4025 /* Handle the to-be-discarded finite value. */
4026 state->N--;
4027 if (state->N > 0)
4028 finite_interval_mi(&state->sumX, newval, &state->sumX);
4029 else
4030 {
4031 /* All values discarded, reset the state */
4032 Assert(state->N == 0);
4033 memset(&state->sumX, 0, sizeof(state->sumX));
4034 }
4035}
4036
4037/*
4038 * Transition function for sum() and avg() interval aggregates.
4039 */
4040Datum
4042{
4044
4046
4047 /* Create the state data on the first call */
4048 if (state == NULL)
4049 state = makeIntervalAggState(fcinfo);
4050
4051 if (!PG_ARGISNULL(1))
4053
4055}
4056
4057/*
4058 * Combine function for sum() and avg() interval aggregates.
4059 *
4060 * Combine the given internal aggregate states and place the combination in
4061 * the first argument.
4062 */
4063Datum
4065{
4068
4071
4072 if (state2 == NULL)
4074
4075 if (state1 == NULL)
4076 {
4077 /* manually copy all fields from state2 to state1 */
4078 state1 = makeIntervalAggState(fcinfo);
4079
4080 state1->N = state2->N;
4081 state1->pInfcount = state2->pInfcount;
4082 state1->nInfcount = state2->nInfcount;
4083
4084 state1->sumX.day = state2->sumX.day;
4085 state1->sumX.month = state2->sumX.month;
4086 state1->sumX.time = state2->sumX.time;
4087
4089 }
4090
4091 state1->N += state2->N;
4092 state1->pInfcount += state2->pInfcount;
4093 state1->nInfcount += state2->nInfcount;
4094
4095 /* Accumulate finite interval values, if any. */
4096 if (state2->N > 0)
4097 finite_interval_pl(&state1->sumX, &state2->sumX, &state1->sumX);
4098
4100}
4101
4102/*
4103 * interval_avg_serialize
4104 * Serialize IntervalAggState for interval aggregates.
4105 */
4106Datum
4108{
4111 bytea *result;
4112
4113 /* Ensure we disallow calling when not in aggregate context */
4114 if (!AggCheckCallContext(fcinfo, NULL))
4115 elog(ERROR, "aggregate function called in non-aggregate context");
4116
4118
4120
4121 /* N */
4122 pq_sendint64(&buf, state->N);
4123
4124 /* sumX */
4125 pq_sendint64(&buf, state->sumX.time);
4126 pq_sendint32(&buf, state->sumX.day);
4127 pq_sendint32(&buf, state->sumX.month);
4128
4129 /* pInfcount */
4130 pq_sendint64(&buf, state->pInfcount);
4131
4132 /* nInfcount */
4133 pq_sendint64(&buf, state->nInfcount);
4134
4135 result = pq_endtypsend(&buf);
4136
4137 PG_RETURN_BYTEA_P(result);
4138}
4139
4140/*
4141 * interval_avg_deserialize
4142 * Deserialize bytea into IntervalAggState for interval aggregates.
4143 */
4144Datum
4146{
4147 bytea *sstate;
4148 IntervalAggState *result;
4150
4151 if (!AggCheckCallContext(fcinfo, NULL))
4152 elog(ERROR, "aggregate function called in non-aggregate context");
4153
4154 sstate = PG_GETARG_BYTEA_PP(0);
4155
4156 /*
4157 * Initialize a StringInfo so that we can "receive" it using the standard
4158 * recv-function infrastructure.
4159 */
4161 VARSIZE_ANY_EXHDR(sstate));
4162
4164
4165 /* N */
4166 result->N = pq_getmsgint64(&buf);
4167
4168 /* sumX */
4169 result->sumX.time = pq_getmsgint64(&buf);
4170 result->sumX.day = pq_getmsgint(&buf, 4);
4171 result->sumX.month = pq_getmsgint(&buf, 4);
4172
4173 /* pInfcount */
4174 result->pInfcount = pq_getmsgint64(&buf);
4175
4176 /* nInfcount */
4177 result->nInfcount = pq_getmsgint64(&buf);
4178
4179 pq_getmsgend(&buf);
4180
4181 PG_RETURN_POINTER(result);
4182}
4183
4184/*
4185 * Inverse transition function for sum() and avg() interval aggregates.
4186 */
4187Datum
4189{
4191
4193
4194 /* Should not get here with no state */
4195 if (state == NULL)
4196 elog(ERROR, "interval_avg_accum_inv called with NULL state");
4197
4198 if (!PG_ARGISNULL(1))
4200
4202}
4203
4204/* avg(interval) aggregate final function */
4205Datum
4207{
4209
4211
4212 /* If there were no non-null inputs, return NULL */
4213 if (state == NULL || IA_TOTAL_COUNT(state) == 0)
4215
4216 /*
4217 * Aggregating infinities that all have the same sign produces infinity
4218 * with that sign. Aggregating infinities with different signs results in
4219 * an error.
4220 */
4221 if (state->pInfcount > 0 || state->nInfcount > 0)
4222 {
4223 Interval *result;
4224
4225 if (state->pInfcount > 0 && state->nInfcount > 0)
4226 ereport(ERROR,
4228 errmsg("interval out of range")));
4229
4230 result = palloc_object(Interval);
4231 if (state->pInfcount > 0)
4232 INTERVAL_NOEND(result);
4233 else
4234 INTERVAL_NOBEGIN(result);
4235
4236 PG_RETURN_INTERVAL_P(result);
4237 }
4238
4240 IntervalPGetDatum(&state->sumX),
4241 Float8GetDatum((double) state->N));
4242}
4243
4244/* sum(interval) aggregate final function */
4245Datum
4247{
4249 Interval *result;
4250
4252
4253 /* If there were no non-null inputs, return NULL */
4254 if (state == NULL || IA_TOTAL_COUNT(state) == 0)
4256
4257 /*
4258 * Aggregating infinities that all have the same sign produces infinity
4259 * with that sign. Aggregating infinities with different signs results in
4260 * an error.
4261 */
4262 if (state->pInfcount > 0 && state->nInfcount > 0)
4263 ereport(ERROR,
4265 errmsg("interval out of range")));
4266
4267 result = palloc_object(Interval);
4268
4269 if (state->pInfcount > 0)
4270 INTERVAL_NOEND(result);
4271 else if (state->nInfcount > 0)
4272 INTERVAL_NOBEGIN(result);
4273 else
4274 memcpy(result, &state->sumX, sizeof(Interval));
4275
4276 PG_RETURN_INTERVAL_P(result);
4277}
4278
4279/* timestamp_age()
4280 * Calculate time difference while retaining year/month fields.
4281 * Note that this does not result in an accurate absolute time span
4282 * since year and month are out of context once the arithmetic
4283 * is done.
4284 */
4285Datum
4287{
4290 Interval *result;
4291 fsec_t fsec1,
4292 fsec2;
4293 struct pg_itm tt,
4294 *tm = &tt;
4295 struct pg_tm tt1,
4296 *tm1 = &tt1;
4297 struct pg_tm tt2,
4298 *tm2 = &tt2;
4299
4300 result = palloc_object(Interval);
4301
4302 /*
4303 * Handle infinities.
4304 *
4305 * We treat anything that amounts to "infinity - infinity" as an error,
4306 * since the interval type has nothing equivalent to NaN.
4307 */
4309 {
4311 ereport(ERROR,
4313 errmsg("interval out of range")));
4314 else
4315 INTERVAL_NOBEGIN(result);
4316 }
4317 else if (TIMESTAMP_IS_NOEND(dt1))
4318 {
4320 ereport(ERROR,
4322 errmsg("interval out of range")));
4323 else
4324 INTERVAL_NOEND(result);
4325 }
4326 else if (TIMESTAMP_IS_NOBEGIN(dt2))
4327 INTERVAL_NOEND(result);
4328 else if (TIMESTAMP_IS_NOEND(dt2))
4329 INTERVAL_NOBEGIN(result);
4330 else if (timestamp2tm(dt1, NULL, tm1, &fsec1, NULL, NULL) == 0 &&
4331 timestamp2tm(dt2, NULL, tm2, &fsec2, NULL, NULL) == 0)
4332 {
4333 /* form the symbolic difference */
4334 tm->tm_usec = fsec1 - fsec2;
4335 tm->tm_sec = tm1->tm_sec - tm2->tm_sec;
4336 tm->tm_min = tm1->tm_min - tm2->tm_min;
4337 tm->tm_hour = tm1->tm_hour - tm2->tm_hour;
4338 tm->tm_mday = tm1->tm_mday - tm2->tm_mday;
4339 tm->tm_mon = tm1->tm_mon - tm2->tm_mon;
4340 tm->tm_year = tm1->tm_year - tm2->tm_year;
4341
4342 /* flip sign if necessary... */
4343 if (dt1 < dt2)
4344 {
4345 tm->tm_usec = -tm->tm_usec;
4346 tm->tm_sec = -tm->tm_sec;
4347 tm->tm_min = -tm->tm_min;
4348 tm->tm_hour = -tm->tm_hour;
4349 tm->tm_mday = -tm->tm_mday;
4350 tm->tm_mon = -tm->tm_mon;
4351 tm->tm_year = -tm->tm_year;
4352 }
4353
4354 /* propagate any negative fields into the next higher field */
4355 while (tm->tm_usec < 0)
4356 {
4357 tm->tm_usec += USECS_PER_SEC;
4358 tm->tm_sec--;
4359 }
4360
4361 while (tm->tm_sec < 0)
4362 {
4364 tm->tm_min--;
4365 }
4366
4367 while (tm->tm_min < 0)
4368 {
4370 tm->tm_hour--;
4371 }
4372
4373 while (tm->tm_hour < 0)
4374 {
4376 tm->tm_mday--;
4377 }
4378
4379 while (tm->tm_mday < 0)
4380 {
4381 if (dt1 < dt2)
4382 {
4383 tm->tm_mday += day_tab[isleap(tm1->tm_year)][tm1->tm_mon - 1];
4384 tm->tm_mon--;
4385 }
4386 else
4387 {
4388 tm->tm_mday += day_tab[isleap(tm2->tm_year)][tm2->tm_mon - 1];
4389 tm->tm_mon--;
4390 }
4391 }
4392
4393 while (tm->tm_mon < 0)
4394 {
4396 tm->tm_year--;
4397 }
4398
4399 /* recover sign if necessary... */
4400 if (dt1 < dt2)
4401 {
4402 tm->tm_usec = -tm->tm_usec;
4403 tm->tm_sec = -tm->tm_sec;
4404 tm->tm_min = -tm->tm_min;
4405 tm->tm_hour = -tm->tm_hour;
4406 tm->tm_mday = -tm->tm_mday;
4407 tm->tm_mon = -tm->tm_mon;
4408 tm->tm_year = -tm->tm_year;
4409 }
4410
4411 if (itm2interval(tm, result) != 0)
4412 ereport(ERROR,
4414 errmsg("interval out of range")));
4415 }
4416 else
4417 ereport(ERROR,
4419 errmsg("timestamp out of range")));
4420
4421 PG_RETURN_INTERVAL_P(result);
4422}
4423
4424
4425/* timestamptz_age()
4426 * Calculate time difference while retaining year/month fields.
4427 * Note that this does not result in an accurate absolute time span
4428 * since year and month are out of context once the arithmetic
4429 * is done.
4430 */
4431Datum
4433{
4436 Interval *result;
4437 fsec_t fsec1,
4438 fsec2;
4439 struct pg_itm tt,
4440 *tm = &tt;
4441 struct pg_tm tt1,
4442 *tm1 = &tt1;
4443 struct pg_tm tt2,
4444 *tm2 = &tt2;
4445 int tz1;
4446 int tz2;
4447
4448 result = palloc_object(Interval);
4449
4450 /*
4451 * Handle infinities.
4452 *
4453 * We treat anything that amounts to "infinity - infinity" as an error,
4454 * since the interval type has nothing equivalent to NaN.
4455 */
4457 {
4459 ereport(ERROR,
4461 errmsg("interval out of range")));
4462 else
4463 INTERVAL_NOBEGIN(result);
4464 }
4465 else if (TIMESTAMP_IS_NOEND(dt1))
4466 {
4468 ereport(ERROR,
4470 errmsg("interval out of range")));
4471 else
4472 INTERVAL_NOEND(result);
4473 }
4474 else if (TIMESTAMP_IS_NOBEGIN(dt2))
4475 INTERVAL_NOEND(result);
4476 else if (TIMESTAMP_IS_NOEND(dt2))
4477 INTERVAL_NOBEGIN(result);
4478 else if (timestamp2tm(dt1, &tz1, tm1, &fsec1, NULL, NULL) == 0 &&
4479 timestamp2tm(dt2, &tz2, tm2, &fsec2, NULL, NULL) == 0)
4480 {
4481 /* form the symbolic difference */
4482 tm->tm_usec = fsec1 - fsec2;
4483 tm->tm_sec = tm1->tm_sec - tm2->tm_sec;
4484 tm->tm_min = tm1->tm_min - tm2->tm_min;
4485 tm->tm_hour = tm1->tm_hour - tm2->tm_hour;
4486 tm->tm_mday = tm1->tm_mday - tm2->tm_mday;
4487 tm->tm_mon = tm1->tm_mon - tm2->tm_mon;
4488 tm->tm_year = tm1->tm_year - tm2->tm_year;
4489
4490 /* flip sign if necessary... */
4491 if (dt1 < dt2)
4492 {
4493 tm->tm_usec = -tm->tm_usec;
4494 tm->tm_sec = -tm->tm_sec;
4495 tm->tm_min = -tm->tm_min;
4496 tm->tm_hour = -tm->tm_hour;
4497 tm->tm_mday = -tm->tm_mday;
4498 tm->tm_mon = -tm->tm_mon;
4499 tm->tm_year = -tm->tm_year;
4500 }
4501
4502 /* propagate any negative fields into the next higher field */
4503 while (tm->tm_usec < 0)
4504 {
4505 tm->tm_usec += USECS_PER_SEC;
4506 tm->tm_sec--;
4507 }
4508
4509 while (tm->tm_sec < 0)
4510 {
4512 tm->tm_min--;
4513 }
4514
4515 while (tm->tm_min < 0)
4516 {
4518 tm->tm_hour--;
4519 }
4520
4521 while (tm->tm_hour < 0)
4522 {
4524 tm->tm_mday--;
4525 }
4526
4527 while (tm->tm_mday < 0)
4528 {
4529 if (dt1 < dt2)
4530 {
4531 tm->tm_mday += day_tab[isleap(tm1->tm_year)][tm1->tm_mon - 1];
4532 tm->tm_mon--;
4533 }
4534 else
4535 {
4536 tm->tm_mday += day_tab[isleap(tm2->tm_year)][tm2->tm_mon - 1];
4537 tm->tm_mon--;
4538 }
4539 }
4540
4541 while (tm->tm_mon < 0)
4542 {
4544 tm->tm_year--;
4545 }
4546
4547 /*
4548 * Note: we deliberately ignore any difference between tz1 and tz2.
4549 */
4550
4551 /* recover sign if necessary... */
4552 if (dt1 < dt2)
4553 {
4554 tm->tm_usec = -tm->tm_usec;
4555 tm->tm_sec = -tm->tm_sec;
4556 tm->tm_min = -tm->tm_min;
4557 tm->tm_hour = -tm->tm_hour;
4558 tm->tm_mday = -tm->tm_mday;
4559 tm->tm_mon = -tm->tm_mon;
4560 tm->tm_year = -tm->tm_year;
4561 }
4562
4563 if (itm2interval(tm, result) != 0)
4564 ereport(ERROR,
4566 errmsg("interval out of range")));
4567 }
4568 else
4569 ereport(ERROR,
4571 errmsg("timestamp out of range")));
4572
4573 PG_RETURN_INTERVAL_P(result);
4574}
4575
4576
4577/*----------------------------------------------------------
4578 * Conversion operators.
4579 *---------------------------------------------------------*/
4580
4581
4582/* timestamp_bin()
4583 * Bin timestamp into specified interval.
4584 */
4585Datum
4587{
4590 Timestamp origin = PG_GETARG_TIMESTAMP(2);
4591 Timestamp result,
4593 tm_diff,
4594 tm_modulo,
4595 tm_delta;
4596
4599
4600 if (TIMESTAMP_NOT_FINITE(origin))
4601 ereport(ERROR,
4603 errmsg("origin out of range")));
4604
4606 ereport(ERROR,
4608 errmsg("timestamps cannot be binned into infinite intervals")));
4609
4610 if (stride->month != 0)
4611 ereport(ERROR,
4613 errmsg("timestamps cannot be binned into intervals containing months or years")));
4614
4617 ereport(ERROR,
4619 errmsg("interval out of range")));
4620
4621 if (stride_usecs <= 0)
4622 ereport(ERROR,
4624 errmsg("stride must be greater than zero")));
4625
4627 ereport(ERROR,
4629 errmsg("interval out of range")));
4630
4631 /* These calculations cannot overflow */
4634 result = origin + tm_delta;
4635
4636 /*
4637 * We want to round towards -infinity, not 0, when tm_diff is negative and
4638 * not a multiple of stride_usecs. This adjustment *can* cause overflow,
4639 * since the result might now be out of the range origin .. timestamp.
4640 */
4641 if (tm_modulo < 0)
4642 {
4643 if (unlikely(pg_sub_s64_overflow(result, stride_usecs, &result)) ||
4644 !IS_VALID_TIMESTAMP(result))
4645 ereport(ERROR,
4647 errmsg("timestamp out of range")));
4648 }
4649
4650 PG_RETURN_TIMESTAMP(result);
4651}
4652
4653/* timestamp_trunc()
4654 * Truncate timestamp to specified units.
4655 */
4656Datum
4658{
4661 Timestamp result;
4662 int type,
4663 val;
4664 char *lowunits;
4665 fsec_t fsec;
4666 struct pg_tm tt,
4667 *tm = &tt;
4668
4671 false);
4672
4673 type = DecodeUnits(0, lowunits, &val);
4674
4675 if (type == UNITS)
4676 {
4678 {
4679 /*
4680 * Errors thrown here for invalid units should exactly match those
4681 * below, else there will be unexpected discrepancies between
4682 * finite- and infinite-input cases.
4683 */
4684 switch (val)
4685 {
4686 case DTK_WEEK:
4687 case DTK_MILLENNIUM:
4688 case DTK_CENTURY:
4689 case DTK_DECADE:
4690 case DTK_YEAR:
4691 case DTK_QUARTER:
4692 case DTK_MONTH:
4693 case DTK_DAY:
4694 case DTK_HOUR:
4695 case DTK_MINUTE:
4696 case DTK_SECOND:
4697 case DTK_MILLISEC:
4698 case DTK_MICROSEC:
4700 break;
4701 default:
4702 ereport(ERROR,
4704 errmsg("unit \"%s\" not supported for type %s",
4706 result = 0;
4707 }
4708 }
4709
4710 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
4711 ereport(ERROR,
4713 errmsg("timestamp out of range")));
4714
4715 switch (val)
4716 {
4717 case DTK_WEEK:
4718 {
4719 int woy;
4720
4722
4723 /*
4724 * If it is week 52/53 and the month is January, then the
4725 * week must belong to the previous year. Also, some
4726 * December dates belong to the next year.
4727 */
4728 if (woy >= 52 && tm->tm_mon == 1)
4729 --tm->tm_year;
4731 ++tm->tm_year;
4732 isoweek2date(woy, &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
4733 tm->tm_hour = 0;
4734 tm->tm_min = 0;
4735 tm->tm_sec = 0;
4736 fsec = 0;
4737 break;
4738 }
4739 case DTK_MILLENNIUM:
4740 /* see comments in timestamptz_trunc */
4741 if (tm->tm_year > 0)
4742 tm->tm_year = ((tm->tm_year + 999) / 1000) * 1000 - 999;
4743 else
4744 tm->tm_year = -((999 - (tm->tm_year - 1)) / 1000) * 1000 + 1;
4746 case DTK_CENTURY:
4747 /* see comments in timestamptz_trunc */
4748 if (tm->tm_year > 0)
4749 tm->tm_year = ((tm->tm_year + 99) / 100) * 100 - 99;
4750 else
4751 tm->tm_year = -((99 - (tm->tm_year - 1)) / 100) * 100 + 1;
4753 case DTK_DECADE:
4754 /* see comments in timestamptz_trunc */
4755 if (val != DTK_MILLENNIUM && val != DTK_CENTURY)
4756 {
4757 if (tm->tm_year > 0)
4758 tm->tm_year = (tm->tm_year / 10) * 10;
4759 else
4760 tm->tm_year = -((8 - (tm->tm_year - 1)) / 10) * 10;
4761 }
4763 case DTK_YEAR:
4764 tm->tm_mon = 1;
4766 case DTK_QUARTER:
4767 tm->tm_mon = (3 * ((tm->tm_mon - 1) / 3)) + 1;
4769 case DTK_MONTH:
4770 tm->tm_mday = 1;
4772 case DTK_DAY:
4773 tm->tm_hour = 0;
4775 case DTK_HOUR:
4776 tm->tm_min = 0;
4778 case DTK_MINUTE:
4779 tm->tm_sec = 0;
4781 case DTK_SECOND:
4782 fsec = 0;
4783 break;
4784
4785 case DTK_MILLISEC:
4786 fsec = (fsec / 1000) * 1000;
4787 break;
4788
4789 case DTK_MICROSEC:
4790 break;
4791
4792 default:
4793 ereport(ERROR,
4795 errmsg("unit \"%s\" not supported for type %s",
4797 result = 0;
4798 }
4799
4800 if (tm2timestamp(tm, fsec, NULL, &result) != 0)
4801 ereport(ERROR,
4803 errmsg("timestamp out of range")));
4804 }
4805 else
4806 {
4807 ereport(ERROR,
4809 errmsg("unit \"%s\" not recognized for type %s",
4811 result = 0;
4812 }
4813
4814 PG_RETURN_TIMESTAMP(result);
4815}
4816
4817/* timestamptz_bin()
4818 * Bin timestamptz into specified interval using specified origin.
4819 */
4820Datum
4822{
4826 TimestampTz result,
4828 tm_diff,
4829 tm_modulo,
4830 tm_delta;
4831
4834
4835 if (TIMESTAMP_NOT_FINITE(origin))
4836 ereport(ERROR,
4838 errmsg("origin out of range")));
4839
4841 ereport(ERROR,
4843 errmsg("timestamps cannot be binned into infinite intervals")));
4844
4845 if (stride->month != 0)
4846 ereport(ERROR,
4848 errmsg("timestamps cannot be binned into intervals containing months or years")));
4849
4852 ereport(ERROR,
4854 errmsg("interval out of range")));
4855
4856 if (stride_usecs <= 0)
4857 ereport(ERROR,
4859 errmsg("stride must be greater than zero")));
4860
4862 ereport(ERROR,
4864 errmsg("interval out of range")));
4865
4866 /* These calculations cannot overflow */
4869 result = origin + tm_delta;
4870
4871 /*
4872 * We want to round towards -infinity, not 0, when tm_diff is negative and
4873 * not a multiple of stride_usecs. This adjustment *can* cause overflow,
4874 * since the result might now be out of the range origin .. timestamp.
4875 */
4876 if (tm_modulo < 0)
4877 {
4878 if (unlikely(pg_sub_s64_overflow(result, stride_usecs, &result)) ||
4879 !IS_VALID_TIMESTAMP(result))
4880 ereport(ERROR,
4882 errmsg("timestamp out of range")));
4883 }
4884
4885 PG_RETURN_TIMESTAMPTZ(result);
4886}
4887
4888/*
4889 * Common code for timestamptz_trunc() and timestamptz_trunc_zone().
4890 *
4891 * tzp identifies the zone to truncate with respect to. We assume
4892 * infinite timestamps have already been rejected.
4893 */
4894static TimestampTz
4896{
4897 TimestampTz result;
4898 int tz;
4899 int type,
4900 val;
4901 bool redotz = false;
4902 char *lowunits;
4903 fsec_t fsec;
4904 struct pg_tm tt,
4905 *tm = &tt;
4906
4909 false);
4910
4911 type = DecodeUnits(0, lowunits, &val);
4912
4913 if (type == UNITS)
4914 {
4916 {
4917 /*
4918 * Errors thrown here for invalid units should exactly match those
4919 * below, else there will be unexpected discrepancies between
4920 * finite- and infinite-input cases.
4921 */
4922 switch (val)
4923 {
4924 case DTK_WEEK:
4925 case DTK_MILLENNIUM:
4926 case DTK_CENTURY:
4927 case DTK_DECADE:
4928 case DTK_YEAR:
4929 case DTK_QUARTER:
4930 case DTK_MONTH:
4931 case DTK_DAY:
4932 case DTK_HOUR:
4933 case DTK_MINUTE:
4934 case DTK_SECOND:
4935 case DTK_MILLISEC:
4936 case DTK_MICROSEC:
4937 return timestamp;
4938 break;
4939
4940 default:
4941 ereport(ERROR,
4943 errmsg("unit \"%s\" not supported for type %s",
4945 result = 0;
4946 }
4947 }
4948
4949 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, tzp) != 0)
4950 ereport(ERROR,
4952 errmsg("timestamp out of range")));
4953
4954 switch (val)
4955 {
4956 case DTK_WEEK:
4957 {
4958 int woy;
4959
4961
4962 /*
4963 * If it is week 52/53 and the month is January, then the
4964 * week must belong to the previous year. Also, some
4965 * December dates belong to the next year.
4966 */
4967 if (woy >= 52 && tm->tm_mon == 1)
4968 --tm->tm_year;
4970 ++tm->tm_year;
4971 isoweek2date(woy, &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
4972 tm->tm_hour = 0;
4973 tm->tm_min = 0;
4974 tm->tm_sec = 0;
4975 fsec = 0;
4976 redotz = true;
4977 break;
4978 }
4979 /* one may consider DTK_THOUSAND and DTK_HUNDRED... */
4980 case DTK_MILLENNIUM:
4981
4982 /*
4983 * truncating to the millennium? what is this supposed to
4984 * mean? let us put the first year of the millennium... i.e.
4985 * -1000, 1, 1001, 2001...
4986 */
4987 if (tm->tm_year > 0)
4988 tm->tm_year = ((tm->tm_year + 999) / 1000) * 1000 - 999;
4989 else
4990 tm->tm_year = -((999 - (tm->tm_year - 1)) / 1000) * 1000 + 1;
4992 case DTK_CENTURY:
4993 /* truncating to the century? as above: -100, 1, 101... */
4994 if (tm->tm_year > 0)
4995 tm->tm_year = ((tm->tm_year + 99) / 100) * 100 - 99;
4996 else
4997 tm->tm_year = -((99 - (tm->tm_year - 1)) / 100) * 100 + 1;
4999 case DTK_DECADE:
5000
5001 /*
5002 * truncating to the decade? first year of the decade. must
5003 * not be applied if year was truncated before!
5004 */
5005 if (val != DTK_MILLENNIUM && val != DTK_CENTURY)
5006 {
5007 if (tm->tm_year > 0)
5008 tm->tm_year = (tm->tm_year / 10) * 10;
5009 else
5010 tm->tm_year = -((8 - (tm->tm_year - 1)) / 10) * 10;
5011 }
5013 case DTK_YEAR:
5014 tm->tm_mon = 1;
5016 case DTK_QUARTER:
5017 tm->tm_mon = (3 * ((tm->tm_mon - 1) / 3)) + 1;
5019 case DTK_MONTH:
5020 tm->tm_mday = 1;
5022 case DTK_DAY:
5023 tm->tm_hour = 0;
5024 redotz = true; /* for all cases >= DAY */
5026 case DTK_HOUR:
5027 tm->tm_min = 0;
5029 case DTK_MINUTE:
5030 tm->tm_sec = 0;
5032 case DTK_SECOND:
5033 fsec = 0;
5034 break;
5035 case DTK_MILLISEC:
5036 fsec = (fsec / 1000) * 1000;
5037 break;
5038 case DTK_MICROSEC:
5039 break;
5040
5041 default:
5042 ereport(ERROR,
5044 errmsg("unit \"%s\" not supported for type %s",
5046 result = 0;
5047 }
5048
5049 if (redotz)
5050 tz = DetermineTimeZoneOffset(tm, tzp);
5051
5052 if (tm2timestamp(tm, fsec, &tz, &result) != 0)
5053 ereport(ERROR,
5055 errmsg("timestamp out of range")));
5056 }
5057 else
5058 {
5059 ereport(ERROR,
5061 errmsg("unit \"%s\" not recognized for type %s",
5063 result = 0;
5064 }
5065
5066 return result;
5067}
5068
5069/* timestamptz_trunc()
5070 * Truncate timestamptz to specified units in session timezone.
5071 */
5072Datum
5083
5084/* timestamptz_trunc_zone()
5085 * Truncate timestamptz to specified units in specified timezone.
5086 */
5087Datum
5089{
5093 TimestampTz result;
5094 pg_tz *tzp;
5095
5096 /*
5097 * Look up the requested timezone.
5098 */
5099 tzp = lookup_timezone(zone);
5100
5102
5103 PG_RETURN_TIMESTAMPTZ(result);
5104}
5105
5106/* interval_trunc()
5107 * Extract specified field from interval.
5108 */
5109Datum
5111{
5114 Interval *result;
5115 int type,
5116 val;
5117 char *lowunits;
5118 struct pg_itm tt,
5119 *tm = &tt;
5120
5121 result = palloc_object(Interval);
5122
5125 false);
5126
5127 type = DecodeUnits(0, lowunits, &val);
5128
5129 if (type == UNITS)
5130 {
5132 {
5133 /*
5134 * Errors thrown here for invalid units should exactly match those
5135 * below, else there will be unexpected discrepancies between
5136 * finite- and infinite-input cases.
5137 */
5138 switch (val)
5139 {
5140 case DTK_MILLENNIUM:
5141 case DTK_CENTURY:
5142 case DTK_DECADE:
5143 case DTK_YEAR:
5144 case DTK_QUARTER:
5145 case DTK_MONTH:
5146 case DTK_DAY:
5147 case DTK_HOUR:
5148 case DTK_MINUTE:
5149 case DTK_SECOND:
5150 case DTK_MILLISEC:
5151 case DTK_MICROSEC:
5152 memcpy(result, interval, sizeof(Interval));
5153 PG_RETURN_INTERVAL_P(result);
5154 break;
5155
5156 default:
5157 ereport(ERROR,
5159 errmsg("unit \"%s\" not supported for type %s",
5161 (val == DTK_WEEK) ? errdetail("Months usually have fractional weeks.") : 0));
5162 result = NULL;
5163 }
5164 }
5165
5167 switch (val)
5168 {
5169 case DTK_MILLENNIUM:
5170 /* caution: C division may have negative remainder */
5171 tm->tm_year = (tm->tm_year / 1000) * 1000;
5173 case DTK_CENTURY:
5174 /* caution: C division may have negative remainder */
5175 tm->tm_year = (tm->tm_year / 100) * 100;
5177 case DTK_DECADE:
5178 /* caution: C division may have negative remainder */
5179 tm->tm_year = (tm->tm_year / 10) * 10;
5181 case DTK_YEAR:
5182 tm->tm_mon = 0;
5184 case DTK_QUARTER:
5185 tm->tm_mon = 3 * (tm->tm_mon / 3);
5187 case DTK_MONTH:
5188 tm->tm_mday = 0;
5190 case DTK_DAY:
5191 tm->tm_hour = 0;
5193 case DTK_HOUR:
5194 tm->tm_min = 0;
5196 case DTK_MINUTE:
5197 tm->tm_sec = 0;
5199 case DTK_SECOND:
5200 tm->tm_usec = 0;
5201 break;
5202 case DTK_MILLISEC:
5203 tm->tm_usec = (tm->tm_usec / 1000) * 1000;
5204 break;
5205 case DTK_MICROSEC:
5206 break;
5207
5208 default:
5209 ereport(ERROR,
5211 errmsg("unit \"%s\" not supported for type %s",
5213 (val == DTK_WEEK) ? errdetail("Months usually have fractional weeks.") : 0));
5214 }
5215
5216 if (itm2interval(tm, result) != 0)
5217 ereport(ERROR,
5219 errmsg("interval out of range")));
5220 }
5221 else
5222 {
5223 ereport(ERROR,
5225 errmsg("unit \"%s\" not recognized for type %s",
5227 }
5228
5229 PG_RETURN_INTERVAL_P(result);
5230}
5231
5232/* isoweek2j()
5233 *
5234 * Return the Julian day which corresponds to the first day (Monday) of the given ISO 8601 year and week.
5235 * Julian days are used to convert between ISO week dates and Gregorian dates.
5236 *
5237 * XXX: This function has integer overflow hazards, but restructuring it to
5238 * work with the soft-error handling that its callers do is likely more
5239 * trouble than it's worth.
5240 */
5241int
5242isoweek2j(int year, int week)
5243{
5244 int day0,
5245 day4;
5246
5247 /* fourth day of current year */
5248 day4 = date2j(year, 1, 4);
5249
5250 /* day0 == offset to first day of week (Monday) */
5251 day0 = j2day(day4 - 1);
5252
5253 return ((week - 1) * 7) + (day4 - day0);
5254}
5255
5256/* isoweek2date()
5257 * Convert ISO week of year number to date.
5258 * The year field must be specified with the ISO year!
5259 * karel 2000/08/07
5260 */
5261void
5262isoweek2date(int woy, int *year, int *mon, int *mday)
5263{
5264 j2date(isoweek2j(*year, woy), year, mon, mday);
5265}
5266
5267/* isoweekdate2date()
5268 *
5269 * Convert an ISO 8601 week date (ISO year, ISO week) into a Gregorian date.
5270 * Gregorian day of week sent so weekday strings can be supplied.
5271 * Populates year, mon, and mday with the correct Gregorian values.
5272 * year must be passed in as the ISO year.
5273 */
5274void
5275isoweekdate2date(int isoweek, int wday, int *year, int *mon, int *mday)
5276{
5277 int jday;
5278
5279 jday = isoweek2j(*year, isoweek);
5280 /* convert Gregorian week start (Sunday=1) to ISO week start (Monday=1) */
5281 if (wday > 1)
5282 jday += wday - 2;
5283 else
5284 jday += 6;
5285 j2date(jday, year, mon, mday);
5286}
5287
5288/* date2isoweek()
5289 *
5290 * Returns ISO week number of year.
5291 */
5292int
5293date2isoweek(int year, int mon, int mday)
5294{
5295 int day0,
5296 day4,
5297 dayn,
5298 week;
5299
5300 /* current day */
5301 dayn = date2j(year, mon, mday);
5302
5303 /* fourth day of current year */
5304 day4 = date2j(year, 1, 4);
5305
5306 /* day0 == offset to first day of week (Monday) */
5307 day0 = j2day(day4 - 1);
5308
5309 /*
5310 * We need the first week containing a Thursday, otherwise this day falls
5311 * into the previous year for purposes of counting weeks
5312 */
5313 if (dayn < day4 - day0)
5314 {
5315 day4 = date2j(year - 1, 1, 4);
5316
5317 /* day0 == offset to first day of week (Monday) */
5318 day0 = j2day(day4 - 1);
5319 }
5320
5321 week = (dayn - (day4 - day0)) / 7 + 1;
5322
5323 /*
5324 * Sometimes the last few days in a year will fall into the first week of
5325 * the next year, so check for this.
5326 */
5327 if (week >= 52)
5328 {
5329 day4 = date2j(year + 1, 1, 4);
5330
5331 /* day0 == offset to first day of week (Monday) */
5332 day0 = j2day(day4 - 1);
5333
5334 if (dayn >= day4 - day0)
5335 week = (dayn - (day4 - day0)) / 7 + 1;
5336 }
5337
5338 return week;
5339}
5340
5341
5342/* date2isoyear()
5343 *
5344 * Returns ISO 8601 year number.
5345 * Note: zero or negative results follow the year-zero-exists convention.
5346 */
5347int
5348date2isoyear(int year, int mon, int mday)
5349{
5350 int day0,
5351 day4,
5352 dayn,
5353 week;
5354
5355 /* current day */
5356 dayn = date2j(year, mon, mday);
5357
5358 /* fourth day of current year */
5359 day4 = date2j(year, 1, 4);
5360
5361 /* day0 == offset to first day of week (Monday) */
5362 day0 = j2day(day4 - 1);
5363
5364 /*
5365 * We need the first week containing a Thursday, otherwise this day falls
5366 * into the previous year for purposes of counting weeks
5367 */
5368 if (dayn < day4 - day0)
5369 {
5370 day4 = date2j(year - 1, 1, 4);
5371
5372 /* day0 == offset to first day of week (Monday) */
5373 day0 = j2day(day4 - 1);
5374
5375 year--;
5376 }
5377
5378 week = (dayn - (day4 - day0)) / 7 + 1;
5379
5380 /*
5381 * Sometimes the last few days in a year will fall into the first week of
5382 * the next year, so check for this.
5383 */
5384 if (week >= 52)
5385 {
5386 day4 = date2j(year + 1, 1, 4);
5387
5388 /* day0 == offset to first day of week (Monday) */
5389 day0 = j2day(day4 - 1);
5390
5391 if (dayn >= day4 - day0)
5392 year++;
5393 }
5394
5395 return year;
5396}
5397
5398
5399/* date2isoyearday()
5400 *
5401 * Returns the ISO 8601 day-of-year, given a Gregorian year, month and day.
5402 * Possible return values are 1 through 371 (364 in non-leap years).
5403 */
5404int
5405date2isoyearday(int year, int mon, int mday)
5406{
5407 return date2j(year, mon, mday) - isoweek2j(date2isoyear(year, mon, mday), 1) + 1;
5408}
5409
5410/*
5411 * NonFiniteTimestampTzPart
5412 *
5413 * Used by timestamp_part and timestamptz_part when extracting from infinite
5414 * timestamp[tz]. Returns +/-Infinity if that is the appropriate result,
5415 * otherwise returns zero (which should be taken as meaning to return NULL).
5416 *
5417 * Errors thrown here for invalid units should exactly match those that
5418 * would be thrown in the calling functions, else there will be unexpected
5419 * discrepancies between finite- and infinite-input cases.
5420 */
5421static float8
5423 bool isNegative, bool isTz)
5424{
5425 if ((type != UNITS) && (type != RESERV))
5426 ereport(ERROR,
5428 errmsg("unit \"%s\" not recognized for type %s",
5429 lowunits,
5431
5432 switch (unit)
5433 {
5434 /* Oscillating units */
5435 case DTK_MICROSEC:
5436 case DTK_MILLISEC:
5437 case DTK_SECOND:
5438 case DTK_MINUTE:
5439 case DTK_HOUR:
5440 case DTK_DAY:
5441 case DTK_MONTH:
5442 case DTK_QUARTER:
5443 case DTK_WEEK:
5444 case DTK_DOW:
5445 case DTK_ISODOW:
5446 case DTK_DOY:
5447 case DTK_TZ:
5448 case DTK_TZ_MINUTE:
5449 case DTK_TZ_HOUR:
5450 return 0.0;
5451
5452 /* Monotonically-increasing units */
5453 case DTK_YEAR:
5454 case DTK_DECADE:
5455 case DTK_CENTURY:
5456 case DTK_MILLENNIUM:
5457 case DTK_JULIAN:
5458 case DTK_ISOYEAR:
5459 case DTK_EPOCH:
5460 if (isNegative)
5461 return -get_float8_infinity();
5462 else
5463 return get_float8_infinity();
5464
5465 default:
5466 ereport(ERROR,
5468 errmsg("unit \"%s\" not supported for type %s",
5469 lowunits,
5471 return 0.0; /* keep compiler quiet */
5472 }
5473}
5474
5475/* timestamp_part() and extract_timestamp()
5476 * Extract specified field from timestamp.
5477 */
5478static Datum
5480{
5485 int type,
5486 val;
5487 char *lowunits;
5488 fsec_t fsec;
5489 struct pg_tm tt,
5490 *tm = &tt;
5491
5494 false);
5495
5496 type = DecodeUnits(0, lowunits, &val);
5497 if (type == UNKNOWN_FIELD)
5499
5501 {
5504 false);
5505
5506 if (r != 0.0)
5507 {
5508 if (retnumeric)
5509 {
5510 if (r < 0)
5512 CStringGetDatum("-Infinity"),
5514 Int32GetDatum(-1));
5515 else if (r > 0)
5517 CStringGetDatum("Infinity"),
5519 Int32GetDatum(-1));
5520 }
5521 else
5523 }
5524 else
5526 }
5527
5528 if (type == UNITS)
5529 {
5530 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
5531 ereport(ERROR,
5533 errmsg("timestamp out of range")));
5534
5535 switch (val)
5536 {
5537 case DTK_MICROSEC:
5538 intresult = tm->tm_sec * INT64CONST(1000000) + fsec;
5539 break;
5540
5541 case DTK_MILLISEC:
5542 if (retnumeric)
5543 /*---
5544 * tm->tm_sec * 1000 + fsec / 1000
5545 * = (tm->tm_sec * 1'000'000 + fsec) / 1000
5546 */
5548 else
5549 PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + fsec / 1000.0);
5550 break;
5551
5552 case DTK_SECOND:
5553 if (retnumeric)
5554 /*---
5555 * tm->tm_sec + fsec / 1'000'000
5556 * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
5557 */
5559 else
5560 PG_RETURN_FLOAT8(tm->tm_sec + fsec / 1000000.0);
5561 break;
5562
5563 case DTK_MINUTE:
5564 intresult = tm->tm_min;
5565 break;
5566
5567 case DTK_HOUR:
5568 intresult = tm->tm_hour;
5569 break;
5570
5571 case DTK_DAY:
5572 intresult = tm->tm_mday;
5573 break;
5574
5575 case DTK_MONTH:
5576 intresult = tm->tm_mon;
5577 break;
5578
5579 case DTK_QUARTER:
5580 intresult = (tm->tm_mon - 1) / 3 + 1;
5581 break;
5582
5583 case DTK_WEEK:
5585 break;
5586
5587 case DTK_YEAR:
5588 if (tm->tm_year > 0)
5589 intresult = tm->tm_year;
5590 else
5591 /* there is no year 0, just 1 BC and 1 AD */
5592 intresult = tm->tm_year - 1;
5593 break;
5594
5595 case DTK_DECADE:
5596
5597 /*
5598 * what is a decade wrt dates? let us assume that decade 199
5599 * is 1990 thru 1999... decade 0 starts on year 1 BC, and -1
5600 * is 11 BC thru 2 BC...
5601 */
5602 if (tm->tm_year >= 0)
5603 intresult = tm->tm_year / 10;
5604 else
5605 intresult = -((8 - (tm->tm_year - 1)) / 10);
5606 break;
5607
5608 case DTK_CENTURY:
5609
5610 /* ----
5611 * centuries AD, c>0: year in [ (c-1)* 100 + 1 : c*100 ]
5612 * centuries BC, c<0: year in [ c*100 : (c+1) * 100 - 1]
5613 * there is no number 0 century.
5614 * ----
5615 */
5616 if (tm->tm_year > 0)
5617 intresult = (tm->tm_year + 99) / 100;
5618 else
5619 /* caution: C division may have negative remainder */
5620 intresult = -((99 - (tm->tm_year - 1)) / 100);
5621 break;
5622
5623 case DTK_MILLENNIUM:
5624 /* see comments above. */
5625 if (tm->tm_year > 0)
5626 intresult = (tm->tm_year + 999) / 1000;
5627 else
5628 intresult = -((999 - (tm->tm_year - 1)) / 1000);
5629 break;
5630
5631 case DTK_JULIAN:
5632 if (retnumeric)
5636 NULL),
5637 NULL));
5638 else
5641 tm->tm_sec + (fsec / 1000000.0)) / (double) SECS_PER_DAY);
5642 break;
5643
5644 case DTK_ISOYEAR:
5646 /* Adjust BC years */
5647 if (intresult <= 0)
5648 intresult -= 1;
5649 break;
5650
5651 case DTK_DOW:
5652 case DTK_ISODOW:
5654 if (val == DTK_ISODOW && intresult == 0)
5655 intresult = 7;
5656 break;
5657
5658 case DTK_DOY:
5660 - date2j(tm->tm_year, 1, 1) + 1);
5661 break;
5662
5663 case DTK_TZ:
5664 case DTK_TZ_MINUTE:
5665 case DTK_TZ_HOUR:
5666 default:
5667 ereport(ERROR,
5669 errmsg("unit \"%s\" not supported for type %s",
5671 intresult = 0;
5672 }
5673 }
5674 else if (type == RESERV)
5675 {
5676 switch (val)
5677 {
5678 case DTK_EPOCH:
5680 /* (timestamp - epoch) / 1000000 */
5681 if (retnumeric)
5682 {
5683 Numeric result;
5684
5685 if (timestamp < (PG_INT64_MAX + epoch))
5687 else
5688 {
5691 NULL),
5692 int64_to_numeric(1000000),
5693 NULL);
5695 NumericGetDatum(result),
5696 Int32GetDatum(6)));
5697 }
5698 PG_RETURN_NUMERIC(result);
5699 }
5700 else
5701 {
5702 float8 result;
5703
5704 /* try to avoid precision loss in subtraction */
5705 if (timestamp < (PG_INT64_MAX + epoch))
5706 result = (timestamp - epoch) / 1000000.0;
5707 else
5708 result = ((float8) timestamp - epoch) / 1000000.0;
5709 PG_RETURN_FLOAT8(result);
5710 }
5711 break;
5712
5713 default:
5714 ereport(ERROR,
5716 errmsg("unit \"%s\" not supported for type %s",
5718 intresult = 0;
5719 }
5720 }
5721 else
5722 {
5723 ereport(ERROR,
5725 errmsg("unit \"%s\" not recognized for type %s",
5727 intresult = 0;
5728 }
5729
5730 if (retnumeric)
5732 else
5734}
5735
5736Datum
5738{
5739 return timestamp_part_common(fcinfo, false);
5740}
5741
5742Datum
5744{
5745 return timestamp_part_common(fcinfo, true);
5746}
5747
5748/* timestamptz_part() and extract_timestamptz()
5749 * Extract specified field from timestamp with time zone.
5750 */
5751static Datum
5753{
5758 int tz;
5759 int type,
5760 val;
5761 char *lowunits;
5762 fsec_t fsec;
5763 struct pg_tm tt,
5764 *tm = &tt;
5765
5768 false);
5769
5770 type = DecodeUnits(0, lowunits, &val);
5771 if (type == UNKNOWN_FIELD)
5773
5775 {
5778 true);
5779
5780 if (r != 0.0)
5781 {
5782 if (retnumeric)
5783 {
5784 if (r < 0)
5786 CStringGetDatum("-Infinity"),
5788 Int32GetDatum(-1));
5789 else if (r > 0)
5791 CStringGetDatum("Infinity"),
5793 Int32GetDatum(-1));
5794 }
5795 else
5797 }
5798 else
5800 }
5801
5802 if (type == UNITS)
5803 {
5804 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
5805 ereport(ERROR,
5807 errmsg("timestamp out of range")));
5808
5809 switch (val)
5810 {
5811 case DTK_TZ:
5812 intresult = -tz;
5813 break;
5814
5815 case DTK_TZ_MINUTE:
5817 break;
5818
5819 case DTK_TZ_HOUR:
5820 intresult = -tz / SECS_PER_HOUR;
5821 break;
5822
5823 case DTK_MICROSEC:
5824 intresult = tm->tm_sec * INT64CONST(1000000) + fsec;
5825 break;
5826
5827 case DTK_MILLISEC:
5828 if (retnumeric)
5829 /*---
5830 * tm->tm_sec * 1000 + fsec / 1000
5831 * = (tm->tm_sec * 1'000'000 + fsec) / 1000
5832 */
5834 else
5835 PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + fsec / 1000.0);
5836 break;
5837
5838 case DTK_SECOND:
5839 if (retnumeric)
5840 /*---
5841 * tm->tm_sec + fsec / 1'000'000
5842 * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
5843 */
5845 else
5846 PG_RETURN_FLOAT8(tm->tm_sec + fsec / 1000000.0);
5847 break;
5848
5849 case DTK_MINUTE:
5850 intresult = tm->tm_min;
5851 break;
5852
5853 case DTK_HOUR:
5854 intresult = tm->tm_hour;
5855 break;
5856
5857 case DTK_DAY:
5858 intresult = tm->tm_mday;
5859 break;
5860
5861 case DTK_MONTH:
5862 intresult = tm->tm_mon;
5863 break;
5864
5865 case DTK_QUARTER:
5866 intresult = (tm->tm_mon - 1) / 3 + 1;
5867 break;
5868
5869 case DTK_WEEK:
5871 break;
5872
5873 case DTK_YEAR:
5874 if (tm->tm_year > 0)
5875 intresult = tm->tm_year;
5876 else
5877 /* there is no year 0, just 1 BC and 1 AD */
5878 intresult = tm->tm_year - 1;
5879 break;
5880
5881 case DTK_DECADE:
5882 /* see comments in timestamp_part */
5883 if (tm->tm_year > 0)
5884 intresult = tm->tm_year / 10;
5885 else
5886 intresult = -((8 - (tm->tm_year - 1)) / 10);
5887 break;
5888
5889 case DTK_CENTURY:
5890 /* see comments in timestamp_part */
5891 if (tm->tm_year > 0)
5892 intresult = (tm->tm_year + 99) / 100;
5893 else
5894 intresult = -((99 - (tm->tm_year - 1)) / 100);
5895 break;
5896
5897 case DTK_MILLENNIUM:
5898 /* see comments in timestamp_part */
5899 if (tm->tm_year > 0)
5900 intresult = (tm->tm_year + 999) / 1000;
5901 else
5902 intresult = -((999 - (tm->tm_year - 1)) / 1000);
5903 break;
5904
5905 case DTK_JULIAN:
5906 if (retnumeric)
5910 NULL),
5911 NULL));
5912 else
5915 tm->tm_sec + (fsec / 1000000.0)) / (double) SECS_PER_DAY);
5916 break;
5917
5918 case DTK_ISOYEAR:
5920 /* Adjust BC years */
5921 if (intresult <= 0)
5922 intresult -= 1;
5923 break;
5924
5925 case DTK_DOW:
5926 case DTK_ISODOW:
5928 if (val == DTK_ISODOW && intresult == 0)
5929 intresult = 7;
5930 break;
5931
5932 case DTK_DOY:
5934 - date2j(tm->tm_year, 1, 1) + 1);
5935 break;
5936
5937 default:
5938 ereport(ERROR,
5940 errmsg("unit \"%s\" not supported for type %s",
5942 intresult = 0;
5943 }
5944 }
5945 else if (type == RESERV)
5946 {
5947 switch (val)
5948 {
5949 case DTK_EPOCH:
5951 /* (timestamp - epoch) / 1000000 */
5952 if (retnumeric)
5953 {
5954 Numeric result;
5955
5956 if (timestamp < (PG_INT64_MAX + epoch))
5958 else
5959 {
5962 NULL),
5963 int64_to_numeric(1000000),
5964 NULL);
5966 NumericGetDatum(result),
5967 Int32GetDatum(6)));
5968 }
5969 PG_RETURN_NUMERIC(result);
5970 }
5971 else
5972 {
5973 float8 result;
5974
5975 /* try to avoid precision loss in subtraction */
5976 if (timestamp < (PG_INT64_MAX + epoch))
5977 result = (timestamp - epoch) / 1000000.0;
5978 else
5979 result = ((float8) timestamp - epoch) / 1000000.0;
5980 PG_RETURN_FLOAT8(result);
5981 }
5982 break;
5983
5984 default:
5985 ereport(ERROR,
5987 errmsg("unit \"%s\" not supported for type %s",
5989 intresult = 0;
5990 }
5991 }
5992 else
5993 {
5994 ereport(ERROR,
5996 errmsg("unit \"%s\" not recognized for type %s",
5998
5999 intresult = 0;
6000 }
6001
6002 if (retnumeric)
6004 else
6006}
6007
6008Datum
6010{
6011 return timestamptz_part_common(fcinfo, false);
6012}
6013
6014Datum
6016{
6017 return timestamptz_part_common(fcinfo, true);
6018}
6019
6020/*
6021 * NonFiniteIntervalPart
6022 *
6023 * Used by interval_part when extracting from infinite interval. Returns
6024 * +/-Infinity if that is the appropriate result, otherwise returns zero
6025 * (which should be taken as meaning to return NULL).
6026 *
6027 * Errors thrown here for invalid units should exactly match those that
6028 * would be thrown in the calling functions, else there will be unexpected
6029 * discrepancies between finite- and infinite-input cases.
6030 */
6031static float8
6033{
6034 if ((type != UNITS) && (type != RESERV))
6035 ereport(ERROR,
6037 errmsg("unit \"%s\" not recognized for type %s",
6039
6040 switch (unit)
6041 {
6042 /* Oscillating units */
6043 case DTK_MICROSEC:
6044 case DTK_MILLISEC:
6045 case DTK_SECOND:
6046 case DTK_MINUTE:
6047 case DTK_WEEK:
6048 case DTK_MONTH:
6049 case DTK_QUARTER:
6050 return 0.0;
6051
6052 /* Monotonically-increasing units */
6053 case DTK_HOUR:
6054 case DTK_DAY:
6055 case DTK_YEAR:
6056 case DTK_DECADE:
6057 case DTK_CENTURY:
6058 case DTK_MILLENNIUM:
6059 case DTK_EPOCH:
6060 if (isNegative)
6061 return -get_float8_infinity();
6062 else
6063 return get_float8_infinity();
6064
6065 default:
6066 ereport(ERROR,
6068 errmsg("unit \"%s\" not supported for type %s",
6070 return 0.0; /* keep compiler quiet */
6071 }
6072}
6073
6074/* interval_part() and extract_interval()
6075 * Extract specified field from interval.
6076 */
6077static Datum
6079{
6083 int type,
6084 val;
6085 char *lowunits;
6086 struct pg_itm tt,
6087 *tm = &tt;
6088
6091 false);
6092
6093 type = DecodeUnits(0, lowunits, &val);
6094 if (type == UNKNOWN_FIELD)
6096
6098 {
6101
6102 if (r != 0.0)
6103 {
6104 if (retnumeric)
6105 {
6106 if (r < 0)
6108 CStringGetDatum("-Infinity"),
6110 Int32GetDatum(-1));
6111 else if (r > 0)
6113 CStringGetDatum("Infinity"),
6115 Int32GetDatum(-1));
6116 }
6117 else
6119 }
6120 else
6122 }
6123
6124 if (type == UNITS)
6125 {
6127 switch (val)
6128 {
6129 case DTK_MICROSEC:
6130 intresult = tm->tm_sec * INT64CONST(1000000) + tm->tm_usec;
6131 break;
6132
6133 case DTK_MILLISEC:
6134 if (retnumeric)
6135 /*---
6136 * tm->tm_sec * 1000 + fsec / 1000
6137 * = (tm->tm_sec * 1'000'000 + fsec) / 1000
6138 */
6140 else
6141 PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + tm->tm_usec / 1000.0);
6142 break;
6143
6144 case DTK_SECOND:
6145 if (retnumeric)
6146 /*---
6147 * tm->tm_sec + fsec / 1'000'000
6148 * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
6149 */
6151 else
6152 PG_RETURN_FLOAT8(tm->tm_sec + tm->tm_usec / 1000000.0);
6153 break;
6154
6155 case DTK_MINUTE:
6156 intresult = tm->tm_min;
6157 break;
6158
6159 case DTK_HOUR:
6160 intresult = tm->tm_hour;
6161 break;
6162
6163 case DTK_DAY:
6164 intresult = tm->tm_mday;
6165 break;
6166
6167 case DTK_WEEK:
6168 intresult = tm->tm_mday / 7;
6169 break;
6170
6171 case DTK_MONTH:
6172 intresult = tm->tm_mon;
6173 break;
6174
6175 case DTK_QUARTER:
6176
6177 /*
6178 * We want to maintain the rule that a field extracted from a
6179 * negative interval is the negative of the field's value for
6180 * the sign-reversed interval. The broken-down tm_year and
6181 * tm_mon aren't very helpful for that, so work from
6182 * interval->month.
6183 */
6184 if (interval->month >= 0)
6185 intresult = (tm->tm_mon / 3) + 1;
6186 else
6187 intresult = -(((-interval->month % MONTHS_PER_YEAR) / 3) + 1);
6188 break;
6189
6190 case DTK_YEAR:
6191 intresult = tm->tm_year;
6192 break;
6193
6194 case DTK_DECADE:
6195 /* caution: C division may have negative remainder */
6196 intresult = tm->tm_year / 10;
6197 break;
6198
6199 case DTK_CENTURY:
6200 /* caution: C division may have negative remainder */
6201 intresult = tm->tm_year / 100;
6202 break;
6203
6204 case DTK_MILLENNIUM:
6205 /* caution: C division may have negative remainder */
6206 intresult = tm->tm_year / 1000;
6207 break;
6208
6209 default:
6210 ereport(ERROR,
6212 errmsg("unit \"%s\" not supported for type %s",
6214 intresult = 0;
6215 }
6216 }
6217 else if (type == RESERV && val == DTK_EPOCH)
6218 {
6219 if (retnumeric)
6220 {
6221 Numeric result;
6223 int64 val;
6224
6225 /*
6226 * To do this calculation in integer arithmetic even though
6227 * DAYS_PER_YEAR is fractional, multiply everything by 4 and then
6228 * divide by 4 again at the end. This relies on DAYS_PER_YEAR
6229 * being a multiple of 0.25 and on SECS_PER_DAY being a multiple
6230 * of 4.
6231 */
6234 (int64) 4 * interval->day) * (SECS_PER_DAY / 4);
6235
6236 /*---
6237 * result = secs_from_day_month + interval->time / 1'000'000
6238 * = (secs_from_day_month * 1'000'000 + interval->time) / 1'000'000
6239 */
6240
6241 /*
6242 * Try the computation inside int64; if it overflows, do it in
6243 * numeric (slower). This overflow happens around 10^9 days, so
6244 * not common in practice.
6245 */
6246 if (!pg_mul_s64_overflow(secs_from_day_month, 1000000, &val) &&
6248 result = int64_div_fast_to_numeric(val, 6);
6249 else
6250 result =
6253 NULL);
6254
6255 PG_RETURN_NUMERIC(result);
6256 }
6257 else
6258 {
6259 float8 result;
6260
6261 result = interval->time / 1000000.0;
6264 result += ((double) SECS_PER_DAY) * interval->day;
6265
6266 PG_RETURN_FLOAT8(result);
6267 }
6268 }
6269 else
6270 {
6271 ereport(ERROR,
6273 errmsg("unit \"%s\" not recognized for type %s",
6275 intresult = 0;
6276 }
6277
6278 if (retnumeric)
6280 else
6282}
6283
6284Datum
6286{
6287 return interval_part_common(fcinfo, false);
6288}
6289
6290Datum
6292{
6293 return interval_part_common(fcinfo, true);
6294}
6295
6296
6297/* timestamp_zone()
6298 * Encode timestamp type with specified time zone.
6299 * This function is just timestamp2timestamptz() except instead of
6300 * shifting to the global timezone, we shift to the specified timezone.
6301 * This is different from the other AT TIME ZONE cases because instead
6302 * of shifting _to_ a new time zone, it sets the time to _be_ the
6303 * specified timezone.
6304 */
6305Datum
6307{
6310 TimestampTz result;
6311 int tz;
6312 char tzname[TZ_STRLEN_MAX + 1];
6313 int type,
6314 val;
6315 pg_tz *tzp;
6316 struct pg_tm tm;
6317 fsec_t fsec;
6318
6321
6322 /*
6323 * Look up the requested timezone.
6324 */
6326
6327 type = DecodeTimezoneName(tzname, &val, &tzp);
6328
6330 {
6331 /* fixed-offset abbreviation */
6332 tz = val;
6333 result = dt2local(timestamp, tz);
6334 }
6335 else if (type == TZNAME_DYNTZ)
6336 {
6337 /* dynamic-offset abbreviation, resolve using specified time */
6338 if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, tzp) != 0)
6339 ereport(ERROR,
6341 errmsg("timestamp out of range")));
6343 result = dt2local(timestamp, tz);
6344 }
6345 else
6346 {
6347 /* full zone name, rotate to that zone */
6348 if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, tzp) != 0)
6349 ereport(ERROR,
6351 errmsg("timestamp out of range")));
6352 tz = DetermineTimeZoneOffset(&tm, tzp);
6353 if (tm2timestamp(&tm, fsec, &tz, &result) != 0)
6354 ereport(ERROR,
6356 errmsg("timestamp out of range")));
6357 }
6358
6359 if (!IS_VALID_TIMESTAMP(result))
6360 ereport(ERROR,
6362 errmsg("timestamp out of range")));
6363
6364 PG_RETURN_TIMESTAMPTZ(result);
6365}
6366
6367/* timestamp_izone()
6368 * Encode timestamp type with specified time interval as time zone.
6369 */
6370Datum
6372{
6375 TimestampTz result;
6376 int tz;
6377
6380
6382 ereport(ERROR,
6384 errmsg("interval time zone \"%s\" must be finite",
6386 PointerGetDatum(zone))))));
6387
6388 if (zone->month != 0 || zone->day != 0)
6389 ereport(ERROR,
6391 errmsg("interval time zone \"%s\" must not include months or days",
6393 PointerGetDatum(zone))))));
6394
6395 tz = zone->time / USECS_PER_SEC;
6396
6397 result = dt2local(timestamp, tz);
6398
6399 if (!IS_VALID_TIMESTAMP(result))
6400 ereport(ERROR,
6402 errmsg("timestamp out of range")));
6403
6404 PG_RETURN_TIMESTAMPTZ(result);
6405} /* timestamp_izone() */
6406
6407/* TimestampTimestampTzRequiresRewrite()
6408 *
6409 * Returns false if the TimeZone GUC setting causes timestamp_timestamptz and
6410 * timestamptz_timestamp to be no-ops, where the return value has the same
6411 * bits as the argument. Since project convention is to assume a GUC changes
6412 * no more often than STABLE functions change, the answer is valid that long.
6413 */
6414bool
6416{
6417 long offset;
6418
6419 if (pg_get_timezone_offset(session_timezone, &offset) && offset == 0)
6420 return false;
6421 return true;
6422}
6423
6424/* timestamp_timestamptz()
6425 * Convert local timestamp to timestamp at GMT
6426 */
6427Datum
6434
6435/*
6436 * Convert timestamp to timestamp with time zone.
6437 *
6438 * If the timestamp is finite but out of the valid range for timestamptz,
6439 * error handling proceeds based on escontext.
6440 *
6441 * If escontext is NULL, we throw an out-of-range error (hard error).
6442 * If escontext is not NULL, we return NOBEGIN or NOEND for lower bound or
6443 * upper bound overflow, respectively, and record a soft error.
6444 */
6447{
6448 TimestampTz result;
6449 struct pg_tm tt,
6450 *tm = &tt;
6451 fsec_t fsec;
6452 int tz;
6453
6455 return timestamp;
6456
6457 /* timestamp2tm should not fail on valid timestamps, but cope */
6458 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) == 0)
6459 {
6461
6462 result = dt2local(timestamp, -tz);
6463
6464 if (IS_VALID_TIMESTAMP(result))
6465 return result;
6466 }
6467
6468 if (timestamp < 0)
6469 TIMESTAMP_NOBEGIN(result);
6470 else
6471 TIMESTAMP_NOEND(result);
6472
6473 ereturn(escontext, result,
6475 errmsg("timestamp out of range")));
6476}
6477
6478/*
6479 * Promote timestamp to timestamptz, throwing error for overflow.
6480 */
6481static TimestampTz
6486
6487/* timestamptz_timestamp()
6488 * Convert timestamp at GMT to local timestamp
6489 */
6490Datum
6497
6498/*
6499 * Convert timestamptz to timestamp, throwing error for overflow.
6500 */
6501static Timestamp
6506
6507/*
6508 * Convert timestamp with time zone to timestamp.
6509 *
6510 * If the timestamptz is finite but out of the valid range for timestamp,
6511 * error handling proceeds based on escontext.
6512 *
6513 * If escontext is NULL, we throw an out-of-range error (hard error).
6514 * If escontext is not NULL, we return NOBEGIN or NOEND for lower bound or
6515 * upper bound overflow, respectively, and record a soft error.
6516 */
6519{
6520 Timestamp result;
6521 struct pg_tm tt,
6522 *tm = &tt;
6523 fsec_t fsec;
6524 int tz;
6525
6527 result = timestamp;
6528 else
6529 {
6530 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
6531 {
6532 if (timestamp < 0)
6533 TIMESTAMP_NOBEGIN(result);
6534 else
6535 TIMESTAMP_NOEND(result);
6536
6537 ereturn(escontext, result,
6539 errmsg("timestamp out of range")));
6540 }
6541 if (tm2timestamp(tm, fsec, NULL, &result) != 0)
6542 {
6543 if (timestamp < 0)
6544 TIMESTAMP_NOBEGIN(result);
6545 else
6546 TIMESTAMP_NOEND(result);
6547
6548 ereturn(escontext, result,
6550 errmsg("timestamp out of range")));
6551 }
6552 }
6553 return result;
6554}
6555
6556/* timestamptz_zone()
6557 * Evaluate timestamp with time zone type at the specified time zone.
6558 * Returns a timestamp without time zone.
6559 */
6560Datum
6562{
6565 Timestamp result;
6566 int tz;
6567 char tzname[TZ_STRLEN_MAX + 1];
6568 int type,
6569 val;
6570 pg_tz *tzp;
6571
6574
6575 /*
6576 * Look up the requested timezone.
6577 */
6579
6580 type = DecodeTimezoneName(tzname, &val, &tzp);
6581
6583 {
6584 /* fixed-offset abbreviation */
6585 tz = -val;
6586 result = dt2local(timestamp, tz);
6587 }
6588 else if (type == TZNAME_DYNTZ)
6589 {
6590 /* dynamic-offset abbreviation, resolve using specified time */
6591 int isdst;
6592
6594 result = dt2local(timestamp, tz);
6595 }
6596 else
6597 {
6598 /* full zone name, rotate from that zone */
6599 struct pg_tm tm;
6600 fsec_t fsec;
6601
6602 if (timestamp2tm(timestamp, &tz, &tm, &fsec, NULL, tzp) != 0)
6603 ereport(ERROR,
6605 errmsg("timestamp out of range")));
6606 if (tm2timestamp(&tm, fsec, NULL, &result) != 0)
6607 ereport(ERROR,
6609 errmsg("timestamp out of range")));
6610 }
6611
6612 if (!IS_VALID_TIMESTAMP(result))
6613 ereport(ERROR,
6615 errmsg("timestamp out of range")));
6616
6617 PG_RETURN_TIMESTAMP(result);
6618}
6619
6620/* timestamptz_izone()
6621 * Encode timestamp with time zone type with specified time interval as time zone.
6622 * Returns a timestamp without time zone.
6623 */
6624Datum
6626{
6629 Timestamp result;
6630 int tz;
6631
6634
6636 ereport(ERROR,
6638 errmsg("interval time zone \"%s\" must be finite",
6640 PointerGetDatum(zone))))));
6641
6642 if (zone->month != 0 || zone->day != 0)
6643 ereport(ERROR,
6645 errmsg("interval time zone \"%s\" must not include months or days",
6647 PointerGetDatum(zone))))));
6648
6649 tz = -(zone->time / USECS_PER_SEC);
6650
6651 result = dt2local(timestamp, tz);
6652
6653 if (!IS_VALID_TIMESTAMP(result))
6654 ereport(ERROR,
6656 errmsg("timestamp out of range")));
6657
6658 PG_RETURN_TIMESTAMP(result);
6659}
6660
6661/* generate_series_timestamp()
6662 * Generate the set of timestamps from start to finish by step
6663 */
6664Datum
6666{
6669 Timestamp result;
6670
6671 /* stuff done only on the first call of the function */
6672 if (SRF_IS_FIRSTCALL())
6673 {
6675 Timestamp finish = PG_GETARG_TIMESTAMP(1);
6676 Interval *step = PG_GETARG_INTERVAL_P(2);
6677 MemoryContext oldcontext;
6678
6679 /* create a function context for cross-call persistence */
6681
6682 /*
6683 * switch to memory context appropriate for multiple function calls
6684 */
6685 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
6686
6687 /* allocate memory for user context */
6689
6690 /*
6691 * Use fctx to keep state from call to call. Seed current with the
6692 * original start value
6693 */
6694 fctx->current = start;
6695 fctx->finish = finish;
6696 fctx->step = *step;
6697
6698 /* Determine sign of the interval */
6699 fctx->step_sign = interval_sign(&fctx->step);
6700
6701 if (fctx->step_sign == 0)
6702 ereport(ERROR,
6704 errmsg("step size cannot equal zero")));
6705
6706 if (INTERVAL_NOT_FINITE((&fctx->step)))
6707 ereport(ERROR,
6709 errmsg("step size cannot be infinite")));
6710
6711 funcctx->user_fctx = fctx;
6712 MemoryContextSwitchTo(oldcontext);
6713 }
6714
6715 /* stuff done on every call of the function */
6717
6718 /*
6719 * get the saved state and use current as the result for this iteration
6720 */
6721 fctx = funcctx->user_fctx;
6722 result = fctx->current;
6723
6724 if (fctx->step_sign > 0 ?
6725 timestamp_cmp_internal(result, fctx->finish) <= 0 :
6726 timestamp_cmp_internal(result, fctx->finish) >= 0)
6727 {
6728 /* increment current in preparation for next iteration */
6730 TimestampGetDatum(fctx->current),
6731 PointerGetDatum(&fctx->step)));
6732
6733 /* do when there is more left to send */
6735 }
6736 else
6737 {
6738 /* do when there is no more left */
6740 }
6741}
6742
6743/* generate_series_timestamptz()
6744 * Generate the set of timestamps from start to finish by step,
6745 * doing arithmetic in the specified or session timezone.
6746 */
6747static Datum
6749{
6752 TimestampTz result;
6753
6754 /* stuff done only on the first call of the function */
6755 if (SRF_IS_FIRSTCALL())
6756 {
6759 Interval *step = PG_GETARG_INTERVAL_P(2);
6760 text *zone = (PG_NARGS() == 4) ? PG_GETARG_TEXT_PP(3) : NULL;
6761 MemoryContext oldcontext;
6762
6763 /* create a function context for cross-call persistence */
6765
6766 /*
6767 * switch to memory context appropriate for multiple function calls
6768 */
6769 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
6770
6771 /* allocate memory for user context */
6773
6774 /*
6775 * Use fctx to keep state from call to call. Seed current with the
6776 * original start value
6777 */
6778 fctx->current = start;
6779 fctx->finish = finish;
6780 fctx->step = *step;
6781 fctx->attimezone = zone ? lookup_timezone(zone) : session_timezone;
6782
6783 /* Determine sign of the interval */
6784 fctx->step_sign = interval_sign(&fctx->step);
6785
6786 if (fctx->step_sign == 0)
6787 ereport(ERROR,
6789 errmsg("step size cannot equal zero")));
6790
6791 if (INTERVAL_NOT_FINITE((&fctx->step)))
6792 ereport(ERROR,
6794 errmsg("step size cannot be infinite")));
6795
6796 funcctx->user_fctx = fctx;
6797 MemoryContextSwitchTo(oldcontext);
6798 }
6799
6800 /* stuff done on every call of the function */
6802
6803 /*
6804 * get the saved state and use current as the result for this iteration
6805 */
6806 fctx = funcctx->user_fctx;
6807 result = fctx->current;
6808
6809 if (fctx->step_sign > 0 ?
6810 timestamp_cmp_internal(result, fctx->finish) <= 0 :
6811 timestamp_cmp_internal(result, fctx->finish) >= 0)
6812 {
6813 /* increment current in preparation for next iteration */
6814 fctx->current = timestamptz_pl_interval_internal(fctx->current,
6815 &fctx->step,
6816 fctx->attimezone);
6817
6818 /* do when there is more left to send */
6820 }
6821 else
6822 {
6823 /* do when there is no more left */
6825 }
6826}
6827
6828Datum
6833
6834Datum
6839
6840/*
6841 * Planner support function for generate_series(timestamp, timestamp, interval)
6842 */
6843Datum
6845{
6847 Node *ret = NULL;
6848
6850 {
6851 /* Try to estimate the number of rows returned */
6853
6854 if (is_funcclause(req->node)) /* be paranoid */
6855 {
6856 List *args = ((FuncExpr *) req->node)->args;
6857 Node *arg1,
6858 *arg2,
6859 *arg3;
6860
6861 /* We can use estimated argument values here */
6863 arg2 = estimate_expression_value(req->root, lsecond(args));
6864 arg3 = estimate_expression_value(req->root, lthird(args));
6865
6866 /*
6867 * If any argument is constant NULL, we can safely assume that
6868 * zero rows are returned. Otherwise, if they're all non-NULL
6869 * constants, we can calculate the number of rows that will be
6870 * returned.
6871 */
6872 if ((IsA(arg1, Const) && ((Const *) arg1)->constisnull) ||
6873 (IsA(arg2, Const) && ((Const *) arg2)->constisnull) ||
6874 (IsA(arg3, Const) && ((Const *) arg3)->constisnull))
6875 {
6876 req->rows = 0;
6877 ret = (Node *) req;
6878 }
6879 else if (IsA(arg1, Const) && IsA(arg2, Const) && IsA(arg3, Const))
6880 {
6882 finish;
6883 Interval *step;
6884 Datum diff;
6885 double dstep;
6886 int64 dummy;
6887
6889 finish = DatumGetTimestamp(((Const *) arg2)->constvalue);
6890 step = DatumGetIntervalP(((Const *) arg3)->constvalue);
6891
6892 /*
6893 * Perform some prechecks which could cause timestamp_mi to
6894 * raise an ERROR. It's much better to just return some
6895 * default estimate than error out in a support function.
6896 */
6898 !pg_sub_s64_overflow(finish, start, &dummy))
6899 {
6901 TimestampGetDatum(finish),
6903
6904#define INTERVAL_TO_MICROSECONDS(i) ((((double) (i)->month * DAYS_PER_MONTH + (i)->day)) * USECS_PER_DAY + (i)->time)
6905
6907
6908 /* This equation works for either sign of step */
6909 if (dstep != 0.0)
6910 {
6913
6914 req->rows = floor(ddiff / dstep + 1.0);
6915 ret = (Node *) req;
6916 }
6917#undef INTERVAL_TO_MICROSECONDS
6918 }
6919 }
6920 }
6921 }
6922
6923 PG_RETURN_POINTER(ret);
6924}
6925
6926
6927/* timestamp_at_local()
6928 * timestamptz_at_local()
6929 *
6930 * The regression tests do not like two functions with the same proargs and
6931 * prosrc but different proname, but the grammar for AT LOCAL needs an
6932 * overloaded name to handle both types of timestamp, so we make simple
6933 * wrappers for it.
6934 */
6935Datum
6940
6941Datum
#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:75
Node * TemporalSimplify(int32 max_precis, Node *node)
Definition datetime.c:4962
pg_tz * DecodeTimezoneNameToTz(const char *tzname)
Definition datetime.c:3343
int DetermineTimeZoneAbbrevOffsetTS(TimestampTz ts, const char *abbr, pg_tz *tzp, int *isdst)
Definition datetime.c:1803
int DecodeUnits(int field, const char *lowtoken, int *val)
Definition datetime.c:4169
int j2day(int date)
Definition datetime.c:354
int ParseDateTime(const char *timestr, char *workbuf, size_t buflen, char **field, int *ftype, int maxfields, int *numfields)
Definition datetime.c:773
void EncodeInterval(struct pg_itm *itm, int style, char *str)
Definition datetime.c:4707
int DetermineTimeZoneOffset(struct pg_tm *tm, pg_tz *tzp)
Definition datetime.c:1604
void DateTimeParseError(int dterr, DateTimeErrorExtra *extra, const char *str, const char *datatype, Node *escontext)
Definition datetime.c:4214
int DecodeInterval(char **field, int *ftype, int nf, int range, int *dtype, struct pg_itm_in *itm_in)
Definition datetime.c:3486
int DecodeISO8601Interval(char *str, int *dtype, struct pg_itm_in *itm_in)
Definition datetime.c:3951
int ValidateDate(int fmask, bool isjulian, bool is2digits, bool bc, struct pg_tm *tm)
Definition datetime.c:2561
int DecodeSpecial(int field, const char *lowtoken, int *val)
Definition datetime.c:3246
void j2date(int jd, int *year, int *month, int *day)
Definition datetime.c:321
void EncodeDateTime(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str)
Definition datetime.c:4464
int DecodeTimezone(const char *str, int *tzp)
Definition datetime.c:3057
const char *const months[]
Definition datetime.c:81
int DecodeDateTime(char **field, int *ftype, int nf, int *dtype, struct pg_tm *tm, fsec_t *fsec, int *tzp, DateTimeErrorExtra *extra)
Definition datetime.c:997
int date2j(int year, int month, int day)
Definition datetime.c:296
const char *const days[]
Definition datetime.c:84
int DecodeTimezoneName(const char *tzname, int *offset, pg_tz **tz)
Definition datetime.c:3288
int DetermineTimeZoneAbbrevOffset(struct pg_tm *tm, const char *abbr, pg_tz *tzp)
Definition datetime.c:1765
Datum numeric_round(PG_FUNCTION_ARGS)
Definition numeric.c:1526
Numeric int64_to_numeric(int64 val)
Definition numeric.c:4259
Numeric numeric_add_safe(Numeric num1, Numeric num2, Node *escontext)
Definition numeric.c:2881
Numeric int64_div_fast_to_numeric(int64 val1, int log10val2)
Definition numeric.c:4280
Numeric numeric_div_safe(Numeric num1, Numeric num2, Node *escontext)
Definition numeric.c:3152
Numeric numeric_sub_safe(Numeric num1, Numeric num2, Node *escontext)
Definition numeric.c:2957
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:1881
Datum interval_out(PG_FUNCTION_ARGS)
Definition timestamp.c:971
Datum interval_justify_hours(PG_FUNCTION_ARGS)
Definition timestamp.c:2999
Datum make_timestamptz_at_timezone(PG_FUNCTION_ARGS)
Definition timestamp.c:684
int timestamp_cmp_internal(Timestamp dt1, Timestamp dt2)
Definition timestamp.c:2208
long TimestampDifferenceMilliseconds(TimestampTz start_time, TimestampTz stop_time)
Definition timestamp.c:1755
void isoweek2date(int woy, int *year, int *mon, int *mday)
Definition timestamp.c:5262
Datum in_range_timestamp_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3874
void GetEpochTime(struct pg_tm *tm)
Definition timestamp.c:2166
Datum generate_series_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:6829
static float8 NonFiniteTimestampTzPart(int type, int unit, char *lowunits, bool isNegative, bool isTz)
Definition timestamp.c:5422
static INT128 interval_cmp_value(const Interval *interval)
Definition timestamp.c:2522
Datum interval_trunc(PG_FUNCTION_ARGS)
Definition timestamp.c:5110
Datum overlaps_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:2670
Datum extract_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:5743
Datum timestamptypmodout(PG_FUNCTION_ARGS)
Definition timestamp.c:310
Datum interval_gt(PG_FUNCTION_ARGS)
Definition timestamp.c:2589
Datum interval_avg_accum(PG_FUNCTION_ARGS)
Definition timestamp.c:4041
int itmin2interval(struct pg_itm_in *itm_in, Interval *span)
Definition timestamp.c:2113
Datum interval_justify_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:2919
static void finite_interval_mi(const Interval *span1, const Interval *span2, Interval *result)
Definition timestamp.c:3542
Datum timestamptz_part(PG_FUNCTION_ARGS)
Definition timestamp.c:6009
int isoweek2j(int year, int week)
Definition timestamp.c:5242
Datum clock_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:1619
Datum timestamptz_pl_interval_at_zone(PG_FUNCTION_ARGS)
Definition timestamp.c:3399
Datum timestamp_pl_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3088
Datum interval_le(PG_FUNCTION_ARGS)
Definition timestamp.c:2598
Datum interval_avg_serialize(PG_FUNCTION_ARGS)
Definition timestamp.c:4107
Datum interval_mi(PG_FUNCTION_ARGS)
Definition timestamp.c:3557
TimestampTz time_t_to_timestamptz(pg_time_t tm)
Definition timestamp.c:1818
Datum timestamp_le_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:2421
Datum interval_lt(PG_FUNCTION_ARGS)
Definition timestamp.c:2580
Datum timestamp_larger(PG_FUNCTION_ARGS)
Definition timestamp.c:2810
static Datum timestamptz_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition timestamp.c:5752
Datum timestamptz_izone(PG_FUNCTION_ARGS)
Definition timestamp.c:6625
Datum timestamp_cmp_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:2439
static bool AdjustIntervalForTypmod(Interval *interval, int32 typmod, Node *escontext)
Definition timestamp.c:1348
Datum timestamp_part(PG_FUNCTION_ARGS)
Definition timestamp.c:5737
Datum timestamptz_eq_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:2448
Datum interval_hash(PG_FUNCTION_ARGS)
Definition timestamp.c:2632
Datum timestamptztypmodout(PG_FUNCTION_ARGS)
Definition timestamp.c:855
int date2isoweek(int year, int mon, int mday)
Definition timestamp.c:5293
Datum timestamptz_pl_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3378
Datum timestamp_cmp(PG_FUNCTION_ARGS)
Definition timestamp.c:2268
static TimestampTz timestamptz_trunc_internal(text *units, TimestampTz timestamp, pg_tz *tzp)
Definition timestamp.c:4895
Datum timestamp_bin(PG_FUNCTION_ARGS)
Definition timestamp.c:4586
Datum timestamp_zone(PG_FUNCTION_ARGS)
Definition timestamp.c:6306
static pg_tz * lookup_timezone(text *zone)
Definition timestamp.c:558
static TimestampTz timestamp2timestamptz(Timestamp timestamp)
Definition timestamp.c:6482
Datum interval_finite(PG_FUNCTION_ARGS)
Definition timestamp.c:2153
Timestamp SetEpochTimestamp(void)
Definition timestamp.c:2188
Datum timestamptz_ne_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:2457
Datum timestamptz_lt_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:2466
Datum timestamp_sortsupport(PG_FUNCTION_ARGS)
Definition timestamp.c:2277
Datum timestamp_mi_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3205
Datum timestamptypmodin(PG_FUNCTION_ARGS)
Definition timestamp.c:302
bool AdjustTimestampForTypmod(Timestamp *time, int32 typmod, Node *escontext)
Definition timestamp.c:366
Datum timestamptz_ge_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:2493
Datum timestamp_smaller(PG_FUNCTION_ARGS)
Definition timestamp.c:2795
Datum interval_justify_days(PG_FUNCTION_ARGS)
Definition timestamp.c:3041
TimestampTz timestamp2timestamptz_safe(Timestamp timestamp, Node *escontext)
Definition timestamp.c:6446
Datum timestamp_ge(PG_FUNCTION_ARGS)
Definition timestamp.c:2259
Datum interval_avg_accum_inv(PG_FUNCTION_ARGS)
Definition timestamp.c:4188
Datum generate_series_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:6665
int date2isoyearday(int year, int mon, int mday)
Definition timestamp.c:5405
int tm2timestamp(struct pg_tm *tm, fsec_t fsec, int *tzp, Timestamp *result)
Definition timestamp.c:2004
Datum timestamptz_cmp_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:2502
Datum timestamp_ge_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:2430
static Timestamp timestamptz2timestamp(TimestampTz timestamp)
Definition timestamp.c:6502
void TimestampDifference(TimestampTz start_time, TimestampTz stop_time, long *secs, int *microsecs)
Definition timestamp.c:1719
static void do_interval_accum(IntervalAggState *state, Interval *newval)
Definition timestamp.c:3987
Datum timestamp_scale(PG_FUNCTION_ARGS)
Definition timestamp.c:345
Datum timestamptz_scale(PG_FUNCTION_ARGS)
Definition timestamp.c:868
Datum make_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:663
bool TimestampDifferenceExceedsSeconds(TimestampTz start_time, TimestampTz stop_time, int threshold_sec)
Definition timestamp.c:1793
bool TimestampTimestampTzRequiresRewrite(void)
Definition timestamp.c:6415
Datum timestamp_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:6428
Datum timestamp_recv(PG_FUNCTION_ARGS)
Definition timestamp.c:258
Datum timestamp_lt(PG_FUNCTION_ARGS)
Definition timestamp.c:2232
Datum timestamptz_trunc(PG_FUNCTION_ARGS)
Definition timestamp.c:5073
Datum timestamptz_zone(PG_FUNCTION_ARGS)
Definition timestamp.c:6561
static void finite_interval_pl(const Interval *span1, const Interval *span2, Interval *result)
Definition timestamp.c:3486
void isoweekdate2date(int isoweek, int wday, int *year, int *mon, int *mday)
Definition timestamp.c:5275
int32 timestamp_cmp_timestamptz_internal(Timestamp timestampVal, TimestampTz dt2)
Definition timestamp.c:2361
Datum timestamptz_gt_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:2475
Datum timestamptz_hash_extended(PG_FUNCTION_ARGS)
Definition timestamp.c:2351
bool TimestampDifferenceExceeds(TimestampTz start_time, TimestampTz stop_time, int msec)
Definition timestamp.c:1779
static int32 anytimestamp_typmodin(bool istz, ArrayType *ta)
Definition timestamp.c:102
Datum generate_series_timestamp_support(PG_FUNCTION_ARGS)
Definition timestamp.c:6844
Datum interval_cmp(PG_FUNCTION_ARGS)
Definition timestamp.c:2616
Datum interval_sum(PG_FUNCTION_ARGS)
Definition timestamp.c:4246
Datum timestamp_hash_extended(PG_FUNCTION_ARGS)
Definition timestamp.c:2339
Datum timestamptz_le_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:2484
Datum interval_pl(PG_FUNCTION_ARGS)
Definition timestamp.c:3501
Datum interval_um(PG_FUNCTION_ARGS)
Definition timestamp.c:3444
Datum timestamp_skipsupport(PG_FUNCTION_ARGS)
Definition timestamp.c:2320
static float8 NonFiniteIntervalPart(int type, int unit, char *lowunits, bool isNegative)
Definition timestamp.c:6032
void EncodeSpecialTimestamp(Timestamp dt, char *str)
Definition timestamp.c:1585
Datum make_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:1528
static char * anytimestamp_typmodout(bool istz, int32 typmod)
Definition timestamp.c:145
Datum interval_ge(PG_FUNCTION_ARGS)
Definition timestamp.c:2607
static Timestamp make_timestamp_internal(int year, int month, int day, int hour, int min, double sec)
Definition timestamp.c:572
Datum timestamp_gt_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:2412
Datum timestamp_in(PG_FUNCTION_ARGS)
Definition timestamp.c:164
Datum timestamp_le(PG_FUNCTION_ARGS)
Definition timestamp.c:2250
Datum interval_ne(PG_FUNCTION_ARGS)
Definition timestamp.c:2571
Datum timestamptz_hash(PG_FUNCTION_ARGS)
Definition timestamp.c:2345
Datum interval_in(PG_FUNCTION_ARGS)
Definition timestamp.c:889
static Timestamp dt2local(Timestamp dt, int timezone)
Definition timestamp.c:2132
static Datum interval_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition timestamp.c:6078
TimestampTz PgReloadTime
Definition timestamp.c:55
Datum timestamp_ne_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:2394
Datum interval_hash_extended(PG_FUNCTION_ARGS)
Definition timestamp.c:2650
Datum timestamptz_mi_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3387
Datum timestamp_age(PG_FUNCTION_ARGS)
Definition timestamp.c:4286
Datum interval_smaller(PG_FUNCTION_ARGS)
Definition timestamp.c:3457
static void EncodeSpecialInterval(const Interval *interval, char *str)
Definition timestamp.c:1596
Datum timestamptz_mi_interval_at_zone(PG_FUNCTION_ARGS)
Definition timestamp.c:3410
int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
Definition timestamp.c:1908
Datum interval_support(PG_FUNCTION_ARGS)
Definition timestamp.c:1263
Datum timestamptz_in(PG_FUNCTION_ARGS)
Definition timestamp.c:416
static int intervaltypmodleastfield(int32 typmod)
Definition timestamp.c:1210
int32 anytimestamp_typmod_check(bool istz, int32 typmod)
Definition timestamp.c:123
Datum extract_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:6015
Datum pg_postmaster_start_time(PG_FUNCTION_ARGS)
Definition timestamp.c:1625
TimestampTz GetCurrentTimestamp(void)
Definition timestamp.c:1643
static TimeOffset time2t(const int hour, const int min, const int sec, const fsec_t fsec)
Definition timestamp.c:2126
Datum interval_part(PG_FUNCTION_ARGS)
Definition timestamp.c:6285
Datum pg_conf_load_time(PG_FUNCTION_ARGS)
Definition timestamp.c:1631
Datum in_range_interval_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3915
#define IA_TOTAL_COUNT(ia)
Definition timestamp.c:87
const char * timestamptz_to_str(TimestampTz t)
Definition timestamp.c:1860
Datum interval_eq(PG_FUNCTION_ARGS)
Definition timestamp.c:2562
static Datum timestamp_increment(Relation rel, Datum existing, bool *overflow)
Definition timestamp.c:2304
Timestamp GetSQLLocalTimestamp(int32 typmod)
Definition timestamp.c:1675
Datum timestamp_finite(PG_FUNCTION_ARGS)
Definition timestamp.c:2145
static TimestampTz timestamptz_mi_interval_internal(TimestampTz timestamp, Interval *span, pg_tz *attimezone)
Definition timestamp.c:3363
Datum timestamp_trunc(PG_FUNCTION_ARGS)
Definition timestamp.c:4657
Datum mul_d_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3726
Datum timestamptztypmodin(PG_FUNCTION_ARGS)
Definition timestamp.c:847
Datum interval_avg(PG_FUNCTION_ARGS)
Definition timestamp.c:4206
TimestampTz PgStartTime
Definition timestamp.c:52
Datum timestamp_send(PG_FUNCTION_ARGS)
Definition timestamp.c:291
Datum timestamptz_send(PG_FUNCTION_ARGS)
Definition timestamp.c:836
Datum timestamptz_recv(PG_FUNCTION_ARGS)
Definition timestamp.c:802
Datum interval_scale(PG_FUNCTION_ARGS)
Definition timestamp.c:1326
static Datum timestamp_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition timestamp.c:5479
Datum interval_larger(PG_FUNCTION_ARGS)
Definition timestamp.c:3472
Datum timestamp_gt(PG_FUNCTION_ARGS)
Definition timestamp.c:2241
static IntervalAggState * makeIntervalAggState(FunctionCallInfo fcinfo)
Definition timestamp.c:3965
Datum timestamptz_bin(PG_FUNCTION_ARGS)
Definition timestamp.c:4821
Datum timestamptz_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:6491
Datum timestamp_mi(PG_FUNCTION_ARGS)
Definition timestamp.c:2825
Datum timestamptz_at_local(PG_FUNCTION_ARGS)
Definition timestamp.c:6942
Datum interval_send(PG_FUNCTION_ARGS)
Definition timestamp.c:1020
Datum intervaltypmodin(PG_FUNCTION_ARGS)
Definition timestamp.c:1045
#define TIMESTAMP_GT(t1, t2)
Datum timestamp_lt_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:2403
Datum timestamptz_out(PG_FUNCTION_ARGS)
Definition timestamp.c:774
static void interval_um_internal(const Interval *interval, Interval *result)
Definition timestamp.c:3424
Datum timestamp_hash(PG_FUNCTION_ARGS)
Definition timestamp.c:2333
Datum timestamp_out(PG_FUNCTION_ARGS)
Definition timestamp.c:232
Datum timestamp_support(PG_FUNCTION_ARGS)
Definition timestamp.c:325
void interval2itm(Interval span, struct pg_itm *itm)
Definition timestamp.c:2045
Datum float8_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:724
Datum now(PG_FUNCTION_ARGS)
Definition timestamp.c:1607
Datum interval_avg_deserialize(PG_FUNCTION_ARGS)
Definition timestamp.c:4145
Datum timestamp_ne(PG_FUNCTION_ARGS)
Definition timestamp.c:2223
static int interval_cmp_internal(const Interval *interval1, const Interval *interval2)
Definition timestamp.c:2544
Datum interval_recv(PG_FUNCTION_ARGS)
Definition timestamp.c:995
#define INTERVAL_TO_MICROSECONDS(i)
Datum statement_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:1613
Datum timestamptz_age(PG_FUNCTION_ARGS)
Definition timestamp.c:4432
Datum interval_mul(PG_FUNCTION_ARGS)
Definition timestamp.c:3606
Datum interval_div(PG_FUNCTION_ARGS)
Definition timestamp.c:3736
Datum timestamptz_trunc_zone(PG_FUNCTION_ARGS)
Definition timestamp.c:5088
Datum timestamp_eq_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:2385
static TimestampTz timestamptz_pl_interval_internal(TimestampTz timestamp, Interval *span, pg_tz *attimezone)
Definition timestamp.c:3231
static Datum generate_series_timestamptz_internal(FunctionCallInfo fcinfo)
Definition timestamp.c:6748
int itm2interval(struct pg_itm *itm, Interval *span)
Definition timestamp.c:2075
pg_time_t timestamptz_to_time_t(TimestampTz t)
Definition timestamp.c:1840
Datum make_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:643
Datum intervaltypmodout(PG_FUNCTION_ARGS)
Definition timestamp.c:1124
static int interval_sign(const Interval *interval)
Definition timestamp.c:2553
static void do_interval_discard(IntervalAggState *state, Interval *newval)
Definition timestamp.c:4010
Datum timeofday(PG_FUNCTION_ARGS)
Definition timestamp.c:1689
Datum generate_series_timestamptz_at_zone(PG_FUNCTION_ARGS)
Definition timestamp.c:6835
int date2isoyear(int year, int mon, int mday)
Definition timestamp.c:5348
Timestamp timestamptz2timestamp_safe(TimestampTz timestamp, Node *escontext)
Definition timestamp.c:6518
Datum timestamp_izone(PG_FUNCTION_ARGS)
Definition timestamp.c:6371
static Datum timestamp_decrement(Relation rel, Datum existing, bool *underflow)
Definition timestamp.c:2287
static int parse_sane_timezone(struct pg_tm *tm, text *zone)
Definition timestamp.c:489
Datum timestamp_at_local(PG_FUNCTION_ARGS)
Definition timestamp.c:6936
TimestampTz GetSQLCurrentTimestamp(int32 typmod)
Definition timestamp.c:1661
Datum in_range_timestamptz_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3837
Datum interval_avg_combine(PG_FUNCTION_ARGS)
Definition timestamp.c:4064
Datum extract_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:6291
Datum timestamp_eq(PG_FUNCTION_ARGS)
Definition timestamp.c:2214
#define TIMESTAMP_LT(t1, t2)
#define INT64CONST(x)
Definition c.h:593
#define FLOAT8_FITS_IN_INT32(num)
Definition c.h:1140
#define Assert(condition)
Definition c.h:906
int64_t int64
Definition c.h:576
double float8
Definition c.h:677
#define FLOAT8_FITS_IN_INT64(num)
Definition c.h:1142
int32_t int32
Definition c.h:575
#define PG_INT64_MAX
Definition c.h:639
#define PG_INT64_MIN
Definition c.h:638
#define unlikely(x)
Definition c.h:424
#define pg_fallthrough
Definition c.h:144
Node * estimate_expression_value(PlannerInfo *root, Node *node)
Definition clauses.c:2408
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:1547
int errcode(int sqlerrcode)
Definition elog.c:874
int errmsg(const char *fmt,...)
Definition elog.c:1093
#define ereturn(context, dummy_value,...)
Definition elog.h:278
int errhint(const char *fmt,...) pg_attribute_printf(1
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define WARNING
Definition elog.h:36
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define ereport(elevel,...)
Definition elog.h:150
#define palloc_object(type)
Definition fe_memutils.h:74
#define palloc0_object(type)
Definition fe_memutils.h:75
static float8 float8_mul(const float8 val1, const float8 val2)
Definition float.h:163
static float8 get_float8_infinity(void)
Definition float.h:65
#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:686
#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:684
#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:688
#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:125
int IntervalStyle
Definition globals.c:127
#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:248
#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:285
#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:282
#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:271
#define DTK_DOY
Definition datetime.h:176
#define DTK_TZ
Definition datetime.h:146
#define TZNAME_FIXED_OFFSET
Definition datetime.h:299
#define TZNAME_DYNTZ
Definition datetime.h:300
#define DTERR_TZDISP_OVERFLOW
Definition datetime.h:286
#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:283
#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 struct pg_tm tm
Definition localtime.c:104
char * pstrdup(const char *in)
Definition mcxt.c:1781
void * palloc(Size size)
Definition mcxt.c:1387
#define USE_ISO_DATES
Definition miscadmin.h:237
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition nodeAgg.c:4607
int32 exprTypmod(const Node *expr)
Definition nodeFuncs.c:301
Node * relabel_to_typmod(Node *expr, int32 typmod)
Definition nodeFuncs.c:689
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 MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:124
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:1966
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:128
struct pg_tm * pg_localtime(const pg_time_t *timep, const pg_tz *tz)
Definition localtime.c:1345
struct pg_tm * pg_gmtime(const pg_time_t *timep)
Definition localtime.c:1390
long date
Definition pgtypes_date.h:9
int64 timestamp
#define snprintf
Definition port.h:260
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition strlcpy.c:45
#define Int64GetDatumFast(X)
Definition postgres.h:535
static Datum PointerGetDatum(const void *X)
Definition postgres.h:352
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:262
static char * DatumGetCString(Datum X)
Definition postgres.h:365
uint64_t Datum
Definition postgres.h:70
static Datum Float8GetDatum(float8 X)
Definition postgres.h:512
static Datum CStringGetDatum(const char *X)
Definition postgres.h:380
static Datum Int32GetDatum(int32 X)
Definition postgres.h:222
static int32 DatumGetInt32(Datum X)
Definition postgres.h:212
#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 SortSupportData * SortSupport
Definition sortsupport.h:58
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:81
int32 day
Definition timestamp.h:51
int32 month
Definition timestamp.h:52
TimeOffset time
Definition timestamp.h:49
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 lexi.c:60
Definition c.h:739
Definition zic.c:99
int ssup_datum_signed_cmp(Datum x, Datum y, SortSupport ssup)
Definition tuplesort.c:3422
#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:182
void text_to_cstring_buffer(const text *src, char *dst, size_t dst_len)
Definition varlena.c:246
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