Функция Postgres PLV8 с 'RETURNS TABLE' выдает 'ERROR: ReferenceError: $1 не определен'

Попытка вернуть таблицу из PLV8 хранимая процедура.

Он не может распознать входные аргументы, т.е. $1 когда функция с RETURNS TABLE(...),

Работает, когда функция возвращает скаляры:

psql# CREATE OR REPLACE function foo(integer) 
      RETURNS integer 
      LANGUAGE plv8 
      AS $$
         var a=$1;
         return a;
      $$;
CREATE FUNCTION
psql# SELECT * FROM foo(10);
 foo 
-----
  10
(1 row)

Это также работает, если функция RETURNS SETOF,

(Случай 1) С пользовательским типом данных:

psql# CREATE TYPE myrow as (bar int);
CREATE TYPE
psql# CREATE OR REPLACE function foo(integer) 
      RETURNS SETOF myrow
      LANGUAGE plv8 
      AS $$
         var a=$1;
         return {"bar": a};
         // Or alternatively:
         // return plv8.execute('SELECT ' + a +' AS bar');
      $$;
CREATE FUNCTION
psql# SELECT * FROM foo(10);
 bar 
-----
  10
(1 row)

(Случай 2) С SETOF record:

psql# CREATE OR REPLACE function foo(integer) 
      RETURNS SETOF record
      LANGUAGE plv8 
      AS $$
         var a=$1;
         return {"bar": a};
         // Or alternatively:
         // return plv8.execute('SELECT ' + a +' AS bar');
      $$;
CREATE FUNCTION
psql# SELECT * FROM foo(10) AS xxx(bar int);
 bar 
-----
  10
(1 row)

Но это не похоже на работу с RETURNS TABLE:

psql# CREATE OR REPLACE FUNCTION foo(integer) 
      RETURNS TABLE(bar int)  
      LANGUAGE plv8 
      AS $$
         var a=$1;
         return {"bar": a};
         // Doesn't matter cause it doesn't make it here, 
         // but alternative 'return' also fails with same error:
         // return plv8.execute('SELECT ' + a + ' AS bar');
      $$;
CREATE FUNCTION

psql# SELECT * FROM foo(10);
ERROR:  ReferenceError: $1 is not defined
DETAIL:  foo() LINE 2: var a=$1;

Любая идея, почему он задыхается $1?

Я на Postgres 9.4.0 и Plv8 1.4.4.

2 ответа

Кажется, что он работает нормально с именованными аргументами, например, "CREATE OR REPLACE FUNCTION foo(целое число)"

Я на самом деле искал, как вернуть более одного значения из функции plv8. Для дальнейшего использования, параметры OUT, кажется, являются подходящим способом, например

CREATE OR REPLACE FUNCTION foo(a integer, OUT b integer, OUT c integer) 
RETURNS setof record
LANGUAGE plv8 
AS $$

return {b: a * 2, c: a * 10};

$$;

Я думаю, что это не может работать, так как это какое-то искусство, предварительно скомпилированное в plpgsql. Вы можете изменить тип возвращаемого значения в javascript на лету, и это нарушит ожидаемый тип возвращаемого значения (RETURNS TABLE).

Вот еще одна ссылка на проблему Github, если вам интересно:

Другие вопросы по тегам