~ubuntu-branches/ubuntu/lucid/postgresql-8.4/lucid-proposed

« back to all changes in this revision

Viewing changes to src/backend/utils/adt/int.c

  • Committer: Package Import Robot
  • Author(s): Martin Pitt
  • Date: 2012-12-10 15:53:42 UTC
  • mfrom: (1.3.9)
  • Revision ID: package-import@ubuntu.com-20121210155342-3scm68xcxel275jb
Tags: 8.4.15-0ubuntu10.04
* New upstream bug fix release: (LP: #1088393)
  - Fix multiple bugs associated with "CREATE INDEX CONCURRENTLY"
    Fix "CREATE INDEX CONCURRENTLY" to use in-place updates when
    changing the state of an index's pg_index row. This prevents race
    conditions that could cause concurrent sessions to miss updating
    the target index, thus resulting in corrupt concurrently-created
    indexes.
    Also, fix various other operations to ensure that they ignore
    invalid indexes resulting from a failed "CREATE INDEX CONCURRENTLY"
    command. The most important of these is "VACUUM", because an
    auto-vacuum could easily be launched on the table before corrective
    action can be taken to fix or remove the invalid index.
  - See HISTORY/changelog.gz for details about other bug fixes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
671
671
        int32           arg2 = PG_GETARG_INT32(1);
672
672
        int32           result;
673
673
 
674
 
#ifdef WIN32
675
 
 
676
 
        /*
677
 
         * Win32 doesn't throw a catchable exception for SELECT -2147483648 *
678
 
         * (-1);  -- INT_MIN
679
 
         */
680
 
        if (arg2 == -1 && arg1 == INT_MIN)
681
 
                ereport(ERROR,
682
 
                                (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
683
 
                                 errmsg("integer out of range")));
684
 
#endif
685
 
 
686
674
        result = arg1 * arg2;
687
675
 
688
676
        /*
699
687
        if (!(arg1 >= (int32) SHRT_MIN && arg1 <= (int32) SHRT_MAX &&
700
688
                  arg2 >= (int32) SHRT_MIN && arg2 <= (int32) SHRT_MAX) &&
701
689
                arg2 != 0 &&
702
 
                (result / arg2 != arg1 || (arg2 == -1 && arg1 < 0 && result < 0)))
 
690
                ((arg2 == -1 && arg1 < 0 && result < 0) ||
 
691
                 result / arg2 != arg1))
703
692
                ereport(ERROR,
704
693
                                (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
705
694
                                 errmsg("integer out of range")));
722
711
                PG_RETURN_NULL();
723
712
        }
724
713
 
725
 
#ifdef WIN32
726
 
 
727
714
        /*
728
 
         * Win32 doesn't throw a catchable exception for SELECT -2147483648 /
729
 
         * (-1); -- INT_MIN
 
715
         * INT_MIN / -1 is problematic, since the result can't be represented on a
 
716
         * two's-complement machine.  Some machines produce INT_MIN, some produce
 
717
         * zero, some throw an exception.  We can dodge the problem by recognizing
 
718
         * that division by -1 is the same as negation.
730
719
         */
731
 
        if (arg2 == -1 && arg1 == INT_MIN)
732
 
                ereport(ERROR,
733
 
                                (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
734
 
                                 errmsg("integer out of range")));
735
 
#endif
 
720
        if (arg2 == -1)
 
721
        {
 
722
                result = -arg1;
 
723
                /* overflow check (needed for INT_MIN) */
 
724
                if (arg1 != 0 && SAMESIGN(result, arg1))
 
725
                        ereport(ERROR,
 
726
                                        (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
 
727
                                         errmsg("integer out of range")));
 
728
                PG_RETURN_INT32(result);
 
729
        }
 
730
 
 
731
        /* No overflow is possible */
736
732
 
737
733
        result = arg1 / arg2;
738
734
 
739
 
        /*
740
 
         * Overflow check.      The only possible overflow case is for arg1 = INT_MIN,
741
 
         * arg2 = -1, where the correct result is -INT_MIN, which can't be
742
 
         * represented on a two's-complement machine.  Most machines produce
743
 
         * INT_MIN but it seems some produce zero.
744
 
         */
745
 
        if (arg2 == -1 && arg1 < 0 && result <= 0)
746
 
                ereport(ERROR,
747
 
                                (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
748
 
                                 errmsg("integer out of range")));
749
735
        PG_RETURN_INT32(result);
750
736
}
751
737
 
867
853
                PG_RETURN_NULL();
868
854
        }
869
855
 
