numeric_var_test.c
text/x-csrc
#include "postgres.h"
#include "utils/numeric.h"
PG_MODULE_MAGIC;
PG_FUNCTION_INFO_V1(display_numeric);
Datum display_numeric(PG_FUNCTION_ARGS)
{
Numeric num = PG_GETARG_NUMERIC(0);
NumericVar arg;
init_var(&arg);
set_var_from_num(num, &arg);
ereport(NOTICE, errmsg("weight=%d", arg.weight));
ereport(NOTICE, errmsg("dscale=%d", arg.dscale));
switch(arg.sign)
{
case NUMERIC_POS:
ereport(NOTICE, errmsg("Pos"));
break;
case NUMERIC_NEG:
ereport(NOTICE, errmsg("Neg"));
break;
case NUMERIC_NAN:
ereport(NOTICE, errmsg("NaN"));
break;
case NUMERIC_PINF:
ereport(NOTICE, errmsg("+Inf"));
break;
case NUMERIC_NINF:
ereport(NOTICE, errmsg("-Inf"));
break;
default:
ereport(NOTICE, errmsg("SIGN=0x%x", arg.sign));
break;
}
for (int i = 0; i < arg.ndigits; i++)
ereport(NOTICE, errmsg(" %04d", arg.digits[i]));
free_var(&arg);
PG_RETURN_VOID();
}
PG_FUNCTION_INFO_V1(negate_numeric);
Datum negate_numeric(PG_FUNCTION_ARGS)
{
Numeric num = PG_GETARG_NUMERIC(0);
NumericVar arg;
init_var(&arg);
set_var_from_num(num, &arg);
NumericVar result;
init_var(&result);
alloc_var(&result, arg.ndigits);
switch(arg.sign)
{
case NUMERIC_POS:
result.sign = NUMERIC_NEG;
break;
case NUMERIC_NEG:
result.sign = NUMERIC_POS;
break;
case NUMERIC_NAN:
result.sign = NUMERIC_NAN;
break;
case NUMERIC_PINF:
result.sign = NUMERIC_NINF;
break;
case NUMERIC_NINF:
result.sign = NUMERIC_PINF;
break;
default:
ereport(ERROR, errmsg("Unknown sign"));
break;
}
if(result.sign == NUMERIC_POS || result.sign == NUMERIC_NEG)
{
result.weight = arg.weight;
result.dscale = arg.dscale;
for (int i = 0; i < arg.ndigits; i++)
result.digits[i] = arg.digits[i];
}
free_var(&arg);
PG_RETURN_NUMERIC(make_result(&result));
}