Merge branch 'main' into alter_database_nonmain2

pull/7563/head
gurkanindibay 2024-03-20 01:15:17 +03:00
commit 879ab1821a
15 changed files with 258 additions and 383 deletions

View File

@ -11,8 +11,10 @@
* commands from non-main databases. * commands from non-main databases.
* *
* To add support for a new command type, one needs to define a new * To add support for a new command type, one needs to define a new
* NonMainDbDistributeObjectOps object and add it to * NonMainDbDistributeObjectOps object within OperationArray. Also, if
* GetNonMainDbDistributeObjectOps. * 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)" "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 * NonMainDbDistributeObjectOps contains the necessary callbacks / flags to
* support node-wide object management commands from non-main databases. * 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: * cannotBeExecutedInTransaction:
* Indicates whether the statement cannot be executed in a transaction. If * 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 * this is set to true, the statement will be executed directly on the main
* database because there are no transactional visibility issues for such * database because there are no transactional visibility issues for such
* commands. * commands.
* *
* And when this is true, we don't expect getMarkDistributedParams and * checkSupportedObjectType:
* getUnmarkDistributedParams to be implemented. * 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 typedef struct NonMainDbDistributeObjectOps
{ {
MarkDistributedGloballyParams * (*getMarkDistributedParams)(Node * parsetree);
List * (*getUnmarkDistributedParams)(Node * parsetree);
bool cannotBeExecutedInTransaction; bool cannotBeExecutedInTransaction;
bool (*checkSupportedObjectType)(Node *parsetree);
} NonMainDbDistributeObjectOps; } NonMainDbDistributeObjectOps;
/* /*
* getMarkDistributedParams and getUnmarkDistributedParams callbacks for * checkSupportedObjectType callbacks for OperationArray.
* NonMainDbDistributeObjectOps.
*/ */
static MarkDistributedGloballyParams * CreateRoleStmtGetMarkDistributedParams( static bool CreateDbStmtCheckSupportedObjectType(Node *node);
Node *parsetree); static bool DropDbStmtCheckSupportedObjectType(Node *node);
static List * DropRoleStmtGetUnmarkDistributedParams(Node *parsetree); static bool GrantStmtCheckSupportedObjectType(Node *node);
static bool SecLabelStmtCheckSupportedObjectType(Node *node);
/* /*
* NonMainDbDistributeObjectOps for different command types. * OperationArray that holds 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.
*/ */
static const NonMainDbDistributeObjectOps Any_CreateRole = { static const NonMainDbDistributeObjectOps *const OperationArray[] = {
.getMarkDistributedParams = CreateRoleStmtGetMarkDistributedParams, [T_CreateRoleStmt] = &(NonMainDbDistributeObjectOps) {
.getUnmarkDistributedParams = NULL, .cannotBeExecutedInTransaction = false,
.cannotBeExecutedInTransaction = false .checkSupportedObjectType = NULL
}; },
static const NonMainDbDistributeObjectOps Any_DropRole = { [T_DropRoleStmt] = &(NonMainDbDistributeObjectOps) {
.getMarkDistributedParams = NULL, .cannotBeExecutedInTransaction = false,
.getUnmarkDistributedParams = DropRoleStmtGetUnmarkDistributedParams, .checkSupportedObjectType = NULL
.cannotBeExecutedInTransaction = false },
}; [T_AlterRoleStmt] = &(NonMainDbDistributeObjectOps) {
static const NonMainDbDistributeObjectOps Any_AlterRole = { .cannotBeExecutedInTransaction = false,
.getMarkDistributedParams = NULL, .checkSupportedObjectType = NULL
.getUnmarkDistributedParams = NULL, },
.cannotBeExecutedInTransaction = false [T_GrantRoleStmt] = &(NonMainDbDistributeObjectOps) {
}; .cannotBeExecutedInTransaction = false,
static const NonMainDbDistributeObjectOps Any_GrantRole = { .checkSupportedObjectType = NULL
.getMarkDistributedParams = NULL, },
.getUnmarkDistributedParams = NULL, [T_CreatedbStmt] = &(NonMainDbDistributeObjectOps) {
.cannotBeExecutedInTransaction = false .cannotBeExecutedInTransaction = true,
}; .checkSupportedObjectType = CreateDbStmtCheckSupportedObjectType
static const NonMainDbDistributeObjectOps Any_CreateDatabase = { },
.getMarkDistributedParams = NULL, [T_DropdbStmt] = &(NonMainDbDistributeObjectOps) {
.getUnmarkDistributedParams = NULL, .cannotBeExecutedInTransaction = true,
.cannotBeExecutedInTransaction = true .checkSupportedObjectType = DropDbStmtCheckSupportedObjectType
}; },
static const NonMainDbDistributeObjectOps Any_DropDatabase = { [T_GrantStmt] = &(NonMainDbDistributeObjectOps) {
.getMarkDistributedParams = NULL, .cannotBeExecutedInTransaction = false,
.getUnmarkDistributedParams = NULL, .checkSupportedObjectType = GrantStmtCheckSupportedObjectType
.cannotBeExecutedInTransaction = true },
}; [T_SecLabelStmt] = &(NonMainDbDistributeObjectOps) {
.cannotBeExecutedInTransaction = false,
static const NonMainDbDistributeObjectOps Any_AlterDatabase = { .checkSupportedObjectType = SecLabelStmtCheckSupportedObjectType
.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
}; };
/* other static function declarations */ /* other static function declarations */
const NonMainDbDistributeObjectOps * GetNonMainDbDistributeObjectOps(Node *parsetree); const NonMainDbDistributeObjectOps * GetNonMainDbDistributeObjectOps(Node *parsetree);
static void MarkObjectDistributedGloballyOnMainDbs( static void CreateRoleStmtMarkDistGloballyOnMainDbs(CreateRoleStmt *createRoleStmt);
MarkDistributedGloballyParams *markDistributedParams); static void DropRoleStmtUnmarkDistOnLocalMainDb(DropRoleStmt *dropRoleStmt);
static void UnmarkObjectsDistributedOnLocalMainDb(List *unmarkDistributedParamsList); 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())); quote_literal_cstr(CurrentUserName()));
RunCitusMainDBQuery(mainDBQuery->data); RunCitusMainDBQuery(mainDBQuery->data);
if (ops->getUnmarkDistributedParams) if (IsA(parsetree, DropRoleStmt))
{ {
List *unmarkDistributedParamsList = ops->getUnmarkDistributedParams(parsetree); DropRoleStmtUnmarkDistOnLocalMainDb((DropRoleStmt *) parsetree);
UnmarkObjectsDistributedOnLocalMainDb(unmarkDistributedParamsList);
} }
return false; return false;
@ -266,22 +188,14 @@ RunPreprocessNonMainDBCommand(Node *parsetree)
void void
RunPostprocessNonMainDBCommand(Node *parsetree) RunPostprocessNonMainDBCommand(Node *parsetree)
{ {
if (IsMainDB) if (IsMainDB || !GetNonMainDbDistributeObjectOps(parsetree))
{ {
return; return;
} }
const NonMainDbDistributeObjectOps *ops = GetNonMainDbDistributeObjectOps(parsetree); if (IsA(parsetree, CreateRoleStmt))
if (!ops)
{ {
return; CreateRoleStmtMarkDistGloballyOnMainDbs((CreateRoleStmt *) parsetree);
}
if (ops->getMarkDistributedParams)
{
MarkDistributedGloballyParams *markDistributedParams =
ops->getMarkDistributedParams(parsetree);
MarkObjectDistributedGloballyOnMainDbs(markDistributedParams);
} }
} }
@ -294,137 +208,63 @@ RunPostprocessNonMainDBCommand(Node *parsetree)
const NonMainDbDistributeObjectOps * const NonMainDbDistributeObjectOps *
GetNonMainDbDistributeObjectOps(Node *parsetree) GetNonMainDbDistributeObjectOps(Node *parsetree)
{ {
switch (nodeTag(parsetree)) NodeTag tag = nodeTag(parsetree);
if (tag >= lengthof(OperationArray))
{ {
case T_CreateRoleStmt: return NULL;
{
return &Any_CreateRole;
} }
case T_DropRoleStmt: const NonMainDbDistributeObjectOps *ops = OperationArray[tag];
if (ops == NULL)
{ {
return &Any_DropRole; return NULL;
} }
case T_AlterRoleStmt: if (!ops->checkSupportedObjectType ||
ops->checkSupportedObjectType(parsetree))
{ {
return &Any_AlterRole; return ops;
} }
case T_GrantRoleStmt: return NULL;
{ }
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 * CreateRoleStmtMarkDistGloballyOnMainDbs marks the role as
* DATABASE command is for the main database itself, this is a very * distributed on all main databases globally.
* rare case but it's exercised by our test suite.
*/ */
if (strcmp(stmt->dbname, MainDb) != 0) static void
{ CreateRoleStmtMarkDistGloballyOnMainDbs(CreateRoleStmt *createRoleStmt)
return &Any_CreateDatabase; {
} /* object must exist as we've just created it */
bool missingOk = false;
Oid roleId = get_role_oid(createRoleStmt->role, missingOk);
return NULL; MarkObjectDistributedGloballyOnMainDbs(AuthIdRelationId, roleId,
} createRoleStmt->role);
}
case T_DropdbStmt:
{
DropdbStmt *stmt = castNode(DropdbStmt, parsetree);
/* /*
* We don't try to send the query to the main database if the DROP * DropRoleStmtUnmarkDistOnLocalMainDb unmarks the roles as
* DATABASE command is for the main database itself, this is a very * distributed on the local main database.
* rare case but it's exercised by our test suite.
*/ */
if (strcmp(stmt->dbname, MainDb) != 0) static void
DropRoleStmtUnmarkDistOnLocalMainDb(DropRoleStmt *dropRoleStmt)
{
RoleSpec *roleSpec = NULL;
foreach_ptr(roleSpec, dropRoleStmt->roles)
{ {
return &Any_DropDatabase; Oid roleOid = get_role_oid(roleSpec->rolename,
} dropRoleStmt->missing_ok);
if (roleOid == InvalidOid)
return NULL;
}
case T_AlterDatabaseStmt:
{ {
AlterDatabaseStmt *stmt = castNode(AlterDatabaseStmt, parsetree); continue;
/*
* 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; UnmarkObjectDistributedOnLocalMainDb(AuthIdRelationId, roleOid);
}
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;
} }
} }
@ -434,90 +274,78 @@ GetNonMainDbDistributeObjectOps(Node *parsetree)
* distributed on all main databases globally. * distributed on all main databases globally.
*/ */
static void static void
MarkObjectDistributedGloballyOnMainDbs( MarkObjectDistributedGloballyOnMainDbs(Oid catalogRelId, Oid objectId, char *objectName)
MarkDistributedGloballyParams *markDistributedParams)
{ {
StringInfo mainDBQuery = makeStringInfo(); StringInfo mainDBQuery = makeStringInfo();
appendStringInfo(mainDBQuery, appendStringInfo(mainDBQuery,
MARK_OBJECT_DISTRIBUTED, MARK_OBJECT_DISTRIBUTED,
markDistributedParams->catalogRelId, catalogRelId,
quote_literal_cstr(markDistributedParams->name), quote_literal_cstr(objectName),
markDistributedParams->id, objectId,
quote_literal_cstr(CurrentUserName())); quote_literal_cstr(CurrentUserName()));
RunCitusMainDBQuery(mainDBQuery->data); RunCitusMainDBQuery(mainDBQuery->data);
} }
/* /*
* UnmarkObjectsDistributedOnLocalMainDb unmarks a list of objects as * UnmarkObjectDistributedOnLocalMainDb unmarks an object as
* distributed on the local main database. * distributed on the local main database.
*/ */
static void static void
UnmarkObjectsDistributedOnLocalMainDb(List *unmarkDistributedParamsList) UnmarkObjectDistributedOnLocalMainDb(uint16 catalogRelId, Oid objectId)
{ {
int subObjectId = 0; const int subObjectId = 0;
char *checkObjectExistence = "false"; const char *checkObjectExistence = "false";
UnmarkDistributedLocallyParams *unmarkDistributedParams = NULL;
foreach_ptr(unmarkDistributedParams, unmarkDistributedParamsList)
{
StringInfo query = makeStringInfo(); StringInfo query = makeStringInfo();
appendStringInfo(query, appendStringInfo(query,
UNMARK_OBJECT_DISTRIBUTED, UNMARK_OBJECT_DISTRIBUTED,
unmarkDistributedParams->catalogRelId, catalogRelId, objectId,
unmarkDistributedParams->id,
subObjectId, checkObjectExistence); subObjectId, checkObjectExistence);
RunCitusMainDBQuery(query->data); RunCitusMainDBQuery(query->data);
}
} }
/* /*
* getMarkDistributedParams and getUnmarkDistributedParams callback implementations * checkSupportedObjectTypes callbacks for OperationArray lie below.
* for NonMainDbDistributeObjectOps start here.
*/ */
static MarkDistributedGloballyParams * static bool
CreateRoleStmtGetMarkDistributedParams(Node *parsetree) CreateDbStmtCheckSupportedObjectType(Node *node)
{ {
CreateRoleStmt *stmt = castNode(CreateRoleStmt, parsetree); /*
MarkDistributedGloballyParams *params = * We don't try to send the query to the main database if the CREATE
(MarkDistributedGloballyParams *) palloc(sizeof(MarkDistributedGloballyParams)); * DATABASE command is for the main database itself, this is a very
params->name = stmt->role; * rare case but it's exercised by our test suite.
params->catalogRelId = AuthIdRelationId; */
CreatedbStmt *stmt = castNode(CreatedbStmt, node);
/* object must exist as we've just created it */ return strcmp(stmt->dbname, MainDb) != 0;
bool missingOk = false;
params->id = get_role_oid(stmt->role, missingOk);
return params;
} }
static List * static bool
DropRoleStmtGetUnmarkDistributedParams(Node *parsetree) DropDbStmtCheckSupportedObjectType(Node *node)
{ {
DropRoleStmt *stmt = castNode(DropRoleStmt, parsetree); /*
* We don't try to send the query to the main database if the DROP
List *paramsList = NIL; * DATABASE command is for the main database itself, this is a very
* rare case but it's exercised by our test suite.
RoleSpec *roleSpec = NULL; */
foreach_ptr(roleSpec, stmt->roles) DropdbStmt *stmt = castNode(DropdbStmt, node);
{ return strcmp(stmt->dbname, MainDb) != 0;
UnmarkDistributedLocallyParams *params = }
(UnmarkDistributedLocallyParams *) palloc(
sizeof(UnmarkDistributedLocallyParams));
static bool
Oid roleOid = get_role_oid(roleSpec->rolename, stmt->missing_ok); GrantStmtCheckSupportedObjectType(Node *node)
if (roleOid == InvalidOid) {
{ GrantStmt *stmt = castNode(GrantStmt, node);
continue; return stmt->objtype == OBJECT_DATABASE;
} }
params->id = roleOid;
params->catalogRelId = AuthIdRelationId; static bool
SecLabelStmtCheckSupportedObjectType(Node *node)
paramsList = lappend(paramsList, params); {
} SecLabelStmt *stmt = castNode(SecLabelStmt, node);
return stmt->objtype == OBJECT_ROLE;
return paramsList;
} }

View File

@ -491,18 +491,17 @@ GenerateRoleOptionsList(HeapTuple tuple)
options = lappend(options, makeDefElem("password", NULL, -1)); 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, Datum rolValidUntilDatum = SysCacheGetAttr(AUTHNAME, tuple,
Anum_pg_authid_rolvaliduntil, &isNull); Anum_pg_authid_rolvaliduntil, &isNull);
char *rolValidUntil = "infinity";
if (!isNull) if (!isNull)
{ {
rolValidUntil = pstrdup((char *) timestamptz_to_str(rolValidUntilDatum)); char *rolValidUntil = pstrdup((char *) timestamptz_to_str(rolValidUntilDatum));
}
Node *validUntilStringNode = (Node *) makeString(rolValidUntil); Node *validUntilStringNode = (Node *) makeString(rolValidUntil);
DefElem *validUntilOption = makeDefElem("validUntil", validUntilStringNode, -1); DefElem *validUntilOption = makeDefElem("validUntil", validUntilStringNode, -1);
options = lappend(options, validUntilOption); options = lappend(options, validUntilOption);
}
return options; return options;
} }

View File

@ -3053,11 +3053,15 @@ ErrorUnsupportedAlterTableAddColumn(Oid relationId, AlterTableCmd *command,
else if (constraint->contype == CONSTR_FOREIGN) else if (constraint->contype == CONSTR_FOREIGN)
{ {
RangeVar *referencedTable = constraint->pktable; RangeVar *referencedTable = constraint->pktable;
char *referencedColumn = strVal(lfirst(list_head(constraint->pk_attrs)));
Oid referencedRelationId = RangeVarGetRelid(referencedTable, NoLock, false); Oid referencedRelationId = RangeVarGetRelid(referencedTable, NoLock, false);
appendStringInfo(errHint, "FOREIGN KEY (%s) REFERENCES %s(%s)", colName, appendStringInfo(errHint, "FOREIGN KEY (%s) REFERENCES %s", colName,
get_rel_name(referencedRelationId), referencedColumn); get_rel_name(referencedRelationId));
if (list_length(constraint->pk_attrs) > 0)
{
AppendColumnNameList(errHint, constraint->pk_attrs);
}
if (constraint->fk_del_action == FKCONSTR_ACTION_SETNULL) if (constraint->fk_del_action == FKCONSTR_ACTION_SETNULL)
{ {

View File

@ -121,7 +121,7 @@ AppendAlterTableStmt(StringInfo buf, AlterTableStmt *stmt)
* AppendColumnNameList converts a list of columns into comma separated string format * AppendColumnNameList converts a list of columns into comma separated string format
* (colname_1, colname_2, .., colname_n). * (colname_1, colname_2, .., colname_n).
*/ */
static void void
AppendColumnNameList(StringInfo buf, List *columns) AppendColumnNameList(StringInfo buf, List *columns)
{ {
appendStringInfoString(buf, " ("); appendStringInfoString(buf, " (");

View File

@ -492,19 +492,7 @@ stop_metadata_sync_to_node(PG_FUNCTION_ARGS)
bool bool
ClusterHasKnownMetadataWorkers() ClusterHasKnownMetadataWorkers()
{ {
bool workerWithMetadata = false; return !IsCoordinator() || HasMetadataWorkers();
if (!IsCoordinator())
{
workerWithMetadata = true;
}
if (workerWithMetadata || HasMetadataWorkers())
{
return true;
}
return false;
} }

View File

@ -34,6 +34,7 @@
#include "utils/fmgroids.h" #include "utils/fmgroids.h"
#include "utils/memutils.h" #include "utils/memutils.h"
#include "utils/rel.h" #include "utils/rel.h"
#include "utils/syscache.h"
#include "utils/xid8.h" #include "utils/xid8.h"
#include "pg_version_constants.h" #include "pg_version_constants.h"
@ -261,11 +262,28 @@ RecoverWorkerTransactions(WorkerNode *workerNode)
continue; continue;
} }
/* Check if the transaction is created by an outer transaction from a non-main database */
bool outerXidIsNull = false; bool outerXidIsNull = false;
Datum outerXidDatum = heap_getattr(heapTuple, 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, Anum_pg_dist_transaction_outerxid,
tupleDescriptor, &outerXidIsNull); 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; TransactionId outerXid = 0;
if (!outerXidIsNull) if (!outerXidIsNull)

View File

@ -121,6 +121,8 @@ extern void AppendGrantedByInGrant(StringInfo buf, GrantStmt *stmt);
extern void AppendGrantSharedPrefix(StringInfo buf, GrantStmt *stmt); extern void AppendGrantSharedPrefix(StringInfo buf, GrantStmt *stmt);
extern void AppendGrantSharedSuffix(StringInfo buf, GrantStmt *stmt); extern void AppendGrantSharedSuffix(StringInfo buf, GrantStmt *stmt);
extern void AppendColumnNameList(StringInfo buf, List *columns);
/* Common deparser utils */ /* Common deparser utils */
typedef struct DefElemOptionFormat typedef struct DefElemOptionFormat

View File

@ -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 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); 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); 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 -- 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 text;
NOTICE: column "test_6" of relation "referencing" already exists, skipping NOTICE: column "test_6" of relation "referencing" already exists, skipping

View File

@ -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; 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 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 | f | t | f | f | f | f | f | -1 | |
create_group_2 | f | t | f | f | f | f | f | -1 | | infinity create_group_2 | f | t | f | f | f | f | f | -1 | |
create_role | f | t | f | f | f | f | f | -1 | | infinity create_role | f | t | f | f | f | f | f | -1 | |
create_role"edge | f | t | f | f | f | f | f | -1 | | infinity create_role"edge | f | t | f | f | f | f | f | -1 | |
create_role'edge | f | t | f | f | f | f | f | -1 | | infinity create_role'edge | f | t | f | f | f | f | f | -1 | |
create_role_2 | f | t | f | f | f | f | f | -1 | | infinity create_role_2 | f | t | f | f | f | f | f | -1 | |
create_role_sysid | f | t | f | f | f | f | f | -1 | | infinity 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_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_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 | f | t | f | f | t | f | f | -1 | |
create_user_2 | f | t | f | f | t | f | f | -1 | | infinity create_user_2 | f | t | f | f | t | f | f | -1 | |
(11 rows) (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; 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;

View File

@ -188,7 +188,6 @@ select 1 from citus_add_node('localhost', :worker_2_port);
1 1
(1 row) (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 result FROM run_command_on_all_nodes($$
SELECT array_to_json(array_agg(row_to_json(t))) SELECT array_to_json(array_agg(row_to_json(t)))
FROM ( FROM (
@ -204,7 +203,7 @@ $$);
--------------------------------------------------------------------- ---------------------------------------------------------------------
[{"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":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) (3 rows)
--test for alter user --test for alter user
@ -229,7 +228,6 @@ select 1 from citus_add_node('localhost', :worker_2_port);
1 1
(1 row) (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 result FROM run_command_on_all_nodes($$
SELECT array_to_json(array_agg(row_to_json(t))) SELECT array_to_json(array_agg(row_to_json(t)))
FROM ( FROM (
@ -245,7 +243,7 @@ $$);
--------------------------------------------------------------------- ---------------------------------------------------------------------
[{"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":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) (3 rows)
--test for drop user --test for drop user
@ -266,7 +264,6 @@ select 1 from citus_add_node('localhost', :worker_2_port);
1 1
(1 row) (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 result FROM run_command_on_all_nodes($$
SELECT array_to_json(array_agg(row_to_json(t))) SELECT array_to_json(array_agg(row_to_json(t)))
FROM ( FROM (
@ -282,7 +279,7 @@ $$);
--------------------------------------------------------------------- ---------------------------------------------------------------------
[{"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) (3 rows)
-- Clean up: drop the database on worker node 2 -- Clean up: drop the database on worker node 2

View File

@ -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.log_remote_commands TO on;
SET citus.grep_remote_commands = '%SECURITY LABEL%'; SET citus.grep_remote_commands = '%SECURITY LABEL%';
SELECT 1 FROM citus_add_node('localhost', :worker_2_port); 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 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 DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
?column? ?column?
--------------------------------------------------------------------- ---------------------------------------------------------------------

View File

@ -67,6 +67,20 @@ SELECT 1 FROM run_command_on_workers($$SELECT pg_reload_conf()$$);
1 1
(2 rows) (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 -- make sure that the metadata is consistent across all nodes
-- we exclude the distributed_object_data as they are -- we exclude the distributed_object_data as they are
-- not sorted in the same order (as OIDs differ on the nodes) -- not sorted in the same order (as OIDs differ on the nodes)

View File

@ -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 CHECK (test_8 > 0);
ALTER TABLE referencing ADD COLUMN test_8 integer CONSTRAINT check_test_8 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 -- 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 text;
ALTER TABLE referencing ADD COLUMN IF NOT EXISTS test_6 integer; ALTER TABLE referencing ADD COLUMN IF NOT EXISTS test_6 integer;

View File

@ -100,7 +100,6 @@ 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);
-- 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 result FROM run_command_on_all_nodes($$
SELECT array_to_json(array_agg(row_to_json(t))) SELECT array_to_json(array_agg(row_to_json(t)))
FROM ( FROM (
@ -128,7 +127,6 @@ LIMIT 5 VALID UNTIL '2024-01-01';
\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);
-- 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 result FROM run_command_on_all_nodes($$
SELECT array_to_json(array_agg(row_to_json(t))) SELECT array_to_json(array_agg(row_to_json(t)))
FROM ( FROM (
@ -153,7 +151,6 @@ DROP 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);
-- 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 result FROM run_command_on_all_nodes($$
SELECT array_to_json(array_agg(row_to_json(t))) SELECT array_to_json(array_agg(row_to_json(t)))
FROM ( FROM (

View File

@ -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($$ALTER SYSTEM SET datestyle = "ISO, YMD";$$);
SELECT 1 FROM run_command_on_workers($$SELECT pg_reload_conf()$$); 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 -- make sure that the metadata is consistent across all nodes
-- we exclude the distributed_object_data as they are -- we exclude the distributed_object_data as they are
-- not sorted in the same order (as OIDs differ on the nodes) -- not sorted in the same order (as OIDs differ on the nodes)