mirror of https://github.com/citusdata/citus.git
parent
c6fbb72c02
commit
cfd98d15aa
|
@ -374,6 +374,15 @@ static DistributeObjectOps Any_Rename = {
|
|||
.address = NULL,
|
||||
.markDistributed = false,
|
||||
};
|
||||
static DistributeObjectOps Any_SecLabel = {
|
||||
.deparse = DeparseSecLabelStmt,
|
||||
.qualify = NULL,
|
||||
.preprocess = PreprocessSecLabelStmt,
|
||||
.postprocess = PostprocessSecLabelStmt,
|
||||
.operationType = DIST_OPS_ALTER,
|
||||
.address = SecLabelStmtObjectAddress,
|
||||
.markDistributed = false,
|
||||
};
|
||||
static DistributeObjectOps Attribute_Rename = {
|
||||
.deparse = DeparseRenameAttributeStmt,
|
||||
.qualify = QualifyRenameAttributeStmt,
|
||||
|
@ -2020,6 +2029,11 @@ GetDistributeObjectOps(Node *node)
|
|||
return &Vacuum_Analyze;
|
||||
}
|
||||
|
||||
case T_SecLabelStmt:
|
||||
{
|
||||
return &Any_SecLabel;
|
||||
}
|
||||
|
||||
case T_RenameStmt:
|
||||
{
|
||||
RenameStmt *stmt = castNode(RenameStmt, node);
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* seclabel.c
|
||||
*
|
||||
* This file contains the logic of SECURITY LABEL statement propagation.
|
||||
*
|
||||
* Copyright (c) Citus Data, Inc.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
#include "distributed/commands.h"
|
||||
#include "distributed/commands/utility_hook.h"
|
||||
#include "distributed/coordinator_protocol.h"
|
||||
#include "distributed/deparser.h"
|
||||
#include "distributed/log_utils.h"
|
||||
#include "distributed/metadata_sync.h"
|
||||
#include "distributed/metadata/distobject.h"
|
||||
|
||||
/*
|
||||
* PreprocessSecLabelStmt is executed before the statement is applied to the local
|
||||
* postgres instance.
|
||||
*
|
||||
* In this stage we can prepare the commands that need to be run on all workers to assign
|
||||
* security labels on distributed objects, currently supporting just Role objects.
|
||||
*/
|
||||
List *
|
||||
PreprocessSecLabelStmt(Node *node, const char *queryString,
|
||||
ProcessUtilityContext processUtilityContext)
|
||||
{
|
||||
if (!IsCoordinator() || !ShouldPropagate())
|
||||
{
|
||||
return NIL;
|
||||
}
|
||||
|
||||
SecLabelStmt *secLabelStmt = castNode(SecLabelStmt, node);
|
||||
|
||||
List * objectAddresses = GetObjectAddressListFromParseTree(node, false, false);
|
||||
if(!IsAnyObjectDistributed(objectAddresses))
|
||||
{
|
||||
return NIL;
|
||||
}
|
||||
|
||||
if (secLabelStmt->objtype != OBJECT_ROLE)
|
||||
{
|
||||
if (EnableUnsupportedFeatureMessages)
|
||||
{
|
||||
ereport(NOTICE, (errmsg("not propagating SECURITY LABEL commands whose"
|
||||
" object type is not role"),
|
||||
errhint(
|
||||
"Connect to worker nodes directly to manually run the same"
|
||||
" SECURITY LABEL command after disabling DDL propagation.")));
|
||||
}
|
||||
return NIL;
|
||||
}
|
||||
|
||||
if (!EnableCreateRolePropagation)
|
||||
{
|
||||
return NIL;
|
||||
}
|
||||
|
||||
const char *sql = DeparseTreeNode((Node *) secLabelStmt);
|
||||
|
||||
List *commandList = list_make3(DISABLE_DDL_PROPAGATION,
|
||||
(void *) sql,
|
||||
ENABLE_DDL_PROPAGATION);
|
||||
|
||||
return NodeDDLTaskList(NON_COORDINATOR_NODES, commandList);
|
||||
}
|
||||
|
||||
/*
|
||||
* PostprocessSecLabelStmt
|
||||
*/
|
||||
List *
|
||||
PostprocessSecLabelStmt(Node *node, const char *queryString)
|
||||
{
|
||||
if (!EnableCreateRolePropagation || !IsCoordinator() || !ShouldPropagate())
|
||||
{
|
||||
return NIL;
|
||||
}
|
||||
|
||||
SecLabelStmt *secLabelStmt = castNode(SecLabelStmt, node);
|
||||
|
||||
if (secLabelStmt->objtype != OBJECT_ROLE)
|
||||
{
|
||||
return NIL;
|
||||
}
|
||||
|
||||
List * objectAddresses = GetObjectAddressListFromParseTree(node, false, false);
|
||||
if(IsAnyObjectDistributed(objectAddresses))
|
||||
{
|
||||
EnsureAllObjectDependenciesExistOnAllNodes(objectAddresses);
|
||||
}
|
||||
|
||||
return NIL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* SecLabelStmtObjectAddress
|
||||
*/
|
||||
List *
|
||||
SecLabelStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess)
|
||||
{
|
||||
SecLabelStmt *secLabelStmt = castNode(SecLabelStmt, node);
|
||||
|
||||
Relation rel = NULL; /* not used, but required to pass to get_object_address */
|
||||
ObjectAddress address = get_object_address(secLabelStmt->objtype, secLabelStmt->object, &rel,
|
||||
AccessShareLock, missing_ok);
|
||||
|
||||
ObjectAddress *addressPtr = palloc0(sizeof(ObjectAddress));
|
||||
*addressPtr = address;
|
||||
return list_make1(addressPtr);
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* deparse_seclabel_stmts.c
|
||||
* All routines to deparse SECURITY LABEL statements.
|
||||
*
|
||||
* Copyright (c), Citus Data, Inc.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
#include "distributed/deparser.h"
|
||||
#include "nodes/parsenodes.h"
|
||||
|
||||
static void AppendSecLabelStmt(StringInfo buf, SecLabelStmt *stmt);
|
||||
|
||||
/*
|
||||
* DeparseSecLabelStmt builds and returns a string representing of the
|
||||
* SecLabelStmt for application on a remote server.
|
||||
*/
|
||||
char *
|
||||
DeparseSecLabelStmt(Node *node)
|
||||
{
|
||||
SecLabelStmt *secLabelStmt = castNode(SecLabelStmt, node);
|
||||
StringInfoData buf = { 0 };
|
||||
initStringInfo(&buf);
|
||||
|
||||
AppendSecLabelStmt(&buf, secLabelStmt);
|
||||
|
||||
return buf.data;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* AppendSecLabelStmt generates the string representation of the
|
||||
* SecLabelStmt and appends it to the buffer.
|
||||
*/
|
||||
static void
|
||||
AppendSecLabelStmt(StringInfo buf, SecLabelStmt *stmt)
|
||||
{
|
||||
appendStringInfoString(buf, "SECURITY LABEL ");
|
||||
|
||||
if (stmt->provider != NULL)
|
||||
{
|
||||
appendStringInfo(buf, "FOR %s ", stmt->provider);
|
||||
}
|
||||
|
||||
appendStringInfoString(buf, "ON ");
|
||||
|
||||
switch (stmt->objtype)
|
||||
{
|
||||
case OBJECT_ROLE:
|
||||
{
|
||||
appendStringInfo(buf, "ROLE %s ", strVal(castNode(String, stmt->object)));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
ereport(ERROR, (errmsg("unsupported security label statement for"
|
||||
" deparsing")));
|
||||
}
|
||||
}
|
||||
|
||||
appendStringInfoString(buf, "IS ");
|
||||
|
||||
if (stmt->label != NULL)
|
||||
{
|
||||
appendStringInfo(buf, "%s", stmt->label);
|
||||
}
|
||||
else
|
||||
{
|
||||
appendStringInfoString(buf, "NULL");
|
||||
}
|
||||
}
|
|
@ -521,6 +521,12 @@ extern List * AlterSchemaOwnerStmtObjectAddress(Node *node, bool missing_ok,
|
|||
extern List * AlterSchemaRenameStmtObjectAddress(Node *node, bool missing_ok, bool
|
||||
isPostprocess);
|
||||
|
||||
/* seclabel.c - forward declarations*/
|
||||
extern List * PreprocessSecLabelStmt(Node *node, const char *queryString,
|
||||
ProcessUtilityContext processUtilityContext);
|
||||
extern List * PostprocessSecLabelStmt(Node *node, const char *queryString);
|
||||
extern List * SecLabelStmtObjectAddress(Node *node, bool missing_ok, bool isPostprocess);
|
||||
|
||||
/* sequence.c - forward declarations */
|
||||
extern List * PreprocessAlterSequenceStmt(Node *node, const char *queryString,
|
||||
ProcessUtilityContext processUtilityContext);
|
||||
|
|
|
@ -260,6 +260,9 @@ extern void QualifyRenameTextSearchDictionaryStmt(Node *node);
|
|||
extern void QualifyTextSearchConfigurationCommentStmt(Node *node);
|
||||
extern void QualifyTextSearchDictionaryCommentStmt(Node *node);
|
||||
|
||||
/* forward declarations for deparse_seclabel_stmts.c */
|
||||
extern char * DeparseSecLabelStmt(Node *node);
|
||||
|
||||
/* forward declarations for deparse_sequence_stmts.c */
|
||||
extern char * DeparseDropSequenceStmt(Node *node);
|
||||
extern char * DeparseRenameSequenceStmt(Node *node);
|
||||
|
|
Loading…
Reference in New Issue