aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/utils/adt/int.c32
-rw-r--r--src/backend/utils/adt/int8.c180
-rw-r--r--src/include/catalog/catversion.h4
-rw-r--r--src/include/catalog/pg_operator.h14
-rw-r--r--src/include/catalog/pg_proc.h27
-rw-r--r--src/include/utils/builtins.h4
-rw-r--r--src/include/utils/int8.h12
7 files changed, 223 insertions, 50 deletions
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);