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);
}