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 \
|
#define MARK_OBJECT_DISTRIBUTED \
|
||||||
"SELECT citus_internal.mark_object_distributed(%d, %s, %d, %s)"
|
"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
|
* NonMainDbDistributedStatementInfo is used to determine whether a statement is
|
||||||
* supported from non-main databases and whether it should be marked as
|
* supported from non-main databases and whether it should be marked as
|
||||||
|
@ -107,7 +117,7 @@
|
||||||
typedef struct NonMainDbDistributedStatementInfo
|
typedef struct NonMainDbDistributedStatementInfo
|
||||||
{
|
{
|
||||||
int statementType;
|
int statementType;
|
||||||
bool explicitlyMarkAsDistributed;
|
DistributedOperation distributedOperation;
|
||||||
ObjectType *supportedObjectTypes;
|
ObjectType *supportedObjectTypes;
|
||||||
int supportedObjectTypesSize;
|
int supportedObjectTypesSize;
|
||||||
} NonMainDbDistributedStatementInfo;
|
} NonMainDbDistributedStatementInfo;
|
||||||
|
@ -125,11 +135,11 @@ typedef struct ObjectInfo
|
||||||
ObjectType supportedObjectTypesForGrantStmt[] = { OBJECT_DATABASE };
|
ObjectType supportedObjectTypesForGrantStmt[] = { OBJECT_DATABASE };
|
||||||
|
|
||||||
static const NonMainDbDistributedStatementInfo NonMainDbSupportedStatements[] = {
|
static const NonMainDbDistributedStatementInfo NonMainDbSupportedStatements[] = {
|
||||||
{ T_GrantRoleStmt, false, NULL, 0 },
|
{ T_GrantRoleStmt, NO_DISTRIBUTED_OPS, NULL, 0 },
|
||||||
{ T_CreateRoleStmt, true, NULL, 0 },
|
{ T_CreateRoleStmt, MARK_DISTRIBUTED, NULL, 0 },
|
||||||
{ T_DropRoleStmt, false,NULL, 0 },
|
{ T_DropRoleStmt, UNMARK_DISTRIBUTED, NULL, 0 },
|
||||||
{ T_AlterRoleStmt, false, NULL, 0 },
|
{ T_AlterRoleStmt, NO_DISTRIBUTED_OPS, NULL, 0 },
|
||||||
{ T_GrantStmt, false, supportedObjectTypesForGrantStmt,
|
{ T_GrantStmt, NO_DISTRIBUTED_OPS, supportedObjectTypesForGrantStmt,
|
||||||
sizeof(supportedObjectTypesForGrantStmt) / sizeof(ObjectType) }
|
sizeof(supportedObjectTypesForGrantStmt) / sizeof(ObjectType) }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -167,8 +177,10 @@ static bool IsObjectTypeSupported(Node *parsetree, NonMainDbDistributedStatement
|
||||||
nonMainDbDistributedStatementInfo);
|
nonMainDbDistributedStatementInfo);
|
||||||
static bool IsStatementSupportedInNonMainDb(Node *parsetree);
|
static bool IsStatementSupportedInNonMainDb(Node *parsetree);
|
||||||
static bool StatementRequiresMarkDistributedFromNonMainDb(Node *parsetree);
|
static bool StatementRequiresMarkDistributedFromNonMainDb(Node *parsetree);
|
||||||
static ObjectInfo GetObjectInfo(Node *parsetree);
|
static bool StatementRequiresUnmarkDistributedFromNonMainDb(Node *parsetree);
|
||||||
static void MarkObjectDistributedInNonMainDb(Node *parsetree, ObjectInfo objectInfo);
|
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
|
* 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,
|
EXECUTE_COMMAND_ON_REMOTE_NODES_AS_USER,
|
||||||
quote_literal_cstr(queryString),
|
quote_literal_cstr(queryString),
|
||||||
quote_literal_cstr(CurrentUserName()));
|
quote_literal_cstr(CurrentUserName()));
|
||||||
|
|
||||||
|
if (StatementRequiresUnmarkDistributedFromNonMainDb(parsetree))
|
||||||
|
{
|
||||||
|
List *objectInfoList = GetObjectInfoList(parsetree);
|
||||||
|
|
||||||
|
UnmarkObjectDistributedInNonMainDb(objectInfoList);
|
||||||
|
}
|
||||||
|
|
||||||
RunCitusMainDBQuery(mainDBQuery->data);
|
RunCitusMainDBQuery(mainDBQuery->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1677,30 +1697,50 @@ RunPostprocessMainDBCommand(Node *parsetree)
|
||||||
if (IsStatementSupportedInNonMainDb(parsetree) &&
|
if (IsStatementSupportedInNonMainDb(parsetree) &&
|
||||||
StatementRequiresMarkDistributedFromNonMainDb(parsetree))
|
StatementRequiresMarkDistributedFromNonMainDb(parsetree))
|
||||||
{
|
{
|
||||||
ObjectInfo objectInfo = GetObjectInfo(parsetree);
|
List *objectInfoList = GetObjectInfoList(parsetree);
|
||||||
MarkObjectDistributedInNonMainDb(parsetree, objectInfo);
|
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
|
List *
|
||||||
GetObjectInfo(Node *parsetree)
|
GetObjectInfoList(Node *parsetree)
|
||||||
{
|
{
|
||||||
ObjectInfo info;
|
List *infoList = NIL;
|
||||||
|
|
||||||
if (IsA(parsetree, CreateRoleStmt))
|
if (IsA(parsetree, CreateRoleStmt))
|
||||||
{
|
{
|
||||||
CreateRoleStmt *stmt = castNode(CreateRoleStmt, parsetree);
|
CreateRoleStmt *stmt = castNode(CreateRoleStmt, parsetree);
|
||||||
info.name = stmt->role;
|
ObjectInfo *info = palloc(sizeof(ObjectInfo));
|
||||||
info.id = get_role_oid(stmt->role, false);
|
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 */
|
/* Add else if branches for other statement types */
|
||||||
|
|
||||||
return info;
|
return infoList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1709,19 +1749,42 @@ GetObjectInfo(Node *parsetree)
|
||||||
* non-main database.
|
* non-main database.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
MarkObjectDistributedInNonMainDb(Node *parsetree, ObjectInfo objectInfo)
|
MarkObjectDistributedInNonMainDb(Node *parsetree, ObjectInfo *objectInfo)
|
||||||
{
|
{
|
||||||
StringInfo mainDBQuery = makeStringInfo();
|
StringInfo mainDBQuery = makeStringInfo();
|
||||||
appendStringInfo(mainDBQuery,
|
appendStringInfo(mainDBQuery,
|
||||||
MARK_OBJECT_DISTRIBUTED,
|
MARK_OBJECT_DISTRIBUTED,
|
||||||
AuthIdRelationId,
|
AuthIdRelationId,
|
||||||
quote_literal_cstr(objectInfo.name),
|
quote_literal_cstr(objectInfo->name),
|
||||||
objectInfo.id,
|
objectInfo->id,
|
||||||
quote_literal_cstr(CurrentUserName()));
|
quote_literal_cstr(CurrentUserName()));
|
||||||
RunCitusMainDBQuery(mainDBQuery->data);
|
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
|
* IsStatementSupportedIn2Pc returns true if the statement is supported from a
|
||||||
* non-main database.
|
* 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.
|
* as distributed when executed from a non-main database.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
|
@ -1797,7 +1860,31 @@ StatementRequiresMarkDistributedFromNonMainDb(Node *parsetree)
|
||||||
{
|
{
|
||||||
if (type == NonMainDbSupportedStatements[i].statementType)
|
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 classid = PG_GETARG_OID(0);
|
||||||
Oid objid = PG_GETARG_OID(1);
|
Oid objid = PG_GETARG_OID(1);
|
||||||
int32 objsubid = PG_GETARG_INT32(2);
|
int32 objsubid = PG_GETARG_INT32(2);
|
||||||
|
bool checkObjectExistence = true;
|
||||||
|
if (!PG_ARGISNULL(3))
|
||||||
|
{
|
||||||
|
checkObjectExistence = PG_GETARG_BOOL(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ObjectAddress address = { 0 };
|
ObjectAddress address = { 0 };
|
||||||
ObjectAddressSubSet(address, classid, objid, objsubid);
|
ObjectAddressSubSet(address, classid, objid, objsubid);
|
||||||
|
@ -119,7 +125,7 @@ citus_unmark_object_distributed(PG_FUNCTION_ARGS)
|
||||||
PG_RETURN_VOID();
|
PG_RETURN_VOID();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ObjectExists(&address))
|
if (checkObjectExistence && ObjectExists(&address))
|
||||||
{
|
{
|
||||||
ereport(ERROR, (errmsg("object still exists"),
|
ereport(ERROR, (errmsg("object still exists"),
|
||||||
errdetail("the %s \"%s\" 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;
|
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_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"
|
#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$$;
|
AS 'MODULE_PATHNAME', $$citus_unmark_object_distributed$$;
|
||||||
COMMENT ON FUNCTION pg_catalog.citus_unmark_object_distributed(classid oid, objid oid, objsubid int)
|
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';
|
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;
|
revoke CREATE on database metadata_sync_2pc_db from grant_role2pc_user1;
|
||||||
\c regression
|
\c regression
|
||||||
drop user grant_role2pc_user1,grant_role2pc_user2,grant_role2pc_user3,grant_role2pc_user4,grant_role2pc_user5;
|
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;
|
set citus.enable_create_database_propagation to on;
|
||||||
drop database metadata_sync_2pc_db;
|
drop database metadata_sync_2pc_db;
|
||||||
drop schema metadata_sync_2pc_schema;
|
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-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-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"}]
|
[{"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)
|
(3 rows)
|
||||||
|
|
||||||
\c test_db - - :master_port
|
\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-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-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"}]
|
[{"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)
|
(3 rows)
|
||||||
|
|
||||||
\c test_db - - :master_port
|
\c test_db - - :master_port
|
||||||
|
|
|
@ -97,6 +97,8 @@ WITH
|
||||||
SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN REPLICATION BYPASSRLS CONNECTION
|
SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN REPLICATION BYPASSRLS CONNECTION
|
||||||
LIMIT 10 VALID UNTIL '2023-01-01' IN ROLE test_role1;
|
LIMIT 10 VALID UNTIL '2023-01-01' IN ROLE test_role1;
|
||||||
|
|
||||||
|
create role test_role3;
|
||||||
|
|
||||||
\c regression - - :master_port
|
\c regression - - :master_port
|
||||||
|
|
||||||
select 1 from citus_add_node('localhost', :worker_2_port);
|
select 1 from citus_add_node('localhost', :worker_2_port);
|
||||||
|
@ -144,8 +146,11 @@ $$);
|
||||||
--test for drop user
|
--test for drop user
|
||||||
select 1 from citus_remove_node('localhost', :worker_2_port);
|
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
|
\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
|
\c regression - - :master_port
|
||||||
|
|
||||||
|
@ -162,8 +167,6 @@ select result FROM run_command_on_all_nodes($$
|
||||||
) t
|
) t
|
||||||
$$);
|
$$);
|
||||||
|
|
||||||
select * from pg_dist_object;
|
|
||||||
|
|
||||||
set citus.enable_create_database_propagation to on;
|
set citus.enable_create_database_propagation to on;
|
||||||
drop database metadata_sync_2pc_db;
|
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
|
\c test_db - - :master_port
|
||||||
-- Test ALTER ROLE with various options
|
-- Test ALTER ROLE with various options
|
||||||
ALTER ROLE test_role1 WITH PASSWORD 'new_password1';
|
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
|
\c test_db - - :master_port
|
||||||
|
|
||||||
-- Test DROP ROLE
|
-- Test DROP ROLE
|
||||||
|
|
Loading…
Reference in New Issue