PostgreSQL Source Code  git master
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-2018, 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 <time.h>
22 
23 #include "access/hash.h"
24 #include "access/xact.h"
25 #include "libpq/pqformat.h"
26 #include "miscadmin.h"
27 #include "parser/scansup.h"
28 #include "utils/array.h"
29 #include "utils/builtins.h"
30 #include "utils/date.h"
31 #include "utils/datetime.h"
32 #include "utils/nabstime.h"
33 #include "utils/sortsupport.h"
34 
35 /*
36  * gcc's -ffast-math switch breaks routines that expect exact results from
37  * expressions like timeval / SECS_PER_HOUR, where timeval is double.
38  */
39 #ifdef __FAST_MATH__
40 #error -ffast-math is known to break this code
41 #endif
42 
43 
44 static int tm2time(struct pg_tm *tm, fsec_t fsec, TimeADT *result);
45 static int tm2timetz(struct pg_tm *tm, fsec_t fsec, int tz, TimeTzADT *result);
46 static void AdjustTimeForTypmod(TimeADT *time, int32 typmod);
47 
48 
49 /* common code for timetypmodin and timetztypmodin */
50 static int32
51 anytime_typmodin(bool istz, ArrayType *ta)
52 {
53  int32 *tl;
54  int n;
55 
56  tl = ArrayGetIntegerTypmods(ta, &n);
57 
58  /*
59  * we're not too tense about good error message here because grammar
60  * shouldn't allow wrong number of modifiers for TIME
61  */
62  if (n != 1)
63  ereport(ERROR,
64  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
65  errmsg("invalid type modifier")));
66 
67  return anytime_typmod_check(istz, tl[0]);
68 }
69 
70 /* exported so parse_expr.c can use it */
71 int32
72 anytime_typmod_check(bool istz, int32 typmod)
73 {
74  if (typmod < 0)
75  ereport(ERROR,
76  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
77  errmsg("TIME(%d)%s precision must not be negative",
78  typmod, (istz ? " WITH TIME ZONE" : ""))));
79  if (typmod > MAX_TIME_PRECISION)
80  {
82  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
83  errmsg("TIME(%d)%s precision reduced to maximum allowed, %d",
84  typmod, (istz ? " WITH TIME ZONE" : ""),
86  typmod = MAX_TIME_PRECISION;
87  }
88 
89  return typmod;
90 }
91 
92 /* common code for timetypmodout and timetztypmodout */
93 static char *
94 anytime_typmodout(bool istz, int32 typmod)
95 {
96  const char *tz = istz ? " with time zone" : " without time zone";
97 
98  if (typmod >= 0)
99  return psprintf("(%d)%s", (int) typmod, tz);
100  else
101  return psprintf("%s", tz);
102 }
103 
104 
105 /*****************************************************************************
106  * Date ADT
107  *****************************************************************************/
108 
109 
110 /* date_in()
111  * Given date text string, convert to internal date format.
112  */
113 Datum
115 {
116  char *str = PG_GETARG_CSTRING(0);
117  DateADT date;
118  fsec_t fsec;
119  struct pg_tm tt,
120  *tm = &tt;
121  int tzp;
122  int dtype;
123  int nf;
124  int dterr;
125  char *field[MAXDATEFIELDS];
126  int ftype[MAXDATEFIELDS];
127  char workbuf[MAXDATELEN + 1];
128 
129  dterr = ParseDateTime(str, workbuf, sizeof(workbuf),
130  field, ftype, MAXDATEFIELDS, &nf);
131  if (dterr == 0)
132  dterr = DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tzp);
133  if (dterr != 0)
134  DateTimeParseError(dterr, str, "date");
135 
136  switch (dtype)
137  {
138  case DTK_DATE:
139  break;
140 
141  case DTK_CURRENT:
142  ereport(ERROR,
143  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
144  errmsg("date/time value \"current\" is no longer supported")));
145 
146  GetCurrentDateTime(tm);
147  break;
148 
149  case DTK_EPOCH:
150  GetEpochTime(tm);
151  break;
152 
153  case DTK_LATE:
154  DATE_NOEND(date);
155  PG_RETURN_DATEADT(date);
156 
157  case DTK_EARLY:
158  DATE_NOBEGIN(date);
159  PG_RETURN_DATEADT(date);
160 
161  default:
162  DateTimeParseError(DTERR_BAD_FORMAT, str, "date");
163  break;
164  }
165 
166  /* Prevent overflow in Julian-day routines */
167  if (!IS_VALID_JULIAN(tm->tm_year, tm->tm_mon, tm->tm_mday))
168  ereport(ERROR,
169  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
170  errmsg("date out of range: \"%s\"", str)));
171 
172  date = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE;
173 
174  /* Now check for just-out-of-range dates */
175  if (!IS_VALID_DATE(date))
176  ereport(ERROR,
177  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
178  errmsg("date out of range: \"%s\"", str)));
179 
180  PG_RETURN_DATEADT(date);
181 }
182 
183 /* date_out()
184  * Given internal format date, convert to text string.
185  */
186 Datum
188 {
190  char *result;
191  struct pg_tm tt,
192  *tm = &tt;
193  char buf[MAXDATELEN + 1];
194 
195  if (DATE_NOT_FINITE(date))
196  EncodeSpecialDate(date, buf);
197  else
198  {
200  &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
201  EncodeDateOnly(tm, DateStyle, buf);
202  }
203 
204  result = pstrdup(buf);
205  PG_RETURN_CSTRING(result);
206 }
207 
208 /*
209  * date_recv - converts external binary format to date
210  */
211 Datum
213 {
215  DateADT result;
216 
217  result = (DateADT) pq_getmsgint(buf, sizeof(DateADT));
218 
219  /* Limit to the same range that date_in() accepts. */
220  if (DATE_NOT_FINITE(result))
221  /* ok */ ;
222  else if (!IS_VALID_DATE(result))
223  ereport(ERROR,
224  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
225  errmsg("date out of range")));
226 
227  PG_RETURN_DATEADT(result);
228 }
229 
230 /*
231  * date_send - converts date to binary format
232  */
233 Datum
235 {
238 
239  pq_begintypsend(&buf);
240  pq_sendint32(&buf, date);
242 }
243 
244 /*
245  * make_date - date constructor
246  */
247 Datum
249 {
250  struct pg_tm tm;
251  DateADT date;
252  int dterr;
253  bool bc = false;
254 
255  tm.tm_year = PG_GETARG_INT32(0);
256  tm.tm_mon = PG_GETARG_INT32(1);
257  tm.tm_mday = PG_GETARG_INT32(2);
258 
259  /* Handle negative years as BC */
260  if (tm.tm_year < 0)
261  {
262  bc = true;
263  tm.tm_year = -tm.tm_year;
264  }
265 
266  dterr = ValidateDate(DTK_DATE_M, false, false, bc, &tm);
267 
268  if (dterr != 0)
269  ereport(ERROR,
270  (errcode(ERRCODE_DATETIME_FIELD_OVERFLOW),
271  errmsg("date field value out of range: %d-%02d-%02d",
272  tm.tm_year, tm.tm_mon, tm.tm_mday)));
273 
274  /* Prevent overflow in Julian-day routines */
275  if (!IS_VALID_JULIAN(tm.tm_year, tm.tm_mon, tm.tm_mday))
276  ereport(ERROR,
277  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
278  errmsg("date out of range: %d-%02d-%02d",
279  tm.tm_year, tm.tm_mon, tm.tm_mday)));
280 
281  date = date2j(tm.tm_year, tm.tm_mon, tm.tm_mday) - POSTGRES_EPOCH_JDATE;
282 
283  /* Now check for just-out-of-range dates */
284  if (!IS_VALID_DATE(date))
285  ereport(ERROR,
286  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
287  errmsg("date out of range: %d-%02d-%02d",
288  tm.tm_year, tm.tm_mon, tm.tm_mday)));
289 
290  PG_RETURN_DATEADT(date);
291 }
292 
293 /*
294  * Convert reserved date values to string.
295  */
296 void
298 {
299  if (DATE_IS_NOBEGIN(dt))
300  strcpy(str, EARLY);
301  else if (DATE_IS_NOEND(dt))
302  strcpy(str, LATE);
303  else /* shouldn't happen */
304  elog(ERROR, "invalid argument for EncodeSpecialDate");
305 }
306 
307 
308 /*
309  * GetSQLCurrentDate -- implements CURRENT_DATE
310  */
311 DateADT
313 {
314  TimestampTz ts;
315  struct pg_tm tt,
316  *tm = &tt;
317  fsec_t fsec;
318  int tz;
319 
321 
322  if (timestamp2tm(ts, &tz, tm, &fsec, NULL, NULL) != 0)
323  ereport(ERROR,
324  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
325  errmsg("timestamp out of range")));
326 
327  return date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE;
328 }
329 
330 /*
331  * GetSQLCurrentTime -- implements CURRENT_TIME, CURRENT_TIME(n)
332  */
333 TimeTzADT *
335 {
336  TimeTzADT *result;
337  TimestampTz ts;
338  struct pg_tm tt,
339  *tm = &tt;
340  fsec_t fsec;
341  int tz;
342 
344 
345  if (timestamp2tm(ts, &tz, tm, &fsec, NULL, NULL) != 0)
346  ereport(ERROR,
347  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
348  errmsg("timestamp out of range")));
349 
350  result = (TimeTzADT *) palloc(sizeof(TimeTzADT));
351  tm2timetz(tm, fsec, tz, result);
352  AdjustTimeForTypmod(&(result->time), typmod);
353  return result;
354 }
355 
356 /*
357  * GetSQLLocalTime -- implements LOCALTIME, LOCALTIME(n)
358  */
359 TimeADT
361 {
362  TimeADT result;
363  TimestampTz ts;
364  struct pg_tm tt,
365  *tm = &tt;
366  fsec_t fsec;
367  int tz;
368 
370 
371  if (timestamp2tm(ts, &tz, tm, &fsec, NULL, NULL) != 0)
372  ereport(ERROR,
373  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
374  errmsg("timestamp out of range")));
375 
376  tm2time(tm, fsec, &result);
377  AdjustTimeForTypmod(&result, typmod);
378  return result;
379 }
380 
381 
382 /*
383  * Comparison functions for dates
384  */
385 
386 Datum
388 {
389  DateADT dateVal1 = PG_GETARG_DATEADT(0);
390  DateADT dateVal2 = PG_GETARG_DATEADT(1);
391 
392  PG_RETURN_BOOL(dateVal1 == dateVal2);
393 }
394 
395 Datum
397 {
398  DateADT dateVal1 = PG_GETARG_DATEADT(0);
399  DateADT dateVal2 = PG_GETARG_DATEADT(1);
400 
401  PG_RETURN_BOOL(dateVal1 != dateVal2);
402 }
403 
404 Datum
406 {
407  DateADT dateVal1 = PG_GETARG_DATEADT(0);
408  DateADT dateVal2 = PG_GETARG_DATEADT(1);
409 
410  PG_RETURN_BOOL(dateVal1 < dateVal2);
411 }
412 
413 Datum
415 {
416  DateADT dateVal1 = PG_GETARG_DATEADT(0);
417  DateADT dateVal2 = PG_GETARG_DATEADT(1);
418 
419  PG_RETURN_BOOL(dateVal1 <= dateVal2);
420 }
421 
422 Datum
424 {
425  DateADT dateVal1 = PG_GETARG_DATEADT(0);
426  DateADT dateVal2 = PG_GETARG_DATEADT(1);
427 
428  PG_RETURN_BOOL(dateVal1 > dateVal2);
429 }
430 
431 Datum
433 {
434  DateADT dateVal1 = PG_GETARG_DATEADT(0);
435  DateADT dateVal2 = PG_GETARG_DATEADT(1);
436 
437  PG_RETURN_BOOL(dateVal1 >= dateVal2);
438 }
439 
440 Datum
442 {
443  DateADT dateVal1 = PG_GETARG_DATEADT(0);
444  DateADT dateVal2 = PG_GETARG_DATEADT(1);
445 
446  if (dateVal1 < dateVal2)
447  PG_RETURN_INT32(-1);
448  else if (dateVal1 > dateVal2)
449  PG_RETURN_INT32(1);
450  PG_RETURN_INT32(0);
451 }
452 
453 static int
455 {
456  DateADT a = DatumGetDateADT(x);
457  DateADT b = DatumGetDateADT(y);
458 
459  if (a < b)
460  return -1;
461  else if (a > b)
462  return 1;
463  return 0;
464 }
465 
466 Datum
468 {
470 
471  ssup->comparator = date_fastcmp;
472  PG_RETURN_VOID();
473 }
474 
475 Datum
477 {
479 
481 }
482 
483 Datum
485 {
486  DateADT dateVal1 = PG_GETARG_DATEADT(0);
487  DateADT dateVal2 = PG_GETARG_DATEADT(1);
488 
489  PG_RETURN_DATEADT((dateVal1 > dateVal2) ? dateVal1 : dateVal2);
490 }
491 
492 Datum
494 {
495  DateADT dateVal1 = PG_GETARG_DATEADT(0);
496  DateADT dateVal2 = PG_GETARG_DATEADT(1);
497 
498  PG_RETURN_DATEADT((dateVal1 < dateVal2) ? dateVal1 : dateVal2);
499 }
500 
501 /* Compute difference between two dates in days.
502  */
503 Datum
505 {
506  DateADT dateVal1 = PG_GETARG_DATEADT(0);
507  DateADT dateVal2 = PG_GETARG_DATEADT(1);
508 
509  if (DATE_NOT_FINITE(dateVal1) || DATE_NOT_FINITE(dateVal2))
510  ereport(ERROR,
511  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
512  errmsg("cannot subtract infinite dates")));
513 
514  PG_RETURN_INT32((int32) (dateVal1 - dateVal2));
515 }
516 
517 /* Add a number of days to a date, giving a new date.
518  * Must handle both positive and negative numbers of days.
519  */
520 Datum
522 {
523  DateADT dateVal = PG_GETARG_DATEADT(0);
525  DateADT result;
526 
527  if (DATE_NOT_FINITE(dateVal))
528  PG_RETURN_DATEADT(dateVal); /* can't change infinity */
529 
530  result = dateVal + days;
531 
532  /* Check for integer overflow and out-of-allowed-range */
533  if ((days >= 0 ? (result < dateVal) : (result > dateVal)) ||
534  !IS_VALID_DATE(result))
535  ereport(ERROR,
536  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
537  errmsg("date out of range")));
538 
539  PG_RETURN_DATEADT(result);
540 }
541 
542 /* Subtract a number of days from a date, giving a new date.
543  */
544 Datum
546 {
547  DateADT dateVal = PG_GETARG_DATEADT(0);
549  DateADT result;
550 
551  if (DATE_NOT_FINITE(dateVal))
552  PG_RETURN_DATEADT(dateVal); /* can't change infinity */
553 
554  result = dateVal - days;
555 
556  /* Check for integer overflow and out-of-allowed-range */
557  if ((days >= 0 ? (result > dateVal) : (result < dateVal)) ||
558  !IS_VALID_DATE(result))
559  ereport(ERROR,
560  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
561  errmsg("date out of range")));
562 
563  PG_RETURN_DATEADT(result);
564 }
565 
566 /*
567  * Internal routines for promoting date to timestamp and timestamp with
568  * time zone
569  */
570 
571 static Timestamp
573 {
574  Timestamp result;
575 
576  if (DATE_IS_NOBEGIN(dateVal))
577  TIMESTAMP_NOBEGIN(result);
578  else if (DATE_IS_NOEND(dateVal))
579  TIMESTAMP_NOEND(result);
580  else
581  {
582  /*
583  * Date's range is wider than timestamp's, so check for boundaries.
584  * Since dates have the same minimum values as timestamps, only upper
585  * boundary need be checked for overflow.
586  */
587  if (dateVal >= (TIMESTAMP_END_JULIAN - POSTGRES_EPOCH_JDATE))
588  ereport(ERROR,
589  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
590  errmsg("date out of range for timestamp")));
591 
592  /* date is days since 2000, timestamp is microseconds since same... */
593  result = dateVal * USECS_PER_DAY;
594  }
595 
596  return result;
597 }
598 
599 static TimestampTz
601 {
602  TimestampTz result;
603  struct pg_tm tt,
604  *tm = &tt;
605  int tz;
606 
607  if (DATE_IS_NOBEGIN(dateVal))
608  TIMESTAMP_NOBEGIN(result);
609  else if (DATE_IS_NOEND(dateVal))
610  TIMESTAMP_NOEND(result);
611  else
612  {
613  /*
614  * Date's range is wider than timestamp's, so check for boundaries.
615  * Since dates have the same minimum values as timestamps, only upper
616  * boundary need be checked for overflow.
617  */
618  if (dateVal >= (TIMESTAMP_END_JULIAN - POSTGRES_EPOCH_JDATE))
619  ereport(ERROR,
620  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
621  errmsg("date out of range for timestamp")));
622 
623  j2date(dateVal + POSTGRES_EPOCH_JDATE,
624  &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
625  tm->tm_hour = 0;
626  tm->tm_min = 0;
627  tm->tm_sec = 0;
629 
630  result = dateVal * USECS_PER_DAY + tz * USECS_PER_SEC;
631 
632  /*
633  * Since it is possible to go beyond allowed timestamptz range because
634  * of time zone, check for allowed timestamp range after adding tz.
635  */
636  if (!IS_VALID_TIMESTAMP(result))
637  ereport(ERROR,
638  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
639  errmsg("date out of range for timestamp")));
640  }
641 
642  return result;
643 }
644 
645 /*
646  * date2timestamp_no_overflow
647  *
648  * This is chartered to produce a double value that is numerically
649  * equivalent to the corresponding Timestamp value, if the date is in the
650  * valid range of Timestamps, but in any case not throw an overflow error.
651  * We can do this since the numerical range of double is greater than
652  * that of non-erroneous timestamps. The results are currently only
653  * used for statistical estimation purposes.
654  */
655 double
657 {
658  double result;
659 
660  if (DATE_IS_NOBEGIN(dateVal))
661  result = -DBL_MAX;
662  else if (DATE_IS_NOEND(dateVal))
663  result = DBL_MAX;
664  else
665  {
666  /* date is days since 2000, timestamp is microseconds since same... */
667  result = dateVal * (double) USECS_PER_DAY;
668  }
669 
670  return result;
671 }
672 
673 
674 /*
675  * Crosstype comparison functions for dates
676  */
677 
678 Datum
680 {
681  DateADT dateVal = PG_GETARG_DATEADT(0);
683  Timestamp dt1;
684 
685  dt1 = date2timestamp(dateVal);
686 
687  PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) == 0);
688 }
689 
690 Datum
692 {
693  DateADT dateVal = PG_GETARG_DATEADT(0);
695  Timestamp dt1;
696 
697  dt1 = date2timestamp(dateVal);
698 
699  PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) != 0);
700 }
701 
702 Datum
704 {
705  DateADT dateVal = PG_GETARG_DATEADT(0);
707  Timestamp dt1;
708 
709  dt1 = date2timestamp(dateVal);
710 
711  PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) < 0);
712 }
713 
714 Datum
716 {
717  DateADT dateVal = PG_GETARG_DATEADT(0);
719  Timestamp dt1;
720 
721  dt1 = date2timestamp(dateVal);
722 
723  PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) > 0);
724 }
725 
726 Datum
728 {
729  DateADT dateVal = PG_GETARG_DATEADT(0);
731  Timestamp dt1;
732 
733  dt1 = date2timestamp(dateVal);
734 
735  PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) <= 0);
736 }
737 
738 Datum
740 {
741  DateADT dateVal = PG_GETARG_DATEADT(0);
743  Timestamp dt1;
744 
745  dt1 = date2timestamp(dateVal);
746 
747  PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) >= 0);
748 }
749 
750 Datum
752 {
753  DateADT dateVal = PG_GETARG_DATEADT(0);
755  Timestamp dt1;
756 
757  dt1 = date2timestamp(dateVal);
758 
760 }
761 
762 Datum
764 {
765  DateADT dateVal = PG_GETARG_DATEADT(0);
767  TimestampTz dt1;
768 
769  dt1 = date2timestamptz(dateVal);
770 
772 }
773 
774 Datum
776 {
777  DateADT dateVal = PG_GETARG_DATEADT(0);
779  TimestampTz dt1;
780 
781  dt1 = date2timestamptz(dateVal);
782 
784 }
785 
786 Datum
788 {
789  DateADT dateVal = PG_GETARG_DATEADT(0);
791  TimestampTz dt1;
792 
793  dt1 = date2timestamptz(dateVal);
794 
796 }
797 
798 Datum
800 {
801  DateADT dateVal = PG_GETARG_DATEADT(0);
803  TimestampTz dt1;
804 
805  dt1 = date2timestamptz(dateVal);
806 
808 }
809 
810 Datum
812 {
813  DateADT dateVal = PG_GETARG_DATEADT(0);
815  TimestampTz dt1;
816 
817  dt1 = date2timestamptz(dateVal);
818 
820 }
821 
822 Datum
824 {
825  DateADT dateVal = PG_GETARG_DATEADT(0);
827  TimestampTz dt1;
828 
829  dt1 = date2timestamptz(dateVal);
830 
832 }
833 
834 Datum
836 {
837  DateADT dateVal = PG_GETARG_DATEADT(0);
839  TimestampTz dt1;
840 
841  dt1 = date2timestamptz(dateVal);
842 
844 }
845 
846 Datum
848 {
850  DateADT dateVal = PG_GETARG_DATEADT(1);
851  Timestamp dt2;
852 
853  dt2 = date2timestamp(dateVal);
854 
855  PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) == 0);
856 }
857 
858 Datum
860 {
862  DateADT dateVal = PG_GETARG_DATEADT(1);
863  Timestamp dt2;
864 
865  dt2 = date2timestamp(dateVal);
866 
867  PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) != 0);
868 }
869 
870 Datum
872 {
874  DateADT dateVal = PG_GETARG_DATEADT(1);
875  Timestamp dt2;
876 
877  dt2 = date2timestamp(dateVal);
878 
879  PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) < 0);
880 }
881 
882 Datum
884 {
886  DateADT dateVal = PG_GETARG_DATEADT(1);
887  Timestamp dt2;
888 
889  dt2 = date2timestamp(dateVal);
890 
891  PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) > 0);
892 }
893 
894 Datum
896 {
898  DateADT dateVal = PG_GETARG_DATEADT(1);
899  Timestamp dt2;
900 
901  dt2 = date2timestamp(dateVal);
902 
903  PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) <= 0);
904 }
905 
906 Datum
908 {
910  DateADT dateVal = PG_GETARG_DATEADT(1);
911  Timestamp dt2;
912 
913  dt2 = date2timestamp(dateVal);
914 
915  PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) >= 0);
916 }
917 
918 Datum
920 {
922  DateADT dateVal = PG_GETARG_DATEADT(1);
923  Timestamp dt2;
924 
925  dt2 = date2timestamp(dateVal);
926 
928 }
929 
930 Datum
932 {
934  DateADT dateVal = PG_GETARG_DATEADT(1);
935  TimestampTz dt2;
936 
937  dt2 = date2timestamptz(dateVal);
938 
940 }
941 
942 Datum
944 {
946  DateADT dateVal = PG_GETARG_DATEADT(1);
947  TimestampTz dt2;
948 
949  dt2 = date2timestamptz(dateVal);
950 
952 }
953 
954 Datum
956 {
958  DateADT dateVal = PG_GETARG_DATEADT(1);
959  TimestampTz dt2;
960 
961  dt2 = date2timestamptz(dateVal);
962 
964 }
965 
966 Datum
968 {
970  DateADT dateVal = PG_GETARG_DATEADT(1);
971  TimestampTz dt2;
972 
973  dt2 = date2timestamptz(dateVal);
974 
976 }
977 
978 Datum
980 {
982  DateADT dateVal = PG_GETARG_DATEADT(1);
983  TimestampTz dt2;
984 
985  dt2 = date2timestamptz(dateVal);
986 
988 }
989 
990 Datum
992 {
994  DateADT dateVal = PG_GETARG_DATEADT(1);
995  TimestampTz dt2;
996 
997  dt2 = date2timestamptz(dateVal);
998 
1000 }
1001 
1002 Datum
1004 {
1006  DateADT dateVal = PG_GETARG_DATEADT(1);
1007  TimestampTz dt2;
1008 
1009  dt2 = date2timestamptz(dateVal);
1010 
1012 }
1013 
1014 /*
1015  * in_range support function for date.
1016  *
1017  * We implement this by promoting the dates to timestamp (without time zone)
1018  * and then using the timestamp-and-interval in_range function.
1019  */
1020 Datum
1022 {
1024  DateADT base = PG_GETARG_DATEADT(1);
1025  Interval *offset = PG_GETARG_INTERVAL_P(2);
1026  bool sub = PG_GETARG_BOOL(3);
1027  bool less = PG_GETARG_BOOL(4);
1028  Timestamp valStamp;
1029  Timestamp baseStamp;
1030 
1031  valStamp = date2timestamp(val);
1032  baseStamp = date2timestamp(base);
1033 
1035  TimestampGetDatum(valStamp),
1036  TimestampGetDatum(baseStamp),
1037  IntervalPGetDatum(offset),
1038  BoolGetDatum(sub),
1039  BoolGetDatum(less));
1040 }
1041 
1042 
1043 /* Add an interval to a date, giving a new date.
1044  * Must handle both positive and negative intervals.
1045  *
1046  * We implement this by promoting the date to timestamp (without time zone)
1047  * and then using the timestamp plus interval function.
1048  */
1049 Datum
1051 {
1052  DateADT dateVal = PG_GETARG_DATEADT(0);
1053  Interval *span = PG_GETARG_INTERVAL_P(1);
1054  Timestamp dateStamp;
1055 
1056  dateStamp = date2timestamp(dateVal);
1057 
1059  TimestampGetDatum(dateStamp),
1060  PointerGetDatum(span));
1061 }
1062 
1063 /* Subtract an interval from a date, giving a new date.
1064  * Must handle both positive and negative intervals.
1065  *
1066  * We implement this by promoting the date to timestamp (without time zone)
1067  * and then using the timestamp minus interval function.
1068  */
1069 Datum
1071 {
1072  DateADT dateVal = PG_GETARG_DATEADT(0);
1073  Interval *span = PG_GETARG_INTERVAL_P(1);
1074  Timestamp dateStamp;
1075 
1076  dateStamp = date2timestamp(dateVal);
1077 
1079  TimestampGetDatum(dateStamp),
1080  PointerGetDatum(span));
1081 }
1082 
1083 /* date_timestamp()
1084  * Convert date to timestamp data type.
1085  */
1086 Datum
1088 {
1089  DateADT dateVal = PG_GETARG_DATEADT(0);
1090  Timestamp result;
1091 
1092  result = date2timestamp(dateVal);
1093 
1094  PG_RETURN_TIMESTAMP(result);
1095 }
1096 
1097 /* timestamp_date()
1098  * Convert timestamp to date data type.
1099  */
1100 Datum
1102 {
1104  DateADT result;
1105  struct pg_tm tt,
1106  *tm = &tt;
1107  fsec_t fsec;
1108 
1109  if (TIMESTAMP_IS_NOBEGIN(timestamp))
1110  DATE_NOBEGIN(result);
1111  else if (TIMESTAMP_IS_NOEND(timestamp))
1112  DATE_NOEND(result);
1113  else
1114  {
1115  if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
1116  ereport(ERROR,
1117  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
1118  errmsg("timestamp out of range")));
1119 
1120  result = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE;
1121  }
1122 
1123  PG_RETURN_DATEADT(result);
1124 }
1125 
1126 
1127 /* date_timestamptz()
1128  * Convert date to timestamp with time zone data type.
1129  */
1130 Datum
1132 {
1133  DateADT dateVal = PG_GETARG_DATEADT(0);
1134  TimestampTz result;
1135 
1136  result = date2timestamptz(dateVal);
1137 
1138  PG_RETURN_TIMESTAMP(result);
1139 }
1140 
1141 
1142 /* timestamptz_date()
1143  * Convert timestamp with time zone to date data type.
1144  */
1145 Datum
1147 {
1149  DateADT result;
1150  struct pg_tm tt,
1151  *tm = &tt;
1152  fsec_t fsec;
1153  int tz;
1154 
1155  if (TIMESTAMP_IS_NOBEGIN(timestamp))
1156  DATE_NOBEGIN(result);
1157  else if (TIMESTAMP_IS_NOEND(timestamp))
1158  DATE_NOEND(result);
1159  else
1160  {
1161  if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
1162  ereport(ERROR,
1163  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
1164  errmsg("timestamp out of range")));
1165 
1166  result = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE;
1167  }
1168 
1169  PG_RETURN_DATEADT(result);
1170 }
1171 
1172 
1173 /* abstime_date()
1174  * Convert abstime to date data type.
1175  */
1176 Datum
1178 {
1179  AbsoluteTime abstime = PG_GETARG_ABSOLUTETIME(0);
1180  DateADT result;
1181  struct pg_tm tt,
1182  *tm = &tt;
1183  int tz;
1184 
1185  switch (abstime)
1186  {
1187  case INVALID_ABSTIME:
1188  ereport(ERROR,
1189  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1190  errmsg("cannot convert reserved abstime value to date")));
1191  result = 0; /* keep compiler quiet */
1192  break;
1193 
1194  case NOSTART_ABSTIME:
1195  DATE_NOBEGIN(result);
1196  break;
1197 
1198  case NOEND_ABSTIME:
1199  DATE_NOEND(result);
1200  break;
1201 
1202  default:
1203  abstime2tm(abstime, &tz, tm, NULL);
1204  /* Prevent overflow in Julian-day routines */
1205  if (!IS_VALID_JULIAN(tm->tm_year, tm->tm_mon, tm->tm_mday))
1206  ereport(ERROR,
1207  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
1208  errmsg("abstime out of range for date")));
1209  result = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE;
1210  /* Now check for just-out-of-range dates */
1211  if (!IS_VALID_DATE(result))
1212  ereport(ERROR,
1213  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
1214  errmsg("abstime out of range for date")));
1215  break;
1216  }
1217 
1218  PG_RETURN_DATEADT(result);
1219 }
1220 
1221 
1222 /*****************************************************************************
1223  * Time ADT
1224  *****************************************************************************/
1225 
1226 Datum
1228 {
1229  char *str = PG_GETARG_CSTRING(0);
1230 
1231 #ifdef NOT_USED
1232  Oid typelem = PG_GETARG_OID(1);
1233 #endif
1234  int32 typmod = PG_GETARG_INT32(2);
1235  TimeADT result;
1236  fsec_t fsec;
1237  struct pg_tm tt,
1238  *tm = &tt;
1239  int tz;
1240  int nf;
1241  int dterr;
1242  char workbuf[MAXDATELEN + 1];
1243  char *field[MAXDATEFIELDS];
1244  int dtype;
1245  int ftype[MAXDATEFIELDS];
1246 
1247  dterr = ParseDateTime(str, workbuf, sizeof(workbuf),
1248  field, ftype, MAXDATEFIELDS, &nf);
1249  if (dterr == 0)
1250  dterr = DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec, &tz);
1251  if (dterr != 0)
1252  DateTimeParseError(dterr, str, "time");
1253 
1254  tm2time(tm, fsec, &result);
1255  AdjustTimeForTypmod(&result, typmod);
1256 
1257  PG_RETURN_TIMEADT(result);
1258 }
1259 
1260 /* tm2time()
1261  * Convert a tm structure to a time data type.
1262  */
1263 static int
1264 tm2time(struct pg_tm *tm, fsec_t fsec, TimeADT *result)
1265 {
1266  *result = ((((tm->tm_hour * MINS_PER_HOUR + tm->tm_min) * SECS_PER_MINUTE) + tm->tm_sec)
1267  * USECS_PER_SEC) + fsec;
1268  return 0;
1269 }
1270 
1271 /* time2tm()
1272  * Convert time data type to POSIX time structure.
1273  *
1274  * For dates within the range of pg_time_t, convert to the local time zone.
1275  * If out of this range, leave as UTC (in practice that could only happen
1276  * if pg_time_t is just 32 bits) - thomas 97/05/27
1277  */
1278 int
1279 time2tm(TimeADT time, struct pg_tm *tm, fsec_t *fsec)
1280 {
1281  tm->tm_hour = time / USECS_PER_HOUR;
1282  time -= tm->tm_hour * USECS_PER_HOUR;
1283  tm->tm_min = time / USECS_PER_MINUTE;
1284  time -= tm->tm_min * USECS_PER_MINUTE;
1285  tm->tm_sec = time / USECS_PER_SEC;
1286  time -= tm->tm_sec * USECS_PER_SEC;
1287  *fsec = time;
1288  return 0;
1289 }
1290 
1291 Datum
1293 {
1294  TimeADT time = PG_GETARG_TIMEADT(0);
1295  char *result;
1296  struct pg_tm tt,
1297  *tm = &tt;
1298  fsec_t fsec;
1299  char buf[MAXDATELEN + 1];
1300 
1301  time2tm(time, tm, &fsec);
1302  EncodeTimeOnly(tm, fsec, false, 0, DateStyle, buf);
1303 
1304  result = pstrdup(buf);
1305  PG_RETURN_CSTRING(result);
1306 }
1307 
1308 /*
1309  * time_recv - converts external binary format to time
1310  */
1311 Datum
1313 {
1315 
1316 #ifdef NOT_USED
1317  Oid typelem = PG_GETARG_OID(1);
1318 #endif
1319  int32 typmod = PG_GETARG_INT32(2);
1320  TimeADT result;
1321 
1322  result = pq_getmsgint64(buf);
1323 
1324  if (result < INT64CONST(0) || result > USECS_PER_DAY)
1325  ereport(ERROR,
1326  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
1327  errmsg("time out of range")));
1328 
1329  AdjustTimeForTypmod(&result, typmod);
1330 
1331  PG_RETURN_TIMEADT(result);
1332 }
1333 
1334 /*
1335  * time_send - converts time to binary format
1336  */
1337 Datum
1339 {
1340  TimeADT time = PG_GETARG_TIMEADT(0);
1342 
1343  pq_begintypsend(&buf);
1344  pq_sendint64(&buf, time);
1346 }
1347 
1348 Datum
1350 {
1352 
1353  PG_RETURN_INT32(anytime_typmodin(false, ta));
1354 }
1355 
1356 Datum
1358 {
1359  int32 typmod = PG_GETARG_INT32(0);
1360 
1361  PG_RETURN_CSTRING(anytime_typmodout(false, typmod));
1362 }
1363 
1364 /*
1365  * make_time - time constructor
1366  */
1367 Datum
1369 {
1370  int tm_hour = PG_GETARG_INT32(0);
1371  int tm_min = PG_GETARG_INT32(1);
1372  double sec = PG_GETARG_FLOAT8(2);
1373  TimeADT time;
1374 
1375  /* This should match the checks in DecodeTimeOnly */
1376  if (tm_hour < 0 || tm_min < 0 || tm_min > MINS_PER_HOUR - 1 ||
1377  sec < 0 || sec > SECS_PER_MINUTE ||
1378  tm_hour > HOURS_PER_DAY ||
1379  /* test for > 24:00:00 */
1380  (tm_hour == HOURS_PER_DAY && (tm_min > 0 || sec > 0)))
1381  ereport(ERROR,
1382  (errcode(ERRCODE_DATETIME_FIELD_OVERFLOW),
1383  errmsg("time field value out of range: %d:%02d:%02g",
1384  tm_hour, tm_min, sec)));
1385 
1386  /* This should match tm2time */
1387  time = (((tm_hour * MINS_PER_HOUR + tm_min) * SECS_PER_MINUTE)
1388  * USECS_PER_SEC) + rint(sec * USECS_PER_SEC);
1389 
1390  PG_RETURN_TIMEADT(time);
1391 }
1392 
1393 
1394 /* time_transform()
1395  * Flatten calls to time_scale() and timetz_scale() that solely represent
1396  * increases in allowed precision.
1397  */
1398 Datum
1400 {
1402  (Node *) PG_GETARG_POINTER(0)));
1403 }
1404 
1405 /* time_scale()
1406  * Adjust time type for specified scale factor.
1407  * Used by PostgreSQL type system to stuff columns.
1408  */
1409 Datum
1411 {
1412  TimeADT time = PG_GETARG_TIMEADT(0);
1413  int32 typmod = PG_GETARG_INT32(1);
1414  TimeADT result;
1415 
1416  result = time;
1417  AdjustTimeForTypmod(&result, typmod);
1418 
1419  PG_RETURN_TIMEADT(result);
1420 }
1421 
1422 /* AdjustTimeForTypmod()
1423  * Force the precision of the time value to a specified value.
1424  * Uses *exactly* the same code as in AdjustTimestampForTypemod()
1425  * but we make a separate copy because those types do not
1426  * have a fundamental tie together but rather a coincidence of
1427  * implementation. - thomas
1428  */
1429 static void
1431 {
1432  static const int64 TimeScales[MAX_TIME_PRECISION + 1] = {
1433  INT64CONST(1000000),
1434  INT64CONST(100000),
1435  INT64CONST(10000),
1436  INT64CONST(1000),
1437  INT64CONST(100),
1438  INT64CONST(10),
1439  INT64CONST(1)
1440  };
1441 
1442  static const int64 TimeOffsets[MAX_TIME_PRECISION + 1] = {
1443  INT64CONST(500000),
1444  INT64CONST(50000),
1445  INT64CONST(5000),
1446  INT64CONST(500),
1447  INT64CONST(50),
1448  INT64CONST(5),
1449  INT64CONST(0)
1450  };
1451 
1452  if (typmod >= 0 && typmod <= MAX_TIME_PRECISION)
1453  {
1454  if (*time >= INT64CONST(0))
1455  *time = ((*time + TimeOffsets[typmod]) / TimeScales[typmod]) *
1456  TimeScales[typmod];
1457  else
1458  *time = -((((-*time) + TimeOffsets[typmod]) / TimeScales[typmod]) *
1459  TimeScales[typmod]);
1460  }
1461 }
1462 
1463 
1464 Datum
1466 {
1467  TimeADT time1 = PG_GETARG_TIMEADT(0);
1468  TimeADT time2 = PG_GETARG_TIMEADT(1);
1469 
1470  PG_RETURN_BOOL(time1 == time2);
1471 }
1472 
1473 Datum
1475 {
1476  TimeADT time1 = PG_GETARG_TIMEADT(0);
1477  TimeADT time2 = PG_GETARG_TIMEADT(1);
1478 
1479  PG_RETURN_BOOL(time1 != time2);
1480 }
1481 
1482 Datum
1484 {
1485  TimeADT time1 = PG_GETARG_TIMEADT(0);
1486  TimeADT time2 = PG_GETARG_TIMEADT(1);
1487 
1488  PG_RETURN_BOOL(time1 < time2);
1489 }
1490 
1491 Datum
1493 {
1494  TimeADT time1 = PG_GETARG_TIMEADT(0);
1495  TimeADT time2 = PG_GETARG_TIMEADT(1);
1496 
1497  PG_RETURN_BOOL(time1 <= time2);
1498 }
1499 
1500 Datum
1502 {
1503  TimeADT time1 = PG_GETARG_TIMEADT(0);
1504  TimeADT time2 = PG_GETARG_TIMEADT(1);
1505 
1506  PG_RETURN_BOOL(time1 > time2);
1507 }
1508 
1509 Datum
1511 {
1512  TimeADT time1 = PG_GETARG_TIMEADT(0);
1513  TimeADT time2 = PG_GETARG_TIMEADT(1);
1514 
1515  PG_RETURN_BOOL(time1 >= time2);
1516 }
1517 
1518 Datum
1520 {
1521  TimeADT time1 = PG_GETARG_TIMEADT(0);
1522  TimeADT time2 = PG_GETARG_TIMEADT(1);
1523 
1524  if (time1 < time2)
1525  PG_RETURN_INT32(-1);
1526  if (time1 > time2)
1527  PG_RETURN_INT32(1);
1528  PG_RETURN_INT32(0);
1529 }
1530 
1531 Datum
1533 {
1534  return hashint8(fcinfo);
1535 }
1536 
1537 Datum
1539 {
1540  return hashint8extended(fcinfo);
1541 }
1542 
1543 Datum
1545 {
1546  TimeADT time1 = PG_GETARG_TIMEADT(0);
1547  TimeADT time2 = PG_GETARG_TIMEADT(1);
1548 
1549  PG_RETURN_TIMEADT((time1 > time2) ? time1 : time2);
1550 }
1551 
1552 Datum
1554 {
1555  TimeADT time1 = PG_GETARG_TIMEADT(0);
1556  TimeADT time2 = PG_GETARG_TIMEADT(1);
1557 
1558  PG_RETURN_TIMEADT((time1 < time2) ? time1 : time2);
1559 }
1560 
1561 /* overlaps_time() --- implements the SQL OVERLAPS operator.
1562  *
1563  * Algorithm is per SQL spec. This is much harder than you'd think
1564  * because the spec requires us to deliver a non-null answer in some cases
1565  * where some of the inputs are null.
1566  */
1567 Datum
1569 {
1570  /*
1571  * The arguments are TimeADT, but we leave them as generic Datums to avoid
1572  * dereferencing nulls (TimeADT is pass-by-reference!)
1573  */
1574  Datum ts1 = PG_GETARG_DATUM(0);
1575  Datum te1 = PG_GETARG_DATUM(1);
1576  Datum ts2 = PG_GETARG_DATUM(2);
1577  Datum te2 = PG_GETARG_DATUM(3);
1578  bool ts1IsNull = PG_ARGISNULL(0);
1579  bool te1IsNull = PG_ARGISNULL(1);
1580  bool ts2IsNull = PG_ARGISNULL(2);
1581  bool te2IsNull = PG_ARGISNULL(3);
1582 
1583 #define TIMEADT_GT(t1,t2) \
1584  (DatumGetTimeADT(t1) > DatumGetTimeADT(t2))
1585 #define TIMEADT_LT(t1,t2) \
1586  (DatumGetTimeADT(t1) < DatumGetTimeADT(t2))
1587 
1588  /*
1589  * If both endpoints of interval 1 are null, the result is null (unknown).
1590  * If just one endpoint is null, take ts1 as the non-null one. Otherwise,
1591  * take ts1 as the lesser endpoint.
1592  */
1593  if (ts1IsNull)
1594  {
1595  if (te1IsNull)
1596  PG_RETURN_NULL();
1597  /* swap null for non-null */
1598  ts1 = te1;
1599  te1IsNull = true;
1600  }
1601  else if (!te1IsNull)
1602  {
1603  if (TIMEADT_GT(ts1, te1))
1604  {
1605  Datum tt = ts1;
1606 
1607  ts1 = te1;
1608  te1 = tt;
1609  }
1610  }
1611 
1612  /* Likewise for interval 2. */
1613  if (ts2IsNull)
1614  {
1615  if (te2IsNull)
1616  PG_RETURN_NULL();
1617  /* swap null for non-null */
1618  ts2 = te2;
1619  te2IsNull = true;
1620  }
1621  else if (!te2IsNull)
1622  {
1623  if (TIMEADT_GT(ts2, te2))
1624  {
1625  Datum tt = ts2;
1626 
1627  ts2 = te2;
1628  te2 = tt;
1629  }
1630  }
1631 
1632  /*
1633  * At this point neither ts1 nor ts2 is null, so we can consider three
1634  * cases: ts1 > ts2, ts1 < ts2, ts1 = ts2
1635  */
1636  if (TIMEADT_GT(ts1, ts2))
1637  {
1638  /*
1639  * This case is ts1 < te2 OR te1 < te2, which may look redundant but
1640  * in the presence of nulls it's not quite completely so.
1641  */
1642  if (te2IsNull)
1643  PG_RETURN_NULL();
1644  if (TIMEADT_LT(ts1, te2))
1645  PG_RETURN_BOOL(true);
1646  if (te1IsNull)
1647  PG_RETURN_NULL();
1648 
1649  /*
1650  * If te1 is not null then we had ts1 <= te1 above, and we just found
1651  * ts1 >= te2, hence te1 >= te2.
1652  */
1653  PG_RETURN_BOOL(false);
1654  }
1655  else if (TIMEADT_LT(ts1, ts2))
1656  {
1657  /* This case is ts2 < te1 OR te2 < te1 */
1658  if (te1IsNull)
1659  PG_RETURN_NULL();
1660  if (TIMEADT_LT(ts2, te1))
1661  PG_RETURN_BOOL(true);
1662  if (te2IsNull)
1663  PG_RETURN_NULL();
1664 
1665  /*
1666  * If te2 is not null then we had ts2 <= te2 above, and we just found
1667  * ts2 >= te1, hence te2 >= te1.
1668  */
1669  PG_RETURN_BOOL(false);
1670  }
1671  else
1672  {
1673  /*
1674  * For ts1 = ts2 the spec says te1 <> te2 OR te1 = te2, which is a
1675  * rather silly way of saying "true if both are nonnull, else null".
1676  */
1677  if (te1IsNull || te2IsNull)
1678  PG_RETURN_NULL();
1679  PG_RETURN_BOOL(true);
1680  }
1681 
1682 #undef TIMEADT_GT
1683 #undef TIMEADT_LT
1684 }
1685 
1686 /* timestamp_time()
1687  * Convert timestamp to time data type.
1688  */
1689 Datum
1691 {
1693  TimeADT result;
1694  struct pg_tm tt,
1695  *tm = &tt;
1696  fsec_t fsec;
1697 
1698  if (TIMESTAMP_NOT_FINITE(timestamp))
1699  PG_RETURN_NULL();
1700 
1701  if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
1702  ereport(ERROR,
1703  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
1704  errmsg("timestamp out of range")));
1705 
1706  /*
1707  * Could also do this with time = (timestamp / USECS_PER_DAY *
1708  * USECS_PER_DAY) - timestamp;
1709  */
1710  result = ((((tm->tm_hour * MINS_PER_HOUR + tm->tm_min) * SECS_PER_MINUTE) + tm->tm_sec) *
1711  USECS_PER_SEC) + fsec;
1712 
1713  PG_RETURN_TIMEADT(result);
1714 }
1715 
1716 /* timestamptz_time()
1717  * Convert timestamptz to time data type.
1718  */
1719 Datum
1721 {
1723  TimeADT result;
1724  struct pg_tm tt,
1725  *tm = &tt;
1726  int tz;
1727  fsec_t fsec;
1728 
1729  if (TIMESTAMP_NOT_FINITE(timestamp))
1730  PG_RETURN_NULL();
1731 
1732  if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
1733  ereport(ERROR,
1734  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
1735  errmsg("timestamp out of range")));
1736 
1737  /*
1738  * Could also do this with time = (timestamp / USECS_PER_DAY *
1739  * USECS_PER_DAY) - timestamp;
1740  */
1741  result = ((((tm->tm_hour * MINS_PER_HOUR + tm->tm_min) * SECS_PER_MINUTE) + tm->tm_sec) *
1742  USECS_PER_SEC) + fsec;
1743 
1744  PG_RETURN_TIMEADT(result);
1745 }
1746 
1747 /* datetime_timestamp()
1748  * Convert date and time to timestamp data type.
1749  */
1750 Datum
1752 {
1754  TimeADT time = PG_GETARG_TIMEADT(1);
1755  Timestamp result;
1756 
1757  result = date2timestamp(date);
1758  if (!TIMESTAMP_NOT_FINITE(result))
1759  {
1760  result += time;
1761  if (!IS_VALID_TIMESTAMP(result))
1762  ereport(ERROR,
1763  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
1764  errmsg("timestamp out of range")));
1765  }
1766 
1767  PG_RETURN_TIMESTAMP(result);
1768 }
1769 
1770 /* time_interval()
1771  * Convert time to interval data type.
1772  */
1773 Datum
1775 {
1776  TimeADT time = PG_GETARG_TIMEADT(0);
1777  Interval *result;
1778 
1779  result = (Interval *) palloc(sizeof(Interval));
1780 
1781  result->time = time;
1782  result->day = 0;
1783  result->month = 0;
1784 
1785  PG_RETURN_INTERVAL_P(result);
1786 }
1787 
1788 /* interval_time()
1789  * Convert interval to time data type.
1790  *
1791  * This is defined as producing the fractional-day portion of the interval.
1792  * Therefore, we can just ignore the months field. It is not real clear
1793  * what to do with negative intervals, but we choose to subtract the floor,
1794  * so that, say, '-2 hours' becomes '22:00:00'.
1795  */
1796 Datum
1798 {
1799  Interval *span = PG_GETARG_INTERVAL_P(0);
1800  TimeADT result;
1801  int64 days;
1802 
1803  result = span->time;
1804  if (result >= USECS_PER_DAY)
1805  {
1806  days = result / USECS_PER_DAY;
1807  result -= days * USECS_PER_DAY;
1808  }
1809  else if (result < 0)
1810  {
1811  days = (-result + USECS_PER_DAY - 1) / USECS_PER_DAY;
1812  result += days * USECS_PER_DAY;
1813  }
1814 
1815  PG_RETURN_TIMEADT(result);
1816 }
1817 
1818 /* time_mi_time()
1819  * Subtract two times to produce an interval.
1820  */
1821 Datum
1823 {
1824  TimeADT time1 = PG_GETARG_TIMEADT(0);
1825  TimeADT time2 = PG_GETARG_TIMEADT(1);
1826  Interval *result;
1827 
1828  result = (Interval *) palloc(sizeof(Interval));
1829 
1830  result->month = 0;
1831  result->day = 0;
1832  result->time = time1 - time2;
1833 
1834  PG_RETURN_INTERVAL_P(result);
1835 }
1836 
1837 /* time_pl_interval()
1838  * Add interval to time.
1839  */
1840 Datum
1842 {
1843  TimeADT time = PG_GETARG_TIMEADT(0);
1844  Interval *span = PG_GETARG_INTERVAL_P(1);
1845  TimeADT result;
1846 
1847  result = time + span->time;
1848  result -= result / USECS_PER_DAY * USECS_PER_DAY;
1849  if (result < INT64CONST(0))
1850  result += USECS_PER_DAY;
1851 
1852  PG_RETURN_TIMEADT(result);
1853 }
1854 
1855 /* time_mi_interval()
1856  * Subtract interval from time.
1857  */
1858 Datum
1860 {
1861  TimeADT time = PG_GETARG_TIMEADT(0);
1862  Interval *span = PG_GETARG_INTERVAL_P(1);
1863  TimeADT result;
1864 
1865  result = time - span->time;
1866  result -= result / USECS_PER_DAY * USECS_PER_DAY;
1867  if (result < INT64CONST(0))
1868  result += USECS_PER_DAY;
1869 
1870  PG_RETURN_TIMEADT(result);
1871 }
1872 
1873 /*
1874  * in_range support function for time.
1875  */
1876 Datum
1878 {
1880  TimeADT base = PG_GETARG_TIMEADT(1);
1881  Interval *offset = PG_GETARG_INTERVAL_P(2);
1882  bool sub = PG_GETARG_BOOL(3);
1883  bool less = PG_GETARG_BOOL(4);
1884  TimeADT sum;
1885 
1886  /*
1887  * Like time_pl_interval/time_mi_interval, we disregard the month and day
1888  * fields of the offset. So our test for negative should too.
1889  */
1890  if (offset->time < 0)
1891  ereport(ERROR,
1892  (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
1893  errmsg("invalid preceding or following size in window function")));
1894 
1895  /*
1896  * We can't use time_pl_interval/time_mi_interval here, because their
1897  * wraparound behavior would give wrong (or at least undesirable) answers.
1898  * Fortunately the equivalent non-wrapping behavior is trivial, especially
1899  * since we don't worry about integer overflow.
1900  */
1901  if (sub)
1902  sum = base - offset->time;
1903  else
1904  sum = base + offset->time;
1905 
1906  if (less)
1907  PG_RETURN_BOOL(val <= sum);
1908  else
1909  PG_RETURN_BOOL(val >= sum);
1910 }
1911 
1912 
1913 /* time_part()
1914  * Extract specified field from time type.
1915  */
1916 Datum
1918 {
1919  text *units = PG_GETARG_TEXT_PP(0);
1920  TimeADT time = PG_GETARG_TIMEADT(1);
1921  float8 result;
1922  int type,
1923  val;
1924  char *lowunits;
1925 
1926  lowunits = downcase_truncate_identifier(VARDATA_ANY(units),
1927  VARSIZE_ANY_EXHDR(units),
1928  false);
1929 
1930  type = DecodeUnits(0, lowunits, &val);
1931  if (type == UNKNOWN_FIELD)
1932  type = DecodeSpecial(0, lowunits, &val);
1933 
1934  if (type == UNITS)
1935  {
1936  fsec_t fsec;
1937  struct pg_tm tt,
1938  *tm = &tt;
1939 
1940  time2tm(time, tm, &fsec);
1941 
1942  switch (val)
1943  {
1944  case DTK_MICROSEC:
1945  result = tm->tm_sec * 1000000.0 + fsec;
1946  break;
1947 
1948  case DTK_MILLISEC:
1949  result = tm->tm_sec * 1000.0 + fsec / 1000.0;
1950  break;
1951 
1952  case DTK_SECOND:
1953  result = tm->tm_sec + fsec / 1000000.0;
1954  break;
1955 
1956  case DTK_MINUTE:
1957  result = tm->tm_min;
1958  break;
1959 
1960  case DTK_HOUR:
1961  result = tm->tm_hour;
1962  break;
1963 
1964  case DTK_TZ:
1965  case DTK_TZ_MINUTE:
1966  case DTK_TZ_HOUR:
1967  case DTK_DAY:
1968  case DTK_MONTH:
1969  case DTK_QUARTER:
1970  case DTK_YEAR:
1971  case DTK_DECADE:
1972  case DTK_CENTURY:
1973  case DTK_MILLENNIUM:
1974  case DTK_ISOYEAR:
1975  default:
1976  ereport(ERROR,
1977  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1978  errmsg("\"time\" units \"%s\" not recognized",
1979  lowunits)));
1980  result = 0;
1981  }
1982  }
1983  else if (type == RESERV && val == DTK_EPOCH)
1984  {
1985  result = time / 1000000.0;
1986  }
1987  else
1988  {
1989  ereport(ERROR,
1990  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1991  errmsg("\"time\" units \"%s\" not recognized",
1992  lowunits)));
1993  result = 0;
1994  }
1995 
1996  PG_RETURN_FLOAT8(result);
1997 }
1998 
1999 
2000 /*****************************************************************************
2001  * Time With Time Zone ADT
2002  *****************************************************************************/
2003 
2004 /* tm2timetz()
2005  * Convert a tm structure to a time data type.
2006  */
2007 static int
2008 tm2timetz(struct pg_tm *tm, fsec_t fsec, int tz, TimeTzADT *result)
2009 {
2010  result->time = ((((tm->tm_hour * MINS_PER_HOUR + tm->tm_min) * SECS_PER_MINUTE) + tm->tm_sec) *
2011  USECS_PER_SEC) + fsec;
2012  result->zone = tz;
2013 
2014  return 0;
2015 }
2016 
2017 Datum
2019 {
2020  char *str = PG_GETARG_CSTRING(0);
2021 
2022 #ifdef NOT_USED
2023  Oid typelem = PG_GETARG_OID(1);
2024 #endif
2025  int32 typmod = PG_GETARG_INT32(2);
2026  TimeTzADT *result;
2027  fsec_t fsec;
2028  struct pg_tm tt,
2029  *tm = &tt;
2030  int tz;
2031  int nf;
2032  int dterr;
2033  char workbuf[MAXDATELEN + 1];
2034  char *field[MAXDATEFIELDS];
2035  int dtype;
2036  int ftype[MAXDATEFIELDS];
2037 
2038  dterr = ParseDateTime(str, workbuf, sizeof(workbuf),
2039  field, ftype, MAXDATEFIELDS, &nf);
2040  if (dterr == 0)
2041  dterr = DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec, &tz);
2042  if (dterr != 0)
2043  DateTimeParseError(dterr, str, "time with time zone");
2044 
2045  result = (TimeTzADT *) palloc(sizeof(TimeTzADT));
2046  tm2timetz(tm, fsec, tz, result);
2047  AdjustTimeForTypmod(&(result->time), typmod);
2048 
2049  PG_RETURN_TIMETZADT_P(result);
2050 }
2051 
2052 Datum
2054 {
2055  TimeTzADT *time = PG_GETARG_TIMETZADT_P(0);
2056  char *result;
2057  struct pg_tm tt,
2058  *tm = &tt;
2059  fsec_t fsec;
2060  int tz;
2061  char buf[MAXDATELEN + 1];
2062 
2063  timetz2tm(time, tm, &fsec, &tz);
2064  EncodeTimeOnly(tm, fsec, true, tz, DateStyle, buf);
2065 
2066  result = pstrdup(buf);
2067  PG_RETURN_CSTRING(result);
2068 }
2069 
2070 /*
2071  * timetz_recv - converts external binary format to timetz
2072  */
2073 Datum
2075 {
2077 
2078 #ifdef NOT_USED
2079  Oid typelem = PG_GETARG_OID(1);
2080 #endif
2081  int32 typmod = PG_GETARG_INT32(2);
2082  TimeTzADT *result;
2083 
2084  result = (TimeTzADT *) palloc(sizeof(TimeTzADT));
2085 
2086  result->time = pq_getmsgint64(buf);
2087 
2088  if (result->time < INT64CONST(0) || result->time > USECS_PER_DAY)
2089  ereport(ERROR,
2090  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2091  errmsg("time out of range")));
2092 
2093  result->zone = pq_getmsgint(buf, sizeof(result->zone));
2094 
2095  /* Check for sane GMT displacement; see notes in datatype/timestamp.h */
2096  if (result->zone <= -TZDISP_LIMIT || result->zone >= TZDISP_LIMIT)
2097  ereport(ERROR,
2098  (errcode(ERRCODE_INVALID_TIME_ZONE_DISPLACEMENT_VALUE),
2099  errmsg("time zone displacement out of range")));
2100 
2101  AdjustTimeForTypmod(&(result->time), typmod);
2102 
2103  PG_RETURN_TIMETZADT_P(result);
2104 }
2105 
2106 /*
2107  * timetz_send - converts timetz to binary format
2108  */
2109 Datum
2111 {
2112  TimeTzADT *time = PG_GETARG_TIMETZADT_P(0);
2114 
2115  pq_begintypsend(&buf);
2116  pq_sendint64(&buf, time->time);
2117  pq_sendint32(&buf, time->zone);
2119 }
2120 
2121 Datum
2123 {
2125 
2126  PG_RETURN_INT32(anytime_typmodin(true, ta));
2127 }
2128 
2129 Datum
2131 {
2132  int32 typmod = PG_GETARG_INT32(0);
2133 
2134  PG_RETURN_CSTRING(anytime_typmodout(true, typmod));
2135 }
2136 
2137 
2138 /* timetz2tm()
2139  * Convert TIME WITH TIME ZONE data type to POSIX time structure.
2140  */
2141 int
2142 timetz2tm(TimeTzADT *time, struct pg_tm *tm, fsec_t *fsec, int *tzp)
2143 {
2144  TimeOffset trem = time->time;
2145 
2146  tm->tm_hour = trem / USECS_PER_HOUR;
2147  trem -= tm->tm_hour * USECS_PER_HOUR;
2148  tm->tm_min = trem / USECS_PER_MINUTE;
2149  trem -= tm->tm_min * USECS_PER_MINUTE;
2150  tm->tm_sec = trem / USECS_PER_SEC;
2151  *fsec = trem - tm->tm_sec * USECS_PER_SEC;
2152 
2153  if (tzp != NULL)
2154  *tzp = time->zone;
2155 
2156  return 0;
2157 }
2158 
2159 /* timetz_scale()
2160  * Adjust time type for specified scale factor.
2161  * Used by PostgreSQL type system to stuff columns.
2162  */
2163 Datum
2165 {
2166  TimeTzADT *time = PG_GETARG_TIMETZADT_P(0);
2167  int32 typmod = PG_GETARG_INT32(1);
2168  TimeTzADT *result;
2169 
2170  result = (TimeTzADT *) palloc(sizeof(TimeTzADT));
2171 
2172  result->time = time->time;
2173  result->zone = time->zone;
2174 
2175  AdjustTimeForTypmod(&(result->time), typmod);
2176 
2177  PG_RETURN_TIMETZADT_P(result);
2178 }
2179 
2180 
2181 static int
2183 {
2184  TimeOffset t1,
2185  t2;
2186 
2187  /* Primary sort is by true (GMT-equivalent) time */
2188  t1 = time1->time + (time1->zone * USECS_PER_SEC);
2189  t2 = time2->time + (time2->zone * USECS_PER_SEC);
2190 
2191  if (t1 > t2)
2192  return 1;
2193  if (t1 < t2)
2194  return -1;
2195 
2196  /*
2197  * If same GMT time, sort by timezone; we only want to say that two
2198  * timetz's are equal if both the time and zone parts are equal.
2199  */
2200  if (time1->zone > time2->zone)
2201  return 1;
2202  if (time1->zone < time2->zone)
2203  return -1;
2204 
2205  return 0;
2206 }
2207 
2208 Datum
2210 {
2211  TimeTzADT *time1 = PG_GETARG_TIMETZADT_P(0);
2212  TimeTzADT *time2 = PG_GETARG_TIMETZADT_P(1);
2213 
2214  PG_RETURN_BOOL(timetz_cmp_internal(time1, time2) == 0);
2215 }
2216 
2217 Datum
2219 {
2220  TimeTzADT *time1 = PG_GETARG_TIMETZADT_P(0);
2221  TimeTzADT *time2 = PG_GETARG_TIMETZADT_P(1);
2222 
2223  PG_RETURN_BOOL(timetz_cmp_internal(time1, time2) != 0);
2224 }
2225 
2226 Datum
2228 {
2229  TimeTzADT *time1 = PG_GETARG_TIMETZADT_P(0);
2230  TimeTzADT *time2 = PG_GETARG_TIMETZADT_P(1);
2231 
2232  PG_RETURN_BOOL(timetz_cmp_internal(time1, time2) < 0);
2233 }
2234 
2235 Datum
2237 {
2238  TimeTzADT *time1 = PG_GETARG_TIMETZADT_P(0);
2239  TimeTzADT *time2 = PG_GETARG_TIMETZADT_P(1);
2240 
2241  PG_RETURN_BOOL(timetz_cmp_internal(time1, time2) <= 0);
2242 }
2243 
2244 Datum
2246 {
2247  TimeTzADT *time1 = PG_GETARG_TIMETZADT_P(0);
2248  TimeTzADT *time2 = PG_GETARG_TIMETZADT_P(1);
2249 
2250  PG_RETURN_BOOL(timetz_cmp_internal(time1, time2) > 0);
2251 }
2252 
2253 Datum
2255 {
2256  TimeTzADT *time1 = PG_GETARG_TIMETZADT_P(0);
2257  TimeTzADT *time2 = PG_GETARG_TIMETZADT_P(1);
2258 
2259  PG_RETURN_BOOL(timetz_cmp_internal(time1, time2) >= 0);
2260 }
2261 
2262 Datum
2264 {
2265  TimeTzADT *time1 = PG_GETARG_TIMETZADT_P(0);
2266  TimeTzADT *time2 = PG_GETARG_TIMETZADT_P(1);
2267 
2268  PG_RETURN_INT32(timetz_cmp_internal(time1, time2));
2269 }
2270 
2271 Datum
2273 {
2274  TimeTzADT *key = PG_GETARG_TIMETZADT_P(0);
2275  uint32 thash;
2276 
2277  /*
2278  * To avoid any problems with padding bytes in the struct, we figure the
2279  * field hashes separately and XOR them.
2280  */
2282  Int64GetDatumFast(key->time)));
2283  thash ^= DatumGetUInt32(hash_uint32(key->zone));
2284  PG_RETURN_UINT32(thash);
2285 }
2286 
2287 Datum
2289 {
2290  TimeTzADT *key = PG_GETARG_TIMETZADT_P(0);
2291  Datum seed = PG_GETARG_DATUM(1);
2292  uint64 thash;
2293 
2294  /* Same approach as timetz_hash */
2296  Int64GetDatumFast(key->time),
2297  seed));
2299  DatumGetInt64(seed)));
2300  PG_RETURN_UINT64(thash);
2301 }
2302 
2303 Datum
2305 {
2306  TimeTzADT *time1 = PG_GETARG_TIMETZADT_P(0);
2307  TimeTzADT *time2 = PG_GETARG_TIMETZADT_P(1);
2308  TimeTzADT *result;
2309 
2310  if (timetz_cmp_internal(time1, time2) > 0)
2311  result = time1;
2312  else
2313  result = time2;
2314  PG_RETURN_TIMETZADT_P(result);
2315 }
2316 
2317 Datum
2319 {
2320  TimeTzADT *time1 = PG_GETARG_TIMETZADT_P(0);
2321  TimeTzADT *time2 = PG_GETARG_TIMETZADT_P(1);
2322  TimeTzADT *result;
2323 
2324  if (timetz_cmp_internal(time1, time2) < 0)
2325  result = time1;
2326  else
2327  result = time2;
2328  PG_RETURN_TIMETZADT_P(result);
2329 }
2330 
2331 /* timetz_pl_interval()
2332  * Add interval to timetz.
2333  */
2334 Datum
2336 {
2337  TimeTzADT *time = PG_GETARG_TIMETZADT_P(0);
2338  Interval *span = PG_GETARG_INTERVAL_P(1);
2339  TimeTzADT *result;
2340 
2341  result = (TimeTzADT *) palloc(sizeof(TimeTzADT));
2342 
2343  result->time = time->time + span->time;
2344  result->time -= result->time / USECS_PER_DAY * USECS_PER_DAY;
2345  if (result->time < INT64CONST(0))
2346  result->time += USECS_PER_DAY;
2347 
2348  result->zone = time->zone;
2349 
2350  PG_RETURN_TIMETZADT_P(result);
2351 }
2352 
2353 /* timetz_mi_interval()
2354  * Subtract interval from timetz.
2355  */
2356 Datum
2358 {
2359  TimeTzADT *time = PG_GETARG_TIMETZADT_P(0);
2360  Interval *span = PG_GETARG_INTERVAL_P(1);
2361  TimeTzADT *result;
2362 
2363  result = (TimeTzADT *) palloc(sizeof(TimeTzADT));
2364 
2365  result->time = time->time - span->time;
2366  result->time -= result->time / USECS_PER_DAY * USECS_PER_DAY;
2367  if (result->time < INT64CONST(0))
2368  result->time += USECS_PER_DAY;
2369 
2370  result->zone = time->zone;
2371 
2372  PG_RETURN_TIMETZADT_P(result);
2373 }
2374 
2375 /*
2376  * in_range support function for timetz.
2377  */
2378 Datum
2380 {
2382  TimeTzADT *base = PG_GETARG_TIMETZADT_P(1);
2383  Interval *offset = PG_GETARG_INTERVAL_P(2);
2384  bool sub = PG_GETARG_BOOL(3);
2385  bool less = PG_GETARG_BOOL(4);
2386  TimeTzADT sum;
2387 
2388  /*
2389  * Like timetz_pl_interval/timetz_mi_interval, we disregard the month and
2390  * day fields of the offset. So our test for negative should too.
2391  */
2392  if (offset->time < 0)
2393  ereport(ERROR,
2394  (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
2395  errmsg("invalid preceding or following size in window function")));
2396 
2397  /*
2398  * We can't use timetz_pl_interval/timetz_mi_interval here, because their
2399  * wraparound behavior would give wrong (or at least undesirable) answers.
2400  * Fortunately the equivalent non-wrapping behavior is trivial, especially
2401  * since we don't worry about integer overflow.
2402  */
2403  if (sub)
2404  sum.time = base->time - offset->time;
2405  else
2406  sum.time = base->time + offset->time;
2407  sum.zone = base->zone;
2408 
2409  if (less)
2410  PG_RETURN_BOOL(timetz_cmp_internal(val, &sum) <= 0);
2411  else
2412  PG_RETURN_BOOL(timetz_cmp_internal(val, &sum) >= 0);
2413 }
2414 
2415 /* overlaps_timetz() --- implements the SQL OVERLAPS operator.
2416  *
2417  * Algorithm is per SQL spec. This is much harder than you'd think
2418  * because the spec requires us to deliver a non-null answer in some cases
2419  * where some of the inputs are null.
2420  */
2421 Datum
2423 {
2424  /*
2425  * The arguments are TimeTzADT *, but we leave them as generic Datums for
2426  * convenience of notation --- and to avoid dereferencing nulls.
2427  */
2428  Datum ts1 = PG_GETARG_DATUM(0);
2429  Datum te1 = PG_GETARG_DATUM(1);
2430  Datum ts2 = PG_GETARG_DATUM(2);
2431  Datum te2 = PG_GETARG_DATUM(3);
2432  bool ts1IsNull = PG_ARGISNULL(0);
2433  bool te1IsNull = PG_ARGISNULL(1);
2434  bool ts2IsNull = PG_ARGISNULL(2);
2435  bool te2IsNull = PG_ARGISNULL(3);
2436 
2437 #define TIMETZ_GT(t1,t2) \
2438  DatumGetBool(DirectFunctionCall2(timetz_gt,t1,t2))
2439 #define TIMETZ_LT(t1,t2) \
2440  DatumGetBool(DirectFunctionCall2(timetz_lt,t1,t2))
2441 
2442  /*
2443  * If both endpoints of interval 1 are null, the result is null (unknown).
2444  * If just one endpoint is null, take ts1 as the non-null one. Otherwise,
2445  * take ts1 as the lesser endpoint.
2446  */
2447  if (ts1IsNull)
2448  {
2449  if (te1IsNull)
2450  PG_RETURN_NULL();
2451  /* swap null for non-null */
2452  ts1 = te1;
2453  te1IsNull = true;
2454  }
2455  else if (!te1IsNull)
2456  {
2457  if (TIMETZ_GT(ts1, te1))
2458  {
2459  Datum tt = ts1;
2460 
2461  ts1 = te1;
2462  te1 = tt;
2463  }
2464  }
2465 
2466  /* Likewise for interval 2. */
2467  if (ts2IsNull)
2468  {
2469  if (te2IsNull)
2470  PG_RETURN_NULL();
2471  /* swap null for non-null */
2472  ts2 = te2;
2473  te2IsNull = true;
2474  }
2475  else if (!te2IsNull)
2476  {
2477  if (TIMETZ_GT(ts2, te2))
2478  {
2479  Datum tt = ts2;
2480 
2481  ts2 = te2;
2482  te2 = tt;
2483  }
2484  }
2485 
2486  /*
2487  * At this point neither ts1 nor ts2 is null, so we can consider three
2488  * cases: ts1 > ts2, ts1 < ts2, ts1 = ts2
2489  */
2490  if (TIMETZ_GT(ts1, ts2))
2491  {
2492  /*
2493  * This case is ts1 < te2 OR te1 < te2, which may look redundant but
2494  * in the presence of nulls it's not quite completely so.
2495  */
2496  if (te2IsNull)
2497  PG_RETURN_NULL();
2498  if (TIMETZ_LT(ts1, te2))
2499  PG_RETURN_BOOL(true);
2500  if (te1IsNull)
2501  PG_RETURN_NULL();
2502 
2503  /*
2504  * If te1 is not null then we had ts1 <= te1 above, and we just found
2505  * ts1 >= te2, hence te1 >= te2.
2506  */
2507  PG_RETURN_BOOL(false);
2508  }
2509  else if (TIMETZ_LT(ts1, ts2))
2510  {
2511  /* This case is ts2 < te1 OR te2 < te1 */
2512  if (te1IsNull)
2513  PG_RETURN_NULL();
2514  if (TIMETZ_LT(ts2, te1))
2515  PG_RETURN_BOOL(true);
2516  if (te2IsNull)
2517  PG_RETURN_NULL();
2518 
2519  /*
2520  * If te2 is not null then we had ts2 <= te2 above, and we just found
2521  * ts2 >= te1, hence te2 >= te1.
2522  */
2523  PG_RETURN_BOOL(false);
2524  }
2525  else
2526  {
2527  /*
2528  * For ts1 = ts2 the spec says te1 <> te2 OR te1 = te2, which is a
2529  * rather silly way of saying "true if both are nonnull, else null".
2530  */
2531  if (te1IsNull || te2IsNull)
2532  PG_RETURN_NULL();
2533  PG_RETURN_BOOL(true);
2534  }
2535 
2536 #undef TIMETZ_GT
2537 #undef TIMETZ_LT
2538 }
2539 
2540 
2541 Datum
2543 {
2544  TimeTzADT *timetz = PG_GETARG_TIMETZADT_P(0);
2545  TimeADT result;
2546 
2547  /* swallow the time zone and just return the time */
2548  result = timetz->time;
2549 
2550  PG_RETURN_TIMEADT(result);
2551 }
2552 
2553 
2554 Datum
2556 {
2557  TimeADT time = PG_GETARG_TIMEADT(0);
2558  TimeTzADT *result;
2559  struct pg_tm tt,
2560  *tm = &tt;
2561  fsec_t fsec;
2562  int tz;
2563 
2564  GetCurrentDateTime(tm);
2565  time2tm(time, tm, &fsec);
2567 
2568  result = (TimeTzADT *) palloc(sizeof(TimeTzADT));
2569 
2570  result->time = time;
2571  result->zone = tz;
2572 
2573  PG_RETURN_TIMETZADT_P(result);
2574 }
2575 
2576 
2577 /* timestamptz_timetz()
2578  * Convert timestamp to timetz data type.
2579  */
2580 Datum
2582 {
2584  TimeTzADT *result;
2585  struct pg_tm tt,
2586  *tm = &tt;
2587  int tz;
2588  fsec_t fsec;
2589 
2590  if (TIMESTAMP_NOT_FINITE(timestamp))
2591  PG_RETURN_NULL();
2592 
2593  if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
2594  ereport(ERROR,
2595  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2596  errmsg("timestamp out of range")));
2597 
2598  result = (TimeTzADT *) palloc(sizeof(TimeTzADT));
2599 
2600  tm2timetz(tm, fsec, tz, result);
2601 
2602  PG_RETURN_TIMETZADT_P(result);
2603 }
2604 
2605 
2606 /* datetimetz_timestamptz()
2607  * Convert date and timetz to timestamp with time zone data type.
2608  * Timestamp is stored in GMT, so add the time zone
2609  * stored with the timetz to the result.
2610  * - thomas 2000-03-10
2611  */
2612 Datum
2614 {
2616  TimeTzADT *time = PG_GETARG_TIMETZADT_P(1);
2617  TimestampTz result;
2618 
2619  if (DATE_IS_NOBEGIN(date))
2620  TIMESTAMP_NOBEGIN(result);
2621  else if (DATE_IS_NOEND(date))
2622  TIMESTAMP_NOEND(result);
2623  else
2624  {
2625  /*
2626  * Date's range is wider than timestamp's, so check for boundaries.
2627  * Since dates have the same minimum values as timestamps, only upper
2628  * boundary need be checked for overflow.
2629  */
2631  ereport(ERROR,
2632  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2633  errmsg("date out of range for timestamp")));
2634  result = date * USECS_PER_DAY + time->time + time->zone * USECS_PER_SEC;
2635 
2636  /*
2637  * Since it is possible to go beyond allowed timestamptz range because
2638  * of time zone, check for allowed timestamp range after adding tz.
2639  */
2640  if (!IS_VALID_TIMESTAMP(result))
2641  ereport(ERROR,
2642  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2643  errmsg("date out of range for timestamp")));
2644  }
2645 
2646  PG_RETURN_TIMESTAMP(result);
2647 }
2648 
2649 
2650 /* timetz_part()
2651  * Extract specified field from time type.
2652  */
2653 Datum
2655 {
2656  text *units = PG_GETARG_TEXT_PP(0);
2657  TimeTzADT *time = PG_GETARG_TIMETZADT_P(1);
2658  float8 result;
2659  int type,
2660  val;
2661  char *lowunits;
2662 
2663  lowunits = downcase_truncate_identifier(VARDATA_ANY(units),
2664  VARSIZE_ANY_EXHDR(units),
2665  false);
2666 
2667  type = DecodeUnits(0, lowunits, &val);
2668  if (type == UNKNOWN_FIELD)
2669  type = DecodeSpecial(0, lowunits, &val);
2670 
2671  if (type == UNITS)
2672  {
2673  double dummy;
2674  int tz;
2675  fsec_t fsec;
2676  struct pg_tm tt,
2677  *tm = &tt;
2678 
2679  timetz2tm(time, tm, &fsec, &tz);
2680 
2681  switch (val)
2682  {
2683  case DTK_TZ:
2684  result = -tz;
2685  break;
2686 
2687  case DTK_TZ_MINUTE:
2688  result = -tz;
2689  result /= SECS_PER_MINUTE;
2690  FMODULO(result, dummy, (double) SECS_PER_MINUTE);
2691  break;
2692 
2693  case DTK_TZ_HOUR:
2694  dummy = -tz;
2695  FMODULO(dummy, result, (double) SECS_PER_HOUR);
2696  break;
2697 
2698  case DTK_MICROSEC:
2699  result = tm->tm_sec * 1000000.0 + fsec;
2700  break;
2701 
2702  case DTK_MILLISEC:
2703  result = tm->tm_sec * 1000.0 + fsec / 1000.0;
2704  break;
2705 
2706  case DTK_SECOND:
2707  result = tm->tm_sec + fsec / 1000000.0;
2708  break;
2709 
2710  case DTK_MINUTE:
2711  result = tm->tm_min;
2712  break;
2713 
2714  case DTK_HOUR:
2715  result = tm->tm_hour;
2716  break;
2717 
2718  case DTK_DAY:
2719  case DTK_MONTH:
2720  case DTK_QUARTER:
2721  case DTK_YEAR:
2722  case DTK_DECADE:
2723  case DTK_CENTURY:
2724  case DTK_MILLENNIUM:
2725  default:
2726  ereport(ERROR,
2727  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2728  errmsg("\"time with time zone\" units \"%s\" not recognized",
2729  lowunits)));
2730  result = 0;
2731  }
2732  }
2733  else if (type == RESERV && val == DTK_EPOCH)
2734  {
2735  result = time->time / 1000000.0 + time->zone;
2736  }
2737  else
2738  {
2739  ereport(ERROR,
2740  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2741  errmsg("\"time with time zone\" units \"%s\" not recognized",
2742  lowunits)));
2743  result = 0;
2744  }
2745 
2746  PG_RETURN_FLOAT8(result);
2747 }
2748 
2749 /* timetz_zone()
2750  * Encode time with time zone type with specified time zone.
2751  * Applies DST rules as of the current date.
2752  */
2753 Datum
2755 {
2756  text *zone = PG_GETARG_TEXT_PP(0);
2758  TimeTzADT *result;
2759  int tz;
2760  char tzname[TZ_STRLEN_MAX + 1];
2761  char *lowzone;
2762  int type,
2763  val;
2764  pg_tz *tzp;
2765 
2766  /*
2767  * Look up the requested timezone. First we look in the timezone
2768  * abbreviation table (to handle cases like "EST"), and if that fails, we
2769  * look in the timezone database (to handle cases like
2770  * "America/New_York"). (This matches the order in which timestamp input
2771  * checks the cases; it's important because the timezone database unwisely
2772  * uses a few zone names that are identical to offset abbreviations.)
2773  */
2774  text_to_cstring_buffer(zone, tzname, sizeof(tzname));
2775 
2776  /* DecodeTimezoneAbbrev requires lowercase input */
2777  lowzone = downcase_truncate_identifier(tzname,
2778  strlen(tzname),
2779  false);
2780 
2781  type = DecodeTimezoneAbbrev(0, lowzone, &val, &tzp);
2782 
2783  if (type == TZ || type == DTZ)
2784  {
2785  /* fixed-offset abbreviation */
2786  tz = -val;
2787  }
2788  else if (type == DYNTZ)
2789  {
2790  /* dynamic-offset abbreviation, resolve using current time */
2791  pg_time_t now = (pg_time_t) time(NULL);
2792  struct pg_tm *tm;
2793 
2794  tm = pg_localtime(&now, tzp);
2795  tz = DetermineTimeZoneAbbrevOffset(tm, tzname, tzp);
2796  }
2797  else
2798  {
2799  /* try it as a full zone name */
2800  tzp = pg_tzset(tzname);
2801  if (tzp)
2802  {
2803  /* Get the offset-from-GMT that is valid today for the zone */
2804  pg_time_t now = (pg_time_t) time(NULL);
2805  struct pg_tm *tm;
2806 
2807  tm = pg_localtime(&now, tzp);
2808  tz = -tm->tm_gmtoff;
2809  }
2810  else
2811  {
2812  ereport(ERROR,
2813  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2814  errmsg("time zone \"%s\" not recognized", tzname)));
2815  tz = 0; /* keep compiler quiet */
2816  }
2817  }
2818 
2819  result = (TimeTzADT *) palloc(sizeof(TimeTzADT));
2820 
2821  result->time = t->time + (t->zone - tz) * USECS_PER_SEC;
2822  while (result->time < INT64CONST(0))
2823  result->time += USECS_PER_DAY;
2824  while (result->time >= USECS_PER_DAY)
2825  result->time -= USECS_PER_DAY;
2826 
2827  result->zone = tz;
2828 
2829  PG_RETURN_TIMETZADT_P(result);
2830 }
2831 
2832 /* timetz_izone()
2833  * Encode time with time zone type with specified time interval as time zone.
2834  */
2835 Datum
2837 {
2839  TimeTzADT *time = PG_GETARG_TIMETZADT_P(1);
2840  TimeTzADT *result;
2841  int tz;
2842 
2843  if (zone->month != 0 || zone->day != 0)
2844  ereport(ERROR,
2845  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2846  errmsg("interval time zone \"%s\" must not include months or days",
2848  PointerGetDatum(zone))))));
2849 
2850  tz = -(zone->time / USECS_PER_SEC);
2851 
2852  result = (TimeTzADT *) palloc(sizeof(TimeTzADT));
2853 
2854  result->time = time->time + (time->zone - tz) * USECS_PER_SEC;
2855  while (result->time < INT64CONST(0))
2856  result->time += USECS_PER_DAY;
2857  while (result->time >= USECS_PER_DAY)
2858  result->time -= USECS_PER_DAY;
2859 
2860  result->zone = tz;
2861 
2862  PG_RETURN_TIMETZADT_P(result);
2863 }
#define MAXDATELEN
Definition: datetime.h:203
void EncodeDateOnly(struct pg_tm *tm, int style, char *str)
Definition: datetime.c:3873
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
Datum date_cmp_timestamptz(PG_FUNCTION_ARGS)
Definition: date.c:835
#define PG_GETARG_FLOAT8(n)
Definition: fmgr.h:251
#define TIMEADT_LT(t1, t2)
static int32 anytime_typmodin(bool istz, ArrayType *ta)
Definition: date.c:51
Datum timetypmodin(PG_FUNCTION_ARGS)
Definition: date.c:1349
#define PG_GETARG_ABSOLUTETIME(n)
Definition: nabstime.h:58
Datum timetz_cmp(PG_FUNCTION_ARGS)
Definition: date.c:2263
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:326
#define DatumGetUInt32(X)
Definition: postgres.h:471
Datum time_mi_interval(PG_FUNCTION_ARGS)
Definition: date.c:1859
Datum date_eq(PG_FUNCTION_ARGS)
Definition: date.c:387
#define TIMESTAMP_NOEND(j)
Definition: timestamp.h:117
#define DTERR_BAD_FORMAT
Definition: datetime.h:282
Datum timetz_pl_interval(PG_FUNCTION_ARGS)
Definition: date.c:2335
#define DTK_TZ_HOUR
Definition: datetime.h:180
#define DATE_IS_NOEND(j)
Definition: date.h:42
Datum timetz_ge(PG_FUNCTION_ARGS)
Definition: date.c:2254
#define PG_GETARG_INT32(n)
Definition: fmgr.h:239
#define DTK_CENTURY
Definition: datetime.h:172
void GetCurrentDateTime(struct pg_tm *tm)
Definition: datetime.c:354
Datum time_pl_interval(PG_FUNCTION_ARGS)
Definition: date.c:1841
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
Datum date_le(PG_FUNCTION_ARGS)
Definition: date.c:414
#define TIMESTAMP_END_JULIAN
Definition: timestamp.h:181
#define DatumGetDateADT(X)
Definition: date.h:53
Datum date_lt(PG_FUNCTION_ARGS)
Definition: date.c:405
#define UNITS
Definition: datetime.h:108
Datum timestamp_ne_date(PG_FUNCTION_ARGS)
Definition: date.c:859
#define PG_RETURN_TIMETZADT_P(x)
Definition: date.h:67
void DateTimeParseError(int dterr, const char *str, const char *datatype)
Definition: datetime.c:3754
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
Datum time_part(PG_FUNCTION_ARGS)
Definition: date.c:1917
int64 pg_time_t
Definition: pgtime.h:23
TimeADT time
Definition: date.h:29
Datum timetz_scale(PG_FUNCTION_ARGS)
Definition: date.c:2164
#define PG_RETURN_INTERVAL_P(x)
Definition: timestamp.h:41
int timestamp_cmp_internal(Timestamp dt1, Timestamp dt2)
Definition: timestamp.c:2023
PGDLLIMPORT pg_tz * session_timezone
Definition: pgtz.c:28
#define NOSTART_ABSTIME
Definition: nabstime.h:78
Datum abstime_date(PG_FUNCTION_ARGS)
Definition: date.c:1177
Datum timetz_ne(PG_FUNCTION_ARGS)
Definition: date.c:2218
#define DTK_YEAR
Definition: datetime.h:170
Datum datetime_timestamp(PG_FUNCTION_ARGS)
Definition: date.c:1751
#define LATE
Definition: datetime.h:41
int32 anytime_typmod_check(bool istz, int32 typmod)
Definition: date.c:72
#define USECS_PER_SEC
Definition: timestamp.h:94
int32 DateADT
Definition: date.h:23
Datum hashint8(PG_FUNCTION_ARGS)
Definition: hashfunc.c:80
Datum timetz_gt(PG_FUNCTION_ARGS)
Definition: date.c:2245
int64 timestamp
Datum timestamptz_ne_date(PG_FUNCTION_ARGS)
Definition: date.c:943
int64 TimestampTz
Definition: timestamp.h:39
static void pq_sendint32(StringInfo buf, int32 i)
Definition: pqformat.h:148
#define PointerGetDatum(X)
Definition: postgres.h:541
int tm_hour
Definition: pgtime.h:29
#define PG_GETARG_TIMESTAMP(n)
Definition: timestamp.h:35
char * downcase_truncate_identifier(const char *ident, int len, bool warn)
Definition: scansup.c:131
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:238
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:328
Datum timestamp_date(PG_FUNCTION_ARGS)
Definition: date.c:1101
Datum hash_uint32_extended(uint32 k, uint64 seed)
Definition: hashfunc.c:914
Datum time_le(PG_FUNCTION_ARGS)
Definition: date.c:1492
int32 * ArrayGetIntegerTypmods(ArrayType *arr, int *n)
Definition: arrayutils.c:200
char * pstrdup(const char *in)
Definition: mcxt.c:1161
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
#define DTK_QUARTER
Definition: datetime.h:169
Datum date_ne_timestamptz(PG_FUNCTION_ARGS)
Definition: date.c:775
Datum date_eq_timestamp(PG_FUNCTION_ARGS)
Definition: date.c:679
int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
Definition: timestamp.c:1758
Datum timestamp_ge_date(PG_FUNCTION_ARGS)
Definition: date.c:907
#define PG_RETURN_TIMEADT(x)
Definition: date.h:66
StringInfoData * StringInfo
Definition: stringinfo.h:43
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:331
Datum timetz_hash_extended(PG_FUNCTION_ARGS)
Definition: date.c:2288
#define FMODULO(t, q, u)
Definition: datetime.h:240
Datum time_eq(PG_FUNCTION_ARGS)
Definition: date.c:1465
Datum timetypmodout(PG_FUNCTION_ARGS)
Definition: date.c:1357
static int tm2time(struct pg_tm *tm, fsec_t fsec, TimeADT *result)
Definition: date.c:1264
#define PG_RETURN_INT32(x)
Definition: fmgr.h:319
Datum time_interval(PG_FUNCTION_ARGS)
Definition: date.c:1774
Definition: nodes.h:516
void EncodeTimeOnly(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, int style, char *str)
Definition: datetime.c:3958
#define DTK_MILLENNIUM
Definition: datetime.h:173
Datum in_range_time_interval(PG_FUNCTION_ARGS)
Definition: date.c:1877
static void pq_sendint64(StringInfo buf, int64 i)
Definition: pqformat.h:156
#define USECS_PER_MINUTE
Definition: timestamp.h:93
int errcode(int sqlerrcode)
Definition: elog.c:575
Datum date_lt_timestamptz(PG_FUNCTION_ARGS)
Definition: date.c:787
Datum timetz_lt(PG_FUNCTION_ARGS)
Definition: date.c:2227
int time2tm(TimeADT time, struct pg_tm *tm, fsec_t *fsec)
Definition: date.c:1279
double date2timestamp_no_overflow(DateADT dateVal)
Definition: date.c:656
#define TZ
Definition: datetime.h:96
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:246
#define UNKNOWN_FIELD
Definition: datetime.h:125
long date
Definition: pgtypes_date.h:9
static int date_fastcmp(Datum x, Datum y, SortSupport ssup)
Definition: date.c:454
Datum interval_out(PG_FUNCTION_ARGS)
Definition: timestamp.c:958
Datum timetz_mi_interval(PG_FUNCTION_ARGS)
Definition: date.c:2357
int DecodeUnits(int field, char *lowtoken, int *val)
Definition: datetime.c:3717
Datum timestamptz_cmp_date(PG_FUNCTION_ARGS)
Definition: date.c:1003
Datum timestamp_gt_date(PG_FUNCTION_ARGS)
Definition: date.c:883
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:590
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:244
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:335
Datum hashint8extended(PG_FUNCTION_ARGS)
Definition: hashfunc.c:100
long int tm_gmtoff
Definition: pgtime.h:36
static int timetz_cmp_internal(TimeTzADT *time1, TimeTzADT *time2)
Definition: date.c:2182
Datum date_eq_timestamptz(PG_FUNCTION_ARGS)
Definition: date.c:763
Definition: pgtime.h:25
DateADT GetSQLCurrentDate(void)
Definition: date.c:312
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_RETURN_UINT64(x)
Definition: fmgr.h:333
#define DTK_CURRENT
Definition: datetime.h:152
Datum in_range_date_interval(PG_FUNCTION_ARGS)
Definition: date.c:1021
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:348
void text_to_cstring_buffer(const text *src, char *dst, size_t dst_len)
Definition: varlena.c:213
int DecodeTimeOnly(char **field, int *ftype, int nf, int *dtype, struct pg_tm *tm, fsec_t *fsec, int *tzp)
Definition: datetime.c:1731
Datum date_send(PG_FUNCTION_ARGS)
Definition: date.c:234
Datum date_sortsupport(PG_FUNCTION_ARGS)
Definition: date.c:467
#define DTK_DATE_M
Definition: datetime.h:194
#define MINS_PER_HOUR
Definition: timestamp.h:89
#define PG_RETURN_UINT32(x)
Definition: fmgr.h:320
signed int int32
Definition: c.h:313
Datum datetimetz_timestamptz(PG_FUNCTION_ARGS)
Definition: date.c:2613
int32 day
Definition: timestamp.h:47
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:278
Datum timestamp_le_date(PG_FUNCTION_ARGS)
Definition: date.c:895
static struct pg_tm tm
Definition: localtime.c:106
Datum time_scale(PG_FUNCTION_ARGS)
Definition: date.c:1410
#define DATE_NOBEGIN(j)
Definition: date.h:39
pg_tz * pg_tzset(const char *tzname)
Definition: pgtz.c:236
#define DTK_MONTH
Definition: datetime.h:168
#define DTK_MILLISEC
Definition: datetime.h:174
Datum timestamp_mi_interval(PG_FUNCTION_ARGS)
Definition: timestamp.c:2874
Datum time_larger(PG_FUNCTION_ARGS)
Definition: date.c:1544
#define IS_VALID_DATE(d)
Definition: timestamp.h:190
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:248
Datum timestamp_pl_interval(PG_FUNCTION_ARGS)
Definition: timestamp.c:2795
Datum in_range_timetz_interval(PG_FUNCTION_ARGS)
Definition: date.c:2379
#define TIMESTAMP_NOT_FINITE(j)
Definition: timestamp.h:122
#define DTK_DECADE
Definition: datetime.h:171
int DecodeDateTime(char **field, int *ftype, int nf, int *dtype, struct pg_tm *tm, fsec_t *fsec, int *tzp)
Definition: datetime.c:767
#define TZ_STRLEN_MAX
Definition: pgtime.h:44
#define DTK_TZ
Definition: datetime.h:147
#define DTK_HOUR
Definition: datetime.h:165
#define ERROR
Definition: elog.h:43
double float8
Definition: c.h:458
Datum time_lt(PG_FUNCTION_ARGS)
Definition: date.c:1483
#define DatumGetCString(X)
Definition: postgres.h:551
int DecodeTimezoneAbbrev(int field, char *lowtoken, int *offset, pg_tz **tz)
Definition: datetime.c:2971
#define IntervalPGetDatum(X)
Definition: timestamp.h:33
Datum time_cmp(PG_FUNCTION_ARGS)
Definition: date.c:1519
#define DTK_SECOND
Definition: datetime.h:163
Datum date_in(PG_FUNCTION_ARGS)
Definition: date.c:114
int32 zone
Definition: date.h:30
#define DATE_NOT_FINITE(j)
Definition: date.h:43
Datum make_time(PG_FUNCTION_ARGS)
Definition: date.c:1368
Datum time_out(PG_FUNCTION_ARGS)
Definition: date.c:1292
Datum timetztypmodin(PG_FUNCTION_ARGS)
Definition: date.c:2122
TimeTzADT * GetSQLCurrentTime(int32 typmod)
Definition: date.c:334
Datum timetz_send(PG_FUNCTION_ARGS)
Definition: date.c:2110
Datum time_gt(PG_FUNCTION_ARGS)
Definition: date.c:1501
#define DatumGetInt64(X)
Definition: postgres.h:592
Datum date_larger(PG_FUNCTION_ARGS)
Definition: date.c:484
int(* comparator)(Datum x, Datum y, SortSupport ssup)
Definition: sortsupport.h:107
Datum date_timestamp(PG_FUNCTION_ARGS)
Definition: date.c:1087
Datum date_gt_timestamp(PG_FUNCTION_ARGS)
Definition: date.c:715
int tm_mday
Definition: pgtime.h:30
static char * buf
Definition: pg_test_fsync.c:67
#define HOURS_PER_DAY
Definition: timestamp.h:78
#define PG_GETARG_TIMETZADT_P(n)
Definition: date.h:63
#define PG_GETARG_OID(n)
Definition: fmgr.h:245
int tm_mon
Definition: pgtime.h:31
int DetermineTimeZoneOffset(struct pg_tm *tm, pg_tz *tzp)
Definition: datetime.c:1455
Datum time_transform(PG_FUNCTION_ARGS)
Definition: date.c:1399
#define SECS_PER_MINUTE
Definition: timestamp.h:88
Datum timetztypmodout(PG_FUNCTION_ARGS)
Definition: date.c:2130
Datum date_ne(PG_FUNCTION_ARGS)
Definition: date.c:396
#define USECS_PER_HOUR
Definition: timestamp.h:92
TimeOffset time
Definition: timestamp.h:45
#define TIMETZ_LT(t1, t2)
static char * anytime_typmodout(bool istz, int32 typmod)
Definition: date.c:94
Datum date_gt(PG_FUNCTION_ARGS)
Definition: date.c:423
#define INVALID_ABSTIME
Definition: nabstime.h:76
unsigned int uint32
Definition: c.h:325
#define TIMESTAMP_NOBEGIN(j)
Definition: timestamp.h:112
void EncodeSpecialDate(DateADT dt, char *str)
Definition: date.c:297
Datum timestamptz_date(PG_FUNCTION_ARGS)
Definition: date.c:1146
#define DTK_ISOYEAR
Definition: datetime.h:182
const char *const days[]
Definition: datetime.c:70
Datum timestamptz_le_date(PG_FUNCTION_ARGS)
Definition: date.c:979
int32 fsec_t
Definition: timestamp.h:41
int64 TimeADT
Definition: date.h:25
double rint(double x)
Definition: rint.c:22
#define IS_VALID_JULIAN(y, m, d)
Definition: timestamp.h:155
#define USECS_PER_DAY
Definition: timestamp.h:91
int32 AbsoluteTime
Definition: nabstime.h:36
#define DTK_TZ_MINUTE
Definition: datetime.h:181
Datum timetz_le(PG_FUNCTION_ARGS)
Definition: date.c:2236
static void AdjustTimeForTypmod(TimeADT *time, int32 typmod)
Definition: date.c:1430
#define ereport(elevel, rest)
Definition: elog.h:122
#define PG_GETARG_DATEADT(n)
Definition: date.h:61
void j2date(int jd, int *year, int *month, int *day)
Definition: datetime.c:301
#define SECS_PER_HOUR
Definition: timestamp.h:87
#define TimestampGetDatum(X)
Definition: timestamp.h:31
TimeADT GetSQLLocalTime(int32 typmod)
Definition: date.c:360
#define DTK_MINUTE
Definition: datetime.h:164
#define TZDISP_LIMIT
Definition: timestamp.h:104
Datum time_recv(PG_FUNCTION_ARGS)
Definition: date.c:1312
#define DirectFunctionCall5(func, arg1, arg2, arg3, arg4, arg5)
Definition: fmgr.h:598
Datum date_le_timestamptz(PG_FUNCTION_ARGS)
Definition: date.c:811
int32 month
Definition: timestamp.h:48
int64 Timestamp
Definition: timestamp.h:38
Datum date_mii(PG_FUNCTION_ARGS)
Definition: date.c:545
TimestampTz GetCurrentTransactionStartTimestamp(void)
Definition: xact.c:700
static Timestamp date2timestamp(DateADT dateVal)
Definition: date.c:572
Datum date_lt_timestamp(PG_FUNCTION_ARGS)
Definition: date.c:703
#define WARNING
Definition: elog.h:40
Datum date_cmp_timestamp(PG_FUNCTION_ARGS)
Definition: date.c:751
#define DTK_LATE
Definition: datetime.h:154
Datum timetz_zone(PG_FUNCTION_ARGS)
Definition: date.c:2754
int64 TimeOffset
Definition: timestamp.h:40
Datum hash_uint32(uint32 k)
Definition: hashfunc.c:893
static TimestampTz date2timestamptz(DateADT dateVal)
Definition: date.c:600
#define DTK_MICROSEC
Definition: datetime.h:175
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:324
uintptr_t Datum
Definition: postgres.h:367
Datum date_smaller(PG_FUNCTION_ARGS)
Definition: date.c:493
int timetz2tm(TimeTzADT *time, struct pg_tm *tm, fsec_t *fsec, int *tzp)
Definition: date.c:2142
#define timestamptz_cmp_internal(dt1, dt2)
Definition: timestamp.h:98
Definition: pgtz.h:59
#define Int64GetDatumFast(X)
Definition: postgres.h:760
#define BoolGetDatum(X)
Definition: postgres.h:387
Datum time_ne(PG_FUNCTION_ARGS)
Definition: date.c:1474
void abstime2tm(AbsoluteTime _time, int *tzp, struct pg_tm *tm, char **tzn)
Definition: nabstime.c:99
Datum time_send(PG_FUNCTION_ARGS)
Definition: date.c:1338
int date2j(int y, int m, int d)
Definition: datetime.c:276
#define DATE_IS_NOBEGIN(j)
Definition: date.h:40
Datum date_out(PG_FUNCTION_ARGS)
Definition: date.c:187
Datum date_gt_timestamptz(PG_FUNCTION_ARGS)
Definition: date.c:799
#define PG_RETURN_VOID()
Definition: fmgr.h:314
#define DatumGetUInt64(X)
Definition: postgres.h:619
Datum timestamptz_ge_date(PG_FUNCTION_ARGS)
Definition: date.c:991
Datum timetz_time(PG_FUNCTION_ARGS)
Definition: date.c:2542
Datum timetz_smaller(PG_FUNCTION_ARGS)
Definition: date.c:2318
Datum timestamptz_lt_date(PG_FUNCTION_ARGS)
Definition: date.c:955
#define PG_ARGISNULL(n)
Definition: fmgr.h:179
Datum timestamp_cmp_date(PG_FUNCTION_ARGS)
Definition: date.c:919
Datum timetz_recv(PG_FUNCTION_ARGS)
Definition: date.c:2074
Node * TemporalTransform(int32 max_precis, Node *node)
Definition: datetime.c:4475
Datum time_hash_extended(PG_FUNCTION_ARGS)
Definition: date.c:1538
#define PG_GETARG_TIMEADT(n)
Definition: date.h:62
Datum interval_time(PG_FUNCTION_ARGS)
Definition: date.c:1797
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:327
Datum timetz_eq(PG_FUNCTION_ARGS)
Definition: date.c:2209
#define DTK_EARLY
Definition: datetime.h:153
Datum timetz_hash(PG_FUNCTION_ARGS)
Definition: date.c:2272
#define MAXDATEFIELDS
Definition: datetime.h:205
Datum overlaps_time(PG_FUNCTION_ARGS)
Definition: date.c:1568
#define DTK_DAY
Definition: datetime.h:166
Datum make_date(PG_FUNCTION_ARGS)
Definition: date.c:248
int DateStyle
Definition: globals.c:114
#define IS_VALID_TIMESTAMP(t)
Definition: timestamp.h:195
Datum date_cmp(PG_FUNCTION_ARGS)
Definition: date.c:441
#define RESERV
Definition: datetime.h:91
int DecodeSpecial(int field, char *lowtoken, int *val)
Definition: datetime.c:3026
struct pg_tm * pg_localtime(const pg_time_t *timep, const pg_tz *tz)
Definition: localtime.c:1314
Datum time_smaller(PG_FUNCTION_ARGS)
Definition: date.c:1553
Datum date_ge_timestamptz(PG_FUNCTION_ARGS)
Definition: date.c:823
Datum timestamptz_timetz(PG_FUNCTION_ARGS)
Definition: date.c:2581
Datum time_timetz(PG_FUNCTION_ARGS)
Definition: date.c:2555
Datum date_ne_timestamp(PG_FUNCTION_ARGS)
Definition: date.c:691
Datum date_timestamptz(PG_FUNCTION_ARGS)
Definition: date.c:1131
#define DTZ
Definition: datetime.h:97
#define DTK_EPOCH
Definition: datetime.h:155
Datum date_le_timestamp(PG_FUNCTION_ARGS)
Definition: date.c:727
Datum timetz_part(PG_FUNCTION_ARGS)
Definition: date.c:2654
#define PG_RETURN_TIMESTAMP(x)
Definition: timestamp.h:39
Definition: zic.c:98
static int tm2timetz(struct pg_tm *tm, fsec_t fsec, int tz, TimeTzADT *result)
Definition: date.c:2008
Datum timetz_in(PG_FUNCTION_ARGS)
Definition: date.c:2018
int tm_year
Definition: pgtime.h:32
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
void * palloc(Size size)
Definition: mcxt.c:924
int errmsg(const char *fmt,...)
Definition: elog.c:797
Datum in_range_timestamp_interval(PG_FUNCTION_ARGS)
Definition: timestamp.c:3303
#define TIMEADT_GT(t1, t2)
Datum time_mi_time(PG_FUNCTION_ARGS)
Definition: date.c:1822
#define DYNTZ
Definition: datetime.h:98
#define PG_GETARG_TIMESTAMPTZ(n)
Definition: timestamp.h:36
Datum date_recv(PG_FUNCTION_ARGS)
Definition: date.c:212
#define TIMESTAMP_IS_NOEND(j)
Definition: timestamp.h:120
#define TIMESTAMP_IS_NOBEGIN(j)
Definition: timestamp.h:115
Datum timestamptz_gt_date(PG_FUNCTION_ARGS)
Definition: date.c:967
Datum time_in(PG_FUNCTION_ARGS)
Definition: date.c:1227
Datum timestamptz_eq_date(PG_FUNCTION_ARGS)
Definition: date.c:931
int64 pq_getmsgint64(StringInfo msg)
Definition: pqformat.c:455
Datum date_ge_timestamp(PG_FUNCTION_ARGS)
Definition: date.c:739
Datum date_mi_interval(PG_FUNCTION_ARGS)
Definition: date.c:1070
Datum timestamp_time(PG_FUNCTION_ARGS)
Definition: date.c:1690
void GetEpochTime(struct pg_tm *tm)
Definition: timestamp.c:1984
Datum timestamp_lt_date(PG_FUNCTION_ARGS)
Definition: date.c:871
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:247
Definition: c.h:516
#define PG_FUNCTION_ARGS
Definition: fmgr.h:163
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:417
#define POSTGRES_EPOCH_JDATE
Definition: timestamp.h:163
#define PG_RETURN_DATEADT(x)
Definition: date.h:65
#define elog
Definition: elog.h:219
int tm_sec
Definition: pgtime.h:27
int ParseDateTime(const char *timestr, char *workbuf, size_t buflen, char **field, int *ftype, int maxfields, int *numfields)
Definition: datetime.c:546
Datum time_ge(PG_FUNCTION_ARGS)
Definition: date.c:1510
Datum date_mi(PG_FUNCTION_ARGS)
Definition: date.c:504
Definition: date.h:27
#define NOEND_ABSTIME
Definition: nabstime.h:77
#define EARLY
Definition: datetime.h:40
int tm_min
Definition: pgtime.h:28
Datum overlaps_timetz(PG_FUNCTION_ARGS)
Definition: date.c:2422
int DetermineTimeZoneAbbrevOffset(struct pg_tm *tm, const char *abbr, pg_tz *tzp)
Definition: datetime.c:1616
Datum timetz_larger(PG_FUNCTION_ARGS)
Definition: date.c:2304
long val
Definition: informix.c:689
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1534
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:592
#define PG_RETURN_NULL()
Definition: fmgr.h:310
#define DTK_DATE
Definition: datetime.h:145
Datum timetz_out(PG_FUNCTION_ARGS)
Definition: date.c:2053
#define DATE_NOEND(j)
Definition: date.h:41
Datum time_hash(PG_FUNCTION_ARGS)
Definition: date.c:1532
Datum date_pl_interval(PG_FUNCTION_ARGS)
Definition: date.c:1050
Datum timestamptz_time(PG_FUNCTION_ARGS)
Definition: date.c:1720
#define TIMETZ_GT(t1, t2)
Datum date_ge(PG_FUNCTION_ARGS)
Definition: date.c:432
#define MAX_TIME_PRECISION
Definition: date.h:51
Datum date_finite(PG_FUNCTION_ARGS)
Definition: date.c:476
Datum timestamp_eq_date(PG_FUNCTION_ARGS)
Definition: date.c:847
int ValidateDate(int fmask, bool isjulian, bool is2digits, bool bc, struct pg_tm *tm)
Definition: datetime.c:2466
Datum timetz_izone(PG_FUNCTION_ARGS)
Definition: date.c:2836
Datum date_pli(PG_FUNCTION_ARGS)
Definition: date.c:521