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