diff --git a/doc/src/sgml/release.sgml b/doc/src/sgml/release.sgml
index f6601ce1cc318f447c1f4dea4e50c2df539830d5..20ea24d3f0fc510eaceca2d2997ad1b42afcfe69 100644
--- a/doc/src/sgml/release.sgml
+++ b/doc/src/sgml/release.sgml
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/release.sgml,v 1.298 2004/10/01 02:00:43 neilc Exp $
+$PostgreSQL: pgsql/doc/src/sgml/release.sgml,v 1.299 2004/10/04 14:42:46 tgl Exp $
 -->
 
 <appendix id="release">
@@ -256,6 +256,13 @@ $PostgreSQL: pgsql/doc/src/sgml/release.sgml,v 1.298 2004/10/01 02:00:43 neilc E
      </para>
     </listitem>
 
+     <listitem>
+      <para>
+       Overflow in integer arithmetic operations is now detected and
+       reported as an error.
+      </para>
+     </listitem>
+
      <listitem>
       <para>
        The server now warns of empty strings passed to
@@ -1228,6 +1235,12 @@ $PostgreSQL: pgsql/doc/src/sgml/release.sgml,v 1.298 2004/10/01 02:00:43 neilc E
      </para>
     </listitem>
 
+     <listitem>
+      <para>
+       Overflow in integer arithmetic operations is now detected (Tom)
+      </para>
+     </listitem>
+
     <listitem>
       <para>
        Syntax checking of array input values considerably tightened up (Joe)
diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c
index ccee67319ce7e821683bccb865d9c336abc91d60..9bb521183ab074ec3e93d38961a3c18aba7bd776 100644
--- a/src/backend/utils/adt/float.c
+++ b/src/backend/utils/adt/float.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.110 2004/09/02 17:12:50 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.111 2004/10/04 14:42:46 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1147,7 +1147,7 @@ dtoi2(PG_FUNCTION_ARGS)
 	if ((num < SHRT_MIN) || (num > SHRT_MAX))
 		ereport(ERROR,
 				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
-				 errmsg("integer out of range")));
+				 errmsg("smallint out of range")));
 
 	result = (int16) rint(num);
 	PG_RETURN_INT16(result);
@@ -1213,7 +1213,7 @@ ftoi2(PG_FUNCTION_ARGS)
 	if ((num < SHRT_MIN) || (num > SHRT_MAX))
 		ereport(ERROR,
 				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
-				 errmsg("integer out of range")));
+				 errmsg("smallint out of range")));
 
 	result = (int16) rint(num);
 	PG_RETURN_INT16(result);
diff --git a/src/backend/utils/adt/int.c b/src/backend/utils/adt/int.c
index 1183fa9aa0c424b7d0ee28824c8b6ac4b55bd1c1..7dde75014e873562e45ccad28fa2b5bac83bc274 100644
--- a/src/backend/utils/adt/int.c
+++ b/src/backend/utils/adt/int.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/int.c,v 1.62 2004/08/29 05:06:49 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/int.c,v 1.63 2004/10/04 14:42:46 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -28,7 +28,6 @@
  *		Arithmetic operators:
  *		 intmod
  */
-
 #include "postgres.h"
 
 #include <ctype.h>
@@ -38,6 +37,7 @@
 #include "libpq/pqformat.h"
 #include "utils/builtins.h"
 
+
 #ifndef SHRT_MAX
 #define SHRT_MAX (0x7FFF)
 #endif
@@ -45,6 +45,8 @@
 #define SHRT_MIN (-0x8000)
 #endif
 
+#define SAMESIGN(a,b)	(((a) < 0) == ((b) < 0))
+
 typedef struct
 {
 	int32		current;
@@ -52,6 +54,7 @@ typedef struct
 	int32		step;
 } generate_series_fctx;
 
+
 /*****************************************************************************
  *	 USER I/O ROUTINES														 *
  *****************************************************************************/
@@ -291,7 +294,7 @@ i4toi2(PG_FUNCTION_ARGS)
 	if (arg1 < SHRT_MIN || arg1 > SHRT_MAX)
 		ereport(ERROR,
 				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
-				 errmsg("integer out of range")));
+				 errmsg("smallint out of range")));
 
 	PG_RETURN_INT16((int16) arg1);
 }
@@ -601,8 +604,15 @@ Datum
 int4um(PG_FUNCTION_ARGS)
 {
 	int32		arg = PG_GETARG_INT32(0);
+	int32		result;
 
-	PG_RETURN_INT32(-arg);
+	result = -arg;
+	/* overflow check (needed for INT_MIN) */
+	if (arg != 0 && SAMESIGN(result, arg))
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("integer out of range")));
+	PG_RETURN_INT32(result);
 }
 
 Datum
@@ -618,8 +628,19 @@ int4pl(PG_FUNCTION_ARGS)
 {
 	int32		arg1 = PG_GETARG_INT32(0);
 	int32		arg2 = PG_GETARG_INT32(1);
+	int32		result;
 
-	PG_RETURN_INT32(arg1 + arg2);
+	result = arg1 + arg2;
+	/*
+	 * Overflow check.  If the inputs are of different signs then their sum
+	 * cannot overflow.  If the inputs are of the same sign, their sum
+	 * had better be that sign too.
+	 */
+	if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("integer out of range")));
+	PG_RETURN_INT32(result);
 }
 
 Datum
@@ -627,8 +648,19 @@ int4mi(PG_FUNCTION_ARGS)
 {
 	int32		arg1 = PG_GETARG_INT32(0);
 	int32		arg2 = PG_GETARG_INT32(1);
+	int32		result;
 
-	PG_RETURN_INT32(arg1 - arg2);
+	result = arg1 - arg2;
+	/*
+	 * Overflow check.  If the inputs are of the same sign then their
+	 * difference cannot overflow.  If they are of different signs then
+	 * the result should be of the same sign as the first input.
+	 */
+	if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("integer out of range")));
+	PG_RETURN_INT32(result);
 }
 
 Datum
@@ -636,8 +668,28 @@ int4mul(PG_FUNCTION_ARGS)
 {
 	int32		arg1 = PG_GETARG_INT32(0);
 	int32		arg2 = PG_GETARG_INT32(1);
+	int32		result;
 
-	PG_RETURN_INT32(arg1 * arg2);
+	result = arg1 * arg2;
+	/*
+	 * Overflow check.  We basically check to see if result / arg2 gives
+	 * arg1 again.  There are two cases where this fails: arg2 = 0 (which
+	 * cannot overflow) and arg1 = INT_MIN, arg2 = -1 (where the division
+	 * itself will overflow and thus incorrectly match).
+	 *
+	 * Since the division is likely much more expensive than the actual
+	 * multiplication, we'd like to skip it where possible.  The best
+	 * bang for the buck seems to be to check whether both inputs are in
+	 * the int16 range; if so, no overflow is possible.
+	 */
+	if (!(arg1 >= (int32) SHRT_MIN && arg1 <= (int32) SHRT_MAX &&
+		  arg2 >= (int32) SHRT_MIN && arg2 <= (int32) SHRT_MAX) &&
+		arg2 != 0 &&
+		(result/arg2 != arg1 || (arg2 == -1 && arg1 < 0 && result < 0)))
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("integer out of range")));
+	PG_RETURN_INT32(result);
 }
 
 Datum
@@ -645,29 +697,55 @@ int4div(PG_FUNCTION_ARGS)
 {
 	int32		arg1 = PG_GETARG_INT32(0);
 	int32		arg2 = PG_GETARG_INT32(1);
+	int32		result;
 
 	if (arg2 == 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_DIVISION_BY_ZERO),
 				 errmsg("division by zero")));
 
-	PG_RETURN_INT32(arg1 / arg2);
+	result = arg1 / arg2;
+	/*
+	 * Overflow check.  The only possible overflow case is for
+	 * arg1 = INT_MIN, arg2 = -1, where the correct result is -INT_MIN,
+	 * which can't be represented on a two's-complement machine.
+	 */
+	if (arg2 == -1 && arg1 < 0 && result < 0)
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("integer out of range")));
+	PG_RETURN_INT32(result);
 }
 
 Datum
 int4inc(PG_FUNCTION_ARGS)
 {
 	int32		arg = PG_GETARG_INT32(0);
+	int32		result;
 
-	PG_RETURN_INT32(arg + 1);
+	result = arg + 1;
+	/* Overflow check */
+	if (arg > 0 && result < 0)
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("integer out of range")));
+
+	PG_RETURN_INT32(result);
 }
 
 Datum
 int2um(PG_FUNCTION_ARGS)
 {
 	int16		arg = PG_GETARG_INT16(0);
+	int16		result;
 
-	PG_RETURN_INT16(-arg);
+	result = -arg;
+	/* overflow check (needed for SHRT_MIN) */
+	if (arg != 0 && SAMESIGN(result, arg))
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("smallint out of range")));
+	PG_RETURN_INT16(result);
 }
 
 Datum
@@ -683,8 +761,19 @@ int2pl(PG_FUNCTION_ARGS)
 {
 	int16		arg1 = PG_GETARG_INT16(0);
 	int16		arg2 = PG_GETARG_INT16(1);
+	int16		result;
 
-	PG_RETURN_INT16(arg1 + arg2);
+	result = arg1 + arg2;
+	/*
+	 * Overflow check.  If the inputs are of different signs then their sum
+	 * cannot overflow.  If the inputs are of the same sign, their sum
+	 * had better be that sign too.
+	 */
+	if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("smallint out of range")));
+	PG_RETURN_INT16(result);
 }
 
 Datum
@@ -692,8 +781,19 @@ int2mi(PG_FUNCTION_ARGS)
 {
 	int16		arg1 = PG_GETARG_INT16(0);
 	int16		arg2 = PG_GETARG_INT16(1);
+	int16		result;
 
-	PG_RETURN_INT16(arg1 - arg2);
+	result = arg1 - arg2;
+	/*
+	 * Overflow check.  If the inputs are of the same sign then their
+	 * difference cannot overflow.  If they are of different signs then
+	 * the result should be of the same sign as the first input.
+	 */
+	if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("smallint out of range")));
+	PG_RETURN_INT16(result);
 }
 
 Datum
@@ -701,8 +801,20 @@ int2mul(PG_FUNCTION_ARGS)
 {
 	int16		arg1 = PG_GETARG_INT16(0);
 	int16		arg2 = PG_GETARG_INT16(1);
+	int32		result32;
 
-	PG_RETURN_INT16(arg1 * arg2);
+	/*
+	 * The most practical way to detect overflow is to do the arithmetic
+	 * in int32 (so that the result can't overflow) and then do a range
+	 * check.
+	 */
+	result32 = (int32) arg1 * (int32) arg2;
+	if (result32 < SHRT_MIN || result32 > SHRT_MAX)
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("smallint out of range")));
+
+	PG_RETURN_INT16((int16) result32);
 }
 
 Datum
