Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1x1pjs-005RQo-1a for pgsql-admin@arkaria.postgresql.org; Wed, 02 Sep 2026 18:31:12 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1x1pjr-00Ddbx-0O for pgsql-admin@arkaria.postgresql.org; Wed, 02 Sep 2026 18:31:11 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1x1pjq-00Ddbo-1Z for pgsql-admin@lists.postgresql.org; Wed, 02 Sep 2026 18:31:10 +0000 Received: from mail-wm1-x336.google.com ([2a00:1450:4864:20::336]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1x1pjn-00000003g3p-2qNd for pgsql-admin@lists.postgresql.org; Wed, 02 Sep 2026 18:31:09 +0000 Received: by mail-wm1-x336.google.com with SMTP id 5b1f17b1804b1-49b0d78a801so11587955e9.2 for ; Wed, 02 Sep 2026 11:31:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788373866; x=1788978666; darn=lists.postgresql.org; h=in-reply-to:from:content-language:references:cc:to:subject :user-agent:mime-version:date:message-id:content-type:from:to:cc :subject:date:message-id:reply-to:content-type; bh=X7J1W9hkG8Je6OKnP067VVDmdxyMW2DhaJDCfLUyyj4=; b=UO+XznnKi/5I10bnp6xEjT2mXAVdeKtjrLeoSLKYGFiB3zgmbo8U4dHp7CHXtSpMuG 0Nh2JKhMi4zcP0TDcBsRfe09MzLQQxTHvpeZxFkdOCeOHcQD02rdgPbTohM6+rI1ziHl CLBgYkO11HBXwHLIpGWG/5gHucrBuUWChAL2JsaMtVupc+APIKpcUZuIFFTvoOYwWUHt eZpEhmTJG4OQFCXpAjk1yjVD6AaLZn4qxq10zZEOo7LZc0ziiStjT81DfoSh8K1YBnsx MXOaRYrC0IZkp9EXBGw8z4x1hYy03wQbRI400axC9F/7NIn4TyvH/+YQVq7cYAdj78Se +pTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788373866; x=1788978666; h=in-reply-to:from:content-language:references:cc:to:subject :user-agent:mime-version:date:message-id:content-type:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=X7J1W9hkG8Je6OKnP067VVDmdxyMW2DhaJDCfLUyyj4=; b=QW7CCMahhikPYkf5BDWbw723LAAdRqWZtARwUgo3HCVrULnkiohfhz6ZZCAocaGunc NzL/jQ9B6JRGBDJ9dlCKveRX41zil2EMbdVF1Xcf+tEbXtOPlj3VcULGYLwIQ3YZ5hb/ FeMGwVEbhXcUabDDEzPEGsjrcPnsjzRbycnhND7OEDBH5f5HlyD6y0LSZJV6/7Hx0lhS yHWlpoCXwtFuZ0Gpjs7LYtPMUggAqFzHKI4SWS7mtDKP0HVe+96DhNrRwxSolGG4PzA+ f2m+8e+4KSuv48GtxueRZVixV+nMD7x3MKYoh0a8fEAf0W2R5fycq8I6qZN8Drxwowhv v3pw== X-Gm-Message-State: AFuF++lJp1K8rAaj6ZaXS2jQevSQ0fcLziv2TCbLMWSvme+bJPdPRt6e qyaNTpHKJt3wTZO3YK63s9LW8pOfAvUbQ+SktV+SVFrtM6Ufwaba7MD4 X-Gm-Gg: AYBFou1G5Vls2HJ/ugA11Ms/rsyaoW7dXCOhnGqs/QyumU3SoLIR0M+5XWceRnLu0eH J6sH2bIH7ADWqSew+v/S5wWl78++vERN6FeYBePeLqOkX6gZG48rEnBLpBB8evnPufboHWUJHkt 6pJZrtHtxmP/OE8E5TbZaxMS5lPKktgW/wTr9vvImDXa7rW5XXOmQ1CqgjmPq7R1y+pBpa4AtzB zxA1iaHR/jsSZyZkGvsmOo0gu9v9ZNBUF8ktpYfcJ8+kSl7Zw/AW3om92idXGg0+cjqYZN8E02l bvh80OM6unPGX3lljqfmgOzaCxfa7Wp2LmS0foVS9zUKx3Q3VQCrwjLezjE/sqxPgpRpxnWIpRZ KYzuDA4D01n2VC4jkdJNBQD5mugVJ1HCQTfbcVQ512Mwu75MTqoFVvUtAiQGMkMQPMKDxLl885j eH1HBnuqJ9c7r8Q6bkU2UEbNejeXLjlV6GHRQGzVU0tPT/ZUu9qH++DAl052LIFiZi7xgM+aRu7 S4i84LOQP13RyLEZoumLAucb0zAxUd8YJq9n2jGDhIb77ztQden X-Received: by 2002:a05:600c:4ed0:b0:499:726a:a017 with SMTP id 5b1f17b1804b1-49ce57ec163mr130707975e9.1.1788373865968; Wed, 02 Sep 2026 11:31:05 -0700 (PDT) Received: from ?IPV6:2a01:e0a:bf8:b480:cc05:cac1:2948:f472? ([2a01:e0a:bf8:b480:cc05:cac1:2948:f472]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-49ce5927b68sm71609865e9.1.2026.09.02.11.31.05 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 02 Sep 2026 11:31:05 -0700 (PDT) Content-Type: multipart/alternative; boundary="------------pr7AIykLLwf8WyXRWZpVz8y0" Message-ID: <6c814776-0a02-4b31-9a5e-ab281fa9e4fe@gmail.com> Date: Wed, 2 Sep 2026 20:31:05 +0200 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: what is the difference between ROLE clause and IN ROLE clause for CREATE USER statement ? To: Benjamin Leis Cc: pgsql-admin@lists.postgresql.org, sonicmonkey@gmail.com References: Content-Language: en-US From: Pierre Forstmann In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk This is a multi-part message in MIME format. --------------pr7AIykLLwf8WyXRWZpVz8y0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit I have asked chatgpt which says: /CREATE USER ur  ROLE    pg_maintain;  -- pg_maintain is a member of ur CREATE USER uri IN ROLE pg_maintain;  -- uri is a member of pg_maintain / /which creates following role hierarchy:/ /ur ↑ pg_maintain ↑ uri/ / / /and *only |uri| is below |pg_maintain| in the membership hierarchy, so |uri| inherits |pg_maintain|'s maintenance privileges.*/ /That is exactly why |vacuumdb -U uri| succeeds while |vacuumdb -U ur| skips the catalogs./ Even if know that roles and users are almost the same entities in PG, I find this confusing. Thanks. Le 02/09/2026 à 07:52, Benjamin Leis a écrit : > I think create in role makes the user a member of the specified role. > While create role makes the roles members of this new user group.  So > it's a question of which is the container and what is being contained. > > On Tue, Sep 1, 2026, 10:16 PM Pierre Forstmann > wrote: > > Hello, > > I don't understand the difference even after reading CREATE > USER/CREATE > ROLE documentation. > > Here is a scenario that shows a difference with PG 18.6 (built > with pgenv): > > pierre=# create user ur role pg_maintain; > CREATE ROLE > pierre=# create user uri  in role pg_maintain; > CREATE ROLE > pierre=# \du >                               List of roles >   Role name |                         Attributes > -----------+------------------------------------------------------------ >   pierre    | Superuser >   postgres  | Superuser, Create role, Create DB, Replication, > Bypass RLS >   ur        | >   uri       | > > pierre=# \l >                                                       List of > databases >     Name    |  Owner   | Encoding | Locale Provider |  Collate  | > Ctype    | Locale | ICU Rules |   Access privileges > -----------+----------+----------+-----------------+-------------+-------------+--------+-----------+----------------------- >   pierre    | pierre   | UTF8     | libc            | en_US.UTF-8 | > en_US.UTF-8 |        |           | >   postgres  | postgres | UTF8     | libc            | en_US.UTF-8 | > en_US.UTF-8 |        |           | >   template0 | postgres | UTF8     | libc            | en_US.UTF-8 | > en_US.UTF-8 |        |           | =c/postgres          + >             |          |          |                 |  |        | >        |           | postgres=CTc/postgres >   template1 | postgres | UTF8     | libc            | en_US.UTF-8 | > en_US.UTF-8 |        |           | =c/postgres          + >             |          |          |                 |  |        | >        |           | postgres=CTc/postgres > (4 rows) > > > pierre@alma:~$ vacuumdb -U ur > vacuumdb: vacuuming database "pierre" > WARNING:  permission denied to vacuum "pg_proc", skipping it > WARNING:  permission denied to vacuum "pg_attribute", skipping it > WARNING:  permission denied to vacuum "pg_description", skipping it > WARNING:  permission denied to vacuum "pg_collation", skipping it > WARNING:  permission denied to vacuum "pg_statistic", skipping it > WARNING:  permission denied to vacuum "pg_type", skipping it > WARNING:  permission denied to vacuum "pg_class", skipping it > WARNING:  permission denied to vacuum "pg_rewrite", skipping it > WARNING:  permission denied to vacuum "pg_operator", skipping it > WARNING:  permission denied to vacuum "pg_depend", skipping it > WARNING:  permission denied to vacuum "sql_features", skipping it > WARNING:  permission denied to vacuum "pg_amop", skipping it > WARNING:  permission denied to vacuum "pg_constraint", skipping it > WARNING:  permission denied to vacuum "pg_amproc", skipping it > WARNING:  permission denied to vacuum "pg_ts_config_map", skipping it > WARNING:  permission denied to vacuum "pg_index", skipping it > WARNING:  permission denied to vacuum "pg_init_privs", skipping it > WARNING:  permission denied to vacuum "pg_opclass", skipping it > WARNING:  permission denied to vacuum "pg_aggregate", skipping it > WARNING:  permission denied to vacuum "pg_cast", skipping it > WARNING:  permission denied to vacuum "pg_opfamily", skipping it > WARNING:  permission denied to vacuum "pg_conversion", skipping it > WARNING:  permission denied to vacuum "pg_namespace", skipping it > WARNING:  permission denied to vacuum "sql_implementation_info", > skipping it > WARNING:  permission denied to vacuum "pg_am", skipping it > WARNING:  permission denied to vacuum "pg_language", skipping it > WARNING:  permission denied to vacuum "pg_authid", skipping it > WARNING:  permission denied to vacuum "pg_database", skipping it > WARNING:  permission denied to vacuum "pg_tablespace", skipping it > WARNING:  permission denied to vacuum "pg_auth_members", skipping it > WARNING:  permission denied to vacuum "pg_shdescription", skipping it > WARNING:  permission denied to vacuum "pg_ts_config", skipping it > WARNING:  permission denied to vacuum "pg_ts_dict", skipping it > WARNING:  permission denied to vacuum "pg_ts_parser", skipping it > WARNING:  permission denied to vacuum "pg_ts_template", skipping it > WARNING:  permission denied to vacuum "pg_extension", skipping it > WARNING:  permission denied to vacuum "pg_range", skipping it > WARNING:  permission denied to vacuum "sql_parts", skipping it > WARNING:  permission denied to vacuum "sql_sizing", skipping it > WARNING:  permission denied to vacuum "pg_shdepend", skipping it > WARNING:  permission denied to vacuum "pg_transform", skipping it > WARNING:  permission denied to vacuum "pg_sequence", skipping it > WARNING:  permission denied to vacuum "pg_subscription", skipping it > WARNING:  permission denied to vacuum "pg_publication", skipping it > WARNING:  permission denied to vacuum "pg_publication_namespace", > skipping it > WARNING:  permission denied to vacuum "pg_publication_rel", > skipping it > WARNING:  permission denied to vacuum "pg_subscription_rel", > skipping it > WARNING:  permission denied to vacuum "pg_foreign_data_wrapper", > skipping it > WARNING:  permission denied to vacuum "pg_foreign_server", skipping it > WARNING:  permission denied to vacuum "pg_policy", skipping it > WARNING:  permission denied to vacuum "pg_replication_origin", > skipping it > WARNING:  permission denied to vacuum "pg_default_acl", skipping it > WARNING:  permission denied to vacuum "pg_inherits", skipping it > WARNING:  permission denied to vacuum "pg_seclabel", skipping it > WARNING:  permission denied to vacuum "pg_shseclabel", skipping it > WARNING:  permission denied to vacuum "pg_user_mapping", skipping it > WARNING:  permission denied to vacuum "pg_trigger", skipping it > WARNING:  permission denied to vacuum "pg_event_trigger", skipping it > WARNING:  permission denied to vacuum "pg_statistic_ext_data", > skipping it > WARNING:  permission denied to vacuum "pg_statistic_ext", skipping it > WARNING:  permission denied to vacuum "pg_enum", skipping it > WARNING:  permission denied to vacuum "pg_attrdef", skipping it > WARNING:  permission denied to vacuum "pg_largeobject_metadata", > skipping it > WARNING:  permission denied to vacuum "pg_foreign_table", skipping it > WARNING:  permission denied to vacuum "pg_parameter_acl", skipping it > WARNING:  permission denied to vacuum "pg_db_role_setting", > skipping it > WARNING:  permission denied to vacuum "pg_partitioned_table", > skipping it > WARNING:  permission denied to vacuum "pg_largeobject", skipping it > pierre@alma:~$ vacuumdb -U uri > vacuumdb: vacuuming database "pierre" > pierre@alma:~$ > > > Thanks. > > > --------------pr7AIykLLwf8WyXRWZpVz8y0 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 8bit

I have asked chatgpt which says:

CREATE USER ur  ROLE    pg_maintain;  -- pg_maintain is a member of ur
CREATE USER uri IN ROLE pg_maintain;  -- uri is a member of pg_maintain

which creates following role hierarchy:

ur

pg_maintain

uri


and only uri is below pg_maintain in the membership hierarchy, so uri inherits pg_maintain's maintenance privileges.

That is exactly why vacuumdb -U uri succeeds while vacuumdb -U ur skips the catalogs.


Even if know that roles and users are almost the same entities in PG, I find this confusing.

Thanks.


Le 02/09/2026 à 07:52, Benjamin Leis a écrit :
I think create in role makes the user a member of the specified role. While create role makes the roles members of this new user group.  So it's a question of which is the container and what is being contained. 

On Tue, Sep 1, 2026, 10:16 PM Pierre Forstmann <pierre.forstmann@gmail.com> wrote:
Hello,

I don't understand the difference even after reading CREATE USER/CREATE
ROLE documentation.

Here is a scenario that shows a difference with PG 18.6 (built with pgenv):

pierre=# create user ur role pg_maintain;
CREATE ROLE
pierre=# create user uri  in role pg_maintain;
CREATE ROLE
pierre=# \du
                              List of roles
  Role name |                         Attributes
-----------+------------------------------------------------------------
  pierre    | Superuser
  postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS
  ur        |
  uri       |

pierre=# \l
                                                      List of databases
    Name    |  Owner   | Encoding | Locale Provider |   Collate  |   
Ctype    | Locale | ICU Rules |   Access privileges
-----------+----------+----------+-----------------+-------------+-------------+--------+-----------+-----------------------
  pierre    | pierre   | UTF8     | libc            | en_US.UTF-8 |
en_US.UTF-8 |        |           |
  postgres  | postgres | UTF8     | libc            | en_US.UTF-8 |
en_US.UTF-8 |        |           |
  template0 | postgres | UTF8     | libc            | en_US.UTF-8 |
en_US.UTF-8 |        |           | =c/postgres          +
            |          |          |                 |  |             | 
       |           | postgres=CTc/postgres
  template1 | postgres | UTF8     | libc            | en_US.UTF-8 |
en_US.UTF-8 |        |           | =c/postgres          +
            |          |          |                 |  |             | 
       |           | postgres=CTc/postgres
(4 rows)


pierre@alma:~$ vacuumdb -U ur
vacuumdb: vacuuming database "pierre"
WARNING:  permission denied to vacuum "pg_proc", skipping it
WARNING:  permission denied to vacuum "pg_attribute", skipping it
WARNING:  permission denied to vacuum "pg_description", skipping it
WARNING:  permission denied to vacuum "pg_collation", skipping it
WARNING:  permission denied to vacuum "pg_statistic", skipping it
WARNING:  permission denied to vacuum "pg_type", skipping it
WARNING:  permission denied to vacuum "pg_class", skipping it
WARNING:  permission denied to vacuum "pg_rewrite", skipping it
WARNING:  permission denied to vacuum "pg_operator", skipping it
WARNING:  permission denied to vacuum "pg_depend", skipping it
WARNING:  permission denied to vacuum "sql_features", skipping it
WARNING:  permission denied to vacuum "pg_amop", skipping it
WARNING:  permission denied to vacuum "pg_constraint", skipping it
WARNING:  permission denied to vacuum "pg_amproc", skipping it
WARNING:  permission denied to vacuum "pg_ts_config_map", skipping it
WARNING:  permission denied to vacuum "pg_index", skipping it
WARNING:  permission denied to vacuum "pg_init_privs", skipping it
WARNING:  permission denied to vacuum "pg_opclass", skipping it
WARNING:  permission denied to vacuum "pg_aggregate", skipping it
WARNING:  permission denied to vacuum "pg_cast", skipping it
WARNING:  permission denied to vacuum "pg_opfamily", skipping it
WARNING:  permission denied to vacuum "pg_conversion", skipping it
WARNING:  permission denied to vacuum "pg_namespace", skipping it
WARNING:  permission denied to vacuum "sql_implementation_info", skipping it
WARNING:  permission denied to vacuum "pg_am", skipping it
WARNING:  permission denied to vacuum "pg_language", skipping it
WARNING:  permission denied to vacuum "pg_authid", skipping it
WARNING:  permission denied to vacuum "pg_database", skipping it
WARNING:  permission denied to vacuum "pg_tablespace", skipping it
WARNING:  permission denied to vacuum "pg_auth_members", skipping it
WARNING:  permission denied to vacuum "pg_shdescription", skipping it
WARNING:  permission denied to vacuum "pg_ts_config", skipping it
WARNING:  permission denied to vacuum "pg_ts_dict", skipping it
WARNING:  permission denied to vacuum "pg_ts_parser", skipping it
WARNING:  permission denied to vacuum "pg_ts_template", skipping it
WARNING:  permission denied to vacuum "pg_extension", skipping it
WARNING:  permission denied to vacuum "pg_range", skipping it
WARNING:  permission denied to vacuum "sql_parts", skipping it
WARNING:  permission denied to vacuum "sql_sizing", skipping it
WARNING:  permission denied to vacuum "pg_shdepend", skipping it
WARNING:  permission denied to vacuum "pg_transform", skipping it
WARNING:  permission denied to vacuum "pg_sequence", skipping it
WARNING:  permission denied to vacuum "pg_subscription", skipping it
WARNING:  permission denied to vacuum "pg_publication", skipping it
WARNING:  permission denied to vacuum "pg_publication_namespace",
skipping it
WARNING:  permission denied to vacuum "pg_publication_rel", skipping it
WARNING:  permission denied to vacuum "pg_subscription_rel", skipping it
WARNING:  permission denied to vacuum "pg_foreign_data_wrapper", skipping it
WARNING:  permission denied to vacuum "pg_foreign_server", skipping it
WARNING:  permission denied to vacuum "pg_policy", skipping it
WARNING:  permission denied to vacuum "pg_replication_origin", skipping it
WARNING:  permission denied to vacuum "pg_default_acl", skipping it
WARNING:  permission denied to vacuum "pg_inherits", skipping it
WARNING:  permission denied to vacuum "pg_seclabel", skipping it
WARNING:  permission denied to vacuum "pg_shseclabel", skipping it
WARNING:  permission denied to vacuum "pg_user_mapping", skipping it
WARNING:  permission denied to vacuum "pg_trigger", skipping it
WARNING:  permission denied to vacuum "pg_event_trigger", skipping it
WARNING:  permission denied to vacuum "pg_statistic_ext_data", skipping it
WARNING:  permission denied to vacuum "pg_statistic_ext", skipping it
WARNING:  permission denied to vacuum "pg_enum", skipping it
WARNING:  permission denied to vacuum "pg_attrdef", skipping it
WARNING:  permission denied to vacuum "pg_largeobject_metadata", skipping it
WARNING:  permission denied to vacuum "pg_foreign_table", skipping it
WARNING:  permission denied to vacuum "pg_parameter_acl", skipping it
WARNING:  permission denied to vacuum "pg_db_role_setting", skipping it
WARNING:  permission denied to vacuum "pg_partitioned_table", skipping it
WARNING:  permission denied to vacuum "pg_largeobject", skipping it
pierre@alma:~$ vacuumdb -U uri
vacuumdb: vacuuming database "pierre"
pierre@alma:~$


Thanks.



--------------pr7AIykLLwf8WyXRWZpVz8y0--