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