diff --git a/doc/src/sgml/release.sgml b/doc/src/sgml/release.sgml index f6601ce1cc..20ea24d3f0 100644 --- a/doc/src/sgml/release.sgml +++ b/doc/src/sgml/release.sgml @@ -1,5 +1,5 @@ @@ -256,6 +256,13 @@ $PostgreSQL: pgsql/doc/src/sgml/release.sgml,v 1.298 2004/10/01 02:00:43 neilc E + + + Overflow in integer arithmetic operations is now detected and + reported as an error. + + + 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 + + + Overflow in integer arithmetic operations is now detected (Tom) + + + 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 ccee67319c..9bb521183a 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 1183fa9aa0..7dde75014e 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 @@ -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 e58c94268a..96964c82b9 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 9c8abfb365..f99fb89715 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 100f38d593..a4d18417c2 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 b9f6a296b2..e65614a4aa 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 64e5bf58a8..f72aeb278a 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 e5d930e31e..0e6049f29a 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 c766ee5298..0000000000 --- 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 e1eb64792c..5e6bee8cc7 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 7172cc1071..164285dd65 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 fb80fb0a50..07e727de48 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 313eca30e9..a54c7fe7ba 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 e42b4236fd..81bff55712 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 85b22ccd0a..b4c3929d09 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 98b1606430..ec7766219d 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 be3a0a87b5..5cba9ca74d 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;