mirror of https://github.com/citusdata/citus.git
Merge branch 'main' into alter_database_nonmain2
commit
879ab1821a
|
@ -11,8 +11,10 @@
|
|||
* commands from non-main databases.
|
||||
*
|
||||
* To add support for a new command type, one needs to define a new
|
||||
* NonMainDbDistributeObjectOps object and add it to
|
||||
* GetNonMainDbDistributeObjectOps.
|
||||
* NonMainDbDistributeObjectOps object within OperationArray. Also, if
|
||||
* the command requires marking or unmarking some objects as distributed,
|
||||
* the necessary operations can be implemented in
|
||||
* RunPreprocessNonMainDBCommand and RunPostprocessNonMainDBCommand.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
@ -42,161 +44,82 @@
|
|||
"SELECT pg_catalog.citus_unmark_object_distributed(%d, %d, %d, %s)"
|
||||
|
||||
|
||||
/*
|
||||
* Structs used to implement getMarkDistributedParams and
|
||||
* getUnmarkDistributedParams callbacks for NonMainDbDistributeObjectOps.
|
||||
*
|
||||
* Main difference between these two is that while
|
||||
* MarkDistributedGloballyParams contains the name of the object, the other
|
||||
* doesn't. This is because, when marking an object -that is created from a
|
||||
* non-main db- as distributed, citus_internal.mark_object_distributed()
|
||||
* cannot find its name since the object is not visible to outer transaction
|
||||
* (or, read as "the transaction in non-main db").
|
||||
*/
|
||||
typedef struct MarkDistributedGloballyParams
|
||||
{
|
||||
char *name;
|
||||
Oid id;
|
||||
uint16 catalogRelId;
|
||||
} MarkDistributedGloballyParams;
|
||||
|
||||
typedef struct UnmarkDistributedLocallyParams
|
||||
{
|
||||
Oid id;
|
||||
uint16 catalogRelId;
|
||||
} UnmarkDistributedLocallyParams;
|
||||
|
||||
/*
|
||||
* NonMainDbDistributeObjectOps contains the necessary callbacks / flags to
|
||||
* support node-wide object management commands from non-main databases.
|
||||
*
|
||||
* getMarkDistributedParams / getUnmarkDistributedParams:
|
||||
* When creating a distributed object, we always have to mark such objects
|
||||
* as "distributed" but while for some object types we can delegate this to
|
||||
* main database, for some others we have to explicitly send a command to
|
||||
* all nodes in this code-path to achieve this. Callers need to implement
|
||||
* getMarkDistributedParams when that is the case.
|
||||
*
|
||||
* Similarly when dropping a distributed object, we always have to unmark
|
||||
* the target object as "distributed" and our utility hook on remote nodes
|
||||
* achieve this via UnmarkNodeWideObjectsDistributed() because the commands
|
||||
* that we send to workers are executed via main db. However for the local
|
||||
* node, this is not the case as we're not in the main db. For this reason,
|
||||
* callers need to implement getUnmarkDistributedParams to unmark an object
|
||||
* for local node as well.
|
||||
*
|
||||
* We don't expect both of these to be NULL at the same time. However, it's
|
||||
* okay if both of these are NULL.
|
||||
*
|
||||
* Finally, while getMarkDistributedParams is expected to return "a list of
|
||||
* objects", this is not the case for getUnmarkDistributedParams. This is
|
||||
* because, while we expect that a drop command might drop multiple objects
|
||||
* at once, we don't expect a create command to create multiple objects at
|
||||
* once.
|
||||
*
|
||||
* cannotBeExecutedInTransaction:
|
||||
* Indicates whether the statement cannot be executed in a transaction. If
|
||||
* this is set to true, the statement will be executed directly on the main
|
||||
* database because there are no transactional visibility issues for such
|
||||
* commands.
|
||||
*
|
||||
* And when this is true, we don't expect getMarkDistributedParams and
|
||||
* getUnmarkDistributedParams to be implemented.
|
||||
* checkSupportedObjectType:
|
||||
* Callback function that checks whether type of the object referred to by
|
||||
* given statement is supported. Can be NULL if not applicable for the
|
||||
* statement type.
|
||||
*/
|
||||
typedef struct NonMainDbDistributeObjectOps
|
||||
{
|
||||
MarkDistributedGloballyParams * (*getMarkDistributedParams)(Node * parsetree);
|
||||
List * (*getUnmarkDistributedParams)(Node * parsetree);
|
||||
bool cannotBeExecutedInTransaction;
|
||||
bool (*checkSupportedObjectType)(Node *parsetree);
|
||||
} NonMainDbDistributeObjectOps;
|
||||
|
||||
|
||||
/*
|
||||
* getMarkDistributedParams and getUnmarkDistributedParams callbacks for
|
||||
* NonMainDbDistributeObjectOps.
|
||||
* checkSupportedObjectType callbacks for OperationArray.
|
||||
*/
|
||||
static MarkDistributedGloballyParams * CreateRoleStmtGetMarkDistributedParams(
|
||||
Node *parsetree);
|
||||
static List * DropRoleStmtGetUnmarkDistributedParams(Node *parsetree);
|
||||
|
||||
static bool CreateDbStmtCheckSupportedObjectType(Node *node);
|
||||
static bool DropDbStmtCheckSupportedObjectType(Node *node);
|
||||
static bool GrantStmtCheckSupportedObjectType(Node *node);
|
||||
static bool SecLabelStmtCheckSupportedObjectType(Node *node);
|
||||
|
||||
/*
|
||||
* NonMainDbDistributeObjectOps for different command types.
|
||||
*
|
||||
* Naming of these structs are stolen from distribute_object_ops.c. We use
|
||||
* "Any" if the command doesn't have any other variations or if the struct
|
||||
* implements it for all its variations. For example, while we name the struct
|
||||
* for CreateRoleStmt as Any_CreateRole, we name the struct that implements
|
||||
* SecLabelStmt for role objects as Role_SecLabel.
|
||||
* OperationArray that holds NonMainDbDistributeObjectOps for different command types.
|
||||
*/
|
||||
static const NonMainDbDistributeObjectOps Any_CreateRole = {
|
||||
.getMarkDistributedParams = CreateRoleStmtGetMarkDistributedParams,
|
||||
.getUnmarkDistributedParams = NULL,
|
||||
.cannotBeExecutedInTransaction = false
|
||||
};
|
||||
static const NonMainDbDistributeObjectOps Any_DropRole = {
|
||||
.getMarkDistributedParams = NULL,
|
||||
.getUnmarkDistributedParams = DropRoleStmtGetUnmarkDistributedParams,
|
||||
.cannotBeExecutedInTransaction = false
|
||||
};
|
||||
static const NonMainDbDistributeObjectOps Any_AlterRole = {
|
||||
.getMarkDistributedParams = NULL,
|
||||
.getUnmarkDistributedParams = NULL,
|
||||
.cannotBeExecutedInTransaction = false
|
||||
};
|
||||
static const NonMainDbDistributeObjectOps Any_GrantRole = {
|
||||
.getMarkDistributedParams = NULL,
|
||||
.getUnmarkDistributedParams = NULL,
|
||||
.cannotBeExecutedInTransaction = false
|
||||
};
|
||||
static const NonMainDbDistributeObjectOps Any_CreateDatabase = {
|
||||
.getMarkDistributedParams = NULL,
|
||||
.getUnmarkDistributedParams = NULL,
|
||||
.cannotBeExecutedInTransaction = true
|
||||
};
|
||||
static const NonMainDbDistributeObjectOps Any_DropDatabase = {
|
||||
.getMarkDistributedParams = NULL,
|
||||
.getUnmarkDistributedParams = NULL,
|
||||
.cannotBeExecutedInTransaction = true
|
||||
};
|
||||
|
||||
static const NonMainDbDistributeObjectOps Any_AlterDatabase = {
|
||||
.getMarkDistributedParams = NULL,
|
||||
.getUnmarkDistributedParams = NULL,
|
||||
.cannotBeExecutedInTransaction = true
|
||||
};
|
||||
|
||||
static const NonMainDbDistributeObjectOps Any_AlterDatabaseSet = {
|
||||
.getMarkDistributedParams = NULL,
|
||||
.getUnmarkDistributedParams = NULL,
|
||||
.cannotBeExecutedInTransaction = true
|
||||
};
|
||||
|
||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
||||
static const NonMainDbDistributeObjectOps Any_AlterDatabaseRefreshColl = {
|
||||
.getMarkDistributedParams = NULL,
|
||||
.getUnmarkDistributedParams = NULL,
|
||||
.cannotBeExecutedInTransaction = false
|
||||
};
|
||||
#endif
|
||||
|
||||
static const NonMainDbDistributeObjectOps Database_Grant = {
|
||||
.getMarkDistributedParams = NULL,
|
||||
.getUnmarkDistributedParams = NULL,
|
||||
.cannotBeExecutedInTransaction = false
|
||||
};
|
||||
static const NonMainDbDistributeObjectOps Role_SecLabel = {
|
||||
.getMarkDistributedParams = NULL,
|
||||
.getUnmarkDistributedParams = NULL,
|
||||
.cannotBeExecutedInTransaction = false
|
||||
static const NonMainDbDistributeObjectOps *const OperationArray[] = {
|
||||
[T_CreateRoleStmt] = &(NonMainDbDistributeObjectOps) {
|
||||
.cannotBeExecutedInTransaction = false,
|
||||
.checkSupportedObjectType = NULL
|
||||
},
|
||||
[T_DropRoleStmt] = &(NonMainDbDistributeObjectOps) {
|
||||
.cannotBeExecutedInTransaction = false,
|
||||
.checkSupportedObjectType = NULL
|
||||
},
|
||||
[T_AlterRoleStmt] = &(NonMainDbDistributeObjectOps) {
|
||||
.cannotBeExecutedInTransaction = false,
|
||||
.checkSupportedObjectType = NULL
|
||||
},
|
||||
[T_GrantRoleStmt] = &(NonMainDbDistributeObjectOps) {
|
||||
.cannotBeExecutedInTransaction = false,
|
||||
.checkSupportedObjectType = NULL
|
||||
},
|
||||
[T_CreatedbStmt] = &(NonMainDbDistributeObjectOps) {
|
||||
.cannotBeExecutedInTransaction = true,
|
||||
.checkSupportedObjectType = CreateDbStmtCheckSupportedObjectType
|
||||
},
|
||||
[T_DropdbStmt] = &(NonMainDbDistributeObjectOps) {
|
||||
.cannotBeExecutedInTransaction = true,
|
||||
.checkSupportedObjectType = DropDbStmtCheckSupportedObjectType
|
||||
},
|
||||
[T_GrantStmt] = &(NonMainDbDistributeObjectOps) {
|
||||
.cannotBeExecutedInTransaction = false,
|
||||
.checkSupportedObjectType = GrantStmtCheckSupportedObjectType
|
||||
},
|
||||
[T_SecLabelStmt] = &(NonMainDbDistributeObjectOps) {
|
||||
.cannotBeExecutedInTransaction = false,
|
||||
.checkSupportedObjectType = SecLabelStmtCheckSupportedObjectType
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
/* other static function declarations */
|
||||
const NonMainDbDistributeObjectOps * GetNonMainDbDistributeObjectOps(Node *parsetree);
|
||||
static void MarkObjectDistributedGloballyOnMainDbs(
|
||||
MarkDistributedGloballyParams *markDistributedParams);
|
||||
static void UnmarkObjectsDistributedOnLocalMainDb(List *unmarkDistributedParamsList);
|
||||
static void CreateRoleStmtMarkDistGloballyOnMainDbs(CreateRoleStmt *createRoleStmt);
|
||||
static void DropRoleStmtUnmarkDistOnLocalMainDb(DropRoleStmt *dropRoleStmt);
|
||||
static void MarkObjectDistributedGloballyOnMainDbs(Oid catalogRelId, Oid objectId,
|
||||
char *objectName);
|
||||
static void UnmarkObjectDistributedOnLocalMainDb(uint16 catalogRelId, Oid objectId);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -249,10 +172,9 @@ RunPreprocessNonMainDBCommand(Node *parsetree)
|
|||
quote_literal_cstr(CurrentUserName()));
|
||||
RunCitusMainDBQuery(mainDBQuery->data);
|
||||
|
||||
if (ops->getUnmarkDistributedParams)
|
||||
if (IsA(parsetree, DropRoleStmt))
|
||||
{
|
||||
List *unmarkDistributedParamsList = ops->getUnmarkDistributedParams(parsetree);
|
||||
UnmarkObjectsDistributedOnLocalMainDb(unmarkDistributedParamsList);
|
||||
DropRoleStmtUnmarkDistOnLocalMainDb((DropRoleStmt *) parsetree);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -266,22 +188,14 @@ RunPreprocessNonMainDBCommand(Node *parsetree)
|
|||
void
|
||||
RunPostprocessNonMainDBCommand(Node *parsetree)
|
||||
{
|
||||
if (IsMainDB)
|
||||
if (IsMainDB || !GetNonMainDbDistributeObjectOps(parsetree))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const NonMainDbDistributeObjectOps *ops = GetNonMainDbDistributeObjectOps(parsetree);
|
||||
if (!ops)
|
||||
if (IsA(parsetree, CreateRoleStmt))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ops->getMarkDistributedParams)
|
||||
{
|
||||
MarkDistributedGloballyParams *markDistributedParams =
|
||||
ops->getMarkDistributedParams(parsetree);
|
||||
MarkObjectDistributedGloballyOnMainDbs(markDistributedParams);
|
||||
CreateRoleStmtMarkDistGloballyOnMainDbs((CreateRoleStmt *) parsetree);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -294,137 +208,63 @@ RunPostprocessNonMainDBCommand(Node *parsetree)
|
|||
const NonMainDbDistributeObjectOps *
|
||||
GetNonMainDbDistributeObjectOps(Node *parsetree)
|
||||
{
|
||||
switch (nodeTag(parsetree))
|
||||
NodeTag tag = nodeTag(parsetree);
|
||||
if (tag >= lengthof(OperationArray))
|
||||
{
|
||||
case T_CreateRoleStmt:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const NonMainDbDistributeObjectOps *ops = OperationArray[tag];
|
||||
|
||||
if (ops == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!ops->checkSupportedObjectType ||
|
||||
ops->checkSupportedObjectType(parsetree))
|
||||
{
|
||||
return ops;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* CreateRoleStmtMarkDistGloballyOnMainDbs marks the role as
|
||||
* distributed on all main databases globally.
|
||||
*/
|
||||
static void
|
||||
CreateRoleStmtMarkDistGloballyOnMainDbs(CreateRoleStmt *createRoleStmt)
|
||||
{
|
||||
/* object must exist as we've just created it */
|
||||
bool missingOk = false;
|
||||
Oid roleId = get_role_oid(createRoleStmt->role, missingOk);
|
||||
|
||||
MarkObjectDistributedGloballyOnMainDbs(AuthIdRelationId, roleId,
|
||||
createRoleStmt->role);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* DropRoleStmtUnmarkDistOnLocalMainDb unmarks the roles as
|
||||
* distributed on the local main database.
|
||||
*/
|
||||
static void
|
||||
DropRoleStmtUnmarkDistOnLocalMainDb(DropRoleStmt *dropRoleStmt)
|
||||
{
|
||||
RoleSpec *roleSpec = NULL;
|
||||
foreach_ptr(roleSpec, dropRoleStmt->roles)
|
||||
{
|
||||
Oid roleOid = get_role_oid(roleSpec->rolename,
|
||||
dropRoleStmt->missing_ok);
|
||||
if (roleOid == InvalidOid)
|
||||
{
|
||||
return &Any_CreateRole;
|
||||
continue;
|
||||
}
|
||||
|
||||
case T_DropRoleStmt:
|
||||
{
|
||||
return &Any_DropRole;
|
||||
}
|
||||
|
||||
case T_AlterRoleStmt:
|
||||
{
|
||||
return &Any_AlterRole;
|
||||
}
|
||||
|
||||
case T_GrantRoleStmt:
|
||||
{
|
||||
return &Any_GrantRole;
|
||||
}
|
||||
|
||||
case T_CreatedbStmt:
|
||||
{
|
||||
CreatedbStmt *stmt = castNode(CreatedbStmt, parsetree);
|
||||
|
||||
/*
|
||||
* We don't try to send the query to the main database if the CREATE
|
||||
* DATABASE command is for the main database itself, this is a very
|
||||
* rare case but it's exercised by our test suite.
|
||||
*/
|
||||
if (strcmp(stmt->dbname, MainDb) != 0)
|
||||
{
|
||||
return &Any_CreateDatabase;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
case T_DropdbStmt:
|
||||
{
|
||||
DropdbStmt *stmt = castNode(DropdbStmt, parsetree);
|
||||
|
||||
/*
|
||||
* We don't try to send the query to the main database if the DROP
|
||||
* DATABASE command is for the main database itself, this is a very
|
||||
* rare case but it's exercised by our test suite.
|
||||
*/
|
||||
if (strcmp(stmt->dbname, MainDb) != 0)
|
||||
{
|
||||
return &Any_DropDatabase;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
case T_AlterDatabaseStmt:
|
||||
{
|
||||
AlterDatabaseStmt *stmt = castNode(AlterDatabaseStmt, parsetree);
|
||||
|
||||
/*
|
||||
* We don't try to send the query to the main database if the ALTER
|
||||
* DATABASE command is for the main database itself, this is a very
|
||||
* rare case but it's exercised by our test suite.
|
||||
*/
|
||||
if (strcmp(stmt->dbname, MainDb) != 0)
|
||||
{
|
||||
return &Any_AlterDatabase;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
case T_AlterDatabaseSetStmt:
|
||||
{
|
||||
AlterDatabaseSetStmt *stmt = castNode(AlterDatabaseSetStmt, parsetree);
|
||||
|
||||
/*
|
||||
* We don't try to send the query to the main database if the ALTER
|
||||
* DATABASE command is for the main database itself, this is a very
|
||||
* rare case but it's exercised by our test suite.
|
||||
*/
|
||||
if (strcmp(stmt->dbname, MainDb) != 0)
|
||||
{
|
||||
return &Any_AlterDatabaseSet;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if PG_VERSION_NUM >= PG_VERSION_15
|
||||
case T_AlterDatabaseRefreshCollStmt:
|
||||
{
|
||||
return &Any_AlterDatabaseRefreshColl;
|
||||
}
|
||||
#endif
|
||||
|
||||
case T_GrantStmt:
|
||||
{
|
||||
GrantStmt *stmt = castNode(GrantStmt, parsetree);
|
||||
|
||||
switch (stmt->objtype)
|
||||
{
|
||||
case OBJECT_DATABASE:
|
||||
{
|
||||
return &Database_Grant;
|
||||
}
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
case T_SecLabelStmt:
|
||||
{
|
||||
SecLabelStmt *stmt = castNode(SecLabelStmt, parsetree);
|
||||
|
||||
switch (stmt->objtype)
|
||||
{
|
||||
case OBJECT_ROLE:
|
||||
{
|
||||
return &Role_SecLabel;
|
||||
}
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
UnmarkObjectDistributedOnLocalMainDb(AuthIdRelationId, roleOid);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -434,90 +274,78 @@ GetNonMainDbDistributeObjectOps(Node *parsetree)
|
|||
* distributed on all main databases globally.
|
||||
*/
|
||||
static void
|
||||
MarkObjectDistributedGloballyOnMainDbs(
|
||||
MarkDistributedGloballyParams *markDistributedParams)
|
||||
MarkObjectDistributedGloballyOnMainDbs(Oid catalogRelId, Oid objectId, char *objectName)
|
||||
{
|
||||
StringInfo mainDBQuery = makeStringInfo();
|
||||
appendStringInfo(mainDBQuery,
|
||||
MARK_OBJECT_DISTRIBUTED,
|
||||
markDistributedParams->catalogRelId,
|
||||
quote_literal_cstr(markDistributedParams->name),
|
||||
markDistributedParams->id,
|
||||
catalogRelId,
|
||||
quote_literal_cstr(objectName),
|
||||
objectId,
|
||||
quote_literal_cstr(CurrentUserName()));
|
||||
RunCitusMainDBQuery(mainDBQuery->data);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* UnmarkObjectsDistributedOnLocalMainDb unmarks a list of objects as
|
||||
* UnmarkObjectDistributedOnLocalMainDb unmarks an object as
|
||||
* distributed on the local main database.
|
||||
*/
|
||||
static void
|
||||
UnmarkObjectsDistributedOnLocalMainDb(List *unmarkDistributedParamsList)
|
||||
UnmarkObjectDistributedOnLocalMainDb(uint16 catalogRelId, Oid objectId)
|
||||
{
|
||||
int subObjectId = 0;
|
||||
char *checkObjectExistence = "false";
|
||||
const int subObjectId = 0;
|
||||
const char *checkObjectExistence = "false";
|
||||
|
||||
UnmarkDistributedLocallyParams *unmarkDistributedParams = NULL;
|
||||
foreach_ptr(unmarkDistributedParams, unmarkDistributedParamsList)
|
||||
{
|
||||
StringInfo query = makeStringInfo();
|
||||
appendStringInfo(query,
|
||||
UNMARK_OBJECT_DISTRIBUTED,
|
||||
unmarkDistributedParams->catalogRelId,
|
||||
unmarkDistributedParams->id,
|
||||
subObjectId, checkObjectExistence);
|
||||
RunCitusMainDBQuery(query->data);
|
||||
}
|
||||
StringInfo query = makeStringInfo();
|
||||
appendStringInfo(query,
|
||||
UNMARK_OBJECT_DISTRIBUTED,
|
||||
catalogRelId, objectId,
|
||||
subObjectId, checkObjectExistence);
|
||||
RunCitusMainDBQuery(query->data);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* getMarkDistributedParams and getUnmarkDistributedParams callback implementations
|
||||
* for NonMainDbDistributeObjectOps start here.
|
||||
* checkSupportedObjectTypes callbacks for OperationArray lie below.
|
||||
*/
|
||||
static MarkDistributedGloballyParams *
|
||||
CreateRoleStmtGetMarkDistributedParams(Node *parsetree)
|
||||
static bool
|
||||
CreateDbStmtCheckSupportedObjectType(Node *node)
|
||||
{
|
||||
CreateRoleStmt *stmt = castNode(CreateRoleStmt, parsetree);
|
||||
MarkDistributedGloballyParams *params =
|
||||
(MarkDistributedGloballyParams *) palloc(sizeof(MarkDistributedGloballyParams));
|
||||
params->name = stmt->role;
|
||||
params->catalogRelId = AuthIdRelationId;
|
||||
|
||||
/* object must exist as we've just created it */
|
||||
bool missingOk = false;
|
||||
params->id = get_role_oid(stmt->role, missingOk);
|
||||
|
||||
return params;
|
||||
/*
|
||||
* We don't try to send the query to the main database if the CREATE
|
||||
* DATABASE command is for the main database itself, this is a very
|
||||
* rare case but it's exercised by our test suite.
|
||||
*/
|
||||
CreatedbStmt *stmt = castNode(CreatedbStmt, node);
|
||||
return strcmp(stmt->dbname, MainDb) != 0;
|
||||
}
|
||||
|
||||
|
||||
static List *
|
||||
DropRoleStmtGetUnmarkDistributedParams(Node *parsetree)
|
||||
static bool
|
||||
DropDbStmtCheckSupportedObjectType(Node *node)
|
||||
{
|
||||
DropRoleStmt *stmt = castNode(DropRoleStmt, parsetree);
|
||||
|
||||
List *paramsList = NIL;
|
||||
|
||||
RoleSpec *roleSpec = NULL;
|
||||
foreach_ptr(roleSpec, stmt->roles)
|
||||
{
|
||||
UnmarkDistributedLocallyParams *params =
|
||||
(UnmarkDistributedLocallyParams *) palloc(
|
||||
sizeof(UnmarkDistributedLocallyParams));
|
||||
|
||||
Oid roleOid = get_role_oid(roleSpec->rolename, stmt->missing_ok);
|
||||
if (roleOid == InvalidOid)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
params->id = roleOid;
|
||||
params->catalogRelId = AuthIdRelationId;
|
||||
|
||||
paramsList = lappend(paramsList, params);
|
||||
}
|
||||
|
||||
return paramsList;
|
||||
/*
|
||||
* We don't try to send the query to the main database if the DROP
|
||||
* DATABASE command is for the main database itself, this is a very
|
||||
* rare case but it's exercised by our test suite.
|
||||
*/
|
||||
DropdbStmt *stmt = castNode(DropdbStmt, node);
|
||||
return strcmp(stmt->dbname, MainDb) != 0;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
GrantStmtCheckSupportedObjectType(Node *node)
|
||||
{
|
||||
GrantStmt *stmt = castNode(GrantStmt, node);
|
||||
return stmt->objtype == OBJECT_DATABASE;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
SecLabelStmtCheckSupportedObjectType(Node *node)
|
||||
{
|
||||
SecLabelStmt *stmt = castNode(SecLabelStmt, node);
|
||||
return stmt->objtype == OBJECT_ROLE;
|
||||
}
|
||||
|
|
|
@ -491,18 +491,17 @@ GenerateRoleOptionsList(HeapTuple tuple)
|
|||
options = lappend(options, makeDefElem("password", NULL, -1));
|
||||
}
|
||||
|
||||
/* load valid unitl data from the heap tuple, use default of infinity if not set */
|
||||
/* load valid until data from the heap tuple */
|
||||
Datum rolValidUntilDatum = SysCacheGetAttr(AUTHNAME, tuple,
|
||||
Anum_pg_authid_rolvaliduntil, &isNull);
|
||||
char *rolValidUntil = "infinity";
|
||||
if (!isNull)
|
||||
{
|
||||
rolValidUntil = pstrdup((char *) timestamptz_to_str(rolValidUntilDatum));
|
||||
}
|
||||
char *rolValidUntil = pstrdup((char *) timestamptz_to_str(rolValidUntilDatum));
|
||||
|
||||
Node *validUntilStringNode = (Node *) makeString(rolValidUntil);
|
||||
DefElem *validUntilOption = makeDefElem("validUntil", validUntilStringNode, -1);
|
||||
options = lappend(options, validUntilOption);
|
||||
Node *validUntilStringNode = (Node *) makeString(rolValidUntil);
|
||||
DefElem *validUntilOption = makeDefElem("validUntil", validUntilStringNode, -1);
|
||||
options = lappend(options, validUntilOption);
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
|
|
@ -3053,11 +3053,15 @@ ErrorUnsupportedAlterTableAddColumn(Oid relationId, AlterTableCmd *command,
|
|||
else if (constraint->contype == CONSTR_FOREIGN)
|
||||
{
|
||||
RangeVar *referencedTable = constraint->pktable;
|
||||
char *referencedColumn = strVal(lfirst(list_head(constraint->pk_attrs)));
|
||||
Oid referencedRelationId = RangeVarGetRelid(referencedTable, NoLock, false);
|
||||
|
||||
appendStringInfo(errHint, "FOREIGN KEY (%s) REFERENCES %s(%s)", colName,
|
||||
get_rel_name(referencedRelationId), referencedColumn);
|
||||
appendStringInfo(errHint, "FOREIGN KEY (%s) REFERENCES %s", colName,
|
||||
get_rel_name(referencedRelationId));
|
||||
|
||||
if (list_length(constraint->pk_attrs) > 0)
|
||||
{
|
||||
AppendColumnNameList(errHint, constraint->pk_attrs);
|
||||
}
|
||||
|
||||
if (constraint->fk_del_action == FKCONSTR_ACTION_SETNULL)
|
||||
{
|
||||
|
|
|
@ -121,7 +121,7 @@ AppendAlterTableStmt(StringInfo buf, AlterTableStmt *stmt)
|
|||
* AppendColumnNameList converts a list of columns into comma separated string format
|
||||
* (colname_1, colname_2, .., colname_n).
|
||||
*/
|
||||
static void
|
||||
void
|
||||
AppendColumnNameList(StringInfo buf, List *columns)
|
||||
{
|
||||
appendStringInfoString(buf, " (");
|
||||
|
|
|
@ -492,19 +492,7 @@ stop_metadata_sync_to_node(PG_FUNCTION_ARGS)
|
|||
bool
|
||||
ClusterHasKnownMetadataWorkers()
|
||||
{
|
||||
bool workerWithMetadata = false;
|
||||
|
||||
if (!IsCoordinator())
|
||||
{
|
||||
workerWithMetadata = true;
|
||||
}
|
||||
|
||||
if (workerWithMetadata || HasMetadataWorkers())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return !IsCoordinator() || HasMetadataWorkers();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "utils/fmgroids.h"
|
||||
#include "utils/memutils.h"
|
||||
#include "utils/rel.h"
|
||||
#include "utils/syscache.h"
|
||||
#include "utils/xid8.h"
|
||||
|
||||
#include "pg_version_constants.h"
|
||||
|
@ -261,11 +262,28 @@ RecoverWorkerTransactions(WorkerNode *workerNode)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* Check if the transaction is created by an outer transaction from a non-main database */
|
||||
bool outerXidIsNull = false;
|
||||
Datum outerXidDatum = heap_getattr(heapTuple,
|
||||
Anum_pg_dist_transaction_outerxid,
|
||||
tupleDescriptor, &outerXidIsNull);
|
||||
Datum outerXidDatum = 0;
|
||||
if (EnableVersionChecks ||
|
||||
SearchSysCacheExistsAttName(DistTransactionRelationId(), "outer_xid"))
|
||||
{
|
||||
/* Check if the transaction is created by an outer transaction from a non-main database */
|
||||
outerXidDatum = heap_getattr(heapTuple,
|
||||
Anum_pg_dist_transaction_outerxid,
|
||||
tupleDescriptor, &outerXidIsNull);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Normally we don't try to recover prepared transactions when the
|
||||
* binary version doesn't match the sql version. However, we skip
|
||||
* those checks in regression tests by disabling
|
||||
* citus.enable_version_checks. And when this is the case, while
|
||||
* the C code looks for "outer_xid" attribute, pg_dist_transaction
|
||||
* doesn't yet have it.
|
||||
*/
|
||||
Assert(!EnableVersionChecks);
|
||||
}
|
||||
|
||||
TransactionId outerXid = 0;
|
||||
if (!outerXidIsNull)
|
||||
|
|
|
@ -121,6 +121,8 @@ extern void AppendGrantedByInGrant(StringInfo buf, GrantStmt *stmt);
|
|||
extern void AppendGrantSharedPrefix(StringInfo buf, GrantStmt *stmt);
|
||||
extern void AppendGrantSharedSuffix(StringInfo buf, GrantStmt *stmt);
|
||||
|
||||
extern void AppendColumnNameList(StringInfo buf, List *columns);
|
||||
|
||||
/* Common deparser utils */
|
||||
|
||||
typedef struct DefElemOptionFormat
|
||||
|
|
|
@ -44,6 +44,15 @@ ERROR: cannot execute ADD COLUMN command with PRIMARY KEY, UNIQUE, FOREIGN and
|
|||
DETAIL: Adding a column with a constraint in one command is not supported because all constraints in Citus must have explicit names
|
||||
HINT: You can issue each command separately such as ALTER TABLE referencing ADD COLUMN test_8 data_type; ALTER TABLE referencing ADD CONSTRAINT constraint_name CHECK (check_expression);
|
||||
ALTER TABLE referencing ADD COLUMN test_8 integer CONSTRAINT check_test_8 CHECK (test_8 > 0);
|
||||
-- error out properly even if the REFERENCES does not include the column list of the referenced table
|
||||
ALTER TABLE referencing ADD COLUMN test_9 bool, ADD COLUMN test_10 int REFERENCES referenced;
|
||||
ERROR: cannot execute ADD COLUMN command with PRIMARY KEY, UNIQUE, FOREIGN and CHECK constraints
|
||||
DETAIL: Adding a column with a constraint in one command is not supported because all constraints in Citus must have explicit names
|
||||
HINT: You can issue each command separately such as ALTER TABLE referencing ADD COLUMN test_10 data_type; ALTER TABLE referencing ADD CONSTRAINT constraint_name FOREIGN KEY (test_10) REFERENCES referenced;
|
||||
ALTER TABLE referencing ADD COLUMN test_9 bool, ADD COLUMN test_10 int REFERENCES referenced(int_col);
|
||||
ERROR: cannot execute ADD COLUMN command with PRIMARY KEY, UNIQUE, FOREIGN and CHECK constraints
|
||||
DETAIL: Adding a column with a constraint in one command is not supported because all constraints in Citus must have explicit names
|
||||
HINT: You can issue each command separately such as ALTER TABLE referencing ADD COLUMN test_10 data_type; ALTER TABLE referencing ADD CONSTRAINT constraint_name FOREIGN KEY (test_10) REFERENCES referenced (int_col );
|
||||
-- try to add test_6 again, but with IF NOT EXISTS
|
||||
ALTER TABLE referencing ADD COLUMN IF NOT EXISTS test_6 text;
|
||||
NOTICE: column "test_6" of relation "referencing" already exists, skipping
|
||||
|
|
|
@ -121,17 +121,17 @@ SELECT 1 FROM master_add_node('localhost', :worker_2_port);
|
|||
SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, (rolpassword != '') as pass_not_empty, rolvaliduntil FROM pg_authid WHERE rolname LIKE 'create\_%' ORDER BY rolname;
|
||||
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | pass_not_empty | rolvaliduntil
|
||||
---------------------------------------------------------------------
|
||||
create_group | f | t | f | f | f | f | f | -1 | | infinity
|
||||
create_group_2 | f | t | f | f | f | f | f | -1 | | infinity
|
||||
create_role | f | t | f | f | f | f | f | -1 | | infinity
|
||||
create_role"edge | f | t | f | f | f | f | f | -1 | | infinity
|
||||
create_role'edge | f | t | f | f | f | f | f | -1 | | infinity
|
||||
create_role_2 | f | t | f | f | f | f | f | -1 | | infinity
|
||||
create_role_sysid | f | t | f | f | f | f | f | -1 | | infinity
|
||||
create_group | f | t | f | f | f | f | f | -1 | |
|
||||
create_group_2 | f | t | f | f | f | f | f | -1 | |
|
||||
create_role | f | t | f | f | f | f | f | -1 | |
|
||||
create_role"edge | f | t | f | f | f | f | f | -1 | |
|
||||
create_role'edge | f | t | f | f | f | f | f | -1 | |
|
||||
create_role_2 | f | t | f | f | f | f | f | -1 | |
|
||||
create_role_sysid | f | t | f | f | f | f | f | -1 | |
|
||||
create_role_with_everything | t | t | t | t | t | t | t | 105 | t | Thu May 04 17:00:00 2045 PDT
|
||||
create_role_with_nothing | f | f | f | f | f | f | f | 3 | t | Mon May 04 17:00:00 2015 PDT
|
||||
create_user | f | t | f | f | t | f | f | -1 | | infinity
|
||||
create_user_2 | f | t | f | f | t | f | f | -1 | | infinity
|
||||
create_user | f | t | f | f | t | f | f | -1 | |
|
||||
create_user_2 | f | t | f | f | t | f | f | -1 | |
|
||||
(11 rows)
|
||||
|
||||
SELECT roleid::regrole::text AS role, member::regrole::text, grantor::regrole::text, admin_option FROM pg_auth_members WHERE roleid::regrole::text LIKE 'create\_%' ORDER BY 1, 2;
|
||||
|
|
|
@ -188,7 +188,6 @@ select 1 from citus_add_node('localhost', :worker_2_port);
|
|||
1
|
||||
(1 row)
|
||||
|
||||
-- XXX: date is not correct on one of the workers due to https://github.com/citusdata/citus/issues/7533
|
||||
select result FROM run_command_on_all_nodes($$
|
||||
SELECT array_to_json(array_agg(row_to_json(t)))
|
||||
FROM (
|
||||
|
@ -200,11 +199,11 @@ select result FROM run_command_on_all_nodes($$
|
|||
ORDER BY rolname
|
||||
) t
|
||||
$$);
|
||||
result
|
||||
result
|
||||
---------------------------------------------------------------------
|
||||
[{"rolname":"test_role1","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":true,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":true,"date":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,"date":"2023-01-01"},{"rolname":"test_role3","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":false,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":null,"date":null}]
|
||||
[{"rolname":"test_role1","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":true,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":true,"date":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,"date":"2023-01-01"},{"rolname":"test_role3","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":false,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":null,"date":null}]
|
||||
[{"rolname":"test_role1","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":true,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":true,"date":"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,"date":"2023-01-01"},{"rolname":"test_role3","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":false,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":null,"date":"infinity"}]
|
||||
[{"rolname":"test_role1","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":true,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":true,"date":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,"date":"2023-01-01"},{"rolname":"test_role3","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":false,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":null,"date":null}]
|
||||
(3 rows)
|
||||
|
||||
--test for alter user
|
||||
|
@ -229,7 +228,6 @@ select 1 from citus_add_node('localhost', :worker_2_port);
|
|||
1
|
||||
(1 row)
|
||||
|
||||
-- XXX: date is not correct on one of the workers due to https://github.com/citusdata/citus/issues/7533
|
||||
select result FROM run_command_on_all_nodes($$
|
||||
SELECT array_to_json(array_agg(row_to_json(t)))
|
||||
FROM (
|
||||
|
@ -241,11 +239,11 @@ select result FROM run_command_on_all_nodes($$
|
|||
ORDER BY rolname
|
||||
) t
|
||||
$$);
|
||||
result
|
||||
result
|
||||
---------------------------------------------------------------------
|
||||
[{"rolname":"test_role1","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":true,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":true,"date":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,"date":"2024-01-01"},{"rolname":"test_role3","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":false,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":null,"date":null}]
|
||||
[{"rolname":"test_role1","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":true,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":true,"date":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,"date":"2024-01-01"},{"rolname":"test_role3","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":false,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":null,"date":null}]
|
||||
[{"rolname":"test_role1","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":true,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":true,"date":"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,"date":"2024-01-01"},{"rolname":"test_role3","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":false,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":null,"date":"infinity"}]
|
||||
[{"rolname":"test_role1","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":true,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":true,"date":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,"date":"2024-01-01"},{"rolname":"test_role3","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":false,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":null,"date":null}]
|
||||
(3 rows)
|
||||
|
||||
--test for drop user
|
||||
|
@ -266,7 +264,6 @@ select 1 from citus_add_node('localhost', :worker_2_port);
|
|||
1
|
||||
(1 row)
|
||||
|
||||
-- XXX: date is not correct on one of the workers due to https://github.com/citusdata/citus/issues/7533
|
||||
select result FROM run_command_on_all_nodes($$
|
||||
SELECT array_to_json(array_agg(row_to_json(t)))
|
||||
FROM (
|
||||
|
@ -278,11 +275,11 @@ select result FROM run_command_on_all_nodes($$
|
|||
ORDER BY rolname
|
||||
) t
|
||||
$$);
|
||||
result
|
||||
result
|
||||
---------------------------------------------------------------------
|
||||
|
||||
|
||||
[{"rolname":"test_role1","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":true,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":true,"date":"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,"date":"2024-01-01"},{"rolname":"test_role3","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":false,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":null,"date":"infinity"}]
|
||||
[{"rolname":"test_role1","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":true,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":true,"date":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,"date":"2024-01-01"},{"rolname":"test_role3","rolsuper":false,"rolinherit":true,"rolcreaterole":false,"rolcreatedb":false,"rolcanlogin":false,"rolreplication":false,"rolbypassrls":false,"rolconnlimit":-1,"pass_not_empty":null,"date":null}]
|
||||
(3 rows)
|
||||
|
||||
-- Clean up: drop the database on worker node 2
|
||||
|
|
|
@ -167,9 +167,9 @@ SELECT node_type, result FROM get_citus_tests_label_provider_labels('"user 2"')
|
|||
SET citus.log_remote_commands TO on;
|
||||
SET citus.grep_remote_commands = '%SECURITY LABEL%';
|
||||
SELECT 1 FROM citus_add_node('localhost', :worker_2_port);
|
||||
NOTICE: issuing SELECT worker_create_or_alter_role('user1', 'CREATE ROLE user1 NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT NOLOGIN NOREPLICATION NOBYPASSRLS CONNECTION LIMIT -1 PASSWORD NULL VALID UNTIL ''infinity''', 'ALTER ROLE user1 NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT NOLOGIN NOREPLICATION NOBYPASSRLS CONNECTION LIMIT -1 PASSWORD NULL VALID UNTIL ''infinity''');SECURITY LABEL FOR "citus '!tests_label_provider" ON ROLE user1 IS 'citus_classified'
|
||||
NOTICE: issuing SELECT worker_create_or_alter_role('user1', 'CREATE ROLE user1 NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT NOLOGIN NOREPLICATION NOBYPASSRLS CONNECTION LIMIT -1 PASSWORD NULL', 'ALTER ROLE user1 NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT NOLOGIN NOREPLICATION NOBYPASSRLS CONNECTION LIMIT -1 PASSWORD NULL');SECURITY LABEL FOR "citus '!tests_label_provider" ON ROLE user1 IS 'citus_classified'
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
NOTICE: issuing SELECT worker_create_or_alter_role('user 2', 'CREATE ROLE "user 2" NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT NOLOGIN NOREPLICATION NOBYPASSRLS CONNECTION LIMIT -1 PASSWORD NULL VALID UNTIL ''infinity''', 'ALTER ROLE "user 2" NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT NOLOGIN NOREPLICATION NOBYPASSRLS CONNECTION LIMIT -1 PASSWORD NULL VALID UNTIL ''infinity''');SECURITY LABEL FOR "citus '!tests_label_provider" ON ROLE "user 2" IS 'citus ''!unclassified'
|
||||
NOTICE: issuing SELECT worker_create_or_alter_role('user 2', 'CREATE ROLE "user 2" NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT NOLOGIN NOREPLICATION NOBYPASSRLS CONNECTION LIMIT -1 PASSWORD NULL', 'ALTER ROLE "user 2" NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT NOLOGIN NOREPLICATION NOBYPASSRLS CONNECTION LIMIT -1 PASSWORD NULL');SECURITY LABEL FOR "citus '!tests_label_provider" ON ROLE "user 2" IS 'citus ''!unclassified'
|
||||
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
||||
?column?
|
||||
---------------------------------------------------------------------
|
||||
|
|
|
@ -67,6 +67,20 @@ SELECT 1 FROM run_command_on_workers($$SELECT pg_reload_conf()$$);
|
|||
1
|
||||
(2 rows)
|
||||
|
||||
-- In the version that we use for upgrade tests (v10.2.0), we propagate
|
||||
-- "valid until" to the workers as "infinity" even if it's not set. And
|
||||
-- given that "postgres" role is created in the older version, "valid until"
|
||||
-- is set to "infinity" on the workers while this is not the case for
|
||||
-- coordinator. See https://github.com/citusdata/citus/issues/7533.
|
||||
--
|
||||
-- We're fixing this for new versions of Citus and we'll probably backport
|
||||
-- this to some older versions too. However, v10.2.0 won't ever have this
|
||||
-- fix.
|
||||
--
|
||||
-- For this reason, here we set "valid until" to "infinity" for all the
|
||||
-- nodes so that below query doesn't report any difference between the
|
||||
-- metadata on coordinator and workers.
|
||||
ALTER ROLE postgres WITH VALID UNTIL 'infinity';
|
||||
-- make sure that the metadata is consistent across all nodes
|
||||
-- we exclude the distributed_object_data as they are
|
||||
-- not sorted in the same order (as OIDs differ on the nodes)
|
||||
|
|
|
@ -41,6 +41,10 @@ ALTER TABLE referencing ADD COLUMN "test_\'!7" "simple_!\'custom_type";
|
|||
ALTER TABLE referencing ADD COLUMN test_8 integer CHECK (test_8 > 0);
|
||||
ALTER TABLE referencing ADD COLUMN test_8 integer CONSTRAINT check_test_8 CHECK (test_8 > 0);
|
||||
|
||||
-- error out properly even if the REFERENCES does not include the column list of the referenced table
|
||||
ALTER TABLE referencing ADD COLUMN test_9 bool, ADD COLUMN test_10 int REFERENCES referenced;
|
||||
ALTER TABLE referencing ADD COLUMN test_9 bool, ADD COLUMN test_10 int REFERENCES referenced(int_col);
|
||||
|
||||
-- try to add test_6 again, but with IF NOT EXISTS
|
||||
ALTER TABLE referencing ADD COLUMN IF NOT EXISTS test_6 text;
|
||||
ALTER TABLE referencing ADD COLUMN IF NOT EXISTS test_6 integer;
|
||||
|
|
|
@ -100,7 +100,6 @@ create role test_role3;
|
|||
\c regression - - :master_port
|
||||
select 1 from citus_add_node('localhost', :worker_2_port);
|
||||
|
||||
-- XXX: date is not correct on one of the workers due to https://github.com/citusdata/citus/issues/7533
|
||||
select result FROM run_command_on_all_nodes($$
|
||||
SELECT array_to_json(array_agg(row_to_json(t)))
|
||||
FROM (
|
||||
|
@ -128,7 +127,6 @@ LIMIT 5 VALID UNTIL '2024-01-01';
|
|||
\c regression - - :master_port
|
||||
select 1 from citus_add_node('localhost', :worker_2_port);
|
||||
|
||||
-- XXX: date is not correct on one of the workers due to https://github.com/citusdata/citus/issues/7533
|
||||
select result FROM run_command_on_all_nodes($$
|
||||
SELECT array_to_json(array_agg(row_to_json(t)))
|
||||
FROM (
|
||||
|
@ -153,7 +151,6 @@ DROP ROLE test_role3;
|
|||
\c regression - - :master_port
|
||||
select 1 from citus_add_node('localhost', :worker_2_port);
|
||||
|
||||
-- XXX: date is not correct on one of the workers due to https://github.com/citusdata/citus/issues/7533
|
||||
select result FROM run_command_on_all_nodes($$
|
||||
SELECT array_to_json(array_agg(row_to_json(t)))
|
||||
FROM (
|
||||
|
|
|
@ -27,6 +27,21 @@ SET datestyle = "ISO, YMD";
|
|||
SELECT 1 FROM run_command_on_workers($$ALTER SYSTEM SET datestyle = "ISO, YMD";$$);
|
||||
SELECT 1 FROM run_command_on_workers($$SELECT pg_reload_conf()$$);
|
||||
|
||||
-- In the version that we use for upgrade tests (v10.2.0), we propagate
|
||||
-- "valid until" to the workers as "infinity" even if it's not set. And
|
||||
-- given that "postgres" role is created in the older version, "valid until"
|
||||
-- is set to "infinity" on the workers while this is not the case for
|
||||
-- coordinator. See https://github.com/citusdata/citus/issues/7533.
|
||||
--
|
||||
-- We're fixing this for new versions of Citus and we'll probably backport
|
||||
-- this to some older versions too. However, v10.2.0 won't ever have this
|
||||
-- fix.
|
||||
--
|
||||
-- For this reason, here we set "valid until" to "infinity" for all the
|
||||
-- nodes so that below query doesn't report any difference between the
|
||||
-- metadata on coordinator and workers.
|
||||
ALTER ROLE postgres WITH VALID UNTIL 'infinity';
|
||||
|
||||
-- make sure that the metadata is consistent across all nodes
|
||||
-- we exclude the distributed_object_data as they are
|
||||
-- not sorted in the same order (as OIDs differ on the nodes)
|
||||
|
|
Loading…
Reference in New Issue