@@ -710,13 +822,24 @@ int2div(PG_FUNCTION_ARGS)
 {
 	int16		arg1 = PG_GETARG_INT16(0);
 	int16		arg2 = PG_GETARG_INT16(1);
+	int16		result;
 
 	if (arg2 == 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_DIVISION_BY_ZERO),
 				 errmsg("division by zero")));
 
-	PG_RETURN_INT16(arg1 / arg2);
+	result = arg1 / arg2;
+	/*
+	 * Overflow check.  The only possible overflow case is for
+	 * arg1 = SHRT_MIN, arg2 = -1, where the correct result is -SHRT_MIN,
+	 * which can't be represented on a two's-complement machine.
+	 */
+	if (arg2 == -1 && arg1 < 0 && result < 0)
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("smallint out of range")));
+	PG_RETURN_INT16(result);
 }
 
 Datum
@@ -724,8 +847,19 @@ int24pl(PG_FUNCTION_ARGS)
 {
 	int16		arg1 = PG_GETARG_INT16(0);
 	int32		arg2 = PG_GETARG_INT32(1);
+	int32		result;
 
-	PG_RETURN_INT32(arg1 + arg2);
+	result = arg1 + arg2;
+	/*
+	 * Overflow check.  If the inputs are of different signs then their sum
+	 * cannot overflow.  If the inputs are of the same sign, their sum
+	 * had better be that sign too.
+	 */
+	if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("integer out of range")));
+	PG_RETURN_INT32(result);
 }
 
 Datum
@@ -733,8 +867,19 @@ int24mi(PG_FUNCTION_ARGS)
 {
 	int16		arg1 = PG_GETARG_INT16(0);
 	int32		arg2 = PG_GETARG_INT32(1);
+	int32		result;
 
-	PG_RETURN_INT32(arg1 - arg2);
+	result = arg1 - arg2;
+	/*
+	 * Overflow check.  If the inputs are of the same sign then their
+	 * difference cannot overflow.  If they are of different signs then
+	 * the result should be of the same sign as the first input.
+	 */
+	if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("integer out of range")));
+	PG_RETURN_INT32(result);
 }
 
 Datum
@@ -742,8 +887,25 @@ int24mul(PG_FUNCTION_ARGS)
 {
 	int16		arg1 = PG_GETARG_INT16(0);
 	int32		arg2 = PG_GETARG_INT32(1);
+	int32		result;
 
-	PG_RETURN_INT32(arg1 * arg2);
+	result = arg1 * arg2;
+	/*
+	 * Overflow check.  We basically check to see if result / arg2 gives
+	 * arg1 again.  There is one case where this fails: arg2 = 0 (which
+	 * cannot overflow).
+	 *
+	 * Since the division is likely much more expensive than the actual
+	 * multiplication, we'd like to skip it where possible.  The best
+	 * bang for the buck seems to be to check whether both inputs are in
+	 * the int16 range; if so, no overflow is possible.
+	 */
+	if (!(arg2 >= (int32) SHRT_MIN && arg2 <= (int32) SHRT_MAX) &&
+		result/arg2 != arg1)
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("integer out of range")));
+	PG_RETURN_INT32(result);
 }
 
 Datum
@@ -756,8 +918,8 @@ int24div(PG_FUNCTION_ARGS)
 		ereport(ERROR,
 				(errcode(ERRCODE_DIVISION_BY_ZERO),
 				 errmsg("division by zero")));
-
-	PG_RETURN_INT32(arg1 / arg2);
+	/* No overflow is possible */
+	PG_RETURN_INT32((int32) arg1 / arg2);
 }
 
 Datum
@@ -765,8 +927,19 @@ int42pl(PG_FUNCTION_ARGS)
 {
 	int32		arg1 = PG_GETARG_INT32(0);
 	int16		arg2 = PG_GETARG_INT16(1);
+	int32		result;
 
-	PG_RETURN_INT32(arg1 + arg2);
+	result = arg1 + arg2;
+	/*
+	 * Overflow check.  If the inputs are of different signs then their sum
+	 * cannot overflow.  If the inputs are of the same sign, their sum
+	 * had better be that sign too.
+	 */
+	if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("integer out of range")));
+	PG_RETURN_INT32(result);
 }
 
 Datum
@@ -774,8 +947,19 @@ int42mi(PG_FUNCTION_ARGS)
 {
 	int32		arg1 = PG_GETARG_INT32(0);
 	int16		arg2 = PG_GETARG_INT16(1);
+	int32		result;
 
-	PG_RETURN_INT32(arg1 - arg2);
+	result = arg1 - arg2;
+	/*
+	 * Overflow check.  If the inputs are of the same sign then their
+	 * difference cannot overflow.  If they are of different signs then
+	 * the result should be of the same sign as the first input.
+	 */
+	if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("integer out of range")));
+	PG_RETURN_INT32(result);
 }
 
 Datum
@@ -783,8 +967,25 @@ int42mul(PG_FUNCTION_ARGS)
 {
 	int32		arg1 = PG_GETARG_INT32(0);
 	int16		arg2 = PG_GETARG_INT16(1);
+	int32		result;
 
-	PG_RETURN_INT32(arg1 * arg2);
+	result = arg1 * arg2;
+	/*
+	 * Overflow check.  We basically check to see if result / arg1 gives
+	 * arg2 again.  There is one case where this fails: arg1 = 0 (which
+	 * cannot overflow).
+	 *
+	 * Since the division is likely much more expensive than the actual
+	 * multiplication, we'd like to skip it where possible.  The best
+	 * bang for the buck seems to be to check whether both inputs are in
+	 * the int16 range; if so, no overflow is possible.
+	 */
+	if (!(arg1 >= (int32) SHRT_MIN && arg1 <= (int32) SHRT_MAX) &&
+		result/arg1 != arg2)
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("integer out of range")));
+	PG_RETURN_INT32(result);
 }
 
 Datum
@@ -792,13 +993,24 @@ int42div(PG_FUNCTION_ARGS)
 {
 	int32		arg1 = PG_GETARG_INT32(0);
 	int16		arg2 = PG_GETARG_INT16(1);
+	int32		result;
 
 	if (arg2 == 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_DIVISION_BY_ZERO),
 				 errmsg("division by zero")));
 
-	PG_RETURN_INT32(arg1 / arg2);
+	result = arg1 / arg2;
+	/*
+	 * Overflow check.  The only possible overflow case is for
+	 * arg1 = INT_MIN, arg2 = -1, where the correct result is -INT_MIN,
+	 * which can't be represented on a two's-complement machine.
+	 */
+	if (arg2 == -1 && arg1 < 0 && result < 0)
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("integer out of range")));
+	PG_RETURN_INT32(result);
 }
 
 Datum
@@ -811,6 +1023,7 @@ int4mod(PG_FUNCTION_ARGS)
 		ereport(ERROR,
 				(errcode(ERRCODE_DIVISION_BY_ZERO),
 				 errmsg("division by zero")));
+	/* No overflow is possible */
 
 	PG_RETURN_INT32(arg1 % arg2);
 }
@@ -825,6 +1038,7 @@ int2mod(PG_FUNCTION_ARGS)
 		ereport(ERROR,
 				(errcode(ERRCODE_DIVISION_BY_ZERO),
 				 errmsg("division by zero")));
+	/* No overflow is possible */
 
 	PG_RETURN_INT16(arg1 % arg2);
 }
@@ -839,6 +1053,7 @@ int24mod(PG_FUNCTION_ARGS)
 		ereport(ERROR,
 				(errcode(ERRCODE_DIVISION_BY_ZERO),
 				 errmsg("division by zero")));
+	/* No overflow is possible */
 
 	PG_RETURN_INT32(arg1 % arg2);
 }
@@ -853,6 +1068,7 @@ int42mod(PG_FUNCTION_ARGS)
 		ereport(ERROR,
 				(errcode(ERRCODE_DIVISION_BY_ZERO),
 				 errmsg("division by zero")));
+	/* No overflow is possible */
 
 	PG_RETURN_INT32(arg1 % arg2);
 }
@@ -865,16 +1081,30 @@ Datum
 int4abs(PG_FUNCTION_ARGS)
 {
 	int32		arg1 = PG_GETARG_INT32(0);
+	int32		result;
 
-	PG_RETURN_INT32((arg1 < 0) ? -arg1 : arg1);
+	result = (arg1 < 0) ? -arg1 : arg1;
+	/* overflow check (needed for INT_MIN) */
+	if (result < 0)
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("integer out of range")));
+	PG_RETURN_INT32(result);
 }
 
 Datum
 int2abs(PG_FUNCTION_ARGS)
 {
 	int16		arg1 = PG_GETARG_INT16(0);
+	int16		result;
 
-	PG_RETURN_INT16((arg1 < 0) ? -arg1 : arg1);
+	result = (arg1 < 0) ? -arg1 : arg1;
+	/* overflow check (needed for SHRT_MIN) */
+	if (result < 0)
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("smallint out of range")));
+	PG_RETURN_INT16(result);
 }
 
 Datum
@@ -913,7 +1143,8 @@ int4smaller(PG_FUNCTION_ARGS)
 	PG_RETURN_INT32((arg1 < arg2) ? arg1 : arg2);
 }
 
-/* Binary arithmetics
+/*
+ * Bit-pushing operators
  *
  *		int[24]and		- returns arg1 & arg2
  *		int[24]or		- returns arg1 | arg2
diff --git a/src/backend/utils/adt/int8.c b/src/backend/utils/adt/int8.c
index e58c94268ad3fc4d36c0d492c53014194a085f80..96964c82b9ed5cf41c159264bf03cb0106db3549 100644
--- a/src/backend/utils/adt/int8.c
+++ b/src/backend/utils/adt/int8.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/int8.c,v 1.55 2004/08/29 05:06:49 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/int8.c,v 1.56 2004/10/04 14:42:46 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -24,6 +24,8 @@
 
 #define MAXINT8LEN		25
 
+#define SAMESIGN(a,b)	(((a) < 0) == ((b) < 0))
+
 typedef struct
 {
 	int64		current;
@@ -31,6 +33,7 @@ typedef struct
 	int64		step;
 } generate_series_fctx;
 
+
 /***********************************************************************
  **
  **		Routines for 64-bit integers.
@@ -67,7 +70,6 @@ scanint8(const char *str, bool errorOK, int64 *result)
 	if (*ptr == '-')
 	{
 		ptr++;
-		sign = -1;
 
 		/*
 		 * Do an explicit check for INT64_MIN.	Ugly though this is, it's
@@ -75,12 +77,15 @@ scanint8(const char *str, bool errorOK, int64 *result)
 		 * portably.
 		 */
 #ifndef INT64_IS_BUSTED
-		if (strcmp(ptr, "9223372036854775808") == 0)
+		if (strncmp(ptr, "9223372036854775808", 19) == 0)
 		{
-			*result = -INT64CONST(0x7fffffffffffffff) - 1;
-			return true;
+			tmp = -INT64CONST(0x7fffffffffffffff) - 1;
+			ptr += 19;
+			goto gotdigits;
 		}
 #endif
+
+		sign = -1;
 	}
 	else if (*ptr == '+')
 		ptr++;
@@ -93,7 +98,8 @@ scanint8(const char *str, bool errorOK, int64 *result)
 		else
 			ereport(ERROR,
 					(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
-			errmsg("invalid input syntax for type bigint: \"%s\"", str)));
+					 errmsg("invalid input syntax for integer: \"%s\"",
+							str)));
 	}
 
 	/* process digits */
@@ -108,11 +114,14 @@ scanint8(const char *str, bool errorOK, int64 *result)
 			else
 				ereport(ERROR,
 						(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
-						 errmsg("integer out of range")));
+						 errmsg("value \"%s\" is out of range for type bigint",
+								str)));
 		}
 		tmp = newtmp;
 	}
 
+gotdigits:
+
 	/* allow trailing whitespace, but not other trailing chars */
 	while (*ptr != '\0' && isspace((unsigned char) *ptr))
 		ptr++;
@@ -124,7 +133,8 @@ scanint8(const char *str, bool errorOK, int64 *result)
 		else
 			ereport(ERROR,
 					(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
-			errmsg("invalid input syntax for type bigint: \"%s\"", str)));
+					 errmsg("invalid input syntax for integer: \"%s\"",
+							str)));
 	}
 
 	*result = (sign < 0) ? -tmp : tmp;
@@ -485,58 +495,118 @@ int28ge(PG_FUNCTION_ARGS)
 Datum
 int8um(PG_FUNCTION_ARGS)
 {
-	int64		val = PG_GETARG_INT64(0);
+	int64		arg = PG_GETARG_INT64(0);
+	int64		result;
 
-	PG_RETURN_INT64(-val);
+	result = -arg;
+	/* overflow check (needed for INT64_MIN) */
+	if (arg != 0 && SAMESIGN(result, arg))
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("bigint out of range")));
+	PG_RETURN_INT64(result);
 }
 
 Datum
 int8up(PG_FUNCTION_ARGS)
 {
-	int64		val = PG_GETARG_INT64(0);
+	int64		arg = PG_GETARG_INT64(0);
 
-	PG_RETURN_INT64(val);
+	PG_RETURN_INT64(arg);
 }
 
 Datum
 int8pl(PG_FUNCTION_ARGS)
 {
-	int64		val1 = PG_GETARG_INT64(0);
-	int64		val2 = PG_GETARG_INT64(1);
+	int64		arg1 = PG_GETARG_INT64(0);
+	int64		arg2 = PG_GETARG_INT64(1);
+	int64		result;
 
-	PG_RETURN_INT64(val1 + val2);
+	result = arg1 + arg2;
+	/*
+	 * Overflow check.  If the inputs are of different signs then their sum
+	 * cannot overflow.  If the inputs are of the same sign, their sum
+	 * had better be that sign too.
+	 */
+	if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("bigint out of range")));
+	PG_RETURN_INT64(result);
 }
 
 Datum
 int8mi(PG_FUNCTION_ARGS)
 {
-	int64		val1 = PG_GETARG_INT64(0);
-	int64		val2 = PG_GETARG_INT64(1);
+	int64		arg1 = PG_GETARG_INT64(0);
+	int64		arg2 = PG_GETARG_INT64(1);
+	int64		result;
 
-	PG_RETURN_INT64(val1 - val2);
+	result = arg1 - arg2;
+	/*
+	 * Overflow check.  If the inputs are of the same sign then their
+	 * difference cannot overflow.  If they are of different signs then
+	 * the result should be of the same sign as the first input.
+	 */
+	if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("bigint out of range")));
+	PG_RETURN_INT64(result);
 }
 
 Datum
 int8mul(PG_FUNCTION_ARGS)
 {
-	int64		val1 = PG_GETARG_INT64(0);
-	int64		val2 = PG_GETARG_INT64(1);
+	int64		arg1 = PG_GETARG_INT64(0);
+	int64		arg2 = PG_GETARG_INT64(1);
+	int64		result;
 
-	PG_RETURN_INT64(val1 * val2);
+	result = arg1 * arg2;
+	/*
+	 * Overflow check.  We basically check to see if result / arg2 gives
+	 * arg1 again.  There are two cases where this fails: arg2 = 0 (which
+	 * cannot overflow) and arg1 = INT64_MIN, arg2 = -1 (where the division
+	 * itself will overflow and thus incorrectly match).
+	 *
+	 * Since the division is likely much more expensive than the actual
+	 * multiplication, we'd like to skip it where possible.  The best
+	 * bang for the buck seems to be to check whether both inputs are in
+	 * the int32 range; if so, no overflow is possible.
+	 */
+	if (!(arg1 == (int64) ((int32) arg1) &&
+		  arg2 == (int64) ((int32) arg2)) &&
+		arg2 != 0 &&
+		(result/arg2 != arg1 || (arg2 == -1 && arg1 < 0 && result < 0)))
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("bigint out of range")));
+	PG_RETURN_INT64(result);
 }
 
 Datum
 int8div(PG_FUNCTION_ARGS)
 {
-	int64		val1 = PG_GETARG_INT64(0);
-	int64		val2 = PG_GETARG_INT64(1);
+	int64		arg1 = PG_GETARG_INT64(0);
+	int64		arg2 = PG_GETARG_INT64(1);
+	int64		result;
 
-	if (val2 == 0)
+	if (arg2 == 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_DIVISION_BY_ZERO),
 				 errmsg("division by zero")));
 
-	PG_RETURN_INT64(val1 / val2);
+	result = arg1 / arg2;
+	/*
+	 * Overflow check.  The only possible overflow case is for
+	 * arg1 = INT64_MIN, arg2 = -1, where the correct result is -INT64_MIN,
+	 * which can't be represented on a two's-complement machine.
+	 */
+	if (arg2 == -1 && arg1 < 0 && result < 0)
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("bigint out of range")));
+	PG_RETURN_INT64(result);
 }
 
 /* int8abs()
@@ -546,8 +616,15 @@ Datum
 int8abs(PG_FUNCTION_ARGS)
 {
 	int64		arg1 = PG_GETARG_INT64(0);
+	int64		result;
 
-	PG_RETURN_INT64((arg1 < 0) ? -arg1 : arg1);
+	result = (arg1 < 0) ? -arg1 : arg1;
+	/* overflow check (needed for INT64_MIN) */
+	if (result < 0)
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("bigint out of range")));
+	PG_RETURN_INT64(result);
 }
 
 /* int8mod()
@@ -556,20 +633,16 @@ int8abs(PG_FUNCTION_ARGS)
 Datum
 int8mod(PG_FUNCTION_ARGS)
 {
-	int64		val1 = PG_GETARG_INT64(0);
-	int64		val2 = PG_GETARG_INT64(1);
-	int64		result;
+	int64		arg1 = PG_GETARG_INT64(0);
+	int64		arg2 = PG_GETARG_INT64(1);
 
-	if (val2 == 0)
+	if (arg2 == 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_DIVISION_BY_ZERO),
 				 errmsg("division by zero")));
+	/* No overflow is possible */
 
-	result = val1 / val2;
-	result *= val2;
-	result = val1 - result;
-
-	PG_RETURN_INT64(result);
+	PG_RETURN_INT64(arg1 % arg2);
 }
 
 
@@ -577,18 +650,26 @@ Datum
 int8inc(PG_FUNCTION_ARGS)
 {
 	int64		arg = PG_GETARG_INT64(0);
+	int64		result;
 
-	PG_RETURN_INT64(arg + 1);
+	result = arg + 1;
+	/* Overflow check */
+	if (arg > 0 && result < 0)
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("bigint out of range")));
+
+	PG_RETURN_INT64(result);
 }
 
 Datum
 int8larger(PG_FUNCTION_ARGS)
 {
-	int64		val1 = PG_GETARG_INT64(0);
-	int64		val2 = PG_GETARG_INT64(1);
+	int64		arg1 = PG_GETARG_INT64(0);
+	int64		arg2 = PG_GETARG_INT64(1);
 	int64		result;
 
-	result = ((val1 > val2) ? val1 : val2);
+	result = ((arg1 > arg2) ? arg1 : arg2);
 
 	PG_RETURN_INT64(result);
 }
@@ -596,11 +677,11 @@ int8larger(PG_FUNCTION_ARGS)
 Datum
 int8smaller(PG_FUNCTION_ARGS)
 {
-	int64		val1 = PG_GETARG_INT64(0);
-	int64		val2 = PG_GETARG_INT64(1);
+	int64		arg1 = PG_GETARG_INT64(0);
+	int64		arg2 = PG_GETARG_INT64(1);
 	int64		result;
 
-	result = ((val1 < val2) ? val1 : val2);
+	result = ((arg1 < arg2) ? arg1 : arg2);
 
 	PG_RETURN_INT64(result);
 }
