Re: Rejection of the smallest int8
От | sugita@sra.co.jp |
---|---|
Тема | Re: Rejection of the smallest int8 |
Дата | |
Msg-id | 20011122.180052.48523519.sugita@sra.co.jp обсуждение исходный текст |
Ответ на | Re: Rejection of the smallest int8 (Tom Lane <tgl@sss.pgh.pa.us>) |
Список | 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 по дате отправления: