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);
|
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
|
* If a partition is being created and if its parent is a distributed
|
||||||
* table, we will distribute this table as well.
|
* table, we will distribute this table as well.
|
||||||
*/
|
*/
|
||||||
if (IsCitusTable(parentRelationId))
|
if (IsCitusTable(parentRelationId))
|
||||||
{
|
{
|
||||||
Oid relationId = RangeVarGetRelid(createStatement->relation, NoLock, missingOk);
|
|
||||||
Var *parentDistributionColumn = DistPartitionKeyOrError(parentRelationId);
|
Var *parentDistributionColumn = DistPartitionKeyOrError(parentRelationId);
|
||||||
char parentDistributionMethod = DISTRIBUTE_BY_HASH;
|
char parentDistributionMethod = DISTRIBUTE_BY_HASH;
|
||||||
char *parentRelationName = generate_qualified_relation_name(parentRelationId);
|
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
|
public.non_distributed_partitioned_table | a | public.non_distributed_partitioned_table_1 | 0 | 10
|
||||||
(6 rows)
|
(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_2008;
|
||||||
ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2009;
|
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_2010;
|
||||||
ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2011;
|
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,
|
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;
|
reference_table, reference_table_2;
|
||||||
RESET SEARCH_PATH;
|
RESET SEARCH_PATH;
|
||||||
-- not timestamp partitioned
|
-- 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;
|
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_2008;
|
||||||
ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2009;
|
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_2010;
|
||||||
ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2011;
|
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,
|
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;
|
reference_table, reference_table_2;
|
||||||
|
|
||||||
RESET SEARCH_PATH;
|
RESET SEARCH_PATH;
|
||||||
|
|
Loading…
Reference in New Issue