mirror of https://github.com/citusdata/citus.git
Co-authored-by: TsinghuaLucky912 <tsinghualucky912@foxmail.com> Fixes https://github.com/citusdata/citus/issues/5763pull/6535/head
parent
3b24c47470
commit
ad6450b793
|
@ -254,6 +254,15 @@ static DistributeObjectOps Any_CreateRole = {
|
||||||
.address = CreateRoleStmtObjectAddress,
|
.address = CreateRoleStmtObjectAddress,
|
||||||
.markDistributed = true,
|
.markDistributed = true,
|
||||||
};
|
};
|
||||||
|
static DistributeObjectOps Any_DropOwned = {
|
||||||
|
.deparse = DeparseDropOwnedStmt,
|
||||||
|
.qualify = NULL,
|
||||||
|
.preprocess = PreprocessDropOwnedStmt,
|
||||||
|
.postprocess = NULL,
|
||||||
|
.operationType = DIST_OPS_DROP,
|
||||||
|
.address = NULL,
|
||||||
|
.markDistributed = false,
|
||||||
|
};
|
||||||
static DistributeObjectOps Any_DropRole = {
|
static DistributeObjectOps Any_DropRole = {
|
||||||
.deparse = DeparseDropRoleStmt,
|
.deparse = DeparseDropRoleStmt,
|
||||||
.qualify = NULL,
|
.qualify = NULL,
|
||||||
|
@ -1658,6 +1667,11 @@ GetDistributeObjectOps(Node *node)
|
||||||
return &Any_DropRole;
|
return &Any_DropRole;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case T_DropOwnedStmt:
|
||||||
|
{
|
||||||
|
return &Any_DropOwned;
|
||||||
|
}
|
||||||
|
|
||||||
case T_DropStmt:
|
case T_DropStmt:
|
||||||
{
|
{
|
||||||
DropStmt *stmt = castNode(DropStmt, node);
|
DropStmt *stmt = castNode(DropStmt, node);
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* owned.c
|
||||||
|
* Commands for DROP OWNED statements.
|
||||||
|
*
|
||||||
|
* Copyright (c) Citus Data, Inc.
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "access/heapam.h"
|
||||||
|
#include "access/htup_details.h"
|
||||||
|
#include "access/genam.h"
|
||||||
|
#include "access/table.h"
|
||||||
|
#include "access/xact.h"
|
||||||
|
#include "catalog/catalog.h"
|
||||||
|
#include "catalog/pg_auth_members.h"
|
||||||
|
#include "catalog/pg_authid.h"
|
||||||
|
#include "catalog/pg_db_role_setting.h"
|
||||||
|
#include "catalog/pg_type.h"
|
||||||
|
#include "catalog/objectaddress.h"
|
||||||
|
#include "commands/dbcommands.h"
|
||||||
|
#include "distributed/citus_ruleutils.h"
|
||||||
|
#include "distributed/citus_safe_lib.h"
|
||||||
|
#include "distributed/commands.h"
|
||||||
|
#include "distributed/commands/utility_hook.h"
|
||||||
|
#include "distributed/deparser.h"
|
||||||
|
#include "distributed/listutils.h"
|
||||||
|
#include "distributed/coordinator_protocol.h"
|
||||||
|
#include "distributed/metadata/distobject.h"
|
||||||
|
#include "distributed/metadata_sync.h"
|
||||||
|
#include "distributed/metadata/distobject.h"
|
||||||
|
#include "distributed/multi_executor.h"
|
||||||
|
#include "distributed/relation_access_tracking.h"
|
||||||
|
#include "distributed/version_compat.h"
|
||||||
|
#include "distributed/worker_transaction.h"
|
||||||
|
#include "miscadmin.h"
|
||||||
|
#include "nodes/makefuncs.h"
|
||||||
|
#include "nodes/parsenodes.h"
|
||||||
|
#include "nodes/pg_list.h"
|
||||||
|
#include "parser/scansup.h"
|
||||||
|
#include "utils/builtins.h"
|
||||||
|
#include "utils/fmgroids.h"
|
||||||
|
#include "utils/rel.h"
|
||||||
|
#include "utils/varlena.h"
|
||||||
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PreprocessDropOwnedStmt finds the distributed role out of the ones
|
||||||
|
* being dropped and unmarks them distributed and creates the drop statements
|
||||||
|
* for the workers.
|
||||||
|
*/
|
||||||
|
List *
|
||||||
|
PreprocessDropOwnedStmt(Node *node, const char *queryString,
|
||||||
|
ProcessUtilityContext processUtilityContext)
|
||||||
|
{
|
||||||
|
DropOwnedStmt *stmt = castNode(DropOwnedStmt, node);
|
||||||
|
List *allDropRoles = stmt->roles;
|
||||||
|
|
||||||
|
List *distributedDropRoles = FilterDistributedRoles(allDropRoles);
|
||||||
|
if (list_length(distributedDropRoles) <= 0)
|
||||||
|
{
|
||||||
|
return NIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ShouldPropagate())
|
||||||
|
{
|
||||||
|
return NIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check creation against multi-statement transaction policy */
|
||||||
|
if (!ShouldPropagateCreateInCoordinatedTransction())
|
||||||
|
{
|
||||||
|
return NIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnsureCoordinator();
|
||||||
|
|
||||||
|
stmt->roles = distributedDropRoles;
|
||||||
|
char *sql = DeparseTreeNode((Node *) stmt);
|
||||||
|
stmt->roles = allDropRoles;
|
||||||
|
|
||||||
|
List *commands = list_make3(DISABLE_DDL_PROPAGATION,
|
||||||
|
sql,
|
||||||
|
ENABLE_DDL_PROPAGATION);
|
||||||
|
|
||||||
|
return NodeDDLTaskList(NON_COORDINATOR_NODES, commands);
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* deparse_owned_stmts.c
|
||||||
|
* Functions to turn all Statement structures related to owned back
|
||||||
|
* into sql.
|
||||||
|
*
|
||||||
|
* Copyright (c), Citus Data, Inc.
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "pg_version_compat.h"
|
||||||
|
|
||||||
|
#include "distributed/citus_ruleutils.h"
|
||||||
|
#include "distributed/deparser.h"
|
||||||
|
#include "lib/stringinfo.h"
|
||||||
|
#include "nodes/parsenodes.h"
|
||||||
|
#include "utils/builtins.h"
|
||||||
|
|
||||||
|
static void AppendDropOwnedStmt(StringInfo buf, DropOwnedStmt *stmt);
|
||||||
|
static void AppendRoleList(StringInfo buf, List *roleList);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DeparseDropOwnedStmt builds and returns a string representing of the
|
||||||
|
* DropOwnedStmt for application on a remote server.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
DeparseDropOwnedStmt(Node *node)
|
||||||
|
{
|
||||||
|
DropOwnedStmt *stmt = castNode(DropOwnedStmt, node);
|
||||||
|
|
||||||
|
StringInfoData buf = { 0 };
|
||||||
|
initStringInfo(&buf);
|
||||||
|
|
||||||
|
AppendDropOwnedStmt(&buf, stmt);
|
||||||
|
|
||||||
|
return buf.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AppendDropOwnedStmt generates the string representation of the
|
||||||
|
* DropOwnedStmt and appends it to the buffer.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
AppendDropOwnedStmt(StringInfo buf, DropOwnedStmt *stmt)
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, "DROP OWNED BY ");
|
||||||
|
|
||||||
|
AppendRoleList(buf, stmt->roles);
|
||||||
|
|
||||||
|
if (stmt->behavior == DROP_RESTRICT)
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, " RESTRICT");
|
||||||
|
}
|
||||||
|
else if (stmt->behavior == DROP_CASCADE)
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, " CASCADE");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
AppendRoleList(StringInfo buf, List *roleList)
|
||||||
|
{
|
||||||
|
ListCell *cell = NULL;
|
||||||
|
foreach(cell, roleList)
|
||||||
|
{
|
||||||
|
Node *roleNode = (Node *) lfirst(cell);
|
||||||
|
Assert(IsA(roleNode, RoleSpec) || IsA(roleNode, AccessPriv));
|
||||||
|
char const *rolename = NULL;
|
||||||
|
if (IsA(roleNode, RoleSpec))
|
||||||
|
{
|
||||||
|
rolename = RoleSpecString((RoleSpec *) roleNode, true);
|
||||||
|
}
|
||||||
|
appendStringInfoString(buf, rolename);
|
||||||
|
if (cell != list_tail(roleList))
|
||||||
|
{
|
||||||
|
appendStringInfo(buf, ", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -385,6 +385,9 @@ extern bool IsReindexWithParam_compat(ReindexStmt *stmt, char *paramName);
|
||||||
extern List * CreateExtensionStmtObjectAddress(Node *stmt, bool missing_ok, bool
|
extern List * CreateExtensionStmtObjectAddress(Node *stmt, bool missing_ok, bool
|
||||||
isPostprocess);
|
isPostprocess);
|
||||||
|
|
||||||
|
/* owned.c - forward declarations */
|
||||||
|
extern List * PreprocessDropOwnedStmt(Node *node, const char *queryString,
|
||||||
|
ProcessUtilityContext processUtilityContext);
|
||||||
|
|
||||||
/* policy.c - forward declarations */
|
/* policy.c - forward declarations */
|
||||||
extern List * CreatePolicyCommands(Oid relationId);
|
extern List * CreatePolicyCommands(Oid relationId);
|
||||||
|
|
|
@ -196,6 +196,9 @@ extern char * DeparseCreateRoleStmt(Node *stmt);
|
||||||
extern char * DeparseDropRoleStmt(Node *stmt);
|
extern char * DeparseDropRoleStmt(Node *stmt);
|
||||||
extern char * DeparseGrantRoleStmt(Node *stmt);
|
extern char * DeparseGrantRoleStmt(Node *stmt);
|
||||||
|
|
||||||
|
/* forward declarations for deparse_owned_stmts.c */
|
||||||
|
extern char * DeparseDropOwnedStmt(Node *node);
|
||||||
|
|
||||||
/* forward declarations for deparse_extension_stmts.c */
|
/* forward declarations for deparse_extension_stmts.c */
|
||||||
extern DefElem * GetExtensionOption(List *extensionOptions,
|
extern DefElem * GetExtensionOption(List *extensionOptions,
|
||||||
const char *defname);
|
const char *defname);
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
--
|
||||||
|
-- ISSUE_5763
|
||||||
|
--
|
||||||
|
-- Issue: DROP OWNED BY fails to drop the schemas on the workers
|
||||||
|
-- Link: https://github.com/citusdata/citus/issues/5763
|
||||||
|
--
|
||||||
|
CREATE USER issue_5763_1 WITH SUPERUSER;
|
||||||
|
CREATE USER issue_5763_2 WITH SUPERUSER;
|
||||||
|
\c - issue_5763_1 - :master_port
|
||||||
|
CREATE SCHEMA issue_5763_sc_1;
|
||||||
|
\c - issue_5763_2 - :master_port
|
||||||
|
CREATE SCHEMA issue_5763_sc_2;
|
||||||
|
\c - postgres - :master_port
|
||||||
|
DROP OWNED BY issue_5763_1, issue_5763_2;
|
||||||
|
\c - issue_5763_1 - :master_port
|
||||||
|
CREATE SCHEMA issue_5763_sc_1;
|
||||||
|
\c - postgres - :master_port
|
||||||
|
DROP SCHEMA issue_5763_sc_1;
|
||||||
|
DROP USER issue_5763_1, issue_5763_2;
|
||||||
|
-- test CASCADE options
|
||||||
|
CREATE USER issue_5763_3 WITH SUPERUSER;
|
||||||
|
\c - issue_5763_3 - :master_port
|
||||||
|
CREATE SCHEMA issue_5763_sc_3;
|
||||||
|
CREATE TABLE issue_5763_sc_3.tb1(id int);
|
||||||
|
\c - postgres - :master_port
|
||||||
|
DROP OWNED BY issue_5763_3 CASCADE;
|
||||||
|
DROP USER issue_5763_3;
|
||||||
|
-- test non-distributed role
|
||||||
|
SET citus.enable_create_role_propagation TO off;
|
||||||
|
CREATE USER issue_5763_4 WITH SUPERUSER;
|
||||||
|
NOTICE: not propagating CREATE ROLE/USER commands to worker nodes
|
||||||
|
HINT: Connect to worker nodes directly to manually create all necessary users and roles.
|
||||||
|
\c - issue_5763_4 - :master_port
|
||||||
|
set citus.enable_ddl_propagation = off;
|
||||||
|
CREATE SCHEMA issue_5763_sc_4;
|
||||||
|
\c - postgres - :master_port
|
||||||
|
DROP OWNED BY issue_5763_4 RESTRICT;
|
||||||
|
DROP USER issue_5763_4;
|
|
@ -545,27 +545,6 @@ DROP TABLE
|
||||||
test,
|
test,
|
||||||
test_coloc,
|
test_coloc,
|
||||||
colocation_table;
|
colocation_table;
|
||||||
SELECT run_command_on_workers($$DROP OWNED BY full_access$$);
|
|
||||||
run_command_on_workers
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
(localhost,57637,t,"DROP OWNED")
|
|
||||||
(localhost,57638,t,"DROP OWNED")
|
|
||||||
(2 rows)
|
|
||||||
|
|
||||||
SELECT run_command_on_workers($$DROP OWNED BY some_role$$);
|
|
||||||
run_command_on_workers
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
(localhost,57637,t,"DROP OWNED")
|
|
||||||
(localhost,57638,t,"DROP OWNED")
|
|
||||||
(2 rows)
|
|
||||||
|
|
||||||
SELECT run_command_on_workers($$DROP OWNED BY read_access$$);
|
|
||||||
run_command_on_workers
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
(localhost,57637,t,"DROP OWNED")
|
|
||||||
(localhost,57638,t,"DROP OWNED")
|
|
||||||
(2 rows)
|
|
||||||
|
|
||||||
DROP USER full_access;
|
DROP USER full_access;
|
||||||
DROP USER read_access;
|
DROP USER read_access;
|
||||||
DROP USER no_access;
|
DROP USER no_access;
|
||||||
|
|
|
@ -1154,13 +1154,6 @@ SET citus.next_shard_id TO 1197000;
|
||||||
-- we do not use run_command_on_coordinator_and_workers here because when there is CASCADE, it causes deadlock
|
-- we do not use run_command_on_coordinator_and_workers here because when there is CASCADE, it causes deadlock
|
||||||
DROP OWNED BY "test-user" CASCADE;
|
DROP OWNED BY "test-user" CASCADE;
|
||||||
NOTICE: drop cascades to table schema_with_user.test_table
|
NOTICE: drop cascades to table schema_with_user.test_table
|
||||||
SELECT run_command_on_workers('DROP OWNED BY "test-user" CASCADE');
|
|
||||||
run_command_on_workers
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
(localhost,57637,t,"DROP OWNED")
|
|
||||||
(localhost,57638,t,"DROP OWNED")
|
|
||||||
(2 rows)
|
|
||||||
|
|
||||||
DROP USER "test-user";
|
DROP USER "test-user";
|
||||||
DROP FUNCTION run_command_on_coordinator_and_workers(p_sql text);
|
DROP FUNCTION run_command_on_coordinator_and_workers(p_sql text);
|
||||||
-- test run_command_on_* UDFs with schema
|
-- test run_command_on_* UDFs with schema
|
||||||
|
|
|
@ -489,18 +489,6 @@ SET client_min_messages TO WARNING;
|
||||||
DROP SCHEMA single_node_ent CASCADE;
|
DROP SCHEMA single_node_ent CASCADE;
|
||||||
DROP OWNED BY full_access_single_node;
|
DROP OWNED BY full_access_single_node;
|
||||||
DROP OWNED BY read_access_single_node;
|
DROP OWNED BY read_access_single_node;
|
||||||
SELECT run_command_on_workers($$DROP OWNED BY full_access_single_node$$);
|
|
||||||
run_command_on_workers
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
(localhost,57637,t,"DROP OWNED")
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SELECT run_command_on_workers($$DROP OWNED BY read_access_single_node$$);
|
|
||||||
run_command_on_workers
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
(localhost,57637,t,"DROP OWNED")
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
DROP ROLE full_access_single_node;
|
DROP ROLE full_access_single_node;
|
||||||
DROP ROLE read_access_single_node;
|
DROP ROLE read_access_single_node;
|
||||||
-- remove the nodes for next tests
|
-- remove the nodes for next tests
|
||||||
|
|
|
@ -95,7 +95,7 @@ test: multi_dropped_column_aliases foreign_key_restriction_enforcement
|
||||||
test: binary_protocol
|
test: binary_protocol
|
||||||
test: alter_table_set_access_method
|
test: alter_table_set_access_method
|
||||||
test: alter_distributed_table
|
test: alter_distributed_table
|
||||||
test: issue_5248 issue_5099
|
test: issue_5248 issue_5099 issue_5763
|
||||||
test: object_propagation_debug
|
test: object_propagation_debug
|
||||||
test: undistribute_table
|
test: undistribute_table
|
||||||
test: run_command_on_all_nodes
|
test: run_command_on_all_nodes
|
||||||
|
@ -113,3 +113,4 @@ test: ensure_no_intermediate_data_leak
|
||||||
# --------
|
# --------
|
||||||
test: ensure_no_shared_connection_leak
|
test: ensure_no_shared_connection_leak
|
||||||
test: check_mx
|
test: check_mx
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
--
|
||||||
|
-- ISSUE_5763
|
||||||
|
--
|
||||||
|
-- Issue: DROP OWNED BY fails to drop the schemas on the workers
|
||||||
|
-- Link: https://github.com/citusdata/citus/issues/5763
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE USER issue_5763_1 WITH SUPERUSER;
|
||||||
|
CREATE USER issue_5763_2 WITH SUPERUSER;
|
||||||
|
|
||||||
|
\c - issue_5763_1 - :master_port
|
||||||
|
CREATE SCHEMA issue_5763_sc_1;
|
||||||
|
|
||||||
|
\c - issue_5763_2 - :master_port
|
||||||
|
CREATE SCHEMA issue_5763_sc_2;
|
||||||
|
|
||||||
|
\c - postgres - :master_port
|
||||||
|
DROP OWNED BY issue_5763_1, issue_5763_2;
|
||||||
|
|
||||||
|
\c - issue_5763_1 - :master_port
|
||||||
|
CREATE SCHEMA issue_5763_sc_1;
|
||||||
|
|
||||||
|
\c - postgres - :master_port
|
||||||
|
DROP SCHEMA issue_5763_sc_1;
|
||||||
|
DROP USER issue_5763_1, issue_5763_2;
|
||||||
|
|
||||||
|
-- test CASCADE options
|
||||||
|
CREATE USER issue_5763_3 WITH SUPERUSER;
|
||||||
|
|
||||||
|
\c - issue_5763_3 - :master_port
|
||||||
|
CREATE SCHEMA issue_5763_sc_3;
|
||||||
|
CREATE TABLE issue_5763_sc_3.tb1(id int);
|
||||||
|
|
||||||
|
\c - postgres - :master_port
|
||||||
|
DROP OWNED BY issue_5763_3 CASCADE;
|
||||||
|
|
||||||
|
DROP USER issue_5763_3;
|
||||||
|
|
||||||
|
-- test non-distributed role
|
||||||
|
SET citus.enable_create_role_propagation TO off;
|
||||||
|
CREATE USER issue_5763_4 WITH SUPERUSER;
|
||||||
|
|
||||||
|
\c - issue_5763_4 - :master_port
|
||||||
|
set citus.enable_ddl_propagation = off;
|
||||||
|
CREATE SCHEMA issue_5763_sc_4;
|
||||||
|
|
||||||
|
\c - postgres - :master_port
|
||||||
|
DROP OWNED BY issue_5763_4 RESTRICT;
|
||||||
|
|
||||||
|
DROP USER issue_5763_4;
|
|
@ -328,9 +328,6 @@ DROP TABLE
|
||||||
test,
|
test,
|
||||||
test_coloc,
|
test_coloc,
|
||||||
colocation_table;
|
colocation_table;
|
||||||
SELECT run_command_on_workers($$DROP OWNED BY full_access$$);
|
|
||||||
SELECT run_command_on_workers($$DROP OWNED BY some_role$$);
|
|
||||||
SELECT run_command_on_workers($$DROP OWNED BY read_access$$);
|
|
||||||
DROP USER full_access;
|
DROP USER full_access;
|
||||||
DROP USER read_access;
|
DROP USER read_access;
|
||||||
DROP USER no_access;
|
DROP USER no_access;
|
||||||
|
|
|
@ -842,7 +842,6 @@ SET citus.next_shard_id TO 1197000;
|
||||||
|
|
||||||
-- we do not use run_command_on_coordinator_and_workers here because when there is CASCADE, it causes deadlock
|
-- we do not use run_command_on_coordinator_and_workers here because when there is CASCADE, it causes deadlock
|
||||||
DROP OWNED BY "test-user" CASCADE;
|
DROP OWNED BY "test-user" CASCADE;
|
||||||
SELECT run_command_on_workers('DROP OWNED BY "test-user" CASCADE');
|
|
||||||
DROP USER "test-user";
|
DROP USER "test-user";
|
||||||
|
|
||||||
DROP FUNCTION run_command_on_coordinator_and_workers(p_sql text);
|
DROP FUNCTION run_command_on_coordinator_and_workers(p_sql text);
|
||||||
|
|
|
@ -313,8 +313,6 @@ DROP SCHEMA single_node_ent CASCADE;
|
||||||
|
|
||||||
DROP OWNED BY full_access_single_node;
|
DROP OWNED BY full_access_single_node;
|
||||||
DROP OWNED BY read_access_single_node;
|
DROP OWNED BY read_access_single_node;
|
||||||
SELECT run_command_on_workers($$DROP OWNED BY full_access_single_node$$);
|
|
||||||
SELECT run_command_on_workers($$DROP OWNED BY read_access_single_node$$);
|
|
||||||
DROP ROLE full_access_single_node;
|
DROP ROLE full_access_single_node;
|
||||||
DROP ROLE read_access_single_node;
|
DROP ROLE read_access_single_node;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue