SRF written in C - Mailing list pgsql-general

From Felipe de Jesús Molina Bravo
Subject SRF written in C
Date
Msg-id 1214924559.4382.24.camel@fjmb
Whole thread Raw
Responses Re: SRF written in C
List pgsql-general
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

pgsql-general by date:

Previous
From: Tom Lane
Date:
Subject: Re: Problems with a C function, pg_uname(), and String concatenation.
Next
From: "Albe Laurenz"
Date:
Subject: Re: SAST FATAL: could not access private key file "server.key"