mirror of https://github.com/citusdata/citus.git
Create the ALTER ROLE propagation
parent
217890af5f
commit
5ae7b219ff
|
@ -0,0 +1,281 @@
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* role.c
|
||||||
|
* Commands for ALTER ROLE statements.
|
||||||
|
*
|
||||||
|
* Copyright (c) Citus Data, Inc.
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "access/heapam.h"
|
||||||
|
#include "access/htup_details.h"
|
||||||
|
#if PG_VERSION_NUM >= 120000
|
||||||
|
#include "access/table.h"
|
||||||
|
#endif
|
||||||
|
#include "catalog/catalog.h"
|
||||||
|
#include "catalog/pg_authid.h"
|
||||||
|
#include "distributed/citus_ruleutils.h"
|
||||||
|
#include "distributed/commands.h"
|
||||||
|
#include "distributed/commands/utility_hook.h"
|
||||||
|
#include "distributed/deparser.h"
|
||||||
|
#include "distributed/master_protocol.h"
|
||||||
|
#include "distributed/worker_transaction.h"
|
||||||
|
#include "nodes/makefuncs.h"
|
||||||
|
#include "nodes/parsenodes.h"
|
||||||
|
#include "utils/acl.h"
|
||||||
|
#include "utils/builtins.h"
|
||||||
|
#include "utils/rel.h"
|
||||||
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
static const char * ExtractEncryptedPassword(Oid roleOid);
|
||||||
|
static const char * CreateAlterRoleIfExistsCommand(AlterRoleStmt *stmt);
|
||||||
|
static DefElem * makeDefElemInt(char *name, int value);
|
||||||
|
|
||||||
|
/* controlled via GUC */
|
||||||
|
bool EnableAlterRolePropagation = false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ProcessAlterRoleStmt actually creates the plan we need to execute for alter
|
||||||
|
* role statement. We need to do it this way because we need to use the encrypted
|
||||||
|
* password, which is, in some cases, created at standardProcessUtility.
|
||||||
|
*/
|
||||||
|
List *
|
||||||
|
ProcessAlterRoleStmt(AlterRoleStmt *stmt, const char *queryString)
|
||||||
|
{
|
||||||
|
ListCell *optionCell = NULL;
|
||||||
|
List *commands = NIL;
|
||||||
|
|
||||||
|
if (!EnableAlterRolePropagation || !IsCoordinator())
|
||||||
|
{
|
||||||
|
return NIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure that no new nodes are added after this point until the end of the
|
||||||
|
* transaction by taking a RowShareLock on pg_dist_node, which conflicts with the
|
||||||
|
* ExclusiveLock taken by master_add_node.
|
||||||
|
*/
|
||||||
|
LockRelationOid(DistNodeRelationId(), RowShareLock);
|
||||||
|
|
||||||
|
foreach(optionCell, stmt->options)
|
||||||
|
{
|
||||||
|
DefElem *option = (DefElem *) lfirst(optionCell);
|
||||||
|
|
||||||
|
if (strcasecmp(option->defname, "password") == 0)
|
||||||
|
{
|
||||||
|
Oid roleOid = get_rolespec_oid(stmt->role, true);
|
||||||
|
const char *encryptedPassword = ExtractEncryptedPassword(roleOid);
|
||||||
|
|
||||||
|
if (encryptedPassword != NULL)
|
||||||
|
{
|
||||||
|
Value *encryptedPasswordValue = makeString((char *) encryptedPassword);
|
||||||
|
option->arg = (Node *) encryptedPasswordValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
option->arg = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
commands = list_make1((void *) CreateAlterRoleIfExistsCommand(stmt));
|
||||||
|
|
||||||
|
return NodeDDLTaskList(ALL_WORKERS, commands);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CreateAlterRoleIfExistsCommand creates ALTER ROLE command, from the alter role node
|
||||||
|
* using the alter_role_if_exists() UDF.
|
||||||
|
*/
|
||||||
|
static const char *
|
||||||
|
CreateAlterRoleIfExistsCommand(AlterRoleStmt *stmt)
|
||||||
|
{
|
||||||
|
StringInfoData alterRoleQueryBuffer = { 0 };
|
||||||
|
const char *roleName = RoleSpecString(stmt->role, false);
|
||||||
|
const char *alterRoleQuery = DeparseTreeNode((Node *) stmt);
|
||||||
|
|
||||||
|
initStringInfo(&alterRoleQueryBuffer);
|
||||||
|
appendStringInfo(&alterRoleQueryBuffer,
|
||||||
|
"SELECT alter_role_if_exists(%s, %s)",
|
||||||
|
quote_literal_cstr(roleName),
|
||||||
|
quote_literal_cstr(alterRoleQuery));
|
||||||
|
|
||||||
|
return alterRoleQueryBuffer.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ExtractEncryptedPassword extracts the encrypted password of a role. The function
|
||||||
|
* gets the password from the pg_authid table.
|
||||||
|
*/
|
||||||
|
static const char *
|
||||||
|
ExtractEncryptedPassword(Oid roleOid)
|
||||||
|
{
|
||||||
|
Relation pgAuthId = heap_open(AuthIdRelationId, AccessShareLock);
|
||||||
|
TupleDesc pgAuthIdDescription = RelationGetDescr(pgAuthId);
|
||||||
|
HeapTuple tuple = SearchSysCache1(AUTHOID, roleOid);
|
||||||
|
bool isNull = true;
|
||||||
|
Datum passwordDatum;
|
||||||
|
|
||||||
|
if (!HeapTupleIsValid(tuple))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
passwordDatum = heap_getattr(tuple, Anum_pg_authid_rolpassword,
|
||||||
|
pgAuthIdDescription, &isNull);
|
||||||
|
|
||||||
|
heap_close(pgAuthId, AccessShareLock);
|
||||||
|
ReleaseSysCache(tuple);
|
||||||
|
|
||||||
|
if (isNull)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pstrdup(TextDatumGetCString(passwordDatum));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GenerateAlterRoleIfExistsCommand generate ALTER ROLE command that copies a role from
|
||||||
|
* the pg_authid table.
|
||||||
|
*/
|
||||||
|
static const char *
|
||||||
|
GenerateAlterRoleIfExistsCommand(HeapTuple tuple, TupleDesc pgAuthIdDescription)
|
||||||
|
{
|
||||||
|
char *rolPassword = "";
|
||||||
|
char *rolValidUntil = "infinity";
|
||||||
|
Datum rolValidUntilDatum;
|
||||||
|
Datum rolPasswordDatum;
|
||||||
|
bool isNull = true;
|
||||||
|
Form_pg_authid role = ((Form_pg_authid) GETSTRUCT(tuple));
|
||||||
|
AlterRoleStmt *stmt = makeNode(AlterRoleStmt);
|
||||||
|
const char *rolename = NameStr(role->rolname);
|
||||||
|
|
||||||
|
stmt->role = makeNode(RoleSpec);
|
||||||
|
stmt->role->roletype = ROLESPEC_CSTRING;
|
||||||
|
stmt->role->location = -1;
|
||||||
|
stmt->role->rolename = pstrdup(rolename);
|
||||||
|
stmt->action = 1;
|
||||||
|
stmt->options = NIL;
|
||||||
|
|
||||||
|
stmt->options =
|
||||||
|
lappend(stmt->options,
|
||||||
|
makeDefElemInt("superuser", role->rolsuper));
|
||||||
|
|
||||||
|
stmt->options =
|
||||||
|
lappend(stmt->options,
|
||||||
|
makeDefElemInt("createdb", role->rolcreatedb));
|
||||||
|
|
||||||
|
stmt->options =
|
||||||
|
lappend(stmt->options,
|
||||||
|
makeDefElemInt("createrole", role->rolcreaterole));
|
||||||
|
|
||||||
|
stmt->options =
|
||||||
|
lappend(stmt->options,
|
||||||
|
makeDefElemInt("inherit", role->rolinherit));
|
||||||
|
|
||||||
|
stmt->options =
|
||||||
|
lappend(stmt->options,
|
||||||
|
makeDefElemInt("canlogin", role->rolcanlogin));
|
||||||
|
|
||||||
|
stmt->options =
|
||||||
|
lappend(stmt->options,
|
||||||
|
makeDefElemInt("isreplication", role->rolreplication));
|
||||||
|
|
||||||
|
stmt->options =
|
||||||
|
lappend(stmt->options,
|
||||||
|
makeDefElemInt("bypassrls", role->rolbypassrls));
|
||||||
|
|
||||||
|
|
||||||
|
stmt->options =
|
||||||
|
lappend(stmt->options,
|
||||||
|
makeDefElemInt("connectionlimit", role->rolconnlimit));
|
||||||
|
|
||||||
|
|
||||||
|
rolPasswordDatum = heap_getattr(tuple, Anum_pg_authid_rolpassword,
|
||||||
|
pgAuthIdDescription, &isNull);
|
||||||
|
if (!isNull)
|
||||||
|
{
|
||||||
|
rolPassword = pstrdup(TextDatumGetCString(rolPasswordDatum));
|
||||||
|
stmt->options = lappend(stmt->options, makeDefElem("password",
|
||||||
|
(Node *) makeString(
|
||||||
|
rolPassword),
|
||||||
|
-1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stmt->options = lappend(stmt->options, makeDefElem("password", NULL, -1));
|
||||||
|
}
|
||||||
|
|
||||||
|
rolValidUntilDatum = heap_getattr(tuple, Anum_pg_authid_rolvaliduntil,
|
||||||
|
pgAuthIdDescription, &isNull);
|
||||||
|
if (!isNull)
|
||||||
|
{
|
||||||
|
rolValidUntil = pstrdup((char *) timestamptz_to_str(rolValidUntilDatum));
|
||||||
|
}
|
||||||
|
|
||||||
|
stmt->options = lappend(stmt->options, makeDefElem("validUntil",
|
||||||
|
(Node *) makeString(rolValidUntil),
|
||||||
|
-1));
|
||||||
|
|
||||||
|
return CreateAlterRoleIfExistsCommand(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GenerateAlterRoleIfExistsCommandAllRoles creates ALTER ROLE commands
|
||||||
|
* that copies all roles from the pg_authid table.
|
||||||
|
*/
|
||||||
|
List *
|
||||||
|
GenerateAlterRoleIfExistsCommandAllRoles()
|
||||||
|
{
|
||||||
|
Relation pgAuthId = heap_open(AuthIdRelationId, AccessShareLock);
|
||||||
|
TupleDesc pgAuthIdDescription = RelationGetDescr(pgAuthId);
|
||||||
|
HeapTuple tuple = NULL;
|
||||||
|
List *commands = NIL;
|
||||||
|
const char *alterRoleQuery = NULL;
|
||||||
|
|
||||||
|
#if PG_VERSION_NUM >= 120000
|
||||||
|
TableScanDesc scan = table_beginscan_catalog(pgAuthId, 0, NULL);
|
||||||
|
#else
|
||||||
|
HeapScanDesc scan = heap_beginscan_catalog(pgAuthId, 0, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||||
|
{
|
||||||
|
const char *rolename = NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The default roles are skipped, because reserved roles
|
||||||
|
* cannot be altered.
|
||||||
|
*/
|
||||||
|
if (IsReservedName(rolename))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
alterRoleQuery = GenerateAlterRoleIfExistsCommand(tuple, pgAuthIdDescription);
|
||||||
|
commands = lappend(commands, (void *) alterRoleQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
heap_endscan(scan);
|
||||||
|
heap_close(pgAuthId, AccessShareLock);
|
||||||
|
|
||||||
|
return commands;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* makeDefElemInt creates a DefElem with integer typed value with -1 as location.
|
||||||
|
*/
|
||||||
|
static DefElem *
|
||||||
|
makeDefElemInt(char *name, int value)
|
||||||
|
{
|
||||||
|
return makeDefElem(name, (Node *) makeInteger(value), -1);
|
||||||
|
}
|
|
@ -739,6 +739,38 @@ multi_ProcessUtility(PlannedStmt *pstmt,
|
||||||
ddlJobs = ProcessCreateFunctionStmt(castNode(CreateFunctionStmt, parsetree),
|
ddlJobs = ProcessCreateFunctionStmt(castNode(CreateFunctionStmt, parsetree),
|
||||||
queryString);
|
queryString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsA(parsetree, AlterRoleStmt))
|
||||||
|
{
|
||||||
|
Assert(ddlJobs == NIL); /* jobs should not have been set before */
|
||||||
|
ddlJobs = ProcessAlterRoleStmt(castNode(AlterRoleStmt, parsetree),
|
||||||
|
queryString);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsA(parsetree, AlterRoleSetStmt) && EnableAlterRolePropagation)
|
||||||
|
{
|
||||||
|
ereport(NOTICE, (errmsg("Citus partially supports ALTER ROLE for "
|
||||||
|
"distributed databases"),
|
||||||
|
|
||||||
|
errdetail(
|
||||||
|
"Citus does not propagate ALTER ROLE ... SET/RESET "
|
||||||
|
"commands to workers"),
|
||||||
|
|
||||||
|
errhint("You can manually alter roles on workers.")));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsA(parsetree, RenameStmt) && ((RenameStmt *) parsetree)->renameType ==
|
||||||
|
OBJECT_ROLE && EnableAlterRolePropagation)
|
||||||
|
{
|
||||||
|
ereport(NOTICE, (errmsg("Citus partially supports ALTER ROLE for "
|
||||||
|
"distributed databases"),
|
||||||
|
|
||||||
|
errdetail(
|
||||||
|
"Citus does not propagate ALTER ROLE ... RENAME TO "
|
||||||
|
"commands to workers"),
|
||||||
|
|
||||||
|
errhint("You can manually alter roles on workers.")));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -93,6 +93,11 @@ DeparseTreeNode(Node *stmt)
|
||||||
return DeparseAlterObjectDependsStmt(castNode(AlterObjectDependsStmt, stmt));
|
return DeparseAlterObjectDependsStmt(castNode(AlterObjectDependsStmt, stmt));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case T_AlterRoleStmt:
|
||||||
|
{
|
||||||
|
return DeparseAlterRoleStmt(castNode(AlterRoleStmt, stmt));
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
ereport(ERROR, (errmsg("unsupported statement for deparsing")));
|
ereport(ERROR, (errmsg("unsupported statement for deparsing")));
|
||||||
|
|
|
@ -402,7 +402,7 @@ AppendAlterFunctionOwnerStmt(StringInfo buf, AlterOwnerStmt *stmt)
|
||||||
|
|
||||||
appendStringInfo(buf, "ALTER %s ", ObjectTypeToKeyword(stmt->objectType));
|
appendStringInfo(buf, "ALTER %s ", ObjectTypeToKeyword(stmt->objectType));
|
||||||
AppendFunctionName(buf, func, stmt->objectType);
|
AppendFunctionName(buf, func, stmt->objectType);
|
||||||
appendStringInfo(buf, " OWNER TO %s;", RoleSpecString(stmt->newowner));
|
appendStringInfo(buf, " OWNER TO %s;", RoleSpecString(stmt->newowner, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,139 @@
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* deparse_role_stmts.c
|
||||||
|
* All routines to deparse role statements.
|
||||||
|
* This file contains all entry points specific for ALTER ROLE statement
|
||||||
|
* deparsing as well as functions that are currently only used for deparsing
|
||||||
|
* ALTER ROLE statements.
|
||||||
|
*
|
||||||
|
* Copyright (c), Citus Data, Inc.
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "distributed/citus_ruleutils.h"
|
||||||
|
#include "distributed/deparser.h"
|
||||||
|
#include "lib/stringinfo.h"
|
||||||
|
#include "nodes/parsenodes.h"
|
||||||
|
#include "utils/builtins.h"
|
||||||
|
|
||||||
|
static void AppendAlterRoleStmt(StringInfo buf, AlterRoleStmt *stmt);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DeparseAlterRoleStmt builds and returns a string representing of the
|
||||||
|
* AlterRoleStmt for application on a remote server.
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
DeparseAlterRoleStmt(AlterRoleStmt *stmt)
|
||||||
|
{
|
||||||
|
StringInfoData buf = { 0 };
|
||||||
|
initStringInfo(&buf);
|
||||||
|
|
||||||
|
AppendAlterRoleStmt(&buf, stmt);
|
||||||
|
|
||||||
|
return buf.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AppendAlterRoleStmt generates the string representation of the
|
||||||
|
* AlterRoleStmt and appends it to the buffer.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
AppendAlterRoleStmt(StringInfo buf, AlterRoleStmt *stmt)
|
||||||
|
{
|
||||||
|
ListCell *optionCell = NULL;
|
||||||
|
RoleSpec *role = stmt->role;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the role_specification used is CURRENT_USER or SESSION_USER,
|
||||||
|
* it will be converted to thats roles role name.
|
||||||
|
*/
|
||||||
|
appendStringInfo(buf, "ALTER ROLE %s", RoleSpecString(role, true));
|
||||||
|
|
||||||
|
foreach(optionCell, stmt->options)
|
||||||
|
{
|
||||||
|
DefElem *option = (DefElem *) lfirst(optionCell);
|
||||||
|
|
||||||
|
if (strcmp(option->defname, "superuser") == 0 && intVal(option->arg))
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, " SUPERUSER");
|
||||||
|
}
|
||||||
|
else if (strcmp(option->defname, "superuser") == 0 && !intVal(option->arg))
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, " NOSUPERUSER");
|
||||||
|
}
|
||||||
|
else if (strcmp(option->defname, "createdb") == 0 && intVal(option->arg))
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, " CREATEDB");
|
||||||
|
}
|
||||||
|
else if (strcmp(option->defname, "createdb") == 0 && !intVal(option->arg))
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, " NOCREATEDB");
|
||||||
|
}
|
||||||
|
else if (strcmp(option->defname, "createrole") == 0 && intVal(option->arg))
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, " CREATEROLE");
|
||||||
|
}
|
||||||
|
else if (strcmp(option->defname, "createrole") == 0 && !intVal(option->arg))
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, " NOCREATEROLE");
|
||||||
|
}
|
||||||
|
else if (strcmp(option->defname, "inherit") == 0 && intVal(option->arg))
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, " INHERIT");
|
||||||
|
}
|
||||||
|
else if (strcmp(option->defname, "inherit") == 0 && !intVal(option->arg))
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, " NOINHERIT");
|
||||||
|
}
|
||||||
|
else if (strcmp(option->defname, "canlogin") == 0 && intVal(option->arg))
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, " LOGIN");
|
||||||
|
}
|
||||||
|
else if (strcmp(option->defname, "canlogin") == 0 && !intVal(option->arg))
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, " NOLOGIN");
|
||||||
|
}
|
||||||
|
else if (strcmp(option->defname, "isreplication") == 0 && intVal(option->arg))
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, " REPLICATION");
|
||||||
|
}
|
||||||
|
else if (strcmp(option->defname, "isreplication") == 0 && !intVal(option->arg))
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, " NOREPLICATION");
|
||||||
|
}
|
||||||
|
else if (strcmp(option->defname, "bypassrls") == 0 && intVal(option->arg))
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, " BYPASSRLS");
|
||||||
|
}
|
||||||
|
else if (strcmp(option->defname, "bypassrls") == 0 && !intVal(option->arg))
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, " NOBYPASSRLS");
|
||||||
|
}
|
||||||
|
else if (strcmp(option->defname, "connectionlimit") == 0)
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, " CONNECTION LIMIT %d", intVal(option->arg));
|
||||||
|
}
|
||||||
|
else if (strcmp(option->defname, "password") == 0)
|
||||||
|
{
|
||||||
|
if (option->arg != NULL)
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, " PASSWORD %s", quote_literal_cstr(strVal(
|
||||||
|
option->arg)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, " PASSWORD NULL");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strcmp(option->defname, "validUntil") == 0)
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, " VALID UNTIL %s", quote_literal_cstr(strVal(
|
||||||
|
option->arg)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -505,5 +505,5 @@ AppendAlterTypeOwnerStmt(StringInfo buf, AlterOwnerStmt *stmt)
|
||||||
|
|
||||||
names = (List *) stmt->object;
|
names = (List *) stmt->object;
|
||||||
appendStringInfo(buf, "ALTER TYPE %s OWNER TO %s;", NameListToQuotedString(names),
|
appendStringInfo(buf, "ALTER TYPE %s OWNER TO %s;", NameListToQuotedString(names),
|
||||||
RoleSpecString(stmt->newowner));
|
RoleSpecString(stmt->newowner, true));
|
||||||
}
|
}
|
||||||
|
|
|
@ -730,6 +730,16 @@ RegisterCitusConfigVariables(void)
|
||||||
GUC_NO_SHOW_ALL,
|
GUC_NO_SHOW_ALL,
|
||||||
NULL, NULL, NULL);
|
NULL, NULL, NULL);
|
||||||
|
|
||||||
|
DefineCustomBoolVariable(
|
||||||
|
"citus.enable_alter_role_propagation",
|
||||||
|
gettext_noop("Enables propagating role passwords statements to workers"),
|
||||||
|
NULL,
|
||||||
|
&EnableAlterRolePropagation,
|
||||||
|
false,
|
||||||
|
PGC_USERSET,
|
||||||
|
GUC_STANDARD,
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
|
||||||
DefineCustomEnumVariable(
|
DefineCustomEnumVariable(
|
||||||
"citus.propagate_set_commands",
|
"citus.propagate_set_commands",
|
||||||
gettext_noop("Sets which SET commands are propagated to workers."),
|
gettext_noop("Sets which SET commands are propagated to workers."),
|
||||||
|
|
|
@ -8,6 +8,7 @@ COMMENT ON COLUMN pg_catalog.pg_dist_node.shouldhaveshards IS
|
||||||
#include "udfs/get_rebalance_table_shards_plan/9.1-1.sql"
|
#include "udfs/get_rebalance_table_shards_plan/9.1-1.sql"
|
||||||
#include "udfs/master_add_node/9.1-1.sql"
|
#include "udfs/master_add_node/9.1-1.sql"
|
||||||
#include "udfs/master_add_inactive_node/9.1-1.sql"
|
#include "udfs/master_add_inactive_node/9.1-1.sql"
|
||||||
|
#include "udfs/alter_role_if_exists/9.1-1.sql"
|
||||||
|
|
||||||
-- we don't maintain replication factor of reference tables anymore and just
|
-- we don't maintain replication factor of reference tables anymore and just
|
||||||
-- use -1 instead.
|
-- use -1 instead.
|
||||||
|
@ -70,4 +71,3 @@ CREATE AGGREGATE citus.coord_combine_agg(oid, cstring, anyelement) (
|
||||||
);
|
);
|
||||||
COMMENT ON AGGREGATE citus.coord_combine_agg(oid, cstring, anyelement)
|
COMMENT ON AGGREGATE citus.coord_combine_agg(oid, cstring, anyelement)
|
||||||
IS 'support aggregate for implementing combining partial aggregate results from workers';
|
IS 'support aggregate for implementing combining partial aggregate results from workers';
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
CREATE OR REPLACE FUNCTION pg_catalog.alter_role_if_exists(
|
||||||
|
role_name text,
|
||||||
|
utility_query text)
|
||||||
|
RETURNS BOOL
|
||||||
|
LANGUAGE C STRICT
|
||||||
|
AS 'MODULE_PATHNAME', $$alter_role_if_exists$$;
|
||||||
|
|
||||||
|
COMMENT ON FUNCTION pg_catalog.alter_role_if_exists(
|
||||||
|
role_name text,
|
||||||
|
utility_query text)
|
||||||
|
IS 'runs the utility query, if the role exists';
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
CREATE OR REPLACE FUNCTION pg_catalog.alter_role_if_exists(
|
||||||
|
role_name text,
|
||||||
|
utility_query text)
|
||||||
|
RETURNS BOOL
|
||||||
|
LANGUAGE C STRICT
|
||||||
|
AS 'MODULE_PATHNAME', $$alter_role_if_exists$$;
|
||||||
|
|
||||||
|
COMMENT ON FUNCTION pg_catalog.alter_role_if_exists(
|
||||||
|
role_name text,
|
||||||
|
utility_query text)
|
||||||
|
IS 'runs the utility query, if the role exists';
|
||||||
|
|
|
@ -1371,25 +1371,34 @@ simple_quote_literal(StringInfo buf, const char *val)
|
||||||
*
|
*
|
||||||
* CURRENT_USER - resolved to the user name of the current role being used
|
* CURRENT_USER - resolved to the user name of the current role being used
|
||||||
* SESSION_USER - resolved to the user name of the user that opened the session
|
* SESSION_USER - resolved to the user name of the user that opened the session
|
||||||
|
*
|
||||||
|
* withQuoteIdendifier is used, because if the results will be used in a query the quotes are needed but if not there
|
||||||
|
* should not be extra quotes.
|
||||||
*/
|
*/
|
||||||
const char *
|
const char *
|
||||||
RoleSpecString(RoleSpec *spec)
|
RoleSpecString(RoleSpec *spec, bool withQuoteIdendifier)
|
||||||
{
|
{
|
||||||
switch (spec->roletype)
|
switch (spec->roletype)
|
||||||
{
|
{
|
||||||
case ROLESPEC_CSTRING:
|
case ROLESPEC_CSTRING:
|
||||||
{
|
{
|
||||||
return quote_identifier(spec->rolename);
|
return withQuoteIdendifier ?
|
||||||
|
quote_identifier(spec->rolename) :
|
||||||
|
spec->rolename;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ROLESPEC_CURRENT_USER:
|
case ROLESPEC_CURRENT_USER:
|
||||||
{
|
{
|
||||||
return quote_identifier(GetUserNameFromId(GetUserId(), false));
|
return withQuoteIdendifier ?
|
||||||
|
quote_identifier(GetUserNameFromId(GetUserId(), false)) :
|
||||||
|
GetUserNameFromId(GetUserId(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
case ROLESPEC_SESSION_USER:
|
case ROLESPEC_SESSION_USER:
|
||||||
{
|
{
|
||||||
return quote_identifier(GetUserNameFromId(GetSessionUserId(), false));
|
return withQuoteIdendifier ?
|
||||||
|
quote_identifier(GetUserNameFromId(GetSessionUserId(), false)) :
|
||||||
|
GetUserNameFromId(GetSessionUserId(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
case ROLESPEC_PUBLIC:
|
case ROLESPEC_PUBLIC:
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
#include "commands/sequence.h"
|
#include "commands/sequence.h"
|
||||||
#include "distributed/citus_acquire_lock.h"
|
#include "distributed/citus_acquire_lock.h"
|
||||||
#include "distributed/colocation_utils.h"
|
#include "distributed/colocation_utils.h"
|
||||||
|
#include "distributed/commands.h"
|
||||||
|
#include "distributed/commands/utility_hook.h"
|
||||||
#include "distributed/connection_management.h"
|
#include "distributed/connection_management.h"
|
||||||
#include "distributed/maintenanced.h"
|
#include "distributed/maintenanced.h"
|
||||||
#include "distributed/master_protocol.h"
|
#include "distributed/master_protocol.h"
|
||||||
|
@ -388,6 +390,28 @@ SetUpDistributedTableDependencies(WorkerNode *newWorkerNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PropagateRolesToNewNode copies the roles' attributes in the new node. Roles that do
|
||||||
|
* not exist in the workers are not created and simply skipped.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
PropagateRolesToNewNode(WorkerNode *newWorkerNode)
|
||||||
|
{
|
||||||
|
List *ddlCommands = NIL;
|
||||||
|
|
||||||
|
if (!EnableAlterRolePropagation)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ddlCommands = GenerateAlterRoleIfExistsCommandAllRoles();
|
||||||
|
|
||||||
|
SendCommandListToWorkerInSingleTransaction(newWorkerNode->workerName,
|
||||||
|
newWorkerNode->workerPort,
|
||||||
|
CitusExtensionOwnerName(), ddlCommands);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ModifiableWorkerNode gets the requested WorkerNode and also gets locks
|
* ModifiableWorkerNode gets the requested WorkerNode and also gets locks
|
||||||
* required for modifying it. This fails if the node does not exist.
|
* required for modifying it. This fails if the node does not exist.
|
||||||
|
@ -565,6 +589,7 @@ ActivateNode(char *nodeName, int nodePort)
|
||||||
|
|
||||||
newWorkerNode = SetNodeState(nodeName, nodePort, isActive);
|
newWorkerNode = SetNodeState(nodeName, nodePort, isActive);
|
||||||
|
|
||||||
|
PropagateRolesToNewNode(newWorkerNode);
|
||||||
SetUpDistributedTableDependencies(newWorkerNode);
|
SetUpDistributedTableDependencies(newWorkerNode);
|
||||||
return newWorkerNode->nodeId;
|
return newWorkerNode->nodeId;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* role.c
|
||||||
|
*
|
||||||
|
* Utilities for ALTER ROLE statments.
|
||||||
|
*
|
||||||
|
* Copyright (c) Citus Data, Inc.
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "distributed/commands/utility_hook.h"
|
||||||
|
#include "distributed/worker_protocol.h"
|
||||||
|
#include "fmgr.h"
|
||||||
|
#include "tcop/dest.h"
|
||||||
|
#include "tcop/utility.h"
|
||||||
|
#include "utils/builtins.h"
|
||||||
|
|
||||||
|
PG_FUNCTION_INFO_V1(alter_role_if_exists);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* alter_role_if_exists checks if the role, whose name is given
|
||||||
|
* in the first parameter exists and then runs the query, which is the second
|
||||||
|
* parameter. This UDF is particularly used for ALTER ROLE queries, how ever it
|
||||||
|
* can run any other query too.
|
||||||
|
*/
|
||||||
|
Datum
|
||||||
|
alter_role_if_exists(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
text *rolenameText = PG_GETARG_TEXT_P(0);
|
||||||
|
const char *rolename = text_to_cstring(rolenameText);
|
||||||
|
text *utilityQueryText = PG_GETARG_TEXT_P(1);
|
||||||
|
const char *utilityQuery = text_to_cstring(utilityQueryText);
|
||||||
|
Node *parseTree = NULL;
|
||||||
|
|
||||||
|
if (get_role_oid(rolename, true) == InvalidOid)
|
||||||
|
{
|
||||||
|
PG_RETURN_BOOL(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
parseTree = ParseTreeNode(utilityQuery);
|
||||||
|
|
||||||
|
CitusProcessUtility(parseTree, utilityQuery, PROCESS_UTILITY_TOPLEVEL, NULL,
|
||||||
|
None_Receiver, NULL);
|
||||||
|
|
||||||
|
PG_RETURN_BOOL(true);
|
||||||
|
}
|
|
@ -41,7 +41,7 @@ extern char * pg_get_indexclusterdef_string(Oid indexRelationId);
|
||||||
extern List * pg_get_table_grants(Oid relationId);
|
extern List * pg_get_table_grants(Oid relationId);
|
||||||
extern bool contain_nextval_expression_walker(Node *node, void *context);
|
extern bool contain_nextval_expression_walker(Node *node, void *context);
|
||||||
extern char * pg_get_replica_identity_command(Oid tableRelationId);
|
extern char * pg_get_replica_identity_command(Oid tableRelationId);
|
||||||
extern const char * RoleSpecString(RoleSpec *spec);
|
extern const char * RoleSpecString(RoleSpec *spec, bool withQuoteIdendifier);
|
||||||
|
|
||||||
/* Function declarations for version dependent PostgreSQL ruleutils functions */
|
/* Function declarations for version dependent PostgreSQL ruleutils functions */
|
||||||
extern void pg_get_query_def(Query *query, StringInfo buffer);
|
extern void pg_get_query_def(Query *query, StringInfo buffer);
|
||||||
|
|
|
@ -116,6 +116,11 @@ extern List * PlanRenameStmt(RenameStmt *renameStmt, const char *renameCommand);
|
||||||
extern void ErrorIfUnsupportedRenameStmt(RenameStmt *renameStmt);
|
extern void ErrorIfUnsupportedRenameStmt(RenameStmt *renameStmt);
|
||||||
|
|
||||||
|
|
||||||
|
/* role.c - forward declarations*/
|
||||||
|
extern List * ProcessAlterRoleStmt(AlterRoleStmt *stmt, const char *queryString);
|
||||||
|
extern List * GenerateAlterRoleIfExistsCommandAllRoles(void);
|
||||||
|
|
||||||
|
|
||||||
/* schema.c - forward declarations */
|
/* schema.c - forward declarations */
|
||||||
extern void ProcessDropSchemaStmt(DropStmt *dropSchemaStatement);
|
extern void ProcessDropSchemaStmt(DropStmt *dropSchemaStatement);
|
||||||
extern List * PlanAlterTableSchemaStmt(AlterObjectSchemaStmt *stmt,
|
extern List * PlanAlterTableSchemaStmt(AlterObjectSchemaStmt *stmt,
|
||||||
|
|
|
@ -30,6 +30,7 @@ extern PropSetCmdBehavior PropagateSetCommands;
|
||||||
extern bool EnableDDLPropagation;
|
extern bool EnableDDLPropagation;
|
||||||
extern bool EnableDependencyCreation;
|
extern bool EnableDependencyCreation;
|
||||||
extern bool EnableCreateTypePropagation;
|
extern bool EnableCreateTypePropagation;
|
||||||
|
extern bool EnableAlterRolePropagation;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A DDLJob encapsulates the remote tasks and commands needed to process all or
|
* A DDLJob encapsulates the remote tasks and commands needed to process all or
|
||||||
|
|
|
@ -69,4 +69,8 @@ extern void QualifyAlterFunctionSchemaStmt(AlterObjectSchemaStmt *stmt);
|
||||||
extern void QualifyAlterFunctionOwnerStmt(AlterOwnerStmt *stmt);
|
extern void QualifyAlterFunctionOwnerStmt(AlterOwnerStmt *stmt);
|
||||||
extern void QualifyAlterFunctionDependsStmt(AlterObjectDependsStmt *stmt);
|
extern void QualifyAlterFunctionDependsStmt(AlterObjectDependsStmt *stmt);
|
||||||
|
|
||||||
|
|
||||||
|
/* forward declarations for deparse_role_stmts.c */
|
||||||
|
extern const char * DeparseAlterRoleStmt(AlterRoleStmt *stmt);
|
||||||
|
|
||||||
#endif /* CITUS_DEPARSER_H */
|
#endif /* CITUS_DEPARSER_H */
|
||||||
|
|
|
@ -0,0 +1,253 @@
|
||||||
|
CREATE SCHEMA alter_role;
|
||||||
|
SET citus.enable_alter_role_propagation to ON;
|
||||||
|
CREATE ROLE alter_role_1 WITH LOGIN;
|
||||||
|
NOTICE: not propagating CREATE ROLE/USER commands to worker nodes
|
||||||
|
HINT: Connect to worker nodes directly to manually create all necessary users and roles.
|
||||||
|
SELECT run_command_on_workers($$CREATE ROLE alter_role_1 WITH LOGIN;$$);
|
||||||
|
run_command_on_workers
|
||||||
|
-----------------------------------
|
||||||
|
(localhost,57637,t,"CREATE ROLE")
|
||||||
|
(localhost,57638,t,"CREATE ROLE")
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
-- postgres errors out
|
||||||
|
ALTER ROLE alter_role_1 WITH SUPERUSER NOSUPERUSER;
|
||||||
|
ERROR: conflicting or redundant options
|
||||||
|
-- make sure that we propagate all options accurately
|
||||||
|
ALTER ROLE alter_role_1 WITH SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN REPLICATION BYPASSRLS CONNECTION LIMIT 66 VALID UNTIL '2032-05-05';
|
||||||
|
SELECT row(rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, EXTRACT (year FROM rolvaliduntil)) FROM pg_authid WHERE rolname = 'alter_role_1';
|
||||||
|
row
|
||||||
|
---------------------------------------
|
||||||
|
(alter_role_1,t,t,t,t,t,t,t,66,,2032)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT run_command_on_workers($$SELECT row(rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, EXTRACT (year FROM rolvaliduntil)) FROM pg_authid WHERE rolname = 'alter_role_1'$$);
|
||||||
|
run_command_on_workers
|
||||||
|
-------------------------------------------------------------
|
||||||
|
(localhost,57637,t,"(alter_role_1,t,t,t,t,t,t,t,66,,2032)")
|
||||||
|
(localhost,57638,t,"(alter_role_1,t,t,t,t,t,t,t,66,,2032)")
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
-- make sure that we propagate all options accurately
|
||||||
|
ALTER ROLE alter_role_1 WITH NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT NOLOGIN NOREPLICATION NOBYPASSRLS CONNECTION LIMIT 0 VALID UNTIL '2052-05-05';
|
||||||
|
SELECT row(rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, EXTRACT (year FROM rolvaliduntil)) FROM pg_authid WHERE rolname = 'alter_role_1';
|
||||||
|
row
|
||||||
|
--------------------------------------
|
||||||
|
(alter_role_1,f,f,f,f,f,f,f,0,,2052)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT run_command_on_workers($$SELECT row(rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, EXTRACT (year FROM rolvaliduntil)) FROM pg_authid WHERE rolname = 'alter_role_1'$$);
|
||||||
|
run_command_on_workers
|
||||||
|
------------------------------------------------------------
|
||||||
|
(localhost,57637,t,"(alter_role_1,f,f,f,f,f,f,f,0,,2052)")
|
||||||
|
(localhost,57638,t,"(alter_role_1,f,f,f,f,f,f,f,0,,2052)")
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
-- make sure that non-existent users are handled properly
|
||||||
|
ALTER ROLE alter_role_2 WITH SUPERUSER NOSUPERUSER;
|
||||||
|
ERROR: conflicting or redundant options
|
||||||
|
ALTER ROLE alter_role_2 WITH SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN REPLICATION BYPASSRLS CONNECTION LIMIT 66 VALID UNTIL '2032-05-05';
|
||||||
|
ERROR: role "alter_role_2" does not exist
|
||||||
|
-- make sure that CURRENT_USER just works fine
|
||||||
|
ALTER ROLE CURRENT_USER WITH CONNECTION LIMIT 123;
|
||||||
|
SELECT rolconnlimit FROM pg_authid WHERE rolname = CURRENT_USER;
|
||||||
|
rolconnlimit
|
||||||
|
--------------
|
||||||
|
123
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT run_command_on_workers($$SELECT rolconnlimit FROM pg_authid WHERE rolname = CURRENT_USER;$$);
|
||||||
|
run_command_on_workers
|
||||||
|
-------------------------
|
||||||
|
(localhost,57637,t,123)
|
||||||
|
(localhost,57638,t,123)
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
-- make sure that SESSION_USER just works fine
|
||||||
|
ALTER ROLE SESSION_USER WITH CONNECTION LIMIT 124;
|
||||||
|
SELECT rolconnlimit FROM pg_authid WHERE rolname = SESSION_USER;
|
||||||
|
rolconnlimit
|
||||||
|
--------------
|
||||||
|
124
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT run_command_on_workers($$SELECT rolconnlimit FROM pg_authid WHERE rolname = SESSION_USER;$$);
|
||||||
|
run_command_on_workers
|
||||||
|
-------------------------
|
||||||
|
(localhost,57637,t,124)
|
||||||
|
(localhost,57638,t,124)
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
-- now lets test the passwords in more detail
|
||||||
|
ALTER ROLE alter_role_1 WITH PASSWORD NULL;
|
||||||
|
SELECT rolpassword is NULL FROM pg_authid WHERE rolname = 'alter_role_1';
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT run_command_on_workers($$SELECT rolpassword is NULL FROM pg_authid WHERE rolname = 'alter_role_1'$$);
|
||||||
|
run_command_on_workers
|
||||||
|
------------------------
|
||||||
|
(localhost,57637,t,t)
|
||||||
|
(localhost,57638,t,t)
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
ALTER ROLE alter_role_1 WITH PASSWORD 'test1';
|
||||||
|
SELECT rolpassword FROM pg_authid WHERE rolname = 'alter_role_1';
|
||||||
|
rolpassword
|
||||||
|
-------------------------------------
|
||||||
|
md52f9cc8d65e37edcc45c4a489bdfc699d
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT run_command_on_workers($$SELECT rolpassword FROM pg_authid WHERE rolname = 'alter_role_1'$$);
|
||||||
|
run_command_on_workers
|
||||||
|
---------------------------------------------------------
|
||||||
|
(localhost,57637,t,md52f9cc8d65e37edcc45c4a489bdfc699d)
|
||||||
|
(localhost,57638,t,md52f9cc8d65e37edcc45c4a489bdfc699d)
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
ALTER ROLE alter_role_1 WITH ENCRYPTED PASSWORD 'test2';
|
||||||
|
SELECT rolpassword FROM pg_authid WHERE rolname = 'alter_role_1';
|
||||||
|
rolpassword
|
||||||
|
-------------------------------------
|
||||||
|
md5e17f7818c5ec023fa87bdb97fd3e842e
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT run_command_on_workers($$SELECT rolpassword FROM pg_authid WHERE rolname = 'alter_role_1'$$);
|
||||||
|
run_command_on_workers
|
||||||
|
---------------------------------------------------------
|
||||||
|
(localhost,57637,t,md5e17f7818c5ec023fa87bdb97fd3e842e)
|
||||||
|
(localhost,57638,t,md5e17f7818c5ec023fa87bdb97fd3e842e)
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
ALTER ROLE alter_role_1 WITH ENCRYPTED PASSWORD 'md59cce240038b7b335c6aa9674a6f13e72';
|
||||||
|
SELECT rolpassword FROM pg_authid WHERE rolname = 'alter_role_1';
|
||||||
|
rolpassword
|
||||||
|
-------------------------------------
|
||||||
|
md59cce240038b7b335c6aa9674a6f13e72
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT run_command_on_workers($$SELECT rolpassword FROM pg_authid WHERE rolname = 'alter_role_1'$$);
|
||||||
|
run_command_on_workers
|
||||||
|
---------------------------------------------------------
|
||||||
|
(localhost,57637,t,md59cce240038b7b335c6aa9674a6f13e72)
|
||||||
|
(localhost,57638,t,md59cce240038b7b335c6aa9674a6f13e72)
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
-- edge case role names
|
||||||
|
CREATE ROLE "alter_role'1" WITH LOGIN;
|
||||||
|
NOTICE: not propagating CREATE ROLE/USER commands to worker nodes
|
||||||
|
HINT: Connect to worker nodes directly to manually create all necessary users and roles.
|
||||||
|
SELECT run_command_on_workers($$CREATE ROLE "alter_role'1" WITH LOGIN;$$);
|
||||||
|
run_command_on_workers
|
||||||
|
-----------------------------------
|
||||||
|
(localhost,57637,t,"CREATE ROLE")
|
||||||
|
(localhost,57638,t,"CREATE ROLE")
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
ALTER ROLE "alter_role'1" CREATEROLE;
|
||||||
|
SELECT rolcreaterole FROM pg_authid WHERE rolname = 'alter_role''1';
|
||||||
|
rolcreaterole
|
||||||
|
---------------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT run_command_on_workers($$SELECT rolcreaterole FROM pg_authid WHERE rolname = 'alter_role''1'$$);
|
||||||
|
run_command_on_workers
|
||||||
|
------------------------
|
||||||
|
(localhost,57637,t,t)
|
||||||
|
(localhost,57638,t,t)
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
CREATE ROLE "alter_role""1" WITH LOGIN;
|
||||||
|
NOTICE: not propagating CREATE ROLE/USER commands to worker nodes
|
||||||
|
HINT: Connect to worker nodes directly to manually create all necessary users and roles.
|
||||||
|
SELECT run_command_on_workers($$CREATE ROLE "alter_role""1" WITH LOGIN;$$);
|
||||||
|
run_command_on_workers
|
||||||
|
-----------------------------------
|
||||||
|
(localhost,57637,t,"CREATE ROLE")
|
||||||
|
(localhost,57638,t,"CREATE ROLE")
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
ALTER ROLE "alter_role""1" CREATEROLE;
|
||||||
|
SELECT rolcreaterole FROM pg_authid WHERE rolname = 'alter_role"1';
|
||||||
|
rolcreaterole
|
||||||
|
---------------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT run_command_on_workers($$SELECT rolcreaterole FROM pg_authid WHERE rolname = 'alter_role"1'$$);
|
||||||
|
run_command_on_workers
|
||||||
|
------------------------
|
||||||
|
(localhost,57637,t,t)
|
||||||
|
(localhost,57638,t,t)
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
-- add node
|
||||||
|
ALTER ROLE alter_role_1 WITH SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN REPLICATION BYPASSRLS CONNECTION LIMIT 66 VALID UNTIL '2032-05-05' PASSWORD 'test3';
|
||||||
|
SELECT row(rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, EXTRACT (year FROM rolvaliduntil)) FROM pg_authid WHERE rolname = 'alter_role_1';
|
||||||
|
row
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
(alter_role_1,t,t,t,t,t,t,t,66,md5ead5c53df946838b1291bba7757f41a7,2032)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT run_command_on_workers($$SELECT row(rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, EXTRACT (year FROM rolvaliduntil)) FROM pg_authid WHERE rolname = 'alter_role_1'$$);
|
||||||
|
run_command_on_workers
|
||||||
|
------------------------------------------------------------------------------------------------
|
||||||
|
(localhost,57637,t,"(alter_role_1,t,t,t,t,t,t,t,66,md5ead5c53df946838b1291bba7757f41a7,2032)")
|
||||||
|
(localhost,57638,t,"(alter_role_1,t,t,t,t,t,t,t,66,md5ead5c53df946838b1291bba7757f41a7,2032)")
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT master_remove_node('localhost', :worker_1_port);
|
||||||
|
master_remove_node
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
ALTER ROLE alter_role_1 WITH NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT NOLOGIN NOREPLICATION NOBYPASSRLS CONNECTION LIMIT 0 VALID UNTIL '2052-05-05' PASSWORD 'test4';
|
||||||
|
SELECT row(rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, EXTRACT (year FROM rolvaliduntil)) FROM pg_authid WHERE rolname = 'alter_role_1';
|
||||||
|
row
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
(alter_role_1,f,f,f,f,f,f,f,0,md5be308f25c7b1a2d50c85cf7e6f074df9,2052)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT run_command_on_workers($$SELECT row(rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, EXTRACT (year FROM rolvaliduntil)) FROM pg_authid WHERE rolname = 'alter_role_1'$$);
|
||||||
|
run_command_on_workers
|
||||||
|
-----------------------------------------------------------------------------------------------
|
||||||
|
(localhost,57638,t,"(alter_role_1,f,f,f,f,f,f,f,0,md5be308f25c7b1a2d50c85cf7e6f074df9,2052)")
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT 1 FROM master_add_node('localhost', :worker_1_port);
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT row(rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, EXTRACT (year FROM rolvaliduntil)) FROM pg_authid WHERE rolname = 'alter_role_1';
|
||||||
|
row
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
(alter_role_1,f,f,f,f,f,f,f,0,md5be308f25c7b1a2d50c85cf7e6f074df9,2052)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT run_command_on_workers($$SELECT row(rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, EXTRACT (year FROM rolvaliduntil)) FROM pg_authid WHERE rolname = 'alter_role_1'$$);
|
||||||
|
run_command_on_workers
|
||||||
|
-----------------------------------------------------------------------------------------------
|
||||||
|
(localhost,57637,t,"(alter_role_1,f,f,f,f,f,f,f,0,md5be308f25c7b1a2d50c85cf7e6f074df9,2052)")
|
||||||
|
(localhost,57638,t,"(alter_role_1,f,f,f,f,f,f,f,0,md5be308f25c7b1a2d50c85cf7e6f074df9,2052)")
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
-- table belongs to a role
|
||||||
|
-- we don't support propagation of configuration_parameters and notice the users
|
||||||
|
ALTER ROLE alter_role_1 SET enable_hashagg TO FALSE;
|
||||||
|
NOTICE: Citus partially supports ALTER ROLE for distributed databases
|
||||||
|
DETAIL: Citus does not propagate ALTER ROLE ... SET/RESET commands to workers
|
||||||
|
HINT: You can manually alter roles on workers.
|
||||||
|
-- we don't support propagation of ALTER ROLE ... RENAME TO commands.
|
||||||
|
ALTER ROLE alter_role_1 RENAME TO alter_role_1_new;
|
||||||
|
NOTICE: MD5 password cleared because of role rename
|
||||||
|
NOTICE: Citus partially supports ALTER ROLE for distributed databases
|
||||||
|
DETAIL: Citus does not propagate ALTER ROLE ... RENAME TO commands to workers
|
||||||
|
HINT: You can manually alter roles on workers.
|
||||||
|
SET citus.enable_alter_role_propagation to OFF;
|
||||||
|
DROP SCHEMA alter_role CASCADE;
|
|
@ -0,0 +1,123 @@
|
||||||
|
Parsed test spec with 2 sessions
|
||||||
|
|
||||||
|
starting permutation: s1-enable-propagation s2-enable-propagation s1-begin s1-alter-role-1 s2-add-node s1-commit
|
||||||
|
run_command_on_workers
|
||||||
|
|
||||||
|
(localhost,57637,t,"CREATE ROLE")
|
||||||
|
(localhost,57638,t,"CREATE ROLE")
|
||||||
|
step s1-enable-propagation:
|
||||||
|
SET citus.enable_alter_role_propagation to ON;
|
||||||
|
|
||||||
|
step s2-enable-propagation:
|
||||||
|
SET citus.enable_alter_role_propagation to ON;
|
||||||
|
|
||||||
|
step s1-begin:
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
step s1-alter-role-1:
|
||||||
|
ALTER ROLE alter_role_1 NOSUPERUSER;
|
||||||
|
|
||||||
|
step s2-add-node:
|
||||||
|
SELECT 1 FROM master_add_node('localhost', 57637);
|
||||||
|
<waiting ...>
|
||||||
|
step s1-commit:
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
step s2-add-node: <... completed>
|
||||||
|
?column?
|
||||||
|
|
||||||
|
1
|
||||||
|
run_command_on_workers
|
||||||
|
|
||||||
|
(localhost,57637,t,"DROP ROLE")
|
||||||
|
(localhost,57638,t,"DROP ROLE")
|
||||||
|
|
||||||
|
starting permutation: s1-enable-propagation s2-enable-propagation s1-begin s1-add-node s2-alter-role-1 s1-commit
|
||||||
|
run_command_on_workers
|
||||||
|
|
||||||
|
(localhost,57637,t,"CREATE ROLE")
|
||||||
|
(localhost,57638,t,"CREATE ROLE")
|
||||||
|
step s1-enable-propagation:
|
||||||
|
SET citus.enable_alter_role_propagation to ON;
|
||||||
|
|
||||||
|
step s2-enable-propagation:
|
||||||
|
SET citus.enable_alter_role_propagation to ON;
|
||||||
|
|
||||||
|
step s1-begin:
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
step s1-add-node:
|
||||||
|
SELECT 1 FROM master_add_node('localhost', 57637);
|
||||||
|
|
||||||
|
?column?
|
||||||
|
|
||||||
|
1
|
||||||
|
step s2-alter-role-1:
|
||||||
|
ALTER ROLE alter_role_1 NOSUPERUSER;
|
||||||
|
<waiting ...>
|
||||||
|
step s1-commit:
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
step s2-alter-role-1: <... completed>
|
||||||
|
run_command_on_workers
|
||||||
|
|
||||||
|
(localhost,57637,t,"DROP ROLE")
|
||||||
|
(localhost,57638,t,"DROP ROLE")
|
||||||
|
|
||||||
|
starting permutation: s1-enable-propagation s2-enable-propagation s1-begin s1-alter-role-1 s2-alter-role-1 s1-commit
|
||||||
|
run_command_on_workers
|
||||||
|
|
||||||
|
(localhost,57637,t,"CREATE ROLE")
|
||||||
|
(localhost,57638,t,"CREATE ROLE")
|
||||||
|
step s1-enable-propagation:
|
||||||
|
SET citus.enable_alter_role_propagation to ON;
|
||||||
|
|
||||||
|
step s2-enable-propagation:
|
||||||
|
SET citus.enable_alter_role_propagation to ON;
|
||||||
|
|
||||||
|
step s1-begin:
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
step s1-alter-role-1:
|
||||||
|
ALTER ROLE alter_role_1 NOSUPERUSER;
|
||||||
|
|
||||||
|
step s2-alter-role-1:
|
||||||
|
ALTER ROLE alter_role_1 NOSUPERUSER;
|
||||||
|
<waiting ...>
|
||||||
|
step s1-commit:
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
step s2-alter-role-1: <... completed>
|
||||||
|
error in steps s1-commit s2-alter-role-1: ERROR: tuple concurrently updated
|
||||||
|
run_command_on_workers
|
||||||
|
|
||||||
|
(localhost,57637,t,"DROP ROLE")
|
||||||
|
(localhost,57638,t,"DROP ROLE")
|
||||||
|
|
||||||
|
starting permutation: s1-enable-propagation s2-enable-propagation s1-begin s1-alter-role-1 s2-alter-role-2 s1-commit
|
||||||
|
run_command_on_workers
|
||||||
|
|
||||||
|
(localhost,57637,t,"CREATE ROLE")
|
||||||
|
(localhost,57638,t,"CREATE ROLE")
|
||||||
|
step s1-enable-propagation:
|
||||||
|
SET citus.enable_alter_role_propagation to ON;
|
||||||
|
|
||||||
|
step s2-enable-propagation:
|
||||||
|
SET citus.enable_alter_role_propagation to ON;
|
||||||
|
|
||||||
|
step s1-begin:
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
step s1-alter-role-1:
|
||||||
|
ALTER ROLE alter_role_1 NOSUPERUSER;
|
||||||
|
|
||||||
|
step s2-alter-role-2:
|
||||||
|
ALTER ROLE alter_role_2 NOSUPERUSER;
|
||||||
|
|
||||||
|
step s1-commit:
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
run_command_on_workers
|
||||||
|
|
||||||
|
(localhost,57637,t,"DROP ROLE")
|
||||||
|
(localhost,57638,t,"DROP ROLE")
|
|
@ -27,6 +27,7 @@ test: isolation_drop_shards isolation_copy_placement_vs_modification
|
||||||
test: isolation_insert_vs_vacuum isolation_transaction_recovery
|
test: isolation_insert_vs_vacuum isolation_transaction_recovery
|
||||||
test: isolation_progress_monitoring
|
test: isolation_progress_monitoring
|
||||||
test: isolation_dump_local_wait_edges
|
test: isolation_dump_local_wait_edges
|
||||||
|
test: isolation_alter_role_propagation
|
||||||
|
|
||||||
test: isolation_replace_wait_function
|
test: isolation_replace_wait_function
|
||||||
test: isolation_distributed_deadlock_detection
|
test: isolation_distributed_deadlock_detection
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
test: multi_extension
|
test: multi_extension
|
||||||
test: multi_703_upgrade
|
test: multi_703_upgrade
|
||||||
test: multi_cluster_management
|
test: multi_cluster_management
|
||||||
|
test: alter_role_propagation
|
||||||
test: multi_test_helpers
|
test: multi_test_helpers
|
||||||
test: multi_table_ddl
|
test: multi_table_ddl
|
||||||
test: multi_name_lengths
|
test: multi_name_lengths
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
setup
|
||||||
|
{
|
||||||
|
CREATE ROLE alter_role_1 WITH LOGIN;
|
||||||
|
SELECT run_command_on_workers($$CREATE ROLE alter_role_1 WITH LOGIN;$$);
|
||||||
|
|
||||||
|
CREATE ROLE alter_role_2 WITH LOGIN;
|
||||||
|
SELECT run_command_on_workers($$CREATE ROLE alter_role_2 WITH LOGIN;$$);
|
||||||
|
}
|
||||||
|
|
||||||
|
teardown
|
||||||
|
{
|
||||||
|
DROP ROLE IF EXISTS alter_role_1;
|
||||||
|
SELECT run_command_on_workers($$DROP ROLE IF EXISTS alter_role_1;$$);
|
||||||
|
|
||||||
|
DROP ROLE IF EXISTS alter_role_2;
|
||||||
|
SELECT run_command_on_workers($$DROP ROLE IF EXISTS alter_role_2;$$);
|
||||||
|
}
|
||||||
|
|
||||||
|
session "s1"
|
||||||
|
|
||||||
|
step "s1-enable-propagation"
|
||||||
|
{
|
||||||
|
SET citus.enable_alter_role_propagation to ON;
|
||||||
|
}
|
||||||
|
|
||||||
|
step "s1-begin"
|
||||||
|
{
|
||||||
|
BEGIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
step "s1-alter-role-1"
|
||||||
|
{
|
||||||
|
ALTER ROLE alter_role_1 NOSUPERUSER;
|
||||||
|
}
|
||||||
|
|
||||||
|
step "s1-add-node"
|
||||||
|
{
|
||||||
|
SELECT 1 FROM master_add_node('localhost', 57637);
|
||||||
|
}
|
||||||
|
|
||||||
|
step "s1-commit"
|
||||||
|
{
|
||||||
|
COMMIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
session "s2"
|
||||||
|
|
||||||
|
step "s2-enable-propagation"
|
||||||
|
{
|
||||||
|
SET citus.enable_alter_role_propagation to ON;
|
||||||
|
}
|
||||||
|
|
||||||
|
step "s2-alter-role-1"
|
||||||
|
{
|
||||||
|
ALTER ROLE alter_role_1 NOSUPERUSER;
|
||||||
|
}
|
||||||
|
|
||||||
|
step "s2-alter-role-2"
|
||||||
|
{
|
||||||
|
ALTER ROLE alter_role_2 NOSUPERUSER;
|
||||||
|
}
|
||||||
|
|
||||||
|
step "s2-add-node"
|
||||||
|
{
|
||||||
|
SELECT 1 FROM master_add_node('localhost', 57637);
|
||||||
|
}
|
||||||
|
|
||||||
|
permutation "s1-enable-propagation" "s2-enable-propagation" "s1-begin" "s1-alter-role-1" "s2-add-node" "s1-commit"
|
||||||
|
permutation "s1-enable-propagation" "s2-enable-propagation" "s1-begin" "s1-add-node" "s2-alter-role-1" "s1-commit"
|
||||||
|
|
||||||
|
permutation "s1-enable-propagation" "s2-enable-propagation" "s1-begin" "s1-alter-role-1" "s2-alter-role-1" "s1-commit"
|
||||||
|
permutation "s1-enable-propagation" "s2-enable-propagation" "s1-begin" "s1-alter-role-1" "s2-alter-role-2" "s1-commit"
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
CREATE SCHEMA alter_role;
|
||||||
|
|
||||||
|
SET citus.enable_alter_role_propagation to ON;
|
||||||
|
|
||||||
|
CREATE ROLE alter_role_1 WITH LOGIN;
|
||||||
|
SELECT run_command_on_workers($$CREATE ROLE alter_role_1 WITH LOGIN;$$);
|
||||||
|
|
||||||
|
-- postgres errors out
|
||||||
|
ALTER ROLE alter_role_1 WITH SUPERUSER NOSUPERUSER;
|
||||||
|
|
||||||
|
-- make sure that we propagate all options accurately
|
||||||
|
ALTER ROLE alter_role_1 WITH SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN REPLICATION BYPASSRLS CONNECTION LIMIT 66 VALID UNTIL '2032-05-05';
|
||||||
|
SELECT row(rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, EXTRACT (year FROM rolvaliduntil)) FROM pg_authid WHERE rolname = 'alter_role_1';
|
||||||
|
SELECT run_command_on_workers($$SELECT row(rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, EXTRACT (year FROM rolvaliduntil)) FROM pg_authid WHERE rolname = 'alter_role_1'$$);
|
||||||
|
|
||||||
|
-- make sure that we propagate all options accurately
|
||||||
|
ALTER ROLE alter_role_1 WITH NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT NOLOGIN NOREPLICATION NOBYPASSRLS CONNECTION LIMIT 0 VALID UNTIL '2052-05-05';
|
||||||
|
SELECT row(rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, EXTRACT (year FROM rolvaliduntil)) FROM pg_authid WHERE rolname = 'alter_role_1';
|
||||||
|
SELECT run_command_on_workers($$SELECT row(rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, EXTRACT (year FROM rolvaliduntil)) FROM pg_authid WHERE rolname = 'alter_role_1'$$);
|
||||||
|
|
||||||
|
-- make sure that non-existent users are handled properly
|
||||||
|
ALTER ROLE alter_role_2 WITH SUPERUSER NOSUPERUSER;
|
||||||
|
ALTER ROLE alter_role_2 WITH SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN REPLICATION BYPASSRLS CONNECTION LIMIT 66 VALID UNTIL '2032-05-05';
|
||||||
|
|
||||||
|
-- make sure that CURRENT_USER just works fine
|
||||||
|
ALTER ROLE CURRENT_USER WITH CONNECTION LIMIT 123;
|
||||||
|
SELECT rolconnlimit FROM pg_authid WHERE rolname = CURRENT_USER;
|
||||||
|
SELECT run_command_on_workers($$SELECT rolconnlimit FROM pg_authid WHERE rolname = CURRENT_USER;$$);
|
||||||
|
|
||||||
|
-- make sure that SESSION_USER just works fine
|
||||||
|
ALTER ROLE SESSION_USER WITH CONNECTION LIMIT 124;
|
||||||
|
SELECT rolconnlimit FROM pg_authid WHERE rolname = SESSION_USER;
|
||||||
|
SELECT run_command_on_workers($$SELECT rolconnlimit FROM pg_authid WHERE rolname = SESSION_USER;$$);
|
||||||
|
|
||||||
|
-- now lets test the passwords in more detail
|
||||||
|
ALTER ROLE alter_role_1 WITH PASSWORD NULL;
|
||||||
|
SELECT rolpassword is NULL FROM pg_authid WHERE rolname = 'alter_role_1';
|
||||||
|
SELECT run_command_on_workers($$SELECT rolpassword is NULL FROM pg_authid WHERE rolname = 'alter_role_1'$$);
|
||||||
|
|
||||||
|
ALTER ROLE alter_role_1 WITH PASSWORD 'test1';
|
||||||
|
SELECT rolpassword FROM pg_authid WHERE rolname = 'alter_role_1';
|
||||||
|
SELECT run_command_on_workers($$SELECT rolpassword FROM pg_authid WHERE rolname = 'alter_role_1'$$);
|
||||||
|
|
||||||
|
ALTER ROLE alter_role_1 WITH ENCRYPTED PASSWORD 'test2';
|
||||||
|
SELECT rolpassword FROM pg_authid WHERE rolname = 'alter_role_1';
|
||||||
|
SELECT run_command_on_workers($$SELECT rolpassword FROM pg_authid WHERE rolname = 'alter_role_1'$$);
|
||||||
|
|
||||||
|
ALTER ROLE alter_role_1 WITH ENCRYPTED PASSWORD 'md59cce240038b7b335c6aa9674a6f13e72';
|
||||||
|
SELECT rolpassword FROM pg_authid WHERE rolname = 'alter_role_1';
|
||||||
|
SELECT run_command_on_workers($$SELECT rolpassword FROM pg_authid WHERE rolname = 'alter_role_1'$$);
|
||||||
|
|
||||||
|
|
||||||
|
-- edge case role names
|
||||||
|
|
||||||
|
CREATE ROLE "alter_role'1" WITH LOGIN;
|
||||||
|
SELECT run_command_on_workers($$CREATE ROLE "alter_role'1" WITH LOGIN;$$);
|
||||||
|
ALTER ROLE "alter_role'1" CREATEROLE;
|
||||||
|
SELECT rolcreaterole FROM pg_authid WHERE rolname = 'alter_role''1';
|
||||||
|
SELECT run_command_on_workers($$SELECT rolcreaterole FROM pg_authid WHERE rolname = 'alter_role''1'$$);
|
||||||
|
|
||||||
|
CREATE ROLE "alter_role""1" WITH LOGIN;
|
||||||
|
SELECT run_command_on_workers($$CREATE ROLE "alter_role""1" WITH LOGIN;$$);
|
||||||
|
ALTER ROLE "alter_role""1" CREATEROLE;
|
||||||
|
SELECT rolcreaterole FROM pg_authid WHERE rolname = 'alter_role"1';
|
||||||
|
SELECT run_command_on_workers($$SELECT rolcreaterole FROM pg_authid WHERE rolname = 'alter_role"1'$$);
|
||||||
|
|
||||||
|
|
||||||
|
-- add node
|
||||||
|
ALTER ROLE alter_role_1 WITH SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN REPLICATION BYPASSRLS CONNECTION LIMIT 66 VALID UNTIL '2032-05-05' PASSWORD 'test3';
|
||||||
|
SELECT row(rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, EXTRACT (year FROM rolvaliduntil)) FROM pg_authid WHERE rolname = 'alter_role_1';
|
||||||
|
SELECT run_command_on_workers($$SELECT row(rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, EXTRACT (year FROM rolvaliduntil)) FROM pg_authid WHERE rolname = 'alter_role_1'$$);
|
||||||
|
SELECT master_remove_node('localhost', :worker_1_port);
|
||||||
|
ALTER ROLE alter_role_1 WITH NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT NOLOGIN NOREPLICATION NOBYPASSRLS CONNECTION LIMIT 0 VALID UNTIL '2052-05-05' PASSWORD 'test4';
|
||||||
|
SELECT row(rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, EXTRACT (year FROM rolvaliduntil)) FROM pg_authid WHERE rolname = 'alter_role_1';
|
||||||
|
SELECT run_command_on_workers($$SELECT row(rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, EXTRACT (year FROM rolvaliduntil)) FROM pg_authid WHERE rolname = 'alter_role_1'$$);
|
||||||
|
SELECT 1 FROM master_add_node('localhost', :worker_1_port);
|
||||||
|
SELECT row(rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, EXTRACT (year FROM rolvaliduntil)) FROM pg_authid WHERE rolname = 'alter_role_1';
|
||||||
|
SELECT run_command_on_workers($$SELECT row(rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, EXTRACT (year FROM rolvaliduntil)) FROM pg_authid WHERE rolname = 'alter_role_1'$$);
|
||||||
|
|
||||||
|
|
||||||
|
-- table belongs to a role
|
||||||
|
|
||||||
|
|
||||||
|
-- we don't support propagation of configuration_parameters and notice the users
|
||||||
|
ALTER ROLE alter_role_1 SET enable_hashagg TO FALSE;
|
||||||
|
|
||||||
|
-- we don't support propagation of ALTER ROLE ... RENAME TO commands.
|
||||||
|
ALTER ROLE alter_role_1 RENAME TO alter_role_1_new;
|
||||||
|
|
||||||
|
SET citus.enable_alter_role_propagation to OFF;
|
||||||
|
|
||||||
|
DROP SCHEMA alter_role CASCADE;
|
Loading…
Reference in New Issue