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