9

In Postgresql, I want to call 3rd party libraries like moment.js or AWS lambda JS Client to invoke serverless functions from within the DB. I don't see any docs or examples how to do so: https://github.com/plv8/plv8/blob/master/README.md

Is this possible and where can I find examples of how to 'import' or 'require' additional libraries?

Jason
  • 2,006
  • 3
  • 21
  • 36

3 Answers3

10

The plv8 language is trusted so there is no way to load anything from the file system. However you can load modules from the database.

Create a table with source code of a module and load it using select and eval(). A simple example to illustrate the idea:

create table js_modules (
    name text primary key,
    source text
);

insert into js_modules values
('test', 'function test() { return "this is a test"; }' );

Load the module from js_modules in your function:

create or replace function my_function()
returns text language plv8 as $$
//  load module 'test' from the table js_modules
    var res = plv8.execute("select source from js_modules where name = 'test'");
    eval(res[0].source);
//  now the function test() is defined
    return test();
$$;

select my_function();

CREATE FUNCTION
  my_function   
----------------
 this is a test
(1 row) 

You can find a more elaborate example with an elegant require() function in this post: A Deep Dive into PL/v8.. Its is based on plv8.start_proc (see also a short example here).

Peter Krauss
  • 13,174
  • 24
  • 167
  • 304
klin
  • 112,967
  • 15
  • 204
  • 232
  • 2
    Ugly solution: with `select source` and `eval()` we lost all performance of V8... There are no way to "pre compile"? – Peter Krauss May 22 '19 at 16:07
  • I do not think it's ugly. It's just everything you can do without interfering with the `plv8` extension's source code. – klin May 22 '19 at 16:19
  • ... Hum... No pre-compile way? (no way to register into PostgreSQL user-calalog-lib after eval?) – Peter Krauss May 22 '19 at 16:30
  • @PeterKrauss - I've forgotten, there is also initialization function, see the second option in [Is it possible to create a re-usable function with the PostgreSQL plv8 extension?](https://stackoverflow.com/q/49631866/1995738) – klin May 22 '19 at 17:13
  • Thanks, it's what I was looking for. (edited to simplify for other readers). – Peter Krauss May 22 '19 at 21:24
  • https://github.com/jerrySievert/plv8-modules is a tool to make it easier to load code into the database (and available via "require" using plv8.start_proc) – armb Apr 28 '20 at 09:56
1

I have two hints pointing in the NO direction:

  1. You can use PLV8 in Amazon RDS PosgreSQL. RDS doesn't allow any language which is not trusted. As explained in PostgreSQL documentation:

    TRUSTED

    TRUSTED specifies that the language does not grant access to data that the user would not otherwise have.

    If PLV8 could use libraries, those would (most probably) allow for performing operations such as downloading data via HTTP, or checking the file system, which would contravene this restriction (and possibly, put RDS system at hacking risk).

  2. Presentation PLV8 - The PostgreSQL web side by Lucio Grenzi.

    Slide #10:

    PLV8: a trusted language

      [...]

    • no way to load external processing modules from the file system

A possible alternative

I have used the PLPERLu (u meaning untrusted) language. Using that language, you can use libraries. Your libraries should be in the standard locations for the PERL installation being used by PostgreSQL (as defined when you CREATE LANGUAGE).

joanolo
  • 6,028
  • 1
  • 29
  • 37
0

Quite a while later... it is possible in AWS RDS PostgreSQL to invoke Lambda functions in versions:

  • 14.1 and higher minor versions
  • 13.2 and higher minor versions
  • 12.6 and higher minor versions

with select statements like:

Synchronous

SELECT * FROM aws_lambda.invoke(:'aws_lambda_arn_1', '{"body": "Hello from Postgres!"}'::json);

Async

SELECT * FROM aws_lambda.invoke(:'aws_lambda_arn_1', '{"body": "Hello from Postgres!"}'::json, 'Event');

Of course, there is more to setting it up in the instructions here: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/PostgreSQL-Lambda.html

Richard Collette
  • 5,462
  • 4
  • 53
  • 79