Почему функции PostgreSQL возвращают пустые столбцы, а не строки, если тип возвращаемого значения — имя таблицы?

Если я создам функцию f, которая запрашивает функцию, я думаю, что ее будет легче читать, если возвращаемый тип будет именем таблицы, а не RETURNS TABLE(id integer, name text).

CREATE TABLE users ( id integer, name text );

CREATE OR REPLACE FUNCTION f() 
 RETURNS users 
 AS $$ 
   SELECT * FROM users
   WHERE FALSE 
 $$ 
 LANGUAGE SQL;

Но я получаю странные результаты, когда запрос в функции возвращает нулевые строки.

SELECT * FROM f();

Ожидаемый результат

+------+--------+
| id   | name   |
|------+--------|
+------+--------+

Фактический результат

+--------+--------+
| id     | name   |
|--------+--------|
| <null> | <null> |
+--------+--------+

Если столбцов больше, они все равно будут null. Если запрос в функции возвращает какие-либо строки, то он работает так, как ожидалось. Я не получаю такого поведения, если использую синтаксис RETURNS TABLE(...).

Есть ли способ обойти это?

Я использую PostgreSQL 9.6.


person The Hoff    schedule 14.02.2020    source источник


Ответы (1)


Это не имеет ничего общего с типом возвращаемого значения, но с тем фактом, что вы объявили функцию, возвращающую одну строку.

Заменять

RETURNS users

с участием

RETURNS SETOF users

и ваша функция будет работать так, как ожидалось.

Как и ваша функция, она вернет NULL, если запрос не имеет результатов, и вернет первую строку, если запрос имеет более одной строки результатов.

person Laurenz Albe    schedule 14.02.2020