Thread: Re: [HACKERS] PL/Java issues
Jan, In Oracle a call from sql into java (be it trigger, stored procedure or function), is required to be a call to a static method. Thus in Oracle all the work is left for the programmer to manage object instances and operate on the correct ones. While I don't like this limitation in Oracle, I can't see a better way of implementing things. Therefore if you want to operate on object instances you (in Oracle) need to code up object caches that can hold the instances across function calls so that two or more functions can operate on the same instance as necessary. What this implies to the implementation is that in order to be possible the multiple function calls need to run inside the same jvm (so you can access the static caches across the different calls). If every call created a new jvm instance in Oracle you couldn't do very much. The Oracle jvm essentially gives you one jvm per connection (although technically it is somewhere between one jvm for the whole server and one per connection - i.e. it has the memory and process footprint of a single jvm for the entire server, but appears to the user as a jvm per connection). Having one jvm per connection is important to limit multiple connections ability to stomp on each others data. Something similar could probably a done for postgres by having one jvm running, by having each postgres connection having a unique thread in that jvm and having each connection thread run with its own class loader instance so that separate classes (and thus static members) are loaded for each connection. thanks, --Barry Jan Wieck wrote: > I have included the JDBC mailing list since I guess most Java developers > are around here, but not necessarily on Hackers. > > Dave Cramer and I where discussing a few issues about the PL/Java > implementation last night and would like to get more input and > suggestions on the matter. > > The basic question is the definition of the lifetime of an object and > it's identificaition when doing nested calls in this context. In the OO > world, ideally a real world object is translated into one instance of a > class. And complex structures are trees of instances, possibly of > different classes. As an example, a sales order consists of the order > header and a variable number of order lines. Therefore, per order we > have one OH instance and several OL's. So far so good. Naturally, one > Java object instance would correspond to one row in a database. > > If we now implement a stored procedure in PL/Java, that means that a > pg_proc entry corresponds to a specific method of a specific class (its > signature). But there is no obvious relationship between functions and > tables or other objects. Because of that it is not implicitly clear if > an incoming call to a method is meant for an existing instance or if a > new one should be created. > > As an example, if a PL/Java trigger on the order header executes an SPI > query on the order lines, a trigger on the order line (also in PL/Java) > might now want to call a method on it's parent object (the order header > that is waiting for the SPI result set). This should NOT result in > another OH instance being created for the same logical OH. > > Probably it is not possible to map these things automatically while > keeping the system flexible enough to be usefull. But is it feasable to > require the programmer to provide glue code for every procedure that > does all these things? How does Oracle attack this problem? > > > Jan >
Barry, Ok, so if we drop this limitation then we leave it up to the architect to manage the caching problem themselves. The class loader issue is interesting, this would mean that each object static or otherwise would not be able to overwrite others data. --dc-- On Wed, 2003-12-31 at 19:34, Barry Lind wrote: > Jan, > > In Oracle a call from sql into java (be it trigger, stored procedure or > function), is required to be a call to a static method. Thus in Oracle > all the work is left for the programmer to manage object instances and > operate on the correct ones. While I don't like this limitation in > Oracle, I can't see a better way of implementing things. > > Therefore if you want to operate on object instances you (in Oracle) > need to code up object caches that can hold the instances across > function calls so that two or more functions can operate on the same > instance as necessary. What this implies to the implementation is that > in order to be possible the multiple function calls need to run inside > the same jvm (so you can access the static caches across the different > calls). If every call created a new jvm instance in Oracle you couldn't > do very much. The Oracle jvm essentially gives you one jvm per > connection (although technically it is somewhere between one jvm for the > whole server and one per connection - i.e. it has the memory and process > footprint of a single jvm for the entire server, but appears to the user > as a jvm per connection). Having one jvm per connection is important to > limit multiple connections ability to stomp on each others data. > Something similar could probably a done for postgres by having one jvm > running, by having each postgres connection having a unique thread in > that jvm and having each connection thread run with its own class loader > instance so that separate classes (and thus static members) are loaded > for each connection. > > thanks, > --Barry > > > Jan Wieck wrote: > > I have included the JDBC mailing list since I guess most Java developers > > are around here, but not necessarily on Hackers. > > > > Dave Cramer and I where discussing a few issues about the PL/Java > > implementation last night and would like to get more input and > > suggestions on the matter. > > > > The basic question is the definition of the lifetime of an object and > > it's identificaition when doing nested calls in this context. In the OO > > world, ideally a real world object is translated into one instance of a > > class. And complex structures are trees of instances, possibly of > > different classes. As an example, a sales order consists of the order > > header and a variable number of order lines. Therefore, per order we > > have one OH instance and several OL's. So far so good. Naturally, one > > Java object instance would correspond to one row in a database. > > > > If we now implement a stored procedure in PL/Java, that means that a > > pg_proc entry corresponds to a specific method of a specific class (its > > signature). But there is no obvious relationship between functions and > > tables or other objects. Because of that it is not implicitly clear if > > an incoming call to a method is meant for an existing instance or if a > > new one should be created. > > > > As an example, if a PL/Java trigger on the order header executes an SPI > > query on the order lines, a trigger on the order line (also in PL/Java) > > might now want to call a method on it's parent object (the order header > > that is waiting for the SPI result set). This should NOT result in > > another OH instance being created for the same logical OH. > > > > Probably it is not possible to map these things automatically while > > keeping the system flexible enough to be usefull. But is it feasable to > > require the programmer to provide glue code for every procedure that > > does all these things? How does Oracle attack this problem? > > > > > > Jan > > > > > > ---------------------------(end of broadcast)--------------------------- > TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org > > -- Dave Cramer 519 939 0336 ICQ # 1467551
Barry, This appears in principal to be very close to a servlet container. I'm wondering if we could just use something like jetty as the basis for the work? It has already defined class loading per the servlet spec. It is already setup to handle multiple requests, and load balancing, etc. Dave On Wed, 2003-12-31 at 19:34, Barry Lind wrote: > Jan, > > In Oracle a call from sql into java (be it trigger, stored procedure or > function), is required to be a call to a static method. Thus in Oracle > all the work is left for the programmer to manage object instances and > operate on the correct ones. While I don't like this limitation in > Oracle, I can't see a better way of implementing things. > > Therefore if you want to operate on object instances you (in Oracle) > need to code up object caches that can hold the instances across > function calls so that two or more functions can operate on the same > instance as necessary. What this implies to the implementation is that > in order to be possible the multiple function calls need to run inside > the same jvm (so you can access the static caches across the different > calls). If every call created a new jvm instance in Oracle you couldn't > do very much. The Oracle jvm essentially gives you one jvm per > connection (although technically it is somewhere between one jvm for the > whole server and one per connection - i.e. it has the memory and process > footprint of a single jvm for the entire server, but appears to the user > as a jvm per connection). Having one jvm per connection is important to > limit multiple connections ability to stomp on each others data. > Something similar could probably a done for postgres by having one jvm > running, by having each postgres connection having a unique thread in > that jvm and having each connection thread run with its own class loader > instance so that separate classes (and thus static members) are loaded > for each connection. > > thanks, > --Barry > > > Jan Wieck wrote: > > I have included the JDBC mailing list since I guess most Java developers > > are around here, but not necessarily on Hackers. > > > > Dave Cramer and I where discussing a few issues about the PL/Java > > implementation last night and would like to get more input and > > suggestions on the matter. > > > > The basic question is the definition of the lifetime of an object and > > it's identificaition when doing nested calls in this context. In the OO > > world, ideally a real world object is translated into one instance of a > > class. And complex structures are trees of instances, possibly of > > different classes. As an example, a sales order consists of the order > > header and a variable number of order lines. Therefore, per order we > > have one OH instance and several OL's. So far so good. Naturally, one > > Java object instance would correspond to one row in a database. > > > > If we now implement a stored procedure in PL/Java, that means that a > > pg_proc entry corresponds to a specific method of a specific class (its > > signature). But there is no obvious relationship between functions and > > tables or other objects. Because of that it is not implicitly clear if > > an incoming call to a method is meant for an existing instance or if a > > new one should be created. > > > > As an example, if a PL/Java trigger on the order header executes an SPI > > query on the order lines, a trigger on the order line (also in PL/Java) > > might now want to call a method on it's parent object (the order header > > that is waiting for the SPI result set). This should NOT result in > > another OH instance being created for the same logical OH. > > > > Probably it is not possible to map these things automatically while > > keeping the system flexible enough to be usefull. But is it feasable to > > require the programmer to provide glue code for every procedure that > > does all these things? How does Oracle attack this problem? > > > > > > Jan > > > > > > ---------------------------(end of broadcast)--------------------------- > TIP 4: Don't 'kill -9' the postmaster > -- Dave Cramer 519 939 0336 ICQ # 1467551
Dave Cramer wrote: > Barry, > > Ok, so if we drop this limitation then we leave it up to the architect > to manage the caching problem themselves. Maybe I don't understand enough about Java, but isn't this limitation (only static methods callable) exactly what avoids having to deal with the call->instance association in the PL framework? I think we still want to go a little further in the framework and provide at least the object caches. Since we don't have any ON COMMIT or ON ROLLBACK triggers, it'd be hard for the PL programmer to deal with cleanup and object dereferencing, especially in the case of transaction abort. > > The class loader issue is interesting, this would mean that each object > static or otherwise would not be able to overwrite others data. I think if we would create one thread per backend (on the first call of any PL/Java proc of course), and also have one class loader per thread, that'd be sufficient at least from a security point of view. Jan > > --dc-- > On Wed, 2003-12-31 at 19:34, Barry Lind wrote: >> Jan, >> >> In Oracle a call from sql into java (be it trigger, stored procedure or >> function), is required to be a call to a static method. Thus in Oracle >> all the work is left for the programmer to manage object instances and >> operate on the correct ones. While I don't like this limitation in >> Oracle, I can't see a better way of implementing things. >> >> Therefore if you want to operate on object instances you (in Oracle) >> need to code up object caches that can hold the instances across >> function calls so that two or more functions can operate on the same >> instance as necessary. What this implies to the implementation is that >> in order to be possible the multiple function calls need to run inside >> the same jvm (so you can access the static caches across the different >> calls). If every call created a new jvm instance in Oracle you couldn't >> do very much. The Oracle jvm essentially gives you one jvm per >> connection (although technically it is somewhere between one jvm for the >> whole server and one per connection - i.e. it has the memory and process >> footprint of a single jvm for the entire server, but appears to the user >> as a jvm per connection). Having one jvm per connection is important to >> limit multiple connections ability to stomp on each others data. >> Something similar could probably a done for postgres by having one jvm >> running, by having each postgres connection having a unique thread in >> that jvm and having each connection thread run with its own class loader >> instance so that separate classes (and thus static members) are loaded >> for each connection. >> >> thanks, >> --Barry >> >> >> Jan Wieck wrote: >> > I have included the JDBC mailing list since I guess most Java developers >> > are around here, but not necessarily on Hackers. >> > >> > Dave Cramer and I where discussing a few issues about the PL/Java >> > implementation last night and would like to get more input and >> > suggestions on the matter. >> > >> > The basic question is the definition of the lifetime of an object and >> > it's identificaition when doing nested calls in this context. In the OO >> > world, ideally a real world object is translated into one instance of a >> > class. And complex structures are trees of instances, possibly of >> > different classes. As an example, a sales order consists of the order >> > header and a variable number of order lines. Therefore, per order we >> > have one OH instance and several OL's. So far so good. Naturally, one >> > Java object instance would correspond to one row in a database. >> > >> > If we now implement a stored procedure in PL/Java, that means that a >> > pg_proc entry corresponds to a specific method of a specific class (its >> > signature). But there is no obvious relationship between functions and >> > tables or other objects. Because of that it is not implicitly clear if >> > an incoming call to a method is meant for an existing instance or if a >> > new one should be created. >> > >> > As an example, if a PL/Java trigger on the order header executes an SPI >> > query on the order lines, a trigger on the order line (also in PL/Java) >> > might now want to call a method on it's parent object (the order header >> > that is waiting for the SPI result set). This should NOT result in >> > another OH instance being created for the same logical OH. >> > >> > Probably it is not possible to map these things automatically while >> > keeping the system flexible enough to be usefull. But is it feasable to >> > require the programmer to provide glue code for every procedure that >> > does all these things? How does Oracle attack this problem? >> > >> > >> > Jan >> > >> >> >> >> ---------------------------(end of broadcast)--------------------------- >> TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org >> >> -- #======================================================================# # It's easier to get forgiveness for being wrong than for being right. # # Let's break this rule - forgive me. # #================================================== JanWieck@Yahoo.com #
Barry, Ok, so if we drop this limitation then we leave it up to the architect to manage the caching problem themselves. The class loader issue is interesting, this would mean that each object static or otherwise would not be able to overwrite others data. --dc-- On Wed, 2003-12-31 at 19:34, Barry Lind wrote: > Jan, > > In Oracle a call from sql into java (be it trigger, stored procedure or > function), is required to be a call to a static method. Thus in Oracle > all the work is left for the programmer to manage object instances and > operate on the correct ones. While I don't like this limitation in > Oracle, I can't see a better way of implementing things. > > Therefore if you want to operate on object instances you (in Oracle) > need to code up object caches that can hold the instances across > function calls so that two or more functions can operate on the same > instance as necessary. What this implies to the implementation is that > in order to be possible the multiple function calls need to run inside > the same jvm (so you can access the static caches across the different > calls). If every call created a new jvm instance in Oracle you couldn't > do very much. The Oracle jvm essentially gives you one jvm per > connection (although technically it is somewhere between one jvm for the > whole server and one per connection - i.e. it has the memory and process > footprint of a single jvm for the entire server, but appears to the user > as a jvm per connection). Having one jvm per connection is important to > limit multiple connections ability to stomp on each others data. > Something similar could probably a done for postgres by having one jvm > running, by having each postgres connection having a unique thread in > that jvm and having each connection thread run with its own class loader > instance so that separate classes (and thus static members) are loaded > for each connection. > > thanks, > --Barry > > > Jan Wieck wrote: > > I have included the JDBC mailing list since I guess most Java developers > > are around here, but not necessarily on Hackers. > > > > Dave Cramer and I where discussing a few issues about the PL/Java > > implementation last night and would like to get more input and > > suggestions on the matter. > > > > The basic question is the definition of the lifetime of an object and > > it's identificaition when doing nested calls in this context. In the OO > > world, ideally a real world object is translated into one instance of a > > class. And complex structures are trees of instances, possibly of > > different classes. As an example, a sales order consists of the order > > header and a variable number of order lines. Therefore, per order we > > have one OH instance and several OL's. So far so good. Naturally, one > > Java object instance would correspond to one row in a database. > > > > If we now implement a stored procedure in PL/Java, that means that a > > pg_proc entry corresponds to a specific method of a specific class (its > > signature). But there is no obvious relationship between functions and > > tables or other objects. Because of that it is not implicitly clear if > > an incoming call to a method is meant for an existing instance or if a > > new one should be created. > > > > As an example, if a PL/Java trigger on the order header executes an SPI > > query on the order lines, a trigger on the order line (also in PL/Java) > > might now want to call a method on it's parent object (the order header > > that is waiting for the SPI result set). This should NOT result in > > another OH instance being created for the same logical OH. > > > > Probably it is not possible to map these things automatically while > > keeping the system flexible enough to be usefull. But is it feasable to > > require the programmer to provide glue code for every procedure that > > does all these things? How does Oracle attack this problem? > > > > > > Jan > > > > > > ---------------------------(end of broadcast)--------------------------- > TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org > >