diff --git a/src/backend/distributed/commands/dependencies.c b/src/backend/distributed/commands/dependencies.c index acdb9aa13..402b63adc 100644 --- a/src/backend/distributed/commands/dependencies.c +++ b/src/backend/distributed/commands/dependencies.c @@ -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,bool fetchGrantStatements); +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,true); + 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,true); + List *dependencyCommands = GetDependencyCreateDDLCommands(dependency, true); /* create a new list with dependencies that actually created commands */ if (list_length(dependencyCommands) > 0) @@ -605,7 +606,8 @@ GetDependencyCreateDDLCommands(const ObjectAddress *dependency, bool fetchGrantS case OCLASS_ROLE: { - return GenerateCreateOrAlterRoleCommand(dependency->objectId,fetchGrantStatements); + return GenerateCreateOrAlterRoleCommand(dependency->objectId, + fetchGrantStatements); } case OCLASS_SCHEMA: @@ -685,7 +687,8 @@ GetAllDependencyCreateDDLCommands(const List *dependencies) ObjectAddress *dependency = NULL; foreach_ptr(dependency, dependencies) { - ddlCommands = list_concat(ddlCommands, GetDependencyCreateDDLCommands(dependency,false)); + ddlCommands = list_concat(ddlCommands, GetDependencyCreateDDLCommands(dependency, + false)); } return ddlCommands; diff --git a/src/backend/distributed/commands/role.c b/src/backend/distributed/commands/role.c index edadfc0ba..4e6410f6d 100644 --- a/src/backend/distributed/commands/role.c +++ b/src/backend/distributed/commands/role.c @@ -56,11 +56,6 @@ #include "distributed/version_compat.h" #include "distributed/worker_transaction.h" -typedef struct GrantRoleStmts -{ - List *adminStmts; - List *otherStmts; -} GrantRoleStmts; static const char * ExtractEncryptedPassword(Oid roleOid); static const char * CreateAlterRoleIfExistsCommand(AlterRoleStmt *stmt); @@ -72,7 +67,9 @@ static DefElem * makeDefElemInt(char *name, int value); static DefElem * makeDefElemBool(char *name, bool value); static List * GenerateRoleOptionsList(HeapTuple tuple); static List * GenerateGrantRoleStmtsFromOptions(RoleSpec *roleSpec, List *options); -static GrantRoleStmts GenerateGrantRoleStmtsOfRole(Oid roleid); +static List * GenerateGrantRoleStmtsOfRole(Oid roleid); +static GrantRoleStmt * GetGrantRoleStmtFromAuthMemberRecord(Form_pg_auth_members + membership); static List * GenerateSecLabelOnRoleStmts(Oid roleid, char *rolename); static void EnsureSequentialModeForRoleDDL(void); @@ -521,8 +518,6 @@ GenerateRoleOptionsList(HeapTuple tuple) List * GenerateCreateOrAlterRoleCommand(Oid roleOid, bool fetchGrantStmts) { - - elog(NOTICE, "Generating create or alter role command for role %u with fetchGrantStmts %s", roleOid,fetchGrantStmts ? "true" : "false"); HeapTuple roleTuple = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleOid)); Form_pg_authid role = ((Form_pg_authid) GETSTRUCT(roleTuple)); char *rolename = pstrdup(NameStr(role->rolname)); @@ -571,18 +566,10 @@ GenerateCreateOrAlterRoleCommand(Oid roleOid, bool fetchGrantStmts) if (EnableCreateRolePropagation) { - if(fetchGrantStmts){ - elog(NOTICE, "Fetching grant statements for role %s", rolename); - List *grantRoleStmtList = NIL; - GrantRoleStmts grantRoleStmts= GenerateGrantRoleStmtsOfRole(roleOid); - - grantRoleStmtList = list_concat(grantRoleStmts.adminStmts, grantRoleStmts.otherStmts); - - Node *stmt = NULL; - foreach_ptr(stmt, grantRoleStmtList) - { - completeRoleList = lappend(completeRoleList, DeparseTreeNode(stmt)); - } + if (fetchGrantStmts) + { + completeRoleList = list_concat(completeRoleList, GenerateGrantRoleStmtsOfRole( + roleOid)); } /* @@ -883,151 +870,171 @@ GenerateGrantRoleStmtsFromOptions(RoleSpec *roleSpec, List *options) * GenerateGrantRoleStmtsOfRole generates the GrantRoleStmts for the memberships * of the role whose oid is roleid. */ -static GrantRoleStmts +static List * GenerateGrantRoleStmtsOfRole(Oid roleid) { - Relation pgAuthMembers = table_open(AuthMemRelationId, AccessShareLock); - HeapTuple tuple = NULL; + Relation pgAuthMembers = table_open(AuthMemRelationId, AccessShareLock); + HeapTuple tuple = NULL; - List *adminStmts = NIL; - List *otherStmts = NIL; + List *adminStmts = NIL; + List *otherStmts = NIL; + List *allStmts = NIL; - ScanKeyData skey[1]; + ScanKeyData skey[1]; - ScanKeyInit(&skey[0], Anum_pg_auth_members_member, BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(roleid)); - SysScanDesc scan = systable_beginscan(pgAuthMembers, AuthMemMemRoleIndexId, true, - NULL, 1, &skey[0]); + ScanKeyInit(&skey[0], Anum_pg_auth_members_member, BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(roleid)); + SysScanDesc scan = systable_beginscan(pgAuthMembers, AuthMemMemRoleIndexId, true, + NULL, 1, &skey[0]); - while (HeapTupleIsValid(tuple = systable_getnext(scan))) - { - Form_pg_auth_members membership = (Form_pg_auth_members) GETSTRUCT(tuple); + while (HeapTupleIsValid(tuple = systable_getnext(scan))) + { + 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))) - { - /* we only need to propagate the grant if the grantor is distributed */ - continue; - } + GrantRoleStmt *grantRoleStmt = GetGrantRoleStmtFromAuthMemberRecord(membership); + if (grantRoleStmt == NULL) + { + continue; + } - GrantRoleStmt *grantRoleStmt = makeNode(GrantRoleStmt); - grantRoleStmt->is_grant = true; + if (membership->admin_option) + { + adminStmts = lappend(adminStmts, grantRoleStmt); + } + else + { + otherStmts = lappend(otherStmts, grantRoleStmt); + } + } - RoleSpec *grantedRole = makeNode(RoleSpec); - grantedRole->roletype = ROLESPEC_CSTRING; - grantedRole->location = -1; - grantedRole->rolename = GetUserNameFromId(membership->roleid, true); - grantRoleStmt->granted_roles = list_make1(grantedRole); + systable_endscan(scan); + table_close(pgAuthMembers, AccessShareLock); - RoleSpec *granteeRole = makeNode(RoleSpec); - granteeRole->roletype = ROLESPEC_CSTRING; - granteeRole->location = -1; - granteeRole->rolename = GetUserNameFromId(membership->member, true); - grantRoleStmt->grantee_roles = list_make1(granteeRole); + allStmts = list_concat(adminStmts, otherStmts); + List *commands = NIL; + Node *stmt = NULL; + foreach_ptr(stmt, allStmts) + { + commands = lappend(commands, DeparseTreeNode(stmt)); + } - 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 - if (membership->admin_option) - { - adminStmts = lappend(adminStmts, grantRoleStmt); - } - else - { - otherStmts = lappend(otherStmts, grantRoleStmt); - } - } - - systable_endscan(scan); - table_close(pgAuthMembers, AccessShareLock); - - GrantRoleStmts result; - result.adminStmts = adminStmts; - result.otherStmts = otherStmts; - - return result; + return commands; } -/**/ -List * GenerateGrantRoleStmts() +List * +GenerateGrantRoleStmts() { - Relation pgAuthMembers = table_open(AuthMemRelationId, AccessShareLock); - HeapTuple tuple = NULL; - List *adminStmts = NIL; - List *otherStmts = NIL; + 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); + 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); - - ObjectAddress *roleAddress = palloc0(sizeof(ObjectAddress)); - ObjectAddressSet(*roleAddress, AuthIdRelationId, membership->grantor); - elog(NOTICE, "Role name: %s", GetUserNameFromId(membership->roleid, true)); - elog(NOTICE, "Member name: %s", GetUserNameFromId(membership->member, true)); - if (!IsAnyObjectDistributed(list_make1(roleAddress))) - { - /* we only need to propagate the grant if the grantor is distributed */ - continue; - } - - //log role name - elog(NOTICE, "Role name fetched: %s", GetUserNameFromId(membership->roleid, true)); - elog(NOTICE, "Member name fetched: %s", GetUserNameFromId(membership->member, true)); - GrantRoleStmts grantRoleStmts = GenerateGrantRoleStmtsOfRole(membership->roleid); - adminStmts = list_concat(adminStmts, grantRoleStmts.adminStmts); - otherStmts = list_concat(otherStmts, grantRoleStmts.otherStmts); - } - - systable_endscan(scan); - table_close(pgAuthMembers, AccessShareLock); - - List *allGrantStatements = list_concat(adminStmts, otherStmts); - - Node *stmt = NULL; - List *grantStatements = NIL; - foreach_ptr(stmt, allGrantStatements) + while (HeapTupleIsValid(tuple = systable_getnext(scan))) { - grantStatements = lappend(grantStatements, DeparseTreeNode(stmt)); + Form_pg_auth_members membership = (Form_pg_auth_members) GETSTRUCT(tuple); + + GrantRoleStmt *grantRoleStmt = GetGrantRoleStmtFromAuthMemberRecord(membership); + if (grantRoleStmt == NULL) + { + continue; + } + + if (membership->admin_option) + { + adminStmts = lappend(adminStmts, grantRoleStmt); + } + else + { + otherStmts = lappend(otherStmts, grantRoleStmt); + } } - return grantStatements; + 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); + if (!IsAnyObjectDistributed(list_make1(roleAddress))) + { + /* we only need to propagate the grant if the grantor is distributed */ + return NULL; + } + + 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; } diff --git a/src/include/distributed/commands.h b/src/include/distributed/commands.h index 8d15a1527..0b005d5d2 100644 --- a/src/include/distributed/commands.h +++ b/src/include/distributed/commands.h @@ -515,7 +515,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,bool fetchGrantStatements); +extern List * GenerateCreateOrAlterRoleCommand(Oid roleOid, bool fetchGrantStatements); extern List * CreateRoleStmtObjectAddress(Node *stmt, bool missing_ok, bool isPostprocess); diff --git a/src/test/regress/expected/granted_by_support.out b/src/test/regress/expected/granted_by_support.out index 2687c8009..976f7c7a0 100644 --- a/src/test/regress/expected/granted_by_support.out +++ b/src/test/regress/expected/granted_by_support.out @@ -18,20 +18,30 @@ grant role3 to "role5'_test" granted by role4; grant role2 to "role5'_test" granted by role3; grant role4 to "role5'_test" with admin option; grant role4 to role1 with admin option GRANTED BY "role5'_test"; -ERROR: Citus can not handle circular dependencies between distributed objects -DETAIL: "role role1" circularly depends itself, resolve circular dependency first grant role4 to role3 with admin option GRANTED BY role1; -ERROR: permission denied to grant privileges as role "role1" -DETAIL: The grantor must have the ADMIN option on role "role4". +ERROR: role "role4" is a member of role "role3" grant role3 to role1 with admin option GRANTED BY role4; -ERROR: Citus can not handle circular dependencies between distributed objects -DETAIL: "role role1" circularly depends itself, resolve circular dependency first grant "role5'_test" to role1 with admin option; -ERROR: Citus can not handle circular dependencies between distributed objects -DETAIL: "role role1" circularly depends itself, resolve circular dependency first grant "role5'_test" to role3 with admin option GRANTED BY role1; -ERROR: permission denied to grant privileges as role "role1" -DETAIL: The grantor must have the ADMIN option on role "role5'_test". +ERROR: role "role5'_test" is a member of role "role3" +SELECT member::regrole, roleid::regrole as role, grantor::regrole, admin_option + FROM pg_auth_members + WHERE member::regrole::text in + ('role1','role2','role3','role4','"role5''_test"') + order by member::regrole::text, roleid::regrole::text; + member | role | grantor | admin_option +--------------------------------------------------------------------- + "role5'_test" | role2 | role3 | f + "role5'_test" | role3 | role4 | f + "role5'_test" | role4 | postgres | t + role1 | "role5'_test" | postgres | t + role1 | role2 | postgres | t + role1 | role3 | role4 | t + role1 | role4 | "role5'_test" | t + role3 | role2 | role1 | t + role4 | role3 | postgres | t +(9 rows) + select result FROM run_command_on_all_nodes( $$ SELECT array_to_json(array_agg(row_to_json(t))) @@ -44,10 +54,10 @@ select result FROM run_command_on_all_nodes( ) t $$ ); - result + result --------------------------------------------------------------------- - [{"member":"\"role5'_test\"","role":"role2","grantor":"role3","admin_option":false},{"member":"\"role5'_test\"","role":"role3","grantor":"role4","admin_option":false},{"member":"\"role5'_test\"","role":"role4","grantor":"postgres","admin_option":true},{"member":"role1","role":"role2","grantor":"postgres","admin_option":true},{"member":"role3","role":"role2","grantor":"role1","admin_option":true},{"member":"role4","role":"role3","grantor":"postgres","admin_option":true}] - [{"member":"\"role5'_test\"","role":"role2","grantor":"role3","admin_option":false},{"member":"\"role5'_test\"","role":"role3","grantor":"role4","admin_option":false},{"member":"\"role5'_test\"","role":"role4","grantor":"postgres","admin_option":true},{"member":"role1","role":"role2","grantor":"postgres","admin_option":true},{"member":"role3","role":"role2","grantor":"role1","admin_option":true},{"member":"role4","role":"role3","grantor":"postgres","admin_option":true}] + [{"member":"\"role5'_test\"","role":"role2","grantor":"role3","admin_option":false},{"member":"\"role5'_test\"","role":"role3","grantor":"role4","admin_option":false},{"member":"\"role5'_test\"","role":"role4","grantor":"postgres","admin_option":true},{"member":"role1","role":"\"role5'_test\"","grantor":"postgres","admin_option":true},{"member":"role1","role":"role2","grantor":"postgres","admin_option":true},{"member":"role1","role":"role3","grantor":"role4","admin_option":true},{"member":"role1","role":"role4","grantor":"\"role5'_test\"","admin_option":true},{"member":"role3","role":"role2","grantor":"role1","admin_option":true},{"member":"role4","role":"role3","grantor":"postgres","admin_option":true}] + [{"member":"\"role5'_test\"","role":"role2","grantor":"role3","admin_option":false},{"member":"\"role5'_test\"","role":"role3","grantor":"role4","admin_option":false},{"member":"\"role5'_test\"","role":"role4","grantor":"postgres","admin_option":true},{"member":"role1","role":"\"role5'_test\"","grantor":"postgres","admin_option":true},{"member":"role1","role":"role2","grantor":"postgres","admin_option":true},{"member":"role1","role":"role3","grantor":"role4","admin_option":true},{"member":"role1","role":"role4","grantor":"\"role5'_test\"","admin_option":true},{"member":"role3","role":"role2","grantor":"role1","admin_option":true},{"member":"role4","role":"role3","grantor":"postgres","admin_option":true}] (2 rows) select 1 from citus_add_node ('localhost',:worker_2_port); @@ -56,6 +66,25 @@ select 1 from citus_add_node ('localhost',:worker_2_port); 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 + ('role1','role2','role3','role4','"role5''_test"') + order by member::regrole::text, roleid::regrole::text + ) t + $$ +); + result +--------------------------------------------------------------------- + [{"member":"\"role5'_test\"","role":"role2","grantor":"role3","admin_option":false},{"member":"\"role5'_test\"","role":"role3","grantor":"role4","admin_option":false},{"member":"\"role5'_test\"","role":"role4","grantor":"postgres","admin_option":true},{"member":"role1","role":"\"role5'_test\"","grantor":"postgres","admin_option":true},{"member":"role1","role":"role2","grantor":"postgres","admin_option":true},{"member":"role1","role":"role3","grantor":"role4","admin_option":true},{"member":"role1","role":"role4","grantor":"\"role5'_test\"","admin_option":true},{"member":"role3","role":"role2","grantor":"role1","admin_option":true},{"member":"role4","role":"role3","grantor":"postgres","admin_option":true}] + [{"member":"\"role5'_test\"","role":"role2","grantor":"role3","admin_option":false},{"member":"\"role5'_test\"","role":"role3","grantor":"role4","admin_option":false},{"member":"\"role5'_test\"","role":"role4","grantor":"postgres","admin_option":true},{"member":"role1","role":"\"role5'_test\"","grantor":"postgres","admin_option":true},{"member":"role1","role":"role2","grantor":"postgres","admin_option":true},{"member":"role1","role":"role3","grantor":"role4","admin_option":true},{"member":"role1","role":"role4","grantor":"\"role5'_test\"","admin_option":true},{"member":"role3","role":"role2","grantor":"role1","admin_option":true},{"member":"role4","role":"role3","grantor":"postgres","admin_option":true}] + [{"member":"\"role5'_test\"","role":"role2","grantor":"role3","admin_option":false},{"member":"\"role5'_test\"","role":"role3","grantor":"role4","admin_option":false},{"member":"\"role5'_test\"","role":"role4","grantor":"postgres","admin_option":true},{"member":"role1","role":"\"role5'_test\"","grantor":"postgres","admin_option":true},{"member":"role1","role":"role2","grantor":"postgres","admin_option":true},{"member":"role1","role":"role3","grantor":"role4","admin_option":true},{"member":"role1","role":"role4","grantor":"\"role5'_test\"","admin_option":true},{"member":"role3","role":"role2","grantor":"role1","admin_option":true},{"member":"role4","role":"role3","grantor":"postgres","admin_option":true}] +(3 rows) + --clean all resources drop role role1,role2,role3,role4,"role5'_test"; select result FROM run_command_on_all_nodes( diff --git a/src/test/regress/sql/granted_by_support.sql b/src/test/regress/sql/granted_by_support.sql index a6f133bc7..4ed7b8bd5 100644 --- a/src/test/regress/sql/granted_by_support.sql +++ b/src/test/regress/sql/granted_by_support.sql @@ -40,14 +40,20 @@ select result FROM run_command_on_all_nodes( ) t $$ ); - -set citus.log_remote_commands = on; ---set citus.grep_remote_commands = '%GRANT%'; - select 1 from citus_add_node ('localhost',:worker_2_port); -reset citus.log_remote_commands; -reset citus.grep_remote_commands; +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 + ('role1','role2','role3','role4','"role5''_test"') + order by member::regrole::text, roleid::regrole::text + ) t + $$ +); --clean all resources drop role role1,role2,role3,role4,"role5'_test"; @@ -64,24 +70,3 @@ select result FROM run_command_on_all_nodes( ) t $$ ); - - -GRANT role2 TO role3 WITH INHERIT TRUE, ADMIN OPTION GRANTED BY role1;; -GRANT role2 TO role3 WITH INHERIT TRUE, ADMIN OPTION GRANTED BY role1;; -GRANT role3 TO role4 WITH INHERIT TRUE, ADMIN OPTION GRANTED BY postgres;; x -GRANT role3 TO role4 WITH INHERIT TRUE, ADMIN OPTION GRANTED BY postgres;; -GRANT role2 TO role3 WITH INHERIT TRUE, ADMIN OPTION GRANTED BY role1;; x -GRANT role4 TO "role5'_test" WITH INHERIT TRUE, ADMIN OPTION GRANTED BY postgres;; x -GRANT role2 TO "role5'_test" WITH INHERIT TRUE GRANTED BY role3;; x -GRANT role3 TO "role5'_test" WITH INHERIT TRUE GRANTED BY role4 ; x - - - "role5'_test" | role2 | role3 | f x - "role5'_test" | role3 | role4 | f x - "role5'_test" | role4 | postgres | t x - role1 | "role5'_test" | postgres | t - role1 | role2 | postgres | t - role1 | role3 | role4 | t - role1 | role4 | "role5'_test" | t - role3 | role2 | role1 | t x - role4 | role3 | postgres | t x