Обсуждение: SRF written in C
Hi
what can i do for a SRF written in C, can called as follow:
select * from obtAscendencia('(11099,15685)','(6808,9621)');
I can call the function:
select obtAscendencia('(11099,15685)','(6808,9621)');
the code of function is:
PG_FUNCTION_INFO_V1(obtAscendencia);
Datum
obtAscendencia(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
intervaloFarey *intF; //intervalo de Farey que
subexiste durente
//la gneracion de lo jerarquia
Racional *r = NULL;//el resultado de obtPadre
Racional *pi; //padre inicial
/* stuff done only on the first call of the function */
if (SRF_IS_FIRSTCALL())
{
MemoryContext oldcontext;
/* create a function context for cross-call persistence
*/
funcctx = SRF_FIRSTCALL_INIT();
intF = (intervaloFarey *)
palloc(sizeof(intervaloFarey));
pi = (Racional *) PG_GETARG_POINTER(0);
intF->izq.num = pi->num;
intF->izq.den = pi->den;
pi = (Racional *) PG_GETARG_POINTER(1);
intF->der.num = pi->num;
intF->der.den = pi->den;
//memeoria fija durante la generacion de la descendencia
directa
funcctx->user_fctx = intF;
oldcontext =
MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
MemoryContextSwitchTo(oldcontext);
}
/* stuff done on every call of the function */
funcctx = SRF_PERCALL_SETUP();
intF = funcctx->user_fctx;//fjmb
// attinmeta = funcctx->attinmeta;
r = obtPadre( &intF->izq, &intF->der );
elog(INFO, "obtAscendencia. retorno de obtPadre. izq : %d,%d
",r->num, r->den);
if ( ( r->num != 1 ) &&
( r->den != 2 ) )
{
char **strRel;
HeapTuple tuple;
//actualizamos la memoria fija durante
//el retorno de los nodos generado
//(ver documentacion de funciones SRF)
intF->der.num = intF->izq.num;
intF->der.den = intF->izq.den;
intF->izq.num = r->num;
intF->izq.den = r->den;
elog(INFO, "obtAscendencia. estructura quedo: %d,%d der:
%d,%d ",
intF->izq.num,
intF->izq.den,
intF->der.num,
intF->der.den
);
SRF_RETURN_NEXT(funcctx, (Datum)(r));
}
else /* do when there is no more left */
{
pfree(intF);
SRF_RETURN_DONE(funcctx);
}
}
definition:
CREATE OR REPLACE FUNCTION obtAscendencia(Racional, Racional)
RETURNS SETOF Racional
AS '/usr/lib/postgresql/farey', 'obtAscendencia'
LANGUAGE C VOLATILE STRICT;
In short, get the direct ancestors of a given node in a tree. This tree
is formed with nested interval and sequence farey. rest of code:
Datum obt_derecho(PG_FUNCTION_ARGS)
{
Racional *p_izq = (Racional *) PG_GETARG_POINTER(0);
Racional *n_izq = (Racional *) PG_GETARG_POINTER(1);
Racional *result = NULL;
result = (Racional *) palloc(sizeof(Racional));
result->num = n_izq->num - p_izq->num;
result->den = n_izq->den - p_izq->den;
PG_RETURN_POINTER(result);
}
Racional* obtPadre( Racional *li, Racional *ld){
Racional *lip;
Racional *tr = NULL; //ap temporal, para hacer el intercambio
bool cont;
int opAnt; //operacion anterior
lip = (Racional *) palloc(sizeof(Racional));
tr = (Racional *) palloc(sizeof(Racional));
cont = true;
opAnt = 0;
while( cont ){
if ( li->num > ld->num ){
//intercambiamos li <-> ld
SWAP_RACIONAL(li, ld );
cont = false;
}
lip->num = ld->num - li->num;
lip->den = ld->den - li->den;
if ( cont ){
while( cont ){
//recorremos
SWAP_RACIONAL(li, ld );
li->num = lip->num;
li->den = lip->den;
if ( li->num > ld->num ){ //si hay intercambio ...
continua en el ciclo
SWAP_RACIONAL(li, ld );
}else{ //si no hay intercambio
cont = false; //salimos del ciclo ....
}
//... pero antes de salir calculamos
lip->num = ld->num - li->num;
lip->den = ld->den - li->den;
}
}
}
return ( lip );
}
Definiton of "Racional" was gotten the manuals of postgres...
thanks in advance
On Tue, Jul 01, 2008 at 10:02:39AM -0500, Felipe de Jesús Molina Bravo wrote:
> Hi
>
> what can i do for a SRF written in C, can called as follow:
>
> select * from obtAscendencia('(11099,15685)','(6808,9621)');
>
> I can call the function:
> select obtAscendencia('(11099,15685)','(6808,9621)');
I'm afraid you did not explain what exactly the problem is. Do you mean
that one or the other of the statements doesn't work? Which one, and
what is the error message?
Have a nice day,
--
Martijn van Oosterhout <kleptog@svana.org> http://svana.org/kleptog/
> Please line up in a tree and maintain the heap invariant while
> boarding. Thank you for flying nlogn airlines.
Вложения
El mié, 02-07-2008 a las 08:02 +0200, Martijn van Oosterhout escribió:
> On Tue, Jul 01, 2008 at 10:02:39AM -0500, Felipe de Jesús Molina Bravo wrote:
> > Hi
> >
> > what can i do for a SRF written in C, can called as follow:
> >
> > select * from obtAscendencia('(11099,15685)','(6808,9621)');
> >
> > I can call the function:
> > select obtAscendencia('(11099,15685)','(6808,9621)');
>
> I'm afraid you did not explain what exactly the problem is. Do you mean
> that one or the other of the statements doesn't work? Which one, and
> what is the error message?
>
> Have a nice day,
ok... sorry
the next statement:
select * from obtAscendencia('(11099,15685)','(6808,9621)');
never end .... i need to kill the process assigned for my statement...
and the other statement:
select obtAscendencia('(11099,15685)','(6808,9621)');
is correct ... the output is:
obtascendencia
----------------
(4291, 6064)
(1774, 2507)
(1031, 1457)
(288, 407)
(121, 171)
(75, 106)
(29, 41)
(12, 17)
(7, 10)
(2, 3)
(10 filas)
and my question is :
Why can not perform my function as the first statement?
I suspect that my error is:
r = obtPadre( &intF->izq, &intF->der );
if ( ( r->num != 1 ) &&
( r->den != 2 ) )
{
intF->der.num = intF->izq.num;
intF->der.den = intF->izq.den;
intF->izq.num = r->num;
intF->izq.den = r->den;
SRF_RETURN_NEXT(funcctx, (Datum)(r));
}
Where "r" is type "Racional" (Rational)...
thanks in advance
see you
Felipe de Jesús Molina Bravo wrote: > I suspect that my error is: > > r = obtPadre( &intF->izq, &intF->der ); You didn't show obtPadre(). -- Alvaro Herrera http://www.CommandPrompt.com/ PostgreSQL Replication, Consulting, Custom Development, 24x7 support
El mié, 02-07-2008 a las 10:39 -0400, Alvaro Herrera escribió:
> Felipe de Jesús Molina Bravo wrote:
>
> > I suspect that my error is:
> >
> > r = obtPadre( &intF->izq, &intF->der );
>
> You didn't show obtPadre().
>
ok it is:
Racional* obtPadre( Racional *li, Racional *ld){
Racional *lip;
Racional *tr = NULL; //ap temporal, para hacer el intercambio
bool cont;
int opAnt; //operacion anterior
lip = (Racional *) palloc(sizeof(Racional));
tr = (Racional *) palloc(sizeof(Racional));
cont = true;
opAnt = 0;
while( cont ){
if ( li->num > ld->num ){
//intercambiamos li <-> ld
SWAP_RACIONAL(li, ld );
cont = false;
}
lip->num = ld->num - li->num;
lip->den = ld->den - li->den;
if ( cont ){
while( cont ){
//recorremos
SWAP_RACIONAL(li, ld );
li->num = lip->num;
li->den = lip->den;
if ( li->num > ld->num ){ //si hay intercambio ...
continua en el ciclo
SWAP_RACIONAL(li, ld );
}else{ //si no hay intercambio
cont = false; //salimos del ciclo ....
}
//... pero antes de salir calculamos
lip->num = ld->num - li->num;
lip->den = ld->den - li->den;
}
}
}
return ( lip );
}