Re: Fallo Initdb (Era: Sumar TIMESTAMP + TIME en el Source Code)

From: Luis D(dot) García <ldgarc(at)gmail(dot)com>
To: "Alvaro Herrera" <alvherre(at)commandprompt(dot)com>
Cc: pgsql-es-ayuda(at)postgresql(dot)org
Subject: Re: Fallo Initdb (Era: Sumar TIMESTAMP + TIME en el Source Code)
Date: 2007-09-04 01:16:02
Message-ID: 3de424340709031816v6c89a739s25f18a0f58a3520b@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

Hola Alvaro primero que nada disculpa que responda tan tarde pero he tenido
algunos
problemas con la conexión a internet en mi casa y no había podido entrar al
correo para
responder tu mail.

Ahh ya se lo que estas haciendo -- estas copiando el truco en
> pg_authid.h. Lo siento, no puedes hacer eso porque como ahi se
> especifica, en ese catalogo es posible que esa columna sea NULL, lo cual
> te permite algunas libertadas; pero aca no puedes hacer eso.

En efecto es eso lo que he estado tratando de hacer pues justamente en el
pg_authid
es el único lugar del catálogo donde utilizan un Timestamp.

Lo siento mucho, es mas dificil de lo que esperabas, pero estas en
> territorio sin cartografiar. Buena suerte. El proyecto en GSoC que
> estoy apadrinando esta en tu mismo problema, quizas puedan compartir la
> experiencia.

Resolví el problema que tenía con el Initdb, pero lamentablemente no pude
llegar
a almacenar los datos que tenia como Timestamp e Interval, tuve que seguir
haciéndolo
por medio del tipo de dato Namedata para que no me diese problemas.

Ahora, ya pude resolver el problema que tenía desde hace tiempo para poder
realizar
las operaciones con los Timestamp e Intervals respectivos. Lo que hice fue
almacenar
los valores en strings (char *) y los almacene en nodos de tipo Value. Una
vez que almacené
los valores en dichas estructuras modifiqué las funciones a partir de las
cuales obtenía
los timestamps e intervals que tenía en el pg_class, de manera que la
función donde hago
los cálculos quedara de la siguiente manera (coloco en negritas lo que
pienso te interesaría
ver):