870
 
        result = arg1 / arg2;
871
 
 
872
856
        /*
873
 
         * Overflow check.      The only possible overflow case is for arg1 =
874
 
         * SHRT_MIN, arg2 = -1, where the correct result is -SHRT_MIN, which can't
875
 
         * be represented on a two's-complement machine.  Most machines produce
876
 
         * SHRT_MIN but it seems some produce zero.
 
857
         * SHRT_MIN / -1 is problematic, since the result can't be represented on
 
858
         * a two's-complement machine.  Some machines produce SHRT_MIN, some
 
859
         * produce zero, some throw an exception.  We can dodge the problem by
 
860
         * recognizing that division by -1 is the same as negation.
877
861
         */
878
 
        if (arg2 == -1 && arg1 < 0 && result <= 0)
879
 
                ereport(ERROR,
880
 
                                (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
881
 
                                 errmsg("smallint out of range")));
 
862
        if (arg2 == -1)
 
863
        {
 
864
                result = -arg1;
 
865
                /* overflow check (needed for SHRT_MIN) */
 
866
                if (arg1 != 0 && SAMESIGN(result, arg1))
 
867
                        ereport(ERROR,
 
868
                                        (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
 
869
                                         errmsg("smallint out of range")));
 
870
                PG_RETURN_INT16(result);
 
871
        }
 
872
 
 
873
        /* No overflow is possible */
 
874
 
 
875
        result = arg1 / arg2;
 
876
 
882
877
        PG_RETURN_INT16(result);
883
878
}
884
879
 
1055
1050
                PG_RETURN_NULL();
1056
1051
        }
1057
1052
 
1058
 
        result = arg1 / arg2;
1059
 
 
1060
1053
        /*
1061
 
         * Overflow check.      The only possible overflow case is for arg1 = INT_MIN,
1062
 
         * arg2 = -1, where the correct result is -INT_MIN, which can't be
1063
 
         * represented on a two's-complement machine.  Most machines produce
1064
 
         * INT_MIN but it seems some produce zero.
 
1054
         * INT_MIN / -1 is problematic, since the result can't be represented on a
 
1055
         * two's-complement machine.  Some machines produce INT_MIN, some produce
 
1056
         * zero, some throw an exception.  We can dodge the problem by recognizing
 
1057
         * that division by -1 is the same as negation.
1065
1058
         */
1066
 
        if (arg2 == -1 && arg1 < 0 && result <= 0)
1067
 
                ereport(ERROR,
1068
 
                                (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1069
 
                                 errmsg("integer out of range")));
 
1059
        if (arg2 == -1)
 
1060
        {
 
1061
                result = -arg1;
 
1062
                /* overflow check (needed for INT_MIN) */
 
1063
                if (arg1 != 0 && SAMESIGN(result, arg1))
 
1064
                        ereport(ERROR,
 
1065
                                        (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
 
1066
                                         errmsg("integer out of range")));
 
1067
                PG_RETURN_INT32(result);
 
1068
        }
 
1069
 
 
1070
        /* No overflow is possible */
 
1071
 
 
1072
        result = arg1 / arg2;
 
1073
 
1070
1074
        PG_RETURN_INT32(result);
1071
1075
}
1072
1076
 
1085
1089
                PG_RETURN_NULL();
1086
1090
        }
1087
1091
 
1088
 
        /* SELECT ((-2147483648)::int4) % (-1); causes a floating point exception */
1089
 
        if (arg1 == INT_MIN && arg2 == -1)
 
1092
        /*
 
1093
         * Some machines throw a floating-point exception for INT_MIN % -1, which
 
1094
         * is a bit silly since the correct answer is perfectly well-defined,
 
1095
         * namely zero.
 
1096
         */
 
1097
        if (arg2 == -1)
1090
1098
                PG_RETURN_INT32(0);
1091
1099
 
1092
1100
        /* No overflow is possible */
1109
1117
                PG_RETURN_NULL();
1110
1118
        }
1111
1119
 
 
1120
        /*
 
1121
         * Some machines throw a floating-point exception for INT_MIN % -1, which
 
1122
         * is a bit silly since the correct answer is perfectly well-defined,
 
1123
         * namely zero.  (It's not clear this ever happens when dealing with
 
1124
         * int16, but we might as well have the test for safety.)
 
1125
         */
 
1126
        if (arg2 == -1)
 
1127
                PG_RETURN_INT16(0);
 
1128
 
1112
1129
        /* No overflow is possible */
1113
1130
 
1114
1131
        PG_RETURN_INT16(arg1 % arg2);