Thread: Javascript support in the backend, i.e. PL/JS
Hi All, I've been writing some code[1] to support Javascript in the backend. I've got the basic bits working, the next job for me is implementing SPI support. Currently, it runs simple bits of code like the following: CREATE FUNCTION jsinc(n INTEGER) RETURNS INTEGER LANGUAGE pljs AS $$ return n+1; $$; It knows to compile the code inside a javascript function, passing the parameters with the specified names. If no names are specified, $n style naming is used--Javascript nicely deviates from C syntax in respect of allowing $ in parameter names. It knows how to handle boolean and numeric (int[248], float[48] and numeric) types are known about at the moment. Javascript has only one numeric type, so everything behaves as a double. For SPI, I'm thinking that I'd currently like to attempt some object orientated style interface. In simplest terms, it would look a bit like this: portal = { next : function () { return {} } close : function () { } } plan = { query : function (args,readonly) { return portal; } execute : function (args) { } close : function () { }} spi = { prepare : function (sql,argtypes) { return plan; } } So running some SQL would probably look something like: for (row in spi.prepare("SELECT 1 AS n").query()) { print(row.n); } The spi object would be passed into the javascript function as an extra parameter, maybe with the name "__spi" to avoid name clashes. I may put some shortcuts in if things turn out to be too slow later on, but I'd prefer not to. Most other languages seem to expose the SPI functions directly, but that seems like a bit of a waste in a language that should be able to do OO stuff. PL/Java seems to have its hands tied with JDBC, so I can't look there for much inspiration. Are there any other OO languages that do things well? Let me know what you think! Sam p.s. the main reason for doing this is because I think Javascript is a nice language!. Having said that, Nulls are handled very badly by javascript, so (1+null = 1) and ("_"+null+"_" = "_null_")! [1] http://xen.samason.me.uk/~sam/repos/pljs/ It's definitely work in progress! I have fun with header clashes between Postgres and Spidermonkey---hence the split into C files.
On 16/11/2007, Sam Mason <sam@samason.me.uk> wrote: > Hi All, > > I've been writing some code[1] to support Javascript in the backend. > I've got the basic bits working, the next job for me is implementing > SPI support. Currently, it runs simple bits of code like the > following: > > CREATE FUNCTION jsinc(n INTEGER) RETURNS INTEGER LANGUAGE pljs AS $$ > return n+1; > $$; nice Pavel > > It knows to compile the code inside a javascript function, passing the > parameters with the specified names. If no names are specified, $n > style naming is used--Javascript nicely deviates from C syntax in > respect of allowing $ in parameter names. It knows how to handle > boolean and numeric (int[248], float[48] and numeric) types are known > about at the moment. Javascript has only one numeric type, so > everything behaves as a double. > > For SPI, I'm thinking that I'd currently like to attempt some object > orientated style interface. In simplest terms, it would look a bit > like this: > > portal = { > next : function () { return {} } > close : function () { } > } > > plan = { > query : function (args,readonly) { return portal; } > execute : function (args) { } > close : function () { } > } > > spi = { > prepare : function (sql,argtypes) { return plan; } > } > > So running some SQL would probably look something like: > > for (row in spi.prepare("SELECT 1 AS n").query()) { > print(row.n); > } > > The spi object would be passed into the javascript function as an extra > parameter, maybe with the name "__spi" to avoid name clashes. > > I may put some shortcuts in if things turn out to be too slow later > on, but I'd prefer not to. Most other languages seem to expose the > SPI functions directly, but that seems like a bit of a waste in a > language that should be able to do OO stuff. PL/Java seems to have > its hands tied with JDBC, so I can't look there for much inspiration. > Are there any other OO languages that do things well? > > > Let me know what you think! > > > Sam > > p.s. the main reason for doing this is because I think Javascript is a > nice language!. Having said that, Nulls are handled very badly by > javascript, so (1+null = 1) and ("_"+null+"_" = "_null_")! > > [1] http://xen.samason.me.uk/~sam/repos/pljs/ > > It's definitely work in progress! I have fun with header > clashes between Postgres and Spidermonkey---hence the split > into C files. > > ---------------------------(end of broadcast)--------------------------- > TIP 7: You can help support the PostgreSQL project by donating at > > http://www.postgresql.org/about/donate >
On Fri, Nov 16, 2007 at 09:20:37AM +0100, Pavel Stehule wrote: > On 16/11/2007, Sam Mason <sam@samason.me.uk> wrote: > > Hi All, > > > > I've been writing some code[1] to support Javascript in the backend. > > I've got the basic bits working, the next job for me is implementing > > SPI support. Currently, it runs simple bits of code like the > > following: > > > > CREATE FUNCTION jsinc(n INTEGER) RETURNS INTEGER LANGUAGE pljs AS $$ > > return n+1; > > $$; > > nice It obviously runs much more complicated bits of javascript, but the main point is that it can't touch the outside world in any way. Functions are (as far as I understand the javascript implementation) completely deterministic (IMMUTABLE, in PG speak). Sam
On Friday 16 November 2007 09:10:43 Sam Mason wrote: > Hi All, > > I've been writing some code[1] to support Javascript in the backend. [snip] Wow, this is supercool! Most people, as you probably know, don't like JS as a language 'cause they think of it as a "web-browser language with lots of bad side-effects", but that's 'cause they don't know the language, really. JS actually has some nice programming concepts and being able to use it as an SP seems pretty attractive. Keep up the good work! -- Andreas Joseph Krogh <andreak@officenet.no> Senior Software Developer / Manager ------------------------+---------------------------------------------+ OfficeNet AS | The most difficult thing in the world is to | Karenslyst Allé 11 | know how to do a thing and to watch | PO. Box 529 Skøyen | somebody else doing it wrong, without | 0214 Oslo | comment. | NORWAY | | Tlf: +47 24 15 38 90 | | Fax: +47 24 15 38 91 | | Mobile: +47 909 56 963 | | ------------------------+---------------------------------------------+
On Fri, Nov 16, 2007 at 09:49:38AM +0100, Andreas Joseph Krogh wrote: > Most people, as you probably know, don't like JS as a language 'cause they > think of it as a "web-browser language with lots of bad side-effects", but > that's 'cause they don't know the language, really. Javascript is a very nice little language. There are a few weirdos (the treatment of NULLs I noted before being one of them) but amazingly few of them considering that's it's a scripting language. I think it's had some amazingly good effects hasn't it? There all sort of cool things happening in web browsers (quite a few of them shouldn't happen there, but that's beside the point) that build on Javascript. I'd love to see something like Caja[1] actually getting somewhere---I have a lot of respect for the people behind it and it would be very cool if it managed to break into the mainstream at some point. Some of you may have heard my rants (mainly on #postgresql) about object-capability security. It's from there that I thought it would be good to have spi come in through a parameter, if you have subscripts that you don't want to touch your database then just don't pass them a reference to the spi object and they won't be able to. Likewise, IMMUTABLE functions probably shouldn't get the spi parameter in the first place. > JS actually has some nice > programming concepts and being able to use it as an SP seems pretty > attractive. Keep up the good work! SP? I hope my code will get useful some point soon. Sam [1] http://code.google.com/p/google-caja/
On Friday 16 November 2007 11:29:09 Sam Mason wrote: [snip] > SP? Stored Procedure -- Andreas Joseph Krogh <andreak@officenet.no> Senior Software Developer / Manager ------------------------+---------------------------------------------+ OfficeNet AS | The most difficult thing in the world is to | Karenslyst Allé 11 | know how to do a thing and to watch | PO. Box 529 Skøyen | somebody else doing it wrong, without | 0214 Oslo | comment. | NORWAY | | Tlf: +47 24 15 38 90 | | Fax: +47 24 15 38 91 | | Mobile: +47 909 56 963 | | ------------------------+---------------------------------------------+
On Fri, Nov 16, 2007 at 12:05:02PM +0100, Andreas Joseph Krogh wrote: > On Friday 16 November 2007 11:29:09 Sam Mason wrote: > [snip] > > SP? > > Stored Procedure That was kind of obvious wasn't it! I failed to parse that because of the "an" before it; "an stored procedure" doesn't make much sense! English is a great language isn't it. :) Sam
On Friday 16 November 2007 12:23:26 Sam Mason wrote: > On Fri, Nov 16, 2007 at 12:05:02PM +0100, Andreas Joseph Krogh wrote: > > On Friday 16 November 2007 11:29:09 Sam Mason wrote: > > [snip] > > > > > SP? > > > > Stored Procedure > > That was kind of obvious wasn't it! I failed to parse that because > of the "an" before it; "an stored procedure" doesn't make much sense! > English is a great language isn't it. :) Yea, I wrote "an" 'cause I pronounce it "ess pee"... -- Andreas Joseph Krogh <andreak@officenet.no> Senior Software Developer / Manager ------------------------+---------------------------------------------+ OfficeNet AS | The most difficult thing in the world is to | Karenslyst Allé 11 | know how to do a thing and to watch | PO. Box 529 Skøyen | somebody else doing it wrong, without | 0214 Oslo | comment. | NORWAY | | Tlf: +47 24 15 38 90 | | Fax: +47 24 15 38 91 | | Mobile: +47 909 56 963 | | ------------------------+---------------------------------------------+
Sam Mason <sam@samason.me.uk> writes: > For SPI, I'm thinking that I'd currently like to attempt some object > orientated style interface. ... > So running some SQL would probably look something like: > for (row in spi.prepare("SELECT 1 AS n").query()) { > print(row.n); > } What's not apparent to me is how one can avoid re-planning the query every single time the function is called? More generally, I think that the average programmer would rather just not be bothered with all these details; he'd want to write for (row in spi.query("...sql..." [, arguments])) { ... I don't object to exposing the machinery for those who like to play with such stuff, but you should have shortcuts to keep the simple things simple. regards, tom lane
On Fri, Nov 16, 2007 at 10:56:55AM -0500, Tom Lane wrote: > Sam Mason <sam@samason.me.uk> writes: > > For SPI, I'm thinking that I'd currently like to attempt some object > > orientated style interface. ... > > So running some SQL would probably look something like: > > > for (row in spi.prepare("SELECT 1 AS n").query()) { > > print(row.n); > > } > > What's not apparent to me is how one can avoid re-planning the query > every single time the function is called? Nothing. I've not got a good solution for avoiding replanning between invocations of the PL/JS function either. I wanted to get the most complicated case working first, and as of about 5 minutes ago, it appears to be. Code's still quite a mess, but seems to be functioning. > More generally, I think that the average programmer would rather just > not be bothered with all these details; he'd want to write > > for (row in spi.query("...sql..." [, arguments])) { ... > > I don't object to exposing the machinery for those who like to play with > such stuff, but you should have shortcuts to keep the simple things > simple. OK. Would you expect this to use cursors under the hood? I can't see a good way of making this work without them unless I accept that they're going to fail if the record set gets too large. Sam
Sam Mason <sam@samason.me.uk> writes: > On Fri, Nov 16, 2007 at 10:56:55AM -0500, Tom Lane wrote: >> More generally, I think that the average programmer would rather just >> not be bothered with all these details; he'd want to write >> >> for (row in spi.query("...sql..." [, arguments])) { ... > OK. Would you expect this to use cursors under the hood? I can't see a > good way of making this work without them unless I accept that they're > going to fail if the record set gets too large. Yeah, you want it to "just work" ... regards, tom lane