Привилегии
Любой объект принадлежит какой-либо роли. При создании объекта во время сеанса роль становится его владельцем и получает права на любые действия с ним. Для получения доступа к объекту, владельцем которого роль не является, необходимы привилегии. Привилегии устанавливаются на объекты в их метаданных и запоминаются в форме ACL (Access Control List) следующим образом:
grantee=privilege[*].../grantor +
Используемые обозначения:
grantee— роль, которой были назначены привилегии;privilege— сами привилегии;[*]— символ, который означает возможность передачи привилегии;grantor— роль, предоставившая привилегии;+— такой символ ставится, если ролей с привилегиями много и они не помещаются на одну строчку.
Для каждого типа объектов в PostgreSQL существует отдельная команда просмотра привилегий. Полный перечень команд приведен в справочной таблице. Привилегии по умолчанию (полные права владельца) не отображаются в ACL до первого изменения списка доступа.
Создадим таблицу def_privs и проверим ее список доступа.
postgres@postgres=# CREATE TABLE def_privs(n int);
CREATE TABLE
postgres@postgres=# \dp def_privs
Access privileges
Schema | Name | Type |Access privileges|Column privileges|Policies
--------+-----------+---------+-----------------+-----------------+----------
public | def_privs | table | | |
(1 row)
В столбце Access privileges данные отсутствуют — привилегии владельца по умолчанию не выводятся.
Назначение привилегий
Назначать привилегии может одна из трех ролей:
- владелец объекта;
- роль с правом передачи привилегий;
- суперпользователь.
Для назначения привилегии используется команда GRANT. При ее применении нужно указать, какие привилегии, на какой объект и для какой роли необходимо выдать.
Создадим роль aspirant и попробуем выполнить запрос к таблице studentab с ее помощью.
postgres@postgres=# CREATE USER aspirant;
CREATE ROLE
Почему используется команда CREATE USER?
Поскольку дальше нужно будет выполнить запрос к таблице studentab, потребуется подключиться к базе данных my_db, а для этого нужен атрибут LOGIN. Его можно выдать явно как в команде CREATE ROLE, так и скрытно при помощи CREATE USER. Синтаксис команды получается короче и удобнее при том же результате.
postgres@postgres=# \c my_db aspirant
You are now connected to database "my_db" as user "aspirant".
aspirant@my_db=> SELECT * FROM studentab;
ERROR: permission denied for table suptab
Роль aspirant не входит в групповую роль grp_students, которая владеет таблицей studentab, поэтому на нее не распространяются права владельца объекта. Для выполнения запроса необходимо выдать соответствующую привилегию (разрешение на чтение таблицы) от имени владельца объекта.
aspirant@postgres=> \c my_db student
You are now connected to database "my_db" as user "student".
student@my_db=> GRANT SELECT ON studentab TO aspirant ;
GRANT
student@my_db=> \c - aspirant
You are now connected to database "my_db" as user "aspirant".
aspirant@my_db=> SELECT * FROM studentab;
id | str
----+-----
(0 rows)
Как видим, запрос успешно выполнен.
Действия с разными объектами отличаются. Рассмотрим их подробнее.
Привилегии для таблиц и представлений
Для работы с таблицами и представлениями можно назначить следующие привилегии (в скобках указаны их буквенные обозначения в ACL):
SELECT— чтение таблицы, представления, столбца (r— read);INSERT— вставка в таблицу или представление (a— append);UPDATE— изменение значений столбцов таблиц или представлений (w— write);DELETE— удаление строк в таблицах или представлениях (d— delete);TRUNCATE— опустошение таблицы (D);REFERENCES— создание ссылки на столбец внешним ключом (x);TRIGGER— создание триггера для таблицы или представления (t).
Привилегии можно выдать не только на целый объект, но и на его часть — отдельные столбцы.
Установим для роли aspirant привилегии на чтение и вставку данных для некоторых столбцов. Для этого переключимся на student и создадим новую таблицу.
aspirant@my_db=> \c - student
You are now connected to database "my_db" as user "student".
student@my_db=> CREATE TABLE ptab (n integer, t text);
CREATE TABLE
Выдадим aspirant возможность чтения столбца n и вставки данных в столбцы n и t в таблице ptab.
student@my_db=> GRANT SELECT(n),INSERT(n,t) ON ptab TO aspirant;
GRANT
Получить установленные привилегии на таблицу можно метакомандой \dp.
student@my_db=> \dp ptab
Access privileges
Schema | Name | Type |Access privileges| Column privileges | Policies
--------+------+---------+-----------------+-----------------------+----------
public | ptab | table | | n: +|
| | | | aspirant=ar/student+|
| | | | t: +|
| | | | aspirant=a/student |
(1 row)
В столбце Access privileges перечислены все роли и их привилегии для данного объекта. Если привилегии выданы на конкретные столбцы, роли будут сгруппированы по этим столбцам, как в нашем случае. Разберем запись из ACL подробнее.
Столбец привилегий разделен на 2 группы: для столбца n и столбца t таблицы ptab.
Посмотрим на запись столбца n. Перед знаком равенства указана роль aspirant, которой выданы привилегии. Буквенные обозначения привилегий пишутся после знака равенства, в нашем случае это ar. Буква a соответствует разрешению на вставку данных в текущий столбец, а буква r— разрешению на чтение данных.
Запись столбца t практически не отличается от предыдущей: на текущий столбец выдана только привилегия на вставку данных.
Привилегии для баз данных
По сравнению с таблицами у баз данных меньше возможных привилегий:
CREATE(C) — разрешает создание новых схем, публикаций и подключение расширений;CONNECT(c) — разрешает подключение к базе данных;TEMPORARY(T) — создание временных объектов в базе данных.
По умолчанию на все базы данных устанавливаются 2 привилегии: T и c. Подключение к базе данных требует не только наличия соответствующей привилегии, но и разрешения на подключение в файле pg_hba.conf, о котором будет рассказано позже.
В качестве демонстрации работы с привилегиями для баз данных выберем разрешение на создание схем (как раз дальше речь пойдет про них). Попробуем создать схему от имени aspirant.
student@my_db=> \c - aspirant
You are now connected to database "my_db" as user "aspirant".
aspirant@my_db=> CREATE SCHEMA asp_sch;
ERROR: permission denied for database my_db
Поскольку роль aspirant не входит в grp_students и пока не имеет нужной привилегии, то не может и создать схему — недостаточно прав. Переключимся на владельца базы данных, grp_students, и выдадим привилегию C.
aspirant@my_db=> SET ROLE grp_students;
SET
aspirant@my_db=> GRANT CREATE ON DATABASE my_db TO aspirant;
GRANT
Обратите внимание, что в команде выдачи прав добавилось ключевое слово DATABASE. Оно позволяет явно указать, что права выдаются именно на базу данных, а не объекты в ней. Если не указывать ключевое слово, система будет искать объект my_db внутри базы данных, к которой выполнено подключение на данный момент.
Теперь вернемся к роли aspirant и посмотрим на привилегии баз данных. Для получения информации по базам данных, в том числе выданных привилегий, используется метакоманда \l.
aspirant@my_db=> RESET ROLE;
RESET
aspirant@my_db=> \l
List of databases
Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider | Access privileges
-----------+--------------+----------+-------------+-------------+------------+-----------------+-------------------------------
my_db | grp_students | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =Tc/grp_students +
| | | | | | | grp_students=CTc/grp_students+
| | | | | | | aspirant=C/grp_students
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc |
sch_db | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =c/postgres +
| | | | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =c/postgres +
| | | | | | | postgres=CTc/postgres
(5 rows)
У my_db появилась запись для роли aspirant с привилегией C, выданной grp_students. Но обратим внимание на первую запись. Она отличается от остальных — нет имени роли перед знаком равенства. Это и есть маркер тех самых прав по умолчанию, которые работают для всех ролей. Устанавливаются они автоматически системой от имени владельца базы данных.
Попробуем вновь создать схему asp_sch.
aspirant@my_db=> CREATE SCHEMA asp_sch;
CREATE SCHEMA
С выданной привилегией проблем с нехваткой прав не возникло и схема была успешно создана.
Привилегии для схем
Для схем привилегий еще меньше, их существует всего две:
USAGE(U) — разрешает взаимодействовать с объектами внутри схемы;CREATE(C) — разрешает создавать объекты внутри схемы и переименовывать их.
Создадим новую схему и выдадим на нее право на взаимодействие роли aspirant. Поскольку student за счет членства в grp_students является владельцем my_db на ровне с групповой ролью, переключимся на него и создадим схему my_schema.
aspirant@my_db=> \c - student
You are now connected to database "my_db" as user "student".
student@my_db=> CREATE SCHEMA my_schema;
CREATE SCHEMA
Чтобы выдать привилегию на взаимодействие с будущими объектами схемы, применяем ту же команду GRANT вместе с ключевым словом — SCHEMA.
student@my_db=> GRANT USAGE ON SCHEMA my_schema TO aspirant;
GRANT
Проверить выданные привилегии для конкретной схемы можно с помощью метакоманды \dn+ и указания названия схемы.
student@my_db=> \dn+ my_schema
List of schemas
Name | Owner | Access privileges | Description
-----------+----------+--------------------+----------
my_schema | student | student=UC/student+|
| | aspirant=U/student |
(1 row)
Привилегии на установку параметров
Суперпользователь может предоставить право изменять конкретные сессионные параметры с контекстом. Это позволяет делать привилегия SET (s). Также можно предоставить привилегию на изменение параметров на уровне экземпляра командой ALTER SYSTEM — привилегия ALTER SYSTEM с аббревиатурой (A).
Взаимодействовать со всеми параметрами может только суперпользователь или роль, которой были выданы такие привилегии. Поэтому для демонстрации выдачи привилегии на параметр переключимся на postgres.
student@my_db=> \c - postgres
You are now connected to database "my_db" as user "postgres".
Проверим привилегии на параметр commit_delay, позволяющий дожидаться в течение разрешенного времени фиксации сразу нескольких активных транзакций для снижения нагрузки на журнал предзаписи. Получить подробности о параметре можно метакомандой \dconfig+.
postgres@my_db=# \dconfig+ commit_delay
List of configuration parameters
Parameter | Value | Type | Context |Access privileges
--------------+----------+---------+-----------+--------------------
commit_delay | 0 | integer | superuser |
В поле Context стоит superuser, что не позволяет обычным пользователям менять данный параметр.
Выдадим роли student право менять его в рамках сессии. Для параметров используется ключевое слово PARAMETER.
postgres@my_db=# GRANT SET ON PARAMETER commit_delay TO student;
GRANT
Вновь проверим привилегии на параметр commit_delay.
postgres@my_db=# \dconfig+ commit_delay
List of configuration parameters
Parameter | Value | Type | Context |Access privileges
--------------+----------+---------+-----------+----------------------
commit_delay | 0 | integer | superuser | postgres=sA/postgres+
| | | | student=s/postgres
Другие привилегии
Реже остальных приходится взаимодействовать с последовательностями (ключевое слово для команды GRANT — SEQUENCE). Перечислим привилегии для них:
SELECT(r) — право вызывать функциюcurrvalдля получения ранее сгенерированного значения;UPDATE(w) — право на выполнение функцийnextvalдля получения нового значения последовательности иsetvalдля установки начального значения последовательности;USAGE(U) — право выполнять функцииcurrvalиnextval.
Кроме перечисленных выше привилегий есть еще несколько:
-
CREATE(C) — позволяет создавать объекты в табличных пространствах; -
EXECUTE(X) — позволяет выполнять функции и процедуры; -
USAGE(U):- использование процедурных языков;
- право выполнять функции
currvalиnextvalдля последовательностей; - право создания нового сервера для оберток внешних данных;
- позволяет создавать внешние таблицы для внешних серверов.
Привилегии, установленные на табличные пространства, можно увидеть с помощью метакоманды \db+. Привилегии на функции и процедуры показывает метакоманда \df+. Расширения для подключения внешних источников данных (FDW — Foreign Data Wrapper) будут обсуждаться далее по курсу.
Право передачи
В PostgreSQL также реализован механизм передачи привилегий ролью-получателем. Для этого в конце команды GRANT есть опция GRANT OPTION. Рассмотрим такой случай на примере.
Создадим новую таблицу и предоставим роли student привилегии на нее с правом передачи.
postgres@my_db=# CREATE TABLE suptab (s date);
CREATE TABLE
postgres@my_db=# GRANT SELECT ON suptab TO student WITH GRANT OPTION;
GRANT
Опция GRANT OPTION указывается после ключевого слова WITH в конце команды.
Переключимся на student и проверим привилегии на таблицу.
postgres@my_db=# \c - student
You are now connected to database "my_db" as user "student".
student@my_db=> \dp suptab
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+--------+---------+---------------------------+--------------------+----------
public | suptab | table | postgres=arwdDxt/postgres+| |
| | | student=r*/postgres | |
Сразу после буквенного обозначения привилегии SELECT (r) появился символ *, который означает, что роль может передавать данную привилегию.
Роль может передавать только те привилегии, при выдаче которых было указано право передачи. Если роли выдали несколько привилегий с правом передачи, запись привилегий в ACL будет выглядеть следующим образом:
student=r*а*/postgres
Попробуем передать привилегию чтения таблицы роли aspirant.
student@my_db=> GRANT SELECT ON suptab TO aspirant;
GRANT
student@my_db=> \dp suptab
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+--------+---------+---------------------------+--------------------+----------
public | suptab | table | postgres=arwdDxt/postgres+| |
| | | student=r*/postgres +| |
| | | aspirant=r/student | |
Привилегия успешно была передана, теперь читать таблицу могут и роль student, и роль aspirant.
Изъятие привилегий
Чтобы изъять привилегии, роль, выдавшая их, должна применить команду REVOKE с указанием изымаемой привилегии, объекта, на который она выдавалась, и собственно роли, у которой ее изымают. В случае необходимости изъятия права передачи, отнимать привилегии нужно в том порядке, в котором они выдавались.
Попробуем лишить роль aspirant привилегии чтения таблицы suptab от имени postgres.
student@my_db=> \c - postgres
You are now connected to database "my_db" as user "postgres".
postgres@my_db=# REVOKE SELECT ON suptab FROM aspirant;
REVOKE
postgres@my_db=# \dp suptab
Access privileges
Schema | Name | Type | Access privileges | Column privileges |
--------+--------+---------+---------------------------+--------------------+-
public | suptab | table | postgres=arwdDxt/postgres+| |
| | | student=r*/postgres +| |
| | | aspirant=r/student | |
(1 row)
Несмотря на вроде выполненный отзыв привилегий, в поле Access privileges в записи роли aspirant ничего не изменилось.
Это специфика команды REVOKE. При выполнении запроса на отзыв привилегий система не нашла те, которые можно было бы отозвать. Такая ситуация не считается ошибкой, поэтому и вернула стандартный вывод.
Роль postgres не выдавала привилегию SELECT роли aspirant, поэтому напрямую отозвать ее не может. Есть три варианта, как это можно сделать:
- отозвать привилегию от имени
student; - отозвать только те привилегии, которые
studentвыдавал с помощью права передачи, от имениpostgres; - отозвать все привилегии, которые
studentкогда-либо выдавал, от имениpostgres.
У каждого варианта есть свои плюсы и минусы. Так отзыв привилегий от имени роли student позволяет точечно ограничить роль aspirant, лишив ее только привилегии SELECT. Однако в таком случае требуется доступ к роли student. В нашем случае действия выполняются от имени суперпользователя, поэтому проблем с переключением на роль student не возникло бы. Второй вариант позволяет лишить привилегии SELECT все роли, которые получили данное право от student благодаря праву передачи (GRANT OPTION). Самый радикальный вариант — третий, когда отзываются все привилегии, которые student когда либо выдавал.
Примеры использования вариантов команды REVOKE
Предположим, что для таблицы suptab выданы следующие привилегии:
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+--------+-------+---------------------------+-------------------+----------
public | suptab | table | postgres=arwdDxt/postgres+| |
| | | student=ar*/postgres +| |
| | | aspirant=r/student | |
(1 rows)
Применим первый вариант.
-
Отозвать привилегию от имени
student. Необходимо переключиться на рольstudentи от его имени отозвать привилегию ролиaspirant.postgres@my_db=# SET ROLE student;SET ROLEpostgres@my_db=# REVOKE SELECT ON suptab FROM aspirant;REVOKEpostgres@my_db=# \dp suptabAccess privilegesSchema | Name | Type | Access privileges | Column privileges | Policies-------+--------+-------+---------------------------+-------------------+----------public | suptab | table | postgres=arwdDxt/postgres+| || | | student=ar*/postgres +| |(1 rows)Данный способ позволяет изъять определенную привилегию у нужной роли.
Применим второй вариант к той же ситуации с привилегиями.
-
Отозвать только те привилегии, которые
studentвыдавал с помощью права передачи, от имениpostgresможно двумя способами: с сохранением привилегииSELECTуstudentи с его изъятием.Если нет необходимости лишать роль
studentпривилегии на чтение таблицы, в начале командыREVOKEнужно указать ключевое словоGRANT OPTION FOR, а в конце —CASCADE. Первое ключевое слово лишит роль права передачи, но сохранит привилегию, а второе — изымет привилегию у всех ролей, которые получили ее отstudent.postgres@my_db=# REVOKE GRANT OPTION FOR SELECT ON suptab FROM student CASCADE;REVOKEpostgres@my_db=# \dp suptabAccess privilegesSchema | Name | Type | Access privileges | Column privileges | Policies--------+--------+-------+---------------------------+-------------------+----------public | suptab | table | postgres=arwdDxt/postgres+| || | | student=ar/postgres | |(1 rows)Если же нужно лишить привилегии
SELECTв том числе и саму рольstudent, ключевое словоGRANT OPTION FORне указывается.postgres@my_db=# REVOKE SELECT ON suptab FROM student CASCADE;REVOKEpostgres@my_db=# \dp suptabAccess privilegesSchema | Name | Type | Access privileges | Column privileges | Policies--------+--------+-------+---------------------------+-------------------+----------public | suptab | table | postgres=arwdDxt/postgres+| || | | student=a/postgres | |(1 rows)
Перед применением третьего варианта немного усложним ситуацию с привилегиями.
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+----------+-------+---------------------+-------------------+----------
public | suptab | table | student=r*/postgres+| |
| | | aspirant=r/student | |
public | suptab_1 | table | student=a*/postgres+| |
| | | aspirant=a/student | |
(2 rows)
Теперь есть две таблицы, в которых роль student имеет право передачи определенной привилегии, а роль aspirant получила их от student. Применим третий вариант.
-
Отозвать все привилегии, которые
studentкогда-либо выдавал, от имениpostgresможно с помощью ключевого словаALL PRIVILEGES ON. Поскольку есть две таблицы, на которые у ролиstudentесть привилегии, чтобы изъять их все, добавим связку ключевых словALL TABLES IN SCHEMA public. Такая команда лишит и рольstudentвсех привилегий на всех таблицы в общей схеме, но и роли, которые получили отstudentкакие-либо привилегии.postgres@my_db=# REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM student CASCADE;REVOKEpostgres@my_db=# \dpAccess privilegesSchema | Name | Type | Access privileges | Column privileges | Policies--------+----------+-------+--------------------------+-------------------+----------public | suptab | table | | |public | suptab_1 | table | | |(2 rows)Как видим, все привилегии исчезли. Данный способ является самым радикальным, и поэтому опасным.
Для демонстрации работы с отзывом не только привилегии, но и права передачи, выберем второй вариант. При указании ключевого слова GRANT OPTION роль student лишится права передачи привилегии, а ключевое слово CASCADE изымет привилегию у всех ролей, которые получили ее от student.
postgres@my_db=# REVOKE GRANT OPTION FOR SELECT ON suptab FROM student CASCADE;
REVOKE
Проверим привилегии на таблицу suptab.
postgres@my_db=# \dp suptab
Access privileges
Schema | Name | Type | Access privileges | Column privileges |
--------+--------+---------+---------------------------+--------------------+-
public | suptab | table | postgres=arwdDxt/postgres+| |
| | | student=r/postgres | |
Привилегии у роли aspirant пропали, но сохранились у student уже без символа *.
Права по умолчанию
Предоставлять каждый раз привилегии на новые объекты может быть весьма неудобно, поэтому в PostgreSQL есть механизм предоставления привилегий по умолчанию с помощью команды ALTER DEFAULT PRIVILEGES. Например, при установке привилегий по умолчанию на схему все новые объекты в ней автоматически получат данные привилегии.
Для примера создадим от имени student схему и установим на нее привилегии по умолчанию.
postgres@my_db=# \c - student
You are now connected to database "my_db" as user "student".
student@my_db=> CREATE SCHEMA def_sch;
CREATE SCHEMA
Установка привилегий по умолчанию не сильно отличается от выдачи привилегий: нужно только указать ключевое слово в начале и целевой объект.
student@my_db=> ALTER DEFAULT PRIVILEGES IN SCHEMA def_sch GRANT SELECT ON TABLES TO aspirant;
ALTER DEFAULT PRIVILEGES
Теперь при создании любой таблицы в схеме def_sch роль aspirant будет автоматически получать на них привилегию SELECT.
Для просмотра привилегий по умолчанию есть отдельная метакоманда \ddp.
student@my_db=> \ddp
Default access privileges
Owner | Schema | Type | Access privileges
----------+---------+-------+--------------------
student | def_sch | table | aspirant=r/student
(1 rows)
В выводе прописывается владелец схемы (student), тип объектов, на которые будут распространяться привилегии (table) и сама ACL запись, которая будет автоматически записана в метаданных объекта (aspirant=r/student).
Создадим в схеме def_sch пустую таблицу new_tab. Для этого нужно указать название схемы, а через точку — название таблицы. Чтобы создать пустую таблицу, можно использовать пустые скобки.
student@my_db=> CREATE TABLE def_sch.new_tab();
CREATE TABLE
Теперь проверим привилегии на новую таблицу.
student@my_db=> \dp def_sch.new_tab
Access privileges
Schema | Name | Type | Access privileges | Column privileges |
---------+---------+---------+-------------------------+--------------------+-
def_sch | new_tab | table | student=arwdDxt/student+| |
| | | aspirant=r/student | |
(1 row)
Роль aspirant успешно получила привилегию чтения для таблицы new_tab.
Итоги
- Привилегии хранятся в ACL в формате
grantee=privilege[*]/grantor; - Назначать привилегии могут владелец объекта, роль с правом передачи и суперпользователь;
- Команда
GRANTвыдает привилегии, командаREVOKE— изымает; - Для таблиц:
SELECT(r),INSERT(a),UPDATE(w),DELETE(d),TRUNCATE(D),REFERENCES(x),TRIGGER(t); - Для баз данных:
CREATE(C),CONNECT(c),TEMPORARY(T); - Для схем:
USAGE(U),CREATE(C); - Привилегии можно выдавать на отдельные столбцы таблицы:
GRANT SELECT(столбец) ON таблица TO роль; - Опция
GRANT OPTIONдает получателю право передавать привилегию — в ACL обозначается символом*; REVOKE … CASCADEизымает привилегии у всех ролей, получивших их через право передачи.
Самопроверка
Вопрос 1
Какие привилегии могут быть выданы на таблицы и представления? Выберите все верные варианты.
Вопрос 2
Выполнен запрос:
student@my_db=> GRANT SELECT(n),INSERT(n,t) ON ptab TO aspirant;
В выводе \dp ptab в столбце Column privileges для столбца n появится запись aspirant=ar/student. Что означает ar?
Вопрос 3
Какие привилегии могут быть выданы на базу данных? Выберите все верные варианты.
Вопрос 4
Выполнены команды:
postgres@my_db=# GRANT SELECT ON suptab TO student WITH GRANT OPTION;
student@my_db=> GRANT SELECT ON suptab TO aspirant;
В выводе \dp suptab для student в Access privileges появится символ. Какой?
Вопрос 5
Роль postgres пытается отозвать привилегию у aspirant, которую выдала student:
postgres@my_db=# REVOKE SELECT ON suptab FROM aspirant;
Что произойдет?
Вопрос 6
Выполнена команда:
postgres@my_db=# REVOKE GRANT OPTION FOR SELECT ON suptab FROM student CASCADE;
Что произойдет?
Вопрос 7
Выполнены команды:
student@my_db=> ALTER DEFAULT PRIVILEGES IN SCHEMA def_sch GRANT SELECT ON TABLES TO aspirant;
student@my_db=> CREATE TABLE def_sch.new_tab();
Какие привилегии получит aspirant на new_tab?