PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
nabstime.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * nabstime.c
4  * Utilities for the built-in type "AbsoluteTime".
5  * Functions for the built-in type "RelativeTime".
6  * Functions for the built-in type "TimeInterval".
7  *
8  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
9  * Portions Copyright (c) 1994, Regents of the University of California
10  *
11  *
12  * IDENTIFICATION
13  * src/backend/utils/adt/nabstime.c
14  *
15  *-------------------------------------------------------------------------
16  */
17 #include "postgres.h"
18 
19 #include <ctype.h>
20 #include <float.h>
21 #include <limits.h>
22 #include <math.h>
23 #include <time.h>
24 #include <sys/time.h>
25 
26 #include "libpq/pqformat.h"
27 #include "miscadmin.h"
28 #include "utils/builtins.h"
29 #include "utils/datetime.h"
30 #include "utils/nabstime.h"
31 
32 #define MIN_DAYNUM (-24856) /* December 13, 1901 */
33 #define MAX_DAYNUM 24854 /* January 18, 2038 */
34 
35 /*
36  * Unix epoch is Jan 1 00:00:00 1970.
37  * Postgres knows about times sixty-eight years on either side of that
38  * for these 4-byte types.
39  *
40  * "tinterval" is two 4-byte fields.
41  * Definitions for parsing tinterval.
42  */
43 
44 #define IsSpace(C) ((C) == ' ')
45 
46 #define T_INTERVAL_INVAL 0 /* data represents no valid tinterval */
47 #define T_INTERVAL_VALID 1 /* data represents a valid tinterval */
48 /*
49  * ['Mon May 10 23:59:12 1943 PST' 'Sun Jan 14 03:14:21 1973 PST']
50  * 0 1 2 3 4 5 6
51  * 1234567890123456789012345678901234567890123456789012345678901234
52  *
53  * we allocate some extra -- timezones are usually 3 characters but
54  * this is not in the POSIX standard...
55  */
56 #define T_INTERVAL_LEN 80
57 #define INVALID_INTERVAL_STR "Undefined Range"
58 #define INVALID_INTERVAL_STR_LEN (sizeof(INVALID_INTERVAL_STR)-1)
59 
60 #define ABSTIMEMIN(t1, t2) \
61  (DatumGetBool(DirectFunctionCall2(abstimele, \
62  AbsoluteTimeGetDatum(t1), \
63  AbsoluteTimeGetDatum(t2))) ? (t1) : (t2))
64 #define ABSTIMEMAX(t1, t2) \
65  (DatumGetBool(DirectFunctionCall2(abstimelt, \
66  AbsoluteTimeGetDatum(t1), \
67  AbsoluteTimeGetDatum(t2))) ? (t2) : (t1))
68 
69 
70 /*
71  * Function prototypes -- internal to this file only
72  */
73 
74 static AbsoluteTime tm2abstime(struct pg_tm *tm, int tz);
75 static void reltime2tm(RelativeTime time, struct pg_tm *tm);
76 static void parsetinterval(char *i_string,
77  AbsoluteTime *i_start,
78  AbsoluteTime *i_end);
79 
80 
81 /*
82  * GetCurrentAbsoluteTime()
83  *
84  * Get the current system time (relative to Unix epoch).
85  *
86  * NB: this will overflow in 2038; it should be gone long before that.
87  */
90 {
91  time_t now;
92 
93  now = time(NULL);
94  return (AbsoluteTime) now;
95 }
96 
97 
98 void
99 abstime2tm(AbsoluteTime _time, int *tzp, struct pg_tm *tm, char **tzn)
100 {
101  pg_time_t time = (pg_time_t) _time;
102  struct pg_tm *tx;
103 
104  if (tzp != NULL)
105  tx = pg_localtime(&time, session_timezone);
106  else
107  tx = pg_gmtime(&time);
108 
109  tm->tm_year = tx->tm_year + 1900;
110  tm->tm_mon = tx->tm_mon + 1;
111  tm->tm_mday = tx->tm_mday;
112  tm->tm_hour = tx->tm_hour;
113  tm->tm_min = tx->tm_min;
114  tm->tm_sec = tx->tm_sec;
115  tm->tm_isdst = tx->tm_isdst;
116 
117  tm->tm_gmtoff = tx->tm_gmtoff;
118  tm->tm_zone = tx->tm_zone;
119 
120  if (tzp != NULL)
121  {
122  *tzp = -tm->tm_gmtoff; /* tm_gmtoff is Sun/DEC-ism */
123 
124  /*
125  * XXX FreeBSD man pages indicate that this should work - tgl 97/04/23
126  */
127  if (tzn != NULL)
128  {
129  /*
130  * Copy no more than MAXTZLEN bytes of timezone to tzn, in case it
131  * contains an error message, which doesn't fit in the buffer
132  */
133  StrNCpy(*tzn, tm->tm_zone, MAXTZLEN + 1);
134  if (strlen(tm->tm_zone) > MAXTZLEN)
136  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
137  errmsg("invalid time zone name: \"%s\"",
138  tm->tm_zone)));
139  }
140  }
141  else
142  tm->tm_isdst = -1;
143 }
144 
145 
146 /* tm2abstime()
147  * Convert a tm structure to abstime.
148  * Note that tm has full year (not 1900-based) and 1-based month.
149  */
150 static AbsoluteTime
151 tm2abstime(struct pg_tm *tm, int tz)
152 {
153  int day;
154  AbsoluteTime sec;
155 
156  /* validate, before going out of range on some members */
157  if (tm->tm_year < 1901 || tm->tm_year > 2038 ||
158  tm->tm_mon < 1 || tm->tm_mon > MONTHS_PER_YEAR ||
159  tm->tm_mday < 1 || tm->tm_mday > 31 ||
160  tm->tm_hour < 0 ||
161  tm->tm_hour > HOURS_PER_DAY || /* test for > 24:00:00 */
162  (tm->tm_hour == HOURS_PER_DAY && (tm->tm_min > 0 || tm->tm_sec > 0)) ||
163  tm->tm_min < 0 || tm->tm_min > MINS_PER_HOUR - 1 ||
164  tm->tm_sec < 0 || tm->tm_sec > SECS_PER_MINUTE)
165  return INVALID_ABSTIME;
166 
167  day = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - UNIX_EPOCH_JDATE;
168 
169  /* check for time out of range */
170  if (day < MIN_DAYNUM || day > MAX_DAYNUM)
171  return INVALID_ABSTIME;
172 
173  /* convert to seconds */
174  sec = tm->tm_sec + tz + (tm->tm_min + (day * HOURS_PER_DAY + tm->tm_hour) * MINS_PER_HOUR) * SECS_PER_MINUTE;
175 
176  /*
177  * check for overflow. We need a little slop here because the H/M/S plus
178  * TZ offset could add up to more than 1 day.
179  */
180  if ((day >= MAX_DAYNUM - 10 && sec < 0) ||
181  (day <= MIN_DAYNUM + 10 && sec > 0))
182  return INVALID_ABSTIME;
183 
184  /* check for reserved values (e.g. "current" on edge of usual range */
185  if (!AbsoluteTimeIsReal(sec))
186  return INVALID_ABSTIME;
187 
188  return sec;
189 }
190 
191 
192 /* abstimein()
193  * Decode date/time string and return abstime.
194  */
195 Datum
197 {
198  char *str = PG_GETARG_CSTRING(0);
200  fsec_t fsec;
201  int tz = 0;
202  struct pg_tm date,
203  *tm = &date;
204  int dterr;
205  char *field[MAXDATEFIELDS];
206  char workbuf[MAXDATELEN + 1];
207  int dtype;
208  int nf,
209  ftype[MAXDATEFIELDS];
210 
211  dterr = ParseDateTime(str, workbuf, sizeof(workbuf),
212  field, ftype, MAXDATEFIELDS, &nf);
213  if (dterr == 0)
214  dterr = DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tz);
215  if (dterr != 0)
216  DateTimeParseError(dterr, str, "abstime");
217 
218  switch (dtype)
219  {
220  case DTK_DATE:
221  result = tm2abstime(tm, tz);
222  break;
223 
224  case DTK_EPOCH:
225 
226  /*
227  * Don't bother retaining this as a reserved value, but instead
228  * just set to the actual epoch time (1970-01-01)
229  */
230  result = 0;
231  break;
232 
233  case DTK_LATE:
234  result = NOEND_ABSTIME;
235  break;
236 
237  case DTK_EARLY:
238  result = NOSTART_ABSTIME;
239  break;
240 
241  case DTK_INVALID:
242  result = INVALID_ABSTIME;
243  break;
244 
245  default:
246  elog(ERROR, "unexpected dtype %d while parsing abstime \"%s\"",
247  dtype, str);
248  result = INVALID_ABSTIME;
249  break;
250  };
251 
252  PG_RETURN_ABSOLUTETIME(result);
253 }
254 
255 
256 /* abstimeout()
257  * Given an AbsoluteTime return the English text version of the date
258  */
259 Datum
261 {
263  char *result;
264  int tz;
265  double fsec = 0;
266  struct pg_tm tt,
267  *tm = &tt;
268  char buf[MAXDATELEN + 1];
269  char zone[MAXDATELEN + 1],
270  *tzn = zone;
271 
272  switch (time)
273  {
274  /*
275  * Note that timestamp no longer supports 'invalid'. Retain
276  * 'invalid' for abstime for now, but dump it someday.
277  */
278  case INVALID_ABSTIME:
279  strcpy(buf, INVALID);
280  break;
281  case NOEND_ABSTIME:
282  strcpy(buf, LATE);
283  break;
284  case NOSTART_ABSTIME:
285  strcpy(buf, EARLY);
286  break;
287  default:
288  abstime2tm(time, &tz, tm, &tzn);
289  EncodeDateTime(tm, fsec, true, tz, tzn, DateStyle, buf);
290  break;
291  }
292 
293  result = pstrdup(buf);
294  PG_RETURN_CSTRING(result);
295 }
296 
297 /*
298  * abstimerecv - converts external binary format to abstime
299  */
300 Datum
302 {
304 
306 }
307 
308 /*
309  * abstimesend - converts abstime to binary format
310  */
311 Datum
313 {
316 
317  pq_begintypsend(&buf);
318  pq_sendint(&buf, time, sizeof(time));
320 }
321 
322 
323 /* abstime_finite()
324  */
325 Datum
327 {
329 
330  PG_RETURN_BOOL(abstime != INVALID_ABSTIME &&
331  abstime != NOSTART_ABSTIME &&
332  abstime != NOEND_ABSTIME);
333 }
334 
335 
336 /*
337  * abstime comparison routines
338  */
339 static int
341 {
342  /*
343  * We consider all INVALIDs to be equal and larger than any non-INVALID.
344  * This is somewhat arbitrary; the important thing is to have a consistent
345  * sort order.
346  */
347  if (a == INVALID_ABSTIME)
348  {
349  if (b == INVALID_ABSTIME)
350  return 0; /* INVALID = INVALID */
351  else
352  return 1; /* INVALID > non-INVALID */
353  }
354 
355  if (b == INVALID_ABSTIME)
356  return -1; /* non-INVALID < INVALID */
357 
358  if (a > b)
359  return 1;
360  else if (a == b)
361  return 0;
362  else
363  return -1;
364 }
365 
366 Datum
368 {
371 
372  PG_RETURN_BOOL(abstime_cmp_internal(t1, t2) == 0);
373 }
374 
375 Datum
377 {
380 
381  PG_RETURN_BOOL(abstime_cmp_internal(t1, t2) != 0);
382 }
383 
384 Datum
386 {
389 
391 }
392 
393 Datum
395 {
398 
400 }
401 
402 Datum
404 {
407 
408  PG_RETURN_BOOL(abstime_cmp_internal(t1, t2) <= 0);
409 }
410 
411 Datum
413 {
416 
417  PG_RETURN_BOOL(abstime_cmp_internal(t1, t2) >= 0);
418 }
419 
420 Datum
422 {
425 
427 }
428 
429 
430 /* timestamp_abstime()
431  * Convert timestamp to abstime.
432  */
433 Datum
435 {
438  fsec_t fsec;
439  int tz;
440  struct pg_tm tt,
441  *tm = &tt;
442 
443  if (TIMESTAMP_IS_NOBEGIN(timestamp))
444  result = NOSTART_ABSTIME;
445  else if (TIMESTAMP_IS_NOEND(timestamp))
446  result = NOEND_ABSTIME;
447  else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) == 0)
448  {
450  result = tm2abstime(tm, tz);
451  }
452  else
453  {
454  ereport(ERROR,
455  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
456  errmsg("timestamp out of range")));
457  result = INVALID_ABSTIME;
458  }
459 
460  PG_RETURN_ABSOLUTETIME(result);
461 }
462 
463 /* abstime_timestamp()
464  * Convert abstime to timestamp.
465  */
466 Datum
468 {
471  struct pg_tm tt,
472  *tm = &tt;
473  int tz;
474  char zone[MAXDATELEN + 1],
475  *tzn = zone;
476 
477  switch (abstime)
478  {
479  case INVALID_ABSTIME:
480  ereport(ERROR,
481  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
482  errmsg("cannot convert abstime \"invalid\" to timestamp")));
483  TIMESTAMP_NOBEGIN(result);
484  break;
485 
486  case NOSTART_ABSTIME:
487  TIMESTAMP_NOBEGIN(result);
488  break;
489 
490  case NOEND_ABSTIME:
491  TIMESTAMP_NOEND(result);
492  break;
493 
494  default:
495  abstime2tm(abstime, &tz, tm, &tzn);
496  if (tm2timestamp(tm, 0, NULL, &result) != 0)
497  ereport(ERROR,
498  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
499  errmsg("timestamp out of range")));
500  break;
501  };
502 
503  PG_RETURN_TIMESTAMP(result);
504 }
505 
506 
507 /* timestamptz_abstime()
508  * Convert timestamp with time zone to abstime.
509  */
510 Datum
512 {
515  fsec_t fsec;
516  struct pg_tm tt,
517  *tm = &tt;
518 
519  if (TIMESTAMP_IS_NOBEGIN(timestamp))
520  result = NOSTART_ABSTIME;
521  else if (TIMESTAMP_IS_NOEND(timestamp))
522  result = NOEND_ABSTIME;
523  else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) == 0)
524  result = tm2abstime(tm, 0);
525  else
526  {
527  ereport(ERROR,
528  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
529  errmsg("timestamp out of range")));
530  result = INVALID_ABSTIME;
531  }
532 
533  PG_RETURN_ABSOLUTETIME(result);
534 }
535 
536 /* abstime_timestamptz()
537  * Convert abstime to timestamp with time zone.
538  */
539 Datum
541 {
544  struct pg_tm tt,
545  *tm = &tt;
546  int tz;
547  char zone[MAXDATELEN + 1],
548  *tzn = zone;
549 
550  switch (abstime)
551  {
552  case INVALID_ABSTIME:
553  ereport(ERROR,
554  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
555  errmsg("cannot convert abstime \"invalid\" to timestamp")));
556  TIMESTAMP_NOBEGIN(result);
557  break;
558 
559  case NOSTART_ABSTIME:
560  TIMESTAMP_NOBEGIN(result);
561  break;
562 
563  case NOEND_ABSTIME:
564  TIMESTAMP_NOEND(result);
565  break;
566 
567  default:
568  abstime2tm(abstime, &tz, tm, &tzn);
569  if (tm2timestamp(tm, 0, &tz, &result) != 0)
570  ereport(ERROR,
571  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
572  errmsg("timestamp out of range")));
573  break;
574  };
575 
576  PG_RETURN_TIMESTAMP(result);
577 }
578 
579 
580 /*****************************************************************************
581  * USER I/O ROUTINES *
582  *****************************************************************************/
583 
584 /*
585  * reltimein - converts a reltime string in an internal format
586  */
587 Datum
589 {
590  char *str = PG_GETARG_CSTRING(0);
592  struct pg_tm tt,
593  *tm = &tt;
594  fsec_t fsec;
595  int dtype;
596  int dterr;
597  char *field[MAXDATEFIELDS];
598  int nf,
599  ftype[MAXDATEFIELDS];
600  char workbuf[MAXDATELEN + 1];
601 
602  dterr = ParseDateTime(str, workbuf, sizeof(workbuf),
603  field, ftype, MAXDATEFIELDS, &nf);
604  if (dterr == 0)
605  dterr = DecodeInterval(field, ftype, nf, INTERVAL_FULL_RANGE,
606  &dtype, tm, &fsec);
607 
608  /* if those functions think it's a bad format, try ISO8601 style */
609  if (dterr == DTERR_BAD_FORMAT)
610  dterr = DecodeISO8601Interval(str,
611  &dtype, tm, &fsec);
612 
613  if (dterr != 0)
614  {
615  if (dterr == DTERR_FIELD_OVERFLOW)
616  dterr = DTERR_INTERVAL_OVERFLOW;
617  DateTimeParseError(dterr, str, "reltime");
618  }
619 
620  switch (dtype)
621  {
622  case DTK_DELTA:
623  result = ((tm->tm_hour * MINS_PER_HOUR + tm->tm_min) * SECS_PER_MINUTE) + tm->tm_sec;
624  result += tm->tm_year * SECS_PER_YEAR + ((tm->tm_mon * DAYS_PER_MONTH) + tm->tm_mday) * SECS_PER_DAY;
625  break;
626 
627  default:
628  elog(ERROR, "unexpected dtype %d while parsing reltime \"%s\"",
629  dtype, str);
630  result = INVALID_RELTIME;
631  break;
632  }
633 
634  PG_RETURN_RELATIVETIME(result);
635 }
636 
637 /*
638  * reltimeout - converts the internal format to a reltime string
639  */
640 Datum
642 {
644  char *result;
645  struct pg_tm tt,
646  *tm = &tt;
647  char buf[MAXDATELEN + 1];
648 
649  reltime2tm(time, tm);
650  EncodeInterval(tm, 0, IntervalStyle, buf);
651 
652  result = pstrdup(buf);
653  PG_RETURN_CSTRING(result);
654 }
655 
656 /*
657  * reltimerecv - converts external binary format to reltime
658  */
659 Datum
661 {
663 
665 }
666 
667 /*
668  * reltimesend - converts reltime to binary format
669  */
670 Datum
672 {
675 
676  pq_begintypsend(&buf);
677  pq_sendint(&buf, time, sizeof(time));
679 }
680 
681 
682 static void
684 {
685  double dtime = time;
686 
687  FMODULO(dtime, tm->tm_year, 31557600);
688  FMODULO(dtime, tm->tm_mon, 2592000);
689  FMODULO(dtime, tm->tm_mday, SECS_PER_DAY);
690  FMODULO(dtime, tm->tm_hour, SECS_PER_HOUR);
691  FMODULO(dtime, tm->tm_min, SECS_PER_MINUTE);
692  FMODULO(dtime, tm->tm_sec, 1);
693 }
694 
695 
696 /*
697  * tintervalin - converts an tinterval string to internal format
698  */
699 Datum
701 {
702  char *tintervalstr = PG_GETARG_CSTRING(0);
703  TimeInterval tinterval;
704  AbsoluteTime i_start,
705  i_end,
706  t1,
707  t2;
708 
709  parsetinterval(tintervalstr, &t1, &t2);
710 
711  tinterval = (TimeInterval) palloc(sizeof(TimeIntervalData));
712 
713  if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
714  tinterval->status = T_INTERVAL_INVAL; /* undefined */
715  else
716  tinterval->status = T_INTERVAL_VALID;
717 
718  i_start = ABSTIMEMIN(t1, t2);
719  i_end = ABSTIMEMAX(t1, t2);
720  tinterval->data[0] = i_start;
721  tinterval->data[1] = i_end;
722 
723  PG_RETURN_TIMEINTERVAL(tinterval);
724 }
725 
726 
727 /*
728  * tintervalout - converts an internal tinterval format to a string
729  */
730 Datum
732 {
733  TimeInterval tinterval = PG_GETARG_TIMEINTERVAL(0);
734  char *i_str,
735  *p;
736 
737  i_str = (char *) palloc(T_INTERVAL_LEN); /* ["..." "..."] */
738  strcpy(i_str, "[\"");
739  if (tinterval->status == T_INTERVAL_INVAL)
740  strcat(i_str, INVALID_INTERVAL_STR);
741  else
742  {
744  AbsoluteTimeGetDatum(tinterval->data[0])));
745  strcat(i_str, p);
746  pfree(p);
747  strcat(i_str, "\" \"");
749  AbsoluteTimeGetDatum(tinterval->data[1])));
750  strcat(i_str, p);
751  pfree(p);
752  }
753  strcat(i_str, "\"]");
754  PG_RETURN_CSTRING(i_str);
755 }
756 
757 /*
758  * tintervalrecv - converts external binary format to tinterval
759  */
760 Datum
762 {
764  TimeInterval tinterval;
765  int32 status;
766 
767  tinterval = (TimeInterval) palloc(sizeof(TimeIntervalData));
768 
769  tinterval->status = pq_getmsgint(buf, sizeof(tinterval->status));
770  tinterval->data[0] = pq_getmsgint(buf, sizeof(tinterval->data[0]));
771  tinterval->data[1] = pq_getmsgint(buf, sizeof(tinterval->data[1]));
772 
773  if (tinterval->data[0] == INVALID_ABSTIME ||
774  tinterval->data[1] == INVALID_ABSTIME)
775  status = T_INTERVAL_INVAL; /* undefined */
776  else
777  status = T_INTERVAL_VALID;
778 
779  if (status != tinterval->status)
780  ereport(ERROR,
781  (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
782  errmsg("invalid status in external \"tinterval\" value")));
783 
784  PG_RETURN_TIMEINTERVAL(tinterval);
785 }
786 
787 /*
788  * tintervalsend - converts tinterval to binary format
789  */
790 Datum
792 {
793  TimeInterval tinterval = PG_GETARG_TIMEINTERVAL(0);
795 
796  pq_begintypsend(&buf);
797  pq_sendint(&buf, tinterval->status, sizeof(tinterval->status));
798  pq_sendint(&buf, tinterval->data[0], sizeof(tinterval->data[0]));
799  pq_sendint(&buf, tinterval->data[1], sizeof(tinterval->data[1]));
801 }
802 
803 
804 /*****************************************************************************
805  * PUBLIC ROUTINES *
806  *****************************************************************************/
807 
808 Datum
810 {
812  RelativeTime time;
813  int year,
814  month,
815  day;
816  TimeOffset span;
817 
818  year = interval->month / MONTHS_PER_YEAR;
819  month = interval->month % MONTHS_PER_YEAR;
820  day = interval->day;
821 
822  span = ((INT64CONST(365250000) * year + INT64CONST(30000000) * month +
823  INT64CONST(1000000) * day) * INT64CONST(86400)) +
824  interval->time;
825  span /= USECS_PER_SEC;
826 
827  if (span < INT_MIN || span > INT_MAX)
828  time = INVALID_RELTIME;
829  else
830  time = span;
831 
833 }
834 
835 
836 Datum
838 {
840  Interval *result;
841  int year,
842  month,
843  day;
844 
845  result = (Interval *) palloc(sizeof(Interval));
846 
847  switch (reltime)
848  {
849  case INVALID_RELTIME:
850  ereport(ERROR,
851  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
852  errmsg("cannot convert reltime \"invalid\" to interval")));
853  result->time = 0;
854  result->day = 0;
855  result->month = 0;
856  break;
857 
858  default:
859  year = reltime / SECS_PER_YEAR;
860  reltime -= year * SECS_PER_YEAR;
861  month = reltime / (DAYS_PER_MONTH * SECS_PER_DAY);
862  reltime -= month * (DAYS_PER_MONTH * SECS_PER_DAY);
863  day = reltime / SECS_PER_DAY;
864  reltime -= day * SECS_PER_DAY;
865 
866  result->time = (reltime * USECS_PER_SEC);
867  result->month = MONTHS_PER_YEAR * year + month;
868  result->day = day;
869  break;
870  }
871 
872  PG_RETURN_INTERVAL_P(result);
873 }
874 
875 
876 /*
877  * mktinterval - creates a time interval with endpoints t1 and t2
878  */
879 Datum
881 {
884  AbsoluteTime tstart = ABSTIMEMIN(t1, t2);
885  AbsoluteTime tend = ABSTIMEMAX(t1, t2);
886  TimeInterval tinterval;
887 
888  tinterval = (TimeInterval) palloc(sizeof(TimeIntervalData));
889 
890  if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
891  tinterval->status = T_INTERVAL_INVAL;
892 
893  else
894  {
895  tinterval->status = T_INTERVAL_VALID;
896  tinterval->data[0] = tstart;
897  tinterval->data[1] = tend;
898  }
899 
900  PG_RETURN_TIMEINTERVAL(tinterval);
901 }
902 
903 /*
904  * timepl, timemi and abstimemi use the formula
905  * abstime + reltime = abstime
906  * so abstime - reltime = abstime
907  * and abstime - abstime = reltime
908  */
909 
910 /*
911  * timepl - returns the value of (abstime t1 + reltime t2)
912  */
913 Datum
915 {
918 
919  if (AbsoluteTimeIsReal(t1) &&
920  RelativeTimeIsValid(t2) &&
921  ((t2 > 0 && t1 < NOEND_ABSTIME - t2) ||
922  (t2 <= 0 && t1 > NOSTART_ABSTIME - t2))) /* prevent overflow */
923  PG_RETURN_ABSOLUTETIME(t1 + t2);
924 
926 }
927 
928 
929 /*
930  * timemi - returns the value of (abstime t1 - reltime t2)
931  */
932 Datum
934 {
937 
938  if (AbsoluteTimeIsReal(t1) &&
939  RelativeTimeIsValid(t2) &&
940  ((t2 > 0 && t1 > NOSTART_ABSTIME + t2) ||
941  (t2 <= 0 && t1 < NOEND_ABSTIME + t2))) /* prevent overflow */
942  PG_RETURN_ABSOLUTETIME(t1 - t2);
943 
945 }
946 
947 
948 /*
949  * intinterval - returns true iff absolute date is in the tinterval
950  */
951 Datum
953 {
955  TimeInterval tinterval = PG_GETARG_TIMEINTERVAL(1);
956 
957  if (tinterval->status == T_INTERVAL_VALID && t != INVALID_ABSTIME)
958  {
961  AbsoluteTimeGetDatum(tinterval->data[0]))) &&
964  AbsoluteTimeGetDatum(tinterval->data[1]))))
965  PG_RETURN_BOOL(true);
966  }
967  PG_RETURN_BOOL(false);
968 }
969 
970 /*
971  * tintervalrel - returns relative time corresponding to tinterval
972  */
973 Datum
975 {
976  TimeInterval tinterval = PG_GETARG_TIMEINTERVAL(0);
977  AbsoluteTime t1 = tinterval->data[0];
978  AbsoluteTime t2 = tinterval->data[1];
979 
980  if (tinterval->status != T_INTERVAL_VALID)
982 
983  if (AbsoluteTimeIsReal(t1) &&
984  AbsoluteTimeIsReal(t2))
985  PG_RETURN_RELATIVETIME(t2 - t1);
986 
988 }
989 
990 
991 /*
992  * timenow - returns time "now", internal format
993  *
994  * Now AbsoluteTime is time since Jan 1 1970 -mer 7 Feb 1992
995  */
996 Datum
998 {
1000 }
1001 
1002 /*
1003  * reltime comparison routines
1004  */
1005 static int
1007 {
1008  /*
1009  * We consider all INVALIDs to be equal and larger than any non-INVALID.
1010  * This is somewhat arbitrary; the important thing is to have a consistent
1011  * sort order.
1012  */
1013  if (a == INVALID_RELTIME)
1014  {
1015  if (b == INVALID_RELTIME)
1016  return 0; /* INVALID = INVALID */
1017  else
1018  return 1; /* INVALID > non-INVALID */
1019  }
1020 
1021  if (b == INVALID_RELTIME)
1022  return -1; /* non-INVALID < INVALID */
1023 
1024  if (a > b)
1025  return 1;
1026  else if (a == b)
1027  return 0;
1028  else
1029  return -1;
1030 }
1031 
1032 Datum
1034 {
1037 
1038  PG_RETURN_BOOL(reltime_cmp_internal(t1, t2) == 0);
1039 }
1040 
1041 Datum
1043 {
1046 
1047  PG_RETURN_BOOL(reltime_cmp_internal(t1, t2) != 0);
1048 }
1049 
1050 Datum
1052 {
1055 
1056  PG_RETURN_BOOL(reltime_cmp_internal(t1, t2) < 0);
1057 }
1058 
1059 Datum
1061 {
1064 
1065  PG_RETURN_BOOL(reltime_cmp_internal(t1, t2) > 0);
1066 }
1067 
1068 Datum
1070 {
1073 
1074  PG_RETURN_BOOL(reltime_cmp_internal(t1, t2) <= 0);
1075 }
1076 
1077 Datum
1079 {
1082 
1083  PG_RETURN_BOOL(reltime_cmp_internal(t1, t2) >= 0);
1084 }
1085 
1086 Datum
1088 {
1091 
1093 }
1094 
1095 
1096 /*
1097  * tintervalsame - returns true iff tinterval i1 is same as tinterval i2
1098  * Check begin and end time.
1099  */
1100 Datum
1102 {
1105 
1106  if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
1107  PG_RETURN_BOOL(false);
1108 
1110  AbsoluteTimeGetDatum(i1->data[0]),
1111  AbsoluteTimeGetDatum(i2->data[0]))) &&
1113  AbsoluteTimeGetDatum(i1->data[1]),
1114  AbsoluteTimeGetDatum(i2->data[1]))))
1115  PG_RETURN_BOOL(true);
1116  PG_RETURN_BOOL(false);
1117 }
1118 
1119 /*
1120  * tinterval comparison routines
1121  *
1122  * Note: comparison is based only on the lengths of the tintervals, not on
1123  * endpoint values (as long as they're not INVALID). This is pretty bogus,
1124  * but since it's only a legacy datatype, we're not going to change it.
1125  *
1126  * Some other bogus things that won't be changed for compatibility reasons:
1127  * 1. The interval length computations overflow at 2^31 seconds, causing
1128  * intervals longer than that to sort oddly compared to those shorter.
1129  * 2. infinity and minus infinity (NOEND_ABSTIME and NOSTART_ABSTIME) are
1130  * just ordinary integers. Since this code doesn't handle them specially,
1131  * it's possible for [a b] to be considered longer than [c infinity] for
1132  * finite abstimes a, b, c. In combination with the previous point, the
1133  * interval [-infinity infinity] is treated as being shorter than many finite
1134  * intervals :-(
1135  *
1136  * If tinterval is ever reimplemented atop timestamp, it'd be good to give
1137  * some consideration to avoiding these problems.
1138  */
1139 static int
1141 {
1142  bool a_invalid;
1143  bool b_invalid;
1144  AbsoluteTime a_len;
1145  AbsoluteTime b_len;
1146 
1147  /*
1148  * We consider all INVALIDs to be equal and larger than any non-INVALID.
1149  * This is somewhat arbitrary; the important thing is to have a consistent
1150  * sort order.
1151  */
1152  a_invalid = a->status == T_INTERVAL_INVAL ||
1153  a->data[0] == INVALID_ABSTIME ||
1154  a->data[1] == INVALID_ABSTIME;
1155  b_invalid = b->status == T_INTERVAL_INVAL ||
1156  b->data[0] == INVALID_ABSTIME ||
1157  b->data[1] == INVALID_ABSTIME;
1158 
1159  if (a_invalid)
1160  {
1161  if (b_invalid)
1162  return 0; /* INVALID = INVALID */
1163  else
1164  return 1; /* INVALID > non-INVALID */
1165  }
1166 
1167  if (b_invalid)
1168  return -1; /* non-INVALID < INVALID */
1169 
1170  a_len = a->data[1] - a->data[0];
1171  b_len = b->data[1] - b->data[0];
1172 
1173  if (a_len > b_len)
1174  return 1;
1175  else if (a_len == b_len)
1176  return 0;
1177  else
1178  return -1;
1179 }
1180 
1181 Datum
1183 {
1186 
1187  PG_RETURN_BOOL(tinterval_cmp_internal(i1, i2) == 0);
1188 }
1189 
1190 Datum
1192 {
1195 
1196  PG_RETURN_BOOL(tinterval_cmp_internal(i1, i2) != 0);
1197 }
1198 
1199 Datum
1201 {
1204 
1206 }
1207 
1208 Datum
1210 {
1213 
1214  PG_RETURN_BOOL(tinterval_cmp_internal(i1, i2) <= 0);
1215 }
1216 
1217 Datum
1219 {
1222 
1224 }
1225 
1226 Datum
1228 {
1231 
1232  PG_RETURN_BOOL(tinterval_cmp_internal(i1, i2) >= 0);
1233 }
1234 
1235 Datum
1237 {
1240 
1242 }
1243 
1244 
1245 /*
1246  * tintervalleneq - returns true iff length of tinterval i is equal to
1247  * reltime t
1248  * tintervallenne - returns true iff length of tinterval i is not equal
1249  * to reltime t
1250  * tintervallenlt - returns true iff length of tinterval i is less than
1251  * reltime t
1252  * tintervallengt - returns true iff length of tinterval i is greater
1253  * than reltime t
1254  * tintervallenle - returns true iff length of tinterval i is less or
1255  * equal than reltime t
1256  * tintervallenge - returns true iff length of tinterval i is greater or
1257  * equal than reltime t
1258  */
1259 Datum
1261 {
1264  RelativeTime rt;
1265 
1266  if (i->status == T_INTERVAL_INVAL || t == INVALID_RELTIME)
1267  PG_RETURN_BOOL(false);
1269  TimeIntervalGetDatum(i)));
1270  PG_RETURN_BOOL(rt != INVALID_RELTIME && rt == t);
1271 }
1272 
1273 Datum
1275 {
1278  RelativeTime rt;
1279 
1280  if (i->status == T_INTERVAL_INVAL || t == INVALID_RELTIME)
1281  PG_RETURN_BOOL(false);
1283  TimeIntervalGetDatum(i)));
1284  PG_RETURN_BOOL(rt != INVALID_RELTIME && rt != t);
1285 }
1286 
1287 Datum
1289 {
1292  RelativeTime rt;
1293 
1294  if (i->status == T_INTERVAL_INVAL || t == INVALID_RELTIME)
1295  PG_RETURN_BOOL(false);
1297  TimeIntervalGetDatum(i)));
1298  PG_RETURN_BOOL(rt != INVALID_RELTIME && rt < t);
1299 }
1300 
1301 Datum
1303 {
1306  RelativeTime rt;
1307 
1308  if (i->status == T_INTERVAL_INVAL || t == INVALID_RELTIME)
1309  PG_RETURN_BOOL(false);
1311  TimeIntervalGetDatum(i)));
1312  PG_RETURN_BOOL(rt != INVALID_RELTIME && rt > t);
1313 }
1314 
1315 Datum
1317 {
1320  RelativeTime rt;
1321 
1322  if (i->status == T_INTERVAL_INVAL || t == INVALID_RELTIME)
1323  PG_RETURN_BOOL(false);
1325  TimeIntervalGetDatum(i)));
1326  PG_RETURN_BOOL(rt != INVALID_RELTIME && rt <= t);
1327 }
1328 
1329 Datum
1331 {
1334  RelativeTime rt;
1335 
1336  if (i->status == T_INTERVAL_INVAL || t == INVALID_RELTIME)
1337  PG_RETURN_BOOL(false);
1339  TimeIntervalGetDatum(i)));
1340  PG_RETURN_BOOL(rt != INVALID_RELTIME && rt >= t);
1341 }
1342 
1343 /*
1344  * tintervalct - returns true iff tinterval i1 contains tinterval i2
1345  */
1346 Datum
1348 {
1351 
1352  if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
1353  PG_RETURN_BOOL(false);
1355  AbsoluteTimeGetDatum(i1->data[0]),
1356  AbsoluteTimeGetDatum(i2->data[0]))) &&
1358  AbsoluteTimeGetDatum(i1->data[1]),
1359  AbsoluteTimeGetDatum(i2->data[1]))))
1360  PG_RETURN_BOOL(true);
1361  PG_RETURN_BOOL(false);
1362 }
1363 
1364 /*
1365  * tintervalov - returns true iff tinterval i1 (partially) overlaps i2
1366  */
1367 Datum
1369 {
1372 
1373  if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
1374  PG_RETURN_BOOL(false);
1376  AbsoluteTimeGetDatum(i1->data[1]),
1377  AbsoluteTimeGetDatum(i2->data[0]))) ||
1379  AbsoluteTimeGetDatum(i1->data[0]),
1380  AbsoluteTimeGetDatum(i2->data[1]))))
1381  PG_RETURN_BOOL(false);
1382  PG_RETURN_BOOL(true);
1383 }
1384 
1385 /*
1386  * tintervalstart - returns the start of tinterval i
1387  */
1388 Datum
1390 {
1392 
1393  if (i->status == T_INTERVAL_INVAL)
1396 }
1397 
1398 /*
1399  * tintervalend - returns the end of tinterval i
1400  */
1401 Datum
1403 {
1405 
1406  if (i->status == T_INTERVAL_INVAL)
1409 }
1410 
1411 
1412 /*****************************************************************************
1413  * PRIVATE ROUTINES *
1414  *****************************************************************************/
1415 
1416 /*
1417  * parsetinterval -- parse a tinterval string
1418  *
1419  * output parameters:
1420  * i_start, i_end: tinterval margins
1421  *
1422  * Time interval:
1423  * `[' {` '} `'' <AbsTime> `'' {` '} `'' <AbsTime> `'' {` '} `]'
1424  *
1425  * OR `Undefined Range' (see also INVALID_INTERVAL_STR)
1426  *
1427  * where <AbsTime> satisfies the syntax of absolute time.
1428  *
1429  * e.g. [ ' Jan 18 1902' 'Jan 1 00:00:00 1970']
1430  */
1431 static void
1432 parsetinterval(char *i_string,
1433  AbsoluteTime *i_start,
1434  AbsoluteTime *i_end)
1435 {
1436  char *p,
1437  *p1;
1438  char c;
1439 
1440  p = i_string;
1441  /* skip leading blanks up to '[' */
1442  while ((c = *p) != '\0')
1443  {
1444  if (IsSpace(c))
1445  p++;
1446  else if (c != '[')
1447  goto bogus; /* syntax error */
1448  else
1449  break;
1450  }
1451  if (c == '\0')
1452  goto bogus; /* syntax error */
1453  p++;
1454  /* skip leading blanks up to '"' */
1455  while ((c = *p) != '\0')
1456  {
1457  if (IsSpace(c))
1458  p++;
1459  else if (c != '"')
1460  goto bogus; /* syntax error */
1461  else
1462  break;
1463  }
1464  if (c == '\0')
1465  goto bogus; /* syntax error */
1466  p++;
1467  if (strncmp(INVALID_INTERVAL_STR, p, strlen(INVALID_INTERVAL_STR)) == 0)
1468  goto bogus; /* undefined range, handled like a syntax err. */
1469  /* search for the end of the first date and change it to a \0 */
1470  p1 = p;
1471  while ((c = *p1) != '\0')
1472  {
1473  if (c == '"')
1474  break;
1475  p1++;
1476  }
1477  if (c == '\0')
1478  goto bogus; /* syntax error */
1479  *p1 = '\0';
1480  /* get the first date */
1482  CStringGetDatum(p)));
1483  /* undo change to \0 */
1484  *p1 = c;
1485  p = ++p1;
1486  /* skip blanks up to '"', beginning of second date */
1487  while ((c = *p) != '\0')
1488  {
1489  if (IsSpace(c))
1490  p++;
1491  else if (c != '"')
1492  goto bogus; /* syntax error */
1493  else
1494  break;
1495  }
1496  if (c == '\0')
1497  goto bogus; /* syntax error */
1498  p++;
1499  /* search for the end of the second date and change it to a \0 */
1500  p1 = p;
1501  while ((c = *p1) != '\0')
1502  {
1503  if (c == '"')
1504  break;
1505  p1++;
1506  }
1507  if (c == '\0')
1508  goto bogus; /* syntax error */
1509  *p1 = '\0';
1510  /* get the second date */
1512  CStringGetDatum(p)));
1513  /* undo change to \0 */
1514  *p1 = c;
1515  p = ++p1;
1516  /* skip blanks up to ']' */
1517  while ((c = *p) != '\0')
1518  {
1519  if (IsSpace(c))
1520  p++;
1521  else if (c != ']')
1522  goto bogus; /* syntax error */
1523  else
1524  break;
1525  }
1526  if (c == '\0')
1527  goto bogus; /* syntax error */
1528  p++;
1529  c = *p;
1530  if (c != '\0')
1531  goto bogus; /* syntax error */
1532 
1533  /* it seems to be a valid tinterval */
1534  return;
1535 
1536 bogus:
1537  ereport(ERROR,
1538  (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
1539  errmsg("invalid input syntax for type %s: \"%s\"",
1540  "tinterval", i_string)));
1541  *i_start = *i_end = INVALID_ABSTIME; /* keep compiler quiet */
1542 }
1543 
1544 
1545 /*****************************************************************************
1546  *
1547  *****************************************************************************/
1548 
1549 /*
1550  * timeofday -
1551  * returns the current time as a text. similar to timenow() but returns
1552  * seconds with more precision (up to microsecs). (I need this to compare
1553  * the Wisconsin benchmark with Illustra whose TimeNow() shows current
1554  * time with precision up to microsecs.) - ay 3/95
1555  */
1556 Datum
1558 {
1559  struct timeval tp;
1560  char templ[128];
1561  char buf[128];
1562  pg_time_t tt;
1563 
1564  gettimeofday(&tp, NULL);
1565  tt = (pg_time_t) tp.tv_sec;
1566  pg_strftime(templ, sizeof(templ), "%a %b %d %H:%M:%S.%%06d %Y %Z",
1568  snprintf(buf, sizeof(buf), templ, tp.tv_usec);
1569 
1571 }
#define MAXDATELEN
Definition: datetime.h:203
static void reltime2tm(RelativeTime time, struct pg_tm *tm)
Definition: nabstime.c:683
#define PG_GETARG_ABSOLUTETIME(n)
Definition: nabstime.h:58
Datum tintervallt(PG_FUNCTION_ARGS)
Definition: nabstime.c:1200
Datum tintervalsend(PG_FUNCTION_ARGS)
Definition: nabstime.c:791
size_t pg_strftime(char *s, size_t max, const char *format, const struct pg_tm *tm)
Definition: strftime.c:122
Datum tintervalstart(PG_FUNCTION_ARGS)
Definition: nabstime.c:1389
#define TIMESTAMP_NOEND(j)
Definition: timestamp.h:117
static void parsetinterval(char *i_string, AbsoluteTime *i_start, AbsoluteTime *i_end)
Definition: nabstime.c:1432
#define DTERR_BAD_FORMAT
Definition: datetime.h:282
#define PG_RETURN_RELATIVETIME(x)
Definition: nabstime.h:63
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
Datum abstimegt(PG_FUNCTION_ARGS)
Definition: nabstime.c:394
int gettimeofday(struct timeval *tp, struct timezone *tzp)
Definition: gettimeofday.c:105
Datum tintervalout(PG_FUNCTION_ARGS)
Definition: nabstime.c:731
Datum abstime_timestamptz(PG_FUNCTION_ARGS)
Definition: nabstime.c:540
void DateTimeParseError(int dterr, const char *str, const char *datatype)
Definition: datetime.c:3765
int64 pg_time_t
Definition: pgtime.h:23
Datum timemi(PG_FUNCTION_ARGS)
Definition: nabstime.c:933
Datum abstimeeq(PG_FUNCTION_ARGS)
Definition: nabstime.c:367
#define PG_RETURN_INTERVAL_P(x)
Definition: timestamp.h:41
#define NOSTART_ABSTIME
Definition: nabstime.h:78
struct pg_tm * pg_gmtime(const pg_time_t *timep)
Definition: localtime.c:1355
static int reltime_cmp_internal(RelativeTime a, RelativeTime b)
Definition: nabstime.c:1006
#define AbsoluteTimeGetDatum(X)
Definition: nabstime.h:54
Datum abstimeout(PG_FUNCTION_ARGS)
Definition: nabstime.c:260
Datum tintervalsame(PG_FUNCTION_ARGS)
Definition: nabstime.c:1101
int tm_isdst
Definition: pgtime.h:35
Datum tintervallenlt(PG_FUNCTION_ARGS)
Definition: nabstime.c:1288
#define LATE
Definition: datetime.h:41
#define USECS_PER_SEC
Definition: timestamp.h:94
Definition: isn.c:33
TimeIntervalData * TimeInterval
Definition: nabstime.h:45
#define DTK_DELTA
Definition: datetime.h:162
int64 timestamp
int64 TimestampTz
Definition: timestamp.h:39
int tm_hour
Definition: pgtime.h:29
Datum reltimesend(PG_FUNCTION_ARGS)
Definition: nabstime.c:671
Datum tintervalle(PG_FUNCTION_ARGS)
Definition: nabstime.c:1209
#define PG_GETARG_TIMESTAMP(n)
Definition: timestamp.h:35
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:359
#define PG_RETURN_TIMEINTERVAL(x)
Definition: nabstime.h:64
Datum timestamptz_abstime(PG_FUNCTION_ARGS)
Definition: nabstime.c:511
char * pstrdup(const char *in)
Definition: mcxt.c:1077
Datum timenow(PG_FUNCTION_ARGS)
Definition: nabstime.c:997
int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
Definition: timestamp.c:1758
Datum tintervallenle(PG_FUNCTION_ARGS)
Definition: nabstime.c:1316
#define T_INTERVAL_VALID
Definition: nabstime.c:47
StringInfoData * StringInfo
Definition: stringinfo.h:43
#define FMODULO(t, q, u)
Definition: datetime.h:240
#define PG_RETURN_INT32(x)
Definition: fmgr.h:314
Datum abstimene(PG_FUNCTION_ARGS)
Definition: nabstime.c:376
#define INVALID_RELTIME
Definition: nabstime.h:80
static AbsoluteTime tm2abstime(struct pg_tm *tm, int tz)
Definition: nabstime.c:151
Datum reltimene(PG_FUNCTION_ARGS)
Definition: nabstime.c:1042
static int tinterval_cmp_internal(TimeInterval a, TimeInterval b)
Definition: nabstime.c:1140
int errcode(int sqlerrcode)
Definition: elog.c:575
int IntervalStyle
Definition: globals.c:109
Datum reltimeout(PG_FUNCTION_ARGS)
Definition: nabstime.c:641
return result
Definition: formatting.c:1633
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
long date
Definition: pgtypes_date.h:8
#define MAXTZLEN
Definition: miscadmin.h:238
#define PG_GETARG_TIMEINTERVAL(n)
Definition: nabstime.h:60
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:584
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:329
long int tm_gmtoff
Definition: pgtime.h:36
Definition: pgtime.h:25
#define T_INTERVAL_INVAL
Definition: nabstime.c:46
Datum reltimeeq(PG_FUNCTION_ARGS)
Definition: nabstime.c:1033
#define INTERVAL_FULL_RANGE
Definition: timestamp.h:48
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:379
Datum interval_reltime(PG_FUNCTION_ARGS)
Definition: nabstime.c:809
#define MAX_DAYNUM
Definition: nabstime.c:33
#define MINS_PER_HOUR
Definition: timestamp.h:89
#define DTK_INVALID
Definition: datetime.h:151
signed int int32
Definition: c.h:256
int32 day
Definition: timestamp.h:47
static struct pg_tm tm
Definition: localtime.c:111
Datum mktinterval(PG_FUNCTION_ARGS)
Definition: nabstime.c:880
#define MONTHS_PER_YEAR
Definition: timestamp.h:69
Datum reltimein(PG_FUNCTION_ARGS)
Definition: nabstime.c:588
void pfree(void *pointer)
Definition: mcxt.c:950
int DecodeDateTime(char **field, int *ftype, int nf, int *dtype, struct pg_tm *tm, fsec_t *fsec, int *tzp)
Definition: datetime.c:783
Datum reltimegt(PG_FUNCTION_ARGS)
Definition: nabstime.c:1060
#define ERROR
Definition: elog.h:43
#define DTERR_FIELD_OVERFLOW
Definition: datetime.h:283
Datum reltimege(PG_FUNCTION_ARGS)
Definition: nabstime.c:1078
#define DatumGetCString(X)
Definition: postgres.h:572
#define PG_RETURN_ABSOLUTETIME(x)
Definition: nabstime.h:62
#define SECS_PER_DAY
Definition: timestamp.h:86
#define DTERR_INTERVAL_OVERFLOW
Definition: datetime.h:285
#define DatumGetRelativeTime(X)
Definition: nabstime.h:51
Datum timeofday(PG_FUNCTION_ARGS)
Definition: nabstime.c:1557
char * c
int tm_mday
Definition: pgtime.h:30
static char * buf
Definition: pg_test_fsync.c:66
#define HOURS_PER_DAY
Definition: timestamp.h:78
int tm_mon
Definition: pgtime.h:31
Datum abstimele(PG_FUNCTION_ARGS)
Definition: nabstime.c:403
int DetermineTimeZoneOffset(struct pg_tm *tm, pg_tz *tzp)
Definition: datetime.c:1471
Datum reltimele(PG_FUNCTION_ARGS)
Definition: nabstime.c:1069
#define SECS_PER_MINUTE
Definition: timestamp.h:88
AbsoluteTime GetCurrentAbsoluteTime(void)
Definition: nabstime.c:89
#define CStringGetDatum(X)
Definition: postgres.h:584
#define DatumGetBool(X)
Definition: postgres.h:399
TimeOffset time
Definition: timestamp.h:45
void EncodeDateTime(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str)
Definition: datetime.c:3999
#define INVALID_ABSTIME
Definition: nabstime.h:76
#define TIMESTAMP_NOBEGIN(j)
Definition: timestamp.h:112
Datum abstimein(PG_FUNCTION_ARGS)
Definition: nabstime.c:196
#define IsSpace(C)
Definition: nabstime.c:44
int32 fsec_t
Definition: timestamp.h:41
int32 RelativeTime
Definition: nabstime.h:37
int32 AbsoluteTime
Definition: nabstime.h:36
const char * tm_zone
Definition: pgtime.h:37
#define ereport(elevel, rest)
Definition: elog.h:122
Datum reltimerecv(PG_FUNCTION_ARGS)
Definition: nabstime.c:660
#define SECS_PER_HOUR
Definition: timestamp.h:87
int DecodeISO8601Interval(char *str, int *dtype, struct pg_tm *tm, fsec_t *fsec)
Definition: datetime.c:3521
int32 month
Definition: timestamp.h:48
int64 Timestamp
Definition: timestamp.h:38
Datum abstime_timestamp(PG_FUNCTION_ARGS)
Definition: nabstime.c:467
void EncodeInterval(struct pg_tm *tm, fsec_t fsec, int style, char *str)
Definition: datetime.c:4241
#define WARNING
Definition: elog.h:40
Datum tintervalov(PG_FUNCTION_ARGS)
Definition: nabstime.c:1368
Datum tintervallengt(PG_FUNCTION_ARGS)
Definition: nabstime.c:1302
#define DTK_LATE
Definition: datetime.h:154
int64 TimeOffset
Definition: timestamp.h:40
#define PG_GETARG_RELATIVETIME(n)
Definition: nabstime.h:59
Datum tintervalrel(PG_FUNCTION_ARGS)
Definition: nabstime.c:974
#define DAYS_PER_MONTH
Definition: timestamp.h:77
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
uintptr_t Datum
Definition: postgres.h:372
#define ABSTIMEMAX(t1, t2)
Definition: nabstime.c:64
#define TimeIntervalGetDatum(X)
Definition: nabstime.h:56
Datum tintervalin(PG_FUNCTION_ARGS)
Definition: nabstime.c:700
#define INVALID_INTERVAL_STR
Definition: nabstime.c:57
void abstime2tm(AbsoluteTime _time, int *tzp, struct pg_tm *tm, char **tzn)
Definition: nabstime.c:99
int date2j(int y, int m, int d)
Definition: datetime.c:292
Datum tintervalct(PG_FUNCTION_ARGS)
Definition: nabstime.c:1347
Datum btreltimecmp(PG_FUNCTION_ARGS)
Definition: nabstime.c:1087
Datum abstimerecv(PG_FUNCTION_ARGS)
Definition: nabstime.c:301
int tm2timestamp(struct pg_tm *tm, fsec_t fsec, int *tzp, Timestamp *result)
Definition: timestamp.c:1854
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:330
#define SECS_PER_YEAR
Definition: timestamp.h:85
text * cstring_to_text(const char *s)
Definition: varlena.c:149
#define NULL
Definition: c.h:229
Datum btabstimecmp(PG_FUNCTION_ARGS)
Definition: nabstime.c:421
#define StrNCpy(dst, src, len)
Definition: c.h:831
#define INT64CONST(x)
Definition: c.h:310
AbsoluteTime data[2]
Definition: nabstime.h:42
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:322
#define T_INTERVAL_LEN
Definition: nabstime.c:56
#define DatumGetAbsoluteTime(X)
Definition: nabstime.h:50
#define DTK_EARLY
Definition: datetime.h:153
#define MAXDATEFIELDS
Definition: datetime.h:205
Datum abstimelt(PG_FUNCTION_ARGS)
Definition: nabstime.c:385
int DateStyle
Definition: globals.c:107
Datum tintervalleneq(PG_FUNCTION_ARGS)
Definition: nabstime.c:1260
Datum tintervalend(PG_FUNCTION_ARGS)
Definition: nabstime.c:1402
struct pg_tm * pg_localtime(const pg_time_t *timep, const pg_tz *tz)
Definition: localtime.c:1314
Datum tintervallenne(PG_FUNCTION_ARGS)
Definition: nabstime.c:1274
#define ABSTIMEMIN(t1, t2)
Definition: nabstime.c:60
Datum timestamp_abstime(PG_FUNCTION_ARGS)
Definition: nabstime.c:434
Datum intinterval(PG_FUNCTION_ARGS)
Definition: nabstime.c:952
Datum tintervallenge(PG_FUNCTION_ARGS)
Definition: nabstime.c:1330
Datum tintervalge(PG_FUNCTION_ARGS)
Definition: nabstime.c:1227
#define DTK_EPOCH
Definition: datetime.h:155
#define PG_RETURN_TIMESTAMP(x)
Definition: timestamp.h:39
Definition: zic.c:90
Datum tintervaleq(PG_FUNCTION_ARGS)
Definition: nabstime.c:1182
#define AbsoluteTimeIsReal(time)
Definition: nabstime.h:91
Datum timepl(PG_FUNCTION_ARGS)
Definition: nabstime.c:914
int tm_year
Definition: pgtime.h:32
static int abstime_cmp_internal(AbsoluteTime a, AbsoluteTime b)
Definition: nabstime.c:340
void * palloc(Size size)
Definition: mcxt.c:849
int errmsg(const char *fmt,...)
Definition: elog.c:797
void pq_sendint(StringInfo buf, int i, int b)
Definition: pqformat.c:236
Datum bttintervalcmp(PG_FUNCTION_ARGS)
Definition: nabstime.c:1236
Datum tintervalgt(PG_FUNCTION_ARGS)
Definition: nabstime.c:1218
Datum abstime_finite(PG_FUNCTION_ARGS)
Definition: nabstime.c:326
#define TIMESTAMP_IS_NOEND(j)
Definition: timestamp.h:120
#define TIMESTAMP_IS_NOBEGIN(j)
Definition: timestamp.h:115
int DecodeInterval(char **field, int *ftype, int nf, int range, int *dtype, struct pg_tm *tm, fsec_t *fsec)
Definition: datetime.c:3095
int i
#define RelativeTimeIsValid(time)
Definition: nabstime.h:95
Datum abstimesend(PG_FUNCTION_ARGS)
Definition: nabstime.c:312
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:242
Datum reltime_interval(PG_FUNCTION_ARGS)
Definition: nabstime.c:837
#define PG_FUNCTION_ARGS
Definition: fmgr.h:158
pg_tz * session_timezone
Definition: pgtz.c:28
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:448
#define UNIX_EPOCH_JDATE
Definition: timestamp.h:162
Datum tintervalne(PG_FUNCTION_ARGS)
Definition: nabstime.c:1191
#define elog
Definition: elog.h:219
Datum abstimege(PG_FUNCTION_ARGS)
Definition: nabstime.c:412
int tm_sec
Definition: pgtime.h:27
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:224
int ParseDateTime(const char *timestr, char *workbuf, size_t buflen, char **field, int *ftype, int maxfields, int *numfields)
Definition: datetime.c:562
#define NOEND_ABSTIME
Definition: nabstime.h:77
#define EARLY
Definition: datetime.h:40
int tm_min
Definition: pgtime.h:28
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1534
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:586
#define DTK_DATE
Definition: datetime.h:145
Datum reltimelt(PG_FUNCTION_ARGS)
Definition: nabstime.c:1051
Datum tintervalrecv(PG_FUNCTION_ARGS)
Definition: nabstime.c:761