mirror of https://github.com/citusdata/citus.git
ALTER TABLE <tblname> SET SCHEMA <schemaname> for single shard tables (#7004)
Adds support for altering schema of single shard tables. We do that in 2 steps. 1. Undistribute the tenant table at `preprocess` step, 2. Distribute new schema if it is a distributed schema after DDLs are propagated. DESCRIPTION: Adds support for altering a table's schema to/from distributed schemas.ahmet-testing
parent
ce2ba1d07e
commit
fba5c8dd30
|
@ -248,7 +248,8 @@ undistribute_table(PG_FUNCTION_ARGS)
|
|||
|
||||
TableConversionParameters params = {
|
||||
.relationId = relationId,
|
||||
.cascadeViaForeignKeys = cascadeViaForeignKeys
|
||||
.cascadeViaForeignKeys = cascadeViaForeignKeys,
|
||||
.bypassTenantCheck = false
|
||||
};
|
||||
|
||||
UndistributeTable(¶ms);
|
||||
|
@ -429,6 +430,55 @@ UndistributeTables(List *relationIdList)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* EnsureUndistributeTenantTableSafe ensures that it is safe to undistribute a tenant table.
|
||||
*/
|
||||
void
|
||||
EnsureUndistributeTenantTableSafe(Oid relationId, const char *operationName)
|
||||
{
|
||||
Oid schemaId = get_rel_namespace(relationId);
|
||||
Assert(IsTenantSchema(schemaId));
|
||||
|
||||
/* We only allow undistribute while altering schema */
|
||||
if (strcmp(operationName, TenantOperationNames[TENANT_SET_SCHEMA]) != 0)
|
||||
{
|
||||
ErrorIfTenantTable(relationId, operationName);
|
||||
}
|
||||
|
||||
char *tableName = get_rel_name(relationId);
|
||||
char *schemaName = get_namespace_name(schemaId);
|
||||
|
||||
/*
|
||||
* Partition table cannot be undistributed. Otherwise, its parent table would still
|
||||
* be a tenant table whereas partition table would be a local table.
|
||||
*/
|
||||
if (PartitionTable(relationId))
|
||||
{
|
||||
ereport(ERROR, (errmsg("%s is not allowed for partition table %s in distributed "
|
||||
"schema %s", operationName, tableName, schemaName),
|
||||
errdetail("partition table should be under the same distributed "
|
||||
"schema as its parent and be a tenant table.")));
|
||||
}
|
||||
|
||||
/*
|
||||
* When table is referenced by or referencing to a table in the same tenant
|
||||
* schema, we should disallow undistributing the table since we do not allow
|
||||
* foreign keys from/to Citus local or Postgres local table to/from distributed
|
||||
* schema.
|
||||
*/
|
||||
List *fkeyCommandsWithSingleShardTables =
|
||||
GetFKeyCreationCommandsRelationInvolvedWithTableType(
|
||||
relationId, INCLUDE_SINGLE_SHARD_TABLES);
|
||||
if (fkeyCommandsWithSingleShardTables != NIL)
|
||||
{
|
||||
ereport(ERROR, (errmsg("%s is not allowed for table %s in distributed schema %s",
|
||||
operationName, tableName, schemaName),
|
||||
errdetail("distributed schemas cannot have foreign keys from/to "
|
||||
"local tables or different schema")));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* UndistributeTable undistributes the given table. It uses ConvertTable function to
|
||||
* create a new local table and move everything to that table.
|
||||
|
@ -449,7 +499,13 @@ UndistributeTable(TableConversionParameters *params)
|
|||
"because the table is not distributed")));
|
||||
}
|
||||
|
||||
ErrorIfTenantTable(params->relationId, "undistribute_table");
|
||||
Oid schemaId = get_rel_namespace(params->relationId);
|
||||
if (!params->bypassTenantCheck && IsTenantSchema(schemaId) &&
|
||||
IsCitusTableType(params->relationId, SINGLE_SHARD_DISTRIBUTED))
|
||||
{
|
||||
EnsureUndistributeTenantTableSafe(params->relationId,
|
||||
TenantOperationNames[TENANT_UNDISTRIBUTE_TABLE]);
|
||||
}
|
||||
|
||||
if (!params->cascadeViaForeignKeys)
|
||||
{
|
||||
|
@ -506,7 +562,7 @@ AlterDistributedTable(TableConversionParameters *params)
|
|||
"is not distributed")));
|
||||
}
|
||||
|
||||
ErrorIfTenantTable(params->relationId, "alter_distributed_table");
|
||||
ErrorIfTenantTable(params->relationId, TenantOperationNames[TENANT_ALTER_TABLE]);
|
||||
ErrorIfColocateWithTenantTable(params->colocateWith);
|
||||
|
||||
EnsureTableNotForeign(params->relationId);
|
||||
|
@ -1267,7 +1323,8 @@ ErrorIfColocateWithTenantTable(char *colocateWith)
|
|||
{
|
||||
text *colocateWithTableNameText = cstring_to_text(colocateWith);
|
||||
Oid colocateWithTableId = ResolveRelationId(colocateWithTableNameText, false);
|
||||
ErrorIfTenantTable(colocateWithTableId, "colocate_with");
|
||||
ErrorIfTenantTable(colocateWithTableId,
|
||||
TenantOperationNames[TENANT_COLOCATE_WITH]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -468,7 +468,8 @@ ExecuteCascadeOperationForRelationIdList(List *relationIdList,
|
|||
{
|
||||
TableConversionParameters params = {
|
||||
.relationId = relationId,
|
||||
.cascadeViaForeignKeys = cascadeViaForeignKeys
|
||||
.cascadeViaForeignKeys = cascadeViaForeignKeys,
|
||||
.bypassTenantCheck = false
|
||||
};
|
||||
UndistributeTable(¶ms);
|
||||
}
|
||||
|
|
|
@ -1356,6 +1356,10 @@ IsTableTypeIncluded(Oid relationId, int flags)
|
|||
{
|
||||
return (flags & INCLUDE_LOCAL_TABLES) != 0;
|
||||
}
|
||||
else if (IsCitusTableType(relationId, SINGLE_SHARD_DISTRIBUTED))
|
||||
{
|
||||
return (flags & INCLUDE_SINGLE_SHARD_TABLES) != 0;
|
||||
}
|
||||
else if (IsCitusTableType(relationId, DISTRIBUTED_TABLE))
|
||||
{
|
||||
return (flags & INCLUDE_DISTRIBUTED_TABLES) != 0;
|
||||
|
|
|
@ -40,6 +40,14 @@ static void EnsureSchemaExist(Oid schemaId);
|
|||
/* controlled via citus.enable_schema_based_sharding GUC */
|
||||
bool EnableSchemaBasedSharding = false;
|
||||
|
||||
const char *TenantOperationNames[TOTAL_TENANT_OPERATION] = {
|
||||
"undistribute_table",
|
||||
"alter_distributed_table",
|
||||
"colocate_with",
|
||||
"update_distributed_table_colocation",
|
||||
"set schema",
|
||||
};
|
||||
|
||||
|
||||
PG_FUNCTION_INFO_V1(citus_internal_unregister_tenant_schema_globally);
|
||||
PG_FUNCTION_INFO_V1(citus_schema_distribute);
|
||||
|
@ -374,12 +382,7 @@ SchemaGetNonShardTableIdList(Oid schemaId)
|
|||
* - Schema name is in the allowed-list,
|
||||
* - Schema does not depend on an extension (created by extension),
|
||||
* - No extension depends on the schema (CREATE EXTENSION <ext> SCHEMA <schema>),
|
||||
* - Current user should be the owner of tables under the schema,
|
||||
* - Table kinds are supported,
|
||||
* - Referencing and referenced foreign keys for the tables under the schema are
|
||||
* supported,
|
||||
* - Tables under the schema are not owned by an extension,
|
||||
* - Only Citus local and Postgres local tables exist under the schema.
|
||||
* - Some checks for the table for being a valid tenant table.
|
||||
*/
|
||||
static void
|
||||
EnsureSchemaCanBeDistributed(Oid schemaId, List *schemaTableIdList)
|
||||
|
@ -409,39 +412,55 @@ EnsureSchemaCanBeDistributed(Oid schemaId, List *schemaTableIdList)
|
|||
Oid relationId = InvalidOid;
|
||||
foreach_oid(relationId, schemaTableIdList)
|
||||
{
|
||||
/* Ensure table owner */
|
||||
EnsureTableOwner(relationId);
|
||||
EnsureTenantTable(relationId, "citus_schema_distribute");
|
||||
}
|
||||
}
|
||||
|
||||
/* Check relation kind */
|
||||
EnsureTableKindSupportedForTenantSchema(relationId);
|
||||
|
||||
/* Check foreign keys */
|
||||
EnsureFKeysForTenantTable(relationId);
|
||||
/*
|
||||
* EnsureTenantTable ensures the table can be a valid tenant table.
|
||||
* - Current user should be the owner of table,
|
||||
* - Table kind is supported,
|
||||
* - Referencing and referenced foreign keys for the table are supported,
|
||||
* - Table is not owned by an extension,
|
||||
* - Table should be Citus local or Postgres local table.
|
||||
*/
|
||||
void
|
||||
EnsureTenantTable(Oid relationId, char *operationName)
|
||||
{
|
||||
/* Ensure table owner */
|
||||
EnsureTableOwner(relationId);
|
||||
|
||||
/* Check table not owned by an extension */
|
||||
ObjectAddress *tableAddress = palloc0(sizeof(ObjectAddress));
|
||||
ObjectAddressSet(*tableAddress, RelationRelationId, relationId);
|
||||
if (IsAnyObjectAddressOwnedByExtension(list_make1(tableAddress), NULL))
|
||||
{
|
||||
char *tableName = get_namespace_name(schemaId);
|
||||
ereport(ERROR, (errmsg("schema cannot be distributed since it has "
|
||||
"table %s which is owned by an extension",
|
||||
tableName)));
|
||||
}
|
||||
/* Check relation kind */
|
||||
EnsureTableKindSupportedForTenantSchema(relationId);
|
||||
|
||||
/* Postgres local tables are allowed */
|
||||
if (!IsCitusTable(relationId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
/* Check foreign keys */
|
||||
EnsureFKeysForTenantTable(relationId);
|
||||
|
||||
/* Only Citus local tables, amongst Citus table types, are allowed */
|
||||
if (!IsCitusTableType(relationId, CITUS_LOCAL_TABLE))
|
||||
{
|
||||
ereport(ERROR, (errmsg("schema already has distributed tables"),
|
||||
errhint("Undistribute distributed tables under "
|
||||
"the schema before distributing the schema.")));
|
||||
}
|
||||
/* Check table not owned by an extension */
|
||||
ObjectAddress *tableAddress = palloc0(sizeof(ObjectAddress));
|
||||
ObjectAddressSet(*tableAddress, RelationRelationId, relationId);
|
||||
if (IsAnyObjectAddressOwnedByExtension(list_make1(tableAddress), NULL))
|
||||
{
|
||||
Oid schemaId = get_rel_namespace(relationId);
|
||||
char *tableName = get_namespace_name(schemaId);
|
||||
ereport(ERROR, (errmsg("schema cannot be distributed since it has "
|
||||
"table %s which is owned by an extension",
|
||||
tableName)));
|
||||
}
|
||||
|
||||
/* Postgres local tables are allowed */
|
||||
if (!IsCitusTable(relationId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Only Citus local tables, amongst Citus table types, are allowed */
|
||||
if (!IsCitusTableType(relationId, CITUS_LOCAL_TABLE))
|
||||
{
|
||||
ereport(ERROR, (errmsg("distributed schema cannot have distributed tables"),
|
||||
errhint("Undistribute distributed tables before "
|
||||
"'%s'.", operationName)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -743,7 +762,7 @@ citus_schema_undistribute(PG_FUNCTION_ARGS)
|
|||
* if the given relation is a tenant table.
|
||||
*/
|
||||
void
|
||||
ErrorIfTenantTable(Oid relationId, char *operationName)
|
||||
ErrorIfTenantTable(Oid relationId, const char *operationName)
|
||||
{
|
||||
if (IsTenantSchema(get_rel_namespace(relationId)))
|
||||
{
|
||||
|
@ -753,20 +772,3 @@ ErrorIfTenantTable(Oid relationId, char *operationName)
|
|||
operationName)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ErrorIfTenantSchema errors out with the given operation name,
|
||||
* if the given schema is a tenant schema.
|
||||
*/
|
||||
void
|
||||
ErrorIfTenantSchema(Oid nspOid, char *operationName)
|
||||
{
|
||||
if (IsTenantSchema(nspOid))
|
||||
{
|
||||
ereport(ERROR, (errmsg(
|
||||
"%s is not allowed for %s because it is a distributed schema",
|
||||
get_namespace_name(nspOid),
|
||||
operationName)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "distributed/resource_lock.h"
|
||||
#include "distributed/version_compat.h"
|
||||
#include "distributed/worker_shard_visibility.h"
|
||||
#include "distributed/tenant_schema_metadata.h"
|
||||
#include "foreign/foreign.h"
|
||||
#include "lib/stringinfo.h"
|
||||
#include "nodes/parsenodes.h"
|
||||
|
@ -2310,9 +2311,52 @@ PreprocessAlterTableSchemaStmt(Node *node, const char *queryString,
|
|||
return NIL;
|
||||
}
|
||||
|
||||
ErrorIfTenantTable(relationId, "ALTER TABLE SET SCHEMA");
|
||||
ErrorIfTenantSchema(get_namespace_oid(stmt->newschema, false),
|
||||
"ALTER TABLE SET SCHEMA");
|
||||
Oid oldSchemaId = get_rel_namespace(relationId);
|
||||
Oid newSchemaId = get_namespace_oid(stmt->newschema, stmt->missing_ok);
|
||||
if (!OidIsValid(oldSchemaId) || !OidIsValid(newSchemaId))
|
||||
{
|
||||
return NIL;
|
||||
}
|
||||
|
||||
/* Do nothing if new schema is the same as old schema */
|
||||
if (newSchemaId == oldSchemaId)
|
||||
{
|
||||
return NIL;
|
||||
}
|
||||
|
||||
/* Undistribute table if its old schema is a tenant schema */
|
||||
if (IsTenantSchema(oldSchemaId) && IsCoordinator())
|
||||
{
|
||||
EnsureUndistributeTenantTableSafe(relationId,
|
||||
TenantOperationNames[TENANT_SET_SCHEMA]);
|
||||
|
||||
char *oldSchemaName = get_namespace_name(oldSchemaId);
|
||||
char *tableName = stmt->relation->relname;
|
||||
ereport(NOTICE, (errmsg("undistributing table %s in distributed schema %s "
|
||||
"before altering its schema", tableName, oldSchemaName)));
|
||||
|
||||
/* Undistribute tenant table by suppressing weird notices */
|
||||
TableConversionParameters params = {
|
||||
.relationId = relationId,
|
||||
.cascadeViaForeignKeys = false,
|
||||
.bypassTenantCheck = true,
|
||||
.suppressNoticeMessages = true,
|
||||
};
|
||||
UndistributeTable(¶ms);
|
||||
|
||||
/* relation id changes after undistribute_table */
|
||||
relationId = get_relname_relid(tableName, oldSchemaId);
|
||||
|
||||
/*
|
||||
* After undistribution, the table could be Citus table or Postgres table.
|
||||
* If it is Postgres table, do not propagate the `ALTER TABLE SET SCHEMA`
|
||||
* command to workers.
|
||||
*/
|
||||
if (!IsCitusTable(relationId))
|
||||
{
|
||||
return NIL;
|
||||
}
|
||||
}
|
||||
|
||||
DDLJob *ddlJob = palloc0(sizeof(DDLJob));
|
||||
QualifyTreeNode((Node *) stmt);
|
||||
|
@ -4166,3 +4210,61 @@ ConvertNewTableIfNecessary(Node *createStmt)
|
|||
CreateCitusLocalTable(createdRelationId, cascade, autoConverted);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ConvertToTenantTableIfNecessary converts given relation to a tenant table if its
|
||||
* schema changed to a distributed schema.
|
||||
*/
|
||||
void
|
||||
ConvertToTenantTableIfNecessary(AlterObjectSchemaStmt *stmt)
|
||||
{
|
||||
Assert(stmt->objectType == OBJECT_TABLE || stmt->objectType == OBJECT_FOREIGN_TABLE);
|
||||
|
||||
if (!IsCoordinator())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* We will let Postgres deal with missing_ok
|
||||
*/
|
||||
List *tableAddresses = GetObjectAddressListFromParseTree((Node *) stmt, true, true);
|
||||
|
||||
/* the code-path only supports a single object */
|
||||
Assert(list_length(tableAddresses) == 1);
|
||||
|
||||
/* We have already asserted that we have exactly 1 address in the addresses. */
|
||||
ObjectAddress *tableAddress = linitial(tableAddresses);
|
||||
char relKind = get_rel_relkind(tableAddress->objectId);
|
||||
if (relKind == RELKIND_SEQUENCE || relKind == RELKIND_VIEW)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Oid relationId = tableAddress->objectId;
|
||||
Oid schemaId = get_namespace_oid(stmt->newschema, stmt->missing_ok);
|
||||
if (!OidIsValid(schemaId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make table a tenant table when its schema actually changed. When its schema
|
||||
* is not changed as in `ALTER TABLE <tbl> SET SCHEMA <same_schema>`, we detect
|
||||
* that by seeing the table is still a single shard table. (i.e. not undistributed
|
||||
* at `preprocess` step)
|
||||
*/
|
||||
if (!IsCitusTableType(relationId, SINGLE_SHARD_DISTRIBUTED) &&
|
||||
IsTenantSchema(schemaId))
|
||||
{
|
||||
EnsureTenantTable(relationId, "ALTER TABLE SET SCHEMA");
|
||||
|
||||
char *schemaName = get_namespace_name(schemaId);
|
||||
char *tableName = stmt->relation->relname;
|
||||
ereport(NOTICE, (errmsg("converting table %s to a tenant table in distributed "
|
||||
"schema %s", tableName, schemaName)));
|
||||
|
||||
CreateTenantSchemaTable(relationId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -370,6 +370,18 @@ multi_ProcessUtility(PlannedStmt *pstmt,
|
|||
|
||||
ConvertNewTableIfNecessary(createStmt);
|
||||
}
|
||||
|
||||
if (context == PROCESS_UTILITY_TOPLEVEL &&
|
||||
IsA(parsetree, AlterObjectSchemaStmt))
|
||||
{
|
||||
AlterObjectSchemaStmt *alterSchemaStmt = castNode(AlterObjectSchemaStmt,
|
||||
parsetree);
|
||||
if (alterSchemaStmt->objectType == OBJECT_TABLE ||
|
||||
alterSchemaStmt->objectType == OBJECT_FOREIGN_TABLE)
|
||||
{
|
||||
ConvertToTenantTableIfNecessary(alterSchemaStmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UtilityHookLevel--;
|
||||
|
@ -999,7 +1011,8 @@ UndistributeDisconnectedCitusLocalTables(void)
|
|||
TableConversionParameters params = {
|
||||
.relationId = citusLocalTableId,
|
||||
.cascadeViaForeignKeys = true,
|
||||
.suppressNoticeMessages = true
|
||||
.suppressNoticeMessages = true,
|
||||
.bypassTenantCheck = false
|
||||
};
|
||||
UndistributeTable(¶ms);
|
||||
}
|
||||
|
|
|
@ -116,7 +116,7 @@ update_distributed_table_colocation(PG_FUNCTION_ARGS)
|
|||
text *colocateWithTableNameText = PG_GETARG_TEXT_P(1);
|
||||
|
||||
EnsureTableOwner(targetRelationId);
|
||||
ErrorIfTenantTable(targetRelationId, "update_distributed_table_colocation");
|
||||
ErrorIfTenantTable(targetRelationId, TenantOperationNames[TENANT_UPDATE_COLOCATION]);
|
||||
|
||||
char *colocateWithTableName = text_to_cstring(colocateWithTableNameText);
|
||||
if (IsColocateWithNone(colocateWithTableName))
|
||||
|
@ -127,7 +127,8 @@ update_distributed_table_colocation(PG_FUNCTION_ARGS)
|
|||
else
|
||||
{
|
||||
Oid colocateWithTableId = ResolveRelationId(colocateWithTableNameText, false);
|
||||
ErrorIfTenantTable(colocateWithTableId, "colocate_with");
|
||||
ErrorIfTenantTable(colocateWithTableId,
|
||||
TenantOperationNames[TENANT_COLOCATE_WITH]);
|
||||
EnsureTableOwner(colocateWithTableId);
|
||||
MarkTablesColocated(colocateWithTableId, targetRelationId);
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@ typedef enum ExtractForeignKeyConstraintsMode
|
|||
/* exclude the self-referencing foreign keys */
|
||||
EXCLUDE_SELF_REFERENCES = 1 << 2,
|
||||
|
||||
/* any combination of the 4 flags below is supported */
|
||||
/* any combination of the 5 flags below is supported */
|
||||
/* include foreign keys when the other table is a distributed table*/
|
||||
INCLUDE_DISTRIBUTED_TABLES = 1 << 3,
|
||||
|
||||
|
@ -131,9 +131,13 @@ typedef enum ExtractForeignKeyConstraintsMode
|
|||
/* include foreign keys when the other table is a Postgres local table*/
|
||||
INCLUDE_LOCAL_TABLES = 1 << 6,
|
||||
|
||||
/* include foreign keys when the other table is a single shard table*/
|
||||
INCLUDE_SINGLE_SHARD_TABLES = 1 << 7,
|
||||
|
||||
/* include foreign keys regardless of the other table's type */
|
||||
INCLUDE_ALL_TABLE_TYPES = INCLUDE_DISTRIBUTED_TABLES | INCLUDE_REFERENCE_TABLES |
|
||||
INCLUDE_CITUS_LOCAL_TABLES | INCLUDE_LOCAL_TABLES
|
||||
INCLUDE_CITUS_LOCAL_TABLES | INCLUDE_LOCAL_TABLES |
|
||||
INCLUDE_SINGLE_SHARD_TABLES
|
||||
} ExtractForeignKeyConstraintMode;
|
||||
|
||||
|
||||
|
@ -155,6 +159,19 @@ typedef enum SearchForeignKeyColumnFlags
|
|||
/* callers can also pass union of above flags */
|
||||
} SearchForeignKeyColumnFlags;
|
||||
|
||||
|
||||
typedef enum TenantOperation
|
||||
{
|
||||
TENANT_UNDISTRIBUTE_TABLE = 0,
|
||||
TENANT_ALTER_TABLE,
|
||||
TENANT_COLOCATE_WITH,
|
||||
TENANT_UPDATE_COLOCATION,
|
||||
TENANT_SET_SCHEMA,
|
||||
} TenantOperation;
|
||||
|
||||
#define TOTAL_TENANT_OPERATION 5
|
||||
extern const char *TenantOperationNames[TOTAL_TENANT_OPERATION];
|
||||
|
||||
/* begin.c - forward declarations */
|
||||
extern void SaveBeginCommandProperties(TransactionStmt *transactionStmt);
|
||||
|
||||
|
@ -593,6 +610,7 @@ extern char * GetAlterColumnWithNextvalDefaultCmd(Oid sequenceOid, Oid relationI
|
|||
|
||||
extern void ErrorIfTableHasIdentityColumn(Oid relationId);
|
||||
extern void ConvertNewTableIfNecessary(Node *createStmt);
|
||||
extern void ConvertToTenantTableIfNecessary(AlterObjectSchemaStmt *alterObjectSchemaStmt);
|
||||
|
||||
/* text_search.c - forward declarations */
|
||||
extern List * GetCreateTextSearchConfigStatements(const ObjectAddress *address);
|
||||
|
@ -792,11 +810,11 @@ extern void UpdateAutoConvertedForConnectedRelations(List *relationId, bool
|
|||
extern bool ShouldUseSchemaBasedSharding(char *schemaName);
|
||||
extern bool ShouldCreateTenantSchemaTable(Oid relationId);
|
||||
extern bool IsTenantSchema(Oid schemaId);
|
||||
extern void EnsureTenantTable(Oid relationId, char *operationName);
|
||||
extern void ErrorIfIllegalPartitioningInTenantSchema(Oid parentRelationId,
|
||||
Oid partitionRelationId);
|
||||
extern void CreateTenantSchemaTable(Oid relationId);
|
||||
extern void ErrorIfTenantTable(Oid relationId, char *operationName);
|
||||
extern void ErrorIfTenantSchema(Oid nspOid, char *operationName);
|
||||
extern void ErrorIfTenantTable(Oid relationId, const char *operationName);
|
||||
extern uint32 CreateTenantSchemaColocationId(void);
|
||||
|
||||
#endif /*CITUS_COMMANDS_H */
|
||||
|
|
|
@ -172,6 +172,12 @@ typedef struct TableConversionParameters
|
|||
* messages that we explicitly issue
|
||||
*/
|
||||
bool suppressNoticeMessages;
|
||||
|
||||
/*
|
||||
* bypassTenantCheck skips tenant table checks to allow some internal
|
||||
* operations which are normally disallowed
|
||||
*/
|
||||
bool bypassTenantCheck;
|
||||
} TableConversionParameters;
|
||||
|
||||
typedef struct TableConversionReturn
|
||||
|
@ -363,6 +369,7 @@ extern void CreateDistributedTable(Oid relationId, char *distributionColumnName,
|
|||
bool shardCountIsStrict, char *colocateWithTableName);
|
||||
extern void CreateReferenceTable(Oid relationId);
|
||||
extern void CreateTruncateTrigger(Oid relationId);
|
||||
extern void EnsureUndistributeTenantTableSafe(Oid relationId, const char *operationName);
|
||||
extern TableConversionReturn * UndistributeTable(TableConversionParameters *params);
|
||||
extern void UndistributeTables(List *relationIdList);
|
||||
|
||||
|
|
|
@ -482,8 +482,8 @@ SELECT create_distributed_table('tenant1.dist', 'id');
|
|||
(1 row)
|
||||
|
||||
SELECT citus_schema_distribute('tenant1');
|
||||
ERROR: schema already has distributed tables
|
||||
HINT: Undistribute distributed tables under the schema before distributing the schema.
|
||||
ERROR: distributed schema cannot have distributed tables
|
||||
HINT: Undistribute distributed tables before 'citus_schema_distribute'.
|
||||
SELECT undistribute_table('tenant1.dist');
|
||||
undistribute_table
|
||||
---------------------------------------------------------------------
|
||||
|
@ -510,8 +510,8 @@ SELECT create_reference_table('tenant1.ref2');
|
|||
(1 row)
|
||||
|
||||
SELECT citus_schema_distribute('tenant1');
|
||||
ERROR: schema already has distributed tables
|
||||
HINT: Undistribute distributed tables under the schema before distributing the schema.
|
||||
ERROR: distributed schema cannot have distributed tables
|
||||
HINT: Undistribute distributed tables before 'citus_schema_distribute'.
|
||||
SELECT undistribute_table('tenant1.ref2');
|
||||
undistribute_table
|
||||
---------------------------------------------------------------------
|
||||
|
@ -766,8 +766,8 @@ SELECT create_distributed_table('tenant1.new_dist', 'id');
|
|||
(1 row)
|
||||
|
||||
SELECT citus_schema_distribute('tenant1');
|
||||
ERROR: schema already has distributed tables
|
||||
HINT: Undistribute distributed tables under the schema before distributing the schema.
|
||||
ERROR: distributed schema cannot have distributed tables
|
||||
HINT: Undistribute distributed tables before 'citus_schema_distribute'.
|
||||
SELECT undistribute_table('tenant1.new_dist');
|
||||
undistribute_table
|
||||
---------------------------------------------------------------------
|
||||
|
@ -795,8 +795,8 @@ SELECT create_distributed_table('tenant1.single_shard_t', NULL);
|
|||
(1 row)
|
||||
|
||||
SELECT citus_schema_distribute('tenant1');
|
||||
ERROR: schema already has distributed tables
|
||||
HINT: Undistribute distributed tables under the schema before distributing the schema.
|
||||
ERROR: distributed schema cannot have distributed tables
|
||||
HINT: Undistribute distributed tables before 'citus_schema_distribute'.
|
||||
SELECT undistribute_table('tenant1.single_shard_t');
|
||||
undistribute_table
|
||||
---------------------------------------------------------------------
|
||||
|
|
|
@ -80,24 +80,148 @@ ERROR: tenant_2.test_table is not allowed for update_distributed_table_colocati
|
|||
-- verify we also don't allow colocate_with a tenant table
|
||||
SELECT update_distributed_table_colocation('regular_schema.test_table', colocate_with => 'tenant_2.test_table');
|
||||
ERROR: tenant_2.test_table is not allowed for colocate_with because it belongs to a distributed schema
|
||||
-- verify we don't allow undistribute_table for tenant tables
|
||||
SELECT undistribute_table('tenant_2.test_table');
|
||||
ERROR: tenant_2.test_table is not allowed for undistribute_table because it belongs to a distributed schema
|
||||
-- verify we do not allow undistribute_table for tenant tables
|
||||
CREATE TABLE tenant_2.undist_table(id int);
|
||||
SELECT undistribute_table('tenant_2.undist_table');
|
||||
ERROR: tenant_2.undist_table is not allowed for undistribute_table because it belongs to a distributed schema
|
||||
-- verify we don't allow alter_distributed_table for tenant tables
|
||||
SELECT alter_distributed_table('tenant_2.test_table', colocate_with => 'none');
|
||||
ERROR: tenant_2.test_table is not allowed for alter_distributed_table because it belongs to a distributed schema
|
||||
-- verify we also don't allow colocate_with a tenant table
|
||||
SELECT alter_distributed_table('regular_schema.test_table', colocate_with => 'tenant_2.test_table');
|
||||
ERROR: tenant_2.test_table is not allowed for colocate_with because it belongs to a distributed schema
|
||||
-- verify we don't allow ALTER TABLE SET SCHEMA for tenant tables
|
||||
ALTER TABLE tenant_2.test_table SET SCHEMA regular_schema;
|
||||
ERROR: tenant_2.test_table is not allowed for ALTER TABLE SET SCHEMA because it belongs to a distributed schema
|
||||
-- verify we don't allow ALTER TABLE SET SCHEMA for tenant schemas
|
||||
ALTER TABLE regular_schema.test_table SET SCHEMA tenant_2;
|
||||
ERROR: tenant_2 is not allowed for ALTER TABLE SET SCHEMA because it is a distributed schema
|
||||
-- the same, from tenant schema to tenant schema
|
||||
ALTER TABLE tenant_2.test_table SET SCHEMA tenant_3;
|
||||
ERROR: tenant_2.test_table is not allowed for ALTER TABLE SET SCHEMA because it belongs to a distributed schema
|
||||
-- verify we can set tenant table's schema to regular schema
|
||||
CREATE TABLE tenant_2.test_table2(id int);
|
||||
ALTER TABLE tenant_2.test_table2 SET SCHEMA regular_schema;
|
||||
NOTICE: undistributing table test_table2 in distributed schema tenant_2 before altering its schema
|
||||
-- verify that regular_schema.test_table2 does not exist in pg_dist_partition
|
||||
SELECT COUNT(*)=0 FROM pg_dist_partition
|
||||
WHERE logicalrelid = 'regular_schema.test_table2'::regclass AND
|
||||
partmethod = 'n' AND repmodel = 's' AND colocationid > 0;
|
||||
?column?
|
||||
---------------------------------------------------------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
-- verify that tenant_2.test_table2 does not exist
|
||||
SELECT * FROM tenant_2.test_table2;
|
||||
ERROR: relation "tenant_2.test_table2" does not exist
|
||||
-- verify we can set regular table's schema to distributed schema
|
||||
CREATE TABLE regular_schema.test_table3(id int);
|
||||
ALTER TABLE regular_schema.test_table3 SET SCHEMA tenant_2;
|
||||
NOTICE: converting table test_table3 to a tenant table in distributed schema tenant_2
|
||||
-- verify that tenant_2.test_table3 is recorded in pg_dist_partition as a single-shard table.
|
||||
SELECT COUNT(*)=1 FROM pg_dist_partition
|
||||
WHERE logicalrelid = 'tenant_2.test_table3'::regclass AND
|
||||
partmethod = 'n' AND repmodel = 's' AND colocationid > 0;
|
||||
?column?
|
||||
---------------------------------------------------------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
-- verify that regular_schema.test_table3 does not exist
|
||||
SELECT * FROM regular_schema.test_table3;
|
||||
ERROR: relation "regular_schema.test_table3" does not exist
|
||||
-- verify we can set tenant table's schema to another distributed schema
|
||||
CREATE TABLE tenant_2.test_table4(id int);
|
||||
ALTER TABLE tenant_2.test_table4 SET SCHEMA tenant_3;
|
||||
NOTICE: undistributing table test_table4 in distributed schema tenant_2 before altering its schema
|
||||
NOTICE: converting table test_table4 to a tenant table in distributed schema tenant_3
|
||||
-- verify that tenant_3.test_table4 is recorded in pg_dist_partition as a single-shard table.
|
||||
SELECT COUNT(*)=1 FROM pg_dist_partition
|
||||
WHERE logicalrelid = 'tenant_3.test_table4'::regclass AND
|
||||
partmethod = 'n' AND repmodel = 's' AND colocationid > 0;
|
||||
?column?
|
||||
---------------------------------------------------------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
-- verify that tenant_2.test_table4 does not exist
|
||||
SELECT * FROM tenant_2.test_table4;
|
||||
ERROR: relation "tenant_2.test_table4" does not exist
|
||||
-- verify that we can put a local table in regular schema into distributed schema
|
||||
CREATE TABLE regular_schema.pg_local_tbl(id int);
|
||||
ALTER TABLE regular_schema.pg_local_tbl SET SCHEMA tenant_2;
|
||||
NOTICE: converting table pg_local_tbl to a tenant table in distributed schema tenant_2
|
||||
-- verify that we can put a Citus local table in regular schema into distributed schema
|
||||
CREATE TABLE regular_schema.citus_local_tbl(id int);
|
||||
SELECT citus_add_local_table_to_metadata('regular_schema.citus_local_tbl');
|
||||
citus_add_local_table_to_metadata
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
ALTER TABLE regular_schema.citus_local_tbl SET SCHEMA tenant_2;
|
||||
NOTICE: converting table citus_local_tbl to a tenant table in distributed schema tenant_2
|
||||
-- verify that we do not allow a hash distributed table in regular schema into distributed schema
|
||||
CREATE TABLE regular_schema.hash_dist_tbl(id int);
|
||||
SELECT create_distributed_table('regular_schema.hash_dist_tbl', 'id');
|
||||
create_distributed_table
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
ALTER TABLE regular_schema.hash_dist_tbl SET SCHEMA tenant_2;
|
||||
ERROR: distributed schema cannot have distributed tables
|
||||
HINT: Undistribute distributed tables before 'ALTER TABLE SET SCHEMA'.
|
||||
-- verify that we do not allow a reference table in regular schema into distributed schema
|
||||
CREATE TABLE regular_schema.ref_tbl(id int PRIMARY KEY);
|
||||
SELECT create_reference_table('regular_schema.ref_tbl');
|
||||
create_reference_table
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
ALTER TABLE regular_schema.ref_tbl SET SCHEMA tenant_2;
|
||||
ERROR: distributed schema cannot have distributed tables
|
||||
HINT: Undistribute distributed tables before 'ALTER TABLE SET SCHEMA'.
|
||||
-- verify that we can put a table in tenant schema into regular schema
|
||||
CREATE TABLE tenant_2.tenant_tbl(id int);
|
||||
ALTER TABLE tenant_2.tenant_tbl SET SCHEMA regular_schema;
|
||||
NOTICE: undistributing table tenant_tbl in distributed schema tenant_2 before altering its schema
|
||||
-- verify that we can put a table in tenant schema into another tenant schema
|
||||
CREATE TABLE tenant_2.tenant_tbl2(id int);
|
||||
ALTER TABLE tenant_2.tenant_tbl2 SET SCHEMA tenant_3;
|
||||
NOTICE: undistributing table tenant_tbl2 in distributed schema tenant_2 before altering its schema
|
||||
NOTICE: converting table tenant_tbl2 to a tenant table in distributed schema tenant_3
|
||||
-- verify that we do not allow a local table in regular schema into distributed schema if it has foreign key to a non-reference table in another schema
|
||||
CREATE TABLE regular_schema.pg_local_tbl1(id int PRIMARY KEY);
|
||||
CREATE TABLE regular_schema.pg_local_tbl2(id int REFERENCES regular_schema.pg_local_tbl1(id));
|
||||
ALTER TABLE regular_schema.pg_local_tbl2 SET SCHEMA tenant_2;
|
||||
ERROR: foreign keys from distributed schemas can only point to the same distributed schema or reference tables in regular schemas
|
||||
DETAIL: "tenant_2.pg_local_tbl2" references "regular_schema.pg_local_tbl1" via foreign key constraint "pg_local_tbl2_id_fkey"
|
||||
-- verify that we allow a local table in regular schema into distributed schema if it has foreign key to a reference table in another schema
|
||||
CREATE TABLE regular_schema.pg_local_tbl3(id int REFERENCES regular_schema.ref_tbl(id));
|
||||
ALTER TABLE regular_schema.pg_local_tbl3 SET SCHEMA tenant_2;
|
||||
NOTICE: converting table pg_local_tbl3 to a tenant table in distributed schema tenant_2
|
||||
-- verify that we do not allow a table in tenant schema into regular schema if it has foreign key to/from another table in the same schema
|
||||
CREATE TABLE tenant_2.tenant_tbl1(id int PRIMARY KEY);
|
||||
CREATE TABLE tenant_2.tenant_tbl2(id int REFERENCES tenant_2.tenant_tbl1(id));
|
||||
ALTER TABLE tenant_2.tenant_tbl1 SET SCHEMA regular_schema;
|
||||
ERROR: set schema is not allowed for table tenant_tbl1 in distributed schema tenant_2
|
||||
DETAIL: distributed schemas cannot have foreign keys from/to local tables or different schema
|
||||
ALTER TABLE tenant_2.tenant_tbl2 SET SCHEMA regular_schema;
|
||||
ERROR: set schema is not allowed for table tenant_tbl2 in distributed schema tenant_2
|
||||
DETAIL: distributed schemas cannot have foreign keys from/to local tables or different schema
|
||||
-- verify that we do not allow a table in distributed schema into another distributed schema if it has foreign key to/from another table in the same schema
|
||||
CREATE TABLE tenant_2.tenant_tbl3(id int PRIMARY KEY);
|
||||
CREATE TABLE tenant_2.tenant_tbl4(id int REFERENCES tenant_2.tenant_tbl3(id));
|
||||
ALTER TABLE tenant_2.tenant_tbl3 SET SCHEMA tenant_3;
|
||||
ERROR: set schema is not allowed for table tenant_tbl3 in distributed schema tenant_2
|
||||
DETAIL: distributed schemas cannot have foreign keys from/to local tables or different schema
|
||||
ALTER TABLE tenant_2.tenant_tbl4 SET SCHEMA tenant_3;
|
||||
ERROR: set schema is not allowed for table tenant_tbl4 in distributed schema tenant_2
|
||||
DETAIL: distributed schemas cannot have foreign keys from/to local tables or different schema
|
||||
-- alter set non-existent schema
|
||||
ALTER TABLE tenant_2.test_table SET SCHEMA ghost_schema;
|
||||
ERROR: schema "ghost_schema" does not exist
|
||||
ALTER TABLE IF EXISTS tenant_2.test_table SET SCHEMA ghost_schema;
|
||||
ERROR: schema "ghost_schema" does not exist
|
||||
-- alter set non-existent table
|
||||
ALTER TABLE tenant_2.ghost_table SET SCHEMA ghost_schema;
|
||||
ERROR: relation "tenant_2.ghost_table" does not exist
|
||||
ALTER TABLE IF EXISTS tenant_2.ghost_table SET SCHEMA ghost_schema;
|
||||
NOTICE: relation "ghost_table" does not exist, skipping
|
||||
-- (on coordinator) verify that colocation id is set for empty tenants too
|
||||
SELECT colocationid > 0 FROM pg_dist_schema
|
||||
WHERE schemaid::regnamespace::text IN ('tenant_1', 'tenant_3');
|
||||
|
@ -265,8 +389,8 @@ SELECT EXISTS(
|
|||
(1 row)
|
||||
|
||||
INSERT INTO tenant_4.another_partitioned_table VALUES (1, 'a');
|
||||
ERROR: insert or update on table "another_partitioned_table_child_1920040" violates foreign key constraint "another_partitioned_table_a_fkey_1920039"
|
||||
DETAIL: Key (a)=(1) is not present in table "partitioned_table_1920037".
|
||||
ERROR: insert or update on table "another_partitioned_table_child_1920090" violates foreign key constraint "another_partitioned_table_a_fkey_1920089"
|
||||
DETAIL: Key (a)=(1) is not present in table "partitioned_table_1920087".
|
||||
CONTEXT: while executing command on localhost:xxxxx
|
||||
INSERT INTO tenant_4.partitioned_table VALUES (1, 'a');
|
||||
INSERT INTO tenant_4.another_partitioned_table VALUES (1, 'a');
|
||||
|
|
|
@ -59,18 +59,100 @@ SELECT citus_add_local_table_to_metadata('tenant_2.test_table');
|
|||
SELECT update_distributed_table_colocation('tenant_2.test_table', colocate_with => 'none');
|
||||
-- verify we also don't allow colocate_with a tenant table
|
||||
SELECT update_distributed_table_colocation('regular_schema.test_table', colocate_with => 'tenant_2.test_table');
|
||||
-- verify we don't allow undistribute_table for tenant tables
|
||||
SELECT undistribute_table('tenant_2.test_table');
|
||||
|
||||
-- verify we do not allow undistribute_table for tenant tables
|
||||
CREATE TABLE tenant_2.undist_table(id int);
|
||||
SELECT undistribute_table('tenant_2.undist_table');
|
||||
|
||||
-- verify we don't allow alter_distributed_table for tenant tables
|
||||
SELECT alter_distributed_table('tenant_2.test_table', colocate_with => 'none');
|
||||
-- verify we also don't allow colocate_with a tenant table
|
||||
SELECT alter_distributed_table('regular_schema.test_table', colocate_with => 'tenant_2.test_table');
|
||||
-- verify we don't allow ALTER TABLE SET SCHEMA for tenant tables
|
||||
ALTER TABLE tenant_2.test_table SET SCHEMA regular_schema;
|
||||
-- verify we don't allow ALTER TABLE SET SCHEMA for tenant schemas
|
||||
ALTER TABLE regular_schema.test_table SET SCHEMA tenant_2;
|
||||
-- the same, from tenant schema to tenant schema
|
||||
ALTER TABLE tenant_2.test_table SET SCHEMA tenant_3;
|
||||
|
||||
-- verify we can set tenant table's schema to regular schema
|
||||
CREATE TABLE tenant_2.test_table2(id int);
|
||||
ALTER TABLE tenant_2.test_table2 SET SCHEMA regular_schema;
|
||||
-- verify that regular_schema.test_table2 does not exist in pg_dist_partition
|
||||
SELECT COUNT(*)=0 FROM pg_dist_partition
|
||||
WHERE logicalrelid = 'regular_schema.test_table2'::regclass AND
|
||||
partmethod = 'n' AND repmodel = 's' AND colocationid > 0;
|
||||
-- verify that tenant_2.test_table2 does not exist
|
||||
SELECT * FROM tenant_2.test_table2;
|
||||
|
||||
-- verify we can set regular table's schema to distributed schema
|
||||
CREATE TABLE regular_schema.test_table3(id int);
|
||||
ALTER TABLE regular_schema.test_table3 SET SCHEMA tenant_2;
|
||||
-- verify that tenant_2.test_table3 is recorded in pg_dist_partition as a single-shard table.
|
||||
SELECT COUNT(*)=1 FROM pg_dist_partition
|
||||
WHERE logicalrelid = 'tenant_2.test_table3'::regclass AND
|
||||
partmethod = 'n' AND repmodel = 's' AND colocationid > 0;
|
||||
-- verify that regular_schema.test_table3 does not exist
|
||||
SELECT * FROM regular_schema.test_table3;
|
||||
|
||||
-- verify we can set tenant table's schema to another distributed schema
|
||||
CREATE TABLE tenant_2.test_table4(id int);
|
||||
ALTER TABLE tenant_2.test_table4 SET SCHEMA tenant_3;
|
||||
-- verify that tenant_3.test_table4 is recorded in pg_dist_partition as a single-shard table.
|
||||
SELECT COUNT(*)=1 FROM pg_dist_partition
|
||||
WHERE logicalrelid = 'tenant_3.test_table4'::regclass AND
|
||||
partmethod = 'n' AND repmodel = 's' AND colocationid > 0;
|
||||
-- verify that tenant_2.test_table4 does not exist
|
||||
SELECT * FROM tenant_2.test_table4;
|
||||
|
||||
-- verify that we can put a local table in regular schema into distributed schema
|
||||
CREATE TABLE regular_schema.pg_local_tbl(id int);
|
||||
ALTER TABLE regular_schema.pg_local_tbl SET SCHEMA tenant_2;
|
||||
|
||||
-- verify that we can put a Citus local table in regular schema into distributed schema
|
||||
CREATE TABLE regular_schema.citus_local_tbl(id int);
|
||||
SELECT citus_add_local_table_to_metadata('regular_schema.citus_local_tbl');
|
||||
ALTER TABLE regular_schema.citus_local_tbl SET SCHEMA tenant_2;
|
||||
|
||||
-- verify that we do not allow a hash distributed table in regular schema into distributed schema
|
||||
CREATE TABLE regular_schema.hash_dist_tbl(id int);
|
||||
SELECT create_distributed_table('regular_schema.hash_dist_tbl', 'id');
|
||||
ALTER TABLE regular_schema.hash_dist_tbl SET SCHEMA tenant_2;
|
||||
|
||||
-- verify that we do not allow a reference table in regular schema into distributed schema
|
||||
CREATE TABLE regular_schema.ref_tbl(id int PRIMARY KEY);
|
||||
SELECT create_reference_table('regular_schema.ref_tbl');
|
||||
ALTER TABLE regular_schema.ref_tbl SET SCHEMA tenant_2;
|
||||
|
||||
-- verify that we can put a table in tenant schema into regular schema
|
||||
CREATE TABLE tenant_2.tenant_tbl(id int);
|
||||
ALTER TABLE tenant_2.tenant_tbl SET SCHEMA regular_schema;
|
||||
|
||||
-- verify that we can put a table in tenant schema into another tenant schema
|
||||
CREATE TABLE tenant_2.tenant_tbl2(id int);
|
||||
ALTER TABLE tenant_2.tenant_tbl2 SET SCHEMA tenant_3;
|
||||
|
||||
-- verify that we do not allow a local table in regular schema into distributed schema if it has foreign key to a non-reference table in another schema
|
||||
CREATE TABLE regular_schema.pg_local_tbl1(id int PRIMARY KEY);
|
||||
CREATE TABLE regular_schema.pg_local_tbl2(id int REFERENCES regular_schema.pg_local_tbl1(id));
|
||||
ALTER TABLE regular_schema.pg_local_tbl2 SET SCHEMA tenant_2;
|
||||
|
||||
-- verify that we allow a local table in regular schema into distributed schema if it has foreign key to a reference table in another schema
|
||||
CREATE TABLE regular_schema.pg_local_tbl3(id int REFERENCES regular_schema.ref_tbl(id));
|
||||
ALTER TABLE regular_schema.pg_local_tbl3 SET SCHEMA tenant_2;
|
||||
|
||||
-- verify that we do not allow a table in tenant schema into regular schema if it has foreign key to/from another table in the same schema
|
||||
CREATE TABLE tenant_2.tenant_tbl1(id int PRIMARY KEY);
|
||||
CREATE TABLE tenant_2.tenant_tbl2(id int REFERENCES tenant_2.tenant_tbl1(id));
|
||||
ALTER TABLE tenant_2.tenant_tbl1 SET SCHEMA regular_schema;
|
||||
ALTER TABLE tenant_2.tenant_tbl2 SET SCHEMA regular_schema;
|
||||
|
||||
-- verify that we do not allow a table in distributed schema into another distributed schema if it has foreign key to/from another table in the same schema
|
||||
CREATE TABLE tenant_2.tenant_tbl3(id int PRIMARY KEY);
|
||||
CREATE TABLE tenant_2.tenant_tbl4(id int REFERENCES tenant_2.tenant_tbl3(id));
|
||||
ALTER TABLE tenant_2.tenant_tbl3 SET SCHEMA tenant_3;
|
||||
ALTER TABLE tenant_2.tenant_tbl4 SET SCHEMA tenant_3;
|
||||
|
||||
-- alter set non-existent schema
|
||||
ALTER TABLE tenant_2.test_table SET SCHEMA ghost_schema;
|
||||
ALTER TABLE IF EXISTS tenant_2.test_table SET SCHEMA ghost_schema;
|
||||
-- alter set non-existent table
|
||||
ALTER TABLE tenant_2.ghost_table SET SCHEMA ghost_schema;
|
||||
ALTER TABLE IF EXISTS tenant_2.ghost_table SET SCHEMA ghost_schema;
|
||||
|
||||
-- (on coordinator) verify that colocation id is set for empty tenants too
|
||||
SELECT colocationid > 0 FROM pg_dist_schema
|
||||
|
|
Loading…
Reference in New Issue