date.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:28k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * date.c
  4.  *   Utilities for the built-in type "AbsoluteTime" (defined in nabstime).
  5.  *   Functions for the built-in type "RelativeTime".
  6.  *   Functions for the built-in type "TimeInterval".
  7.  *
  8.  * Copyright (c) 1994, Regents of the University of California
  9.  *
  10.  *
  11.  * IDENTIFICATION
  12.  *   $Header: /usr/local/cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.32.2.1 1999/08/02 05:24:51 scrappy Exp $
  13.  *
  14.  * NOTES
  15.  *  This code is actually (almost) unused.
  16.  *  It needs to be integrated with Time and struct trange.
  17.  *
  18.  * XXX This code needs to be rewritten to work with the "new" definitions
  19.  * XXX in h/tim.h.  Look for int32's, int, long, etc. in the code.  The
  20.  * XXX definitions in h/tim.h may need to be rethought also.
  21.  *
  22.  * XXX This code has been cleaned up some - avi 07/07/93
  23.  *
  24.  *-------------------------------------------------------------------------
  25.  */
  26. #include <ctype.h>
  27. #include <time.h>
  28. #include <sys/time.h>
  29. #include <sys/types.h>
  30. #include "postgres.h"
  31. #ifdef HAVE_FLOAT_H
  32. #include <float.h>
  33. #endif
  34. #ifdef HAVE_LIMITS_H
  35. #include <limits.h>
  36. #endif
  37. #include "access/xact.h"
  38. #include "miscadmin.h"
  39. #include "utils/builtins.h"
  40. #include "utils/dt.h"
  41. #define INVALID_RELTIME_STR "Undefined RelTime"
  42. #define INVALID_RELTIME_STR_LEN (sizeof(INVALID_RELTIME_STR)-1)
  43. #define RELTIME_LABEL '@'
  44. #define RELTIME_PAST "ago"
  45. #define DIRMAXLEN (sizeof(RELTIME_PAST)-1)
  46. /*
  47.  * Unix epoch is Jan  1 00:00:00 1970.  Postgres knows about times
  48.  * sixty-eight years on either side of that.
  49.  */
  50. #define IsSpace(C) ((C) == ' ')
  51. #define T_INTERVAL_INVAL   0 /* data represents no valid interval */
  52. #define T_INTERVAL_VALID   1 /* data represents a valid interval */
  53. /*
  54.  * ['Mon May 10 23:59:12 1943 PST' 'Sun Jan 14 03:14:21 1973 PST']
  55.  * 0 1   2 3   4 5   6
  56.  * 1234567890123456789012345678901234567890123456789012345678901234
  57.  *
  58.  * we allocate some extra -- timezones are usually 3 characters but
  59.  * this is not in the POSIX standard...
  60.  */
  61. #define T_INTERVAL_LEN 80
  62. #define INVALID_INTERVAL_STR "Undefined Range"
  63. #define INVALID_INTERVAL_STR_LEN (sizeof(INVALID_INTERVAL_STR)-1)
  64. #define ABSTIMEMIN(t1, t2) abstimele((t1),(t2)) ? (t1) : (t2)
  65. #define ABSTIMEMAX(t1, t2) abstimelt((t1),(t2)) ? (t2) : (t1)
  66. #ifdef NOT_USED
  67. static char *unit_tab[] = {
  68. "second", "seconds", "minute", "minutes",
  69. "hour", "hours", "day", "days", "week", "weeks",
  70. "month", "months", "year", "years"};
  71. #define UNITMAXLEN 7 /* max length of a unit name */
  72. #define NUNITS 14 /* number of different units */
  73. /* table of seconds per unit (month = 30 days, year = 365 days)  */
  74. static int sec_tab[] = {
  75. 1, 1, 60, 60,
  76. 3600, 3600, 86400, 86400, 604800, 604800,
  77. 2592000, 2592000, 31536000, 31536000};
  78. #endif
  79. /*
  80.  * Function prototypes -- internal to this file only
  81.  */
  82. static void reltime2tm(RelativeTime time, struct tm * tm);
  83. #ifdef NOT_USED
  84. static int correct_unit(char *unit, int *unptr);
  85. static int correct_dir(char *direction, int *signptr);
  86. #endif
  87. static int istinterval(char *i_string,
  88. AbsoluteTime *i_start,
  89. AbsoluteTime *i_end);
  90. /*****************************************************************************
  91.  *  USER I/O ROUTINES  *
  92.  *****************************************************************************/
  93. /*
  94.  * reltimein - converts a reltime string in an internal format
  95.  */
  96. RelativeTime
  97. reltimein(char *str)
  98. {
  99. RelativeTime result;
  100. struct tm tt,
  101.    *tm = &tt;
  102. double fsec;
  103. int dtype;
  104. char    *field[MAXDATEFIELDS];
  105. int nf,
  106. ftype[MAXDATEFIELDS];
  107. char lowstr[MAXDATELEN + 1];
  108. if (!PointerIsValid(str))
  109. elog(ERROR, "Bad (null) date external representation", NULL);
  110. if (strlen(str) > MAXDATELEN)
  111. elog(ERROR, "Bad (length) reltime external representation '%s'", str);
  112. if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
  113. || (DecodeDateDelta(field, ftype, nf, &dtype, tm, &fsec) != 0))
  114. elog(ERROR, "Bad reltime external representation '%s'", str);
  115. #ifdef DATEDEBUG
  116. printf("reltimein- %d fields are type %d (DTK_DATE=%d)n", nf, dtype, DTK_DATE);
  117. #endif
  118. switch (dtype)
  119. {
  120. case DTK_DELTA:
  121. result = ((((tm->tm_hour * 60) + tm->tm_min) * 60) + tm->tm_sec);
  122. result += (((tm->tm_year * 365) + (tm->tm_mon * 30) + tm->tm_mday) * (24 * 60 * 60));
  123. return result;
  124. default:
  125. return INVALID_RELTIME;
  126. }
  127. elog(ERROR, "Bad reltime (internal coding error) '%s'", str);
  128. return INVALID_RELTIME;
  129. } /* reltimein() */
  130. /*
  131.  * reltimeout - converts the internal format to a reltime string
  132.  */
  133. char *
  134. reltimeout(RelativeTime time)
  135. {
  136. char    *result;
  137. struct tm tt,
  138.    *tm = &tt;
  139. char buf[MAXDATELEN + 1];
  140. if (time == INVALID_RELTIME)
  141. {
  142. strcpy(buf, INVALID_RELTIME_STR);
  143. }
  144. else
  145. {
  146. reltime2tm(time, tm);
  147. EncodeTimeSpan(tm, 0, DateStyle, buf);
  148. }
  149. result = palloc(strlen(buf) + 1);
  150. strcpy(result, buf);
  151. return result;
  152. } /* reltimeout() */
  153. #define TMODULO(t,q,u) 
  154. do { 
  155. q = (t / u); 
  156. if (q != 0) t -= (q * u); 
  157. } while(0)
  158. static void
  159. reltime2tm(RelativeTime time, struct tm * tm)
  160. {
  161. TMODULO(time, tm->tm_year, 31536000);
  162. TMODULO(time, tm->tm_mon, 2592000);
  163. TMODULO(time, tm->tm_mday, 86400);
  164. TMODULO(time, tm->tm_hour, 3600);
  165. TMODULO(time, tm->tm_min, 60);
  166. TMODULO(time, tm->tm_sec, 1);
  167. return;
  168. } /* reltime2tm() */
  169. #ifdef NOT_USED
  170. int
  171. dummyfunc()
  172. {
  173. char    *timestring;
  174. long quantity;
  175. int i;
  176. int unitnr;
  177. timestring = (char *) palloc(Max(strlen(INVALID_RELTIME_STR),
  178.  UNITMAXLEN) + 1);
  179. if (timevalue == INVALID_RELTIME)
  180. {
  181. strcpy(timestring, INVALID_RELTIME_STR);
  182. return timestring;
  183. }
  184. if (timevalue == 0)
  185. i = 1; /* unit = 'seconds' */
  186. else
  187. for (i = 12; i >= 0; i = i - 2)
  188. if ((timevalue % sec_tab[i]) == 0)
  189. break; /* appropriate unit found */
  190. unitnr = i;
  191. quantity = (timevalue / sec_tab[unitnr]);
  192. if (quantity > 1 || quantity < -1)
  193. unitnr++; /* adjust index for PLURAL of unit */
  194. if (quantity >= 0)
  195. sprintf(timestring, "%c %lu %s", RELTIME_LABEL,
  196. quantity, unit_tab[unitnr]);
  197. else
  198. sprintf(timestring, "%c %lu %s %s", RELTIME_LABEL,
  199. (quantity * -1), unit_tab[unitnr], RELTIME_PAST);
  200. return timestring;
  201. }
  202. #endif
  203. /*
  204.  * tintervalin - converts an interval string to an internal format
  205.  */
  206. TimeInterval
  207. tintervalin(char *intervalstr)
  208. {
  209. int error;
  210. AbsoluteTime i_start,
  211. i_end,
  212. t1,
  213. t2;
  214. TimeInterval interval;
  215. interval = (TimeInterval) palloc(sizeof(TimeIntervalData));
  216. error = istinterval(intervalstr, &t1, &t2);
  217. if (error == 0)
  218. interval->status = T_INTERVAL_INVAL;
  219. if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
  220. interval->status = T_INTERVAL_INVAL; /* undefined  */
  221. else
  222. {
  223. i_start = ABSTIMEMIN(t1, t2);
  224. i_end = ABSTIMEMAX(t1, t2);
  225. interval->data[0] = i_start;
  226. interval->data[1] = i_end;
  227. interval->status = T_INTERVAL_VALID;
  228. }
  229. return interval;
  230. }
  231. /*
  232.  * tintervalout - converts an internal interval format to a string
  233.  *
  234.  */
  235. char *
  236. tintervalout(TimeInterval interval)
  237. {
  238. char    *i_str,
  239.    *p;
  240. i_str = (char *) palloc(T_INTERVAL_LEN); /* ['...' '...'] */
  241. strcpy(i_str, "["");
  242. if (interval->status == T_INTERVAL_INVAL)
  243. strcat(i_str, INVALID_INTERVAL_STR);
  244. else
  245. {
  246. p = nabstimeout(interval->data[0]);
  247. strcat(i_str, p);
  248. pfree(p);
  249. strcat(i_str, "" "");
  250. p = nabstimeout(interval->data[1]);
  251. strcat(i_str, p);
  252. pfree(p);
  253. }
  254. strcat(i_str, ""]");
  255. return i_str;
  256. }
  257. /*****************************************************************************
  258.  *  PUBLIC ROUTINES  *
  259.  *****************************************************************************/
  260. RelativeTime
  261. timespan_reltime(TimeSpan *timespan)
  262. {
  263. RelativeTime time;
  264. int year,
  265. month;
  266. double span;
  267. if (!PointerIsValid(timespan))
  268. time = INVALID_RELTIME;
  269. if (TIMESPAN_IS_INVALID(*timespan))
  270. {
  271. time = INVALID_RELTIME;
  272. }
  273. else
  274. {
  275. if (timespan->month == 0)
  276. {
  277. year = 0;
  278. month = 0;
  279. }
  280. else if (abs(timespan->month) >= 12)
  281. {
  282. year = (timespan->month / 12);
  283. month = (timespan->month % 12);
  284. }
  285. else
  286. {
  287. year = 0;
  288. month = timespan->month;
  289. }
  290. span = (((((double) 365 * year) + ((double) 30 * month)) * 86400) + timespan->time);
  291. #ifdef DATEDEBUG
  292. printf("timespan_reltime- convert m%d s%f to %f [%d %d]n",
  293.    timespan->month, timespan->time, span, INT_MIN, INT_MAX);
  294. #endif
  295. time = (((span > INT_MIN) && (span < INT_MAX)) ? span : INVALID_RELTIME);
  296. }
  297. return time;
  298. } /* timespan_reltime() */
  299. TimeSpan   *
  300. reltime_timespan(RelativeTime reltime)
  301. {
  302. TimeSpan   *result;
  303. int year,
  304. month;
  305. if (!PointerIsValid(result = palloc(sizeof(TimeSpan))))
  306. elog(ERROR, "Memory allocation failed, can't convert reltime to timespan", NULL);
  307. switch (reltime)
  308. {
  309. case INVALID_RELTIME:
  310. TIMESPAN_INVALID(*result);
  311. break;
  312. default:
  313. TMODULO(reltime, year, 31536000);
  314. TMODULO(reltime, month, 2592000);
  315. result->time = reltime;
  316. result->month = ((12 * year) + month);
  317. }
  318. return result;
  319. } /* reltime_timespan() */
  320. /*
  321.  * mktinterval - creates a time interval with endpoints t1 and t2
  322.  */
  323. TimeInterval
  324. mktinterval(AbsoluteTime t1, AbsoluteTime t2)
  325. {
  326. AbsoluteTime tstart = ABSTIMEMIN(t1, t2),
  327. tend = ABSTIMEMAX(t1, t2);
  328. TimeInterval interval;
  329. interval = (TimeInterval) palloc(sizeof(TimeIntervalData));
  330. if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME)
  331. interval->status = T_INTERVAL_INVAL;
  332. else
  333. {
  334. interval->status = T_INTERVAL_VALID;
  335. interval->data[0] = tstart;
  336. interval->data[1] = tend;
  337. }
  338. return interval;
  339. }
  340. /*
  341.  * timepl, timemi and abstimemi use the formula
  342.  * abstime + reltime = abstime
  343.  * so abstime - reltime = abstime
  344.  * and abstime - abstime = reltime
  345.  */
  346. /*
  347.  * timepl - returns the value of (abstime t1 + relime t2)
  348.  */
  349. AbsoluteTime
  350. timepl(AbsoluteTime t1, RelativeTime t2)
  351. {
  352. if (t1 == CURRENT_ABSTIME)
  353. t1 = GetCurrentTransactionStartTime();
  354. if (AbsoluteTimeIsReal(t1) &&
  355. RelativeTimeIsValid(t2) &&
  356. ((t2 > 0) ? (t1 < NOEND_ABSTIME - t2)
  357.  : (t1 > NOSTART_ABSTIME - t2))) /* prevent overflow */
  358. return t1 + t2;
  359. return INVALID_ABSTIME;
  360. }
  361. /*
  362.  * timemi - returns the value of (abstime t1 - reltime t2)
  363.  */
  364. AbsoluteTime
  365. timemi(AbsoluteTime t1, RelativeTime t2)
  366. {
  367. if (t1 == CURRENT_ABSTIME)
  368. t1 = GetCurrentTransactionStartTime();
  369. if (AbsoluteTimeIsReal(t1) &&
  370. RelativeTimeIsValid(t2) &&
  371. ((t2 > 0) ? (t1 > NOSTART_ABSTIME + t2)
  372.  : (t1 < NOEND_ABSTIME + t2))) /* prevent overflow */
  373. return t1 - t2;
  374. return INVALID_ABSTIME;
  375. }
  376. /*
  377.  * abstimemi - returns the value of (abstime t1 - abstime t2)
  378.  */
  379. static RelativeTime
  380. abstimemi(AbsoluteTime t1, AbsoluteTime t2)
  381. {
  382. if (t1 == CURRENT_ABSTIME)
  383. t1 = GetCurrentTransactionStartTime();
  384. if (t2 == CURRENT_ABSTIME)
  385. t2 = GetCurrentTransactionStartTime();
  386. if (AbsoluteTimeIsReal(t1) &&
  387. AbsoluteTimeIsReal(t2))
  388. return t1 - t2;
  389. return INVALID_RELTIME;
  390. }
  391. /*
  392.  * ininterval - returns 1, iff absolute date is in the interval
  393.  */
  394. int
  395. ininterval(AbsoluteTime t, TimeInterval interval)
  396. {
  397. if (interval->status == T_INTERVAL_VALID && t != INVALID_ABSTIME)
  398. return (abstimege(t, interval->data[0]) &&
  399. abstimele(t, interval->data[1]));
  400. return 0;
  401. }
  402. /*
  403.  * intervalrel - returns  relative time corresponding to interval
  404.  */
  405. RelativeTime
  406. intervalrel(TimeInterval interval)
  407. {
  408. if (interval->status == T_INTERVAL_VALID)
  409. return abstimemi(interval->data[1], interval->data[0]);
  410. else
  411. return INVALID_RELTIME;
  412. }
  413. /*
  414.  * timenow - returns  time "now", internal format
  415.  *
  416.  * Now AbsoluteTime is time since Jan 1 1970 -mer 7 Feb 1992
  417.  */
  418. AbsoluteTime
  419. timenow()
  420. {
  421. time_t sec;
  422. if (time(&sec) < 0)
  423. return INVALID_ABSTIME;
  424. return (AbsoluteTime) sec;
  425. }
  426. /*
  427.  * reltimeeq - returns 1, iff arguments are equal
  428.  * reltimene - returns 1, iff arguments are not equal
  429.  * reltimelt - returns 1, iff t1 less than t2
  430.  * reltimegt - returns 1, iff t1 greater than t2
  431.  * reltimele - returns 1, iff t1 less than or equal to t2
  432.  * reltimege - returns 1, iff t1 greater than or equal to t2
  433.  */
  434. bool
  435. reltimeeq(RelativeTime t1, RelativeTime t2)
  436. {
  437. if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
  438. return 0;
  439. return t1 == t2;
  440. }
  441. bool
  442. reltimene(RelativeTime t1, RelativeTime t2)
  443. {
  444. if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
  445. return 0;
  446. return t1 != t2;
  447. }
  448. bool
  449. reltimelt(RelativeTime t1, RelativeTime t2)
  450. {
  451. if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
  452. return 0;
  453. return t1 < t2;
  454. }
  455. bool
  456. reltimegt(RelativeTime t1, RelativeTime t2)
  457. {
  458. if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
  459. return 0;
  460. return t1 > t2;
  461. }
  462. bool
  463. reltimele(RelativeTime t1, RelativeTime t2)
  464. {
  465. if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
  466. return 0;
  467. return t1 <= t2;
  468. }
  469. bool
  470. reltimege(RelativeTime t1, RelativeTime t2)
  471. {
  472. if (t1 == INVALID_RELTIME || t2 == INVALID_RELTIME)
  473. return 0;
  474. return t1 >= t2;
  475. }
  476. /*
  477.  * intervalsame - returns 1, iff interval i1 is same as interval i2
  478.  * Check begin and end time.
  479.  */
  480. bool
  481. intervalsame(TimeInterval i1, TimeInterval i2)
  482. {
  483. if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
  484. return FALSE; /* invalid interval */
  485. return (abstimeeq(i1->data[0], i2->data[0]) &&
  486. abstimeeq(i1->data[1], i2->data[1]));
  487. } /* intervalsame() */
  488. /*
  489.  * intervaleq - returns 1, iff interval i1 is equal to interval i2
  490.  * Check length of intervals.
  491.  */
  492. bool
  493. intervaleq(TimeInterval i1, TimeInterval i2)
  494. {
  495. AbsoluteTime t10,
  496. t11,
  497. t20,
  498. t21;
  499. if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
  500. return FALSE; /* invalid interval */
  501. t10 = i1->data[0];
  502. t11 = i1->data[1];
  503. t20 = i2->data[0];
  504. t21 = i2->data[1];
  505. if ((t10 == INVALID_ABSTIME) || (t20 == INVALID_ABSTIME)
  506. || (t20 == INVALID_ABSTIME) || (t21 == INVALID_ABSTIME))
  507. return FALSE;
  508. if (t10 == CURRENT_ABSTIME)
  509. t10 = GetCurrentTransactionStartTime();
  510. if (t11 == CURRENT_ABSTIME)
  511. t11 = GetCurrentTransactionStartTime();
  512. if (t20 == CURRENT_ABSTIME)
  513. t20 = GetCurrentTransactionStartTime();
  514. if (t21 == CURRENT_ABSTIME)
  515. t21 = GetCurrentTransactionStartTime();
  516. return (t11 - t10) == (t21 - t20);
  517. } /* intervaleq() */
  518. /*
  519.  * intervalne - returns 1, iff interval i1 is not equal to interval i2
  520.  * Check length of intervals.
  521.  */
  522. bool
  523. intervalne(TimeInterval i1, TimeInterval i2)
  524. {
  525. AbsoluteTime t10,
  526. t11,
  527. t20,
  528. t21;
  529. if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
  530. return FALSE; /* invalid interval */
  531. t10 = i1->data[0];
  532. t11 = i1->data[1];
  533. t20 = i2->data[0];
  534. t21 = i2->data[1];
  535. if ((t10 == INVALID_ABSTIME) || (t20 == INVALID_ABSTIME)
  536. || (t20 == INVALID_ABSTIME) || (t21 == INVALID_ABSTIME))
  537. return FALSE;
  538. if (t10 == CURRENT_ABSTIME)
  539. t10 = GetCurrentTransactionStartTime();
  540. if (t11 == CURRENT_ABSTIME)
  541. t11 = GetCurrentTransactionStartTime();
  542. if (t20 == CURRENT_ABSTIME)
  543. t20 = GetCurrentTransactionStartTime();
  544. if (t21 == CURRENT_ABSTIME)
  545. t21 = GetCurrentTransactionStartTime();
  546. return (t11 - t10) != (t21 - t20);
  547. } /* intervalne() */
  548. /*
  549.  * intervallt - returns TRUE, iff interval i1 is less than interval i2
  550.  * Check length of intervals.
  551.  */
  552. bool
  553. intervallt(TimeInterval i1, TimeInterval i2)
  554. {
  555. AbsoluteTime t10,
  556. t11,
  557. t20,
  558. t21;
  559. if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
  560. return FALSE; /* invalid interval */
  561. t10 = i1->data[0];
  562. t11 = i1->data[1];
  563. t20 = i2->data[0];
  564. t21 = i2->data[1];
  565. if ((t10 == INVALID_ABSTIME) || (t20 == INVALID_ABSTIME)
  566. || (t20 == INVALID_ABSTIME) || (t21 == INVALID_ABSTIME))
  567. return FALSE;
  568. if (t10 == CURRENT_ABSTIME)
  569. t10 = GetCurrentTransactionStartTime();
  570. if (t11 == CURRENT_ABSTIME)
  571. t11 = GetCurrentTransactionStartTime();
  572. if (t20 == CURRENT_ABSTIME)
  573. t20 = GetCurrentTransactionStartTime();
  574. if (t21 == CURRENT_ABSTIME)
  575. t21 = GetCurrentTransactionStartTime();
  576. return (t11 - t10) < (t21 - t20);
  577. } /* intervallt() */
  578. /*
  579.  * intervalle - returns TRUE, iff interval i1 is less than or equal to interval i2
  580.  * Check length of intervals.
  581.  */
  582. bool
  583. intervalle(TimeInterval i1, TimeInterval i2)
  584. {
  585. AbsoluteTime t10,
  586. t11,
  587. t20,
  588. t21;
  589. if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
  590. return FALSE; /* invalid interval */
  591. t10 = i1->data[0];
  592. t11 = i1->data[1];
  593. t20 = i2->data[0];
  594. t21 = i2->data[1];
  595. if ((t10 == INVALID_ABSTIME) || (t20 == INVALID_ABSTIME)
  596. || (t20 == INVALID_ABSTIME) || (t21 == INVALID_ABSTIME))
  597. return FALSE;
  598. if (t10 == CURRENT_ABSTIME)
  599. t10 = GetCurrentTransactionStartTime();
  600. if (t11 == CURRENT_ABSTIME)
  601. t11 = GetCurrentTransactionStartTime();
  602. if (t20 == CURRENT_ABSTIME)
  603. t20 = GetCurrentTransactionStartTime();
  604. if (t21 == CURRENT_ABSTIME)
  605. t21 = GetCurrentTransactionStartTime();
  606. return (t11 - t10) <= (t21 - t20);
  607. } /* intervalle() */
  608. /*
  609.  * intervalgt - returns TRUE, iff interval i1 is less than interval i2
  610.  * Check length of intervals.
  611.  */
  612. bool
  613. intervalgt(TimeInterval i1, TimeInterval i2)
  614. {
  615. AbsoluteTime t10,
  616. t11,
  617. t20,
  618. t21;
  619. if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
  620. return FALSE; /* invalid interval */
  621. t10 = i1->data[0];
  622. t11 = i1->data[1];
  623. t20 = i2->data[0];
  624. t21 = i2->data[1];
  625. if ((t10 == INVALID_ABSTIME) || (t20 == INVALID_ABSTIME)
  626. || (t20 == INVALID_ABSTIME) || (t21 == INVALID_ABSTIME))
  627. return FALSE;
  628. if (t10 == CURRENT_ABSTIME)
  629. t10 = GetCurrentTransactionStartTime();
  630. if (t11 == CURRENT_ABSTIME)
  631. t11 = GetCurrentTransactionStartTime();
  632. if (t20 == CURRENT_ABSTIME)
  633. t20 = GetCurrentTransactionStartTime();
  634. if (t21 == CURRENT_ABSTIME)
  635. t21 = GetCurrentTransactionStartTime();
  636. return (t11 - t10) > (t21 - t20);
  637. } /* intervalgt() */
  638. /*
  639.  * intervalge - returns TRUE, iff interval i1 is less than or equal to interval i2
  640.  * Check length of intervals.
  641.  */
  642. bool
  643. intervalge(TimeInterval i1, TimeInterval i2)
  644. {
  645. AbsoluteTime t10,
  646. t11,
  647. t20,
  648. t21;
  649. if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
  650. return FALSE; /* invalid interval */
  651. t10 = i1->data[0];
  652. t11 = i1->data[1];
  653. t20 = i2->data[0];
  654. t21 = i2->data[1];
  655. if ((t10 == INVALID_ABSTIME) || (t20 == INVALID_ABSTIME)
  656. || (t20 == INVALID_ABSTIME) || (t21 == INVALID_ABSTIME))
  657. return FALSE;
  658. if (t10 == CURRENT_ABSTIME)
  659. t10 = GetCurrentTransactionStartTime();
  660. if (t11 == CURRENT_ABSTIME)
  661. t11 = GetCurrentTransactionStartTime();
  662. if (t20 == CURRENT_ABSTIME)
  663. t20 = GetCurrentTransactionStartTime();
  664. if (t21 == CURRENT_ABSTIME)
  665. t21 = GetCurrentTransactionStartTime();
  666. return (t11 - t10) >= (t21 - t20);
  667. } /* intervalge() */
  668. /*
  669.  * intervalleneq - returns 1, iff length of interval i is equal to
  670.  * reltime t
  671.  */
  672. bool
  673. intervalleneq(TimeInterval i, RelativeTime t)
  674. {
  675. RelativeTime rt;
  676. if ((i->status == T_INTERVAL_INVAL) || (t == INVALID_RELTIME))
  677. return 0;
  678. rt = intervalrel(i);
  679. return rt != INVALID_RELTIME && rt == t;
  680. }
  681. /*
  682.  * intervallenne - returns 1, iff length of interval i is not equal
  683.  * to reltime t
  684.  */
  685. bool
  686. intervallenne(TimeInterval i, RelativeTime t)
  687. {
  688. RelativeTime rt;
  689. if ((i->status == T_INTERVAL_INVAL) || (t == INVALID_RELTIME))
  690. return 0;
  691. rt = intervalrel(i);
  692. return rt != INVALID_RELTIME && rt != t;
  693. }
  694. /*
  695.  * intervallenlt - returns 1, iff length of interval i is less than
  696.  * reltime t
  697.  */
  698. bool
  699. intervallenlt(TimeInterval i, RelativeTime t)
  700. {
  701. RelativeTime rt;
  702. if ((i->status == T_INTERVAL_INVAL) || (t == INVALID_RELTIME))
  703. return 0;
  704. rt = intervalrel(i);
  705. return rt != INVALID_RELTIME && rt < t;
  706. }
  707. /*
  708.  * intervallengt - returns 1, iff length of interval i is greater than
  709.  * reltime t
  710.  */
  711. bool
  712. intervallengt(TimeInterval i, RelativeTime t)
  713. {
  714. RelativeTime rt;
  715. if ((i->status == T_INTERVAL_INVAL) || (t == INVALID_RELTIME))
  716. return 0;
  717. rt = intervalrel(i);
  718. return rt != INVALID_RELTIME && rt > t;
  719. }
  720. /*
  721.  * intervallenle - returns 1, iff length of interval i is less or equal
  722.  * than reltime t
  723.  */
  724. bool
  725. intervallenle(TimeInterval i, RelativeTime t)
  726. {
  727. RelativeTime rt;
  728. if ((i->status == T_INTERVAL_INVAL) || (t == INVALID_RELTIME))
  729. return 0;
  730. rt = intervalrel(i);
  731. return rt != INVALID_RELTIME && rt <= t;
  732. }
  733. /*
  734.  * intervallenge - returns 1, iff length of interval i is greater or
  735.  * equal than reltime t
  736.  */
  737. bool
  738. intervallenge(TimeInterval i, RelativeTime t)
  739. {
  740. RelativeTime rt;
  741. if ((i->status == T_INTERVAL_INVAL) || (t == INVALID_RELTIME))
  742. return 0;
  743. rt = intervalrel(i);
  744. return rt != INVALID_RELTIME && rt >= t;
  745. }
  746. /*
  747.  * intervalct - returns 1, iff interval i1 contains interval i2
  748.  */
  749. bool
  750. intervalct(TimeInterval i1, TimeInterval i2)
  751. {
  752. if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
  753. return 0;
  754. return (abstimele(i1->data[0], i2->data[0]) &&
  755. abstimege(i1->data[1], i2->data[1]));
  756. }
  757. /*
  758.  * intervalov - returns 1, iff interval i1 (partially) overlaps i2
  759.  */
  760. bool
  761. intervalov(TimeInterval i1, TimeInterval i2)
  762. {
  763. if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL)
  764. return 0;
  765. return (!(abstimelt(i1->data[1], i2->data[0]) ||
  766.   abstimegt(i1->data[0], i2->data[1])));
  767. }
  768. /*
  769.  * intervalstart - returns  the start of interval i
  770.  */
  771. AbsoluteTime
  772. intervalstart(TimeInterval i)
  773. {
  774. if (i->status == T_INTERVAL_INVAL)
  775. return INVALID_ABSTIME;
  776. return i->data[0];
  777. }
  778. /*
  779.  * intervalend - returns  the end of interval i
  780.  */
  781. AbsoluteTime
  782. intervalend(TimeInterval i)
  783. {
  784. if (i->status == T_INTERVAL_INVAL)
  785. return INVALID_ABSTIME;
  786. return i->data[1];
  787. }
  788. /*****************************************************************************
  789.  *  PRIVATE ROUTINES  *
  790.  *****************************************************************************/
  791. #ifdef NOT_USED
  792. /*
  793.  * isreltime - returns 1, iff datestring is of type reltime
  794.  *   2, iff datestring is 'invalid time' identifier
  795.  *   0, iff datestring contains a syntax error
  796.  * VALID time less or equal +/-  `@ 68 years'
  797.  *
  798.  */
  799. int
  800. isreltime(char *str)
  801. {
  802. struct tm tt,
  803.    *tm = &tt;
  804. double fsec;
  805. int dtype;
  806. char    *field[MAXDATEFIELDS];
  807. int nf,
  808. ftype[MAXDATEFIELDS];
  809. char lowstr[MAXDATELEN + 1];
  810. if (!PointerIsValid(str))
  811. return 0;
  812. if (strlen(str) > MAXDATELEN)
  813. return 0;
  814. if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
  815. || (DecodeDateDelta(field, ftype, nf, &dtype, tm, &fsec) != 0))
  816. return 0;
  817. switch (dtype)
  818. {
  819. case (DTK_DELTA):
  820. return (abs(tm->tm_year) <= 68) ? 1 : 0;
  821. break;
  822. case (DTK_INVALID):
  823. return 2;
  824. break;
  825. default:
  826. return 0;
  827. break;
  828. }
  829. return 0;
  830. } /* isreltime() */
  831. #endif
  832. #ifdef NOT_USED
  833. int
  834. dummyfunc()
  835. {
  836. char    *p;
  837. char c;
  838. int i;
  839. char unit[UNITMAXLEN];
  840. char direction[DIRMAXLEN];
  841. int localSign;
  842. int localUnitNumber;
  843. long localQuantity;
  844. if (!PointerIsValid(sign))
  845. sign = &localSign;
  846. if (!PointerIsValid(unitnr))
  847. unitnr = &localUnitNumber;
  848. if (!PointerIsValid(quantity))
  849. quantity = &localQuantity;
  850. unit[0] = '';
  851. direction[0] = '';
  852. p = timestring;
  853. /* skip leading blanks */
  854. while ((c = *p) != '')
  855. {
  856. if (c != ' ')
  857. break;
  858. p++;
  859. }
  860. /* Test whether 'invalid time' identifier or not */
  861. if (!strncmp(INVALID_RELTIME_STR, p, strlen(INVALID_RELTIME_STR) + 1))
  862. return 2; /* correct 'invalid time' identifier found */
  863. /* handle label of relative time */
  864. if (c != RELTIME_LABEL)
  865. return 0; /* syntax error */
  866. c = *++p;
  867. if (c != ' ')
  868. return 0; /* syntax error */
  869. p++;
  870. /* handle the quantity */
  871. *quantity = 0;
  872. for (;;)
  873. {
  874. c = *p;
  875. if (isdigit(c))
  876. {
  877. *quantity = *quantity * 10 + (c - '0');
  878. p++;
  879. }
  880. else
  881. {
  882. if (c == ' ')
  883. break; /* correct quantity found */
  884. else
  885. return 0; /* syntax error */
  886. }
  887. }
  888. /* handle unit */
  889. p++;
  890. i = 0;
  891. for (;;)
  892. {
  893. c = *p;
  894. if (c >= 'a' && c <= 'z' && i <= (UNITMAXLEN - 1))
  895. {
  896. unit[i] = c;
  897. p++;
  898. i++;
  899. }
  900. else
  901. {
  902. if ((c == ' ' || c == '')
  903. && correct_unit(unit, unitnr))
  904. break; /* correct unit found */
  905. else
  906. return 0; /* syntax error */
  907. }
  908. }
  909. /* handle optional direction */
  910. if (c == ' ')
  911. p++;
  912. i = 0;
  913. *sign = 1;
  914. for (;;)
  915. {
  916. c = *p;
  917. if (c >= 'a' && c <= 'z' && i <= (DIRMAXLEN - 1))
  918. {
  919. direction[i] = c;
  920. p++;
  921. i++;
  922. }
  923. else
  924. {
  925. if ((c == ' ' || c == '') && i == 0)
  926. {
  927. *sign = 1;
  928. break; /* no direction specified */
  929. }
  930. if ((c == ' ' || c == '') && i != 0)
  931. {
  932. direction[i] = '';
  933. correct_dir(direction, sign);
  934. break; /* correct direction found */
  935. }
  936. else
  937. return 0; /* syntax error */
  938. }
  939. }
  940. return 1;
  941. }
  942. /*
  943.  * correct_unit - returns 1, iff unit is a correct unit description
  944.  *
  945.  * output parameter:
  946.  * unptr: points to an integer which is the appropriate unit number
  947.  *    (see function isreltime())
  948.  */
  949. static int
  950. correct_unit(char *unit, int *unptr)
  951. {
  952. int j = 0;
  953. while (j < NUNITS)
  954. {
  955. if (strncmp(unit, unit_tab[j], strlen(unit_tab[j])) == 0)
  956. {
  957. *unptr = j;
  958. return 1;
  959. }
  960. j++;
  961. }
  962. return 0; /* invalid unit descriptor */
  963. }
  964. /*
  965.  * correct_dir - returns 1, iff direction is a correct identifier
  966.  *
  967.  * output parameter:
  968.  * signptr: points to -1 if dir corresponds to past tense
  969.  *  else  to 1
  970.  */
  971. static int
  972. correct_dir(char *direction, int *signptr)
  973. {
  974. *signptr = 1;
  975. if (strncmp(RELTIME_PAST, direction, strlen(RELTIME_PAST) + 1) == 0)
  976. {
  977. *signptr = -1;
  978. return 1;
  979. }
  980. else
  981. return 0; /* invalid direction descriptor */
  982. }
  983. #endif
  984. /*
  985.  * istinterval - returns 1, iff i_string is a valid interval descr.
  986.  *   0, iff i_string is NOT a valid interval desc.
  987.  *   2, iff any time is INVALID_ABSTIME
  988.  *
  989.  * output parameter:
  990.  * i_start, i_end: interval margins
  991.  *
  992.  * Time interval:
  993.  * `[' {` '} `'' <AbsTime> `'' {` '} `'' <AbsTime> `'' {` '} `]'
  994.  *
  995.  * OR `Undefined Range' (see also INVALID_INTERVAL_STR)
  996.  *
  997.  * where <AbsTime> satisfies the syntax of absolute time.
  998.  *
  999.  * e.g.  [  '  Jan 18 1902'   'Jan 1 00:00:00 1970']
  1000.  */
  1001. static int
  1002. istinterval(char *i_string,
  1003. AbsoluteTime *i_start,
  1004. AbsoluteTime *i_end)
  1005. {
  1006. char    *p,
  1007.    *p1;
  1008. char c;
  1009. p = i_string;
  1010. /* skip leading blanks up to '[' */
  1011. while ((c = *p) != '')
  1012. {
  1013. if (IsSpace(c))
  1014. p++;
  1015. else if (c != '[')
  1016. return 0; /* syntax error */
  1017. else
  1018. break;
  1019. }
  1020. p++;
  1021. /* skip leading blanks up to "'" */
  1022. while ((c = *p) != '')
  1023. {
  1024. if (IsSpace(c))
  1025. p++;
  1026. else if (c != '"')
  1027. return 0; /* syntax error */
  1028. else
  1029. break;
  1030. }
  1031. p++;
  1032. if (strncmp(INVALID_INTERVAL_STR, p, strlen(INVALID_INTERVAL_STR)) == 0)
  1033. return 0; /* undefined range, handled like a syntax
  1034.  * err. */
  1035. /* search for the end of the first date and change it to a NULL */
  1036. p1 = p;
  1037. while ((c = *p1) != '')
  1038. {
  1039. if (c == '"')
  1040. {
  1041. *p1 = '';
  1042. break;
  1043. }
  1044. p1++;
  1045. }
  1046. /* get the first date */
  1047. *i_start = nabstimein(p); /* first absolute date */
  1048. /* rechange NULL at the end of the first date to a "'" */
  1049. *p1 = '"';
  1050. p = ++p1;
  1051. /* skip blanks up to "'", beginning of second date */
  1052. while ((c = *p) != '')
  1053. {
  1054. if (IsSpace(c))
  1055. p++;
  1056. else if (c != '"')
  1057. return 0; /* syntax error */
  1058. else
  1059. break;
  1060. }
  1061. p++;
  1062. /* search for the end of the second date and change it to a NULL */
  1063. p1 = p;
  1064. while ((c = *p1) != '')
  1065. {
  1066. if (c == '"')
  1067. {
  1068. *p1 = '';
  1069. break;
  1070. }
  1071. p1++;
  1072. }
  1073. /* get the second date */
  1074. *i_end = nabstimein(p); /* second absolute date */
  1075. /* rechange NULL at the end of the first date to a ''' */
  1076. *p1 = '"';
  1077. p = ++p1;
  1078. /* skip blanks up to ']' */
  1079. while ((c = *p) != '')
  1080. {
  1081. if (IsSpace(c))
  1082. p++;
  1083. else if (c != ']')
  1084. return 0; /* syntax error */
  1085. else
  1086. break;
  1087. }
  1088. p++;
  1089. c = *p;
  1090. if (c != '')
  1091. return 0; /* syntax error */
  1092. /* it seems to be a valid interval */
  1093. return 1;
  1094. }
  1095. /*****************************************************************************
  1096.  *
  1097.  *****************************************************************************/
  1098. /*
  1099.  * timeofday -
  1100.  *    returns the current time as a text. similar to timenow() but returns
  1101.  *    seconds with more precision (up to microsecs). (I need this to compare
  1102.  *    the Wisconsin benchmark with Illustra whose TimeNow() shows current
  1103.  *    time with precision up to microsecs.)   - ay 3/95
  1104.  */
  1105. text *
  1106. timeofday(void)
  1107. {
  1108. struct timeval tp;
  1109. struct timezone tpz;
  1110. char templ[500];
  1111. char buf[500];
  1112. text    *tm;
  1113. int len = 0;
  1114. gettimeofday(&tp, &tpz);
  1115. strftime(templ, sizeof(templ), "%a %b %d %H:%M:%S.%%d %Y %Z",
  1116.  localtime((time_t *) &tp.tv_sec));
  1117. sprintf(buf, templ, tp.tv_usec);
  1118. len = VARHDRSZ + strlen(buf);
  1119. tm = (text *) palloc(len);
  1120. VARSIZE(tm) = len;
  1121. strncpy(VARDATA(tm), buf, strlen(buf));
  1122. return tm;
  1123. }