Re: Rejection of the smallest int8 - Mailing list pgsql-patches

From sugita@sra.co.jp
Subject Re: Rejection of the smallest int8
Date
Msg-id 20011122.180052.48523519.sugita@sra.co.jp
Whole thread Raw
In response to Re: Rejection of the smallest int8  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-patches
From: Tom Lane <tgl@sss.pgh.pa.us>
Subject: Re: [PATCHES] Rejection of the smallest int8
Date: Wed, 21 Nov 2001 12:54:31 -0500

;;; I said:
;;; > If you can see a way around that, we're all ears ...
;;;
;;; Of course there's always the brute-force solution:
;;;
;;;     if (strcmp(ptr, "-9223372036854775808") == 0)
;;;        return -9223372036854775808;
;;;     else
;;;        <<proceed with int8in>>
;;;
;;; (modulo some #ifdef hacking to attach the correct L or LL suffix to the
;;; constant, but you get the idea)
;;;
;;; This qualifies as pretty durn ugly, but might indeed be more portable
;;; than any other alternative.  Comments?

I made a new patch. Toward zero fault is fixed.

Kind regards,


Kenji Sugita
sugita@sra.co.jp
Index: int8.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/int8.c,v
retrieving revision 1.35
diff -u -3 -p -r1.35 int8.c
--- int8.c    2001/10/25 14:10:06    1.35
+++ int8.c    2001/11/22 08:48:09
@@ -28,6 +28,12 @@

 #define MAXINT8LEN        25

+#ifndef INT64_MAX
+#define INT64_MAX (0x7FFFFFFFFFFFFFFFLL)
+#endif
+#ifndef INT64_MIN
+#define INT64_MIN (-INT64_MAX-1)
+#endif
 #ifndef INT_MAX
 #define INT_MAX (0x7FFFFFFFL)
 #endif
@@ -62,6 +68,7 @@ int8in(PG_FUNCTION_ARGS)
     char       *ptr = str;
     int64        tmp = 0;
     int            sign = 1;
+    int64        limit;

     /*
      * Do our own scan, rather than relying on sscanf which might be
@@ -75,18 +82,26 @@ int8in(PG_FUNCTION_ARGS)
         ptr++;
     if (!isdigit((unsigned char) *ptr)) /* require at least one digit */
         elog(ERROR, "Bad int8 external representation \"%s\"", str);
+    if (sign < 0)
+        limit = INT64_MIN;
+    else
+        limit = -INT64_MAX;
     while (*ptr && isdigit((unsigned char) *ptr))        /* process digits */
     {
-        int64        newtmp = tmp * 10 + (*ptr++ - '0');
+        int            digit;

-        if ((newtmp / 10) != tmp)        /* overflow? */
+        if (tmp < -(INT64_MAX/10))        /* overflow? */
+            elog(ERROR, "int8 value out of range: \"%s\"", str);
+        digit = *ptr++ - '0';
+        tmp *= 10;
+        if (tmp < limit + digit)
             elog(ERROR, "int8 value out of range: \"%s\"", str);
-        tmp = newtmp;
+        tmp -= digit;
     }
     if (*ptr)                    /* trailing junk? */
         elog(ERROR, "Bad int8 external representation \"%s\"", str);

-    result = (sign < 0) ? -tmp : tmp;
+    result = (sign < 0) ? tmp : -tmp;

     PG_RETURN_INT64(result);
 }

pgsql-patches by date:

Previous
From: Stephan Szabo
Date:
Subject: Re: More FK patches
Next
From: "Igor Kovalenko"
Date:
Subject: Support for QNX6, POSIX IPC and PTHREAD-style locking