Fixes drop role pg_dist_object removal issue

pull/7461/head
gurkanindibay 2024-01-31 17:22:16 +03:00
parent c57d642408
commit dd45a2c874
10 changed files with 265 additions and 78 deletions

View File

@ -95,6 +95,16 @@
#define MARK_OBJECT_DISTRIBUTED \
"SELECT citus_internal.mark_object_distributed(%d, %s, %d, %s)"
#define UNMARK_OBJECT_DISTRIBUTED \
"SELECT pg_catalog.citus_unmark_object_distributed(%d, %d, %d,%s)"
typedef enum
{
NO_DISTRIBUTED_OPS,
MARK_DISTRIBUTED,
UNMARK_DISTRIBUTED
} DistributedOperation;
/*
* NonMainDbDistributedStatementInfo is used to determine whether a statement is
* supported from non-main databases and whether it should be marked as
@ -107,7 +117,7 @@
typedef struct NonMainDbDistributedStatementInfo
{
int statementType;
bool explicitlyMarkAsDistributed;
DistributedOperation distributedOperation;
ObjectType *supportedObjectTypes;
int supportedObjectTypesSize;
} NonMainDbDistributedStatementInfo;
@ -125,11 +135,11 @@ typedef struct ObjectInfo
ObjectType supportedObjectTypesForGrantStmt[] = { OBJECT_DATABASE };
static const NonMainDbDistributedStatementInfo NonMainDbSupportedStatements[] = {
{ T_GrantRoleStmt, false, NULL, 0 },
{ T_CreateRoleStmt, true, NULL, 0 },
{ T_DropRoleStmt, false,NULL, 0 },
{ T_AlterRoleStmt, false, NULL, 0 },
{ T_GrantStmt, false, supportedObjectTypesForGrantStmt,
{ T_GrantRoleStmt, NO_DISTRIBUTED_OPS, NULL, 0 },
{ T_CreateRoleStmt, MARK_DISTRIBUTED, NULL, 0 },
{ T_DropRoleStmt, UNMARK_DISTRIBUTED, NULL, 0 },
{ T_AlterRoleStmt, NO_DISTRIBUTED_OPS, NULL, 0 },
{ T_GrantStmt, NO_DISTRIBUTED_OPS, supportedObjectTypesForGrantStmt,
sizeof(supportedObjectTypesForGrantStmt) / sizeof(ObjectType) }
};
@ -167,8 +177,10 @@ static bool IsObjectTypeSupported(Node *parsetree, NonMainDbDistributedStatement
nonMainDbDistributedStatementInfo);
static bool IsStatementSupportedInNonMainDb(Node *parsetree);
static bool StatementRequiresMarkDistributedFromNonMainDb(Node *parsetree);
static ObjectInfo GetObjectInfo(Node *parsetree);
static void MarkObjectDistributedInNonMainDb(Node *parsetree, ObjectInfo objectInfo);
static bool StatementRequiresUnmarkDistributedFromNonMainDb(Node *parsetree);
static List * GetObjectInfoList(Node *parsetree);
static void MarkObjectDistributedInNonMainDb(Node *parsetree, ObjectInfo *objectInfo);
static void UnmarkObjectDistributedInNonMainDb(List *objectInfoList);
/*
* ProcessUtilityParseTree is a convenience method to create a PlannedStmt out of
@ -1663,6 +1675,14 @@ RunPreprocessMainDBCommand(Node *parsetree, const char *queryString)
EXECUTE_COMMAND_ON_REMOTE_NODES_AS_USER,
quote_literal_cstr(queryString),
quote_literal_cstr(CurrentUserName()));
if (StatementRequiresUnmarkDistributedFromNonMainDb(parsetree))
{
List *objectInfoList = GetObjectInfoList(parsetree);
UnmarkObjectDistributedInNonMainDb(objectInfoList);
}
RunCitusMainDBQuery(mainDBQuery->data);
}
@ -1677,30 +1697,50 @@ RunPostprocessMainDBCommand(Node *parsetree)
if (IsStatementSupportedInNonMainDb(parsetree) &&
StatementRequiresMarkDistributedFromNonMainDb(parsetree))
{
ObjectInfo objectInfo = GetObjectInfo(parsetree);
MarkObjectDistributedInNonMainDb(parsetree, objectInfo);
List *objectInfoList = GetObjectInfoList(parsetree);
ObjectInfo *objectInfo = NULL;
if (objectInfoList != NIL)
{
objectInfo = (ObjectInfo *) linitial(objectInfoList);
MarkObjectDistributedInNonMainDb(parsetree, objectInfo);
}
}
}
/*
* GetObjectInfo returns the name and oid of the object in the given parsetree.
* GetObjectInfoList returns the names and oids of the object in the given parsetree.
*/
static ObjectInfo
GetObjectInfo(Node *parsetree)
List *
GetObjectInfoList(Node *parsetree)
{
ObjectInfo info;
List *infoList = NIL;
if (IsA(parsetree, CreateRoleStmt))
{
CreateRoleStmt *stmt = castNode(CreateRoleStmt, parsetree);
info.name = stmt->role;
info.id = get_role_oid(stmt->role, false);
ObjectInfo *info = palloc(sizeof(ObjectInfo));
info->name = stmt->role;
info->id = get_role_oid(stmt->role, false);
infoList = lappend(infoList, info);
}
else if (IsA(parsetree, DropRoleStmt))
{
DropRoleStmt *stmt = castNode(DropRoleStmt, parsetree);
RoleSpec *roleSpec;
foreach_ptr(roleSpec, stmt->roles)
{
ObjectInfo *info = palloc(sizeof(ObjectInfo));
info->name = roleSpec->rolename;
info->id = get_role_oid(roleSpec->rolename, false);
infoList = lappend(infoList, info);
}
}
/* Add else if branches for other statement types */
return info;
return infoList;
}
@ -1709,19 +1749,42 @@ GetObjectInfo(Node *parsetree)
* non-main database.
*/
static void
MarkObjectDistributedInNonMainDb(Node *parsetree, ObjectInfo objectInfo)
MarkObjectDistributedInNonMainDb(Node *parsetree, ObjectInfo *objectInfo)
{
StringInfo mainDBQuery = makeStringInfo();
appendStringInfo(mainDBQuery,
MARK_OBJECT_DISTRIBUTED,
AuthIdRelationId,
quote_literal_cstr(objectInfo.name),
objectInfo.id,
quote_literal_cstr(objectInfo->name),
objectInfo->id,
quote_literal_cstr(CurrentUserName()));
RunCitusMainDBQuery(mainDBQuery->data);
}
/*
* UnmarkObjectDistributedInNonMainDb unmarks the given object as distributed on the
* non-main database.
*/
static void
UnmarkObjectDistributedInNonMainDb(List *objectInfoList)
{
ObjectInfo *objectInfo = NULL;
int subObjectId = 0;
char *checkObjectExistence = "false";
foreach_ptr(objectInfo, objectInfoList)
{
StringInfo query = makeStringInfo();
appendStringInfo(query,
UNMARK_OBJECT_DISTRIBUTED,
AuthIdRelationId,
objectInfo->id,
subObjectId, checkObjectExistence);
RunCitusMainDBQuery(query->data);
}
}
/*
* IsStatementSupportedIn2Pc returns true if the statement is supported from a
* non-main database.
@ -1784,7 +1847,7 @@ IsObjectTypeSupported(Node *parsetree, NonMainDbDistributedStatementInfo
/*
* DoesStatementRequireMarkDistributedFor2PC returns true if the statement should be marked
* StatementRequiresMarkDistributedFromNonMainDb returns true if the statement should be marked
* as distributed when executed from a non-main database.
*/
static bool
@ -1797,7 +1860,31 @@ StatementRequiresMarkDistributedFromNonMainDb(Node *parsetree)
{
if (type == NonMainDbSupportedStatements[i].statementType)
{
return NonMainDbSupportedStatements[i].explicitlyMarkAsDistributed;
return NonMainDbSupportedStatements[i].distributedOperation ==
MARK_DISTRIBUTED;
}
}
return false;
}
/*
* StatementRequiresUnmarkDistributedFromNonMainDb returns true if the statement should be marked
* as distributed when executed from a non-main database.
*/
static bool
StatementRequiresUnmarkDistributedFromNonMainDb(Node *parsetree)
{
NodeTag type = nodeTag(parsetree);
for (int i = 0; i < sizeof(NonMainDbSupportedStatements) /
sizeof(NonMainDbSupportedStatements[0]); i++)
{
if (type == NonMainDbSupportedStatements[i].statementType)
{
return NonMainDbSupportedStatements[i].distributedOperation ==
UNMARK_DISTRIBUTED;
}
}

View File

@ -109,6 +109,12 @@ citus_unmark_object_distributed(PG_FUNCTION_ARGS)
Oid classid = PG_GETARG_OID(0);
Oid objid = PG_GETARG_OID(1);
int32 objsubid = PG_GETARG_INT32(2);
bool checkObjectExistence = true;
if (!PG_ARGISNULL(3))
{
checkObjectExistence = PG_GETARG_BOOL(3);
}
ObjectAddress address = { 0 };
ObjectAddressSubSet(address, classid, objid, objsubid);
@ -119,7 +125,7 @@ citus_unmark_object_distributed(PG_FUNCTION_ARGS)
PG_RETURN_VOID();
}
if (ObjectExists(&address))
if (checkObjectExistence && ObjectExists(&address))
{
ereport(ERROR, (errmsg("object still exists"),
errdetail("the %s \"%s\" still exists",

View File

@ -27,3 +27,5 @@ REVOKE ALL ON FUNCTION citus_internal.restore_isolation_tester_func FROM PUBLIC;
REVOKE ALL ON FUNCTION citus_internal.start_management_transaction FROM PUBLIC;
#include "udfs/citus_internal_add_colocation_metadata/12.2-1.sql"
#include "udfs/citus_unmark_object_distributed/12.2-1.sql"

View File

@ -27,3 +27,5 @@ DROP FUNCTION citus_internal.add_colocation_metadata(int, int, int, regtype, oid
#include "../udfs/citus_internal_add_colocation_metadata/11.0-1.sql"
DROP FUNCTION pg_catalog.citus_unmark_object_distributed(oid,oid,int,boolean);

View File

@ -0,0 +1,10 @@
CREATE FUNCTION pg_catalog.citus_unmark_object_distributed(classid oid, objid oid, objsubid int,checkobjectexistence boolean)
RETURNS void
LANGUAGE C STRICT
AS 'MODULE_PATHNAME', $$citus_unmark_object_distributed$$;
COMMENT ON FUNCTION pg_catalog.citus_unmark_object_distributed(classid oid, objid oid, objsubid int,checkobjectexistence boolean)
IS 'remove an object address from citus.pg_dist_object once the object has been deleted.
This method is overload of citus_unmark_object_distributed with additionl parameter checkobjectexistence
In regular scenario, if object exists on database, pg_dist_object record is not being deleted
However, when we send a command which deletes pg_dist_object,we need to get oid of the object,
so we need to delete the record before actual drop operation .';

View File

@ -4,3 +4,14 @@ CREATE FUNCTION pg_catalog.citus_unmark_object_distributed(classid oid, objid oi
AS 'MODULE_PATHNAME', $$citus_unmark_object_distributed$$;
COMMENT ON FUNCTION pg_catalog.citus_unmark_object_distributed(classid oid, objid oid, objsubid int)
IS 'remove an object address from citus.pg_dist_object once the object has been deleted';
CREATE FUNCTION pg_catalog.citus_unmark_object_distributed(classid oid, objid oid, objsubid int,checkobjectexistence boolean)
RETURNS void
LANGUAGE C STRICT
AS 'MODULE_PATHNAME', $$citus_unmark_object_distributed$$;
COMMENT ON FUNCTION pg_catalog.citus_unmark_object_distributed(classid oid, objid oid, objsubid int,checkobjectexistence boolean)
IS 'remove an object address from citus.pg_dist_object once the object has been deleted.
This method is overload of citus_unmark_object_distributed with additionl parameter checkobjectexistence
In regular scenario, if object exists on database, pg_dist_object record is not being deleted
However, when we send a command which deletes pg_dist_object,we need to get oid of the object,
so we need to delete the record before actual drop operation .';

View File

@ -126,6 +126,124 @@ revoke CONNECT on database metadata_sync_2pc_db from grant_role2pc_user2;
revoke CREATE on database metadata_sync_2pc_db from grant_role2pc_user1;
\c regression
drop user grant_role2pc_user1,grant_role2pc_user2,grant_role2pc_user3,grant_role2pc_user4,grant_role2pc_user5;
--test for user operations
--test for create user
\c regression - - :master_port
select 1 from citus_remove_node('localhost', :worker_2_port);
?column?
---------------------------------------------------------------------
1
(1 row)
\c metadata_sync_2pc_db - - :master_port
CREATE ROLE test_role1 WITH LOGIN PASSWORD 'password1';
\c metadata_sync_2pc_db - - :worker_1_port
CREATE USER "test_role2-needs\!escape"
WITH
SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN REPLICATION BYPASSRLS CONNECTION
LIMIT 10 VALID UNTIL '2023-01-01' IN ROLE test_role1;
create role test_role3;
\c regression - - :master_port
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 rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb,
rolcanlogin, rolreplication, rolbypassrls, rolconnlimit,
(rolpassword != '') as pass_not_empty, rolvaliduntil
FROM pg_authid
WHERE rolname in ('test_role1', 'test_role2-needs\!escape')
ORDER BY rolname
) t
$$);
result
---------------------------------------------------------------------
[{"rolname":"test_role1","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":true,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":true,"rolvaliduntil":null},{"rolname":"test_role2-needs\\!escape","rolsuper":true,"rolinherit":true,"rolcreaterole":true,"rolcreatedb":true,"rolcanlogin":true,"rolreplication":true,"rolbypassrls":true,"rolconnlimit":10,"pass_not_empty":null,"rolvaliduntil":"2023-01-01T00:00:00+03:00"}]
[{"rolname":"test_role1","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":true,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":true,"rolvaliduntil":null},{"rolname":"test_role2-needs\\!escape","rolsuper":true,"rolinherit":true,"rolcreaterole":true,"rolcreatedb":true,"rolcanlogin":true,"rolreplication":true,"rolbypassrls":true,"rolconnlimit":10,"pass_not_empty":null,"rolvaliduntil":"2023-01-01T11:00:00+03:00"}]
[{"rolname":"test_role1","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":true,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":true,"rolvaliduntil":"infinity"},{"rolname":"test_role2-needs\\!escape","rolsuper":true,"rolinherit":true,"rolcreaterole":true,"rolcreatedb":true,"rolcanlogin":true,"rolreplication":true,"rolbypassrls":true,"rolconnlimit":10,"pass_not_empty":null,"rolvaliduntil":"2023-01-01T00:00:00+03:00"}]
(3 rows)
--test for alter user
select 1 from citus_remove_node('localhost', :worker_2_port);
?column?
---------------------------------------------------------------------
1
(1 row)
\c metadata_sync_2pc_db - - :master_port
-- Test ALTER ROLE with various options
ALTER ROLE test_role1 WITH PASSWORD 'new_password1';
\c metadata_sync_2pc_db - - :worker_1_port
ALTER USER "test_role2-needs\!escape"
WITH
NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT NOLOGIN NOREPLICATION NOBYPASSRLS CONNECTION
LIMIT 5 VALID UNTIL '2024-01-01';
\c regression - - :master_port
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 rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb,
rolcanlogin, rolreplication, rolbypassrls, rolconnlimit,
(rolpassword != '') as pass_not_empty, rolvaliduntil
FROM pg_authid
WHERE rolname in ('test_role1', 'test_role2-needs\!escape')
ORDER BY rolname
) t
$$);
result
---------------------------------------------------------------------
[{"rolname":"test_role1","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":true,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":true,"rolvaliduntil":null},{"rolname":"test_role2-needs\\!escape","rolsuper":false,"rolinherit":false,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":false,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":5,"pass_not_empty":null,"rolvaliduntil":"2024-01-01T00:00:00+03:00"}]
[{"rolname":"test_role1","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":true,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":true,"rolvaliduntil":null},{"rolname":"test_role2-needs\\!escape","rolsuper":false,"rolinherit":false,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":false,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":5,"pass_not_empty":null,"rolvaliduntil":"2024-01-01T11:00:00+03:00"}]
[{"rolname":"test_role1","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":true,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":true,"rolvaliduntil":"infinity"},{"rolname":"test_role2-needs\\!escape","rolsuper":false,"rolinherit":false,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":false,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":5,"pass_not_empty":null,"rolvaliduntil":"2024-01-01T00:00:00+03:00"}]
(3 rows)
--test for drop user
select 1 from citus_remove_node('localhost', :worker_2_port);
?column?
---------------------------------------------------------------------
1
(1 row)
\c metadata_sync_2pc_db - - :worker_1_port
DROP ROLE test_role1, "test_role2-needs\!escape";
\c metadata_sync_2pc_db - - :master_port
DROP ROLE test_role3;
\c regression - - :master_port
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 rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb,
rolcanlogin, rolreplication, rolbypassrls, rolconnlimit,
(rolpassword != '') as pass_not_empty, rolvaliduntil
FROM pg_authid
WHERE rolname in ('test_role1', 'test_role2-needs\!escape')
ORDER BY rolname
) t
$$);
result
---------------------------------------------------------------------
[{"rolname":"test_role1","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":true,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":true,"rolvaliduntil":"infinity"},{"rolname":"test_role2-needs\\!escape","rolsuper":false,"rolinherit":false,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":false,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":5,"pass_not_empty":null,"rolvaliduntil":"2024-01-01T00:00:00+03:00"}]
(3 rows)
set citus.enable_create_database_propagation to on;
drop database metadata_sync_2pc_db;
drop schema metadata_sync_2pc_schema;

View File

@ -27,22 +27,6 @@ $$);
[{"rolname":"test_role1","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":true,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":true,"rolvaliduntil":null},{"rolname":"test_role2-needs\\!escape","rolsuper":true,"rolinherit":true,"rolcreaterole":true,"rolcreatedb":true,"rolcanlogin":true,"rolreplication":true,"rolbypassrls":true,"rolconnlimit":10,"pass_not_empty":null,"rolvaliduntil":"2023-01-01T00:00:00+03:00"}]
[{"rolname":"test_role1","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":true,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":true,"rolvaliduntil":null},{"rolname":"test_role2-needs\\!escape","rolsuper":true,"rolinherit":true,"rolcreaterole":true,"rolcreatedb":true,"rolcanlogin":true,"rolreplication":true,"rolbypassrls":true,"rolconnlimit":10,"pass_not_empty":null,"rolvaliduntil":"2023-01-01T11:00:00+03:00"}]
[{"rolname":"test_role1","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":true,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":true,"rolvaliduntil":null},{"rolname":"test_role2-needs\\!escape","rolsuper":true,"rolinherit":true,"rolcreaterole":true,"rolcreatedb":true,"rolcanlogin":true,"rolreplication":true,"rolbypassrls":true,"rolconnlimit":10,"pass_not_empty":null,"rolvaliduntil":"2023-01-01T00:00:00+03:00"}]
(3 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 ('test_role1', 'test_role2-needs\!escape')
ORDER BY member::regrole::text
) t
$$);
result
---------------------------------------------------------------------
(3 rows)
\c test_db - - :master_port
@ -70,22 +54,6 @@ $$);
[{"rolname":"test_role1","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":true,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":true,"rolvaliduntil":null},{"rolname":"test_role2-needs\\!escape","rolsuper":false,"rolinherit":false,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":false,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":5,"pass_not_empty":null,"rolvaliduntil":"2024-01-01T00:00:00+03:00"}]
[{"rolname":"test_role1","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":true,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":true,"rolvaliduntil":null},{"rolname":"test_role2-needs\\!escape","rolsuper":false,"rolinherit":false,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":false,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":5,"pass_not_empty":null,"rolvaliduntil":"2024-01-01T11:00:00+03:00"}]
[{"rolname":"test_role1","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":true,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":true,"rolvaliduntil":null},{"rolname":"test_role2-needs\\!escape","rolsuper":false,"rolinherit":false,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":false,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":5,"pass_not_empty":null,"rolvaliduntil":"2024-01-01T00:00:00+03:00"}]
(3 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 ('test_role1', 'test_role2-needs\!escape')
ORDER BY member::regrole::text
) t
$$);
result
---------------------------------------------------------------------
(3 rows)
\c test_db - - :master_port

View File

@ -97,6 +97,8 @@ WITH
SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN REPLICATION BYPASSRLS CONNECTION
LIMIT 10 VALID UNTIL '2023-01-01' IN ROLE test_role1;
create role test_role3;
\c regression - - :master_port
select 1 from citus_add_node('localhost', :worker_2_port);
@ -144,8 +146,11 @@ $$);
--test for drop user
select 1 from citus_remove_node('localhost', :worker_2_port);
\c metadata_sync_2pc_db - - :worker_1_port
DROP ROLE test_role1, "test_role2-needs\!escape";
\c metadata_sync_2pc_db - - :master_port
DROP ROLE IF EXISTS test_role1, "test_role2-needs\!escape";
DROP ROLE test_role3;
\c regression - - :master_port
@ -162,8 +167,6 @@ select result FROM run_command_on_all_nodes($$
) t
$$);
select * from pg_dist_object;
set citus.enable_create_database_propagation to on;
drop database metadata_sync_2pc_db;

View File

@ -31,16 +31,6 @@ select result FROM run_command_on_all_nodes($$
$$);
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 ('test_role1', 'test_role2-needs\!escape')
ORDER BY member::regrole::text
) t
$$);
\c test_db - - :master_port
-- Test ALTER ROLE with various options
ALTER ROLE test_role1 WITH PASSWORD 'new_password1';
@ -67,16 +57,6 @@ select result FROM run_command_on_all_nodes($$
$$);
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 ('test_role1', 'test_role2-needs\!escape')
ORDER BY member::regrole::text
) t
$$);
\c test_db - - :master_port
-- Test DROP ROLE