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/* common code for timetypmodin and timetztypmodin */
43static int32
45{
46 int32 *tl;
47 int n;
48
50
51 /*
52 * we're not too tense about good error message here because grammar
53 * shouldn't allow wrong number of modifiers for TIME
54 */
55 if (n != 1)
58 errmsg("invalid type modifier")));
59
60 return anytime_typmod_check(istz, tl[0]);
61}
62
63/* exported so parse_expr.c can use it */
66{
67 if (typmod < 0)
70 errmsg("TIME(%d)%s precision must not be negative",
71 typmod, (istz ? " WITH TIME ZONE" : ""))));
72 if (typmod > MAX_TIME_PRECISION)
73 {
76 errmsg("TIME(%d)%s precision reduced to maximum allowed, %d",
77 typmod, (istz ? " WITH TIME ZONE" : ""),
79 typmod = MAX_TIME_PRECISION;
80 }
81
82 return typmod;
83}
84
85/* common code for timetypmodout and timetztypmodout */
86static char *
88{
89 const char *tz = istz ? " with time zone" : " without time zone";
90
91 if (typmod >= 0)
92 return psprintf("(%d)%s", (int) typmod, tz);
93 else
94 return pstrdup(tz);
95}
96
97
98/*****************************************************************************
99 * Date ADT
100 *****************************************************************************/
101
102
103/*
104 * date_in()
105 * Given date text string, convert to internal date format.
106 */
107Datum
109{
110 char *str = PG_GETARG_CSTRING(0);
111 Node *escontext = fcinfo->context;
113 fsec_t fsec;
114 struct pg_tm tt,
115 *tm = &tt;
116 int tzp;
117 int dtype;
118 int nf;
119 int dterr;
120 char *field[MAXDATEFIELDS];
121 int ftype[MAXDATEFIELDS];
122 char workbuf[MAXDATELEN + 1];
123 DateTimeErrorExtra extra;
124
126 field, ftype, MAXDATEFIELDS, &nf);
127 if (dterr == 0)
128 dterr = DecodeDateTime(field, ftype, nf,
129 &dtype, tm, &fsec, &tzp, &extra);
130 if (dterr != 0)
131 {
132 DateTimeParseError(dterr, &extra, str, "date", escontext);
134 }
135
136 switch (dtype)
137 {
138 case DTK_DATE:
139 break;
140
141 case DTK_EPOCH:
143 break;
144
145 case DTK_LATE:
148
149 case DTK_EARLY:
152
153 default:
154 DateTimeParseError(DTERR_BAD_FORMAT, &extra, str, "date", escontext);
156 }
157
158 /* Prevent overflow in Julian-day routines */
160 ereturn(escontext, (Datum) 0,
162 errmsg("date out of range: \"%s\"", str)));
163
165
166 /* Now check for just-out-of-range dates */
167 if (!IS_VALID_DATE(date))
168 ereturn(escontext, (Datum) 0,
170 errmsg("date out of range: \"%s\"", str)));
171
173}
174
175/*
176 * date_out()
177 * Given internal format date, convert to text string.
178 */
179Datum
181{
183 char *result;
184 struct pg_tm tt,
185 *tm = &tt;
186 char buf[MAXDATELEN + 1];
187
190 else
191 {
193 &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
195 }
196
197 result = pstrdup(buf);
199}
200
201/*
202 * date_recv - converts external binary format to date
203 */
204Datum
206{
209
210 result = (DateADT) pq_getmsgint(buf, sizeof(DateADT));
211
212 /* Limit to the same range that date_in() accepts. */
214 /* ok */ ;
215 else if (!IS_VALID_DATE(result))
218 errmsg("date out of range")));
219
221}
222
223/*
224 * date_send - converts date to binary format
225 */
226Datum
236
237/*
238 * make_date - date constructor
239 */
240Datum
242{
243 struct pg_tm tm;
245 int dterr;
246 bool bc = false;
247
251
252 /* Handle negative years as BC */
253 if (tm.tm_year < 0)
254 {
255 int year = tm.tm_year;
256
257 bc = true;
258 if (pg_neg_s32_overflow(year, &year))
261 errmsg("date field value out of range: %d-%02d-%02d",
263 tm.tm_year = year;
264 }
265
266 dterr = ValidateDate(DTK_DATE_M, false, false, bc, &tm);
267
268 if (dterr != 0)
271 errmsg("date field value out of range: %d-%02d-%02d",
273
274 /* Prevent overflow in Julian-day routines */
278 errmsg("date out of range: %d-%02d-%02d",
280
282
283 /* Now check for just-out-of-range dates */
284 if (!IS_VALID_DATE(date))
287 errmsg("date out of range: %d-%02d-%02d",
289
291}
292
293/*
294 * Convert reserved date values to string.
295 */
296void
298{
299 if (DATE_IS_NOBEGIN(dt))
300 strcpy(str, EARLY);
301 else if (DATE_IS_NOEND(dt))
302 strcpy(str, LATE);
303 else /* shouldn't happen */
304 elog(ERROR, "invalid argument for EncodeSpecialDate");
305}
306
307
308/*
309 * GetSQLCurrentDate -- implements CURRENT_DATE
310 */
313{
314 struct pg_tm tm;
315
316 static int cache_year = 0;
317 static int cache_mon = 0;
318 static int cache_mday = 0;
319 static DateADT cache_date;
320
322
323 /*
324 * date2j involves several integer divisions; moreover, unless our session
325 * lives across local midnight, we don't really have to do it more than
326 * once. So it seems worth having a separate cache here.
327 */
328 if (tm.tm_year != cache_year ||
329 tm.tm_mon != cache_mon ||
331 {
336 }
337
338 return cache_date;
339}
340
341/*
342 * GetSQLCurrentTime -- implements CURRENT_TIME, CURRENT_TIME(n)
343 */
344TimeTzADT *
346{
348 struct pg_tm tt,
349 *tm = &tt;
350 fsec_t fsec;
351 int tz;
352
353 GetCurrentTimeUsec(tm, &fsec, &tz);
354
356 tm2timetz(tm, fsec, tz, result);
357 AdjustTimeForTypmod(&(result->time), typmod);
358 return result;
359}
360
361/*
362 * GetSQLLocalTime -- implements LOCALTIME, LOCALTIME(n)
363 */
366{
368 struct pg_tm tt,
369 *tm = &tt;
370 fsec_t fsec;
371 int tz;
372
373 GetCurrentTimeUsec(tm, &fsec, &tz);
374
375 tm2time(tm, fsec, &result);
376 AdjustTimeForTypmod(&result, typmod);
377 return result;
378}
379
380
381/*
382 * Comparison functions for dates
383 */
384
385Datum
393
394Datum
402
403Datum
411
412Datum
420
421Datum
429
430Datum
438
439Datum
451
452Datum
460
461static Datum
463{
465
467 {
468 /* return value is undefined */
469 *underflow = true;
470 return (Datum) 0;
471 }
472
473 *underflow = false;
474 return DateADTGetDatum(dexisting - 1);
475}
476
477static Datum
479{
481
483 {
484 /* return value is undefined */
485 *overflow = true;
486 return (Datum) 0;
487 }
488
489 *overflow = false;
490 return DateADTGetDatum(dexisting + 1);
491}
492
493Datum
505
506Datum
511
512Datum
517
518Datum
525
526Datum
534
535Datum
543
544/*
545 * Compute difference between two dates in days.
546 */
547Datum
560
561/*
562 * Add a number of days to a date, giving a new date.
563 * Must handle both positive and negative numbers of days.
564 */
565Datum
567{
571
573 PG_RETURN_DATEADT(dateVal); /* can't change infinity */
574
575 result = dateVal + days;
576
577 /* Check for integer overflow and out-of-allowed-range */
578 if ((days >= 0 ? (result < dateVal) : (result > dateVal)) ||
582 errmsg("date out of range")));
583
585}
586
587/*
588 * Subtract a number of days from a date, giving a new date.
589 */
590Datum
592{
596
598 PG_RETURN_DATEADT(dateVal); /* can't change infinity */
599
600 result = dateVal - days;
601
602 /* Check for integer overflow and out-of-allowed-range */
603 if ((days >= 0 ? (result > dateVal) : (result < dateVal)) ||
607 errmsg("date out of range")));
608
610}
611
612
613/*
614 * Promote date to timestamp.
615 *
616 * If the date falls out of the valid range for the timestamp type, error
617 * handling proceeds based on escontext.
618 *
619 * If escontext is NULL, we throw an out-of-range error (hard error).
620 * If escontext is not NULL, we return NOBEGIN or NOEND for lower bound or
621 * upper bound overflow, respectively, and record a soft error.
622 *
623 * Note: Lower bound overflow is currently not possible, as both date and
624 * timestamp datatypes share the same lower boundary: Julian day zero.
625 */
628{
630
633 else if (DATE_IS_NOEND(dateVal))
635 else
636 {
637 /*
638 * Since dates have the same minimum values as timestamps, only upper
639 * boundary need be checked for overflow.
640 */
642 {
644 ereturn(escontext, result,
646 errmsg("date out of range for timestamp")));
647 }
648
649 /* date is days since 2000, timestamp is microseconds since same... */
651 }
652
653 return result;
654}
655
656/*
657 * Promote date to timestamp, throwing error for overflow.
658 */
659static TimestampTz
664
665/*
666 * Promote date to timestamp with time zone.
667 *
668 * If the date falls out of the valid range for the timestamp type, error
669 * handling proceeds based on escontext.
670 *
671 * If escontext is NULL, we throw an out-of-range error (hard error).
672 * If escontext is not NULL, we return NOBEGIN or NOEND for lower bound or
673 * upper bound overflow, respectively, and record a soft error.
674 */
677{
679 struct pg_tm tt,
680 *tm = &tt;
681 int tz;
682
685 else if (DATE_IS_NOEND(dateVal))
687 else
688 {
689 /*
690 * Since dates have the same minimum values as timestamps, only upper
691 * boundary need be checked for overflow.
692 */
694 {
696 ereturn(escontext, result,
698 errmsg("date out of range for timestamp")));
699 }
700
702 &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
703 tm->tm_hour = 0;
704 tm->tm_min = 0;
705 tm->tm_sec = 0;
707
709
710 /*
711 * Since it is possible to go beyond allowed timestamptz range because
712 * of time zone, check for allowed timestamp range after adding tz.
713 */
715 {
716 if (result < MIN_TIMESTAMP)
718 else
720
721 ereturn(escontext, result,
723 errmsg("date out of range for timestamp")));
724 }
725 }
726
727 return result;
728}
729
730/*
731 * date2timestamp_no_overflow
732 *
733 * This is chartered to produce a double value that is numerically
734 * equivalent to the corresponding Timestamp value, if the date is in the
735 * valid range of Timestamps, but in any case not throw an overflow error.
736 * We can do this since the numerical range of double is greater than
737 * that of non-erroneous timestamps. The results are currently only
738 * used for statistical estimation purposes.
739 */
740double
742{
743 double result;
744
746 result = -DBL_MAX;
747 else if (DATE_IS_NOEND(dateVal))
748 result = DBL_MAX;
749 else
750 {
751 /* date is days since 2000, timestamp is microseconds since same... */
753 }
754
755 return result;
756}
757
758
759/*
760 * Crosstype comparison functions for dates
761 */
762
763int32
765{
768
769 dt1 = date2timestamp_safe(dateVal, (Node *) &escontext);
770 if (escontext.error_occurred)
771 {
772 Assert(TIMESTAMP_IS_NOEND(dt1)); /* NOBEGIN case cannot occur */
773
774 /* dt1 is larger than any finite timestamp, but less than infinity */
775 return TIMESTAMP_IS_NOEND(dt2) ? -1 : +1;
776 }
777
779}
780
781Datum
789
790Datum
798
799Datum
807
808Datum
816
817Datum
825
826Datum
834
835Datum
843
844int32
846{
849
850 dt1 = date2timestamptz_safe(dateVal, (Node *) &escontext);
851
852 if (escontext.error_occurred)
853 {
855 {
856 /* dt1 is larger than any finite timestamp, but less than infinity */
857 return TIMESTAMP_IS_NOEND(dt2) ? -1 : +1;
858 }
860 {
861 /* dt1 is less than any finite timestamp, but more than -infinity */
862 return TIMESTAMP_IS_NOBEGIN(dt2) ? +1 : -1;
863 }
864 }
865
867}
868
869Datum
877
878Datum
886
887Datum
895
896Datum
904
905Datum
913
914Datum
922
923Datum
931
932Datum
940
941Datum
949
950Datum
958
959Datum
967
968Datum
976
977Datum
985
986Datum
994
995Datum
1003
1004Datum
1012
1013Datum
1021
1022Datum
1030
1031Datum
1039
1040Datum
1048
1049Datum
1057
1058/*
1059 * in_range support function for date.
1060 *
1061 * We implement this by promoting the dates to timestamp (without time zone)
1062 * and then using the timestamp-and-interval in_range function.
1063 */
1064Datum
1066{
1068 DateADT base = PG_GETARG_DATEADT(1);
1069 Interval *offset = PG_GETARG_INTERVAL_P(2);
1070 bool sub = PG_GETARG_BOOL(3);
1071 bool less = PG_GETARG_BOOL(4);
1074
1075 /* XXX we could support out-of-range cases here, perhaps */
1077 baseStamp = date2timestamp(base);
1078
1082 IntervalPGetDatum(offset),
1083 BoolGetDatum(sub),
1085}
1086
1087
1088/*
1089 * extract_date()
1090 * Extract specified field from date type.
1091 */
1092Datum
1094{
1098 int type,
1099 val;
1100 char *lowunits;
1101 int year,
1102 mon,
1103 mday;
1104
1107 false);
1108
1109 type = DecodeUnits(0, lowunits, &val);
1110 if (type == UNKNOWN_FIELD)
1112
1113 if (DATE_NOT_FINITE(date) && (type == UNITS || type == RESERV))
1114 {
1115 switch (val)
1116 {
1117 /* Oscillating units */
1118 case DTK_DAY:
1119 case DTK_MONTH:
1120 case DTK_QUARTER:
1121 case DTK_WEEK:
1122 case DTK_DOW:
1123 case DTK_ISODOW:
1124 case DTK_DOY:
1126 break;
1127
1128 /* Monotonically-increasing units */
1129 case DTK_YEAR:
1130 case DTK_DECADE:
1131 case DTK_CENTURY:
1132 case DTK_MILLENNIUM:
1133 case DTK_JULIAN:
1134 case DTK_ISOYEAR:
1135 case DTK_EPOCH:
1136 if (DATE_IS_NOBEGIN(date))
1138 CStringGetDatum("-Infinity"),
1140 Int32GetDatum(-1))));
1141 else
1143 CStringGetDatum("Infinity"),
1145 Int32GetDatum(-1))));
1146 default:
1147 ereport(ERROR,
1149 errmsg("unit \"%s\" not supported for type %s",
1151 }
1152 }
1153 else if (type == UNITS)
1154 {
1155 j2date(date + POSTGRES_EPOCH_JDATE, &year, &mon, &mday);
1156
1157 switch (val)
1158 {
1159 case DTK_DAY:
1160 intresult = mday;
1161 break;
1162
1163 case DTK_MONTH:
1164 intresult = mon;
1165 break;
1166
1167 case DTK_QUARTER:
1168 intresult = (mon - 1) / 3 + 1;
1169 break;
1170
1171 case DTK_WEEK:
1172 intresult = date2isoweek(year, mon, mday);
1173 break;
1174
1175 case DTK_YEAR:
1176 if (year > 0)
1177 intresult = year;
1178 else
1179 /* there is no year 0, just 1 BC and 1 AD */
1180 intresult = year - 1;
1181 break;
1182
1183 case DTK_DECADE:
1184 /* see comments in timestamp_part */
1185 if (year >= 0)
1186 intresult = year / 10;
1187 else
1188 intresult = -((8 - (year - 1)) / 10);
1189 break;
1190
1191 case DTK_CENTURY:
1192 /* see comments in timestamp_part */
1193 if (year > 0)
1194 intresult = (year + 99) / 100;
1195 else
1196 intresult = -((99 - (year - 1)) / 100);
1197 break;
1198
1199 case DTK_MILLENNIUM:
1200 /* see comments in timestamp_part */
1201 if (year > 0)
1202 intresult = (year + 999) / 1000;
1203 else
1204 intresult = -((999 - (year - 1)) / 1000);
1205 break;
1206
1207 case DTK_JULIAN:
1209 break;
1210
1211 case DTK_ISOYEAR:
1212 intresult = date2isoyear(year, mon, mday);
1213 /* Adjust BC years */
1214 if (intresult <= 0)
1215 intresult -= 1;
1216 break;
1217
1218 case DTK_DOW:
1219 case DTK_ISODOW:
1221 if (val == DTK_ISODOW && intresult == 0)
1222 intresult = 7;
1223 break;
1224
1225 case DTK_DOY:
1226 intresult = date2j(year, mon, mday) - date2j(year, 1, 1) + 1;
1227 break;
1228
1229 default:
1230 ereport(ERROR,
1232 errmsg("unit \"%s\" not supported for type %s",
1234 intresult = 0;
1235 }
1236 }
1237 else if (type == RESERV)
1238 {
1239 switch (val)
1240 {
1241 case DTK_EPOCH:
1243 break;
1244
1245 default:
1246 ereport(ERROR,
1248 errmsg("unit \"%s\" not supported for type %s",
1250 intresult = 0;
1251 }
1252 }
1253 else
1254 {
1255 ereport(ERROR,
1257 errmsg("unit \"%s\" not recognized for type %s",
1259 intresult = 0;
1260 }
1261
1263}
1264
1265
1266/*
1267 * Add an interval to a date, giving a new date.
1268 * Must handle both positive and negative intervals.
1269 *
1270 * We implement this by promoting the date to timestamp (without time zone)
1271 * and then using the timestamp plus interval function.
1272 */
1273Datum
1286
1287/*
1288 * Subtract an interval from a date, giving a new date.
1289 * Must handle both positive and negative intervals.
1290 *
1291 * We implement this by promoting the date to timestamp (without time zone)
1292 * and then using the timestamp minus interval function.
1293 */
1294Datum
1307
1308/*
1309 * date_timestamp()
1310 * Convert date to timestamp data type.
1311 */
1312Datum
1314{
1317
1318 result = date2timestamp_safe(dateVal, fcinfo->context);
1319 if (SOFT_ERROR_OCCURRED(fcinfo->context))
1321
1323}
1324
1325/*
1326 * timestamp_date()
1327 * Convert timestamp to date data type.
1328 */
1329Datum
1331{
1334
1335 result = timestamp2date_safe(timestamp, fcinfo->context);
1336 if (SOFT_ERROR_OCCURRED(fcinfo->context))
1338
1340}
1341
1342/*
1343 * Convert timestamp to date.
1344 *
1345 * If the timestamp falls out of the valid range for the date type, error
1346 * handling proceeds based on escontext.
1347 *
1348 * If escontext is NULL, we throw an out-of-range error (hard error).
1349 * If escontext is not NULL, we return NOBEGIN or NOEND for lower bound or
1350 * upper bound overflow, respectively, and record a soft error.
1351 *
1352 * Note: given the ranges of the types, overflow is only possible at
1353 * the lower bound of the range, but we don't assume that in this code.
1354 */
1355DateADT
1357{
1359 struct pg_tm tt,
1360 *tm = &tt;
1361 fsec_t fsec;
1362
1365 else if (TIMESTAMP_IS_NOEND(timestamp))
1367 else
1368 {
1369 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
1370 {
1371 if (timestamp < 0)
1373 else
1374 DATE_NOEND(result); /* not actually reachable */
1375
1376 ereturn(escontext, result,
1378 errmsg("timestamp out of range")));
1379 }
1380
1382 }
1383
1384 return result;
1385}
1386
1387
1388/*
1389 * date_timestamptz()
1390 * Convert date to timestamp with time zone data type.
1391 */
1392Datum
1394{
1397
1398 result = date2timestamptz_safe(dateVal, fcinfo->context);
1399 if (SOFT_ERROR_OCCURRED(fcinfo->context))
1401
1403}
1404
1405
1406/*
1407 * timestamptz_date()
1408 * Convert timestamp with time zone to date data type.
1409 */
1410Datum
1412{
1415
1416 result = timestamptz2date_safe(timestamp, fcinfo->context);
1417 if (SOFT_ERROR_OCCURRED(fcinfo->context))
1419
1421}
1422
1423/*
1424 * Convert timestamptz to date.
1425 *
1426 * If the timestamp falls out of the valid range for the date type, error
1427 * handling proceeds based on escontext.
1428 *
1429 * If escontext is NULL, we throw an out-of-range error (hard error).
1430 * If escontext is not NULL, we return NOBEGIN or NOEND for lower bound or
1431 * upper bound overflow, respectively, and record a soft error.
1432 *
1433 * Note: given the ranges of the types, overflow is only possible at
1434 * the lower bound of the range, but we don't assume that in this code.
1435 */
1436DateADT
1438{
1440 struct pg_tm tt,
1441 *tm = &tt;
1442 fsec_t fsec;
1443 int tz;
1444
1447 else if (TIMESTAMP_IS_NOEND(timestamp))
1449 else
1450 {
1451 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
1452 {
1453 if (timestamp < 0)
1455 else
1456 DATE_NOEND(result); /* not actually reachable */
1457
1458 ereturn(escontext, result,
1460 errmsg("timestamp out of range")));
1461 }
1462
1464 }
1465
1466 return result;
1467}
1468
1469
1470/*****************************************************************************
1471 * Time ADT
1472 *****************************************************************************/
1473
1474Datum
1476{
1477 char *str = PG_GETARG_CSTRING(0);
1478#ifdef NOT_USED
1479 Oid typelem = PG_GETARG_OID(1);
1480#endif
1481 int32 typmod = PG_GETARG_INT32(2);
1482 Node *escontext = fcinfo->context;
1484 fsec_t fsec;
1485 struct pg_tm tt,
1486 *tm = &tt;
1487 int tz;
1488 int nf;
1489 int dterr;
1490 char workbuf[MAXDATELEN + 1];
1491 char *field[MAXDATEFIELDS];
1492 int dtype;
1493 int ftype[MAXDATEFIELDS];
1494 DateTimeErrorExtra extra;
1495
1497 field, ftype, MAXDATEFIELDS, &nf);
1498 if (dterr == 0)
1499 dterr = DecodeTimeOnly(field, ftype, nf,
1500 &dtype, tm, &fsec, &tz, &extra);
1501 if (dterr != 0)
1502 {
1503 DateTimeParseError(dterr, &extra, str, "time", escontext);
1505 }
1506
1507 tm2time(tm, fsec, &result);
1508 AdjustTimeForTypmod(&result, typmod);
1509
1511}
1512
1513/*
1514 * tm2time()
1515 * Convert a tm structure to a time data type.
1516 */
1517int
1519{
1521 * USECS_PER_SEC) + fsec;
1522 return 0;
1523}
1524
1525/*
1526 * time_overflows()
1527 * Check to see if a broken-down time-of-day is out of range.
1528 */
1529bool
1530time_overflows(int hour, int min, int sec, fsec_t fsec)
1531{
1532 /* Range-check the fields individually. */
1537 return true;
1538
1539 /*
1540 * Because we allow, eg, hour = 24 or sec = 60, we must check separately
1541 * that the total time value doesn't exceed 24:00:00.
1542 */
1543 if ((((((hour * MINS_PER_HOUR + min) * SECS_PER_MINUTE)
1544 + sec) * USECS_PER_SEC) + fsec) > USECS_PER_DAY)
1545 return true;
1546
1547 return false;
1548}
1549
1550/*
1551 * float_time_overflows()
1552 * Same, when we have seconds + fractional seconds as one "double" value.
1553 */
1554bool
1555float_time_overflows(int hour, int min, double sec)
1556{
1557 /* Range-check the fields individually. */
1560 return true;
1561
1562 /*
1563 * "sec", being double, requires extra care. Cope with NaN, and round off
1564 * before applying the range check to avoid unexpected errors due to
1565 * imprecise input. (We assume rint() behaves sanely with infinities.)
1566 */
1567 if (isnan(sec))
1568 return true;
1569 sec = rint(sec * USECS_PER_SEC);
1571 return true;
1572
1573 /*
1574 * Because we allow, eg, hour = 24 or sec = 60, we must check separately
1575 * that the total time value doesn't exceed 24:00:00. This must match the
1576 * way that callers will convert the fields to a time.
1577 */
1578 if (((((hour * MINS_PER_HOUR + min) * SECS_PER_MINUTE)
1579 * USECS_PER_SEC) + (int64) sec) > USECS_PER_DAY)
1580 return true;
1581
1582 return false;
1583}
1584
1585
1586/*
1587 * time2tm()
1588 * Convert time data type to POSIX time structure.
1589 *
1590 * Note that only the hour/min/sec/fractional-sec fields are filled in.
1591 */
1592int
1593time2tm(TimeADT time, struct pg_tm *tm, fsec_t *fsec)
1594{
1595 tm->tm_hour = time / USECS_PER_HOUR;
1596 time -= tm->tm_hour * USECS_PER_HOUR;
1597 tm->tm_min = time / USECS_PER_MINUTE;
1598 time -= tm->tm_min * USECS_PER_MINUTE;
1599 tm->tm_sec = time / USECS_PER_SEC;
1600 time -= tm->tm_sec * USECS_PER_SEC;
1601 *fsec = time;
1602 return 0;
1603}
1604
1605Datum
1607{
1608 TimeADT time = PG_GETARG_TIMEADT(0);
1609 char *result;
1610 struct pg_tm tt,
1611 *tm = &tt;
1612 fsec_t fsec;
1613 char buf[MAXDATELEN + 1];
1614
1615 time2tm(time, tm, &fsec);
1616 EncodeTimeOnly(tm, fsec, false, 0, DateStyle, buf);
1617
1618 result = pstrdup(buf);
1620}
1621
1622/*
1623 * time_recv - converts external binary format to time
1624 */
1625Datum
1627{
1629
1630#ifdef NOT_USED
1631 Oid typelem = PG_GETARG_OID(1);
1632#endif
1633 int32 typmod = PG_GETARG_INT32(2);
1635
1637
1638 if (result < INT64CONST(0) || result > USECS_PER_DAY)
1639 ereport(ERROR,
1641 errmsg("time out of range")));
1642
1643 AdjustTimeForTypmod(&result, typmod);
1644
1646}
1647
1648/*
1649 * time_send - converts time to binary format
1650 */
1651Datum
1661
1662Datum
1669
1670Datum
1672{
1673 int32 typmod = PG_GETARG_INT32(0);
1674
1675 PG_RETURN_CSTRING(anytime_typmodout(false, typmod));
1676}
1677
1678/*
1679 * make_time - time constructor
1680 */
1681Datum
1683{
1684 int tm_hour = PG_GETARG_INT32(0);
1685 int tm_min = PG_GETARG_INT32(1);
1686 double sec = PG_GETARG_FLOAT8(2);
1687 TimeADT time;
1688
1689 /* Check for time overflow */
1691 ereport(ERROR,
1693 errmsg("time field value out of range: %d:%02d:%02g",
1694 tm_hour, tm_min, sec)));
1695
1696 /* This should match tm2time */
1698 * USECS_PER_SEC) + (int64) rint(sec * USECS_PER_SEC);
1699
1700 PG_RETURN_TIMEADT(time);
1701}
1702
1703
1704/*
1705 * time_support()
1706 *
1707 * Planner support function for the time_scale() and timetz_scale()
1708 * length coercion functions (we need not distinguish them here).
1709 */
1710Datum
1712{
1714 Node *ret = NULL;
1715
1717 {
1719
1720 ret = TemporalSimplify(MAX_TIME_PRECISION, (Node *) req->fcall);
1721 }
1722
1723 PG_RETURN_POINTER(ret);
1724}
1725
1726/*
1727 * time_scale()
1728 * Adjust time type for specified scale factor.
1729 * Used by PostgreSQL type system to stuff columns.
1730 */
1731Datum
1733{
1734 TimeADT time = PG_GETARG_TIMEADT(0);
1735 int32 typmod = PG_GETARG_INT32(1);
1737
1738 result = time;
1739 AdjustTimeForTypmod(&result, typmod);
1740
1742}
1743
1744/*
1745 * AdjustTimeForTypmod()
1746 * Force the precision of the time value to a specified value.
1747 * Uses *exactly* the same code as in AdjustTimestampForTypmod()
1748 * but we make a separate copy because those types do not
1749 * have a fundamental tie together but rather a coincidence of
1750 * implementation. - thomas
1751 */
1752void
1754{
1755 static const int64 TimeScales[MAX_TIME_PRECISION + 1] = {
1756 INT64CONST(1000000),
1757 INT64CONST(100000),
1758 INT64CONST(10000),
1759 INT64CONST(1000),
1760 INT64CONST(100),
1761 INT64CONST(10),
1762 INT64CONST(1)
1763 };
1764
1765 static const int64 TimeOffsets[MAX_TIME_PRECISION + 1] = {
1766 INT64CONST(500000),
1767 INT64CONST(50000),
1768 INT64CONST(5000),
1769 INT64CONST(500),
1770 INT64CONST(50),
1771 INT64CONST(5),
1772 INT64CONST(0)
1773 };
1774
1775 if (typmod >= 0 && typmod <= MAX_TIME_PRECISION)
1776 {
1777 if (*time >= INT64CONST(0))
1778 *time = ((*time + TimeOffsets[typmod]) / TimeScales[typmod]) *
1779 TimeScales[typmod];
1780 else
1781 *time = -((((-*time) + TimeOffsets[typmod]) / TimeScales[typmod]) *
1782 TimeScales[typmod]);
1783 }
1784}
1785
1786
1787Datum
1795
1796Datum
1804
1805Datum
1813
1814Datum
1822
1823Datum
1831
1832Datum
1840
1841Datum
1843{
1846
1847 if (time1 < time2)
1848 PG_RETURN_INT32(-1);
1849 if (time1 > time2)
1850 PG_RETURN_INT32(1);
1851 PG_RETURN_INT32(0);
1852}
1853
1854Datum
1856{
1857 return hashint8(fcinfo);
1858}
1859
1860Datum
1862{
1863 return hashint8extended(fcinfo);
1864}
1865
1866Datum
1874
1875Datum
1883
1884/*
1885 * overlaps_time() --- implements the SQL OVERLAPS operator.
1886 *
1887 * Algorithm is per SQL spec. This is much harder than you'd think
1888 * because the spec requires us to deliver a non-null answer in some cases
1889 * where some of the inputs are null.
1890 */
1891Datum
1893{
1894 /*
1895 * The arguments are TimeADT, but we leave them as generic Datums to avoid
1896 * dereferencing nulls (TimeADT is pass-by-reference!)
1897 */
1902 bool ts1IsNull = PG_ARGISNULL(0);
1903 bool te1IsNull = PG_ARGISNULL(1);
1904 bool ts2IsNull = PG_ARGISNULL(2);
1905 bool te2IsNull = PG_ARGISNULL(3);
1906
1907#define TIMEADT_GT(t1,t2) \
1908 (DatumGetTimeADT(t1) > DatumGetTimeADT(t2))
1909#define TIMEADT_LT(t1,t2) \
1910 (DatumGetTimeADT(t1) < DatumGetTimeADT(t2))
1911
1912 /*
1913 * If both endpoints of interval 1 are null, the result is null (unknown).
1914 * If just one endpoint is null, take ts1 as the non-null one. Otherwise,
1915 * take ts1 as the lesser endpoint.
1916 */
1917 if (ts1IsNull)
1918 {
1919 if (te1IsNull)
1921 /* swap null for non-null */
1922 ts1 = te1;
1923 te1IsNull = true;
1924 }
1925 else if (!te1IsNull)
1926 {
1927 if (TIMEADT_GT(ts1, te1))
1928 {
1929 Datum tt = ts1;
1930
1931 ts1 = te1;
1932 te1 = tt;
1933 }
1934 }
1935
1936 /* Likewise for interval 2. */
1937 if (ts2IsNull)
1938 {
1939 if (te2IsNull)
1941 /* swap null for non-null */
1942 ts2 = te2;
1943 te2IsNull = true;
1944 }
1945 else if (!te2IsNull)
1946 {
1947 if (TIMEADT_GT(ts2, te2))
1948 {
1949 Datum tt = ts2;
1950
1951 ts2 = te2;
1952 te2 = tt;
1953 }
1954 }
1955
1956 /*
1957 * At this point neither ts1 nor ts2 is null, so we can consider three
1958 * cases: ts1 > ts2, ts1 < ts2, ts1 = ts2
1959 */
1960 if (TIMEADT_GT(ts1, ts2))
1961 {
1962 /*
1963 * This case is ts1 < te2 OR te1 < te2, which may look redundant but
1964 * in the presence of nulls it's not quite completely so.
1965 */
1966 if (te2IsNull)
1968 if (TIMEADT_LT(ts1, te2))
1969 PG_RETURN_BOOL(true);
1970 if (te1IsNull)
1972
1973 /*
1974 * If te1 is not null then we had ts1 <= te1 above, and we just found
1975 * ts1 >= te2, hence te1 >= te2.
1976 */
1977 PG_RETURN_BOOL(false);
1978 }
1979 else if (TIMEADT_LT(ts1, ts2))
1980 {
1981 /* This case is ts2 < te1 OR te2 < te1 */
1982 if (te1IsNull)
1984 if (TIMEADT_LT(ts2, te1))
1985 PG_RETURN_BOOL(true);
1986 if (te2IsNull)
1988
1989 /*
1990 * If te2 is not null then we had ts2 <= te2 above, and we just found
1991 * ts2 >= te1, hence te2 >= te1.
1992 */
1993 PG_RETURN_BOOL(false);
1994 }
1995 else
1996 {
1997 /*
1998 * For ts1 = ts2 the spec says te1 <> te2 OR te1 = te2, which is a
1999 * rather silly way of saying "true if both are nonnull, else null".
2000 */
2001 if (te1IsNull || te2IsNull)
2003 PG_RETURN_BOOL(true);
2004 }
2005
2006#undef TIMEADT_GT
2007#undef TIMEADT_LT
2008}
2009
2010/*
2011 * timestamp_time()
2012 * Convert timestamp to time data type.
2013 */
2014Datum
2016{
2019 struct pg_tm tt,
2020 *tm = &tt;
2021 fsec_t fsec;
2022
2025
2026 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
2027 ereturn(fcinfo->context, (Datum) 0,
2029 errmsg("timestamp out of range")));
2030
2031 /*
2032 * Could also do this with time = (timestamp / USECS_PER_DAY *
2033 * USECS_PER_DAY) - timestamp;
2034 */
2036 USECS_PER_SEC) + fsec;
2037
2039}
2040
2041/*
2042 * timestamptz_time()
2043 * Convert timestamptz to time data type.
2044 */
2045Datum
2047{
2050 struct pg_tm tt,
2051 *tm = &tt;
2052 int tz;
2053 fsec_t fsec;
2054
2057
2058 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
2059 ereturn(fcinfo->context, (Datum) 0,
2061 errmsg("timestamp out of range")));
2062
2063 /*
2064 * Could also do this with time = (timestamp / USECS_PER_DAY *
2065 * USECS_PER_DAY) - timestamp;
2066 */
2068 USECS_PER_SEC) + fsec;
2069
2071}
2072
2073/*
2074 * datetime_timestamp()
2075 * Convert date and time to timestamp data type.
2076 */
2077Datum
2079{
2081 TimeADT time = PG_GETARG_TIMEADT(1);
2083
2086 {
2087 result += time;
2089 ereport(ERROR,
2091 errmsg("timestamp out of range")));
2092 }
2093
2095}
2096
2097/*
2098 * time_interval()
2099 * Convert time to interval data type.
2100 */
2101Datum
2103{
2104 TimeADT time = PG_GETARG_TIMEADT(0);
2106
2108
2109 result->time = time;
2110 result->day = 0;
2111 result->month = 0;
2112
2114}
2115
2116/*
2117 * interval_time()
2118 * Convert interval to time data type.
2119 *
2120 * This is defined as producing the fractional-day portion of the interval.
2121 * Therefore, we can just ignore the months field. It is not real clear
2122 * what to do with negative intervals, but we choose to subtract the floor,
2123 * so that, say, '-2 hours' becomes '22:00:00'.
2124 */
2125Datum
2127{
2130
2132 ereturn(fcinfo->context, (Datum) 0,
2134 errmsg("cannot convert infinite interval to time")));
2135
2136 result = span->time % USECS_PER_DAY;
2137 if (result < 0)
2139
2141}
2142
2143/*
2144 * time_mi_time()
2145 * Subtract two times to produce an interval.
2146 */
2147Datum
2149{
2153
2155
2156 result->month = 0;
2157 result->day = 0;
2158 result->time = time1 - time2;
2159
2161}
2162
2163/*
2164 * time_pl_interval()
2165 * Add interval to time.
2166 */
2167Datum
2169{
2170 TimeADT time = PG_GETARG_TIMEADT(0);
2173
2175 ereport(ERROR,
2177 errmsg("cannot add infinite interval to time")));
2178
2179 result = time + span->time;
2181 if (result < INT64CONST(0))
2183
2185}
2186
2187/*
2188 * time_mi_interval()
2189 * Subtract interval from time.
2190 */
2191Datum
2193{
2194 TimeADT time = PG_GETARG_TIMEADT(0);
2197
2199 ereport(ERROR,
2201 errmsg("cannot subtract infinite interval from time")));
2202
2203 result = time - span->time;
2205 if (result < INT64CONST(0))
2207
2209}
2210
2211/*
2212 * in_range support function for time.
2213 */
2214Datum
2216{
2218 TimeADT base = PG_GETARG_TIMEADT(1);
2219 Interval *offset = PG_GETARG_INTERVAL_P(2);
2220 bool sub = PG_GETARG_BOOL(3);
2221 bool less = PG_GETARG_BOOL(4);
2222 TimeADT sum;
2223
2224 /*
2225 * Like time_pl_interval/time_mi_interval, we disregard the month and day
2226 * fields of the offset. So our test for negative should too. This also
2227 * catches -infinity, so we only need worry about +infinity below.
2228 */
2229 if (offset->time < 0)
2230 ereport(ERROR,
2232 errmsg("invalid preceding or following size in window function")));
2233
2234 /*
2235 * We can't use time_pl_interval/time_mi_interval here, because their
2236 * wraparound behavior would give wrong (or at least undesirable) answers.
2237 * Fortunately the equivalent non-wrapping behavior is trivial, except
2238 * that adding an infinite (or very large) interval might cause integer
2239 * overflow. Subtraction cannot overflow here.
2240 */
2241 if (sub)
2242 sum = base - offset->time;
2243 else if (pg_add_s64_overflow(base, offset->time, &sum))
2245
2246 if (less)
2247 PG_RETURN_BOOL(val <= sum);
2248 else
2249 PG_RETURN_BOOL(val >= sum);
2250}
2251
2252
2253/*
2254 * time_part() and extract_time()
2255 * Extract specified field from time type.
2256 */
2257static Datum
2259{
2261 TimeADT time = PG_GETARG_TIMEADT(1);
2263 int type,
2264 val;
2265 char *lowunits;
2266
2269 false);
2270
2271 type = DecodeUnits(0, lowunits, &val);
2272 if (type == UNKNOWN_FIELD)
2274
2275 if (type == UNITS)
2276 {
2277 fsec_t fsec;
2278 struct pg_tm tt,
2279 *tm = &tt;
2280
2281 time2tm(time, tm, &fsec);
2282
2283 switch (val)
2284 {
2285 case DTK_MICROSEC:
2286 intresult = tm->tm_sec * INT64CONST(1000000) + fsec;
2287 break;
2288
2289 case DTK_MILLISEC:
2290 if (retnumeric)
2291 /*---
2292 * tm->tm_sec * 1000 + fsec / 1000
2293 * = (tm->tm_sec * 1'000'000 + fsec) / 1000
2294 */
2296 else
2297 PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + fsec / 1000.0);
2298 break;
2299
2300 case DTK_SECOND:
2301 if (retnumeric)
2302 /*---
2303 * tm->tm_sec + fsec / 1'000'000
2304 * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
2305 */
2307 else
2308 PG_RETURN_FLOAT8(tm->tm_sec + fsec / 1000000.0);
2309 break;
2310
2311 case DTK_MINUTE:
2312 intresult = tm->tm_min;
2313 break;
2314
2315 case DTK_HOUR:
2316 intresult = tm->tm_hour;
2317 break;
2318
2319 case DTK_TZ:
2320 case DTK_TZ_MINUTE:
2321 case DTK_TZ_HOUR:
2322 case DTK_DAY:
2323 case DTK_MONTH:
2324 case DTK_QUARTER:
2325 case DTK_YEAR:
2326 case DTK_DECADE:
2327 case DTK_CENTURY:
2328 case DTK_MILLENNIUM:
2329 case DTK_ISOYEAR:
2330 default:
2331 ereport(ERROR,
2333 errmsg("unit \"%s\" not supported for type %s",
2335 intresult = 0;
2336 }
2337 }
2338 else if (type == RESERV && val == DTK_EPOCH)
2339 {
2340 if (retnumeric)
2342 else
2343 PG_RETURN_FLOAT8(time / 1000000.0);
2344 }
2345 else
2346 {
2347 ereport(ERROR,
2349 errmsg("unit \"%s\" not recognized for type %s",
2351 intresult = 0;
2352 }
2353
2354 if (retnumeric)
2356 else
2358}
2359
2360Datum
2362{
2363 return time_part_common(fcinfo, false);
2364}
2365
2366Datum
2368{
2369 return time_part_common(fcinfo, true);
2370}
2371
2372
2373/*****************************************************************************
2374 * Time With Time Zone ADT
2375 *****************************************************************************/
2376
2377/*
2378 * tm2timetz()
2379 * Convert a tm structure to a time data type.
2380 */
2381int
2382tm2timetz(struct pg_tm *tm, fsec_t fsec, int tz, TimeTzADT *result)
2383{
2384 result->time = ((((tm->tm_hour * MINS_PER_HOUR + tm->tm_min) * SECS_PER_MINUTE) + tm->tm_sec) *
2385 USECS_PER_SEC) + fsec;
2386 result->zone = tz;
2387
2388 return 0;
2389}
2390
2391Datum
2393{
2394 char *str = PG_GETARG_CSTRING(0);
2395#ifdef NOT_USED
2396 Oid typelem = PG_GETARG_OID(1);
2397#endif
2398 int32 typmod = PG_GETARG_INT32(2);
2399 Node *escontext = fcinfo->context;
2401 fsec_t fsec;
2402 struct pg_tm tt,
2403 *tm = &tt;
2404 int tz;
2405 int nf;
2406 int dterr;
2407 char workbuf[MAXDATELEN + 1];
2408 char *field[MAXDATEFIELDS];
2409 int dtype;
2410 int ftype[MAXDATEFIELDS];
2411 DateTimeErrorExtra extra;
2412
2414 field, ftype, MAXDATEFIELDS, &nf);
2415 if (dterr == 0)
2416 dterr = DecodeTimeOnly(field, ftype, nf,
2417 &dtype, tm, &fsec, &tz, &extra);
2418 if (dterr != 0)
2419 {
2420 DateTimeParseError(dterr, &extra, str, "time with time zone",
2421 escontext);
2423 }
2424
2426 tm2timetz(tm, fsec, tz, result);
2427 AdjustTimeForTypmod(&(result->time), typmod);
2428
2430}
2431
2432Datum
2434{
2436 char *result;
2437 struct pg_tm tt,
2438 *tm = &tt;
2439 fsec_t fsec;
2440 int tz;
2441 char buf[MAXDATELEN + 1];
2442
2443 timetz2tm(time, tm, &fsec, &tz);
2444 EncodeTimeOnly(tm, fsec, true, tz, DateStyle, buf);
2445
2446 result = pstrdup(buf);
2448}
2449
2450/*
2451 * timetz_recv - converts external binary format to timetz
2452 */
2453Datum
2455{
2457
2458#ifdef NOT_USED
2459 Oid typelem = PG_GETARG_OID(1);
2460#endif
2461 int32 typmod = PG_GETARG_INT32(2);
2463
2465
2466 result->time = pq_getmsgint64(buf);
2467
2468 if (result->time < INT64CONST(0) || result->time > USECS_PER_DAY)
2469 ereport(ERROR,
2471 errmsg("time out of range")));
2472
2473 result->zone = pq_getmsgint(buf, sizeof(result->zone));
2474
2475 /* Check for sane GMT displacement; see notes in datatype/timestamp.h */
2476 if (result->zone <= -TZDISP_LIMIT || result->zone >= TZDISP_LIMIT)
2477 ereport(ERROR,
2479 errmsg("time zone displacement out of range")));
2480
2481 AdjustTimeForTypmod(&(result->time), typmod);
2482
2484}
2485
2486/*
2487 * timetz_send - converts timetz to binary format
2488 */
2489Datum
2500
2501Datum
2508
2509Datum
2511{
2512 int32 typmod = PG_GETARG_INT32(0);
2513
2514 PG_RETURN_CSTRING(anytime_typmodout(true, typmod));
2515}
2516
2517
2518/*
2519 * timetz2tm()
2520 * Convert TIME WITH TIME ZONE data type to POSIX time structure.
2521 */
2522int
2523timetz2tm(TimeTzADT *time, struct pg_tm *tm, fsec_t *fsec, int *tzp)
2524{
2525 TimeOffset trem = time->time;
2526
2532 *fsec = trem - tm->tm_sec * USECS_PER_SEC;
2533
2534 if (tzp != NULL)
2535 *tzp = time->zone;
2536
2537 return 0;
2538}
2539
2540/*
2541 * timetz_scale()
2542 * Adjust time type for specified scale factor.
2543 * Used by PostgreSQL type system to stuff columns.
2544 */
2545Datum
2547{
2549 int32 typmod = PG_GETARG_INT32(1);
2551
2553
2554 result->time = time->time;
2555 result->zone = time->zone;
2556
2557 AdjustTimeForTypmod(&(result->time), typmod);
2558
2560}
2561
2562
2563static int
2565{
2566 TimeOffset t1,
2567 t2;
2568
2569 /* Primary sort is by true (GMT-equivalent) time */
2570 t1 = time1->time + (time1->zone * USECS_PER_SEC);
2571 t2 = time2->time + (time2->zone * USECS_PER_SEC);
2572
2573 if (t1 > t2)
2574 return 1;
2575 if (t1 < t2)
2576 return -1;
2577
2578 /*
2579 * If same GMT time, sort by timezone; we only want to say that two
2580 * timetz's are equal if both the time and zone parts are equal.
2581 */
2582 if (time1->zone > time2->zone)
2583 return 1;
2584 if (time1->zone < time2->zone)
2585 return -1;
2586
2587 return 0;
2588}
2589
2590Datum
2598
2599Datum
2607
2608Datum
2616
2617Datum
2625
2626Datum
2634
2635Datum
2643
2644Datum
2652
2653Datum
2655{
2657 uint32 thash;
2658
2659 /*
2660 * To avoid any problems with padding bytes in the struct, we figure the
2661 * field hashes separately and XOR them.
2662 */
2664 Int64GetDatumFast(key->time)));
2665 thash ^= DatumGetUInt32(hash_uint32(key->zone));
2667}
2668
2669Datum
2671{
2673 Datum seed = PG_GETARG_DATUM(1);
2674 uint64 thash;
2675
2676 /* Same approach as timetz_hash */
2678 Int64GetDatumFast(key->time),
2679 seed));
2681 DatumGetInt64(seed)));
2683}
2684
2685Datum
2698
2699Datum
2712
2713/*
2714 * timetz_pl_interval()
2715 * Add interval to timetz.
2716 */
2717Datum
2719{
2723
2725 ereport(ERROR,
2727 errmsg("cannot add infinite interval to time")));
2728
2730
2731 result->time = time->time + span->time;
2732 result->time -= result->time / USECS_PER_DAY * USECS_PER_DAY;
2733 if (result->time < INT64CONST(0))
2734 result->time += USECS_PER_DAY;
2735
2736 result->zone = time->zone;
2737
2739}
2740
2741/*
2742 * timetz_mi_interval()
2743 * Subtract interval from timetz.
2744 */
2745Datum
2747{
2751
2753 ereport(ERROR,
2755 errmsg("cannot subtract infinite interval from time")));
2756
2758
2759 result->time = time->time - span->time;
2760 result->time -= result->time / USECS_PER_DAY * USECS_PER_DAY;
2761 if (result->time < INT64CONST(0))
2762 result->time += USECS_PER_DAY;
2763
2764 result->zone = time->zone;
2765
2767}
2768
2769/*
2770 * in_range support function for timetz.
2771 */
2772Datum
2774{
2777 Interval *offset = PG_GETARG_INTERVAL_P(2);
2778 bool sub = PG_GETARG_BOOL(3);
2779 bool less = PG_GETARG_BOOL(4);
2780 TimeTzADT sum;
2781
2782 /*
2783 * Like timetz_pl_interval/timetz_mi_interval, we disregard the month and
2784 * day fields of the offset. So our test for negative should too. This
2785 * also catches -infinity, so we only need worry about +infinity below.
2786 */
2787 if (offset->time < 0)
2788 ereport(ERROR,
2790 errmsg("invalid preceding or following size in window function")));
2791
2792 /*
2793 * We can't use timetz_pl_interval/timetz_mi_interval here, because their
2794 * wraparound behavior would give wrong (or at least undesirable) answers.
2795 * Fortunately the equivalent non-wrapping behavior is trivial, except
2796 * that adding an infinite (or very large) interval might cause integer
2797 * overflow. Subtraction cannot overflow here.
2798 */
2799 if (sub)
2800 sum.time = base->time - offset->time;
2801 else if (pg_add_s64_overflow(base->time, offset->time, &sum.time))
2803 sum.zone = base->zone;
2804
2805 if (less)
2807 else
2809}
2810
2811/*
2812 * overlaps_timetz() --- implements the SQL OVERLAPS operator.
2813 *
2814 * Algorithm is per SQL spec. This is much harder than you'd think
2815 * because the spec requires us to deliver a non-null answer in some cases
2816 * where some of the inputs are null.
2817 */
2818Datum
2820{
2821 /*
2822 * The arguments are TimeTzADT *, but we leave them as generic Datums for
2823 * convenience of notation --- and to avoid dereferencing nulls.
2824 */
2829 bool ts1IsNull = PG_ARGISNULL(0);
2830 bool te1IsNull = PG_ARGISNULL(1);
2831 bool ts2IsNull = PG_ARGISNULL(2);
2832 bool te2IsNull = PG_ARGISNULL(3);
2833
2834#define TIMETZ_GT(t1,t2) \
2835 DatumGetBool(DirectFunctionCall2(timetz_gt,t1,t2))
2836#define TIMETZ_LT(t1,t2) \
2837 DatumGetBool(DirectFunctionCall2(timetz_lt,t1,t2))
2838
2839 /*
2840 * If both endpoints of interval 1 are null, the result is null (unknown).
2841 * If just one endpoint is null, take ts1 as the non-null one. Otherwise,
2842 * take ts1 as the lesser endpoint.
2843 */
2844 if (ts1IsNull)
2845 {
2846 if (te1IsNull)
2848 /* swap null for non-null */
2849 ts1 = te1;
2850 te1IsNull = true;
2851 }
2852 else if (!te1IsNull)
2853 {
2854 if (TIMETZ_GT(ts1, te1))
2855 {
2856 Datum tt = ts1;
2857
2858 ts1 = te1;
2859 te1 = tt;
2860 }
2861 }
2862
2863 /* Likewise for interval 2. */
2864 if (ts2IsNull)
2865 {
2866 if (te2IsNull)
2868 /* swap null for non-null */
2869 ts2 = te2;
2870 te2IsNull = true;
2871 }
2872 else if (!te2IsNull)
2873 {
2874 if (TIMETZ_GT(ts2, te2))
2875 {
2876 Datum tt = ts2;
2877
2878 ts2 = te2;
2879 te2 = tt;
2880 }
2881 }
2882
2883 /*
2884 * At this point neither ts1 nor ts2 is null, so we can consider three
2885 * cases: ts1 > ts2, ts1 < ts2, ts1 = ts2
2886 */
2887 if (TIMETZ_GT(ts1, ts2))
2888 {
2889 /*
2890 * This case is ts1 < te2 OR te1 < te2, which may look redundant but
2891 * in the presence of nulls it's not quite completely so.
2892 */
2893 if (te2IsNull)
2895 if (TIMETZ_LT(ts1, te2))
2896 PG_RETURN_BOOL(true);
2897 if (te1IsNull)
2899
2900 /*
2901 * If te1 is not null then we had ts1 <= te1 above, and we just found
2902 * ts1 >= te2, hence te1 >= te2.
2903 */
2904 PG_RETURN_BOOL(false);
2905 }
2906 else if (TIMETZ_LT(ts1, ts2))
2907 {
2908 /* This case is ts2 < te1 OR te2 < te1 */
2909 if (te1IsNull)
2911 if (TIMETZ_LT(ts2, te1))
2912 PG_RETURN_BOOL(true);
2913 if (te2IsNull)
2915
2916 /*
2917 * If te2 is not null then we had ts2 <= te2 above, and we just found
2918 * ts2 >= te1, hence te2 >= te1.
2919 */
2920 PG_RETURN_BOOL(false);
2921 }
2922 else
2923 {
2924 /*
2925 * For ts1 = ts2 the spec says te1 <> te2 OR te1 = te2, which is a
2926 * rather silly way of saying "true if both are nonnull, else null".
2927 */
2928 if (te1IsNull || te2IsNull)
2930 PG_RETURN_BOOL(true);
2931 }
2932
2933#undef TIMETZ_GT
2934#undef TIMETZ_LT
2935}
2936
2937
2938Datum
2940{
2943
2944 /* swallow the time zone and just return the time */
2945 result = timetz->time;
2946
2948}
2949
2950
2951Datum
2953{
2954 TimeADT time = PG_GETARG_TIMEADT(0);
2956 struct pg_tm tt,
2957 *tm = &tt;
2958 fsec_t fsec;
2959 int tz;
2960
2962 time2tm(time, tm, &fsec);
2964
2966
2967 result->time = time;
2968 result->zone = tz;
2969
2971}
2972
2973
2974/*
2975 * timestamptz_timetz()
2976 * Convert timestamp to timetz data type.
2977 */
2978Datum
2980{
2983 struct pg_tm tt,
2984 *tm = &tt;
2985 int tz;
2986 fsec_t fsec;
2987
2990
2991 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
2992 ereturn(fcinfo->context, (Datum) 0,
2994 errmsg("timestamp out of range")));
2995
2997
2998 tm2timetz(tm, fsec, tz, result);
2999
3001}
3002
3003
3004/*
3005 * datetimetz_timestamptz()
3006 * Convert date and timetz to timestamp with time zone data type.
3007 * Timestamp is stored in GMT, so add the time zone
3008 * stored with the timetz to the result.
3009 * - thomas 2000-03-10
3010 */
3011Datum
3013{
3017
3018 if (DATE_IS_NOBEGIN(date))
3020 else if (DATE_IS_NOEND(date))
3022 else
3023 {
3024 /*
3025 * Date's range is wider than timestamp's, so check for boundaries.
3026 * Since dates have the same minimum values as timestamps, only upper
3027 * boundary need be checked for overflow.
3028 */
3030 ereport(ERROR,
3032 errmsg("date out of range for timestamp")));
3033 result = date * USECS_PER_DAY + time->time + time->zone * USECS_PER_SEC;
3034
3035 /*
3036 * Since it is possible to go beyond allowed timestamptz range because
3037 * of time zone, check for allowed timestamp range after adding tz.
3038 */
3040 ereport(ERROR,
3042 errmsg("date out of range for timestamp")));
3043 }
3044
3046}
3047
3048
3049/*
3050 * timetz_part() and extract_timetz()
3051 * Extract specified field from time type.
3052 */
3053static Datum
3055{
3059 int type,
3060 val;
3061 char *lowunits;
3062
3065 false);
3066
3067 type = DecodeUnits(0, lowunits, &val);
3068 if (type == UNKNOWN_FIELD)
3070
3071 if (type == UNITS)
3072 {
3073 int tz;
3074 fsec_t fsec;
3075 struct pg_tm tt,
3076 *tm = &tt;
3077
3078 timetz2tm(time, tm, &fsec, &tz);
3079
3080 switch (val)
3081 {
3082 case DTK_TZ:
3083 intresult = -tz;
3084 break;
3085
3086 case DTK_TZ_MINUTE:
3088 break;
3089
3090 case DTK_TZ_HOUR:
3091 intresult = -tz / SECS_PER_HOUR;
3092 break;
3093
3094 case DTK_MICROSEC:
3095 intresult = tm->tm_sec * INT64CONST(1000000) + fsec;
3096 break;
3097
3098 case DTK_MILLISEC:
3099 if (retnumeric)
3100 /*---
3101 * tm->tm_sec * 1000 + fsec / 1000
3102 * = (tm->tm_sec * 1'000'000 + fsec) / 1000
3103 */
3105 else
3106 PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + fsec / 1000.0);
3107 break;
3108
3109 case DTK_SECOND:
3110 if (retnumeric)
3111 /*---
3112 * tm->tm_sec + fsec / 1'000'000
3113 * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
3114 */
3116 else
3117 PG_RETURN_FLOAT8(tm->tm_sec + fsec / 1000000.0);
3118 break;
3119
3120 case DTK_MINUTE:
3121 intresult = tm->tm_min;
3122 break;
3123
3124 case DTK_HOUR:
3125 intresult = tm->tm_hour;
3126 break;
3127
3128 case DTK_DAY:
3129 case DTK_MONTH:
3130 case DTK_QUARTER:
3131 case DTK_YEAR:
3132 case DTK_DECADE:
3133 case DTK_CENTURY:
3134 case DTK_MILLENNIUM:
3135 default:
3136 ereport(ERROR,
3138 errmsg("unit \"%s\" not supported for type %s",
3140 intresult = 0;
3141 }
3142 }
3143 else if (type == RESERV && val == DTK_EPOCH)
3144 {
3145 if (retnumeric)
3146 /*---
3147 * time->time / 1'000'000 + time->zone
3148 * = (time->time + time->zone * 1'000'000) / 1'000'000
3149 */
3150 PG_RETURN_NUMERIC(int64_div_fast_to_numeric(time->time + time->zone * INT64CONST(1000000), 6));
3151 else
3152 PG_RETURN_FLOAT8(time->time / 1000000.0 + time->zone);
3153 }
3154 else
3155 {
3156 ereport(ERROR,
3158 errmsg("unit \"%s\" not recognized for type %s",
3160 intresult = 0;
3161 }
3162
3163 if (retnumeric)
3165 else
3167}
3168
3169
3170Datum
3172{
3173 return timetz_part_common(fcinfo, false);
3174}
3175
3176Datum
3178{
3179 return timetz_part_common(fcinfo, true);
3180}
3181
3182/*
3183 * timetz_zone()
3184 * Encode time with time zone type with specified time zone.
3185 * Applies DST rules as of the transaction start time.
3186 */
3187Datum
3189{
3193 int tz;
3194 char tzname[TZ_STRLEN_MAX + 1];
3195 int type,
3196 val;
3197 pg_tz *tzp;
3198
3199 /*
3200 * Look up the requested timezone.
3201 */
3203
3204 type = DecodeTimezoneName(tzname, &val, &tzp);
3205
3207 {
3208 /* fixed-offset abbreviation */
3209 tz = -val;
3210 }
3211 else if (type == TZNAME_DYNTZ)
3212 {
3213 /* dynamic-offset abbreviation, resolve using transaction start time */
3215 int isdst;
3216
3218 }
3219 else
3220 {
3221 /* Get the offset-from-GMT that is valid now for the zone name */
3223 struct pg_tm tm;
3224 fsec_t fsec;
3225
3226 if (timestamp2tm(now, &tz, &tm, &fsec, NULL, tzp) != 0)
3227 ereport(ERROR,
3229 errmsg("timestamp out of range")));
3230 }
3231
3233
3234 result->time = t->time + (t->zone - tz) * USECS_PER_SEC;
3235 /* C99 modulo has the wrong sign convention for negative input */
3236 while (result->time < INT64CONST(0))
3237 result->time += USECS_PER_DAY;
3238 if (result->time >= USECS_PER_DAY)
3239 result->time %= USECS_PER_DAY;
3240
3241 result->zone = tz;
3242
3244}
3245
3246/*
3247 * timetz_izone()
3248 * Encode time with time zone type with specified time interval as time zone.
3249 */
3250Datum
3252{
3256 int tz;
3257
3259 ereport(ERROR,
3261 errmsg("interval time zone \"%s\" must be finite",
3263 PointerGetDatum(zone))))));
3264
3265 if (zone->month != 0 || zone->day != 0)
3266 ereport(ERROR,
3268 errmsg("interval time zone \"%s\" must not include months or days",
3270 PointerGetDatum(zone))))));
3271
3272 tz = -(zone->time / USECS_PER_SEC);
3273
3275
3276 result->time = time->time + (time->zone - tz) * USECS_PER_SEC;
3277 /* C99 modulo has the wrong sign convention for negative input */
3278 while (result->time < INT64CONST(0))
3279 result->time += USECS_PER_DAY;
3280 if (result->time >= USECS_PER_DAY)
3281 result->time %= USECS_PER_DAY;
3282
3283 result->zone = tz;
3284
3286}
3287
3288/*
3289 * timetz_at_local()
3290 *
3291 * Unlike for timestamp[tz]_at_local, the type for timetz does not flip between
3292 * time with/without time zone, so we cannot just call the conversion function.
3293 */
3294Datum
#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:4995
int DetermineTimeZoneAbbrevOffsetTS(TimestampTz ts, const char *abbr, pg_tz *tzp, int *isdst)
Definition datetime.c:1810
int DecodeUnits(int field, const char *lowtoken, int *val)
Definition datetime.c:4196
int DecodeTimeOnly(char **field, int *ftype, int nf, int *dtype, struct pg_tm *tm, fsec_t *fsec, int *tzp, DateTimeErrorExtra *extra)
Definition datetime.c:1927
int j2day(int date)
Definition datetime.c:355
int ParseDateTime(const char *timestr, char *workbuf, size_t buflen, char **field, int *ftype, int maxfields, int *numfields)
Definition datetime.c:775
int DetermineTimeZoneOffset(struct pg_tm *tm, pg_tz *tzp)
Definition datetime.c:1608
void DateTimeParseError(int dterr, DateTimeErrorExtra *extra, const char *str, const char *datatype, Node *escontext)
Definition datetime.c:4241
void EncodeTimeOnly(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, int style, char *str)
Definition datetime.c:4465
int ValidateDate(int fmask, bool isjulian, bool is2digits, bool bc, struct pg_tm *tm)
Definition datetime.c:2573
int DecodeSpecial(int field, const char *lowtoken, int *val)
Definition datetime.c:3266
void j2date(int jd, int *year, int *month, int *day)
Definition datetime.c:322
void GetCurrentDateTime(struct pg_tm *tm)
Definition datetime.c:377
void EncodeDateOnly(struct pg_tm *tm, int style, char *str)
Definition datetime.c:4379
int DecodeDateTime(char **field, int *ftype, int nf, int *dtype, struct pg_tm *tm, fsec_t *fsec, int *tzp, DateTimeErrorExtra *extra)
Definition datetime.c:1000
int date2j(int year, int month, int day)
Definition datetime.c:297
void GetCurrentTimeUsec(struct pg_tm *tm, fsec_t *fsec, int *tzp)
Definition datetime.c:398
const char *const days[]
Definition datetime.c:85
int DecodeTimezoneName(const char *tzname, int *offset, pg_tz **tz)
Definition datetime.c:3309
Numeric int64_to_numeric(int64 val)
Definition numeric.c:4264
Numeric int64_div_fast_to_numeric(int64 val1, int log10val2)
Definition numeric.c:4285
Datum numeric_in(PG_FUNCTION_ARGS)
Definition numeric.c:626
Datum interval_out(PG_FUNCTION_ARGS)
Definition timestamp.c:974
int timestamp_cmp_internal(Timestamp dt1, Timestamp dt2)
Definition timestamp.c:2222
Datum in_range_timestamp_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3895
void GetEpochTime(struct pg_tm *tm)
Definition timestamp.c:2180
Datum timestamp_pl_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3104
int date2isoweek(int year, int mon, int mday)
Definition timestamp.c:5326
Datum timestamp_mi_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3221
int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
Definition timestamp.c:1918
Datum now(PG_FUNCTION_ARGS)
Definition timestamp.c:1613
int date2isoyear(int year, int mon, int mday)
Definition timestamp.c:5382
#define INT64CONST(x)
Definition c.h:630
#define Assert(condition)
Definition c.h:943
int64_t int64
Definition c.h:621
int32_t int32
Definition c.h:620
uint64_t uint64
Definition c.h:625
uint32_t uint32
Definition c.h:624
uint32 result
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:933
int32 date_cmp_timestamp_internal(DateADT dateVal, Timestamp dt2)
Definition date.c:764
Datum date_send(PG_FUNCTION_ARGS)
Definition date.c:227
Datum timetz_izone(PG_FUNCTION_ARGS)
Definition date.c:3251
Timestamp date2timestamp_safe(DateADT dateVal, Node *escontext)
Definition date.c:627
int timetz2tm(TimeTzADT *time, struct pg_tm *tm, fsec_t *fsec, int *tzp)
Definition date.c:2523
Datum timestamp_ne_date(PG_FUNCTION_ARGS)
Definition date.c:942
Datum date_ne_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:879
Datum date_sortsupport(PG_FUNCTION_ARGS)
Definition date.c:453
Datum date_cmp(PG_FUNCTION_ARGS)
Definition date.c:440
Datum date_le(PG_FUNCTION_ARGS)
Definition date.c:413
Datum time_part(PG_FUNCTION_ARGS)
Definition date.c:2361
Datum time_eq(PG_FUNCTION_ARGS)
Definition date.c:1788
Datum timetz_send(PG_FUNCTION_ARGS)
Definition date.c:2490
Datum timetztypmodout(PG_FUNCTION_ARGS)
Definition date.c:2510
#define TIMETZ_GT(t1, t2)
Datum timestamp_ge_date(PG_FUNCTION_ARGS)
Definition date.c:978
static char * anytime_typmodout(bool istz, int32 typmod)
Definition date.c:87
Datum timetz_pl_interval(PG_FUNCTION_ARGS)
Definition date.c:2718
Datum timetz_smaller(PG_FUNCTION_ARGS)
Definition date.c:2700
Datum timetypmodin(PG_FUNCTION_ARGS)
Definition date.c:1663
Datum date_lt_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:888
Datum make_time(PG_FUNCTION_ARGS)
Definition date.c:1682
static Datum date_decrement(Relation rel, Datum existing, bool *underflow)
Definition date.c:462
Datum date_larger(PG_FUNCTION_ARGS)
Definition date.c:527
Datum in_range_time_interval(PG_FUNCTION_ARGS)
Definition date.c:2215
Datum date_gt_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:897
Datum date_lt_timestamp(PG_FUNCTION_ARGS)
Definition date.c:800
Datum timetz_ne(PG_FUNCTION_ARGS)
Definition date.c:2600
Datum time_interval(PG_FUNCTION_ARGS)
Definition date.c:2102
Datum date_eq(PG_FUNCTION_ARGS)
Definition date.c:386
Datum timetz_larger(PG_FUNCTION_ARGS)
Definition date.c:2686
Datum time_le(PG_FUNCTION_ARGS)
Definition date.c:1815
Datum timetz_part(PG_FUNCTION_ARGS)
Definition date.c:3171
Datum in_range_timetz_interval(PG_FUNCTION_ARGS)
Definition date.c:2773
Datum extract_time(PG_FUNCTION_ARGS)
Definition date.c:2367
Datum interval_time(PG_FUNCTION_ARGS)
Definition date.c:2126
TimestampTz date2timestamptz_safe(DateADT dateVal, Node *escontext)
Definition date.c:676
Datum date_mi_interval(PG_FUNCTION_ARGS)
Definition date.c:1295
Datum hashdateextended(PG_FUNCTION_ARGS)
Definition date.c:513
Datum date_eq_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:870
bool float_time_overflows(int hour, int min, double sec)
Definition date.c:1555
Datum timetz_gt(PG_FUNCTION_ARGS)
Definition date.c:2627
Datum timetz_at_local(PG_FUNCTION_ARGS)
Definition date.c:3295
Datum timestamp_gt_date(PG_FUNCTION_ARGS)
Definition date.c:960
Datum date_finite(PG_FUNCTION_ARGS)
Definition date.c:519
DateADT timestamp2date_safe(Timestamp timestamp, Node *escontext)
Definition date.c:1356
Datum in_range_date_interval(PG_FUNCTION_ARGS)
Definition date.c:1065
Datum time_cmp(PG_FUNCTION_ARGS)
Definition date.c:1842
Datum timestamp_time(PG_FUNCTION_ARGS)
Definition date.c:2015
Datum time_mi_time(PG_FUNCTION_ARGS)
Definition date.c:2148
Datum time_ge(PG_FUNCTION_ARGS)
Definition date.c:1833
int32 anytime_typmod_check(bool istz, int32 typmod)
Definition date.c:65
#define TIMEADT_GT(t1, t2)
Datum datetime_timestamp(PG_FUNCTION_ARGS)
Definition date.c:2078
static Datum timetz_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition date.c:3054
Datum date_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:1393
Datum date_ne_timestamp(PG_FUNCTION_ARGS)
Definition date.c:791
Datum timestamptz_ge_date(PG_FUNCTION_ARGS)
Definition date.c:1041
Datum date_eq_timestamp(PG_FUNCTION_ARGS)
Definition date.c:782
int tm2time(struct pg_tm *tm, fsec_t fsec, TimeADT *result)
Definition date.c:1518
Datum timetz_ge(PG_FUNCTION_ARGS)
Definition date.c:2636
Datum timestamp_lt_date(PG_FUNCTION_ARGS)
Definition date.c:951
Datum timestamptz_lt_date(PG_FUNCTION_ARGS)
Definition date.c:1014
Datum timetz_cmp(PG_FUNCTION_ARGS)
Definition date.c:2645
TimeADT GetSQLLocalTime(int32 typmod)
Definition date.c:365
Datum timetztypmodin(PG_FUNCTION_ARGS)
Definition date.c:2502
Datum timetz_recv(PG_FUNCTION_ARGS)
Definition date.c:2454
Datum time_recv(PG_FUNCTION_ARGS)
Definition date.c:1626
Datum time_mi_interval(PG_FUNCTION_ARGS)
Definition date.c:2192
Datum time_support(PG_FUNCTION_ARGS)
Definition date.c:1711
int tm2timetz(struct pg_tm *tm, fsec_t fsec, int tz, TimeTzADT *result)
Definition date.c:2382
Datum date_out(PG_FUNCTION_ARGS)
Definition date.c:180
DateADT timestamptz2date_safe(TimestampTz timestamp, Node *escontext)
Definition date.c:1437
Datum timetz_time(PG_FUNCTION_ARGS)
Definition date.c:2939
Datum timetz_in(PG_FUNCTION_ARGS)
Definition date.c:2392
Datum time_timetz(PG_FUNCTION_ARGS)
Definition date.c:2952
Datum time_lt(PG_FUNCTION_ARGS)
Definition date.c:1806
Datum date_in(PG_FUNCTION_ARGS)
Definition date.c:108
Datum date_gt(PG_FUNCTION_ARGS)
Definition date.c:422
bool time_overflows(int hour, int min, int sec, fsec_t fsec)
Definition date.c:1530
Datum timetz_mi_interval(PG_FUNCTION_ARGS)
Definition date.c:2746
Datum extract_timetz(PG_FUNCTION_ARGS)
Definition date.c:3177
Datum date_ge_timestamp(PG_FUNCTION_ARGS)
Definition date.c:827
static int32 anytime_typmodin(bool istz, ArrayType *ta)
Definition date.c:44
Datum date_mii(PG_FUNCTION_ARGS)
Definition date.c:591
Datum date_pl_interval(PG_FUNCTION_ARGS)
Definition date.c:1274
Datum overlaps_timetz(PG_FUNCTION_ARGS)
Definition date.c:2819
static Datum time_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition date.c:2258
Datum time_gt(PG_FUNCTION_ARGS)
Definition date.c:1824
Datum date_recv(PG_FUNCTION_ARGS)
Definition date.c:205
Datum timetz_lt(PG_FUNCTION_ARGS)
Definition date.c:2609
Datum time_out(PG_FUNCTION_ARGS)
Definition date.c:1606
Datum date_cmp_timestamp(PG_FUNCTION_ARGS)
Definition date.c:836
Datum time_hash(PG_FUNCTION_ARGS)
Definition date.c:1855
Datum time_larger(PG_FUNCTION_ARGS)
Definition date.c:1867
#define TIMETZ_LT(t1, t2)
Datum time_smaller(PG_FUNCTION_ARGS)
Definition date.c:1876
Datum time_ne(PG_FUNCTION_ARGS)
Definition date.c:1797
DateADT GetSQLCurrentDate(void)
Definition date.c:312
Datum timetz_eq(PG_FUNCTION_ARGS)
Definition date.c:2591
Datum date_gt_timestamp(PG_FUNCTION_ARGS)
Definition date.c:809
Datum timestamptz_timetz(PG_FUNCTION_ARGS)
Definition date.c:2979
void AdjustTimeForTypmod(TimeADT *time, int32 typmod)
Definition date.c:1753
Datum date_le_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:906
Datum date_pli(PG_FUNCTION_ARGS)
Definition date.c:566
Datum extract_date(PG_FUNCTION_ARGS)
Definition date.c:1093
Datum timestamptz_date(PG_FUNCTION_ARGS)
Definition date.c:1411
Datum timetz_le(PG_FUNCTION_ARGS)
Definition date.c:2618
Datum date_lt(PG_FUNCTION_ARGS)
Definition date.c:404
Datum timetz_hash(PG_FUNCTION_ARGS)
Definition date.c:2654
static Datum date_increment(Relation rel, Datum existing, bool *overflow)
Definition date.c:478
static TimestampTz date2timestamp(DateADT dateVal)
Definition date.c:660
static int timetz_cmp_internal(TimeTzADT *time1, TimeTzADT *time2)
Definition date.c:2564
Datum timestamptz_gt_date(PG_FUNCTION_ARGS)
Definition date.c:1023
Datum hashdate(PG_FUNCTION_ARGS)
Definition date.c:507
Datum timestamp_date(PG_FUNCTION_ARGS)
Definition date.c:1330
Datum date_ge(PG_FUNCTION_ARGS)
Definition date.c:431
Datum time_in(PG_FUNCTION_ARGS)
Definition date.c:1475
Datum time_hash_extended(PG_FUNCTION_ARGS)
Definition date.c:1861
Datum time_pl_interval(PG_FUNCTION_ARGS)
Definition date.c:2168
Datum datetimetz_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:3012
int time2tm(TimeADT time, struct pg_tm *tm, fsec_t *fsec)
Definition date.c:1593
Datum timestamptz_ne_date(PG_FUNCTION_ARGS)
Definition date.c:1005
Datum date_smaller(PG_FUNCTION_ARGS)
Definition date.c:536
void EncodeSpecialDate(DateADT dt, char *str)
Definition date.c:297
Datum timestamp_le_date(PG_FUNCTION_ARGS)
Definition date.c:969
Datum timetypmodout(PG_FUNCTION_ARGS)
Definition date.c:1671
Datum timestamptz_eq_date(PG_FUNCTION_ARGS)
Definition date.c:996
Datum timetz_scale(PG_FUNCTION_ARGS)
Definition date.c:2546
Datum timestamptz_cmp_date(PG_FUNCTION_ARGS)
Definition date.c:1050
Datum date_ge_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:915
Datum timetz_hash_extended(PG_FUNCTION_ARGS)
Definition date.c:2670
Datum date_skipsupport(PG_FUNCTION_ARGS)
Definition date.c:494
Datum timetz_zone(PG_FUNCTION_ARGS)
Definition date.c:3188
Datum date_cmp_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:924
int32 date_cmp_timestamptz_internal(DateADT dateVal, TimestampTz dt2)
Definition date.c:845
double date2timestamp_no_overflow(DateADT dateVal)
Definition date.c:741
Datum make_date(PG_FUNCTION_ARGS)
Definition date.c:241
TimeTzADT * GetSQLCurrentTime(int32 typmod)
Definition date.c:345
Datum date_le_timestamp(PG_FUNCTION_ARGS)
Definition date.c:818
Datum time_send(PG_FUNCTION_ARGS)
Definition date.c:1652
Datum date_mi(PG_FUNCTION_ARGS)
Definition date.c:548
Datum timestamp_cmp_date(PG_FUNCTION_ARGS)
Definition date.c:987
Datum date_ne(PG_FUNCTION_ARGS)
Definition date.c:395
Datum time_scale(PG_FUNCTION_ARGS)
Definition date.c:1732
Datum timestamptz_time(PG_FUNCTION_ARGS)
Definition date.c:2046
#define TIMEADT_LT(t1, t2)
Datum timetz_out(PG_FUNCTION_ARGS)
Definition date.c:2433
Datum overlaps_time(PG_FUNCTION_ARGS)
Definition date.c:1892
Datum date_timestamp(PG_FUNCTION_ARGS)
Definition date.c:1313
Datum timestamptz_le_date(PG_FUNCTION_ARGS)
Definition date.c:1032
#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:875
#define ereturn(context, dummy_value,...)
Definition elog.h:280
#define WARNING
Definition elog.h:37
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
#define ereport(elevel,...)
Definition elog.h:152
struct SortSupportData * SortSupport
Definition execnodes.h:61
#define palloc_object(type)
Definition fe_memutils.h:89
#define 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:690
#define PG_GETARG_FLOAT8(n)
Definition fmgr.h:283
#define PG_RETURN_FLOAT8(x)
Definition fmgr.h:369
#define PG_GETARG_POINTER(n)
Definition fmgr.h:277
#define PG_RETURN_CSTRING(x)
Definition fmgr.h:364
#define PG_ARGISNULL(n)
Definition fmgr.h:209
#define DirectFunctionCall1(func, arg1)
Definition fmgr.h:688
#define PG_GETARG_DATUM(n)
Definition fmgr.h:268
#define PG_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:696
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition fmgr.h:692
#define PG_RETURN_POINTER(x)
Definition fmgr.h:363
#define PG_FUNCTION_ARGS
Definition fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition fmgr.h:360
char * format_type_be(Oid type_oid)
int DateStyle
Definition globals.c:127
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:104
Datum hashint8(PG_FUNCTION_ARGS)
Definition hashfunc.c:84
#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:284
#define DTK_DATE_M
Definition datetime.h:191
#define DTK_MILLENNIUM
Definition datetime.h:170
#define DTK_EARLY
Definition datetime.h:150
#define DTK_ISOYEAR
Definition datetime.h:179
#define MAXDATELEN
Definition datetime.h:200
#define DTK_DOY
Definition datetime.h:176
#define DTK_TZ
Definition datetime.h:146
#define TZNAME_FIXED_OFFSET
Definition datetime.h:301
#define TZNAME_DYNTZ
Definition datetime.h:302
#define 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:1910
#define SOFT_ERROR_OCCURRED(escontext)
Definition miscnodes.h:53
#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 * errmsg
static char buf[DEFAULT_XLOG_SEG_SIZE]
const char * pg_get_timezone_name(pg_tz *tz)
Definition localtime.c:1992
#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:222
static uint64 DatumGetUInt64(Datum X)
Definition postgres.h:436
#define Int64GetDatumFast(X)
Definition postgres.h:538
static int64 DatumGetInt64(Datum X)
Definition postgres.h:416
static Datum BoolGetDatum(bool X)
Definition postgres.h:112
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
static char * DatumGetCString(Datum X)
Definition postgres.h:365
uint64_t Datum
Definition postgres.h:70
static Datum CStringGetDatum(const char *X)
Definition postgres.h:383
static Datum Int32GetDatum(int32 X)
Definition postgres.h:212
#define PointerGetDatum(X)
Definition postgres.h:354
#define InvalidOid
unsigned int Oid
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition pqformat.c:414
void pq_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 StringInfoData * StringInfo
Definition string.h:15
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:776
Definition zic.c:101
int ssup_datum_int32_cmp(Datum x, Datum y, SortSupport ssup)
Definition tuplesort.c:3475
#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:184
void text_to_cstring_buffer(const text *src, char *dst, size_t dst_len)
Definition varlena.c:248
const char * type
TimestampTz GetCurrentTransactionStartTimestamp(void)
Definition xact.c:872