Thread: sin() in PostgreSQL?
Is there a sin() function in PostgreSQL? I need to create a view in PostgreSQL that uses sin(x), and the only real mathematical functions I see supported are dexp() and dpow(). I tried using dexp(I) to get the exponential of an imaginary number (which would make writing sin() easy), but this didn't work, since dexp() expects a floating point argument. Is there an easy way to get sin()?
I tried the following, one at a time, to create sin() for PostgreSQL: CREATE FUNCTION sin(float8) RETURNS float8 AS '/usr/lib/libm.so' LANGUAGE 'c'; CREATE FUNCTION sin(float4) RETURNS float4 AS '/usr/lib/libm.so' LANGUAGE 'c'; CREATE FUNCTION sin(float4) RETURNS float8 AS '/usr/lib/libm.so' LANGUAGE 'c'; CREATE FUNCTION sin(float8) RETURNS float4 AS '/usr/lib/libm.so' LANGUAGE 'c'; Each of these gave different and odd results (and a 'segmentation fault' at one point), but none of them gave the right answer. What am I doing wrong?
On Mon, 31 Jan 2000 mathprof@bigfoot.com wrote: > I tried the following, one at a time, to create sin() for PostgreSQL: > > CREATE FUNCTION sin(float8) RETURNS float8 AS '/usr/lib/libm.so' LANGUAGE 'c'; > CREATE FUNCTION sin(float4) RETURNS float4 AS '/usr/lib/libm.so' LANGUAGE 'c'; > CREATE FUNCTION sin(float4) RETURNS float8 AS '/usr/lib/libm.so' LANGUAGE 'c'; > CREATE FUNCTION sin(float8) RETURNS float4 AS '/usr/lib/libm.so' LANGUAGE 'c'; > > Each of these gave different and odd results (and a 'segmentation fault' > at one point), but none of them gave the right answer. What am I doing > wrong? Yes, it is probably wrong. Very offen PG's buildin functions allocate memory for result and IMHO your trial wrong mixing pointers. See a backend/utils/atd in PG source as example. Karel
Karel Zak - Zakkr wrote: > > On Mon, 31 Jan 2000 mathprof@bigfoot.com wrote: > > > I tried the following, one at a time, to create sin() for PostgreSQL: > > > > CREATE FUNCTION sin(float8) RETURNS float8 AS '/usr/lib/libm.so' LANGUAGE 'c'; > > CREATE FUNCTION sin(float4) RETURNS float4 AS '/usr/lib/libm.so' LANGUAGE 'c'; > > CREATE FUNCTION sin(float4) RETURNS float8 AS '/usr/lib/libm.so' LANGUAGE 'c'; > > CREATE FUNCTION sin(float8) RETURNS float4 AS '/usr/lib/libm.so' LANGUAGE 'c'; > > > > Each of these gave different and odd results (and a 'segmentation fault' > > at one point), but none of them gave the right answer. What am I doing > > wrong? > > Yes, it is probably wrong. Very offen PG's buildin functions allocate memory > for result and IMHO your trial wrong mixing pointers. See a backend/utils/atd > in PG source as example. More specifically, only 1,2 and 4 byte integer values may be passed by call-by-value to userdefined C functions in PostgreSQL. That is, floats are passed by reference (pointers) while the math lib passes them by value - you have to write your own wrappers around the mathlib sin function. Sevo
Thanks! Based on this, I created a file called "test.c" as follows: #include <math.h> float pg_sin(float *x) {return(sin(*x));} and compiled it using: "gcc test.c -lm -shared" to create a shared object file. I then tried the same steps as below (substituting "/usr/lib/libm.so" with the path to my "a.out" file created by gcc), but this still didn't work? I'm getting different wrong values, but they're still wrong nonetheless? On Tue, 1 Feb 2000, Sevo Stille wrote: > Date: Tue, 01 Feb 2000 13:06:37 +0100 > From: Sevo Stille <sevo@ip23.net> > To: Karel Zak - Zakkr <zakkr@zf.jcu.cz> > Cc: mathprof@bigfoot.com, pgsql-general@postgreSQL.org > Subject: Re: [GENERAL] Linking in sin() as a C function > > Karel Zak - Zakkr wrote: > > > > On Mon, 31 Jan 2000 mathprof@bigfoot.com wrote: > > > > > I tried the following, one at a time, to create sin() for PostgreSQL: > > > > > > CREATE FUNCTION sin(float8) RETURNS float8 AS '/usr/lib/libm.so' LANGUAGE 'c'; > > > CREATE FUNCTION sin(float4) RETURNS float4 AS '/usr/lib/libm.so' LANGUAGE 'c'; > > > CREATE FUNCTION sin(float4) RETURNS float8 AS '/usr/lib/libm.so' LANGUAGE 'c'; > > > CREATE FUNCTION sin(float8) RETURNS float4 AS '/usr/lib/libm.so' LANGUAGE 'c'; > > > > > > Each of these gave different and odd results (and a 'segmentation fault' > > > at one point), but none of them gave the right answer. What am I doing > > > wrong? > > > > Yes, it is probably wrong. Very offen PG's buildin functions allocate memory > > for result and IMHO your trial wrong mixing pointers. See a backend/utils/atd > > in PG source as example. > > More specifically, only 1,2 and 4 byte integer values may be passed by > call-by-value to userdefined C functions in PostgreSQL. That is, floats > are passed by reference (pointers) while the math lib passes them by > value - you have to write your own wrappers around the mathlib sin > function. > > Sevo > > ************ >
mathprof@bigfoot.com wrote: > > Thanks! Based on this, I created a file called "test.c" as follows: > > #include <math.h> > float pg_sin(float *x) {return(sin(*x));} > > and compiled it using: "gcc test.c -lm -shared" to create a shared object > file. I then tried the same steps as below (substituting > "/usr/lib/libm.so" with the path to my "a.out" file created by gcc), but > this still didn't work? I'm getting different wrong values, but they're > still wrong nonetheless? The return has to be a pointer too. Try: #include <math.h> #include "postgres.h" #include "utils/palloc.h" float *pg_sin(float *x){ float *f = (float *)palloc(sizeof(float)); *f = sin(*x); return f; } Sevo -- Sevo Stille sevo@ip23.net