@ -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