Безопасность на уровне строк, неоднозначная ссылка

Я пытаюсь создать политику в postgres, которая приводит к column reference "person_id" is ambiguous.

Чтобы сделать небольшой аналогичный пример, давайте опишем 3 таблицы: person, group и group_member.

У человека есть: id, имя
В группе есть: id, person_id и имя
Член группы имеет: id, person_id, group_id

Я упростил свою политику, но соответствующая часть выглядит примерно так:

CREATE POLICY insert_group_member ON public."group" FOR INSERT TO user_role WITH CHECK (
  EXISTS (
    SELECT * FROM "group" AS g
      LEFT JOIN "group_member" AS gm ON
        g.person_id = gm.person_id
        AND g.id = gm.group_id
      WHERE
        g.id = id AND
        gm.person_id = person_id AND
        g.members_can_invite = TRUE
  )
);

person_id в этом случае может относиться к group.person_id или group_member.person_id из подвыбора, но я действительно хочу, чтобы это был person_id из «with check». Обычно это работает и в других местах.

Вопрос: есть ли способ четко указать, что столбец person_id исходит из политики, а не из выбора или объединения. Примечание. Я ожидал, что смещение имен таблиц решит эту проблему, но, похоже, это не так.


person Parris    schedule 09.10.2017    source источник
comment
user_role.person_id работает?   -  person Craig Ringer    schedule 09.10.2017
comment
@CraigRinger, который меняет его на - missing FROM-clause entry for table "user_role"   -  person Parris    schedule 09.10.2017
comment
Какое определение для user_role?   -  person Laurenz Albe    schedule 09.10.2017
comment
@LaurenzAlbe это CREATE ROLE user_role;   -  person Parris    schedule 09.10.2017
comment
Я неправильно прочитал статью, я должен был сказать public."group" не user_role   -  person Craig Ringer    schedule 09.10.2017


Ответы (1)


Вы должны указать все ссылки на столбцы, например:

...
WHERE g.id = "group".id
  AND gm.person_id = "group".person_id
person Laurenz Albe    schedule 09.10.2017
comment
Но group_id должен поступать от group_member как часть исходного запроса. Я предполагаю, что все, что попадает в логику политики. - person Parris; 09.10.2017
comment
Хотя это привело меня к правильному ответу. group_member.person_id - правильный ответ. Использование псевдонимов для всех остальных операторов select from - правильный подход в сочетании с использованием исходного имени таблицы, к которому применяется ваша политика. Если вы обновите свой ответ, я его приму. Для всех, кто это читает, я бы порекомендовал сделать это в отдельной функции вместо встроенного выбора. Скорее всего, вы попадете в место, где получаете бесконечную рекурсию. См. Обсуждение здесь - postgresql-archive.org/ < / а> - person Parris; 10.10.2017
comment
Собственно, при ближайшем рассмотрении я совершенно не понимаю вашу политику. Каковы ограничения внешнего ключа между вашими таблицами? Зачем вам вообще нужен group_member в запросе, если он добавлен с помощью левого внешнего соединения и не отображается ни в каком состоянии? - person Laurenz Albe; 10.10.2017
comment
Я немного изменил его сейчас. Я понял, что ошибся в вопросе (спасибо). Внешние ключи находятся между person_id = ›person.id для group_member и group и group_id =› group.id для group_member. - person Parris; 10.10.2017
comment
Но тогда неквалифицированные ссылки на group_id и person_id должны относиться к "group", верно? - person Laurenz Albe; 10.10.2017
comment
ааа да, ты прав. Понятно. Простите, я запуталась. Спасибо! - person Parris; 10.10.2017