Re: Srf function : missing library on PostgreSQL 8.3.6 on Windows? - Mailing list pgsql-general
From | Ben Ali Rachid |
---|---|
Subject | Re: Srf function : missing library on PostgreSQL 8.3.6 on Windows? |
Date | |
Msg-id | 659064.79401.qm@web28514.mail.ukl.yahoo.com Whole thread Raw |
In response to | Srf function : missing library on PostgreSQL 8.3.6 on Windows? (Ben Ali Rachid <souliman239@yahoo.fr>) |
Responses |
Re: Srf function : missing library on PostgreSQL 8.3.6 on Windows?
|
List | 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 |
pgsql-general by date: