PostgreSQL Source Code git master
Loading...
Searching...
No Matches
timestamp.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * timestamp.c
4 * Functions for the built-in SQL types "timestamp" and "interval".
5 *
6 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/backend/utils/adt/timestamp.c
12 *
13 *-------------------------------------------------------------------------
14 */
15
16#include "postgres.h"
17
18#include <ctype.h>
19#include <math.h>
20#include <limits.h>
21#include <sys/time.h>
22
23#include "access/xact.h"
24#include "catalog/pg_type.h"
25#include "common/int.h"
26#include "common/int128.h"
27#include "funcapi.h"
28#include "libpq/pqformat.h"
29#include "miscadmin.h"
30#include "nodes/nodeFuncs.h"
31#include "nodes/supportnodes.h"
32#include "optimizer/optimizer.h"
33#include "parser/scansup.h"
34#include "utils/array.h"
35#include "utils/builtins.h"
36#include "utils/date.h"
37#include "utils/datetime.h"
38#include "utils/float.h"
39#include "utils/numeric.h"
40#include "utils/skipsupport.h"
41#include "utils/sortsupport.h"
42
43
44/* Set at postmaster start */
46
47/* Set at configuration reload */
49
57
66
67/*
68 * The transition datatype for interval aggregates is declared as internal.
69 * It's a pointer to an IntervalAggState allocated in the aggregate context.
70 */
71typedef struct IntervalAggState
72{
73 int64 N; /* count of finite intervals processed */
74 Interval sumX; /* sum of finite intervals processed */
75 /* These counts are *not* included in N! Use IA_TOTAL_COUNT() as needed */
76 int64 pInfcount; /* count of +infinity intervals */
77 int64 nInfcount; /* count of -infinity intervals */
79
80#define IA_TOTAL_COUNT(ia) \
81 ((ia)->N + (ia)->pInfcount + (ia)->nInfcount)
82
83static TimeOffset time2t(const int hour, const int min, const int sec, const fsec_t fsec);
86 Node *escontext);
89
90static void EncodeSpecialInterval(const Interval *interval, char *str);
91static void interval_um_internal(const Interval *interval, Interval *result);
92
93/* common code for timestamptypmodin and timestamptztypmodin */
94static int32
96{
97 int32 *tl;
98 int n;
99
101
102 /*
103 * we're not too tense about good error message here because grammar
104 * shouldn't allow wrong number of modifiers for TIMESTAMP
105 */
106 if (n != 1)
109 errmsg("invalid type modifier")));
110
112}
113
114/* exported so parse_expr.c can use it */
115int32
117{
118 if (typmod < 0)
121 errmsg("TIMESTAMP(%d)%s precision must not be negative",
122 typmod, (istz ? " WITH TIME ZONE" : ""))));
123 if (typmod > MAX_TIMESTAMP_PRECISION)
124 {
127 errmsg("TIMESTAMP(%d)%s precision reduced to maximum allowed, %d",
128 typmod, (istz ? " WITH TIME ZONE" : ""),
131 }
132
133 return typmod;
134}
135
136/* common code for timestamptypmodout and timestamptztypmodout */
137static char *
139{
140 const char *tz = istz ? " with time zone" : " without time zone";
141
142 if (typmod >= 0)
143 return psprintf("(%d)%s", (int) typmod, tz);
144 else
145 return pstrdup(tz);
146}
147
148
149/*****************************************************************************
150 * USER I/O ROUTINES *
151 *****************************************************************************/
152
153/* timestamp_in()
154 * Convert a string to internal form.
155 */
156Datum
158{
159 char *str = PG_GETARG_CSTRING(0);
160#ifdef NOT_USED
161 Oid typelem = PG_GETARG_OID(1);
162#endif
163 int32 typmod = PG_GETARG_INT32(2);
164 Node *escontext = fcinfo->context;
165 Timestamp result;
166 fsec_t fsec;
167 struct pg_tm tt,
168 *tm = &tt;
169 int tz;
170 int dtype;
171 int nf;
172 int dterr;
173 char *field[MAXDATEFIELDS];
174 int ftype[MAXDATEFIELDS];
176 DateTimeErrorExtra extra;
177
179 field, ftype, MAXDATEFIELDS, &nf);
180 if (dterr == 0)
181 dterr = DecodeDateTime(field, ftype, nf,
182 &dtype, tm, &fsec, &tz, &extra);
183 if (dterr != 0)
184 {
185 DateTimeParseError(dterr, &extra, str, "timestamp", escontext);
187 }
188
189 switch (dtype)
190 {
191 case DTK_DATE:
192 if (tm2timestamp(tm, fsec, NULL, &result) != 0)
193 ereturn(escontext, (Datum) 0,
195 errmsg("timestamp out of range: \"%s\"", str)));
196 break;
197
198 case DTK_EPOCH:
199 result = SetEpochTimestamp();
200 break;
201
202 case DTK_LATE:
203 TIMESTAMP_NOEND(result);
204 break;
205
206 case DTK_EARLY:
207 TIMESTAMP_NOBEGIN(result);
208 break;
209
210 default:
211 elog(ERROR, "unexpected dtype %d while parsing timestamp \"%s\"",
212 dtype, str);
213 TIMESTAMP_NOEND(result);
214 }
215
216 AdjustTimestampForTypmod(&result, typmod, escontext);
217
218 PG_RETURN_TIMESTAMP(result);
219}
220
221/* timestamp_out()
222 * Convert a timestamp to external form.
223 */
224Datum
226{
228 char *result;
229 struct pg_tm tt,
230 *tm = &tt;
231 fsec_t fsec;
232 char buf[MAXDATELEN + 1];
233
236 else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) == 0)
237 EncodeDateTime(tm, fsec, false, 0, NULL, DateStyle, buf);
238 else
241 errmsg("timestamp out of range")));
242
243 result = pstrdup(buf);
244 PG_RETURN_CSTRING(result);
245}
246
247/*
248 * timestamp_recv - converts external binary format to timestamp
249 */
250Datum
252{
254
255#ifdef NOT_USED
256 Oid typelem = PG_GETARG_OID(1);
257#endif
258 int32 typmod = PG_GETARG_INT32(2);
260 struct pg_tm tt,
261 *tm = &tt;
262 fsec_t fsec;
263
265
266 /* range check: see if timestamp_out would like it */
268 /* ok */ ;
269 else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0 ||
273 errmsg("timestamp out of range")));
274
276
278}
279
280/*
281 * timestamp_send - converts timestamp to binary format
282 */
283Datum
293
294Datum
301
302Datum
309
310
311/*
312 * timestamp_support()
313 *
314 * Planner support function for the timestamp_scale() and timestamptz_scale()
315 * length coercion functions (we need not distinguish them here).
316 */
317Datum
332
333/* timestamp_scale()
334 * Adjust time type for specified scale factor.
335 * Used by PostgreSQL type system to stuff columns.
336 */
337Datum
339{
341 int32 typmod = PG_GETARG_INT32(1);
342 Timestamp result;
343
344 result = timestamp;
345
346 if (!AdjustTimestampForTypmod(&result, typmod, fcinfo->context))
348
349 PG_RETURN_TIMESTAMP(result);
350}
351
352/*
353 * AdjustTimestampForTypmod --- round off a timestamp to suit given typmod
354 * Works for either timestamp or timestamptz.
355 *
356 * Returns true on success, false on failure (if escontext points to an
357 * ErrorSaveContext; otherwise errors are thrown).
358 */
359bool
361{
362 static const int64 TimestampScales[MAX_TIMESTAMP_PRECISION + 1] = {
363 INT64CONST(1000000),
364 INT64CONST(100000),
365 INT64CONST(10000),
366 INT64CONST(1000),
367 INT64CONST(100),
368 INT64CONST(10),
369 INT64CONST(1)
370 };
371
373 INT64CONST(500000),
374 INT64CONST(50000),
375 INT64CONST(5000),
376 INT64CONST(500),
377 INT64CONST(50),
378 INT64CONST(5),
379 INT64CONST(0)
380 };
381
382 if (!TIMESTAMP_NOT_FINITE(*time)
383 && (typmod != -1) && (typmod != MAX_TIMESTAMP_PRECISION))
384 {
386 ereturn(escontext, false,
388 errmsg("timestamp(%d) precision must be between %d and %d",
389 typmod, 0, MAX_TIMESTAMP_PRECISION)));
390
391 if (*time >= INT64CONST(0))
392 {
393 *time = ((*time + TimestampOffsets[typmod]) / TimestampScales[typmod]) *
394 TimestampScales[typmod];
395 }
396 else
397 {
398 *time = -((((-*time) + TimestampOffsets[typmod]) / TimestampScales[typmod])
399 * TimestampScales[typmod]);
400 }
401 }
402
403 return true;
404}
405
406/* timestamptz_in()
407 * Convert a string to internal form.
408 */
409Datum
411{
412 char *str = PG_GETARG_CSTRING(0);
413#ifdef NOT_USED
414 Oid typelem = PG_GETARG_OID(1);
415#endif
416 int32 typmod = PG_GETARG_INT32(2);
417 Node *escontext = fcinfo->context;
418 TimestampTz result;
419 fsec_t fsec;
420 struct pg_tm tt,
421 *tm = &tt;
422 int tz;
423 int dtype;
424 int nf;
425 int dterr;
426 char *field[MAXDATEFIELDS];
427 int ftype[MAXDATEFIELDS];
429 DateTimeErrorExtra extra;
430
432 field, ftype, MAXDATEFIELDS, &nf);
433 if (dterr == 0)
434 dterr = DecodeDateTime(field, ftype, nf,
435 &dtype, tm, &fsec, &tz, &extra);
436 if (dterr != 0)
437 {
438 DateTimeParseError(dterr, &extra, str, "timestamp with time zone",
439 escontext);
441 }
442
443 switch (dtype)
444 {
445 case DTK_DATE:
446 if (tm2timestamp(tm, fsec, &tz, &result) != 0)
447 ereturn(escontext, (Datum) 0,
449 errmsg("timestamp out of range: \"%s\"", str)));
450 break;
451
452 case DTK_EPOCH:
453 result = SetEpochTimestamp();
454 break;
455
456 case DTK_LATE:
457 TIMESTAMP_NOEND(result);
458 break;
459
460 case DTK_EARLY:
461 TIMESTAMP_NOBEGIN(result);
462 break;
463
464 default:
465 elog(ERROR, "unexpected dtype %d while parsing timestamptz \"%s\"",
466 dtype, str);
467 TIMESTAMP_NOEND(result);
468 }
469
470 AdjustTimestampForTypmod(&result, typmod, escontext);
471
472 PG_RETURN_TIMESTAMPTZ(result);
473}
474
475/*
476 * Try to parse a timezone specification, and return its timezone offset value
477 * if it's acceptable. Otherwise, an error is thrown.
478 *
479 * Note: some code paths update tm->tm_isdst, and some don't; current callers
480 * don't care, so we don't bother being consistent.
481 */
482static int
484{
485 char tzname[TZ_STRLEN_MAX + 1];
486 int dterr;
487 int tz;
488
490
491 /*
492 * Look up the requested timezone. First we try to interpret it as a
493 * numeric timezone specification; if DecodeTimezone decides it doesn't
494 * like the format, we try timezone abbreviations and names.
495 *
496 * Note pg_tzset happily parses numeric input that DecodeTimezone would
497 * reject. To avoid having it accept input that would otherwise be seen
498 * as invalid, it's enough to disallow having a digit in the first
499 * position of our input string.
500 */
501 if (isdigit((unsigned char) *tzname))
504 errmsg("invalid input syntax for type %s: \"%s\"",
505 "numeric time zone", tzname),
506 errhint("Numeric time zones must have \"-\" or \"+\" as first character.")));
507
509 if (dterr != 0)
510 {
511 int type,
512 val;
513 pg_tz *tzp;
514
518 errmsg("numeric time zone \"%s\" out of range", tzname)));
519 else if (dterr != DTERR_BAD_FORMAT)
522 errmsg("time zone \"%s\" not recognized", tzname)));
523
525
527 {
528 /* fixed-offset abbreviation */
529 tz = -val;
530 }
531 else if (type == TZNAME_DYNTZ)
532 {
533 /* dynamic-offset abbreviation, resolve using specified time */
535 }
536 else
537 {
538 /* full zone name */
539 tz = DetermineTimeZoneOffset(tm, tzp);
540 }
541 }
542
543 return tz;
544}
545
546/*
547 * Look up the requested timezone, returning a pg_tz struct.
548 *
549 * This is the same as DecodeTimezoneNameToTz, but starting with a text Datum.
550 */
551static pg_tz *
553{
554 char tzname[TZ_STRLEN_MAX + 1];
555
557
559}
560
561/*
562 * make_timestamp_internal
563 * workhorse for make_timestamp and make_timestamptz
564 */
565static Timestamp
566make_timestamp_internal(int year, int month, int day,
567 int hour, int min, double sec)
568{
569 struct pg_tm tm;
571 TimeOffset time;
572 int dterr;
573 bool bc = false;
574 Timestamp result;
575
576 tm.tm_year = year;
577 tm.tm_mon = month;
578 tm.tm_mday = day;
579
580 /* Handle negative years as BC */
581 if (tm.tm_year < 0)
582 {
583 bc = true;
584 tm.tm_year = -tm.tm_year;
585 }
586
587 dterr = ValidateDate(DTK_DATE_M, false, false, bc, &tm);
588
589 if (dterr != 0)
592 errmsg("date field value out of range: %d-%02d-%02d",
593 year, month, day)));
594
598 errmsg("date out of range: %d-%02d-%02d",
599 year, month, day)));
600
602
603 /* Check for time overflow */
604 if (float_time_overflows(hour, min, sec))
607 errmsg("time field value out of range: %d:%02d:%02g",
608 hour, min, sec)));
609
610 /* This should match tm2time */
611 time = (((hour * MINS_PER_HOUR + min) * SECS_PER_MINUTE)
613
615 pg_add_s64_overflow(result, time, &result)))
618 errmsg("timestamp out of range: %d-%02d-%02d %d:%02d:%02g",
619 year, month, day,
620 hour, min, sec)));
621
622 /* final range check catches just-out-of-range timestamps */
623 if (!IS_VALID_TIMESTAMP(result))
626 errmsg("timestamp out of range: %d-%02d-%02d %d:%02d:%02g",
627 year, month, day,
628 hour, min, sec)));
629
630 return result;
631}
632
633/*
634 * make_timestamp() - timestamp constructor
635 */
636Datum
638{
639 int32 year = PG_GETARG_INT32(0);
640 int32 month = PG_GETARG_INT32(1);
643 int32 min = PG_GETARG_INT32(4);
644 float8 sec = PG_GETARG_FLOAT8(5);
645 Timestamp result;
646
647 result = make_timestamp_internal(year, month, mday,
648 hour, min, sec);
649
650 PG_RETURN_TIMESTAMP(result);
651}
652
653/*
654 * make_timestamptz() - timestamp with time zone constructor
655 */
656Datum
658{
659 int32 year = PG_GETARG_INT32(0);
660 int32 month = PG_GETARG_INT32(1);
663 int32 min = PG_GETARG_INT32(4);
664 float8 sec = PG_GETARG_FLOAT8(5);
665 Timestamp result;
666
667 result = make_timestamp_internal(year, month, mday,
668 hour, min, sec);
669
671}
672
673/*
674 * Construct a timestamp with time zone.
675 * As above, but the time zone is specified as seventh argument.
676 */
677Datum
679{
680 int32 year = PG_GETARG_INT32(0);
681 int32 month = PG_GETARG_INT32(1);
684 int32 min = PG_GETARG_INT32(4);
685 float8 sec = PG_GETARG_FLOAT8(5);
687 TimestampTz result;
689 struct pg_tm tt;
690 int tz;
691 fsec_t fsec;
692
694 hour, min, sec);
695
696 if (timestamp2tm(timestamp, NULL, &tt, &fsec, NULL, NULL) != 0)
699 errmsg("timestamp out of range")));
700
702
703 result = dt2local(timestamp, -tz);
704
705 if (!IS_VALID_TIMESTAMP(result))
708 errmsg("timestamp out of range")));
709
710 PG_RETURN_TIMESTAMPTZ(result);
711}
712
713/*
714 * to_timestamp(double precision)
715 * Convert UNIX epoch to timestamptz.
716 */
717Datum
719{
721 TimestampTz result;
722
723 /* Deal with NaN and infinite inputs ... */
724 if (isnan(seconds))
727 errmsg("timestamp cannot be NaN")));
728
729 if (isinf(seconds))
730 {
731 if (seconds < 0)
732 TIMESTAMP_NOBEGIN(result);
733 else
734 TIMESTAMP_NOEND(result);
735 }
736 else
737 {
738 /* Out of range? */
739 if (seconds <
741 || seconds >=
745 errmsg("timestamp out of range: \"%g\"", seconds)));
746
747 /* Convert UNIX epoch to Postgres epoch */
749
751 result = (int64) seconds;
752
753 /* Recheck in case roundoff produces something just out of range */
754 if (!IS_VALID_TIMESTAMP(result))
757 errmsg("timestamp out of range: \"%g\"",
758 PG_GETARG_FLOAT8(0))));
759 }
760
761 PG_RETURN_TIMESTAMP(result);
762}
763
764/* timestamptz_out()
765 * Convert a timestamp to external form.
766 */
767Datum
769{
771 char *result;
772 int tz;
773 struct pg_tm tt,
774 *tm = &tt;
775 fsec_t fsec;
776 const char *tzn;
777 char buf[MAXDATELEN + 1];
778
781 else if (timestamp2tm(dt, &tz, tm, &fsec, &tzn, NULL) == 0)
782 EncodeDateTime(tm, fsec, true, tz, tzn, DateStyle, buf);
783 else
786 errmsg("timestamp out of range")));
787
788 result = pstrdup(buf);
789 PG_RETURN_CSTRING(result);
790}
791
792/*
793 * timestamptz_recv - converts external binary format to timestamptz
794 */
795Datum
797{
799
800#ifdef NOT_USED
801 Oid typelem = PG_GETARG_OID(1);
802#endif
803 int32 typmod = PG_GETARG_INT32(2);
805 int tz;
806 struct pg_tm tt,
807 *tm = &tt;
808 fsec_t fsec;
809
811
812 /* range check: see if timestamptz_out would like it */
814 /* ok */ ;
815 else if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0 ||
819 errmsg("timestamp out of range")));
820
822
824}
825
826/*
827 * timestamptz_send - converts timestamptz to binary format
828 */
829Datum
839
840Datum
847
848Datum
855
856
857/* timestamptz_scale()
858 * Adjust time type for specified scale factor.
859 * Used by PostgreSQL type system to stuff columns.
860 */
861Datum
863{
865 int32 typmod = PG_GETARG_INT32(1);
866 TimestampTz result;
867
868 result = timestamp;
869
870 if (!AdjustTimestampForTypmod(&result, typmod, fcinfo->context))
872
873 PG_RETURN_TIMESTAMPTZ(result);
874}
875
876
877/* interval_in()
878 * Convert a string to internal form.
879 *
880 * External format(s):
881 * Uses the generic date/time parsing and decoding routines.
882 */
883Datum
885{
886 char *str = PG_GETARG_CSTRING(0);
887#ifdef NOT_USED
888 Oid typelem = PG_GETARG_OID(1);
889#endif
890 int32 typmod = PG_GETARG_INT32(2);
891 Node *escontext = fcinfo->context;
892 Interval *result;
893 struct pg_itm_in tt,
894 *itm_in = &tt;
895 int dtype;
896 int nf;
897 int range;
898 int dterr;
899 char *field[MAXDATEFIELDS];
900 int ftype[MAXDATEFIELDS];
901 char workbuf[256];
902 DateTimeErrorExtra extra;
903
904 itm_in->tm_year = 0;
905 itm_in->tm_mon = 0;
906 itm_in->tm_mday = 0;
907 itm_in->tm_usec = 0;
908
909 if (typmod >= 0)
910 range = INTERVAL_RANGE(typmod);
911 else
913
914 dterr = ParseDateTime(str, workbuf, sizeof(workbuf), field,
915 ftype, MAXDATEFIELDS, &nf);
916 if (dterr == 0)
917 dterr = DecodeInterval(field, ftype, nf, range,
918 &dtype, itm_in);
919
920 /* if those functions think it's a bad format, try ISO8601 style */
921 if (dterr == DTERR_BAD_FORMAT)
923 &dtype, itm_in);
924
925 if (dterr != 0)
926 {
929 DateTimeParseError(dterr, &extra, str, "interval", escontext);
931 }
932
933 result = palloc_object(Interval);
934
935 switch (dtype)
936 {
937 case DTK_DELTA:
938 if (itmin2interval(itm_in, result) != 0)
939 ereturn(escontext, (Datum) 0,
941 errmsg("interval out of range")));
942 break;
943
944 case DTK_LATE:
945 INTERVAL_NOEND(result);
946 break;
947
948 case DTK_EARLY:
949 INTERVAL_NOBEGIN(result);
950 break;
951
952 default:
953 elog(ERROR, "unexpected dtype %d while parsing interval \"%s\"",
954 dtype, str);
955 }
956
957 AdjustIntervalForTypmod(result, typmod, escontext);
958
959 PG_RETURN_INTERVAL_P(result);
960}
961
962/* interval_out()
963 * Convert a time span to external form.
964 */
965Datum
967{
969 char *result;
970 struct pg_itm tt,
971 *itm = &tt;
972 char buf[MAXDATELEN + 1];
973
976 else
977 {
980 }
981
982 result = pstrdup(buf);
983 PG_RETURN_CSTRING(result);
984}
985
986/*
987 * interval_recv - converts external binary format to interval
988 */
989Datum
991{
993
994#ifdef NOT_USED
995 Oid typelem = PG_GETARG_OID(1);
996#endif
997 int32 typmod = PG_GETARG_INT32(2);
999
1001
1003 interval->day = pq_getmsgint(buf, sizeof(interval->day));
1005
1007
1009}
1010
1011/*
1012 * interval_send - converts interval to binary format
1013 */
1014Datum
1026
1027/*
1028 * The interval typmod stores a "range" in its high 16 bits and a "precision"
1029 * in its low 16 bits. Both contribute to defining the resolution of the
1030 * type. Range addresses resolution granules larger than one second, and
1031 * precision specifies resolution below one second. This representation can
1032 * express all SQL standard resolutions, but we implement them all in terms of
1033 * truncating rightward from some position. Range is a bitmap of permitted
1034 * fields, but only the temporally-smallest such field is significant to our
1035 * calculations. Precision is a count of sub-second decimal places to retain.
1036 * Setting all bits (INTERVAL_FULL_PRECISION) gives the same truncation
1037 * semantics as choosing MAX_INTERVAL_PRECISION.
1038 */
1039Datum
1041{
1043 int32 *tl;
1044 int n;
1045 int32 typmod;
1046
1048
1049 /*
1050 * tl[0] - interval range (fields bitmask) tl[1] - precision (optional)
1051 *
1052 * Note we must validate tl[0] even though it's normally guaranteed
1053 * correct by the grammar --- consider SELECT 'foo'::"interval"(1000).
1054 */
1055 if (n > 0)
1056 {
1057 switch (tl[0])
1058 {
1059 case INTERVAL_MASK(YEAR):
1060 case INTERVAL_MASK(MONTH):
1061 case INTERVAL_MASK(DAY):
1062 case INTERVAL_MASK(HOUR):
1063 case INTERVAL_MASK(MINUTE):
1064 case INTERVAL_MASK(SECOND):
1073 /* all OK */
1074 break;
1075 default:
1076 ereport(ERROR,
1078 errmsg("invalid INTERVAL type modifier")));
1079 }
1080 }
1081
1082 if (n == 1)
1083 {
1084 if (tl[0] != INTERVAL_FULL_RANGE)
1086 else
1087 typmod = -1;
1088 }
1089 else if (n == 2)
1090 {
1091 if (tl[1] < 0)
1092 ereport(ERROR,
1094 errmsg("INTERVAL(%d) precision must not be negative",
1095 tl[1])));
1096 if (tl[1] > MAX_INTERVAL_PRECISION)
1097 {
1100 errmsg("INTERVAL(%d) precision reduced to maximum allowed, %d",
1103 }
1104 else
1105 typmod = INTERVAL_TYPMOD(tl[1], tl[0]);
1106 }
1107 else
1108 {
1109 ereport(ERROR,
1111 errmsg("invalid INTERVAL type modifier")));
1112 typmod = 0; /* keep compiler quiet */
1113 }
1114
1115 PG_RETURN_INT32(typmod);
1116}
1117
1118Datum
1120{
1121 int32 typmod = PG_GETARG_INT32(0);
1122 char *res = (char *) palloc(64);
1123 int fields;
1124 int precision;
1125 const char *fieldstr;
1126
1127 if (typmod < 0)
1128 {
1129 *res = '\0';
1130 PG_RETURN_CSTRING(res);
1131 }
1132
1133 fields = INTERVAL_RANGE(typmod);
1134 precision = INTERVAL_PRECISION(typmod);
1135
1136 switch (fields)
1137 {
1138 case INTERVAL_MASK(YEAR):
1139 fieldstr = " year";
1140 break;
1141 case INTERVAL_MASK(MONTH):
1142 fieldstr = " month";
1143 break;
1144 case INTERVAL_MASK(DAY):
1145 fieldstr = " day";
1146 break;
1147 case INTERVAL_MASK(HOUR):
1148 fieldstr = " hour";
1149 break;
1150 case INTERVAL_MASK(MINUTE):
1151 fieldstr = " minute";
1152 break;
1153 case INTERVAL_MASK(SECOND):
1154 fieldstr = " second";
1155 break;
1157 fieldstr = " year to month";
1158 break;
1160 fieldstr = " day to hour";
1161 break;
1163 fieldstr = " day to minute";
1164 break;
1166 fieldstr = " day to second";
1167 break;
1169 fieldstr = " hour to minute";
1170 break;
1172 fieldstr = " hour to second";
1173 break;
1175 fieldstr = " minute to second";
1176 break;
1178 fieldstr = "";
1179 break;
1180 default:
1181 elog(ERROR, "invalid INTERVAL typmod: 0x%x", typmod);
1182 fieldstr = "";
1183 break;
1184 }
1185
1186 if (precision != INTERVAL_FULL_PRECISION)
1187 snprintf(res, 64, "%s(%d)", fieldstr, precision);
1188 else
1189 snprintf(res, 64, "%s", fieldstr);
1190
1191 PG_RETURN_CSTRING(res);
1192}
1193
1194/*
1195 * Given an interval typmod value, return a code for the least-significant
1196 * field that the typmod allows to be nonzero, for instance given
1197 * INTERVAL DAY TO HOUR we want to identify "hour".
1198 *
1199 * The results should be ordered by field significance, which means
1200 * we can't use the dt.h macros YEAR etc, because for some odd reason
1201 * they aren't ordered that way. Instead, arbitrarily represent
1202 * SECOND = 0, MINUTE = 1, HOUR = 2, DAY = 3, MONTH = 4, YEAR = 5.
1203 */
1204static int
1206{
1207 if (typmod < 0)
1208 return 0; /* SECOND */
1209
1210 switch (INTERVAL_RANGE(typmod))
1211 {
1212 case INTERVAL_MASK(YEAR):
1213 return 5; /* YEAR */
1214 case INTERVAL_MASK(MONTH):
1215 return 4; /* MONTH */
1216 case INTERVAL_MASK(DAY):
1217 return 3; /* DAY */
1218 case INTERVAL_MASK(HOUR):
1219 return 2; /* HOUR */
1220 case INTERVAL_MASK(MINUTE):
1221 return 1; /* MINUTE */
1222 case INTERVAL_MASK(SECOND):
1223 return 0; /* SECOND */
1225 return 4; /* MONTH */
1227 return 2; /* HOUR */
1229 return 1; /* MINUTE */
1231 return 0; /* SECOND */
1233 return 1; /* MINUTE */
1235 return 0; /* SECOND */
1237 return 0; /* SECOND */
1239 return 0; /* SECOND */
1240 default:
1241 elog(ERROR, "invalid INTERVAL typmod: 0x%x", typmod);
1242 break;
1243 }
1244 return 0; /* can't get here, but keep compiler quiet */
1245}
1246
1247
1248/*
1249 * interval_support()
1250 *
1251 * Planner support function for interval_scale().
1252 *
1253 * Flatten superfluous calls to interval_scale(). The interval typmod is
1254 * complex to permit accepting and regurgitating all SQL standard variations.
1255 * For truncation purposes, it boils down to a single, simple granularity.
1256 */
1257Datum
1259{
1261 Node *ret = NULL;
1262
1264 {
1266 FuncExpr *expr = req->fcall;
1267 Node *typmod;
1268
1269 Assert(list_length(expr->args) >= 2);
1270
1271 typmod = (Node *) lsecond(expr->args);
1272
1273 if (IsA(typmod, Const) && !((Const *) typmod)->constisnull)
1274 {
1275 Node *source = (Node *) linitial(expr->args);
1277 bool noop;
1278
1279 if (new_typmod < 0)
1280 noop = true;
1281 else
1282 {
1284 int old_least_field;
1285 int new_least_field;
1286 int old_precis;
1287 int new_precis;
1288
1291 if (old_typmod < 0)
1293 else
1296
1297 /*
1298 * Cast is a no-op if least field stays the same or decreases
1299 * while precision stays the same or increases. But
1300 * precision, which is to say, sub-second precision, only
1301 * affects ranges that include SECOND.
1302 */
1304 (old_least_field > 0 /* SECOND */ ||
1307 }
1308 if (noop)
1310 }
1311 }
1312
1313 PG_RETURN_POINTER(ret);
1314}
1315
1316/* interval_scale()
1317 * Adjust interval type for specified fields.
1318 * Used by PostgreSQL type system to stuff columns.
1319 */
1320Datum
1322{
1324 int32 typmod = PG_GETARG_INT32(1);
1325 Interval *result;
1326
1327 result = palloc_object(Interval);
1328 *result = *interval;
1329
1330 if (!AdjustIntervalForTypmod(result, typmod, fcinfo->context))
1332
1333 PG_RETURN_INTERVAL_P(result);
1334}
1335
1336/*
1337 * Adjust interval for specified precision, in both YEAR to SECOND
1338 * range and sub-second precision.
1339 *
1340 * Returns true on success, false on failure (if escontext points to an
1341 * ErrorSaveContext; otherwise errors are thrown).
1342 */
1343static bool
1345 Node *escontext)
1346{
1347 static const int64 IntervalScales[MAX_INTERVAL_PRECISION + 1] = {
1348 INT64CONST(1000000),
1349 INT64CONST(100000),
1350 INT64CONST(10000),
1351 INT64CONST(1000),
1352 INT64CONST(100),
1353 INT64CONST(10),
1354 INT64CONST(1)
1355 };
1356
1357 static const int64 IntervalOffsets[MAX_INTERVAL_PRECISION + 1] = {
1358 INT64CONST(500000),
1359 INT64CONST(50000),
1360 INT64CONST(5000),
1361 INT64CONST(500),
1362 INT64CONST(50),
1363 INT64CONST(5),
1364 INT64CONST(0)
1365 };
1366
1367 /* Typmod has no effect on infinite intervals */
1369 return true;
1370
1371 /*
1372 * Unspecified range and precision? Then not necessary to adjust. Setting
1373 * typmod to -1 is the convention for all data types.
1374 */
1375 if (typmod >= 0)
1376 {
1377 int range = INTERVAL_RANGE(typmod);
1378 int precision = INTERVAL_PRECISION(typmod);
1379
1380 /*
1381 * Our interpretation of intervals with a limited set of fields is
1382 * that fields to the right of the last one specified are zeroed out,
1383 * but those to the left of it remain valid. Thus for example there
1384 * is no operational difference between INTERVAL YEAR TO MONTH and
1385 * INTERVAL MONTH. In some cases we could meaningfully enforce that
1386 * higher-order fields are zero; for example INTERVAL DAY could reject
1387 * nonzero "month" field. However that seems a bit pointless when we
1388 * can't do it consistently. (We cannot enforce a range limit on the
1389 * highest expected field, since we do not have any equivalent of
1390 * SQL's <interval leading field precision>.) If we ever decide to
1391 * revisit this, interval_support will likely require adjusting.
1392 *
1393 * Note: before PG 8.4 we interpreted a limited set of fields as
1394 * actually causing a "modulo" operation on a given value, potentially
1395 * losing high-order as well as low-order information. But there is
1396 * no support for such behavior in the standard, and it seems fairly
1397 * undesirable on data consistency grounds anyway. Now we only
1398 * perform truncation or rounding of low-order fields.
1399 */
1401 {
1402 /* Do nothing... */
1403 }
1404 else if (range == INTERVAL_MASK(YEAR))
1405 {
1407 interval->day = 0;
1408 interval->time = 0;
1409 }
1410 else if (range == INTERVAL_MASK(MONTH))
1411 {
1412 interval->day = 0;
1413 interval->time = 0;
1414 }
1415 /* YEAR TO MONTH */
1416 else if (range == (INTERVAL_MASK(YEAR) | INTERVAL_MASK(MONTH)))
1417 {
1418 interval->day = 0;
1419 interval->time = 0;
1420 }
1421 else if (range == INTERVAL_MASK(DAY))
1422 {
1423 interval->time = 0;
1424 }
1425 else if (range == INTERVAL_MASK(HOUR))
1426 {
1429 }
1430 else if (range == INTERVAL_MASK(MINUTE))
1431 {
1434 }
1435 else if (range == INTERVAL_MASK(SECOND))
1436 {
1437 /* fractional-second rounding will be dealt with below */
1438 }
1439 /* DAY TO HOUR */
1440 else if (range == (INTERVAL_MASK(DAY) |
1442 {
1445 }
1446 /* DAY TO MINUTE */
1447 else if (range == (INTERVAL_MASK(DAY) |
1450 {
1453 }
1454 /* DAY TO SECOND */
1455 else if (range == (INTERVAL_MASK(DAY) |
1459 {
1460 /* fractional-second rounding will be dealt with below */
1461 }
1462 /* HOUR TO MINUTE */
1463 else if (range == (INTERVAL_MASK(HOUR) |
1465 {
1468 }
1469 /* HOUR TO SECOND */
1470 else if (range == (INTERVAL_MASK(HOUR) |
1473 {
1474 /* fractional-second rounding will be dealt with below */
1475 }
1476 /* MINUTE TO SECOND */
1477 else if (range == (INTERVAL_MASK(MINUTE) |
1479 {
1480 /* fractional-second rounding will be dealt with below */
1481 }
1482 else
1483 elog(ERROR, "unrecognized interval typmod: %d", typmod);
1484
1485 /* Need to adjust sub-second precision? */
1486 if (precision != INTERVAL_FULL_PRECISION)
1487 {
1489 ereturn(escontext, false,
1491 errmsg("interval(%d) precision must be between %d and %d",
1492 precision, 0, MAX_INTERVAL_PRECISION)));
1493
1494 if (interval->time >= INT64CONST(0))
1495 {
1497 IntervalOffsets[precision],
1498 &interval->time))
1499 ereturn(escontext, false,
1501 errmsg("interval out of range")));
1502 interval->time -= interval->time % IntervalScales[precision];
1503 }
1504 else
1505 {
1507 IntervalOffsets[precision],
1508 &interval->time))
1509 ereturn(escontext, false,
1511 errmsg("interval out of range")));
1512 interval->time -= interval->time % IntervalScales[precision];
1513 }
1514 }
1515 }
1516
1517 return true;
1518}
1519
1520/*
1521 * make_interval - numeric Interval constructor
1522 */
1523Datum
1525{
1532 double secs = PG_GETARG_FLOAT8(6);
1533 Interval *result;
1534
1535 /*
1536 * Reject out-of-range inputs. We reject any input values that cause
1537 * integer overflow of the corresponding interval fields.
1538 */
1539 if (isinf(secs) || isnan(secs))
1540 goto out_of_range;
1541
1542 result = palloc_object(Interval);
1543
1544 /* years and months -> months */
1546 pg_add_s32_overflow(result->month, months, &result->month))
1547 goto out_of_range;
1548
1549 /* weeks and days -> days */
1550 if (pg_mul_s32_overflow(weeks, DAYS_PER_WEEK, &result->day) ||
1551 pg_add_s32_overflow(result->day, days, &result->day))
1552 goto out_of_range;
1553
1554 /* hours and mins -> usecs (cannot overflow 64-bit) */
1556
1557 /* secs -> usecs */
1559 if (!FLOAT8_FITS_IN_INT64(secs) ||
1560 pg_add_s64_overflow(result->time, (int64) secs, &result->time))
1561 goto out_of_range;
1562
1563 /* make sure that the result is finite */
1564 if (INTERVAL_NOT_FINITE(result))
1565 goto out_of_range;
1566
1567 PG_RETURN_INTERVAL_P(result);
1568
1570 ereport(ERROR,
1572 errmsg("interval out of range"));
1573
1574 PG_RETURN_NULL(); /* keep compiler quiet */
1575}
1576
1577/* EncodeSpecialTimestamp()
1578 * Convert reserved timestamp data type to string.
1579 */
1580void
1582{
1584 strcpy(str, EARLY);
1585 else if (TIMESTAMP_IS_NOEND(dt))
1586 strcpy(str, LATE);
1587 else /* shouldn't happen */
1588 elog(ERROR, "invalid argument for EncodeSpecialTimestamp");
1589}
1590
1591static void
1593{
1595 strcpy(str, EARLY);
1596 else if (INTERVAL_IS_NOEND(interval))
1597 strcpy(str, LATE);
1598 else /* shouldn't happen */
1599 elog(ERROR, "invalid argument for EncodeSpecialInterval");
1600}
1601
1602Datum
1607
1608Datum
1613
1614Datum
1619
1620Datum
1625
1626Datum
1631
1632/*
1633 * GetCurrentTimestamp -- get the current operating system time
1634 *
1635 * Result is in the form of a TimestampTz value, and is expressed to the
1636 * full precision of the gettimeofday() syscall
1637 */
1640{
1641 TimestampTz result;
1642 struct timeval tp;
1643
1644 gettimeofday(&tp, NULL);
1645
1646 result = (TimestampTz) tp.tv_sec -
1648 result = (result * USECS_PER_SEC) + tp.tv_usec;
1649
1650 return result;
1651}
1652
1653/*
1654 * GetSQLCurrentTimestamp -- implements CURRENT_TIMESTAMP, CURRENT_TIMESTAMP(n)
1655 */
1658{
1659 TimestampTz ts;
1660
1662 if (typmod >= 0)
1663 AdjustTimestampForTypmod(&ts, typmod, NULL);
1664 return ts;
1665}
1666
1667/*
1668 * GetSQLLocalTimestamp -- implements LOCALTIMESTAMP, LOCALTIMESTAMP(n)
1669 */
1672{
1673 Timestamp ts;
1674
1676 if (typmod >= 0)
1677 AdjustTimestampForTypmod(&ts, typmod, NULL);
1678 return ts;
1679}
1680
1681/*
1682 * timeofday(*) -- returns the current time as a text.
1683 */
1684Datum
1686{
1687 struct timeval tp;
1688 char templ[128];
1689 char buf[128];
1690 pg_time_t tt;
1691
1692 gettimeofday(&tp, NULL);
1693 tt = (pg_time_t) tp.tv_sec;
1694 pg_strftime(templ, sizeof(templ), "%a %b %d %H:%M:%S.%%06d %Y %Z",
1696 snprintf(buf, sizeof(buf), templ, tp.tv_usec);
1697
1699}
1700
1701/*
1702 * TimestampDifference -- convert the difference between two timestamps
1703 * into integer seconds and microseconds
1704 *
1705 * This is typically used to calculate a wait timeout for select(2),
1706 * which explains the otherwise-odd choice of output format.
1707 *
1708 * Both inputs must be ordinary finite timestamps (in current usage,
1709 * they'll be results from GetCurrentTimestamp()).
1710 *
1711 * We expect start_time <= stop_time. If not, we return zeros,
1712 * since then we're already past the previously determined stop_time.
1713 */
1714void
1716 long *secs, int *microsecs)
1717{
1719
1720 if (diff <= 0)
1721 {
1722 *secs = 0;
1723 *microsecs = 0;
1724 }
1725 else
1726 {
1727 *secs = (long) (diff / USECS_PER_SEC);
1729 }
1730}
1731
1732/*
1733 * TimestampDifferenceMilliseconds -- convert the difference between two
1734 * timestamps into integer milliseconds
1735 *
1736 * This is typically used to calculate a wait timeout for WaitLatch()
1737 * or a related function. The choice of "long" as the result type
1738 * is to harmonize with that; furthermore, we clamp the result to at most
1739 * INT_MAX milliseconds, because that's all that WaitLatch() allows.
1740 *
1741 * We expect start_time <= stop_time. If not, we return zero,
1742 * since then we're already past the previously determined stop_time.
1743 *
1744 * Subtracting finite and infinite timestamps works correctly, returning
1745 * zero or INT_MAX as appropriate.
1746 *
1747 * Note we round up any fractional millisecond, since waiting for just
1748 * less than the intended timeout is undesirable.
1749 */
1750long
1752{
1754
1755 /* Deal with zero or negative elapsed time quickly. */
1756 if (start_time >= stop_time)
1757 return 0;
1758 /* To not fail with timestamp infinities, we must detect overflow. */
1760 return (long) INT_MAX;
1761 if (diff >= (INT_MAX * INT64CONST(1000) - 999))
1762 return (long) INT_MAX;
1763 else
1764 return (long) ((diff + 999) / 1000);
1765}
1766
1767/*
1768 * TimestampDifferenceExceeds -- report whether the difference between two
1769 * timestamps is >= a threshold (expressed in milliseconds)
1770 *
1771 * Both inputs must be ordinary finite timestamps (in current usage,
1772 * they'll be results from GetCurrentTimestamp()).
1773 */
1774bool
1783
1784/*
1785 * Check if the difference between two timestamps is >= a given
1786 * threshold (expressed in seconds).
1787 */
1788bool
1791 int threshold_sec)
1792{
1793 long secs;
1794 int usecs;
1795
1796 /* Calculate the difference in seconds */
1798
1799 return (secs >= threshold_sec);
1800}
1801
1802/*
1803 * Convert a time_t to TimestampTz.
1804 *
1805 * We do not use time_t internally in Postgres, but this is provided for use
1806 * by functions that need to interpret, say, a stat(2) result.
1807 *
1808 * To avoid having the function's ABI vary depending on the width of time_t,
1809 * we declare the argument as pg_time_t, which is cast-compatible with
1810 * time_t but always 64 bits wide (unless the platform has no 64-bit type).
1811 * This detail should be invisible to callers, at least at source code level.
1812 */
1815{
1816 TimestampTz result;
1817
1818 result = (TimestampTz) tm -
1820 result *= USECS_PER_SEC;
1821
1822 return result;
1823}
1824
1825/*
1826 * Convert a TimestampTz to time_t.
1827 *
1828 * This too is just marginally useful, but some places need it.
1829 *
1830 * To avoid having the function's ABI vary depending on the width of time_t,
1831 * we declare the result as pg_time_t, which is cast-compatible with
1832 * time_t but always 64 bits wide (unless the platform has no 64-bit type).
1833 * This detail should be invisible to callers, at least at source code level.
1834 */
1837{
1838 pg_time_t result;
1839
1840 result = (pg_time_t) (t / USECS_PER_SEC +
1842
1843 return result;
1844}
1845
1846/*
1847 * Produce a C-string representation of a TimestampTz.
1848 *
1849 * This is mostly for use in emitting messages. The primary difference
1850 * from timestamptz_out is that we force the output format to ISO. Note
1851 * also that the result is in a static buffer, not pstrdup'd.
1852 *
1853 * See also pg_strftime.
1854 */
1855const char *
1857{
1858 static char buf[MAXDATELEN + 1];
1859 int tz;
1860 struct pg_tm tt,
1861 *tm = &tt;
1862 fsec_t fsec;
1863 const char *tzn;
1864
1865 if (TIMESTAMP_NOT_FINITE(t))
1867 else if (timestamp2tm(t, &tz, tm, &fsec, &tzn, NULL) == 0)
1868 EncodeDateTime(tm, fsec, true, tz, tzn, USE_ISO_DATES, buf);
1869 else
1870 strlcpy(buf, "(timestamp out of range)", sizeof(buf));
1871
1872 return buf;
1873}
1874
1875
1876void
1877dt2time(Timestamp jd, int *hour, int *min, int *sec, fsec_t *fsec)
1878{
1879 TimeOffset time;
1880
1881 time = jd;
1882
1883 *hour = time / USECS_PER_HOUR;
1884 time -= (*hour) * USECS_PER_HOUR;
1885 *min = time / USECS_PER_MINUTE;
1886 time -= (*min) * USECS_PER_MINUTE;
1887 *sec = time / USECS_PER_SEC;
1888 *fsec = time - (*sec * USECS_PER_SEC);
1889} /* dt2time() */
1890
1891
1892/*
1893 * timestamp2tm() - Convert timestamp data type to POSIX time structure.
1894 *
1895 * Note that year is _not_ 1900-based, but is an explicit full value.
1896 * Also, month is one-based, _not_ zero-based.
1897 * Returns:
1898 * 0 on success
1899 * -1 on out of range
1900 *
1901 * If attimezone is NULL, the global timezone setting will be used.
1902 */
1903int
1904timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
1905{
1907 Timestamp time;
1909
1910 /* Use session timezone if caller asks for default */
1911 if (attimezone == NULL)
1912 attimezone = session_timezone;
1913
1914 time = dt;
1915 TMODULO(time, date, USECS_PER_DAY);
1916
1917 if (time < INT64CONST(0))
1918 {
1919 time += USECS_PER_DAY;
1920 date -= 1;
1921 }
1922
1923 /* add offset to go from J2000 back to standard Julian date */
1925
1926 /* Julian day routine does not work for negative Julian days */
1928 return -1;
1929
1930 j2date((int) date, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
1931 dt2time(time, &tm->tm_hour, &tm->tm_min, &tm->tm_sec, fsec);
1932
1933 /* Done if no TZ conversion wanted */
1934 if (tzp == NULL)
1935 {
1936 tm->tm_isdst = -1;
1937 tm->tm_gmtoff = 0;
1938 tm->tm_zone = NULL;
1939 if (tzn != NULL)
1940 *tzn = NULL;
1941 return 0;
1942 }
1943
1944 /*
1945 * If the time falls within the range of pg_time_t, use pg_localtime() to
1946 * rotate to the local time zone.
1947 *
1948 * First, convert to an integral timestamp, avoiding possibly
1949 * platform-specific roundoff-in-wrong-direction errors, and adjust to
1950 * Unix epoch. Then see if we can convert to pg_time_t without loss. This
1951 * coding avoids hardwiring any assumptions about the width of pg_time_t,
1952 * so it should behave sanely on machines without int64.
1953 */
1954 dt = (dt - *fsec) / USECS_PER_SEC +
1956 utime = (pg_time_t) dt;
1957 if ((Timestamp) utime == dt)
1958 {
1959 struct pg_tm *tx = pg_localtime(&utime, attimezone);
1960
1961 tm->tm_year = tx->tm_year + 1900;
1962 tm->tm_mon = tx->tm_mon + 1;
1963 tm->tm_mday = tx->tm_mday;
1964 tm->tm_hour = tx->tm_hour;
1965 tm->tm_min = tx->tm_min;
1966 tm->tm_sec = tx->tm_sec;
1967 tm->tm_isdst = tx->tm_isdst;
1968 tm->tm_gmtoff = tx->tm_gmtoff;
1969 tm->tm_zone = tx->tm_zone;
1970 *tzp = -tm->tm_gmtoff;
1971 if (tzn != NULL)
1972 *tzn = tm->tm_zone;
1973 }
1974 else
1975 {
1976 /*
1977 * When out of range of pg_time_t, treat as GMT
1978 */
1979 *tzp = 0;
1980 /* Mark this as *no* time zone available */
1981 tm->tm_isdst = -1;
1982 tm->tm_gmtoff = 0;
1983 tm->tm_zone = NULL;
1984 if (tzn != NULL)
1985 *tzn = NULL;
1986 }
1987
1988 return 0;
1989}
1990
1991
1992/* tm2timestamp()
1993 * Convert a tm structure to a timestamp data type.
1994 * Note that year is _not_ 1900-based, but is an explicit full value.
1995 * Also, month is one-based, _not_ zero-based.
1996 *
1997 * Returns -1 on failure (value out of range).
1998 */
1999int
2000tm2timestamp(struct pg_tm *tm, fsec_t fsec, int *tzp, Timestamp *result)
2001{
2003 TimeOffset time;
2004
2005 /* Prevent overflow in Julian-day routines */
2007 {
2008 *result = 0; /* keep compiler quiet */
2009 return -1;
2010 }
2011
2013 time = time2t(tm->tm_hour, tm->tm_min, tm->tm_sec, fsec);
2014
2016 pg_add_s64_overflow(*result, time, result)))
2017 {
2018 *result = 0; /* keep compiler quiet */
2019 return -1;
2020 }
2021 if (tzp != NULL)
2022 *result = dt2local(*result, -(*tzp));
2023
2024 /* final range check catches just-out-of-range timestamps */
2025 if (!IS_VALID_TIMESTAMP(*result))
2026 {
2027 *result = 0; /* keep compiler quiet */
2028 return -1;
2029 }
2030
2031 return 0;
2032}
2033
2034
2035/* interval2itm()
2036 * Convert an Interval to a pg_itm structure.
2037 * Note: overflow is not possible, because the pg_itm fields are
2038 * wide enough for all possible conversion results.
2039 */
2040void
2042{
2043 TimeOffset time;
2045
2046 itm->tm_year = span.month / MONTHS_PER_YEAR;
2047 itm->tm_mon = span.month % MONTHS_PER_YEAR;
2048 itm->tm_mday = span.day;
2049 time = span.time;
2050
2051 tfrac = time / USECS_PER_HOUR;
2052 time -= tfrac * USECS_PER_HOUR;
2053 itm->tm_hour = tfrac;
2054 tfrac = time / USECS_PER_MINUTE;
2055 time -= tfrac * USECS_PER_MINUTE;
2056 itm->tm_min = (int) tfrac;
2057 tfrac = time / USECS_PER_SEC;
2058 time -= tfrac * USECS_PER_SEC;
2059 itm->tm_sec = (int) tfrac;
2060 itm->tm_usec = (int) time;
2061}
2062
2063/* itm2interval()
2064 * Convert a pg_itm structure to an Interval.
2065 * Returns 0 if OK, -1 on overflow.
2066 *
2067 * This is for use in computations expected to produce finite results. Any
2068 * inputs that lead to infinite results are treated as overflows.
2069 */
2070int
2072{
2073 int64 total_months = (int64) itm->tm_year * MONTHS_PER_YEAR + itm->tm_mon;
2074
2076 return -1;
2077 span->month = (int32) total_months;
2078 span->day = itm->tm_mday;
2080 &span->time))
2081 return -1;
2082 /* tm_min, tm_sec are 32 bits, so intermediate products can't overflow */
2083 if (pg_add_s64_overflow(span->time, itm->tm_min * USECS_PER_MINUTE,
2084 &span->time))
2085 return -1;
2086 if (pg_add_s64_overflow(span->time, itm->tm_sec * USECS_PER_SEC,
2087 &span->time))
2088 return -1;
2089 if (pg_add_s64_overflow(span->time, itm->tm_usec,
2090 &span->time))
2091 return -1;
2093 return -1;
2094 return 0;
2095}
2096
2097/* itmin2interval()
2098 * Convert a pg_itm_in structure to an Interval.
2099 * Returns 0 if OK, -1 on overflow.
2100 *
2101 * Note: if the result is infinite, it is not treated as an overflow. This
2102 * avoids any dump/reload hazards from pre-17 databases that do not support
2103 * infinite intervals, but do allow finite intervals with all fields set to
2104 * INT_MIN/INT_MAX (outside the documented range). Such intervals will be
2105 * silently converted to +/-infinity. This may not be ideal, but seems
2106 * preferable to failure, and ought to be pretty unlikely in practice.
2107 */
2108int
2110{
2111 int64 total_months = (int64) itm_in->tm_year * MONTHS_PER_YEAR + itm_in->tm_mon;
2112
2114 return -1;
2115 span->month = (int32) total_months;
2116 span->day = itm_in->tm_mday;
2117 span->time = itm_in->tm_usec;
2118 return 0;
2119}
2120
2121static TimeOffset
2122time2t(const int hour, const int min, const int sec, const fsec_t fsec)
2123{
2124 return (((((hour * MINS_PER_HOUR) + min) * SECS_PER_MINUTE) + sec) * USECS_PER_SEC) + fsec;
2125}
2126
2127static Timestamp
2129{
2130 dt -= (timezone * USECS_PER_SEC);
2131 return dt;
2132}
2133
2134
2135/*****************************************************************************
2136 * PUBLIC ROUTINES *
2137 *****************************************************************************/
2138
2139
2140Datum
2147
2148Datum
2155
2156
2157/*----------------------------------------------------------
2158 * Relational operators for timestamp.
2159 *---------------------------------------------------------*/
2160
2161void
2163{
2164 struct pg_tm *t0;
2165 pg_time_t epoch = 0;
2166
2167 t0 = pg_gmtime(&epoch);
2168
2169 if (t0 == NULL)
2170 elog(ERROR, "could not convert epoch to timestamp: %m");
2171
2172 tm->tm_year = t0->tm_year;
2173 tm->tm_mon = t0->tm_mon;
2174 tm->tm_mday = t0->tm_mday;
2175 tm->tm_hour = t0->tm_hour;
2176 tm->tm_min = t0->tm_min;
2177 tm->tm_sec = t0->tm_sec;
2178
2179 tm->tm_year += 1900;
2180 tm->tm_mon++;
2181}
2182
2185{
2186 Timestamp dt;
2187 struct pg_tm tt,
2188 *tm = &tt;
2189
2191 /* we don't bother to test for failure ... */
2192 tm2timestamp(tm, 0, NULL, &dt);
2193
2194 return dt;
2195} /* SetEpochTimestamp() */
2196
2197/*
2198 * We are currently sharing some code between timestamp and timestamptz.
2199 * The comparison functions are among them. - thomas 2001-09-25
2200 *
2201 * timestamp_relop - is timestamp1 relop timestamp2
2202 */
2203int
2205{
2206 return (dt1 < dt2) ? -1 : ((dt1 > dt2) ? 1 : 0);
2207}
2208
2209Datum
2217
2218Datum
2226
2227Datum
2235
2236Datum
2244
2245Datum
2253
2254Datum
2262
2263Datum
2271
2272Datum
2280
2281/* note: this is used for timestamptz also */
2282static Datum
2284{
2286
2287 if (texisting == PG_INT64_MIN)
2288 {
2289 /* return value is undefined */
2290 *underflow = true;
2291 return (Datum) 0;
2292 }
2293
2294 *underflow = false;
2295 return TimestampGetDatum(texisting - 1);
2296}
2297
2298/* note: this is used for timestamptz also */
2299static Datum
2301{
2303
2304 if (texisting == PG_INT64_MAX)
2305 {
2306 /* return value is undefined */
2307 *overflow = true;
2308 return (Datum) 0;
2309 }
2310
2311 *overflow = false;
2312 return TimestampGetDatum(texisting + 1);
2313}
2314
2315Datum
2327
2328Datum
2330{
2331 return hashint8(fcinfo);
2332}
2333
2334Datum
2339
2340Datum
2342{
2343 return hashint8(fcinfo);
2344}
2345
2346Datum
2351
2352/*
2353 * Cross-type comparison functions for timestamp vs timestamptz
2354 */
2355
2356int32
2358{
2361
2363 if (escontext.error_occurred)
2364 {
2366 {
2367 /* dt1 is larger than any finite timestamp, but less than infinity */
2368 return TIMESTAMP_IS_NOEND(dt2) ? -1 : +1;
2369 }
2371 {
2372 /* dt1 is less than any finite timestamp, but more than -infinity */
2373 return TIMESTAMP_IS_NOBEGIN(dt2) ? +1 : -1;
2374 }
2375 }
2376
2378}
2379
2380Datum
2388
2389Datum
2397
2398Datum
2406
2407Datum
2415
2416Datum
2424
2425Datum
2433
2434Datum
2442
2443Datum
2451
2452Datum
2460
2461Datum
2469
2470Datum
2478
2479Datum
2487
2488Datum
2496
2497Datum
2505
2506
2507/*
2508 * interval_relop - is interval1 relop interval2
2509 *
2510 * Interval comparison is based on converting interval values to a linear
2511 * representation expressed in the units of the time field (microseconds,
2512 * in the case of integer timestamps) with days assumed to be always 24 hours
2513 * and months assumed to be always 30 days. To avoid overflow, we need a
2514 * wider-than-int64 datatype for the linear representation, so use INT128.
2515 */
2516
2517static inline INT128
2519{
2520 INT128 span;
2521 int64 days;
2522
2523 /*
2524 * Combine the month and day fields into an integral number of days.
2525 * Because the inputs are int32, int64 arithmetic suffices here.
2526 */
2527 days = interval->month * INT64CONST(30);
2528 days += interval->day;
2529
2530 /* Widen time field to 128 bits */
2532
2533 /* Scale up days to microseconds, forming a 128-bit product */
2535
2536 return span;
2537}
2538
2539static int
2547
2548static int
2556
2557Datum
2565
2566Datum
2574
2575Datum
2583
2584Datum
2592
2593Datum
2601
2602Datum
2610
2611Datum
2619
2620/*
2621 * Hashing for intervals
2622 *
2623 * We must produce equal hashvals for values that interval_cmp_internal()
2624 * considers equal. So, compute the net span the same way it does,
2625 * and then hash that.
2626 */
2627Datum
2629{
2632 int64 span64;
2633
2634 /*
2635 * Use only the least significant 64 bits for hashing. The upper 64 bits
2636 * seldom add any useful information, and besides we must do it like this
2637 * for compatibility with hashes calculated before use of INT128 was
2638 * introduced.
2639 */
2641
2643}
2644
2645Datum
2658
2659/* overlaps_timestamp() --- implements the SQL OVERLAPS operator.
2660 *
2661 * Algorithm is per SQL spec. This is much harder than you'd think
2662 * because the spec requires us to deliver a non-null answer in some cases
2663 * where some of the inputs are null.
2664 */
2665Datum
2667{
2668 /*
2669 * The arguments are Timestamps, but we leave them as generic Datums to
2670 * avoid unnecessary conversions between value and reference forms --- not
2671 * to mention possible dereferences of null pointers.
2672 */
2677 bool ts1IsNull = PG_ARGISNULL(0);
2678 bool te1IsNull = PG_ARGISNULL(1);
2679 bool ts2IsNull = PG_ARGISNULL(2);
2680 bool te2IsNull = PG_ARGISNULL(3);
2681
2682#define TIMESTAMP_GT(t1,t2) \
2683 DatumGetBool(DirectFunctionCall2(timestamp_gt,t1,t2))
2684#define TIMESTAMP_LT(t1,t2) \
2685 DatumGetBool(DirectFunctionCall2(timestamp_lt,t1,t2))
2686
2687 /*
2688 * If both endpoints of interval 1 are null, the result is null (unknown).
2689 * If just one endpoint is null, take ts1 as the non-null one. Otherwise,
2690 * take ts1 as the lesser endpoint.
2691 */
2692 if (ts1IsNull)
2693 {
2694 if (te1IsNull)
2696 /* swap null for non-null */
2697 ts1 = te1;
2698 te1IsNull = true;
2699 }
2700 else if (!te1IsNull)
2701 {
2702 if (TIMESTAMP_GT(ts1, te1))
2703 {
2704 Datum tt = ts1;
2705
2706 ts1 = te1;
2707 te1 = tt;
2708 }
2709 }
2710
2711 /* Likewise for interval 2. */
2712 if (ts2IsNull)
2713 {
2714 if (te2IsNull)
2716 /* swap null for non-null */
2717 ts2 = te2;
2718 te2IsNull = true;
2719 }
2720 else if (!te2IsNull)
2721 {
2722 if (TIMESTAMP_GT(ts2, te2))
2723 {
2724 Datum tt = ts2;
2725
2726 ts2 = te2;
2727 te2 = tt;
2728 }
2729 }
2730
2731 /*
2732 * At this point neither ts1 nor ts2 is null, so we can consider three
2733 * cases: ts1 > ts2, ts1 < ts2, ts1 = ts2
2734 */
2735 if (TIMESTAMP_GT(ts1, ts2))
2736 {
2737 /*
2738 * This case is ts1 < te2 OR te1 < te2, which may look redundant but
2739 * in the presence of nulls it's not quite completely so.
2740 */
2741 if (te2IsNull)
2743 if (TIMESTAMP_LT(ts1, te2))
2744 PG_RETURN_BOOL(true);
2745 if (te1IsNull)
2747
2748 /*
2749 * If te1 is not null then we had ts1 <= te1 above, and we just found
2750 * ts1 >= te2, hence te1 >= te2.
2751 */
2752 PG_RETURN_BOOL(false);
2753 }
2754 else if (TIMESTAMP_LT(ts1, ts2))
2755 {
2756 /* This case is ts2 < te1 OR te2 < te1 */
2757 if (te1IsNull)
2759 if (TIMESTAMP_LT(ts2, te1))
2760 PG_RETURN_BOOL(true);
2761 if (te2IsNull)
2763
2764 /*
2765 * If te2 is not null then we had ts2 <= te2 above, and we just found
2766 * ts2 >= te1, hence te2 >= te1.
2767 */
2768 PG_RETURN_BOOL(false);
2769 }
2770 else
2771 {
2772 /*
2773 * For ts1 = ts2 the spec says te1 <> te2 OR te1 = te2, which is a
2774 * rather silly way of saying "true if both are non-null, else null".
2775 */
2776 if (te1IsNull || te2IsNull)
2778 PG_RETURN_BOOL(true);
2779 }
2780
2781#undef TIMESTAMP_GT
2782#undef TIMESTAMP_LT
2783}
2784
2785
2786/*----------------------------------------------------------
2787 * "Arithmetic" operators on date/times.
2788 *---------------------------------------------------------*/
2789
2790Datum
2792{
2795 Timestamp result;
2796
2797 /* use timestamp_cmp_internal to be sure this agrees with comparisons */
2798 if (timestamp_cmp_internal(dt1, dt2) < 0)
2799 result = dt1;
2800 else
2801 result = dt2;
2802 PG_RETURN_TIMESTAMP(result);
2803}
2804
2805Datum
2807{
2810 Timestamp result;
2811
2812 if (timestamp_cmp_internal(dt1, dt2) > 0)
2813 result = dt1;
2814 else
2815 result = dt2;
2816 PG_RETURN_TIMESTAMP(result);
2817}
2818
2819
2820Datum
2822{
2825 Interval *result;
2826
2827 result = palloc_object(Interval);
2828
2829 /*
2830 * Handle infinities.
2831 *
2832 * We treat anything that amounts to "infinity - infinity" as an error,
2833 * since the interval type has nothing equivalent to NaN.
2834 */
2836 {
2838 {
2840 ereport(ERROR,
2842 errmsg("interval out of range")));
2843 else
2844 INTERVAL_NOBEGIN(result);
2845 }
2846 else if (TIMESTAMP_IS_NOEND(dt1))
2847 {
2849 ereport(ERROR,
2851 errmsg("interval out of range")));
2852 else
2853 INTERVAL_NOEND(result);
2854 }
2855 else if (TIMESTAMP_IS_NOBEGIN(dt2))
2856 INTERVAL_NOEND(result);
2857 else /* TIMESTAMP_IS_NOEND(dt2) */
2858 INTERVAL_NOBEGIN(result);
2859
2860 PG_RETURN_INTERVAL_P(result);
2861 }
2862
2863 if (unlikely(pg_sub_s64_overflow(dt1, dt2, &result->time)))
2864 ereport(ERROR,
2866 errmsg("interval out of range")));
2867
2868 result->month = 0;
2869 result->day = 0;
2870
2871 /*----------
2872 * This is wrong, but removing it breaks a lot of regression tests.
2873 * For example:
2874 *
2875 * test=> SET timezone = 'EST5EDT';
2876 * test=> SELECT
2877 * test-> ('2005-10-30 13:22:00-05'::timestamptz -
2878 * test(> '2005-10-29 13:22:00-04'::timestamptz);
2879 * ?column?
2880 * ----------------
2881 * 1 day 01:00:00
2882 * (1 row)
2883 *
2884 * so adding that to the first timestamp gets:
2885 *
2886 * test=> SELECT
2887 * test-> ('2005-10-29 13:22:00-04'::timestamptz +
2888 * test(> ('2005-10-30 13:22:00-05'::timestamptz -
2889 * test(> '2005-10-29 13:22:00-04'::timestamptz)) at time zone 'EST';
2890 * timezone
2891 * --------------------
2892 * 2005-10-30 14:22:00
2893 * (1 row)
2894 *----------
2895 */
2897 IntervalPGetDatum(result)));
2898
2899 PG_RETURN_INTERVAL_P(result);
2900}
2901
2902/*
2903 * interval_justify_interval()
2904 *
2905 * Adjust interval so 'month', 'day', and 'time' portions are within
2906 * customary bounds. Specifically:
2907 *
2908 * 0 <= abs(time) < 24 hours
2909 * 0 <= abs(day) < 30 days
2910 *
2911 * Also, the sign bit on all three fields is made equal, so either
2912 * all three fields are negative or all are positive.
2913 */
2914Datum
2916{
2918 Interval *result;
2921
2922 result = palloc_object(Interval);
2923 result->month = span->month;
2924 result->day = span->day;
2925 result->time = span->time;
2926
2927 /* do nothing for infinite intervals */
2928 if (INTERVAL_NOT_FINITE(result))
2929 PG_RETURN_INTERVAL_P(result);
2930
2931 /* pre-justify days if it might prevent overflow */
2932 if ((result->day > 0 && result->time > 0) ||
2933 (result->day < 0 && result->time < 0))
2934 {
2935 wholemonth = result->day / DAYS_PER_MONTH;
2936 result->day -= wholemonth * DAYS_PER_MONTH;
2937 if (pg_add_s32_overflow(result->month, wholemonth, &result->month))
2938 ereport(ERROR,
2940 errmsg("interval out of range")));
2941 }
2942
2943 /*
2944 * Since TimeOffset is int64, abs(wholeday) can't exceed about 1.07e8. If
2945 * we pre-justified then abs(result->day) is less than DAYS_PER_MONTH, so
2946 * this addition can't overflow. If we didn't pre-justify, then day and
2947 * time are of different signs, so it still can't overflow.
2948 */
2950 result->day += wholeday;
2951
2952 wholemonth = result->day / DAYS_PER_MONTH;
2953 result->day -= wholemonth * DAYS_PER_MONTH;
2954 if (pg_add_s32_overflow(result->month, wholemonth, &result->month))
2955 ereport(ERROR,
2957 errmsg("interval out of range")));
2958
2959 if (result->month > 0 &&
2960 (result->day < 0 || (result->day == 0 && result->time < 0)))
2961 {
2962 result->day += DAYS_PER_MONTH;
2963 result->month--;
2964 }
2965 else if (result->month < 0 &&
2966 (result->day > 0 || (result->day == 0 && result->time > 0)))
2967 {
2968 result->day -= DAYS_PER_MONTH;
2969 result->month++;
2970 }
2971
2972 if (result->day > 0 && result->time < 0)
2973 {
2974 result->time += USECS_PER_DAY;
2975 result->day--;
2976 }
2977 else if (result->day < 0 && result->time > 0)
2978 {
2979 result->time -= USECS_PER_DAY;
2980 result->day++;
2981 }
2982
2983 PG_RETURN_INTERVAL_P(result);
2984}
2985
2986/*
2987 * interval_justify_hours()
2988 *
2989 * Adjust interval so 'time' contains less than a whole day, adding
2990 * the excess to 'day'. This is useful for
2991 * situations (such as non-TZ) where '1 day' = '24 hours' is valid,
2992 * e.g. interval subtraction and division.
2993 */
2994Datum
2996{
2998 Interval *result;
3000
3001 result = palloc_object(Interval);
3002 result->month = span->month;
3003 result->day = span->day;
3004 result->time = span->time;
3005
3006 /* do nothing for infinite intervals */
3007 if (INTERVAL_NOT_FINITE(result))
3008 PG_RETURN_INTERVAL_P(result);
3009
3011 if (pg_add_s32_overflow(result->day, wholeday, &result->day))
3012 ereport(ERROR,
3014 errmsg("interval out of range")));
3015
3016 if (result->day > 0 && result->time < 0)
3017 {
3018 result->time += USECS_PER_DAY;
3019 result->day--;
3020 }
3021 else if (result->day < 0 && result->time > 0)
3022 {
3023 result->time -= USECS_PER_DAY;
3024 result->day++;
3025 }
3026
3027 PG_RETURN_INTERVAL_P(result);
3028}
3029
3030/*
3031 * interval_justify_days()
3032 *
3033 * Adjust interval so 'day' contains less than 30 days, adding
3034 * the excess to 'month'.
3035 */
3036Datum
3038{
3040 Interval *result;
3042
3043 result = palloc_object(Interval);
3044 result->month = span->month;
3045 result->day = span->day;
3046 result->time = span->time;
3047
3048 /* do nothing for infinite intervals */
3049 if (INTERVAL_NOT_FINITE(result))
3050 PG_RETURN_INTERVAL_P(result);
3051
3052 wholemonth = result->day / DAYS_PER_MONTH;
3053 result->day -= wholemonth * DAYS_PER_MONTH;
3054 if (pg_add_s32_overflow(result->month, wholemonth, &result->month))
3055 ereport(ERROR,
3057 errmsg("interval out of range")));
3058
3059 if (result->month > 0 && result->day < 0)
3060 {
3061 result->day += DAYS_PER_MONTH;
3062 result->month--;
3063 }
3064 else if (result->month < 0 && result->day > 0)
3065 {
3066 result->day -= DAYS_PER_MONTH;
3067 result->month++;
3068 }
3069
3070 PG_RETURN_INTERVAL_P(result);
3071}
3072
3073/* timestamp_pl_interval()
3074 * Add an interval to a timestamp data type.
3075 * Note that interval has provisions for qualitative year/month and day
3076 * units, so try to do the right thing with them.
3077 * To add a month, increment the month, and use the same day of month.
3078 * Then, if the next month has fewer days, set the day of month
3079 * to the last day of month.
3080 * To add a day, increment the mday, and use the same time of day.
3081 * Lastly, add in the "quantitative time".
3082 */
3083Datum
3085{
3088 Timestamp result;
3089
3090 /*
3091 * Handle infinities.
3092 *
3093 * We treat anything that amounts to "infinity - infinity" as an error,
3094 * since the timestamp type has nothing equivalent to NaN.
3095 */
3097 {
3099 ereport(ERROR,
3101 errmsg("timestamp out of range")));
3102 else
3103 TIMESTAMP_NOBEGIN(result);
3104 }
3105 else if (INTERVAL_IS_NOEND(span))
3106 {
3108 ereport(ERROR,
3110 errmsg("timestamp out of range")));
3111 else
3112 TIMESTAMP_NOEND(result);
3113 }
3115 result = timestamp;
3116 else
3117 {
3118 if (span->month != 0)
3119 {
3120 struct pg_tm tt,
3121 *tm = &tt;
3122 fsec_t fsec;
3123
3124 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
3125 ereport(ERROR,
3127 errmsg("timestamp out of range")));
3128
3129 if (pg_add_s32_overflow(tm->tm_mon, span->month, &tm->tm_mon))
3130 ereport(ERROR,
3132 errmsg("timestamp out of range")));
3133 if (tm->tm_mon > MONTHS_PER_YEAR)
3134 {
3135 tm->tm_year += (tm->tm_mon - 1) / MONTHS_PER_YEAR;
3136 tm->tm_mon = ((tm->tm_mon - 1) % MONTHS_PER_YEAR) + 1;
3137 }
3138 else if (tm->tm_mon < 1)
3139 {
3140 tm->tm_year += tm->tm_mon / MONTHS_PER_YEAR - 1;
3142 }
3143
3144 /* adjust for end of month boundary problems... */
3145 if (tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1])
3146 tm->tm_mday = (day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]);
3147
3148 if (tm2timestamp(tm, fsec, NULL, &timestamp) != 0)
3149 ereport(ERROR,
3151 errmsg("timestamp out of range")));
3152 }
3153
3154 if (span->day != 0)
3155 {
3156 struct pg_tm tt,
3157 *tm = &tt;
3158 fsec_t fsec;
3159 int julian;
3160
3161 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
3162 ereport(ERROR,
3164 errmsg("timestamp out of range")));
3165
3166 /*
3167 * Add days by converting to and from Julian. We need an overflow
3168 * check here since j2date expects a non-negative integer input.
3169 */
3171 if (pg_add_s32_overflow(julian, span->day, &julian) ||
3172 julian < 0)
3173 ereport(ERROR,
3175 errmsg("timestamp out of range")));
3177
3178 if (tm2timestamp(tm, fsec, NULL, &timestamp) != 0)
3179 ereport(ERROR,
3181 errmsg("timestamp out of range")));
3182 }
3183
3185 ereport(ERROR,
3187 errmsg("timestamp out of range")));
3188
3190 ereport(ERROR,
3192 errmsg("timestamp out of range")));
3193
3194 result = timestamp;
3195 }
3196
3197 PG_RETURN_TIMESTAMP(result);
3198}
3199
3200Datum
3213
3214
3215/* timestamptz_pl_interval_internal()
3216 * Add an interval to a timestamptz, in the given (or session) timezone.
3217 *
3218 * Note that interval has provisions for qualitative year/month and day
3219 * units, so try to do the right thing with them.
3220 * To add a month, increment the month, and use the same day of month.
3221 * Then, if the next month has fewer days, set the day of month
3222 * to the last day of month.
3223 * To add a day, increment the mday, and use the same time of day.
3224 * Lastly, add in the "quantitative time".
3225 */
3226static TimestampTz
3228 Interval *span,
3229 pg_tz *attimezone)
3230{
3231 TimestampTz result;
3232 int tz;
3233
3234 /*
3235 * Handle infinities.
3236 *
3237 * We treat anything that amounts to "infinity - infinity" as an error,
3238 * since the timestamptz type has nothing equivalent to NaN.
3239 */
3241 {
3243 ereport(ERROR,
3245 errmsg("timestamp out of range")));
3246 else
3247 TIMESTAMP_NOBEGIN(result);
3248 }
3249 else if (INTERVAL_IS_NOEND(span))
3250 {
3252 ereport(ERROR,
3254 errmsg("timestamp out of range")));
3255 else
3256 TIMESTAMP_NOEND(result);
3257 }
3259 result = timestamp;
3260 else
3261 {
3262 /* Use session timezone if caller asks for default */
3263 if (attimezone == NULL)
3264 attimezone = session_timezone;
3265
3266 if (span->month != 0)
3267 {
3268 struct pg_tm tt,
3269 *tm = &tt;
3270 fsec_t fsec;
3271
3272 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, attimezone) != 0)
3273 ereport(ERROR,
3275 errmsg("timestamp out of range")));
3276
3277 if (pg_add_s32_overflow(tm->tm_mon, span->month, &tm->tm_mon))
3278 ereport(ERROR,
3280 errmsg("timestamp out of range")));
3281 if (tm->tm_mon > MONTHS_PER_YEAR)
3282 {
3283 tm->tm_year += (tm->tm_mon - 1) / MONTHS_PER_YEAR;
3284 tm->tm_mon = ((tm->tm_mon - 1) % MONTHS_PER_YEAR) + 1;
3285 }
3286 else if (tm->tm_mon < 1)
3287 {
3288 tm->tm_year += tm->tm_mon / MONTHS_PER_YEAR - 1;
3290 }
3291
3292 /* adjust for end of month boundary problems... */
3293 if (tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1])
3294 tm->tm_mday = (day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]);
3295
3296 tz = DetermineTimeZoneOffset(tm, attimezone);
3297
3298 if (tm2timestamp(tm, fsec, &tz, &timestamp) != 0)
3299 ereport(ERROR,
3301 errmsg("timestamp out of range")));
3302 }
3303
3304 if (span->day != 0)
3305 {
3306 struct pg_tm tt,
3307 *tm = &tt;
3308 fsec_t fsec;
3309 int julian;
3310
3311 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, attimezone) != 0)
3312 ereport(ERROR,
3314 errmsg("timestamp out of range")));
3315
3316 /*
3317 * Add days by converting to and from Julian. We need an overflow
3318 * check here since j2date expects a non-negative integer input.
3319 * In practice though, it will give correct answers for small
3320 * negative Julian dates; we should allow -1 to avoid
3321 * timezone-dependent failures, as discussed in timestamp.h.
3322 */
3324 if (pg_add_s32_overflow(julian, span->day, &julian) ||
3325 julian < -1)
3326 ereport(ERROR,
3328 errmsg("timestamp out of range")));
3330
3331 tz = DetermineTimeZoneOffset(tm, attimezone);
3332
3333 if (tm2timestamp(tm, fsec, &tz, &timestamp) != 0)
3334 ereport(ERROR,
3336 errmsg("timestamp out of range")));
3337 }
3338
3340 ereport(ERROR,
3342 errmsg("timestamp out of range")));
3343
3345 ereport(ERROR,
3347 errmsg("timestamp out of range")));
3348
3349 result = timestamp;
3350 }
3351
3352 return result;
3353}
3354
3355/* timestamptz_mi_interval_internal()
3356 * As above, but subtract the interval.
3357 */
3358static TimestampTz
3369
3370/* timestamptz_pl_interval()
3371 * Add an interval to a timestamptz, in the session timezone.
3372 */
3373Datum
3381
3382Datum
3390
3391/* timestamptz_pl_interval_at_zone()
3392 * Add an interval to a timestamptz, in the specified timezone.
3393 */
3394Datum
3404
3405Datum
3415
3416/* interval_um_internal()
3417 * Negate an interval.
3418 */
3419static void
3421{
3423 INTERVAL_NOEND(result);
3424 else if (INTERVAL_IS_NOEND(interval))
3425 INTERVAL_NOBEGIN(result);
3426 else
3427 {
3428 /* Negate each field, guarding against overflow */
3429 if (pg_sub_s64_overflow(INT64CONST(0), interval->time, &result->time) ||
3430 pg_sub_s32_overflow(0, interval->day, &result->day) ||
3431 pg_sub_s32_overflow(0, interval->month, &result->month) ||
3432 INTERVAL_NOT_FINITE(result))
3433 ereport(ERROR,
3435 errmsg("interval out of range")));
3436 }
3437}
3438
3439Datum
3441{
3443 Interval *result;
3444
3445 result = palloc_object(Interval);
3447
3448 PG_RETURN_INTERVAL_P(result);
3449}
3450
3451
3452Datum
3454{
3457 Interval *result;
3458
3459 /* use interval_cmp_internal to be sure this agrees with comparisons */
3461 result = interval1;
3462 else
3463 result = interval2;
3464 PG_RETURN_INTERVAL_P(result);
3465}
3466
3467Datum
3469{
3472 Interval *result;
3473
3475 result = interval1;
3476 else
3477 result = interval2;
3478 PG_RETURN_INTERVAL_P(result);
3479}
3480
3481static void
3483{
3486
3487 if (pg_add_s32_overflow(span1->month, span2->month, &result->month) ||
3488 pg_add_s32_overflow(span1->day, span2->day, &result->day) ||
3489 pg_add_s64_overflow(span1->time, span2->time, &result->time) ||
3490 INTERVAL_NOT_FINITE(result))
3491 ereport(ERROR,
3493 errmsg("interval out of range")));
3494}
3495
3496Datum
3498{
3501 Interval *result;
3502
3503 result = palloc_object(Interval);
3504
3505 /*
3506 * Handle infinities.
3507 *
3508 * We treat anything that amounts to "infinity - infinity" as an error,
3509 * since the interval type has nothing equivalent to NaN.
3510 */
3512 {
3514 ereport(ERROR,
3516 errmsg("interval out of range")));
3517 else
3518 INTERVAL_NOBEGIN(result);
3519 }
3520 else if (INTERVAL_IS_NOEND(span1))
3521 {
3523 ereport(ERROR,
3525 errmsg("interval out of range")));
3526 else
3527 INTERVAL_NOEND(result);
3528 }
3529 else if (INTERVAL_NOT_FINITE(span2))
3530 memcpy(result, span2, sizeof(Interval));
3531 else
3532 finite_interval_pl(span1, span2, result);
3533
3534 PG_RETURN_INTERVAL_P(result);
3535}
3536
3537static void
3539{
3542
3543 if (pg_sub_s32_overflow(span1->month, span2->month, &result->month) ||
3544 pg_sub_s32_overflow(span1->day, span2->day, &result->day) ||
3545 pg_sub_s64_overflow(span1->time, span2->time, &result->time) ||
3546 INTERVAL_NOT_FINITE(result))
3547 ereport(ERROR,
3549 errmsg("interval out of range")));
3550}
3551
3552Datum
3554{
3557 Interval *result;
3558
3559 result = palloc_object(Interval);
3560
3561 /*
3562 * Handle infinities.
3563 *
3564 * We treat anything that amounts to "infinity - infinity" as an error,
3565 * since the interval type has nothing equivalent to NaN.
3566 */
3568 {
3570 ereport(ERROR,
3572 errmsg("interval out of range")));
3573 else
3574 INTERVAL_NOBEGIN(result);
3575 }
3576 else if (INTERVAL_IS_NOEND(span1))
3577 {
3579 ereport(ERROR,
3581 errmsg("interval out of range")));
3582 else
3583 INTERVAL_NOEND(result);
3584 }
3585 else if (INTERVAL_IS_NOBEGIN(span2))
3586 INTERVAL_NOEND(result);
3587 else if (INTERVAL_IS_NOEND(span2))
3588 INTERVAL_NOBEGIN(result);
3589 else
3590 finite_interval_mi(span1, span2, result);
3591
3592 PG_RETURN_INTERVAL_P(result);
3593}
3594
3595/*
3596 * There is no interval_abs(): it is unclear what value to return:
3597 * http://archives.postgresql.org/pgsql-general/2009-10/msg01031.php
3598 * http://archives.postgresql.org/pgsql-general/2009-11/msg00041.php
3599 */
3600
3601Datum
3603{
3606 double month_remainder_days,
3609 int32 orig_month = span->month,
3610 orig_day = span->day;
3611 Interval *result;
3612
3613 result = palloc_object(Interval);
3614
3615 /*
3616 * Handle NaN and infinities.
3617 *
3618 * We treat "0 * infinity" and "infinity * 0" as errors, since the
3619 * interval type has nothing equivalent to NaN.
3620 */
3621 if (isnan(factor))
3622 goto out_of_range;
3623
3625 {
3626 if (factor == 0.0)
3627 goto out_of_range;
3628
3629 if (factor < 0.0)
3630 interval_um_internal(span, result);
3631 else
3632 memcpy(result, span, sizeof(Interval));
3633
3634 PG_RETURN_INTERVAL_P(result);
3635 }
3636 if (isinf(factor))
3637 {
3638 int isign = interval_sign(span);
3639
3640 if (isign == 0)
3641 goto out_of_range;
3642
3643 if (factor * isign < 0)
3644 INTERVAL_NOBEGIN(result);
3645 else
3646 INTERVAL_NOEND(result);
3647
3648 PG_RETURN_INTERVAL_P(result);
3649 }
3650
3651 result_double = span->month * factor;
3653 goto out_of_range;
3654 result->month = (int32) result_double;
3655
3656 result_double = span->day * factor;
3658 goto out_of_range;
3659 result->day = (int32) result_double;
3660
3661 /*
3662 * The above correctly handles the whole-number part of the month and day
3663 * products, but we have to do something with any fractional part
3664 * resulting when the factor is non-integral. We cascade the fractions
3665 * down to lower units using the conversion factors DAYS_PER_MONTH and
3666 * SECS_PER_DAY. Note we do NOT cascade up, since we are not forced to do
3667 * so by the representation. The user can choose to cascade up later,
3668 * using justify_hours and/or justify_days.
3669 */
3670
3671 /*
3672 * Fractional months full days into days.
3673 *
3674 * Floating point calculation are inherently imprecise, so these
3675 * calculations are crafted to produce the most reliable result possible.
3676 * TSROUND() is needed to more accurately produce whole numbers where
3677 * appropriate.
3678 */
3681 sec_remainder = (orig_day * factor - result->day +
3684
3685 /*
3686 * Might have 24:00:00 hours due to rounding, or >24 hours because of time
3687 * cascade from months and days. It might still be >24 if the combination
3688 * of cascade and the seconds factor operation itself.
3689 */
3691 {
3692 if (pg_add_s32_overflow(result->day,
3693 (int) (sec_remainder / SECS_PER_DAY),
3694 &result->day))
3695 goto out_of_range;
3697 }
3698
3699 /* cascade units down */
3701 &result->day))
3702 goto out_of_range;
3705 goto out_of_range;
3706 result->time = (int64) result_double;
3707
3708 if (INTERVAL_NOT_FINITE(result))
3709 goto out_of_range;
3710
3711 PG_RETURN_INTERVAL_P(result);
3712
3714 ereport(ERROR,
3716 errmsg("interval out of range"));
3717
3718 PG_RETURN_NULL(); /* keep compiler quiet */
3719}
3720
3721Datum
3723{
3724 /* Args are float8 and Interval *, but leave them as generic Datum */
3727
3729}
3730
3731Datum
3733{
3736 double month_remainder_days,
3739 int32 orig_month = span->month,
3740 orig_day = span->day;
3741 Interval *result;
3742
3743 result = palloc_object(Interval);
3744
3745 if (factor == 0.0)
3746 ereport(ERROR,
3748 errmsg("division by zero")));
3749
3750 /*
3751 * Handle NaN and infinities.
3752 *
3753 * We treat "infinity / infinity" as an error, since the interval type has
3754 * nothing equivalent to NaN. Otherwise, dividing by infinity is handled
3755 * by the regular division code, causing all fields to be set to zero.
3756 */
3757 if (isnan(factor))
3758 goto out_of_range;
3759
3761 {
3762 if (isinf(factor))
3763 goto out_of_range;
3764
3765 if (factor < 0.0)
3766 interval_um_internal(span, result);
3767 else
3768 memcpy(result, span, sizeof(Interval));
3769
3770 PG_RETURN_INTERVAL_P(result);
3771 }
3772
3773 result_double = span->month / factor;
3775 goto out_of_range;
3776 result->month = (int32) result_double;
3777
3778 result_double = span->day / factor;
3780 goto out_of_range;
3781 result->day = (int32) result_double;
3782
3783 /*
3784 * Fractional months full days into days. See comment in interval_mul().
3785 */
3788 sec_remainder = (orig_day / factor - result->day +
3792 {
3793 if (pg_add_s32_overflow(result->day,
3794 (int) (sec_remainder / SECS_PER_DAY),
3795 &result->day))
3796 goto out_of_range;
3798 }
3799
3800 /* cascade units down */
3802 &result->day))
3803 goto out_of_range;
3806 goto out_of_range;
3807 result->time = (int64) result_double;
3808
3809 if (INTERVAL_NOT_FINITE(result))
3810 goto out_of_range;
3811
3812 PG_RETURN_INTERVAL_P(result);
3813
3815 ereport(ERROR,
3817 errmsg("interval out of range"));
3818
3819 PG_RETURN_NULL(); /* keep compiler quiet */
3820}
3821
3822
3823/*
3824 * in_range support functions for timestamps and intervals.
3825 *
3826 * Per SQL spec, we support these with interval as the offset type.
3827 * The spec's restriction that the offset not be negative is a bit hard to
3828 * decipher for intervals, but we choose to interpret it the same as our
3829 * interval comparison operators would.
3830 */
3831
3832Datum
3834{
3837 Interval *offset = PG_GETARG_INTERVAL_P(2);
3838 bool sub = PG_GETARG_BOOL(3);
3839 bool less = PG_GETARG_BOOL(4);
3840 TimestampTz sum;
3841
3842 if (interval_sign(offset) < 0)
3843 ereport(ERROR,
3845 errmsg("invalid preceding or following size in window function")));
3846
3847 /*
3848 * Deal with cases where both base and offset are infinite, and computing
3849 * base +/- offset would cause an error. As for float and numeric types,
3850 * we assume that all values infinitely precede +infinity and infinitely
3851 * follow -infinity. See in_range_float8_float8() for reasoning.
3852 */
3853 if (INTERVAL_IS_NOEND(offset) &&
3854 (sub ? TIMESTAMP_IS_NOEND(base) : TIMESTAMP_IS_NOBEGIN(base)))
3855 PG_RETURN_BOOL(true);
3856
3857 /* We don't currently bother to avoid overflow hazards here */
3858 if (sub)
3859 sum = timestamptz_mi_interval_internal(base, offset, NULL);
3860 else
3861 sum = timestamptz_pl_interval_internal(base, offset, NULL);
3862
3863 if (less)
3864 PG_RETURN_BOOL(val <= sum);
3865 else
3866 PG_RETURN_BOOL(val >= sum);
3867}
3868
3869Datum
3871{
3874 Interval *offset = PG_GETARG_INTERVAL_P(2);
3875 bool sub = PG_GETARG_BOOL(3);
3876 bool less = PG_GETARG_BOOL(4);
3877 Timestamp sum;
3878
3879 if (interval_sign(offset) < 0)
3880 ereport(ERROR,
3882 errmsg("invalid preceding or following size in window function")));
3883
3884 /*
3885 * Deal with cases where both base and offset are infinite, and computing
3886 * base +/- offset would cause an error. As for float and numeric types,
3887 * we assume that all values infinitely precede +infinity and infinitely
3888 * follow -infinity. See in_range_float8_float8() for reasoning.
3889 */
3890 if (INTERVAL_IS_NOEND(offset) &&
3891 (sub ? TIMESTAMP_IS_NOEND(base) : TIMESTAMP_IS_NOBEGIN(base)))
3892 PG_RETURN_BOOL(true);
3893
3894 /* We don't currently bother to avoid overflow hazards here */
3895 if (sub)
3897 TimestampGetDatum(base),
3898 IntervalPGetDatum(offset)));
3899 else
3901 TimestampGetDatum(base),
3902 IntervalPGetDatum(offset)));
3903
3904 if (less)
3905 PG_RETURN_BOOL(val <= sum);
3906 else
3907 PG_RETURN_BOOL(val >= sum);
3908}
3909
3910Datum
3912{
3914 Interval *base = PG_GETARG_INTERVAL_P(1);
3915 Interval *offset = PG_GETARG_INTERVAL_P(2);
3916 bool sub = PG_GETARG_BOOL(3);
3917 bool less = PG_GETARG_BOOL(4);
3918 Interval *sum;
3919
3920 if (interval_sign(offset) < 0)
3921 ereport(ERROR,
3923 errmsg("invalid preceding or following size in window function")));
3924
3925 /*
3926 * Deal with cases where both base and offset are infinite, and computing
3927 * base +/- offset would cause an error. As for float and numeric types,
3928 * we assume that all values infinitely precede +infinity and infinitely
3929 * follow -infinity. See in_range_float8_float8() for reasoning.
3930 */
3931 if (INTERVAL_IS_NOEND(offset) &&
3932 (sub ? INTERVAL_IS_NOEND(base) : INTERVAL_IS_NOBEGIN(base)))
3933 PG_RETURN_BOOL(true);
3934
3935 /* We don't currently bother to avoid overflow hazards here */
3936 if (sub)
3938 IntervalPGetDatum(base),
3939 IntervalPGetDatum(offset)));
3940 else
3942 IntervalPGetDatum(base),
3943 IntervalPGetDatum(offset)));
3944
3945 if (less)
3947 else
3949}
3950
3951
3952/*
3953 * Prepare state data for an interval aggregate function, that needs to compute
3954 * sum and count, in the aggregate's memory context.
3955 *
3956 * The function is used when the state data needs to be allocated in aggregate's
3957 * context. When the state data needs to be allocated in the current memory
3958 * context, we use palloc0 directly e.g. interval_avg_deserialize().
3959 */
3960static IntervalAggState *
3962{
3964 MemoryContext agg_context;
3966
3967 if (!AggCheckCallContext(fcinfo, &agg_context))
3968 elog(ERROR, "aggregate function called in non-aggregate context");
3969
3970 old_context = MemoryContextSwitchTo(agg_context);
3971
3973
3975
3976 return state;
3977}
3978
3979/*
3980 * Accumulate a new input value for interval aggregate functions.
3981 */
3982static void
3984{
3985 /* Infinite inputs are counted separately, and do not affect "N" */
3987 {
3988 state->nInfcount++;
3989 return;
3990 }
3991
3993 {
3994 state->pInfcount++;
3995 return;
3996 }
3997
3998 finite_interval_pl(&state->sumX, newval, &state->sumX);
3999 state->N++;
4000}
4001
4002/*
4003 * Remove the given interval value from the aggregated state.
4004 */
4005static void
4007{
4008 /* Infinite inputs are counted separately, and do not affect "N" */
4010 {
4011 state->nInfcount--;
4012 return;
4013 }
4014
4016 {
4017 state->pInfcount--;
4018 return;
4019 }
4020
4021 /* Handle the to-be-discarded finite value. */
4022 state->N--;
4023 if (state->N > 0)
4024 finite_interval_mi(&state->sumX, newval, &state->sumX);
4025 else
4026 {
4027 /* All values discarded, reset the state */
4028 Assert(state->N == 0);
4029 memset(&state->sumX, 0, sizeof(state->sumX));
4030 }
4031}
4032
4033/*
4034 * Transition function for sum() and avg() interval aggregates.
4035 */
4036Datum
4038{
4040
4042
4043 /* Create the state data on the first call */
4044 if (state == NULL)
4045 state = makeIntervalAggState(fcinfo);
4046
4047 if (!PG_ARGISNULL(1))
4049
4051}
4052
4053/*
4054 * Combine function for sum() and avg() interval aggregates.
4055 *
4056 * Combine the given internal aggregate states and place the combination in
4057 * the first argument.
4058 */
4059Datum
4061{
4064
4067
4068 if (state2 == NULL)
4070
4071 if (state1 == NULL)
4072 {
4073 /* manually copy all fields from state2 to state1 */
4074 state1 = makeIntervalAggState(fcinfo);
4075
4076 state1->N = state2->N;
4077 state1->pInfcount = state2->pInfcount;
4078 state1->nInfcount = state2->nInfcount;
4079
4080 state1->sumX.day = state2->sumX.day;
4081 state1->sumX.month = state2->sumX.month;
4082 state1->sumX.time = state2->sumX.time;
4083
4085 }
4086
4087 state1->N += state2->N;
4088 state1->pInfcount += state2->pInfcount;
4089 state1->nInfcount += state2->nInfcount;
4090
4091 /* Accumulate finite interval values, if any. */
4092 if (state2->N > 0)
4093 finite_interval_pl(&state1->sumX, &state2->sumX, &state1->sumX);
4094
4096}
4097
4098/*
4099 * interval_avg_serialize
4100 * Serialize IntervalAggState for interval aggregates.
4101 */
4102Datum
4104{
4107 bytea *result;
4108
4109 /* Ensure we disallow calling when not in aggregate context */
4110 if (!AggCheckCallContext(fcinfo, NULL))
4111 elog(ERROR, "aggregate function called in non-aggregate context");
4112
4114
4116
4117 /* N */
4118 pq_sendint64(&buf, state->N);
4119
4120 /* sumX */
4121 pq_sendint64(&buf, state->sumX.time);
4122 pq_sendint32(&buf, state->sumX.day);
4123 pq_sendint32(&buf, state->sumX.month);
4124
4125 /* pInfcount */
4126 pq_sendint64(&buf, state->pInfcount);
4127
4128 /* nInfcount */
4129 pq_sendint64(&buf, state->nInfcount);
4130
4131 result = pq_endtypsend(&buf);
4132
4133 PG_RETURN_BYTEA_P(result);
4134}
4135
4136/*
4137 * interval_avg_deserialize
4138 * Deserialize bytea into IntervalAggState for interval aggregates.
4139 */
4140Datum
4142{
4143 bytea *sstate;
4144 IntervalAggState *result;
4146
4147 if (!AggCheckCallContext(fcinfo, NULL))
4148 elog(ERROR, "aggregate function called in non-aggregate context");
4149
4150 sstate = PG_GETARG_BYTEA_PP(0);
4151
4152 /*
4153 * Initialize a StringInfo so that we can "receive" it using the standard
4154 * recv-function infrastructure.
4155 */
4157 VARSIZE_ANY_EXHDR(sstate));
4158
4160
4161 /* N */
4162 result->N = pq_getmsgint64(&buf);
4163
4164 /* sumX */
4165 result->sumX.time = pq_getmsgint64(&buf);
4166 result->sumX.day = pq_getmsgint(&buf, 4);
4167 result->sumX.month = pq_getmsgint(&buf, 4);
4168
4169 /* pInfcount */
4170 result->pInfcount = pq_getmsgint64(&buf);
4171
4172 /* nInfcount */
4173 result->nInfcount = pq_getmsgint64(&buf);
4174
4175 pq_getmsgend(&buf);
4176
4177 PG_RETURN_POINTER(result);
4178}
4179
4180/*
4181 * Inverse transition function for sum() and avg() interval aggregates.
4182 */
4183Datum
4185{
4187
4189
4190 /* Should not get here with no state */
4191 if (state == NULL)
4192 elog(ERROR, "interval_avg_accum_inv called with NULL state");
4193
4194 if (!PG_ARGISNULL(1))
4196
4198}
4199
4200/* avg(interval) aggregate final function */
4201Datum
4203{
4205
4207
4208 /* If there were no non-null inputs, return NULL */
4209 if (state == NULL || IA_TOTAL_COUNT(state) == 0)
4211
4212 /*
4213 * Aggregating infinities that all have the same sign produces infinity
4214 * with that sign. Aggregating infinities with different signs results in
4215 * an error.
4216 */
4217 if (state->pInfcount > 0 || state->nInfcount > 0)
4218 {
4219 Interval *result;
4220
4221 if (state->pInfcount > 0 && state->nInfcount > 0)
4222 ereport(ERROR,
4224 errmsg("interval out of range")));
4225
4226 result = palloc_object(Interval);
4227 if (state->pInfcount > 0)
4228 INTERVAL_NOEND(result);
4229 else
4230 INTERVAL_NOBEGIN(result);
4231
4232 PG_RETURN_INTERVAL_P(result);
4233 }
4234
4236 IntervalPGetDatum(&state->sumX),
4237 Float8GetDatum((double) state->N));
4238}
4239
4240/* sum(interval) aggregate final function */
4241Datum
4243{
4245 Interval *result;
4246
4248
4249 /* If there were no non-null inputs, return NULL */
4250 if (state == NULL || IA_TOTAL_COUNT(state) == 0)
4252
4253 /*
4254 * Aggregating infinities that all have the same sign produces infinity
4255 * with that sign. Aggregating infinities with different signs results in
4256 * an error.
4257 */
4258 if (state->pInfcount > 0 && state->nInfcount > 0)
4259 ereport(ERROR,
4261 errmsg("interval out of range")));
4262
4263 result = palloc_object(Interval);
4264
4265 if (state->pInfcount > 0)
4266 INTERVAL_NOEND(result);
4267 else if (state->nInfcount > 0)
4268 INTERVAL_NOBEGIN(result);
4269 else
4270 memcpy(result, &state->sumX, sizeof(Interval));
4271
4272 PG_RETURN_INTERVAL_P(result);
4273}
4274
4275/* timestamp_age()
4276 * Calculate time difference while retaining year/month fields.
4277 * Note that this does not result in an accurate absolute time span
4278 * since year and month are out of context once the arithmetic
4279 * is done.
4280 */
4281Datum
4283{
4286 Interval *result;
4287 fsec_t fsec1,
4288 fsec2;
4289 struct pg_itm tt,
4290 *tm = &tt;
4291 struct pg_tm tt1,
4292 *tm1 = &tt1;
4293 struct pg_tm tt2,
4294 *tm2 = &tt2;
4295
4296 result = palloc_object(Interval);
4297
4298 /*
4299 * Handle infinities.
4300 *
4301 * We treat anything that amounts to "infinity - infinity" as an error,
4302 * since the interval type has nothing equivalent to NaN.
4303 */
4305 {
4307 ereport(ERROR,
4309 errmsg("interval out of range")));
4310 else
4311 INTERVAL_NOBEGIN(result);
4312 }
4313 else if (TIMESTAMP_IS_NOEND(dt1))
4314 {
4316 ereport(ERROR,
4318 errmsg("interval out of range")));
4319 else
4320 INTERVAL_NOEND(result);
4321 }
4322 else if (TIMESTAMP_IS_NOBEGIN(dt2))
4323 INTERVAL_NOEND(result);
4324 else if (TIMESTAMP_IS_NOEND(dt2))
4325 INTERVAL_NOBEGIN(result);
4326 else if (timestamp2tm(dt1, NULL, tm1, &fsec1, NULL, NULL) == 0 &&
4327 timestamp2tm(dt2, NULL, tm2, &fsec2, NULL, NULL) == 0)
4328 {
4329 /* form the symbolic difference */
4330 tm->tm_usec = fsec1 - fsec2;
4331 tm->tm_sec = tm1->tm_sec - tm2->tm_sec;
4332 tm->tm_min = tm1->tm_min - tm2->tm_min;
4333 tm->tm_hour = tm1->tm_hour - tm2->tm_hour;
4334 tm->tm_mday = tm1->tm_mday - tm2->tm_mday;
4335 tm->tm_mon = tm1->tm_mon - tm2->tm_mon;
4336 tm->tm_year = tm1->tm_year - tm2->tm_year;
4337
4338 /* flip sign if necessary... */
4339 if (dt1 < dt2)
4340 {
4341 tm->tm_usec = -tm->tm_usec;
4342 tm->tm_sec = -tm->tm_sec;
4343 tm->tm_min = -tm->tm_min;
4344 tm->tm_hour = -tm->tm_hour;
4345 tm->tm_mday = -tm->tm_mday;
4346 tm->tm_mon = -tm->tm_mon;
4347 tm->tm_year = -tm->tm_year;
4348 }
4349
4350 /* propagate any negative fields into the next higher field */
4351 while (tm->tm_usec < 0)
4352 {
4353 tm->tm_usec += USECS_PER_SEC;
4354 tm->tm_sec--;
4355 }
4356
4357 while (tm->tm_sec < 0)
4358 {
4360 tm->tm_min--;
4361 }
4362
4363 while (tm->tm_min < 0)
4364 {
4366 tm->tm_hour--;
4367 }
4368
4369 while (tm->tm_hour < 0)
4370 {
4372 tm->tm_mday--;
4373 }
4374
4375 while (tm->tm_mday < 0)
4376 {
4377 if (dt1 < dt2)
4378 {
4379 tm->tm_mday += day_tab[isleap(tm1->tm_year)][tm1->tm_mon - 1];
4380 tm->tm_mon--;
4381 }
4382 else
4383 {
4384 tm->tm_mday += day_tab[isleap(tm2->tm_year)][tm2->tm_mon - 1];
4385 tm->tm_mon--;
4386 }
4387 }
4388
4389 while (tm->tm_mon < 0)
4390 {
4392 tm->tm_year--;
4393 }
4394
4395 /* recover sign if necessary... */
4396 if (dt1 < dt2)
4397 {
4398 tm->tm_usec = -tm->tm_usec;
4399 tm->tm_sec = -tm->tm_sec;
4400 tm->tm_min = -tm->tm_min;
4401 tm->tm_hour = -tm->tm_hour;
4402 tm->tm_mday = -tm->tm_mday;
4403 tm->tm_mon = -tm->tm_mon;
4404 tm->tm_year = -tm->tm_year;
4405 }
4406
4407 if (itm2interval(tm, result) != 0)
4408 ereport(ERROR,
4410 errmsg("interval out of range")));
4411 }
4412 else
4413 ereport(ERROR,
4415 errmsg("timestamp out of range")));
4416
4417 PG_RETURN_INTERVAL_P(result);
4418}
4419
4420
4421/* timestamptz_age()
4422 * Calculate time difference while retaining year/month fields.
4423 * Note that this does not result in an accurate absolute time span
4424 * since year and month are out of context once the arithmetic
4425 * is done.
4426 */
4427Datum
4429{
4432 Interval *result;
4433 fsec_t fsec1,
4434 fsec2;
4435 struct pg_itm tt,
4436 *tm = &tt;
4437 struct pg_tm tt1,
4438 *tm1 = &tt1;
4439 struct pg_tm tt2,
4440 *tm2 = &tt2;
4441 int tz1;
4442 int tz2;
4443
4444 result = palloc_object(Interval);
4445
4446 /*
4447 * Handle infinities.
4448 *
4449 * We treat anything that amounts to "infinity - infinity" as an error,
4450 * since the interval type has nothing equivalent to NaN.
4451 */
4453 {
4455 ereport(ERROR,
4457 errmsg("interval out of range")));
4458 else
4459 INTERVAL_NOBEGIN(result);
4460 }
4461 else if (TIMESTAMP_IS_NOEND(dt1))
4462 {
4464 ereport(ERROR,
4466 errmsg("interval out of range")));
4467 else
4468 INTERVAL_NOEND(result);
4469 }
4470 else if (TIMESTAMP_IS_NOBEGIN(dt2))
4471 INTERVAL_NOEND(result);
4472 else if (TIMESTAMP_IS_NOEND(dt2))
4473 INTERVAL_NOBEGIN(result);
4474 else if (timestamp2tm(dt1, &tz1, tm1, &fsec1, NULL, NULL) == 0 &&
4475 timestamp2tm(dt2, &tz2, tm2, &fsec2, NULL, NULL) == 0)
4476 {
4477 /* form the symbolic difference */
4478 tm->tm_usec = fsec1 - fsec2;
4479 tm->tm_sec = tm1->tm_sec - tm2->tm_sec;
4480 tm->tm_min = tm1->tm_min - tm2->tm_min;
4481 tm->tm_hour = tm1->tm_hour - tm2->tm_hour;
4482 tm->tm_mday = tm1->tm_mday - tm2->tm_mday;
4483 tm->tm_mon = tm1->tm_mon - tm2->tm_mon;
4484 tm->tm_year = tm1->tm_year - tm2->tm_year;
4485
4486 /* flip sign if necessary... */
4487 if (dt1 < dt2)
4488 {
4489 tm->tm_usec = -tm->tm_usec;
4490 tm->tm_sec = -tm->tm_sec;
4491 tm->tm_min = -tm->tm_min;
4492 tm->tm_hour = -tm->tm_hour;
4493 tm->tm_mday = -tm->tm_mday;
4494 tm->tm_mon = -tm->tm_mon;
4495 tm->tm_year = -tm->tm_year;
4496 }
4497
4498 /* propagate any negative fields into the next higher field */
4499 while (tm->tm_usec < 0)
4500 {
4501 tm->tm_usec += USECS_PER_SEC;
4502 tm->tm_sec--;
4503 }
4504
4505 while (tm->tm_sec < 0)
4506 {
4508 tm->tm_min--;
4509 }
4510
4511 while (tm->tm_min < 0)
4512 {
4514 tm->tm_hour--;
4515 }
4516
4517 while (tm->tm_hour < 0)
4518 {
4520 tm->tm_mday--;
4521 }
4522
4523 while (tm->tm_mday < 0)
4524 {
4525 if (dt1 < dt2)
4526 {
4527 tm->tm_mday += day_tab[isleap(tm1->tm_year)][tm1->tm_mon - 1];
4528 tm->tm_mon--;
4529 }
4530 else
4531 {
4532 tm->tm_mday += day_tab[isleap(tm2->tm_year)][tm2->tm_mon - 1];
4533 tm->tm_mon--;
4534 }
4535 }
4536
4537 while (tm->tm_mon < 0)
4538 {
4540 tm->tm_year--;
4541 }
4542
4543 /*
4544 * Note: we deliberately ignore any difference between tz1 and tz2.
4545 */
4546
4547 /* recover sign if necessary... */
4548 if (dt1 < dt2)
4549 {
4550 tm->tm_usec = -tm->tm_usec;
4551 tm->tm_sec = -tm->tm_sec;
4552 tm->tm_min = -tm->tm_min;
4553 tm->tm_hour = -tm->tm_hour;
4554 tm->tm_mday = -tm->tm_mday;
4555 tm->tm_mon = -tm->tm_mon;
4556 tm->tm_year = -tm->tm_year;
4557 }
4558
4559 if (itm2interval(tm, result) != 0)
4560 ereport(ERROR,
4562 errmsg("interval out of range")));
4563 }
4564 else
4565 ereport(ERROR,
4567 errmsg("timestamp out of range")));
4568
4569 PG_RETURN_INTERVAL_P(result);
4570}
4571
4572
4573/*----------------------------------------------------------
4574 * Conversion operators.
4575 *---------------------------------------------------------*/
4576
4577
4578/* timestamp_bin()
4579 * Bin timestamp into specified interval.
4580 */
4581Datum
4583{
4586 Timestamp origin = PG_GETARG_TIMESTAMP(2);
4587 Timestamp result,
4589 tm_diff,
4590 tm_modulo,
4591 tm_delta;
4592
4595
4596 if (TIMESTAMP_NOT_FINITE(origin))
4597 ereport(ERROR,
4599 errmsg("origin out of range")));
4600
4602 ereport(ERROR,
4604 errmsg("timestamps cannot be binned into infinite intervals")));
4605
4606 if (stride->month != 0)
4607 ereport(ERROR,
4609 errmsg("timestamps cannot be binned into intervals containing months or years")));
4610
4613 ereport(ERROR,
4615 errmsg("interval out of range")));
4616
4617 if (stride_usecs <= 0)
4618 ereport(ERROR,
4620 errmsg("stride must be greater than zero")));
4621
4623 ereport(ERROR,
4625 errmsg("interval out of range")));
4626
4627 /* These calculations cannot overflow */
4630 result = origin + tm_delta;
4631
4632 /*
4633 * We want to round towards -infinity, not 0, when tm_diff is negative and
4634 * not a multiple of stride_usecs. This adjustment *can* cause overflow,
4635 * since the result might now be out of the range origin .. timestamp.
4636 */
4637 if (tm_modulo < 0)
4638 {
4639 if (unlikely(pg_sub_s64_overflow(result, stride_usecs, &result)) ||
4640 !IS_VALID_TIMESTAMP(result))
4641 ereport(ERROR,
4643 errmsg("timestamp out of range")));
4644 }
4645
4646 PG_RETURN_TIMESTAMP(result);
4647}
4648
4649/* timestamp_trunc()
4650 * Truncate timestamp to specified units.
4651 */
4652Datum
4654{
4657 Timestamp result;
4658 int type,
4659 val;
4660 char *lowunits;
4661 fsec_t fsec;
4662 struct pg_tm tt,
4663 *tm = &tt;
4664
4667 false);
4668
4669 type = DecodeUnits(0, lowunits, &val);
4670
4671 if (type == UNITS)
4672 {
4674 {
4675 /*
4676 * Errors thrown here for invalid units should exactly match those
4677 * below, else there will be unexpected discrepancies between
4678 * finite- and infinite-input cases.
4679 */
4680 switch (val)
4681 {
4682 case DTK_WEEK:
4683 case DTK_MILLENNIUM:
4684 case DTK_CENTURY:
4685 case DTK_DECADE:
4686 case DTK_YEAR:
4687 case DTK_QUARTER:
4688 case DTK_MONTH:
4689 case DTK_DAY:
4690 case DTK_HOUR:
4691 case DTK_MINUTE:
4692 case DTK_SECOND:
4693 case DTK_MILLISEC:
4694 case DTK_MICROSEC:
4696 break;
4697 default:
4698 ereport(ERROR,
4700 errmsg("unit \"%s\" not supported for type %s",
4702 result = 0;
4703 }
4704 }
4705
4706 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
4707 ereport(ERROR,
4709 errmsg("timestamp out of range")));
4710
4711 switch (val)
4712 {
4713 case DTK_WEEK:
4714 {
4715 int woy;
4716
4718
4719 /*
4720 * If it is week 52/53 and the month is January, then the
4721 * week must belong to the previous year. Also, some
4722 * December dates belong to the next year.
4723 */
4724 if (woy >= 52 && tm->tm_mon == 1)
4725 --tm->tm_year;
4727 ++tm->tm_year;
4728 isoweek2date(woy, &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
4729 tm->tm_hour = 0;
4730 tm->tm_min = 0;
4731 tm->tm_sec = 0;
4732 fsec = 0;
4733 break;
4734 }
4735 case DTK_MILLENNIUM:
4736 /* see comments in timestamptz_trunc */
4737 if (tm->tm_year > 0)
4738 tm->tm_year = ((tm->tm_year + 999) / 1000) * 1000 - 999;
4739 else
4740 tm->tm_year = -((999 - (tm->tm_year - 1)) / 1000) * 1000 + 1;
4742 case DTK_CENTURY:
4743 /* see comments in timestamptz_trunc */
4744 if (tm->tm_year > 0)
4745 tm->tm_year = ((tm->tm_year + 99) / 100) * 100 - 99;
4746 else
4747 tm->tm_year = -((99 - (tm->tm_year - 1)) / 100) * 100 + 1;
4749 case DTK_DECADE:
4750 /* see comments in timestamptz_trunc */
4751 if (val != DTK_MILLENNIUM && val != DTK_CENTURY)
4752 {
4753 if (tm->tm_year > 0)
4754 tm->tm_year = (tm->tm_year / 10) * 10;
4755 else
4756 tm->tm_year = -((8 - (tm->tm_year - 1)) / 10) * 10;
4757 }
4759 case DTK_YEAR:
4760 tm->tm_mon = 1;
4762 case DTK_QUARTER:
4763 tm->tm_mon = (3 * ((tm->tm_mon - 1) / 3)) + 1;
4765 case DTK_MONTH:
4766 tm->tm_mday = 1;
4768 case DTK_DAY:
4769 tm->tm_hour = 0;
4771 case DTK_HOUR:
4772 tm->tm_min = 0;
4774 case DTK_MINUTE:
4775 tm->tm_sec = 0;
4777 case DTK_SECOND:
4778 fsec = 0;
4779 break;
4780
4781 case DTK_MILLISEC:
4782 fsec = (fsec / 1000) * 1000;
4783 break;
4784
4785 case DTK_MICROSEC:
4786 break;
4787
4788 default:
4789 ereport(ERROR,
4791 errmsg("unit \"%s\" not supported for type %s",
4793 result = 0;
4794 }
4795
4796 if (tm2timestamp(tm, fsec, NULL, &result) != 0)
4797 ereport(ERROR,
4799 errmsg("timestamp out of range")));
4800 }
4801 else
4802 {
4803 ereport(ERROR,
4805 errmsg("unit \"%s\" not recognized for type %s",
4807 result = 0;
4808 }
4809
4810 PG_RETURN_TIMESTAMP(result);
4811}
4812
4813/* timestamptz_bin()
4814 * Bin timestamptz into specified interval using specified origin.
4815 */
4816Datum
4818{
4822 TimestampTz result,
4824 tm_diff,
4825 tm_modulo,
4826 tm_delta;
4827
4830
4831 if (TIMESTAMP_NOT_FINITE(origin))
4832 ereport(ERROR,
4834 errmsg("origin out of range")));
4835
4837 ereport(ERROR,
4839 errmsg("timestamps cannot be binned into infinite intervals")));
4840
4841 if (stride->month != 0)
4842 ereport(ERROR,
4844 errmsg("timestamps cannot be binned into intervals containing months or years")));
4845
4848 ereport(ERROR,
4850 errmsg("interval out of range")));
4851
4852 if (stride_usecs <= 0)
4853 ereport(ERROR,
4855 errmsg("stride must be greater than zero")));
4856
4858 ereport(ERROR,
4860 errmsg("interval out of range")));
4861
4862 /* These calculations cannot overflow */
4865 result = origin + tm_delta;
4866
4867 /*
4868 * We want to round towards -infinity, not 0, when tm_diff is negative and
4869 * not a multiple of stride_usecs. This adjustment *can* cause overflow,
4870 * since the result might now be out of the range origin .. timestamp.
4871 */
4872 if (tm_modulo < 0)
4873 {
4874 if (unlikely(pg_sub_s64_overflow(result, stride_usecs, &result)) ||
4875 !IS_VALID_TIMESTAMP(result))
4876 ereport(ERROR,
4878 errmsg("timestamp out of range")));
4879 }
4880
4881 PG_RETURN_TIMESTAMPTZ(result);
4882}
4883
4884/*
4885 * Common code for timestamptz_trunc() and timestamptz_trunc_zone().
4886 *
4887 * tzp identifies the zone to truncate with respect to. We assume
4888 * infinite timestamps have already been rejected.
4889 */
4890static TimestampTz
4892{
4893 TimestampTz result;
4894 int tz;
4895 int type,
4896 val;
4897 bool redotz = false;
4898 char *lowunits;
4899 fsec_t fsec;
4900 struct pg_tm tt,
4901 *tm = &tt;
4902
4905 false);
4906
4907 type = DecodeUnits(0, lowunits, &val);
4908
4909 if (type == UNITS)
4910 {
4912 {
4913 /*
4914 * Errors thrown here for invalid units should exactly match those
4915 * below, else there will be unexpected discrepancies between
4916 * finite- and infinite-input cases.
4917 */
4918 switch (val)
4919 {
4920 case DTK_WEEK:
4921 case DTK_MILLENNIUM:
4922 case DTK_CENTURY:
4923 case DTK_DECADE:
4924 case DTK_YEAR:
4925 case DTK_QUARTER:
4926 case DTK_MONTH:
4927 case DTK_DAY:
4928 case DTK_HOUR:
4929 case DTK_MINUTE:
4930 case DTK_SECOND:
4931 case DTK_MILLISEC:
4932 case DTK_MICROSEC:
4933 return timestamp;
4934 break;
4935
4936 default:
4937 ereport(ERROR,
4939 errmsg("unit \"%s\" not supported for type %s",
4941 result = 0;
4942 }
4943 }
4944
4945 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, tzp) != 0)
4946 ereport(ERROR,
4948 errmsg("timestamp out of range")));
4949
4950 switch (val)
4951 {
4952 case DTK_WEEK:
4953 {
4954 int woy;
4955
4957
4958 /*
4959 * If it is week 52/53 and the month is January, then the
4960 * week must belong to the previous year. Also, some
4961 * December dates belong to the next year.
4962 */
4963 if (woy >= 52 && tm->tm_mon == 1)
4964 --tm->tm_year;
4966 ++tm->tm_year;
4967 isoweek2date(woy, &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
4968 tm->tm_hour = 0;
4969 tm->tm_min = 0;
4970 tm->tm_sec = 0;
4971 fsec = 0;
4972 redotz = true;
4973 break;
4974 }
4975 /* one may consider DTK_THOUSAND and DTK_HUNDRED... */
4976 case DTK_MILLENNIUM:
4977
4978 /*
4979 * truncating to the millennium? what is this supposed to
4980 * mean? let us put the first year of the millennium... i.e.
4981 * -1000, 1, 1001, 2001...
4982 */
4983 if (tm->tm_year > 0)
4984 tm->tm_year = ((tm->tm_year + 999) / 1000) * 1000 - 999;
4985 else
4986 tm->tm_year = -((999 - (tm->tm_year - 1)) / 1000) * 1000 + 1;
4988 case DTK_CENTURY:
4989 /* truncating to the century? as above: -100, 1, 101... */
4990 if (tm->tm_year > 0)
4991 tm->tm_year = ((tm->tm_year + 99) / 100) * 100 - 99;
4992 else
4993 tm->tm_year = -((99 - (tm->tm_year - 1)) / 100) * 100 + 1;
4995 case DTK_DECADE:
4996
4997 /*
4998 * truncating to the decade? first year of the decade. must
4999 * not be applied if year was truncated before!
5000 */
5001 if (val != DTK_MILLENNIUM && val != DTK_CENTURY)
5002 {
5003 if (tm->tm_year > 0)
5004 tm->tm_year = (tm->tm_year / 10) * 10;
5005 else
5006 tm->tm_year = -((8 - (tm->tm_year - 1)) / 10) * 10;
5007 }
5009 case DTK_YEAR:
5010 tm->tm_mon = 1;
5012 case DTK_QUARTER:
5013 tm->tm_mon = (3 * ((tm->tm_mon - 1) / 3)) + 1;
5015 case DTK_MONTH:
5016 tm->tm_mday = 1;
5018 case DTK_DAY:
5019 tm->tm_hour = 0;
5020 redotz = true; /* for all cases >= DAY */
5022 case DTK_HOUR:
5023 tm->tm_min = 0;
5025 case DTK_MINUTE:
5026 tm->tm_sec = 0;
5028 case DTK_SECOND:
5029 fsec = 0;
5030 break;
5031 case DTK_MILLISEC:
5032 fsec = (fsec / 1000) * 1000;
5033 break;
5034 case DTK_MICROSEC:
5035 break;
5036
5037 default:
5038 ereport(ERROR,
5040 errmsg("unit \"%s\" not supported for type %s",
5042 result = 0;
5043 }
5044
5045 if (redotz)
5046 tz = DetermineTimeZoneOffset(tm, tzp);
5047
5048 if (tm2timestamp(tm, fsec, &tz, &result) != 0)
5049 ereport(ERROR,
5051 errmsg("timestamp out of range")));
5052 }
5053 else
5054 {
5055 ereport(ERROR,
5057 errmsg("unit \"%s\" not recognized for type %s",
5059 result = 0;
5060 }
5061
5062 return result;
5063}
5064
5065/* timestamptz_trunc()
5066 * Truncate timestamptz to specified units in session timezone.
5067 */
5068Datum
5079
5080/* timestamptz_trunc_zone()
5081 * Truncate timestamptz to specified units in specified timezone.
5082 */
5083Datum
5085{
5089 TimestampTz result;
5090 pg_tz *tzp;
5091
5092 /*
5093 * Look up the requested timezone.
5094 */
5095 tzp = lookup_timezone(zone);
5096
5098
5099 PG_RETURN_TIMESTAMPTZ(result);
5100}
5101
5102/* interval_trunc()
5103 * Extract specified field from interval.
5104 */
5105Datum
5107{
5110 Interval *result;
5111 int type,
5112 val;
5113 char *lowunits;
5114 struct pg_itm tt,
5115 *tm = &tt;
5116
5117 result = palloc_object(Interval);
5118
5121 false);
5122
5123 type = DecodeUnits(0, lowunits, &val);
5124
5125 if (type == UNITS)
5126 {
5128 {
5129 /*
5130 * Errors thrown here for invalid units should exactly match those
5131 * below, else there will be unexpected discrepancies between
5132 * finite- and infinite-input cases.
5133 */
5134 switch (val)
5135 {
5136 case DTK_MILLENNIUM:
5137 case DTK_CENTURY:
5138 case DTK_DECADE:
5139 case DTK_YEAR:
5140 case DTK_QUARTER:
5141 case DTK_MONTH:
5142 case DTK_DAY:
5143 case DTK_HOUR:
5144 case DTK_MINUTE:
5145 case DTK_SECOND:
5146 case DTK_MILLISEC:
5147 case DTK_MICROSEC:
5148 memcpy(result, interval, sizeof(Interval));
5149 PG_RETURN_INTERVAL_P(result);
5150 break;
5151
5152 default:
5153 ereport(ERROR,
5155 errmsg("unit \"%s\" not supported for type %s",
5157 (val == DTK_WEEK) ? errdetail("Months usually have fractional weeks.") : 0));
5158 result = NULL;
5159 }
5160 }
5161
5163 switch (val)
5164 {
5165 case DTK_MILLENNIUM:
5166 /* caution: C division may have negative remainder */
5167 tm->tm_year = (tm->tm_year / 1000) * 1000;
5169 case DTK_CENTURY:
5170 /* caution: C division may have negative remainder */
5171 tm->tm_year = (tm->tm_year / 100) * 100;
5173 case DTK_DECADE:
5174 /* caution: C division may have negative remainder */
5175 tm->tm_year = (tm->tm_year / 10) * 10;
5177 case DTK_YEAR:
5178 tm->tm_mon = 0;
5180 case DTK_QUARTER:
5181 tm->tm_mon = 3 * (tm->tm_mon / 3);
5183 case DTK_MONTH:
5184 tm->tm_mday = 0;
5186 case DTK_DAY:
5187 tm->tm_hour = 0;
5189 case DTK_HOUR:
5190 tm->tm_min = 0;
5192 case DTK_MINUTE:
5193 tm->tm_sec = 0;
5195 case DTK_SECOND:
5196 tm->tm_usec = 0;
5197 break;
5198 case DTK_MILLISEC:
5199 tm->tm_usec = (tm->tm_usec / 1000) * 1000;
5200 break;
5201 case DTK_MICROSEC:
5202 break;
5203
5204 default:
5205 ereport(ERROR,
5207 errmsg("unit \"%s\" not supported for type %s",
5209 (val == DTK_WEEK) ? errdetail("Months usually have fractional weeks.") : 0));
5210 }
5211
5212 if (itm2interval(tm, result) != 0)
5213 ereport(ERROR,
5215 errmsg("interval out of range")));
5216 }
5217 else
5218 {
5219 ereport(ERROR,
5221 errmsg("unit \"%s\" not recognized for type %s",
5223 }
5224
5225 PG_RETURN_INTERVAL_P(result);
5226}
5227
5228/* isoweek2j()
5229 *
5230 * Return the Julian day which corresponds to the first day (Monday) of the given ISO 8601 year and week.
5231 * Julian days are used to convert between ISO week dates and Gregorian dates.
5232 *
5233 * XXX: This function has integer overflow hazards, but restructuring it to
5234 * work with the soft-error handling that its callers do is likely more
5235 * trouble than it's worth.
5236 */
5237int
5238isoweek2j(int year, int week)
5239{
5240 int day0,
5241 day4;
5242
5243 /* fourth day of current year */
5244 day4 = date2j(year, 1, 4);
5245
5246 /* day0 == offset to first day of week (Monday) */
5247 day0 = j2day(day4 - 1);
5248
5249 return ((week - 1) * 7) + (day4 - day0);
5250}
5251
5252/* isoweek2date()
5253 * Convert ISO week of year number to date.
5254 * The year field must be specified with the ISO year!
5255 * karel 2000/08/07
5256 */
5257void
5258isoweek2date(int woy, int *year, int *mon, int *mday)
5259{
5260 j2date(isoweek2j(*year, woy), year, mon, mday);
5261}
5262
5263/* isoweekdate2date()
5264 *
5265 * Convert an ISO 8601 week date (ISO year, ISO week) into a Gregorian date.
5266 * Gregorian day of week sent so weekday strings can be supplied.
5267 * Populates year, mon, and mday with the correct Gregorian values.
5268 * year must be passed in as the ISO year.
5269 */
5270void
5271isoweekdate2date(int isoweek, int wday, int *year, int *mon, int *mday)
5272{
5273 int jday;
5274
5275 jday = isoweek2j(*year, isoweek);
5276 /* convert Gregorian week start (Sunday=1) to ISO week start (Monday=1) */
5277 if (wday > 1)
5278 jday += wday - 2;
5279 else
5280 jday += 6;
5281 j2date(jday, year, mon, mday);
5282}
5283
5284/* date2isoweek()
5285 *
5286 * Returns ISO week number of year.
5287 */
5288int
5289date2isoweek(int year, int mon, int mday)
5290{
5291 int day0,
5292 day4,
5293 dayn,
5294 week;
5295
5296 /* current day */
5297 dayn = date2j(year, mon, mday);
5298
5299 /* fourth day of current year */
5300 day4 = date2j(year, 1, 4);
5301
5302 /* day0 == offset to first day of week (Monday) */
5303 day0 = j2day(day4 - 1);
5304
5305 /*
5306 * We need the first week containing a Thursday, otherwise this day falls
5307 * into the previous year for purposes of counting weeks
5308 */
5309 if (dayn < day4 - day0)
5310 {
5311 day4 = date2j(year - 1, 1, 4);
5312
5313 /* day0 == offset to first day of week (Monday) */
5314 day0 = j2day(day4 - 1);
5315 }
5316
5317 week = (dayn - (day4 - day0)) / 7 + 1;
5318
5319 /*
5320 * Sometimes the last few days in a year will fall into the first week of
5321 * the next year, so check for this.
5322 */
5323 if (week >= 52)
5324 {
5325 day4 = date2j(year + 1, 1, 4);
5326
5327 /* day0 == offset to first day of week (Monday) */
5328 day0 = j2day(day4 - 1);
5329
5330 if (dayn >= day4 - day0)
5331 week = (dayn - (day4 - day0)) / 7 + 1;
5332 }
5333
5334 return week;
5335}
5336
5337
5338/* date2isoyear()
5339 *
5340 * Returns ISO 8601 year number.
5341 * Note: zero or negative results follow the year-zero-exists convention.
5342 */
5343int
5344date2isoyear(int year, int mon, int mday)
5345{
5346 int day0,
5347 day4,
5348 dayn,
5349 week;
5350
5351 /* current day */
5352 dayn = date2j(year, mon, mday);
5353
5354 /* fourth day of current year */
5355 day4 = date2j(year, 1, 4);
5356
5357 /* day0 == offset to first day of week (Monday) */
5358 day0 = j2day(day4 - 1);
5359
5360 /*
5361 * We need the first week containing a Thursday, otherwise this day falls
5362 * into the previous year for purposes of counting weeks
5363 */
5364 if (dayn < day4 - day0)
5365 {
5366 day4 = date2j(year - 1, 1, 4);
5367
5368 /* day0 == offset to first day of week (Monday) */
5369 day0 = j2day(day4 - 1);
5370
5371 year--;
5372 }
5373
5374 week = (dayn - (day4 - day0)) / 7 + 1;
5375
5376 /*
5377 * Sometimes the last few days in a year will fall into the first week of
5378 * the next year, so check for this.
5379 */
5380 if (week >= 52)
5381 {
5382 day4 = date2j(year + 1, 1, 4);
5383
5384 /* day0 == offset to first day of week (Monday) */
5385 day0 = j2day(day4 - 1);
5386
5387 if (dayn >= day4 - day0)
5388 year++;
5389 }
5390
5391 return year;
5392}
5393
5394
5395/* date2isoyearday()
5396 *
5397 * Returns the ISO 8601 day-of-year, given a Gregorian year, month and day.
5398 * Possible return values are 1 through 371 (364 in non-leap years).
5399 */
5400int
5401date2isoyearday(int year, int mon, int mday)
5402{
5403 return date2j(year, mon, mday) - isoweek2j(date2isoyear(year, mon, mday), 1) + 1;
5404}
5405
5406/*
5407 * NonFiniteTimestampTzPart
5408 *
5409 * Used by timestamp_part and timestamptz_part when extracting from infinite
5410 * timestamp[tz]. Returns +/-Infinity if that is the appropriate result,
5411 * otherwise returns zero (which should be taken as meaning to return NULL).
5412 *
5413 * Errors thrown here for invalid units should exactly match those that
5414 * would be thrown in the calling functions, else there will be unexpected
5415 * discrepancies between finite- and infinite-input cases.
5416 */
5417static float8
5419 bool isNegative, bool isTz)
5420{
5421 if ((type != UNITS) && (type != RESERV))
5422 ereport(ERROR,
5424 errmsg("unit \"%s\" not recognized for type %s",
5425 lowunits,
5427
5428 switch (unit)
5429 {
5430 /* Oscillating units */
5431 case DTK_MICROSEC:
5432 case DTK_MILLISEC:
5433 case DTK_SECOND:
5434 case DTK_MINUTE:
5435 case DTK_HOUR:
5436 case DTK_DAY:
5437 case DTK_MONTH:
5438 case DTK_QUARTER:
5439 case DTK_WEEK:
5440 case DTK_DOW:
5441 case DTK_ISODOW:
5442 case DTK_DOY:
5443 case DTK_TZ:
5444 case DTK_TZ_MINUTE:
5445 case DTK_TZ_HOUR:
5446 return 0.0;
5447
5448 /* Monotonically-increasing units */
5449 case DTK_YEAR:
5450 case DTK_DECADE:
5451 case DTK_CENTURY:
5452 case DTK_MILLENNIUM:
5453 case DTK_JULIAN:
5454 case DTK_ISOYEAR:
5455 case DTK_EPOCH:
5456 if (isNegative)
5457 return -get_float8_infinity();
5458 else
5459 return get_float8_infinity();
5460
5461 default:
5462 ereport(ERROR,
5464 errmsg("unit \"%s\" not supported for type %s",
5465 lowunits,
5467 return 0.0; /* keep compiler quiet */
5468 }
5469}
5470
5471/* timestamp_part() and extract_timestamp()
5472 * Extract specified field from timestamp.
5473 */
5474static Datum
5476{
5481 int type,
5482 val;
5483 char *lowunits;
5484 fsec_t fsec;
5485 struct pg_tm tt,
5486 *tm = &tt;
5487
5490 false);
5491
5492 type = DecodeUnits(0, lowunits, &val);
5493 if (type == UNKNOWN_FIELD)
5495
5497 {
5500 false);
5501
5502 if (r != 0.0)
5503 {
5504 if (retnumeric)
5505 {
5506 if (r < 0)
5508 CStringGetDatum("-Infinity"),
5510 Int32GetDatum(-1));
5511 else if (r > 0)
5513 CStringGetDatum("Infinity"),
5515 Int32GetDatum(-1));
5516 }
5517 else
5519 }
5520 else
5522 }
5523
5524 if (type == UNITS)
5525 {
5526 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
5527 ereport(ERROR,
5529 errmsg("timestamp out of range")));
5530
5531 switch (val)
5532 {
5533 case DTK_MICROSEC:
5534 intresult = tm->tm_sec * INT64CONST(1000000) + fsec;
5535 break;
5536
5537 case DTK_MILLISEC:
5538 if (retnumeric)
5539 /*---
5540 * tm->tm_sec * 1000 + fsec / 1000
5541 * = (tm->tm_sec * 1'000'000 + fsec) / 1000
5542 */
5544 else
5545 PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + fsec / 1000.0);
5546 break;
5547
5548 case DTK_SECOND:
5549 if (retnumeric)
5550 /*---
5551 * tm->tm_sec + fsec / 1'000'000
5552 * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
5553 */
5555 else
5556 PG_RETURN_FLOAT8(tm->tm_sec + fsec / 1000000.0);
5557 break;
5558
5559 case DTK_MINUTE:
5560 intresult = tm->tm_min;
5561 break;
5562
5563 case DTK_HOUR:
5564 intresult = tm->tm_hour;
5565 break;
5566
5567 case DTK_DAY:
5568 intresult = tm->tm_mday;
5569 break;
5570
5571 case DTK_MONTH:
5572 intresult = tm->tm_mon;
5573 break;
5574
5575 case DTK_QUARTER:
5576 intresult = (tm->tm_mon - 1) / 3 + 1;
5577 break;
5578
5579 case DTK_WEEK:
5581 break;
5582
5583 case DTK_YEAR:
5584 if (tm->tm_year > 0)
5585 intresult = tm->tm_year;
5586 else
5587 /* there is no year 0, just 1 BC and 1 AD */
5588 intresult = tm->tm_year - 1;
5589 break;
5590
5591 case DTK_DECADE:
5592
5593 /*
5594 * what is a decade wrt dates? let us assume that decade 199
5595 * is 1990 thru 1999... decade 0 starts on year 1 BC, and -1
5596 * is 11 BC thru 2 BC...
5597 */
5598 if (tm->tm_year >= 0)
5599 intresult = tm->tm_year / 10;
5600 else
5601 intresult = -((8 - (tm->tm_year - 1)) / 10);
5602 break;
5603
5604 case DTK_CENTURY:
5605
5606 /* ----
5607 * centuries AD, c>0: year in [ (c-1)* 100 + 1 : c*100 ]
5608 * centuries BC, c<0: year in [ c*100 : (c+1) * 100 - 1]
5609 * there is no number 0 century.
5610 * ----
5611 */
5612 if (tm->tm_year > 0)
5613 intresult = (tm->tm_year + 99) / 100;
5614 else
5615 /* caution: C division may have negative remainder */
5616 intresult = -((99 - (tm->tm_year - 1)) / 100);
5617 break;
5618
5619 case DTK_MILLENNIUM:
5620 /* see comments above. */
5621 if (tm->tm_year > 0)
5622 intresult = (tm->tm_year + 999) / 1000;
5623 else
5624 intresult = -((999 - (tm->tm_year - 1)) / 1000);
5625 break;
5626
5627 case DTK_JULIAN:
5628 if (retnumeric)
5632 NULL),
5633 NULL));
5634 else
5637 tm->tm_sec + (fsec / 1000000.0)) / (double) SECS_PER_DAY);
5638 break;
5639
5640 case DTK_ISOYEAR:
5642 /* Adjust BC years */
5643 if (intresult <= 0)
5644 intresult -= 1;
5645 break;
5646
5647 case DTK_DOW:
5648 case DTK_ISODOW:
5650 if (val == DTK_ISODOW && intresult == 0)
5651 intresult = 7;
5652 break;
5653
5654 case DTK_DOY:
5656 - date2j(tm->tm_year, 1, 1) + 1);
5657 break;
5658
5659 case DTK_TZ:
5660 case DTK_TZ_MINUTE:
5661 case DTK_TZ_HOUR:
5662 default:
5663 ereport(ERROR,
5665 errmsg("unit \"%s\" not supported for type %s",
5667 intresult = 0;
5668 }
5669 }
5670 else if (type == RESERV)
5671 {
5672 switch (val)
5673 {
5674 case DTK_EPOCH:
5676 /* (timestamp - epoch) / 1000000 */
5677 if (retnumeric)
5678 {
5679 Numeric result;
5680
5681 if (timestamp < (PG_INT64_MAX + epoch))
5683 else
5684 {
5687 NULL),
5688 int64_to_numeric(1000000),
5689 NULL);
5691 NumericGetDatum(result),
5692 Int32GetDatum(6)));
5693 }
5694 PG_RETURN_NUMERIC(result);
5695 }
5696 else
5697 {
5698 float8 result;
5699
5700 /* try to avoid precision loss in subtraction */
5701 if (timestamp < (PG_INT64_MAX + epoch))
5702 result = (timestamp - epoch) / 1000000.0;
5703 else
5704 result = ((float8) timestamp - epoch) / 1000000.0;
5705 PG_RETURN_FLOAT8(result);
5706 }
5707 break;
5708
5709 default:
5710 ereport(ERROR,
5712 errmsg("unit \"%s\" not supported for type %s",
5714 intresult = 0;
5715 }
5716 }
5717 else
5718 {
5719 ereport(ERROR,
5721 errmsg("unit \"%s\" not recognized for type %s",
5723 intresult = 0;
5724 }
5725
5726 if (retnumeric)
5728 else
5730}
5731
5732Datum
5734{
5735 return timestamp_part_common(fcinfo, false);
5736}
5737
5738Datum
5740{
5741 return timestamp_part_common(fcinfo, true);
5742}
5743
5744/* timestamptz_part() and extract_timestamptz()
5745 * Extract specified field from timestamp with time zone.
5746 */
5747static Datum
5749{
5754 int tz;
5755 int type,
5756 val;
5757 char *lowunits;
5758 fsec_t fsec;
5759 struct pg_tm tt,
5760 *tm = &tt;
5761
5764 false);
5765
5766 type = DecodeUnits(0, lowunits, &val);
5767 if (type == UNKNOWN_FIELD)
5769
5771 {
5774 true);
5775
5776 if (r != 0.0)
5777 {
5778 if (retnumeric)
5779 {
5780 if (r < 0)
5782 CStringGetDatum("-Infinity"),
5784 Int32GetDatum(-1));
5785 else if (r > 0)
5787 CStringGetDatum("Infinity"),
5789 Int32GetDatum(-1));
5790 }
5791 else
5793 }
5794 else
5796 }
5797
5798 if (type == UNITS)
5799 {
5800 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
5801 ereport(ERROR,
5803 errmsg("timestamp out of range")));
5804
5805 switch (val)
5806 {
5807 case DTK_TZ:
5808 intresult = -tz;
5809 break;
5810
5811 case DTK_TZ_MINUTE:
5813 break;
5814
5815 case DTK_TZ_HOUR:
5816 intresult = -tz / SECS_PER_HOUR;
5817 break;
5818
5819 case DTK_MICROSEC:
5820 intresult = tm->tm_sec * INT64CONST(1000000) + fsec;
5821 break;
5822
5823 case DTK_MILLISEC:
5824 if (retnumeric)
5825 /*---
5826 * tm->tm_sec * 1000 + fsec / 1000
5827 * = (tm->tm_sec * 1'000'000 + fsec) / 1000
5828 */
5830 else
5831 PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + fsec / 1000.0);
5832 break;
5833
5834 case DTK_SECOND:
5835 if (retnumeric)
5836 /*---
5837 * tm->tm_sec + fsec / 1'000'000
5838 * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
5839 */
5841 else
5842 PG_RETURN_FLOAT8(tm->tm_sec + fsec / 1000000.0);
5843 break;
5844
5845 case DTK_MINUTE:
5846 intresult = tm->tm_min;
5847 break;
5848
5849 case DTK_HOUR:
5850 intresult = tm->tm_hour;
5851 break;
5852
5853 case DTK_DAY:
5854 intresult = tm->tm_mday;
5855 break;
5856
5857 case DTK_MONTH:
5858 intresult = tm->tm_mon;
5859 break;
5860
5861 case DTK_QUARTER:
5862 intresult = (tm->tm_mon - 1) / 3 + 1;
5863 break;
5864
5865 case DTK_WEEK:
5867 break;
5868
5869 case DTK_YEAR:
5870 if (tm->tm_year > 0)
5871 intresult = tm->tm_year;
5872 else
5873 /* there is no year 0, just 1 BC and 1 AD */
5874 intresult = tm->tm_year - 1;
5875 break;
5876
5877 case DTK_DECADE:
5878 /* see comments in timestamp_part */
5879 if (tm->tm_year > 0)
5880 intresult = tm->tm_year / 10;
5881 else
5882 intresult = -((8 - (tm->tm_year - 1)) / 10);
5883 break;
5884
5885 case DTK_CENTURY:
5886 /* see comments in timestamp_part */
5887 if (tm->tm_year > 0)
5888 intresult = (tm->tm_year + 99) / 100;
5889 else
5890 intresult = -((99 - (tm->tm_year - 1)) / 100);
5891 break;
5892
5893 case DTK_MILLENNIUM:
5894 /* see comments in timestamp_part */
5895 if (tm->tm_year > 0)
5896 intresult = (tm->tm_year + 999) / 1000;
5897 else
5898 intresult = -((999 - (tm->tm_year - 1)) / 1000);
5899 break;
5900
5901 case DTK_JULIAN:
5902 if (retnumeric)
5906 NULL),
5907 NULL));
5908 else
5911 tm->tm_sec + (fsec / 1000000.0)) / (double) SECS_PER_DAY);
5912 break;
5913
5914 case DTK_ISOYEAR:
5916 /* Adjust BC years */
5917 if (intresult <= 0)
5918 intresult -= 1;
5919 break;
5920
5921 case DTK_DOW:
5922 case DTK_ISODOW:
5924 if (val == DTK_ISODOW && intresult == 0)
5925 intresult = 7;
5926 break;
5927
5928 case DTK_DOY:
5930 - date2j(tm->tm_year, 1, 1) + 1);
5931 break;
5932
5933 default:
5934 ereport(ERROR,
5936 errmsg("unit \"%s\" not supported for type %s",
5938 intresult = 0;
5939 }
5940 }
5941 else if (type == RESERV)
5942 {
5943 switch (val)
5944 {
5945 case DTK_EPOCH:
5947 /* (timestamp - epoch) / 1000000 */
5948 if (retnumeric)
5949 {
5950 Numeric result;
5951
5952 if (timestamp < (PG_INT64_MAX + epoch))
5954 else
5955 {
5958 NULL),
5959 int64_to_numeric(1000000),
5960 NULL);
5962 NumericGetDatum(result),
5963 Int32GetDatum(6)));
5964 }
5965 PG_RETURN_NUMERIC(result);
5966 }
5967 else
5968 {
5969 float8 result;
5970
5971 /* try to avoid precision loss in subtraction */
5972 if (timestamp < (PG_INT64_MAX + epoch))
5973 result = (timestamp - epoch) / 1000000.0;
5974 else
5975 result = ((float8) timestamp - epoch) / 1000000.0;
5976 PG_RETURN_FLOAT8(result);
5977 }
5978 break;
5979
5980 default:
5981 ereport(ERROR,
5983 errmsg("unit \"%s\" not supported for type %s",
5985 intresult = 0;
5986 }
5987 }
5988 else
5989 {
5990 ereport(ERROR,
5992 errmsg("unit \"%s\" not recognized for type %s",
5994
5995 intresult = 0;
5996 }
5997
5998 if (retnumeric)
6000 else
6002}
6003
6004Datum
6006{
6007 return timestamptz_part_common(fcinfo, false);
6008}
6009
6010Datum
6012{
6013 return timestamptz_part_common(fcinfo, true);
6014}
6015
6016/*
6017 * NonFiniteIntervalPart
6018 *
6019 * Used by interval_part when extracting from infinite interval. Returns
6020 * +/-Infinity if that is the appropriate result, otherwise returns zero
6021 * (which should be taken as meaning to return NULL).
6022 *
6023 * Errors thrown here for invalid units should exactly match those that
6024 * would be thrown in the calling functions, else there will be unexpected
6025 * discrepancies between finite- and infinite-input cases.
6026 */
6027static float8
6029{
6030 if ((type != UNITS) && (type != RESERV))
6031 ereport(ERROR,
6033 errmsg("unit \"%s\" not recognized for type %s",
6035
6036 switch (unit)
6037 {
6038 /* Oscillating units */
6039 case DTK_MICROSEC:
6040 case DTK_MILLISEC:
6041 case DTK_SECOND:
6042 case DTK_MINUTE:
6043 case DTK_WEEK:
6044 case DTK_MONTH:
6045 case DTK_QUARTER:
6046 return 0.0;
6047
6048 /* Monotonically-increasing units */
6049 case DTK_HOUR:
6050 case DTK_DAY:
6051 case DTK_YEAR:
6052 case DTK_DECADE:
6053 case DTK_CENTURY:
6054 case DTK_MILLENNIUM:
6055 case DTK_EPOCH:
6056 if (isNegative)
6057 return -get_float8_infinity();
6058 else
6059 return get_float8_infinity();
6060
6061 default:
6062 ereport(ERROR,
6064 errmsg("unit \"%s\" not supported for type %s",
6066 return 0.0; /* keep compiler quiet */
6067 }
6068}
6069
6070/* interval_part() and extract_interval()
6071 * Extract specified field from interval.
6072 */
6073static Datum
6075{
6079 int type,
6080 val;
6081 char *lowunits;
6082 struct pg_itm tt,
6083 *tm = &tt;
6084
6087 false);
6088
6089 type = DecodeUnits(0, lowunits, &val);
6090 if (type == UNKNOWN_FIELD)
6092
6094 {
6097
6098 if (r != 0.0)
6099 {
6100 if (retnumeric)
6101 {
6102 if (r < 0)
6104 CStringGetDatum("-Infinity"),
6106 Int32GetDatum(-1));
6107 else if (r > 0)
6109 CStringGetDatum("Infinity"),
6111 Int32GetDatum(-1));
6112 }
6113 else
6115 }
6116 else
6118 }
6119
6120 if (type == UNITS)
6121 {
6123 switch (val)
6124 {
6125 case DTK_MICROSEC:
6126 intresult = tm->tm_sec * INT64CONST(1000000) + tm->tm_usec;
6127 break;
6128
6129 case DTK_MILLISEC:
6130 if (retnumeric)
6131 /*---
6132 * tm->tm_sec * 1000 + fsec / 1000
6133 * = (tm->tm_sec * 1'000'000 + fsec) / 1000
6134 */
6136 else
6137 PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + tm->tm_usec / 1000.0);
6138 break;
6139
6140 case DTK_SECOND:
6141 if (retnumeric)
6142 /*---
6143 * tm->tm_sec + fsec / 1'000'000
6144 * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
6145 */
6147 else
6148 PG_RETURN_FLOAT8(tm->tm_sec + tm->tm_usec / 1000000.0);
6149 break;
6150
6151 case DTK_MINUTE:
6152 intresult = tm->tm_min;
6153 break;
6154
6155 case DTK_HOUR:
6156 intresult = tm->tm_hour;
6157 break;
6158
6159 case DTK_DAY:
6160 intresult = tm->tm_mday;
6161 break;
6162
6163 case DTK_WEEK:
6164 intresult = tm->tm_mday / 7;
6165 break;
6166
6167 case DTK_MONTH:
6168 intresult = tm->tm_mon;
6169 break;
6170
6171 case DTK_QUARTER:
6172
6173 /*
6174 * We want to maintain the rule that a field extracted from a
6175 * negative interval is the negative of the field's value for
6176 * the sign-reversed interval. The broken-down tm_year and
6177 * tm_mon aren't very helpful for that, so work from
6178 * interval->month.
6179 */
6180 if (interval->month >= 0)
6181 intresult = (tm->tm_mon / 3) + 1;
6182 else
6183 intresult = -(((-interval->month % MONTHS_PER_YEAR) / 3) + 1);
6184 break;
6185
6186 case DTK_YEAR:
6187 intresult = tm->tm_year;
6188 break;
6189
6190 case DTK_DECADE:
6191 /* caution: C division may have negative remainder */
6192 intresult = tm->tm_year / 10;
6193 break;
6194
6195 case DTK_CENTURY:
6196 /* caution: C division may have negative remainder */
6197 intresult = tm->tm_year / 100;
6198 break;
6199
6200 case DTK_MILLENNIUM:
6201 /* caution: C division may have negative remainder */
6202 intresult = tm->tm_year / 1000;
6203 break;
6204
6205 default:
6206 ereport(ERROR,
6208 errmsg("unit \"%s\" not supported for type %s",
6210 intresult = 0;
6211 }
6212 }
6213 else if (type == RESERV && val == DTK_EPOCH)
6214 {
6215 if (retnumeric)
6216 {
6217 Numeric result;
6219 int64 val;
6220
6221 /*
6222 * To do this calculation in integer arithmetic even though
6223 * DAYS_PER_YEAR is fractional, multiply everything by 4 and then
6224 * divide by 4 again at the end. This relies on DAYS_PER_YEAR
6225 * being a multiple of 0.25 and on SECS_PER_DAY being a multiple
6226 * of 4.
6227 */
6230 (int64) 4 * interval->day) * (SECS_PER_DAY / 4);
6231
6232 /*---
6233 * result = secs_from_day_month + interval->time / 1'000'000
6234 * = (secs_from_day_month * 1'000'000 + interval->time) / 1'000'000
6235 */
6236
6237 /*
6238 * Try the computation inside int64; if it overflows, do it in
6239 * numeric (slower). This overflow happens around 10^9 days, so
6240 * not common in practice.
6241 */
6242 if (!pg_mul_s64_overflow(secs_from_day_month, 1000000, &val) &&
6244 result = int64_div_fast_to_numeric(val, 6);
6245 else
6246 result =
6249 NULL);
6250
6251 PG_RETURN_NUMERIC(result);
6252 }
6253 else
6254 {
6255 float8 result;
6256
6257 result = interval->time / 1000000.0;
6260 result += ((double) SECS_PER_DAY) * interval->day;
6261
6262 PG_RETURN_FLOAT8(result);
6263 }
6264 }
6265 else
6266 {
6267 ereport(ERROR,
6269 errmsg("unit \"%s\" not recognized for type %s",
6271 intresult = 0;
6272 }
6273
6274 if (retnumeric)
6276 else
6278}
6279
6280Datum
6282{
6283 return interval_part_common(fcinfo, false);
6284}
6285
6286Datum
6288{
6289 return interval_part_common(fcinfo, true);
6290}
6291
6292
6293/* timestamp_zone()
6294 * Encode timestamp type with specified time zone.
6295 * This function is just timestamp2timestamptz() except instead of
6296 * shifting to the global timezone, we shift to the specified timezone.
6297 * This is different from the other AT TIME ZONE cases because instead
6298 * of shifting _to_ a new time zone, it sets the time to _be_ the
6299 * specified timezone.
6300 */
6301Datum
6303{
6306 TimestampTz result;
6307 int tz;
6308 char tzname[TZ_STRLEN_MAX + 1];
6309 int type,
6310 val;
6311 pg_tz *tzp;
6312 struct pg_tm tm;
6313 fsec_t fsec;
6314
6317
6318 /*
6319 * Look up the requested timezone.
6320 */
6322
6323 type = DecodeTimezoneName(tzname, &val, &tzp);
6324
6326 {
6327 /* fixed-offset abbreviation */
6328 tz = val;
6329 result = dt2local(timestamp, tz);
6330 }
6331 else if (type == TZNAME_DYNTZ)
6332 {
6333 /* dynamic-offset abbreviation, resolve using specified time */
6334 if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, tzp) != 0)
6335 ereport(ERROR,
6337 errmsg("timestamp out of range")));
6339 result = dt2local(timestamp, tz);
6340 }
6341 else
6342 {
6343 /* full zone name, rotate to that zone */
6344 if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, tzp) != 0)
6345 ereport(ERROR,
6347 errmsg("timestamp out of range")));
6348 tz = DetermineTimeZoneOffset(&tm, tzp);
6349 if (tm2timestamp(&tm, fsec, &tz, &result) != 0)
6350 ereport(ERROR,
6352 errmsg("timestamp out of range")));
6353 }
6354
6355 if (!IS_VALID_TIMESTAMP(result))
6356 ereport(ERROR,
6358 errmsg("timestamp out of range")));
6359
6360 PG_RETURN_TIMESTAMPTZ(result);
6361}
6362
6363/* timestamp_izone()
6364 * Encode timestamp type with specified time interval as time zone.
6365 */
6366Datum
6368{
6371 TimestampTz result;
6372 int tz;
6373
6376
6378 ereport(ERROR,
6380 errmsg("interval time zone \"%s\" must be finite",
6382 PointerGetDatum(zone))))));
6383
6384 if (zone->month != 0 || zone->day != 0)
6385 ereport(ERROR,
6387 errmsg("interval time zone \"%s\" must not include months or days",
6389 PointerGetDatum(zone))))));
6390
6391 tz = zone->time / USECS_PER_SEC;
6392
6393 result = dt2local(timestamp, tz);
6394
6395 if (!IS_VALID_TIMESTAMP(result))
6396 ereport(ERROR,
6398 errmsg("timestamp out of range")));
6399
6400 PG_RETURN_TIMESTAMPTZ(result);
6401} /* timestamp_izone() */
6402
6403/* TimestampTimestampTzRequiresRewrite()
6404 *
6405 * Returns false if the TimeZone GUC setting causes timestamp_timestamptz and
6406 * timestamptz_timestamp to be no-ops, where the return value has the same
6407 * bits as the argument. Since project convention is to assume a GUC changes
6408 * no more often than STABLE functions change, the answer is valid that long.
6409 */
6410bool
6412{
6413 long offset;
6414
6415 if (pg_get_timezone_offset(session_timezone, &offset) && offset == 0)
6416 return false;
6417 return true;
6418}
6419
6420/* timestamp_timestamptz()
6421 * Convert local timestamp to timestamp at GMT
6422 */
6423Datum
6425{
6427 TimestampTz result;
6428
6429 result = timestamp2timestamptz_safe(timestamp, fcinfo->context);
6430 if (SOFT_ERROR_OCCURRED(fcinfo->context))
6432
6433 PG_RETURN_TIMESTAMPTZ(result);
6434}
6435
6436/*
6437 * Convert timestamp to timestamp with time zone.
6438 *
6439 * If the timestamp is finite but out of the valid range for timestamptz,
6440 * error handling proceeds based on escontext.
6441 *
6442 * If escontext is NULL, we throw an out-of-range error (hard error).
6443 * If escontext is not NULL, we return NOBEGIN or NOEND for lower bound or
6444 * upper bound overflow, respectively, and record a soft error.
6445 */
6448{
6449 TimestampTz result;
6450 struct pg_tm tt,
6451 *tm = &tt;
6452 fsec_t fsec;
6453 int tz;
6454
6456 return timestamp;
6457
6458 /* timestamp2tm should not fail on valid timestamps, but cope */
6459 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) == 0)
6460 {
6462
6463 result = dt2local(timestamp, -tz);
6464
6465 if (IS_VALID_TIMESTAMP(result))
6466 return result;
6467 }
6468
6469 if (timestamp < 0)
6470 TIMESTAMP_NOBEGIN(result);
6471 else
6472 TIMESTAMP_NOEND(result);
6473
6474 ereturn(escontext, result,
6476 errmsg("timestamp out of range")));
6477}
6478
6479/*
6480 * Promote timestamp to timestamptz, throwing error for overflow.
6481 */
6482static TimestampTz
6487
6488/* timestamptz_timestamp()
6489 * Convert timestamp at GMT to local timestamp
6490 */
6491Datum
6493{
6495 Timestamp result;
6496
6497 result = timestamptz2timestamp_safe(timestamp, fcinfo->context);
6498 if (unlikely(SOFT_ERROR_OCCURRED(fcinfo->context)))
6500
6501 PG_RETURN_TIMESTAMP(result);
6502}
6503
6504/*
6505 * Convert timestamptz to timestamp, throwing error for overflow.
6506 */
6507static Timestamp
6512
6513/*
6514 * Convert timestamp with time zone to timestamp.
6515 *
6516 * If the timestamptz is finite but out of the valid range for timestamp,
6517 * error handling proceeds based on escontext.
6518 *
6519 * If escontext is NULL, we throw an out-of-range error (hard error).
6520 * If escontext is not NULL, we return NOBEGIN or NOEND for lower bound or
6521 * upper bound overflow, respectively, and record a soft error.
6522 */
6525{
6526 Timestamp result;
6527 struct pg_tm tt,
6528 *tm = &tt;
6529 fsec_t fsec;
6530 int tz;
6531
6533 result = timestamp;
6534 else
6535 {
6536 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
6537 {
6538 if (timestamp < 0)
6539 TIMESTAMP_NOBEGIN(result);
6540 else
6541 TIMESTAMP_NOEND(result);
6542
6543 ereturn(escontext, result,
6545 errmsg("timestamp out of range")));
6546 }
6547 if (tm2timestamp(tm, fsec, NULL, &result) != 0)
6548 {
6549 if (timestamp < 0)
6550 TIMESTAMP_NOBEGIN(result);
6551 else
6552 TIMESTAMP_NOEND(result);
6553
6554 ereturn(escontext, result,
6556 errmsg("timestamp out of range")));
6557 }
6558 }
6559 return result;
6560}
6561
6562/* timestamptz_zone()
6563 * Evaluate timestamp with time zone type at the specified time zone.
6564 * Returns a timestamp without time zone.
6565 */
6566Datum
6568{
6571 Timestamp result;
6572 int tz;
6573 char tzname[TZ_STRLEN_MAX + 1];
6574 int type,
6575 val;
6576 pg_tz *tzp;
6577
6580
6581 /*
6582 * Look up the requested timezone.
6583 */
6585
6586 type = DecodeTimezoneName(tzname, &val, &tzp);
6587
6589 {
6590 /* fixed-offset abbreviation */
6591 tz = -val;
6592 result = dt2local(timestamp, tz);
6593 }
6594 else if (type == TZNAME_DYNTZ)
6595 {
6596 /* dynamic-offset abbreviation, resolve using specified time */
6597 int isdst;
6598
6600 result = dt2local(timestamp, tz);
6601 }
6602 else
6603 {
6604 /* full zone name, rotate from that zone */
6605 struct pg_tm tm;
6606 fsec_t fsec;
6607
6608 if (timestamp2tm(timestamp, &tz, &tm, &fsec, NULL, tzp) != 0)
6609 ereport(ERROR,
6611 errmsg("timestamp out of range")));
6612 if (tm2timestamp(&tm, fsec, NULL, &result) != 0)
6613 ereport(ERROR,
6615 errmsg("timestamp out of range")));
6616 }
6617
6618 if (!IS_VALID_TIMESTAMP(result))
6619 ereport(ERROR,
6621 errmsg("timestamp out of range")));
6622
6623 PG_RETURN_TIMESTAMP(result);
6624}
6625
6626/* timestamptz_izone()
6627 * Encode timestamp with time zone type with specified time interval as time zone.
6628 * Returns a timestamp without time zone.
6629 */
6630Datum
6632{
6635 Timestamp result;
6636 int tz;
6637
6640
6642 ereport(ERROR,
6644 errmsg("interval time zone \"%s\" must be finite",
6646 PointerGetDatum(zone))))));
6647
6648 if (zone->month != 0 || zone->day != 0)
6649 ereport(ERROR,
6651 errmsg("interval time zone \"%s\" must not include months or days",
6653 PointerGetDatum(zone))))));
6654
6655 tz = -(zone->time / USECS_PER_SEC);
6656
6657 result = dt2local(timestamp, tz);
6658
6659 if (!IS_VALID_TIMESTAMP(result))
6660 ereport(ERROR,
6662 errmsg("timestamp out of range")));
6663
6664 PG_RETURN_TIMESTAMP(result);
6665}
6666
6667/* generate_series_timestamp()
6668 * Generate the set of timestamps from start to finish by step
6669 */
6670Datum
6672{
6675 Timestamp result;
6676
6677 /* stuff done only on the first call of the function */
6678 if (SRF_IS_FIRSTCALL())
6679 {
6681 Timestamp finish = PG_GETARG_TIMESTAMP(1);
6682 Interval *step = PG_GETARG_INTERVAL_P(2);
6683 MemoryContext oldcontext;
6684
6685 /* create a function context for cross-call persistence */
6687
6688 /*
6689 * switch to memory context appropriate for multiple function calls
6690 */
6691 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
6692
6693 /* allocate memory for user context */
6695
6696 /*
6697 * Use fctx to keep state from call to call. Seed current with the
6698 * original start value
6699 */
6700 fctx->current = start;
6701 fctx->finish = finish;
6702 fctx->step = *step;
6703
6704 /* Determine sign of the interval */
6705 fctx->step_sign = interval_sign(&fctx->step);
6706
6707 if (fctx->step_sign == 0)
6708 ereport(ERROR,
6710 errmsg("step size cannot equal zero")));
6711
6712 if (INTERVAL_NOT_FINITE((&fctx->step)))
6713 ereport(ERROR,
6715 errmsg("step size cannot be infinite")));
6716
6717 funcctx->user_fctx = fctx;
6718 MemoryContextSwitchTo(oldcontext);
6719 }
6720
6721 /* stuff done on every call of the function */
6723
6724 /*
6725 * get the saved state and use current as the result for this iteration
6726 */
6727 fctx = funcctx->user_fctx;
6728 result = fctx->current;
6729
6730 if (fctx->step_sign > 0 ?
6731 timestamp_cmp_internal(result, fctx->finish) <= 0 :
6732 timestamp_cmp_internal(result, fctx->finish) >= 0)
6733 {
6734 /* increment current in preparation for next iteration */
6736 TimestampGetDatum(fctx->current),
6737 PointerGetDatum(&fctx->step)));
6738
6739 /* do when there is more left to send */
6741 }
6742 else
6743 {
6744 /* do when there is no more left */
6746 }
6747}
6748
6749/* generate_series_timestamptz()
6750 * Generate the set of timestamps from start to finish by step,
6751 * doing arithmetic in the specified or session timezone.
6752 */
6753static Datum
6755{
6758 TimestampTz result;
6759
6760 /* stuff done only on the first call of the function */
6761 if (SRF_IS_FIRSTCALL())
6762 {
6765 Interval *step = PG_GETARG_INTERVAL_P(2);
6766 text *zone = (PG_NARGS() == 4) ? PG_GETARG_TEXT_PP(3) : NULL;
6767 MemoryContext oldcontext;
6768
6769 /* create a function context for cross-call persistence */
6771
6772 /*
6773 * switch to memory context appropriate for multiple function calls
6774 */
6775 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
6776
6777 /* allocate memory for user context */
6779
6780 /*
6781 * Use fctx to keep state from call to call. Seed current with the
6782 * original start value
6783 */
6784 fctx->current = start;
6785 fctx->finish = finish;
6786 fctx->step = *step;
6787 fctx->attimezone = zone ? lookup_timezone(zone) : session_timezone;
6788
6789 /* Determine sign of the interval */
6790 fctx->step_sign = interval_sign(&fctx->step);
6791
6792 if (fctx->step_sign == 0)
6793 ereport(ERROR,
6795 errmsg("step size cannot equal zero")));
6796
6797 if (INTERVAL_NOT_FINITE((&fctx->step)))
6798 ereport(ERROR,
6800 errmsg("step size cannot be infinite")));
6801
6802 funcctx->user_fctx = fctx;
6803 MemoryContextSwitchTo(oldcontext);
6804 }
6805
6806 /* stuff done on every call of the function */
6808
6809 /*
6810 * get the saved state and use current as the result for this iteration
6811 */
6812 fctx = funcctx->user_fctx;
6813 result = fctx->current;
6814
6815 if (fctx->step_sign > 0 ?
6816 timestamp_cmp_internal(result, fctx->finish) <= 0 :
6817 timestamp_cmp_internal(result, fctx->finish) >= 0)
6818 {
6819 /* increment current in preparation for next iteration */
6820 fctx->current = timestamptz_pl_interval_internal(fctx->current,
6821 &fctx->step,
6822 fctx->attimezone);
6823
6824 /* do when there is more left to send */
6826 }
6827 else
6828 {
6829 /* do when there is no more left */
6831 }
6832}
6833
6834Datum
6839
6840Datum
6845
6846/*
6847 * Planner support function for generate_series(timestamp, timestamp, interval)
6848 */
6849Datum
6851{
6853 Node *ret = NULL;
6854
6856 {
6857 /* Try to estimate the number of rows returned */
6859
6860 if (is_funcclause(req->node)) /* be paranoid */
6861 {
6862 List *args = ((FuncExpr *) req->node)->args;
6863 Node *arg1,
6864 *arg2,
6865 *arg3;
6866
6867 /* We can use estimated argument values here */
6869 arg2 = estimate_expression_value(req->root, lsecond(args));
6870 arg3 = estimate_expression_value(req->root, lthird(args));
6871
6872 /*
6873 * If any argument is constant NULL, we can safely assume that
6874 * zero rows are returned. Otherwise, if they're all non-NULL
6875 * constants, we can calculate the number of rows that will be
6876 * returned.
6877 */
6878 if ((IsA(arg1, Const) && ((Const *) arg1)->constisnull) ||
6879 (IsA(arg2, Const) && ((Const *) arg2)->constisnull) ||
6880 (IsA(arg3, Const) && ((Const *) arg3)->constisnull))
6881 {
6882 req->rows = 0;
6883 ret = (Node *) req;
6884 }
6885 else if (IsA(arg1, Const) && IsA(arg2, Const) && IsA(arg3, Const))
6886 {
6888 finish;
6889 Interval *step;
6890 Datum diff;
6891 double dstep;
6892 int64 dummy;
6893
6895 finish = DatumGetTimestamp(((Const *) arg2)->constvalue);
6896 step = DatumGetIntervalP(((Const *) arg3)->constvalue);
6897
6898 /*
6899 * Perform some prechecks which could cause timestamp_mi to
6900 * raise an ERROR. It's much better to just return some
6901 * default estimate than error out in a support function.
6902 */
6904 !pg_sub_s64_overflow(finish, start, &dummy))
6905 {
6907 TimestampGetDatum(finish),
6909
6910#define INTERVAL_TO_MICROSECONDS(i) ((((double) (i)->month * DAYS_PER_MONTH + (i)->day)) * USECS_PER_DAY + (i)->time)
6911
6913
6914 /* This equation works for either sign of step */
6915 if (dstep != 0.0)
6916 {
6919
6920 req->rows = floor(ddiff / dstep + 1.0);
6921 ret = (Node *) req;
6922 }
6923#undef INTERVAL_TO_MICROSECONDS
6924 }
6925 }
6926 }
6927 }
6928
6929 PG_RETURN_POINTER(ret);
6930}
6931
6932
6933/* timestamp_at_local()
6934 * timestamptz_at_local()
6935 *
6936 * The regression tests do not like two functions with the same proargs and
6937 * prosrc but different proname, but the grammar for AT LOCAL needs an
6938 * overloaded name to handle both types of timestamp, so we make simple
6939 * wrappers for it.
6940 */
6941Datum
6946
6947Datum
#define PG_GETARG_ARRAYTYPE_P(n)
Definition array.h:263
int32 * ArrayGetIntegerTypmods(ArrayType *arr, int *n)
Definition arrayutils.c:233
const int day_tab[2][13]
Definition datetime.c:76
Node * TemporalSimplify(int32 max_precis, Node *node)
Definition datetime.c:4963
pg_tz * DecodeTimezoneNameToTz(const char *tzname)
Definition datetime.c:3344
int DetermineTimeZoneAbbrevOffsetTS(TimestampTz ts, const char *abbr, pg_tz *tzp, int *isdst)
Definition datetime.c:1804
int DecodeUnits(int field, const char *lowtoken, int *val)
Definition datetime.c:4170
int j2day(int date)
Definition datetime.c:355
int ParseDateTime(const char *timestr, char *workbuf, size_t buflen, char **field, int *ftype, int maxfields, int *numfields)
Definition datetime.c:774
void EncodeInterval(struct pg_itm *itm, int style, char *str)
Definition datetime.c:4708
int DetermineTimeZoneOffset(struct pg_tm *tm, pg_tz *tzp)
Definition datetime.c:1605
void DateTimeParseError(int dterr, DateTimeErrorExtra *extra, const char *str, const char *datatype, Node *escontext)
Definition datetime.c:4215
int DecodeInterval(char **field, int *ftype, int nf, int range, int *dtype, struct pg_itm_in *itm_in)
Definition datetime.c:3487
int DecodeISO8601Interval(char *str, int *dtype, struct pg_itm_in *itm_in)
Definition datetime.c:3952
int ValidateDate(int fmask, bool isjulian, bool is2digits, bool bc, struct pg_tm *tm)
Definition datetime.c:2562
int DecodeSpecial(int field, const char *lowtoken, int *val)
Definition datetime.c:3247
void j2date(int jd, int *year, int *month, int *day)
Definition datetime.c:322
void EncodeDateTime(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str)
Definition datetime.c:4465
int DecodeTimezone(const char *str, int *tzp)
Definition datetime.c:3058
const char *const months[]
Definition datetime.c:82
int DecodeDateTime(char **field, int *ftype, int nf, int *dtype, struct pg_tm *tm, fsec_t *fsec, int *tzp, DateTimeErrorExtra *extra)
Definition datetime.c:998
int date2j(int year, int month, int day)
Definition datetime.c:297
const char *const days[]
Definition datetime.c:85
int DecodeTimezoneName(const char *tzname, int *offset, pg_tz **tz)
Definition datetime.c:3289
int DetermineTimeZoneAbbrevOffset(struct pg_tm *tm, const char *abbr, pg_tz *tzp)
Definition datetime.c:1766
Datum numeric_round(PG_FUNCTION_ARGS)
Definition numeric.c:1528
Numeric int64_to_numeric(int64 val)
Definition numeric.c:4264
Numeric numeric_add_safe(Numeric num1, Numeric num2, Node *escontext)
Definition numeric.c:2883
Numeric int64_div_fast_to_numeric(int64 val1, int log10val2)
Definition numeric.c:4285
Numeric numeric_div_safe(Numeric num1, Numeric num2, Node *escontext)
Definition numeric.c:3157
Numeric numeric_sub_safe(Numeric num1, Numeric num2, Node *escontext)
Definition numeric.c:2959
Datum numeric_in(PG_FUNCTION_ARGS)
Definition numeric.c:626
void dt2time(Timestamp jd, int *hour, int *min, int *sec, fsec_t *fsec)
Definition timestamp.c:1877
Datum interval_out(PG_FUNCTION_ARGS)
Definition timestamp.c:966
Datum interval_justify_hours(PG_FUNCTION_ARGS)
Definition timestamp.c:2995
Datum make_timestamptz_at_timezone(PG_FUNCTION_ARGS)
Definition timestamp.c:678
int timestamp_cmp_internal(Timestamp dt1, Timestamp dt2)
Definition timestamp.c:2204
long TimestampDifferenceMilliseconds(TimestampTz start_time, TimestampTz stop_time)
Definition timestamp.c:1751
void isoweek2date(int woy, int *year, int *mon, int *mday)
Definition timestamp.c:5258
Datum in_range_timestamp_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3870
void GetEpochTime(struct pg_tm *tm)
Definition timestamp.c:2162
Datum generate_series_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:6835
static float8 NonFiniteTimestampTzPart(int type, int unit, char *lowunits, bool isNegative, bool isTz)
Definition timestamp.c:5418
static INT128 interval_cmp_value(const Interval *interval)
Definition timestamp.c:2518
Datum interval_trunc(PG_FUNCTION_ARGS)
Definition timestamp.c:5106
Datum overlaps_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:2666
Datum extract_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:5739
Datum timestamptypmodout(PG_FUNCTION_ARGS)
Definition timestamp.c:303
Datum interval_gt(PG_FUNCTION_ARGS)
Definition timestamp.c:2585
Datum interval_avg_accum(PG_FUNCTION_ARGS)
Definition timestamp.c:4037
int itmin2interval(struct pg_itm_in *itm_in, Interval *span)
Definition timestamp.c:2109
Datum interval_justify_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:2915
static void finite_interval_mi(const Interval *span1, const Interval *span2, Interval *result)
Definition timestamp.c:3538
Datum timestamptz_part(PG_FUNCTION_ARGS)
Definition timestamp.c:6005
int isoweek2j(int year, int week)
Definition timestamp.c:5238
Datum clock_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:1615
Datum timestamptz_pl_interval_at_zone(PG_FUNCTION_ARGS)
Definition timestamp.c:3395
Datum timestamp_pl_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3084
Datum interval_le(PG_FUNCTION_ARGS)
Definition timestamp.c:2594
Datum interval_avg_serialize(PG_FUNCTION_ARGS)
Definition timestamp.c:4103
Datum interval_mi(PG_FUNCTION_ARGS)
Definition timestamp.c:3553
TimestampTz time_t_to_timestamptz(pg_time_t tm)
Definition timestamp.c:1814
Datum timestamp_le_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:2417
Datum interval_lt(PG_FUNCTION_ARGS)
Definition timestamp.c:2576
Datum timestamp_larger(PG_FUNCTION_ARGS)
Definition timestamp.c:2806
static Datum timestamptz_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition timestamp.c:5748
Datum timestamptz_izone(PG_FUNCTION_ARGS)
Definition timestamp.c:6631
Datum timestamp_cmp_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:2435
static bool AdjustIntervalForTypmod(Interval *interval, int32 typmod, Node *escontext)
Definition timestamp.c:1344
Datum timestamp_part(PG_FUNCTION_ARGS)
Definition timestamp.c:5733
Datum timestamptz_eq_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:2444
Datum interval_hash(PG_FUNCTION_ARGS)
Definition timestamp.c:2628
Datum timestamptztypmodout(PG_FUNCTION_ARGS)
Definition timestamp.c:849
int date2isoweek(int year, int mon, int mday)
Definition timestamp.c:5289
Datum timestamptz_pl_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3374
Datum timestamp_cmp(PG_FUNCTION_ARGS)
Definition timestamp.c:2264
static TimestampTz timestamptz_trunc_internal(text *units, TimestampTz timestamp, pg_tz *tzp)
Definition timestamp.c:4891
Datum timestamp_bin(PG_FUNCTION_ARGS)
Definition timestamp.c:4582
Datum timestamp_zone(PG_FUNCTION_ARGS)
Definition timestamp.c:6302
static pg_tz * lookup_timezone(text *zone)
Definition timestamp.c:552
static TimestampTz timestamp2timestamptz(Timestamp timestamp)
Definition timestamp.c:6483
Datum interval_finite(PG_FUNCTION_ARGS)
Definition timestamp.c:2149
Datum timestamptz_ne_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:2453
Datum timestamptz_lt_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:2462
Datum timestamp_sortsupport(PG_FUNCTION_ARGS)
Definition timestamp.c:2273
Datum timestamp_mi_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3201
Datum timestamptypmodin(PG_FUNCTION_ARGS)
Definition timestamp.c:295
bool AdjustTimestampForTypmod(Timestamp *time, int32 typmod, Node *escontext)
Definition timestamp.c:360
Datum timestamptz_ge_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:2489
Datum timestamp_smaller(PG_FUNCTION_ARGS)
Definition timestamp.c:2791
Datum interval_justify_days(PG_FUNCTION_ARGS)
Definition timestamp.c:3037
TimestampTz timestamp2timestamptz_safe(Timestamp timestamp, Node *escontext)
Definition timestamp.c:6447
Datum timestamp_ge(PG_FUNCTION_ARGS)
Definition timestamp.c:2255
Datum interval_avg_accum_inv(PG_FUNCTION_ARGS)
Definition timestamp.c:4184
Datum generate_series_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:6671
int date2isoyearday(int year, int mon, int mday)
Definition timestamp.c:5401
Datum timestamptz_cmp_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:2498
Datum timestamp_ge_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:2426
static Timestamp timestamptz2timestamp(TimestampTz timestamp)
Definition timestamp.c:6508
void TimestampDifference(TimestampTz start_time, TimestampTz stop_time, long *secs, int *microsecs)
Definition timestamp.c:1715
static void do_interval_accum(IntervalAggState *state, Interval *newval)
Definition timestamp.c:3983
Datum timestamp_scale(PG_FUNCTION_ARGS)
Definition timestamp.c:338
Datum timestamptz_scale(PG_FUNCTION_ARGS)
Definition timestamp.c:862
Datum make_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:657
bool TimestampDifferenceExceedsSeconds(TimestampTz start_time, TimestampTz stop_time, int threshold_sec)
Definition timestamp.c:1789
bool TimestampTimestampTzRequiresRewrite(void)
Definition timestamp.c:6411
Datum timestamp_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:6424
Datum timestamp_recv(PG_FUNCTION_ARGS)
Definition timestamp.c:251
Datum timestamp_lt(PG_FUNCTION_ARGS)
Definition timestamp.c:2228
Datum timestamptz_trunc(PG_FUNCTION_ARGS)
Definition timestamp.c:5069
Datum timestamptz_zone(PG_FUNCTION_ARGS)
Definition timestamp.c:6567
static void finite_interval_pl(const Interval *span1, const Interval *span2, Interval *result)
Definition timestamp.c:3482
void isoweekdate2date(int isoweek, int wday, int *year, int *mon, int *mday)
Definition timestamp.c:5271
int32 timestamp_cmp_timestamptz_internal(Timestamp timestampVal, TimestampTz dt2)
Definition timestamp.c:2357
Datum timestamptz_gt_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:2471
Datum timestamptz_hash_extended(PG_FUNCTION_ARGS)
Definition timestamp.c:2347
bool TimestampDifferenceExceeds(TimestampTz start_time, TimestampTz stop_time, int msec)
Definition timestamp.c:1775
static int32 anytimestamp_typmodin(bool istz, ArrayType *ta)
Definition timestamp.c:95
Datum generate_series_timestamp_support(PG_FUNCTION_ARGS)
Definition timestamp.c:6850
Datum interval_cmp(PG_FUNCTION_ARGS)
Definition timestamp.c:2612
Datum interval_sum(PG_FUNCTION_ARGS)
Definition timestamp.c:4242
Datum timestamp_hash_extended(PG_FUNCTION_ARGS)
Definition timestamp.c:2335
Datum timestamptz_le_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:2480
Datum interval_pl(PG_FUNCTION_ARGS)
Definition timestamp.c:3497
Datum interval_um(PG_FUNCTION_ARGS)
Definition timestamp.c:3440
Datum timestamp_skipsupport(PG_FUNCTION_ARGS)
Definition timestamp.c:2316
static float8 NonFiniteIntervalPart(int type, int unit, char *lowunits, bool isNegative)
Definition timestamp.c:6028
Datum make_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:1524
static char * anytimestamp_typmodout(bool istz, int32 typmod)
Definition timestamp.c:138
Datum interval_ge(PG_FUNCTION_ARGS)
Definition timestamp.c:2603
static Timestamp make_timestamp_internal(int year, int month, int day, int hour, int min, double sec)
Definition timestamp.c:566
Datum timestamp_gt_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:2408
Datum timestamp_in(PG_FUNCTION_ARGS)
Definition timestamp.c:157
Datum timestamp_le(PG_FUNCTION_ARGS)
Definition timestamp.c:2246
Datum interval_ne(PG_FUNCTION_ARGS)
Definition timestamp.c:2567
Datum timestamptz_hash(PG_FUNCTION_ARGS)
Definition timestamp.c:2341
Datum interval_in(PG_FUNCTION_ARGS)
Definition timestamp.c:884
static Datum interval_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition timestamp.c:6074
TimestampTz PgReloadTime
Definition timestamp.c:48
Datum timestamp_ne_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:2390
Datum interval_hash_extended(PG_FUNCTION_ARGS)
Definition timestamp.c:2646
Datum timestamptz_mi_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3383
Datum timestamp_age(PG_FUNCTION_ARGS)
Definition timestamp.c:4282
Datum interval_smaller(PG_FUNCTION_ARGS)
Definition timestamp.c:3453
static void EncodeSpecialInterval(const Interval *interval, char *str)
Definition timestamp.c:1592
Datum timestamptz_mi_interval_at_zone(PG_FUNCTION_ARGS)
Definition timestamp.c:3406
Datum interval_support(PG_FUNCTION_ARGS)
Definition timestamp.c:1258
Datum timestamptz_in(PG_FUNCTION_ARGS)
Definition timestamp.c:410
static int intervaltypmodleastfield(int32 typmod)
Definition timestamp.c:1205
int32 anytimestamp_typmod_check(bool istz, int32 typmod)
Definition timestamp.c:116
Datum extract_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:6011
Datum pg_postmaster_start_time(PG_FUNCTION_ARGS)
Definition timestamp.c:1621
TimestampTz GetCurrentTimestamp(void)
Definition timestamp.c:1639
Datum interval_part(PG_FUNCTION_ARGS)
Definition timestamp.c:6281
Datum pg_conf_load_time(PG_FUNCTION_ARGS)
Definition timestamp.c:1627
Datum in_range_interval_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3911
#define IA_TOTAL_COUNT(ia)
Definition timestamp.c:80
const char * timestamptz_to_str(TimestampTz t)
Definition timestamp.c:1856
Datum interval_eq(PG_FUNCTION_ARGS)
Definition timestamp.c:2558
static Datum timestamp_increment(Relation rel, Datum existing, bool *overflow)
Definition timestamp.c:2300
Timestamp GetSQLLocalTimestamp(int32 typmod)
Definition timestamp.c:1671
Datum timestamp_finite(PG_FUNCTION_ARGS)
Definition timestamp.c:2141
static TimestampTz timestamptz_mi_interval_internal(TimestampTz timestamp, Interval *span, pg_tz *attimezone)
Definition timestamp.c:3359
Datum timestamp_trunc(PG_FUNCTION_ARGS)
Definition timestamp.c:4653
Datum mul_d_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3722
Datum timestamptztypmodin(PG_FUNCTION_ARGS)
Definition timestamp.c:841
Datum interval_avg(PG_FUNCTION_ARGS)
Definition timestamp.c:4202
TimestampTz PgStartTime
Definition timestamp.c:45
Datum timestamp_send(PG_FUNCTION_ARGS)
Definition timestamp.c:284
Datum timestamptz_send(PG_FUNCTION_ARGS)
Definition timestamp.c:830
Datum timestamptz_recv(PG_FUNCTION_ARGS)
Definition timestamp.c:796
Datum interval_scale(PG_FUNCTION_ARGS)
Definition timestamp.c:1321
static Datum timestamp_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition timestamp.c:5475
Datum interval_larger(PG_FUNCTION_ARGS)
Definition timestamp.c:3468
Datum timestamp_gt(PG_FUNCTION_ARGS)
Definition timestamp.c:2237
static IntervalAggState * makeIntervalAggState(FunctionCallInfo fcinfo)
Definition timestamp.c:3961
Datum timestamptz_bin(PG_FUNCTION_ARGS)
Definition timestamp.c:4817
Datum timestamptz_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:6492
Datum timestamp_mi(PG_FUNCTION_ARGS)
Definition timestamp.c:2821
Datum timestamptz_at_local(PG_FUNCTION_ARGS)
Definition timestamp.c:6948
Datum interval_send(PG_FUNCTION_ARGS)
Definition timestamp.c:1015
Datum intervaltypmodin(PG_FUNCTION_ARGS)
Definition timestamp.c:1040
#define TIMESTAMP_GT(t1, t2)
Datum timestamp_lt_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:2399
Datum timestamptz_out(PG_FUNCTION_ARGS)
Definition timestamp.c:768
static void interval_um_internal(const Interval *interval, Interval *result)
Definition timestamp.c:3420
Datum timestamp_hash(PG_FUNCTION_ARGS)
Definition timestamp.c:2329
Datum timestamp_out(PG_FUNCTION_ARGS)
Definition timestamp.c:225
Datum timestamp_support(PG_FUNCTION_ARGS)
Definition timestamp.c:318
void interval2itm(Interval span, struct pg_itm *itm)
Definition timestamp.c:2041
Datum float8_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:718
Datum now(PG_FUNCTION_ARGS)
Definition timestamp.c:1603
Datum interval_avg_deserialize(PG_FUNCTION_ARGS)
Definition timestamp.c:4141
Datum timestamp_ne(PG_FUNCTION_ARGS)
Definition timestamp.c:2219
static int interval_cmp_internal(const Interval *interval1, const Interval *interval2)
Definition timestamp.c:2540
Datum interval_recv(PG_FUNCTION_ARGS)
Definition timestamp.c:990
#define INTERVAL_TO_MICROSECONDS(i)
Datum statement_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:1609
Datum timestamptz_age(PG_FUNCTION_ARGS)
Definition timestamp.c:4428
Datum interval_mul(PG_FUNCTION_ARGS)
Definition timestamp.c:3602
Datum interval_div(PG_FUNCTION_ARGS)
Definition timestamp.c:3732
Datum timestamptz_trunc_zone(PG_FUNCTION_ARGS)
Definition timestamp.c:5084
Datum timestamp_eq_timestamptz(PG_FUNCTION_ARGS)
Definition timestamp.c:2381
static TimestampTz timestamptz_pl_interval_internal(TimestampTz timestamp, Interval *span, pg_tz *attimezone)
Definition timestamp.c:3227
static Datum generate_series_timestamptz_internal(FunctionCallInfo fcinfo)
Definition timestamp.c:6754
int itm2interval(struct pg_itm *itm, Interval *span)
Definition timestamp.c:2071
pg_time_t timestamptz_to_time_t(TimestampTz t)
Definition timestamp.c:1836
Datum make_timestamp(PG_FUNCTION_ARGS)
Definition timestamp.c:637
Datum intervaltypmodout(PG_FUNCTION_ARGS)
Definition timestamp.c:1119
static int interval_sign(const Interval *interval)
Definition timestamp.c:2549
static void do_interval_discard(IntervalAggState *state, Interval *newval)
Definition timestamp.c:4006
Datum timeofday(PG_FUNCTION_ARGS)
Definition timestamp.c:1685
Datum generate_series_timestamptz_at_zone(PG_FUNCTION_ARGS)
Definition timestamp.c:6841
int date2isoyear(int year, int mon, int mday)
Definition timestamp.c:5344
Timestamp timestamptz2timestamp_safe(TimestampTz timestamp, Node *escontext)
Definition timestamp.c:6524
Datum timestamp_izone(PG_FUNCTION_ARGS)
Definition timestamp.c:6367
static Datum timestamp_decrement(Relation rel, Datum existing, bool *underflow)
Definition timestamp.c:2283
static int parse_sane_timezone(struct pg_tm *tm, text *zone)
Definition timestamp.c:483
Datum timestamp_at_local(PG_FUNCTION_ARGS)
Definition timestamp.c:6942
TimestampTz GetSQLCurrentTimestamp(int32 typmod)
Definition timestamp.c:1657
Datum in_range_timestamptz_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3833
Datum interval_avg_combine(PG_FUNCTION_ARGS)
Definition timestamp.c:4060
Datum extract_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:6287
Datum timestamp_eq(PG_FUNCTION_ARGS)
Definition timestamp.c:2210
#define TIMESTAMP_LT(t1, t2)
#define INT64CONST(x)
Definition c.h:632
#define FLOAT8_FITS_IN_INT32(num)
Definition c.h:1179
#define Assert(condition)
Definition c.h:945
int64_t int64
Definition c.h:615
double float8
Definition c.h:716
#define FLOAT8_FITS_IN_INT64(num)
Definition c.h:1181
int32_t int32
Definition c.h:614
#define PG_INT64_MAX
Definition c.h:678
#define PG_INT64_MIN
Definition c.h:677
#define unlikely(x)
Definition c.h:432
#define pg_fallthrough
Definition c.h:152
Node * estimate_expression_value(PlannerInfo *root, Node *node)
Definition clauses.c:2639
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:1540
int errcode(int sqlerrcode)
Definition elog.c:874
#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
struct SortSupportData * SortSupport
Definition execnodes.h:60
#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 int timestamp2tm(timestamp dt, int *tzp, struct tm *tm, fsec_t *fsec, const char **tzn)
Definition timestamp.c:88
static void EncodeSpecialTimestamp(timestamp dt, char *str)
Definition timestamp.c:187
static timestamp dt2local(timestamp dt, int tz)
Definition timestamp.c:23
static int64 time2t(const int hour, const int min, const int sec, const fsec_t fsec)
Definition timestamp.c:17
static timestamp SetEpochTimestamp(void)
Definition timestamp.c:62
int tm2timestamp(struct tm *tm, fsec_t fsec, int *tzp, timestamp *result)
Definition timestamp.c:37
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
#define SOFT_ERROR_OCCURRED(escontext)
Definition miscnodes.h:53
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition nodeAgg.c:4609
int32 exprTypmod(const Node *expr)
Definition nodeFuncs.c:304
Node * relabel_to_typmod(Node *expr, int32 typmod)
Definition nodeFuncs.c:694
static bool is_funcclause(const void *clause)
Definition nodeFuncs.h:69
#define IsA(nodeptr, _type_)
Definition nodes.h:164
static Numeric DatumGetNumeric(Datum X)
Definition numeric.h:64
#define PG_RETURN_NUMERIC(x)
Definition numeric.h:83
static Datum NumericGetDatum(Numeric X)
Definition numeric.h:76
static char * errmsg
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h: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:525
static Datum PointerGetDatum(const void *X)
Definition postgres.h:342
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
static char * DatumGetCString(Datum X)
Definition postgres.h:355
uint64_t Datum
Definition postgres.h:70
static Datum Float8GetDatum(float8 X)
Definition postgres.h:502
static Datum CStringGetDatum(const char *X)
Definition postgres.h:370
static Datum Int32GetDatum(int32 X)
Definition postgres.h:212
static int32 DatumGetInt32(Datum X)
Definition postgres.h:202
#define InvalidOid
unsigned int Oid
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition pqformat.c:414
void pq_getmsgend(StringInfo msg)
Definition pqformat.c:634
void pq_begintypsend(StringInfo buf)
Definition pqformat.c:325
int64 pq_getmsgint64(StringInfo msg)
Definition pqformat.c:452
bytea * pq_endtypsend(StringInfo buf)
Definition pqformat.c:345
static void pq_sendint32(StringInfo buf, uint32 i)
Definition pqformat.h:144
static void pq_sendint64(StringInfo buf, uint64 i)
Definition pqformat.h:152
static int fb(int x)
char * psprintf(const char *fmt,...)
Definition psprintf.c:43
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
char * downcase_truncate_identifier(const char *ident, int len, bool warn)
Definition scansup.c:38
struct SkipSupportData * SkipSupport
Definition skipsupport.h:50
struct StringInfoData * StringInfo
Definition string.h:15
static void initReadOnlyStringInfo(StringInfo str, char *data, int len)
Definition stringinfo.h:157
List * args
Definition primnodes.h:801
Interval sumX
Definition timestamp.c:74
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:778
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:184
void text_to_cstring_buffer(const text *src, char *dst, size_t dst_len)
Definition varlena.c:248
const char * type
static const unsigned __int64 epoch
int gettimeofday(struct timeval *tp, void *tzp)
TimestampTz GetCurrentStatementStartTimestamp(void)
Definition xact.c:881
TimestampTz GetCurrentTransactionStartTimestamp(void)
Definition xact.c:872