More timezone patches by Thomas:
authorMarc G. Fournier
Fri, 25 Apr 1997 18:40:50 +0000 (18:40 +0000)
committerMarc G. Fournier
Fri, 25 Apr 1997 18:40:50 +0000 (18:40 +0000)
Here are patches which should help fix timezone problems in the
datetime and abstime code. Also, I repatched varlena.c to add in
some comments and a little error checking on top of Vadim's earlier
repairs. There are slight mods to the circle data type to have the
distance operator between circles measure the distance between
closest points rather than between centers.

src/backend/utils/adt/dt.c
src/backend/utils/adt/geo_ops.c
src/backend/utils/adt/nabstime.c
src/backend/utils/adt/varlena.c
src/include/utils/dt.h
src/include/utils/geo_decls.h
src/update6_0-6_1.sh [deleted file]
src/update6_0-6_1.sql [deleted file]

index 46c7317c529608a38d6a4f47996f4071bb4045e6..7b90e1ca6d69f7d907fcdfdb41dcb32572e5be1c 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/dt.c,v 1.16 1997/04/22 17:36:44 scrappy Exp $
+ *    $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/dt.c,v 1.17 1997/04/25 18:40:13 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -120,6 +120,7 @@ char *
 datetime_out(DateTime *dt)
 {
     char *result;
+    int tz;
     struct tm tt, *tm = &tt;
     double fsec;
     char buf[MAXDATELEN+1];
@@ -130,8 +131,8 @@ datetime_out(DateTime *dt)
     if (DATETIME_IS_RESERVED(*dt)) {
    EncodeSpecialDateTime(*dt, buf);
 
-    } else if (datetime2tm( *dt, &CTimeZone, tm, &fsec) == 0) {
-   EncodeDateTime(tm, fsec, DateStyle, buf);
+    } else if (datetime2tm( *dt, &tz, tm, &fsec) == 0) {
+   EncodeDateTime(tm, fsec, &tz, DateStyle, buf);
 
     } else {
    EncodeSpecialDateTime(DT_INVALID, buf);
@@ -840,6 +841,7 @@ datetime_part(text *units, DateTime *datetime)
     float64 result;
 
     DateTime dt;
+    int tz;
     int type, val;
     int i;
     char *up, *lp, lowunits[MAXDATELEN+1];
@@ -874,10 +876,10 @@ printf( "datetime_part- units %s type=%d value=%d\n", lowunits, type, val);
 
    dt = (DATETIME_IS_RELATIVE(*datetime)? SetDateTime(*datetime): *datetime); 
 
-   if (datetime2tm( dt, &CTimeZone, tm, &fsec) == 0) {
+   if (datetime2tm( dt, &tz, tm, &fsec) == 0) {
        switch (val) {
        case DTK_TZ:
-       *result = CTimeZone;
+       *result = tz;
        break;
 
        case DTK_MICROSEC:
@@ -929,7 +931,7 @@ printf( "datetime_part- units %s type=%d value=%d\n", lowunits, type, val);
        break;
 
        default:
-       elog(WARN,"Datetime units %s not yet supported",units);
+       elog(WARN,"Datetime units %s not supported",units);
        *result = 0;
        };
 
@@ -1401,21 +1403,9 @@ datetime2tm( DateTime dt, int *tzp, struct tm *tm, double *fsec)
 {
     double date, time, sec;
     time_t utime;
-
-    if (tzp != NULL) {
-   /* XXX HACK to get time behavior compatible with Postgres v6.0 - tgl 97/04/07 */
-   if ((tm->tm_year > 1902) && (tm->tm_year < 2038)) {
-       utime = ((date2j(2000,1,1)-date2j(1970,1,1))*86400+dt);
-       localtime((time_t *) &utime);
-#ifdef DATEDEBUG
-printf( "datetime2tm- use system time zone = %ld (CTimeZone = %d)\n", (long int) utime, CTimeZone);
+#ifdef USE_POSIX_TIME
+    struct tm *tx;
 #endif
-       dt = dt2local( dt, timezone);
-
-   } else {
-       dt = dt2local( dt, *tzp);
-   };
-    };
 
     time = (modf( dt/86400, &date)*86400);
     date += date2j(2000,1,1);
@@ -1428,8 +1418,7 @@ printf( "datetime2tm- use system time zone = %ld (CTimeZone = %d)\n", (long int)
     if (date < 0) return -1;
 
 #ifdef DATEDEBUG
-printf( "datetime2tm- date is %f (%f %f)\n",
- ((tzp != NULL)? dt2local(dt, -(*tzp)): dt), date, time);
+printf( "datetime2tm- date is %f (%f %f)\n", dt, date, time);
 #endif
 
     j2date((int) date, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
@@ -1437,7 +1426,7 @@ printf( "datetime2tm- date is %f (%f %f)\n",
 
 #ifdef DATEDEBUG
 printf( "datetime2tm- date is %d.%02d.%02d\n", tm->tm_year, tm->tm_mon, tm->tm_mday);
-printf( "datetime2tm- time is %02d:%02d:%2.2f\n", tm->tm_hour, tm->tm_min, sec);
+printf( "datetime2tm- time is %02d:%02d:%02.0f\n", tm->tm_hour, tm->tm_min, sec);
 #endif
 
     *fsec = modf(JROUND(sec),&sec);
@@ -1447,11 +1436,62 @@ printf( "datetime2tm- time is %02d:%02d:%2.2f\n", tm->tm_hour, tm->tm_min, sec);
 printf( "datetime2tm- time is %02d:%02d:%02d %.7f\n", tm->tm_hour, tm->tm_min, tm->tm_sec, *fsec);
 #endif
 
-    tm->tm_isdst = -1;
+    if (tzp != NULL) {
+   /* XXX HACK to get time behavior compatible with Postgres v6.0 - tgl 97/04/07 */
+   if ((tm->tm_year >= 1902) && (tm->tm_year < 2038)) {
+       utime = (dt + (date2j(2000,1,1)-date2j(1970,1,1))*86400);
+#ifdef USE_POSIX_TIME
+       tx = localtime(&utime);
+#ifdef DATEDEBUG
+printf( "datetime2tm- (localtime) %d.%02d.%02d %02d:%02d:%02.0f %s %s dst=%d\n",
+ tx->tm_year, tx->tm_mon, tx->tm_mday, tx->tm_hour, tx->tm_min, sec,
+ tzname[0], tzname[1], tx->tm_isdst);
+#endif
+       tm->tm_year = tx->tm_year + 1900;
+       tm->tm_mon = tx->tm_mon + 1;
+       tm->tm_mday = tx->tm_mday;
+       tm->tm_hour = tx->tm_hour;
+       tm->tm_min = tx->tm_min;
+       tm->tm_sec = tx->tm_sec;
+       tm->tm_isdst = tx->tm_isdst;
+#ifdef HAVE_INT_TIMEZONE
+       *tzp = (tm->tm_isdst? (timezone - 3600): timezone);
+#else /* !HAVE_INT_TIMEZONE */
+       *tzp = (tm->tm_isdst? (tm->tm_gmtoff - 3600): tm->tm_gmtoff); /* tm_gmtoff is Sun/DEC-ism */
+#endif
+#else /* !USE_POSIX_TIME */
+       *tzp = CTimeZone;   /* V7 conventions; don't know timezone? */
+#endif
+   } else {
+       *tzp = 0;
+       tm->tm_isdst = 0;
+#ifdef USE_POSIX_TIME
+#ifdef HAVE_INT_TIMEZONE
+       tzname[0] = "GMT";
+#else /* !HAVE_INT_TIMEZONE */
+       tm->tm_zone = "GMT";
+#endif
+#else /* !USE_POSIX_TIME */
+       strcpy( CTZName, "GMT");
+#endif
+   };
+
+   dt = dt2local( dt, *tzp);
+
+    } else {
+   tm->tm_isdst = 0;
+    };
+
+#ifdef DATEDEBUG
+printf( "datetime2tm- date is %d.%02d.%02d\n", tm->tm_year, tm->tm_mon, tm->tm_mday);
+printf( "datetime2tm- time is %02d:%02d:%02d %.7f\n", tm->tm_hour, tm->tm_min, tm->tm_sec, *fsec);
+#endif
 
 #ifdef DATEDEBUG
+#ifdef HAVE_INT_TIMEZONE
 printf( "datetime2tm- timezone is %s; offset is %d (%d); daylight is %d\n",
- CTZName, ((tzp != NULL)? *tzp: 0), CTimeZone, CDayLight);
+ tzname[tm->tm_isdst != 0], ((tzp != NULL)? *tzp: 0), CTimeZone, CDayLight);
+#endif
 #endif
 
     return 0;
@@ -1824,9 +1864,13 @@ printf( "DecodeDateTime- month field %s value is %d\n", field[i], val);
        break;
 
        case DTZ:
-       tm->tm_isdst = 0;
-       /* FALLTHROUGH! */
+       tm->tm_isdst = 1;
+       if (tzp == NULL) return -1;
+       *tzp = val * 60;
+       break;
+
        case TZ:
+       tm->tm_isdst = 0;
        if (tzp == NULL) return -1;
        *tzp = val * 60;
        break;
@@ -1883,15 +1927,29 @@ printf( " %02d:%02d:%02d\n", tm->tm_hour, tm->tm_min, tm->tm_sec);
     /* timezone not specified? then find local timezone if possible */
     /* XXX HACK to get correct behavior relative to Postgres v6.0 - tgl 97/04/07 */
     if ((*dtype == DTK_DATE) && ((fmask & DTK_DATE_M) == DTK_DATE_M)
-      && (tzp != NULL) && (! (fmask & DTK_M(TZ)))
-      && (tm->tm_year > 1902) && (tm->tm_year < 2038)) {
-   tm->tm_year -= 1900;
-   tm->tm_mon -= 1;
-   mktime(tm);
-   tm->tm_year += 1900;
-   tm->tm_mon += 1;
+      && (tzp != NULL) && (! (fmask & DTK_M(TZ)))) {
+
+   if ((tm->tm_year >= 1902) && (tm->tm_year < 2038)) {
+#ifdef USE_POSIX_TIME
+       tm->tm_year -= 1900;
+       tm->tm_mon -= 1;
+       tm->tm_isdst = -1;
+       mktime(tm);
+       tm->tm_year += 1900;
+       tm->tm_mon += 1;
 
-   *tzp = timezone;
+#ifdef HAVE_INT_TIMEZONE
+       *tzp = ((tm->tm_isdst > 0)? (timezone - 3600): timezone);
+#else /* !HAVE_INT_TIMEZONE */
+       *tzp = tm->tm_gmtoff;
+#endif
+#else /* !USE_POSIX_TIME */
+       *tzp = CTimeZone;
+#endif
+   } else {
+       tm->tm_isdst = 0;
+       *tzp = 0;
+   };
     };
 
     return 0;
@@ -1960,7 +2018,7 @@ printf( "DecodeTimeOnly- RESERV field %s value is %d\n", field[i], val);
            tm->tm_hour = 0;
            tm->tm_min = 0;
            tm->tm_sec = 0;
-           tm->tm_isdst = -1;
+           tm->tm_isdst = 0;
            break;
 
        default:
@@ -2695,7 +2753,7 @@ printf( "EncodeSpecialDateTime- unrecognized date\n");
 /* EncodeDateTime()
  * Encode date and time interpreted as local time.
  */
-int EncodeDateTime(struct tm *tm, double fsec, int style, char *str)
+int EncodeDateTime(struct tm *tm, double fsec, int *tzp, int style, char *str)
 {
     char mabbrev[4], dabbrev[4];
     int day, hour, min;
@@ -2706,11 +2764,36 @@ int EncodeDateTime(struct tm *tm, double fsec, int style, char *str)
 
     sec = (tm->tm_sec + fsec);
 
+#if FALSE
     tm->tm_isdst = -1;
+#endif
 
 #ifdef DATEDEBUG
+#ifdef USE_POSIX_TIME
+#ifdef HAVE_INT_TIMEZONE
+printf( "EncodeDateTime- timezone is %s (%s); offset is %d (%d); daylight is %d (%d)\n",
+ tzname[0], CTZName, *tzp, CTimeZone, tm->tm_isdst, CDayLight);
+#else
 printf( "EncodeDateTime- timezone is %s (%s); offset is %ld (%d); daylight is %d (%d)\n",
- tzname[0], CTZName, (long int) timezone, CTimeZone, daylight, CDayLight);
+ tm->tm_zone, CTZName, (- tm->tm_gmtoff), CTimeZone, tm->tm_isdst, CDayLight);
+#endif
+#else
+printf( "EncodeDateTime- timezone is %s; offset is %d; daylight is %d\n",
+ CTZName, CTimeZone, CDayLight);
+#endif
+#endif
+
+#ifdef USE_POSIX_TIME
+    /* XXX HACK to get time behavior compatible with Postgres v6.0 - tgl 97/04/07 */
+    if ((tm->tm_year >= 1902) && (tm->tm_year < 2038)) {
+   tm->tm_year -= 1900;
+   tm->tm_mon -= 1;
+   mktime(tm);
+   tm->tm_year += 1900;
+   tm->tm_mon += 1;
+    } else {
+   tm->tm_isdst = -1;
+    };
 #endif
 
     day = date2j( tm->tm_year, tm->tm_mon, tm->tm_mday);
@@ -2730,21 +2813,20 @@ printf( "EncodeDateTime- day is %d\n", day);
     /* compatible with ISO date formats */
     if (style == USE_ISO_DATES) {
    if (tm->tm_year > 0) {
-#if FALSE
-       sprintf( str, "%04d-%02d-%02d %02d:%02d:%05.2f %s",
-         tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, sec, CTZName);
-#endif
        sprintf( str, "%04d-%02d-%02d %02d:%02d:",
          tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min);
        sprintf( (str+17), ((fsec != 0)? "%05.2f": "%02.0f"), sec);
-       hour = -(CTimeZone / 3600);
-       min = ((abs(CTimeZone) / 60) % 60);
-       sprintf( (str+strlen(str)), ((min != 0)? "%+03d:%02d": "%+03d"), hour, min);
-#if FALSE
-       sprintf( str, "%04d-%02d-%02d %02d:%02d:%05.2f%+03d:%02d",
-         tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, sec,
-         hour, min);
-#endif
+
+       if (tm->tm_isdst >= 0) {
+       if (tzp != NULL) {
+           hour = -(*tzp / 3600);
+           min = ((abs(*tzp) / 60) % 60);
+       } else {
+           hour = 0;
+           min = 0;
+       };
+       sprintf( (str+strlen(str)), ((min != 0)? "%+03d:%02d": "%+03d"), hour, min);
+       };
 
    } else {
        if (tm->tm_hour || tm->tm_min) {
@@ -2764,8 +2846,20 @@ printf( "EncodeDateTime- day is %d\n", day);
        sprintf( str, "%02d/%02d", tm->tm_mon, tm->tm_mday);
    };
    if (tm->tm_year > 0) {
-       sprintf( (str+5), "/%04d %02d:%02d:%05.2f %s",
-         tm->tm_year, tm->tm_hour, tm->tm_min, sec, CTZName);
+       sprintf( (str+5), "/%04d %02d:%02d:%05.2f",
+         tm->tm_year, tm->tm_hour, tm->tm_min, sec);
+
+       if (tm->tm_isdst >= 0) {
+#ifdef USE_POSIX_TIME
+#ifdef HAVE_INT_TIMEZONE
+       sprintf( (str+22), " %s", tzname[(tm->tm_isdst > 0)]);
+#else /* !HAVE_INT_TIMEZONE */
+       sprintf( (str+22), " %s", tm->tm_zone);
+#endif
+#else /* !USE_POSIX_TIME */
+       sprintf( (str+22), " %s", CTZName);
+#endif
+       };
 
    } else {
        sprintf( (str+5), "/%04d %02d:%02d %s",
@@ -2781,12 +2875,20 @@ printf( "EncodeDateTime- day is %d\n", day);
        sprintf( (str+4), "%3s %02d", mabbrev, tm->tm_mday);
    };
    if (tm->tm_year > 0) {
-#if FALSE
-       sprintf( (str+10), " %02d:%02d:%05.2f %04d %s",
-         tm->tm_hour, tm->tm_min, sec, tm->tm_year, CTZName);
+       sprintf( (str+10), " %02d:%02d:%05.2f %04d",
+         tm->tm_hour, tm->tm_min, sec, tm->tm_year);
+
+       if (tm->tm_isdst >= 0) {
+#ifdef USE_POSIX_TIME
+#ifdef HAVE_INT_TIMEZONE
+       sprintf( (str+27), " %s", tzname[(tm->tm_isdst > 0)]);
+#else
+       sprintf( (str+27), " %s", tm->tm_zone);
 #endif
-       sprintf( (str+10), " %02d:%02d:%05.2f %04d %s",
-         tm->tm_hour, tm->tm_min, sec, tm->tm_year, (daylight? tzname[1]: tzname[0]));
+#else
+       sprintf( (str+27), " %s", CTZName);
+#endif
+       };
 
    } else {
        sprintf( (str+10), " %02d:%02d %04d %s",
@@ -2798,7 +2900,7 @@ printf( "EncodeDateTime- day is %d\n", day);
 printf( "EncodeDateTime- date result is %s\n", str);
 #endif
 
-#ifdef DATEDEBUG
+#if defined(DATEDEBUG) && FALSE
     if (tm->tm_year >= 1000) tm->tm_year -= 1900;
     tm->tm_mon -= 1;
     strftime( buf, sizeof(buf), "%y.%m.%d %H:%M:%S %Z", tm);
index 4dacd09f1c6c5bd5104caa97522142c5fdfd22ce..1be8577a2d65521e8e22cbd6f0009759286da861 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v 1.3 1997/04/22 17:31:32 scrappy Exp $
+ *    $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v 1.4 1997/04/25 18:40:25 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2675,7 +2675,7 @@ poly_path(POLYGON *poly)
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v 1.3 1997/04/22 17:31:32 scrappy Exp $
+ *    $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v 1.4 1997/04/25 18:40:25 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -3075,18 +3075,35 @@ double *circle_radius(CIRCLE *circle)
 }
 
 
-/* circle_distance -   returns the distance between the
- *               center points of two circlees.
+/* circle_distance -   returns the distance between
+ *               two circles.
  */
 double *circle_distance(CIRCLE *circle1, CIRCLE *circle2)
 {
     double *result;
 
     result = PALLOCTYPE(double);
-    *result = point_dt(&circle1->center,&circle2->center);
+    *result = (point_dt(&circle1->center,&circle2->center)
+      - (circle1->radius + circle2->radius));
+    if (*result < 0) *result = 0;
 
     return(result);
-}
+} /* circle_distance() */
+
+
+/* dist_pc -   returns the distance between
+ *           a point and a circle.
+ */
+double *dist_pc(Point *point, CIRCLE *circle)
+{
+    double *result;
+
+    result = PALLOCTYPE(double);
+    *result = (point_dt(point,&circle->center) - circle->radius);
+    if (*result < 0) *result = 0;
+
+    return(result);
+} /* dist_pc() */
 
 
 /* circle_center   -   returns the center point of the circle.
index b227528ed3363f91731475548bd0ff019bc141cd..881206fc59fb070ac6eeb989457ead6f08467cc5 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.24 1997/04/22 17:36:57 scrappy Exp $
+ *    $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.25 1997/04/25 18:40:33 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
  *
  * Returns the number of seconds since epoch (January 1 1970 GMT)
  */
-
 AbsoluteTime
 GetCurrentAbsoluteTime(void)
 {
     time_t now;
 
 #ifdef USE_POSIX_TIME
+    struct tm *tm;
+
     now = time(NULL);
 #else /* ! USE_POSIX_TIME */
-    struct timeb tbnow;        /* the old V7-ism */
+    struct timeb tb;       /* the old V7-ism */
 
-    (void) ftime(&tbnow);
-    now = tbnow.time;
+    (void) ftime(&tb);
+    now = tb.time;
 #endif
 
     if (! HasCTZSet) {
 #ifdef USE_POSIX_TIME
 #if defined(HAVE_TZSET) && defined(HAVE_INT_TIMEZONE)
-   tzset();
-   CTimeZone = timezone;
-   CDayLight = daylight;
-   strcpy( CTZName, tzname[0]);
-#else /* !HAVE_TZSET */
-   struct tm *tmnow = localtime(&now);
+   tm = localtime(&now);
 
-   CTimeZone = - tmnow->tm_gmtoff; /* tm_gmtoff is Sun/DEC-ism */
-   CDayLight = (tmnow->tm_isdst > 0);
-   /* XXX is there a better way to get local timezone string in V7? - tgl 97/03/18 */
-   strftime( CTZName, MAXTZLEN, "%Z", localtime(&now));
+   CDayLight = tm->tm_isdst;
+   CTimeZone = (tm->tm_isdst? (timezone - 3600): timezone);
+   strcpy( CTZName, tzname[tm->tm_isdst]);
+#else /* !HAVE_TZSET */
+   tm = localtime(&now);
+
+   CTimeZone = - tm->tm_gmtoff;    /* tm_gmtoff is Sun/DEC-ism */
+   CDayLight = (tm->tm_isdst > 0);
+   /* XXX is there a better way to get local timezone string w/o tzname? - tgl 97/03/18 */
+   strftime( CTZName, MAXTZLEN, "%Z", tm);
+   /* XXX FreeBSD man pages indicate that this should work - tgl 97/04/23 */
+   strcpy(CTZName, tm->tm_zone);
 #endif
 #else /* ! USE_POSIX_TIME */
-   CTimeZone = tbnow.timezone * 60;
-   CDayLight = (tbnow.dstflag != 0);
+   CTimeZone = tb.timezone * 60;
+   CDayLight = (tb.dstflag != 0);
    /* XXX does this work to get the local timezone string in V7? - tgl 97/03/18 */
    strftime( CTZName, MAXTZLEN, "%Z", localtime(&now));
 #endif 
@@ -91,7 +95,9 @@ printf( "GetCurrentAbsoluteTime- timezone is %s -> %d seconds from UTC\n",
 void
 GetCurrentTime(struct tm *tm)
 {
-    abstime2tm( GetCurrentTransactionStartTime(), &CTimeZone, tm);
+    int tz;
+
+    abstime2tm( GetCurrentTransactionStartTime(), &tz, tm);
 
     return;
 } /* GetCurrentTime() */
@@ -157,12 +163,14 @@ tm2abstime( struct tm *tm, int tz)
       (day == MIN_DAYNUM && sec > 0))
    return(INVALID_ABSTIME);
 
+#if FALSE
     /* daylight correction */
     if (tm->tm_isdst < 0) {        /* unknown; find out */
    tm->tm_isdst = (CDayLight > 0);
     };
     if (tm->tm_isdst > 0)
    sec -= 60*60;
+#endif
 
     /* check for reserved values (e.g. "current" on edge of usual range */
     if (!AbsoluteTimeIsReal(sec))
@@ -511,10 +519,10 @@ datetime_abstime(DateTime *datetime)
 
     } else {
    if (DATETIME_IS_RELATIVE(*datetime)) {
-       datetime2tm( SetDateTime(*datetime), &CTimeZone, tm, &fsec);
+       datetime2tm( SetDateTime(*datetime), NULL, tm, &fsec);
        result = tm2abstime( tm, 0);
 
-   } else if (datetime2tm( *datetime, &CTimeZone, tm, &fsec) == 0) {
+   } else if (datetime2tm( *datetime, NULL, tm, &fsec) == 0) {
        result = tm2abstime( tm, 0);
 
    } else {
index e5749cce0d05f901a0899f2dbabad6b53f2b6f45..80ac9937fffaa2df67c405df822a67558c2ff1f3 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.14 1997/04/21 04:31:53 vadim Exp $
+ *    $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.15 1997/04/25 18:40:39 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -288,19 +288,23 @@ textne(struct varlena *arg1, struct varlena *arg2)
 /* text_lt()
  * Comparison function for text strings.
  * Includes locale support, but must copy strings to temporary memory
- * to allow null-termination for inputs to strcoll().
+ *  to allow null-termination for inputs to strcoll().
+ * XXX HACK code for textlen() indicates that there can be embedded nulls
+ *  but it appears that most routines (incl. this one) assume not! - tgl 97/04/07
  */
 bool
 text_lt(struct varlena *arg1, struct varlena *arg2) 
 {
+    bool result;
+
+#ifdef USE_LOCALE
+    int cval;
+#endif
     int len;
 #ifdef UNSIGNED_CHAR_TEXT
     unsigned
 #endif
     char *a1p, *a2p;
-#ifdef USE_LOCALE
-    int cval;
-#endif
     
     if (arg1 == NULL || arg2 == NULL)
    return((bool) FALSE);
@@ -308,9 +312,11 @@ text_lt(struct varlena *arg1, struct varlena *arg2)
     len = (((VARSIZE(arg1) <= VARSIZE(arg2))? VARSIZE(arg1): VARSIZE(arg2))-VARHDRSZ);
     
 #ifdef USE_LOCALE
-
-    a1p = palloc (len+1);
-    a2p = palloc (len+1);
+    if (!PointerIsValid(a1p = PALLOC(len+1))
+      || !PointerIsValid(a2p = PALLOC(len+1))) {
+   elog(WARN,"Unable to allocate memory for text comparison",NULL);
+   return(FALSE);
+    };
 
     memcpy(a1p, VARDATA(arg1), len);
     *(a1p+len) = '\0';
@@ -318,15 +324,11 @@ text_lt(struct varlena *arg1, struct varlena *arg2)
     *(a2p+len) = '\0';
 
     cval = strcoll(a1p,a2p);
-    
-    pfree (a1p);
-    pfree (a2p);
-
-    return((bool) ( (cval < 0) || 
-           ( (cval == 0) && (VARSIZE(arg1) < VARSIZE(arg2)) ) ) );
+    result = ((cval < 0) || ((cval == 0) && (VARSIZE(arg1) < VARSIZE(arg2))));
 
+    PFREE(a1p);
+    PFREE(a2p);
 #else
-
     a1p = (unsigned char *)VARDATA(arg1);
     a2p = (unsigned char *)VARDATA(arg2);
     
@@ -335,28 +337,33 @@ text_lt(struct varlena *arg1, struct varlena *arg2)
    a2p++;
    len--;
     };
-    return((bool) (len? (*a1p < *a2p): (VARSIZE(arg1) < VARSIZE(arg2))));
 
+    result = (len? (*a1p < *a2p): (VARSIZE(arg1) < VARSIZE(arg2)));
 #endif
 
+    return(result);
 } /* text_lt() */
 
 /* text_le()
  * Comparison function for text strings.
  * Includes locale support, but must copy strings to temporary memory
- * to allow null-termination for inputs to strcoll().
+ *  to allow null-termination for inputs to strcoll().
+ * XXX HACK code for textlen() indicates that there can be embedded nulls
+ *  but it appears that most routines (incl. this one) assume not! - tgl 97/04/07
  */
 bool
 text_le(struct varlena *arg1, struct varlena *arg2) 
 {
+    bool result;
+
+#ifdef USE_LOCALE
+    int cval;
+#endif
     int len;
 #ifdef UNSIGNED_CHAR_TEXT
     unsigned
 #endif
     char *a1p, *a2p;
-#ifdef USE_LOCALE
-    int cval;
-#endif
     
     if (arg1 == NULL || arg2 == NULL)
    return((bool) 0);
@@ -364,9 +371,11 @@ text_le(struct varlena *arg1, struct varlena *arg2)
     len = (((VARSIZE(arg1) <= VARSIZE(arg2))? VARSIZE(arg1): VARSIZE(arg2))-VARHDRSZ);
     
 #ifdef USE_LOCALE
-
-    a1p = palloc (len+1);
-    a2p = palloc (len+1);
+    if (!PointerIsValid(a1p = PALLOC(len+1))
+      || !PointerIsValid(a2p = PALLOC(len+1))) {
+   elog(WARN,"Unable to allocate memory for text comparison",NULL);
+   return(FALSE);
+    };
 
     memcpy(a1p, VARDATA(arg1), len);
     *(a1p+len) = '\0';
@@ -374,15 +383,11 @@ text_le(struct varlena *arg1, struct varlena *arg2)
     *(a2p+len) = '\0';
 
     cval = strcoll(a1p,a2p);
-    
-    pfree (a1p);
-    pfree (a2p);
-
-    return ((bool) ( (cval < 0) || 
-           ( (cval == 0) && (VARSIZE(arg1) <= VARSIZE(arg2)) ) ) );
+    result = ((cval < 0) || ((cval == 0) && (VARSIZE(arg1) <= VARSIZE(arg2))));
 
+    PFREE(a1p);
+    PFREE(a2p);
 #else
-
     a1p = (unsigned char *)VARDATA(arg1);
     a2p = (unsigned char *)VARDATA(arg2);
     
@@ -392,10 +397,10 @@ text_le(struct varlena *arg1, struct varlena *arg2)
    len--;
     };
 
-    return((bool) (len? (*a1p <= *a2p): (VARSIZE(arg1) <= VARSIZE(arg2))));
-
+    result = (len? (*a1p <= *a2p): (VARSIZE(arg1) <= VARSIZE(arg2)));
 #endif
 
+    return(result);
 } /* text_le() */
 
 bool
index 9005f5c51fc63f7b9a61e42b2fac0b11531ea425..01fff066f406fcd54b1ebd75ea601b5672e55416 100644 (file)
@@ -8,7 +8,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: dt.h,v 1.5 1997/04/02 18:32:20 scrappy Exp $
+ * $Id: dt.h,v 1.6 1997/04/25 18:40:45 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -319,7 +319,7 @@ extern int DecodeDateDelta( char *field[], int ftype[],
 extern int DecodeUnits(int field, char *lowtoken, int *val);
 
 extern int EncodeSpecialDateTime(DateTime dt, char *str);
-extern int EncodeDateTime(struct tm *tm, double fsec, int style, char *str);
+extern int EncodeDateTime(struct tm *tm, double fsec, int *tzp, int style, char *str);
 extern int EncodeTimeSpan(struct tm *tm, double fsec, int style, char *str);
 
 extern datetkn *datebsearch(char *key, datetkn *base, unsigned int nel);
index cdd9f6895a687381f5f89e680d0022ee8e2821e3..2d0aeee86fb0e77ea5d5da85f933c84d92dc46de 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: geo_decls.h,v 1.2 1997/04/22 17:32:41 scrappy Exp $
+ * $Id: geo_decls.h,v 1.3 1997/04/25 18:40:50 scrappy Exp $
  *
  * NOTE
  *    These routines do *not* use the float types from adt/.
@@ -321,6 +321,7 @@ extern double *circle_area(CIRCLE *circle);
 extern double *circle_diameter(CIRCLE *circle);
 extern double *circle_radius(CIRCLE *circle);
 extern double *circle_distance(CIRCLE *circle1, CIRCLE *circle2);
+extern double *dist_pc(Point *point, CIRCLE *circle);
 extern Point *circle_center(CIRCLE *circle);
 extern CIRCLE *circle(Point *center, float8 *radius);
 extern CIRCLE *poly_circle(POLYGON *poly);
diff --git a/src/update6_0-6_1.sh b/src/update6_0-6_1.sh
deleted file mode 100644 (file)
index 44b3c9a..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/bin/sh
-# update
-# Script to apply patches to existing databases
-#  to upgrade from Postgres v6.0 to v6.1.
-echo ""
-echo "This utility does a minimal upgrade for existing v6.0 databases."
-echo "Note that several new features and functions in Postgres"
-echo " will not be available unless the databases are reloaded"
-echo " from a clean install of v6.1."
-echo ""
-echo "This update script is not necessary for new or reloaded databases,"
-echo " but will not damage them. You should update existing v6.1beta"
-echo " databases created on or before 1997-04-04 (when the patches for"
-echo " aggregate functions were applied to the v6.1beta source tree)."
-echo ""
-echo "Features present with this simple update include:"
-echo " - aggregate operators sum() and avg() behave correctly with NULLs"
-echo " - the point distance operator '<===>' returns float8 rather than int4"
-echo " - some duplicate function OIDs are renumbered to eliminate conflicts"
-echo ""
-echo "Features unavailable with only this simple update include:"
-echo " - new string handling functions a la Oracle/Ingres"
-echo " - new date and time data types and expanded functionality"
-echo " - some new function overloading to simplify function names"
-echo ""
-echo "Note that if v6.0 databases are not reloaded from a clean install of v6.1"
-echo " or if this update is not applied to existing v6.0 databases:"
-echo " - aggregate functions avg() and sum() may divide-by-zero for int4 data types"
-#
-srcdir=`pwd`
-srcsql="update6_0-6_1.sql"
-CMDSQL="psql"
-SRCSQL="$srcdir/$srcsql"
-#
-if [ -z $SRCSQL ]; then
-   echo "unable to locate $SRCSQL"
-   exit 1
-fi
-#
-echo ""
-echo "updating databases found in $PGDATA/base"
-echo ""
-#
-cd $PGDATA/base
-for d in *
-do
-   echo "updating $d at `date` ..."
-   echo "try $CMDSQL $d < $SRCSQL"
-   $CMDSQL $d < $SRCSQL
-   echo "completed updating $d at `date`"
-done
-#
-echo ""
-echo "completed all updates at `date`"
-echo ""
-exit
diff --git a/src/update6_0-6_1.sql b/src/update6_0-6_1.sql
deleted file mode 100644 (file)
index e60e8d9..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
--- Aggregate functions
--- Thomas Lockhart
--- This fixes the behavior of built-in aggregate functions avg() and sum().
--- Code tested on postgres95 v1.0.9, postgres v6.0, and postgres v6.1b-970315.
--- Original definitions return zero rather than null for empty set attributes.
--- Postgres source code says that null behavior for aggregates is not correct,
---  but does describe the correct behavior for pass-by-reference data types
---  if it is given null initial values (from pg_aggregate).
--- Note that pass-by-value data types (e.g. int4) require a simple source code
---  change in backend/executor/nodeAgg.c to avoid divide-by-zero results.
--- If this SQL update is applied without making the corresponding source code
---  patch, then floating point types will work correctly but integer types will
---  divide-by-zero.
--- If the source code patch is applied but this SQL update is not, then there
---  will be divide-by-zero results for floating point types.
-
--- For aggregate attributes, the correct behavior is as follows:
--- count(*) should return a count of all tuples, null or otherwise
--- count(col) should return a count of all non-null values, zero if none
--- avg(col), sum(col), etc should ignore null fields and return null if there
---  are no non-null inputs
--- Ref: the original Date book
-
-update pg_aggregate set agginitval1=null
- where aggname = 'avg' or aggname = 'sum';
-
--- Geometric functions
--- Thomas Lockhart
--- This replaces the distance operator with one returning a floating point number.
--- The original operator 'pointdist' returned an integer.
--- There is no corresponding source code change required for this patch.
-
-update pg_operator set oprresult = 701, oprcode = 'point_distance'::regproc
- where oprname = '<===>' and oprresult = 23;
-
--- Date functions
--- Thomas Lockhart
--- This fixes conflicting OIDs within the date and time declarations.
-
-update pg_proc set oid = 1138::oid where proname = 'date_larger';
-update pg_proc set oid = 1139::oid where proname = 'date_smaller';
-update pg_proc set oid = 1140::oid where proname = 'date_mi';
-update pg_proc set oid = 1141::oid where proname = 'date_pli';
-update pg_proc set oid = 1142::oid where proname = 'date_mii';
-update pg_proc set oid = 1143::oid where proname = 'timein';
-update pg_proc set oid = 1144::oid where proname = 'timeout';
-update pg_proc set oid = 1145::oid where proname = 'time_eq';