@@ -680,18 +680,6 @@ int4mul(PG_FUNCTION_ARGS)
680
680
int32 arg2 = PG_GETARG_INT32 (1 );
681
681
int32 result ;
682
682
683
- #ifdef WIN32
684
-
685
- /*
686
- * Win32 doesn't throw a catchable exception for SELECT -2147483648 *
687
- * (-1); -- INT_MIN
688
- */
689
- if (arg2 == -1 && arg1 == INT_MIN )
690
- ereport (ERROR ,
691
- (errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
692
- errmsg ("integer out of range" )));
693
- #endif
694
-
695
683
result = arg1 * arg2 ;
696
684
697
685
/*
@@ -708,7 +696,8 @@ int4mul(PG_FUNCTION_ARGS)
708
696
if (!(arg1 >= (int32 ) SHRT_MIN && arg1 <= (int32 ) SHRT_MAX &&
709
697
arg2 >= (int32 ) SHRT_MIN && arg2 <= (int32 ) SHRT_MAX ) &&
710
698
arg2 != 0 &&
711
- (result / arg2 != arg1 || (arg2 == -1 && arg1 < 0 && result < 0 )))
699
+ ((arg2 == -1 && arg1 < 0 && result < 0 ) ||
700
+ result / arg2 != arg1 ))
712
701
ereport (ERROR ,
713
702
(errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
714
703
errmsg ("integer out of range" )));
@@ -731,30 +720,27 @@ int4div(PG_FUNCTION_ARGS)
731
720
PG_RETURN_NULL ();
732
721
}
733
722
734
- #ifdef WIN32
735
-
736
723
/*
737
- * Win32 doesn't throw a catchable exception for SELECT -2147483648 /
738
- * (-1); -- INT_MIN
724
+ * INT_MIN / -1 is problematic, since the result can't be represented on a
725
+ * two's-complement machine. Some machines produce INT_MIN, some produce
726
+ * zero, some throw an exception. We can dodge the problem by recognizing
727
+ * that division by -1 is the same as negation.
739
728
*/
740
- if (arg2 == -1 && arg1 == INT_MIN )
741
- ereport (ERROR ,
742
- (errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
743
- errmsg ("integer out of range" )));
744
- #endif
729
+ if (arg2 == -1 )
730
+ {
731
+ result = - arg1 ;
732
+ /* overflow check (needed for INT_MIN) */
733
+ if (arg1 != 0 && SAMESIGN (result , arg1 ))
734
+ ereport (ERROR ,
735
+ (errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
736
+ errmsg ("integer out of range" )));
737
+ PG_RETURN_INT32 (result );
738
+ }
739
+
740
+ /* No overflow is possible */
745
741
746
742
result = arg1 / arg2 ;
747
743
748
- /*
749
- * Overflow check. The only possible overflow case is for arg1 = INT_MIN,
750
- * arg2 = -1, where the correct result is -INT_MIN, which can't be
751
- * represented on a two's-complement machine. Most machines produce
752
- * INT_MIN but it seems some produce zero.
753
- */
754
- if (arg2 == -1 && arg1 < 0 && result <= 0 )
755
- ereport (ERROR ,
756
- (errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
757
- errmsg ("integer out of range" )));
758
744
PG_RETURN_INT32 (result );
759
745
}
760
746
@@ -876,18 +862,27 @@ int2div(PG_FUNCTION_ARGS)
876
862
PG_RETURN_NULL ();
877
863
}
878
864
879
- result = arg1 / arg2 ;
880
-
881
865
/*
882
- * Overflow check. The only possible overflow case is for arg1 =
883
- * SHRT_MIN, arg2 = -1, where the correct result is - SHRT_MIN, which can't
884
- * be represented on a two's-complement machine . Most machines produce
885
- * SHRT_MIN but it seems some produce zero .
866
+ * SHRT_MIN / -1 is problematic, since the result can't be represented on
867
+ * a two's-complement machine. Some machines produce SHRT_MIN, some
868
+ * produce zero, some throw an exception . We can dodge the problem by
869
+ * recognizing that division by -1 is the same as negation .
886
870
*/
887
- if (arg2 == -1 && arg1 < 0 && result <= 0 )
888
- ereport (ERROR ,
889
- (errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
890
- errmsg ("smallint out of range" )));
871
+ if (arg2 == -1 )
872
+ {
873
+ result = - arg1 ;
874
+ /* overflow check (needed for SHRT_MIN) */
875
+ if (arg1 != 0 && SAMESIGN (result , arg1 ))
876
+ ereport (ERROR ,
877
+ (errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
878
+ errmsg ("smallint out of range" )));
879
+ PG_RETURN_INT16 (result );
880
+ }
881
+
882
+ /* No overflow is possible */
883
+
884
+ result = arg1 / arg2 ;
885
+
891
886
PG_RETURN_INT16 (result );
892
887
}
893
888
@@ -1064,18 +1059,27 @@ int42div(PG_FUNCTION_ARGS)
1064
1059
PG_RETURN_NULL ();
1065
1060
}
1066
1061
1067
- result = arg1 / arg2 ;
1068
-
1069
1062
/*
1070
- * Overflow check. The only possible overflow case is for arg1 = INT_MIN,
1071
- * arg2 = -1, where the correct result is - INT_MIN, which can't be
1072
- * represented on a two's-complement machine . Most machines produce
1073
- * INT_MIN but it seems some produce zero .
1063
+ * INT_MIN / -1 is problematic, since the result can't be represented on a
1064
+ * two's-complement machine. Some machines produce INT_MIN, some produce
1065
+ * zero, some throw an exception . We can dodge the problem by recognizing
1066
+ * that division by -1 is the same as negation .
1074
1067
*/
1075
- if (arg2 == -1 && arg1 < 0 && result <= 0 )
1076
- ereport (ERROR ,
1077
- (errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
1078
- errmsg ("integer out of range" )));
1068
+ if (arg2 == -1 )
1069
+ {
1070
+ result = - arg1 ;
1071
+ /* overflow check (needed for INT_MIN) */
1072
+ if (arg1 != 0 && SAMESIGN (result , arg1 ))
1073
+ ereport (ERROR ,
1074
+ (errcode (ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE ),
1075
+ errmsg ("integer out of range" )));
1076
+ PG_RETURN_INT32 (result );
1077
+ }
1078
+
1079
+ /* No overflow is possible */
1080
+
1081
+ result = arg1 / arg2 ;
1082
+
1079
1083
PG_RETURN_INT32 (result );
1080
1084
}
1081
1085
0 commit comments