поддержка записей любого типа в моей функции - PullRequest
0 голосов
/ 11 декабря 2018

В отличие от PL/pgSQL функций, функции языка SQL принимают записи и массивы записей.Работает следующий скрипт:

create type testtyp1 as ( a int, b unknown );
create type testtyp2 as ( a int, b text );
create type testtyp3 as ( a int, b varchar(8000) );

create or replace function xdecode(variadic args anyarray) RETURNS text AS $$
  select 'x'::text;
$$ LANGUAGE sql;

-- the function should support all these:
select xdecode( (1,'a'),(2,'b') );
select xdecode( (1,'a')::testtyp1, (2,'b')::testtyp1 );
select xdecode( (1,'a')::testtyp2, (2,'b')::testtyp2 );
select xdecode( (1,'a')::testtyp3, (2,'b')::testtyp3 );

И важно, это тоже:

select xdecode( (0.1,now()), (0.2,now()) );

Теперь мне нужно изменить функцию, чтобы она возвращала 2-й столбец элемента массива, чей 1-й столбецсоответствует определенному условию.

Проблема в том, что столбцы записи могут иметь любое имя или вообще не иметь имени.Другая проблема заключается в том, что символьные константы в PostgreSQL имеют тип: unknown.

Если я попытаюсь привести строку к любому другому типу, вызов завершится неудачно:

create or replace function xdecode(variadic args anyarray) RETURNS text AS $$
  select args[1]::testtyp1::text
$$ LANGUAGE sql;
...
> select xdecode( (1,'a'),(2,'b') );
cannot cast type record to testtyp1
> select xdecode( (1,'a')::testtyp3, (2,'b')::testtyp3 );
cannot cast type testtyp3 to testtyp1

Iмогу обойтись без знания имен столбцов с помощью вспомогательной функции:

create or replace function hlp(arg anyelement) RETURNS record AS $$
  select arg;
$$ LANGUAGE sql;

create or replace function xdecode(variadic args anyarray) RETURNS text AS $$
  select b::text from hlp( args[1] ) AS T(a int , b unknown);
$$ LANGUAGE sql;

Но я ничего не могу поделать, не зная, unknown или text:

> select xdecode( (1,'a'),(2,'b') );
a
> select xdecode( (1,'a')::testtyp1, (2,'b')::testtyp1 );
a
> select xdecode( (1,'a')::testtyp2, (2,'b')::testtyp2 );
Returned type text at ordinal position 2, but query expects unknown.
> select xdecode( (1,'a')::testtyp3, (2,'b')::testtyp3 );
Returned type text at ordinal position 2, but query expects unknown.

Не указание типов невозможно:

create or replace function xdecode(variadic args anyarray) RETURNS text AS $$
  select b::text from hlp( args[1] ) AS T(a, b);
$$ LANGUAGE sql;
> select xdecode( (1,'a'),(2,'b') );
a column definition list is required for functions returning "record"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...