/* ---------
* --MODIFIED: ldgarcia - [29/08] - Evaluates valid time values
corresponding to defined relfrequency
* ---------
*
*/
static char *Valid_Time_and_Frequency_Validation( Oid relationId, int
reltuples, int vttype, TSQLInsertStmt *tsql)
{

ResTarget *init = makeNode (ResTarget);
ResTarget *final = makeNode (ResTarget);
Datum new_valid_time;
A_Const *n_i = makeNode (A_Const);
A_Const *n_f = makeNode (A_Const);
char *i_valid_time = NULL;
char *f_valid_time = NULL;
Value *new_val = makeNode(Value);

init = (ResTarget *) tsql->initialEvent;
n_i = (A_Const *) init->val;
i_valid_time = n_i->val.val.str;

new_val->type = T_String;
new_val->val.str = i_valid_time;
new_valid_time = DirectFunctionCall3(timestamp_in,
CStringGetDatum(strVal(new_val)),
ObjectIdGetDatum(InvalidOid),
Int32GetDatum(-1));

if (reltuples > 0)
{
Datum freq;
Datum last_valid_time;
Datum result;
Value *timestamp_val = makeNode(Value);
Value *frequency_val = makeNode(Value);

frequency_val->type = T_String;
frequency_val->val.str = strVal(
get_rel_frequency_measure(relationId));

freq = DirectFunctionCall3(interval_in,
CStringGetDatum(strVal(frequency_val)),
ObjectIdGetDatum(InvalidOid),
Int32GetDatum(-1));

timestamp_val->type = T_String;
timestamp_val->val.str =
strVal(get_rel_last_valid_time(relationId));

last_valid_time = DirectFunctionCall3(timestamp_in,
CStringGetDatum(strVal(timestamp_val)),
ObjectIdGetDatum(InvalidOid),
Int32GetDatum(-1));

result = DirectFunctionCall2( timestamp_pl_interval,
last_valid_time,
freq);

if ( DatumGetTimestamp(result) != DatumGetTimestamp(new_valid_time)
)

ereport(ERROR,(errcode(ERRCODE_TSQL3_INVALID_DEFINITION),errmsg("\"Valid
Time\" defined for this data doesn't respect the frequency stored for this
table")));

if (vttype==2)
{
Datum final_valid_time;
Datum final_result;
Value *final_val = makeNode(Value);

final = (ResTarget *) tsql->finalEvent;
n_f = (A_Const *) final->val;
f_valid_time = n_f->val.val.str;

final_val->type = T_String;
final_val->val.str = f_valid_time;

final_valid_time = DirectFunctionCall3(timestamp_in,
CStringGetDatum(strVal(final_val)),
ObjectIdGetDatum(InvalidOid),
Int32GetDatum(-1));

final_result = DirectFunctionCall2( timestamp_pl_interval,
result,
freq);

if ( DatumGetTimestamp(final_result) !=
DatumGetTimestamp(final_valid_time) )

ereport(ERROR,(errcode(ERRCODE_TSQL3_INVALID_DEFINITION),errmsg("\"Final
Valid Time\" defined for this state data doesn't respect the frequency
stored for this table")));

}

}

if ( (reltuples<=0) && (vttype==2) )
{
Datum final_valid_time;
Datum freq;
Datum last_valid_time;
Datum result;
Value *final_val = makeNode(Value);
Value *timestamp_val = makeNode(Value);
Value *frequency_val = makeNode(Value);

frequency_val->type = T_String;
frequency_val->val.str =
strVal(get_rel_frequency_measure(relationId));

freq = DirectFunctionCall3(interval_in,
CStringGetDatum(strVal(frequency_val)),
ObjectIdGetDatum(InvalidOid),
Int32GetDatum(-1));

timestamp_val->type = T_String;
timestamp_val->val.str = i_valid_time;

last_valid_time = DirectFunctionCall3(timestamp_in,
CStringGetDatum(strVal(timestamp_val)),
ObjectIdGetDatum(InvalidOid),
Int32GetDatum(-1));

result = DirectFunctionCall2( timestamp_pl_interval,
last_valid_time,
freq);

final = (ResTarget *) tsql->finalEvent;
n_f = (A_Const *) final->val;
f_valid_time = n_f->val.val.str;

final_val->type = T_String;
final_val->val.str = f_valid_time;

final_valid_time = DirectFunctionCall3(timestamp_in,
CStringGetDatum(strVal(final_val)),
ObjectIdGetDatum(InvalidOid),
Int32GetDatum(-1));

if ( DatumGetTimestamp(result) !=
DatumGetTimestamp(final_valid_time) )

ereport(ERROR,(errcode(ERRCODE_TSQL3_INVALID_DEFINITION),errmsg("\"Final
Valid Time\" defined for this state data doesn't respect the frequency
stored for this table")));

}

return ( DatumGetCString( DirectFunctionCall1( timestamp_out,
new_valid_time ) ) );

}

En realidad no sé si en tu caso te podrá servir, pero al menos en el mío fue
lo que me
funcionó de acuerdo a lo que necesitaba y como tengo muy poco tiempo para
terminar
con la codificación de mi tesis prefiero seguir de esta manera, al menos
hasta que tenga
tiempo para depurar todos los cambios que he hecho.

Si necesitas que explique un poco más el código de arriba avísame, aunque en
grandes
rasgos lo que hago es comparar un Timestamp dado en un InsertStmt con el
resultado
de una suma del último Timestamp que se almacenó en la tabla Foo y la
frecuencia de
tiempo según el cual se almacenarán los datos en esa tabla, y si esto
coincide entonces
almaceno ese dato. En código a alto nivel sería algo como:

if ( timestamp_tupla_entrante == (ult_timestamp_almacenado_en_foo +
frec_tiempo_definida_sobre_foo) )
almacenar_tupla_entrante( )
else
rechazar_tupla_entrante( )

De igual forma te agradezco la ayuda que me has dado y espero consigan un
buen
resultado en el proyecto que lideras.

Saludos.

PD: tengo algunas consultas adicionales en las que pienso podrías ayudarme,
pero
las colocaré en otro thread pues ya se tratan del SELECT como tal.

--
Luis D. García M.

Telf: (+58) 2418662663
Cel.: (+58) 4143482018

- FACYT - UC -
- Computación -

In response to

Responses

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Diana Marcela P 2007-09-04 02:11:28 backup pg_dump y pg_restore
Previous Message pablo 2007-09-04 00:52:44 Re: cargar miles de registros en forma recurrente