Thread: Runtime accepting build discrepancies
Scenario: A user download a pre-built PostgreSQL 7.4.7 from somewhere and a pre-built pljava distro from gborg. He gets everything running but suddenly encounteres problems with the timetz type. PL/Java apparently return the time as zero. The problem is caused by the postgresql binary being built using --enable-integer-datetimes whereas the PL/Java binary is not. The dynamic loader doesn't detect this and I bet there's a ton of combinations that will link just fine but perhaps crash (badly) in runtime. I would like to detect discrepancies like this during runtime somehow. I feel that it's either that or stop providing pre-built binaries altogether. I realize that I can't be the only one with this problem. How is this normally handled? Regards, Thomas Hallgren
Thomas Hallgren <thhal@mailblocks.com> writes: > A user download a pre-built PostgreSQL 7.4.7 from somewhere and a > pre-built pljava distro from gborg. He gets everything running but > suddenly encounteres problems with the timetz type. PL/Java apparently > return the time as zero. The problem is caused by the postgresql binary > being built using --enable-integer-datetimes whereas the PL/Java binary > is not. Why is PL/Java dependent on the internal representation of any particular datatype? Seems like this is a symptom of bad PL design more than anything else. > The dynamic loader doesn't detect this and I bet there's a ton of > combinations that will link just fine but perhaps crash (badly) in > runtime. I would like to detect discrepancies like this during runtime > somehow. I feel that it's either that or stop providing pre-built > binaries altogether. I realize that I can't be the only one with this > problem. How is this normally handled? If you want you can look into pg_control to see how the database is set up. regards, tom lane
Tom Lane wrote: >Why is PL/Java dependent on the internal representation of any >particular datatype? Seems like this is a symptom of bad PL design >more than anything else. > > I didn't see any other way of doing it short of using string conversions. That doesn't seem very optimal. Java's internal representation of time is millisecs so I have code in place that looks like this (t in this case is a TimeADT): #ifdef HAVE_INT64_Time mSecs = t / 1000; /* Convert to millisecs */ if(tzAdjust) mSecs += Timestamp_getCurrentTimeZone()* 1000;/* Adjust from local time to UTC */ #else if(tzAdjust) t += Timestamp_getCurrentTimeZone();/* Adjust from local time to UTC */ t *= 1000.0; /* Convert to millisecs */ mSecs = (jlong)floor(t); #endif I'm of course interested in improving it. Especially if you consider this bad PL design. What do you suggest I do instead? >>The dynamic loader doesn't detect this and I bet there's a ton of >>combinations that will link just fine but perhaps crash (badly) in >>runtime. I would like to detect discrepancies like this during runtime >>somehow. I feel that it's either that or stop providing pre-built >>binaries altogether. I realize that I can't be the only one with this >>problem. How is this normally handled? >> >> > >If you want you can look into pg_control to see how the database is >set up. > > That would cover this. Thanks (I'd still appreciate an alternative suggestion on the above though). Regards, Thomas Hallgren
Thomas, I worked on this and created some interface for decoupling java datatypes and their representations. In my implementation the mapping is N:N, so it is not directly applicable to your schema, but perhaps you can use some piece of it. I am not ready with all default data types, but the most important types are ready. http://cvs.plj.codehaus.org/pl-j/src/interfaces/org/pgj/typemapping/ Also, on stored procedure javadoc tags, could you take a look at this link: http://docs.codehaus.org/display/PLJ/Developer+tools I am really interersted in your opinion. Ragards, Laszlo On Thu, 10 Mar 2005, Thomas Hallgren wrote: > Tom Lane wrote: > > >Why is PL/Java dependent on the internal representation of any > >particular datatype? Seems like this is a symptom of bad PL design > >more than anything else. > > > > > I didn't see any other way of doing it short of using string > conversions. That doesn't seem very optimal. Java's internal > representation of time is millisecs so I have code in place that looks > like this (t in this case is a TimeADT): > > #ifdef HAVE_INT64_Time > mSecs = t / 1000; /* Convert to millisecs */ > if(tzAdjust) > mSecs += Timestamp_getCurrentTimeZone() * 1000;/* Adjust from > local time to UTC */ > #else > if(tzAdjust) > t += Timestamp_getCurrentTimeZone();/* Adjust from local time to > UTC */ > t *= 1000.0; /* Convert to millisecs */ > mSecs = (jlong)floor(t); > #endif > > I'm of course interested in improving it. Especially if you consider > this bad PL design. What do you suggest I do instead? > > >>The dynamic loader doesn't detect this and I bet there's a ton of > >>combinations that will link just fine but perhaps crash (badly) in > >>runtime. I would like to detect discrepancies like this during runtime > >>somehow. I feel that it's either that or stop providing pre-built > >>binaries altogether. I realize that I can't be the only one with this > >>problem. How is this normally handled? > >> > >> > > > >If you want you can look into pg_control to see how the database is > >set up. > > > > > That would cover this. Thanks (I'd still appreciate an alternative > suggestion on the above though). > > Regards, > Thomas Hallgren > > > ---------------------------(end of broadcast)--------------------------- > TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org >
Laszlo, > I worked on this and created some interface for decoupling java datatypes > and their representations. In my implementation the mapping is N:N, so it > is not directly applicable to your schema, but perhaps you can use some > piece of it. > I am not ready with all default data types, but the most important types > are ready. > http://cvs.plj.codehaus.org/pl-j/src/interfaces/org/pgj/typemapping/ > I can't find anything in your typemapping package that would solve this problem. I'm faced with coercing Datum instances returned by SPI_getbinval in the server into their Java correspondance where the binary representation will vary depending on how PostgreSQL is compiled. Let's assume I have a TIMETZOID as the type. I must then use the following calls to get the time. TimeTzADT* tza = DatumGetTimeTzADTP(arg); TimeADT t = tza->time + tza->zone; /* Convert to UTC */ The catch is that depending on the setting of macro HAVE_INT64_TIMESTAMP the TimeADT will be a typedef for either an int64 or a double. In case of int64 the representation is in microsecs but if it's a double the value is seconds (with fractions of course). If PL/Java is compiled with a different setting of this macro, it will think a double representing seconds is an int64 containing millisecs or vice versa. The solution is probably to make PL/Java insensitive to this macro and instead consult the GUC variable "integer_datetimes" and use my own variations of TimeTzADT and TimeADT. How do PL/J address this problem? - thomas
Thomas Hallgren wrote: > Laszlo, > >> I worked on this and created some interface for decoupling java >> datatypes >> and their representations. In my implementation the mapping is N:N, >> so it >> is not directly applicable to your schema, but perhaps you can use some >> piece of it. >> I am not ready with all default data types, but the most important types >> are ready. >> http://cvs.plj.codehaus.org/pl-j/src/interfaces/org/pgj/typemapping/ >> > I can't find anything in your typemapping package that would solve > this problem. I'm faced with coercing Datum instances returned by > SPI_getbinval in the server into their Java correspondance where the > binary representation will vary depending on how PostgreSQL is compiled. IMHO this is why decoupling is good and neccesary. If one configures the RDBMS to use different another of data, then I simply replace a couple of lines in the data mapping configuration. In the case of custom datatypes in PostgreSQL, the same happens. This is no code modification nor recomplitation in PL-J, only a reconfiguration. This is why I have sent that link, but this configuration file fragment may explain it better: <typemapper> <map> <type db="timestamp" class="org.pgj.typemapping.postgres.PGTimestamp"/> <!-- type db="timestamp" class="org.pgj.typemapping.postgres.PGTimestampINT64"/ --> > > Let's assume I have a TIMETZOID as the type. I must then use the > following calls to get the time. > > TimeTzADT* tza = DatumGetTimeTzADTP(arg); > TimeADT t = tza->time + tza->zone; /* Convert to UTC */ > > The catch is that depending on the setting of macro > HAVE_INT64_TIMESTAMP the TimeADT will be a typedef for either an int64 > or a double. In case of int64 the representation is in microsecs but > if it's a double the value is seconds (with fractions of course). > > If PL/Java is compiled with a different setting of this macro, it will > think a double representing seconds is an int64 containing millisecs > or vice versa. The solution is probably to make PL/Java insensitive to > this macro and instead consult the GUC variable "integer_datetimes" > and use my own variations of TimeTzADT and TimeADT. > > How do PL/J address this problem? > > - thomas > > > ---------------------------(end of broadcast)--------------------------- > TIP 7: don't forget to increase your free space map settings -- Regards, László Hornyák software developer
Attachment
Laszlo Hornyak wrote: > IMHO this is why decoupling is good and neccesary. If one configures > the RDBMS to use different another of data, then I simply replace a > couple of lines in the data mapping configuration. In the case of > custom datatypes in PostgreSQL, the same happens. This is no code > modification nor recomplitation in PL-J, only a reconfiguration. > This is why I have sent that link, but this configuration file > fragment may explain it better: > <typemapper> > <map> > <type db="timestamp" > class="org.pgj.typemapping.postgres.PGTimestamp"/> > <!-- type db="timestamp" > class="org.pgj.typemapping.postgres.PGTimestampINT64"/ --> Sure Laszlo. That solves everything. But where do you get the information on what to comment out and what to use in the first place? Regards, Thomas Hallgren
The default should be the default used by PostgreSQL, and the extra ones should be commented out under it. Not the most user friendly solution, but can we do anything else? Laszlo On Fri, 11 Mar 2005, Thomas Hallgren wrote: > Laszlo Hornyak wrote: > > > IMHO this is why decoupling is good and neccesary. If one configures > > the RDBMS to use different another of data, then I simply replace a > > couple of lines in the data mapping configuration. In the case of > > custom datatypes in PostgreSQL, the same happens. This is no code > > modification nor recomplitation in PL-J, only a reconfiguration. > > This is why I have sent that link, but this configuration file > > fragment may explain it better: > > <typemapper> > > <map> > > <type db="timestamp" > > class="org.pgj.typemapping.postgres.PGTimestamp"/> > > <!-- type db="timestamp" > > class="org.pgj.typemapping.postgres.PGTimestampINT64"/ --> > > Sure Laszlo. That solves everything. But where do you get the > information on what to comment out and what to use in the first place? > > Regards, > Thomas Hallgren >
Laszlo Hornyak wrote: >The default should be the default used by PostgreSQL, and the extra ones >should be commented out under it. >Not the most user friendly solution, but can we do anything else? > > Yes, we can do as I suggested and select mapping depending on the GUC variable "integer_datetimes". I guess you have some initial handshake between the postgresql backend and the JVM where you can negotiate things like that? Regards, Thomas Hallgren