@@ -608,83 +689,172 @@ int8smaller(PG_FUNCTION_ARGS)
 Datum
 int84pl(PG_FUNCTION_ARGS)
 {
-	int64		val1 = PG_GETARG_INT64(0);
-	int32		val2 = PG_GETARG_INT32(1);
+	int64		arg1 = PG_GETARG_INT64(0);
+	int32		arg2 = PG_GETARG_INT32(1);
+	int64		result;
 
-	PG_RETURN_INT64(val1 + val2);
+	result = arg1 + arg2;
+	/*
+	 * Overflow check.  If the inputs are of different signs then their sum
+	 * cannot overflow.  If the inputs are of the same sign, their sum
+	 * had better be that sign too.
+	 */
+	if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("bigint out of range")));
+	PG_RETURN_INT64(result);
 }
 
 Datum
 int84mi(PG_FUNCTION_ARGS)
 {
-	int64		val1 = PG_GETARG_INT64(0);
-	int32		val2 = PG_GETARG_INT32(1);
+	int64		arg1 = PG_GETARG_INT64(0);
+	int32		arg2 = PG_GETARG_INT32(1);
+	int64		result;
 
-	PG_RETURN_INT64(val1 - val2);
+	result = arg1 - arg2;
+	/*
+	 * Overflow check.  If the inputs are of the same sign then their
+	 * difference cannot overflow.  If they are of different signs then
+	 * the result should be of the same sign as the first input.
+	 */
+	if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("bigint out of range")));
+	PG_RETURN_INT64(result);
 }
 
 Datum
 int84mul(PG_FUNCTION_ARGS)
 {
-	int64		val1 = PG_GETARG_INT64(0);
-	int32		val2 = PG_GETARG_INT32(1);
+	int64		arg1 = PG_GETARG_INT64(0);
+	int32		arg2 = PG_GETARG_INT32(1);
+	int64		result;
 
-	PG_RETURN_INT64(val1 * val2);
+	result = arg1 * arg2;
+	/*
+	 * Overflow check.  We basically check to see if result / arg1 gives
+	 * arg2 again.  There is one case where this fails: arg1 = 0 (which
+	 * cannot overflow).
+	 *
+	 * Since the division is likely much more expensive than the actual
+	 * multiplication, we'd like to skip it where possible.  The best
+	 * bang for the buck seems to be to check whether both inputs are in
+	 * the int32 range; if so, no overflow is possible.
+	 */
+	if (arg1 != (int64) ((int32) arg1) &&
+		result/arg1 != arg2)
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("bigint out of range")));
+	PG_RETURN_INT64(result);
 }
 
 Datum
 int84div(PG_FUNCTION_ARGS)
 {
-	int64		val1 = PG_GETARG_INT64(0);
-	int32		val2 = PG_GETARG_INT32(1);
+	int64		arg1 = PG_GETARG_INT64(0);
+	int32		arg2 = PG_GETARG_INT32(1);
+	int64		result;
 
-	if (val2 == 0)
+	if (arg2 == 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_DIVISION_BY_ZERO),
 				 errmsg("division by zero")));
 
-	PG_RETURN_INT64(val1 / val2);
+	result = arg1 / arg2;
+	/*
+	 * Overflow check.  The only possible overflow case is for
+	 * arg1 = INT64_MIN, arg2 = -1, where the correct result is -INT64_MIN,
+	 * which can't be represented on a two's-complement machine.
+	 */
+	if (arg2 == -1 && arg1 < 0 && result < 0)
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("bigint out of range")));
+	PG_RETURN_INT64(result);
 }
 
 Datum
 int48pl(PG_FUNCTION_ARGS)
 {
-	int32		val1 = PG_GETARG_INT32(0);
-	int64		val2 = PG_GETARG_INT64(1);
+	int32		arg1 = PG_GETARG_INT32(0);
+	int64		arg2 = PG_GETARG_INT64(1);
+	int64		result;
 
-	PG_RETURN_INT64(val1 + val2);
+	result = arg1 + arg2;
+	/*
+	 * Overflow check.  If the inputs are of different signs then their sum
+	 * cannot overflow.  If the inputs are of the same sign, their sum
+	 * had better be that sign too.
+	 */
+	if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("bigint out of range")));
+	PG_RETURN_INT64(result);
 }
 
 Datum
 int48mi(PG_FUNCTION_ARGS)
 {
-	int32		val1 = PG_GETARG_INT32(0);
-	int64		val2 = PG_GETARG_INT64(1);
+	int32		arg1 = PG_GETARG_INT32(0);
+	int64		arg2 = PG_GETARG_INT64(1);
+	int64		result;
 
-	PG_RETURN_INT64(val1 - val2);
+	result = arg1 - arg2;
+	/*
+	 * Overflow check.  If the inputs are of the same sign then their
+	 * difference cannot overflow.  If they are of different signs then
+	 * the result should be of the same sign as the first input.
+	 */
+	if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("bigint out of range")));
+	PG_RETURN_INT64(result);
 }
 
 Datum
 int48mul(PG_FUNCTION_ARGS)
 {
-	int32		val1 = PG_GETARG_INT32(0);
-	int64		val2 = PG_GETARG_INT64(1);
+	int32		arg1 = PG_GETARG_INT32(0);
+	int64		arg2 = PG_GETARG_INT64(1);
+	int64		result;
 
-	PG_RETURN_INT64(val1 * val2);
+	result = arg1 * arg2;
+	/*
+	 * Overflow check.  We basically check to see if result / arg2 gives
+	 * arg1 again.  There is one case where this fails: arg2 = 0 (which
+	 * cannot overflow).
+	 *
+	 * Since the division is likely much more expensive than the actual
+	 * multiplication, we'd like to skip it where possible.  The best
+	 * bang for the buck seems to be to check whether both inputs are in
+	 * the int32 range; if so, no overflow is possible.
+	 */
+	if (arg2 != (int64) ((int32) arg2) &&
+		result/arg2 != arg1)
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("bigint out of range")));
+	PG_RETURN_INT64(result);
 }
 
 Datum
 int48div(PG_FUNCTION_ARGS)
 {
-	int32		val1 = PG_GETARG_INT32(0);
-	int64		val2 = PG_GETARG_INT64(1);
+	int32		arg1 = PG_GETARG_INT32(0);
+	int64		arg2 = PG_GETARG_INT64(1);
 
-	if (val2 == 0)
+	if (arg2 == 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_DIVISION_BY_ZERO),
 				 errmsg("division by zero")));
-
-	PG_RETURN_INT64(val1 / val2);
+	/* No overflow is possible */
+	PG_RETURN_INT64((int64) arg1 / arg2);
 }
 
 /* Binary arithmetics
@@ -757,21 +927,21 @@ int8shr(PG_FUNCTION_ARGS)
 Datum
 int48(PG_FUNCTION_ARGS)
 {
-	int32		val = PG_GETARG_INT32(0);
+	int32		arg = PG_GETARG_INT32(0);
 
-	PG_RETURN_INT64((int64) val);
+	PG_RETURN_INT64((int64) arg);
 }
 
 Datum
 int84(PG_FUNCTION_ARGS)
 {
-	int64		val = PG_GETARG_INT64(0);
+	int64		arg = PG_GETARG_INT64(0);
 	int32		result;
 
-	result = (int32) val;
+	result = (int32) arg;
 
 	/* Test for overflow by reverse-conversion. */
-	if ((int64) result != val)
+	if ((int64) result != arg)
 		ereport(ERROR,
 				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
 				 errmsg("integer out of range")));
@@ -782,24 +952,24 @@ int84(PG_FUNCTION_ARGS)
 Datum
 int28(PG_FUNCTION_ARGS)
 {
-	int16		val = PG_GETARG_INT16(0);
+	int16		arg = PG_GETARG_INT16(0);
 
-	PG_RETURN_INT64((int64) val);
+	PG_RETURN_INT64((int64) arg);
 }
 
 Datum
 int82(PG_FUNCTION_ARGS)
 {
-	int64		val = PG_GETARG_INT64(0);
+	int64		arg = PG_GETARG_INT64(0);
 	int16		result;
 
-	result = (int16) val;
+	result = (int16) arg;
 
 	/* Test for overflow by reverse-conversion. */
-	if ((int64) result != val)
+	if ((int64) result != arg)
 		ereport(ERROR,
 				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
-				 errmsg("integer out of range")));
+				 errmsg("smallint out of range")));
 
 	PG_RETURN_INT16(result);
 }
@@ -807,10 +977,10 @@ int82(PG_FUNCTION_ARGS)
 Datum
 i8tod(PG_FUNCTION_ARGS)
 {
-	int64		val = PG_GETARG_INT64(0);
+	int64		arg = PG_GETARG_INT64(0);
 	float8		result;
 
-	result = val;
+	result = arg;
 
 	PG_RETURN_FLOAT8(result);
 }
@@ -821,23 +991,23 @@ i8tod(PG_FUNCTION_ARGS)
 Datum
 dtoi8(PG_FUNCTION_ARGS)
 {
-	float8		val = PG_GETARG_FLOAT8(0);
+	float8		arg = PG_GETARG_FLOAT8(0);
 	int64		result;
 
-	/* Round val to nearest integer (but it's still in float form) */
-	val = rint(val);
+	/* Round arg to nearest integer (but it's still in float form) */
+	arg = rint(arg);
 
 	/*
 	 * Does it fit in an int64?  Avoid assuming that we have handy
 	 * constants defined for the range boundaries, instead test for
 	 * overflow by reverse-conversion.
 	 */
-	result = (int64) val;
+	result = (int64) arg;
 
-	if ((float8) result != val)
+	if ((float8) result != arg)
 		ereport(ERROR,
 				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
-				 errmsg("integer out of range")));
+				 errmsg("bigint out of range")));
 
 	PG_RETURN_INT64(result);
 }
@@ -845,10 +1015,10 @@ dtoi8(PG_FUNCTION_ARGS)
 Datum
 i8tof(PG_FUNCTION_ARGS)
 {
-	int64		val = PG_GETARG_INT64(0);
+	int64		arg = PG_GETARG_INT64(0);
 	float4		result;
 
-	result = val;
+	result = arg;
 
 	PG_RETURN_FLOAT4(result);
 }
@@ -859,24 +1029,24 @@ i8tof(PG_FUNCTION_ARGS)
 Datum
 ftoi8(PG_FUNCTION_ARGS)
 {
-	float4		val = PG_GETARG_FLOAT4(0);
+	float4		arg = PG_GETARG_FLOAT4(0);
 	int64		result;
-	float8		dval;
+	float8		darg;
 
-	/* Round val to nearest integer (but it's still in float form) */
-	dval = rint(val);
+	/* Round arg to nearest integer (but it's still in float form) */
+	darg = rint(arg);
 
 	/*
 	 * Does it fit in an int64?  Avoid assuming that we have handy
 	 * constants defined for the range boundaries, instead test for
 	 * overflow by reverse-conversion.
 	 */
-	result = (int64) dval;
+	result = (int64) darg;
 
-	if ((float8) result != dval)
+	if ((float8) result != darg)
 		ereport(ERROR,
 				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
-				 errmsg("integer out of range")));
+				 errmsg("bigint out of range")));
 
 	PG_RETURN_INT64(result);
 }
