mirror of https://github.com/citusdata/citus.git
Fixes drop role pg_dist_object removal issue
parent
c57d642408
commit
dd45a2c874
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
10
src/backend/distributed/sql/udfs/citus_unmark_object_distributed/12.2-1.sql
generated
Normal file
10
src/backend/distributed/sql/udfs/citus_unmark_object_distributed/12.2-1.sql
generated
Normal 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 .';
|
|
@ -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 .';
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue