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/* date_in()
104 * Given date text string, convert to internal date format.
105 */
106Datum
108{
109 char *str = PG_GETARG_CSTRING(0);
110 Node *escontext = fcinfo->context;
112 fsec_t fsec;
113 struct pg_tm tt,
114 *tm = &tt;
115 int tzp;
116 int dtype;
117 int nf;
118 int dterr;
119 char *field[MAXDATEFIELDS];
120 int ftype[MAXDATEFIELDS];
121 char workbuf[MAXDATELEN + 1];
122 DateTimeErrorExtra extra;
123
125 field, ftype, MAXDATEFIELDS, &nf);
126 if (dterr == 0)
127 dterr = DecodeDateTime(field, ftype, nf,
128 &dtype, tm, &fsec, &tzp, &extra);
129 if (dterr != 0)
130 {
131 DateTimeParseError(dterr, &extra, str, "date", escontext);
133 }
134
135 switch (dtype)
136 {
137 case DTK_DATE:
138 break;
139
140 case DTK_EPOCH:
142 break;
143
144 case DTK_LATE:
147
148 case DTK_EARLY:
151
152 default:
153 DateTimeParseError(DTERR_BAD_FORMAT, &extra, str, "date", escontext);
155 }
156
157 /* Prevent overflow in Julian-day routines */
159 ereturn(escontext, (Datum) 0,
161 errmsg("date out of range: \"%s\"", str)));
162
164
165 /* Now check for just-out-of-range dates */
166 if (!IS_VALID_DATE(date))
167 ereturn(escontext, (Datum) 0,
169 errmsg("date out of range: \"%s\"", str)));
170
172}
173
174/* date_out()
175 * Given internal format date, convert to text string.
176 */
177Datum
179{
181 char *result;
182 struct pg_tm tt,
183 *tm = &tt;
184 char buf[MAXDATELEN + 1];
185
188 else
189 {
191 &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
193 }
194
195 result = pstrdup(buf);
197}
198
199/*
200 * date_recv - converts external binary format to date
201 */
202Datum
204{
207
208 result = (DateADT) pq_getmsgint(buf, sizeof(DateADT));
209
210 /* Limit to the same range that date_in() accepts. */
212 /* ok */ ;
213 else if (!IS_VALID_DATE(result))
216 errmsg("date out of range")));
217
219}
220
221/*
222 * date_send - converts date to binary format
223 */
224Datum
234
235/*
236 * make_date - date constructor
237 */
238Datum
240{
241 struct pg_tm tm;
243 int dterr;
244 bool bc = false;
245
249
250 /* Handle negative years as BC */
251 if (tm.tm_year < 0)
252 {
253 int year = tm.tm_year;
254
255 bc = true;
256 if (pg_neg_s32_overflow(year, &year))
259 errmsg("date field value out of range: %d-%02d-%02d",
261 tm.tm_year = year;
262 }
263
264 dterr = ValidateDate(DTK_DATE_M, false, false, bc, &tm);
265
266 if (dterr != 0)
269 errmsg("date field value out of range: %d-%02d-%02d",
271
272 /* Prevent overflow in Julian-day routines */
276 errmsg("date out of range: %d-%02d-%02d",
278
280
281 /* Now check for just-out-of-range dates */
282 if (!IS_VALID_DATE(date))
285 errmsg("date out of range: %d-%02d-%02d",
287
289}
290
291/*
292 * Convert reserved date values to string.
293 */
294void
296{
297 if (DATE_IS_NOBEGIN(dt))
298 strcpy(str, EARLY);
299 else if (DATE_IS_NOEND(dt))
300 strcpy(str, LATE);
301 else /* shouldn't happen */
302 elog(ERROR, "invalid argument for EncodeSpecialDate");
303}
304
305
306/*
307 * GetSQLCurrentDate -- implements CURRENT_DATE
308 */
311{
312 struct pg_tm tm;
313
314 static int cache_year = 0;
315 static int cache_mon = 0;
316 static int cache_mday = 0;
317 static DateADT cache_date;
318
320
321 /*
322 * date2j involves several integer divisions; moreover, unless our session
323 * lives across local midnight, we don't really have to do it more than
324 * once. So it seems worth having a separate cache here.
325 */
326 if (tm.tm_year != cache_year ||
327 tm.tm_mon != cache_mon ||
329 {
334 }
335
336 return cache_date;
337}
338
339/*
340 * GetSQLCurrentTime -- implements CURRENT_TIME, CURRENT_TIME(n)
341 */
342TimeTzADT *
344{
346 struct pg_tm tt,
347 *tm = &tt;
348 fsec_t fsec;
349 int tz;
350
351 GetCurrentTimeUsec(tm, &fsec, &tz);
352
354 tm2timetz(tm, fsec, tz, result);
355 AdjustTimeForTypmod(&(result->time), typmod);
356 return result;
357}
358
359/*
360 * GetSQLLocalTime -- implements LOCALTIME, LOCALTIME(n)
361 */
364{
366 struct pg_tm tt,
367 *tm = &tt;
368 fsec_t fsec;
369 int tz;
370
371 GetCurrentTimeUsec(tm, &fsec, &tz);
372
373 tm2time(tm, fsec, &result);
374 AdjustTimeForTypmod(&result, typmod);
375 return result;
376}
377
378
379/*
380 * Comparison functions for dates
381 */
382
383Datum
391
392Datum
400
401Datum
409
410Datum
418
419Datum
427
428Datum
436
437Datum
449
450Datum
458
459static Datum
461{
463
465 {
466 /* return value is undefined */
467 *underflow = true;
468 return (Datum) 0;
469 }
470
471 *underflow = false;
472 return DateADTGetDatum(dexisting - 1);
473}
474
475static Datum
477{
479
481 {
482 /* return value is undefined */
483 *overflow = true;
484 return (Datum) 0;
485 }
486
487 *overflow = false;
488 return DateADTGetDatum(dexisting + 1);
489}
490
491Datum
503
504Datum
509
510Datum
515
516Datum
523
524Datum
532
533Datum
541
542/* Compute difference between two dates in days.
543 */
544Datum
557
558/* Add a number of days to a date, giving a new date.
559 * Must handle both positive and negative numbers of days.
560 */
561Datum
563{
567
569 PG_RETURN_DATEADT(dateVal); /* can't change infinity */
570
571 result = dateVal + days;
572
573 /* Check for integer overflow and out-of-allowed-range */
574 if ((days >= 0 ? (result < dateVal) : (result > dateVal)) ||
578 errmsg("date out of range")));
579
581}
582
583/* Subtract a number of days from a date, giving a new date.
584 */
585Datum
587{
591
593 PG_RETURN_DATEADT(dateVal); /* can't change infinity */
594
595 result = dateVal - days;
596
597 /* Check for integer overflow and out-of-allowed-range */
598 if ((days >= 0 ? (result > dateVal) : (result < dateVal)) ||
602 errmsg("date out of range")));
603
605}
606
607
608/*
609 * Promote date to timestamp.
610 *
611 * If the date falls out of the valid range for the timestamp type, error
612 * handling proceeds based on escontext.
613 *
614 * If escontext is NULL, we throw an out-of-range error (hard error).
615 * If escontext is not NULL, we return NOBEGIN or NOEND for lower bound or
616 * upper bound overflow, respectively, and record a soft error.
617 *
618 * Note: Lower bound overflow is currently not possible, as both date and
619 * timestamp datatypes share the same lower boundary: Julian day zero.
620 */
623{
625
628 else if (DATE_IS_NOEND(dateVal))
630 else
631 {
632 /*
633 * Since dates have the same minimum values as timestamps, only upper
634 * boundary need be checked for overflow.
635 */
637 {
639 ereturn(escontext, result,
641 errmsg("date out of range for timestamp")));
642 }
643
644 /* date is days since 2000, timestamp is microseconds since same... */
646 }
647
648 return result;
649}
650
651/*
652 * Promote date to timestamp, throwing error for overflow.
653 */
654static TimestampTz
659
660/*
661 * Promote date to timestamp with time zone.
662 *
663 * If the date falls out of the valid range for the timestamp type, error
664 * handling proceeds based on escontext.
665 *
666 * If escontext is NULL, we throw an out-of-range error (hard error).
667 * If escontext is not NULL, we return NOBEGIN or NOEND for lower bound or
668 * upper bound overflow, respectively, and record a soft error.
669 */
672{
674 struct pg_tm tt,
675 *tm = &tt;
676 int tz;
677
680 else if (DATE_IS_NOEND(dateVal))
682 else
683 {
684 /*
685 * Since dates have the same minimum values as timestamps, only upper
686 * boundary need be checked for overflow.
687 */
689 {
691 ereturn(escontext, result,
693 errmsg("date out of range for timestamp")));
694 }
695
697 &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
698 tm->tm_hour = 0;
699 tm->tm_min = 0;
700 tm->tm_sec = 0;
702
704
705 /*
706 * Since it is possible to go beyond allowed timestamptz range because
707 * of time zone, check for allowed timestamp range after adding tz.
708 */
710 {
711 if (result < MIN_TIMESTAMP)
713 else
715
716 ereturn(escontext, result,
718 errmsg("date out of range for timestamp")));
719 }
720 }
721
722 return result;
723}
724
725/*
726 * date2timestamp_no_overflow
727 *
728 * This is chartered to produce a double value that is numerically
729 * equivalent to the corresponding Timestamp value, if the date is in the
730 * valid range of Timestamps, but in any case not throw an overflow error.
731 * We can do this since the numerical range of double is greater than
732 * that of non-erroneous timestamps. The results are currently only
733 * used for statistical estimation purposes.
734 */
735double
737{
738 double result;
739
741 result = -DBL_MAX;
742 else if (DATE_IS_NOEND(dateVal))
743 result = DBL_MAX;
744 else
745 {
746 /* date is days since 2000, timestamp is microseconds since same... */
748 }
749
750 return result;
751}
752
753
754/*
755 * Crosstype comparison functions for dates
756 */
757
758int32
760{
763
764 dt1 = date2timestamp_safe(dateVal, (Node *) &escontext);
765 if (escontext.error_occurred)
766 {
767 Assert(TIMESTAMP_IS_NOEND(dt1)); /* NOBEGIN case cannot occur */
768
769 /* dt1 is larger than any finite timestamp, but less than infinity */
770 return TIMESTAMP_IS_NOEND(dt2) ? -1 : +1;
771 }
772
774}
775
776Datum
784
785Datum
793
794Datum
802
803Datum
811
812Datum
820
821Datum
829
830Datum
838
839int32
841{
844
845 dt1 = date2timestamptz_safe(dateVal, (Node *) &escontext);
846
847 if (escontext.error_occurred)
848 {
850 {
851 /* dt1 is larger than any finite timestamp, but less than infinity */
852 return TIMESTAMP_IS_NOEND(dt2) ? -1 : +1;
853 }
855 {
856 /* dt1 is less than any finite timestamp, but more than -infinity */
857 return TIMESTAMP_IS_NOBEGIN(dt2) ? +1 : -1;
858 }
859 }
860
862}
863
864Datum
872
873Datum
881
882Datum
890
891Datum
899
900Datum
908
909Datum
917
918Datum
926
927Datum
935
936Datum
944
945Datum
953
954Datum
962
963Datum
971
972Datum
980
981Datum
989
990Datum
998
999Datum
1007
1008Datum
1016
1017Datum
1025
1026Datum
1034
1035Datum
1043
1044Datum
1052
1053/*
1054 * in_range support function for date.
1055 *
1056 * We implement this by promoting the dates to timestamp (without time zone)
1057 * and then using the timestamp-and-interval in_range function.
1058 */
1059Datum
1061{
1063 DateADT base = PG_GETARG_DATEADT(1);
1064 Interval *offset = PG_GETARG_INTERVAL_P(2);
1065 bool sub = PG_GETARG_BOOL(3);
1066 bool less = PG_GETARG_BOOL(4);
1069
1070 /* XXX we could support out-of-range cases here, perhaps */
1072 baseStamp = date2timestamp(base);
1073
1077 IntervalPGetDatum(offset),
1078 BoolGetDatum(sub),
1080}
1081
1082
1083/* extract_date()
1084 * Extract specified field from date type.
1085 */
1086Datum
1088{
1092 int type,
1093 val;
1094 char *lowunits;
1095 int year,
1096 mon,
1097 mday;
1098
1101 false);
1102
1103 type = DecodeUnits(0, lowunits, &val);
1104 if (type == UNKNOWN_FIELD)
1106
1107 if (DATE_NOT_FINITE(date) && (type == UNITS || type == RESERV))
1108 {
1109 switch (val)
1110 {
1111 /* Oscillating units */
1112 case DTK_DAY:
1113 case DTK_MONTH:
1114 case DTK_QUARTER:
1115 case DTK_WEEK:
1116 case DTK_DOW:
1117 case DTK_ISODOW:
1118 case DTK_DOY:
1120 break;
1121
1122 /* Monotonically-increasing units */
1123 case DTK_YEAR:
1124 case DTK_DECADE:
1125 case DTK_CENTURY:
1126 case DTK_MILLENNIUM:
1127 case DTK_JULIAN:
1128 case DTK_ISOYEAR:
1129 case DTK_EPOCH:
1130 if (DATE_IS_NOBEGIN(date))
1132 CStringGetDatum("-Infinity"),
1134 Int32GetDatum(-1))));
1135 else
1137 CStringGetDatum("Infinity"),
1139 Int32GetDatum(-1))));
1140 default:
1141 ereport(ERROR,
1143 errmsg("unit \"%s\" not supported for type %s",
1145 }
1146 }
1147 else if (type == UNITS)
1148 {
1149 j2date(date + POSTGRES_EPOCH_JDATE, &year, &mon, &mday);
1150
1151 switch (val)
1152 {
1153 case DTK_DAY:
1154 intresult = mday;
1155 break;
1156
1157 case DTK_MONTH:
1158 intresult = mon;
1159 break;
1160
1161 case DTK_QUARTER:
1162 intresult = (mon - 1) / 3 + 1;
1163 break;
1164
1165 case DTK_WEEK:
1166 intresult = date2isoweek(year, mon, mday);
1167 break;
1168
1169 case DTK_YEAR:
1170 if (year > 0)
1171 intresult = year;
1172 else
1173 /* there is no year 0, just 1 BC and 1 AD */
1174 intresult = year - 1;
1175 break;
1176
1177 case DTK_DECADE:
1178 /* see comments in timestamp_part */
1179 if (year >= 0)
1180 intresult = year / 10;
1181 else
1182 intresult = -((8 - (year - 1)) / 10);
1183 break;
1184
1185 case DTK_CENTURY:
1186 /* see comments in timestamp_part */
1187 if (year > 0)
1188 intresult = (year + 99) / 100;
1189 else
1190 intresult = -((99 - (year - 1)) / 100);
1191 break;
1192
1193 case DTK_MILLENNIUM:
1194 /* see comments in timestamp_part */
1195 if (year > 0)
1196 intresult = (year + 999) / 1000;
1197 else
1198 intresult = -((999 - (year - 1)) / 1000);
1199 break;
1200
1201 case DTK_JULIAN:
1203 break;
1204
1205 case DTK_ISOYEAR:
1206 intresult = date2isoyear(year, mon, mday);
1207 /* Adjust BC years */
1208 if (intresult <= 0)
1209 intresult -= 1;
1210 break;
1211
1212 case DTK_DOW:
1213 case DTK_ISODOW:
1215 if (val == DTK_ISODOW && intresult == 0)
1216 intresult = 7;
1217 break;
1218
1219 case DTK_DOY:
1220 intresult = date2j(year, mon, mday) - date2j(year, 1, 1) + 1;
1221 break;
1222
1223 default:
1224 ereport(ERROR,
1226 errmsg("unit \"%s\" not supported for type %s",
1228 intresult = 0;
1229 }
1230 }
1231 else if (type == RESERV)
1232 {
1233 switch (val)
1234 {
1235 case DTK_EPOCH:
1237 break;
1238
1239 default:
1240 ereport(ERROR,
1242 errmsg("unit \"%s\" not supported for type %s",
1244 intresult = 0;
1245 }
1246 }
1247 else
1248 {
1249 ereport(ERROR,
1251 errmsg("unit \"%s\" not recognized for type %s",
1253 intresult = 0;
1254 }
1255
1257}
1258
1259
1260/* Add an interval to a date, giving a new date.
1261 * Must handle both positive and negative intervals.
1262 *
1263 * We implement this by promoting the date to timestamp (without time zone)
1264 * and then using the timestamp plus interval function.
1265 */
1266Datum
1279
1280/* Subtract an interval from a date, giving a new date.
1281 * Must handle both positive and negative intervals.
1282 *
1283 * We implement this by promoting the date to timestamp (without time zone)
1284 * and then using the timestamp minus interval function.
1285 */
1286Datum
1299
1300/* date_timestamp()
1301 * Convert date to timestamp data type.
1302 */
1303Datum
1305{
1308
1309 result = date2timestamp_safe(dateVal, fcinfo->context);
1310 if (SOFT_ERROR_OCCURRED(fcinfo->context))
1312
1314}
1315
1316/* timestamp_date()
1317 * Convert timestamp to date data type.
1318 */
1319Datum
1321{
1324
1325 result = timestamp2date_safe(timestamp, fcinfo->context);
1326 if (SOFT_ERROR_OCCURRED(fcinfo->context))
1328
1330}
1331
1332/*
1333 * Convert timestamp to date.
1334 *
1335 * If the timestamp falls out of the valid range for the date type, error
1336 * handling proceeds based on escontext.
1337 *
1338 * If escontext is NULL, we throw an out-of-range error (hard error).
1339 * If escontext is not NULL, we return NOBEGIN or NOEND for lower bound or
1340 * upper bound overflow, respectively, and record a soft error.
1341 *
1342 * Note: given the ranges of the types, overflow is only possible at
1343 * the lower bound of the range, but we don't assume that in this code.
1344 */
1345DateADT
1347{
1349 struct pg_tm tt,
1350 *tm = &tt;
1351 fsec_t fsec;
1352
1355 else if (TIMESTAMP_IS_NOEND(timestamp))
1357 else
1358 {
1359 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
1360 {
1361 if (timestamp < 0)
1363 else
1364 DATE_NOEND(result); /* not actually reachable */
1365
1366 ereturn(escontext, result,
1368 errmsg("timestamp out of range")));
1369 }
1370
1372 }
1373
1374 return result;
1375}
1376
1377
1378/* date_timestamptz()
1379 * Convert date to timestamp with time zone data type.
1380 */
1381Datum
1383{
1386
1387 result = date2timestamptz_safe(dateVal, fcinfo->context);
1388 if (SOFT_ERROR_OCCURRED(fcinfo->context))
1390
1392}
1393
1394
1395/* timestamptz_date()
1396 * Convert timestamp with time zone to date data type.
1397 */
1398Datum
1400{
1403
1404 result = timestamptz2date_safe(timestamp, fcinfo->context);
1405 if (SOFT_ERROR_OCCURRED(fcinfo->context))
1407
1409}
1410
1411/*
1412 * Convert timestamptz to date.
1413 *
1414 * If the timestamp falls out of the valid range for the date type, error
1415 * handling proceeds based on escontext.
1416 *
1417 * If escontext is NULL, we throw an out-of-range error (hard error).
1418 * If escontext is not NULL, we return NOBEGIN or NOEND for lower bound or
1419 * upper bound overflow, respectively, and record a soft error.
1420 *
1421 * Note: given the ranges of the types, overflow is only possible at
1422 * the lower bound of the range, but we don't assume that in this code.
1423 */
1424DateADT
1426{
1428 struct pg_tm tt,
1429 *tm = &tt;
1430 fsec_t fsec;
1431 int tz;
1432
1435 else if (TIMESTAMP_IS_NOEND(timestamp))
1437 else
1438 {
1439 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
1440 {
1441 if (timestamp < 0)
1443 else
1444 DATE_NOEND(result); /* not actually reachable */
1445
1446 ereturn(escontext, result,
1448 errmsg("timestamp out of range")));
1449 }
1450
1452 }
1453
1454 return result;
1455}
1456
1457
1458/*****************************************************************************
1459 * Time ADT
1460 *****************************************************************************/
1461
1462Datum
1464{
1465 char *str = PG_GETARG_CSTRING(0);
1466#ifdef NOT_USED
1467 Oid typelem = PG_GETARG_OID(1);
1468#endif
1469 int32 typmod = PG_GETARG_INT32(2);
1470 Node *escontext = fcinfo->context;
1472 fsec_t fsec;
1473 struct pg_tm tt,
1474 *tm = &tt;
1475 int tz;
1476 int nf;
1477 int dterr;
1478 char workbuf[MAXDATELEN + 1];
1479 char *field[MAXDATEFIELDS];
1480 int dtype;
1481 int ftype[MAXDATEFIELDS];
1482 DateTimeErrorExtra extra;
1483
1485 field, ftype, MAXDATEFIELDS, &nf);
1486 if (dterr == 0)
1487 dterr = DecodeTimeOnly(field, ftype, nf,
1488 &dtype, tm, &fsec, &tz, &extra);
1489 if (dterr != 0)
1490 {
1491 DateTimeParseError(dterr, &extra, str, "time", escontext);
1493 }
1494
1495 tm2time(tm, fsec, &result);
1496 AdjustTimeForTypmod(&result, typmod);
1497
1499}
1500
1501/* tm2time()
1502 * Convert a tm structure to a time data type.
1503 */
1504int
1506{
1508 * USECS_PER_SEC) + fsec;
1509 return 0;
1510}
1511
1512/* time_overflows()
1513 * Check to see if a broken-down time-of-day is out of range.
1514 */
1515bool
1516time_overflows(int hour, int min, int sec, fsec_t fsec)
1517{
1518 /* Range-check the fields individually. */
1523 return true;
1524
1525 /*
1526 * Because we allow, eg, hour = 24 or sec = 60, we must check separately
1527 * that the total time value doesn't exceed 24:00:00.
1528 */
1529 if ((((((hour * MINS_PER_HOUR + min) * SECS_PER_MINUTE)
1530 + sec) * USECS_PER_SEC) + fsec) > USECS_PER_DAY)
1531 return true;
1532
1533 return false;
1534}
1535
1536/* float_time_overflows()
1537 * Same, when we have seconds + fractional seconds as one "double" value.
1538 */
1539bool
1540float_time_overflows(int hour, int min, double sec)
1541{
1542 /* Range-check the fields individually. */
1545 return true;
1546
1547 /*
1548 * "sec", being double, requires extra care. Cope with NaN, and round off
1549 * before applying the range check to avoid unexpected errors due to
1550 * imprecise input. (We assume rint() behaves sanely with infinities.)
1551 */
1552 if (isnan(sec))
1553 return true;
1554 sec = rint(sec * USECS_PER_SEC);
1556 return true;
1557
1558 /*
1559 * Because we allow, eg, hour = 24 or sec = 60, we must check separately
1560 * that the total time value doesn't exceed 24:00:00. This must match the
1561 * way that callers will convert the fields to a time.
1562 */
1563 if (((((hour * MINS_PER_HOUR + min) * SECS_PER_MINUTE)
1564 * USECS_PER_SEC) + (int64) sec) > USECS_PER_DAY)
1565 return true;
1566
1567 return false;
1568}
1569
1570
1571/* time2tm()
1572 * Convert time data type to POSIX time structure.
1573 *
1574 * Note that only the hour/min/sec/fractional-sec fields are filled in.
1575 */
1576int
1577time2tm(TimeADT time, struct pg_tm *tm, fsec_t *fsec)
1578{
1579 tm->tm_hour = time / USECS_PER_HOUR;
1580 time -= tm->tm_hour * USECS_PER_HOUR;
1581 tm->tm_min = time / USECS_PER_MINUTE;
1582 time -= tm->tm_min * USECS_PER_MINUTE;
1583 tm->tm_sec = time / USECS_PER_SEC;
1584 time -= tm->tm_sec * USECS_PER_SEC;
1585 *fsec = time;
1586 return 0;
1587}
1588
1589Datum
1591{
1592 TimeADT time = PG_GETARG_TIMEADT(0);
1593 char *result;
1594 struct pg_tm tt,
1595 *tm = &tt;
1596 fsec_t fsec;
1597 char buf[MAXDATELEN + 1];
1598
1599 time2tm(time, tm, &fsec);
1600 EncodeTimeOnly(tm, fsec, false, 0, DateStyle, buf);
1601
1602 result = pstrdup(buf);
1604}
1605
1606/*
1607 * time_recv - converts external binary format to time
1608 */
1609Datum
1611{
1613
1614#ifdef NOT_USED
1615 Oid typelem = PG_GETARG_OID(1);
1616#endif
1617 int32 typmod = PG_GETARG_INT32(2);
1619
1621
1622 if (result < INT64CONST(0) || result > USECS_PER_DAY)
1623 ereport(ERROR,
1625 errmsg("time out of range")));
1626
1627 AdjustTimeForTypmod(&result, typmod);
1628
1630}
1631
1632/*
1633 * time_send - converts time to binary format
1634 */
1635Datum
1645
1646Datum
1653
1654Datum
1656{
1657 int32 typmod = PG_GETARG_INT32(0);
1658
1659 PG_RETURN_CSTRING(anytime_typmodout(false, typmod));
1660}
1661
1662/*
1663 * make_time - time constructor
1664 */
1665Datum
1667{
1668 int tm_hour = PG_GETARG_INT32(0);
1669 int tm_min = PG_GETARG_INT32(1);
1670 double sec = PG_GETARG_FLOAT8(2);
1671 TimeADT time;
1672
1673 /* Check for time overflow */
1675 ereport(ERROR,
1677 errmsg("time field value out of range: %d:%02d:%02g",
1678 tm_hour, tm_min, sec)));
1679
1680 /* This should match tm2time */
1682 * USECS_PER_SEC) + (int64) rint(sec * USECS_PER_SEC);
1683
1684 PG_RETURN_TIMEADT(time);
1685}
1686
1687
1688/* time_support()
1689 *
1690 * Planner support function for the time_scale() and timetz_scale()
1691 * length coercion functions (we need not distinguish them here).
1692 */
1693Datum
1695{
1697 Node *ret = NULL;
1698
1700 {
1702
1703 ret = TemporalSimplify(MAX_TIME_PRECISION, (Node *) req->fcall);
1704 }
1705
1706 PG_RETURN_POINTER(ret);
1707}
1708
1709/* time_scale()
1710 * Adjust time type for specified scale factor.
1711 * Used by PostgreSQL type system to stuff columns.
1712 */
1713Datum
1715{
1716 TimeADT time = PG_GETARG_TIMEADT(0);
1717 int32 typmod = PG_GETARG_INT32(1);
1719
1720 result = time;
1721 AdjustTimeForTypmod(&result, typmod);
1722
1724}
1725
1726/* AdjustTimeForTypmod()
1727 * Force the precision of the time value to a specified value.
1728 * Uses *exactly* the same code as in AdjustTimestampForTypmod()
1729 * but we make a separate copy because those types do not
1730 * have a fundamental tie together but rather a coincidence of
1731 * implementation. - thomas
1732 */
1733void
1735{
1736 static const int64 TimeScales[MAX_TIME_PRECISION + 1] = {
1737 INT64CONST(1000000),
1738 INT64CONST(100000),
1739 INT64CONST(10000),
1740 INT64CONST(1000),
1741 INT64CONST(100),
1742 INT64CONST(10),
1743 INT64CONST(1)
1744 };
1745
1746 static const int64 TimeOffsets[MAX_TIME_PRECISION + 1] = {
1747 INT64CONST(500000),
1748 INT64CONST(50000),
1749 INT64CONST(5000),
1750 INT64CONST(500),
1751 INT64CONST(50),
1752 INT64CONST(5),
1753 INT64CONST(0)
1754 };
1755
1756 if (typmod >= 0 && typmod <= MAX_TIME_PRECISION)
1757 {
1758 if (*time >= INT64CONST(0))
1759 *time = ((*time + TimeOffsets[typmod]) / TimeScales[typmod]) *
1760 TimeScales[typmod];
1761 else
1762 *time = -((((-*time) + TimeOffsets[typmod]) / TimeScales[typmod]) *
1763 TimeScales[typmod]);
1764 }
1765}
1766
1767
1768Datum
1776
1777Datum
1785
1786Datum
1794
1795Datum
1803
1804Datum
1812
1813Datum
1821
1822Datum
1824{
1827
1828 if (time1 < time2)
1829 PG_RETURN_INT32(-1);
1830 if (time1 > time2)
1831 PG_RETURN_INT32(1);
1832 PG_RETURN_INT32(0);
1833}
1834
1835Datum
1837{
1838 return hashint8(fcinfo);
1839}
1840
1841Datum
1843{
1844 return hashint8extended(fcinfo);
1845}
1846
1847Datum
1855
1856Datum
1864
1865/* overlaps_time() --- implements the SQL OVERLAPS operator.
1866 *
1867 * Algorithm is per SQL spec. This is much harder than you'd think
1868 * because the spec requires us to deliver a non-null answer in some cases
1869 * where some of the inputs are null.
1870 */
1871Datum
1873{
1874 /*
1875 * The arguments are TimeADT, but we leave them as generic Datums to avoid
1876 * dereferencing nulls (TimeADT is pass-by-reference!)
1877 */
1882 bool ts1IsNull = PG_ARGISNULL(0);
1883 bool te1IsNull = PG_ARGISNULL(1);
1884 bool ts2IsNull = PG_ARGISNULL(2);
1885 bool te2IsNull = PG_ARGISNULL(3);
1886
1887#define TIMEADT_GT(t1,t2) \
1888 (DatumGetTimeADT(t1) > DatumGetTimeADT(t2))
1889#define TIMEADT_LT(t1,t2) \
1890 (DatumGetTimeADT(t1) < DatumGetTimeADT(t2))
1891
1892 /*
1893 * If both endpoints of interval 1 are null, the result is null (unknown).
1894 * If just one endpoint is null, take ts1 as the non-null one. Otherwise,
1895 * take ts1 as the lesser endpoint.
1896 */
1897 if (ts1IsNull)
1898 {
1899 if (te1IsNull)
1901 /* swap null for non-null */
1902 ts1 = te1;
1903 te1IsNull = true;
1904 }
1905 else if (!te1IsNull)
1906 {
1907 if (TIMEADT_GT(ts1, te1))
1908 {
1909 Datum tt = ts1;
1910
1911 ts1 = te1;
1912 te1 = tt;
1913 }
1914 }
1915
1916 /* Likewise for interval 2. */
1917 if (ts2IsNull)
1918 {
1919 if (te2IsNull)
1921 /* swap null for non-null */
1922 ts2 = te2;
1923 te2IsNull = true;
1924 }
1925 else if (!te2IsNull)
1926 {
1927 if (TIMEADT_GT(ts2, te2))
1928 {
1929 Datum tt = ts2;
1930
1931 ts2 = te2;
1932 te2 = tt;
1933 }
1934 }
1935
1936 /*
1937 * At this point neither ts1 nor ts2 is null, so we can consider three
1938 * cases: ts1 > ts2, ts1 < ts2, ts1 = ts2
1939 */
1940 if (TIMEADT_GT(ts1, ts2))
1941 {
1942 /*
1943 * This case is ts1 < te2 OR te1 < te2, which may look redundant but
1944 * in the presence of nulls it's not quite completely so.
1945 */
1946 if (te2IsNull)
1948 if (TIMEADT_LT(ts1, te2))
1949 PG_RETURN_BOOL(true);
1950 if (te1IsNull)
1952
1953 /*
1954 * If te1 is not null then we had ts1 <= te1 above, and we just found
1955 * ts1 >= te2, hence te1 >= te2.
1956 */
1957 PG_RETURN_BOOL(false);
1958 }
1959 else if (TIMEADT_LT(ts1, ts2))
1960 {
1961 /* This case is ts2 < te1 OR te2 < te1 */
1962 if (te1IsNull)
1964 if (TIMEADT_LT(ts2, te1))
1965 PG_RETURN_BOOL(true);
1966 if (te2IsNull)
1968
1969 /*
1970 * If te2 is not null then we had ts2 <= te2 above, and we just found
1971 * ts2 >= te1, hence te2 >= te1.
1972 */
1973 PG_RETURN_BOOL(false);
1974 }
1975 else
1976 {
1977 /*
1978 * For ts1 = ts2 the spec says te1 <> te2 OR te1 = te2, which is a
1979 * rather silly way of saying "true if both are nonnull, else null".
1980 */
1981 if (te1IsNull || te2IsNull)
1983 PG_RETURN_BOOL(true);
1984 }
1985
1986#undef TIMEADT_GT
1987#undef TIMEADT_LT
1988}
1989
1990/* timestamp_time()
1991 * Convert timestamp to time data type.
1992 */
1993Datum
1995{
1998 struct pg_tm tt,
1999 *tm = &tt;
2000 fsec_t fsec;
2001
2004
2005 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
2006 ereturn(fcinfo->context, (Datum) 0,
2008 errmsg("timestamp out of range")));
2009
2010 /*
2011 * Could also do this with time = (timestamp / USECS_PER_DAY *
2012 * USECS_PER_DAY) - timestamp;
2013 */
2015 USECS_PER_SEC) + fsec;
2016
2018}
2019
2020/* timestamptz_time()
2021 * Convert timestamptz to time data type.
2022 */
2023Datum
2025{
2028 struct pg_tm tt,
2029 *tm = &tt;
2030 int tz;
2031 fsec_t fsec;
2032
2035
2036 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
2037 ereturn(fcinfo->context, (Datum) 0,
2039 errmsg("timestamp out of range")));
2040
2041 /*
2042 * Could also do this with time = (timestamp / USECS_PER_DAY *
2043 * USECS_PER_DAY) - timestamp;
2044 */
2046 USECS_PER_SEC) + fsec;
2047
2049}
2050
2051/* datetime_timestamp()
2052 * Convert date and time to timestamp data type.
2053 */
2054Datum
2056{
2058 TimeADT time = PG_GETARG_TIMEADT(1);
2060
2063 {
2064 result += time;
2066 ereport(ERROR,
2068 errmsg("timestamp out of range")));
2069 }
2070
2072}
2073
2074/* time_interval()
2075 * Convert time to interval data type.
2076 */
2077Datum
2079{
2080 TimeADT time = PG_GETARG_TIMEADT(0);
2082
2084
2085 result->time = time;
2086 result->day = 0;
2087 result->month = 0;
2088
2090}
2091
2092/* interval_time()
2093 * Convert interval to time data type.
2094 *
2095 * This is defined as producing the fractional-day portion of the interval.
2096 * Therefore, we can just ignore the months field. It is not real clear
2097 * what to do with negative intervals, but we choose to subtract the floor,
2098 * so that, say, '-2 hours' becomes '22:00:00'.
2099 */
2100Datum
2102{
2105
2107 ereturn(fcinfo->context, (Datum) 0,
2109 errmsg("cannot convert infinite interval to time")));
2110
2111 result = span->time % USECS_PER_DAY;
2112 if (result < 0)
2114
2116}
2117
2118/* time_mi_time()
2119 * Subtract two times to produce an interval.
2120 */
2121Datum
2123{
2127
2129
2130 result->month = 0;
2131 result->day = 0;
2132 result->time = time1 - time2;
2133
2135}
2136
2137/* time_pl_interval()
2138 * Add interval to time.
2139 */
2140Datum
2142{
2143 TimeADT time = PG_GETARG_TIMEADT(0);
2146
2148 ereport(ERROR,
2150 errmsg("cannot add infinite interval to time")));
2151
2152 result = time + span->time;
2154 if (result < INT64CONST(0))
2156
2158}
2159
2160/* time_mi_interval()
2161 * Subtract interval from time.
2162 */
2163Datum
2165{
2166 TimeADT time = PG_GETARG_TIMEADT(0);
2169
2171 ereport(ERROR,
2173 errmsg("cannot subtract infinite interval from time")));
2174
2175 result = time - span->time;
2177 if (result < INT64CONST(0))
2179
2181}
2182
2183/*
2184 * in_range support function for time.
2185 */
2186Datum
2188{
2190 TimeADT base = PG_GETARG_TIMEADT(1);
2191 Interval *offset = PG_GETARG_INTERVAL_P(2);
2192 bool sub = PG_GETARG_BOOL(3);
2193 bool less = PG_GETARG_BOOL(4);
2194 TimeADT sum;
2195
2196 /*
2197 * Like time_pl_interval/time_mi_interval, we disregard the month and day
2198 * fields of the offset. So our test for negative should too. This also
2199 * catches -infinity, so we only need worry about +infinity below.
2200 */
2201 if (offset->time < 0)
2202 ereport(ERROR,
2204 errmsg("invalid preceding or following size in window function")));
2205
2206 /*
2207 * We can't use time_pl_interval/time_mi_interval here, because their
2208 * wraparound behavior would give wrong (or at least undesirable) answers.
2209 * Fortunately the equivalent non-wrapping behavior is trivial, except
2210 * that adding an infinite (or very large) interval might cause integer
2211 * overflow. Subtraction cannot overflow here.
2212 */
2213 if (sub)
2214 sum = base - offset->time;
2215 else if (pg_add_s64_overflow(base, offset->time, &sum))
2217
2218 if (less)
2219 PG_RETURN_BOOL(val <= sum);
2220 else
2221 PG_RETURN_BOOL(val >= sum);
2222}
2223
2224
2225/* time_part() and extract_time()
2226 * Extract specified field from time type.
2227 */
2228static Datum
2230{
2232 TimeADT time = PG_GETARG_TIMEADT(1);
2234 int type,
2235 val;
2236 char *lowunits;
2237
2240 false);
2241
2242 type = DecodeUnits(0, lowunits, &val);
2243 if (type == UNKNOWN_FIELD)
2245
2246 if (type == UNITS)
2247 {
2248 fsec_t fsec;
2249 struct pg_tm tt,
2250 *tm = &tt;
2251
2252 time2tm(time, tm, &fsec);
2253
2254 switch (val)
2255 {
2256 case DTK_MICROSEC:
2257 intresult = tm->tm_sec * INT64CONST(1000000) + fsec;
2258 break;
2259
2260 case DTK_MILLISEC:
2261 if (retnumeric)
2262 /*---
2263 * tm->tm_sec * 1000 + fsec / 1000
2264 * = (tm->tm_sec * 1'000'000 + fsec) / 1000
2265 */
2267 else
2268 PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + fsec / 1000.0);
2269 break;
2270
2271 case DTK_SECOND:
2272 if (retnumeric)
2273 /*---
2274 * tm->tm_sec + fsec / 1'000'000
2275 * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
2276 */
2278 else
2279 PG_RETURN_FLOAT8(tm->tm_sec + fsec / 1000000.0);
2280 break;
2281
2282 case DTK_MINUTE:
2283 intresult = tm->tm_min;
2284 break;
2285
2286 case DTK_HOUR:
2287 intresult = tm->tm_hour;
2288 break;
2289
2290 case DTK_TZ:
2291 case DTK_TZ_MINUTE:
2292 case DTK_TZ_HOUR:
2293 case DTK_DAY:
2294 case DTK_MONTH:
2295 case DTK_QUARTER:
2296 case DTK_YEAR:
2297 case DTK_DECADE:
2298 case DTK_CENTURY:
2299 case DTK_MILLENNIUM:
2300 case DTK_ISOYEAR:
2301 default:
2302 ereport(ERROR,
2304 errmsg("unit \"%s\" not supported for type %s",
2306 intresult = 0;
2307 }
2308 }
2309 else if (type == RESERV && val == DTK_EPOCH)
2310 {
2311 if (retnumeric)
2313 else
2314 PG_RETURN_FLOAT8(time / 1000000.0);
2315 }
2316 else
2317 {
2318 ereport(ERROR,
2320 errmsg("unit \"%s\" not recognized for type %s",
2322 intresult = 0;
2323 }
2324
2325 if (retnumeric)
2327 else
2329}
2330
2331Datum
2333{
2334 return time_part_common(fcinfo, false);
2335}
2336
2337Datum
2339{
2340 return time_part_common(fcinfo, true);
2341}
2342
2343
2344/*****************************************************************************
2345 * Time With Time Zone ADT
2346 *****************************************************************************/
2347
2348/* tm2timetz()
2349 * Convert a tm structure to a time data type.
2350 */
2351int
2352tm2timetz(struct pg_tm *tm, fsec_t fsec, int tz, TimeTzADT *result)
2353{
2354 result->time = ((((tm->tm_hour * MINS_PER_HOUR + tm->tm_min) * SECS_PER_MINUTE) + tm->tm_sec) *
2355 USECS_PER_SEC) + fsec;
2356 result->zone = tz;
2357
2358 return 0;
2359}
2360
2361Datum
2363{
2364 char *str = PG_GETARG_CSTRING(0);
2365#ifdef NOT_USED
2366 Oid typelem = PG_GETARG_OID(1);
2367#endif
2368 int32 typmod = PG_GETARG_INT32(2);
2369 Node *escontext = fcinfo->context;
2371 fsec_t fsec;
2372 struct pg_tm tt,
2373 *tm = &tt;
2374 int tz;
2375 int nf;
2376 int dterr;
2377 char workbuf[MAXDATELEN + 1];
2378 char *field[MAXDATEFIELDS];
2379 int dtype;
2380 int ftype[MAXDATEFIELDS];
2381 DateTimeErrorExtra extra;
2382
2384 field, ftype, MAXDATEFIELDS, &nf);
2385 if (dterr == 0)
2386 dterr = DecodeTimeOnly(field, ftype, nf,
2387 &dtype, tm, &fsec, &tz, &extra);
2388 if (dterr != 0)
2389 {
2390 DateTimeParseError(dterr, &extra, str, "time with time zone",
2391 escontext);
2393 }
2394
2396 tm2timetz(tm, fsec, tz, result);
2397 AdjustTimeForTypmod(&(result->time), typmod);
2398
2400}
2401
2402Datum
2404{
2406 char *result;
2407 struct pg_tm tt,
2408 *tm = &tt;
2409 fsec_t fsec;
2410 int tz;
2411 char buf[MAXDATELEN + 1];
2412
2413 timetz2tm(time, tm, &fsec, &tz);
2414 EncodeTimeOnly(tm, fsec, true, tz, DateStyle, buf);
2415
2416 result = pstrdup(buf);
2418}
2419
2420/*
2421 * timetz_recv - converts external binary format to timetz
2422 */
2423Datum
2425{
2427
2428#ifdef NOT_USED
2429 Oid typelem = PG_GETARG_OID(1);
2430#endif
2431 int32 typmod = PG_GETARG_INT32(2);
2433
2435
2436 result->time = pq_getmsgint64(buf);
2437
2438 if (result->time < INT64CONST(0) || result->time > USECS_PER_DAY)
2439 ereport(ERROR,
2441 errmsg("time out of range")));
2442
2443 result->zone = pq_getmsgint(buf, sizeof(result->zone));
2444
2445 /* Check for sane GMT displacement; see notes in datatype/timestamp.h */
2446 if (result->zone <= -TZDISP_LIMIT || result->zone >= TZDISP_LIMIT)
2447 ereport(ERROR,
2449 errmsg("time zone displacement out of range")));
2450
2451 AdjustTimeForTypmod(&(result->time), typmod);
2452
2454}
2455
2456/*
2457 * timetz_send - converts timetz to binary format
2458 */
2459Datum
2470
2471Datum
2478
2479Datum
2481{
2482 int32 typmod = PG_GETARG_INT32(0);
2483
2484 PG_RETURN_CSTRING(anytime_typmodout(true, typmod));
2485}
2486
2487
2488/* timetz2tm()
2489 * Convert TIME WITH TIME ZONE data type to POSIX time structure.
2490 */
2491int
2492timetz2tm(TimeTzADT *time, struct pg_tm *tm, fsec_t *fsec, int *tzp)
2493{
2494 TimeOffset trem = time->time;
2495
2501 *fsec = trem - tm->tm_sec * USECS_PER_SEC;
2502
2503 if (tzp != NULL)
2504 *tzp = time->zone;
2505
2506 return 0;
2507}
2508
2509/* timetz_scale()
2510 * Adjust time type for specified scale factor.
2511 * Used by PostgreSQL type system to stuff columns.
2512 */
2513Datum
2515{
2517 int32 typmod = PG_GETARG_INT32(1);
2519
2521
2522 result->time = time->time;
2523 result->zone = time->zone;
2524
2525 AdjustTimeForTypmod(&(result->time), typmod);
2526
2528}
2529
2530
2531static int
2533{
2534 TimeOffset t1,
2535 t2;
2536
2537 /* Primary sort is by true (GMT-equivalent) time */
2538 t1 = time1->time + (time1->zone * USECS_PER_SEC);
2539 t2 = time2->time + (time2->zone * USECS_PER_SEC);
2540
2541 if (t1 > t2)
2542 return 1;
2543 if (t1 < t2)
2544 return -1;
2545
2546 /*
2547 * If same GMT time, sort by timezone; we only want to say that two
2548 * timetz's are equal if both the time and zone parts are equal.
2549 */
2550 if (time1->zone > time2->zone)
2551 return 1;
2552 if (time1->zone < time2->zone)
2553 return -1;
2554
2555 return 0;
2556}
2557
2558Datum
2566
2567Datum
2575
2576Datum
2584
2585Datum
2593
2594Datum
2602
2603Datum
2611
2612Datum
2620
2621Datum
2623{
2625 uint32 thash;
2626
2627 /*
2628 * To avoid any problems with padding bytes in the struct, we figure the
2629 * field hashes separately and XOR them.
2630 */
2632 Int64GetDatumFast(key->time)));
2633 thash ^= DatumGetUInt32(hash_uint32(key->zone));
2635}
2636
2637Datum
2639{
2641 Datum seed = PG_GETARG_DATUM(1);
2642 uint64 thash;
2643
2644 /* Same approach as timetz_hash */
2646 Int64GetDatumFast(key->time),
2647 seed));
2649 DatumGetInt64(seed)));
2651}
2652
2653Datum
2666
2667Datum
2680
2681/* timetz_pl_interval()
2682 * Add interval to timetz.
2683 */
2684Datum
2686{
2690
2692 ereport(ERROR,
2694 errmsg("cannot add infinite interval to time")));
2695
2697
2698 result->time = time->time + span->time;
2699 result->time -= result->time / USECS_PER_DAY * USECS_PER_DAY;
2700 if (result->time < INT64CONST(0))
2701 result->time += USECS_PER_DAY;
2702
2703 result->zone = time->zone;
2704
2706}
2707
2708/* timetz_mi_interval()
2709 * Subtract interval from timetz.
2710 */
2711Datum
2713{
2717
2719 ereport(ERROR,
2721 errmsg("cannot subtract infinite interval from time")));
2722
2724
2725 result->time = time->time - span->time;
2726 result->time -= result->time / USECS_PER_DAY * USECS_PER_DAY;
2727 if (result->time < INT64CONST(0))
2728 result->time += USECS_PER_DAY;
2729
2730 result->zone = time->zone;
2731
2733}
2734
2735/*
2736 * in_range support function for timetz.
2737 */
2738Datum
2740{
2743 Interval *offset = PG_GETARG_INTERVAL_P(2);
2744 bool sub = PG_GETARG_BOOL(3);
2745 bool less = PG_GETARG_BOOL(4);
2746 TimeTzADT sum;
2747
2748 /*
2749 * Like timetz_pl_interval/timetz_mi_interval, we disregard the month and
2750 * day fields of the offset. So our test for negative should too. This
2751 * also catches -infinity, so we only need worry about +infinity below.
2752 */
2753 if (offset->time < 0)
2754 ereport(ERROR,
2756 errmsg("invalid preceding or following size in window function")));
2757
2758 /*
2759 * We can't use timetz_pl_interval/timetz_mi_interval here, because their
2760 * wraparound behavior would give wrong (or at least undesirable) answers.
2761 * Fortunately the equivalent non-wrapping behavior is trivial, except
2762 * that adding an infinite (or very large) interval might cause integer
2763 * overflow. Subtraction cannot overflow here.
2764 */
2765 if (sub)
2766 sum.time = base->time - offset->time;
2767 else if (pg_add_s64_overflow(base->time, offset->time, &sum.time))
2769 sum.zone = base->zone;
2770
2771 if (less)
2773 else
2775}
2776
2777/* overlaps_timetz() --- implements the SQL OVERLAPS operator.
2778 *
2779 * Algorithm is per SQL spec. This is much harder than you'd think
2780 * because the spec requires us to deliver a non-null answer in some cases
2781 * where some of the inputs are null.
2782 */
2783Datum
2785{
2786 /*
2787 * The arguments are TimeTzADT *, but we leave them as generic Datums for
2788 * convenience of notation --- and to avoid dereferencing nulls.
2789 */
2794 bool ts1IsNull = PG_ARGISNULL(0);
2795 bool te1IsNull = PG_ARGISNULL(1);
2796 bool ts2IsNull = PG_ARGISNULL(2);
2797 bool te2IsNull = PG_ARGISNULL(3);
2798
2799#define TIMETZ_GT(t1,t2) \
2800 DatumGetBool(DirectFunctionCall2(timetz_gt,t1,t2))
2801#define TIMETZ_LT(t1,t2) \
2802 DatumGetBool(DirectFunctionCall2(timetz_lt,t1,t2))
2803
2804 /*
2805 * If both endpoints of interval 1 are null, the result is null (unknown).
2806 * If just one endpoint is null, take ts1 as the non-null one. Otherwise,
2807 * take ts1 as the lesser endpoint.
2808 */
2809 if (ts1IsNull)
2810 {
2811 if (te1IsNull)
2813 /* swap null for non-null */
2814 ts1 = te1;
2815 te1IsNull = true;
2816 }
2817 else if (!te1IsNull)
2818 {
2819 if (TIMETZ_GT(ts1, te1))
2820 {
2821 Datum tt = ts1;
2822
2823 ts1 = te1;
2824 te1 = tt;
2825 }
2826 }
2827
2828 /* Likewise for interval 2. */
2829 if (ts2IsNull)
2830 {
2831 if (te2IsNull)
2833 /* swap null for non-null */
2834 ts2 = te2;
2835 te2IsNull = true;
2836 }
2837 else if (!te2IsNull)
2838 {
2839 if (TIMETZ_GT(ts2, te2))
2840 {
2841 Datum tt = ts2;
2842
2843 ts2 = te2;
2844 te2 = tt;
2845 }
2846 }
2847
2848 /*
2849 * At this point neither ts1 nor ts2 is null, so we can consider three
2850 * cases: ts1 > ts2, ts1 < ts2, ts1 = ts2
2851 */
2852 if (TIMETZ_GT(ts1, ts2))
2853 {
2854 /*
2855 * This case is ts1 < te2 OR te1 < te2, which may look redundant but
2856 * in the presence of nulls it's not quite completely so.
2857 */
2858 if (te2IsNull)
2860 if (TIMETZ_LT(ts1, te2))
2861 PG_RETURN_BOOL(true);
2862 if (te1IsNull)
2864
2865 /*
2866 * If te1 is not null then we had ts1 <= te1 above, and we just found
2867 * ts1 >= te2, hence te1 >= te2.
2868 */
2869 PG_RETURN_BOOL(false);
2870 }
2871 else if (TIMETZ_LT(ts1, ts2))
2872 {
2873 /* This case is ts2 < te1 OR te2 < te1 */
2874 if (te1IsNull)
2876 if (TIMETZ_LT(ts2, te1))
2877 PG_RETURN_BOOL(true);
2878 if (te2IsNull)
2880
2881 /*
2882 * If te2 is not null then we had ts2 <= te2 above, and we just found
2883 * ts2 >= te1, hence te2 >= te1.
2884 */
2885 PG_RETURN_BOOL(false);
2886 }
2887 else
2888 {
2889 /*
2890 * For ts1 = ts2 the spec says te1 <> te2 OR te1 = te2, which is a
2891 * rather silly way of saying "true if both are nonnull, else null".
2892 */
2893 if (te1IsNull || te2IsNull)
2895 PG_RETURN_BOOL(true);
2896 }
2897
2898#undef TIMETZ_GT
2899#undef TIMETZ_LT
2900}
2901
2902
2903Datum
2905{
2908
2909 /* swallow the time zone and just return the time */
2910 result = timetz->time;
2911
2913}
2914
2915
2916Datum
2918{
2919 TimeADT time = PG_GETARG_TIMEADT(0);
2921 struct pg_tm tt,
2922 *tm = &tt;
2923 fsec_t fsec;
2924 int tz;
2925
2927 time2tm(time, tm, &fsec);
2929
2931
2932 result->time = time;
2933 result->zone = tz;
2934
2936}
2937
2938
2939/* timestamptz_timetz()
2940 * Convert timestamp to timetz data type.
2941 */
2942Datum
2944{
2947 struct pg_tm tt,
2948 *tm = &tt;
2949 int tz;
2950 fsec_t fsec;
2951
2954
2955 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
2956 ereturn(fcinfo->context, (Datum) 0,
2958 errmsg("timestamp out of range")));
2959
2961
2962 tm2timetz(tm, fsec, tz, result);
2963
2965}
2966
2967
2968/* datetimetz_timestamptz()
2969 * Convert date and timetz to timestamp with time zone data type.
2970 * Timestamp is stored in GMT, so add the time zone
2971 * stored with the timetz to the result.
2972 * - thomas 2000-03-10
2973 */
2974Datum
2976{
2980
2981 if (DATE_IS_NOBEGIN(date))
2983 else if (DATE_IS_NOEND(date))
2985 else
2986 {
2987 /*
2988 * Date's range is wider than timestamp's, so check for boundaries.
2989 * Since dates have the same minimum values as timestamps, only upper
2990 * boundary need be checked for overflow.
2991 */
2993 ereport(ERROR,
2995 errmsg("date out of range for timestamp")));
2996 result = date * USECS_PER_DAY + time->time + time->zone * USECS_PER_SEC;
2997
2998 /*
2999 * Since it is possible to go beyond allowed timestamptz range because
3000 * of time zone, check for allowed timestamp range after adding tz.
3001 */
3003 ereport(ERROR,
3005 errmsg("date out of range for timestamp")));
3006 }
3007
3009}
3010
3011
3012/* timetz_part() and extract_timetz()
3013 * Extract specified field from time type.
3014 */
3015static Datum
3017{
3021 int type,
3022 val;
3023 char *lowunits;
3024
3027 false);
3028
3029 type = DecodeUnits(0, lowunits, &val);
3030 if (type == UNKNOWN_FIELD)
3032
3033 if (type == UNITS)
3034 {
3035 int tz;
3036 fsec_t fsec;
3037 struct pg_tm tt,
3038 *tm = &tt;
3039
3040 timetz2tm(time, tm, &fsec, &tz);
3041
3042 switch (val)
3043 {
3044 case DTK_TZ:
3045 intresult = -tz;
3046 break;
3047
3048 case DTK_TZ_MINUTE:
3050 break;
3051
3052 case DTK_TZ_HOUR:
3053 intresult = -tz / SECS_PER_HOUR;
3054 break;
3055
3056 case DTK_MICROSEC:
3057 intresult = tm->tm_sec * INT64CONST(1000000) + fsec;
3058 break;
3059
3060 case DTK_MILLISEC:
3061 if (retnumeric)
3062 /*---
3063 * tm->tm_sec * 1000 + fsec / 1000
3064 * = (tm->tm_sec * 1'000'000 + fsec) / 1000
3065 */
3067 else
3068 PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + fsec / 1000.0);
3069 break;
3070
3071 case DTK_SECOND:
3072 if (retnumeric)
3073 /*---
3074 * tm->tm_sec + fsec / 1'000'000
3075 * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
3076 */
3078 else
3079 PG_RETURN_FLOAT8(tm->tm_sec + fsec / 1000000.0);
3080 break;
3081
3082 case DTK_MINUTE:
3083 intresult = tm->tm_min;
3084 break;
3085
3086 case DTK_HOUR:
3087 intresult = tm->tm_hour;
3088 break;
3089
3090 case DTK_DAY:
3091 case DTK_MONTH:
3092 case DTK_QUARTER:
3093 case DTK_YEAR:
3094 case DTK_DECADE:
3095 case DTK_CENTURY:
3096 case DTK_MILLENNIUM:
3097 default:
3098 ereport(ERROR,
3100 errmsg("unit \"%s\" not supported for type %s",
3102 intresult = 0;
3103 }
3104 }
3105 else if (type == RESERV && val == DTK_EPOCH)
3106 {
3107 if (retnumeric)
3108 /*---
3109 * time->time / 1'000'000 + time->zone
3110 * = (time->time + time->zone * 1'000'000) / 1'000'000
3111 */
3112 PG_RETURN_NUMERIC(int64_div_fast_to_numeric(time->time + time->zone * INT64CONST(1000000), 6));
3113 else
3114 PG_RETURN_FLOAT8(time->time / 1000000.0 + time->zone);
3115 }
3116 else
3117 {
3118 ereport(ERROR,
3120 errmsg("unit \"%s\" not recognized for type %s",
3122 intresult = 0;
3123 }
3124
3125 if (retnumeric)
3127 else
3129}
3130
3131
3132Datum
3134{
3135 return timetz_part_common(fcinfo, false);
3136}
3137
3138Datum
3140{
3141 return timetz_part_common(fcinfo, true);
3142}
3143
3144/* timetz_zone()
3145 * Encode time with time zone type with specified time zone.
3146 * Applies DST rules as of the transaction start time.
3147 */
3148Datum
3150{
3154 int tz;
3155 char tzname[TZ_STRLEN_MAX + 1];
3156 int type,
3157 val;
3158 pg_tz *tzp;
3159
3160 /*
3161 * Look up the requested timezone.
3162 */
3164
3165 type = DecodeTimezoneName(tzname, &val, &tzp);
3166
3168 {
3169 /* fixed-offset abbreviation */
3170 tz = -val;
3171 }
3172 else if (type == TZNAME_DYNTZ)
3173 {
3174 /* dynamic-offset abbreviation, resolve using transaction start time */
3176 int isdst;
3177
3179 }
3180 else
3181 {
3182 /* Get the offset-from-GMT that is valid now for the zone name */
3184 struct pg_tm tm;
3185 fsec_t fsec;
3186
3187 if (timestamp2tm(now, &tz, &tm, &fsec, NULL, tzp) != 0)
3188 ereport(ERROR,
3190 errmsg("timestamp out of range")));
3191 }
3192
3194
3195 result->time = t->time + (t->zone - tz) * USECS_PER_SEC;
3196 /* C99 modulo has the wrong sign convention for negative input */
3197 while (result->time < INT64CONST(0))
3198 result->time += USECS_PER_DAY;
3199 if (result->time >= USECS_PER_DAY)
3200 result->time %= USECS_PER_DAY;
3201
3202 result->zone = tz;
3203
3205}
3206
3207/* timetz_izone()
3208 * Encode time with time zone type with specified time interval as time zone.
3209 */
3210Datum
3212{
3216 int tz;
3217
3219 ereport(ERROR,
3221 errmsg("interval time zone \"%s\" must be finite",
3223 PointerGetDatum(zone))))));
3224
3225 if (zone->month != 0 || zone->day != 0)
3226 ereport(ERROR,
3228 errmsg("interval time zone \"%s\" must not include months or days",
3230 PointerGetDatum(zone))))));
3231
3232 tz = -(zone->time / USECS_PER_SEC);
3233
3235
3236 result->time = time->time + (time->zone - tz) * USECS_PER_SEC;
3237 /* C99 modulo has the wrong sign convention for negative input */
3238 while (result->time < INT64CONST(0))
3239 result->time += USECS_PER_DAY;
3240 if (result->time >= USECS_PER_DAY)
3241 result->time %= USECS_PER_DAY;
3242
3243 result->zone = tz;
3244
3246}
3247
3248/* timetz_at_local()
3249 *
3250 * Unlike for timestamp[tz]_at_local, the type for timetz does not flip between
3251 * time with/without time zone, so we cannot just call the conversion function.
3252 */
3253Datum
#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:4963
int DetermineTimeZoneAbbrevOffsetTS(TimestampTz ts, const char *abbr, pg_tz *tzp, int *isdst)
Definition datetime.c:1804
int DecodeUnits(int field, const char *lowtoken, int *val)
Definition datetime.c:4170
int DecodeTimeOnly(char **field, int *ftype, int nf, int *dtype, struct pg_tm *tm, fsec_t *fsec, int *tzp, DateTimeErrorExtra *extra)
Definition datetime.c:1918
int j2day(int date)
Definition datetime.c:355
int ParseDateTime(const char *timestr, char *workbuf, size_t buflen, char **field, int *ftype, int maxfields, int *numfields)
Definition datetime.c:774
int DetermineTimeZoneOffset(struct pg_tm *tm, pg_tz *tzp)
Definition datetime.c:1605
void DateTimeParseError(int dterr, DateTimeErrorExtra *extra, const char *str, const char *datatype, Node *escontext)
Definition datetime.c:4215
void EncodeTimeOnly(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, int style, char *str)
Definition datetime.c:4435
int ValidateDate(int fmask, bool isjulian, bool is2digits, bool bc, struct pg_tm *tm)
Definition datetime.c:2562
int DecodeSpecial(int field, const char *lowtoken, int *val)
Definition datetime.c:3247
void j2date(int jd, int *year, int *month, int *day)
Definition datetime.c:322
void GetCurrentDateTime(struct pg_tm *tm)
Definition datetime.c:377
void EncodeDateOnly(struct pg_tm *tm, int style, char *str)
Definition datetime.c:4350
int DecodeDateTime(char **field, int *ftype, int nf, int *dtype, struct pg_tm *tm, fsec_t *fsec, int *tzp, DateTimeErrorExtra *extra)
Definition datetime.c:998
int date2j(int year, int month, int day)
Definition datetime.c:297
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:3289
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:966
int timestamp_cmp_internal(Timestamp dt1, Timestamp dt2)
Definition timestamp.c:2204
Datum in_range_timestamp_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3870
void GetEpochTime(struct pg_tm *tm)
Definition timestamp.c:2162
Datum timestamp_pl_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3084
int date2isoweek(int year, int mon, int mday)
Definition timestamp.c:5289
Datum timestamp_mi_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3201
int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
Definition timestamp.c:1904
Datum now(PG_FUNCTION_ARGS)
Definition timestamp.c:1603
int date2isoyear(int year, int mon, int mday)
Definition timestamp.c:5344
#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:928
int32 date_cmp_timestamp_internal(DateADT dateVal, Timestamp dt2)
Definition date.c:759
Datum date_send(PG_FUNCTION_ARGS)
Definition date.c:225
Datum timetz_izone(PG_FUNCTION_ARGS)
Definition date.c:3211
Timestamp date2timestamp_safe(DateADT dateVal, Node *escontext)
Definition date.c:622
int timetz2tm(TimeTzADT *time, struct pg_tm *tm, fsec_t *fsec, int *tzp)
Definition date.c:2492
Datum timestamp_ne_date(PG_FUNCTION_ARGS)
Definition date.c:937
Datum date_ne_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:874
Datum date_sortsupport(PG_FUNCTION_ARGS)
Definition date.c:451
Datum date_cmp(PG_FUNCTION_ARGS)
Definition date.c:438
Datum date_le(PG_FUNCTION_ARGS)
Definition date.c:411
Datum time_part(PG_FUNCTION_ARGS)
Definition date.c:2332
Datum time_eq(PG_FUNCTION_ARGS)
Definition date.c:1769
Datum timetz_send(PG_FUNCTION_ARGS)
Definition date.c:2460
Datum timetztypmodout(PG_FUNCTION_ARGS)
Definition date.c:2480
#define TIMETZ_GT(t1, t2)
Datum timestamp_ge_date(PG_FUNCTION_ARGS)
Definition date.c:973
static char * anytime_typmodout(bool istz, int32 typmod)
Definition date.c:87
Datum timetz_pl_interval(PG_FUNCTION_ARGS)
Definition date.c:2685
Datum timetz_smaller(PG_FUNCTION_ARGS)
Definition date.c:2668
Datum timetypmodin(PG_FUNCTION_ARGS)
Definition date.c:1647
Datum date_lt_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:883
Datum make_time(PG_FUNCTION_ARGS)
Definition date.c:1666
static Datum date_decrement(Relation rel, Datum existing, bool *underflow)
Definition date.c:460
Datum date_larger(PG_FUNCTION_ARGS)
Definition date.c:525
Datum in_range_time_interval(PG_FUNCTION_ARGS)
Definition date.c:2187
Datum date_gt_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:892
Datum date_lt_timestamp(PG_FUNCTION_ARGS)
Definition date.c:795
Datum timetz_ne(PG_FUNCTION_ARGS)
Definition date.c:2568
Datum time_interval(PG_FUNCTION_ARGS)
Definition date.c:2078
Datum date_eq(PG_FUNCTION_ARGS)
Definition date.c:384
Datum timetz_larger(PG_FUNCTION_ARGS)
Definition date.c:2654
Datum time_le(PG_FUNCTION_ARGS)
Definition date.c:1796
Datum timetz_part(PG_FUNCTION_ARGS)
Definition date.c:3133
Datum in_range_timetz_interval(PG_FUNCTION_ARGS)
Definition date.c:2739
Datum extract_time(PG_FUNCTION_ARGS)
Definition date.c:2338
Datum interval_time(PG_FUNCTION_ARGS)
Definition date.c:2101
TimestampTz date2timestamptz_safe(DateADT dateVal, Node *escontext)
Definition date.c:671
Datum date_mi_interval(PG_FUNCTION_ARGS)
Definition date.c:1287
Datum hashdateextended(PG_FUNCTION_ARGS)
Definition date.c:511
Datum date_eq_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:865
bool float_time_overflows(int hour, int min, double sec)
Definition date.c:1540
Datum timetz_gt(PG_FUNCTION_ARGS)
Definition date.c:2595
Datum timetz_at_local(PG_FUNCTION_ARGS)
Definition date.c:3254
Datum timestamp_gt_date(PG_FUNCTION_ARGS)
Definition date.c:955
Datum date_finite(PG_FUNCTION_ARGS)
Definition date.c:517
DateADT timestamp2date_safe(Timestamp timestamp, Node *escontext)
Definition date.c:1346
Datum in_range_date_interval(PG_FUNCTION_ARGS)
Definition date.c:1060
Datum time_cmp(PG_FUNCTION_ARGS)
Definition date.c:1823
Datum timestamp_time(PG_FUNCTION_ARGS)
Definition date.c:1994
Datum time_mi_time(PG_FUNCTION_ARGS)
Definition date.c:2122
Datum time_ge(PG_FUNCTION_ARGS)
Definition date.c:1814
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:2055
static Datum timetz_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition date.c:3016
Datum date_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:1382
Datum date_ne_timestamp(PG_FUNCTION_ARGS)
Definition date.c:786
Datum timestamptz_ge_date(PG_FUNCTION_ARGS)
Definition date.c:1036
Datum date_eq_timestamp(PG_FUNCTION_ARGS)
Definition date.c:777
int tm2time(struct pg_tm *tm, fsec_t fsec, TimeADT *result)
Definition date.c:1505
Datum timetz_ge(PG_FUNCTION_ARGS)
Definition date.c:2604
Datum timestamp_lt_date(PG_FUNCTION_ARGS)
Definition date.c:946
Datum timestamptz_lt_date(PG_FUNCTION_ARGS)
Definition date.c:1009
Datum timetz_cmp(PG_FUNCTION_ARGS)
Definition date.c:2613
TimeADT GetSQLLocalTime(int32 typmod)
Definition date.c:363
Datum timetztypmodin(PG_FUNCTION_ARGS)
Definition date.c:2472
Datum timetz_recv(PG_FUNCTION_ARGS)
Definition date.c:2424
Datum time_recv(PG_FUNCTION_ARGS)
Definition date.c:1610
Datum time_mi_interval(PG_FUNCTION_ARGS)
Definition date.c:2164
Datum time_support(PG_FUNCTION_ARGS)
Definition date.c:1694
int tm2timetz(struct pg_tm *tm, fsec_t fsec, int tz, TimeTzADT *result)
Definition date.c:2352
Datum date_out(PG_FUNCTION_ARGS)
Definition date.c:178
DateADT timestamptz2date_safe(TimestampTz timestamp, Node *escontext)
Definition date.c:1425
Datum timetz_time(PG_FUNCTION_ARGS)
Definition date.c:2904
Datum timetz_in(PG_FUNCTION_ARGS)
Definition date.c:2362
Datum time_timetz(PG_FUNCTION_ARGS)
Definition date.c:2917
Datum time_lt(PG_FUNCTION_ARGS)
Definition date.c:1787
Datum date_in(PG_FUNCTION_ARGS)
Definition date.c:107
Datum date_gt(PG_FUNCTION_ARGS)
Definition date.c:420
bool time_overflows(int hour, int min, int sec, fsec_t fsec)
Definition date.c:1516
Datum timetz_mi_interval(PG_FUNCTION_ARGS)
Definition date.c:2712
Datum extract_timetz(PG_FUNCTION_ARGS)
Definition date.c:3139
Datum date_ge_timestamp(PG_FUNCTION_ARGS)
Definition date.c:822
static int32 anytime_typmodin(bool istz, ArrayType *ta)
Definition date.c:44
Datum date_mii(PG_FUNCTION_ARGS)
Definition date.c:586
Datum date_pl_interval(PG_FUNCTION_ARGS)
Definition date.c:1267
Datum overlaps_timetz(PG_FUNCTION_ARGS)
Definition date.c:2784
static Datum time_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition date.c:2229
Datum time_gt(PG_FUNCTION_ARGS)
Definition date.c:1805
Datum date_recv(PG_FUNCTION_ARGS)
Definition date.c:203
Datum timetz_lt(PG_FUNCTION_ARGS)
Definition date.c:2577
Datum time_out(PG_FUNCTION_ARGS)
Definition date.c:1590
Datum date_cmp_timestamp(PG_FUNCTION_ARGS)
Definition date.c:831
Datum time_hash(PG_FUNCTION_ARGS)
Definition date.c:1836
Datum time_larger(PG_FUNCTION_ARGS)
Definition date.c:1848
#define TIMETZ_LT(t1, t2)
Datum time_smaller(PG_FUNCTION_ARGS)
Definition date.c:1857
Datum time_ne(PG_FUNCTION_ARGS)
Definition date.c:1778
DateADT GetSQLCurrentDate(void)
Definition date.c:310
Datum timetz_eq(PG_FUNCTION_ARGS)
Definition date.c:2559
Datum date_gt_timestamp(PG_FUNCTION_ARGS)
Definition date.c:804
Datum timestamptz_timetz(PG_FUNCTION_ARGS)
Definition date.c:2943
void AdjustTimeForTypmod(TimeADT *time, int32 typmod)
Definition date.c:1734
Datum date_le_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:901
Datum date_pli(PG_FUNCTION_ARGS)
Definition date.c:562
Datum extract_date(PG_FUNCTION_ARGS)
Definition date.c:1087
Datum timestamptz_date(PG_FUNCTION_ARGS)
Definition date.c:1399
Datum timetz_le(PG_FUNCTION_ARGS)
Definition date.c:2586
Datum date_lt(PG_FUNCTION_ARGS)
Definition date.c:402
Datum timetz_hash(PG_FUNCTION_ARGS)
Definition date.c:2622
static Datum date_increment(Relation rel, Datum existing, bool *overflow)
Definition date.c:476
static TimestampTz date2timestamp(DateADT dateVal)
Definition date.c:655
static int timetz_cmp_internal(TimeTzADT *time1, TimeTzADT *time2)
Definition date.c:2532
Datum timestamptz_gt_date(PG_FUNCTION_ARGS)
Definition date.c:1018
Datum hashdate(PG_FUNCTION_ARGS)
Definition date.c:505
Datum timestamp_date(PG_FUNCTION_ARGS)
Definition date.c:1320
Datum date_ge(PG_FUNCTION_ARGS)
Definition date.c:429
Datum time_in(PG_FUNCTION_ARGS)
Definition date.c:1463
Datum time_hash_extended(PG_FUNCTION_ARGS)
Definition date.c:1842
Datum time_pl_interval(PG_FUNCTION_ARGS)
Definition date.c:2141
Datum datetimetz_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:2975
int time2tm(TimeADT time, struct pg_tm *tm, fsec_t *fsec)
Definition date.c:1577
Datum timestamptz_ne_date(PG_FUNCTION_ARGS)
Definition date.c:1000
Datum date_smaller(PG_FUNCTION_ARGS)
Definition date.c:534
void EncodeSpecialDate(DateADT dt, char *str)
Definition date.c:295
Datum timestamp_le_date(PG_FUNCTION_ARGS)
Definition date.c:964
Datum timetypmodout(PG_FUNCTION_ARGS)
Definition date.c:1655
Datum timestamptz_eq_date(PG_FUNCTION_ARGS)
Definition date.c:991
Datum timetz_scale(PG_FUNCTION_ARGS)
Definition date.c:2514
Datum timestamptz_cmp_date(PG_FUNCTION_ARGS)
Definition date.c:1045
Datum date_ge_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:910
Datum timetz_hash_extended(PG_FUNCTION_ARGS)
Definition date.c:2638
Datum date_skipsupport(PG_FUNCTION_ARGS)
Definition date.c:492
Datum timetz_zone(PG_FUNCTION_ARGS)
Definition date.c:3149
Datum date_cmp_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:919
int32 date_cmp_timestamptz_internal(DateADT dateVal, TimestampTz dt2)
Definition date.c:840
double date2timestamp_no_overflow(DateADT dateVal)
Definition date.c:736
Datum make_date(PG_FUNCTION_ARGS)
Definition date.c:239
TimeTzADT * GetSQLCurrentTime(int32 typmod)
Definition date.c:343
Datum date_le_timestamp(PG_FUNCTION_ARGS)
Definition date.c:813
Datum time_send(PG_FUNCTION_ARGS)
Definition date.c:1636
Datum date_mi(PG_FUNCTION_ARGS)
Definition date.c:545
Datum timestamp_cmp_date(PG_FUNCTION_ARGS)
Definition date.c:982
Datum date_ne(PG_FUNCTION_ARGS)
Definition date.c:393
Datum time_scale(PG_FUNCTION_ARGS)
Definition date.c:1714
Datum timestamptz_time(PG_FUNCTION_ARGS)
Definition date.c:2024
#define TIMEADT_LT(t1, t2)
Datum timetz_out(PG_FUNCTION_ARGS)
Definition date.c:2403
Datum overlaps_time(PG_FUNCTION_ARGS)
Definition date.c:1872
Datum date_timestamp(PG_FUNCTION_ARGS)
Definition date.c:1304
Datum timestamptz_le_date(PG_FUNCTION_ARGS)
Definition date.c:1027
#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:874
#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: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: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: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 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: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:222
static uint64 DatumGetUInt64(Datum X)
Definition postgres.h:423
#define Int64GetDatumFast(X)
Definition postgres.h:525
static int64 DatumGetInt64(Datum X)
Definition postgres.h:403
static Datum PointerGetDatum(const void *X)
Definition postgres.h:342
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:355
uint64_t Datum
Definition postgres.h:70
static Datum CStringGetDatum(const char *X)
Definition postgres.h:370
static Datum Int32GetDatum(int32 X)
Definition postgres.h:212
#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:99
int ssup_datum_int32_cmp(Datum x, Datum y, SortSupport ssup)
Definition tuplesort.c:3472
#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