@@ -884,13 +1054,13 @@ ftoi8(PG_FUNCTION_ARGS)
 Datum
 i8tooid(PG_FUNCTION_ARGS)
 {
-	int64		val = PG_GETARG_INT64(0);
+	int64		arg = PG_GETARG_INT64(0);
 	Oid			result;
 
-	result = (Oid) val;
+	result = (Oid) arg;
 
 	/* Test for overflow by reverse-conversion. */
-	if ((int64) result != val)
+	if ((int64) result != arg)
 		ereport(ERROR,
 				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
 				 errmsg("OID out of range")));
@@ -901,9 +1071,9 @@ i8tooid(PG_FUNCTION_ARGS)
 Datum
 oidtoi8(PG_FUNCTION_ARGS)
 {
-	Oid			val = PG_GETARG_OID(0);
+	Oid			arg = PG_GETARG_OID(0);
 
-	PG_RETURN_INT64((int64) val);
+	PG_RETURN_INT64((int64) arg);
 }
 
 Datum
@@ -929,13 +1099,13 @@ text_int8(PG_FUNCTION_ARGS)
 Datum
 int8_text(PG_FUNCTION_ARGS)
 {
-	/* val is int64, but easier to leave it as Datum */
-	Datum		val = PG_GETARG_DATUM(0);
+	/* arg is int64, but easier to leave it as Datum */
+	Datum		arg = PG_GETARG_DATUM(0);
 	char	   *s;
 	int			len;
 	text	   *result;
 
-	s = DatumGetCString(DirectFunctionCall1(int8out, val));
+	s = DatumGetCString(DirectFunctionCall1(int8out, arg));
 	len = strlen(s);
 
 	result = (text *) palloc(VARHDRSZ + len);
diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c
index 9c8abfb365aa4c39ddd5241b7c8cd73e52e12b7e..f99fb8971535fc120ce669238cbe91dff1b2de04 100644
--- a/src/backend/utils/adt/numeric.c
+++ b/src/backend/utils/adt/numeric.c
@@ -14,7 +14,7 @@
  * Copyright (c) 1998-2004, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.79 2004/08/30 02:54:39 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.80 2004/10/04 14:42:46 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1826,7 +1826,7 @@ numeric_int8(PG_FUNCTION_ARGS)
 	if (NUMERIC_IS_NAN(num))
 		ereport(ERROR,
 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-				 errmsg("cannot convert NaN to integer")));
+				 errmsg("cannot convert NaN to bigint")));
 
 	/* Convert to variable format and thence to int8 */
 	init_var(&x);
@@ -1835,7 +1835,7 @@ numeric_int8(PG_FUNCTION_ARGS)
 	if (!numericvar_to_int8(&x, &result))
 		ereport(ERROR,
 				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
-				 errmsg("integer out of range")));
+				 errmsg("bigint out of range")));
 
 	free_var(&x);
 
@@ -1874,7 +1874,7 @@ numeric_int2(PG_FUNCTION_ARGS)
 	if (NUMERIC_IS_NAN(num))
 		ereport(ERROR,
 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-				 errmsg("cannot convert NaN to integer")));
+				 errmsg("cannot convert NaN to smallint")));
 
 	/* Convert to variable format and thence to int8 */
 	init_var(&x);
@@ -1883,7 +1883,7 @@ numeric_int2(PG_FUNCTION_ARGS)
 	if (!numericvar_to_int8(&x, &val))
 		ereport(ERROR,
 				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
-				 errmsg("integer out of range")));
+				 errmsg("smallint out of range")));
 
 	free_var(&x);
 
@@ -1894,7 +1894,7 @@ numeric_int2(PG_FUNCTION_ARGS)
 	if ((int64) result != val)
 		ereport(ERROR,
 				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
-				 errmsg("integer out of range")));
+				 errmsg("smallint out of range")));
 
 	PG_RETURN_INT16(result);
 }
diff --git a/src/backend/utils/adt/numutils.c b/src/backend/utils/adt/numutils.c
index 100f38d593f1290b2ec21a71b60921f54ec5a8b2..a4d18417c220d0e396ddea65667177a7441db099 100644
--- a/src/backend/utils/adt/numutils.c
+++ b/src/backend/utils/adt/numutils.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/numutils.c,v 1.65 2004/08/29 05:06:49 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/numutils.c,v 1.66 2004/10/04 14:42:46 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -114,7 +114,7 @@ pg_atoi(char *s, int size, int c)
 			if (errno == ERANGE || l < SHRT_MIN || l > SHRT_MAX)
 				ereport(ERROR,
 						(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
-						 errmsg("value \"%s\" is out of range for type shortint", s)));
+						 errmsg("value \"%s\" is out of range for type smallint", s)));
 			break;
 		case sizeof(int8):
 			if (errno == ERANGE || l < SCHAR_MIN || l > SCHAR_MAX)
diff --git a/src/backend/utils/adt/varbit.c b/src/backend/utils/adt/varbit.c
index b9f6a296b230aae4d7aa8594c893aef49c4425a9..e65614a4aa49f70223e20883546baab0e27280da 100644
--- a/src/backend/utils/adt/varbit.c
+++ b/src/backend/utils/adt/varbit.c
@@ -9,7 +9,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/varbit.c,v 1.42 2004/08/29 05:06:49 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/varbit.c,v 1.43 2004/10/04 14:42:46 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1310,7 +1310,7 @@ bittoint8(PG_FUNCTION_ARGS)
 	if (VARBITLEN(arg) > sizeof(result) * BITS_PER_BYTE)
 		ereport(ERROR,
 				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
-				 errmsg("integer out of range")));
+				 errmsg("bigint out of range")));
 
 	result = 0;
 	for (r = VARBITS(arg); r < VARBITEND(arg); r++)
diff --git a/src/test/regress/expected/int2.out b/src/test/regress/expected/int2.out
index 64e5bf58a8c2e198510e889f37f838f1f393a7f2..f72aeb278aed71a8033bad14353d70523491cf57 100644
--- a/src/test/regress/expected/int2.out
+++ b/src/test/regress/expected/int2.out
@@ -14,7 +14,7 @@ INSERT INTO INT2_TBL(f1) VALUES ('32767');
 INSERT INTO INT2_TBL(f1) VALUES ('-32767');
 -- bad input values -- should give errors
 INSERT INTO INT2_TBL(f1) VALUES ('100000');
-ERROR:  value "100000" is out of range for type shortint
+ERROR:  value "100000" is out of range for type smallint
 INSERT INTO INT2_TBL(f1) VALUES ('asdf');
 ERROR:  invalid input syntax for integer: "asdf"
 INSERT INTO INT2_TBL(f1) VALUES ('    ');
@@ -144,14 +144,15 @@ SELECT '' AS three, i.* FROM INT2_TBL i WHERE (i.f1 % int4 '2') = int2 '0';
 (3 rows)
 
 SELECT '' AS five, i.f1, i.f1 * int2 '2' AS x FROM INT2_TBL i;
- five |   f1   |   x   
-------+--------+-------
-      |      0 |     0
-      |   1234 |  2468
-      |  -1234 | -2468
-      |  32767 |    -2
-      | -32767 |     2
-(5 rows)
+ERROR:  smallint out of range
+SELECT '' AS five, i.f1, i.f1 * int2 '2' AS x FROM INT2_TBL i
+WHERE abs(f1) < 16384;
+ five |  f1   |   x   
+------+-------+-------
+      |     0 |     0
+      |  1234 |  2468
+      | -1234 | -2468
+(3 rows)
 
 SELECT '' AS five, i.f1, i.f1 * int4 '2' AS x FROM INT2_TBL i;
  five |   f1   |   x    
@@ -164,14 +165,16 @@ SELECT '' AS five, i.f1, i.f1 * int4 '2' AS x FROM INT2_TBL i;
 (5 rows)
 
 SELECT '' AS five, i.f1, i.f1 + int2 '2' AS x FROM INT2_TBL i;
+ERROR:  smallint out of range
+SELECT '' AS five, i.f1, i.f1 + int2 '2' AS x FROM INT2_TBL i
+WHERE f1 < 32766;
  five |   f1   |   x    
 ------+--------+--------
       |      0 |      2
       |   1234 |   1236
       |  -1234 |  -1232
-      |  32767 | -32767
       | -32767 | -32765
-(5 rows)
+(4 rows)
 
 SELECT '' AS five, i.f1, i.f1 + int4 '2' AS x FROM INT2_TBL i;
  five |   f1   |   x    
@@ -184,14 +187,16 @@ SELECT '' AS five, i.f1, i.f1 + int4 '2' AS x FROM INT2_TBL i;
 (5 rows)
 
 SELECT '' AS five, i.f1, i.f1 - int2 '2' AS x FROM INT2_TBL i;
- five |   f1   |   x   
-------+--------+-------
-      |      0 |    -2
-      |   1234 |  1232
-      |  -1234 | -1236
-      |  32767 | 32765
-      | -32767 | 32767
-(5 rows)
+ERROR:  smallint out of range
+SELECT '' AS five, i.f1, i.f1 - int2 '2' AS x FROM INT2_TBL i
+WHERE f1 > -32767;
+ five |  f1   |   x   
+------+-------+-------
+      |     0 |    -2
+      |  1234 |  1232
+      | -1234 | -1236
+      | 32767 | 32765
+(4 rows)
 
 SELECT '' AS five, i.f1, i.f1 - int4 '2' AS x FROM INT2_TBL i;
  five |   f1   |   x    
diff --git a/src/test/regress/expected/int4.out b/src/test/regress/expected/int4.out
index e5d930e31e071b93198576ca0677a46f68643486..0e6049f29a86cfc2c9b11f1dfc67bcd318e61593 100644
--- a/src/test/regress/expected/int4.out
+++ b/src/test/regress/expected/int4.out
@@ -144,64 +144,74 @@ SELECT '' AS three, i.* FROM INT4_TBL i WHERE (i.f1 % int4 '2') = int2 '0';
 (3 rows)
 
 SELECT '' AS five, i.f1, i.f1 * int2 '2' AS x FROM INT4_TBL i;
- five |     f1      |    x    
-------+-------------+---------
-      |           0 |       0
-      |      123456 |  246912
-      |     -123456 | -246912
-      |  2147483647 |      -2
-      | -2147483647 |       2
-(5 rows)
+ERROR:  integer out of range
+SELECT '' AS five, i.f1, i.f1 * int2 '2' AS x FROM INT4_TBL i
+WHERE abs(f1) < 1073741824;
+ five |   f1    |    x    
+------+---------+---------
+      |       0 |       0
+      |  123456 |  246912
+      | -123456 | -246912
+(3 rows)
 
 SELECT '' AS five, i.f1, i.f1 * int4 '2' AS x FROM INT4_TBL i;
