Re: funcion plpgsql .... corrupcion de indice

From: Felipe de Jesús Molina Bravo <fjmolinabravo(at)gmail(dot)com>
To: "Alvaro Herrera" <alvherre(at)alvh(dot)no-ip(dot)org>
Cc: pgsql-es-ayuda(at)postgresql(dot)org
Subject: Re: funcion plpgsql .... corrupcion de indice
Date: 2008-12-11 17:38:30
Message-ID: c31298e50812110938k778713c3iac385a37c2b5f966@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

El 11 de diciembre de 2008 10:51, Alvaro Herrera
<alvherre(at)alvh(dot)no-ip(dot)org>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)
>

In response to

Responses

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Jorge Diaz 2008-12-11 17:47:21 Fwd: Select desde ASP
Previous Message Felipe de Jesús Molina Bravo 2008-12-11 17:28:53 Re: funcion plpgsql .... corrupcion de indice