【PostgreSQL】ユーザ・ロールは何が違うのか？

## 初めに
初めてPostgreSQLに触れたときにユーザとロールの違いに困惑しました。
過去形にしてますが、この記事をまとめるまでなんとなく同じもんぐらいの認識でいました。
そんな曖昧な認識をこの記事で解消して下さい。

## 記事で得られること
- PostgreSQLについて詳しくなれる
- ユーザ・ロールについて理解できる

## ユーザ・ロールとは？
ユーザ・ロールと呼び方があるが、PostgreSQLの内部的にはロールで統一されています。
ログイン権限があればユーザ。逆にログイン権限がなければロール。という分け方で覚えておけば大丈夫です。
ではなぜログイン権限の可否で呼び方が変わるのか？

## `CREATE ROLE`と`CREATE USER`
なぜログイン権限の可否で呼び方が変わるのかは
`CREATE ROLE`と`CREATE USER`についてソースコードを見たら納得ができます。

まずは`CREATE ROLE`について、以下がソースコードです。
``` src/backend/parser/gram.y
CreateRoleStmt:
			CREATE ROLE RoleId opt_with OptRoleList
				{
					CreateRoleStmt *n = makeNode(CreateRoleStmt);

					n->stmt_type = ROLESTMT_ROLE;
					n->role = $3;
					n->options = $5;
					$$ = (Node *) n;
				}
		;
```

次に`CREATE USER`のソースコードです。
``` src/backend/parser/gram.y
/*****************************************************************************
 *
 * Create a new Postgres DBMS user (role with implied login ability)
 *
 *****************************************************************************/

CreateUserStmt:
			CREATE USER RoleId opt_with OptRoleList
				{
					CreateRoleStmt *n = makeNode(CreateRoleStmt);

					n->stmt_type = ROLESTMT_USER;
					n->role = $3;
					n->options = $5;
					$$ = (Node *) n;
				}
		;
```
`makeNode(CreateRoleStmt)`でCreateRoleStmtを利用しているので、`CREATE USER`を利用しても内部的にはロールを作成するようになっています。
また、`n->stmt_type`に`ROLESTMT_USER`を代入しているのも把握しておきます。
続いて、ログイン権限の可否について確認しましょう。
ログイン権限の可否はCreateRole()関数について読むと理解できます。
<details>
<summary>CreateRole()のソースコード</summary>

``` src/backend/commands/user.c
/*
 * CREATE ROLE
 */
Oid
CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
{
	Relation	pg_authid_rel;
	TupleDesc	pg_authid_dsc;
	HeapTuple	tuple;
	Datum		new_record[Natts_pg_authid] = {0};
	bool		new_record_nulls[Natts_pg_authid] = {0};
	Oid			currentUserId = GetUserId();
	Oid			roleid;
	ListCell   *item;
	ListCell   *option;
	char	   *password = NULL;	/* user password */
	bool		issuper = false;	/* Make the user a superuser? */
	bool		inherit = true; /* Auto inherit privileges? */
	bool		createrole = false; /* Can this user create roles? */
	bool		createdb = false;	/* Can the user create databases? */
	bool		canlogin = false;	/* Can this user login? */
	bool		isreplication = false;	/* Is this a replication role? */
	bool		bypassrls = false;	/* Is this a row security enabled role? */
	int			connlimit = -1; /* maximum connections allowed */
	List	   *addroleto = NIL;	/* roles to make this a member of */
	List	   *rolemembers = NIL;	/* roles to be members of this role */
	List	   *adminmembers = NIL; /* roles to be admins of this role */
	char	   *validUntil = NULL;	/* time the login is valid until */
	Datum		validUntil_datum;	/* same, as timestamptz Datum */
	bool		validUntil_null;
	DefElem    *dpassword = NULL;
	DefElem    *dissuper = NULL;
	DefElem    *dinherit = NULL;
	DefElem    *dcreaterole = NULL;
	DefElem    *dcreatedb = NULL;
	DefElem    *dcanlogin = NULL;
	DefElem    *disreplication = NULL;
	DefElem    *dconnlimit = NULL;
	DefElem    *daddroleto = NULL;
	DefElem    *drolemembers = NULL;
	DefElem    *dadminmembers = NULL;
	DefElem    *dvalidUntil = NULL;
	DefElem    *dbypassRLS = NULL;
	GrantRoleOptions popt;

	/* The defaults can vary depending on the original statement type */
	switch (stmt->stmt_type)
	{
		case ROLESTMT_ROLE:
			break;
		case ROLESTMT_USER:
			canlogin = true;
			/* may eventually want inherit to default to false here */
			break;
		case ROLESTMT_GROUP:
			break;
	}
```

</details>

`bool canlogin = false;`としているので`CREATE ROLE`はデフォルトでログイン権限がありません。
そしてswitch文の箇所で`ROLESTMT_USER`であればログイン権限が付与されるように書かれています。
`CREATE USER`の`stmt_type`で`ROLESTMT_USER`が記載されていたのはこの箇所で利用されてました。
```
	switch (stmt->stmt_type)
	{
		case ROLESTMT_ROLE:
			break;
		case ROLESTMT_USER:
			canlogin = true;
			/* may eventually want inherit to default to false here */
			break;
		case ROLESTMT_GROUP:
			break;
	}
 ```

 以上の理由からログイン権限の可否でユーザ・ロールを分けていることが理解できます。

 ## まとめ
 ユーザ・ロールの違いについては以下の通り
 - ユーザは作成時デフォルトでログイン権限がある
 - ロールは作成時デフォルトでログイン権限がない

会話の中での使い分けを理由も知った上でできればちょいとできる人と思われるので有効活用して下さい（？）