- five |     f1      |    x    
-------+-------------+---------
-      |           0 |       0
-      |      123456 |  246912
-      |     -123456 | -246912
-      |  2147483647 |      -2
-      | -2147483647 |       2
-(5 rows)
+ERROR:  integer out of range
+SELECT '' AS five, i.f1, i.f1 * int4 '2' AS x FROM INT4_TBL i
+WHERE abs(f1) < 1073741824;
+ five |   f1    |    x    
+------+---------+---------
+      |       0 |       0
+      |  123456 |  246912
+      | -123456 | -246912
+(3 rows)
 
 SELECT '' AS five, i.f1, i.f1 + int2 '2' AS x FROM INT4_TBL i;
+ERROR:  integer out of range
+SELECT '' AS five, i.f1, i.f1 + int2 '2' AS x FROM INT4_TBL i
+WHERE f1 < 2147483646;
  five |     f1      |      x      
 ------+-------------+-------------
       |           0 |           2
       |      123456 |      123458
       |     -123456 |     -123454
-      |  2147483647 | -2147483647
       | -2147483647 | -2147483645
-(5 rows)
+(4 rows)
 
 SELECT '' AS five, i.f1, i.f1 + int4 '2' AS x FROM INT4_TBL i;
+ERROR:  integer out of range
+SELECT '' AS five, i.f1, i.f1 + int4 '2' AS x FROM INT4_TBL i
+WHERE f1 < 2147483646;
  five |     f1      |      x      
 ------+-------------+-------------
       |           0 |           2
       |      123456 |      123458
       |     -123456 |     -123454
-      |  2147483647 | -2147483647
       | -2147483647 | -2147483645
-(5 rows)
+(4 rows)
 
 SELECT '' AS five, i.f1, i.f1 - int2 '2' AS x FROM INT4_TBL i;
- five |     f1      |     x      
-------+-------------+------------
-      |           0 |         -2
-      |      123456 |     123454
-      |     -123456 |    -123458
-      |  2147483647 | 2147483645
-      | -2147483647 | 2147483647
-(5 rows)
+ERROR:  integer out of range
+SELECT '' AS five, i.f1, i.f1 - int2 '2' AS x FROM INT4_TBL i
+WHERE f1 > -2147483647;
+ five |     f1     |     x      
+------+------------+------------
+      |          0 |         -2
+      |     123456 |     123454
+      |    -123456 |    -123458
+      | 2147483647 | 2147483645
+(4 rows)
 
 SELECT '' AS five, i.f1, i.f1 - int4 '2' AS x FROM INT4_TBL i;
- five |     f1      |     x      
-------+-------------+------------
-      |           0 |         -2
-      |      123456 |     123454
-      |     -123456 |    -123458
-      |  2147483647 | 2147483645
-      | -2147483647 | 2147483647
-(5 rows)
+ERROR:  integer out of range
+SELECT '' AS five, i.f1, i.f1 - int4 '2' AS x FROM INT4_TBL i
+WHERE f1 > -2147483647;
+ five |     f1     |     x      
+------+------------+------------
+      |          0 |         -2
+      |     123456 |     123454
+      |    -123456 |    -123458
+      | 2147483647 | 2147483645
+(4 rows)
 
 SELECT '' AS five, i.f1, i.f1 / int2 '2' AS x FROM INT4_TBL i;
  five |     f1      |      x      
diff --git a/src/test/regress/expected/int8-exp-three-digits-win32.out b/src/test/regress/expected/int8-exp-three-digits-win32.out
deleted file mode 100644
index c766ee52987714bb44b8cb9acd45c23e18d392bc..0000000000000000000000000000000000000000
--- a/src/test/regress/expected/int8-exp-three-digits-win32.out
+++ /dev/null
@@ -1,300 +0,0 @@
---
--- INT8
--- Test int8 64-bit integers.
---
-CREATE TABLE INT8_TBL(q1 int8, q2 int8);
-INSERT INTO INT8_TBL VALUES('123','456');
-INSERT INTO INT8_TBL VALUES('123','4567890123456789');
-INSERT INTO INT8_TBL VALUES('4567890123456789','123');
-INSERT INTO INT8_TBL VALUES('4567890123456789','4567890123456789');
-INSERT INTO INT8_TBL VALUES('4567890123456789','-4567890123456789');
--- bad inputs
-INSERT INTO INT8_TBL(q1) VALUES ('      ');
-ERROR:  invalid input syntax for type bigint: "      "
-INSERT INTO INT8_TBL(q1) VALUES ('xxx');
-ERROR:  invalid input syntax for type bigint: "xxx"
-INSERT INTO INT8_TBL(q1) VALUES ('3908203590239580293850293850329485');
-ERROR:  integer out of range
-INSERT INTO INT8_TBL(q1) VALUES ('-1204982019841029840928340329840934');
-ERROR:  integer out of range
-INSERT INTO INT8_TBL(q1) VALUES ('- 123');
-ERROR:  invalid input syntax for type bigint: "- 123"
-INSERT INTO INT8_TBL(q1) VALUES ('  345     5');
-ERROR:  invalid input syntax for type bigint: "  345     5"
-INSERT INTO INT8_TBL(q1) VALUES ('');
-ERROR:  invalid input syntax for type bigint: ""
-SELECT * FROM INT8_TBL;
-        q1        |        q2         
-------------------+-------------------
-              123 |               456
-              123 |  4567890123456789
- 4567890123456789 |               123
- 4567890123456789 |  4567890123456789
- 4567890123456789 | -4567890123456789
-(5 rows)
-
-SELECT '' AS five, q1 AS plus, -q1 AS minus FROM INT8_TBL;
- five |       plus       |       minus       
-------+------------------+-------------------
-      |              123 |              -123
-      |              123 |              -123
-      | 4567890123456789 | -4567890123456789
-      | 4567890123456789 | -4567890123456789
-      | 4567890123456789 | -4567890123456789
-(5 rows)
-
-SELECT '' AS five, q1, q2, q1 + q2 AS plus FROM INT8_TBL;
- five |        q1        |        q2         |       plus       
-------+------------------+-------------------+------------------
-      |              123 |               456 |              579
-      |              123 |  4567890123456789 | 4567890123456912
-      | 4567890123456789 |               123 | 4567890123456912
-      | 4567890123456789 |  4567890123456789 | 9135780246913578
-      | 4567890123456789 | -4567890123456789 |                0
-(5 rows)
-
-SELECT '' AS five, q1, q2, q1 - q2 AS minus FROM INT8_TBL;
- five |        q1        |        q2         |       minus       
-------+------------------+-------------------+-------------------
-      |              123 |               456 |              -333
-      |              123 |  4567890123456789 | -4567890123456666
-      | 4567890123456789 |               123 |  4567890123456666
-      | 4567890123456789 |  4567890123456789 |                 0
-      | 4567890123456789 | -4567890123456789 |  9135780246913578
-(5 rows)
-
-SELECT '' AS three, q1, q2, q1 * q2 AS multiply FROM INT8_TBL
- WHERE q1 < 1000 or (q2 > 0 and q2 < 1000);
- three |        q1        |        q2        |      multiply      
--------+------------------+------------------+--------------------
-       |              123 |              456 |              56088
-       |              123 | 4567890123456789 | 561850485185185047
-       | 4567890123456789 |              123 | 561850485185185047
-(3 rows)
-
-SELECT '' AS five, q1, q2, q1 / q2 AS divide FROM INT8_TBL;
- five |        q1        |        q2         |     divide     
-------+------------------+-------------------+----------------
-      |              123 |               456 |              0
-      |              123 |  4567890123456789 |              0
-      | 4567890123456789 |               123 | 37137318076884
-      | 4567890123456789 |  4567890123456789 |              1
-      | 4567890123456789 | -4567890123456789 |             -1
-(5 rows)
-
-SELECT '' AS five, q1, float8(q1) FROM INT8_TBL;
- five |        q1        |        float8         
-------+------------------+-----------------------
-      |              123 |                   123
-      |              123 |                   123
-      | 4567890123456789 | 4.56789012345679e+015
-      | 4567890123456789 | 4.56789012345679e+015
-      | 4567890123456789 | 4.56789012345679e+015
-(5 rows)
-
-SELECT '' AS five, q2, float8(q2) FROM INT8_TBL;
- five |        q2         |         float8         
-------+-------------------+------------------------
-      |               456 |                    456
-      |  4567890123456789 |  4.56789012345679e+015
-      |               123 |                    123
-      |  4567890123456789 |  4.56789012345679e+015
-      | -4567890123456789 | -4.56789012345679e+015
-(5 rows)
-
-SELECT '' AS five, 2 * q1 AS "twice int4" FROM INT8_TBL;
- five |    twice int4    
-------+------------------
-      |              246
-      |              246
-      | 9135780246913578
-      | 9135780246913578
-      | 9135780246913578
-(5 rows)
-
-SELECT '' AS five, q1 * 2 AS "twice int4" FROM INT8_TBL;
- five |    twice int4    
-------+------------------
-      |              246
-      |              246
-      | 9135780246913578
-      | 9135780246913578
-      | 9135780246913578
-(5 rows)
-
--- TO_CHAR()
---
-SELECT '' AS to_char_1, to_char(q1, '9G999G999G999G999G999'), to_char(q2, '9,999,999,999,999,999') 
-	FROM INT8_TBL;
- to_char_1 |        to_char         |        to_char         
------------+------------------------+------------------------
-           |                    123 |                    456
-           |                    123 |  4,567,890,123,456,789
-           |  4,567,890,123,456,789 |                    123
-           |  4,567,890,123,456,789 |  4,567,890,123,456,789
-           |  4,567,890,123,456,789 | -4,567,890,123,456,789
-(5 rows)
-
-SELECT '' AS to_char_2, to_char(q1, '9G999G999G999G999G999D999G999'), to_char(q2, '9,999,999,999,999,999.999,999') 
-	FROM INT8_TBL;	
- to_char_2 |            to_char             |            to_char             
------------+--------------------------------+--------------------------------
-           |                    123.000,000 |                    456.000,000
-           |                    123.000,000 |  4,567,890,123,456,789.000,000
-           |  4,567,890,123,456,789.000,000 |                    123.000,000
-           |  4,567,890,123,456,789.000,000 |  4,567,890,123,456,789.000,000
-           |  4,567,890,123,456,789.000,000 | -4,567,890,123,456,789.000,000
-(5 rows)
-
-SELECT '' AS to_char_3, to_char( (q1 * -1), '9999999999999999PR'), to_char( (q2 * -1), '9999999999999999.999PR') 
-	FROM INT8_TBL;
- to_char_3 |      to_char       |        to_char         
------------+--------------------+------------------------
-           |              <123> |              <456.000>
-           |              <123> | <4567890123456789.000>
-           | <4567890123456789> |              <123.000>
-           | <4567890123456789> | <4567890123456789.000>
-           | <4567890123456789> |  4567890123456789.000 
-(5 rows)
-
-SELECT '' AS to_char_4, to_char( (q1 * -1), '9999999999999999S'), to_char( (q2 * -1), 'S9999999999999999') 
-	FROM INT8_TBL;
- to_char_4 |      to_char      |      to_char      
------------+-------------------+-------------------
-           |              123- |              -456
-           |              123- | -4567890123456789
-           | 4567890123456789- |              -123
-           | 4567890123456789- | -4567890123456789
-           | 4567890123456789- | +4567890123456789
-(5 rows)
-
-SELECT '' AS to_char_5,  to_char(q2, 'MI9999999999999999')     FROM INT8_TBL;	
- to_char_5 |      to_char      
------------+-------------------
-           |               456
-           |  4567890123456789
-           |               123
-           |  4567890123456789
-           | -4567890123456789
-(5 rows)
-
-SELECT '' AS to_char_6,  to_char(q2, 'FMS9999999999999999')    FROM INT8_TBL;
- to_char_6 |      to_char      
------------+-------------------
-           | +456
-           | +4567890123456789
-           | +123
-           | +4567890123456789
-           | -4567890123456789
-(5 rows)
-
-SELECT '' AS to_char_7,  to_char(q2, 'FM9999999999999999THPR') FROM INT8_TBL;
- to_char_7 |      to_char       
------------+--------------------
-           | 456TH
-           | 4567890123456789TH
-           | 123RD
-           | 4567890123456789TH
-           | <4567890123456789>
-(5 rows)
-
-SELECT '' AS to_char_8,  to_char(q2, 'SG9999999999999999th')   FROM INT8_TBL;	
- to_char_8 |       to_char       
------------+---------------------
-           | +             456th
-           | +4567890123456789th
-           | +             123rd
-           | +4567890123456789th
-           | -4567890123456789
-(5 rows)
-
-SELECT '' AS to_char_9,  to_char(q2, '0999999999999999')       FROM INT8_TBL;	
- to_char_9 |      to_char      
------------+-------------------
-           |  0000000000000456
-           |  4567890123456789
-           |  0000000000000123
-           |  4567890123456789
-           | -4567890123456789
-(5 rows)
-
-SELECT '' AS to_char_10, to_char(q2, 'S0999999999999999')      FROM INT8_TBL;	
- to_char_10 |      to_char      
-------------+-------------------
-            | +0000000000000456
-            | +4567890123456789
-            | +0000000000000123
-            | +4567890123456789
-            | -4567890123456789
-(5 rows)
-
-SELECT '' AS to_char_11, to_char(q2, 'FM0999999999999999')     FROM INT8_TBL;	
- to_char_11 |      to_char      
-------------+-------------------
-            | 0000000000000456
-            | 4567890123456789
-            | 0000000000000123
-            | 4567890123456789
-            | -4567890123456789
-(5 rows)
-
-SELECT '' AS to_char_12, to_char(q2, 'FM9999999999999999.000') FROM INT8_TBL;
- to_char_12 |        to_char        
-------------+-----------------------
-            | 456.000
-            | 4567890123456789.000
-            | 123.000
-            | 4567890123456789.000
-            | -4567890123456789.000
-(5 rows)
-
-SELECT '' AS to_char_13, to_char(q2, 'L9999999999999999.000')  FROM INT8_TBL;	
- to_char_13 |        to_char         
-------------+------------------------
-            |                456.000
-            |   4567890123456789.000
-            |                123.000
-            |   4567890123456789.000
-            |  -4567890123456789.000
-(5 rows)
-
-SELECT '' AS to_char_14, to_char(q2, 'FM9999999999999999.999') FROM INT8_TBL;
- to_char_14 |      to_char       
-------------+--------------------
-            | 456.
-            | 4567890123456789.
-            | 123.
-            | 4567890123456789.
-            | -4567890123456789.
-(5 rows)
-
-SELECT '' AS to_char_15, to_char(q2, 'S 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 . 9 9 9') FROM INT8_TBL;
- to_char_15 |                  to_char                  
-------------+-------------------------------------------
-            |                            +4 5 6 . 0 0 0
-            |  +4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 . 0 0 0
-            |                            +1 2 3 . 0 0 0
-            |  +4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 . 0 0 0
-            |  -4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 . 0 0 0
-(5 rows)
-
-SELECT '' AS to_char_16, to_char(q2, '99999 "text" 9999 "9999" 999 "\\"text between quote marks\\"" 9999') FROM INT8_TBL;
- to_char_16 |                          to_char                          
-------------+-----------------------------------------------------------
-            |       text      9999     "text between quote marks"   456
-            |  45678 text 9012 9999 345 "text between quote marks" 6789
-            |       text      9999     "text between quote marks"   123
-            |  45678 text 9012 9999 345 "text between quote marks" 6789
-            | -45678 text 9012 9999 345 "text between quote marks" 6789
-(5 rows)
-
-SELECT '' AS to_char_17, to_char(q2, '999999SG9999999999')     FROM INT8_TBL;
- to_char_17 |      to_char      
-------------+-------------------
-            |       +       456
-            | 456789+0123456789
-            |       +       123
-            | 456789+0123456789
-            | 456789-0123456789
-(5 rows)
-
diff --git a/src/test/regress/expected/int8-exp-three-digits.out b/src/test/regress/expected/int8-exp-three-digits.out
index e1eb64792c6a2d0a004c8af5c97034cdf929ea64..5e6bee8cc792015c0481e87265d5505e53e62fa4 100644
--- a/src/test/regress/expected/int8-exp-three-digits.out
+++ b/src/test/regress/expected/int8-exp-three-digits.out
@@ -3,11 +3,26 @@
 -- Test int8 64-bit integers.
 --
 CREATE TABLE INT8_TBL(q1 int8, q2 int8);
