El 11 de diciembre de 2008 10:51, Alvaro Herrera
<[EMAIL PROTECTED]>escribió:

> Felipe de Jesús Molina Bravo escribió:
>
> > entonces hago un REINDEX a la tabla:
> >
> > aeevrm=# REINDEX TABLE pt_j_producto ;
> >
> > y vuelvo a  ejecutar:
> >
> > aeevrm=# select * from pt_j_producto where izq='(426142, 541847)';
> >  idproducto |       izq        |       der        |      padre      |
> > idvarclase | idclase | idvariable | idvargeo | tiponodo | comportamiento
> > |     xml_reftemporal     | control | html
> >
> ------------+------------------+------------------+-----------------+------------+---------+------------+----------+----------+----------------+-------------------------+---------+------
> >       52844 | (426142, 541847) | (328605, 417827) | (97537, 124020)
> > |            |     517 |            |          | 4        |
>  |
> > <rts id="37" comp="0"/> | 1       |
> > (1 fila)
>
> Hmm.  ¿Qué versión de Postgres es esta?  ¿Puedes por favor mostrar el
> código de los números racionales?  Quizás haya algún bug en el algoritmo
> de inserción.


lo probe en 8.3.1 y 8.3.5 con los mismos resultados.... va el fuente de los
racionales (las funciones : obt_mcd y racional_obt_mitad fueron creadas por
mi):


#include "postgres.h"

#include "fmgr.h"
#include "libpq/pqformat.h"        /* needed for send/recv functions */
#include "executor/spi.h"

#include <racional.h>

PG_MODULE_MAGIC;

Datum        racional_in(PG_FUNCTION_ARGS);
Datum        racional_out(PG_FUNCTION_ARGS);
Datum        racional_text(PG_FUNCTION_ARGS);
Datum        racional_recv(PG_FUNCTION_ARGS);
Datum        racional_send(PG_FUNCTION_ARGS);
Datum        racional_add(PG_FUNCTION_ARGS);
Datum        racional_abs_lt(PG_FUNCTION_ARGS);
Datum        racional_abs_le(PG_FUNCTION_ARGS);
Datum        racional_abs_eq(PG_FUNCTION_ARGS);
Datum        racional_abs_ge(PG_FUNCTION_ARGS);
Datum        racional_abs_gt(PG_FUNCTION_ARGS);
Datum        racional_abs_cmp(PG_FUNCTION_ARGS);
Datum   racional_obt_mitad(PG_FUNCTION_ARGS);
int4    obt_mcd(Racional *);

PG_FUNCTION_INFO_V1(racional_in);

Datum
racional_in(PG_FUNCTION_ARGS)
{
    char       *str = PG_GETARG_CSTRING(0);
    int4         x, y;
    Racional   *result;
  int4     mcd; //maximo comun divisor

    if (sscanf(str, " ( %d , %d )", &x, &y) != 2)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                 errmsg("invalid input syntax for rational: \"%s\"",
                        str)));

    result = (Racional *) palloc(sizeof(Racional));
    result->num = x;
    result->den = y;
  mcd = obt_mcd( result );

  if ( mcd > 0){
       result->num = result->num / mcd;
       result->den = result->den / mcd;
  }
    PG_RETURN_POINTER(result);
}

PG_FUNCTION_INFO_V1(racional_out);

Datum
racional_out(PG_FUNCTION_ARGS)
{
    Racional    *racional = (Racional *) PG_GETARG_POINTER(0);
    char          *result;

    result = (char *) palloc(100);
    snprintf(result, 100, "(%d, %d)", racional->num, racional->den );
    PG_RETURN_CSTRING(result);
}


/**
 * Convierte de racional a text
 */
PG_FUNCTION_INFO_V1(racional_text);
Datum
racional_text(PG_FUNCTION_ARGS)
{
    Racional    *racional = (Racional *) PG_GETARG_POINTER(0);
    char          *result;
    char *pba = (char *) palloc(100);
  int tam = VARHDRSZ + 100;//sizeof(result);
  text *destino = (text *) palloc( tam );

    result = (char *) palloc(100);
    snprintf(result, 100, "(%d, %d)", racional->num, racional->den );


    snprintf(pba, 100, "(%d)", sizeof(result));
  memcpy(destino->vl_dat, result, tam);

//    PG_RETURN_CSTRING(result);
  PG_RETURN_TEXT_P(destino);
}



PG_FUNCTION_INFO_V1(racional_recv);

Datum
racional_recv(PG_FUNCTION_ARGS)
{
    StringInfo    buf = (StringInfo) PG_GETARG_POINTER(0);
    Racional    *result;

    result = (Racional *) palloc(sizeof(Racional));
    result->num = pq_getmsgint( buf, 4 );
    result->den = pq_getmsgint( buf, 4 );
    PG_RETURN_POINTER(result);
}

