The byte order of the system where PostgreSQL is running is a detail mostly invisible in PL/Java, but there are two capabilities of PL/Java where it can matter:
Point
example illustrates a mirrored type. If PL/Java uses a different byte order than the underlying system, mirrored types will be visibly broken, having different values seen in PostgreSQL and in Java.ComplexScalar
example illustrates a PL/Java-defined base type. With a base type, differences between PL/Java byte order and that of the underlying system are less noticeable (because nothing but PL/Java ever touches the type’s representation). However, in a database with existing data stored as PL/Java base types, changing PL/Java’s byte order will render the data visibly bogus.In older PL/Java versions up to and including 1.5.0-BETA2
, byte order was always big-endian regardless of the underlying system. That means that on little-endian hardware (which is very common), PL/Java mirrored types will have been noticeably broken, and probably seldom used. Base types may have seen more use, and existing databases may have data stored in PL/Java base types using big-endian order.
Beginning with PL/Java 1.5.0, byte order is selectable, and has different defaults for base types and mirrored types. For base types, the default remains big-endian, to minimize disruption if a database has legacy data stored that way, and to preserve the binary send/receive/COPY
format for those types. For mirrored types, the default is changed to native (that is, the same as the underlying system), because nothing else makes much sense for a mirrored type.
At present, all PL/Java base types implicitly have a send/receive/COPY
binary format reflecting their internal stored format, and are not able to use their send
and receive
function slots to define a custom format for binary transfer. Because the binary COPY
format documentation specifies network byte order (that is, big-endian), there are no plans to change the default stored form from big_endian
for base types, until some future release decouples the stored representation from that for binary transfer.
In some future release, the default byte order for base types may change, and a site with stored data in PL/Java base types will then need to apply a migration step to the existing data (or keep the big-endian byte order by explicitly selecting it instead of the default). Methods to migrate existing data are covered below.
The byte order is set with Java system properties, which can be specified with the -D
option within the PostgreSQL configuration setting pljava.vmoptions
. For example, to set native
byte order for all uses:
SET pljava.vmoptions TO '-Dorg.postgresql.pljava.udt.byteorder=native`;
The allowable values are big_endian
, little_endian
, and native
.
More-specific properties are available to set the byte order for specific uses, and more-specific ones override less-specific ones:
org.postgresql.pljava.udt.byteorder.scalar org.postgresql.pljava.udt.byteorder.mirror
Again, for release 1.5.0, the defaults are big_endian
for scalar
and native
for mirror
.
Even these more-specific properties are still shortcuts, and only work at the time of starting the Java VM. After the VM is running, these properties do not exist, setting them has no effect, and the only properties that matter are four even more specific ones that set the scalar
and mirror
byte ordering for both directions of conversion. What possible use that could have is the subject of the next section.
While there is no need for a migration step as long as the base type byte order remains big-endian, and there will be no change to that default until a future PL/Java release, workable migration approaches are covered here in advance.
A simple migration approach will be to do a (non-binary) dump (with PL/Java still configured for big-endian order), change PL/Java’s configuration to use native order, and reload the data.
It is also possible, with a careful procedure and making use of the ability to set byte order independently for conversion from PostgreSQL to Java objects and the reverse direction, to do the migration with UPDATE
. This method is covered on the byte-order migration page.