-INSERT INTO INT8_TBL VALUES('123','456');
-INSERT INTO INT8_TBL VALUES('123','4567890123456789');
+INSERT INTO INT8_TBL VALUES('  123   ','  456');
+INSERT INTO INT8_TBL VALUES('123   ','4567890123456789');
 INSERT INTO INT8_TBL VALUES('4567890123456789','123');
 INSERT INTO INT8_TBL VALUES('4567890123456789','4567890123456789');
 INSERT INTO INT8_TBL VALUES('4567890123456789','-4567890123456789');
+-- bad inputs
+INSERT INTO INT8_TBL(q1) VALUES ('      ');
+ERROR:  invalid input syntax for integer: "      "
+INSERT INTO INT8_TBL(q1) VALUES ('xxx');
+ERROR:  invalid input syntax for integer: "xxx"
+INSERT INTO INT8_TBL(q1) VALUES ('3908203590239580293850293850329485');
+ERROR:  value "3908203590239580293850293850329485" is out of range for type bigint
+INSERT INTO INT8_TBL(q1) VALUES ('-1204982019841029840928340329840934');
+ERROR:  value "-1204982019841029840928340329840934" is out of range for type bigint
+INSERT INTO INT8_TBL(q1) VALUES ('- 123');
+ERROR:  invalid input syntax for integer: "- 123"
+INSERT INTO INT8_TBL(q1) VALUES ('  345     5');
+ERROR:  invalid input syntax for integer: "  345     5"
+INSERT INTO INT8_TBL(q1) VALUES ('');
+ERROR:  invalid input syntax for integer: ""
 SELECT * FROM INT8_TBL;
         q1        |        q2         
 ------------------+-------------------
@@ -48,6 +63,8 @@ SELECT '' AS five, q1, q2, q1 - q2 AS minus FROM INT8_TBL;
       | 4567890123456789 | -4567890123456789 |  9135780246913578
 (5 rows)
 
+SELECT '' AS three, q1, q2, q1 * q2 AS multiply FROM INT8_TBL;
+ERROR:  bigint out of range
 SELECT '' AS three, q1, q2, q1 * q2 AS multiply FROM INT8_TBL
  WHERE q1 < 1000 or (q2 > 0 and q2 < 1000);
  three |        q1        |        q2        |      multiply      
