#postgresql #plpgsql #hasura
#postgresql #plpgsql #хасура
Вопрос:
У меня есть функция ниже ( is_organizer
), которая работает и позволяет мне использовать этот метод в качестве вычисляемого поля в Hasura. Приведенная ниже функция ( is_chapter_member
), которая почти идентична, не работает.
РАБОТАЕТ
CREATE OR REPLACE FUNCTION is_organizer(event_row events, hasura_session json)
RETURNS boolean AS $$
SELECT EXISTS (
SELECT 1
FROM event_organizers o
WHERE
o.user_id::text = hasura_session->>'x-hasura-user-id'
AND
(event_row.id = o.event_id OR event_row.event_template_id = o.event_template_id)
);
$$ LANGUAGE SQL STRICT IMMUTABLE;
НАРУШЕНО
CREATE OR REPLACE FUNCTION is_chapter_member(c chapters, hasura_session json)
RETURNS boolean AS $$
SELECT EXISTS (
SELECT 1
FROM chapter_members m
WHERE
m.user_id::text = hasura_session->>'x-hasura-user-id'
AND
c.chapter_id = m.chapter_id
);
$$ LANGUAGE SQL STRICT IMMUTABLE;
При попытке добавить эту функцию (не вызывать ее, просто создать) Postgres выдает следующую ошибку:
ERROR: missing FROM-clause entry for table "c"
LINE 9: c.chapter_id = m.chapter_id
Зачем параметру функции нужно предложение where? Таблица сбрасывается ниже…
Table "public.chapters"
Column | Type | Collation | Nullable | Default
----------------- -------------------------- ----------- ---------- --------------------------------------
id | integer | | not null | nextval('chapters_id_seq'::regclass)
title | text | | not null |
slug | text | | not null |
description | jsonb | | |
avatar_url | text | | |
photo_url | text | | |
region | text | | |
maps_api_result | jsonb | | |
lat | numeric(11,8) | | |
lng | numeric(11,8) | | |
created_at | timestamp with time zone | | not null | now()
updated_at | timestamp with time zone | | not null | now()
deleted_at | timestamp with time zone | | |
Table "public.chapter_members"
Column | Type | Collation | Nullable | Default
------------ -------------------------- ----------- ---------- ---------
user_id | integer | | not null |
chapter_id | integer | | not null |
created_at | timestamp with time zone | | not null | now()
updated_at | timestamp with time zone | | not null | now()
Table "public.events"
Column | Type | Collation | Nullable | Default
------------------- ----------------------------- ----------- ---------- ---------------------------------------------------
id | integer | | not null | nextval('events_id_seq'::regclass)
event_template_id | integer | | not null |
venue_id | integer | | |
starts_at | timestamp without time zone | | not null |
duration | interval | | not null |
title | text | | |
slug | text | | |
description | text | | |
photo_url | text | | |
created_at | timestamp without time zone | | not null | now()
updated_at | timestamp without time zone | | not null | now()
deleted_at | timestamp without time zone | | |
ends_at | timestamp without time zone | | | generated always as (starts_at duration) stored
Table "public.event_organizers"
Column | Type | Collation | Nullable | Default
------------------- --------- ----------- ---------- ----------------------------------------------
id | integer | | not null | nextval('event_organizers_id_seq'::regclass)
user_id | integer | | not null |
event_id | integer | | |
event_template_id | integer | | |
Комментарии:
1. попробуйте
(c).chapters
— в анализаторе могут возникнуть проблемы, поскольку <x>.<y> определяется как <таблица> . <столбец> ссылка по стандартам SQL. Типы записей / строк поддерживаются не всеми СУБД.2. @RichardHuxton вы были на правильном пути. Использование
(c).chapter_id
вызвало следующую проблему, которая заключалась в отсутствующем поле, окончательный ответ ниже.
Ответ №1:
Оказалось, что в неработающей функции использовалось неправильное имя столбца. chapter_id
должно было быть только id
в c
аргументе. Я воспользовался подсказкой Ричарда и попытался поместить скобки вокруг аргумента, например (c).chapter_id
. Затем это правильно сказало мне, что chapter_id
этого не существует, и позволило мне исправить проблему.