mirror of https://github.com/citusdata/citus.git
Merge pull request #749 from robin900/forbid-exclusion-constraints
Handle EXCLUDE constraints properly on distributed tablespull/782/merge
commit
70fd42c41c
|
@ -29,6 +29,7 @@
|
|||
#include "distributed/metadata_cache.h"
|
||||
#include "distributed/pg_dist_partition.h"
|
||||
#include "executor/spi.h"
|
||||
#include "distributed/multi_logical_planner.h"
|
||||
#include "nodes/execnodes.h"
|
||||
#include "nodes/nodeFuncs.h"
|
||||
#include "nodes/pg_list.h"
|
||||
|
@ -186,10 +187,10 @@ master_create_distributed_table(PG_FUNCTION_ARGS)
|
|||
}
|
||||
|
||||
/*
|
||||
* Do not allow UNIQUE constraint and/or PRIMARY KEY on append partitioned tables,
|
||||
* Forbid UNIQUE, PRIMARY KEY, or EXCLUDE constraints on append partitioned tables,
|
||||
* since currently there is no way of enforcing uniqueness for overlapping shards.
|
||||
*
|
||||
* Similarly, do not allow UNIQUE constraint and/or PRIMARY KEY if it does not
|
||||
* Similarly, do not allow such constraints it they do not
|
||||
* include partition column. This check is important for two reasons. First,
|
||||
* currently Citus does not enforce uniqueness constraint on multiple shards.
|
||||
* Second, INSERT INTO .. ON CONFLICT (i.e., UPSERT) queries can be executed with no
|
||||
|
@ -209,23 +210,25 @@ master_create_distributed_table(PG_FUNCTION_ARGS)
|
|||
/* extract index key information from the index's pg_index info */
|
||||
indexInfo = BuildIndexInfo(indexDesc);
|
||||
|
||||
/* only check unique indexes */
|
||||
if (indexInfo->ii_Unique == false)
|
||||
/* only check unique indexes and exclusion constraints. */
|
||||
if (indexInfo->ii_Unique == false && indexInfo->ii_ExclusionOps == NULL)
|
||||
{
|
||||
index_close(indexDesc, NoLock);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Citus cannot enforce uniqueness constraints with overlapping shards. Thus,
|
||||
* emit a warning for unique indexes on append partitioned tables.
|
||||
* Citus cannot enforce uniqueness/exclusion constraints with overlapping shards.
|
||||
* Thus, emit a warning for unique indexes and exclusion constraints on
|
||||
* append partitioned tables.
|
||||
*/
|
||||
if (distributionMethod == DISTRIBUTE_BY_APPEND)
|
||||
{
|
||||
ereport(WARNING, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("table \"%s\" has a unique constraint",
|
||||
errmsg("table \"%s\" has a UNIQUE or EXCLUDE constraint",
|
||||
distributedRelationName),
|
||||
errdetail("Unique constraints and primary keys on "
|
||||
errdetail("UNIQUE constraints, EXCLUDE constraints, "
|
||||
"and PRIMARY KEYs on "
|
||||
"append-partitioned tables cannot be enforced."),
|
||||
errhint("Consider using hash partitioning.")));
|
||||
}
|
||||
|
@ -236,7 +239,21 @@ master_create_distributed_table(PG_FUNCTION_ARGS)
|
|||
for (attributeIndex = 0; attributeIndex < attributeCount; attributeIndex++)
|
||||
{
|
||||
AttrNumber attributeNumber = attributeNumberArray[attributeIndex];
|
||||
if (distributionColumn->varattno == attributeNumber)
|
||||
bool uniqueConstraint = false;
|
||||
bool exclusionConstraintWithEquality = false;
|
||||
|
||||
if (distributionColumn->varattno != attributeNumber)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
uniqueConstraint = indexInfo->ii_Unique;
|
||||
exclusionConstraintWithEquality = (indexInfo->ii_ExclusionOps != NULL &&
|
||||
OperatorImplementsEquality(
|
||||
indexInfo->ii_ExclusionOps[
|
||||
attributeIndex]));
|
||||
|
||||
if (uniqueConstraint || exclusionConstraintWithEquality)
|
||||
{
|
||||
hasDistributionColumn = true;
|
||||
break;
|
||||
|
@ -248,9 +265,10 @@ master_create_distributed_table(PG_FUNCTION_ARGS)
|
|||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("cannot distribute relation: \"%s\"",
|
||||
distributedRelationName),
|
||||
errdetail("Distributed relations cannot have "
|
||||
"UNIQUE constraints or PRIMARY KEYs that do not "
|
||||
"include the partition column.")));
|
||||
errdetail("Distributed relations cannot have UNIQUE, "
|
||||
"EXCLUDE, or PRIMARY KEY constraints that do not "
|
||||
"include the partition column (with an equality "
|
||||
"operator if EXCLUDE).")));
|
||||
}
|
||||
|
||||
index_close(indexDesc, NoLock);
|
||||
|
|
|
@ -640,15 +640,15 @@ GetTableDDLEvents(Oid relationId)
|
|||
|
||||
/*
|
||||
* A primary key index is always created by a constraint statement.
|
||||
* A unique key index is created by a constraint if and only if the
|
||||
* index has a corresponding constraint entry in pg_depend. Any other
|
||||
* index form is never associated with a constraint.
|
||||
* A unique key index or exclusion index is created by a constraint
|
||||
* if and only if the index has a corresponding constraint entry in pg_depend.
|
||||
* Any other index form is never associated with a constraint.
|
||||
*/
|
||||
if (indexForm->indisprimary)
|
||||
{
|
||||
isConstraint = true;
|
||||
}
|
||||
else if (indexForm->indisunique)
|
||||
else if (indexForm->indisunique || indexForm->indisexclusion)
|
||||
{
|
||||
Oid constraintId = get_index_constraint(indexId);
|
||||
isConstraint = OidIsValid(constraintId);
|
||||
|
|
|
@ -423,7 +423,8 @@ TypeAddIndexConstraint(const AlterTableCmd *command)
|
|||
{
|
||||
Constraint *constraint = (Constraint *) command->def;
|
||||
if (constraint->contype == CONSTR_PRIMARY ||
|
||||
constraint->contype == CONSTR_UNIQUE)
|
||||
constraint->contype == CONSTR_UNIQUE ||
|
||||
constraint->contype == CONSTR_EXCLUSION)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -466,7 +467,7 @@ TypeDropIndexConstraint(const AlterTableCmd *command,
|
|||
* At this stage, our only option is performing a relationId lookup. We
|
||||
* first find the relationId, and then scan the pg_constraints system
|
||||
* catalog using this relationId. Finally, we check if the passed in
|
||||
* constraint is for a primary key or unique index.
|
||||
* constraint is for a primary key, unique, or exclusion index.
|
||||
*/
|
||||
relationId = RangeVarGetRelid(relation, NoLock, failOK);
|
||||
if (!OidIsValid(relationId))
|
||||
|
@ -497,7 +498,8 @@ TypeDropIndexConstraint(const AlterTableCmd *command,
|
|||
{
|
||||
/* we found the constraint, now check if it is for an index */
|
||||
if (constraintForm->contype == CONSTRAINT_PRIMARY ||
|
||||
constraintForm->contype == CONSTRAINT_UNIQUE)
|
||||
constraintForm->contype == CONSTRAINT_UNIQUE ||
|
||||
constraintForm->contype == CONSTRAINT_EXCLUSION)
|
||||
{
|
||||
indexConstraint = true;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#define SHARD_NAME_SEPARATOR '_'
|
||||
#define INVALID_SHARD_ID 0
|
||||
|
||||
|
||||
/*
|
||||
* RelayFileState represents last known states of shards on a given node. We
|
||||
* currently only have shards in finalized or cached state; and set this state
|
||||
|
|
|
@ -24,8 +24,8 @@ CREATE TABLE lineitem (
|
|||
l_comment varchar(44) not null,
|
||||
PRIMARY KEY(l_orderkey, l_linenumber) );
|
||||
SELECT master_create_distributed_table('lineitem', 'l_orderkey', 'append');
|
||||
WARNING: table "lineitem" has a unique constraint
|
||||
DETAIL: Unique constraints and primary keys on append-partitioned tables cannot be enforced.
|
||||
WARNING: table "lineitem" has a UNIQUE or EXCLUDE constraint
|
||||
DETAIL: UNIQUE constraints, EXCLUDE constraints, and PRIMARY KEYs on append-partitioned tables cannot be enforced.
|
||||
HINT: Consider using hash partitioning.
|
||||
master_create_distributed_table
|
||||
---------------------------------
|
||||
|
@ -47,8 +47,8 @@ CREATE TABLE orders (
|
|||
o_comment varchar(79) not null,
|
||||
PRIMARY KEY(o_orderkey) );
|
||||
SELECT master_create_distributed_table('orders', 'o_orderkey', 'append');
|
||||
WARNING: table "orders" has a unique constraint
|
||||
DETAIL: Unique constraints and primary keys on append-partitioned tables cannot be enforced.
|
||||
WARNING: table "orders" has a UNIQUE or EXCLUDE constraint
|
||||
DETAIL: UNIQUE constraints, EXCLUDE constraints, and PRIMARY KEYs on append-partitioned tables cannot be enforced.
|
||||
HINT: Consider using hash partitioning.
|
||||
master_create_distributed_table
|
||||
---------------------------------
|
||||
|
@ -119,86 +119,3 @@ SELECT master_create_distributed_table('supplier', 's_suppkey', 'append');
|
|||
|
||||
(1 row)
|
||||
|
||||
-- now test that Citus cannot distribute unique constraints that do not include
|
||||
-- the partition column
|
||||
CREATE TABLE primary_key_on_non_part_col
|
||||
(
|
||||
partition_col integer,
|
||||
other_col integer PRIMARY KEY
|
||||
);
|
||||
SELECT master_create_distributed_table('primary_key_on_non_part_col', 'partition_col', 'hash');
|
||||
ERROR: cannot distribute relation: "primary_key_on_non_part_col"
|
||||
DETAIL: Distributed relations cannot have UNIQUE constraints or PRIMARY KEYs that do not include the partition column.
|
||||
CREATE TABLE unique_const_on_non_part_col
|
||||
(
|
||||
partition_col integer,
|
||||
other_col integer UNIQUE
|
||||
);
|
||||
SELECT master_create_distributed_table('primary_key_on_non_part_col', 'partition_col', 'hash');
|
||||
ERROR: cannot distribute relation: "primary_key_on_non_part_col"
|
||||
DETAIL: Distributed relations cannot have UNIQUE constraints or PRIMARY KEYs that do not include the partition column.
|
||||
-- now show that Citus can distribute unique constrints that include
|
||||
-- the partition column
|
||||
CREATE TABLE primary_key_on_part_col
|
||||
(
|
||||
partition_col integer PRIMARY KEY,
|
||||
other_col integer
|
||||
);
|
||||
SELECT master_create_distributed_table('primary_key_on_part_col', 'partition_col', 'hash');
|
||||
master_create_distributed_table
|
||||
---------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
CREATE TABLE unique_const_on_part_col
|
||||
(
|
||||
partition_col integer UNIQUE,
|
||||
other_col integer
|
||||
);
|
||||
SELECT master_create_distributed_table('unique_const_on_part_col', 'partition_col', 'hash');
|
||||
master_create_distributed_table
|
||||
---------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
CREATE TABLE unique_const_on_two_columns
|
||||
(
|
||||
partition_col integer,
|
||||
other_col integer,
|
||||
UNIQUE (partition_col, other_col)
|
||||
);
|
||||
SELECT master_create_distributed_table('unique_const_on_two_columns', 'partition_col', 'hash');
|
||||
master_create_distributed_table
|
||||
---------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
CREATE TABLE unique_const_append_partitioned_tables
|
||||
(
|
||||
partition_col integer UNIQUE,
|
||||
other_col integer
|
||||
);
|
||||
SELECT master_create_distributed_table('unique_const_append_partitioned_tables', 'partition_col', 'append');
|
||||
WARNING: table "unique_const_append_partitioned_tables" has a unique constraint
|
||||
DETAIL: Unique constraints and primary keys on append-partitioned tables cannot be enforced.
|
||||
HINT: Consider using hash partitioning.
|
||||
master_create_distributed_table
|
||||
---------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
CREATE TABLE unique_const_range_partitioned_tables
|
||||
(
|
||||
partition_col integer UNIQUE,
|
||||
other_col integer
|
||||
);
|
||||
SELECT master_create_distributed_table('unique_const_range_partitioned_tables', 'partition_col', 'range');
|
||||
master_create_distributed_table
|
||||
---------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- drop unnecessary tables
|
||||
DROP TABLE primary_key_on_non_part_col, unique_const_on_non_part_col CASCADE;
|
||||
DROP TABLE primary_key_on_part_col, unique_const_on_part_col, unique_const_on_two_columns CASCADE;
|
||||
DROP TABLE unique_const_range_partitioned_tables CASCADE;
|
||||
|
|
|
@ -0,0 +1,461 @@
|
|||
--
|
||||
-- MULTI_CREATE_TABLE_CONSTRAINTS
|
||||
--
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 365000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 365000;
|
||||
-- test that Citus forbids unique and EXCLUDE constraints on append-partitioned tables.
|
||||
CREATE TABLE uniq_cns_append_tables
|
||||
(
|
||||
partition_col integer UNIQUE,
|
||||
other_col integer
|
||||
);
|
||||
SELECT master_create_distributed_table('uniq_cns_append_tables', 'partition_col', 'append');
|
||||
WARNING: table "uniq_cns_append_tables" has a UNIQUE or EXCLUDE constraint
|
||||
DETAIL: UNIQUE constraints, EXCLUDE constraints, and PRIMARY KEYs on append-partitioned tables cannot be enforced.
|
||||
HINT: Consider using hash partitioning.
|
||||
master_create_distributed_table
|
||||
---------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
CREATE TABLE excl_cns_append_tables
|
||||
(
|
||||
partition_col integer,
|
||||
other_col integer,
|
||||
EXCLUDE (partition_col WITH =)
|
||||
);
|
||||
SELECT master_create_distributed_table('excl_cns_append_tables', 'partition_col', 'append');
|
||||
WARNING: table "excl_cns_append_tables" has a UNIQUE or EXCLUDE constraint
|
||||
DETAIL: UNIQUE constraints, EXCLUDE constraints, and PRIMARY KEYs on append-partitioned tables cannot be enforced.
|
||||
HINT: Consider using hash partitioning.
|
||||
master_create_distributed_table
|
||||
---------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- test that Citus cannot distribute unique constraints that do not include
|
||||
-- the partition column on hash-partitioned tables.
|
||||
CREATE TABLE pk_on_non_part_col
|
||||
(
|
||||
partition_col integer,
|
||||
other_col integer PRIMARY KEY
|
||||
);
|
||||
SELECT master_create_distributed_table('pk_on_non_part_col', 'partition_col', 'hash');
|
||||
ERROR: cannot distribute relation: "pk_on_non_part_col"
|
||||
DETAIL: Distributed relations cannot have UNIQUE, EXCLUDE, or PRIMARY KEY constraints that do not include the partition column (with an equality operator if EXCLUDE).
|
||||
CREATE TABLE uq_on_non_part_col
|
||||
(
|
||||
partition_col integer,
|
||||
other_col integer UNIQUE
|
||||
);
|
||||
SELECT master_create_distributed_table('uq_on_non_part_col', 'partition_col', 'hash');
|
||||
ERROR: cannot distribute relation: "uq_on_non_part_col"
|
||||
DETAIL: Distributed relations cannot have UNIQUE, EXCLUDE, or PRIMARY KEY constraints that do not include the partition column (with an equality operator if EXCLUDE).
|
||||
CREATE TABLE ex_on_non_part_col
|
||||
(
|
||||
partition_col integer,
|
||||
other_col integer,
|
||||
EXCLUDE (other_col WITH =)
|
||||
);
|
||||
SELECT master_create_distributed_table('ex_on_non_part_col', 'partition_col', 'hash');
|
||||
ERROR: cannot distribute relation: "ex_on_non_part_col"
|
||||
DETAIL: Distributed relations cannot have UNIQUE, EXCLUDE, or PRIMARY KEY constraints that do not include the partition column (with an equality operator if EXCLUDE).
|
||||
-- now show that Citus can distribute unique and EXCLUDE constraints that
|
||||
-- include the partition column for hash-partitioned tables.
|
||||
-- However, EXCLUDE constraints must include the partition column with
|
||||
-- an equality operator.
|
||||
-- These tests are for UNNAMED constraints.
|
||||
CREATE TABLE pk_on_part_col
|
||||
(
|
||||
partition_col integer PRIMARY KEY,
|
||||
other_col integer
|
||||
);
|
||||
SELECT master_create_distributed_table('pk_on_part_col', 'partition_col', 'hash');
|
||||
master_create_distributed_table
|
||||
---------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
CREATE TABLE uq_part_col
|
||||
(
|
||||
partition_col integer UNIQUE,
|
||||
other_col integer
|
||||
);
|
||||
SELECT master_create_distributed_table('uq_part_col', 'partition_col', 'hash');
|
||||
master_create_distributed_table
|
||||
---------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
CREATE TABLE uq_two_columns
|
||||
(
|
||||
partition_col integer,
|
||||
other_col integer,
|
||||
UNIQUE (partition_col, other_col)
|
||||
);
|
||||
SELECT master_create_distributed_table('uq_two_columns', 'partition_col', 'hash');
|
||||
master_create_distributed_table
|
||||
---------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT master_create_worker_shards('uq_two_columns', '4', '2');
|
||||
master_create_worker_shards
|
||||
-----------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
INSERT INTO uq_two_columns (partition_col, other_col) VALUES (1,1);
|
||||
INSERT INTO uq_two_columns (partition_col, other_col) VALUES (1,1);
|
||||
ERROR: duplicate key value violates unique constraint "uq_two_columns_partition_col_other_col_key_365000"
|
||||
DETAIL: Key (partition_col, other_col)=(1, 1) already exists.
|
||||
CONTEXT: while executing command on localhost:57637
|
||||
CREATE TABLE ex_on_part_col
|
||||
(
|
||||
partition_col integer,
|
||||
other_col integer,
|
||||
EXCLUDE (partition_col WITH =)
|
||||
);
|
||||
SELECT master_create_distributed_table('ex_on_part_col', 'partition_col', 'hash');
|
||||
master_create_distributed_table
|
||||
---------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT master_create_worker_shards('ex_on_part_col', '4', '2');
|
||||
master_create_worker_shards
|
||||
-----------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
INSERT INTO ex_on_part_col (partition_col, other_col) VALUES (1,1);
|
||||
INSERT INTO ex_on_part_col (partition_col, other_col) VALUES (1,2);
|
||||
ERROR: conflicting key value violates exclusion constraint "ex_on_part_col_partition_col_excl_365004"
|
||||
DETAIL: Key (partition_col)=(1) conflicts with existing key (partition_col)=(1).
|
||||
CONTEXT: while executing command on localhost:57637
|
||||
CREATE TABLE ex_on_two_columns
|
||||
(
|
||||
partition_col integer,
|
||||
other_col integer,
|
||||
EXCLUDE (partition_col WITH =, other_col WITH =)
|
||||
);
|
||||
SELECT master_create_distributed_table('ex_on_two_columns', 'partition_col', 'hash');
|
||||
master_create_distributed_table
|
||||
---------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT master_create_worker_shards('ex_on_two_columns', '4', '2');
|
||||
master_create_worker_shards
|
||||
-----------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
INSERT INTO ex_on_two_columns (partition_col, other_col) VALUES (1,1);
|
||||
INSERT INTO ex_on_two_columns (partition_col, other_col) VALUES (1,1);
|
||||
ERROR: conflicting key value violates exclusion constraint "ex_on_two_columns_partition_col_other_col_excl_365008"
|
||||
DETAIL: Key (partition_col, other_col)=(1, 1) conflicts with existing key (partition_col, other_col)=(1, 1).
|
||||
CONTEXT: while executing command on localhost:57637
|
||||
CREATE TABLE ex_wrong_operator
|
||||
(
|
||||
partition_col tsrange,
|
||||
other_col tsrange,
|
||||
EXCLUDE USING gist (other_col WITH =, partition_col WITH &&)
|
||||
);
|
||||
SELECT master_create_distributed_table('ex_wrong_operator', 'partition_col', 'hash');
|
||||
ERROR: cannot distribute relation: "ex_wrong_operator"
|
||||
DETAIL: Distributed relations cannot have UNIQUE, EXCLUDE, or PRIMARY KEY constraints that do not include the partition column (with an equality operator if EXCLUDE).
|
||||
CREATE TABLE ex_overlaps
|
||||
(
|
||||
partition_col tsrange,
|
||||
other_col tsrange,
|
||||
EXCLUDE USING gist (other_col WITH &&, partition_col WITH =)
|
||||
);
|
||||
SELECT master_create_distributed_table('ex_overlaps', 'partition_col', 'hash');
|
||||
master_create_distributed_table
|
||||
---------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT master_create_worker_shards('ex_overlaps', '4', '2');
|
||||
master_create_worker_shards
|
||||
-----------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
INSERT INTO ex_overlaps (partition_col, other_col) VALUES ('[2016-01-01 00:00:00, 2016-02-01 00:00:00]', '[2016-01-01 00:00:00, 2016-02-01 00:00:00]');
|
||||
INSERT INTO ex_overlaps (partition_col, other_col) VALUES ('[2016-01-01 00:00:00, 2016-02-01 00:00:00]', '[2016-01-15 00:00:00, 2016-02-01 00:00:00]');
|
||||
ERROR: conflicting key value violates exclusion constraint "ex_overlaps_other_col_partition_col_excl_365015"
|
||||
DETAIL: Key (other_col, partition_col)=(["2016-01-15 00:00:00","2016-02-01 00:00:00"], ["2016-01-01 00:00:00","2016-02-01 00:00:00"]) conflicts with existing key (other_col, partition_col)=(["2016-01-01 00:00:00","2016-02-01 00:00:00"], ["2016-01-01 00:00:00","2016-02-01 00:00:00"]).
|
||||
CONTEXT: while executing command on localhost:57638
|
||||
-- now show that Citus can distribute unique and EXCLUDE constraints that
|
||||
-- include the partition column, for hash-partitioned tables.
|
||||
-- However, EXCLUDE constraints must include the partition column with
|
||||
-- an equality operator.
|
||||
-- These tests are for NAMED constraints.
|
||||
CREATE TABLE pk_on_part_col_named
|
||||
(
|
||||
partition_col integer CONSTRAINT pk_on_part_col_named_pk PRIMARY KEY,
|
||||
other_col integer
|
||||
);
|
||||
SELECT master_create_distributed_table('pk_on_part_col_named', 'partition_col', 'hash');
|
||||
master_create_distributed_table
|
||||
---------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
CREATE TABLE uq_part_col_named
|
||||
(
|
||||
partition_col integer CONSTRAINT uq_part_col_named_uniq UNIQUE,
|
||||
other_col integer
|
||||
);
|
||||
SELECT master_create_distributed_table('uq_part_col_named', 'partition_col', 'hash');
|
||||
master_create_distributed_table
|
||||
---------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
CREATE TABLE uq_two_columns_named
|
||||
(
|
||||
partition_col integer,
|
||||
other_col integer,
|
||||
CONSTRAINT uq_two_columns_named_uniq UNIQUE (partition_col, other_col)
|
||||
);
|
||||
SELECT master_create_distributed_table('uq_two_columns_named', 'partition_col', 'hash');
|
||||
master_create_distributed_table
|
||||
---------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT master_create_worker_shards('uq_two_columns_named', '4', '2');
|
||||
master_create_worker_shards
|
||||
-----------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
INSERT INTO uq_two_columns_named (partition_col, other_col) VALUES (1,1);
|
||||
INSERT INTO uq_two_columns_named (partition_col, other_col) VALUES (1,1);
|
||||
ERROR: duplicate key value violates unique constraint "uq_two_columns_named_uniq_365016"
|
||||
DETAIL: Key (partition_col, other_col)=(1, 1) already exists.
|
||||
CONTEXT: while executing command on localhost:57637
|
||||
CREATE TABLE ex_on_part_col_named
|
||||
(
|
||||
partition_col integer,
|
||||
other_col integer,
|
||||
CONSTRAINT ex_on_part_col_named_exclude EXCLUDE (partition_col WITH =)
|
||||
);
|
||||
SELECT master_create_distributed_table('ex_on_part_col_named', 'partition_col', 'hash');
|
||||
master_create_distributed_table
|
||||
---------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT master_create_worker_shards('ex_on_part_col_named', '4', '2');
|
||||
master_create_worker_shards
|
||||
-----------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
INSERT INTO ex_on_part_col_named (partition_col, other_col) VALUES (1,1);
|
||||
INSERT INTO ex_on_part_col_named (partition_col, other_col) VALUES (1,2);
|
||||
ERROR: conflicting key value violates exclusion constraint "ex_on_part_col_named_exclude_365020"
|
||||
DETAIL: Key (partition_col)=(1) conflicts with existing key (partition_col)=(1).
|
||||
CONTEXT: while executing command on localhost:57637
|
||||
CREATE TABLE ex_on_two_columns_named
|
||||
(
|
||||
partition_col integer,
|
||||
other_col integer,
|
||||
CONSTRAINT ex_on_two_columns_named_exclude EXCLUDE (partition_col WITH =, other_col WITH =)
|
||||
);
|
||||
SELECT master_create_distributed_table('ex_on_two_columns_named', 'partition_col', 'hash');
|
||||
master_create_distributed_table
|
||||
---------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT master_create_worker_shards('ex_on_two_columns_named', '4', '2');
|
||||
master_create_worker_shards
|
||||
-----------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
INSERT INTO ex_on_two_columns_named (partition_col, other_col) VALUES (1,1);
|
||||
INSERT INTO ex_on_two_columns_named (partition_col, other_col) VALUES (1,1);
|
||||
ERROR: conflicting key value violates exclusion constraint "ex_on_two_columns_named_exclude_365024"
|
||||
DETAIL: Key (partition_col, other_col)=(1, 1) conflicts with existing key (partition_col, other_col)=(1, 1).
|
||||
CONTEXT: while executing command on localhost:57637
|
||||
CREATE TABLE ex_multiple_excludes
|
||||
(
|
||||
partition_col integer,
|
||||
other_col integer,
|
||||
other_other_col integer,
|
||||
CONSTRAINT ex_multiple_excludes_excl1 EXCLUDE (partition_col WITH =, other_col WITH =),
|
||||
CONSTRAINT ex_multiple_excludes_excl2 EXCLUDE (partition_col WITH =, other_other_col WITH =)
|
||||
);
|
||||
SELECT master_create_distributed_table('ex_multiple_excludes', 'partition_col', 'hash');
|
||||
master_create_distributed_table
|
||||
---------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT master_create_worker_shards('ex_multiple_excludes', '4', '2');
|
||||
master_create_worker_shards
|
||||
-----------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
INSERT INTO ex_multiple_excludes (partition_col, other_col, other_other_col) VALUES (1,1,1);
|
||||
INSERT INTO ex_multiple_excludes (partition_col, other_col, other_other_col) VALUES (1,1,2);
|
||||
ERROR: conflicting key value violates exclusion constraint "ex_multiple_excludes_excl1_365028"
|
||||
DETAIL: Key (partition_col, other_col)=(1, 1) conflicts with existing key (partition_col, other_col)=(1, 1).
|
||||
CONTEXT: while executing command on localhost:57637
|
||||
INSERT INTO ex_multiple_excludes (partition_col, other_col, other_other_col) VALUES (1,2,1);
|
||||
ERROR: conflicting key value violates exclusion constraint "ex_multiple_excludes_excl2_365028"
|
||||
DETAIL: Key (partition_col, other_other_col)=(1, 1) conflicts with existing key (partition_col, other_other_col)=(1, 1).
|
||||
CONTEXT: while executing command on localhost:57637
|
||||
CREATE TABLE ex_wrong_operator_named
|
||||
(
|
||||
partition_col tsrange,
|
||||
other_col tsrange,
|
||||
CONSTRAINT ex_wrong_operator_named_exclude EXCLUDE USING gist (other_col WITH =, partition_col WITH &&)
|
||||
);
|
||||
SELECT master_create_distributed_table('ex_wrong_operator_named', 'partition_col', 'hash');
|
||||
ERROR: cannot distribute relation: "ex_wrong_operator_named"
|
||||
DETAIL: Distributed relations cannot have UNIQUE, EXCLUDE, or PRIMARY KEY constraints that do not include the partition column (with an equality operator if EXCLUDE).
|
||||
CREATE TABLE ex_overlaps_named
|
||||
(
|
||||
partition_col tsrange,
|
||||
other_col tsrange,
|
||||
CONSTRAINT ex_overlaps_operator_named_exclude EXCLUDE USING gist (other_col WITH &&, partition_col WITH =)
|
||||
);
|
||||
SELECT master_create_distributed_table('ex_overlaps_named', 'partition_col', 'hash');
|
||||
master_create_distributed_table
|
||||
---------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT master_create_worker_shards('ex_overlaps_named', '4', '2');
|
||||
master_create_worker_shards
|
||||
-----------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
INSERT INTO ex_overlaps_named (partition_col, other_col) VALUES ('[2016-01-01 00:00:00, 2016-02-01 00:00:00]', '[2016-01-01 00:00:00, 2016-02-01 00:00:00]');
|
||||
INSERT INTO ex_overlaps_named (partition_col, other_col) VALUES ('[2016-01-01 00:00:00, 2016-02-01 00:00:00]', '[2016-01-15 00:00:00, 2016-02-01 00:00:00]');
|
||||
ERROR: conflicting key value violates exclusion constraint "ex_overlaps_operator_named_exclude_365035"
|
||||
DETAIL: Key (other_col, partition_col)=(["2016-01-15 00:00:00","2016-02-01 00:00:00"], ["2016-01-01 00:00:00","2016-02-01 00:00:00"]) conflicts with existing key (other_col, partition_col)=(["2016-01-01 00:00:00","2016-02-01 00:00:00"], ["2016-01-01 00:00:00","2016-02-01 00:00:00"]).
|
||||
CONTEXT: while executing command on localhost:57638
|
||||
-- now show that Citus allows unique constraints on range-partitioned tables.
|
||||
CREATE TABLE uq_range_tables
|
||||
(
|
||||
partition_col integer UNIQUE,
|
||||
other_col integer
|
||||
);
|
||||
SELECT master_create_distributed_table('uq_range_tables', 'partition_col', 'range');
|
||||
master_create_distributed_table
|
||||
---------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- show that CHECK constraints are distributed.
|
||||
CREATE TABLE check_example
|
||||
(
|
||||
partition_col integer UNIQUE,
|
||||
other_col integer CHECK (other_col >= 100),
|
||||
other_other_col integer CHECK (abs(other_other_col) >= 100)
|
||||
);
|
||||
SELECT master_create_distributed_table('check_example', 'partition_col', 'hash');
|
||||
master_create_distributed_table
|
||||
---------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT master_create_worker_shards('check_example', '2', '2');
|
||||
master_create_worker_shards
|
||||
-----------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
\c - - - :worker_1_port
|
||||
\d check_example*
|
||||
Table "public.check_example_365036"
|
||||
Column | Type | Modifiers
|
||||
-----------------+---------+-----------
|
||||
partition_col | integer |
|
||||
other_col | integer |
|
||||
other_other_col | integer |
|
||||
Indexes:
|
||||
"check_example_partition_col_key_365036" UNIQUE CONSTRAINT, btree (partition_col)
|
||||
Check constraints:
|
||||
"check_example_other_col_check" CHECK (other_col >= 100)
|
||||
"check_example_other_other_col_check" CHECK (abs(other_other_col) >= 100)
|
||||
|
||||
Table "public.check_example_365037"
|
||||
Column | Type | Modifiers
|
||||
-----------------+---------+-----------
|
||||
partition_col | integer |
|
||||
other_col | integer |
|
||||
other_other_col | integer |
|
||||
Indexes:
|
||||
"check_example_partition_col_key_365037" UNIQUE CONSTRAINT, btree (partition_col)
|
||||
Check constraints:
|
||||
"check_example_other_col_check" CHECK (other_col >= 100)
|
||||
"check_example_other_other_col_check" CHECK (abs(other_other_col) >= 100)
|
||||
|
||||
Index "public.check_example_partition_col_key_365036"
|
||||
Column | Type | Definition
|
||||
---------------+---------+---------------
|
||||
partition_col | integer | partition_col
|
||||
unique, btree, for table "public.check_example_365036"
|
||||
|
||||
Index "public.check_example_partition_col_key_365037"
|
||||
Column | Type | Definition
|
||||
---------------+---------+---------------
|
||||
partition_col | integer | partition_col
|
||||
unique, btree, for table "public.check_example_365037"
|
||||
|
||||
\c - - - :worker_2_port
|
||||
\d check_example*
|
||||
Table "public.check_example_365036"
|
||||
Column | Type | Modifiers
|
||||
-----------------+---------+-----------
|
||||
partition_col | integer |
|
||||
other_col | integer |
|
||||
other_other_col | integer |
|
||||
Indexes:
|
||||
"check_example_partition_col_key_365036" UNIQUE CONSTRAINT, btree (partition_col)
|
||||
Check constraints:
|
||||
"check_example_other_col_check" CHECK (other_col >= 100)
|
||||
"check_example_other_other_col_check" CHECK (abs(other_other_col) >= 100)
|
||||
|
||||
Table "public.check_example_365037"
|
||||
Column | Type | Modifiers
|
||||
-----------------+---------+-----------
|
||||
partition_col | integer |
|
||||
other_col | integer |
|
||||
other_other_col | integer |
|
||||
Indexes:
|
||||
"check_example_partition_col_key_365037" UNIQUE CONSTRAINT, btree (partition_col)
|
||||
Check constraints:
|
||||
"check_example_other_col_check" CHECK (other_col >= 100)
|
||||
"check_example_other_other_col_check" CHECK (abs(other_other_col) >= 100)
|
||||
|
||||
Index "public.check_example_partition_col_key_365036"
|
||||
Column | Type | Definition
|
||||
---------------+---------+---------------
|
||||
partition_col | integer | partition_col
|
||||
unique, btree, for table "public.check_example_365036"
|
||||
|
||||
Index "public.check_example_partition_col_key_365037"
|
||||
Column | Type | Definition
|
||||
---------------+---------+---------------
|
||||
partition_col | integer | partition_col
|
||||
unique, btree, for table "public.check_example_365037"
|
||||
|
||||
\c - - - :master_port
|
||||
-- drop unnecessary tables
|
||||
DROP TABLE pk_on_non_part_col, uq_on_non_part_col CASCADE;
|
||||
DROP TABLE pk_on_part_col, uq_part_col, uq_two_columns CASCADE;
|
||||
DROP TABLE ex_on_part_col, ex_on_two_columns, ex_multiple_excludes, ex_overlaps CASCADE;
|
||||
DROP TABLE ex_on_part_col_named, ex_on_two_columns_named, ex_overlaps_named CASCADE;
|
||||
DROP TABLE uq_range_tables, check_example CASCADE;
|
|
@ -23,6 +23,7 @@ test: multi_table_ddl
|
|||
# uploading data to it.
|
||||
# ----------
|
||||
test: multi_create_table
|
||||
test: multi_create_table_constraints
|
||||
test: multi_master_protocol
|
||||
test: multi_load_data
|
||||
|
||||
|
|
|
@ -458,8 +458,8 @@ CREATE TABLE customer_worker_copy_append (
|
|||
primary key (c_custkey));
|
||||
CREATE INDEX ON customer_worker_copy_append (c_name);
|
||||
SELECT master_create_distributed_table('customer_worker_copy_append', 'c_custkey', 'append');
|
||||
WARNING: table "customer_worker_copy_append" has a unique constraint
|
||||
DETAIL: Unique constraints and primary keys on append-partitioned tables cannot be enforced.
|
||||
WARNING: table "customer_worker_copy_append" has a UNIQUE or EXCLUDE constraint
|
||||
DETAIL: UNIQUE constraints, EXCLUDE constraints, and PRIMARY KEYs on append-partitioned tables cannot be enforced.
|
||||
HINT: Consider using hash partitioning.
|
||||
master_create_distributed_table
|
||||
---------------------------------
|
||||
|
|
|
@ -2,11 +2,9 @@
|
|||
-- MULTI_CREATE_TABLE
|
||||
--
|
||||
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 360000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 360000;
|
||||
|
||||
|
||||
-- Create new table definitions for use in testing in distributed planning and
|
||||
-- execution functionality. Also create indexes to boost performance.
|
||||
|
||||
|
@ -99,65 +97,3 @@ CREATE TABLE supplier
|
|||
s_comment varchar(101) not null
|
||||
);
|
||||
SELECT master_create_distributed_table('supplier', 's_suppkey', 'append');
|
||||
|
||||
|
||||
-- now test that Citus cannot distribute unique constraints that do not include
|
||||
-- the partition column
|
||||
CREATE TABLE primary_key_on_non_part_col
|
||||
(
|
||||
partition_col integer,
|
||||
other_col integer PRIMARY KEY
|
||||
);
|
||||
SELECT master_create_distributed_table('primary_key_on_non_part_col', 'partition_col', 'hash');
|
||||
|
||||
CREATE TABLE unique_const_on_non_part_col
|
||||
(
|
||||
partition_col integer,
|
||||
other_col integer UNIQUE
|
||||
);
|
||||
SELECT master_create_distributed_table('primary_key_on_non_part_col', 'partition_col', 'hash');
|
||||
|
||||
-- now show that Citus can distribute unique constrints that include
|
||||
-- the partition column
|
||||
CREATE TABLE primary_key_on_part_col
|
||||
(
|
||||
partition_col integer PRIMARY KEY,
|
||||
other_col integer
|
||||
);
|
||||
SELECT master_create_distributed_table('primary_key_on_part_col', 'partition_col', 'hash');
|
||||
|
||||
CREATE TABLE unique_const_on_part_col
|
||||
(
|
||||
partition_col integer UNIQUE,
|
||||
other_col integer
|
||||
);
|
||||
SELECT master_create_distributed_table('unique_const_on_part_col', 'partition_col', 'hash');
|
||||
|
||||
CREATE TABLE unique_const_on_two_columns
|
||||
(
|
||||
partition_col integer,
|
||||
other_col integer,
|
||||
UNIQUE (partition_col, other_col)
|
||||
);
|
||||
SELECT master_create_distributed_table('unique_const_on_two_columns', 'partition_col', 'hash');
|
||||
|
||||
CREATE TABLE unique_const_append_partitioned_tables
|
||||
(
|
||||
partition_col integer UNIQUE,
|
||||
other_col integer
|
||||
);
|
||||
SELECT master_create_distributed_table('unique_const_append_partitioned_tables', 'partition_col', 'append');
|
||||
|
||||
CREATE TABLE unique_const_range_partitioned_tables
|
||||
(
|
||||
partition_col integer UNIQUE,
|
||||
other_col integer
|
||||
);
|
||||
SELECT master_create_distributed_table('unique_const_range_partitioned_tables', 'partition_col', 'range');
|
||||
|
||||
-- drop unnecessary tables
|
||||
DROP TABLE primary_key_on_non_part_col, unique_const_on_non_part_col CASCADE;
|
||||
DROP TABLE primary_key_on_part_col, unique_const_on_part_col, unique_const_on_two_columns CASCADE;
|
||||
DROP TABLE unique_const_range_partitioned_tables CASCADE;
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,238 @@
|
|||
--
|
||||
-- MULTI_CREATE_TABLE_CONSTRAINTS
|
||||
--
|
||||
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_shardid_seq RESTART 365000;
|
||||
ALTER SEQUENCE pg_catalog.pg_dist_jobid_seq RESTART 365000;
|
||||
|
||||
-- test that Citus forbids unique and EXCLUDE constraints on append-partitioned tables.
|
||||
|
||||
CREATE TABLE uniq_cns_append_tables
|
||||
(
|
||||
partition_col integer UNIQUE,
|
||||
other_col integer
|
||||
);
|
||||
SELECT master_create_distributed_table('uniq_cns_append_tables', 'partition_col', 'append');
|
||||
|
||||
CREATE TABLE excl_cns_append_tables
|
||||
(
|
||||
partition_col integer,
|
||||
other_col integer,
|
||||
EXCLUDE (partition_col WITH =)
|
||||
);
|
||||
SELECT master_create_distributed_table('excl_cns_append_tables', 'partition_col', 'append');
|
||||
|
||||
-- test that Citus cannot distribute unique constraints that do not include
|
||||
-- the partition column on hash-partitioned tables.
|
||||
|
||||
CREATE TABLE pk_on_non_part_col
|
||||
(
|
||||
partition_col integer,
|
||||
other_col integer PRIMARY KEY
|
||||
);
|
||||
SELECT master_create_distributed_table('pk_on_non_part_col', 'partition_col', 'hash');
|
||||
|
||||
CREATE TABLE uq_on_non_part_col
|
||||
(
|
||||
partition_col integer,
|
||||
other_col integer UNIQUE
|
||||
);
|
||||
SELECT master_create_distributed_table('uq_on_non_part_col', 'partition_col', 'hash');
|
||||
|
||||
CREATE TABLE ex_on_non_part_col
|
||||
(
|
||||
partition_col integer,
|
||||
other_col integer,
|
||||
EXCLUDE (other_col WITH =)
|
||||
);
|
||||
SELECT master_create_distributed_table('ex_on_non_part_col', 'partition_col', 'hash');
|
||||
|
||||
-- now show that Citus can distribute unique and EXCLUDE constraints that
|
||||
-- include the partition column for hash-partitioned tables.
|
||||
-- However, EXCLUDE constraints must include the partition column with
|
||||
-- an equality operator.
|
||||
-- These tests are for UNNAMED constraints.
|
||||
|
||||
CREATE TABLE pk_on_part_col
|
||||
(
|
||||
partition_col integer PRIMARY KEY,
|
||||
other_col integer
|
||||
);
|
||||
SELECT master_create_distributed_table('pk_on_part_col', 'partition_col', 'hash');
|
||||
|
||||
CREATE TABLE uq_part_col
|
||||
(
|
||||
partition_col integer UNIQUE,
|
||||
other_col integer
|
||||
);
|
||||
SELECT master_create_distributed_table('uq_part_col', 'partition_col', 'hash');
|
||||
|
||||
CREATE TABLE uq_two_columns
|
||||
(
|
||||
partition_col integer,
|
||||
other_col integer,
|
||||
UNIQUE (partition_col, other_col)
|
||||
);
|
||||
SELECT master_create_distributed_table('uq_two_columns', 'partition_col', 'hash');
|
||||
SELECT master_create_worker_shards('uq_two_columns', '4', '2');
|
||||
INSERT INTO uq_two_columns (partition_col, other_col) VALUES (1,1);
|
||||
INSERT INTO uq_two_columns (partition_col, other_col) VALUES (1,1);
|
||||
|
||||
CREATE TABLE ex_on_part_col
|
||||
(
|
||||
partition_col integer,
|
||||
other_col integer,
|
||||
EXCLUDE (partition_col WITH =)
|
||||
);
|
||||
SELECT master_create_distributed_table('ex_on_part_col', 'partition_col', 'hash');
|
||||
SELECT master_create_worker_shards('ex_on_part_col', '4', '2');
|
||||
INSERT INTO ex_on_part_col (partition_col, other_col) VALUES (1,1);
|
||||
INSERT INTO ex_on_part_col (partition_col, other_col) VALUES (1,2);
|
||||
|
||||
CREATE TABLE ex_on_two_columns
|
||||
(
|
||||
partition_col integer,
|
||||
other_col integer,
|
||||
EXCLUDE (partition_col WITH =, other_col WITH =)
|
||||
);
|
||||
SELECT master_create_distributed_table('ex_on_two_columns', 'partition_col', 'hash');
|
||||
SELECT master_create_worker_shards('ex_on_two_columns', '4', '2');
|
||||
INSERT INTO ex_on_two_columns (partition_col, other_col) VALUES (1,1);
|
||||
INSERT INTO ex_on_two_columns (partition_col, other_col) VALUES (1,1);
|
||||
|
||||
CREATE TABLE ex_wrong_operator
|
||||
(
|
||||
partition_col tsrange,
|
||||
other_col tsrange,
|
||||
EXCLUDE USING gist (other_col WITH =, partition_col WITH &&)
|
||||
);
|
||||
SELECT master_create_distributed_table('ex_wrong_operator', 'partition_col', 'hash');
|
||||
|
||||
CREATE TABLE ex_overlaps
|
||||
(
|
||||
partition_col tsrange,
|
||||
other_col tsrange,
|
||||
EXCLUDE USING gist (other_col WITH &&, partition_col WITH =)
|
||||
);
|
||||
SELECT master_create_distributed_table('ex_overlaps', 'partition_col', 'hash');
|
||||
SELECT master_create_worker_shards('ex_overlaps', '4', '2');
|
||||
INSERT INTO ex_overlaps (partition_col, other_col) VALUES ('[2016-01-01 00:00:00, 2016-02-01 00:00:00]', '[2016-01-01 00:00:00, 2016-02-01 00:00:00]');
|
||||
INSERT INTO ex_overlaps (partition_col, other_col) VALUES ('[2016-01-01 00:00:00, 2016-02-01 00:00:00]', '[2016-01-15 00:00:00, 2016-02-01 00:00:00]');
|
||||
|
||||
-- now show that Citus can distribute unique and EXCLUDE constraints that
|
||||
-- include the partition column, for hash-partitioned tables.
|
||||
-- However, EXCLUDE constraints must include the partition column with
|
||||
-- an equality operator.
|
||||
-- These tests are for NAMED constraints.
|
||||
|
||||
CREATE TABLE pk_on_part_col_named
|
||||
(
|
||||
partition_col integer CONSTRAINT pk_on_part_col_named_pk PRIMARY KEY,
|
||||
other_col integer
|
||||
);
|
||||
SELECT master_create_distributed_table('pk_on_part_col_named', 'partition_col', 'hash');
|
||||
|
||||
CREATE TABLE uq_part_col_named
|
||||
(
|
||||
partition_col integer CONSTRAINT uq_part_col_named_uniq UNIQUE,
|
||||
other_col integer
|
||||
);
|
||||
SELECT master_create_distributed_table('uq_part_col_named', 'partition_col', 'hash');
|
||||
|
||||
CREATE TABLE uq_two_columns_named
|
||||
(
|
||||
partition_col integer,
|
||||
other_col integer,
|
||||
CONSTRAINT uq_two_columns_named_uniq UNIQUE (partition_col, other_col)
|
||||
);
|
||||
SELECT master_create_distributed_table('uq_two_columns_named', 'partition_col', 'hash');
|
||||
SELECT master_create_worker_shards('uq_two_columns_named', '4', '2');
|
||||
INSERT INTO uq_two_columns_named (partition_col, other_col) VALUES (1,1);
|
||||
INSERT INTO uq_two_columns_named (partition_col, other_col) VALUES (1,1);
|
||||
|
||||
CREATE TABLE ex_on_part_col_named
|
||||
(
|
||||
partition_col integer,
|
||||
other_col integer,
|
||||
CONSTRAINT ex_on_part_col_named_exclude EXCLUDE (partition_col WITH =)
|
||||
);
|
||||
SELECT master_create_distributed_table('ex_on_part_col_named', 'partition_col', 'hash');
|
||||
SELECT master_create_worker_shards('ex_on_part_col_named', '4', '2');
|
||||
INSERT INTO ex_on_part_col_named (partition_col, other_col) VALUES (1,1);
|
||||
INSERT INTO ex_on_part_col_named (partition_col, other_col) VALUES (1,2);
|
||||
|
||||
CREATE TABLE ex_on_two_columns_named
|
||||
(
|
||||
partition_col integer,
|
||||
other_col integer,
|
||||
CONSTRAINT ex_on_two_columns_named_exclude EXCLUDE (partition_col WITH =, other_col WITH =)
|
||||
);
|
||||
SELECT master_create_distributed_table('ex_on_two_columns_named', 'partition_col', 'hash');
|
||||
SELECT master_create_worker_shards('ex_on_two_columns_named', '4', '2');
|
||||
INSERT INTO ex_on_two_columns_named (partition_col, other_col) VALUES (1,1);
|
||||
INSERT INTO ex_on_two_columns_named (partition_col, other_col) VALUES (1,1);
|
||||
|
||||
CREATE TABLE ex_multiple_excludes
|
||||
(
|
||||
partition_col integer,
|
||||
other_col integer,
|
||||
other_other_col integer,
|
||||
CONSTRAINT ex_multiple_excludes_excl1 EXCLUDE (partition_col WITH =, other_col WITH =),
|
||||
CONSTRAINT ex_multiple_excludes_excl2 EXCLUDE (partition_col WITH =, other_other_col WITH =)
|
||||
);
|
||||
SELECT master_create_distributed_table('ex_multiple_excludes', 'partition_col', 'hash');
|
||||
SELECT master_create_worker_shards('ex_multiple_excludes', '4', '2');
|
||||
INSERT INTO ex_multiple_excludes (partition_col, other_col, other_other_col) VALUES (1,1,1);
|
||||
INSERT INTO ex_multiple_excludes (partition_col, other_col, other_other_col) VALUES (1,1,2);
|
||||
INSERT INTO ex_multiple_excludes (partition_col, other_col, other_other_col) VALUES (1,2,1);
|
||||
|
||||
CREATE TABLE ex_wrong_operator_named
|
||||
(
|
||||
partition_col tsrange,
|
||||
other_col tsrange,
|
||||
CONSTRAINT ex_wrong_operator_named_exclude EXCLUDE USING gist (other_col WITH =, partition_col WITH &&)
|
||||
);
|
||||
SELECT master_create_distributed_table('ex_wrong_operator_named', 'partition_col', 'hash');
|
||||
|
||||
CREATE TABLE ex_overlaps_named
|
||||
(
|
||||
partition_col tsrange,
|
||||
other_col tsrange,
|
||||
CONSTRAINT ex_overlaps_operator_named_exclude EXCLUDE USING gist (other_col WITH &&, partition_col WITH =)
|
||||
);
|
||||
SELECT master_create_distributed_table('ex_overlaps_named', 'partition_col', 'hash');
|
||||
SELECT master_create_worker_shards('ex_overlaps_named', '4', '2');
|
||||
INSERT INTO ex_overlaps_named (partition_col, other_col) VALUES ('[2016-01-01 00:00:00, 2016-02-01 00:00:00]', '[2016-01-01 00:00:00, 2016-02-01 00:00:00]');
|
||||
INSERT INTO ex_overlaps_named (partition_col, other_col) VALUES ('[2016-01-01 00:00:00, 2016-02-01 00:00:00]', '[2016-01-15 00:00:00, 2016-02-01 00:00:00]');
|
||||
|
||||
-- now show that Citus allows unique constraints on range-partitioned tables.
|
||||
|
||||
CREATE TABLE uq_range_tables
|
||||
(
|
||||
partition_col integer UNIQUE,
|
||||
other_col integer
|
||||
);
|
||||
SELECT master_create_distributed_table('uq_range_tables', 'partition_col', 'range');
|
||||
|
||||
-- show that CHECK constraints are distributed.
|
||||
CREATE TABLE check_example
|
||||
(
|
||||
partition_col integer UNIQUE,
|
||||
other_col integer CHECK (other_col >= 100),
|
||||
other_other_col integer CHECK (abs(other_other_col) >= 100)
|
||||
);
|
||||
SELECT master_create_distributed_table('check_example', 'partition_col', 'hash');
|
||||
SELECT master_create_worker_shards('check_example', '2', '2');
|
||||
|
||||
\c - - - :worker_1_port
|
||||
\d check_example*
|
||||
\c - - - :worker_2_port
|
||||
\d check_example*
|
||||
\c - - - :master_port
|
||||
|
||||
-- drop unnecessary tables
|
||||
DROP TABLE pk_on_non_part_col, uq_on_non_part_col CASCADE;
|
||||
DROP TABLE pk_on_part_col, uq_part_col, uq_two_columns CASCADE;
|
||||
DROP TABLE ex_on_part_col, ex_on_two_columns, ex_multiple_excludes, ex_overlaps CASCADE;
|
||||
DROP TABLE ex_on_part_col_named, ex_on_two_columns_named, ex_overlaps_named CASCADE;
|
||||
DROP TABLE uq_range_tables, check_example CASCADE;
|
Loading…
Reference in New Issue