mirror of
https://github.com/postgres/postgres.git
synced 2025-06-27 23:21:58 +03:00
Add numeric <-> int8 and numeric <-> int2 conversion functions, as well
as a unary minus operator for numeric. Now that long numeric constants will get converted to NUMERIC in early parsing, it's essential to have numeric->int8 conversion to avoid 'can't convert' errors on undecorated int8 constants. Threw in the rest for completeness while I was in the area. I did not force an initdb for this, since the system will still run without the new pg_proc/pg_operator entries. Possibly I should've.
This commit is contained in:
@ -5,7 +5,7 @@
|
||||
*
|
||||
* 1998 Jan Wieck
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/numeric.c,v 1.24 2000/01/20 02:21:44 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/numeric.c,v 1.25 2000/02/24 02:05:30 tgl Exp $
|
||||
*
|
||||
* ----------
|
||||
*/
|
||||
@ -357,7 +357,7 @@ numeric(Numeric num, int32 typmod)
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
*
|
||||
* Rounding and the like
|
||||
* Sign manipulation, rounding and the like
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
@ -395,6 +395,51 @@ numeric_abs(Numeric num)
|
||||
}
|
||||
|
||||
|
||||
Numeric
|
||||
numeric_uminus(Numeric num)
|
||||
{
|
||||
Numeric res;
|
||||
|
||||
/* ----------
|
||||
* Handle NULL
|
||||
* ----------
|
||||
*/
|
||||
if (num == NULL)
|
||||
return NULL;
|
||||
|
||||
/* ----------
|
||||
* Handle NaN
|
||||
* ----------
|
||||
*/
|
||||
if (NUMERIC_IS_NAN(num))
|
||||
return make_result(&const_nan);
|
||||
|
||||
/* ----------
|
||||
* Do it the easy way directly on the packed format
|
||||
* ----------
|
||||
*/
|
||||
res = (Numeric) palloc(num->varlen);
|
||||
memcpy(res, num, num->varlen);
|
||||
|
||||
/* ----------
|
||||
* The packed format is known to be totally zero digit trimmed
|
||||
* always. So we can identify a ZERO by the fact that there
|
||||
* are no digits at all. Do nothing to a zero.
|
||||
* ----------
|
||||
*/
|
||||
if (num->varlen != NUMERIC_HDRSZ)
|
||||
{
|
||||
/* Else, flip the sign */
|
||||
if (NUMERIC_SIGN(num) == NUMERIC_POS)
|
||||
res->n_sign_dscale = NUMERIC_NEG | NUMERIC_DSCALE(num);
|
||||
else
|
||||
res->n_sign_dscale = NUMERIC_POS | NUMERIC_DSCALE(num);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
Numeric
|
||||
numeric_sign(Numeric num)
|
||||
{
|
||||
@ -1465,7 +1510,7 @@ numeric_ln(Numeric num)
|
||||
|
||||
|
||||
/* ----------
|
||||
* numeric_ln() -
|
||||
* numeric_log() -
|
||||
*
|
||||
* Compute the logarithm of x in a given base
|
||||
* ----------
|
||||
@ -1596,6 +1641,8 @@ numeric_power(Numeric num1, Numeric num2)
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
Numeric
|
||||
int4_numeric(int32 val)
|
||||
{
|
||||
@ -1627,7 +1674,7 @@ numeric_int4(Numeric num)
|
||||
return 0;
|
||||
|
||||
if (NUMERIC_IS_NAN(num))
|
||||
return 0;
|
||||
elog(ERROR, "Cannot convert NaN to int4");
|
||||
|
||||
/* ----------
|
||||
* Get the number in the variable format so we can round to integer.
|
||||
@ -1647,6 +1694,108 @@ numeric_int4(Numeric num)
|
||||
}
|
||||
|
||||
|
||||
Numeric
|
||||
int8_numeric(int64 *val)
|
||||
{
|
||||
Numeric res;
|
||||
NumericVar result;
|
||||
char *tmp;
|
||||
|
||||
init_var(&result);
|
||||
|
||||
tmp = int8out(val);
|
||||
set_var_from_str(tmp, &result);
|
||||
res = make_result(&result);
|
||||
|
||||
free_var(&result);
|
||||
pfree(tmp);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
int64 *
|
||||
numeric_int8(Numeric num)
|
||||
{
|
||||
NumericVar x;
|
||||
char *str;
|
||||
int64 *result;
|
||||
|
||||
if (num == NULL)
|
||||
return NULL;
|
||||
|
||||
if (NUMERIC_IS_NAN(num))
|
||||
elog(ERROR, "Cannot convert NaN to int8");
|
||||
|
||||
/* ----------
|
||||
* Get the number in the variable format so we can round to integer.
|
||||
* ----------
|
||||
*/
|
||||
init_var(&x);
|
||||
set_var_from_num(num, &x);
|
||||
|
||||
str = get_str_from_var(&x, 0); /* dscale = 0 produces rounding */
|
||||
|
||||
free_var(&x);
|
||||
|
||||
result = int8in(str);
|
||||
pfree(str);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Numeric
|
||||
int2_numeric(int16 val)
|
||||
{
|
||||
Numeric res;
|
||||
NumericVar result;
|
||||
char *tmp;
|
||||
|
||||
init_var(&result);
|
||||
|
||||
tmp = int2out(val);
|
||||
set_var_from_str(tmp, &result);
|
||||
res = make_result(&result);
|
||||
|
||||
free_var(&result);
|
||||
pfree(tmp);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
int16
|
||||
numeric_int2(Numeric num)
|
||||
{
|
||||
NumericVar x;
|
||||
char *str;
|
||||
int16 result;
|
||||
|
||||
if (num == NULL)
|
||||
return 0;
|
||||
|
||||
if (NUMERIC_IS_NAN(num))
|
||||
elog(ERROR, "Cannot convert NaN to int2");
|
||||
|
||||
/* ----------
|
||||
* Get the number in the variable format so we can round to integer.
|
||||
* ----------
|
||||
*/
|
||||
init_var(&x);
|
||||
set_var_from_num(num, &x);
|
||||
|
||||
str = get_str_from_var(&x, 0); /* dscale = 0 produces rounding */
|
||||
|
||||
free_var(&x);
|
||||
|
||||
result = int2in(str);
|
||||
pfree(str);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Numeric
|
||||
float8_numeric(float64 val)
|
||||
{
|
||||
|
Reference in New Issue
Block a user