Обсуждение: manipulating NUMERIC values in C extension

Поиск
Список
Период
Сортировка

manipulating NUMERIC values in C extension

От
Geoff Winkless
Дата:
Hi

I'd like to be able to perform some manipulation on NUMERIC values in
a C function; however the exposed functionality in numeric.h is pretty
restrictive.

I can see numeric_normalize will return a pointer to a string
representation, which is workable, and if there were an equivalent
string-to-numeric function that would be enough (although not the most
efficient) but I can't see a way to get a string back in to a numeric
value to return.

numeric_in looks like it might do what I want but to do that I would
have to build a FunctionCallInfo struct to do that, and I'm not 100%
clear how to do that either :(

I _could_ return the result as a varchar and cast it back to numeric
in the SQL, but that's not very clean.

Accessing the numeric structure directly would work too but I'm
assuming that's not recommended since it's not exposed in numeric.h.

Any thoughts would be appreciated,

Geoff


Re: manipulating NUMERIC values in C extension

От
John McKown
Дата:
On Fri, Jun 8, 2018 at 7:27 AM Geoff Winkless <pgsqladmin@geoff.dj> wrote:
Hi

I'd like to be able to perform some manipulation on NUMERIC values in
a C function; however the exposed functionality in numeric.h is pretty
restrictive.

I can see numeric_normalize will return a pointer to a string
representation, which is workable, and if there were an equivalent
string-to-numeric function that would be enough (although not the most
efficient) but I can't see a way to get a string back in to a numeric
value to return.

numeric_in looks like it might do what I want but to do that I would
have to build a FunctionCallInfo struct to do that, and I'm not 100%
clear how to do that either :(

I _could_ return the result as a varchar and cast it back to numeric
in the SQL, but that's not very clean.

Accessing the numeric structure directly would work too but I'm
assuming that's not recommended since it's not exposed in numeric.h.

Any thoughts would be appreciated,

Have you considered the standard C library functions: "atoi()", "atof()", "atol()", and "atoll()" ?

 

Geoff



--
Rap music is performed by those that can not sing so others can not think.

Maranatha! <><
John McKown

Re: manipulating NUMERIC values in C extension

От
Geoff Winkless
Дата:
On Fri, 8 Jun 2018 at 13:27, Geoff Winkless <pgsqladmin@geoff.dj> wrote:
> numeric_in looks like it might do what I want but to do that I would
> have to build a FunctionCallInfo struct to do that, and I'm not 100%
> clear how to do that either :(

Answering my own question, looks like

  res = DatumGetNumeric(DirectFunctionCall3(numeric_in,
CStringGetDatum(buf), 0, -1));

should do it, judging from
https://api.pgxn.org/src/orafce/orafce-3.6.1/convert.c

Geoff


Re: manipulating NUMERIC values in C extension

От
Geoff Winkless
Дата:
On Fri, 8 Jun 2018 at 13:47, Geoff Winkless <pgsqladmin@geoff.dj> wrote:
> Answering my own question, looks like

And just in case anyone googling the question comes across this, this
example code works.

#include "postgres.h"
#include <string.h>
#include "fmgr.h"
#include "utils/geo_decls.h"
#include "funcapi.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/numeric.h"
#include "catalog/pg_type.h"

PG_MODULE_MAGIC;
PG_FUNCTION_INFO_V1(pgnumeric_x10);

Datum
pgnumeric_x10(PG_FUNCTION_ARGS) {
  Numeric v;
  char *r;
  char mybuff[1000];
  double f;
  v=PG_GETARG_NUMERIC(0);
  r=numeric_normalize(v);
  f=atof(r)*10;
  sprintf(mybuff, "%f", f);
  v = DatumGetNumeric(DirectFunctionCall3(numeric_in,
CStringGetDatum(mybuff), 0, -1));
  pfree(r);
  PG_RETURN_NUMERIC(v);
}

Example of it running:

=# CREATE OR REPLACE FUNCTION pgnumeric_x10(NUMERIC) RETURNS NUMERIC
AS 'testpgnumchange.so', 'pgnumeric_x10' LANGUAGE C STRICT IMMUTABLE;
CREATE FUNCTION
Time: 0.811 ms
=# select pgnumeric_x10(132387.4823487::NUMERIC);
 pgnumeric_x10
----------------
 1323874.823487
(1 row)

Time: 0.593 ms
=#

For obvious reasons I wouldn't suggest using atof on a numeric, we
have our own functions for manipulating _Decimal128 which is what I'll
actually be using in the end version, but this is easier to compile as
an example :)

Geoff


Re: manipulating NUMERIC values in C extension

От
Geoff Winkless
Дата:
On Fri, 8 Jun 2018 at 13:44, John McKown <john.archie.mckown@gmail.com> wrote:
> Have you considered the standard C library functions: "atoi()", "atof()", "atol()", and "atoll()" ?

Hi John

My issue wasn't so much how to get a number out of the string, rather
how to get that value back into a NUMERIC object to return back to the
server.

Thanks for taking the time to reply though, it's appreciated.

Geoff