Почему я не могу использовать аргумент plsql в этом предложении where?

#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 этого не существует, и позволило мне исправить проблему.