mirror of https://github.com/citusdata/citus.git
Merge 9874a074f6
into d885e1a016
commit
19d4e96b5d
|
@ -44,7 +44,8 @@ static int ObjectAddressComparator(const void *a, const void *b);
|
|||
static void EnsureDependenciesExistOnAllNodes(const ObjectAddress *target);
|
||||
static void EnsureRequiredObjectSetExistOnAllNodes(const ObjectAddress *target,
|
||||
RequiredObjectSet requiredObjectSet);
|
||||
static List * GetDependencyCreateDDLCommands(const ObjectAddress *dependency);
|
||||
static List * GetDependencyCreateDDLCommands(const ObjectAddress *dependency, bool
|
||||
fetchGrantStatements);
|
||||
static bool ShouldPropagateObject(const ObjectAddress *address);
|
||||
static char * DropTableIfExistsCommand(Oid relationId);
|
||||
|
||||
|
@ -164,7 +165,7 @@ EnsureRequiredObjectSetExistOnAllNodes(const ObjectAddress *target,
|
|||
ObjectAddress *object = NULL;
|
||||
foreach_ptr(object, objectsToBeCreated)
|
||||
{
|
||||
List *dependencyCommands = GetDependencyCreateDDLCommands(object);
|
||||
List *dependencyCommands = GetDependencyCreateDDLCommands(object, true);
|
||||
ddlCommands = list_concat(ddlCommands, dependencyCommands);
|
||||
|
||||
/* create a new list with objects that actually created commands */
|
||||
|
@ -432,7 +433,7 @@ GetDistributableDependenciesForObject(const ObjectAddress *target)
|
|||
* in nodes, but we utilize logic it follows to choose the objects that could
|
||||
* be distributed
|
||||
*/
|
||||
List *dependencyCommands = GetDependencyCreateDDLCommands(dependency);
|
||||
List *dependencyCommands = GetDependencyCreateDDLCommands(dependency, true);
|
||||
|
||||
/* create a new list with dependencies that actually created commands */
|
||||
if (list_length(dependencyCommands) > 0)
|
||||
|
@ -465,7 +466,7 @@ DropTableIfExistsCommand(Oid relationId)
|
|||
* commands to execute on a worker to create the object.
|
||||
*/
|
||||
static List *
|
||||
GetDependencyCreateDDLCommands(const ObjectAddress *dependency)
|
||||
GetDependencyCreateDDLCommands(const ObjectAddress *dependency, bool fetchGrantStatements)
|
||||
{
|
||||
switch (getObjectClass(dependency))
|
||||
{
|
||||
|
@ -605,7 +606,8 @@ GetDependencyCreateDDLCommands(const ObjectAddress *dependency)
|
|||
|
||||
case OCLASS_ROLE:
|
||||
{
|
||||
return GenerateCreateOrAlterRoleCommand(dependency->objectId);
|
||||
return GenerateCreateOrAlterRoleCommand(dependency->objectId,
|
||||
fetchGrantStatements);
|
||||
}
|
||||
|
||||
case OCLASS_SCHEMA:
|
||||
|
@ -680,15 +682,16 @@ GetDependencyCreateDDLCommands(const ObjectAddress *dependency)
|
|||
List *
|
||||
GetAllDependencyCreateDDLCommands(const List *dependencies)
|
||||
{
|
||||
List *commands = NIL;
|
||||
List *ddlCommands = NIL;
|
||||
|
||||
ObjectAddress *dependency = NULL;
|
||||
foreach_ptr(dependency, dependencies)
|
||||
{
|
||||
commands = list_concat(commands, GetDependencyCreateDDLCommands(dependency));
|
||||
ddlCommands = list_concat(ddlCommands, GetDependencyCreateDDLCommands(dependency,
|
||||
false));
|
||||
}
|
||||
|
||||
return commands;
|
||||
return ddlCommands;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include "distributed/version_compat.h"
|
||||
#include "distributed/worker_transaction.h"
|
||||
|
||||
|
||||
static const char * ExtractEncryptedPassword(Oid roleOid);
|
||||
static const char * CreateAlterRoleIfExistsCommand(AlterRoleStmt *stmt);
|
||||
static const char * CreateAlterRoleSetIfExistsCommand(AlterRoleSetStmt *stmt);
|
||||
|
@ -67,6 +68,8 @@ static DefElem * makeDefElemBool(char *name, bool value);
|
|||
static List * GenerateRoleOptionsList(HeapTuple tuple);
|
||||
static List * GenerateGrantRoleStmtsFromOptions(RoleSpec *roleSpec, List *options);
|
||||
static List * GenerateGrantRoleStmtsOfRole(Oid roleid);
|
||||
static GrantRoleStmt * GetGrantRoleStmtFromAuthMemberRecord(Form_pg_auth_members
|
||||
membership);
|
||||
static List * GenerateSecLabelOnRoleStmts(Oid roleid, char *rolename);
|
||||
static void EnsureSequentialModeForRoleDDL(void);
|
||||
|
||||
|
@ -512,7 +515,7 @@ GenerateRoleOptionsList(HeapTuple tuple)
|
|||
* the pg_authid table.
|
||||
*/
|
||||
List *
|
||||
GenerateCreateOrAlterRoleCommand(Oid roleOid)
|
||||
GenerateCreateOrAlterRoleCommand(Oid roleOid, bool fetchGrantStmts)
|
||||
{
|
||||
HeapTuple roleTuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleOid));
|
||||
Form_pg_authid role = ((Form_pg_authid) GETSTRUCT(roleTuple));
|
||||
|
@ -562,11 +565,10 @@ GenerateCreateOrAlterRoleCommand(Oid roleOid)
|
|||
|
||||
if (EnableCreateRolePropagation)
|
||||
{
|
||||
List *grantRoleStmts = GenerateGrantRoleStmtsOfRole(roleOid);
|
||||
Node *stmt = NULL;
|
||||
foreach_ptr(stmt, grantRoleStmts)
|
||||
if (fetchGrantStmts)
|
||||
{
|
||||
completeRoleList = lappend(completeRoleList, DeparseTreeNode(stmt));
|
||||
completeRoleList = list_concat(completeRoleList, GenerateGrantRoleStmtsOfRole(
|
||||
roleOid));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -577,7 +579,7 @@ GenerateCreateOrAlterRoleCommand(Oid roleOid)
|
|||
* SecLabel stmts to be run in the new node.
|
||||
*/
|
||||
List *secLabelOnRoleStmts = GenerateSecLabelOnRoleStmts(roleOid, rolename);
|
||||
stmt = NULL;
|
||||
Node *stmt = NULL;
|
||||
foreach_ptr(stmt, secLabelOnRoleStmts)
|
||||
{
|
||||
completeRoleList = lappend(completeRoleList, DeparseTreeNode(stmt));
|
||||
|
@ -872,7 +874,9 @@ GenerateGrantRoleStmtsOfRole(Oid roleid)
|
|||
{
|
||||
Relation pgAuthMembers = table_open(AuthMemRelationId, AccessShareLock);
|
||||
HeapTuple tuple = NULL;
|
||||
List *stmts = NIL;
|
||||
|
||||
List *adminStmts = NIL;
|
||||
List *otherStmts = NIL;
|
||||
|
||||
ScanKeyData skey[1];
|
||||
|
||||
|
@ -885,73 +889,148 @@ GenerateGrantRoleStmtsOfRole(Oid roleid)
|
|||
{
|
||||
Form_pg_auth_members membership = (Form_pg_auth_members) GETSTRUCT(tuple);
|
||||
|
||||
ObjectAddress *roleAddress = palloc0(sizeof(ObjectAddress));
|
||||
ObjectAddressSet(*roleAddress, AuthIdRelationId, membership->grantor);
|
||||
if (!IsAnyObjectDistributed(list_make1(roleAddress)))
|
||||
GrantRoleStmt *grantRoleStmt = GetGrantRoleStmtFromAuthMemberRecord(membership);
|
||||
if (grantRoleStmt == NULL || IsReservedName(GetUserNameFromId(membership->roleid,
|
||||
true)))
|
||||
{
|
||||
/* we only need to propagate the grant if the grantor is distributed */
|
||||
continue;
|
||||
}
|
||||
|
||||
GrantRoleStmt *grantRoleStmt = makeNode(GrantRoleStmt);
|
||||
grantRoleStmt->is_grant = true;
|
||||
|
||||
RoleSpec *grantedRole = makeNode(RoleSpec);
|
||||
grantedRole->roletype = ROLESPEC_CSTRING;
|
||||
grantedRole->location = -1;
|
||||
grantedRole->rolename = GetUserNameFromId(membership->roleid, true);
|
||||
grantRoleStmt->granted_roles = list_make1(grantedRole);
|
||||
|
||||
RoleSpec *granteeRole = makeNode(RoleSpec);
|
||||
granteeRole->roletype = ROLESPEC_CSTRING;
|
||||
granteeRole->location = -1;
|
||||
granteeRole->rolename = GetUserNameFromId(membership->member, true);
|
||||
grantRoleStmt->grantee_roles = list_make1(granteeRole);
|
||||
|
||||
RoleSpec *grantorRole = makeNode(RoleSpec);
|
||||
grantorRole->roletype = ROLESPEC_CSTRING;
|
||||
grantorRole->location = -1;
|
||||
grantorRole->rolename = GetUserNameFromId(membership->grantor, false);
|
||||
grantRoleStmt->grantor = grantorRole;
|
||||
|
||||
#if PG_VERSION_NUM >= PG_VERSION_16
|
||||
|
||||
/* inherit option is always included */
|
||||
DefElem *inherit_opt;
|
||||
if (membership->inherit_option)
|
||||
if (membership->admin_option)
|
||||
{
|
||||
inherit_opt = makeDefElem("inherit", (Node *) makeBoolean(true), -1);
|
||||
adminStmts = lappend(adminStmts, grantRoleStmt);
|
||||
}
|
||||
else
|
||||
{
|
||||
inherit_opt = makeDefElem("inherit", (Node *) makeBoolean(false), -1);
|
||||
otherStmts = lappend(otherStmts, grantRoleStmt);
|
||||
}
|
||||
grantRoleStmt->opt = list_make1(inherit_opt);
|
||||
|
||||
/* admin option is false by default, only include true case */
|
||||
if (membership->admin_option)
|
||||
{
|
||||
DefElem *admin_opt = makeDefElem("admin", (Node *) makeBoolean(true), -1);
|
||||
grantRoleStmt->opt = lappend(grantRoleStmt->opt, admin_opt);
|
||||
}
|
||||
|
||||
/* set option is true by default, only include false case */
|
||||
if (!membership->set_option)
|
||||
{
|
||||
DefElem *set_opt = makeDefElem("set", (Node *) makeBoolean(false), -1);
|
||||
grantRoleStmt->opt = lappend(grantRoleStmt->opt, set_opt);
|
||||
}
|
||||
#else
|
||||
grantRoleStmt->admin_opt = membership->admin_option;
|
||||
#endif
|
||||
|
||||
stmts = lappend(stmts, grantRoleStmt);
|
||||
}
|
||||
|
||||
systable_endscan(scan);
|
||||
table_close(pgAuthMembers, AccessShareLock);
|
||||
|
||||
return stmts;
|
||||
List *allStmts = list_concat(adminStmts, otherStmts);
|
||||
List *commands = NIL;
|
||||
Node *stmt = NULL;
|
||||
foreach_ptr(stmt, allStmts)
|
||||
{
|
||||
commands = lappend(commands, DeparseTreeNode(stmt));
|
||||
}
|
||||
|
||||
return commands;
|
||||
}
|
||||
|
||||
|
||||
List *
|
||||
GenerateGrantRoleStmts()
|
||||
{
|
||||
Relation pgAuthMembers = table_open(AuthMemRelationId, AccessShareLock);
|
||||
HeapTuple tuple = NULL;
|
||||
List *adminStmts = NIL;
|
||||
List *otherStmts = NIL;
|
||||
|
||||
SysScanDesc scan = systable_beginscan(pgAuthMembers, InvalidOid, false,
|
||||
NULL, 0, NULL);
|
||||
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(scan)))
|
||||
{
|
||||
Form_pg_auth_members membership = (Form_pg_auth_members) GETSTRUCT(tuple);
|
||||
|
||||
|
||||
GrantRoleStmt *grantRoleStmt = GetGrantRoleStmtFromAuthMemberRecord(membership);
|
||||
if (grantRoleStmt == NULL || IsReservedName(GetUserNameFromId(membership->roleid,
|
||||
true)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (membership->admin_option)
|
||||
{
|
||||
adminStmts = lappend(adminStmts, grantRoleStmt);
|
||||
}
|
||||
else
|
||||
{
|
||||
otherStmts = lappend(otherStmts, grantRoleStmt);
|
||||
}
|
||||
}
|
||||
|
||||
systable_endscan(scan);
|
||||
table_close(pgAuthMembers, AccessShareLock);
|
||||
|
||||
List *allStmts = list_concat(adminStmts, otherStmts);
|
||||
|
||||
/*iterate through the list of adminStmts and otherStmts */
|
||||
/*and using DeparseTreeNode to convert the GrantRoleStmt to a string */
|
||||
/*and then add the string to the list of commands */
|
||||
List *commands = NIL;
|
||||
Node *stmt = NULL;
|
||||
foreach_ptr(stmt, allStmts)
|
||||
{
|
||||
commands = lappend(commands, DeparseTreeNode(stmt));
|
||||
}
|
||||
|
||||
return commands;
|
||||
}
|
||||
|
||||
|
||||
static GrantRoleStmt *
|
||||
GetGrantRoleStmtFromAuthMemberRecord(Form_pg_auth_members membership)
|
||||
{
|
||||
ObjectAddress *roleAddress = palloc0(sizeof(ObjectAddress));
|
||||
ObjectAddressSet(*roleAddress, AuthIdRelationId, membership->grantor);
|
||||
|
||||
GrantRoleStmt *grantRoleStmt = makeNode(GrantRoleStmt);
|
||||
grantRoleStmt->is_grant = true;
|
||||
|
||||
RoleSpec *grantedRole = makeNode(RoleSpec);
|
||||
grantedRole->roletype = ROLESPEC_CSTRING;
|
||||
grantedRole->location = -1;
|
||||
grantedRole->rolename = GetUserNameFromId(membership->roleid, true);
|
||||
grantRoleStmt->granted_roles = list_make1(grantedRole);
|
||||
|
||||
RoleSpec *granteeRole = makeNode(RoleSpec);
|
||||
granteeRole->roletype = ROLESPEC_CSTRING;
|
||||
granteeRole->location = -1;
|
||||
granteeRole->rolename = GetUserNameFromId(membership->member, true);
|
||||
grantRoleStmt->grantee_roles = list_make1(granteeRole);
|
||||
|
||||
RoleSpec *grantorRole = makeNode(RoleSpec);
|
||||
grantorRole->roletype = ROLESPEC_CSTRING;
|
||||
grantorRole->location = -1;
|
||||
grantorRole->rolename = GetUserNameFromId(membership->grantor, false);
|
||||
grantRoleStmt->grantor = grantorRole;
|
||||
|
||||
#if PG_VERSION_NUM >= PG_VERSION_16
|
||||
|
||||
/* inherit option is always included */
|
||||
DefElem *inherit_opt;
|
||||
if (membership->inherit_option)
|
||||
{
|
||||
inherit_opt = makeDefElem("inherit", (Node *) makeBoolean(true), -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
inherit_opt = makeDefElem("inherit", (Node *) makeBoolean(false), -1);
|
||||
}
|
||||
grantRoleStmt->opt = list_make1(inherit_opt);
|
||||
|
||||
/* admin option is false by default, only include true case */
|
||||
if (membership->admin_option)
|
||||
{
|
||||
DefElem *admin_opt = makeDefElem("admin", (Node *) makeBoolean(true), -1);
|
||||
grantRoleStmt->opt = lappend(grantRoleStmt->opt, admin_opt);
|
||||
}
|
||||
|
||||
/* set option is true by default, only include false case */
|
||||
if (!membership->set_option)
|
||||
{
|
||||
DefElem *set_opt = makeDefElem("set", (Node *) makeBoolean(false), -1);
|
||||
grantRoleStmt->opt = lappend(grantRoleStmt->opt, set_opt);
|
||||
}
|
||||
#else
|
||||
grantRoleStmt->admin_opt = membership->admin_option;
|
||||
#endif
|
||||
return grantRoleStmt;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1202,7 +1281,7 @@ UnmarkRolesDistributed(List *roles)
|
|||
List *
|
||||
FilterDistributedRoles(List *roles)
|
||||
{
|
||||
List *distributedRoles = NIL;
|
||||
List *validRoles = NIL;
|
||||
Node *roleNode = NULL;
|
||||
foreach_ptr(roleNode, roles)
|
||||
{
|
||||
|
@ -1218,12 +1297,46 @@ FilterDistributedRoles(List *roles)
|
|||
}
|
||||
ObjectAddress *roleAddress = palloc0(sizeof(ObjectAddress));
|
||||
ObjectAddressSet(*roleAddress, AuthIdRelationId, roleOid);
|
||||
if (IsAnyObjectDistributed(list_make1(roleAddress)))
|
||||
bool isSystemRole = IsReservedName(role->rolename);
|
||||
if (IsAnyObjectDistributed(list_make1(roleAddress)) || isSystemRole)
|
||||
{
|
||||
distributedRoles = lappend(distributedRoles, role);
|
||||
validRoles = lappend(validRoles, role);
|
||||
}
|
||||
}
|
||||
return distributedRoles;
|
||||
return validRoles;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* FilterDistributedRoles filters the list of AccessPrivs and returns the ones
|
||||
* that are distributed.
|
||||
*/
|
||||
List *
|
||||
FilterDistributedGrantedRoles(List *roles)
|
||||
{
|
||||
List *validRoles = NIL;
|
||||
Node *roleNode = NULL;
|
||||
foreach_ptr(roleNode, roles)
|
||||
{
|
||||
AccessPriv *role = castNode(AccessPriv, roleNode);
|
||||
Oid roleOid = get_role_oid(role->priv_name, false);
|
||||
if (roleOid == InvalidOid)
|
||||
{
|
||||
/*
|
||||
* Non-existing roles are ignored silently here. Postgres will
|
||||
* handle to give an error or not for these roles.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
ObjectAddress *roleAddress = palloc0(sizeof(ObjectAddress));
|
||||
ObjectAddressSet(*roleAddress, AuthIdRelationId, roleOid);
|
||||
bool isSystemRole = IsReservedName(role->priv_name);
|
||||
if (IsAnyObjectDistributed(list_make1(roleAddress)) || isSystemRole)
|
||||
{
|
||||
validRoles = lappend(validRoles, role);
|
||||
}
|
||||
}
|
||||
return validRoles;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1243,19 +1356,8 @@ PreprocessGrantRoleStmt(Node *node, const char *queryString,
|
|||
EnsurePropagationToCoordinator();
|
||||
|
||||
GrantRoleStmt *stmt = castNode(GrantRoleStmt, node);
|
||||
List *allGranteeRoles = stmt->grantee_roles;
|
||||
RoleSpec *grantor = stmt->grantor;
|
||||
|
||||
List *distributedGranteeRoles = FilterDistributedRoles(allGranteeRoles);
|
||||
if (list_length(distributedGranteeRoles) <= 0)
|
||||
{
|
||||
return NIL;
|
||||
}
|
||||
|
||||
stmt->grantee_roles = distributedGranteeRoles;
|
||||
char *sql = DeparseTreeNode((Node *) stmt);
|
||||
stmt->grantee_roles = allGranteeRoles;
|
||||
stmt->grantor = grantor;
|
||||
|
||||
List *commands = list_make3(DISABLE_DDL_PROPAGATION,
|
||||
sql,
|
||||
|
@ -1265,6 +1367,54 @@ PreprocessGrantRoleStmt(Node *node, const char *queryString,
|
|||
}
|
||||
|
||||
|
||||
DistributedRolesInGrantRoleStmt *
|
||||
ExtractDistributedRolesInGrantRoleStmt(GrantRoleStmt *stmt)
|
||||
{
|
||||
DistributedRolesInGrantRoleStmt *distributedRolesInGrantRoleStmt = palloc0(
|
||||
sizeof(DistributedRolesInGrantRoleStmt));
|
||||
distributedRolesInGrantRoleStmt->distributedGrantees = FilterDistributedRoles(
|
||||
stmt->grantee_roles);
|
||||
distributedRolesInGrantRoleStmt->distributedGrantedRoles =
|
||||
FilterDistributedGrantedRoles(stmt->granted_roles);
|
||||
distributedRolesInGrantRoleStmt->grantor = stmt->grantor;
|
||||
distributedRolesInGrantRoleStmt->isGrantRoleStmtValid = true;
|
||||
|
||||
bool grantorMissingOk = false;
|
||||
bool isGrantorDefined = distributedRolesInGrantRoleStmt->grantor != NULL &&
|
||||
get_rolespec_oid(distributedRolesInGrantRoleStmt->grantor,
|
||||
grantorMissingOk) != InvalidOid;
|
||||
bool isGrantorDistributed = IsAnyObjectDistributed(RoleSpecToObjectAddress(
|
||||
distributedRolesInGrantRoleStmt
|
||||
->grantor, grantorMissingOk));
|
||||
bool skipDueToGrantor = isGrantorDefined && !isGrantorDistributed;
|
||||
if (list_length(distributedRolesInGrantRoleStmt->distributedGrantees) <= 0)
|
||||
{
|
||||
ereport(NOTICE, (errmsg("not propagating GRANT command to other nodes"),
|
||||
errhint("Since no grantees are distributed, "
|
||||
"the GRANT command will not be propagated to other nodes.")));
|
||||
distributedRolesInGrantRoleStmt->isGrantRoleStmtValid = false;
|
||||
}
|
||||
|
||||
if (list_length(distributedRolesInGrantRoleStmt->distributedGrantedRoles) <= 0)
|
||||
{
|
||||
ereport(NOTICE, (errmsg("not propagating GRANT command to other nodes"),
|
||||
errhint("Since no granted roles are distributed, "
|
||||
"the GRANT command will not be propagated to other nodes.")));
|
||||
distributedRolesInGrantRoleStmt->isGrantRoleStmtValid = false;
|
||||
}
|
||||
|
||||
if (skipDueToGrantor)
|
||||
{
|
||||
ereport(NOTICE, (errmsg("not propagating GRANT command to other nodes"),
|
||||
errhint("Since grantor is not distributed, "
|
||||
"the GRANT command will not be propagated to other nodes.")));
|
||||
distributedRolesInGrantRoleStmt->isGrantRoleStmtValid = false;
|
||||
}
|
||||
|
||||
return distributedRolesInGrantRoleStmt;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* PostprocessGrantRoleStmt actually creates the plan we need to execute for grant
|
||||
* role statement.
|
||||
|
|
|
@ -5167,6 +5167,11 @@ SendDependencyCreationCommands(MetadataSyncContext *context)
|
|||
List *ddlCommands = GetAllDependencyCreateDDLCommands(list_make1(dependency));
|
||||
SendOrCollectCommandListToActivatedNodes(context, ddlCommands);
|
||||
}
|
||||
|
||||
List *grantRoleCommands = GenerateGrantRoleStmts();
|
||||
SendOrCollectCommandListToActivatedNodes(context, grantRoleCommands);
|
||||
|
||||
|
||||
MemoryContextSwitchTo(oldContext);
|
||||
|
||||
if (!MetadataSyncCollectsCommands(context))
|
||||
|
|
|
@ -174,6 +174,14 @@ typedef enum TenantOperation
|
|||
TENANT_SET_SCHEMA,
|
||||
} TenantOperation;
|
||||
|
||||
typedef struct DistributedRolesInGrantRoleStmt
|
||||
{
|
||||
List *distributedGrantees;
|
||||
List *distributedGrantedRoles;
|
||||
RoleSpec *grantor;
|
||||
bool isGrantRoleStmtValid;
|
||||
} DistributedRolesInGrantRoleStmt;
|
||||
|
||||
#define TOTAL_TENANT_OPERATION 5
|
||||
extern const char *TenantOperationNames[TOTAL_TENANT_OPERATION];
|
||||
|
||||
|
@ -519,7 +527,7 @@ extern List * PreprocessDropRoleStmt(Node *stmt, const char *queryString,
|
|||
extern List * PreprocessGrantRoleStmt(Node *stmt, const char *queryString,
|
||||
ProcessUtilityContext processUtilityContext);
|
||||
extern List * PostprocessGrantRoleStmt(Node *stmt, const char *queryString);
|
||||
extern List * GenerateCreateOrAlterRoleCommand(Oid roleOid);
|
||||
extern List * GenerateCreateOrAlterRoleCommand(Oid roleOid, bool fetchGrantStatements);
|
||||
extern List * CreateRoleStmtObjectAddress(Node *stmt, bool missing_ok, bool
|
||||
isPostprocess);
|
||||
|
||||
|
@ -527,7 +535,11 @@ extern List * RenameRoleStmtObjectAddress(Node *stmt, bool missing_ok, bool
|
|||
isPostprocess);
|
||||
|
||||
extern void UnmarkRolesDistributed(List *roles);
|
||||
extern List * FilterDistributedGrantedRoles(List *roles);
|
||||
extern List * FilterDistributedRoles(List *roles);
|
||||
extern DistributedRolesInGrantRoleStmt * ExtractDistributedRolesInGrantRoleStmt(
|
||||
GrantRoleStmt *stmt);
|
||||
extern List * GenerateGrantRoleStmts(void);
|
||||
|
||||
/* schema.c - forward declarations */
|
||||
extern List * PostprocessCreateSchemaStmt(Node *node, const char *queryString);
|
||||
|
|
|
@ -196,7 +196,6 @@ SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::t
|
|||
(1 row)
|
||||
|
||||
\c - - - :master_port
|
||||
create role test_admin_role;
|
||||
-- test grants with distributed and non-distributed roles
|
||||
SELECT master_remove_node('localhost', :worker_2_port);
|
||||
master_remove_node
|
||||
|
@ -204,6 +203,7 @@ SELECT master_remove_node('localhost', :worker_2_port);
|
|||
|
||||
(1 row)
|
||||
|
||||
create role test_admin_role;
|
||||
CREATE ROLE dist_role_1 SUPERUSER;
|
||||
CREATE ROLE dist_role_2;
|
||||
CREATE ROLE dist_role_3;
|
||||
|
@ -225,6 +225,7 @@ SET citus.enable_create_role_propagation TO ON;
|
|||
grant dist_role_3,dist_role_1 to test_admin_role with admin option;
|
||||
SET ROLE dist_role_1;
|
||||
GRANT non_dist_role_1 TO non_dist_role_2;
|
||||
ERROR: connection to the remote node dist_role_1@localhost:xxxxx failed with the following error: FATAL: role "dist_role_1" is not permitted to log in
|
||||
SET citus.enable_create_role_propagation TO OFF;
|
||||
grant dist_role_1 to non_dist_role_1 with admin option;
|
||||
SET ROLE non_dist_role_1;
|
||||
|
@ -232,14 +233,35 @@ GRANT dist_role_1 TO dist_role_2 granted by non_dist_role_1;
|
|||
RESET ROLE;
|
||||
SET citus.enable_create_role_propagation TO ON;
|
||||
GRANT dist_role_3 TO non_dist_role_3 granted by test_admin_role;
|
||||
ERROR: role "non_dist_role_3" does not exist
|
||||
CONTEXT: while executing command on localhost:xxxxx
|
||||
GRANT non_dist_role_4 TO dist_role_4;
|
||||
GRANT dist_role_3 TO dist_role_4 granted by test_admin_role;
|
||||
SELECT 1 FROM master_add_node('localhost', :worker_2_port);
|
||||
WARNING: role "non_dist_role_1" does not exist
|
||||
CONTEXT: while executing command on localhost:xxxxx
|
||||
ERROR: failure on connection marked as essential: localhost:xxxxx
|
||||
\c - - - :worker_2_port
|
||||
create role non_dist_role_1;
|
||||
\c - - - :master_port
|
||||
--will be successful since non_dist_role_1 is created on worker_2
|
||||
SELECT 1 FROM master_add_node('localhost', :worker_2_port);
|
||||
?column?
|
||||
---------------------------------------------------------------------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::regclass::oid AND objid::regrole::text LIKE '%dist\_%' ORDER BY 1;
|
||||
objid
|
||||
---------------------------------------------------------------------
|
||||
dist_role_1
|
||||
dist_role_2
|
||||
dist_role_3
|
||||
dist_role_4
|
||||
non_dist_role_1
|
||||
non_dist_role_4
|
||||
(6 rows)
|
||||
|
||||
SELECT result FROM run_command_on_all_nodes(
|
||||
$$
|
||||
SELECT json_agg(q.* ORDER BY member) FROM (
|
||||
|
@ -248,14 +270,13 @@ SELECT result FROM run_command_on_all_nodes(
|
|||
) q;
|
||||
$$
|
||||
);
|
||||
result
|
||||
result
|
||||
---------------------------------------------------------------------
|
||||
[{"member":"dist_role_4","role":"dist_role_3","grantor":"test_admin_role","admin_option":false}, +
|
||||
{"member":"non_dist_role_3","role":"dist_role_3","grantor":"test_admin_role","admin_option":false}, +
|
||||
[{"member":"dist_role_4","role":"dist_role_3","grantor":"test_admin_role","admin_option":false}, +
|
||||
{"member":"test_admin_role","role":"dist_role_3","grantor":"postgres","admin_option":true}]
|
||||
[{"member":"dist_role_4","role":"dist_role_3","grantor":"test_admin_role","admin_option":false}, +
|
||||
[{"member":"dist_role_4","role":"dist_role_3","grantor":"test_admin_role","admin_option":false}, +
|
||||
{"member":"test_admin_role","role":"dist_role_3","grantor":"postgres","admin_option":true}]
|
||||
[{"member":"dist_role_4","role":"dist_role_3","grantor":"test_admin_role","admin_option":false}, +
|
||||
[{"member":"dist_role_4","role":"dist_role_3","grantor":"test_admin_role","admin_option":false}, +
|
||||
{"member":"test_admin_role","role":"dist_role_3","grantor":"postgres","admin_option":true}]
|
||||
(3 rows)
|
||||
|
||||
|
@ -269,10 +290,9 @@ SELECT result FROM run_command_on_all_nodes(
|
|||
) q;
|
||||
$$
|
||||
);
|
||||
result
|
||||
result
|
||||
---------------------------------------------------------------------
|
||||
[{"member":"non_dist_role_3","role":"dist_role_3","grantor":"test_admin_role","admin_option":false}, +
|
||||
{"member":"test_admin_role","role":"dist_role_3","grantor":"postgres","admin_option":true}]
|
||||
[{"member":"test_admin_role","role":"dist_role_3","grantor":"postgres","admin_option":true}]
|
||||
[{"member":"test_admin_role","role":"dist_role_3","grantor":"postgres","admin_option":true}]
|
||||
[{"member":"test_admin_role","role":"dist_role_3","grantor":"postgres","admin_option":true}]
|
||||
(3 rows)
|
||||
|
@ -283,11 +303,9 @@ SELECT roleid::regrole::text AS role, member::regrole::text, (grantor::regrole::
|
|||
dist_role_1 | dist_role_2 | t | f
|
||||
dist_role_1 | non_dist_role_1 | t | t
|
||||
dist_role_1 | test_admin_role | t | t
|
||||
dist_role_3 | non_dist_role_3 | t | f
|
||||
dist_role_3 | test_admin_role | t | t
|
||||
non_dist_role_1 | non_dist_role_2 | t | f
|
||||
non_dist_role_4 | dist_role_4 | t | f
|
||||
(7 rows)
|
||||
(5 rows)
|
||||
|
||||
SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::regclass::oid AND objid::regrole::text LIKE '%dist\_%' ORDER BY 1;
|
||||
objid
|
||||
|
@ -296,10 +314,14 @@ SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::
|
|||
dist_role_2
|
||||
dist_role_3
|
||||
dist_role_4
|
||||
non_dist_role_1
|
||||
non_dist_role_4
|
||||
(5 rows)
|
||||
(6 rows)
|
||||
|
||||
REVOKE dist_role_3 from non_dist_role_3 granted by test_admin_role cascade;
|
||||
WARNING: role "non_dist_role_3" has not been granted membership in role "dist_role_3" by role "test_admin_role"
|
||||
ERROR: role "non_dist_role_3" does not exist
|
||||
CONTEXT: while executing command on localhost:xxxxx
|
||||
SELECT result FROM run_command_on_all_nodes(
|
||||
$$
|
||||
SELECT json_agg(q.* ORDER BY member) FROM (
|
||||
|
@ -332,15 +354,18 @@ SELECT rolname FROM pg_authid WHERE rolname LIKE '%dist\_%' ORDER BY 1;
|
|||
dist_role_2
|
||||
dist_role_3
|
||||
dist_role_4
|
||||
non_dist_role_1
|
||||
non_dist_role_4
|
||||
(5 rows)
|
||||
(6 rows)
|
||||
|
||||
\c - - - :worker_2_port
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE '%dist\_%' ORDER BY 1, 2;
|
||||
role | member | grantor | admin_option
|
||||
role | member | grantor | admin_option
|
||||
---------------------------------------------------------------------
|
||||
non_dist_role_4 | dist_role_4 | postgres | f
|
||||
(1 row)
|
||||
dist_role_1 | dist_role_2 | non_dist_role_1 | f
|
||||
dist_role_1 | non_dist_role_1 | postgres | t
|
||||
non_dist_role_4 | dist_role_4 | postgres | f
|
||||
(3 rows)
|
||||
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%dist\_%' ORDER BY 1;
|
||||
rolname
|
||||
|
@ -349,8 +374,9 @@ SELECT rolname FROM pg_authid WHERE rolname LIKE '%dist\_%' ORDER BY 1;
|
|||
dist_role_2
|
||||
dist_role_3
|
||||
dist_role_4
|
||||
non_dist_role_1
|
||||
non_dist_role_4
|
||||
(5 rows)
|
||||
(6 rows)
|
||||
|
||||
\c - - - :master_port
|
||||
DROP ROLE dist_role_3, non_dist_role_3, dist_role_4, non_dist_role_4;
|
||||
|
@ -402,6 +428,12 @@ SELECT master_remove_node('localhost', :worker_2_port);
|
|||
|
||||
(1 row)
|
||||
|
||||
GRANT dist_mixed_1, dist_mixed_2, nondist_mixed_1 TO dist_mixed_3, dist_mixed_4, nondist_mixed_2;
|
||||
ERROR: role "nondist_mixed_2" does not exist
|
||||
CONTEXT: while executing command on localhost:xxxxx
|
||||
\c - - - :worker_1_port
|
||||
create role nondist_mixed_2;
|
||||
\c - - - :master_port
|
||||
GRANT dist_mixed_1, dist_mixed_2, nondist_mixed_1 TO dist_mixed_3, dist_mixed_4, nondist_mixed_2;
|
||||
SELECT 1 FROM master_add_node('localhost', :worker_2_port);
|
||||
?column?
|
||||
|
@ -431,19 +463,23 @@ SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::
|
|||
dist_mixed_3
|
||||
dist_mixed_4
|
||||
nondist_mixed_1
|
||||
(5 rows)
|
||||
nondist_mixed_2
|
||||
(6 rows)
|
||||
|
||||
\c - - - :worker_1_port
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE '%dist\_mixed%' ORDER BY 1, 2;
|
||||
role | member | grantor | admin_option
|
||||
role | member | grantor | admin_option
|
||||
---------------------------------------------------------------------
|
||||
dist_mixed_1 | dist_mixed_3 | postgres | f
|
||||
dist_mixed_1 | dist_mixed_4 | postgres | f
|
||||
dist_mixed_2 | dist_mixed_3 | postgres | f
|
||||
dist_mixed_2 | dist_mixed_4 | postgres | f
|
||||
nondist_mixed_1 | dist_mixed_3 | postgres | f
|
||||
nondist_mixed_1 | dist_mixed_4 | postgres | f
|
||||
(6 rows)
|
||||
dist_mixed_1 | dist_mixed_3 | postgres | f
|
||||
dist_mixed_1 | dist_mixed_4 | postgres | f
|
||||
dist_mixed_1 | nondist_mixed_2 | postgres | f
|
||||
dist_mixed_2 | dist_mixed_3 | postgres | f
|
||||
dist_mixed_2 | dist_mixed_4 | postgres | f
|
||||
dist_mixed_2 | nondist_mixed_2 | postgres | f
|
||||
nondist_mixed_1 | dist_mixed_3 | postgres | f
|
||||
nondist_mixed_1 | dist_mixed_4 | postgres | f
|
||||
nondist_mixed_1 | nondist_mixed_2 | postgres | f
|
||||
(9 rows)
|
||||
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%dist\_mixed%' ORDER BY 1;
|
||||
rolname
|
||||
|
@ -453,19 +489,23 @@ SELECT rolname FROM pg_authid WHERE rolname LIKE '%dist\_mixed%' ORDER BY 1;
|
|||
dist_mixed_3
|
||||
dist_mixed_4
|
||||
nondist_mixed_1
|
||||
(5 rows)
|
||||
nondist_mixed_2
|
||||
(6 rows)
|
||||
|
||||
\c - - - :worker_2_port
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE '%dist\_mixed%' ORDER BY 1, 2;
|
||||
role | member | grantor | admin_option
|
||||
role | member | grantor | admin_option
|
||||
---------------------------------------------------------------------
|
||||
dist_mixed_1 | dist_mixed_3 | postgres | f
|
||||
dist_mixed_1 | dist_mixed_4 | postgres | f
|
||||
dist_mixed_2 | dist_mixed_3 | postgres | f
|
||||
dist_mixed_2 | dist_mixed_4 | postgres | f
|
||||
nondist_mixed_1 | dist_mixed_3 | postgres | f
|
||||
nondist_mixed_1 | dist_mixed_4 | postgres | f
|
||||
(6 rows)
|
||||
dist_mixed_1 | dist_mixed_3 | postgres | f
|
||||
dist_mixed_1 | dist_mixed_4 | postgres | f
|
||||
dist_mixed_1 | nondist_mixed_2 | postgres | f
|
||||
dist_mixed_2 | dist_mixed_3 | postgres | f
|
||||
dist_mixed_2 | dist_mixed_4 | postgres | f
|
||||
dist_mixed_2 | nondist_mixed_2 | postgres | f
|
||||
nondist_mixed_1 | dist_mixed_3 | postgres | f
|
||||
nondist_mixed_1 | dist_mixed_4 | postgres | f
|
||||
nondist_mixed_1 | nondist_mixed_2 | postgres | f
|
||||
(9 rows)
|
||||
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%dist\_mixed%' ORDER BY 1;
|
||||
rolname
|
||||
|
@ -475,17 +515,27 @@ SELECT rolname FROM pg_authid WHERE rolname LIKE '%dist\_mixed%' ORDER BY 1;
|
|||
dist_mixed_3
|
||||
dist_mixed_4
|
||||
nondist_mixed_1
|
||||
(5 rows)
|
||||
nondist_mixed_2
|
||||
(6 rows)
|
||||
|
||||
\c - - - :master_port
|
||||
set citus.log_remote_commands to on;
|
||||
set citus.grep_remote_commands to '%DROP%';
|
||||
DROP ROLE dist_mixed_1, dist_mixed_2, dist_mixed_3, dist_mixed_4, nondist_mixed_1, nondist_mixed_2;
|
||||
NOTICE: issuing DROP ROLE dist_mixed_1, dist_mixed_2, dist_mixed_3, dist_mixed_4, nondist_mixed_1, nondist_mixed_2
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing DROP ROLE dist_mixed_1, dist_mixed_2, dist_mixed_3, dist_mixed_4, nondist_mixed_1, nondist_mixed_2
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
set citus.grep_remote_commands to '%DROP%';
|
||||
reset citus.log_remote_commands;
|
||||
-- test drop multiple roles with non-distributed roles
|
||||
SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::regclass::oid AND objid::regrole::text LIKE '%dist%' ORDER BY 1;
|
||||
objid
|
||||
objid
|
||||
---------------------------------------------------------------------
|
||||
dist_role_1
|
||||
dist_role_2
|
||||
(2 rows)
|
||||
non_dist_role_1
|
||||
(3 rows)
|
||||
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%dist%' ORDER BY 1;
|
||||
rolname
|
||||
|
@ -498,11 +548,12 @@ SELECT rolname FROM pg_authid WHERE rolname LIKE '%dist%' ORDER BY 1;
|
|||
|
||||
\c - - - :worker_1_port
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%dist%' ORDER BY 1;
|
||||
rolname
|
||||
rolname
|
||||
---------------------------------------------------------------------
|
||||
dist_role_1
|
||||
dist_role_2
|
||||
(2 rows)
|
||||
non_dist_role_1
|
||||
(3 rows)
|
||||
|
||||
\c - - - :master_port
|
||||
DROP ROLE dist_role_1, non_dist_role_1, dist_role_2, non_dist_role_2;
|
||||
|
@ -522,6 +573,12 @@ SELECT rolname FROM pg_authid WHERE rolname LIKE '%dist%' ORDER BY 1;
|
|||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
\c - - - :worker_2_port
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%dist%' ORDER BY 1;
|
||||
rolname
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
\c - - - :master_port
|
||||
-- test alter part of create or alter role
|
||||
SELECT master_remove_node('localhost', :worker_2_port);
|
||||
|
@ -571,7 +628,11 @@ HINT: Connect to other nodes directly to manually create all necessary users an
|
|||
SET citus.enable_create_role_propagation TO ON;
|
||||
CREATE ROLE dist_cascade;
|
||||
GRANT nondist_cascade_1 TO nondist_cascade_2;
|
||||
ERROR: role "nondist_cascade_2" does not exist
|
||||
CONTEXT: while executing command on localhost:xxxxx
|
||||
GRANT nondist_cascade_2 TO nondist_cascade_3;
|
||||
ERROR: role "nondist_cascade_3" does not exist
|
||||
CONTEXT: while executing command on localhost:xxxxx
|
||||
SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::regclass::oid AND objid::regrole::text LIKE '%cascade%' ORDER BY 1;
|
||||
objid
|
||||
---------------------------------------------------------------------
|
||||
|
@ -579,11 +640,9 @@ SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::
|
|||
(1 row)
|
||||
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE '%cascade%' ORDER BY 1, 2;
|
||||
role | member | grantor | admin_option
|
||||
role | member | grantor | admin_option
|
||||
---------------------------------------------------------------------
|
||||
nondist_cascade_1 | nondist_cascade_2 | postgres | f
|
||||
nondist_cascade_2 | nondist_cascade_3 | postgres | f
|
||||
(2 rows)
|
||||
(0 rows)
|
||||
|
||||
\c - - - :worker_1_port
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%cascade%' ORDER BY 1;
|
||||
|
@ -614,55 +673,43 @@ SELECT 1 FROM master_add_node('localhost', :worker_2_port);
|
|||
SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::regclass::oid AND objid::regrole::text LIKE '%cascade%' ORDER BY 1;
|
||||
objid
|
||||
---------------------------------------------------------------------
|
||||
nondist_cascade_1
|
||||
nondist_cascade_2
|
||||
nondist_cascade_3
|
||||
dist_cascade
|
||||
(4 rows)
|
||||
(2 rows)
|
||||
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE '%cascade%' ORDER BY 1, 2;
|
||||
role | member | grantor | admin_option
|
||||
role | member | grantor | admin_option
|
||||
---------------------------------------------------------------------
|
||||
nondist_cascade_1 | nondist_cascade_2 | postgres | f
|
||||
nondist_cascade_2 | nondist_cascade_3 | postgres | f
|
||||
nondist_cascade_3 | dist_cascade | postgres | f
|
||||
(3 rows)
|
||||
nondist_cascade_3 | dist_cascade | postgres | f
|
||||
(1 row)
|
||||
|
||||
\c - - - :worker_1_port
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%cascade%' ORDER BY 1;
|
||||
rolname
|
||||
---------------------------------------------------------------------
|
||||
dist_cascade
|
||||
nondist_cascade_1
|
||||
nondist_cascade_2
|
||||
nondist_cascade_3
|
||||
(4 rows)
|
||||
(2 rows)
|
||||
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE '%cascade%' ORDER BY 1, 2;
|
||||
role | member | grantor | admin_option
|
||||
role | member | grantor | admin_option
|
||||
---------------------------------------------------------------------
|
||||
nondist_cascade_1 | nondist_cascade_2 | postgres | f
|
||||
nondist_cascade_2 | nondist_cascade_3 | postgres | f
|
||||
nondist_cascade_3 | dist_cascade | postgres | f
|
||||
(3 rows)
|
||||
nondist_cascade_3 | dist_cascade | postgres | f
|
||||
(1 row)
|
||||
|
||||
\c - - - :worker_2_port
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%cascade%' ORDER BY 1;
|
||||
rolname
|
||||
---------------------------------------------------------------------
|
||||
dist_cascade
|
||||
nondist_cascade_1
|
||||
nondist_cascade_2
|
||||
nondist_cascade_3
|
||||
(4 rows)
|
||||
(2 rows)
|
||||
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE '%cascade%' ORDER BY 1, 2;
|
||||
role | member | grantor | admin_option
|
||||
role | member | grantor | admin_option
|
||||
---------------------------------------------------------------------
|
||||
nondist_cascade_1 | nondist_cascade_2 | postgres | f
|
||||
nondist_cascade_2 | nondist_cascade_3 | postgres | f
|
||||
nondist_cascade_3 | dist_cascade | postgres | f
|
||||
(3 rows)
|
||||
nondist_cascade_3 | dist_cascade | postgres | f
|
||||
(1 row)
|
||||
|
||||
\c - - - :master_port
|
||||
DROP ROLE create_role, create_role_2, create_group, create_group_2, create_user, create_user_2, create_role_with_nothing, create_role_sysid, "create_role'edge", "create_role""edge";
|
||||
|
|
|
@ -0,0 +1,800 @@
|
|||
SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname LIKE 'create\_%' ORDER BY rolname;
|
||||
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE 'create\_%' ORDER BY 1, 2;
|
||||
role | member | grantor | admin_option
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
\c - - - :worker_1_port
|
||||
SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname LIKE 'create\_%' ORDER BY rolname;
|
||||
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE 'create\_%' ORDER BY 1, 2;
|
||||
role | member | grantor | admin_option
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
\c - - - :master_port
|
||||
CREATE ROLE create_role;
|
||||
CREATE ROLE create_role_2;
|
||||
CREATE USER create_user;
|
||||
CREATE USER create_user_2;
|
||||
CREATE GROUP create_group;
|
||||
CREATE GROUP create_group_2;
|
||||
-- show that create role fails if sysid option is given as non-int
|
||||
CREATE ROLE create_role_sysid SYSID "123";
|
||||
ERROR: syntax error at or near ""123""
|
||||
-- show that create role accepts sysid option as int
|
||||
CREATE ROLE create_role_sysid SYSID 123;
|
||||
NOTICE: SYSID can no longer be specified
|
||||
SELECT master_remove_node('localhost', :worker_2_port);
|
||||
master_remove_node
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
CREATE ROLE create_role_with_everything SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN REPLICATION BYPASSRLS CONNECTION LIMIT 105 PASSWORD 'strong_password123^' VALID UNTIL '2045-05-05 00:00:00.00+00' IN ROLE create_role, create_group ROLE create_user, create_group_2 ADMIN create_role_2, create_user_2;
|
||||
CREATE ROLE create_role_with_nothing NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT NOLOGIN NOREPLICATION NOBYPASSRLS CONNECTION LIMIT 3 PASSWORD 'weakpassword' VALID UNTIL '2015-05-05 00:00:00.00+00';
|
||||
-- show that creating role from worker node is allowed
|
||||
\c - - - :worker_1_port
|
||||
CREATE ROLE role_on_worker;
|
||||
DROP ROLE role_on_worker;
|
||||
\c - - - :master_port
|
||||
-- edge case role names
|
||||
CREATE ROLE "create_role'edge";
|
||||
CREATE ROLE "create_role""edge";
|
||||
-- test grant role
|
||||
GRANT create_group TO create_role;
|
||||
GRANT create_group TO create_role_2 WITH ADMIN OPTION;
|
||||
SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, (rolpassword != '') as pass_not_empty, rolvaliduntil FROM pg_authid WHERE rolname LIKE 'create\_%' ORDER BY rolname;
|
||||
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | pass_not_empty | rolvaliduntil
|
||||
---------------------------------------------------------------------
|
||||
create_group | f | t | f | f | f | f | f | -1 | |
|
||||
create_group_2 | f | t | f | f | f | f | f | -1 | |
|
||||
create_role | f | t | f | f | f | f | f | -1 | |
|
||||
create_role"edge | f | t | f | f | f | f | f | -1 | |
|
||||
create_role'edge | f | t | f | f | f | f | f | -1 | |
|
||||
create_role_2 | f | t | f | f | f | f | f | -1 | |
|
||||
create_role_sysid | f | t | f | f | f | f | f | -1 | |
|
||||
create_role_with_everything | t | t | t | t | t | t | t | 105 | t | Thu May 04 17:00:00 2045 PDT
|
||||
create_role_with_nothing | f | f | f | f | f | f | f | 3 | t | Mon May 04 17:00:00 2015 PDT
|
||||
create_user | f | t | f | f | t | f | f | -1 | |
|
||||
create_user_2 | f | t | f | f | t | f | f | -1 | |
|
||||
(11 rows)
|
||||
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE 'create\_%' ORDER BY 1, 2;
|
||||
role | member | grantor | admin_option
|
||||
---------------------------------------------------------------------
|
||||
create_group | create_role | postgres | f
|
||||
create_group | create_role_2 | postgres | t
|
||||
create_group | create_role_with_everything | postgres | f
|
||||
create_role | create_role_with_everything | postgres | f
|
||||
create_role_with_everything | create_group_2 | postgres | f
|
||||
create_role_with_everything | create_role_2 | postgres | t
|
||||
create_role_with_everything | create_user | postgres | f
|
||||
create_role_with_everything | create_user_2 | postgres | t
|
||||
(8 rows)
|
||||
|
||||
\c - - - :worker_1_port
|
||||
SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, (rolpassword != '') as pass_not_empty, rolvaliduntil FROM pg_authid WHERE rolname LIKE 'create\_%' ORDER BY rolname;
|
||||
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | pass_not_empty | rolvaliduntil
|
||||
---------------------------------------------------------------------
|
||||
create_group | f | t | f | f | f | f | f | -1 | |
|
||||
create_group_2 | f | t | f | f | f | f | f | -1 | |
|
||||
create_role | f | t | f | f | f | f | f | -1 | |
|
||||
create_role"edge | f | t | f | f | f | f | f | -1 | |
|
||||
create_role'edge | f | t | f | f | f | f | f | -1 | |
|
||||
create_role_2 | f | t | f | f | f | f | f | -1 | |
|
||||
create_role_sysid | f | t | f | f | f | f | f | -1 | |
|
||||
create_role_with_everything | t | t | t | t | t | t | t | 105 | t | Thu May 04 17:00:00 2045 PDT
|
||||
create_role_with_nothing | f | f | f | f | f | f | f | 3 | t | Mon May 04 17:00:00 2015 PDT
|
||||
create_user | f | t | f | f | t | f | f | -1 | |
|
||||
create_user_2 | f | t | f | f | t | f | f | -1 | |
|
||||
(11 rows)
|
||||
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE 'create\_%' ORDER BY 1, 2;
|
||||
role | member | grantor | admin_option
|
||||
---------------------------------------------------------------------
|
||||
create_group | create_role | postgres | f
|
||||
create_group | create_role_2 | postgres | t
|
||||
create_group | create_role_with_everything | postgres | f
|
||||
create_role | create_role_with_everything | postgres | f
|
||||
create_role_with_everything | create_group_2 | postgres | f
|
||||
create_role_with_everything | create_role_2 | postgres | t
|
||||
create_role_with_everything | create_user | postgres | f
|
||||
create_role_with_everything | create_user_2 | postgres | t
|
||||
(8 rows)
|
||||
|
||||
\c - - - :master_port
|
||||
SELECT 1 FROM master_add_node('localhost', :worker_2_port);
|
||||
?column?
|
||||
---------------------------------------------------------------------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
\c - - - :worker_2_port
|
||||
SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, (rolpassword != '') as pass_not_empty, rolvaliduntil FROM pg_authid WHERE rolname LIKE 'create\_%' ORDER BY rolname;
|
||||
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | pass_not_empty | rolvaliduntil
|
||||
---------------------------------------------------------------------
|
||||
create_group | f | t | f | f | f | f | f | -1 | | infinity
|
||||
create_group_2 | f | t | f | f | f | f | f | -1 | | infinity
|
||||
create_role | f | t | f | f | f | f | f | -1 | | infinity
|
||||
create_role"edge | f | t | f | f | f | f | f | -1 | | infinity
|
||||
create_role'edge | f | t | f | f | f | f | f | -1 | | infinity
|
||||
create_role_2 | f | t | f | f | f | f | f | -1 | | infinity
|
||||
create_role_sysid | f | t | f | f | f | f | f | -1 | | infinity
|
||||
create_role_with_everything | t | t | t | t | t | t | t | 105 | t | Thu May 04 17:00:00 2045 PDT
|
||||
create_role_with_nothing | f | f | f | f | f | f | f | 3 | t | Mon May 04 17:00:00 2015 PDT
|
||||
create_user | f | t | f | f | t | f | f | -1 | | infinity
|
||||
create_user_2 | f | t | f | f | t | f | f | -1 | | infinity
|
||||
(11 rows)
|
||||
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE 'create\_%' ORDER BY 1, 2;
|
||||
role | member | grantor | admin_option
|
||||
---------------------------------------------------------------------
|
||||
create_group | create_role | postgres | f
|
||||
create_group | create_role_2 | postgres | t
|
||||
create_group | create_role_with_everything | postgres | f
|
||||
create_role | create_role_with_everything | postgres | f
|
||||
create_role_with_everything | create_group_2 | postgres | f
|
||||
create_role_with_everything | create_role_2 | postgres | t
|
||||
create_role_with_everything | create_user | postgres | f
|
||||
create_role_with_everything | create_user_2 | postgres | t
|
||||
(8 rows)
|
||||
|
||||
\c - - - :master_port
|
||||
DROP ROLE create_role_with_everything;
|
||||
REVOKE create_group FROM create_role;
|
||||
REVOKE ADMIN OPTION FOR create_group FROM create_role_2;
|
||||
\c - - - :master_port
|
||||
SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, (rolpassword != '') as pass_not_empty, rolvaliduntil FROM pg_authid WHERE rolname LIKE 'create\_%' ORDER BY rolname;
|
||||
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | pass_not_empty | rolvaliduntil
|
||||
---------------------------------------------------------------------
|
||||
create_group | f | t | f | f | f | f | f | -1 | |
|
||||
create_group_2 | f | t | f | f | f | f | f | -1 | |
|
||||
create_role | f | t | f | f | f | f | f | -1 | |
|
||||
create_role"edge | f | t | f | f | f | f | f | -1 | |
|
||||
create_role'edge | f | t | f | f | f | f | f | -1 | |
|
||||
create_role_2 | f | t | f | f | f | f | f | -1 | |
|
||||
create_role_sysid | f | t | f | f | f | f | f | -1 | |
|
||||
create_role_with_nothing | f | f | f | f | f | f | f | 3 | t | Mon May 04 17:00:00 2015 PDT
|
||||
create_user | f | t | f | f | t | f | f | -1 | |
|
||||
create_user_2 | f | t | f | f | t | f | f | -1 | |
|
||||
(10 rows)
|
||||
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE 'create\_%' ORDER BY 1, 2;
|
||||
role | member | grantor | admin_option
|
||||
---------------------------------------------------------------------
|
||||
create_group | create_role_2 | postgres | f
|
||||
(1 row)
|
||||
|
||||
\c - - - :worker_1_port
|
||||
SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, (rolpassword != '') as pass_not_empty, rolvaliduntil FROM pg_authid WHERE rolname LIKE 'create\_%' ORDER BY rolname;
|
||||
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | pass_not_empty | rolvaliduntil
|
||||
---------------------------------------------------------------------
|
||||
create_group | f | t | f | f | f | f | f | -1 | |
|
||||
create_group_2 | f | t | f | f | f | f | f | -1 | |
|
||||
create_role | f | t | f | f | f | f | f | -1 | |
|
||||
create_role"edge | f | t | f | f | f | f | f | -1 | |
|
||||
create_role'edge | f | t | f | f | f | f | f | -1 | |
|
||||
create_role_2 | f | t | f | f | f | f | f | -1 | |
|
||||
create_role_sysid | f | t | f | f | f | f | f | -1 | |
|
||||
create_role_with_nothing | f | f | f | f | f | f | f | 3 | t | Mon May 04 17:00:00 2015 PDT
|
||||
create_user | f | t | f | f | t | f | f | -1 | |
|
||||
create_user_2 | f | t | f | f | t | f | f | -1 | |
|
||||
(10 rows)
|
||||
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE 'create\_%' ORDER BY 1, 2;
|
||||
role | member | grantor | admin_option
|
||||
---------------------------------------------------------------------
|
||||
create_group | create_role_2 | postgres | f
|
||||
(1 row)
|
||||
|
||||
\c - - - :master_port
|
||||
-- test grants with distributed and non-distributed roles
|
||||
SELECT master_remove_node('localhost', :worker_2_port);
|
||||
master_remove_node
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
create role test_admin_role;
|
||||
CREATE ROLE dist_role_1 SUPERUSER;
|
||||
CREATE ROLE dist_role_2;
|
||||
CREATE ROLE dist_role_3;
|
||||
CREATE ROLE dist_role_4;
|
||||
SET citus.enable_create_role_propagation TO OFF;
|
||||
CREATE ROLE non_dist_role_1 SUPERUSER;
|
||||
NOTICE: not propagating CREATE ROLE/USER commands to other nodes
|
||||
HINT: Connect to other nodes directly to manually create all necessary users and roles.
|
||||
CREATE ROLE non_dist_role_2;
|
||||
NOTICE: not propagating CREATE ROLE/USER commands to other nodes
|
||||
HINT: Connect to other nodes directly to manually create all necessary users and roles.
|
||||
CREATE ROLE non_dist_role_3;
|
||||
NOTICE: not propagating CREATE ROLE/USER commands to other nodes
|
||||
HINT: Connect to other nodes directly to manually create all necessary users and roles.
|
||||
CREATE ROLE non_dist_role_4;
|
||||
NOTICE: not propagating CREATE ROLE/USER commands to other nodes
|
||||
HINT: Connect to other nodes directly to manually create all necessary users and roles.
|
||||
SET citus.enable_create_role_propagation TO ON;
|
||||
grant dist_role_3,dist_role_1 to test_admin_role with admin option;
|
||||
SET ROLE dist_role_1;
|
||||
GRANT non_dist_role_1 TO non_dist_role_2;
|
||||
ERROR: connection to the remote node dist_role_1@localhost:xxxxx failed with the following error: FATAL: role "dist_role_1" is not permitted to log in
|
||||
SET citus.enable_create_role_propagation TO OFF;
|
||||
grant dist_role_1 to non_dist_role_1 with admin option;
|
||||
SET ROLE non_dist_role_1;
|
||||
GRANT dist_role_1 TO dist_role_2 granted by non_dist_role_1;
|
||||
RESET ROLE;
|
||||
SET citus.enable_create_role_propagation TO ON;
|
||||
GRANT dist_role_3 TO non_dist_role_3 granted by test_admin_role;
|
||||
ERROR: role "non_dist_role_3" does not exist
|
||||
CONTEXT: while executing command on localhost:xxxxx
|
||||
GRANT non_dist_role_4 TO dist_role_4;
|
||||
GRANT dist_role_3 TO dist_role_4 granted by test_admin_role;
|
||||
SELECT 1 FROM master_add_node('localhost', :worker_2_port);
|
||||
WARNING: role "non_dist_role_1" does not exist
|
||||
CONTEXT: while executing command on localhost:xxxxx
|
||||
ERROR: failure on connection marked as essential: localhost:xxxxx
|
||||
\c - - - :worker_2_port
|
||||
create role non_dist_role_1;
|
||||
\c - - - :master_port
|
||||
--will be successful since non_dist_role_1 is created on worker_2
|
||||
SELECT 1 FROM master_add_node('localhost', :worker_2_port);
|
||||
?column?
|
||||
---------------------------------------------------------------------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::regclass::oid AND objid::regrole::text LIKE '%dist\_%' ORDER BY 1;
|
||||
objid
|
||||
---------------------------------------------------------------------
|
||||
dist_role_1
|
||||
dist_role_2
|
||||
dist_role_3
|
||||
dist_role_4
|
||||
non_dist_role_1
|
||||
non_dist_role_4
|
||||
(6 rows)
|
||||
|
||||
SELECT result FROM run_command_on_all_nodes(
|
||||
$$
|
||||
SELECT json_agg(q.* ORDER BY member) FROM (
|
||||
SELECT member::regrole::text, roleid::regrole::text AS role, grantor::regrole::text, admin_option
|
||||
FROM pg_auth_members WHERE roleid::regrole::text = 'dist_role_3'
|
||||
) q;
|
||||
$$
|
||||
);
|
||||
result
|
||||
---------------------------------------------------------------------
|
||||
[{"member":"dist_role_4","role":"dist_role_3","grantor":"test_admin_role","admin_option":false}, +
|
||||
{"member":"test_admin_role","role":"dist_role_3","grantor":"postgres","admin_option":true}]
|
||||
[{"member":"dist_role_4","role":"dist_role_3","grantor":"test_admin_role","admin_option":false}, +
|
||||
{"member":"test_admin_role","role":"dist_role_3","grantor":"postgres","admin_option":true}]
|
||||
[{"member":"dist_role_4","role":"dist_role_3","grantor":"test_admin_role","admin_option":false}, +
|
||||
{"member":"test_admin_role","role":"dist_role_3","grantor":"postgres","admin_option":true}]
|
||||
(3 rows)
|
||||
|
||||
REVOKE dist_role_3 from dist_role_4 granted by test_admin_role cascade;
|
||||
SELECT result FROM run_command_on_all_nodes(
|
||||
$$
|
||||
SELECT json_agg(q.* ORDER BY member) FROM (
|
||||
SELECT member::regrole::text, roleid::regrole::text AS role, grantor::regrole::text, admin_option
|
||||
FROM pg_auth_members WHERE roleid::regrole::text = 'dist_role_3'
|
||||
order by member::regrole::text
|
||||
) q;
|
||||
$$
|
||||
);
|
||||
result
|
||||
---------------------------------------------------------------------
|
||||
[{"member":"test_admin_role","role":"dist_role_3","grantor":"postgres","admin_option":true}]
|
||||
[{"member":"test_admin_role","role":"dist_role_3","grantor":"postgres","admin_option":true}]
|
||||
[{"member":"test_admin_role","role":"dist_role_3","grantor":"postgres","admin_option":true}]
|
||||
(3 rows)
|
||||
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, (grantor::regrole::text IN ('postgres', 'non_dist_role_1', 'dist_role_1','test_admin_role')) AS grantor, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE '%dist\_%' ORDER BY 1, 2;
|
||||
role | member | grantor | admin_option
|
||||
---------------------------------------------------------------------
|
||||
dist_role_1 | dist_role_2 | t | f
|
||||
dist_role_1 | non_dist_role_1 | t | t
|
||||
dist_role_1 | test_admin_role | t | t
|
||||
dist_role_3 | test_admin_role | t | t
|
||||
non_dist_role_4 | dist_role_4 | t | f
|
||||
(5 rows)
|
||||
|
||||
SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::regclass::oid AND objid::regrole::text LIKE '%dist\_%' ORDER BY 1;
|
||||
objid
|
||||
---------------------------------------------------------------------
|
||||
dist_role_1
|
||||
dist_role_2
|
||||
dist_role_3
|
||||
dist_role_4
|
||||
non_dist_role_1
|
||||
non_dist_role_4
|
||||
(6 rows)
|
||||
|
||||
REVOKE dist_role_3 from non_dist_role_3 granted by test_admin_role cascade;
|
||||
WARNING: role "non_dist_role_3" is not a member of role "dist_role_3"
|
||||
ERROR: role "non_dist_role_3" does not exist
|
||||
CONTEXT: while executing command on localhost:xxxxx
|
||||
SELECT result FROM run_command_on_all_nodes(
|
||||
$$
|
||||
SELECT json_agg(q.* ORDER BY member) FROM (
|
||||
SELECT member::regrole::text, roleid::regrole::text AS role, grantor::regrole::text, admin_option
|
||||
FROM pg_auth_members WHERE roleid::regrole::text = 'dist_role_3'
|
||||
order by member::regrole::text
|
||||
) q;
|
||||
$$
|
||||
);
|
||||
result
|
||||
---------------------------------------------------------------------
|
||||
[{"member":"test_admin_role","role":"dist_role_3","grantor":"postgres","admin_option":true}]
|
||||
[{"member":"test_admin_role","role":"dist_role_3","grantor":"postgres","admin_option":true}]
|
||||
[{"member":"test_admin_role","role":"dist_role_3","grantor":"postgres","admin_option":true}]
|
||||
(3 rows)
|
||||
|
||||
revoke dist_role_3,dist_role_1 from test_admin_role cascade;
|
||||
drop role test_admin_role;
|
||||
\c - - - :worker_1_port
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE '%dist\_%' ORDER BY 1, 2;
|
||||
role | member | grantor | admin_option
|
||||
---------------------------------------------------------------------
|
||||
non_dist_role_4 | dist_role_4 | postgres | f
|
||||
(1 row)
|
||||
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%dist\_%' ORDER BY 1;
|
||||
rolname
|
||||
---------------------------------------------------------------------
|
||||
dist_role_1
|
||||
dist_role_2
|
||||
dist_role_3
|
||||
dist_role_4
|
||||
non_dist_role_1
|
||||
non_dist_role_4
|
||||
(6 rows)
|
||||
|
||||
\c - - - :worker_2_port
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE '%dist\_%' ORDER BY 1, 2;
|
||||
role | member | grantor | admin_option
|
||||
---------------------------------------------------------------------
|
||||
dist_role_1 | dist_role_2 | non_dist_role_1 | f
|
||||
dist_role_1 | non_dist_role_1 | dist_role_1 | t
|
||||
non_dist_role_4 | dist_role_4 | postgres | f
|
||||
(3 rows)
|
||||
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%dist\_%' ORDER BY 1;
|
||||
rolname
|
||||
---------------------------------------------------------------------
|
||||
dist_role_1
|
||||
dist_role_2
|
||||
dist_role_3
|
||||
dist_role_4
|
||||
non_dist_role_1
|
||||
non_dist_role_4
|
||||
(6 rows)
|
||||
|
||||
\c - - - :master_port
|
||||
DROP ROLE dist_role_3, non_dist_role_3, dist_role_4, non_dist_role_4;
|
||||
-- test grant with multiple mixed roles
|
||||
CREATE ROLE dist_mixed_1;
|
||||
CREATE ROLE dist_mixed_2;
|
||||
CREATE ROLE dist_mixed_3;
|
||||
CREATE ROLE dist_mixed_4;
|
||||
SET citus.enable_create_role_propagation TO OFF;
|
||||
CREATE ROLE nondist_mixed_1;
|
||||
NOTICE: not propagating CREATE ROLE/USER commands to other nodes
|
||||
HINT: Connect to other nodes directly to manually create all necessary users and roles.
|
||||
CREATE ROLE nondist_mixed_2;
|
||||
NOTICE: not propagating CREATE ROLE/USER commands to other nodes
|
||||
HINT: Connect to other nodes directly to manually create all necessary users and roles.
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE '%dist\_mixed%' ORDER BY 1, 2;
|
||||
role | member | grantor | admin_option
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::regclass::oid AND objid::regrole::text LIKE '%dist\_mixed%' ORDER BY 1;
|
||||
objid
|
||||
---------------------------------------------------------------------
|
||||
dist_mixed_1
|
||||
dist_mixed_2
|
||||
dist_mixed_3
|
||||
dist_mixed_4
|
||||
(4 rows)
|
||||
|
||||
\c - - - :worker_1_port
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE '%dist\_mixed%' ORDER BY 1, 2;
|
||||
role | member | grantor | admin_option
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%dist\_mixed%' ORDER BY 1;
|
||||
rolname
|
||||
---------------------------------------------------------------------
|
||||
dist_mixed_1
|
||||
dist_mixed_2
|
||||
dist_mixed_3
|
||||
dist_mixed_4
|
||||
(4 rows)
|
||||
|
||||
\c - - - :master_port
|
||||
SELECT master_remove_node('localhost', :worker_2_port);
|
||||
master_remove_node
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
GRANT dist_mixed_1, dist_mixed_2, nondist_mixed_1 TO dist_mixed_3, dist_mixed_4, nondist_mixed_2;
|
||||
ERROR: role "nondist_mixed_2" does not exist
|
||||
CONTEXT: while executing command on localhost:xxxxx
|
||||
\c - - - :worker_1_port
|
||||
create role nondist_mixed_2;
|
||||
\c - - - :master_port
|
||||
GRANT dist_mixed_1, dist_mixed_2, nondist_mixed_1 TO dist_mixed_3, dist_mixed_4, nondist_mixed_2;
|
||||
SELECT 1 FROM master_add_node('localhost', :worker_2_port);
|
||||
?column?
|
||||
---------------------------------------------------------------------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE '%dist\_mixed%' ORDER BY 1, 2;
|
||||
role | member | grantor | admin_option
|
||||
---------------------------------------------------------------------
|
||||
dist_mixed_1 | dist_mixed_3 | postgres | f
|
||||
dist_mixed_1 | dist_mixed_4 | postgres | f
|
||||
dist_mixed_1 | nondist_mixed_2 | postgres | f
|
||||
dist_mixed_2 | dist_mixed_3 | postgres | f
|
||||
dist_mixed_2 | dist_mixed_4 | postgres | f
|
||||
dist_mixed_2 | nondist_mixed_2 | postgres | f
|
||||
nondist_mixed_1 | dist_mixed_3 | postgres | f
|
||||
nondist_mixed_1 | dist_mixed_4 | postgres | f
|
||||
nondist_mixed_1 | nondist_mixed_2 | postgres | f
|
||||
(9 rows)
|
||||
|
||||
SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::regclass::oid AND objid::regrole::text LIKE '%dist\_mixed%' ORDER BY 1;
|
||||
objid
|
||||
---------------------------------------------------------------------
|
||||
dist_mixed_1
|
||||
dist_mixed_2
|
||||
dist_mixed_3
|
||||
dist_mixed_4
|
||||
nondist_mixed_1
|
||||
nondist_mixed_2
|
||||
(6 rows)
|
||||
|
||||
\c - - - :worker_1_port
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE '%dist\_mixed%' ORDER BY 1, 2;
|
||||
role | member | grantor | admin_option
|
||||
---------------------------------------------------------------------
|
||||
dist_mixed_1 | dist_mixed_3 | postgres | f
|
||||
dist_mixed_1 | dist_mixed_4 | postgres | f
|
||||
dist_mixed_1 | nondist_mixed_2 | postgres | f
|
||||
dist_mixed_2 | dist_mixed_3 | postgres | f
|
||||
dist_mixed_2 | dist_mixed_4 | postgres | f
|
||||
dist_mixed_2 | nondist_mixed_2 | postgres | f
|
||||
nondist_mixed_1 | dist_mixed_3 | postgres | f
|
||||
nondist_mixed_1 | dist_mixed_4 | postgres | f
|
||||
nondist_mixed_1 | nondist_mixed_2 | postgres | f
|
||||
(9 rows)
|
||||
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%dist\_mixed%' ORDER BY 1;
|
||||
rolname
|
||||
---------------------------------------------------------------------
|
||||
dist_mixed_1
|
||||
dist_mixed_2
|
||||
dist_mixed_3
|
||||
dist_mixed_4
|
||||
nondist_mixed_1
|
||||
nondist_mixed_2
|
||||
(6 rows)
|
||||
|
||||
\c - - - :worker_2_port
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE '%dist\_mixed%' ORDER BY 1, 2;
|
||||
role | member | grantor | admin_option
|
||||
---------------------------------------------------------------------
|
||||
dist_mixed_1 | dist_mixed_3 | postgres | f
|
||||
dist_mixed_1 | dist_mixed_4 | postgres | f
|
||||
dist_mixed_1 | nondist_mixed_2 | postgres | f
|
||||
dist_mixed_2 | dist_mixed_3 | postgres | f
|
||||
dist_mixed_2 | dist_mixed_4 | postgres | f
|
||||
dist_mixed_2 | nondist_mixed_2 | postgres | f
|
||||
nondist_mixed_1 | dist_mixed_3 | postgres | f
|
||||
nondist_mixed_1 | dist_mixed_4 | postgres | f
|
||||
nondist_mixed_1 | nondist_mixed_2 | postgres | f
|
||||
(9 rows)
|
||||
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%dist\_mixed%' ORDER BY 1;
|
||||
rolname
|
||||
---------------------------------------------------------------------
|
||||
dist_mixed_1
|
||||
dist_mixed_2
|
||||
dist_mixed_3
|
||||
dist_mixed_4
|
||||
nondist_mixed_1
|
||||
nondist_mixed_2
|
||||
(6 rows)
|
||||
|
||||
\c - - - :master_port
|
||||
set citus.log_remote_commands to on;
|
||||
set citus.grep_remote_commands to '%DROP%';
|
||||
DROP ROLE dist_mixed_1, dist_mixed_2, dist_mixed_3, dist_mixed_4, nondist_mixed_1, nondist_mixed_2;
|
||||
NOTICE: issuing DROP ROLE dist_mixed_1, dist_mixed_2, dist_mixed_3, dist_mixed_4, nondist_mixed_1, nondist_mixed_2
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing DROP ROLE dist_mixed_1, dist_mixed_2, dist_mixed_3, dist_mixed_4, nondist_mixed_1, nondist_mixed_2
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
set citus.grep_remote_commands to '%DROP%';
|
||||
reset citus.log_remote_commands;
|
||||
-- test drop multiple roles with non-distributed roles
|
||||
SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::regclass::oid AND objid::regrole::text LIKE '%dist%' ORDER BY 1;
|
||||
objid
|
||||
---------------------------------------------------------------------
|
||||
dist_role_1
|
||||
dist_role_2
|
||||
non_dist_role_1
|
||||
(3 rows)
|
||||
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%dist%' ORDER BY 1;
|
||||
rolname
|
||||
---------------------------------------------------------------------
|
||||
dist_role_1
|
||||
dist_role_2
|
||||
non_dist_role_1
|
||||
non_dist_role_2
|
||||
(4 rows)
|
||||
|
||||
\c - - - :worker_1_port
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%dist%' ORDER BY 1;
|
||||
rolname
|
||||
---------------------------------------------------------------------
|
||||
dist_role_1
|
||||
dist_role_2
|
||||
non_dist_role_1
|
||||
(3 rows)
|
||||
|
||||
\c - - - :master_port
|
||||
DROP ROLE dist_role_1, non_dist_role_1, dist_role_2, non_dist_role_2;
|
||||
SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::regclass::oid AND objid::regrole::text LIKE '%dist%' ORDER BY 1;
|
||||
objid
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%dist%' ORDER BY 1;
|
||||
rolname
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
\c - - - :worker_1_port
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%dist%' ORDER BY 1;
|
||||
rolname
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
\c - - - :worker_2_port
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%dist%' ORDER BY 1;
|
||||
rolname
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
\c - - - :master_port
|
||||
-- test alter part of create or alter role
|
||||
SELECT master_remove_node('localhost', :worker_2_port);
|
||||
master_remove_node
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
DROP ROLE create_role, create_role_2;
|
||||
\c - - - :worker_2_port
|
||||
SELECT rolname, rolcanlogin FROM pg_authid WHERE rolname = 'create_role' OR rolname = 'create_role_2' ORDER BY rolname;
|
||||
rolname | rolcanlogin
|
||||
---------------------------------------------------------------------
|
||||
create_role | f
|
||||
create_role_2 | f
|
||||
(2 rows)
|
||||
|
||||
\c - - - :master_port
|
||||
CREATE ROLE create_role LOGIN;
|
||||
SELECT 1 FROM master_add_node('localhost', :worker_2_port);
|
||||
?column?
|
||||
---------------------------------------------------------------------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
CREATE ROLE create_role_2 LOGIN;
|
||||
\c - - - :worker_2_port
|
||||
SELECT rolname, rolcanlogin FROM pg_authid WHERE rolname = 'create_role' OR rolname = 'create_role_2' ORDER BY rolname;
|
||||
rolname | rolcanlogin
|
||||
---------------------------------------------------------------------
|
||||
create_role | t
|
||||
create_role_2 | t
|
||||
(2 rows)
|
||||
|
||||
\c - - - :master_port
|
||||
-- test cascading grants
|
||||
SET citus.enable_create_role_propagation TO OFF;
|
||||
CREATE ROLE nondist_cascade_1;
|
||||
NOTICE: not propagating CREATE ROLE/USER commands to other nodes
|
||||
HINT: Connect to other nodes directly to manually create all necessary users and roles.
|
||||
CREATE ROLE nondist_cascade_2;
|
||||
NOTICE: not propagating CREATE ROLE/USER commands to other nodes
|
||||
HINT: Connect to other nodes directly to manually create all necessary users and roles.
|
||||
CREATE ROLE nondist_cascade_3;
|
||||
NOTICE: not propagating CREATE ROLE/USER commands to other nodes
|
||||
HINT: Connect to other nodes directly to manually create all necessary users and roles.
|
||||
SET citus.enable_create_role_propagation TO ON;
|
||||
CREATE ROLE dist_cascade;
|
||||
GRANT nondist_cascade_1 TO nondist_cascade_2;
|
||||
ERROR: role "nondist_cascade_2" does not exist
|
||||
CONTEXT: while executing command on localhost:xxxxx
|
||||
GRANT nondist_cascade_2 TO nondist_cascade_3;
|
||||
ERROR: role "nondist_cascade_3" does not exist
|
||||
CONTEXT: while executing command on localhost:xxxxx
|
||||
SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::regclass::oid AND objid::regrole::text LIKE '%cascade%' ORDER BY 1;
|
||||
objid
|
||||
---------------------------------------------------------------------
|
||||
dist_cascade
|
||||
(1 row)
|
||||
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE '%cascade%' ORDER BY 1, 2;
|
||||
role | member | grantor | admin_option
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
\c - - - :worker_1_port
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%cascade%' ORDER BY 1;
|
||||
rolname
|
||||
---------------------------------------------------------------------
|
||||
dist_cascade
|
||||
(1 row)
|
||||
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE '%cascade%' ORDER BY 1, 2;
|
||||
role | member | grantor | admin_option
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
\c - - - :master_port
|
||||
SELECT master_remove_node('localhost', :worker_2_port);
|
||||
master_remove_node
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
GRANT nondist_cascade_3 TO dist_cascade;
|
||||
SELECT 1 FROM master_add_node('localhost', :worker_2_port);
|
||||
?column?
|
||||
---------------------------------------------------------------------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::regclass::oid AND objid::regrole::text LIKE '%cascade%' ORDER BY 1;
|
||||
objid
|
||||
---------------------------------------------------------------------
|
||||
nondist_cascade_3
|
||||
dist_cascade
|
||||
(2 rows)
|
||||
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE '%cascade%' ORDER BY 1, 2;
|
||||
role | member | grantor | admin_option
|
||||
---------------------------------------------------------------------
|
||||
nondist_cascade_3 | dist_cascade | postgres | f
|
||||
(1 row)
|
||||
|
||||
\c - - - :worker_1_port
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%cascade%' ORDER BY 1;
|
||||
rolname
|
||||
---------------------------------------------------------------------
|
||||
dist_cascade
|
||||
nondist_cascade_3
|
||||
(2 rows)
|
||||
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE '%cascade%' ORDER BY 1, 2;
|
||||
role | member | grantor | admin_option
|
||||
---------------------------------------------------------------------
|
||||
nondist_cascade_3 | dist_cascade | postgres | f
|
||||
(1 row)
|
||||
|
||||
\c - - - :worker_2_port
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%cascade%' ORDER BY 1;
|
||||
rolname
|
||||
---------------------------------------------------------------------
|
||||
dist_cascade
|
||||
nondist_cascade_3
|
||||
(2 rows)
|
||||
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE '%cascade%' ORDER BY 1, 2;
|
||||
role | member | grantor | admin_option
|
||||
---------------------------------------------------------------------
|
||||
nondist_cascade_3 | dist_cascade | postgres | f
|
||||
(1 row)
|
||||
|
||||
\c - - - :master_port
|
||||
DROP ROLE create_role, create_role_2, create_group, create_group_2, create_user, create_user_2, create_role_with_nothing, create_role_sysid, "create_role'edge", "create_role""edge";
|
||||
-- test grant non-existing roles
|
||||
CREATE ROLE existing_role_1;
|
||||
CREATE ROLE existing_role_2;
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE '%existing%' ORDER BY 1, 2;
|
||||
role | member | grantor | admin_option
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
GRANT existing_role_1, nonexisting_role_1 TO existing_role_2, nonexisting_role_2;
|
||||
ERROR: role "nonexisting_role_2" does not exist
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE '%existing%' ORDER BY 1, 2;
|
||||
role | member | grantor | admin_option
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
-- test drop non-existing roles
|
||||
SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::regclass::oid AND objid::regrole::text LIKE '%existing%' ORDER BY 1;
|
||||
objid
|
||||
---------------------------------------------------------------------
|
||||
existing_role_1
|
||||
existing_role_2
|
||||
(2 rows)
|
||||
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%existing%' ORDER BY 1;
|
||||
rolname
|
||||
---------------------------------------------------------------------
|
||||
existing_role_1
|
||||
existing_role_2
|
||||
(2 rows)
|
||||
|
||||
\c - - - :worker_1_port
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%existing%' ORDER BY 1;
|
||||
rolname
|
||||
---------------------------------------------------------------------
|
||||
existing_role_1
|
||||
existing_role_2
|
||||
(2 rows)
|
||||
|
||||
\c - - - :master_port
|
||||
DROP ROLE existing_role_1, existing_role_2, nonexisting_role_1, nonexisting_role_2;
|
||||
ERROR: role "nonexisting_role_1" does not exist
|
||||
SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::regclass::oid AND objid::regrole::text LIKE '%existing%' ORDER BY 1;
|
||||
objid
|
||||
---------------------------------------------------------------------
|
||||
existing_role_1
|
||||
existing_role_2
|
||||
(2 rows)
|
||||
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%existing%' ORDER BY 1;
|
||||
rolname
|
||||
---------------------------------------------------------------------
|
||||
existing_role_1
|
||||
existing_role_2
|
||||
(2 rows)
|
||||
|
||||
\c - - - :worker_1_port
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%existing%' ORDER BY 1;
|
||||
rolname
|
||||
---------------------------------------------------------------------
|
||||
existing_role_1
|
||||
existing_role_2
|
||||
(2 rows)
|
||||
|
||||
\c - - - :master_port
|
||||
DROP ROLE IF EXISTS existing_role_1, existing_role_2, nonexisting_role_1, nonexisting_role_2;
|
||||
NOTICE: role "nonexisting_role_1" does not exist, skipping
|
||||
NOTICE: role "nonexisting_role_2" does not exist, skipping
|
||||
SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::regclass::oid AND objid::regrole::text LIKE '%existing%' ORDER BY 1;
|
||||
objid
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%existing%' ORDER BY 1;
|
||||
rolname
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
\c - - - :worker_1_port
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%existing%' ORDER BY 1;
|
||||
rolname
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
\c - - - :master_port
|
||||
DROP ROLE nondist_cascade_1, nondist_cascade_2, nondist_cascade_3, dist_cascade;
|
|
@ -0,0 +1,194 @@
|
|||
-- Active: 1700033167033@@localhost@9700@gurkanindibay@public
|
||||
--In below tests, complex role hierarchy is created and then granted by support is tested.
|
||||
--- Test 1: Tests from main database
|
||||
select 1 from citus_remove_node ('localhost',:worker_2_port);
|
||||
?column?
|
||||
---------------------------------------------------------------------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
set citus.enable_create_role_propagation to off;
|
||||
create role non_dist_role1;
|
||||
NOTICE: not propagating CREATE ROLE/USER commands to other nodes
|
||||
HINT: Connect to other nodes directly to manually create all necessary users and roles.
|
||||
reset citus.enable_create_role_propagation;
|
||||
SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::regclass::oid AND objid::regrole::text= 'non_dist_role1' ORDER BY 1;
|
||||
objid
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
create role dist_role1;
|
||||
create role dist_role2;
|
||||
create role dist_role3;
|
||||
create role dist_role4;
|
||||
create role "dist_role5'_test";
|
||||
grant dist_role2 to dist_role1 with admin option;
|
||||
grant dist_role2 to dist_role3 with admin option granted by dist_role1;
|
||||
grant dist_role3 to dist_role4 with admin option;
|
||||
-- With enable_create_role_propagation on, all grantees are propagated.
|
||||
-- To test non-distributed grantor, set this option off for some roles.
|
||||
set citus.enable_create_role_propagation to off;
|
||||
grant non_dist_role1 to dist_role1 with admin option;
|
||||
grant dist_role2 to non_dist_role1 with admin option;
|
||||
grant dist_role2 to dist_role4 granted by non_dist_role1 ;
|
||||
reset citus.enable_create_role_propagation;
|
||||
grant dist_role2 to "dist_role5'_test" granted by non_dist_role1;--will fail since non_dist_role1 does not exist on worker_1
|
||||
ERROR: role "non_dist_role1" does not exist
|
||||
CONTEXT: while executing command on localhost:xxxxx
|
||||
\c - - - :master_port
|
||||
grant dist_role3 to "dist_role5'_test" granted by dist_role4;
|
||||
grant dist_role2 to "dist_role5'_test" granted by dist_role3;
|
||||
--will fail since non_dist_role2 does not exist in worker_1
|
||||
grant dist_role2 to non_dist_role2 with admin option;
|
||||
ERROR: role "non_dist_role2" does not exist
|
||||
grant dist_role2 to dist_role4 granted by non_dist_role2 ;
|
||||
ERROR: role "non_dist_role2" does not exist
|
||||
grant non_dist_role2 to "dist_role5'_test";
|
||||
ERROR: role "non_dist_role2" does not exist
|
||||
\c - - - :worker_1_port
|
||||
create role non_dist_role2;
|
||||
\c - - - :master_port
|
||||
--will be successful since non_dist_role has been created on worker_1
|
||||
grant dist_role2 to non_dist_role2 with admin option;
|
||||
grant dist_role2 to dist_role4 granted by non_dist_role2 ;
|
||||
grant non_dist_role2 to "dist_role5'_test";
|
||||
grant dist_role4 to "dist_role5'_test" with admin option;
|
||||
select result FROM run_command_on_all_nodes(
|
||||
$$
|
||||
SELECT array_to_json(array_agg(row_to_json(t)))
|
||||
FROM (
|
||||
SELECT member::regrole, roleid::regrole as role, grantor::regrole, admin_option
|
||||
FROM pg_auth_members
|
||||
WHERE member::regrole::text in
|
||||
('dist_role1','non_dist_role1')
|
||||
order by member::regrole::text, roleid::regrole::text
|
||||
) t
|
||||
$$
|
||||
);
|
||||
result
|
||||
---------------------------------------------------------------------
|
||||
[{"member":"dist_role1","role":"dist_role2","grantor":"postgres","admin_option":true},{"member":"dist_role1","role":"non_dist_role1","grantor":"postgres","admin_option":true},{"member":"non_dist_role1","role":"dist_role2","grantor":"postgres","admin_option":true}]
|
||||
[{"member":"dist_role1","role":"dist_role2","grantor":"postgres","admin_option":true}]
|
||||
(2 rows)
|
||||
|
||||
--below command propagates the non_dist_role1 since non_dist_role1 is already granted to dist_role1
|
||||
--and citus sees granted roles as a dependency and citus propagates the dependent roles
|
||||
grant dist_role4 to dist_role1 with admin option GRANTED BY "dist_role5'_test";
|
||||
SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::regclass::oid AND objid::regrole::text= 'non_dist_role1' ORDER BY 1;
|
||||
objid
|
||||
---------------------------------------------------------------------
|
||||
non_dist_role1
|
||||
(1 row)
|
||||
|
||||
grant dist_role4 to dist_role3 with admin option GRANTED BY dist_role1; --fails since already dist_role3 granted to dist_role4
|
||||
ERROR: role "dist_role4" is a member of role "dist_role3"
|
||||
--Below command will not be successful since non_dist_role1 is propagated with the dependency resolution above
|
||||
--however, ADMIN OPTION is not propagated for non_dist_role1 to worker 1 because the citus.enable_create_role_propagation is off
|
||||
grant non_dist_role1 to dist_role4 granted by dist_role1;
|
||||
ERROR: permission denied to grant privileges as role "dist_role1"
|
||||
DETAIL: The grantor must have the ADMIN option on role "non_dist_role1".
|
||||
CONTEXT: while executing command on localhost:xxxxx
|
||||
grant dist_role3 to dist_role1 with admin option GRANTED BY dist_role4;
|
||||
grant "dist_role5'_test" to dist_role1 with admin option;
|
||||
grant "dist_role5'_test" to dist_role3 with admin option GRANTED BY dist_role1;--fails since already dist_role3 granted to "dist_role5'_test"
|
||||
ERROR: role "dist_role5'_test" is a member of role "dist_role3"
|
||||
set citus.enable_create_role_propagation to off;
|
||||
create role non_dist_role_for_mds;
|
||||
NOTICE: not propagating CREATE ROLE/USER commands to other nodes
|
||||
HINT: Connect to other nodes directly to manually create all necessary users and roles.
|
||||
grant dist_role3 to non_dist_role_for_mds with admin option;
|
||||
grant non_dist_role_for_mds to dist_role1 with admin option;
|
||||
grant dist_role3 to dist_role4 with admin option GRANTED BY non_dist_role_for_mds;
|
||||
reset citus.enable_create_role_propagation;
|
||||
SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::regclass::oid AND objid::regrole::text= 'non_dist_role_for_mds' ORDER BY 1;
|
||||
objid
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
select result FROM run_command_on_all_nodes(
|
||||
$$
|
||||
SELECT array_to_json(array_agg(row_to_json(t)))
|
||||
FROM (
|
||||
SELECT member::regrole, roleid::regrole as role, grantor::regrole, admin_option
|
||||
FROM pg_auth_members
|
||||
WHERE member::regrole::text in
|
||||
('dist_role1','dist_role2','dist_role3','dist_role4','"role5''_test"', 'non_dist_role_for_mds','non_dist_role1','non_dist_role2')
|
||||
order by member::regrole::text, roleid::regrole::text
|
||||
) t
|
||||
$$
|
||||
);
|
||||
result
|
||||
---------------------------------------------------------------------
|
||||
[{"member":"dist_role1","role":"\"dist_role5'_test\"","grantor":"postgres","admin_option":true},{"member":"dist_role1","role":"dist_role2","grantor":"postgres","admin_option":true},{"member":"dist_role1","role":"dist_role3","grantor":"dist_role4","admin_option":true},{"member":"dist_role1","role":"dist_role4","grantor":"\"dist_role5'_test\"","admin_option":true},{"member":"dist_role1","role":"non_dist_role1","grantor":"postgres","admin_option":true},{"member":"dist_role1","role":"non_dist_role_for_mds","grantor":"postgres","admin_option":true},{"member":"dist_role3","role":"dist_role2","grantor":"dist_role1","admin_option":true},{"member":"dist_role4","role":"dist_role2","grantor":"non_dist_role2","admin_option":false},{"member":"dist_role4","role":"dist_role2","grantor":"non_dist_role1","admin_option":false},{"member":"dist_role4","role":"dist_role3","grantor":"postgres","admin_option":true},{"member":"dist_role4","role":"dist_role3","grantor":"non_dist_role_for_mds","admin_option":true},{"member":"non_dist_role1","role":"dist_role2","grantor":"postgres","admin_option":true},{"member":"non_dist_role2","role":"dist_role2","grantor":"postgres","admin_option":true},{"member":"non_dist_role_for_mds","role":"dist_role3","grantor":"postgres","admin_option":true}]
|
||||
[{"member":"dist_role1","role":"\"dist_role5'_test\"","grantor":"postgres","admin_option":true},{"member":"dist_role1","role":"dist_role2","grantor":"postgres","admin_option":true},{"member":"dist_role1","role":"dist_role3","grantor":"dist_role4","admin_option":true},{"member":"dist_role1","role":"dist_role4","grantor":"\"dist_role5'_test\"","admin_option":true},{"member":"dist_role3","role":"dist_role2","grantor":"dist_role1","admin_option":true},{"member":"dist_role4","role":"dist_role2","grantor":"non_dist_role2","admin_option":false},{"member":"dist_role4","role":"dist_role3","grantor":"postgres","admin_option":true},{"member":"non_dist_role1","role":"dist_role2","grantor":"postgres","admin_option":true},{"member":"non_dist_role2","role":"dist_role2","grantor":"postgres","admin_option":true}]
|
||||
(2 rows)
|
||||
|
||||
set citus.enable_create_role_propagation to off;
|
||||
create role non_dist_role_mds_fail;
|
||||
NOTICE: not propagating CREATE ROLE/USER commands to other nodes
|
||||
HINT: Connect to other nodes directly to manually create all necessary users and roles.
|
||||
grant dist_role2 to non_dist_role_mds_fail with admin option;
|
||||
grant dist_role2 to non_dist_role_for_mds GRANTED BY non_dist_role_mds_fail;
|
||||
reset citus.enable_create_role_propagation;
|
||||
--will fail since non_dist_role_for_mds is not in dependency resolution
|
||||
select 1 from citus_add_node ('localhost',:worker_2_port);
|
||||
WARNING: role "non_dist_role_mds_fail" does not exist
|
||||
CONTEXT: while executing command on localhost:xxxxx
|
||||
ERROR: failure on connection marked as essential: localhost:xxxxx
|
||||
--this grant statement will add non_dist_role_mds_fail to dist_role3 dependencies
|
||||
grant non_dist_role_mds_fail to dist_role3;
|
||||
--will be successful since non_dist_role_mds_fail is in dependency resolution of dist_role3
|
||||
-- and will be created in metadata sync phase
|
||||
select 1 from citus_add_node ('localhost',:worker_2_port);
|
||||
?column?
|
||||
---------------------------------------------------------------------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
select result FROM run_command_on_all_nodes(
|
||||
$$
|
||||
SELECT array_to_json(array_agg(row_to_json(t)))
|
||||
FROM (
|
||||
SELECT member::regrole, roleid::regrole as role, grantor::regrole, admin_option
|
||||
FROM pg_auth_members
|
||||
WHERE member::regrole::text in
|
||||
('dist_role1','dist_role2','dist_role3','dist_role4','"role5''_test"','non_dist_role_for_mds','non_dist_role1','non_dist_role2')
|
||||
order by member::regrole::text, roleid::regrole::text
|
||||
) t
|
||||
$$
|
||||
);
|
||||
result
|
||||
---------------------------------------------------------------------
|
||||
[{"member":"dist_role1","role":"\"dist_role5'_test\"","grantor":"postgres","admin_option":true},{"member":"dist_role1","role":"dist_role2","grantor":"postgres","admin_option":true},{"member":"dist_role1","role":"dist_role3","grantor":"dist_role4","admin_option":true},{"member":"dist_role1","role":"dist_role4","grantor":"\"dist_role5'_test\"","admin_option":true},{"member":"dist_role1","role":"non_dist_role1","grantor":"postgres","admin_option":true},{"member":"dist_role1","role":"non_dist_role_for_mds","grantor":"postgres","admin_option":true},{"member":"dist_role3","role":"dist_role2","grantor":"dist_role1","admin_option":true},{"member":"dist_role3","role":"non_dist_role_mds_fail","grantor":"postgres","admin_option":false},{"member":"dist_role4","role":"dist_role2","grantor":"non_dist_role2","admin_option":false},{"member":"dist_role4","role":"dist_role2","grantor":"non_dist_role1","admin_option":false},{"member":"dist_role4","role":"dist_role3","grantor":"non_dist_role_for_mds","admin_option":true},{"member":"dist_role4","role":"dist_role3","grantor":"postgres","admin_option":true},{"member":"non_dist_role1","role":"dist_role2","grantor":"postgres","admin_option":true},{"member":"non_dist_role2","role":"dist_role2","grantor":"postgres","admin_option":true},{"member":"non_dist_role_for_mds","role":"dist_role2","grantor":"non_dist_role_mds_fail","admin_option":false},{"member":"non_dist_role_for_mds","role":"dist_role3","grantor":"postgres","admin_option":true}]
|
||||
[{"member":"dist_role1","role":"\"dist_role5'_test\"","grantor":"postgres","admin_option":true},{"member":"dist_role1","role":"dist_role2","grantor":"postgres","admin_option":true},{"member":"dist_role1","role":"dist_role3","grantor":"dist_role4","admin_option":true},{"member":"dist_role1","role":"dist_role4","grantor":"\"dist_role5'_test\"","admin_option":true},{"member":"dist_role3","role":"dist_role2","grantor":"dist_role1","admin_option":true},{"member":"dist_role3","role":"non_dist_role_mds_fail","grantor":"postgres","admin_option":false},{"member":"dist_role4","role":"dist_role2","grantor":"non_dist_role2","admin_option":false},{"member":"dist_role4","role":"dist_role3","grantor":"postgres","admin_option":true},{"member":"non_dist_role1","role":"dist_role2","grantor":"postgres","admin_option":true},{"member":"non_dist_role2","role":"dist_role2","grantor":"postgres","admin_option":true}]
|
||||
[{"member":"dist_role1","role":"\"dist_role5'_test\"","grantor":"postgres","admin_option":true},{"member":"dist_role1","role":"dist_role2","grantor":"postgres","admin_option":true},{"member":"dist_role1","role":"dist_role3","grantor":"dist_role4","admin_option":true},{"member":"dist_role1","role":"dist_role4","grantor":"\"dist_role5'_test\"","admin_option":true},{"member":"dist_role1","role":"non_dist_role1","grantor":"postgres","admin_option":true},{"member":"dist_role1","role":"non_dist_role_for_mds","grantor":"postgres","admin_option":true},{"member":"dist_role3","role":"dist_role2","grantor":"dist_role1","admin_option":true},{"member":"dist_role3","role":"non_dist_role_mds_fail","grantor":"postgres","admin_option":false},{"member":"dist_role4","role":"dist_role2","grantor":"non_dist_role2","admin_option":false},{"member":"dist_role4","role":"dist_role2","grantor":"non_dist_role1","admin_option":false},{"member":"dist_role4","role":"dist_role3","grantor":"postgres","admin_option":true},{"member":"dist_role4","role":"dist_role3","grantor":"non_dist_role_for_mds","admin_option":true},{"member":"non_dist_role1","role":"dist_role2","grantor":"postgres","admin_option":true},{"member":"non_dist_role2","role":"dist_role2","grantor":"postgres","admin_option":true},{"member":"non_dist_role_for_mds","role":"dist_role2","grantor":"non_dist_role_mds_fail","admin_option":false},{"member":"non_dist_role_for_mds","role":"dist_role3","grantor":"postgres","admin_option":true}]
|
||||
(3 rows)
|
||||
|
||||
--clean all resources
|
||||
drop role dist_role1,dist_role2,dist_role3,dist_role4,"dist_role5'_test";
|
||||
drop role non_dist_role1,non_dist_role2,non_dist_role_for_mds,non_dist_role_mds_fail;
|
||||
SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::regclass::oid AND objid::regrole::text= 'non_dist_role1' ORDER BY 1;
|
||||
objid
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
reset citus.enable_create_role_propagation;
|
||||
select result FROM run_command_on_all_nodes(
|
||||
$$
|
||||
SELECT array_to_json(array_agg(row_to_json(t)))
|
||||
FROM (
|
||||
SELECT member::regrole, roleid::regrole as role, grantor::regrole, admin_option
|
||||
FROM pg_auth_members
|
||||
WHERE member::regrole::text in
|
||||
('dist_role1','dist_role2','dist_role3','dist_role4','"role5''_test"','non_dist_role_for_mds','non_dist_role1','non_dist_role2')
|
||||
order by member::regrole::text, roleid::regrole::text
|
||||
) t
|
||||
$$
|
||||
);
|
||||
result
|
||||
---------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
(3 rows)
|
||||
|
|
@ -0,0 +1,193 @@
|
|||
-- Active: 1700033167033@@localhost@9700@gurkanindibay@public
|
||||
--In below tests, complex role hierarchy is created and then granted by support is tested.
|
||||
--- Test 1: Tests from main database
|
||||
select 1 from citus_remove_node ('localhost',:worker_2_port);
|
||||
?column?
|
||||
---------------------------------------------------------------------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
set citus.enable_create_role_propagation to off;
|
||||
create role non_dist_role1;
|
||||
NOTICE: not propagating CREATE ROLE/USER commands to other nodes
|
||||
HINT: Connect to other nodes directly to manually create all necessary users and roles.
|
||||
reset citus.enable_create_role_propagation;
|
||||
SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::regclass::oid AND objid::regrole::text= 'non_dist_role1' ORDER BY 1;
|
||||
objid
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
create role dist_role1;
|
||||
create role dist_role2;
|
||||
create role dist_role3;
|
||||
create role dist_role4;
|
||||
create role "dist_role5'_test";
|
||||
grant dist_role2 to dist_role1 with admin option;
|
||||
grant dist_role2 to dist_role3 with admin option granted by dist_role1;
|
||||
grant dist_role3 to dist_role4 with admin option;
|
||||
-- With enable_create_role_propagation on, all grantees are propagated.
|
||||
-- To test non-distributed grantor, set this option off for some roles.
|
||||
set citus.enable_create_role_propagation to off;
|
||||
grant non_dist_role1 to dist_role1 with admin option;
|
||||
grant dist_role2 to non_dist_role1 with admin option;
|
||||
grant dist_role2 to dist_role4 granted by non_dist_role1 ;
|
||||
reset citus.enable_create_role_propagation;
|
||||
grant dist_role2 to "dist_role5'_test" granted by non_dist_role1;--will fail since non_dist_role1 does not exist on worker_1
|
||||
ERROR: role "non_dist_role1" does not exist
|
||||
CONTEXT: while executing command on localhost:xxxxx
|
||||
\c - - - :master_port
|
||||
grant dist_role3 to "dist_role5'_test" granted by dist_role4;
|
||||
grant dist_role2 to "dist_role5'_test" granted by dist_role3;
|
||||
--will fail since non_dist_role2 does not exist in worker_1
|
||||
grant dist_role2 to non_dist_role2 with admin option;
|
||||
ERROR: role "non_dist_role2" does not exist
|
||||
grant dist_role2 to dist_role4 granted by non_dist_role2 ;
|
||||
ERROR: role "non_dist_role2" does not exist
|
||||
grant non_dist_role2 to "dist_role5'_test";
|
||||
ERROR: role "non_dist_role2" does not exist
|
||||
\c - - - :worker_1_port
|
||||
create role non_dist_role2;
|
||||
\c - - - :master_port
|
||||
--will be successful since non_dist_role has been created on worker_1
|
||||
grant dist_role2 to non_dist_role2 with admin option;
|
||||
grant dist_role2 to dist_role4 granted by non_dist_role2 ;
|
||||
NOTICE: role "dist_role4" is already a member of role "dist_role2"
|
||||
grant non_dist_role2 to "dist_role5'_test";
|
||||
grant dist_role4 to "dist_role5'_test" with admin option;
|
||||
select result FROM run_command_on_all_nodes(
|
||||
$$
|
||||
SELECT array_to_json(array_agg(row_to_json(t)))
|
||||
FROM (
|
||||
SELECT member::regrole, roleid::regrole as role, grantor::regrole, admin_option
|
||||
FROM pg_auth_members
|
||||
WHERE member::regrole::text in
|
||||
('dist_role1','non_dist_role1')
|
||||
order by member::regrole::text, roleid::regrole::text
|
||||
) t
|
||||
$$
|
||||
);
|
||||
result
|
||||
---------------------------------------------------------------------
|
||||
[{"member":"dist_role1","role":"dist_role2","grantor":"postgres","admin_option":true},{"member":"dist_role1","role":"non_dist_role1","grantor":"postgres","admin_option":true},{"member":"non_dist_role1","role":"dist_role2","grantor":"postgres","admin_option":true}]
|
||||
[{"member":"dist_role1","role":"dist_role2","grantor":"postgres","admin_option":true}]
|
||||
(2 rows)
|
||||
|
||||
--below command propagates the non_dist_role1 since non_dist_role1 is already granted to dist_role1
|
||||
--and citus sees granted roles as a dependency and citus propagates the dependent roles
|
||||
grant dist_role4 to dist_role1 with admin option GRANTED BY "dist_role5'_test";
|
||||
SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::regclass::oid AND objid::regrole::text= 'non_dist_role1' ORDER BY 1;
|
||||
objid
|
||||
---------------------------------------------------------------------
|
||||
non_dist_role1
|
||||
(1 row)
|
||||
|
||||
grant dist_role4 to dist_role3 with admin option GRANTED BY dist_role1; --fails since already dist_role3 granted to dist_role4
|
||||
ERROR: role "dist_role4" is a member of role "dist_role3"
|
||||
--Below command will not be successful since non_dist_role1 is propagated with the dependency resolution above
|
||||
--however, ADMIN OPTION is not propagated for non_dist_role1 to worker 1 because the citus.enable_create_role_propagation is off
|
||||
grant non_dist_role1 to dist_role4 granted by dist_role1;
|
||||
grant dist_role3 to dist_role1 with admin option GRANTED BY dist_role4;
|
||||
grant "dist_role5'_test" to dist_role1 with admin option;
|
||||
grant "dist_role5'_test" to dist_role3 with admin option GRANTED BY dist_role1;--fails since already dist_role3 granted to "dist_role5'_test"
|
||||
ERROR: role "dist_role5'_test" is a member of role "dist_role3"
|
||||
set citus.enable_create_role_propagation to off;
|
||||
create role non_dist_role_for_mds;
|
||||
NOTICE: not propagating CREATE ROLE/USER commands to other nodes
|
||||
HINT: Connect to other nodes directly to manually create all necessary users and roles.
|
||||
grant dist_role3 to non_dist_role_for_mds with admin option;
|
||||
grant non_dist_role_for_mds to dist_role1 with admin option;
|
||||
grant dist_role3 to dist_role4 with admin option GRANTED BY non_dist_role_for_mds;
|
||||
NOTICE: role "dist_role4" is already a member of role "dist_role3"
|
||||
reset citus.enable_create_role_propagation;
|
||||
SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::regclass::oid AND objid::regrole::text= 'non_dist_role_for_mds' ORDER BY 1;
|
||||
objid
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
select result FROM run_command_on_all_nodes(
|
||||
$$
|
||||
SELECT array_to_json(array_agg(row_to_json(t)))
|
||||
FROM (
|
||||
SELECT member::regrole, roleid::regrole as role, grantor::regrole, admin_option
|
||||
FROM pg_auth_members
|
||||
WHERE member::regrole::text in
|
||||
('dist_role1','dist_role2','dist_role3','dist_role4','"role5''_test"', 'non_dist_role_for_mds','non_dist_role1','non_dist_role2')
|
||||
order by member::regrole::text, roleid::regrole::text
|
||||
) t
|
||||
$$
|
||||
);
|
||||
result
|
||||
---------------------------------------------------------------------
|
||||
[{"member":"dist_role1","role":"\"dist_role5'_test\"","grantor":"postgres","admin_option":true},{"member":"dist_role1","role":"dist_role2","grantor":"postgres","admin_option":true},{"member":"dist_role1","role":"dist_role3","grantor":"dist_role4","admin_option":true},{"member":"dist_role1","role":"dist_role4","grantor":"\"dist_role5'_test\"","admin_option":true},{"member":"dist_role1","role":"non_dist_role1","grantor":"postgres","admin_option":true},{"member":"dist_role1","role":"non_dist_role_for_mds","grantor":"postgres","admin_option":true},{"member":"dist_role3","role":"dist_role2","grantor":"dist_role1","admin_option":true},{"member":"dist_role4","role":"dist_role2","grantor":"non_dist_role1","admin_option":false},{"member":"dist_role4","role":"dist_role3","grantor":"postgres","admin_option":true},{"member":"dist_role4","role":"non_dist_role1","grantor":"dist_role1","admin_option":false},{"member":"non_dist_role1","role":"dist_role2","grantor":"postgres","admin_option":true},{"member":"non_dist_role2","role":"dist_role2","grantor":"postgres","admin_option":true},{"member":"non_dist_role_for_mds","role":"dist_role3","grantor":"postgres","admin_option":true}]
|
||||
[{"member":"dist_role1","role":"\"dist_role5'_test\"","grantor":"postgres","admin_option":true},{"member":"dist_role1","role":"dist_role2","grantor":"postgres","admin_option":true},{"member":"dist_role1","role":"dist_role3","grantor":"dist_role4","admin_option":true},{"member":"dist_role1","role":"dist_role4","grantor":"\"dist_role5'_test\"","admin_option":true},{"member":"dist_role3","role":"dist_role2","grantor":"dist_role1","admin_option":true},{"member":"dist_role4","role":"dist_role2","grantor":"non_dist_role2","admin_option":false},{"member":"dist_role4","role":"dist_role3","grantor":"postgres","admin_option":true},{"member":"dist_role4","role":"non_dist_role1","grantor":"dist_role1","admin_option":false},{"member":"non_dist_role1","role":"dist_role2","grantor":"postgres","admin_option":true},{"member":"non_dist_role2","role":"dist_role2","grantor":"postgres","admin_option":true}]
|
||||
(2 rows)
|
||||
|
||||
set citus.enable_create_role_propagation to off;
|
||||
create role non_dist_role_mds_fail;
|
||||
NOTICE: not propagating CREATE ROLE/USER commands to other nodes
|
||||
HINT: Connect to other nodes directly to manually create all necessary users and roles.
|
||||
grant dist_role2 to non_dist_role_mds_fail with admin option;
|
||||
grant dist_role2 to non_dist_role_for_mds GRANTED BY non_dist_role_mds_fail;
|
||||
reset citus.enable_create_role_propagation;
|
||||
--will fail since non_dist_role_for_mds is not in dependency resolution
|
||||
select 1 from citus_add_node ('localhost',:worker_2_port);
|
||||
WARNING: role "non_dist_role_mds_fail" does not exist
|
||||
CONTEXT: while executing command on localhost:xxxxx
|
||||
ERROR: failure on connection marked as essential: localhost:xxxxx
|
||||
--this grant statement will add non_dist_role_mds_fail to dist_role3 dependencies
|
||||
grant non_dist_role_mds_fail to dist_role3;
|
||||
--will be successful since non_dist_role_mds_fail is in dependency resolution of dist_role3
|
||||
-- and will be created in metadata sync phase
|
||||
select 1 from citus_add_node ('localhost',:worker_2_port);
|
||||
?column?
|
||||
---------------------------------------------------------------------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
select result FROM run_command_on_all_nodes(
|
||||
$$
|
||||
SELECT array_to_json(array_agg(row_to_json(t)))
|
||||
FROM (
|
||||
SELECT member::regrole, roleid::regrole as role, grantor::regrole, admin_option
|
||||
FROM pg_auth_members
|
||||
WHERE member::regrole::text in
|
||||
('dist_role1','dist_role2','dist_role3','dist_role4','"role5''_test"','non_dist_role_for_mds','non_dist_role1','non_dist_role2')
|
||||
order by member::regrole::text, roleid::regrole::text
|
||||
) t
|
||||
$$
|
||||
);
|
||||
result
|
||||
---------------------------------------------------------------------
|
||||
[{"member":"dist_role1","role":"\"dist_role5'_test\"","grantor":"postgres","admin_option":true},{"member":"dist_role1","role":"dist_role2","grantor":"postgres","admin_option":true},{"member":"dist_role1","role":"dist_role3","grantor":"dist_role4","admin_option":true},{"member":"dist_role1","role":"dist_role4","grantor":"\"dist_role5'_test\"","admin_option":true},{"member":"dist_role1","role":"non_dist_role1","grantor":"postgres","admin_option":true},{"member":"dist_role1","role":"non_dist_role_for_mds","grantor":"postgres","admin_option":true},{"member":"dist_role3","role":"dist_role2","grantor":"dist_role1","admin_option":true},{"member":"dist_role3","role":"non_dist_role_mds_fail","grantor":"postgres","admin_option":false},{"member":"dist_role4","role":"dist_role2","grantor":"non_dist_role1","admin_option":false},{"member":"dist_role4","role":"dist_role3","grantor":"postgres","admin_option":true},{"member":"dist_role4","role":"non_dist_role1","grantor":"dist_role1","admin_option":false},{"member":"non_dist_role1","role":"dist_role2","grantor":"postgres","admin_option":true},{"member":"non_dist_role2","role":"dist_role2","grantor":"postgres","admin_option":true},{"member":"non_dist_role_for_mds","role":"dist_role2","grantor":"non_dist_role_mds_fail","admin_option":false},{"member":"non_dist_role_for_mds","role":"dist_role3","grantor":"postgres","admin_option":true}]
|
||||
[{"member":"dist_role1","role":"\"dist_role5'_test\"","grantor":"postgres","admin_option":true},{"member":"dist_role1","role":"dist_role2","grantor":"postgres","admin_option":true},{"member":"dist_role1","role":"dist_role3","grantor":"dist_role4","admin_option":true},{"member":"dist_role1","role":"dist_role4","grantor":"\"dist_role5'_test\"","admin_option":true},{"member":"dist_role3","role":"dist_role2","grantor":"dist_role1","admin_option":true},{"member":"dist_role3","role":"non_dist_role_mds_fail","grantor":"postgres","admin_option":false},{"member":"dist_role4","role":"dist_role2","grantor":"non_dist_role2","admin_option":false},{"member":"dist_role4","role":"dist_role3","grantor":"postgres","admin_option":true},{"member":"dist_role4","role":"non_dist_role1","grantor":"dist_role1","admin_option":false},{"member":"non_dist_role1","role":"dist_role2","grantor":"postgres","admin_option":true},{"member":"non_dist_role2","role":"dist_role2","grantor":"postgres","admin_option":true}]
|
||||
[{"member":"dist_role1","role":"\"dist_role5'_test\"","grantor":"postgres","admin_option":true},{"member":"dist_role1","role":"dist_role2","grantor":"postgres","admin_option":true},{"member":"dist_role1","role":"dist_role3","grantor":"dist_role4","admin_option":true},{"member":"dist_role1","role":"dist_role4","grantor":"\"dist_role5'_test\"","admin_option":true},{"member":"dist_role1","role":"non_dist_role1","grantor":"postgres","admin_option":true},{"member":"dist_role1","role":"non_dist_role_for_mds","grantor":"postgres","admin_option":true},{"member":"dist_role3","role":"dist_role2","grantor":"dist_role1","admin_option":true},{"member":"dist_role3","role":"non_dist_role_mds_fail","grantor":"postgres","admin_option":false},{"member":"dist_role4","role":"dist_role2","grantor":"non_dist_role1","admin_option":false},{"member":"dist_role4","role":"dist_role3","grantor":"postgres","admin_option":true},{"member":"dist_role4","role":"non_dist_role1","grantor":"dist_role1","admin_option":false},{"member":"non_dist_role1","role":"dist_role2","grantor":"postgres","admin_option":true},{"member":"non_dist_role2","role":"dist_role2","grantor":"postgres","admin_option":true},{"member":"non_dist_role_for_mds","role":"dist_role2","grantor":"non_dist_role_mds_fail","admin_option":false},{"member":"non_dist_role_for_mds","role":"dist_role3","grantor":"postgres","admin_option":true}]
|
||||
(3 rows)
|
||||
|
||||
--clean all resources
|
||||
drop role dist_role1,dist_role2,dist_role3,dist_role4,"dist_role5'_test";
|
||||
drop role non_dist_role1,non_dist_role2,non_dist_role_for_mds,non_dist_role_mds_fail;
|
||||
SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::regclass::oid AND objid::regrole::text= 'non_dist_role1' ORDER BY 1;
|
||||
objid
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
reset citus.enable_create_role_propagation;
|
||||
select result FROM run_command_on_all_nodes(
|
||||
$$
|
||||
SELECT array_to_json(array_agg(row_to_json(t)))
|
||||
FROM (
|
||||
SELECT member::regrole, roleid::regrole as role, grantor::regrole, admin_option
|
||||
FROM pg_auth_members
|
||||
WHERE member::regrole::text in
|
||||
('dist_role1','dist_role2','dist_role3','dist_role4','"role5''_test"','non_dist_role_for_mds','non_dist_role1','non_dist_role2')
|
||||
order by member::regrole::text, roleid::regrole::text
|
||||
) t
|
||||
$$
|
||||
);
|
||||
result
|
||||
---------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
(3 rows)
|
||||
|
|
@ -1012,14 +1012,14 @@ WHERE roleid::regrole::text = 'role1' ORDER BY 1, 2;
|
|||
-- Set GUCs to log remote commands and filter on REVOKE commands
|
||||
SET citus.log_remote_commands TO on;
|
||||
SET citus.grep_remote_commands = '%REVOKE%';
|
||||
-- test REVOKES as well
|
||||
GRANT role1 TO role2;
|
||||
REVOKE SET OPTION FOR role1 FROM role2;
|
||||
-- test REVOKES as well
|
||||
GRANT role1 TO role2;
|
||||
REVOKE SET OPTION FOR role1 FROM role2;
|
||||
NOTICE: issuing REVOKE SET OPTION FOR role1 FROM role2 RESTRICT;
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing REVOKE SET OPTION FOR role1 FROM role2 RESTRICT;
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
REVOKE INHERIT OPTION FOR role1 FROM role2;
|
||||
REVOKE INHERIT OPTION FOR role1 FROM role2;
|
||||
NOTICE: issuing REVOKE INHERIT OPTION FOR role1 FROM role2 RESTRICT;
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing REVOKE INHERIT OPTION FOR role1 FROM role2 RESTRICT;
|
||||
|
@ -1033,14 +1033,16 @@ CREATE ROLE role5;
|
|||
RESET citus.enable_ddl_propagation;
|
||||
-- by default, admin option is false, inherit is true, set is true
|
||||
GRANT role3 TO role4;
|
||||
ERROR: role "role4" does not exist
|
||||
CONTEXT: while executing command on localhost:xxxxx
|
||||
GRANT role3 TO role5 WITH ADMIN TRUE, INHERIT FALSE, SET FALSE;
|
||||
ERROR: role "role5" does not exist
|
||||
CONTEXT: while executing command on localhost:xxxxx
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, admin_option, inherit_option, set_option FROM pg_auth_members
|
||||
WHERE roleid::regrole::text = 'role3' ORDER BY 1, 2;
|
||||
role | member | admin_option | inherit_option | set_option
|
||||
role | member | admin_option | inherit_option | set_option
|
||||
---------------------------------------------------------------------
|
||||
role3 | role4 | f | t | t
|
||||
role3 | role5 | t | f | f
|
||||
(2 rows)
|
||||
(0 rows)
|
||||
|
||||
DROP ROLE role3, role4, role5;
|
||||
-- Test that everything works fine for roles that are propagated
|
||||
|
@ -1120,7 +1122,7 @@ DROP ROLE role6, role7, role8, role9, role10, role11, role12,
|
|||
-- when adding a new node.
|
||||
-- First, we need to remove the node:
|
||||
SELECT 1 FROM citus_remove_node('localhost', :worker_2_port);
|
||||
?column?
|
||||
?column?
|
||||
---------------------------------------------------------------------
|
||||
1
|
||||
(1 row)
|
||||
|
|
|
@ -62,6 +62,7 @@ test: alter_database_propagation
|
|||
|
||||
test: citus_shards
|
||||
test: reassign_owned
|
||||
test: granted_by_support
|
||||
|
||||
# ----------
|
||||
# multi_citus_tools tests utility functions written for citus tools
|
||||
|
|
|
@ -75,12 +75,12 @@ SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::t
|
|||
|
||||
\c - - - :master_port
|
||||
|
||||
create role test_admin_role;
|
||||
|
||||
-- test grants with distributed and non-distributed roles
|
||||
|
||||
SELECT master_remove_node('localhost', :worker_2_port);
|
||||
|
||||
create role test_admin_role;
|
||||
|
||||
CREATE ROLE dist_role_1 SUPERUSER;
|
||||
CREATE ROLE dist_role_2;
|
||||
CREATE ROLE dist_role_3;
|
||||
|
@ -123,6 +123,17 @@ GRANT dist_role_3 TO dist_role_4 granted by test_admin_role;
|
|||
|
||||
SELECT 1 FROM master_add_node('localhost', :worker_2_port);
|
||||
|
||||
\c - - - :worker_2_port
|
||||
create role non_dist_role_1;
|
||||
|
||||
\c - - - :master_port
|
||||
--will be successful since non_dist_role_1 is created on worker_2
|
||||
SELECT 1 FROM master_add_node('localhost', :worker_2_port);
|
||||
|
||||
SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::regclass::oid AND objid::regrole::text LIKE '%dist\_%' ORDER BY 1;
|
||||
|
||||
|
||||
|
||||
SELECT result FROM run_command_on_all_nodes(
|
||||
$$
|
||||
SELECT json_agg(q.* ORDER BY member) FROM (
|
||||
|
@ -194,6 +205,12 @@ SELECT rolname FROM pg_authid WHERE rolname LIKE '%dist\_mixed%' ORDER BY 1;
|
|||
|
||||
SELECT master_remove_node('localhost', :worker_2_port);
|
||||
GRANT dist_mixed_1, dist_mixed_2, nondist_mixed_1 TO dist_mixed_3, dist_mixed_4, nondist_mixed_2;
|
||||
|
||||
\c - - - :worker_1_port
|
||||
create role nondist_mixed_2;
|
||||
|
||||
\c - - - :master_port
|
||||
GRANT dist_mixed_1, dist_mixed_2, nondist_mixed_1 TO dist_mixed_3, dist_mixed_4, nondist_mixed_2;
|
||||
SELECT 1 FROM master_add_node('localhost', :worker_2_port);
|
||||
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE '%dist\_mixed%' ORDER BY 1, 2;
|
||||
|
@ -206,7 +223,12 @@ SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::t
|
|||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%dist\_mixed%' ORDER BY 1;
|
||||
|
||||
\c - - - :master_port
|
||||
set citus.log_remote_commands to on;
|
||||
set citus.grep_remote_commands to '%DROP%';
|
||||
DROP ROLE dist_mixed_1, dist_mixed_2, dist_mixed_3, dist_mixed_4, nondist_mixed_1, nondist_mixed_2;
|
||||
set citus.grep_remote_commands to '%DROP%';
|
||||
reset citus.log_remote_commands;
|
||||
|
||||
|
||||
-- test drop multiple roles with non-distributed roles
|
||||
|
||||
|
@ -224,6 +246,9 @@ SELECT rolname FROM pg_authid WHERE rolname LIKE '%dist%' ORDER BY 1;
|
|||
|
||||
\c - - - :worker_1_port
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%dist%' ORDER BY 1;
|
||||
|
||||
\c - - - :worker_2_port
|
||||
SELECT rolname FROM pg_authid WHERE rolname LIKE '%dist%' ORDER BY 1;
|
||||
\c - - - :master_port
|
||||
|
||||
-- test alter part of create or alter role
|
||||
|
@ -321,3 +346,4 @@ SELECT rolname FROM pg_authid WHERE rolname LIKE '%existing%' ORDER BY 1;
|
|||
\c - - - :master_port
|
||||
|
||||
DROP ROLE nondist_cascade_1, nondist_cascade_2, nondist_cascade_3, dist_cascade;
|
||||
|
||||
|
|
|
@ -0,0 +1,168 @@
|
|||
-- Active: 1700033167033@@localhost@9700@gurkanindibay@public
|
||||
--In below tests, complex role hierarchy is created and then granted by support is tested.
|
||||
|
||||
--- Test 1: Tests from main database
|
||||
select 1 from citus_remove_node ('localhost',:worker_2_port);
|
||||
set citus.enable_create_role_propagation to off;
|
||||
create role non_dist_role1;
|
||||
reset citus.enable_create_role_propagation;
|
||||
SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::regclass::oid AND objid::regrole::text= 'non_dist_role1' ORDER BY 1;
|
||||
|
||||
create role dist_role1;
|
||||
create role dist_role2;
|
||||
create role dist_role3;
|
||||
create role dist_role4;
|
||||
create role "dist_role5'_test";
|
||||
|
||||
grant dist_role2 to dist_role1 with admin option;
|
||||
grant dist_role2 to dist_role3 with admin option granted by dist_role1;
|
||||
grant dist_role3 to dist_role4 with admin option;
|
||||
|
||||
-- With enable_create_role_propagation on, all grantees are propagated.
|
||||
-- To test non-distributed grantor, set this option off for some roles.
|
||||
set citus.enable_create_role_propagation to off;
|
||||
grant non_dist_role1 to dist_role1 with admin option;
|
||||
grant dist_role2 to non_dist_role1 with admin option;
|
||||
grant dist_role2 to dist_role4 granted by non_dist_role1 ;
|
||||
reset citus.enable_create_role_propagation;
|
||||
|
||||
grant dist_role2 to "dist_role5'_test" granted by non_dist_role1;--will fail since non_dist_role1 does not exist on worker_1
|
||||
|
||||
|
||||
\c - - - :master_port
|
||||
grant dist_role3 to "dist_role5'_test" granted by dist_role4;
|
||||
grant dist_role2 to "dist_role5'_test" granted by dist_role3;
|
||||
|
||||
|
||||
--will fail since non_dist_role2 does not exist in worker_1
|
||||
grant dist_role2 to non_dist_role2 with admin option;
|
||||
grant dist_role2 to dist_role4 granted by non_dist_role2 ;
|
||||
grant non_dist_role2 to "dist_role5'_test";
|
||||
|
||||
|
||||
\c - - - :worker_1_port
|
||||
create role non_dist_role2;
|
||||
|
||||
\c - - - :master_port
|
||||
--will be successful since non_dist_role has been created on worker_1
|
||||
grant dist_role2 to non_dist_role2 with admin option;
|
||||
grant dist_role2 to dist_role4 granted by non_dist_role2 ;
|
||||
grant non_dist_role2 to "dist_role5'_test";
|
||||
|
||||
|
||||
grant dist_role4 to "dist_role5'_test" with admin option;
|
||||
|
||||
select result FROM run_command_on_all_nodes(
|
||||
$$
|
||||
SELECT array_to_json(array_agg(row_to_json(t)))
|
||||
FROM (
|
||||
SELECT member::regrole, roleid::regrole as role, grantor::regrole, admin_option
|
||||
FROM pg_auth_members
|
||||
WHERE member::regrole::text in
|
||||
('dist_role1','non_dist_role1')
|
||||
order by member::regrole::text, roleid::regrole::text
|
||||
) t
|
||||
$$
|
||||
);
|
||||
|
||||
--below command propagates the non_dist_role1 since non_dist_role1 is already granted to dist_role1
|
||||
--and citus sees granted roles as a dependency and citus propagates the dependent roles
|
||||
|
||||
grant dist_role4 to dist_role1 with admin option GRANTED BY "dist_role5'_test";
|
||||
|
||||
SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::regclass::oid AND objid::regrole::text= 'non_dist_role1' ORDER BY 1;
|
||||
|
||||
grant dist_role4 to dist_role3 with admin option GRANTED BY dist_role1; --fails since already dist_role3 granted to dist_role4
|
||||
|
||||
--Below command will not be successful since non_dist_role1 is propagated with the dependency resolution above
|
||||
--however, ADMIN OPTION is not propagated for non_dist_role1 to worker 1 because the citus.enable_create_role_propagation is off
|
||||
grant non_dist_role1 to dist_role4 granted by dist_role1;
|
||||
|
||||
grant dist_role3 to dist_role1 with admin option GRANTED BY dist_role4;
|
||||
grant "dist_role5'_test" to dist_role1 with admin option;
|
||||
grant "dist_role5'_test" to dist_role3 with admin option GRANTED BY dist_role1;--fails since already dist_role3 granted to "dist_role5'_test"
|
||||
|
||||
|
||||
|
||||
|
||||
set citus.enable_create_role_propagation to off;
|
||||
create role non_dist_role_for_mds;
|
||||
|
||||
grant dist_role3 to non_dist_role_for_mds with admin option;
|
||||
grant non_dist_role_for_mds to dist_role1 with admin option;
|
||||
|
||||
grant dist_role3 to dist_role4 with admin option GRANTED BY non_dist_role_for_mds;
|
||||
reset citus.enable_create_role_propagation;
|
||||
|
||||
SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::regclass::oid AND objid::regrole::text= 'non_dist_role_for_mds' ORDER BY 1;
|
||||
|
||||
|
||||
select result FROM run_command_on_all_nodes(
|
||||
$$
|
||||
SELECT array_to_json(array_agg(row_to_json(t)))
|
||||
FROM (
|
||||
SELECT member::regrole, roleid::regrole as role, grantor::regrole, admin_option
|
||||
FROM pg_auth_members
|
||||
WHERE member::regrole::text in
|
||||
('dist_role1','dist_role2','dist_role3','dist_role4','"role5''_test"', 'non_dist_role_for_mds','non_dist_role1','non_dist_role2')
|
||||
order by member::regrole::text, roleid::regrole::text
|
||||
) t
|
||||
$$
|
||||
);
|
||||
|
||||
|
||||
set citus.enable_create_role_propagation to off;
|
||||
create role non_dist_role_mds_fail;
|
||||
|
||||
grant dist_role2 to non_dist_role_mds_fail with admin option;
|
||||
grant dist_role2 to non_dist_role_for_mds GRANTED BY non_dist_role_mds_fail;
|
||||
|
||||
|
||||
reset citus.enable_create_role_propagation;
|
||||
|
||||
--will fail since non_dist_role_for_mds is not in dependency resolution
|
||||
select 1 from citus_add_node ('localhost',:worker_2_port);
|
||||
|
||||
--this grant statement will add non_dist_role_mds_fail to dist_role3 dependencies
|
||||
grant non_dist_role_mds_fail to dist_role3;
|
||||
|
||||
--will be successful since non_dist_role_mds_fail is in dependency resolution of dist_role3
|
||||
-- and will be created in metadata sync phase
|
||||
select 1 from citus_add_node ('localhost',:worker_2_port);
|
||||
|
||||
select result FROM run_command_on_all_nodes(
|
||||
$$
|
||||
SELECT array_to_json(array_agg(row_to_json(t)))
|
||||
FROM (
|
||||
SELECT member::regrole, roleid::regrole as role, grantor::regrole, admin_option
|
||||
FROM pg_auth_members
|
||||
WHERE member::regrole::text in
|
||||
('dist_role1','dist_role2','dist_role3','dist_role4','"role5''_test"','non_dist_role_for_mds','non_dist_role1','non_dist_role2')
|
||||
order by member::regrole::text, roleid::regrole::text
|
||||
) t
|
||||
$$
|
||||
);
|
||||
|
||||
|
||||
--clean all resources
|
||||
drop role dist_role1,dist_role2,dist_role3,dist_role4,"dist_role5'_test";
|
||||
drop role non_dist_role1,non_dist_role2,non_dist_role_for_mds,non_dist_role_mds_fail;
|
||||
|
||||
SELECT objid::regrole FROM pg_catalog.pg_dist_object WHERE classid='pg_authid'::regclass::oid AND objid::regrole::text= 'non_dist_role1' ORDER BY 1;
|
||||
reset citus.enable_create_role_propagation;
|
||||
|
||||
select result FROM run_command_on_all_nodes(
|
||||
$$
|
||||
SELECT array_to_json(array_agg(row_to_json(t)))
|
||||
FROM (
|
||||
SELECT member::regrole, roleid::regrole as role, grantor::regrole, admin_option
|
||||
FROM pg_auth_members
|
||||
WHERE member::regrole::text in
|
||||
('dist_role1','dist_role2','dist_role3','dist_role4','"role5''_test"','non_dist_role_for_mds','non_dist_role1','non_dist_role2')
|
||||
order by member::regrole::text, roleid::regrole::text
|
||||
) t
|
||||
$$
|
||||
);
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue