Кажется, что SETOF должен быть подмножеством таблицы и не может иметь новых столбцов. Например, я попытался:
CREATE FUNCTION getfoo(int) RETURNS SETOF table_a AS $$
SELECT *, 'asdf' as extra FROM table_a WHERE id = $1;
$$ LANGUAGE SQL;
, что привело к сообщенной Hasura ошибке:
SQL Execution Failed
postgres-error: return type mismatch in function declared to return table_a
{
"path": "$.args[0].args",
"error": "query execution failed",
"internal": {
"arguments": [],
"error": {
"status_code": "42P13",
"exec_status": "FatalError",
"message": "return type mismatch in function declared to return table_a",
"description": "Final statement returns too many columns.",
"hint": ""
},
"prepared": false,
"statement": "CREATE FUNCTION getfoo(int) RETURNS SETOF table_a AS $$\n SELECT *, 'asdf' as extra FROM table_a WHERE id = $1;\n$$ LANGUAGE SQL;"
},
"code": "postgres-error"
}
Однако есть несколько других вариантов:
- Добавить Столбец "промежуточного итога" на
table_b
сам (путем изменения определения функции. Подробно ниже. - Если этого недостаточно, другой вариант - создать представление для table_b, в котором есть столбец running_total, используя sum и раздел. И затем создайте связь между table_a и table_b_view.
- Создайте триггер для table_b, чтобы при добавлении новой строки он вычислял столбец running_total и сохранял его, так как эти данные выглядят как stati c поскольку он основан на исторических данных.
Вариант 1 подробно описан ниже, поскольку он наиболее близко напоминает исходную реализацию (использование функции):
CREATE OR REPLACE FUNCTION public.table_b_running_total(table_b_row table_b)
RETURNS bigint
LANGUAGE sql
STABLE
AS $function$
SELECT SUM (qty)
FROM table_b
WHERE product_id = table_b_row.product_id
AND created_at <= table_b_row.created_at
LIMIT 1
$function$
С этим я смог получить желаемый результат - т. К. Требуемый ответ graphql точно не совпадает.
query:
query MyQuery {
table_a(where:{ id: { _eq: 1 }}) {
id
product_id
table_bs {
id
product_id
qty
created_at
table_b_running_total
}
}
}
response :
{
"data": {
"table_a": [
{
"id": 1,
"product_id": "1",
"table_bs": [
{
"id": 1,
"product_id": "1",
"qty": 6,
"created_at": "2020-01-01T00:00:00+00:00",
"table_b_running_total": 6
},
{
"id": 5,
"product_id": "1",
"qty": 4,
"created_at": "2020-01-03T00:00:00+00:00",
"table_b_running_total": 10
}
]
}
]
}
}