@@ -139,7 +156,7 @@ SELECT '' AS to_char_3, to_char( (q1 * -1), '9999999999999999PR'), to_char( (q2
            |              <123> | <4567890123456789.000>
            | <4567890123456789> |              <123.000>
            | <4567890123456789> | <4567890123456789.000>
-           | <4567890123456789> |  4567890123456789.000
+           | <4567890123456789> |  4567890123456789.000 
 (5 rows)
 
 SELECT '' AS to_char_4, to_char( (q1 * -1), '9999999999999999S'), to_char( (q2 * -1), 'S9999999999999999') 
@@ -154,12 +171,12 @@ SELECT '' AS to_char_4, to_char( (q1 * -1), '9999999999999999S'), to_char( (q2 *
 (5 rows)
 
 SELECT '' AS to_char_5,  to_char(q2, 'MI9999999999999999')     FROM INT8_TBL;	
- to_char_5 |      to_char       
------------+--------------------
-           |                456
-           |   4567890123456789
-           |                123
-           |   4567890123456789
+ to_char_5 |      to_char      
+-----------+-------------------
+           |               456
+           |  4567890123456789
+           |               123
+           |  4567890123456789
            | -4567890123456789
 (5 rows)
 
@@ -256,11 +273,11 @@ SELECT '' AS to_char_14, to_char(q2, 'FM9999999999999999.999') FROM INT8_TBL;
 SELECT '' AS to_char_15, to_char(q2, 'S 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 . 9 9 9') FROM INT8_TBL;
  to_char_15 |                  to_char                  
 ------------+-------------------------------------------
-            |                           +4 5 6 . 0 0 0 
-            | + 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 . 0 0 0
-            |                           +1 2 3 . 0 0 0 
-            | + 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 . 0 0 0
-            | - 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 . 0 0 0
+            |                            +4 5 6 . 0 0 0
+            |  +4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 . 0 0 0
+            |                            +1 2 3 . 0 0 0
+            |  +4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 . 0 0 0
+            |  -4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 . 0 0 0
 (5 rows)
 
 SELECT '' AS to_char_16, to_char(q2, '99999 "text" 9999 "9999" 999 "\\"text between quote marks\\"" 9999') FROM INT8_TBL;
diff --git a/src/test/regress/expected/int8.out b/src/test/regress/expected/int8.out
index 7172cc1071a5bb3e97c685fde6ff787bfde54f96..164285dd65a36ef1ede03bddadf92ca5609ac74d 100644
--- a/src/test/regress/expected/int8.out
+++ b/src/test/regress/expected/int8.out
@@ -10,19 +10,19 @@ INSERT INTO INT8_TBL VALUES('4567890123456789','4567890123456789');
 INSERT INTO INT8_TBL VALUES('4567890123456789','-4567890123456789');
 -- bad inputs
 INSERT INTO INT8_TBL(q1) VALUES ('      ');
-ERROR:  invalid input syntax for type bigint: "      "
+ERROR:  invalid input syntax for integer: "      "
 INSERT INTO INT8_TBL(q1) VALUES ('xxx');
-ERROR:  invalid input syntax for type bigint: "xxx"
+ERROR:  invalid input syntax for integer: "xxx"
 INSERT INTO INT8_TBL(q1) VALUES ('3908203590239580293850293850329485');
-ERROR:  integer out of range
+ERROR:  value "3908203590239580293850293850329485" is out of range for type bigint
 INSERT INTO INT8_TBL(q1) VALUES ('-1204982019841029840928340329840934');
-ERROR:  integer out of range
+ERROR:  value "-1204982019841029840928340329840934" is out of range for type bigint
 INSERT INTO INT8_TBL(q1) VALUES ('- 123');
-ERROR:  invalid input syntax for type bigint: "- 123"
+ERROR:  invalid input syntax for integer: "- 123"
 INSERT INTO INT8_TBL(q1) VALUES ('  345     5');
-ERROR:  invalid input syntax for type bigint: "  345     5"
+ERROR:  invalid input syntax for integer: "  345     5"
 INSERT INTO INT8_TBL(q1) VALUES ('');
-ERROR:  invalid input syntax for type bigint: ""
+ERROR:  invalid input syntax for integer: ""
 SELECT * FROM INT8_TBL;
         q1        |        q2         
 ------------------+-------------------
@@ -63,6 +63,8 @@ SELECT '' AS five, q1, q2, q1 - q2 AS minus FROM INT8_TBL;
       | 4567890123456789 | -4567890123456789 |  9135780246913578
 (5 rows)
 
+SELECT '' AS three, q1, q2, q1 * q2 AS multiply FROM INT8_TBL;
+ERROR:  bigint out of range
 SELECT '' AS three, q1, q2, q1 * q2 AS multiply FROM INT8_TBL
  WHERE q1 < 1000 or (q2 > 0 and q2 < 1000);
  three |        q1        |        q2        |      multiply      
diff --git a/src/test/regress/expected/subselect.out b/src/test/regress/expected/subselect.out
index fb80fb0a503720aaf1f997335264f1af8b41a8a7..07e727de482594b5d8d2e102834c29a126a3f630 100644
--- a/src/test/regress/expected/subselect.out
+++ b/src/test/regress/expected/subselect.out
@@ -146,7 +146,8 @@ SELECT '' AS five, f1 AS "Correlated Field"
 --
 SELECT '' AS eight, ss.f1 AS "Correlated Field", ss.f3 AS "Second Field"
   FROM SUBSELECT_TBL ss
-  WHERE f1 NOT IN (SELECT f1+1 FROM INT4_TBL WHERE f1 != ss.f1);
+  WHERE f1 NOT IN (SELECT f1+1 FROM INT4_TBL
+                   WHERE f1 != ss.f1 AND f1 < 2147483647);
  eight | Correlated Field | Second Field 
 -------+------------------+--------------
        |                2 |            4
diff --git a/src/test/regress/resultmap b/src/test/regress/resultmap
index 313eca30e9f1701da2ccef7e69731bb8ef3b52bc..a54c7fe7baa57cbb66c79f59b6606a800918f3bd 100644
--- a/src/test/regress/resultmap
+++ b/src/test/regress/resultmap
@@ -7,4 +7,4 @@ float8/.*-qnx=float8-exp-three-digits
 float8/i.86-pc-mingw32=float8-exp-three-digits-win32
 float8/i.86-pc-cygwin=float8-small-is-zero
 int8/.*-qnx=int8-exp-three-digits
-int8/i.86-pc-mingw32=int8-exp-three-digits-win32
+int8/i.86-pc-mingw32=int8-exp-three-digits
diff --git a/src/test/regress/sql/int2.sql b/src/test/regress/sql/int2.sql
index e42b4236fdcfda2f9d799c8653e558fba82c67b9..81bff55712043a04ca0ada992400f26d5d67f8ca 100644
--- a/src/test/regress/sql/int2.sql
+++ b/src/test/regress/sql/int2.sql
@@ -63,14 +63,23 @@ SELECT '' AS three, i.* FROM INT2_TBL i WHERE (i.f1 % int4 '2') = int2 '0';
 
 SELECT '' AS five, i.f1, i.f1 * int2 '2' AS x FROM INT2_TBL i;
 
+SELECT '' AS five, i.f1, i.f1 * int2 '2' AS x FROM INT2_TBL i
+WHERE abs(f1) < 16384;
+
 SELECT '' AS five, i.f1, i.f1 * int4 '2' AS x FROM INT2_TBL i;
 
 SELECT '' AS five, i.f1, i.f1 + int2 '2' AS x FROM INT2_TBL i;
 
+SELECT '' AS five, i.f1, i.f1 + int2 '2' AS x FROM INT2_TBL i
+WHERE f1 < 32766;
+
 SELECT '' AS five, i.f1, i.f1 + int4 '2' AS x FROM INT2_TBL i;
 
 SELECT '' AS five, i.f1, i.f1 - int2 '2' AS x FROM INT2_TBL i;
 
+SELECT '' AS five, i.f1, i.f1 - int2 '2' AS x FROM INT2_TBL i
+WHERE f1 > -32767;
+
 SELECT '' AS five, i.f1, i.f1 - int4 '2' AS x FROM INT2_TBL i;
 
 SELECT '' AS five, i.f1, i.f1 / int2 '2' AS x FROM INT2_TBL i;
diff --git a/src/test/regress/sql/int4.sql b/src/test/regress/sql/int4.sql
index 85b22ccd0ab2c0b3ae5ae07424866ba91c781365..b4c3929d09f112a1816c52e9d549694681c33ad7 100644
--- a/src/test/regress/sql/int4.sql
+++ b/src/test/regress/sql/int4.sql
@@ -63,16 +63,34 @@ SELECT '' AS three, i.* FROM INT4_TBL i WHERE (i.f1 % int4 '2') = int2 '0';
 
 SELECT '' AS five, i.f1, i.f1 * int2 '2' AS x FROM INT4_TBL i;
 
+SELECT '' AS five, i.f1, i.f1 * int2 '2' AS x FROM INT4_TBL i
+WHERE abs(f1) < 1073741824;
+
 SELECT '' AS five, i.f1, i.f1 * int4 '2' AS x FROM INT4_TBL i;
 
+SELECT '' AS five, i.f1, i.f1 * int4 '2' AS x FROM INT4_TBL i
+WHERE abs(f1) < 1073741824;
+
 SELECT '' AS five, i.f1, i.f1 + int2 '2' AS x FROM INT4_TBL i;
 
+SELECT '' AS five, i.f1, i.f1 + int2 '2' AS x FROM INT4_TBL i
+WHERE f1 < 2147483646;
+
 SELECT '' AS five, i.f1, i.f1 + int4 '2' AS x FROM INT4_TBL i;
 
+SELECT '' AS five, i.f1, i.f1 + int4 '2' AS x FROM INT4_TBL i
+WHERE f1 < 2147483646;
+
 SELECT '' AS five, i.f1, i.f1 - int2 '2' AS x FROM INT4_TBL i;
 
+SELECT '' AS five, i.f1, i.f1 - int2 '2' AS x FROM INT4_TBL i
+WHERE f1 > -2147483647;
+
 SELECT '' AS five, i.f1, i.f1 - int4 '2' AS x FROM INT4_TBL i;
 
+SELECT '' AS five, i.f1, i.f1 - int4 '2' AS x FROM INT4_TBL i
+WHERE f1 > -2147483647;
+
 SELECT '' AS five, i.f1, i.f1 / int2 '2' AS x FROM INT4_TBL i;
 
 SELECT '' AS five, i.f1, i.f1 / int4 '2' AS x FROM INT4_TBL i;
diff --git a/src/test/regress/sql/int8.sql b/src/test/regress/sql/int8.sql
index 98b1606430daa5f4d7606f81c456317bc9058745..ec7766219d63e578740970cb1e3f902432ab0a82 100644
--- a/src/test/regress/sql/int8.sql
+++ b/src/test/regress/sql/int8.sql
@@ -25,6 +25,7 @@ SELECT '' AS five, q1 AS plus, -q1 AS minus FROM INT8_TBL;
 
 SELECT '' AS five, q1, q2, q1 + q2 AS plus FROM INT8_TBL;
 SELECT '' AS five, q1, q2, q1 - q2 AS minus FROM INT8_TBL;
+SELECT '' AS three, q1, q2, q1 * q2 AS multiply FROM INT8_TBL;
 SELECT '' AS three, q1, q2, q1 * q2 AS multiply FROM INT8_TBL
  WHERE q1 < 1000 or (q2 > 0 and q2 < 1000);
 SELECT '' AS five, q1, q2, q1 / q2 AS divide FROM INT8_TBL;
diff --git a/src/test/regress/sql/subselect.sql b/src/test/regress/sql/subselect.sql
index be3a0a87b5db7db78c8989f532e40c9d2377f346..5cba9ca74d00c75afc1571da406f26f8263090e9 100644
--- a/src/test/regress/sql/subselect.sql
+++ b/src/test/regress/sql/subselect.sql
@@ -71,7 +71,8 @@ SELECT '' AS five, f1 AS "Correlated Field"
 
 SELECT '' AS eight, ss.f1 AS "Correlated Field", ss.f3 AS "Second Field"
   FROM SUBSELECT_TBL ss
-  WHERE f1 NOT IN (SELECT f1+1 FROM INT4_TBL WHERE f1 != ss.f1);
+  WHERE f1 NOT IN (SELECT f1+1 FROM INT4_TBL
+                   WHERE f1 != ss.f1 AND f1 < 2147483647);
 
 select q1, float8(count(*)) / (select count(*) from int8_tbl)
 from int8_tbl group by q1 order by q1;