PG_FUNCTION_INFO_V1(racional_send);

Datum
racional_send(PG_FUNCTION_ARGS)
{
    Racional    *racional = (Racional *) PG_GETARG_POINTER(0);
    StringInfoData buf;

    pq_begintypsend(&buf);
    pq_sendint(&buf,4, racional->num);
    pq_sendint(&buf,4, racional->den);
    PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}

/*****************************************************************************

 * Funcion que reduce a su minima expresión un numero racional.
 *
 * Para hacer esto obtiene el maximo comun divisor
 *****************************************************************************/

int4
obt_mcd(Racional *x ){
   div_t resDiv;
   Racional resRac;

   if (x->num == 0)
      return x->den;

   if (x->den == 0)
      return x->den;

   if (x->num  > x->den){
      resDiv = div( x->num, x->den );
      resRac.num = resDiv.rem;
      resRac.den = x->den;
         //return obt_mcd( mod(a,b), b);
      return obt_mcd( &resRac );
   }
   else{
      resDiv =  div( x->den, x->num );
      resRac.num = x->num;
      resRac.den = resDiv.rem;
      return obt_mcd( &resRac );
   }
   return -1;
}
/*****************************************************************************

 * Funcion que obtiene la mitad de dos numeros racionales
 *
 *****************************************************************************/

PG_FUNCTION_INFO_V1(racional_obt_mitad);

Datum
racional_obt_mitad(PG_FUNCTION_ARGS)
{
    Racional    *a = (Racional *) PG_GETARG_POINTER(0);
    Racional    *b = (Racional *) PG_GETARG_POINTER(1);
    Racional    *result;

    result = (Racional *) palloc(sizeof(Racional));
    result->num = a->num + b->num;
    result->den = a->den + b->den;
    PG_RETURN_POINTER(result);
}


#define Comparar(x,y)    ((x)->num*(y)->den - (x)->den*(y)->num)

static int racional_abs_cmp_internal(Racional * a, Racional * b)
{
    double        amag = Comparar( a, b );

    if ( amag < 0 ) //a es menor que cero
        return -1;
    if ( amag > 0 ) //a es mayor que b
        return 1;
    return 0; //son iguales
}


PG_FUNCTION_INFO_V1(racional_abs_lt);

Datum
racional_abs_lt(PG_FUNCTION_ARGS)
{
    Racional    *a = (Racional *) PG_GETARG_POINTER(0);
    Racional    *b = (Racional *) PG_GETARG_POINTER(1);

    PG_RETURN_BOOL(racional_abs_cmp_internal(a, b) < 0);
}

PG_FUNCTION_INFO_V1(racional_abs_le);

Datum
racional_abs_le(PG_FUNCTION_ARGS)
{
    Racional    *a = (Racional *) PG_GETARG_POINTER(0);
    Racional    *b = (Racional *) PG_GETARG_POINTER(1);

    PG_RETURN_BOOL(racional_abs_cmp_internal(a, b) <= 0);
}

PG_FUNCTION_INFO_V1(racional_abs_eq);

Datum
racional_abs_eq(PG_FUNCTION_ARGS)
{
    Racional    *a = (Racional *) PG_GETARG_POINTER(0);
    Racional    *b = (Racional *) PG_GETARG_POINTER(1);

    PG_RETURN_BOOL(racional_abs_cmp_internal(a, b) == 0);
}

PG_FUNCTION_INFO_V1(racional_abs_ge);

Datum
racional_abs_ge(PG_FUNCTION_ARGS)
{
    Racional    *a = (Racional *) PG_GETARG_POINTER(0);
    Racional    *b = (Racional *) PG_GETARG_POINTER(1);

    PG_RETURN_BOOL(racional_abs_cmp_internal(a, b) >= 0);
}

PG_FUNCTION_INFO_V1(racional_abs_gt);

Datum
racional_abs_gt(PG_FUNCTION_ARGS)
{
    Racional    *a = (Racional *) PG_GETARG_POINTER(0);
    Racional    *b = (Racional *) PG_GETARG_POINTER(1);

    PG_RETURN_BOOL(racional_abs_cmp_internal(a, b) > 0);
}

PG_FUNCTION_INFO_V1(racional_abs_cmp);

Datum
racional_abs_cmp(PG_FUNCTION_ARGS)
{
    Racional    *a = (Racional *) PG_GETARG_POINTER(0);
    Racional    *b = (Racional *) PG_GETARG_POINTER(1);

    PG_RETURN_INT32(racional_abs_cmp_internal(a, b));
}








>
>
> --
> Alvaro Herrera
> http://www.amazon.com/gp/registry/CTMLCN8V17R4
> "La Primavera ha venido. Nadie sabe como ha sido" (A. Machado)
>

Responder a