mirror of https://github.com/citusdata/citus.git
Skip 'already exists' in CREATE TABLE IF NOT EXISTS PARTITION OF (#4507)
* Just skip 'already exists' in CT IF NOT EXISTS PARTITION OF * Generalize to tables that are not already distributed partitionspull/4522/head
parent
f1ecbc3a53
commit
7124a7715d
|
@ -283,13 +283,40 @@ PostprocessCreateTableStmtPartitionOf(CreateStmt *createStatement, const
|
|||
|
||||
Assert(parentRelationId != InvalidOid);
|
||||
|
||||
Oid relationId = RangeVarGetRelid(createStatement->relation, NoLock, missingOk);
|
||||
|
||||
/*
|
||||
* In case of an IF NOT EXISTS statement, Postgres lets it pass through the
|
||||
* standardProcess_Utility, and gets into this Post-process hook by
|
||||
* ignoring the statement if the table already exists. Thus, we need to make
|
||||
* sure Citus behaves like plain PG in case the relation already exists.
|
||||
*/
|
||||
if (createStatement->if_not_exists)
|
||||
{
|
||||
if (IsCitusTable(relationId))
|
||||
{
|
||||
/*
|
||||
* Ignore if the relation is already distributed.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
else if (!PartitionTable(relationId) ||
|
||||
PartitionParentOid(relationId) != parentRelationId)
|
||||
{
|
||||
/*
|
||||
* Ignore if the relation is not a partition, or if that
|
||||
* partition's parent is not the current parent from parentRelationId
|
||||
*/
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If a partition is being created and if its parent is a distributed
|
||||
* table, we will distribute this table as well.
|
||||
*/
|
||||
if (IsCitusTable(parentRelationId))
|
||||
{
|
||||
Oid relationId = RangeVarGetRelid(createStatement->relation, NoLock, missingOk);
|
||||
Var *parentDistributionColumn = DistPartitionKeyOrError(parentRelationId);
|
||||
char parentDistributionMethod = DISTRIBUTE_BY_HASH;
|
||||
char *parentRelationName = generate_qualified_relation_name(parentRelationId);
|
||||
|
|
|
@ -1958,12 +1958,43 @@ SELECT parent_table, partition_column, partition, from_value, to_value FROM time
|
|||
public.non_distributed_partitioned_table | a | public.non_distributed_partitioned_table_1 | 0 | 10
|
||||
(6 rows)
|
||||
|
||||
-- create the same partition to verify it behaves like in plain PG
|
||||
CREATE TABLE partitioning_test_2011 PARTITION OF partitioning_test FOR VALUES FROM ('2011-01-01') TO ('2012-01-01');
|
||||
ERROR: relation "partitioning_test_2011" already exists
|
||||
CREATE TABLE IF NOT EXISTS partitioning_test_2011 PARTITION OF partitioning_test FOR VALUES FROM ('2011-01-01') TO ('2012-01-01');
|
||||
NOTICE: relation "partitioning_test_2011" already exists, skipping
|
||||
-- verify we can create a partition that doesn't already exist with IF NOT EXISTS
|
||||
CREATE TABLE IF NOT EXISTS partitioning_test_2013 PARTITION OF partitioning_test FOR VALUES FROM ('2013-01-01') TO ('2014-01-01');
|
||||
SELECT logicalrelid FROM pg_dist_partition WHERE logicalrelid IN ('partitioning_test', 'partitioning_test_2013') ORDER BY 1;
|
||||
logicalrelid
|
||||
---------------------------------------------------------------------
|
||||
partitioning_test
|
||||
partitioning_test_2013
|
||||
(2 rows)
|
||||
|
||||
-- create the same table but that is not a partition and verify it behaves like in plain PG
|
||||
CREATE TABLE not_partition(time date);
|
||||
CREATE TABLE not_partition PARTITION OF partitioning_test FOR VALUES FROM ('2011-01-01') TO ('2012-01-01');
|
||||
ERROR: relation "not_partition" already exists
|
||||
CREATE TABLE IF NOT EXISTS not_partition PARTITION OF partitioning_test FOR VALUES FROM ('2011-01-01') TO ('2012-01-01');
|
||||
NOTICE: relation "not_partition" already exists, skipping
|
||||
DROP TABLE not_partition;
|
||||
-- verify it skips when the partition with the same name belongs to another table
|
||||
CREATE TABLE another_table(id int, time date) PARTITION BY RANGE (time);
|
||||
CREATE TABLE partition_of_other_table PARTITION OF another_table FOR VALUES FROM ('2014-01-01') TO ('2015-01-01');
|
||||
CREATE TABLE partition_of_other_table PARTITION OF partitioning_test FOR VALUES FROM ('2014-01-01') TO ('2015-01-01');
|
||||
ERROR: relation "partition_of_other_table" already exists
|
||||
CREATE TABLE IF NOT EXISTS partition_of_other_table PARTITION OF partitioning_test FOR VALUES FROM ('2014-01-01') TO ('2015-01-01');
|
||||
NOTICE: relation "partition_of_other_table" already exists, skipping
|
||||
ALTER TABLE another_table DETACH PARTITION partition_of_other_table;
|
||||
DROP TABLE another_table, partition_of_other_table;
|
||||
ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2008;
|
||||
ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2009;
|
||||
ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2010;
|
||||
ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2011;
|
||||
ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2013;
|
||||
DROP TABLE partitioning_test, partitioning_test_2008, partitioning_test_2009,
|
||||
partitioning_test_2010, partitioning_test_2011,
|
||||
partitioning_test_2010, partitioning_test_2011, partitioning_test_2013,
|
||||
reference_table, reference_table_2;
|
||||
RESET SEARCH_PATH;
|
||||
-- not timestamp partitioned
|
||||
|
|
|
@ -1155,13 +1155,36 @@ ALTER TABLE partitioning_test ATTACH PARTITION partitioning_test_2011
|
|||
|
||||
SELECT parent_table, partition_column, partition, from_value, to_value FROM time_partitions;
|
||||
|
||||
-- create the same partition to verify it behaves like in plain PG
|
||||
CREATE TABLE partitioning_test_2011 PARTITION OF partitioning_test FOR VALUES FROM ('2011-01-01') TO ('2012-01-01');
|
||||
CREATE TABLE IF NOT EXISTS partitioning_test_2011 PARTITION OF partitioning_test FOR VALUES FROM ('2011-01-01') TO ('2012-01-01');
|
||||
|
||||
-- verify we can create a partition that doesn't already exist with IF NOT EXISTS
|
||||
CREATE TABLE IF NOT EXISTS partitioning_test_2013 PARTITION OF partitioning_test FOR VALUES FROM ('2013-01-01') TO ('2014-01-01');
|
||||
SELECT logicalrelid FROM pg_dist_partition WHERE logicalrelid IN ('partitioning_test', 'partitioning_test_2013') ORDER BY 1;
|
||||
|
||||
-- create the same table but that is not a partition and verify it behaves like in plain PG
|
||||
CREATE TABLE not_partition(time date);
|
||||
CREATE TABLE not_partition PARTITION OF partitioning_test FOR VALUES FROM ('2011-01-01') TO ('2012-01-01');
|
||||
CREATE TABLE IF NOT EXISTS not_partition PARTITION OF partitioning_test FOR VALUES FROM ('2011-01-01') TO ('2012-01-01');
|
||||
DROP TABLE not_partition;
|
||||
|
||||
-- verify it skips when the partition with the same name belongs to another table
|
||||
CREATE TABLE another_table(id int, time date) PARTITION BY RANGE (time);
|
||||
CREATE TABLE partition_of_other_table PARTITION OF another_table FOR VALUES FROM ('2014-01-01') TO ('2015-01-01');
|
||||
CREATE TABLE partition_of_other_table PARTITION OF partitioning_test FOR VALUES FROM ('2014-01-01') TO ('2015-01-01');
|
||||
CREATE TABLE IF NOT EXISTS partition_of_other_table PARTITION OF partitioning_test FOR VALUES FROM ('2014-01-01') TO ('2015-01-01');
|
||||
ALTER TABLE another_table DETACH PARTITION partition_of_other_table;
|
||||
DROP TABLE another_table, partition_of_other_table;
|
||||
|
||||
ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2008;
|
||||
ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2009;
|
||||
ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2010;
|
||||
ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2011;
|
||||
ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2013;
|
||||
|
||||
DROP TABLE partitioning_test, partitioning_test_2008, partitioning_test_2009,
|
||||
partitioning_test_2010, partitioning_test_2011,
|
||||
partitioning_test_2010, partitioning_test_2011, partitioning_test_2013,
|
||||
reference_table, reference_table_2;
|
||||
|
||||
RESET SEARCH_PATH;
|
||||
|
|
Loading…
Reference in New Issue