Thread: SRF written in C

SRF written in C

From
Felipe de Jesús Molina Bravo
Date:
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

Re: SRF written in C

From
Martijn van Oosterhout
Date:
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.

Attachment

Re: SRF written in C

From
Felipe de Jesús Molina Bravo
Date:
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

Re: SRF written in C

From
Alvaro Herrera
Date:
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

Re: SRF written in C

From
Felipe de Jesús Molina Bravo
Date:

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 );
        }