Проблема в вашей функции заключается в том, что конструктор ROW "наносит удар первым", создавая составной тип из двух неизвестных значений, для которых неявное преобразование типов не выполняется.
Вот 5 способов без использования явного приведения :
1. По-прежнему используется предопределенный составной тип / тип строки с явным, подробным синтаксисом (обучающийв основном).При выборе этого параметра для неизвестных типов по умолчанию устанавливается значение text
до , они объединяются в тип ROW:
CREATE OR REPLACE FUNCTION test1()
RETURNS SETOF name_value_pair AS
$func$
BEGIN
RETURN NEXT (SELECT t FROM (SELECT 'email', 'foo@example.com') t);
RETURN NEXT (SELECT t FROM (SELECT 'user_id', 'abc123') t);
END
$func$ LANGUAGE plpgsql IMMUTABLE;
SELECT * FROM test1();
2. Использование RETURNS TABLE
и RETURN QUERY
вместо.Не нужно формировать составные типы для начала, просто позвольте самой функции выполнить этот последний шаг:
CREATE OR REPLACE FUNCTION test2()
RETURNS TABLE (name text, value text) AS
$func$
BEGIN
RETURN QUERY SELECT 'email', 'foo@example.com';
RETURN QUERY SELECT 'user_id', 'abc123';
END
$func$ LANGUAGE plpgsql IMMUTABLE;
SELECT * FROM test2();
3. Или все же использовать составной тип для определения возвращаемого типа.Может быть лучше для вас:
CREATE OR REPLACE FUNCTION test3()
RETURNS SETOF name_value_pair AS
$func$
BEGIN
RETURN QUERY SELECT 'email', 'foo@example.com';
RETURN QUERY SELECT 'user_id', 'abc123';
END
$func$ LANGUAGE plpgsql IMMUTABLE;
SELECT * FROM test3();
4. Хотя это так просто, простое VALUES
выражение в простой SQL-функции короче ибыстрее:
CREATE OR REPLACE FUNCTION test4()
RETURNS SETOF name_value_pair AS
$func$
VALUES
('email', 'foo@example.com')
, ('user_id', 'abc123');
$func$ LANGUAGE sql IMMUTABLE;
SELECT * FROM test4();
5. Или, если имеет , будет PL / pgSQL:
CREATE OR REPLACE FUNCTION test5()
RETURNS SETOF name_value_pair AS
$func$
BEGIN
RETURN QUERY VALUES
('email', 'foo@example.com')
, ('user_id', 'abc123');
END
$func$ LANGUAGE plpgsql IMMUTABLE;
SELECT * FROM test5();
дБ <>fiddle здесь
Неявное преобразование из unknown
в text
для скалярных возвращаемых значений функции было добавлено в Postgres 10 .Postgres 9.6 или старше более строгие и могут вызвать аналогичные ошибки для вариантов 1 - 3. (Только функции 4. и 5. работают в любой версии Postgres.)
ERROR: structure of query does not match function result type
DETAIL: Returned type unknown does not match expected type text in column 1.
Можнообсудить, было ли все еще строгое поведение для типа ROW недосмотром в этом обновлении или намеренно.Я могу предположить, что можно использовать и любой другой случай.
Связанный: