From: | Ben Ali Rachid <souliman239(at)yahoo(dot)fr> |
---|---|
To: | tgl(at)sss(dot)pgh(dot)pa(dot)us |
Cc: | craig(at)postnewspapers(dot)com(dot)au, pgsql-general(at)postgresql(dot)org |
Subject: | Re: Srf function : missing library on PostgreSQL 8.3.6 on Windows? |
Date: | 2009-03-22 17:52:25 |
Message-ID: | 659064.79401.qm@web28514.mail.ukl.yahoo.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-general |
Tom Lane wrote :
> PG_FUNCTION_INFO_V1() generates a function that has to have "C" linkage.
> So does PG_MODULE_MAGIC. I'm actually not sure how you got the module
> to load at all with the latter point ...
Sorry, I forgot this in my previous post :
#ifdef __cplusplus
extern "C" {
#endif
--
#ifdef __cplusplus
}
#endif
I also forgot the definition of the function 'get_normal_pair'. So my (correct) cpp file is like below :
#include "dll.h"
#ifdef __cplusplus
extern "C" {
#endif
PG_MODULE_MAGIC;
void get_normal_pair(float8 *x1, float8 *x2);
void get_normal_pair(float8 *x1, float8 *x2)
{
float8 u1,
u2,
v1,
v2,
s;
do
{
u1 = (float8) rand() / (float8) MAX_RANDOM_VALUE;
u2 = (float8) rand() / (float8) MAX_RANDOM_VALUE;
v1 = (2.0 * u1) - 1.0;
v2 = (2.0 * u2) - 1.0;
s = v1 * v1 + v2 * v2;
}
while (s >= 1.0);
if (s == 0)
{
*x1 = 0;
*x2 = 0;
}
else
{
s = sqrt((-2.0 * log(s)) / s);
*x1 = v1 * s;
*x2 = v2 * s;
}
}
typedef struct
{
float8 mean; /* mean of the distribution */
float8 stddev; /* stddev of the distribution */
float8 carry_val; /* hold second generated value */
bool use_carry; /* use second generated value */
} normal_rand_fctx;
PG_FUNCTION_INFO_V1(normal_rand);
Datum normal_rand(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
int call_cntr;
int max_calls;
normal_rand_fctx *fctx;
float8 mean;
float8 stddev;
float8 carry_val;
bool use_carry;
MemoryContext oldcontext;
/* stuff done only on the first call of the function */
if (SRF_IS_FIRSTCALL())
{
/* create a function context for cross-call persistence */
funcctx = SRF_FIRSTCALL_INIT();
/* switch to memory context appropriate for multiple function calls. */
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
/* total number of tuples to be returned */
funcctx->max_calls = PG_GETARG_UINT32(0);
/* allocate memory for user context */
fctx = (normal_rand_fctx *) palloc(sizeof(normal_rand_fctx));
/*
* Use fctx to keep track of upper and lower bounds from call to call.
* It will also be used to carry over the spare value we get from the
* Box-Muller algorithm so that we only actually calculate a new value
* every other call.
*/
fctx->mean = PG_GETARG_FLOAT8(1);
fctx->stddev = PG_GETARG_FLOAT8(2);
fctx->carry_val = 0;
fctx->use_carry = false;
funcctx->user_fctx = fctx;
MemoryContextSwitchTo(oldcontext);
}
/* stuff done on every call of the function */
funcctx = SRF_PERCALL_SETUP();
call_cntr = funcctx->call_cntr;
max_calls = funcctx->max_calls;
fctx = (normal_rand_fctx*) funcctx->user_fctx;
mean = fctx->mean;
stddev = fctx->stddev;
carry_val = fctx->carry_val;
use_carry = fctx->use_carry;
if (call_cntr < max_calls) /* do when there is more left to send */
{
float8 result;
if (use_carry)
{
/* reset use_carry and use second value obtained on last pass */
fctx->use_carry = false;
result = carry_val;
}
else
{
float8 normval_1;
float8 normval_2;
/* Get the next two normal values */
get_normal_pair(&normval_1, &normval_2);
/* use the first */
result = mean + (stddev * normval_1);
/* and save the second */
fctx->carry_val = mean + (stddev * normval_2);
fctx->use_carry = true;
}
/* send the result */
SRF_RETURN_NEXT(funcctx, Float8GetDatum(result));
}
else
/* do when there is no more left */
SRF_RETURN_DONE(funcctx);
}
#ifdef __cplusplus
}
#endif
I have no problem when I load the DLL (no 'missing magic block' error). The server crashes when I try : SELECT normal_rand(5, 10.0, 20.0) or SELECT * FROM normal_rand(5, 10.0, 20.0).
--
Ben Ali Rachid
From | Date | Subject | |
---|---|---|---|
Next Message | Oliver Weichhold | 2009-03-22 19:05:19 | Understanding Execution Plans |
Previous Message | RebeccaJ | 2009-03-22 17:36:37 | Re: text column constraint, newbie question |