mirror of https://github.com/citusdata/citus.git
Add support for ALTER TABLE .. ATTACH PARTITION
parent
1f8c343d15
commit
2f879f0e26
|
@ -42,6 +42,7 @@
|
||||||
#include "distributed/metadata_sync.h"
|
#include "distributed/metadata_sync.h"
|
||||||
#include "distributed/multi_copy.h"
|
#include "distributed/multi_copy.h"
|
||||||
#include "distributed/multi_join_order.h"
|
#include "distributed/multi_join_order.h"
|
||||||
|
#include "distributed/multi_partitioning_utils.h"
|
||||||
#include "distributed/multi_planner.h"
|
#include "distributed/multi_planner.h"
|
||||||
#include "distributed/multi_router_executor.h"
|
#include "distributed/multi_router_executor.h"
|
||||||
#include "distributed/multi_router_planner.h"
|
#include "distributed/multi_router_planner.h"
|
||||||
|
@ -545,6 +546,45 @@ multi_ProcessUtility(PlannedStmt *pstmt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (IsA(parsetree, AlterTableStmt))
|
||||||
|
{
|
||||||
|
AlterTableStmt *alterTableStatement = (AlterTableStmt *) parsetree;
|
||||||
|
List *commandList = alterTableStatement->cmds;
|
||||||
|
ListCell *commandCell = NULL;
|
||||||
|
|
||||||
|
foreach(commandCell, commandList)
|
||||||
|
{
|
||||||
|
AlterTableCmd *alterTableCommand = (AlterTableCmd *) lfirst(commandCell);
|
||||||
|
|
||||||
|
AlterTableType alterTableType = alterTableCommand->subtype;
|
||||||
|
|
||||||
|
if (alterTableType == AT_AttachPartition)
|
||||||
|
{
|
||||||
|
PartitionCmd *partitionCommand = (PartitionCmd *) alterTableCommand->def;
|
||||||
|
|
||||||
|
char *relationName = partitionCommand->name->relname;
|
||||||
|
char *schemaName = partitionCommand->name->schemaname ?
|
||||||
|
partitionCommand->name->schemaname : "public";
|
||||||
|
|
||||||
|
Oid relationId = get_relname_relid(relationName,
|
||||||
|
get_namespace_oid(schemaName, false));
|
||||||
|
Oid parentId = PartitionParentOid(relationId);
|
||||||
|
|
||||||
|
if (IsDistributedTable(parentId))
|
||||||
|
{
|
||||||
|
Var *parentPartitionKey = DistPartitionKey(parentId);
|
||||||
|
char *parentPartitionKeyStr =
|
||||||
|
get_relid_attribute_name(parentId,
|
||||||
|
parentPartitionKey->varattno);
|
||||||
|
|
||||||
|
CreateHashDistributedTable(relationId, parentPartitionKeyStr,
|
||||||
|
get_rel_name(parentId), 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* TODO: fold VACUUM's processing into the above block */
|
/* TODO: fold VACUUM's processing into the above block */
|
||||||
|
@ -1070,6 +1110,30 @@ PlanAlterTableStmt(AlterTableStmt *alterTableStatement, const char *alterTableCo
|
||||||
constraint->skip_validation = true;
|
constraint->skip_validation = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if (PG_VERSION_NUM >= 100000)
|
||||||
|
else if (alterTableType == AT_AttachPartition)
|
||||||
|
{
|
||||||
|
PartitionCmd *partitionCommand = (PartitionCmd *) command->def;
|
||||||
|
|
||||||
|
char *relationName = partitionCommand->name->relname;
|
||||||
|
char *schemaName = partitionCommand->name->schemaname ?
|
||||||
|
partitionCommand->name->schemaname : "public";
|
||||||
|
|
||||||
|
Oid relationId = get_relname_relid(relationName,
|
||||||
|
get_namespace_oid(schemaName, false));
|
||||||
|
Oid parentId = leftRelationId;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do not generate tasks if relation is not distributed and the parent
|
||||||
|
* is distributed. Because, we'll manually convert the relation into
|
||||||
|
* distribtued relation and co-locate with its parent.
|
||||||
|
*/
|
||||||
|
if (!IsDistributedTable(relationId) && IsDistributedTable(parentId))
|
||||||
|
{
|
||||||
|
return NIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ddlJob = palloc0(sizeof(DDLJob));
|
ddlJob = palloc0(sizeof(DDLJob));
|
||||||
|
@ -1813,6 +1877,9 @@ ErrorIfUnsupportedAlterTableStmt(AlterTableStmt *alterTableStatement)
|
||||||
case AT_DropConstraint:
|
case AT_DropConstraint:
|
||||||
case AT_EnableTrigAll:
|
case AT_EnableTrigAll:
|
||||||
case AT_DisableTrigAll:
|
case AT_DisableTrigAll:
|
||||||
|
#if (PG_VERSION_NUM >= 100000)
|
||||||
|
case AT_AttachPartition:
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* We will not perform any special check for ALTER TABLE DROP CONSTRAINT
|
* We will not perform any special check for ALTER TABLE DROP CONSTRAINT
|
||||||
|
|
|
@ -130,6 +130,59 @@ ORDER BY
|
||||||
localhost | 57638 | 8
|
localhost | 57638 | 8
|
||||||
(2 rows)
|
(2 rows)
|
||||||
|
|
||||||
|
-- citus can also support ALTER TABLE .. ATTACH PARTITION
|
||||||
|
-- even if the partition is not distributed
|
||||||
|
CREATE TABLE partitioning_test_2012(id int, time date);
|
||||||
|
ALTER TABLE partitioning_test ATTACH PARTITION partitioning_test_2012 FOR VALUES FROM ('2012-01-01') TO ('2013-01-01');
|
||||||
|
SELECT
|
||||||
|
*
|
||||||
|
FROM
|
||||||
|
pg_dist_partition
|
||||||
|
WHERE
|
||||||
|
logicalrelid IN ('partitioning_test', 'partitioning_test_2009', 'partitioning_test_2010', 'partitioning_test_2011', 'partitioning_test_2012')
|
||||||
|
ORDER BY 1;
|
||||||
|
logicalrelid | partmethod | partkey | colocationid | repmodel
|
||||||
|
------------------------+------------+------------------------------------------------------------------------------------------------------------------------+--------------+----------
|
||||||
|
partitioning_test | h | {VAR :varno 1 :varattno 1 :vartype 23 :vartypmod -1 :varcollid 0 :varlevelsup 0 :varnoold 1 :varoattno 1 :location -1} | 2 | c
|
||||||
|
partitioning_test_2009 | h | {VAR :varno 1 :varattno 1 :vartype 23 :vartypmod -1 :varcollid 0 :varlevelsup 0 :varnoold 1 :varoattno 1 :location -1} | 2 | c
|
||||||
|
partitioning_test_2010 | h | {VAR :varno 1 :varattno 1 :vartype 23 :vartypmod -1 :varcollid 0 :varlevelsup 0 :varnoold 1 :varoattno 1 :location -1} | 2 | c
|
||||||
|
partitioning_test_2011 | h | {VAR :varno 1 :varattno 1 :vartype 23 :vartypmod -1 :varcollid 0 :varlevelsup 0 :varnoold 1 :varoattno 1 :location -1} | 2 | c
|
||||||
|
partitioning_test_2012 | h | {VAR :varno 1 :varattno 1 :vartype 23 :vartypmod -1 :varcollid 0 :varlevelsup 0 :varnoold 1 :varoattno 1 :location -1} | 2 | c
|
||||||
|
(5 rows)
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
logicalrelid, count(*)
|
||||||
|
FROM pg_dist_shard
|
||||||
|
WHERE logicalrelid IN ('partitioning_test', 'partitioning_test_2009', 'partitioning_test_2010', 'partitioning_test_2011', 'partitioning_test_2012')
|
||||||
|
GROUP BY
|
||||||
|
logicalrelid
|
||||||
|
ORDER BY
|
||||||
|
1,2;
|
||||||
|
logicalrelid | count
|
||||||
|
------------------------+-------
|
||||||
|
partitioning_test | 4
|
||||||
|
partitioning_test_2009 | 4
|
||||||
|
partitioning_test_2010 | 4
|
||||||
|
partitioning_test_2011 | 4
|
||||||
|
partitioning_test_2012 | 4
|
||||||
|
(5 rows)
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
nodename, nodeport, count(*)
|
||||||
|
FROM
|
||||||
|
pg_dist_shard_placement
|
||||||
|
WHERE
|
||||||
|
shardid IN (SELECT shardid FROM pg_dist_shard WHERE logicalrelid IN ('partitioning_test', 'partitioning_test_2009', 'partitioning_test_2010', 'partitioning_test_2011', 'partitioning_test_2012') )
|
||||||
|
GROUP BY
|
||||||
|
nodename, nodeport
|
||||||
|
ORDER BY
|
||||||
|
1,2,3;
|
||||||
|
nodename | nodeport | count
|
||||||
|
-----------+----------+-------
|
||||||
|
localhost | 57637 | 10
|
||||||
|
localhost | 57638 | 10
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
-- dropping the parent should CASCADE to the children as well
|
-- dropping the parent should CASCADE to the children as well
|
||||||
DROP TABLE partitioning_test;
|
DROP TABLE partitioning_test;
|
||||||
\d+ partitioning_test*
|
\d+ partitioning_test*
|
||||||
|
|
|
@ -119,9 +119,56 @@ GROUP BY
|
||||||
ORDER BY
|
ORDER BY
|
||||||
1,2,3;
|
1,2,3;
|
||||||
ERROR: relation "partitioning_test" does not exist
|
ERROR: relation "partitioning_test" does not exist
|
||||||
|
LINE 6: ...shardid FROM pg_dist_shard WHERE logicalrelid IN ('partition...
|
||||||
|
^
|
||||||
|
-- citus can also support ALTER TABLE .. ATTACH PARTITION
|
||||||
|
-- even if the partition is not distributed
|
||||||
|
CREATE TABLE partitioning_test_2012(id int, time date);
|
||||||
|
ALTER TABLE partitioning_test ATTACH PARTITION partitioning_test_2012 FOR VALUES FROM ('2012-01-01') TO ('2013-01-01');
|
||||||
|
ERROR: syntax error at or near "ATTACH"
|
||||||
|
LINE 1: ALTER TABLE partitioning_test ATTACH PARTITION partitioning_...
|
||||||
|
^
|
||||||
|
SELECT
|
||||||
|
*
|
||||||
|
FROM
|
||||||
|
pg_dist_partition
|
||||||
|
WHERE
|
||||||
|
logicalrelid IN ('partitioning_test', 'partitioning_test_2009', 'partitioning_test_2010', 'partitioning_test_2011', 'partitioning_test_2012')
|
||||||
|
ORDER BY 1;
|
||||||
|
ERROR: relation "partitioning_test" does not exist
|
||||||
|
LINE 6: logicalrelid IN ('partitioning_test', 'partitioning_test_20...
|
||||||
|
^
|
||||||
|
SELECT
|
||||||
|
logicalrelid, count(*)
|
||||||
|
FROM pg_dist_shard
|
||||||
|
WHERE logicalrelid IN ('partitioning_test', 'partitioning_test_2009', 'partitioning_test_2010', 'partitioning_test_2011', 'partitioning_test_2012')
|
||||||
|
GROUP BY
|
||||||
|
logicalrelid
|
||||||
|
ORDER BY
|
||||||
|
1,2;
|
||||||
|
ERROR: relation "partitioning_test" does not exist
|
||||||
|
LINE 4: WHERE logicalrelid IN ('partitioning_test', 'partitioning_t...
|
||||||
|
^
|
||||||
|
SELECT
|
||||||
|
nodename, nodeport, count(*)
|
||||||
|
FROM
|
||||||
|
pg_dist_shard_placement
|
||||||
|
WHERE
|
||||||
|
shardid IN (SELECT shardid FROM pg_dist_shard WHERE logicalrelid IN ('partitioning_test', 'partitioning_test_2009', 'partitioning_test_2010', 'partitioning_test_2011', 'partitioning_test_2012') )
|
||||||
|
GROUP BY
|
||||||
|
nodename, nodeport
|
||||||
|
ORDER BY
|
||||||
|
1,2,3;
|
||||||
|
ERROR: relation "partitioning_test" does not exist
|
||||||
LINE 6: ...shardid FROM pg_dist_shard WHERE logicalrelid IN ('partition...
|
LINE 6: ...shardid FROM pg_dist_shard WHERE logicalrelid IN ('partition...
|
||||||
^
|
^
|
||||||
-- dropping the parent should CASCADE to the children as well
|
-- dropping the parent should CASCADE to the children as well
|
||||||
DROP TABLE partitioning_test;
|
DROP TABLE partitioning_test;
|
||||||
ERROR: table "partitioning_test" does not exist
|
ERROR: table "partitioning_test" does not exist
|
||||||
\d+ partitioning_test*
|
\d+ partitioning_test*
|
||||||
|
Table "public.partitioning_test_2012"
|
||||||
|
Column | Type | Modifiers | Storage | Stats target | Description
|
||||||
|
--------+---------+-----------+---------+--------------+-------------
|
||||||
|
id | integer | | plain | |
|
||||||
|
time | date | | plain | |
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,41 @@ GROUP BY
|
||||||
ORDER BY
|
ORDER BY
|
||||||
1,2,3;
|
1,2,3;
|
||||||
|
|
||||||
|
|
||||||
|
-- citus can also support ALTER TABLE .. ATTACH PARTITION
|
||||||
|
-- even if the partition is not distributed
|
||||||
|
CREATE TABLE partitioning_test_2012(id int, time date);
|
||||||
|
ALTER TABLE partitioning_test ATTACH PARTITION partitioning_test_2012 FOR VALUES FROM ('2012-01-01') TO ('2013-01-01');
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
*
|
||||||
|
FROM
|
||||||
|
pg_dist_partition
|
||||||
|
WHERE
|
||||||
|
logicalrelid IN ('partitioning_test', 'partitioning_test_2009', 'partitioning_test_2010', 'partitioning_test_2011', 'partitioning_test_2012')
|
||||||
|
ORDER BY 1;
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
logicalrelid, count(*)
|
||||||
|
FROM pg_dist_shard
|
||||||
|
WHERE logicalrelid IN ('partitioning_test', 'partitioning_test_2009', 'partitioning_test_2010', 'partitioning_test_2011', 'partitioning_test_2012')
|
||||||
|
GROUP BY
|
||||||
|
logicalrelid
|
||||||
|
ORDER BY
|
||||||
|
1,2;
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
nodename, nodeport, count(*)
|
||||||
|
FROM
|
||||||
|
pg_dist_shard_placement
|
||||||
|
WHERE
|
||||||
|
shardid IN (SELECT shardid FROM pg_dist_shard WHERE logicalrelid IN ('partitioning_test', 'partitioning_test_2009', 'partitioning_test_2010', 'partitioning_test_2011', 'partitioning_test_2012') )
|
||||||
|
GROUP BY
|
||||||
|
nodename, nodeport
|
||||||
|
ORDER BY
|
||||||
|
1,2,3;
|
||||||
|
|
||||||
|
|
||||||
-- dropping the parent should CASCADE to the children as well
|
-- dropping the parent should CASCADE to the children as well
|
||||||
DROP TABLE partitioning_test;
|
DROP TABLE partitioning_test;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue