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);
196 PG_RETURN_CSTRING(result);
197}
198
199/*
200 * date_recv - converts external binary format to date
201 */
202Datum
204{
206 DateADT result;
207
208 result = (DateADT) pq_getmsgint(buf, sizeof(DateADT));
209
210 /* Limit to the same range that date_in() accepts. */
211 if (DATE_NOT_FINITE(result))
212 /* ok */ ;
213 else if (!IS_VALID_DATE(result))
216 errmsg("date out of range")));
217
218 PG_RETURN_DATEADT(result);
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{
345 TimeTzADT *result;
346 struct pg_tm tt,
347 *tm = &tt;
348 fsec_t fsec;
349 int tz;
350
351 GetCurrentTimeUsec(tm, &fsec, &tz);
352
353 result = palloc_object(TimeTzADT);
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{
365 TimeADT result;
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{
566 DateADT result;
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)) ||
575 !IS_VALID_DATE(result))
578 errmsg("date out of range")));
579
580 PG_RETURN_DATEADT(result);
581}
582
583/* Subtract a number of days from a date, giving a new date.
584 */
585Datum
587{
590 DateADT result;
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)) ||
599 !IS_VALID_DATE(result))
602 errmsg("date out of range")));
603
604 PG_RETURN_DATEADT(result);
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{
624 Timestamp result;
625
627 TIMESTAMP_NOBEGIN(result);
628 else if (DATE_IS_NOEND(dateVal))
629 TIMESTAMP_NOEND(result);
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 {
638 TIMESTAMP_NOEND(result);
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... */
645 result = dateVal * USECS_PER_DAY;
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{
673 TimestampTz result;
674 struct pg_tm tt,
675 *tm = &tt;
676 int tz;
677
679 TIMESTAMP_NOBEGIN(result);
680 else if (DATE_IS_NOEND(dateVal))
681 TIMESTAMP_NOEND(result);
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 {
690 TIMESTAMP_NOEND(result);
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
703 result = dateVal * USECS_PER_DAY + tz * USECS_PER_SEC;
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 */
709 if (!IS_VALID_TIMESTAMP(result))
710 {
711 if (result < MIN_TIMESTAMP)
712 TIMESTAMP_NOBEGIN(result);
713 else
714 TIMESTAMP_NOEND(result);
715
716 ereturn(escontext, result,
718 errmsg("date out of range for timestamp")));
719 }
720 }
721
722 return result;
723}
724
725/*
726 * Promote date to timestamptz, throwing error for overflow.
727 */
728static TimestampTz
733
734/*
735 * date2timestamp_no_overflow
736 *
737 * This is chartered to produce a double value that is numerically
738 * equivalent to the corresponding Timestamp value, if the date is in the
739 * valid range of Timestamps, but in any case not throw an overflow error.
740 * We can do this since the numerical range of double is greater than
741 * that of non-erroneous timestamps. The results are currently only
742 * used for statistical estimation purposes.
743 */
744double
746{
747 double result;
748
750 result = -DBL_MAX;
751 else if (DATE_IS_NOEND(dateVal))
752 result = DBL_MAX;
753 else
754 {
755 /* date is days since 2000, timestamp is microseconds since same... */
756 result = dateVal * (double) USECS_PER_DAY;
757 }
758
759 return result;
760}
761
762
763/*
764 * Crosstype comparison functions for dates
765 */
766
767int32
769{
772
773 dt1 = date2timestamp_safe(dateVal, (Node *) &escontext);
774 if (escontext.error_occurred)
775 {
776 Assert(TIMESTAMP_IS_NOEND(dt1)); /* NOBEGIN case cannot occur */
777
778 /* dt1 is larger than any finite timestamp, but less than infinity */
779 return TIMESTAMP_IS_NOEND(dt2) ? -1 : +1;
780 }
781
783}
784
785Datum
793
794Datum
802
803Datum
811
812Datum
820
821Datum
829
830Datum
838
839Datum
847
848int32
850{
853
854 dt1 = date2timestamptz_safe(dateVal, (Node *) &escontext);
855
856 if (escontext.error_occurred)
857 {
859 {
860 /* dt1 is larger than any finite timestamp, but less than infinity */
861 return TIMESTAMP_IS_NOEND(dt2) ? -1 : +1;
862 }
864 {
865 /* dt1 is less than any finite timestamp, but more than -infinity */
866 return TIMESTAMP_IS_NOBEGIN(dt2) ? +1 : -1;
867 }
868 }
869
871}
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
1053Datum
1061
1062/*
1063 * in_range support function for date.
1064 *
1065 * We implement this by promoting the dates to timestamp (without time zone)
1066 * and then using the timestamp-and-interval in_range function.
1067 */
1068Datum
1070{
1072 DateADT base = PG_GETARG_DATEADT(1);
1073 Interval *offset = PG_GETARG_INTERVAL_P(2);
1074 bool sub = PG_GETARG_BOOL(3);
1075 bool less = PG_GETARG_BOOL(4);
1078
1079 /* XXX we could support out-of-range cases here, perhaps */
1081 baseStamp = date2timestamp(base);
1082
1086 IntervalPGetDatum(offset),
1087 BoolGetDatum(sub),
1089}
1090
1091
1092/* extract_date()
1093 * Extract specified field from date type.
1094 */
1095Datum
1097{
1101 int type,
1102 val;
1103 char *lowunits;
1104 int year,
1105 mon,
1106 mday;
1107
1110 false);
1111
1112 type = DecodeUnits(0, lowunits, &val);
1113 if (type == UNKNOWN_FIELD)
1115
1116 if (DATE_NOT_FINITE(date) && (type == UNITS || type == RESERV))
1117 {
1118 switch (val)
1119 {
1120 /* Oscillating units */
1121 case DTK_DAY:
1122 case DTK_MONTH:
1123 case DTK_QUARTER:
1124 case DTK_WEEK:
1125 case DTK_DOW:
1126 case DTK_ISODOW:
1127 case DTK_DOY:
1129 break;
1130
1131 /* Monotonically-increasing units */
1132 case DTK_YEAR:
1133 case DTK_DECADE:
1134 case DTK_CENTURY:
1135 case DTK_MILLENNIUM:
1136 case DTK_JULIAN:
1137 case DTK_ISOYEAR:
1138 case DTK_EPOCH:
1139 if (DATE_IS_NOBEGIN(date))
1141 CStringGetDatum("-Infinity"),
1143 Int32GetDatum(-1))));
1144 else
1146 CStringGetDatum("Infinity"),
1148 Int32GetDatum(-1))));
1149 default:
1150 ereport(ERROR,
1152 errmsg("unit \"%s\" not supported for type %s",
1154 }
1155 }
1156 else if (type == UNITS)
1157 {
1158 j2date(date + POSTGRES_EPOCH_JDATE, &year, &mon, &mday);
1159
1160 switch (val)
1161 {
1162 case DTK_DAY:
1163 intresult = mday;
1164 break;
1165
1166 case DTK_MONTH:
1167 intresult = mon;
1168 break;
1169
1170 case DTK_QUARTER:
1171 intresult = (mon - 1) / 3 + 1;
1172 break;
1173
1174 case DTK_WEEK:
1175 intresult = date2isoweek(year, mon, mday);
1176 break;
1177
1178 case DTK_YEAR:
1179 if (year > 0)
1180 intresult = year;
1181 else
1182 /* there is no year 0, just 1 BC and 1 AD */
1183 intresult = year - 1;
1184 break;
1185
1186 case DTK_DECADE:
1187 /* see comments in timestamp_part */
1188 if (year >= 0)
1189 intresult = year / 10;
1190 else
1191 intresult = -((8 - (year - 1)) / 10);
1192 break;
1193
1194 case DTK_CENTURY:
1195 /* see comments in timestamp_part */
1196 if (year > 0)
1197 intresult = (year + 99) / 100;
1198 else
1199 intresult = -((99 - (year - 1)) / 100);
1200 break;
1201
1202 case DTK_MILLENNIUM:
1203 /* see comments in timestamp_part */
1204 if (year > 0)
1205 intresult = (year + 999) / 1000;
1206 else
1207 intresult = -((999 - (year - 1)) / 1000);
1208 break;
1209
1210 case DTK_JULIAN:
1212 break;
1213
1214 case DTK_ISOYEAR:
1215 intresult = date2isoyear(year, mon, mday);
1216 /* Adjust BC years */
1217 if (intresult <= 0)
1218 intresult -= 1;
1219 break;
1220
1221 case DTK_DOW:
1222 case DTK_ISODOW:
1224 if (val == DTK_ISODOW && intresult == 0)
1225 intresult = 7;
1226 break;
1227
1228 case DTK_DOY:
1229 intresult = date2j(year, mon, mday) - date2j(year, 1, 1) + 1;
1230 break;
1231
1232 default:
1233 ereport(ERROR,
1235 errmsg("unit \"%s\" not supported for type %s",
1237 intresult = 0;
1238 }
1239 }
1240 else if (type == RESERV)
1241 {
1242 switch (val)
1243 {
1244 case DTK_EPOCH:
1246 break;
1247
1248 default:
1249 ereport(ERROR,
1251 errmsg("unit \"%s\" not supported for type %s",
1253 intresult = 0;
1254 }
1255 }
1256 else
1257 {
1258 ereport(ERROR,
1260 errmsg("unit \"%s\" not recognized for type %s",
1262 intresult = 0;
1263 }
1264
1266}
1267
1268
1269/* Add an interval to a date, giving a new date.
1270 * Must handle both positive and negative intervals.
1271 *
1272 * We implement this by promoting the date to timestamp (without time zone)
1273 * and then using the timestamp plus interval function.
1274 */
1275Datum
1288
1289/* Subtract an interval from a date, giving a new date.
1290 * Must handle both positive and negative intervals.
1291 *
1292 * We implement this by promoting the date to timestamp (without time zone)
1293 * and then using the timestamp minus interval function.
1294 */
1295Datum
1308
1309/* date_timestamp()
1310 * Convert date to timestamp data type.
1311 */
1312Datum
1314{
1316 Timestamp result;
1317
1318 result = date2timestamp(dateVal);
1319
1320 PG_RETURN_TIMESTAMP(result);
1321}
1322
1323/* timestamp_date()
1324 * Convert timestamp to date data type.
1325 */
1326Datum
1335
1336/*
1337 * Convert timestamp to date.
1338 *
1339 * If the timestamp falls out of the valid range for the date type, error
1340 * handling proceeds based on escontext.
1341 *
1342 * If escontext is NULL, we throw an out-of-range error (hard error).
1343 * If escontext is not NULL, we return NOBEGIN or NOEND for lower bound or
1344 * upper bound overflow, respectively, and record a soft error.
1345 *
1346 * Note: given the ranges of the types, overflow is only possible at
1347 * the lower bound of the range, but we don't assume that in this code.
1348 */
1349DateADT
1351{
1352 DateADT result;
1353 struct pg_tm tt,
1354 *tm = &tt;
1355 fsec_t fsec;
1356
1358 DATE_NOBEGIN(result);
1359 else if (TIMESTAMP_IS_NOEND(timestamp))
1360 DATE_NOEND(result);
1361 else
1362 {
1363 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
1364 {
1365 if (timestamp < 0)
1366 DATE_NOBEGIN(result);
1367 else
1368 DATE_NOEND(result); /* not actually reachable */
1369
1370 ereturn(escontext, result,
1372 errmsg("timestamp out of range")));
1373 }
1374
1376 }
1377
1378 return result;
1379}
1380
1381
1382/* date_timestamptz()
1383 * Convert date to timestamp with time zone data type.
1384 */
1385Datum
1387{
1389 TimestampTz result;
1390
1391 result = date2timestamptz(dateVal);
1392
1393 PG_RETURN_TIMESTAMP(result);
1394}
1395
1396
1397/* timestamptz_date()
1398 * Convert timestamp with time zone to date data type.
1399 */
1400Datum
1409
1410/*
1411 * Convert timestamptz to date.
1412 *
1413 * If the timestamp falls out of the valid range for the date type, error
1414 * handling proceeds based on escontext.
1415 *
1416 * If escontext is NULL, we throw an out-of-range error (hard error).
1417 * If escontext is not NULL, we return NOBEGIN or NOEND for lower bound or
1418 * upper bound overflow, respectively, and record a soft error.
1419 *
1420 * Note: given the ranges of the types, overflow is only possible at
1421 * the lower bound of the range, but we don't assume that in this code.
1422 */
1423DateADT
1425{
1426 DateADT result;
1427 struct pg_tm tt,
1428 *tm = &tt;
1429 fsec_t fsec;
1430 int tz;
1431
1433 DATE_NOBEGIN(result);
1434 else if (TIMESTAMP_IS_NOEND(timestamp))
1435 DATE_NOEND(result);
1436 else
1437 {
1438 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
1439 {
1440 if (timestamp < 0)
1441 DATE_NOBEGIN(result);
1442 else
1443 DATE_NOEND(result); /* not actually reachable */
1444
1445 ereturn(escontext, result,
1447 errmsg("timestamp out of range")));
1448 }
1449
1451 }
1452
1453 return result;
1454}
1455
1456
1457/*****************************************************************************
1458 * Time ADT
1459 *****************************************************************************/
1460
1461Datum
1463{
1464 char *str = PG_GETARG_CSTRING(0);
1465#ifdef NOT_USED
1466 Oid typelem = PG_GETARG_OID(1);
1467#endif
1468 int32 typmod = PG_GETARG_INT32(2);
1469 Node *escontext = fcinfo->context;
1470 TimeADT result;
1471 fsec_t fsec;
1472 struct pg_tm tt,
1473 *tm = &tt;
1474 int tz;
1475 int nf;
1476 int dterr;
1477 char workbuf[MAXDATELEN + 1];
1478 char *field[MAXDATEFIELDS];
1479 int dtype;
1480 int ftype[MAXDATEFIELDS];
1481 DateTimeErrorExtra extra;
1482
1484 field, ftype, MAXDATEFIELDS, &nf);
1485 if (dterr == 0)
1486 dterr = DecodeTimeOnly(field, ftype, nf,
1487 &dtype, tm, &fsec, &tz, &extra);
1488 if (dterr != 0)
1489 {
1490 DateTimeParseError(dterr, &extra, str, "time", escontext);
1492 }
1493
1494 tm2time(tm, fsec, &result);
1495 AdjustTimeForTypmod(&result, typmod);
1496
1497 PG_RETURN_TIMEADT(result);
1498}
1499
1500/* tm2time()
1501 * Convert a tm structure to a time data type.
1502 */
1503int
1504tm2time(struct pg_tm *tm, fsec_t fsec, TimeADT *result)
1505{
1506 *result = ((((tm->tm_hour * MINS_PER_HOUR + tm->tm_min) * SECS_PER_MINUTE) + tm->tm_sec)
1507 * USECS_PER_SEC) + fsec;
1508 return 0;
1509}
1510
1511/* time_overflows()
1512 * Check to see if a broken-down time-of-day is out of range.
1513 */
1514bool
1515time_overflows(int hour, int min, int sec, fsec_t fsec)
1516{
1517 /* Range-check the fields individually. */
1522 return true;
1523
1524 /*
1525 * Because we allow, eg, hour = 24 or sec = 60, we must check separately
1526 * that the total time value doesn't exceed 24:00:00.
1527 */
1528 if ((((((hour * MINS_PER_HOUR + min) * SECS_PER_MINUTE)
1529 + sec) * USECS_PER_SEC) + fsec) > USECS_PER_DAY)
1530 return true;
1531
1532 return false;
1533}
1534
1535/* float_time_overflows()
1536 * Same, when we have seconds + fractional seconds as one "double" value.
1537 */
1538bool
1539float_time_overflows(int hour, int min, double sec)
1540{
1541 /* Range-check the fields individually. */
1544 return true;
1545
1546 /*
1547 * "sec", being double, requires extra care. Cope with NaN, and round off
1548 * before applying the range check to avoid unexpected errors due to
1549 * imprecise input. (We assume rint() behaves sanely with infinities.)
1550 */
1551 if (isnan(sec))
1552 return true;
1553 sec = rint(sec * USECS_PER_SEC);
1555 return true;
1556
1557 /*
1558 * Because we allow, eg, hour = 24 or sec = 60, we must check separately
1559 * that the total time value doesn't exceed 24:00:00. This must match the
1560 * way that callers will convert the fields to a time.
1561 */
1562 if (((((hour * MINS_PER_HOUR + min) * SECS_PER_MINUTE)
1563 * USECS_PER_SEC) + (int64) sec) > USECS_PER_DAY)
1564 return true;
1565
1566 return false;
1567}
1568
1569
1570/* time2tm()
1571 * Convert time data type to POSIX time structure.
1572 *
1573 * Note that only the hour/min/sec/fractional-sec fields are filled in.
1574 */
1575int
1576time2tm(TimeADT time, struct pg_tm *tm, fsec_t *fsec)
1577{
1578 tm->tm_hour = time / USECS_PER_HOUR;
1579 time -= tm->tm_hour * USECS_PER_HOUR;
1580 tm->tm_min = time / USECS_PER_MINUTE;
1581 time -= tm->tm_min * USECS_PER_MINUTE;
1582 tm->tm_sec = time / USECS_PER_SEC;
1583 time -= tm->tm_sec * USECS_PER_SEC;
1584 *fsec = time;
1585 return 0;
1586}
1587
1588Datum
1590{
1591 TimeADT time = PG_GETARG_TIMEADT(0);
1592 char *result;
1593 struct pg_tm tt,
1594 *tm = &tt;
1595 fsec_t fsec;
1596 char buf[MAXDATELEN + 1];
1597
1598 time2tm(time, tm, &fsec);
1599 EncodeTimeOnly(tm, fsec, false, 0, DateStyle, buf);
1600
1601 result = pstrdup(buf);
1602 PG_RETURN_CSTRING(result);
1603}
1604
1605/*
1606 * time_recv - converts external binary format to time
1607 */
1608Datum
1610{
1612
1613#ifdef NOT_USED
1614 Oid typelem = PG_GETARG_OID(1);
1615#endif
1616 int32 typmod = PG_GETARG_INT32(2);
1617 TimeADT result;
1618
1619 result = pq_getmsgint64(buf);
1620
1621 if (result < INT64CONST(0) || result > USECS_PER_DAY)
1622 ereport(ERROR,
1624 errmsg("time out of range")));
1625
1626 AdjustTimeForTypmod(&result, typmod);
1627
1628 PG_RETURN_TIMEADT(result);
1629}
1630
1631/*
1632 * time_send - converts time to binary format
1633 */
1634Datum
1644
1645Datum
1652
1653Datum
1655{
1656 int32 typmod = PG_GETARG_INT32(0);
1657
1658 PG_RETURN_CSTRING(anytime_typmodout(false, typmod));
1659}
1660
1661/*
1662 * make_time - time constructor
1663 */
1664Datum
1666{
1667 int tm_hour = PG_GETARG_INT32(0);
1668 int tm_min = PG_GETARG_INT32(1);
1669 double sec = PG_GETARG_FLOAT8(2);
1670 TimeADT time;
1671
1672 /* Check for time overflow */
1674 ereport(ERROR,
1676 errmsg("time field value out of range: %d:%02d:%02g",
1677 tm_hour, tm_min, sec)));
1678
1679 /* This should match tm2time */
1681 * USECS_PER_SEC) + (int64) rint(sec * USECS_PER_SEC);
1682
1683 PG_RETURN_TIMEADT(time);
1684}
1685
1686
1687/* time_support()
1688 *
1689 * Planner support function for the time_scale() and timetz_scale()
1690 * length coercion functions (we need not distinguish them here).
1691 */
1692Datum
1694{
1696 Node *ret = NULL;
1697
1699 {
1701
1702 ret = TemporalSimplify(MAX_TIME_PRECISION, (Node *) req->fcall);
1703 }
1704
1705 PG_RETURN_POINTER(ret);
1706}
1707
1708/* time_scale()
1709 * Adjust time type for specified scale factor.
1710 * Used by PostgreSQL type system to stuff columns.
1711 */
1712Datum
1714{
1715 TimeADT time = PG_GETARG_TIMEADT(0);
1716 int32 typmod = PG_GETARG_INT32(1);
1717 TimeADT result;
1718
1719 result = time;
1720 AdjustTimeForTypmod(&result, typmod);
1721
1722 PG_RETURN_TIMEADT(result);
1723}
1724
1725/* AdjustTimeForTypmod()
1726 * Force the precision of the time value to a specified value.
1727 * Uses *exactly* the same code as in AdjustTimestampForTypmod()
1728 * but we make a separate copy because those types do not
1729 * have a fundamental tie together but rather a coincidence of
1730 * implementation. - thomas
1731 */
1732void
1734{
1735 static const int64 TimeScales[MAX_TIME_PRECISION + 1] = {
1736 INT64CONST(1000000),
1737 INT64CONST(100000),
1738 INT64CONST(10000),
1739 INT64CONST(1000),
1740 INT64CONST(100),
1741 INT64CONST(10),
1742 INT64CONST(1)
1743 };
1744
1745 static const int64 TimeOffsets[MAX_TIME_PRECISION + 1] = {
1746 INT64CONST(500000),
1747 INT64CONST(50000),
1748 INT64CONST(5000),
1749 INT64CONST(500),
1750 INT64CONST(50),
1751 INT64CONST(5),
1752 INT64CONST(0)
1753 };
1754
1755 if (typmod >= 0 && typmod <= MAX_TIME_PRECISION)
1756 {
1757 if (*time >= INT64CONST(0))
1758 *time = ((*time + TimeOffsets[typmod]) / TimeScales[typmod]) *
1759 TimeScales[typmod];
1760 else
1761 *time = -((((-*time) + TimeOffsets[typmod]) / TimeScales[typmod]) *
1762 TimeScales[typmod]);
1763 }
1764}
1765
1766
1767Datum
1775
1776Datum
1784
1785Datum
1793
1794Datum
1802
1803Datum
1811
1812Datum
1820
1821Datum
1823{
1826
1827 if (time1 < time2)
1828 PG_RETURN_INT32(-1);
1829 if (time1 > time2)
1830 PG_RETURN_INT32(1);
1831 PG_RETURN_INT32(0);
1832}
1833
1834Datum
1836{
1837 return hashint8(fcinfo);
1838}
1839
1840Datum
1842{
1843 return hashint8extended(fcinfo);
1844}
1845
1846Datum
1854
1855Datum
1863
1864/* overlaps_time() --- implements the SQL OVERLAPS operator.
1865 *
1866 * Algorithm is per SQL spec. This is much harder than you'd think
1867 * because the spec requires us to deliver a non-null answer in some cases
1868 * where some of the inputs are null.
1869 */
1870Datum
1872{
1873 /*
1874 * The arguments are TimeADT, but we leave them as generic Datums to avoid
1875 * dereferencing nulls (TimeADT is pass-by-reference!)
1876 */
1881 bool ts1IsNull = PG_ARGISNULL(0);
1882 bool te1IsNull = PG_ARGISNULL(1);
1883 bool ts2IsNull = PG_ARGISNULL(2);
1884 bool te2IsNull = PG_ARGISNULL(3);
1885
1886#define TIMEADT_GT(t1,t2) \
1887 (DatumGetTimeADT(t1) > DatumGetTimeADT(t2))
1888#define TIMEADT_LT(t1,t2) \
1889 (DatumGetTimeADT(t1) < DatumGetTimeADT(t2))
1890
1891 /*
1892 * If both endpoints of interval 1 are null, the result is null (unknown).
1893 * If just one endpoint is null, take ts1 as the non-null one. Otherwise,
1894 * take ts1 as the lesser endpoint.
1895 */
1896 if (ts1IsNull)
1897 {
1898 if (te1IsNull)
1900 /* swap null for non-null */
1901 ts1 = te1;
1902 te1IsNull = true;
1903 }
1904 else if (!te1IsNull)
1905 {
1906 if (TIMEADT_GT(ts1, te1))
1907 {
1908 Datum tt = ts1;
1909
1910 ts1 = te1;
1911 te1 = tt;
1912 }
1913 }
1914
1915 /* Likewise for interval 2. */
1916 if (ts2IsNull)
1917 {
1918 if (te2IsNull)
1920 /* swap null for non-null */
1921 ts2 = te2;
1922 te2IsNull = true;
1923 }
1924 else if (!te2IsNull)
1925 {
1926 if (TIMEADT_GT(ts2, te2))
1927 {
1928 Datum tt = ts2;
1929
1930 ts2 = te2;
1931 te2 = tt;
1932 }
1933 }
1934
1935 /*
1936 * At this point neither ts1 nor ts2 is null, so we can consider three
1937 * cases: ts1 > ts2, ts1 < ts2, ts1 = ts2
1938 */
1939 if (TIMEADT_GT(ts1, ts2))
1940 {
1941 /*
1942 * This case is ts1 < te2 OR te1 < te2, which may look redundant but
1943 * in the presence of nulls it's not quite completely so.
1944 */
1945 if (te2IsNull)
1947 if (TIMEADT_LT(ts1, te2))
1948 PG_RETURN_BOOL(true);
1949 if (te1IsNull)
1951
1952 /*
1953 * If te1 is not null then we had ts1 <= te1 above, and we just found
1954 * ts1 >= te2, hence te1 >= te2.
1955 */
1956 PG_RETURN_BOOL(false);
1957 }
1958 else if (TIMEADT_LT(ts1, ts2))
1959 {
1960 /* This case is ts2 < te1 OR te2 < te1 */
1961 if (te1IsNull)
1963 if (TIMEADT_LT(ts2, te1))
1964 PG_RETURN_BOOL(true);
1965 if (te2IsNull)
1967
1968 /*
1969 * If te2 is not null then we had ts2 <= te2 above, and we just found
1970 * ts2 >= te1, hence te2 >= te1.
1971 */
1972 PG_RETURN_BOOL(false);
1973 }
1974 else
1975 {
1976 /*
1977 * For ts1 = ts2 the spec says te1 <> te2 OR te1 = te2, which is a
1978 * rather silly way of saying "true if both are nonnull, else null".
1979 */
1980 if (te1IsNull || te2IsNull)
1982 PG_RETURN_BOOL(true);
1983 }
1984
1985#undef TIMEADT_GT
1986#undef TIMEADT_LT
1987}
1988
1989/* timestamp_time()
1990 * Convert timestamp to time data type.
1991 */
1992Datum
1994{
1996 TimeADT result;
1997 struct pg_tm tt,
1998 *tm = &tt;
1999 fsec_t fsec;
2000
2003
2004 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
2005 ereport(ERROR,
2007 errmsg("timestamp out of range")));
2008
2009 /*
2010 * Could also do this with time = (timestamp / USECS_PER_DAY *
2011 * USECS_PER_DAY) - timestamp;
2012 */
2013 result = ((((tm->tm_hour * MINS_PER_HOUR + tm->tm_min) * SECS_PER_MINUTE) + tm->tm_sec) *
2014 USECS_PER_SEC) + fsec;
2015
2016 PG_RETURN_TIMEADT(result);
2017}
2018
2019/* timestamptz_time()
2020 * Convert timestamptz to time data type.
2021 */
2022Datum
2024{
2026 TimeADT result;
2027 struct pg_tm tt,
2028 *tm = &tt;
2029 int tz;
2030 fsec_t fsec;
2031
2034
2035 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
2036 ereport(ERROR,
2038 errmsg("timestamp out of range")));
2039
2040 /*
2041 * Could also do this with time = (timestamp / USECS_PER_DAY *
2042 * USECS_PER_DAY) - timestamp;
2043 */
2044 result = ((((tm->tm_hour * MINS_PER_HOUR + tm->tm_min) * SECS_PER_MINUTE) + tm->tm_sec) *
2045 USECS_PER_SEC) + fsec;
2046
2047 PG_RETURN_TIMEADT(result);
2048}
2049
2050/* datetime_timestamp()
2051 * Convert date and time to timestamp data type.
2052 */
2053Datum
2055{
2057 TimeADT time = PG_GETARG_TIMEADT(1);
2058 Timestamp result;
2059
2060 result = date2timestamp(date);
2061 if (!TIMESTAMP_NOT_FINITE(result))
2062 {
2063 result += time;
2064 if (!IS_VALID_TIMESTAMP(result))
2065 ereport(ERROR,
2067 errmsg("timestamp out of range")));
2068 }
2069
2070 PG_RETURN_TIMESTAMP(result);
2071}
2072
2073/* time_interval()
2074 * Convert time to interval data type.
2075 */
2076Datum
2078{
2079 TimeADT time = PG_GETARG_TIMEADT(0);
2080 Interval *result;
2081
2082 result = palloc_object(Interval);
2083
2084 result->time = time;
2085 result->day = 0;
2086 result->month = 0;
2087
2088 PG_RETURN_INTERVAL_P(result);
2089}
2090
2091/* interval_time()
2092 * Convert interval to time data type.
2093 *
2094 * This is defined as producing the fractional-day portion of the interval.
2095 * Therefore, we can just ignore the months field. It is not real clear
2096 * what to do with negative intervals, but we choose to subtract the floor,
2097 * so that, say, '-2 hours' becomes '22:00:00'.
2098 */
2099Datum
2101{
2103 TimeADT result;
2104
2106 ereport(ERROR,
2108 errmsg("cannot convert infinite interval to time")));
2109
2110 result = span->time % USECS_PER_DAY;
2111 if (result < 0)
2112 result += USECS_PER_DAY;
2113
2114 PG_RETURN_TIMEADT(result);
2115}
2116
2117/* time_mi_time()
2118 * Subtract two times to produce an interval.
2119 */
2120Datum
2122{
2125 Interval *result;
2126
2127 result = palloc_object(Interval);
2128
2129 result->month = 0;
2130 result->day = 0;
2131 result->time = time1 - time2;
2132
2133 PG_RETURN_INTERVAL_P(result);
2134}
2135
2136/* time_pl_interval()
2137 * Add interval to time.
2138 */
2139Datum
2141{
2142 TimeADT time = PG_GETARG_TIMEADT(0);
2144 TimeADT result;
2145
2147 ereport(ERROR,
2149 errmsg("cannot add infinite interval to time")));
2150
2151 result = time + span->time;
2152 result -= result / USECS_PER_DAY * USECS_PER_DAY;
2153 if (result < INT64CONST(0))
2154 result += USECS_PER_DAY;
2155
2156 PG_RETURN_TIMEADT(result);
2157}
2158
2159/* time_mi_interval()
2160 * Subtract interval from time.
2161 */
2162Datum
2164{
2165 TimeADT time = PG_GETARG_TIMEADT(0);
2167 TimeADT result;
2168
2170 ereport(ERROR,
2172 errmsg("cannot subtract infinite interval from time")));
2173
2174 result = time - span->time;
2175 result -= result / USECS_PER_DAY * USECS_PER_DAY;
2176 if (result < INT64CONST(0))
2177 result += USECS_PER_DAY;
2178
2179 PG_RETURN_TIMEADT(result);
2180}
2181
2182/*
2183 * in_range support function for time.
2184 */
2185Datum
2187{
2189 TimeADT base = PG_GETARG_TIMEADT(1);
2190 Interval *offset = PG_GETARG_INTERVAL_P(2);
2191 bool sub = PG_GETARG_BOOL(3);
2192 bool less = PG_GETARG_BOOL(4);
2193 TimeADT sum;
2194
2195 /*
2196 * Like time_pl_interval/time_mi_interval, we disregard the month and day
2197 * fields of the offset. So our test for negative should too. This also
2198 * catches -infinity, so we only need worry about +infinity below.
2199 */
2200 if (offset->time < 0)
2201 ereport(ERROR,
2203 errmsg("invalid preceding or following size in window function")));
2204
2205 /*
2206 * We can't use time_pl_interval/time_mi_interval here, because their
2207 * wraparound behavior would give wrong (or at least undesirable) answers.
2208 * Fortunately the equivalent non-wrapping behavior is trivial, except
2209 * that adding an infinite (or very large) interval might cause integer
2210 * overflow. Subtraction cannot overflow here.
2211 */
2212 if (sub)
2213 sum = base - offset->time;
2214 else if (pg_add_s64_overflow(base, offset->time, &sum))
2216
2217 if (less)
2218 PG_RETURN_BOOL(val <= sum);
2219 else
2220 PG_RETURN_BOOL(val >= sum);
2221}
2222
2223
2224/* time_part() and extract_time()
2225 * Extract specified field from time type.
2226 */
2227static Datum
2229{
2231 TimeADT time = PG_GETARG_TIMEADT(1);
2233 int type,
2234 val;
2235 char *lowunits;
2236
2239 false);
2240
2241 type = DecodeUnits(0, lowunits, &val);
2242 if (type == UNKNOWN_FIELD)
2244
2245 if (type == UNITS)
2246 {
2247 fsec_t fsec;
2248 struct pg_tm tt,
2249 *tm = &tt;
2250
2251 time2tm(time, tm, &fsec);
2252
2253 switch (val)
2254 {
2255 case DTK_MICROSEC:
2256 intresult = tm->tm_sec * INT64CONST(1000000) + fsec;
2257 break;
2258
2259 case DTK_MILLISEC:
2260 if (retnumeric)
2261 /*---
2262 * tm->tm_sec * 1000 + fsec / 1000
2263 * = (tm->tm_sec * 1'000'000 + fsec) / 1000
2264 */
2266 else
2267 PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + fsec / 1000.0);
2268 break;
2269
2270 case DTK_SECOND:
2271 if (retnumeric)
2272 /*---
2273 * tm->tm_sec + fsec / 1'000'000
2274 * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
2275 */
2277 else
2278 PG_RETURN_FLOAT8(tm->tm_sec + fsec / 1000000.0);
2279 break;
2280
2281 case DTK_MINUTE:
2282 intresult = tm->tm_min;
2283 break;
2284
2285 case DTK_HOUR:
2286 intresult = tm->tm_hour;
2287 break;
2288
2289 case DTK_TZ:
2290 case DTK_TZ_MINUTE:
2291 case DTK_TZ_HOUR:
2292 case DTK_DAY:
2293 case DTK_MONTH:
2294 case DTK_QUARTER:
2295 case DTK_YEAR:
2296 case DTK_DECADE:
2297 case DTK_CENTURY:
2298 case DTK_MILLENNIUM:
2299 case DTK_ISOYEAR:
2300 default:
2301 ereport(ERROR,
2303 errmsg("unit \"%s\" not supported for type %s",
2305 intresult = 0;
2306 }
2307 }
2308 else if (type == RESERV && val == DTK_EPOCH)
2309 {
2310 if (retnumeric)
2312 else
2313 PG_RETURN_FLOAT8(time / 1000000.0);
2314 }
2315 else
2316 {
2317 ereport(ERROR,
2319 errmsg("unit \"%s\" not recognized for type %s",
2321 intresult = 0;
2322 }
2323
2324 if (retnumeric)
2326 else
2328}
2329
2330Datum
2332{
2333 return time_part_common(fcinfo, false);
2334}
2335
2336Datum
2338{
2339 return time_part_common(fcinfo, true);
2340}
2341
2342
2343/*****************************************************************************
2344 * Time With Time Zone ADT
2345 *****************************************************************************/
2346
2347/* tm2timetz()
2348 * Convert a tm structure to a time data type.
2349 */
2350int
2351tm2timetz(struct pg_tm *tm, fsec_t fsec, int tz, TimeTzADT *result)
2352{
2353 result->time = ((((tm->tm_hour * MINS_PER_HOUR + tm->tm_min) * SECS_PER_MINUTE) + tm->tm_sec) *
2354 USECS_PER_SEC) + fsec;
2355 result->zone = tz;
2356
2357 return 0;
2358}
2359
2360Datum
2362{
2363 char *str = PG_GETARG_CSTRING(0);
2364#ifdef NOT_USED
2365 Oid typelem = PG_GETARG_OID(1);
2366#endif
2367 int32 typmod = PG_GETARG_INT32(2);
2368 Node *escontext = fcinfo->context;
2369 TimeTzADT *result;
2370 fsec_t fsec;
2371 struct pg_tm tt,
2372 *tm = &tt;
2373 int tz;
2374 int nf;
2375 int dterr;
2376 char workbuf[MAXDATELEN + 1];
2377 char *field[MAXDATEFIELDS];
2378 int dtype;
2379 int ftype[MAXDATEFIELDS];
2380 DateTimeErrorExtra extra;
2381
2383 field, ftype, MAXDATEFIELDS, &nf);
2384 if (dterr == 0)
2385 dterr = DecodeTimeOnly(field, ftype, nf,
2386 &dtype, tm, &fsec, &tz, &extra);
2387 if (dterr != 0)
2388 {
2389 DateTimeParseError(dterr, &extra, str, "time with time zone",
2390 escontext);
2392 }
2393
2394 result = palloc_object(TimeTzADT);
2395 tm2timetz(tm, fsec, tz, result);
2396 AdjustTimeForTypmod(&(result->time), typmod);
2397
2398 PG_RETURN_TIMETZADT_P(result);
2399}
2400
2401Datum
2403{
2405 char *result;
2406 struct pg_tm tt,
2407 *tm = &tt;
2408 fsec_t fsec;
2409 int tz;
2410 char buf[MAXDATELEN + 1];
2411
2412 timetz2tm(time, tm, &fsec, &tz);
2413 EncodeTimeOnly(tm, fsec, true, tz, DateStyle, buf);
2414
2415 result = pstrdup(buf);
2416 PG_RETURN_CSTRING(result);
2417}
2418
2419/*
2420 * timetz_recv - converts external binary format to timetz
2421 */
2422Datum
2424{
2426
2427#ifdef NOT_USED
2428 Oid typelem = PG_GETARG_OID(1);
2429#endif
2430 int32 typmod = PG_GETARG_INT32(2);
2431 TimeTzADT *result;
2432
2433 result = palloc_object(TimeTzADT);
2434
2435 result->time = pq_getmsgint64(buf);
2436
2437 if (result->time < INT64CONST(0) || result->time > USECS_PER_DAY)
2438 ereport(ERROR,
2440 errmsg("time out of range")));
2441
2442 result->zone = pq_getmsgint(buf, sizeof(result->zone));
2443
2444 /* Check for sane GMT displacement; see notes in datatype/timestamp.h */
2445 if (result->zone <= -TZDISP_LIMIT || result->zone >= TZDISP_LIMIT)
2446 ereport(ERROR,
2448 errmsg("time zone displacement out of range")));
2449
2450 AdjustTimeForTypmod(&(result->time), typmod);
2451
2452 PG_RETURN_TIMETZADT_P(result);
2453}
2454
2455/*
2456 * timetz_send - converts timetz to binary format
2457 */
2458Datum
2469
2470Datum
2477
2478Datum
2480{
2481 int32 typmod = PG_GETARG_INT32(0);
2482
2483 PG_RETURN_CSTRING(anytime_typmodout(true, typmod));
2484}
2485
2486
2487/* timetz2tm()
2488 * Convert TIME WITH TIME ZONE data type to POSIX time structure.
2489 */
2490int
2491timetz2tm(TimeTzADT *time, struct pg_tm *tm, fsec_t *fsec, int *tzp)
2492{
2493 TimeOffset trem = time->time;
2494
2500 *fsec = trem - tm->tm_sec * USECS_PER_SEC;
2501
2502 if (tzp != NULL)
2503 *tzp = time->zone;
2504
2505 return 0;
2506}
2507
2508/* timetz_scale()
2509 * Adjust time type for specified scale factor.
2510 * Used by PostgreSQL type system to stuff columns.
2511 */
2512Datum
2514{
2516 int32 typmod = PG_GETARG_INT32(1);
2517 TimeTzADT *result;
2518
2519 result = palloc_object(TimeTzADT);
2520
2521 result->time = time->time;
2522 result->zone = time->zone;
2523
2524 AdjustTimeForTypmod(&(result->time), typmod);
2525
2526 PG_RETURN_TIMETZADT_P(result);
2527}
2528
2529
2530static int
2532{
2533 TimeOffset t1,
2534 t2;
2535
2536 /* Primary sort is by true (GMT-equivalent) time */
2537 t1 = time1->time + (time1->zone * USECS_PER_SEC);
2538 t2 = time2->time + (time2->zone * USECS_PER_SEC);
2539
2540 if (t1 > t2)
2541 return 1;
2542 if (t1 < t2)
2543 return -1;
2544
2545 /*
2546 * If same GMT time, sort by timezone; we only want to say that two
2547 * timetz's are equal if both the time and zone parts are equal.
2548 */
2549 if (time1->zone > time2->zone)
2550 return 1;
2551 if (time1->zone < time2->zone)
2552 return -1;
2553
2554 return 0;
2555}
2556
2557Datum
2565
2566Datum
2574
2575Datum
2583
2584Datum
2592
2593Datum
2601
2602Datum
2610
2611Datum
2619
2620Datum
2622{
2624 uint32 thash;
2625
2626 /*
2627 * To avoid any problems with padding bytes in the struct, we figure the
2628 * field hashes separately and XOR them.
2629 */
2631 Int64GetDatumFast(key->time)));
2632 thash ^= DatumGetUInt32(hash_uint32(key->zone));
2634}
2635
2636Datum
2638{
2640 Datum seed = PG_GETARG_DATUM(1);
2641 uint64 thash;
2642
2643 /* Same approach as timetz_hash */
2645 Int64GetDatumFast(key->time),
2646 seed));
2648 DatumGetInt64(seed)));
2650}
2651
2652Datum
2654{
2657 TimeTzADT *result;
2658
2660 result = time1;
2661 else
2662 result = time2;
2663 PG_RETURN_TIMETZADT_P(result);
2664}
2665
2666Datum
2668{
2671 TimeTzADT *result;
2672
2674 result = time1;
2675 else
2676 result = time2;
2677 PG_RETURN_TIMETZADT_P(result);
2678}
2679
2680/* timetz_pl_interval()
2681 * Add interval to timetz.
2682 */
2683Datum
2685{
2688 TimeTzADT *result;
2689
2691 ereport(ERROR,
2693 errmsg("cannot add infinite interval to time")));
2694
2695 result = palloc_object(TimeTzADT);
2696
2697 result->time = time->time + span->time;
2698 result->time -= result->time / USECS_PER_DAY * USECS_PER_DAY;
2699 if (result->time < INT64CONST(0))
2700 result->time += USECS_PER_DAY;
2701
2702 result->zone = time->zone;
2703
2704 PG_RETURN_TIMETZADT_P(result);
2705}
2706
2707/* timetz_mi_interval()
2708 * Subtract interval from timetz.
2709 */
2710Datum
2712{
2715 TimeTzADT *result;
2716
2718 ereport(ERROR,
2720 errmsg("cannot subtract infinite interval from time")));
2721
2722 result = palloc_object(TimeTzADT);
2723
2724 result->time = time->time - span->time;
2725 result->time -= result->time / USECS_PER_DAY * USECS_PER_DAY;
2726 if (result->time < INT64CONST(0))
2727 result->time += USECS_PER_DAY;
2728
2729 result->zone = time->zone;
2730
2731 PG_RETURN_TIMETZADT_P(result);
2732}
2733
2734/*
2735 * in_range support function for timetz.
2736 */
2737Datum
2739{
2742 Interval *offset = PG_GETARG_INTERVAL_P(2);
2743 bool sub = PG_GETARG_BOOL(3);
2744 bool less = PG_GETARG_BOOL(4);
2745 TimeTzADT sum;
2746
2747 /*
2748 * Like timetz_pl_interval/timetz_mi_interval, we disregard the month and
2749 * day fields of the offset. So our test for negative should too. This
2750 * also catches -infinity, so we only need worry about +infinity below.
2751 */
2752 if (offset->time < 0)
2753 ereport(ERROR,
2755 errmsg("invalid preceding or following size in window function")));
2756
2757 /*
2758 * We can't use timetz_pl_interval/timetz_mi_interval here, because their
2759 * wraparound behavior would give wrong (or at least undesirable) answers.
2760 * Fortunately the equivalent non-wrapping behavior is trivial, except
2761 * that adding an infinite (or very large) interval might cause integer
2762 * overflow. Subtraction cannot overflow here.
2763 */
2764 if (sub)
2765 sum.time = base->time - offset->time;
2766 else if (pg_add_s64_overflow(base->time, offset->time, &sum.time))
2768 sum.zone = base->zone;
2769
2770 if (less)
2772 else
2774}
2775
2776/* overlaps_timetz() --- implements the SQL OVERLAPS operator.
2777 *
2778 * Algorithm is per SQL spec. This is much harder than you'd think
2779 * because the spec requires us to deliver a non-null answer in some cases
2780 * where some of the inputs are null.
2781 */
2782Datum
2784{
2785 /*
2786 * The arguments are TimeTzADT *, but we leave them as generic Datums for
2787 * convenience of notation --- and to avoid dereferencing nulls.
2788 */
2793 bool ts1IsNull = PG_ARGISNULL(0);
2794 bool te1IsNull = PG_ARGISNULL(1);
2795 bool ts2IsNull = PG_ARGISNULL(2);
2796 bool te2IsNull = PG_ARGISNULL(3);
2797
2798#define TIMETZ_GT(t1,t2) \
2799 DatumGetBool(DirectFunctionCall2(timetz_gt,t1,t2))
2800#define TIMETZ_LT(t1,t2) \
2801 DatumGetBool(DirectFunctionCall2(timetz_lt,t1,t2))
2802
2803 /*
2804 * If both endpoints of interval 1 are null, the result is null (unknown).
2805 * If just one endpoint is null, take ts1 as the non-null one. Otherwise,
2806 * take ts1 as the lesser endpoint.
2807 */
2808 if (ts1IsNull)
2809 {
2810 if (te1IsNull)
2812 /* swap null for non-null */
2813 ts1 = te1;
2814 te1IsNull = true;
2815 }
2816 else if (!te1IsNull)
2817 {
2818 if (TIMETZ_GT(ts1, te1))
2819 {
2820 Datum tt = ts1;
2821
2822 ts1 = te1;
2823 te1 = tt;
2824 }
2825 }
2826
2827 /* Likewise for interval 2. */
2828 if (ts2IsNull)
2829 {
2830 if (te2IsNull)
2832 /* swap null for non-null */
2833 ts2 = te2;
2834 te2IsNull = true;
2835 }
2836 else if (!te2IsNull)
2837 {
2838 if (TIMETZ_GT(ts2, te2))
2839 {
2840 Datum tt = ts2;
2841
2842 ts2 = te2;
2843 te2 = tt;
2844 }
2845 }
2846
2847 /*
2848 * At this point neither ts1 nor ts2 is null, so we can consider three
2849 * cases: ts1 > ts2, ts1 < ts2, ts1 = ts2
2850 */
2851 if (TIMETZ_GT(ts1, ts2))
2852 {
2853 /*
2854 * This case is ts1 < te2 OR te1 < te2, which may look redundant but
2855 * in the presence of nulls it's not quite completely so.
2856 */
2857 if (te2IsNull)
2859 if (TIMETZ_LT(ts1, te2))
2860 PG_RETURN_BOOL(true);
2861 if (te1IsNull)
2863
2864 /*
2865 * If te1 is not null then we had ts1 <= te1 above, and we just found
2866 * ts1 >= te2, hence te1 >= te2.
2867 */
2868 PG_RETURN_BOOL(false);
2869 }
2870 else if (TIMETZ_LT(ts1, ts2))
2871 {
2872 /* This case is ts2 < te1 OR te2 < te1 */
2873 if (te1IsNull)
2875 if (TIMETZ_LT(ts2, te1))
2876 PG_RETURN_BOOL(true);
2877 if (te2IsNull)
2879
2880 /*
2881 * If te2 is not null then we had ts2 <= te2 above, and we just found
2882 * ts2 >= te1, hence te2 >= te1.
2883 */
2884 PG_RETURN_BOOL(false);
2885 }
2886 else
2887 {
2888 /*
2889 * For ts1 = ts2 the spec says te1 <> te2 OR te1 = te2, which is a
2890 * rather silly way of saying "true if both are nonnull, else null".
2891 */
2892 if (te1IsNull || te2IsNull)
2894 PG_RETURN_BOOL(true);
2895 }
2896
2897#undef TIMETZ_GT
2898#undef TIMETZ_LT
2899}
2900
2901
2902Datum
2904{
2906 TimeADT result;
2907
2908 /* swallow the time zone and just return the time */
2909 result = timetz->time;
2910
2911 PG_RETURN_TIMEADT(result);
2912}
2913
2914
2915Datum
2917{
2918 TimeADT time = PG_GETARG_TIMEADT(0);
2919 TimeTzADT *result;
2920 struct pg_tm tt,
2921 *tm = &tt;
2922 fsec_t fsec;
2923 int tz;
2924
2926 time2tm(time, tm, &fsec);
2928
2929 result = palloc_object(TimeTzADT);
2930
2931 result->time = time;
2932 result->zone = tz;
2933
2934 PG_RETURN_TIMETZADT_P(result);
2935}
2936
2937
2938/* timestamptz_timetz()
2939 * Convert timestamp to timetz data type.
2940 */
2941Datum
2943{
2945 TimeTzADT *result;
2946 struct pg_tm tt,
2947 *tm = &tt;
2948 int tz;
2949 fsec_t fsec;
2950
2953
2954 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
2955 ereport(ERROR,
2957 errmsg("timestamp out of range")));
2958
2959 result = palloc_object(TimeTzADT);
2960
2961 tm2timetz(tm, fsec, tz, result);
2962
2963 PG_RETURN_TIMETZADT_P(result);
2964}
2965
2966
2967/* datetimetz_timestamptz()
2968 * Convert date and timetz to timestamp with time zone data type.
2969 * Timestamp is stored in GMT, so add the time zone
2970 * stored with the timetz to the result.
2971 * - thomas 2000-03-10
2972 */
2973Datum
2975{
2978 TimestampTz result;
2979
2980 if (DATE_IS_NOBEGIN(date))
2981 TIMESTAMP_NOBEGIN(result);
2982 else if (DATE_IS_NOEND(date))
2983 TIMESTAMP_NOEND(result);
2984 else
2985 {
2986 /*
2987 * Date's range is wider than timestamp's, so check for boundaries.
2988 * Since dates have the same minimum values as timestamps, only upper
2989 * boundary need be checked for overflow.
2990 */
2992 ereport(ERROR,
2994 errmsg("date out of range for timestamp")));
2995 result = date * USECS_PER_DAY + time->time + time->zone * USECS_PER_SEC;
2996
2997 /*
2998 * Since it is possible to go beyond allowed timestamptz range because
2999 * of time zone, check for allowed timestamp range after adding tz.
3000 */
3001 if (!IS_VALID_TIMESTAMP(result))
3002 ereport(ERROR,
3004 errmsg("date out of range for timestamp")));
3005 }
3006
3007 PG_RETURN_TIMESTAMP(result);
3008}
3009
3010
3011/* timetz_part() and extract_timetz()
3012 * Extract specified field from time type.
3013 */
3014static Datum
3016{
3020 int type,
3021 val;
3022 char *lowunits;
3023
3026 false);
3027
3028 type = DecodeUnits(0, lowunits, &val);
3029 if (type == UNKNOWN_FIELD)
3031
3032 if (type == UNITS)
3033 {
3034 int tz;
3035 fsec_t fsec;
3036 struct pg_tm tt,
3037 *tm = &tt;
3038
3039 timetz2tm(time, tm, &fsec, &tz);
3040
3041 switch (val)
3042 {
3043 case DTK_TZ:
3044 intresult = -tz;
3045 break;
3046
3047 case DTK_TZ_MINUTE:
3049 break;
3050
3051 case DTK_TZ_HOUR:
3052 intresult = -tz / SECS_PER_HOUR;
3053 break;
3054
3055 case DTK_MICROSEC:
3056 intresult = tm->tm_sec * INT64CONST(1000000) + fsec;
3057 break;
3058
3059 case DTK_MILLISEC:
3060 if (retnumeric)
3061 /*---
3062 * tm->tm_sec * 1000 + fsec / 1000
3063 * = (tm->tm_sec * 1'000'000 + fsec) / 1000
3064 */
3066 else
3067 PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + fsec / 1000.0);
3068 break;
3069
3070 case DTK_SECOND:
3071 if (retnumeric)
3072 /*---
3073 * tm->tm_sec + fsec / 1'000'000
3074 * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
3075 */
3077 else
3078 PG_RETURN_FLOAT8(tm->tm_sec + fsec / 1000000.0);
3079 break;
3080
3081 case DTK_MINUTE:
3082 intresult = tm->tm_min;
3083 break;
3084
3085 case DTK_HOUR:
3086 intresult = tm->tm_hour;
3087 break;
3088
3089 case DTK_DAY:
3090 case DTK_MONTH:
3091 case DTK_QUARTER:
3092 case DTK_YEAR:
3093 case DTK_DECADE:
3094 case DTK_CENTURY:
3095 case DTK_MILLENNIUM:
3096 default:
3097 ereport(ERROR,
3099 errmsg("unit \"%s\" not supported for type %s",
3101 intresult = 0;
3102 }
3103 }
3104 else if (type == RESERV && val == DTK_EPOCH)
3105 {
3106 if (retnumeric)
3107 /*---
3108 * time->time / 1'000'000 + time->zone
3109 * = (time->time + time->zone * 1'000'000) / 1'000'000
3110 */
3111 PG_RETURN_NUMERIC(int64_div_fast_to_numeric(time->time + time->zone * INT64CONST(1000000), 6));
3112 else
3113 PG_RETURN_FLOAT8(time->time / 1000000.0 + time->zone);
3114 }
3115 else
3116 {
3117 ereport(ERROR,
3119 errmsg("unit \"%s\" not recognized for type %s",
3121 intresult = 0;
3122 }
3123
3124 if (retnumeric)
3126 else
3128}
3129
3130
3131Datum
3133{
3134 return timetz_part_common(fcinfo, false);
3135}
3136
3137Datum
3139{
3140 return timetz_part_common(fcinfo, true);
3141}
3142
3143/* timetz_zone()
3144 * Encode time with time zone type with specified time zone.
3145 * Applies DST rules as of the transaction start time.
3146 */
3147Datum
3149{
3152 TimeTzADT *result;
3153 int tz;
3154 char tzname[TZ_STRLEN_MAX + 1];
3155 int type,
3156 val;
3157 pg_tz *tzp;
3158
3159 /*
3160 * Look up the requested timezone.
3161 */
3163
3164 type = DecodeTimezoneName(tzname, &val, &tzp);
3165
3167 {
3168 /* fixed-offset abbreviation */
3169 tz = -val;
3170 }
3171 else if (type == TZNAME_DYNTZ)
3172 {
3173 /* dynamic-offset abbreviation, resolve using transaction start time */
3175 int isdst;
3176
3178 }
3179 else
3180 {
3181 /* Get the offset-from-GMT that is valid now for the zone name */
3183 struct pg_tm tm;
3184 fsec_t fsec;
3185
3186 if (timestamp2tm(now, &tz, &tm, &fsec, NULL, tzp) != 0)
3187 ereport(ERROR,
3189 errmsg("timestamp out of range")));
3190 }
3191
3192 result = palloc_object(TimeTzADT);
3193
3194 result->time = t->time + (t->zone - tz) * USECS_PER_SEC;
3195 /* C99 modulo has the wrong sign convention for negative input */
3196 while (result->time < INT64CONST(0))
3197 result->time += USECS_PER_DAY;
3198 if (result->time >= USECS_PER_DAY)
3199 result->time %= USECS_PER_DAY;
3200
3201 result->zone = tz;
3202
3203 PG_RETURN_TIMETZADT_P(result);
3204}
3205
3206/* timetz_izone()
3207 * Encode time with time zone type with specified time interval as time zone.
3208 */
3209Datum
3211{
3214 TimeTzADT *result;
3215 int tz;
3216
3218 ereport(ERROR,
3220 errmsg("interval time zone \"%s\" must be finite",
3222 PointerGetDatum(zone))))));
3223
3224 if (zone->month != 0 || zone->day != 0)
3225 ereport(ERROR,
3227 errmsg("interval time zone \"%s\" must not include months or days",
3229 PointerGetDatum(zone))))));
3230
3231 tz = -(zone->time / USECS_PER_SEC);
3232
3233 result = palloc_object(TimeTzADT);
3234
3235 result->time = time->time + (time->zone - tz) * USECS_PER_SEC;
3236 /* C99 modulo has the wrong sign convention for negative input */
3237 while (result->time < INT64CONST(0))
3238 result->time += USECS_PER_DAY;
3239 if (result->time >= USECS_PER_DAY)
3240 result->time %= USECS_PER_DAY;
3241
3242 result->zone = tz;
3243
3244 PG_RETURN_TIMETZADT_P(result);
3245}
3246
3247/* timetz_at_local()
3248 *
3249 * Unlike for timestamp[tz]_at_local, the type for timetz does not flip between
3250 * time with/without time zone, so we cannot just call the conversion function.
3251 */
3252Datum
#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:4259
Numeric int64_div_fast_to_numeric(int64 val1, int log10val2)
Definition numeric.c:4280
Datum numeric_in(PG_FUNCTION_ARGS)
Definition numeric.c:626
Datum interval_out(PG_FUNCTION_ARGS)
Definition timestamp.c:964
int timestamp_cmp_internal(Timestamp dt1, Timestamp dt2)
Definition timestamp.c:2201
Datum in_range_timestamp_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3867
void GetEpochTime(struct pg_tm *tm)
Definition timestamp.c:2159
Datum timestamp_pl_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3081
int date2isoweek(int year, int mon, int mday)
Definition timestamp.c:5286
Datum timestamp_mi_interval(PG_FUNCTION_ARGS)
Definition timestamp.c:3198
int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
Definition timestamp.c:1901
Datum now(PG_FUNCTION_ARGS)
Definition timestamp.c:1600
int date2isoyear(int year, int mon, int mday)
Definition timestamp.c:5341
#define INT64CONST(x)
Definition c.h:632
#define Assert(condition)
Definition c.h:945
int64_t int64
Definition c.h:615
int32_t int32
Definition c.h:614
uint64_t uint64
Definition c.h:619
uint32_t uint32
Definition c.h:618
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:937
int32 date_cmp_timestamp_internal(DateADT dateVal, Timestamp dt2)
Definition date.c:768
Datum date_send(PG_FUNCTION_ARGS)
Definition date.c:225
Datum timetz_izone(PG_FUNCTION_ARGS)
Definition date.c:3210
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:2491
Datum timestamp_ne_date(PG_FUNCTION_ARGS)
Definition date.c:946
Datum date_ne_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:883
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:2331
Datum time_eq(PG_FUNCTION_ARGS)
Definition date.c:1768
Datum timetz_send(PG_FUNCTION_ARGS)
Definition date.c:2459
Datum timetztypmodout(PG_FUNCTION_ARGS)
Definition date.c:2479
#define TIMETZ_GT(t1, t2)
Datum timestamp_ge_date(PG_FUNCTION_ARGS)
Definition date.c:982
static char * anytime_typmodout(bool istz, int32 typmod)
Definition date.c:87
Datum timetz_pl_interval(PG_FUNCTION_ARGS)
Definition date.c:2684
Datum timetz_smaller(PG_FUNCTION_ARGS)
Definition date.c:2667
Datum timetypmodin(PG_FUNCTION_ARGS)
Definition date.c:1646
Datum date_lt_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:892
Datum make_time(PG_FUNCTION_ARGS)
Definition date.c:1665
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:2186
Datum date_gt_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:901
Datum date_lt_timestamp(PG_FUNCTION_ARGS)
Definition date.c:804
Datum timetz_ne(PG_FUNCTION_ARGS)
Definition date.c:2567
Datum time_interval(PG_FUNCTION_ARGS)
Definition date.c:2077
Datum date_eq(PG_FUNCTION_ARGS)
Definition date.c:384
Datum timetz_larger(PG_FUNCTION_ARGS)
Definition date.c:2653
Datum time_le(PG_FUNCTION_ARGS)
Definition date.c:1795
Datum timetz_part(PG_FUNCTION_ARGS)
Definition date.c:3132
Datum in_range_timetz_interval(PG_FUNCTION_ARGS)
Definition date.c:2738
Datum extract_time(PG_FUNCTION_ARGS)
Definition date.c:2337
Datum interval_time(PG_FUNCTION_ARGS)
Definition date.c:2100
TimestampTz date2timestamptz_safe(DateADT dateVal, Node *escontext)
Definition date.c:671
Datum date_mi_interval(PG_FUNCTION_ARGS)
Definition date.c:1296
Datum hashdateextended(PG_FUNCTION_ARGS)
Definition date.c:511
Datum date_eq_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:874
bool float_time_overflows(int hour, int min, double sec)
Definition date.c:1539
Datum timetz_gt(PG_FUNCTION_ARGS)
Definition date.c:2594
Datum timetz_at_local(PG_FUNCTION_ARGS)
Definition date.c:3253
Datum timestamp_gt_date(PG_FUNCTION_ARGS)
Definition date.c:964
Datum date_finite(PG_FUNCTION_ARGS)
Definition date.c:517
DateADT timestamp2date_safe(Timestamp timestamp, Node *escontext)
Definition date.c:1350
Datum in_range_date_interval(PG_FUNCTION_ARGS)
Definition date.c:1069
Datum time_cmp(PG_FUNCTION_ARGS)
Definition date.c:1822
Datum timestamp_time(PG_FUNCTION_ARGS)
Definition date.c:1993
Datum time_mi_time(PG_FUNCTION_ARGS)
Definition date.c:2121
Datum time_ge(PG_FUNCTION_ARGS)
Definition date.c:1813
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:2054
static Datum timetz_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition date.c:3015
Datum date_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:1386
Datum date_ne_timestamp(PG_FUNCTION_ARGS)
Definition date.c:795
Datum timestamptz_ge_date(PG_FUNCTION_ARGS)
Definition date.c:1045
Datum date_eq_timestamp(PG_FUNCTION_ARGS)
Definition date.c:786
int tm2time(struct pg_tm *tm, fsec_t fsec, TimeADT *result)
Definition date.c:1504
Datum timetz_ge(PG_FUNCTION_ARGS)
Definition date.c:2603
Datum timestamp_lt_date(PG_FUNCTION_ARGS)
Definition date.c:955
Datum timestamptz_lt_date(PG_FUNCTION_ARGS)
Definition date.c:1018
Datum timetz_cmp(PG_FUNCTION_ARGS)
Definition date.c:2612
TimeADT GetSQLLocalTime(int32 typmod)
Definition date.c:363
Datum timetztypmodin(PG_FUNCTION_ARGS)
Definition date.c:2471
Datum timetz_recv(PG_FUNCTION_ARGS)
Definition date.c:2423
static TimestampTz date2timestamptz(DateADT dateVal)
Definition date.c:729
Datum time_recv(PG_FUNCTION_ARGS)
Definition date.c:1609
Datum time_mi_interval(PG_FUNCTION_ARGS)
Definition date.c:2163
Datum time_support(PG_FUNCTION_ARGS)
Definition date.c:1693
int tm2timetz(struct pg_tm *tm, fsec_t fsec, int tz, TimeTzADT *result)
Definition date.c:2351
Datum date_out(PG_FUNCTION_ARGS)
Definition date.c:178
DateADT timestamptz2date_safe(TimestampTz timestamp, Node *escontext)
Definition date.c:1424
Datum timetz_time(PG_FUNCTION_ARGS)
Definition date.c:2903
Datum timetz_in(PG_FUNCTION_ARGS)
Definition date.c:2361
Datum time_timetz(PG_FUNCTION_ARGS)
Definition date.c:2916
Datum time_lt(PG_FUNCTION_ARGS)
Definition date.c:1786
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:1515
Datum timetz_mi_interval(PG_FUNCTION_ARGS)
Definition date.c:2711
Datum extract_timetz(PG_FUNCTION_ARGS)
Definition date.c:3138
Datum date_ge_timestamp(PG_FUNCTION_ARGS)
Definition date.c:831
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:1276
Datum overlaps_timetz(PG_FUNCTION_ARGS)
Definition date.c:2783
static Datum time_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition date.c:2228
Datum time_gt(PG_FUNCTION_ARGS)
Definition date.c:1804
Datum date_recv(PG_FUNCTION_ARGS)
Definition date.c:203
Datum timetz_lt(PG_FUNCTION_ARGS)
Definition date.c:2576
Datum time_out(PG_FUNCTION_ARGS)
Definition date.c:1589
Datum date_cmp_timestamp(PG_FUNCTION_ARGS)
Definition date.c:840
Datum time_hash(PG_FUNCTION_ARGS)
Definition date.c:1835
Datum time_larger(PG_FUNCTION_ARGS)
Definition date.c:1847
#define TIMETZ_LT(t1, t2)
Datum time_smaller(PG_FUNCTION_ARGS)
Definition date.c:1856
Datum time_ne(PG_FUNCTION_ARGS)
Definition date.c:1777
DateADT GetSQLCurrentDate(void)
Definition date.c:310
Datum timetz_eq(PG_FUNCTION_ARGS)
Definition date.c:2558
Datum date_gt_timestamp(PG_FUNCTION_ARGS)
Definition date.c:813
Datum timestamptz_timetz(PG_FUNCTION_ARGS)
Definition date.c:2942
void AdjustTimeForTypmod(TimeADT *time, int32 typmod)
Definition date.c:1733
Datum date_le_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:910
Datum date_pli(PG_FUNCTION_ARGS)
Definition date.c:562
Datum extract_date(PG_FUNCTION_ARGS)
Definition date.c:1096
Datum timestamptz_date(PG_FUNCTION_ARGS)
Definition date.c:1401
Datum timetz_le(PG_FUNCTION_ARGS)
Definition date.c:2585
Datum date_lt(PG_FUNCTION_ARGS)
Definition date.c:402
Datum timetz_hash(PG_FUNCTION_ARGS)
Definition date.c:2621
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:2531
Datum timestamptz_gt_date(PG_FUNCTION_ARGS)
Definition date.c:1027
Datum hashdate(PG_FUNCTION_ARGS)
Definition date.c:505
Datum timestamp_date(PG_FUNCTION_ARGS)
Definition date.c:1327
Datum date_ge(PG_FUNCTION_ARGS)
Definition date.c:429
Datum time_in(PG_FUNCTION_ARGS)
Definition date.c:1462
Datum time_hash_extended(PG_FUNCTION_ARGS)
Definition date.c:1841
Datum time_pl_interval(PG_FUNCTION_ARGS)
Definition date.c:2140
Datum datetimetz_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:2974
int time2tm(TimeADT time, struct pg_tm *tm, fsec_t *fsec)
Definition date.c:1576
Datum timestamptz_ne_date(PG_FUNCTION_ARGS)
Definition date.c:1009
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:973
Datum timetypmodout(PG_FUNCTION_ARGS)
Definition date.c:1654
Datum timestamptz_eq_date(PG_FUNCTION_ARGS)
Definition date.c:1000
Datum timetz_scale(PG_FUNCTION_ARGS)
Definition date.c:2513
Datum timestamptz_cmp_date(PG_FUNCTION_ARGS)
Definition date.c:1054
Datum date_ge_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:919
Datum timetz_hash_extended(PG_FUNCTION_ARGS)
Definition date.c:2637
Datum date_skipsupport(PG_FUNCTION_ARGS)
Definition date.c:492
Datum timetz_zone(PG_FUNCTION_ARGS)
Definition date.c:3148
Datum date_cmp_timestamptz(PG_FUNCTION_ARGS)
Definition date.c:928
int32 date_cmp_timestamptz_internal(DateADT dateVal, TimestampTz dt2)
Definition date.c:849
double date2timestamp_no_overflow(DateADT dateVal)
Definition date.c:745
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:822
Datum time_send(PG_FUNCTION_ARGS)
Definition date.c:1635
Datum date_mi(PG_FUNCTION_ARGS)
Definition date.c:545
Datum timestamp_cmp_date(PG_FUNCTION_ARGS)
Definition date.c:991
Datum date_ne(PG_FUNCTION_ARGS)
Definition date.c:393
Datum time_scale(PG_FUNCTION_ARGS)
Definition date.c:1713
Datum timestamptz_time(PG_FUNCTION_ARGS)
Definition date.c:2023
#define TIMEADT_LT(t1, t2)
Datum timetz_out(PG_FUNCTION_ARGS)
Definition date.c:2402
Datum overlaps_time(PG_FUNCTION_ARGS)
Definition date.c:1871
Datum date_timestamp(PG_FUNCTION_ARGS)
Definition date.c:1313
Datum timestamptz_le_date(PG_FUNCTION_ARGS)
Definition date.c:1036
#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:278
#define WARNING
Definition elog.h:36
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define ereport(elevel,...)
Definition elog.h:150
struct SortSupportData * SortSupport
Definition execnodes.h:60
#define palloc_object(type)
Definition fe_memutils.h:74
#define PG_RETURN_VOID()
Definition fmgr.h:350
#define PG_GETARG_OID(n)
Definition fmgr.h:275
#define PG_RETURN_UINT32(x)
Definition fmgr.h:356
#define PG_GETARG_TEXT_PP(n)
Definition fmgr.h:310
#define PG_RETURN_BYTEA_P(x)
Definition fmgr.h:373
#define DirectFunctionCall2(func, arg1, arg2)
Definition fmgr.h:686
#define PG_GETARG_FLOAT8(n)
Definition fmgr.h:283
#define PG_RETURN_FLOAT8(x)
Definition fmgr.h:369
#define PG_GETARG_POINTER(n)
Definition fmgr.h:277
#define PG_RETURN_CSTRING(x)
Definition fmgr.h:364
#define PG_ARGISNULL(n)
Definition fmgr.h:209
#define DirectFunctionCall1(func, arg1)
Definition fmgr.h:684
#define PG_GETARG_DATUM(n)
Definition fmgr.h:268
#define PG_GETARG_CSTRING(n)
Definition fmgr.h:278
#define PG_RETURN_NULL()
Definition fmgr.h:346
#define PG_GETARG_INT64(n)
Definition fmgr.h:284
#define PG_RETURN_UINT64(x)
Definition fmgr.h:371
#define PG_RETURN_INT32(x)
Definition fmgr.h:355
#define PG_GETARG_INT32(n)
Definition fmgr.h:269
#define PG_GETARG_BOOL(n)
Definition fmgr.h:274
#define DirectFunctionCall5(func, arg1, arg2, arg3, arg4, arg5)
Definition fmgr.h:692
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition fmgr.h:688
#define PG_RETURN_POINTER(x)
Definition fmgr.h:363
#define PG_FUNCTION_ARGS
Definition fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition fmgr.h:360
char * format_type_be(Oid type_oid)
int DateStyle
Definition globals.c:125
static Datum hash_uint32(uint32 k)
Definition hashfn.h:43
static Datum hash_uint32_extended(uint32 k, uint64 seed)
Definition hashfn.h:49
const char * str
Datum hashint8extended(PG_FUNCTION_ARGS)
Definition hashfunc.c: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 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
int32 day
Definition timestamp.h:51
int32 month
Definition timestamp.h:52
TimeOffset time
Definition timestamp.h:49
Definition nodes.h:135
SkipSupportIncDec decrement
Definition skipsupport.h:91
SkipSupportIncDec increment
Definition skipsupport.h:92
int(* comparator)(Datum x, Datum y, SortSupport ssup)
TimeADT time
Definition date.h:27
int32 zone
Definition date.h:28
Definition pgtime.h:35
int tm_hour
Definition pgtime.h:38
int tm_mday
Definition pgtime.h:39
int tm_mon
Definition pgtime.h:40
int tm_min
Definition pgtime.h:37
int tm_sec
Definition pgtime.h:36
int tm_year
Definition pgtime.h:41
Definition pgtz.h:66
Definition c.h:778
Definition zic.c:99
int ssup_datum_int32_cmp(Datum x, Datum y, SortSupport ssup)
Definition tuplesort.c:3436
#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