00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "postgres.h"
00018
00019 #include <ctype.h>
00020 #include <float.h>
00021 #include <limits.h>
00022 #include <time.h>
00023 #include <sys/time.h>
00024
00025 #include "libpq/pqformat.h"
00026 #include "miscadmin.h"
00027 #include "utils/builtins.h"
00028 #include "utils/datetime.h"
00029 #include "utils/nabstime.h"
00030
00031 #define MIN_DAYNUM (-24856)
00032 #define MAX_DAYNUM 24854
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #define IsSpace(C) ((C) == ' ')
00044
00045 #define T_INTERVAL_INVAL 0
00046 #define T_INTERVAL_VALID 1
00047
00048
00049
00050
00051
00052
00053
00054
00055 #define T_INTERVAL_LEN 80
00056 #define INVALID_INTERVAL_STR "Undefined Range"
00057 #define INVALID_INTERVAL_STR_LEN (sizeof(INVALID_INTERVAL_STR)-1)
00058
00059 #define ABSTIMEMIN(t1, t2) \
00060 (DatumGetBool(DirectFunctionCall2(abstimele, \
00061 AbsoluteTimeGetDatum(t1), \
00062 AbsoluteTimeGetDatum(t2))) ? (t1) : (t2))
00063 #define ABSTIMEMAX(t1, t2) \
00064 (DatumGetBool(DirectFunctionCall2(abstimelt, \
00065 AbsoluteTimeGetDatum(t1), \
00066 AbsoluteTimeGetDatum(t2))) ? (t2) : (t1))
00067
00068
00069
00070
00071
00072
00073 static AbsoluteTime tm2abstime(struct pg_tm * tm, int tz);
00074 static void reltime2tm(RelativeTime time, struct pg_tm * tm);
00075 static void parsetinterval(char *i_string,
00076 AbsoluteTime *i_start,
00077 AbsoluteTime *i_end);
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 AbsoluteTime
00088 GetCurrentAbsoluteTime(void)
00089 {
00090 time_t now;
00091
00092 now = time(NULL);
00093 return (AbsoluteTime) now;
00094 }
00095
00096
00097 void
00098 abstime2tm(AbsoluteTime _time, int *tzp, struct pg_tm * tm, char **tzn)
00099 {
00100 pg_time_t time = (pg_time_t) _time;
00101 struct pg_tm *tx;
00102
00103
00104
00105
00106
00107
00108 if (HasCTZSet && (tzp != NULL))
00109 time -= CTimeZone;
00110
00111 if (!HasCTZSet && tzp != NULL)
00112 tx = pg_localtime(&time, session_timezone);
00113 else
00114 tx = pg_gmtime(&time);
00115
00116 tm->tm_year = tx->tm_year + 1900;
00117 tm->tm_mon = tx->tm_mon + 1;
00118 tm->tm_mday = tx->tm_mday;
00119 tm->tm_hour = tx->tm_hour;
00120 tm->tm_min = tx->tm_min;
00121 tm->tm_sec = tx->tm_sec;
00122 tm->tm_isdst = tx->tm_isdst;
00123
00124 tm->tm_gmtoff = tx->tm_gmtoff;
00125 tm->tm_zone = tx->tm_zone;
00126
00127 if (tzp != NULL)
00128 {
00129
00130
00131
00132
00133 if (HasCTZSet)
00134 {
00135 *tzp = CTimeZone;
00136 tm->tm_gmtoff = CTimeZone;
00137 tm->tm_isdst = 0;
00138 tm->tm_zone = NULL;
00139 if (tzn != NULL)
00140 *tzn = NULL;
00141 }
00142 else
00143 {
00144 *tzp = -tm->tm_gmtoff;
00145
00146
00147
00148
00149
00150 if (tzn != NULL)
00151 {
00152
00153
00154
00155
00156
00157 StrNCpy(*tzn, tm->tm_zone, MAXTZLEN + 1);
00158 if (strlen(tm->tm_zone) > MAXTZLEN)
00159 ereport(WARNING,
00160 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
00161 errmsg("invalid time zone name: \"%s\"",
00162 tm->tm_zone)));
00163 }
00164 }
00165 }
00166 else
00167 tm->tm_isdst = -1;
00168 }
00169
00170
00171
00172
00173
00174
00175 static AbsoluteTime
00176 tm2abstime(struct pg_tm * tm, int tz)
00177 {
00178 int day;
00179 AbsoluteTime sec;
00180
00181
00182 if (tm->tm_year < 1901 || tm->tm_year > 2038 ||
00183 tm->tm_mon < 1 || tm->tm_mon > MONTHS_PER_YEAR ||
00184 tm->tm_mday < 1 || tm->tm_mday > 31 ||
00185 tm->tm_hour < 0 ||
00186 tm->tm_hour > HOURS_PER_DAY ||
00187 (tm->tm_hour == HOURS_PER_DAY && (tm->tm_min > 0 || tm->tm_sec > 0)) ||
00188 tm->tm_min < 0 || tm->tm_min > MINS_PER_HOUR - 1 ||
00189 tm->tm_sec < 0 || tm->tm_sec > SECS_PER_MINUTE)
00190 return INVALID_ABSTIME;
00191
00192 day = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - UNIX_EPOCH_JDATE;
00193
00194
00195 if (day < MIN_DAYNUM || day > MAX_DAYNUM)
00196 return INVALID_ABSTIME;
00197
00198
00199 sec = tm->tm_sec + tz + (tm->tm_min + (day * HOURS_PER_DAY + tm->tm_hour) * MINS_PER_HOUR) * SECS_PER_MINUTE;
00200
00201
00202
00203
00204
00205 if ((day >= MAX_DAYNUM - 10 && sec < 0) ||
00206 (day <= MIN_DAYNUM + 10 && sec > 0))
00207 return INVALID_ABSTIME;
00208
00209
00210 if (!AbsoluteTimeIsReal(sec))
00211 return INVALID_ABSTIME;
00212
00213 return sec;
00214 }
00215
00216
00217
00218
00219
00220 Datum
00221 abstimein(PG_FUNCTION_ARGS)
00222 {
00223 char *str = PG_GETARG_CSTRING(0);
00224 AbsoluteTime result;
00225 fsec_t fsec;
00226 int tz = 0;
00227 struct pg_tm date,
00228 *tm = &date;
00229 int dterr;
00230 char *field[MAXDATEFIELDS];
00231 char workbuf[MAXDATELEN + 1];
00232 int dtype;
00233 int nf,
00234 ftype[MAXDATEFIELDS];
00235
00236 dterr = ParseDateTime(str, workbuf, sizeof(workbuf),
00237 field, ftype, MAXDATEFIELDS, &nf);
00238 if (dterr == 0)
00239 dterr = DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tz);
00240 if (dterr != 0)
00241 DateTimeParseError(dterr, str, "abstime");
00242
00243 switch (dtype)
00244 {
00245 case DTK_DATE:
00246 result = tm2abstime(tm, tz);
00247 break;
00248
00249 case DTK_EPOCH:
00250
00251
00252
00253
00254
00255 result = 0;
00256 break;
00257
00258 case DTK_LATE:
00259 result = NOEND_ABSTIME;
00260 break;
00261
00262 case DTK_EARLY:
00263 result = NOSTART_ABSTIME;
00264 break;
00265
00266 case DTK_INVALID:
00267 result = INVALID_ABSTIME;
00268 break;
00269
00270 default:
00271 elog(ERROR, "unexpected dtype %d while parsing abstime \"%s\"",
00272 dtype, str);
00273 result = INVALID_ABSTIME;
00274 break;
00275 };
00276
00277 PG_RETURN_ABSOLUTETIME(result);
00278 }
00279
00280
00281
00282
00283
00284 Datum
00285 abstimeout(PG_FUNCTION_ARGS)
00286 {
00287 AbsoluteTime time = PG_GETARG_ABSOLUTETIME(0);
00288 char *result;
00289 int tz;
00290 double fsec = 0;
00291 struct pg_tm tt,
00292 *tm = &tt;
00293 char buf[MAXDATELEN + 1];
00294 char zone[MAXDATELEN + 1],
00295 *tzn = zone;
00296
00297 switch (time)
00298 {
00299
00300
00301
00302
00303 case INVALID_ABSTIME:
00304 strcpy(buf, INVALID);
00305 break;
00306 case NOEND_ABSTIME:
00307 strcpy(buf, LATE);
00308 break;
00309 case NOSTART_ABSTIME:
00310 strcpy(buf, EARLY);
00311 break;
00312 default:
00313 abstime2tm(time, &tz, tm, &tzn);
00314 EncodeDateTime(tm, fsec, true, tz, tzn, DateStyle, buf);
00315 break;
00316 }
00317
00318 result = pstrdup(buf);
00319 PG_RETURN_CSTRING(result);
00320 }
00321
00322
00323
00324
00325 Datum
00326 abstimerecv(PG_FUNCTION_ARGS)
00327 {
00328 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
00329
00330 PG_RETURN_ABSOLUTETIME((AbsoluteTime) pq_getmsgint(buf, sizeof(AbsoluteTime)));
00331 }
00332
00333
00334
00335
00336 Datum
00337 abstimesend(PG_FUNCTION_ARGS)
00338 {
00339 AbsoluteTime time = PG_GETARG_ABSOLUTETIME(0);
00340 StringInfoData buf;
00341
00342 pq_begintypsend(&buf);
00343 pq_sendint(&buf, time, sizeof(time));
00344 PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
00345 }
00346
00347
00348
00349
00350 Datum
00351 abstime_finite(PG_FUNCTION_ARGS)
00352 {
00353 AbsoluteTime abstime = PG_GETARG_ABSOLUTETIME(0);
00354
00355 PG_RETURN_BOOL(abstime != INVALID_ABSTIME &&
00356 abstime != NOSTART_ABSTIME &&
00357 abstime != NOEND_ABSTIME);
00358 }
00359
00360
00361
00362
00363
00364 static int
00365 abstime_cmp_internal(AbsoluteTime a, AbsoluteTime b)
00366 {
00367
00368
00369
00370
00371
00372 if (a == INVALID_ABSTIME)
00373 {
00374 if (b == INVALID_ABSTIME)
00375 return 0;
00376 else
00377 return 1;
00378 }
00379
00380 if (b == INVALID_ABSTIME)
00381 return -1;
00382
00383 if (a > b)
00384 return 1;
00385 else if (a == b)
00386 return 0;
00387 else
00388 return -1;
00389 }
00390
00391 Datum
00392 abstimeeq(PG_FUNCTION_ARGS)
00393 {
00394 AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0);
00395 AbsoluteTime t2 = PG_GETARG_ABSOLUTETIME(1);
00396
00397 PG_RETURN_BOOL(abstime_cmp_internal(t1, t2) == 0);
00398 }
00399
00400 Datum
00401 abstimene(PG_FUNCTION_ARGS)
00402 {
00403 AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0);
00404 AbsoluteTime t2 = PG_GETARG_ABSOLUTETIME(1);
00405
00406 PG_RETURN_BOOL(abstime_cmp_internal(t1, t2) != 0);
00407 }
00408
00409 Datum
00410 abstimelt(PG_FUNCTION_ARGS)
00411 {
00412 AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0);
00413 AbsoluteTime t2 = PG_GETARG_ABSOLUTETIME(1);
00414
00415 PG_RETURN_BOOL(abstime_cmp_internal(t1, t2) < 0);
00416 }
00417
00418 Datum
00419 abstimegt(PG_FUNCTION_ARGS)
00420 {
00421 AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0);
00422 AbsoluteTime t2 = PG_GETARG_ABSOLUTETIME(1);
00423
00424 PG_RETURN_BOOL(abstime_cmp_internal(t1, t2) > 0);
00425 }
00426
00427 Datum
00428 abstimele(PG_FUNCTION_ARGS)
00429 {
00430 AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0);
00431 AbsoluteTime t2 = PG_GETARG_ABSOLUTETIME(1);
00432
00433 PG_RETURN_BOOL(abstime_cmp_internal(t1, t2) <= 0);
00434 }
00435
00436 Datum
00437 abstimege(PG_FUNCTION_ARGS)
00438 {
00439 AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0);
00440 AbsoluteTime t2 = PG_GETARG_ABSOLUTETIME(1);
00441
00442 PG_RETURN_BOOL(abstime_cmp_internal(t1, t2) >= 0);
00443 }
00444
00445 Datum
00446 btabstimecmp(PG_FUNCTION_ARGS)
00447 {
00448 AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0);
00449 AbsoluteTime t2 = PG_GETARG_ABSOLUTETIME(1);
00450
00451 PG_RETURN_INT32(abstime_cmp_internal(t1, t2));
00452 }
00453
00454
00455
00456
00457
00458 Datum
00459 timestamp_abstime(PG_FUNCTION_ARGS)
00460 {
00461 Timestamp timestamp = PG_GETARG_TIMESTAMP(0);
00462 AbsoluteTime result;
00463 fsec_t fsec;
00464 int tz;
00465 struct pg_tm tt,
00466 *tm = &tt;
00467
00468 if (TIMESTAMP_IS_NOBEGIN(timestamp))
00469 result = NOSTART_ABSTIME;
00470 else if (TIMESTAMP_IS_NOEND(timestamp))
00471 result = NOEND_ABSTIME;
00472 else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) == 0)
00473 {
00474 tz = DetermineTimeZoneOffset(tm, session_timezone);
00475 result = tm2abstime(tm, tz);
00476 }
00477 else
00478 {
00479 ereport(ERROR,
00480 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
00481 errmsg("timestamp out of range")));
00482 result = INVALID_ABSTIME;
00483 }
00484
00485 PG_RETURN_ABSOLUTETIME(result);
00486 }
00487
00488
00489
00490
00491 Datum
00492 abstime_timestamp(PG_FUNCTION_ARGS)
00493 {
00494 AbsoluteTime abstime = PG_GETARG_ABSOLUTETIME(0);
00495 Timestamp result;
00496 struct pg_tm tt,
00497 *tm = &tt;
00498 int tz;
00499 char zone[MAXDATELEN + 1],
00500 *tzn = zone;
00501
00502 switch (abstime)
00503 {
00504 case INVALID_ABSTIME:
00505 ereport(ERROR,
00506 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
00507 errmsg("cannot convert abstime \"invalid\" to timestamp")));
00508 TIMESTAMP_NOBEGIN(result);
00509 break;
00510
00511 case NOSTART_ABSTIME:
00512 TIMESTAMP_NOBEGIN(result);
00513 break;
00514
00515 case NOEND_ABSTIME:
00516 TIMESTAMP_NOEND(result);
00517 break;
00518
00519 default:
00520 abstime2tm(abstime, &tz, tm, &tzn);
00521 if (tm2timestamp(tm, 0, NULL, &result) != 0)
00522 ereport(ERROR,
00523 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
00524 errmsg("timestamp out of range")));
00525 break;
00526 };
00527
00528 PG_RETURN_TIMESTAMP(result);
00529 }
00530
00531
00532
00533
00534
00535 Datum
00536 timestamptz_abstime(PG_FUNCTION_ARGS)
00537 {
00538 TimestampTz timestamp = PG_GETARG_TIMESTAMP(0);
00539 AbsoluteTime result;
00540 fsec_t fsec;
00541 struct pg_tm tt,
00542 *tm = &tt;
00543
00544 if (TIMESTAMP_IS_NOBEGIN(timestamp))
00545 result = NOSTART_ABSTIME;
00546 else if (TIMESTAMP_IS_NOEND(timestamp))
00547 result = NOEND_ABSTIME;
00548 else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) == 0)
00549 result = tm2abstime(tm, 0);
00550 else
00551 {
00552 ereport(ERROR,
00553 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
00554 errmsg("timestamp out of range")));
00555 result = INVALID_ABSTIME;
00556 }
00557
00558 PG_RETURN_ABSOLUTETIME(result);
00559 }
00560
00561
00562
00563
00564 Datum
00565 abstime_timestamptz(PG_FUNCTION_ARGS)
00566 {
00567 AbsoluteTime abstime = PG_GETARG_ABSOLUTETIME(0);
00568 TimestampTz result;
00569 struct pg_tm tt,
00570 *tm = &tt;
00571 int tz;
00572 char zone[MAXDATELEN + 1],
00573 *tzn = zone;
00574
00575 switch (abstime)
00576 {
00577 case INVALID_ABSTIME:
00578 ereport(ERROR,
00579 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
00580 errmsg("cannot convert abstime \"invalid\" to timestamp")));
00581 TIMESTAMP_NOBEGIN(result);
00582 break;
00583
00584 case NOSTART_ABSTIME:
00585 TIMESTAMP_NOBEGIN(result);
00586 break;
00587
00588 case NOEND_ABSTIME:
00589 TIMESTAMP_NOEND(result);
00590 break;
00591
00592 default:
00593 abstime2tm(abstime, &tz, tm, &tzn);
00594 if (tm2timestamp(tm, 0, &tz, &result) != 0)
00595 ereport(ERROR,
00596 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
00597 errmsg("timestamp out of range")));
00598 break;
00599 };
00600
00601 PG_RETURN_TIMESTAMP(result);
00602 }
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612 Datum
00613 reltimein(PG_FUNCTION_ARGS)
00614 {
00615 char *str = PG_GETARG_CSTRING(0);
00616 RelativeTime result;
00617 struct pg_tm tt,
00618 *tm = &tt;
00619 fsec_t fsec;
00620 int dtype;
00621 int dterr;
00622 char *field[MAXDATEFIELDS];
00623 int nf,
00624 ftype[MAXDATEFIELDS];
00625 char workbuf[MAXDATELEN + 1];
00626
00627 dterr = ParseDateTime(str, workbuf, sizeof(workbuf),
00628 field, ftype, MAXDATEFIELDS, &nf);
00629 if (dterr == 0)
00630 dterr = DecodeInterval(field, ftype, nf, INTERVAL_FULL_RANGE,
00631 &dtype, tm, &fsec);
00632
00633
00634 if (dterr == DTERR_BAD_FORMAT)
00635 dterr = DecodeISO8601Interval(str,
00636 &dtype, tm, &fsec);
00637
00638 if (dterr != 0)
00639 {
00640 if (dterr == DTERR_FIELD_OVERFLOW)
00641 dterr = DTERR_INTERVAL_OVERFLOW;
00642 DateTimeParseError(dterr, str, "reltime");
00643 }
00644
00645 switch (dtype)
00646 {
00647 case DTK_DELTA:
00648 result = ((tm->tm_hour * MINS_PER_HOUR + tm->tm_min) * SECS_PER_MINUTE) + tm->tm_sec;
00649 result += tm->tm_year * SECS_PER_YEAR + ((tm->tm_mon * DAYS_PER_MONTH) + tm->tm_mday) * SECS_PER_DAY;
00650 break;
00651
00652 default:
00653 elog(ERROR, "unexpected dtype %d while parsing reltime \"%s\"",
00654 dtype, str);
00655 result = INVALID_RELTIME;
00656 break;
00657 }
00658
00659 PG_RETURN_RELATIVETIME(result);
00660 }
00661
00662
00663
00664
00665 Datum
00666 reltimeout(PG_FUNCTION_ARGS)
00667 {
00668 RelativeTime time = PG_GETARG_RELATIVETIME(0);
00669 char *result;
00670 struct pg_tm tt,
00671 *tm = &tt;
00672 char buf[MAXDATELEN + 1];
00673
00674 reltime2tm(time, tm);
00675 EncodeInterval(tm, 0, IntervalStyle, buf);
00676
00677 result = pstrdup(buf);
00678 PG_RETURN_CSTRING(result);
00679 }
00680
00681
00682
00683
00684 Datum
00685 reltimerecv(PG_FUNCTION_ARGS)
00686 {
00687 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
00688
00689 PG_RETURN_RELATIVETIME((RelativeTime) pq_getmsgint(buf, sizeof(RelativeTime)));
00690 }
00691
00692
00693
00694
00695 Datum
00696 reltimesend(PG_FUNCTION_ARGS)
00697 {
00698 RelativeTime time = PG_GETARG_RELATIVETIME(0);
00699 StringInfoData buf;
00700
00701 pq_begintypsend(&buf);
00702 pq_sendint(&buf, time, sizeof(time));
00703 PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
00704 }
00705
00706
00707 static void
00708 reltime2tm(RelativeTime time, struct pg_tm * tm)
00709 {
00710 double dtime = time;
00711
00712 FMODULO(dtime, tm->tm_year, 31557600);
00713 FMODULO(dtime, tm->tm_mon, 2592000);
00714 FMODULO(dtime, tm->tm_mday, SECS_PER_DAY);
00715 FMODULO(dtime, tm->tm_hour, SECS_PER_HOUR);
00716 FMODULO(dtime, tm->tm_min, SECS_PER_MINUTE);
00717 FMODULO(dtime, tm->tm_sec, 1);
00718 }
00719
00720
00721
00722
00723
00724 Datum
00725 tintervalin(PG_FUNCTION_ARGS)
00726 {
00727 char *tintervalstr = PG_GETARG_CSTRING(0);
00728 TimeInterval tinterval;
00729 AbsoluteTime i_start,
00730 i_end,
00731 t1,
00732 t2;
00733
00734 parsetinterval(tintervalstr, &t1, &t2);
00735
00736 tinterval = (TimeInterval) palloc(sizeof(TimeIntervalData));
00737
00738 if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
00739 tinterval->status = T_INTERVAL_INVAL;
00740 else
00741 tinterval->status = T_INTERVAL_VALID;
00742
00743 i_start = ABSTIMEMIN(t1, t2);
00744 i_end = ABSTIMEMAX(t1, t2);
00745 tinterval->data[0] = i_start;
00746 tinterval->data[1] = i_end;
00747
00748 PG_RETURN_TIMEINTERVAL(tinterval);
00749 }
00750
00751
00752
00753
00754
00755 Datum
00756 tintervalout(PG_FUNCTION_ARGS)
00757 {
00758 TimeInterval tinterval = PG_GETARG_TIMEINTERVAL(0);
00759 char *i_str,
00760 *p;
00761
00762 i_str = (char *) palloc(T_INTERVAL_LEN);
00763 strcpy(i_str, "[\"");
00764 if (tinterval->status == T_INTERVAL_INVAL)
00765 strcat(i_str, INVALID_INTERVAL_STR);
00766 else
00767 {
00768 p = DatumGetCString(DirectFunctionCall1(abstimeout,
00769 AbsoluteTimeGetDatum(tinterval->data[0])));
00770 strcat(i_str, p);
00771 pfree(p);
00772 strcat(i_str, "\" \"");
00773 p = DatumGetCString(DirectFunctionCall1(abstimeout,
00774 AbsoluteTimeGetDatum(tinterval->data[1])));
00775 strcat(i_str, p);
00776 pfree(p);
00777 }
00778 strcat(i_str, "\"]");
00779 PG_RETURN_CSTRING(i_str);
00780 }
00781
00782
00783
00784
00785 Datum
00786 tintervalrecv(PG_FUNCTION_ARGS)
00787 {
00788 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
00789 TimeInterval tinterval;
00790 int32 status;
00791
00792 tinterval = (TimeInterval) palloc(sizeof(TimeIntervalData));
00793
00794 tinterval->status = pq_getmsgint(buf, sizeof(tinterval->status));
00795 tinterval->data[0] = pq_getmsgint(buf, sizeof(tinterval->data[0]));
00796 tinterval->data[1] = pq_getmsgint(buf, sizeof(tinterval->data[1]));
00797
00798 if (tinterval->data[0] == INVALID_ABSTIME ||
00799 tinterval->data[1] == INVALID_ABSTIME)
00800 status = T_INTERVAL_INVAL;
00801 else
00802 status = T_INTERVAL_VALID;
00803
00804 if (status != tinterval->status)
00805 ereport(ERROR,
00806 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
00807 errmsg("invalid status in external \"tinterval\" value")));
00808
00809 PG_RETURN_TIMEINTERVAL(tinterval);
00810 }
00811
00812
00813
00814
00815 Datum
00816 tintervalsend(PG_FUNCTION_ARGS)
00817 {
00818 TimeInterval tinterval = PG_GETARG_TIMEINTERVAL(0);
00819 StringInfoData buf;
00820
00821 pq_begintypsend(&buf);
00822 pq_sendint(&buf, tinterval->status, sizeof(tinterval->status));
00823 pq_sendint(&buf, tinterval->data[0], sizeof(tinterval->data[0]));
00824 pq_sendint(&buf, tinterval->data[1], sizeof(tinterval->data[1]));
00825 PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
00826 }
00827
00828
00829
00830
00831
00832
00833 Datum
00834 interval_reltime(PG_FUNCTION_ARGS)
00835 {
00836 Interval *interval = PG_GETARG_INTERVAL_P(0);
00837 RelativeTime time;
00838 int year,
00839 month,
00840 day;
00841 TimeOffset span;
00842
00843 year = interval->month / MONTHS_PER_YEAR;
00844 month = interval->month % MONTHS_PER_YEAR;
00845 day = interval->day;
00846
00847 #ifdef HAVE_INT64_TIMESTAMP
00848 span = ((INT64CONST(365250000) * year + INT64CONST(30000000) * month +
00849 INT64CONST(1000000) * day) * INT64CONST(86400)) +
00850 interval->time;
00851 span /= USECS_PER_SEC;
00852 #else
00853 span = (DAYS_PER_YEAR * year + (double) DAYS_PER_MONTH * month + day) * SECS_PER_DAY + interval->time;
00854 #endif
00855
00856 if (span < INT_MIN || span > INT_MAX)
00857 time = INVALID_RELTIME;
00858 else
00859 time = span;
00860
00861 PG_RETURN_RELATIVETIME(time);
00862 }
00863
00864
00865 Datum
00866 reltime_interval(PG_FUNCTION_ARGS)
00867 {
00868 RelativeTime reltime = PG_GETARG_RELATIVETIME(0);
00869 Interval *result;
00870 int year,
00871 month,
00872 day;
00873
00874 result = (Interval *) palloc(sizeof(Interval));
00875
00876 switch (reltime)
00877 {
00878 case INVALID_RELTIME:
00879 ereport(ERROR,
00880 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
00881 errmsg("cannot convert reltime \"invalid\" to interval")));
00882 result->time = 0;
00883 result->day = 0;
00884 result->month = 0;
00885 break;
00886
00887 default:
00888 #ifdef HAVE_INT64_TIMESTAMP
00889 year = reltime / SECS_PER_YEAR;
00890 reltime -= year * SECS_PER_YEAR;
00891 month = reltime / (DAYS_PER_MONTH * SECS_PER_DAY);
00892 reltime -= month * (DAYS_PER_MONTH * SECS_PER_DAY);
00893 day = reltime / SECS_PER_DAY;
00894 reltime -= day * SECS_PER_DAY;
00895
00896 result->time = (reltime * USECS_PER_SEC);
00897 #else
00898 TMODULO(reltime, year, SECS_PER_YEAR);
00899 TMODULO(reltime, month, DAYS_PER_MONTH * SECS_PER_DAY);
00900 TMODULO(reltime, day, SECS_PER_DAY);
00901
00902 result->time = reltime;
00903 #endif
00904 result->month = MONTHS_PER_YEAR * year + month;
00905 result->day = day;
00906 break;
00907 }
00908
00909 PG_RETURN_INTERVAL_P(result);
00910 }
00911
00912
00913
00914
00915
00916 Datum
00917 mktinterval(PG_FUNCTION_ARGS)
00918 {
00919 AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0);
00920 AbsoluteTime t2 = PG_GETARG_ABSOLUTETIME(1);
00921 AbsoluteTime tstart = ABSTIMEMIN(t1, t2);
00922 AbsoluteTime tend = ABSTIMEMAX(t1, t2);
00923 TimeInterval tinterval;
00924
00925 tinterval = (TimeInterval) palloc(sizeof(TimeIntervalData));
00926
00927 if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
00928 tinterval->status = T_INTERVAL_INVAL;
00929
00930 else
00931 {
00932 tinterval->status = T_INTERVAL_VALID;
00933 tinterval->data[0] = tstart;
00934 tinterval->data[1] = tend;
00935 }
00936
00937 PG_RETURN_TIMEINTERVAL(tinterval);
00938 }
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950 Datum
00951 timepl(PG_FUNCTION_ARGS)
00952 {
00953 AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0);
00954 RelativeTime t2 = PG_GETARG_RELATIVETIME(1);
00955
00956 if (AbsoluteTimeIsReal(t1) &&
00957 RelativeTimeIsValid(t2) &&
00958 ((t2 > 0 && t1 < NOEND_ABSTIME - t2) ||
00959 (t2 <= 0 && t1 > NOSTART_ABSTIME - t2)))
00960 PG_RETURN_ABSOLUTETIME(t1 + t2);
00961
00962 PG_RETURN_ABSOLUTETIME(INVALID_ABSTIME);
00963 }
00964
00965
00966
00967
00968
00969 Datum
00970 timemi(PG_FUNCTION_ARGS)
00971 {
00972 AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0);
00973 RelativeTime t2 = PG_GETARG_RELATIVETIME(1);
00974
00975 if (AbsoluteTimeIsReal(t1) &&
00976 RelativeTimeIsValid(t2) &&
00977 ((t2 > 0 && t1 > NOSTART_ABSTIME + t2) ||
00978 (t2 <= 0 && t1 < NOEND_ABSTIME + t2)))
00979 PG_RETURN_ABSOLUTETIME(t1 - t2);
00980
00981 PG_RETURN_ABSOLUTETIME(INVALID_ABSTIME);
00982 }
00983
00984
00985
00986
00987
00988 Datum
00989 intinterval(PG_FUNCTION_ARGS)
00990 {
00991 AbsoluteTime t = PG_GETARG_ABSOLUTETIME(0);
00992 TimeInterval tinterval = PG_GETARG_TIMEINTERVAL(1);
00993
00994 if (tinterval->status == T_INTERVAL_VALID && t != INVALID_ABSTIME)
00995 {
00996 if (DatumGetBool(DirectFunctionCall2(abstimege,
00997 AbsoluteTimeGetDatum(t),
00998 AbsoluteTimeGetDatum(tinterval->data[0]))) &&
00999 DatumGetBool(DirectFunctionCall2(abstimele,
01000 AbsoluteTimeGetDatum(t),
01001 AbsoluteTimeGetDatum(tinterval->data[1]))))
01002 PG_RETURN_BOOL(true);
01003 }
01004 PG_RETURN_BOOL(false);
01005 }
01006
01007
01008
01009
01010 Datum
01011 tintervalrel(PG_FUNCTION_ARGS)
01012 {
01013 TimeInterval tinterval = PG_GETARG_TIMEINTERVAL(0);
01014 AbsoluteTime t1 = tinterval->data[0];
01015 AbsoluteTime t2 = tinterval->data[1];
01016
01017 if (tinterval->status != T_INTERVAL_VALID)
01018 PG_RETURN_RELATIVETIME(INVALID_RELTIME);
01019
01020 if (AbsoluteTimeIsReal(t1) &&
01021 AbsoluteTimeIsReal(t2))
01022 PG_RETURN_RELATIVETIME(t2 - t1);
01023
01024 PG_RETURN_RELATIVETIME(INVALID_RELTIME);
01025 }
01026
01027
01028
01029
01030
01031
01032
01033 Datum
01034 timenow(PG_FUNCTION_ARGS)
01035 {
01036 PG_RETURN_ABSOLUTETIME(GetCurrentAbsoluteTime());
01037 }
01038
01039
01040
01041
01042 static int
01043 reltime_cmp_internal(RelativeTime a, RelativeTime b)
01044 {
01045
01046
01047
01048
01049
01050 if (a == INVALID_RELTIME)
01051 {
01052 if (b == INVALID_RELTIME)
01053 return 0;
01054 else
01055 return 1;
01056 }
01057
01058 if (b == INVALID_RELTIME)
01059 return -1;
01060
01061 if (a > b)
01062 return 1;
01063 else if (a == b)
01064 return 0;
01065 else
01066 return -1;
01067 }
01068
01069 Datum
01070 reltimeeq(PG_FUNCTION_ARGS)
01071 {
01072 RelativeTime t1 = PG_GETARG_RELATIVETIME(0);
01073 RelativeTime t2 = PG_GETARG_RELATIVETIME(1);
01074
01075 PG_RETURN_BOOL(reltime_cmp_internal(t1, t2) == 0);
01076 }
01077
01078 Datum
01079 reltimene(PG_FUNCTION_ARGS)
01080 {
01081 RelativeTime t1 = PG_GETARG_RELATIVETIME(0);
01082 RelativeTime t2 = PG_GETARG_RELATIVETIME(1);
01083
01084 PG_RETURN_BOOL(reltime_cmp_internal(t1, t2) != 0);
01085 }
01086
01087 Datum
01088 reltimelt(PG_FUNCTION_ARGS)
01089 {
01090 RelativeTime t1 = PG_GETARG_RELATIVETIME(0);
01091 RelativeTime t2 = PG_GETARG_RELATIVETIME(1);
01092
01093 PG_RETURN_BOOL(reltime_cmp_internal(t1, t2) < 0);
01094 }
01095
01096 Datum
01097 reltimegt(PG_FUNCTION_ARGS)
01098 {
01099 RelativeTime t1 = PG_GETARG_RELATIVETIME(0);
01100 RelativeTime t2 = PG_GETARG_RELATIVETIME(1);
01101
01102 PG_RETURN_BOOL(reltime_cmp_internal(t1, t2) > 0);
01103 }
01104
01105 Datum
01106 reltimele(PG_FUNCTION_ARGS)
01107 {
01108 RelativeTime t1 = PG_GETARG_RELATIVETIME(0);
01109 RelativeTime t2 = PG_GETARG_RELATIVETIME(1);
01110
01111 PG_RETURN_BOOL(reltime_cmp_internal(t1, t2) <= 0);
01112 }
01113
01114 Datum
01115 reltimege(PG_FUNCTION_ARGS)
01116 {
01117 RelativeTime t1 = PG_GETARG_RELATIVETIME(0);
01118 RelativeTime t2 = PG_GETARG_RELATIVETIME(1);
01119
01120 PG_RETURN_BOOL(reltime_cmp_internal(t1, t2) >= 0);
01121 }
01122
01123 Datum
01124 btreltimecmp(PG_FUNCTION_ARGS)
01125 {
01126 RelativeTime t1 = PG_GETARG_RELATIVETIME(0);
01127 RelativeTime t2 = PG_GETARG_RELATIVETIME(1);
01128
01129 PG_RETURN_INT32(reltime_cmp_internal(t1, t2));
01130 }
01131
01132
01133
01134
01135
01136
01137 Datum
01138 tintervalsame(PG_FUNCTION_ARGS)
01139 {
01140 TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0);
01141 TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1);
01142
01143 if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
01144 PG_RETURN_BOOL(false);
01145
01146 if (DatumGetBool(DirectFunctionCall2(abstimeeq,
01147 AbsoluteTimeGetDatum(i1->data[0]),
01148 AbsoluteTimeGetDatum(i2->data[0]))) &&
01149 DatumGetBool(DirectFunctionCall2(abstimeeq,
01150 AbsoluteTimeGetDatum(i1->data[1]),
01151 AbsoluteTimeGetDatum(i2->data[1]))))
01152 PG_RETURN_BOOL(true);
01153 PG_RETURN_BOOL(false);
01154 }
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176 static int
01177 tinterval_cmp_internal(TimeInterval a, TimeInterval b)
01178 {
01179 bool a_invalid;
01180 bool b_invalid;
01181 AbsoluteTime a_len;
01182 AbsoluteTime b_len;
01183
01184
01185
01186
01187
01188
01189 a_invalid = a->status == T_INTERVAL_INVAL ||
01190 a->data[0] == INVALID_ABSTIME ||
01191 a->data[1] == INVALID_ABSTIME;
01192 b_invalid = b->status == T_INTERVAL_INVAL ||
01193 b->data[0] == INVALID_ABSTIME ||
01194 b->data[1] == INVALID_ABSTIME;
01195
01196 if (a_invalid)
01197 {
01198 if (b_invalid)
01199 return 0;
01200 else
01201 return 1;
01202 }
01203
01204 if (b_invalid)
01205 return -1;
01206
01207 a_len = a->data[1] - a->data[0];
01208 b_len = b->data[1] - b->data[0];
01209
01210 if (a_len > b_len)
01211 return 1;
01212 else if (a_len == b_len)
01213 return 0;
01214 else
01215 return -1;
01216 }
01217
01218 Datum
01219 tintervaleq(PG_FUNCTION_ARGS)
01220 {
01221 TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0);
01222 TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1);
01223
01224 PG_RETURN_BOOL(tinterval_cmp_internal(i1, i2) == 0);
01225 }
01226
01227 Datum
01228 tintervalne(PG_FUNCTION_ARGS)
01229 {
01230 TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0);
01231 TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1);
01232
01233 PG_RETURN_BOOL(tinterval_cmp_internal(i1, i2) != 0);
01234 }
01235
01236 Datum
01237 tintervallt(PG_FUNCTION_ARGS)
01238 {
01239 TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0);
01240 TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1);
01241
01242 PG_RETURN_BOOL(tinterval_cmp_internal(i1, i2) < 0);
01243 }
01244
01245 Datum
01246 tintervalle(PG_FUNCTION_ARGS)
01247 {
01248 TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0);
01249 TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1);
01250
01251 PG_RETURN_BOOL(tinterval_cmp_internal(i1, i2) <= 0);
01252 }
01253
01254 Datum
01255 tintervalgt(PG_FUNCTION_ARGS)
01256 {
01257 TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0);
01258 TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1);
01259
01260 PG_RETURN_BOOL(tinterval_cmp_internal(i1, i2) > 0);
01261 }
01262
01263 Datum
01264 tintervalge(PG_FUNCTION_ARGS)
01265 {
01266 TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0);
01267 TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1);
01268
01269 PG_RETURN_BOOL(tinterval_cmp_internal(i1, i2) >= 0);
01270 }
01271
01272 Datum
01273 bttintervalcmp(PG_FUNCTION_ARGS)
01274 {
01275 TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0);
01276 TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1);
01277
01278 PG_RETURN_INT32(tinterval_cmp_internal(i1, i2));
01279 }
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296 Datum
01297 tintervalleneq(PG_FUNCTION_ARGS)
01298 {
01299 TimeInterval i = PG_GETARG_TIMEINTERVAL(0);
01300 RelativeTime t = PG_GETARG_RELATIVETIME(1);
01301 RelativeTime rt;
01302
01303 if (i->status == T_INTERVAL_INVAL || t == INVALID_RELTIME)
01304 PG_RETURN_BOOL(false);
01305 rt = DatumGetRelativeTime(DirectFunctionCall1(tintervalrel,
01306 TimeIntervalGetDatum(i)));
01307 PG_RETURN_BOOL(rt != INVALID_RELTIME && rt == t);
01308 }
01309
01310 Datum
01311 tintervallenne(PG_FUNCTION_ARGS)
01312 {
01313 TimeInterval i = PG_GETARG_TIMEINTERVAL(0);
01314 RelativeTime t = PG_GETARG_RELATIVETIME(1);
01315 RelativeTime rt;
01316
01317 if (i->status == T_INTERVAL_INVAL || t == INVALID_RELTIME)
01318 PG_RETURN_BOOL(false);
01319 rt = DatumGetRelativeTime(DirectFunctionCall1(tintervalrel,
01320 TimeIntervalGetDatum(i)));
01321 PG_RETURN_BOOL(rt != INVALID_RELTIME && rt != t);
01322 }
01323
01324 Datum
01325 tintervallenlt(PG_FUNCTION_ARGS)
01326 {
01327 TimeInterval i = PG_GETARG_TIMEINTERVAL(0);
01328 RelativeTime t = PG_GETARG_RELATIVETIME(1);
01329 RelativeTime rt;
01330
01331 if (i->status == T_INTERVAL_INVAL || t == INVALID_RELTIME)
01332 PG_RETURN_BOOL(false);
01333 rt = DatumGetRelativeTime(DirectFunctionCall1(tintervalrel,
01334 TimeIntervalGetDatum(i)));
01335 PG_RETURN_BOOL(rt != INVALID_RELTIME && rt < t);
01336 }
01337
01338 Datum
01339 tintervallengt(PG_FUNCTION_ARGS)
01340 {
01341 TimeInterval i = PG_GETARG_TIMEINTERVAL(0);
01342 RelativeTime t = PG_GETARG_RELATIVETIME(1);
01343 RelativeTime rt;
01344
01345 if (i->status == T_INTERVAL_INVAL || t == INVALID_RELTIME)
01346 PG_RETURN_BOOL(false);
01347 rt = DatumGetRelativeTime(DirectFunctionCall1(tintervalrel,
01348 TimeIntervalGetDatum(i)));
01349 PG_RETURN_BOOL(rt != INVALID_RELTIME && rt > t);
01350 }
01351
01352 Datum
01353 tintervallenle(PG_FUNCTION_ARGS)
01354 {
01355 TimeInterval i = PG_GETARG_TIMEINTERVAL(0);
01356 RelativeTime t = PG_GETARG_RELATIVETIME(1);
01357 RelativeTime rt;
01358
01359 if (i->status == T_INTERVAL_INVAL || t == INVALID_RELTIME)
01360 PG_RETURN_BOOL(false);
01361 rt = DatumGetRelativeTime(DirectFunctionCall1(tintervalrel,
01362 TimeIntervalGetDatum(i)));
01363 PG_RETURN_BOOL(rt != INVALID_RELTIME && rt <= t);
01364 }
01365
01366 Datum
01367 tintervallenge(PG_FUNCTION_ARGS)
01368 {
01369 TimeInterval i = PG_GETARG_TIMEINTERVAL(0);
01370 RelativeTime t = PG_GETARG_RELATIVETIME(1);
01371 RelativeTime rt;
01372
01373 if (i->status == T_INTERVAL_INVAL || t == INVALID_RELTIME)
01374 PG_RETURN_BOOL(false);
01375 rt = DatumGetRelativeTime(DirectFunctionCall1(tintervalrel,
01376 TimeIntervalGetDatum(i)));
01377 PG_RETURN_BOOL(rt != INVALID_RELTIME && rt >= t);
01378 }
01379
01380
01381
01382
01383 Datum
01384 tintervalct(PG_FUNCTION_ARGS)
01385 {
01386 TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0);
01387 TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1);
01388
01389 if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
01390 PG_RETURN_BOOL(false);
01391 if (DatumGetBool(DirectFunctionCall2(abstimele,
01392 AbsoluteTimeGetDatum(i1->data[0]),
01393 AbsoluteTimeGetDatum(i2->data[0]))) &&
01394 DatumGetBool(DirectFunctionCall2(abstimege,
01395 AbsoluteTimeGetDatum(i1->data[1]),
01396 AbsoluteTimeGetDatum(i2->data[1]))))
01397 PG_RETURN_BOOL(true);
01398 PG_RETURN_BOOL(false);
01399 }
01400
01401
01402
01403
01404 Datum
01405 tintervalov(PG_FUNCTION_ARGS)
01406 {
01407 TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0);
01408 TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1);
01409
01410 if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
01411 PG_RETURN_BOOL(false);
01412 if (DatumGetBool(DirectFunctionCall2(abstimelt,
01413 AbsoluteTimeGetDatum(i1->data[1]),
01414 AbsoluteTimeGetDatum(i2->data[0]))) ||
01415 DatumGetBool(DirectFunctionCall2(abstimegt,
01416 AbsoluteTimeGetDatum(i1->data[0]),
01417 AbsoluteTimeGetDatum(i2->data[1]))))
01418 PG_RETURN_BOOL(false);
01419 PG_RETURN_BOOL(true);
01420 }
01421
01422
01423
01424
01425 Datum
01426 tintervalstart(PG_FUNCTION_ARGS)
01427 {
01428 TimeInterval i = PG_GETARG_TIMEINTERVAL(0);
01429
01430 if (i->status == T_INTERVAL_INVAL)
01431 PG_RETURN_ABSOLUTETIME(INVALID_ABSTIME);
01432 PG_RETURN_ABSOLUTETIME(i->data[0]);
01433 }
01434
01435
01436
01437
01438 Datum
01439 tintervalend(PG_FUNCTION_ARGS)
01440 {
01441 TimeInterval i = PG_GETARG_TIMEINTERVAL(0);
01442
01443 if (i->status == T_INTERVAL_INVAL)
01444 PG_RETURN_ABSOLUTETIME(INVALID_ABSTIME);
01445 PG_RETURN_ABSOLUTETIME(i->data[1]);
01446 }
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468 static void
01469 parsetinterval(char *i_string,
01470 AbsoluteTime *i_start,
01471 AbsoluteTime *i_end)
01472 {
01473 char *p,
01474 *p1;
01475 char c;
01476
01477 p = i_string;
01478
01479 while ((c = *p) != '\0')
01480 {
01481 if (IsSpace(c))
01482 p++;
01483 else if (c != '[')
01484 goto bogus;
01485 else
01486 break;
01487 }
01488 if (c == '\0')
01489 goto bogus;
01490 p++;
01491
01492 while ((c = *p) != '\0')
01493 {
01494 if (IsSpace(c))
01495 p++;
01496 else if (c != '"')
01497 goto bogus;
01498 else
01499 break;
01500 }
01501 if (c == '\0')
01502 goto bogus;
01503 p++;
01504 if (strncmp(INVALID_INTERVAL_STR, p, strlen(INVALID_INTERVAL_STR)) == 0)
01505 goto bogus;
01506
01507 p1 = p;
01508 while ((c = *p1) != '\0')
01509 {
01510 if (c == '"')
01511 break;
01512 p1++;
01513 }
01514 if (c == '\0')
01515 goto bogus;
01516 *p1 = '\0';
01517
01518 *i_start = DatumGetAbsoluteTime(DirectFunctionCall1(abstimein,
01519 CStringGetDatum(p)));
01520
01521 *p1 = c;
01522 p = ++p1;
01523
01524 while ((c = *p) != '\0')
01525 {
01526 if (IsSpace(c))
01527 p++;
01528 else if (c != '"')
01529 goto bogus;
01530 else
01531 break;
01532 }
01533 if (c == '\0')
01534 goto bogus;
01535 p++;
01536
01537 p1 = p;
01538 while ((c = *p1) != '\0')
01539 {
01540 if (c == '"')
01541 break;
01542 p1++;
01543 }
01544 if (c == '\0')
01545 goto bogus;
01546 *p1 = '\0';
01547
01548 *i_end = DatumGetAbsoluteTime(DirectFunctionCall1(abstimein,
01549 CStringGetDatum(p)));
01550
01551 *p1 = c;
01552 p = ++p1;
01553
01554 while ((c = *p) != '\0')
01555 {
01556 if (IsSpace(c))
01557 p++;
01558 else if (c != ']')
01559 goto bogus;
01560 else
01561 break;
01562 }
01563 if (c == '\0')
01564 goto bogus;
01565 p++;
01566 c = *p;
01567 if (c != '\0')
01568 goto bogus;
01569
01570
01571 return;
01572
01573 bogus:
01574 ereport(ERROR,
01575 (errcode(ERRCODE_INVALID_DATETIME_FORMAT),
01576 errmsg("invalid input syntax for type tinterval: \"%s\"",
01577 i_string)));
01578 *i_start = *i_end = INVALID_ABSTIME;
01579 }
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593 Datum
01594 timeofday(PG_FUNCTION_ARGS)
01595 {
01596 struct timeval tp;
01597 char templ[128];
01598 char buf[128];
01599 pg_time_t tt;
01600
01601 gettimeofday(&tp, NULL);
01602 tt = (pg_time_t) tp.tv_sec;
01603 pg_strftime(templ, sizeof(templ), "%a %b %d %H:%M:%S.%%06d %Y %Z",
01604 pg_localtime(&tt, session_timezone));
01605 snprintf(buf, sizeof(buf), templ, tp.tv_usec);
01606
01607 PG_RETURN_TEXT_P(cstring_to_text(buf));
01608 }