diff --git a/src/backend/utils/adt/int.c b/src/backend/utils/adt/int.c index 64ba146d713..c8dfe1cfeb7 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.81 2008/01/01 19:45:52 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/int.c,v 1.82 2008/06/17 19:10:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1085,36 +1085,6 @@ int2mod(PG_FUNCTION_ARGS) PG_RETURN_INT16(arg1 % arg2); } -Datum -int24mod(PG_FUNCTION_ARGS) -{ - int16 arg1 = PG_GETARG_INT16(0); - int32 arg2 = PG_GETARG_INT32(1); - - if (arg2 == 0) - ereport(ERROR, - (errcode(ERRCODE_DIVISION_BY_ZERO), - errmsg("division by zero"))); - /* No overflow is possible */ - - PG_RETURN_INT32(arg1 % arg2); -} - -Datum -int42mod(PG_FUNCTION_ARGS) -{ - int32 arg1 = PG_GETARG_INT32(0); - int16 arg2 = PG_GETARG_INT16(1); - - if (arg2 == 0) - ereport(ERROR, - (errcode(ERRCODE_DIVISION_BY_ZERO), - errmsg("division by zero"))); - /* No overflow is possible */ - - PG_RETURN_INT32(arg1 % arg2); -} - /* int[24]abs() * Absolute value diff --git a/src/backend/utils/adt/int8.c b/src/backend/utils/adt/int8.c index 6f3f9e21055..dc56df4d186 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.69 2008/04/21 00:26:45 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/int8.c,v 1.70 2008/06/17 19:10:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -922,6 +922,184 @@ int48div(PG_FUNCTION_ARGS) PG_RETURN_INT64((int64) arg1 / arg2); } +Datum +int82pl(PG_FUNCTION_ARGS) +{ + int64 arg1 = PG_GETARG_INT64(0); + int16 arg2 = PG_GETARG_INT16(1); + int64 result; + + 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 +int82mi(PG_FUNCTION_ARGS) +{ + int64 arg1 = PG_GETARG_INT64(0); + int16 arg2 = PG_GETARG_INT16(1); + int64 result; + + 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 +int82mul(PG_FUNCTION_ARGS) +{ + int64 arg1 = PG_GETARG_INT64(0); + int16 arg2 = PG_GETARG_INT16(1); + int64 result; + + 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 +int82div(PG_FUNCTION_ARGS) +{ + int64 arg1 = PG_GETARG_INT64(0); + int16 arg2 = PG_GETARG_INT16(1); + int64 result; + + if (arg2 == 0) + ereport(ERROR, + (errcode(ERRCODE_DIVISION_BY_ZERO), + errmsg("division by zero"))); + + 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 +int28pl(PG_FUNCTION_ARGS) +{ + int16 arg1 = PG_GETARG_INT16(0); + int64 arg2 = PG_GETARG_INT64(1); + int64 result; + + 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 +int28mi(PG_FUNCTION_ARGS) +{ + int16 arg1 = PG_GETARG_INT16(0); + int64 arg2 = PG_GETARG_INT64(1); + int64 result; + + 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 +int28mul(PG_FUNCTION_ARGS) +{ + int16 arg1 = PG_GETARG_INT16(0); + int64 arg2 = PG_GETARG_INT64(1); + int64 result; + + 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 +int28div(PG_FUNCTION_ARGS) +{ + int16 arg1 = PG_GETARG_INT16(0); + int64 arg2 = PG_GETARG_INT64(1); + + if (arg2 == 0) + ereport(ERROR, + (errcode(ERRCODE_DIVISION_BY_ZERO), + errmsg("division by zero"))); + /* No overflow is possible */ + PG_RETURN_INT64((int64) arg1 / arg2); +} + /* Binary arithmetics * * int8and - returns arg1 & arg2 diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 31bfd2d7472..5b434df5156 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -37,7 +37,7 @@ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.462 2008/05/27 00:13:09 tgl Exp $ + * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.463 2008/06/17 19:10:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 200805261 +#define CATALOG_VERSION_NO 200806171 #endif diff --git a/src/include/catalog/pg_operator.h b/src/include/catalog/pg_operator.h index c9f05ec9644..7bb2035b1bb 100644 --- a/src/include/catalog/pg_operator.h +++ b/src/include/catalog/pg_operator.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/pg_operator.h,v 1.159 2008/05/27 00:13:09 tgl Exp $ + * $PostgreSQL: pgsql/src/include/catalog/pg_operator.h,v 1.160 2008/06/17 19:10:56 tgl Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -204,8 +204,6 @@ DATA(insert OID = 544 ( "*" PGNSP PGUID b f f 21 23 23 545 0 int24mul - - ) DATA(insert OID = 545 ( "*" PGNSP PGUID b f f 23 21 23 544 0 int42mul - - )); DATA(insert OID = 546 ( "/" PGNSP PGUID b f f 21 23 23 0 0 int24div - - )); DATA(insert OID = 547 ( "/" PGNSP PGUID b f f 23 21 23 0 0 int42div - - )); -DATA(insert OID = 548 ( "%" PGNSP PGUID b f f 21 23 23 0 0 int24mod - - )); -DATA(insert OID = 549 ( "%" PGNSP PGUID b f f 23 21 23 0 0 int42mod - - )); DATA(insert OID = 550 ( "+" PGNSP PGUID b f f 21 21 21 550 0 int2pl - - )); DATA(insert OID = 551 ( "+" PGNSP PGUID b f f 23 23 23 551 0 int4pl - - )); DATA(insert OID = 552 ( "+" PGNSP PGUID b f f 21 23 23 553 0 int24pl - - )); @@ -321,6 +319,7 @@ DATA(insert OID = 684 ( "+" PGNSP PGUID b f f 20 20 20 684 0 int8pl - - )); DATA(insert OID = 685 ( "-" PGNSP PGUID b f f 20 20 20 0 0 int8mi - - )); DATA(insert OID = 686 ( "*" PGNSP PGUID b f f 20 20 20 686 0 int8mul - - )); DATA(insert OID = 687 ( "/" PGNSP PGUID b f f 20 20 20 0 0 int8div - - )); + DATA(insert OID = 688 ( "+" PGNSP PGUID b f f 20 23 20 692 0 int84pl - - )); DATA(insert OID = 689 ( "-" PGNSP PGUID b f f 20 23 20 0 0 int84mi - - )); DATA(insert OID = 690 ( "*" PGNSP PGUID b f f 20 23 20 694 0 int84mul - - )); @@ -330,6 +329,15 @@ DATA(insert OID = 693 ( "-" PGNSP PGUID b f f 23 20 20 0 0 int48mi - - )); DATA(insert OID = 694 ( "*" PGNSP PGUID b f f 23 20 20 690 0 int48mul - - )); DATA(insert OID = 695 ( "/" PGNSP PGUID b f f 23 20 20 0 0 int48div - - )); +DATA(insert OID = 818 ( "+" PGNSP PGUID b f f 20 21 20 822 0 int82pl - - )); +DATA(insert OID = 819 ( "-" PGNSP PGUID b f f 20 21 20 0 0 int82mi - - )); +DATA(insert OID = 820 ( "*" PGNSP PGUID b f f 20 21 20 824 0 int82mul - - )); +DATA(insert OID = 821 ( "/" PGNSP PGUID b f f 20 21 20 0 0 int82div - - )); +DATA(insert OID = 822 ( "+" PGNSP PGUID b f f 21 20 20 818 0 int28pl - - )); +DATA(insert OID = 823 ( "-" PGNSP PGUID b f f 21 20 20 0 0 int28mi - - )); +DATA(insert OID = 824 ( "*" PGNSP PGUID b f f 21 20 20 820 0 int28mul - - )); +DATA(insert OID = 825 ( "/" PGNSP PGUID b f f 21 20 20 0 0 int28div - - )); + DATA(insert OID = 706 ( "<->" PGNSP PGUID b f f 603 603 701 706 0 box_distance - - )); DATA(insert OID = 707 ( "<->" PGNSP PGUID b f f 602 602 701 707 0 path_distance - - )); DATA(insert OID = 708 ( "<->" PGNSP PGUID b f f 628 628 701 708 0 line_distance - - )); diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index c4bc9f3e7e6..dbe79102822 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.502 2008/05/29 22:48:07 tgl Exp $ + * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.503 2008/06/17 19:10:56 tgl Exp $ * * NOTES * The script catalog/genbki.sh reads this file and generates .bki @@ -351,10 +351,6 @@ DATA(insert OID = 172 ( int24div PGNSP PGUID 12 1 0 f f t f i 2 23 "21 23" DESCR("divide"); DATA(insert OID = 173 ( int42div PGNSP PGUID 12 1 0 f f t f i 2 23 "23 21" _null_ _null_ _null_ int42div - _null_ _null_ )); DESCR("divide"); -DATA(insert OID = 174 ( int24mod PGNSP PGUID 12 1 0 f f t f i 2 23 "21 23" _null_ _null_ _null_ int24mod - _null_ _null_ )); -DESCR("modulus"); -DATA(insert OID = 175 ( int42mod PGNSP PGUID 12 1 0 f f t f i 2 23 "23 21" _null_ _null_ _null_ int42mod - _null_ _null_ )); -DESCR("modulus"); DATA(insert OID = 176 ( int2pl PGNSP PGUID 12 1 0 f f t f i 2 21 "21 21" _null_ _null_ _null_ int2pl - _null_ _null_ )); DESCR("add"); DATA(insert OID = 177 ( int4pl PGNSP PGUID 12 1 0 f f t f i 2 23 "23 23" _null_ _null_ _null_ int4pl - _null_ _null_ )); @@ -1177,10 +1173,6 @@ DATA(insert OID = 940 ( mod PGNSP PGUID 12 1 0 f f t f i 2 21 "21 21" _nul DESCR("modulus"); DATA(insert OID = 941 ( mod PGNSP PGUID 12 1 0 f f t f i 2 23 "23 23" _null_ _null_ _null_ int4mod - _null_ _null_ )); DESCR("modulus"); -DATA(insert OID = 942 ( mod PGNSP PGUID 12 1 0 f f t f i 2 23 "21 23" _null_ _null_ _null_ int24mod - _null_ _null_ )); -DESCR("modulus"); -DATA(insert OID = 943 ( mod PGNSP PGUID 12 1 0 f f t f i 2 23 "23 21" _null_ _null_ _null_ int42mod - _null_ _null_ )); -DESCR("modulus"); DATA(insert OID = 945 ( int8mod PGNSP PGUID 12 1 0 f f t f i 2 20 "20 20" _null_ _null_ _null_ int8mod - _null_ _null_ )); DESCR("modulus"); @@ -1570,6 +1562,23 @@ DESCR("multiply"); DATA(insert OID = 1281 ( int48div PGNSP PGUID 12 1 0 f f t f i 2 20 "23 20" _null_ _null_ _null_ int48div - _null_ _null_ )); DESCR("divide"); +DATA(insert OID = 837 ( int82pl PGNSP PGUID 12 1 0 f f t f i 2 20 "20 21" _null_ _null_ _null_ int82pl - _null_ _null_ )); +DESCR("add"); +DATA(insert OID = 838 ( int82mi PGNSP PGUID 12 1 0 f f t f i 2 20 "20 21" _null_ _null_ _null_ int82mi - _null_ _null_ )); +DESCR("subtract"); +DATA(insert OID = 839 ( int82mul PGNSP PGUID 12 1 0 f f t f i 2 20 "20 21" _null_ _null_ _null_ int82mul - _null_ _null_ )); +DESCR("multiply"); +DATA(insert OID = 840 ( int82div PGNSP PGUID 12 1 0 f f t f i 2 20 "20 21" _null_ _null_ _null_ int82div - _null_ _null_ )); +DESCR("divide"); +DATA(insert OID = 841 ( int28pl PGNSP PGUID 12 1 0 f f t f i 2 20 "21 20" _null_ _null_ _null_ int28pl - _null_ _null_ )); +DESCR("add"); +DATA(insert OID = 942 ( int28mi PGNSP PGUID 12 1 0 f f t f i 2 20 "21 20" _null_ _null_ _null_ int28mi - _null_ _null_ )); +DESCR("subtract"); +DATA(insert OID = 943 ( int28mul PGNSP PGUID 12 1 0 f f t f i 2 20 "21 20" _null_ _null_ _null_ int28mul - _null_ _null_ )); +DESCR("multiply"); +DATA(insert OID = 948 ( int28div PGNSP PGUID 12 1 0 f f t f i 2 20 "21 20" _null_ _null_ _null_ int28div - _null_ _null_ )); +DESCR("divide"); + DATA(insert OID = 1287 ( oid PGNSP PGUID 12 1 0 f f t f i 1 26 "20" _null_ _null_ _null_ i8tooid - _null_ _null_ )); DESCR("convert int8 to oid"); DATA(insert OID = 1288 ( int8 PGNSP PGUID 12 1 0 f f t f i 1 20 "26" _null_ _null_ _null_ oidtoi8 - _null_ _null_ )); diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index e152fe671ab..c34ee7aa904 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.316 2008/05/27 00:13:09 tgl Exp $ + * $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.317 2008/06/17 19:10:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -190,8 +190,6 @@ extern Datum int42mul(PG_FUNCTION_ARGS); extern Datum int42div(PG_FUNCTION_ARGS); extern Datum int4mod(PG_FUNCTION_ARGS); extern Datum int2mod(PG_FUNCTION_ARGS); -extern Datum int24mod(PG_FUNCTION_ARGS); -extern Datum int42mod(PG_FUNCTION_ARGS); extern Datum int2larger(PG_FUNCTION_ARGS); extern Datum int2smaller(PG_FUNCTION_ARGS); extern Datum int4larger(PG_FUNCTION_ARGS); diff --git a/src/include/utils/int8.h b/src/include/utils/int8.h index b7b23100561..c19d167464d 100644 --- a/src/include/utils/int8.h +++ b/src/include/utils/int8.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/utils/int8.h,v 1.48 2008/01/01 19:45:59 momjian Exp $ + * $PostgreSQL: pgsql/src/include/utils/int8.h,v 1.49 2008/06/17 19:10:56 tgl Exp $ * * NOTES * These data types are supported on all 64-bit architectures, and may @@ -96,6 +96,16 @@ extern Datum int48mi(PG_FUNCTION_ARGS); extern Datum int48mul(PG_FUNCTION_ARGS); extern Datum int48div(PG_FUNCTION_ARGS); +extern Datum int82pl(PG_FUNCTION_ARGS); +extern Datum int82mi(PG_FUNCTION_ARGS); +extern Datum int82mul(PG_FUNCTION_ARGS); +extern Datum int82div(PG_FUNCTION_ARGS); + +extern Datum int28pl(PG_FUNCTION_ARGS); +extern Datum int28mi(PG_FUNCTION_ARGS); +extern Datum int28mul(PG_FUNCTION_ARGS); +extern Datum int28div(PG_FUNCTION_ARGS); + extern Datum int48(PG_FUNCTION_ARGS); extern Datum int84(PG_FUNCTION_ARGS);