PostgreSQL Source Code git master
Loading...
Searching...
No Matches
date.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * date.c
4 * implements DATE and TIME data types specified in SQL standard
5 *
6 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994-5, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/backend/utils/adt/date.c
12 *
13 *-------------------------------------------------------------------------
14 */
15
16#include "postgres.h"
17
18#include <ctype.h>
19#include <limits.h>
20#include <float.h>
21#include <math.h>
22#include <time.h>
23
24#include "access/xact.h"
25#include "catalog/pg_type.h"
26#include "common/hashfn.h"
27#include "common/int.h"
28#include "libpq/pqformat.h"
29#include "miscadmin.h"
30#include "nodes/miscnodes.h"
31#include "nodes/supportnodes.h"
32#include "parser/scansup.h"
33#include "utils/array.h"
34#include "utils/builtins.h"
35#include "utils/date.h"
36#include "utils/datetime.h"
37#include "utils/numeric.h"
38#include "utils/skipsupport.h"
39#include "utils/sortsupport.h"
40
41/*
42 * gcc's -ffast-math switch breaks routines that expect exact results from
43 * expressions like timeval / SECS_PER_HOUR, where timeval is double.
44 */
45#ifdef __FAST_MATH__
46#error -ffast-math is known to break this code
47#endif
48
49
50/* common code for timetypmodin and timetztypmodin */
51static int32
53{
54 int32 *tl;
55 int n;
56
58
59 /*
60 * we're not too tense about good error message here because grammar
61 * shouldn't allow wrong number of modifiers for TIME
62 */
63 if (n != 1)
66 errmsg("invalid type modifier")));
67
68 return anytime_typmod_check(istz, tl[0]);
69}
70
71/* exported so parse_expr.c can use it */
74{
75 if (typmod < 0)
78 errmsg("TIME(%d)%s precision must not be negative",
79 typmod, (istz ? " WITH TIME ZONE" : ""))));
80 if (typmod > MAX_TIME_PRECISION)
81 {
84 errmsg("TIME(%d)%s precision reduced to maximum allowed, %d",
85 typmod, (istz ? " WITH TIME ZONE" : ""),
87 typmod = MAX_TIME_PRECISION;
88 }
89
90 return typmod;
91}
92
93/* common code for timetypmodout and timetztypmodout */
94static char *
96{
97 const char *tz = istz ? " with time zone" : " without time zone";
98
99 if (typmod >= 0)
100 return psprintf("(%d)%s", (int) typmod, tz);
101 else
102 return pstrdup(tz);
103}
104
105
106/*****************************************************************************
107 * Date ADT
108 *****************************************************************************/
109
110
111/* date_in()
112 * Given date text string, convert to internal date format.
113 */
114Datum
116{
117 char *str = PG_GETARG_CSTRING(0);
118 Node *escontext = fcinfo->context;
120 fsec_t fsec;
121 struct pg_tm tt,
122 *tm = &tt;
123 int tzp;
124 int dtype;
125 int nf;
126 int dterr;
127 char *field[MAXDATEFIELDS];
128 int ftype[MAXDATEFIELDS];
129 char workbuf[MAXDATELEN + 1];
130 DateTimeErrorExtra extra;
131
133 field, ftype, MAXDATEFIELDS, &nf);
134 if (dterr == 0)
135 dterr = DecodeDateTime(field, ftype, nf,
136 &dtype, tm, &fsec, &tzp, &extra);
137 if (dterr != 0)
138 {
139 DateTimeParseError(dterr, &extra, str, "date", escontext);
141 }
142
143 switch (dtype)
144 {
145 case DTK_DATE:
146 break;
147
148 case DTK_EPOCH:
150 break;
151
152 case DTK_LATE:
155
156 case DTK_EARLY:
159
160 default:
161 DateTimeParseError(DTERR_BAD_FORMAT, &extra, str, "date", escontext);
163 }
164
165 /* Prevent overflow in Julian-day routines */
167 ereturn(escontext, (Datum) 0,
169 errmsg("date out of range: \"%s\"", str)));
170
172
173 /* Now check for just-out-of-range dates */
174 if (!IS_VALID_DATE(date))
175 ereturn(escontext, (Datum) 0,
177 errmsg("date out of range: \"%s\"", str)));
178
180}
181
182/* date_out()
183 * Given internal format date, convert to text string.
184 */
185Datum
187{
189 char *result;
190 struct pg_tm tt,
191 *tm = &tt;
192 char buf[MAXDATELEN + 1];
193
196 else
197 {
199 &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
201 }
202
203 result = pstrdup(buf);
204 PG_RETURN_CSTRING(result);
205}
206
207/*
208 * date_recv - converts external binary format to date
209 */
210Datum
212{
214 DateADT result;
215
216 result = (DateADT) pq_getmsgint(buf, sizeof(DateADT));
217
218 /* Limit to the same range that date_in() accepts. */
219 if (DATE_NOT_FINITE(result))
220 /* ok */ ;
221 else if (!IS_VALID_DATE(result))
224 errmsg("date out of range")));
225
226 PG_RETURN_DATEADT(result);
227}
228
229/*
230 * date_send - converts date to binary format
231 */
232Datum
242
243/*
244 * make_date - date constructor
245 */
246Datum
248{
249 struct pg_tm tm;
251 int dterr;
252 bool bc = false;
253
257
258 /* Handle negative years as BC */
259 if (tm.tm_year < 0)
260 {
261 int year = tm.tm_year;
262
263 bc = true;
264 if (pg_neg_s32_overflow(year, &year))
267 errmsg("date field value out of range: %d-%02d-%02d",
269 tm.tm_year = year;
270 }
271
272 dterr = ValidateDate(DTK_DATE_M, false, false, bc, &tm);
273
274 if (dterr != 0)
277 errmsg("date field value out of range: %d-%02d-%02d",
279
280 /* Prevent overflow in Julian-day routines */
284 errmsg("date out of range: %d-%02d-%02d",
286
288
289 /* Now check for just-out-of-range dates */
290 if (!IS_VALID_DATE(date))
293 errmsg("date out of range: %d-%02d-%02d",
295
297}
298
299/*
300 * Convert reserved date values to string.
301 */
302void
304{
305 if (DATE_IS_NOBEGIN(dt))
306 strcpy(str, EARLY);
307 else if (DATE_IS_NOEND(dt))
308 strcpy(str, LATE);
309 else /* shouldn't happen */
310 elog(ERROR, "invalid argument for EncodeSpecialDate");
311}
312
313
314/*
315 * GetSQLCurrentDate -- implements CURRENT_DATE
316 */
319{
320 struct pg_tm tm;
321
322 static int cache_year = 0;
323 static int cache_mon = 0;
324 static int cache_mday = 0;
325 static DateADT cache_date;
326
328
329 /*
330 * date2j involves several integer divisions; moreover, unless our session
331 * lives across local midnight, we don't really have to do it more than
332 * once. So it seems worth having a separate cache here.
333 */
334 if (tm.tm_year != cache_year ||
335 tm.tm_mon != cache_mon ||
337 {
342 }
343
344 return cache_date;
345}
346
347/*
348 * GetSQLCurrentTime -- implements CURRENT_TIME, CURRENT_TIME(n)
349 */
350TimeTzADT *
352{
353 TimeTzADT *result;
354 struct pg_tm tt,
355 *tm = &tt;
356 fsec_t fsec;
357 int tz;
358
359 GetCurrentTimeUsec(tm, &fsec, &tz);
360
361 result = palloc_object(TimeTzADT);
362 tm2timetz(tm, fsec, tz, result);
363 AdjustTimeForTypmod(&(result->time), typmod);
364 return result;
365}
366
367/*
368 * GetSQLLocalTime -- implements LOCALTIME, LOCALTIME(n)
369 */
372{
373 TimeADT result;
374 struct pg_tm tt,
375 *tm = &tt;
376 fsec_t fsec;
377 int tz;
378
379 GetCurrentTimeUsec(tm, &fsec, &tz);
380
381 tm2time(tm, fsec, &result);
382 AdjustTimeForTypmod(&result, typmod);
383 return result;
384}
385
386
387/*
388 * Comparison functions for dates
389 */
390
391Datum
399
400Datum
408
409Datum
417
418Datum
426
427Datum
435
436Datum
444
445Datum
457
458Datum
466
467static Datum
469{
471
473 {
474 /* return value is undefined */
475 *underflow = true;
476 return (Datum) 0;
477 }
478
479 *underflow = false;
480 return DateADTGetDatum(dexisting - 1);
481}
482
483static Datum
485{
487
489 {
490 /* return value is undefined */
491 *overflow = true;
492 return (Datum) 0;
493 }
494
495 *overflow = false;
496 return DateADTGetDatum(dexisting + 1);
497}
498
499Datum
511
512Datum
517
518Datum
523
524Datum
531
532Datum
540
541Datum
549
550/* Compute difference between two dates in days.
551 */
552Datum
565
566/* Add a number of days to a date, giving a new date.
567 * Must handle both positive and negative numbers of days.
568 */
569Datum
571{
574 DateADT result;
575
577 PG_RETURN_DATEADT(dateVal); /* can't change infinity */
578
579 result = dateVal + days;
580
581 /* Check for integer overflow and out-of-allowed-range */
582 if ((days >= 0 ? (result < dateVal) : (result > dateVal)) ||
583 !IS_VALID_DATE(result))
586 errmsg("date out of range")));
587
588 PG_RETURN_DATEADT(result);
589}
590
591/* Subtract a number of days from a date, giving a new date.
592 */
593Datum
595{
598 DateADT result;
599
601 PG_RETURN_DATEADT(dateVal); /* can't change infinity */
602
603 result = dateVal - days;
604
605 /* Check for integer overflow and out-of-allowed-range */
606 if ((days >= 0 ? (result > dateVal) : (result < dateVal)) ||
607 !IS_VALID_DATE(result))
610 errmsg("date out of range")));
611
612 PG_RETURN_DATEADT(result);
613}
614
615
616/*
617 * Promote date to timestamp.
618 *
619 * If the date falls out of the valid range for the timestamp type, error
620 * handling proceeds based on escontext.
621 *
622 * If escontext is NULL, we throw an out-of-range error (hard error).
623 * If escontext is not NULL, we return NOBEGIN or NOEND for lower bound or
624 * upper bound overflow, respectively, and record a soft error.
625 *
626 * Note: Lower bound overflow is currently not possible, as both date and
627 * timestamp datatypes share the same lower boundary: Julian day zero.
628 */
631{
632 Timestamp result;
633
635 TIMESTAMP_NOBEGIN(result);
636 else if (DATE_IS_NOEND(dateVal))
637 TIMESTAMP_NOEND(result);
638 else
639 {
640 /*
641 * Since dates have the same minimum values as timestamps, only upper
642 * boundary need be checked for overflow.
643 */
645 {
646 TIMESTAMP_NOEND(result);
647 ereturn(escontext, result,
649 errmsg("date out of range for timestamp")));
650 }
651
652 /* date is days since 2000, timestamp is microseconds since same... */
653 result = dateVal * USECS_PER_DAY;
654 }
655
656 return result;
657}
658
659/*
660 * Promote date to timestamp, throwing error for overflow.
661 */
662static TimestampTz
667
668/*
669 * Promote date to timestamp with time zone.
670 *
671 * If the date falls out of the valid range for the timestamp type, error
672 * handling proceeds based on escontext.
673 *
674 * If escontext is NULL, we throw an out-of-range error (hard error).
675 * If escontext is not NULL, we return NOBEGIN or NOEND for lower bound or
676 * upper bound overflow, respectively, and record a soft error.
677 */
680{
681 TimestampTz result;
682 struct pg_tm tt,
683 *tm = &tt;
684 int tz;
685
687 TIMESTAMP_NOBEGIN(result);
688 else if (DATE_IS_NOEND(dateVal))
689 TIMESTAMP_NOEND(result);
690 else
691 {
692 /*
693 * Since dates have the same minimum values as timestamps, only upper
694 * boundary need be checked for overflow.
695 */
697 {
698 TIMESTAMP_NOEND(result);
699 ereturn(escontext, result,
701 errmsg("date out of range for timestamp")));
702 }
703
705 &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
706 tm->tm_hour = 0;
707 tm->tm_min = 0;
708 tm->tm_sec = 0;
710
711 result = dateVal * USECS_PER_DAY + tz * USECS_PER_SEC;
712
713 /*
714 * Since it is possible to go beyond allowed timestamptz range because
715 * of time zone, check for allowed timestamp range after adding tz.
716 */
717 if (!IS_VALID_TIMESTAMP(result))
718 {
719 if (result < MIN_TIMESTAMP)
720 TIMESTAMP_NOBEGIN(result);
721 else
722 TIMESTAMP_NOEND(result);
723
724 ereturn(escontext, result,
726 errmsg("date out of range for timestamp")));
727 }
728 }
729
730 return result;
731}
732
733/*
734 * Promote date to timestamptz, throwing error for overflow.
735 */
736static TimestampTz
741
742/*
743 * date2timestamp_no_overflow
744 *
745 * This is chartered to produce a double value that is numerically
746 * equivalent to the corresponding Timestamp value, if the date is in the
747 * valid range of Timestamps, but in any case not throw an overflow error.
748 * We can do this since the numerical range of double is greater than
749 * that of non-erroneous timestamps. The results are currently only
750 * used for statistical estimation purposes.
751 */
752double
754{
755 double result;
756
758 result = -DBL_MAX;
759 else if (DATE_IS_NOEND(dateVal))
760 result = DBL_MAX;
761 else
762 {
763 /* date is days since 2000, timestamp is microseconds since same... */
764 result = dateVal * (double) USECS_PER_DAY;
765 }
766
767 return result;
768}
769
770
771/*
772 * Crosstype comparison functions for dates
773 */
774
775int32
777{
780
781 dt1 = date2timestamp_safe(dateVal, (Node *) &escontext);
782 if (escontext.error_occurred)
783 {
784 Assert(TIMESTAMP_IS_NOEND(dt1)); /* NOBEGIN case cannot occur */
785
786 /* dt1 is larger than any finite timestamp, but less than infinity */
787 return TIMESTAMP_IS_NOEND(dt2) ? -1 : +1;
788 }
789
791}
792
793Datum
801
802Datum
810
811Datum
819
820Datum
828
829Datum
837
838Datum
846
847Datum
855
856int32
858{
861
862 dt1 = date2timestamptz_safe(dateVal, (Node *) &escontext);
863
864 if (escontext.error_occurred)
865 {
867 {
868 /* dt1 is larger than any finite timestamp, but less than infinity */
869 return TIMESTAMP_IS_NOEND(dt2) ? -1 : +1;
870 }
872 {
873 /* dt1 is less than any finite timestamp, but more than -infinity */
874 return TIMESTAMP_IS_NOBEGIN(dt2) ? +1 : -1;
875 }
876 }
877
879}
880
881Datum
889
890Datum
898
899Datum
907
908Datum
916
917Datum
925
926Datum
934
935Datum
943
944Datum
952
953Datum
961
962Datum
970
971Datum
979
980Datum
988
989Datum
997
998Datum
1006
1007Datum
1015
1016Datum
1024
1025Datum
1033
1034Datum
1042
1043Datum
1051
1052Datum
1060
1061Datum
1069
1070/*
1071 * in_range support function for date.
1072 *
1073 * We implement this by promoting the dates to timestamp (without time zone)
1074 * and then using the timestamp-and-interval in_range function.
1075 */
1076Datum
1078{
1080 DateADT base = PG_GETARG_DATEADT(1);
1081 Interval *offset = PG_GETARG_INTERVAL_P(2);
1082 bool sub = PG_GETARG_BOOL(3);
1083 bool less = PG_GETARG_BOOL(4);
1086
1087 /* XXX we could support out-of-range cases here, perhaps */
1089 baseStamp = date2timestamp(base);
1090
1094 IntervalPGetDatum(offset),
1095 BoolGetDatum(sub),
1097}
1098
1099
1100/* extract_date()
1101 * Extract specified field from date type.
1102 */
1103Datum
1105{
1109 int type,
1110 val;
1111 char *lowunits;
1112 int year,
1113 mon,
1114 mday;
1115
1118 false);
1119
1120 type = DecodeUnits(0, lowunits, &val);
1121 if (type == UNKNOWN_FIELD)
1123
1124 if (DATE_NOT_FINITE(date) && (type == UNITS || type == RESERV))
1125 {
1126 switch (val)
1127 {
1128 /* Oscillating units */
1129 case DTK_DAY:
1130 case DTK_MONTH:
1131 case DTK_QUARTER:
1132 case DTK_WEEK:
1133 case DTK_DOW:
1134 case DTK_ISODOW:
1135 case DTK_DOY:
1137 break;
1138
1139 /* Monotonically-increasing units */
1140 case DTK_YEAR:
1141 case DTK_DECADE:
1142 case DTK_CENTURY:
1143 case DTK_MILLENNIUM:
1144 case DTK_JULIAN:
1145 case DTK_ISOYEAR:
1146 case DTK_EPOCH:
1147 if (DATE_IS_NOBEGIN(date))
1149 CStringGetDatum("-Infinity"),
1151 Int32GetDatum(-1))));
1152 else
1154 CStringGetDatum("Infinity"),
1156 Int32GetDatum(-1))));
1157 default:
1158 ereport(ERROR,
1160 errmsg("unit \"%s\" not supported for type %s",
1162 }
1163 }
1164 else if (type == UNITS)
1165 {
1166 j2date(date + POSTGRES_EPOCH_JDATE, &year, &mon, &mday);
1167
1168 switch (val)
1169 {
1170 case DTK_DAY:
1171 intresult = mday;
1172 break;
1173
1174 case DTK_MONTH:
1175 intresult = mon;
1176 break;
1177
1178 case DTK_QUARTER:
1179 intresult = (mon - 1) / 3 + 1;
1180 break;
1181
1182 case DTK_WEEK:
1183 intresult = date2isoweek(year, mon, mday);
1184 break;
1185
1186 case DTK_YEAR:
1187 if (year > 0)
1188 intresult = year;
1189 else
1190 /* there is no year 0, just 1 BC and 1 AD */
1191 intresult = year - 1;
1192 break;
1193
1194 case DTK_DECADE:
1195 /* see comments in timestamp_part */
1196 if (year >= 0)
1197 intresult = year / 10;
1198 else
1199 intresult = -((8 - (year - 1)) / 10);
1200 break;
1201
1202 case DTK_CENTURY:
1203 /* see comments in timestamp_part */
1204 if (year > 0)
1205 intresult = (year + 99) / 100;
1206 else
1207 intresult = -((99 - (year - 1)) / 100);
1208 break;
1209
1210 case DTK_MILLENNIUM:
1211 /* see comments in timestamp_part */
1212 if (year > 0)
1213 intresult = (year + 999) / 1000;
1214 else
1215 intresult = -((999 - (year - 1)) / 1000);
1216 break;
1217
1218 case DTK_JULIAN:
1220 break;
1221
1222 case DTK_ISOYEAR:
1223 intresult = date2isoyear(year, mon, mday);
1224 /* Adjust BC years */
1225 if (intresult <= 0)
1226 intresult -= 1;
1227 break;
1228
1229 case DTK_DOW:
1230 case DTK_ISODOW:
1232 if (val == DTK_ISODOW && intresult == 0)
1233 intresult = 7;
1234 break;
1235
1236 case DTK_DOY:
1237 intresult = date2j(year, mon, mday) - date2j(year, 1, 1) + 1;
1238 break;
1239
1240 default:
1241 ereport(ERROR,
1243 errmsg("unit \"%s\" not supported for type %s",
1245 intresult = 0;
1246 }
1247 }
1248 else if (type == RESERV)
1249 {
1250 switch (val)
1251 {
1252 case DTK_EPOCH:
1254 break;
1255
1256 default:
1257 ereport(ERROR,
1259 errmsg("unit \"%s\" not supported for type %s",
1261 intresult = 0;
1262 }
1263 }
1264 else
1265 {
1266 ereport(ERROR,
1268 errmsg("unit \"%s\" not recognized for type %s",
1270 intresult = 0;
1271 }
1272
1274}
1275
1276
1277/* Add an interval to a date, giving a new date.
1278 * Must handle both positive and negative intervals.
1279 *
1280 * We implement this by promoting the date to timestamp (without time zone)
1281 * and then using the timestamp plus interval function.
1282 */
1283Datum
1296
1297/* Subtract an interval from a date, giving a new date.
1298 * Must handle both positive and negative intervals.
1299 *
1300 * We implement this by promoting the date to timestamp (without time zone)
1301 * and then using the timestamp minus interval function.
1302 */
1303Datum
1316
1317/* date_timestamp()
1318 * Convert date to timestamp data type.
1319 */
1320Datum
1322{
1324 Timestamp result;
1325
1326 result = date2timestamp(dateVal);
1327
1328 PG_RETURN_TIMESTAMP(result);
1329}
1330
1331/* timestamp_date()
1332 * Convert timestamp to date data type.
1333 */
1334Datum
1343
1344/*
1345 * Convert timestamp to date.
1346 *
1347 * If the timestamp falls out of the valid range for the date type, error
1348 * handling proceeds based on escontext.
1349 *
1350 * If escontext is NULL, we throw an out-of-range error (hard error).
1351 * If escontext is not NULL, we return NOBEGIN or NOEND for lower bound or
1352 * upper bound overflow, respectively, and record a soft error.
1353 *
1354 * Note: given the ranges of the types, overflow is only possible at
1355 * the lower bound of the range, but we don't assume that in this code.
1356 */
1357DateADT
1359{
1360 DateADT result;
1361 struct pg_tm tt,
1362 *tm = &tt;
1363 fsec_t fsec;
1364
1366 DATE_NOBEGIN(result);
1367 else if (TIMESTAMP_IS_NOEND(timestamp))
1368 DATE_NOEND(result);
1369 else
1370 {
1371 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
1372 {
1373 if (timestamp < 0)
1374 DATE_NOBEGIN(result);
1375 else
1376 DATE_NOEND(result); /* not actually reachable */
1377
1378 ereturn(escontext, result,
1380 errmsg("timestamp out of range")));
1381 }
1382
1384 }
1385
1386 return result;
1387}
1388
1389
1390/* date_timestamptz()
1391 * Convert date to timestamp with time zone data type.
1392 */
1393Datum
1395{
1397 TimestampTz result;
1398
1399 result = date2timestamptz(dateVal);
1400
1401 PG_RETURN_TIMESTAMP(result);
1402}
1403
1404
1405/* timestamptz_date()
1406 * Convert timestamp with time zone to date data type.
1407 */
1408Datum
1417
1418/*
1419 * Convert timestamptz to date.
1420 *
1421 * If the timestamp falls out of the valid range for the date type, error
1422 * handling proceeds based on escontext.
1423 *
1424 * If escontext is NULL, we throw an out-of-range error (hard error).
1425 * If escontext is not NULL, we return NOBEGIN or NOEND for lower bound or
1426 * upper bound overflow, respectively, and record a soft error.
1427 *
1428 * Note: given the ranges of the types, overflow is only possible at
1429 * the lower bound of the range, but we don't assume that in this code.
1430 */
1431DateADT
1433{
1434 DateADT result;
1435 struct pg_tm tt,
1436 *tm = &tt;
1437 fsec_t fsec;
1438 int tz;
1439
1441 DATE_NOBEGIN(result);
1442 else if (TIMESTAMP_IS_NOEND(timestamp))
1443 DATE_NOEND(result);
1444 else
1445 {
1446 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
1447 {
1448 if (timestamp < 0)
1449 DATE_NOBEGIN(result);
1450 else
1451 DATE_NOEND(result); /* not actually reachable */
1452
1453 ereturn(escontext, result,
1455 errmsg("timestamp out of range")));
1456 }
1457
1459 }
1460
1461 return result;
1462}
1463
1464
1465/*****************************************************************************
1466 * Time ADT
1467 *****************************************************************************/
1468
1469Datum
1471{
1472 char *str = PG_GETARG_CSTRING(0);
1473#ifdef NOT_USED
1474 Oid typelem = PG_GETARG_OID(1);
1475#endif
1476 int32 typmod = PG_GETARG_INT32(2);
1477 Node *escontext = fcinfo->context;
1478 TimeADT result;
1479 fsec_t fsec;
1480 struct pg_tm tt,
1481 *tm = &tt;
1482 int tz;
1483 int nf;
1484 int dterr;
1485 char workbuf[MAXDATELEN + 1];
1486 char *field[MAXDATEFIELDS];
1487 int dtype;
1488 int ftype[MAXDATEFIELDS];
1489 DateTimeErrorExtra extra;
1490
1492 field, ftype, MAXDATEFIELDS, &nf);
1493 if (dterr == 0)
1494 dterr = DecodeTimeOnly(field, ftype, nf,
1495 &dtype, tm, &fsec, &tz, &extra);
1496 if (dterr != 0)
1497 {
1498 DateTimeParseError(dterr, &extra, str, "time", escontext);
1500 }
1501
1502 tm2time(tm, fsec, &result);
1503 AdjustTimeForTypmod(&result, typmod);
1504
1505 PG_RETURN_TIMEADT(result);
1506}
1507
1508/* tm2time()
1509 * Convert a tm structure to a time data type.
1510 */
1511int
1512tm2time(struct pg_tm *tm, fsec_t fsec, TimeADT *result)
1513{
1514 *result = ((((tm->tm_hour * MINS_PER_HOUR + tm->tm_min) * SECS_PER_MINUTE) + tm->tm_sec)
1515 * USECS_PER_SEC) + fsec;
1516 return 0;
1517}
1518
1519/* time_overflows()
1520 * Check to see if a broken-down time-of-day is out of range.
1521 */
1522bool
1523time_overflows(int hour, int min, int sec, fsec_t fsec)
1524{
1525 /* Range-check the fields individually. */
1530 return true;
1531
1532 /*
1533 * Because we allow, eg, hour = 24 or sec = 60, we must check separately
1534 * that the total time value doesn't exceed 24:00:00.
1535 */
1536 if ((((((hour * MINS_PER_HOUR + min) * SECS_PER_MINUTE)
1537 + sec) * USECS_PER_SEC) + fsec) > USECS_PER_DAY)
1538 return true;
1539
1540 return false;
1541}
1542
1543/* float_time_overflows()
1544 * Same, when we have seconds + fractional seconds as one "double" value.
1545 */
1546bool
1547float_time_overflows(int hour, int min, double sec)
1548{
1549 /* Range-check the fields individually. */
1552 return true;
1553
1554 /*
1555 * "sec", being double, requires extra care. Cope with NaN, and round off
1556 * before applying the range check to avoid unexpected errors due to
1557 * imprecise input. (We assume rint() behaves sanely with infinities.)
1558 */
1559 if (isnan(sec))
1560 return true;
1561 sec = rint(sec * USECS_PER_SEC);
1563 return true;
1564
1565 /*
1566 * Because we allow, eg, hour = 24 or sec = 60, we must check separately
1567 * that the total time value doesn't exceed 24:00:00. This must match the
1568 * way that callers will convert the fields to a time.
1569 */
1570 if (((((hour * MINS_PER_HOUR + min) * SECS_PER_MINUTE)
1571 * USECS_PER_SEC) + (int64) sec) > USECS_PER_DAY)
1572 return true;
1573
1574 return false;
1575}
1576
1577
1578/* time2tm()
1579 * Convert time data type to POSIX time structure.
1580 *
1581 * Note that only the hour/min/sec/fractional-sec fields are filled in.
1582 */
1583int
1584time2tm(TimeADT time, struct pg_tm *tm, fsec_t *fsec)
1585{
1586 tm->tm_hour = time / USECS_PER_HOUR;
1587 time -= tm->tm_hour * USECS_PER_HOUR;
1588 tm->tm_min = time / USECS_PER_MINUTE;
1589 time -= tm->tm_min * USECS_PER_MINUTE;
1590 tm->tm_sec = time / USECS_PER_SEC;
1591 time -= tm->tm_sec * USECS_PER_SEC;
1592 *fsec = time;
1593 return 0;
1594}
1595
1596Datum
1598{
1599 TimeADT time = PG_GETARG_TIMEADT(0);
1600 char *result;
1601 struct pg_tm tt,
1602 *tm = &tt;
1603 fsec_t fsec;
1604 char buf[MAXDATELEN + 1];
1605
1606 time2tm(time, tm, &fsec);
1607 EncodeTimeOnly(tm, fsec, false, 0, DateStyle, buf);
1608
1609 result = pstrdup(buf);
1610 PG_RETURN_CSTRING(result);
1611}
1612
1613/*
1614 * time_recv - converts external binary format to time
1615 */
1616Datum
1618{
1620
1621#ifdef NOT_USED
1622 Oid typelem = PG_GETARG_OID(1);
1623#endif
1624 int32 typmod = PG_GETARG_INT32(2);
1625 TimeADT result;
1626
1627 result = pq_getmsgint64(buf);
1628
1629 if (result < INT64CONST(0) || result > USECS_PER_DAY)
1630 ereport(ERROR,
1632 errmsg("time out of range")));
1633
1634 AdjustTimeForTypmod(&result, typmod);
1635
1636 PG_RETURN_TIMEADT(result);
1637}
1638
1639/*
1640 * time_send - converts time to binary format
1641 */
1642Datum
1652
1653Datum
1660
1661Datum
1663{
1664 int32 typmod = PG_GETARG_INT32(0);
1665
1666 PG_RETURN_CSTRING(anytime_typmodout(false, typmod));
1667}
1668
1669/*
1670 * make_time - time constructor
1671 */
1672Datum
1674{
1675 int tm_hour = PG_GETARG_INT32(0);
1676 int tm_min = PG_GETARG_INT32(1);
1677 double sec = PG_GETARG_FLOAT8(2);
1678 TimeADT time;
1679
1680 /* Check for time overflow */
1682 ereport(ERROR,
1684 errmsg("time field value out of range: %d:%02d:%02g",
1685 tm_hour, tm_min, sec)));
1686
1687 /* This should match tm2time */
1689 * USECS_PER_SEC) + (int64) rint(sec * USECS_PER_SEC);
1690
1691 PG_RETURN_TIMEADT(time);
1692}
1693
1694
1695/* time_support()
1696 *
1697 * Planner support function for the time_scale() and timetz_scale()
1698 * length coercion functions (we need not distinguish them here).
1699 */
1700Datum
1702{
1704 Node *ret = NULL;
1705
1707 {
1709
1710 ret = TemporalSimplify(MAX_TIME_PRECISION, (Node *) req->fcall);
1711 }
1712
1713 PG_RETURN_POINTER(ret);
1714}
1715
1716/* time_scale()
1717 * Adjust time type for specified scale factor.
1718 * Used by PostgreSQL type system to stuff columns.
1719 */
1720Datum
1722{
1723 TimeADT time = PG_GETARG_TIMEADT(0);
1724 int32 typmod = PG_GETARG_INT32(1);
1725 TimeADT result;
1726
1727 result = time;
1728 AdjustTimeForTypmod(&result, typmod);
1729
1730 PG_RETURN_TIMEADT(result);
1731}
1732
1733/* AdjustTimeForTypmod()
1734 * Force the precision of the time value to a specified value.
1735 * Uses *exactly* the same code as in AdjustTimestampForTypmod()
1736 * but we make a separate copy because those types do not
1737 * have a fundamental tie together but rather a coincidence of
1738 * implementation. - thomas
1739 */
1740void
1742{
1743 static const int64 TimeScales[MAX_TIME_PRECISION + 1] = {
1744 INT64CONST(1000000),
1745 INT64CONST(100000),
1746 INT64CONST(10000),
1747 INT64CONST(1000),
1748 INT64CONST(100),
1749 INT64CONST(10),
1750 INT64CONST(1)
1751 };
1752
1753 static const int64 TimeOffsets[MAX_TIME_PRECISION + 1] = {
1754 INT64CONST(500000),
1755 INT64CONST(50000),
1756 INT64CONST(5000),
1757 INT64CONST(500),
1758 INT64CONST(50),
1759 INT64CONST(5),
1760 INT64CONST(0)
1761 };
1762
1763 if (typmod >= 0 && typmod <= MAX_TIME_PRECISION)
1764 {
1765 if (*time >= INT64CONST(0))
1766 *time = ((*time + TimeOffsets[typmod]) / TimeScales[typmod]) *
1767 TimeScales[typmod];
1768 else
1769 *time = -((((-*time) + TimeOffsets[typmod]) / TimeScales[typmod]) *
1770 TimeScales[typmod]);
1771 }
1772}
1773
1774
1775Datum
1783
1784Datum
1792
1793Datum
1801
1802Datum
1810
1811Datum
1819
1820Datum
1828
1829Datum
1831{
1834
1835 if (time1 < time2)
1836 PG_RETURN_INT32(-1);
1837 if (time1 > time2)
1838 PG_RETURN_INT32(1);
1839 PG_RETURN_INT32(0);
1840}
1841
1842Datum
1844{
1845 return hashint8(fcinfo);
1846}
1847
1848Datum
1850{
1851 return hashint8extended(fcinfo);
1852}
1853
1854Datum
1862
1863Datum
1871
1872/* overlaps_time() --- implements the SQL OVERLAPS operator.
1873 *
1874 * Algorithm is per SQL spec. This is much harder than you'd think
1875 * because the spec requires us to deliver a non-null answer in some cases
1876 * where some of the inputs are null.
1877 */
1878Datum
1880{
1881 /*
1882 * The arguments are TimeADT, but we leave them as generic Datums to avoid
1883 * dereferencing nulls (TimeADT is pass-by-reference!)
1884 */
1889 bool ts1IsNull = PG_ARGISNULL(0);
1890 bool te1IsNull = PG_ARGISNULL(1);
1891 bool ts2IsNull = PG_ARGISNULL(2);
1892 bool te2IsNull = PG_ARGISNULL(3);
1893
1894#define TIMEADT_GT(t1,t2) \
1895 (DatumGetTimeADT(t1) > DatumGetTimeADT(t2))
1896#define TIMEADT_LT(t1,t2) \
1897 (DatumGetTimeADT(t1) < DatumGetTimeADT(t2))
1898
1899 /*
1900 * If both endpoints of interval 1 are null, the result is null (unknown).
1901 * If just one endpoint is null, take ts1 as the non-null one. Otherwise,
1902 * take ts1 as the lesser endpoint.
1903 */
1904 if (ts1IsNull)
1905 {
1906 if (te1IsNull)
1908 /* swap null for non-null */
1909 ts1 = te1;
1910 te1IsNull = true;
1911 }
1912 else if (!te1IsNull)
1913 {
1914 if (TIMEADT_GT(ts1, te1))
1915 {
1916 Datum tt = ts1;
1917
1918 ts1 = te1;
1919 te1 = tt;
1920 }
1921 }
1922
1923 /* Likewise for interval 2. */
1924 if (ts2IsNull)
1925 {
1926 if (te2IsNull)
1928 /* swap null for non-null */
1929 ts2 = te2;
1930 te2IsNull = true;
1931 }
1932 else if (!te2IsNull)
1933 {
1934 if (TIMEADT_GT(ts2, te2))
1935 {
1936 Datum tt = ts2;
1937
1938 ts2 = te2;
1939 te2 = tt;
1940 }
1941 }
1942
1943 /*
1944 * At this point neither ts1 nor ts2 is null, so we can consider three
1945 * cases: ts1 > ts2, ts1 < ts2, ts1 = ts2
1946 */
1947 if (TIMEADT_GT(ts1, ts2))
1948 {
1949 /*
1950 * This case is ts1 < te2 OR te1 < te2, which may look redundant but
1951 * in the presence of nulls it's not quite completely so.
1952 */
1953 if (te2IsNull)
1955 if (TIMEADT_LT(ts1, te2))
1956 PG_RETURN_BOOL(true);
1957 if (te1IsNull)
1959
1960 /*
1961 * If te1 is not null then we had ts1 <= te1 above, and we just found
1962 * ts1 >= te2, hence te1 >= te2.
1963 */
1964 PG_RETURN_BOOL(false);
1965 }
1966 else if (TIMEADT_LT(ts1, ts2))
1967 {
1968 /* This case is ts2 < te1 OR te2 < te1 */
1969 if (te1IsNull)
1971 if (TIMEADT_LT(ts2, te1))
1972 PG_RETURN_BOOL(true);
1973 if (te2IsNull)
1975
1976 /*
1977 * If te2 is not null then we had ts2 <= te2 above, and we just found
1978 * ts2 >= te1, hence te2 >= te1.
1979 */
1980 PG_RETURN_BOOL(false);
1981 }
1982 else
1983 {
1984 /*
1985 * For ts1 = ts2 the spec says te1 <> te2 OR te1 = te2, which is a
1986 * rather silly way of saying "true if both are nonnull, else null".
1987 */
1988 if (te1IsNull || te2IsNull)
1990 PG_RETURN_BOOL(true);
1991 }
1992
1993#undef TIMEADT_GT
1994#undef TIMEADT_LT
1995}
1996
1997/* timestamp_time()
1998 * Convert timestamp to time data type.
1999 */
2000Datum
2002{
2004 TimeADT result;
2005 struct pg_tm tt,
2006 *tm = &tt;
2007 fsec_t fsec;
2008
2011
2012 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
2013 ereport(ERROR,
2015 errmsg("timestamp out of range")));
2016
2017 /*
2018 * Could also do this with time = (timestamp / USECS_PER_DAY *
2019 * USECS_PER_DAY) - timestamp;
2020 */
2021 result = ((((tm->tm_hour * MINS_PER_HOUR + tm->tm_min) * SECS_PER_MINUTE) + tm->tm_sec) *
2022 USECS_PER_SEC) + fsec;
2023
2024 PG_RETURN_TIMEADT(result);
2025}
2026
2027/* timestamptz_time()
2028 * Convert timestamptz to time data type.
2029 */
2030Datum
2032{
2034 TimeADT result;
2035 struct pg_tm tt,
2036 *tm = &tt;
2037 int tz;
2038 fsec_t fsec;
2039
2042
2043 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
2044 ereport(ERROR,
2046 errmsg("timestamp out of range")));
2047
2048 /*
2049 * Could also do this with time = (timestamp / USECS_PER_DAY *
2050 * USECS_PER_DAY) - timestamp;
2051 */
2052 result = ((((tm->tm_hour * MINS_PER_HOUR + tm->tm_min) * SECS_PER_MINUTE) + tm->tm_sec) *
2053 USECS_PER_SEC) + fsec;
2054
2055 PG_RETURN_TIMEADT(result);
2056}
2057
2058/* datetime_timestamp()
2059 * Convert date and time to timestamp data type.
2060 */
2061Datum
2063{
2065 TimeADT time = PG_GETARG_TIMEADT(1);
2066 Timestamp result;
2067
2068 result = date2timestamp(date);
2069 if (!TIMESTAMP_NOT_FINITE(result))
2070 {
2071 result += time;
2072 if (!IS_VALID_TIMESTAMP(result))
2073 ereport(ERROR,
2075 errmsg("timestamp out of range")));
2076 }
2077
2078 PG_RETURN_TIMESTAMP(result);
2079}
2080
2081/* time_interval()
2082 * Convert time to interval data type.
2083 */
2084Datum
2086{
2087 TimeADT time = PG_GETARG_TIMEADT(0);
2088 Interval *result;
2089
2090 result = palloc_object(Interval);
2091
2092 result->time = time;
2093 result->day = 0;
2094 result->month = 0;
2095
2096 PG_RETURN_INTERVAL_P(result);
2097}
2098
2099/* interval_time()
2100 * Convert interval to time data type.
2101 *
2102 * This is defined as producing the fractional-day portion of the interval.
2103 * Therefore, we can just ignore the months field. It is not real clear
2104 * what to do with negative intervals, but we choose to subtract the floor,
2105 * so that, say, '-2 hours' becomes '22:00:00'.
2106 */
2107Datum
2109{
2111 TimeADT result;
2112
2114 ereport(ERROR,
2116 errmsg("cannot convert infinite interval to time")));
2117
2118 result = span->time % USECS_PER_DAY;
2119 if (result < 0)
2120 result += USECS_PER_DAY;
2121
2122 PG_RETURN_TIMEADT(result);
2123}
2124
2125/* time_mi_time()
2126 * Subtract two times to produce an interval.
2127 */
2128Datum
2130{
2133 Interval *result;
2134
2135 result = palloc_object(Interval);
2136
2137 result->month = 0;
2138 result->day = 0;
2139 result->time = time1 - time2;
2140
2141 PG_RETURN_INTERVAL_P(result);
2142}
2143
2144/* time_pl_interval()
2145 * Add interval to time.
2146 */
2147Datum
2149{
2150 TimeADT time = PG_GETARG_TIMEADT(0);
2152 TimeADT result;
2153
2155 ereport(ERROR,
2157 errmsg("cannot add infinite interval to time")));
2158
2159 result = time + span->time;
2160 result -= result / USECS_PER_DAY * USECS_PER_DAY;
2161 if (result < INT64CONST(0))
2162 result += USECS_PER_DAY;
2163
2164 PG_RETURN_TIMEADT(result);
2165}
2166
2167/* time_mi_interval()
2168 * Subtract interval from time.
2169 */
2170Datum
2172{
2173 TimeADT time = PG_GETARG_TIMEADT(0);
2175 TimeADT result;
2176
2178 ereport(ERROR,
2180 errmsg("cannot subtract infinite interval from time")));
2181
2182 result = time - span->time;
2183 result -= result / USECS_PER_DAY * USECS_PER_DAY;
2184 if (result < INT64CONST(0))
2185 result += USECS_PER_DAY;
2186
2187 PG_RETURN_TIMEADT(result);
2188}
2189
2190/*
2191 * in_range support function for time.
2192 */
2193Datum
2195{
2197 TimeADT base = PG_GETARG_TIMEADT(1);
2198 Interval *offset = PG_GETARG_INTERVAL_P(2);
2199 bool sub = PG_GETARG_BOOL(3);
2200 bool less = PG_GETARG_BOOL(4);
2201 TimeADT sum;
2202
2203 /*
2204 * Like time_pl_interval/time_mi_interval, we disregard the month and day
2205 * fields of the offset. So our test for negative should too. This also
2206 * catches -infinity, so we only need worry about +infinity below.
2207 */
2208 if (offset->time < 0)
2209 ereport(ERROR,
2211 errmsg("invalid preceding or following size in window function")));
2212
2213 /*
2214 * We can't use time_pl_interval/time_mi_interval here, because their
2215 * wraparound behavior would give wrong (or at least undesirable) answers.
2216 * Fortunately the equivalent non-wrapping behavior is trivial, except
2217 * that adding an infinite (or very large) interval might cause integer
2218 * overflow. Subtraction cannot overflow here.
2219 */
2220 if (sub)
2221 sum = base - offset->time;
2222 else if (pg_add_s64_overflow(base, offset->time, &sum))
2224
2225 if (less)
2226 PG_RETURN_BOOL(val <= sum);
2227 else
2228 PG_RETURN_BOOL(val >= sum);
2229}
2230
2231
2232/* time_part() and extract_time()
2233 * Extract specified field from time type.
2234 */
2235static Datum
2237{
2239 TimeADT time = PG_GETARG_TIMEADT(1);
2241 int type,
2242 val;
2243 char *lowunits;
2244
2247 false);
2248
2249 type = DecodeUnits(0, lowunits, &val);
2250 if (type == UNKNOWN_FIELD)
2252
2253 if (type == UNITS)
2254 {
2255 fsec_t fsec;
2256 struct pg_tm tt,
2257 *tm = &tt;
2258
2259 time2tm(time, tm, &fsec);
2260
2261 switch (val)
2262 {
2263 case DTK_MICROSEC:
2264 intresult = tm->tm_sec * INT64CONST(1000000) + fsec;
2265 break;
2266
2267 case DTK_MILLISEC:
2268 if (retnumeric)
2269 /*---
2270 * tm->tm_sec * 1000 + fsec / 1000
2271 * = (tm->tm_sec * 1'000'000 + fsec) / 1000
2272 */
2274 else
2275 PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + fsec / 1000.0);
2276 break;
2277
2278 case DTK_SECOND:
2279 if (retnumeric)
2280 /*---
2281 * tm->tm_sec + fsec / 1'000'000
2282 * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
2283 */
2285 else
2286 PG_RETURN_FLOAT8(tm->tm_sec + fsec / 1000000.0);
2287 break;
2288
2289 case DTK_MINUTE:
2290 intresult = tm->tm_min;
2291 break;
2292
2293 case DTK_HOUR:
2294 intresult = tm->tm_hour;
2295 break;
2296
2297 case DTK_TZ:
2298 case DTK_TZ_MINUTE:
2299 case DTK_TZ_HOUR:
2300 case DTK_DAY:
2301 case DTK_MONTH:
2302 case DTK_QUARTER:
2303 case DTK_YEAR:
2304 case DTK_DECADE:
2305 case DTK_CENTURY:
2306 case DTK_MILLENNIUM:
2307 case DTK_ISOYEAR:
2308 default:
2309 ereport(ERROR,
2311 errmsg("unit \"%s\" not supported for type %s",
2313 intresult = 0;
2314 }
2315 }
2316 else if (type == RESERV && val == DTK_EPOCH)
2317 {
2318 if (retnumeric)
2320 else
2321 PG_RETURN_FLOAT8(time / 1000000.0);
2322 }
2323 else
2324 {
2325 ereport(ERROR,
2327 errmsg("unit \"%s\" not recognized for type %s",
2329 intresult = 0;
2330 }
2331
2332 if (retnumeric)
2334 else
2336}
2337
2338Datum
2340{
2341 return time_part_common(fcinfo, false);
2342}
2343
2344Datum
2346{
2347 return time_part_common(fcinfo, true);
2348}
2349
2350
2351/*****************************************************************************
2352 * Time With Time Zone ADT
2353 *****************************************************************************/
2354
2355/* tm2timetz()
2356 * Convert a tm structure to a time data type.
2357 */
2358int
2359tm2timetz(struct pg_tm *tm, fsec_t fsec, int tz, TimeTzADT *result)
2360{
2361 result->time = ((((tm->tm_hour * MINS_PER_HOUR + tm->tm_min) * SECS_PER_MINUTE) + tm->tm_sec) *
2362 USECS_PER_SEC) + fsec;
2363 result->zone = tz;
2364
2365 return 0;
2366}
2367
2368Datum
2370{
2371 char *str = PG_GETARG_CSTRING(0);
2372#ifdef NOT_USED
2373 Oid typelem = PG_GETARG_OID(1);
2374#endif
2375 int32 typmod = PG_GETARG_INT32(2);
2376 Node *escontext = fcinfo->context;
2377 TimeTzADT *result;
2378 fsec_t fsec;
2379 struct pg_tm tt,
2380 *tm = &tt;
2381 int tz;
2382 int nf;
2383 int dterr;
2384 char workbuf[MAXDATELEN + 1];
2385 char *field[MAXDATEFIELDS];
2386 int dtype;
2387 int ftype[MAXDATEFIELDS];
2388 DateTimeErrorExtra extra;
2389
2391 field, ftype, MAXDATEFIELDS, &nf);
2392 if (dterr == 0)
2393 dterr = DecodeTimeOnly(field, ftype, nf,
2394 &dtype, tm, &fsec, &tz, &extra);
2395 if (dterr != 0)
2396 {
2397 DateTimeParseError(dterr, &extra, str, "time with time zone",
2398 escontext);
2400 }
2401
2402 result = palloc_object(TimeTzADT);
2403 tm2timetz(tm, fsec, tz, result);
2404 AdjustTimeForTypmod(&(result->time), typmod);
2405
2406 PG_RETURN_TIMETZADT_P(result);
2407}
2408
2409Datum
2411{
2413 char *result;
2414 struct pg_tm tt,
2415 *tm = &tt;
2416 fsec_t fsec;
2417 int tz;
2418 char buf[MAXDATELEN + 1];
2419
2420 timetz2tm(time, tm, &fsec, &tz);
2421 EncodeTimeOnly(tm, fsec, true, tz, DateStyle, buf);
2422
2423 result = pstrdup(buf);
2424 PG_RETURN_CSTRING(result);
2425}
2426
2427/*
2428 * timetz_recv - converts external binary format to timetz
2429 */
2430Datum
2432{
2434
2435#ifdef NOT_USED
2436 Oid typelem = PG_GETARG_OID(1);
2437#endif
2438 int32 typmod = PG_GETARG_INT32(2);
2439 TimeTzADT *result;
2440
2441 result = palloc_object(TimeTzADT);
2442
2443 result->time = pq_getmsgint64(buf);
2444
2445 if (result->time < INT64CONST(0) || result->time > USECS_PER_DAY)
2446 ereport(ERROR,
2448 errmsg("time out of range")));
2449
2450 result->zone = pq_getmsgint(buf, sizeof(result->zone));
2451
2452 /* Check for sane GMT displacement; see notes in datatype/timestamp.h */
2453 if (result->zone <= -TZDISP_LIMIT || result->zone >= TZDISP_LIMIT)
2454 ereport(ERROR,
2456 errmsg("time zone displacement out of range")));
2457
2458 AdjustTimeForTypmod(&(result->time), typmod);
2459
2460 PG_RETURN_TIMETZADT_P(result);
2461}
2462
2463/*
2464 * timetz_send - converts timetz to binary format
2465 */
2466Datum
2477
2478Datum
2485
2486Datum
2488{
2489 int32 typmod = PG_GETARG_INT32(0);
2490
2491 PG_RETURN_CSTRING(anytime_typmodout(true, typmod));
2492}
2493
2494
2495/* timetz2tm()
2496 * Convert TIME WITH TIME ZONE data type to POSIX time structure.
2497 */
2498int
2499timetz2tm(TimeTzADT *time, struct pg_tm *tm, fsec_t *fsec, int *tzp)
2500{
2501 TimeOffset trem = time->time;
2502
2508 *fsec = trem - tm->tm_sec * USECS_PER_SEC;
2509
2510 if (tzp != NULL)
2511 *tzp = time->zone;
2512
2513 return 0;
2514}
2515
2516/* timetz_scale()
2517 * Adjust time type for specified scale factor.
2518 * Used by PostgreSQL type system to stuff columns.
2519 */
2520Datum
2522{
2524 int32 typmod = PG_GETARG_INT32(1);
2525 TimeTzADT *result;
2526
2527 result = palloc_object(TimeTzADT);
2528
2529 result->time = time->time;
2530 result->zone = time->zone;
2531
2532 AdjustTimeForTypmod(&(result->time), typmod);
2533
2534 PG_RETURN_TIMETZADT_P(result);
2535}
2536
2537
2538static int
2540{
2541 TimeOffset t1,
2542 t2;
2543
2544 /* Primary sort is by true (GMT-equivalent) time */
2545 t1 = time1->time + (time1->zone * USECS_PER_SEC);
2546 t2 = time2->time + (time2->zone * USECS_PER_SEC);
2547
2548 if (t1 > t2)
2549 return 1;
2550 if (t1 < t2)
2551 return -1;
2552
2553 /*
2554 * If same GMT time, sort by timezone; we only want to say that two
2555 * timetz's are equal if both the time and zone parts are equal.
2556 */
2557 if (time1->zone > time2->zone)
2558 return 1;
2559 if (time1->zone < time2->zone)
2560 return -1;
2561
2562 return 0;
2563}
2564
2565Datum
2573
2574Datum
2582
2583Datum
2591
2592Datum
2600
2601Datum
2609
2610Datum
2618
2619Datum
2627
2628Datum
2630{
2632 uint32 thash;
2633
2634 /*
2635 * To avoid any problems with padding bytes in the struct, we figure the
2636 * field hashes separately and XOR them.
2637 */
2639 Int64GetDatumFast(key->time)));
2640 thash ^= DatumGetUInt32(hash_uint32(key->zone));
2642}
2643
2644Datum
2646{
2648 Datum seed = PG_GETARG_DATUM(1);
2649 uint64 thash;
2650
2651 /* Same approach as timetz_hash */
2653 Int64GetDatumFast(key->time),
2654 seed));
2656 DatumGetInt64(seed)));
2658}
2659
2660Datum
2662{
2665 TimeTzADT *result;
2666
2668 result = time1;
2669 else
2670 result = time2;
2671 PG_RETURN_TIMETZADT_P(result);
2672}
2673
2674Datum
2676{
2679 TimeTzADT *result;
2680
2682 result = time1;
2683 else
2684 result = time2;
2685 PG_RETURN_TIMETZADT_P(result);
2686}
2687
2688/* timetz_pl_interval()
2689 * Add interval to timetz.
2690 */
2691Datum
2693{
2696 TimeTzADT *result;
2697
2699 ereport(ERROR,
2701 errmsg("cannot add infinite interval to time")));
2702
2703 result = palloc_object(TimeTzADT);
2704
2705 result->time = time->time + span->time;
2706 result->time -= result->time / USECS_PER_DAY * USECS_PER_DAY;
2707 if (result->time < INT64CONST(0))
2708 result->time += USECS_PER_DAY;
2709
2710 result->zone = time->zone;
2711
2712 PG_RETURN_TIMETZADT_P(result);
2713}
2714
2715/* timetz_mi_interval()
2716 * Subtract interval from timetz.
2717 */
2718Datum
2720{
2723 TimeTzADT *result;
2724
2726 ereport(ERROR,
2728 errmsg("cannot subtract infinite interval from time")));
2729
2730 result = palloc_object(TimeTzADT);
2731
2732 result->time = time->time - span->time;
2733 result->time -= result->time / USECS_PER_DAY * USECS_PER_DAY;
2734 if (result->time < INT64CONST(0))
2735 result->time += USECS_PER_DAY;
2736
2737 result->zone = time->zone;
2738
2739 PG_RETURN_TIMETZADT_P(result);
2740}
2741
2742/*
2743 * in_range support function for timetz.
2744 */
2745Datum
2747{
2750 Interval *offset = PG_GETARG_INTERVAL_P(2);
2751 bool sub = PG_GETARG_BOOL(3);
2752 bool less = PG_GETARG_BOOL(4);
2753 TimeTzADT sum;
2754
2755 /*
2756 * Like timetz_pl_interval/timetz_mi_interval, we disregard the month and
2757 * day fields of the offset. So our test for negative should too. This
2758 * also catches -infinity, so we only need worry about +infinity below.
2759 */
2760 if (offset->time < 0)
2761 ereport(ERROR,
2763 errmsg("invalid preceding or following size in window function")));
2764
2765 /*
2766 * We can't use timetz_pl_interval/timetz_mi_interval here, because their
2767 * wraparound behavior would give wrong (or at least undesirable) answers.
2768 * Fortunately the equivalent non-wrapping behavior is trivial, except
2769 * that adding an infinite (or very large) interval might cause integer
2770 * overflow. Subtraction cannot overflow here.
2771 */
2772 if (sub)
2773 sum.time = base->time - offset->time;
2774 else if (pg_add_s64_overflow(base->time, offset->time, &sum.time))
2776 sum.zone = base->zone;
2777
2778 if (less)
2780 else
2782}
2783
2784/* overlaps_timetz() --- implements the SQL OVERLAPS operator.
2785 *
2786 * Algorithm is per SQL spec. This is much harder than you'd think
2787 * because the spec requires us to deliver a non-null answer in some cases
2788 * where some of the inputs are null.
2789 */
2790Datum
2792{
2793 /*
2794 * The arguments are TimeTzADT *, but we leave them as generic Datums for
2795 * convenience of notation --- and to avoid dereferencing nulls.
2796 */
2801 bool ts1IsNull = PG_ARGISNULL(0);
2802 bool te1IsNull = PG_ARGISNULL(1);
2803 bool ts2IsNull = PG_ARGISNULL(2);
2804 bool te2IsNull = PG_ARGISNULL(3);
2805
2806#define TIMETZ_GT(t1,t2) \
2807 DatumGetBool(DirectFunctionCall2(timetz_gt,t1,t2))
2808#define TIMETZ_LT(t1,t2) \
2809 DatumGetBool(DirectFunctionCall2(timetz_lt,t1,t2))
2810
2811 /*
2812 * If both endpoints of interval 1 are null, the result is null (unknown).
2813 * If just one endpoint is null, take ts1 as the non-null one. Otherwise,
2814 * take ts1 as the lesser endpoint.
2815 */
2816 if (ts1IsNull)
2817 {
2818 if (te1IsNull)
2820 /* swap null for non-null */
2821 ts1 = te1;
2822 te1IsNull = true;
2823 }
2824 else if (!te1IsNull)
2825 {
2826 if (TIMETZ_GT(ts1, te1))
2827 {
2828 Datum tt = ts1;
2829
2830 ts1 = te1;
2831 te1 = tt;
2832 }
2833 }
2834
2835 /* Likewise for interval 2. */
2836 if (ts2IsNull)
2837 {
2838 if (te2IsNull)
2840 /* swap null for non-null */
2841 ts2 = te2;
2842 te2IsNull = true;
2843 }
2844 else if (!te2IsNull)
2845 {
2846 if (TIMETZ_GT(ts2, te2))
2847 {
2848 Datum tt = ts2;
2849
2850 ts2 = te2;
2851 te2 = tt;
2852 }
2853 }
2854
2855 /*
2856 * At this point neither ts1 nor ts2 is null, so we can consider three
2857 * cases: ts1 > ts2, ts1 < ts2, ts1 = ts2
2858 */
2859 if (TIMETZ_GT(ts1, ts2))
2860 {
2861 /*
2862 * This case is ts1 < te2 OR te1 < te2, which may look redundant but
2863 * in the presence of nulls it's not quite completely so.
2864 */
2865 if (te2IsNull)
2867 if (TIMETZ_LT(ts1, te2))
2868 PG_RETURN_BOOL(true);
2869 if (te1IsNull)
2871
2872 /*
2873 * If te1 is not null then we had ts1 <= te1 above, and we just found
2874 * ts1 >= te2, hence te1 >= te2.
2875 */
2876 PG_RETURN_BOOL(false);
2877 }
2878 else if (TIMETZ_LT(ts1, ts2))
2879 {
2880 /* This case is ts2 < te1 OR te2 < te1 */
2881 if (te1IsNull)
2883 if (TIMETZ_LT(ts2, te1))
2884 PG_RETURN_BOOL(true);
2885 if (te2IsNull)
2887
2888 /*
2889 * If te2 is not null then we had ts2 <= te2 above, and we just found
2890 * ts2 >= te1, hence te2 >= te1.
2891 */
2892 PG_RETURN_BOOL(false);
2893 }
2894 else
2895 {
2896 /*
2897 * For ts1 = ts2 the spec says te1 <> te2 OR te1 = te2, which is a
2898 * rather silly way of saying "true if both are nonnull, else null".
2899 */
2900 if (te1IsNull || te2IsNull)
2902 PG_RETURN_BOOL(true);
2903 }
2904
2905#undef TIMETZ_GT
2906#undef TIMETZ_LT
2907}
2908
2909
2910Datum
2912{
2914 TimeADT result;
2915
2916 /* swallow the time zone and just return the time */
2917 result = timetz->time;
2918
2919 PG_RETURN_TIMEADT(result);
2920}
2921
2922
2923Datum
2925{
2926 TimeADT time = PG_GETARG_TIMEADT(0);
2927 TimeTzADT *result;
2928 struct pg_tm tt,
2929 *tm = &tt;
2930 fsec_t fsec;
2931 int tz;
2932
2934 time2tm(time, tm, &fsec);
2936
2937 result = palloc_object(TimeTzADT);
2938
2939 result->time = time;
2940 result->zone = tz;
2941
2942 PG_RETURN_TIMETZADT_P(result);
2943}
2944
2945
2946/* timestamptz_timetz()
2947 * Convert timestamp to timetz data type.
2948 */
2949Datum
2951{
2953 TimeTzADT *result;
2954 struct pg_tm tt,
2955 *tm = &tt;
2956 int tz;
2957 fsec_t fsec;
2958
2961
2962 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
2963 ereport(ERROR,
2965 errmsg("timestamp out of range")));
2966
2967 result = palloc_object(TimeTzADT);
2968
2969 tm2timetz(tm, fsec, tz, result);
2970
2971 PG_RETURN_TIMETZADT_P(result);
2972}
2973
2974
2975/* datetimetz_timestamptz()
2976 * Convert date and timetz to timestamp with time zone data type.
2977 * Timestamp is stored in GMT, so add the time zone
2978 * stored with the timetz to the result.
2979 * - thomas 2000-03-10
2980 */
2981Datum
2983{
2986 TimestampTz result;
2987
2988 if (DATE_IS_NOBEGIN(date))
2989 TIMESTAMP_NOBEGIN(result);
2990 else if (DATE_IS_NOEND(date))
2991 TIMESTAMP_NOEND(result);
2992 else
2993 {
2994 /*
2995 * Date's range is wider than timestamp's, so check for boundaries.
2996 * Since dates have the same minimum values as timestamps, only upper
2997 * boundary need be checked for overflow.
2998 */
3000 ereport(ERROR,
3002 errmsg("date out of range for timestamp")));
3003 result = date * USECS_PER_DAY + time->time + time->zone * USECS_PER_SEC;
3004
3005 /*
3006 * Since it is possible to go beyond allowed timestamptz range because
3007 * of time zone, check for allowed timestamp range after adding tz.
3008 */
3009 if (!IS_VALID_TIMESTAMP(result))
3010 ereport(ERROR,
3012 errmsg("date out of range for timestamp")));
3013 }
3014
3015 PG_RETURN_TIMESTAMP(result);
3016}
3017
3018
3019/* timetz_part() and extract_timetz()
3020 * Extract specified field from time type.
3021 */
3022static Datum
3024{
3028 int type,
3029 val;
3030 char *lowunits;
3031
3034 false);
3035
3036 type = DecodeUnits(0, lowunits, &val);
3037 if (type == UNKNOWN_FIELD)
3039
3040 if (type == UNITS)
3041 {
3042 int tz;
3043 fsec_t fsec;
3044 struct pg_tm tt,
3045 *tm = &tt;
3046
3047 timetz2tm(time, tm, &fsec, &tz);
3048
3049 switch (val)
3050 {
3051 case DTK_TZ:
3052 intresult = -tz;
3053 break;
3054
3055 case DTK_TZ_MINUTE:
3057 break;
3058
3059 case DTK_TZ_HOUR:
3060 intresult = -tz / SECS_PER_HOUR;
3061 break;
3062
3063 case DTK_MICROSEC:
3064 intresult = tm->tm_sec * INT64CONST(1000000) + fsec;
3065 break;
3066
3067 case DTK_MILLISEC:
3068 if (retnumeric)
3069 /*---
3070 * tm->tm_sec * 1000 + fsec / 1000
3071 * = (tm->tm_sec * 1'000'000 + fsec) / 1000
3072 */
3074 else
3075 PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + fsec / 1000.0);
3076 break;
3077
3078 case DTK_SECOND:
3079 if (retnumeric)
3080 /*---
3081 * tm->tm_sec + fsec / 1'000'000
3082 * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
3083 */
3085 else
3086 PG_RETURN_FLOAT8(tm->tm_sec + fsec / 1000000.0);
3087 break;
3088
3089 case DTK_MINUTE:
3090 intresult = tm->tm_min;
3091 break;
3092
3093 case DTK_HOUR:
3094 intresult = tm->tm_hour;
3095 break;
3096
3097 case DTK_DAY:
3098 case DTK_MONTH:
3099 case DTK_QUARTER:
3100 case DTK_YEAR:
3101 case DTK_DECADE:
3102 case DTK_CENTURY:
3103 case DTK_MILLENNIUM:
3104 default:
3105 ereport(ERROR,
3107 errmsg("unit \"%s\" not supported for type %s",
3109 intresult = 0;
3110 }
3111 }
3112 else if (type == RESERV && val == DTK_EPOCH)
3113 {
3114 if (retnumeric)
3115 /*---
3116 * time->time / 1'000'000 + time->zone
3117 * = (time->time + time->zone * 1'000'000) / 1'000'000
3118 */
3119 PG_RETURN_NUMERIC(int64_div_fast_to_numeric(time->time + time->zone * INT64CONST(1000000), 6));
3120 else
3121 PG_RETURN_FLOAT8(time->time / 1000000.0 + time->zone);
3122 }
3123 else
3124 {
3125 ereport(ERROR,
3127 errmsg("unit \"%s\" not recognized for type %s",
3129 intresult = 0;
3130 }
3131
3132 if (retnumeric)
3134 else
3136}
3137
3138
3139Datum
3141{
3142 return timetz_part_common(fcinfo, false);
3143}
3144
3145Datum
3147{
3148 return timetz_part_common(fcinfo, true);
3149}
3150
3151/* timetz_zone()
3152 * Encode time with time zone type with specified time zone.
3153 * Applies DST rules as of the transaction start time.
3154 */
3155Datum
3157{
3160 TimeTzADT *result;
3161 int tz;
3162 char tzname[TZ_STRLEN_MAX + 1];
3163 int type,
3164 val;
3165 pg_tz *tzp;
3166
3167 /*
3168 * Look up the requested timezone.
3169 */
3171
3172 type = DecodeTimezoneName(tzname, &val, &tzp);
3173
3175 {
3176 /* fixed-offset abbreviation */
3177 tz = -val;
3178 }
3179 else if (type == TZNAME_DYNTZ)
3180 {
3181 /* dynamic-offset abbreviation, resolve using transaction start time */
3183 int isdst;
3184
3186 }
3187 else
3188 {
3189 /* Get the offset-from-GMT that is valid now for the zone name */
3191 struct pg_tm tm;
3192 fsec_t fsec;
3193
3194 if (timestamp2tm(now, &tz, &tm, &fsec, NULL, tzp) != 0)
3195 ereport(ERROR,
3197 errmsg("timestamp out of range")));
3198 }
3199
3200 result = palloc_object(TimeTzADT);
3201
3202 result->time = t->time + (t->zone - tz) * USECS_PER_SEC;
3203 /* C99 modulo has the wrong sign convention for negative input */
3204 while (result->time < INT64CONST(0))
3205 result->time += USECS_PER_DAY;
3206 if (result->time >= USECS_PER_DAY)
3207 result->time %= USECS_PER_DAY;
3208
3209 result->zone = tz;
3210
3211 PG_RETURN_TIMETZADT_P(result);
3212}
3213
3214/* timetz_izone()
3215 * Encode time with time zone type with specified time interval as time zone.
3216 */
3217Datum
3219{
3222 TimeTzADT *result;
3223 int tz;
3224
3226 ereport(ERROR,
3228 errmsg("interval time zone \"%s\" must be finite",
3230 PointerGetDatum(zone))))));
3231
3232 if (zone->month != 0 || zone->day != 0)
3233 ereport(ERROR,
3235 errmsg("interval time zone \"%s\" must not include months or days",
3237 PointerGetDatum(zone))))));
3238
3239 tz = -(zone->time / USECS_PER_SEC);
3240
3241 result = palloc_object(TimeTzADT);
3242
3243 result->time = time->time + (time->zone - tz) * USECS_PER_SEC;
3244 /* C99 modulo has the wrong sign convention for negative input */
3245 while (result->time < INT64CONST(0))
3246 result->time += USECS_PER_DAY;
3247 if (result->time >= USECS_PER_DAY)
3248 result->time %= USECS_PER_DAY;
3249
3250 result->zone = tz;
3251
3252 PG_RETURN_TIMETZADT_P(result);
3253}
3254
3255/* timetz_at_local()
3256 *
3257 * Unlike for timestamp[tz]_at_local, the type for timetz does not flip between
3258 * time with/without time zone, so we cannot just call the conversion function.
3259 */
3260Datum
#define PG_GETARG_ARRAYTYPE_P(n)
Definition array.h:263
int32 * ArrayGetIntegerTypmods(ArrayType *arr, int *n)
Definition arrayutils.c:233
Node * TemporalSimplify(int32 max_precis, Node *node)
Definition datetime.c:4962
int DetermineTimeZoneAbbrevOffsetTS(TimestampTz ts, const char *abbr, pg_tz *tzp, int *isdst)
Definition datetime.c:1803
int DecodeUnits(int field, const char *lowtoken, int *val)
Definition datetime.c:4169
int DecodeTimeOnly(char **field, int *ftype, int nf, int *dtype, struct pg_tm *tm, fsec_t *fsec, int *tzp, DateTimeErrorExtra *extra)
Definition datetime.c:1917
int j2day(int date)
Definition datetime.c:354
int ParseDateTime(const char *timestr, char *workbuf, size_t buflen, char **field, int *ftype, int maxfields, int *numfields)
Definition datetime.c:773
int DetermineTimeZoneOffset(struct pg_tm *tm, pg_tz *tzp)
Definition datetime.c:1604
void DateTimeParseError(int dterr, DateTimeErrorExtra *extra, const char *str, const char *datatype, Node *escontext)
Definition datetime.c:4214
void EncodeTimeOnly(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, int style, char *str)
Definition datetime.c:4434
int ValidateDate(int fmask, bool isjulian, bool is2digits, bool bc, struct pg_tm *tm)
Definition datetime.c:2561
int DecodeSpecial(int field, const char *lowtoken, int *val)
Definition datetime.c:3246
void j2date(int jd, int *year, int *month, int *day)
Definition datetime.c:321
void GetCurrentDateTime(struct pg_tm *tm)
Definition datetime.c:376
void EncodeDateOnly(struct pg_tm *tm, int style, char *str)
Definition datetime.c:4349
int DecodeDateTime(char **field, int *ftype, int nf, int *dtype, struct pg_tm *tm, fsec_t *fsec, int *tzp, DateTimeErrorExtra *extra)
Definition datetime.c:997
int date2j(int year, int month, int day)
Definition datetime.c:296
void GetCurrentTimeUsec(struct pg_tm *tm, fsec_t *fsec, int *tzp)
Definition datetime.c:397
const char *const days[]
Definition datetime.c:84
int DecodeTimezoneName(const char *tzname, int *offset, pg_tz **tz)
Definition datetime.c:3288
Numeric int64_to_numeric(int64 val)
Definition numeric.c:4259
Numeric int64_div_fast_to_numeric(int64 val1, int log10val2)
Definition numeric.c:4280
Datum numeric_in(PG_FUNCTION_ARGS)
Definition numeric.c:626
Datum interval_out(PG_FUNCTION_ARGS)
Definition timestamp.c:973
int timestamp_cmp_internal(Timestamp dt1, Timestamp dt2)
Definition timestamp.c:2210
Datum in_range_timestamp_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3876
void GetEpochTime(struct pg_tm *tm)
Definition timestamp.c:2168
Datum timestamp_pl_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3090
int date2isoweek(int year, int mon, int mday)
Definition timestamp.c:5295
Datum timestamp_mi_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3207
int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
Definition timestamp.c:1910
Datum now(PG_FUNCTION_ARGS)
Definition timestamp.c:1609
int date2isoyear(int year, int mon, int mday)
Definition timestamp.c:5350
#define INT64CONST(x)
Definition c.h:560
#define Assert(condition)
Definition c.h:873
int64_t int64
Definition c.h:543
int32_t int32
Definition c.h:542
uint64_t uint64
Definition c.h:547
uint32_t uint32
Definition c.h:546
int64 Timestamp
Definition timestamp.h:38
int64 TimestampTz
Definition timestamp.h:39
#define SECS_PER_HOUR
Definition timestamp.h:127
#define IS_VALID_DATE(d)
Definition timestamp.h:262
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 MINS_PER_HOUR
Definition timestamp.h:129
#define IS_VALID_JULIAN(y, m, d)
Definition timestamp.h:227
#define TZDISP_LIMIT
Definition timestamp.h:144
#define IS_VALID_TIMESTAMP(t)
Definition timestamp.h:267
#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 TIMESTAMP_IS_NOEND(j)
Definition timestamp.h:167
#define USECS_PER_MINUTE
Definition timestamp.h:133
#define TIMESTAMP_IS_NOBEGIN(j)
Definition timestamp.h:162
#define UNIX_EPOCH_JDATE
Definition timestamp.h:234
#define TIMESTAMP_NOT_FINITE(j)
Definition timestamp.h:169
#define SECS_PER_DAY
Definition timestamp.h:126
#define POSTGRES_EPOCH_JDATE
Definition timestamp.h:235
#define TIMESTAMP_NOEND(j)
Definition timestamp.h:164
#define MIN_TIMESTAMP
Definition timestamp.h:256
int64 TimeOffset
Definition timestamp.h:40
Datum timestamp_eq_date(PG_FUNCTION_ARGS)
Definition date.c:945
int32 date_cmp_timestamp_internal(DateADT dateVal, Timestamp dt2)
Definition date.c:776
Datum date_send(PG_FUNCTION_ARGS)
Definition date.c:233
Datum timetz_izone(PG_FUNCTION_ARGS)
Definition date.c:3218
Timestamp date2timestamp_safe(DateADT dateVal, Node *escontext)
Definition date.c:630
int timetz2tm(TimeTzADT *time, struct pg_tm *tm, fsec_t *fsec, int *tzp)
Definition date.c:2499
Datum timestamp_ne_date(PG_FUNCTION_ARGS)
Definition date.c:954
Datum date_ne_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:891
Datum date_sortsupport(PG_FUNCTION_ARGS)
Definition date.c:459
Datum date_cmp(PG_FUNCTION_ARGS)
Definition date.c:446
Datum date_le(PG_FUNCTION_ARGS)
Definition date.c:419
Datum time_part(PG_FUNCTION_ARGS)
Definition date.c:2339
Datum time_eq(PG_FUNCTION_ARGS)
Definition date.c:1776
Datum timetz_send(PG_FUNCTION_ARGS)
Definition date.c:2467
Datum timetztypmodout(PG_FUNCTION_ARGS)
Definition date.c:2487
#define TIMETZ_GT(t1, t2)
Datum timestamp_ge_date(PG_FUNCTION_ARGS)
Definition date.c:990
static char * anytime_typmodout(bool istz, int32 typmod)
Definition date.c:95
Datum timetz_pl_interval(PG_FUNCTION_ARGS)
Definition date.c:2692
Datum timetz_smaller(PG_FUNCTION_ARGS)
Definition date.c:2675
Datum timetypmodin(PG_FUNCTION_ARGS)
Definition date.c:1654
Datum date_lt_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:900
Datum make_time(PG_FUNCTION_ARGS)
Definition date.c:1673
static Datum date_decrement(Relation rel, Datum existing, bool *underflow)
Definition date.c:468
Datum date_larger(PG_FUNCTION_ARGS)
Definition date.c:533
Datum in_range_time_interval(PG_FUNCTION_ARGS)
Definition date.c:2194
Datum date_gt_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:909
Datum date_lt_timestamp(PG_FUNCTION_ARGS)
Definition date.c:812
Datum timetz_ne(PG_FUNCTION_ARGS)
Definition date.c:2575
Datum time_interval(PG_FUNCTION_ARGS)
Definition date.c:2085
Datum date_eq(PG_FUNCTION_ARGS)
Definition date.c:392
Datum timetz_larger(PG_FUNCTION_ARGS)
Definition date.c:2661
Datum time_le(PG_FUNCTION_ARGS)
Definition date.c:1803
Datum timetz_part(PG_FUNCTION_ARGS)
Definition date.c:3140
Datum in_range_timetz_interval(PG_FUNCTION_ARGS)
Definition date.c:2746
Datum extract_time(PG_FUNCTION_ARGS)
Definition date.c:2345
Datum interval_time(PG_FUNCTION_ARGS)
Definition date.c:2108
TimestampTz date2timestamptz_safe(DateADT dateVal, Node *escontext)
Definition date.c:679
Datum date_mi_interval(PG_FUNCTION_ARGS)
Definition date.c:1304
Datum hashdateextended(PG_FUNCTION_ARGS)
Definition date.c:519
Datum date_eq_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:882
bool float_time_overflows(int hour, int min, double sec)
Definition date.c:1547
Datum timetz_gt(PG_FUNCTION_ARGS)
Definition date.c:2602
Datum timetz_at_local(PG_FUNCTION_ARGS)
Definition date.c:3261
Datum timestamp_gt_date(PG_FUNCTION_ARGS)
Definition date.c:972
Datum date_finite(PG_FUNCTION_ARGS)
Definition date.c:525
DateADT timestamp2date_safe(Timestamp timestamp, Node *escontext)
Definition date.c:1358
Datum in_range_date_interval(PG_FUNCTION_ARGS)
Definition date.c:1077
Datum time_cmp(PG_FUNCTION_ARGS)
Definition date.c:1830
Datum timestamp_time(PG_FUNCTION_ARGS)
Definition date.c:2001
Datum time_mi_time(PG_FUNCTION_ARGS)
Definition date.c:2129
Datum time_ge(PG_FUNCTION_ARGS)
Definition date.c:1821
int32 anytime_typmod_check(bool istz, int32 typmod)
Definition date.c:73
#define TIMEADT_GT(t1, t2)
Datum datetime_timestamp(PG_FUNCTION_ARGS)
Definition date.c:2062
static Datum timetz_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition date.c:3023
Datum date_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:1394
Datum date_ne_timestamp(PG_FUNCTION_ARGS)
Definition date.c:803
Datum timestamptz_ge_date(PG_FUNCTION_ARGS)
Definition date.c:1053
Datum date_eq_timestamp(PG_FUNCTION_ARGS)
Definition date.c:794
int tm2time(struct pg_tm *tm, fsec_t fsec, TimeADT *result)
Definition date.c:1512
Datum timetz_ge(PG_FUNCTION_ARGS)
Definition date.c:2611
Datum timestamp_lt_date(PG_FUNCTION_ARGS)
Definition date.c:963
Datum timestamptz_lt_date(PG_FUNCTION_ARGS)
Definition date.c:1026
Datum timetz_cmp(PG_FUNCTION_ARGS)
Definition date.c:2620
TimeADT GetSQLLocalTime(int32 typmod)
Definition date.c:371
Datum timetztypmodin(PG_FUNCTION_ARGS)
Definition date.c:2479
Datum timetz_recv(PG_FUNCTION_ARGS)
Definition date.c:2431
static TimestampTz date2timestamptz(DateADT dateVal)
Definition date.c:737
Datum time_recv(PG_FUNCTION_ARGS)
Definition date.c:1617
Datum time_mi_interval(PG_FUNCTION_ARGS)
Definition date.c:2171
Datum time_support(PG_FUNCTION_ARGS)
Definition date.c:1701
int tm2timetz(struct pg_tm *tm, fsec_t fsec, int tz, TimeTzADT *result)
Definition date.c:2359
Datum date_out(PG_FUNCTION_ARGS)
Definition date.c:186
DateADT timestamptz2date_safe(TimestampTz timestamp, Node *escontext)
Definition date.c:1432
Datum timetz_time(PG_FUNCTION_ARGS)
Definition date.c:2911
Datum timetz_in(PG_FUNCTION_ARGS)
Definition date.c:2369
Datum time_timetz(PG_FUNCTION_ARGS)
Definition date.c:2924
Datum time_lt(PG_FUNCTION_ARGS)
Definition date.c:1794
Datum date_in(PG_FUNCTION_ARGS)
Definition date.c:115
Datum date_gt(PG_FUNCTION_ARGS)
Definition date.c:428
bool time_overflows(int hour, int min, int sec, fsec_t fsec)
Definition date.c:1523
Datum timetz_mi_interval(PG_FUNCTION_ARGS)
Definition date.c:2719
Datum extract_timetz(PG_FUNCTION_ARGS)
Definition date.c:3146
Datum date_ge_timestamp(PG_FUNCTION_ARGS)
Definition date.c:839
static int32 anytime_typmodin(bool istz, ArrayType *ta)
Definition date.c:52
Datum date_mii(PG_FUNCTION_ARGS)
Definition date.c:594
Datum date_pl_interval(PG_FUNCTION_ARGS)
Definition date.c:1284
Datum overlaps_timetz(PG_FUNCTION_ARGS)
Definition date.c:2791
static Datum time_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition date.c:2236
Datum time_gt(PG_FUNCTION_ARGS)
Definition date.c:1812
Datum date_recv(PG_FUNCTION_ARGS)
Definition date.c:211
Datum timetz_lt(PG_FUNCTION_ARGS)
Definition date.c:2584
Datum time_out(PG_FUNCTION_ARGS)
Definition date.c:1597
Datum date_cmp_timestamp(PG_FUNCTION_ARGS)
Definition date.c:848
Datum time_hash(PG_FUNCTION_ARGS)
Definition date.c:1843
Datum time_larger(PG_FUNCTION_ARGS)
Definition date.c:1855
#define TIMETZ_LT(t1, t2)
Datum time_smaller(PG_FUNCTION_ARGS)
Definition date.c:1864
Datum time_ne(PG_FUNCTION_ARGS)
Definition date.c:1785
DateADT GetSQLCurrentDate(void)
Definition date.c:318
Datum timetz_eq(PG_FUNCTION_ARGS)
Definition date.c:2566
Datum date_gt_timestamp(PG_FUNCTION_ARGS)
Definition date.c:821
Datum timestamptz_timetz(PG_FUNCTION_ARGS)
Definition date.c:2950
void AdjustTimeForTypmod(TimeADT *time, int32 typmod)
Definition date.c:1741
Datum date_le_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:918
Datum date_pli(PG_FUNCTION_ARGS)
Definition date.c:570
Datum extract_date(PG_FUNCTION_ARGS)
Definition date.c:1104
Datum timestamptz_date(PG_FUNCTION_ARGS)
Definition date.c:1409
Datum timetz_le(PG_FUNCTION_ARGS)
Definition date.c:2593
Datum date_lt(PG_FUNCTION_ARGS)
Definition date.c:410
Datum timetz_hash(PG_FUNCTION_ARGS)
Definition date.c:2629
static Datum date_increment(Relation rel, Datum existing, bool *overflow)
Definition date.c:484
static TimestampTz date2timestamp(DateADT dateVal)
Definition date.c:663
static int timetz_cmp_internal(TimeTzADT *time1, TimeTzADT *time2)
Definition date.c:2539
Datum timestamptz_gt_date(PG_FUNCTION_ARGS)
Definition date.c:1035
Datum hashdate(PG_FUNCTION_ARGS)
Definition date.c:513
Datum timestamp_date(PG_FUNCTION_ARGS)
Definition date.c:1335
Datum date_ge(PG_FUNCTION_ARGS)
Definition date.c:437
Datum time_in(PG_FUNCTION_ARGS)
Definition date.c:1470
Datum time_hash_extended(PG_FUNCTION_ARGS)
Definition date.c:1849
Datum time_pl_interval(PG_FUNCTION_ARGS)
Definition date.c:2148
Datum datetimetz_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:2982
int time2tm(TimeADT time, struct pg_tm *tm, fsec_t *fsec)
Definition date.c:1584
Datum timestamptz_ne_date(PG_FUNCTION_ARGS)
Definition date.c:1017
Datum date_smaller(PG_FUNCTION_ARGS)
Definition date.c:542
void EncodeSpecialDate(DateADT dt, char *str)
Definition date.c:303
Datum timestamp_le_date(PG_FUNCTION_ARGS)
Definition date.c:981
Datum timetypmodout(PG_FUNCTION_ARGS)
Definition date.c:1662
Datum timestamptz_eq_date(PG_FUNCTION_ARGS)
Definition date.c:1008
Datum timetz_scale(PG_FUNCTION_ARGS)
Definition date.c:2521
Datum timestamptz_cmp_date(PG_FUNCTION_ARGS)
Definition date.c:1062
Datum date_ge_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:927
Datum timetz_hash_extended(PG_FUNCTION_ARGS)
Definition date.c:2645
Datum date_skipsupport(PG_FUNCTION_ARGS)
Definition date.c:500
Datum timetz_zone(PG_FUNCTION_ARGS)
Definition date.c:3156
Datum date_cmp_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:936
int32 date_cmp_timestamptz_internal(DateADT dateVal, TimestampTz dt2)
Definition date.c:857
double date2timestamp_no_overflow(DateADT dateVal)
Definition date.c:753
Datum make_date(PG_FUNCTION_ARGS)
Definition date.c:247
TimeTzADT * GetSQLCurrentTime(int32 typmod)
Definition date.c:351
Datum date_le_timestamp(PG_FUNCTION_ARGS)
Definition date.c:830
Datum time_send(PG_FUNCTION_ARGS)
Definition date.c:1643
Datum date_mi(PG_FUNCTION_ARGS)
Definition date.c:553
Datum timestamp_cmp_date(PG_FUNCTION_ARGS)
Definition date.c:999
Datum date_ne(PG_FUNCTION_ARGS)
Definition date.c:401
Datum time_scale(PG_FUNCTION_ARGS)
Definition date.c:1721
Datum timestamptz_time(PG_FUNCTION_ARGS)
Definition date.c:2031
#define TIMEADT_LT(t1, t2)
Datum timetz_out(PG_FUNCTION_ARGS)
Definition date.c:2410
Datum overlaps_time(PG_FUNCTION_ARGS)
Definition date.c:1879
Datum date_timestamp(PG_FUNCTION_ARGS)
Definition date.c:1321
Datum timestamptz_le_date(PG_FUNCTION_ARGS)
Definition date.c:1044
#define DATE_IS_NOEND(j)
Definition date.h:48
#define DATEVAL_NOEND
Definition date.h:43
static Datum DateADTGetDatum(DateADT X)
Definition date.h:78
#define PG_RETURN_TIMETZADT_P(x)
Definition date.h:101
#define PG_RETURN_DATEADT(x)
Definition date.h:99
#define DATE_IS_NOBEGIN(j)
Definition date.h:46
#define DATE_NOT_FINITE(j)
Definition date.h:49
#define DATE_NOEND(j)
Definition date.h:47
#define PG_GETARG_TIMEADT(n)
Definition date.h:96
#define PG_RETURN_TIMEADT(x)
Definition date.h:100
int32 DateADT
Definition date.h:21
static DateADT DatumGetDateADT(Datum X)
Definition date.h:60
#define DATE_NOBEGIN(j)
Definition date.h:45
#define MAX_TIME_PRECISION
Definition date.h:51
int64 TimeADT
Definition date.h:23
#define PG_GETARG_TIMETZADT_P(n)
Definition date.h:97
#define DATEVAL_NOBEGIN
Definition date.h:42
#define PG_GETARG_DATEADT(n)
Definition date.h:95
int errcode(int sqlerrcode)
Definition elog.c:863
int errmsg(const char *fmt,...)
Definition elog.c:1080
#define ereturn(context, dummy_value,...)
Definition elog.h:278
#define WARNING
Definition elog.h:36
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define ereport(elevel,...)
Definition elog.h:150
#define palloc_object(type)
Definition fe_memutils.h:74
#define PG_RETURN_VOID()
Definition fmgr.h:350
#define PG_GETARG_OID(n)
Definition fmgr.h:275
#define PG_RETURN_UINT32(x)
Definition fmgr.h:356
#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_GETARG_CSTRING(n)
Definition fmgr.h:278
#define PG_RETURN_NULL()
Definition fmgr.h:346
#define PG_GETARG_INT64(n)
Definition fmgr.h:284
#define PG_RETURN_UINT64(x)
Definition fmgr.h:371
#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 DirectFunctionCall5(func, arg1, arg2, arg3, arg4, arg5)
Definition fmgr.h:692
#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)
int DateStyle
Definition globals.c:125
static Datum hash_uint32(uint32 k)
Definition hashfn.h:43
static Datum hash_uint32_extended(uint32 k, uint64 seed)
Definition hashfn.h:49
const char * str
Datum hashint8extended(PG_FUNCTION_ARGS)
Definition hashfunc.c:103
Datum hashint8(PG_FUNCTION_ARGS)
Definition hashfunc.c:83
#define MAXDATEFIELDS
Definition datetime.h:202
#define DTK_EPOCH
Definition datetime.h:152
#define UNKNOWN_FIELD
Definition datetime.h:124
#define DTK_DECADE
Definition datetime.h:168
#define DTK_SECOND
Definition datetime.h:160
#define DTK_QUARTER
Definition datetime.h:166
#define DTK_JULIAN
Definition datetime.h:173
#define DTK_TZ_HOUR
Definition datetime.h:177
#define DTK_TZ_MINUTE
Definition datetime.h:178
#define DTK_LATE
Definition datetime.h:151
#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 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 EARLY
Definition datetime.h:39
#define DTK_HOUR
Definition datetime.h:162
#define DTK_WEEK
Definition datetime.h:164
#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 DTK_MINUTE
Definition datetime.h:161
#define UNITS
Definition datetime.h:107
long val
Definition informix.c:689
static bool pg_neg_s32_overflow(int32 a, int32 *result)
Definition int.h:205
static bool pg_add_s64_overflow(int64 a, int64 b, int64 *result)
Definition int.h:235
static struct pg_tm tm
Definition localtime.c:104
char * pstrdup(const char *in)
Definition mcxt.c:1781
#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 char buf[DEFAULT_XLOG_SEG_SIZE]
const char * pg_get_timezone_name(pg_tz *tz)
Definition localtime.c:1990
#define TZ_STRLEN_MAX
Definition pgtime.h:54
PGDLLIMPORT pg_tz * session_timezone
Definition pgtz.c:28
long date
Definition pgtypes_date.h:9
int64 timestamp
static uint32 DatumGetUInt32(Datum X)
Definition postgres.h:232
static uint64 DatumGetUInt64(Datum X)
Definition postgres.h:433
#define Int64GetDatumFast(X)
Definition postgres.h:535
static int64 DatumGetInt64(Datum X)
Definition postgres.h:413
static Datum PointerGetDatum(const void *X)
Definition postgres.h:352
static Datum BoolGetDatum(bool X)
Definition postgres.h:112
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:262
static char * DatumGetCString(Datum X)
Definition postgres.h:365
uint64_t Datum
Definition postgres.h:70
static Datum CStringGetDatum(const char *X)
Definition postgres.h:380
static Datum Int32GetDatum(int32 X)
Definition postgres.h:222
#define InvalidOid
unsigned int Oid
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition pqformat.c:414
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
char * downcase_truncate_identifier(const char *ident, int len, bool warn)
Definition scansup.c:38
struct SkipSupportData * SkipSupport
Definition skipsupport.h:50
struct SortSupportData * SortSupport
Definition sortsupport.h:58
struct StringInfoData * StringInfo
Definition string.h:15
int32 day
Definition timestamp.h:51
int32 month
Definition timestamp.h:52
TimeOffset time
Definition timestamp.h:49
Definition nodes.h:135
SkipSupportIncDec decrement
Definition skipsupport.h:91
SkipSupportIncDec increment
Definition skipsupport.h:92
int(* comparator)(Datum x, Datum y, SortSupport ssup)
TimeADT time
Definition date.h:27
int32 zone
Definition date.h:28
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
int tm_sec
Definition pgtime.h:36
int tm_year
Definition pgtime.h:41
Definition pgtz.h:66
Definition c.h:706
Definition zic.c:99
int ssup_datum_int32_cmp(Datum x, Datum y, SortSupport ssup)
Definition tuplesort.c:3147
#define timestamptz_cmp_internal(dt1, dt2)
Definition timestamp.h:143
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_INTERVAL_P(x)
Definition timestamp.h:69
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:181
void text_to_cstring_buffer(const text *src, char *dst, size_t dst_len)
Definition varlena.c:245
const char * type
TimestampTz GetCurrentTransactionStartTimestamp(void)
Definition xact.c:871