mirror of https://github.com/citusdata/citus.git
add a UDF to update colocation (#3623)
If two tables have the same distribution column type, we implicitly colocate them. This is useful since colocation has a big performance impact in most applications. When a table is rebalanced, all of the colocated tables are also rebalanced. If table A and table B are colocated and we want to rebalance table A, table B will also be rebalanced. We need replica identity so that logical replication can replicate updates and deletes during rebalancing. If table B does not have a replica identity we error out. A solution to this is to introduce a UDF so that colocation can be updated. The remaining tables in the colocation group will stay colocated. For example if table A, B and C are colocated and after updating table B's colocations, table A and table C stay colocated. The "updating colocation" step does not move any data around, it only updated pg_dist_partition and pg_dist_colocation tables. Specifically it creates a new colocation group for the table and updates the entry in pg_dist_partition while invalidating any cache.pull/3635/head
parent
3e980c81e9
commit
3df578010e
|
@ -574,7 +574,7 @@ ColocationIdForNewTable(Oid relationId, Var *distributionColumn,
|
|||
createdColocationGroup = true;
|
||||
}
|
||||
}
|
||||
else if (pg_strncasecmp(colocateWithTableName, "none", NAMEDATALEN) == 0)
|
||||
else if (IsColocateWithNone(colocateWithTableName))
|
||||
{
|
||||
colocationId = GetNextColocationId();
|
||||
|
||||
|
|
|
@ -1389,6 +1389,39 @@ EnsureFunctionOwner(Oid functionId)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* EnsureHashDistributedTable error out if the given relation is not a hash distributed table
|
||||
* with the given message.
|
||||
*/
|
||||
void
|
||||
EnsureHashDistributedTable(Oid relationId)
|
||||
{
|
||||
if (!IsHashDistributedTable(relationId))
|
||||
{
|
||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("relation %s should be a "
|
||||
"hash distributed table", get_rel_name(relationId))));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* IsDistributedTable returns true if the given relation is
|
||||
* a distributed table.
|
||||
*/
|
||||
bool
|
||||
IsHashDistributedTable(Oid relationId)
|
||||
{
|
||||
CitusTableCacheEntry *sourceTableEntry = GetCitusTableCacheEntry(relationId);
|
||||
if (sourceTableEntry == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
char sourceDistributionMethod = sourceTableEntry->partitionMethod;
|
||||
return sourceDistributionMethod == DISTRIBUTE_BY_HASH;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* EnsureSuperUser check that the current user is a superuser and errors out if not.
|
||||
*/
|
||||
|
|
|
@ -3,3 +3,4 @@
|
|||
/* bump version to 9.3-1 */
|
||||
|
||||
#include "udfs/citus_extradata_container/9.3-1.sql"
|
||||
#include "udfs/update_distributed_table_colocation/9.3-1.sql"
|
||||
|
|
6
src/backend/distributed/sql/udfs/update_distributed_table_colocation/9.3-1.sql
generated
Normal file
6
src/backend/distributed/sql/udfs/update_distributed_table_colocation/9.3-1.sql
generated
Normal file
|
@ -0,0 +1,6 @@
|
|||
CREATE OR REPLACE FUNCTION pg_catalog.update_distributed_table_colocation(table_name regclass, colocate_with text)
|
||||
RETURNS void
|
||||
LANGUAGE C STRICT
|
||||
AS 'MODULE_PATHNAME', $$update_distributed_table_colocation$$;
|
||||
COMMENT ON FUNCTION pg_catalog.update_distributed_table_colocation(table_name regclass, colocate_with text)
|
||||
IS 'updates colocation of a table';
|
|
@ -0,0 +1,6 @@
|
|||
CREATE OR REPLACE FUNCTION pg_catalog.update_distributed_table_colocation(table_name regclass, colocate_with text)
|
||||
RETURNS void
|
||||
LANGUAGE C STRICT
|
||||
AS 'MODULE_PATHNAME', $$update_distributed_table_colocation$$;
|
||||
COMMENT ON FUNCTION pg_catalog.update_distributed_table_colocation(table_name regclass, colocate_with text)
|
||||
IS 'updates colocation of a table';
|
|
@ -50,11 +50,13 @@ static int CompareShardPlacementsByNode(const void *leftElement,
|
|||
static void UpdateRelationColocationGroup(Oid distributedRelationId, uint32 colocationId);
|
||||
static List * ColocationGroupTableList(Oid colocationId);
|
||||
static void DeleteColocationGroup(uint32 colocationId);
|
||||
|
||||
static uint32 CreateColocationGroupForRelation(Oid sourceRelationId);
|
||||
static void BreakColocation(Oid sourceRelationId);
|
||||
|
||||
/* exports for SQL callable functions */
|
||||
PG_FUNCTION_INFO_V1(mark_tables_colocated);
|
||||
PG_FUNCTION_INFO_V1(get_colocated_shard_array);
|
||||
PG_FUNCTION_INFO_V1(update_distributed_table_colocation);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -96,6 +98,74 @@ mark_tables_colocated(PG_FUNCTION_ARGS)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* update_distributed_table_colocation updates the colocation of a table.
|
||||
* if colocate_with -> 'none' then the table is assigned a new
|
||||
* colocation group.
|
||||
*/
|
||||
Datum
|
||||
update_distributed_table_colocation(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid targetRelationId = PG_GETARG_OID(0);
|
||||
text *colocateWithTableNameText = PG_GETARG_TEXT_P(1);
|
||||
|
||||
CheckCitusVersion(ERROR);
|
||||
EnsureCoordinator();
|
||||
EnsureTableOwner(targetRelationId);
|
||||
EnsureHashDistributedTable(targetRelationId);
|
||||
|
||||
char *colocateWithTableName = text_to_cstring(colocateWithTableNameText);
|
||||
if (IsColocateWithNone(colocateWithTableName))
|
||||
{
|
||||
BreakColocation(targetRelationId);
|
||||
}
|
||||
else
|
||||
{
|
||||
Oid colocateWithTableId = ResolveRelationId(colocateWithTableNameText, false);
|
||||
EnsureHashDistributedTable(colocateWithTableId);
|
||||
MarkTablesColocated(colocateWithTableId, targetRelationId);
|
||||
}
|
||||
PG_RETURN_VOID();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* IsColocateWithNone returns true if the given table is
|
||||
* the special keyword "none".
|
||||
*/
|
||||
bool
|
||||
IsColocateWithNone(char *colocateWithTableName)
|
||||
{
|
||||
return pg_strncasecmp(colocateWithTableName, "none", NAMEDATALEN) == 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* BreakColocation breaks the colocations of the given relation id.
|
||||
* If t1, t2 and t3 are colocated and we call this function with t2,
|
||||
* t1 and t3 will stay colocated but t2 will have a new colocation id.
|
||||
* Note that this function does not move any data around for the new colocation.
|
||||
*/
|
||||
static void
|
||||
BreakColocation(Oid sourceRelationId)
|
||||
{
|
||||
/*
|
||||
* Get an exclusive lock on the colocation system catalog. Therefore, we
|
||||
* can be sure that there will no modifications on the colocation table
|
||||
* until this transaction is committed.
|
||||
*/
|
||||
Relation pgDistColocation = heap_open(DistColocationRelationId(), ExclusiveLock);
|
||||
|
||||
uint32 newColocationId = GetNextColocationId();
|
||||
UpdateRelationColocationGroup(sourceRelationId, newColocationId);
|
||||
|
||||
/* if there is not any remaining table in the colocation group, delete it */
|
||||
DeleteColocationGroupIfNoTablesBelong(sourceRelationId);
|
||||
|
||||
heap_close(pgDistColocation, NoLock);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_colocated_shards_array returns array of shards ids which are co-located with given
|
||||
* shard.
|
||||
|
@ -131,6 +201,36 @@ get_colocated_shard_array(PG_FUNCTION_ARGS)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* CreateColocationGroupForRelation creates colocation entry in
|
||||
* pg_dist_colocation and updated the colocation id in pg_dist_partition
|
||||
* for the given relation.
|
||||
*/
|
||||
static uint32
|
||||
CreateColocationGroupForRelation(Oid sourceRelationId)
|
||||
{
|
||||
uint32 shardCount = ShardIntervalCount(sourceRelationId);
|
||||
uint32 shardReplicationFactor = TableShardReplicationFactor(sourceRelationId);
|
||||
|
||||
Var *sourceDistributionColumn = DistPartitionKey(sourceRelationId);
|
||||
Oid sourceDistributionColumnType = InvalidOid;
|
||||
Oid sourceDistributionColumnCollation = InvalidOid;
|
||||
|
||||
/* reference tables has NULL distribution column */
|
||||
if (sourceDistributionColumn != NULL)
|
||||
{
|
||||
sourceDistributionColumnType = sourceDistributionColumn->vartype;
|
||||
sourceDistributionColumnCollation = sourceDistributionColumn->varcollid;
|
||||
}
|
||||
|
||||
uint32 sourceColocationId = CreateColocationGroup(shardCount, shardReplicationFactor,
|
||||
sourceDistributionColumnType,
|
||||
sourceDistributionColumnCollation);
|
||||
UpdateRelationColocationGroup(sourceRelationId, sourceColocationId);
|
||||
return sourceColocationId;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MarkTablesColocated puts both tables to same colocation group. If the
|
||||
* source table is in INVALID_COLOCATION_ID group, then it creates a new
|
||||
|
@ -160,24 +260,7 @@ MarkTablesColocated(Oid sourceRelationId, Oid targetRelationId)
|
|||
uint32 sourceColocationId = TableColocationId(sourceRelationId);
|
||||
if (sourceColocationId == INVALID_COLOCATION_ID)
|
||||
{
|
||||
uint32 shardCount = ShardIntervalCount(sourceRelationId);
|
||||
uint32 shardReplicationFactor = TableShardReplicationFactor(sourceRelationId);
|
||||
|
||||
Var *sourceDistributionColumn = DistPartitionKey(sourceRelationId);
|
||||
Oid sourceDistributionColumnType = InvalidOid;
|
||||
Oid sourceDistributionColumnCollation = InvalidOid;
|
||||
|
||||
/* reference tables has NULL distribution column */
|
||||
if (sourceDistributionColumn != NULL)
|
||||
{
|
||||
sourceDistributionColumnType = sourceDistributionColumn->vartype;
|
||||
sourceDistributionColumnCollation = sourceDistributionColumn->varcollid;
|
||||
}
|
||||
|
||||
sourceColocationId = CreateColocationGroup(shardCount, shardReplicationFactor,
|
||||
sourceDistributionColumnType,
|
||||
sourceDistributionColumnCollation);
|
||||
UpdateRelationColocationGroup(sourceRelationId, sourceColocationId);
|
||||
sourceColocationId = CreateColocationGroupForRelation(sourceRelationId);
|
||||
}
|
||||
|
||||
uint32 targetColocationId = TableColocationId(targetRelationId);
|
||||
|
|
|
@ -30,6 +30,7 @@ uint32 ColocationId(int shardCount, int replicationFactor, Oid distributionColum
|
|||
extern uint32 CreateColocationGroup(int shardCount, int replicationFactor,
|
||||
Oid distributionColumnType,
|
||||
Oid distributionColumnCollation);
|
||||
extern bool IsColocateWithNone(char *colocateWithTableName);
|
||||
extern uint32 GetNextColocationId(void);
|
||||
extern void CheckReplicationModel(Oid sourceRelationId, Oid targetRelationId);
|
||||
extern void CheckDistributionColumnType(Oid sourceRelationId, Oid targetRelationId);
|
||||
|
|
|
@ -148,6 +148,8 @@ extern char * TableOwner(Oid relationId);
|
|||
extern void EnsureTablePermissions(Oid relationId, AclMode mode);
|
||||
extern void EnsureTableOwner(Oid relationId);
|
||||
extern void EnsureSchemaOwner(Oid schemaId);
|
||||
extern void EnsureHashDistributedTable(Oid relationId);
|
||||
extern bool IsHashDistributedTable(Oid relationId);
|
||||
extern void EnsureSequenceOwner(Oid sequenceOid);
|
||||
extern void EnsureFunctionOwner(Oid functionId);
|
||||
extern void EnsureSuperUser(void);
|
||||
|
|
|
@ -1032,6 +1032,407 @@ SELECT create_distributed_table('table2_groupG', 'id', colocate_with => 'NONE');
|
|||
SELECT mark_tables_colocated('table1_groupG', ARRAY['table2_groupG']);
|
||||
ERROR: cannot colocate tables table1_groupg and table2_groupg
|
||||
DETAIL: Replication models don't match for table1_groupg and table2_groupg.
|
||||
CREATE TABLE d1(a int, b int);
|
||||
CREATE TABLE d2(a int, b int);
|
||||
CREATE TABLE d3(a int, b int);
|
||||
CREATE TABLE d4(a int, b int);
|
||||
CREATE TABLE different_d1(ch char);
|
||||
CREATE TABLE append_table(a int, b int);
|
||||
CREATE TABLE range_table(a int, b int);
|
||||
-- special keyword none
|
||||
CREATE TABLE none(a int, b int);
|
||||
CREATE TABLE ref(a int);
|
||||
CREATE TABLE local_table(a int);
|
||||
SELECT create_distributed_table('d1', 'a');
|
||||
create_distributed_table
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT create_distributed_table('d2', 'a', colocate_with => 'd1');
|
||||
create_distributed_table
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT create_distributed_table('d3', 'a', colocate_with => 'd2');
|
||||
create_distributed_table
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT create_distributed_table('d4', 'a', colocate_with => 'd3');
|
||||
create_distributed_table
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT create_distributed_table('none', 'a', colocate_with => 'd4');
|
||||
create_distributed_table
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT create_distributed_table('different_d1', 'ch');
|
||||
create_distributed_table
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT create_distributed_table('append_table', 'a', 'append');
|
||||
create_distributed_table
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT create_distributed_table('range_table', 'a', 'range');
|
||||
create_distributed_table
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT create_reference_table('ref');
|
||||
create_reference_table
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- check d1, d2, d3 and d4 has the same colocation id => they are colocated.
|
||||
SELECT get_table_colocation_id('d1');
|
||||
get_table_colocation_id
|
||||
---------------------------------------------------------------------
|
||||
8
|
||||
(1 row)
|
||||
|
||||
SELECT get_table_colocation_id('d2');
|
||||
get_table_colocation_id
|
||||
---------------------------------------------------------------------
|
||||
8
|
||||
(1 row)
|
||||
|
||||
SELECT get_table_colocation_id('d3');
|
||||
get_table_colocation_id
|
||||
---------------------------------------------------------------------
|
||||
8
|
||||
(1 row)
|
||||
|
||||
SELECT get_table_colocation_id('d4');
|
||||
get_table_colocation_id
|
||||
---------------------------------------------------------------------
|
||||
8
|
||||
(1 row)
|
||||
|
||||
SELECT tables_colocated('d1', 'd2');
|
||||
tables_colocated
|
||||
---------------------------------------------------------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
SELECT tables_colocated('d2', 'd3');
|
||||
tables_colocated
|
||||
---------------------------------------------------------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
SELECT tables_colocated('d2', 'd4');
|
||||
tables_colocated
|
||||
---------------------------------------------------------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
SELECT tables_colocated('d3', 'd4');
|
||||
tables_colocated
|
||||
---------------------------------------------------------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
SELECT tables_colocated('d1', 'd3');
|
||||
tables_colocated
|
||||
---------------------------------------------------------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
SELECT tables_colocated('d1', 'd4');
|
||||
tables_colocated
|
||||
---------------------------------------------------------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
-- break colocation of d2
|
||||
SELECT update_distributed_table_colocation('d2', colocate_with => 'none');
|
||||
update_distributed_table_colocation
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- d1 and d3 and d4 should be colocated, d2 should have a new colocation id.
|
||||
SELECT get_table_colocation_id('d1');
|
||||
get_table_colocation_id
|
||||
---------------------------------------------------------------------
|
||||
8
|
||||
(1 row)
|
||||
|
||||
SELECT get_table_colocation_id('d2');
|
||||
get_table_colocation_id
|
||||
---------------------------------------------------------------------
|
||||
11
|
||||
(1 row)
|
||||
|
||||
SELECT get_table_colocation_id('d3');
|
||||
get_table_colocation_id
|
||||
---------------------------------------------------------------------
|
||||
8
|
||||
(1 row)
|
||||
|
||||
SELECT get_table_colocation_id('d4');
|
||||
get_table_colocation_id
|
||||
---------------------------------------------------------------------
|
||||
8
|
||||
(1 row)
|
||||
|
||||
SELECT tables_colocated('d1', 'd2');
|
||||
tables_colocated
|
||||
---------------------------------------------------------------------
|
||||
f
|
||||
(1 row)
|
||||
|
||||
SELECT tables_colocated('d2', 'd3');
|
||||
tables_colocated
|
||||
---------------------------------------------------------------------
|
||||
f
|
||||
(1 row)
|
||||
|
||||
SELECT tables_colocated('d1', 'd3');
|
||||
tables_colocated
|
||||
---------------------------------------------------------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
SELECT tables_colocated('d1', 'd4');
|
||||
tables_colocated
|
||||
---------------------------------------------------------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
-- break colocation of d2
|
||||
-- update colocation should not error if d2 doesn't have any colocated table.
|
||||
SELECT update_distributed_table_colocation('d2', colocate_with => 'none');
|
||||
update_distributed_table_colocation
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- d1 and d3 and d4 should be colocated, d2 should have a new colocation id.
|
||||
SELECT get_table_colocation_id('d1');
|
||||
get_table_colocation_id
|
||||
---------------------------------------------------------------------
|
||||
8
|
||||
(1 row)
|
||||
|
||||
SELECT get_table_colocation_id('d2');
|
||||
get_table_colocation_id
|
||||
---------------------------------------------------------------------
|
||||
12
|
||||
(1 row)
|
||||
|
||||
SELECT get_table_colocation_id('d3');
|
||||
get_table_colocation_id
|
||||
---------------------------------------------------------------------
|
||||
8
|
||||
(1 row)
|
||||
|
||||
SELECT get_table_colocation_id('d4');
|
||||
get_table_colocation_id
|
||||
---------------------------------------------------------------------
|
||||
8
|
||||
(1 row)
|
||||
|
||||
SELECT tables_colocated('d1', 'd2');
|
||||
tables_colocated
|
||||
---------------------------------------------------------------------
|
||||
f
|
||||
(1 row)
|
||||
|
||||
SELECT tables_colocated('d2', 'd3');
|
||||
tables_colocated
|
||||
---------------------------------------------------------------------
|
||||
f
|
||||
(1 row)
|
||||
|
||||
SELECT tables_colocated('d1', 'd3');
|
||||
tables_colocated
|
||||
---------------------------------------------------------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
SELECT tables_colocated('d1', 'd4');
|
||||
tables_colocated
|
||||
---------------------------------------------------------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
SELECT update_distributed_table_colocation('d3', colocate_with => 'd2');
|
||||
update_distributed_table_colocation
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- d1 and d4 should be colocated, d2 and d3 should be colocated.
|
||||
SELECT get_table_colocation_id('d1');
|
||||
get_table_colocation_id
|
||||
---------------------------------------------------------------------
|
||||
8
|
||||
(1 row)
|
||||
|
||||
SELECT get_table_colocation_id('d2');
|
||||
get_table_colocation_id
|
||||
---------------------------------------------------------------------
|
||||
12
|
||||
(1 row)
|
||||
|
||||
SELECT get_table_colocation_id('d3');
|
||||
get_table_colocation_id
|
||||
---------------------------------------------------------------------
|
||||
12
|
||||
(1 row)
|
||||
|
||||
SELECT get_table_colocation_id('d4');
|
||||
get_table_colocation_id
|
||||
---------------------------------------------------------------------
|
||||
8
|
||||
(1 row)
|
||||
|
||||
SELECT tables_colocated('d1', 'd2');
|
||||
tables_colocated
|
||||
---------------------------------------------------------------------
|
||||
f
|
||||
(1 row)
|
||||
|
||||
SELECT tables_colocated('d2', 'd3');
|
||||
tables_colocated
|
||||
---------------------------------------------------------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
SELECT tables_colocated('d1', 'd3');
|
||||
tables_colocated
|
||||
---------------------------------------------------------------------
|
||||
f
|
||||
(1 row)
|
||||
|
||||
SELECT tables_colocated('d1', 'd4');
|
||||
tables_colocated
|
||||
---------------------------------------------------------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
-- special case, colocate with a table named "none".
|
||||
SELECT update_distributed_table_colocation('d3', colocate_with => '"none"');
|
||||
update_distributed_table_colocation
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- d1, d4, d3 and "none" should be colocated;
|
||||
SELECT get_table_colocation_id('d1');
|
||||
get_table_colocation_id
|
||||
---------------------------------------------------------------------
|
||||
8
|
||||
(1 row)
|
||||
|
||||
SELECT get_table_colocation_id('d2');
|
||||
get_table_colocation_id
|
||||
---------------------------------------------------------------------
|
||||
12
|
||||
(1 row)
|
||||
|
||||
SELECT get_table_colocation_id('d3');
|
||||
get_table_colocation_id
|
||||
---------------------------------------------------------------------
|
||||
8
|
||||
(1 row)
|
||||
|
||||
SELECT get_table_colocation_id('d4');
|
||||
get_table_colocation_id
|
||||
---------------------------------------------------------------------
|
||||
8
|
||||
(1 row)
|
||||
|
||||
SELECT get_table_colocation_id('none');
|
||||
get_table_colocation_id
|
||||
---------------------------------------------------------------------
|
||||
8
|
||||
(1 row)
|
||||
|
||||
SELECT tables_colocated('d1', 'd2');
|
||||
tables_colocated
|
||||
---------------------------------------------------------------------
|
||||
f
|
||||
(1 row)
|
||||
|
||||
SELECT tables_colocated('d2', 'd3');
|
||||
tables_colocated
|
||||
---------------------------------------------------------------------
|
||||
f
|
||||
(1 row)
|
||||
|
||||
SELECT tables_colocated('d1', 'd3');
|
||||
tables_colocated
|
||||
---------------------------------------------------------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
SELECT tables_colocated('d1', 'd4');
|
||||
tables_colocated
|
||||
---------------------------------------------------------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
SELECT tables_colocated('d1', 'none');
|
||||
tables_colocated
|
||||
---------------------------------------------------------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
SELECT tables_colocated('d4', 'none');
|
||||
tables_colocated
|
||||
---------------------------------------------------------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
SELECT tables_colocated('d3', 'none');
|
||||
tables_colocated
|
||||
---------------------------------------------------------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
SELECT tables_colocated('d2', 'none');
|
||||
tables_colocated
|
||||
---------------------------------------------------------------------
|
||||
f
|
||||
(1 row)
|
||||
|
||||
-- make sure reference and local tables return an error.
|
||||
SELECT update_distributed_table_colocation('ref', colocate_with => 'none');
|
||||
ERROR: relation ref should be a hash distributed table
|
||||
SELECT update_distributed_table_colocation('local_table', colocate_with => 'none');
|
||||
ERROR: relation local_table is not distributed
|
||||
-- make sure that different types cannot be colocated
|
||||
SELECT update_distributed_table_colocation('different_d1', colocate_with => 'd1');
|
||||
ERROR: cannot colocate tables d1 and different_d1
|
||||
DETAIL: Distribution column types don't match for d1 and different_d1.
|
||||
SELECT update_distributed_table_colocation('d1', colocate_with => 'different_d1');
|
||||
ERROR: cannot colocate tables different_d1 and d1
|
||||
DETAIL: Distribution column types don't match for different_d1 and d1.
|
||||
-- make sure that append distributed tables cannot be colocated
|
||||
SELECT update_distributed_table_colocation('append_table', colocate_with => 'd1');
|
||||
ERROR: relation append_table should be a hash distributed table
|
||||
SELECT update_distributed_table_colocation('d1', colocate_with => 'append_table');
|
||||
ERROR: relation append_table should be a hash distributed table
|
||||
SELECT update_distributed_table_colocation('range_table', colocate_with => 'd1');
|
||||
ERROR: relation range_table should be a hash distributed table
|
||||
SELECT update_distributed_table_colocation('d1', colocate_with => 'range_table');
|
||||
ERROR: relation range_table should be a hash distributed table
|
||||
-- drop tables to clean test space
|
||||
DROP TABLE table1_groupb;
|
||||
DROP TABLE table2_groupb;
|
||||
|
@ -1055,3 +1456,13 @@ DROP TABLE table1_group_none_3;
|
|||
DROP TABLE table1_group_none;
|
||||
DROP TABLE table2_group_none;
|
||||
DROP TABLE table1_group_default;
|
||||
DROP TABLE d1;
|
||||
DROP TABLE d2;
|
||||
DROP TABLE d3;
|
||||
DROP TABLE d4;
|
||||
DROP TABLE different_d1;
|
||||
DROP TABLE append_table;
|
||||
DROP TABLE range_table;
|
||||
DROP TABLE none;
|
||||
DROP TABLE ref;
|
||||
DROP TABLE local_table;
|
||||
|
|
|
@ -92,6 +92,7 @@ SELECT master_create_distributed_table('table6_append', 'id', 'append');
|
|||
SELECT master_create_empty_shard('table6_append');
|
||||
SELECT master_create_empty_shard('table6_append');
|
||||
|
||||
|
||||
-- make table1_group1 and table2_group1 co-located manually
|
||||
SELECT colocation_test_colocate_tables('table1_group1', 'table2_group1');
|
||||
|
||||
|
@ -430,6 +431,122 @@ SELECT create_distributed_table('table2_groupG', 'id', colocate_with => 'NONE');
|
|||
|
||||
SELECT mark_tables_colocated('table1_groupG', ARRAY['table2_groupG']);
|
||||
|
||||
CREATE TABLE d1(a int, b int);
|
||||
CREATE TABLE d2(a int, b int);
|
||||
CREATE TABLE d3(a int, b int);
|
||||
CREATE TABLE d4(a int, b int);
|
||||
CREATE TABLE different_d1(ch char);
|
||||
CREATE TABLE append_table(a int, b int);
|
||||
CREATE TABLE range_table(a int, b int);
|
||||
-- special keyword none
|
||||
CREATE TABLE none(a int, b int);
|
||||
CREATE TABLE ref(a int);
|
||||
CREATE TABLE local_table(a int);
|
||||
|
||||
SELECT create_distributed_table('d1', 'a');
|
||||
SELECT create_distributed_table('d2', 'a', colocate_with => 'd1');
|
||||
SELECT create_distributed_table('d3', 'a', colocate_with => 'd2');
|
||||
SELECT create_distributed_table('d4', 'a', colocate_with => 'd3');
|
||||
SELECT create_distributed_table('none', 'a', colocate_with => 'd4');
|
||||
SELECT create_distributed_table('different_d1', 'ch');
|
||||
SELECT create_distributed_table('append_table', 'a', 'append');
|
||||
SELECT create_distributed_table('range_table', 'a', 'range');
|
||||
|
||||
|
||||
SELECT create_reference_table('ref');
|
||||
|
||||
|
||||
-- check d1, d2, d3 and d4 has the same colocation id => they are colocated.
|
||||
SELECT get_table_colocation_id('d1');
|
||||
SELECT get_table_colocation_id('d2');
|
||||
SELECT get_table_colocation_id('d3');
|
||||
SELECT get_table_colocation_id('d4');
|
||||
|
||||
|
||||
SELECT tables_colocated('d1', 'd2');
|
||||
SELECT tables_colocated('d2', 'd3');
|
||||
SELECT tables_colocated('d2', 'd4');
|
||||
SELECT tables_colocated('d3', 'd4');
|
||||
SELECT tables_colocated('d1', 'd3');
|
||||
SELECT tables_colocated('d1', 'd4');
|
||||
|
||||
-- break colocation of d2
|
||||
SELECT update_distributed_table_colocation('d2', colocate_with => 'none');
|
||||
|
||||
-- d1 and d3 and d4 should be colocated, d2 should have a new colocation id.
|
||||
SELECT get_table_colocation_id('d1');
|
||||
SELECT get_table_colocation_id('d2');
|
||||
SELECT get_table_colocation_id('d3');
|
||||
SELECT get_table_colocation_id('d4');
|
||||
|
||||
SELECT tables_colocated('d1', 'd2');
|
||||
SELECT tables_colocated('d2', 'd3');
|
||||
SELECT tables_colocated('d1', 'd3');
|
||||
SELECT tables_colocated('d1', 'd4');
|
||||
|
||||
-- break colocation of d2
|
||||
-- update colocation should not error if d2 doesn't have any colocated table.
|
||||
SELECT update_distributed_table_colocation('d2', colocate_with => 'none');
|
||||
|
||||
-- d1 and d3 and d4 should be colocated, d2 should have a new colocation id.
|
||||
SELECT get_table_colocation_id('d1');
|
||||
SELECT get_table_colocation_id('d2');
|
||||
SELECT get_table_colocation_id('d3');
|
||||
SELECT get_table_colocation_id('d4');
|
||||
|
||||
SELECT tables_colocated('d1', 'd2');
|
||||
SELECT tables_colocated('d2', 'd3');
|
||||
SELECT tables_colocated('d1', 'd3');
|
||||
SELECT tables_colocated('d1', 'd4');
|
||||
|
||||
SELECT update_distributed_table_colocation('d3', colocate_with => 'd2');
|
||||
|
||||
-- d1 and d4 should be colocated, d2 and d3 should be colocated.
|
||||
SELECT get_table_colocation_id('d1');
|
||||
SELECT get_table_colocation_id('d2');
|
||||
SELECT get_table_colocation_id('d3');
|
||||
SELECT get_table_colocation_id('d4');
|
||||
|
||||
SELECT tables_colocated('d1', 'd2');
|
||||
SELECT tables_colocated('d2', 'd3');
|
||||
SELECT tables_colocated('d1', 'd3');
|
||||
SELECT tables_colocated('d1', 'd4');
|
||||
|
||||
-- special case, colocate with a table named "none".
|
||||
SELECT update_distributed_table_colocation('d3', colocate_with => '"none"');
|
||||
-- d1, d4, d3 and "none" should be colocated;
|
||||
SELECT get_table_colocation_id('d1');
|
||||
SELECT get_table_colocation_id('d2');
|
||||
SELECT get_table_colocation_id('d3');
|
||||
SELECT get_table_colocation_id('d4');
|
||||
SELECT get_table_colocation_id('none');
|
||||
|
||||
SELECT tables_colocated('d1', 'd2');
|
||||
SELECT tables_colocated('d2', 'd3');
|
||||
SELECT tables_colocated('d1', 'd3');
|
||||
SELECT tables_colocated('d1', 'd4');
|
||||
SELECT tables_colocated('d1', 'none');
|
||||
SELECT tables_colocated('d4', 'none');
|
||||
SELECT tables_colocated('d3', 'none');
|
||||
SELECT tables_colocated('d2', 'none');
|
||||
|
||||
-- make sure reference and local tables return an error.
|
||||
SELECT update_distributed_table_colocation('ref', colocate_with => 'none');
|
||||
SELECT update_distributed_table_colocation('local_table', colocate_with => 'none');
|
||||
|
||||
-- make sure that different types cannot be colocated
|
||||
SELECT update_distributed_table_colocation('different_d1', colocate_with => 'd1');
|
||||
SELECT update_distributed_table_colocation('d1', colocate_with => 'different_d1');
|
||||
|
||||
-- make sure that append distributed tables cannot be colocated
|
||||
SELECT update_distributed_table_colocation('append_table', colocate_with => 'd1');
|
||||
SELECT update_distributed_table_colocation('d1', colocate_with => 'append_table');
|
||||
SELECT update_distributed_table_colocation('range_table', colocate_with => 'd1');
|
||||
SELECT update_distributed_table_colocation('d1', colocate_with => 'range_table');
|
||||
|
||||
|
||||
|
||||
|
||||
-- drop tables to clean test space
|
||||
DROP TABLE table1_groupb;
|
||||
DROP TABLE table2_groupb;
|
||||
|
@ -453,3 +570,15 @@ DROP TABLE table1_group_none_3;
|
|||
DROP TABLE table1_group_none;
|
||||
DROP TABLE table2_group_none;
|
||||
DROP TABLE table1_group_default;
|
||||
DROP TABLE d1;
|
||||
DROP TABLE d2;
|
||||
DROP TABLE d3;
|
||||
DROP TABLE d4;
|
||||
DROP TABLE different_d1;
|
||||
DROP TABLE append_table;
|
||||
DROP TABLE range_table;
|
||||
DROP TABLE none;
|
||||
DROP TABLE ref;
|
||||
DROP TABLE local_table;
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue