Merge pull request #2488 from citusdata/validate_constraint

Validate Constraint Support
pull/2492/head
hanefi 2018-11-26 15:20:01 +03:00 committed by GitHub
commit 27930aa462
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 600 additions and 279 deletions

View File

@ -1060,11 +1060,13 @@ ErrorIfUnsupportedAlterTableStmt(AlterTableStmt *alterTableStatement)
case AT_EnableTrigAll:
case AT_DisableTrigAll:
case AT_ReplicaIdentity:
case AT_ValidateConstraint:
{
/*
* We will not perform any special check for ALTER TABLE DROP CONSTRAINT
* , ALTER TABLE .. ALTER COLUMN .. SET NOT NULL and ALTER TABLE ENABLE/
* DISABLE TRIGGER ALL, ALTER TABLE .. REPLICA IDENTITY ..
* DISABLE TRIGGER ALL, ALTER TABLE .. REPLICA IDENTITY .., ALTER TABLE
* .. VALIDATE CONSTRAINT ..
*/
break;
}
@ -1083,7 +1085,7 @@ ErrorIfUnsupportedAlterTableStmt(AlterTableStmt *alterTableStatement)
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("alter table command is currently unsupported"),
errdetail("Only ADD|DROP COLUMN, SET|DROP NOT NULL, "
"SET|DROP DEFAULT, ADD|DROP CONSTRAINT, "
"SET|DROP DEFAULT, ADD|DROP|VALIDATE CONSTRAINT, "
"SET (), RESET (), "
"ATTACH|DETACH PARTITION and TYPE subcommands "
"are supported.")));

View File

@ -113,7 +113,11 @@ RelayEventExtendNames(Node *parseTree, char *schemaName, uint64 shardId)
AppendShardIdToConstraintName(command, shardId);
}
if (command->subtype == AT_DropConstraint)
else if (command->subtype == AT_DropConstraint)
{
AppendShardIdToConstraintName(command, shardId);
}
else if (command->subtype == AT_ValidateConstraint)
{
AppendShardIdToConstraintName(command, shardId);
}
@ -598,7 +602,8 @@ AppendShardIdToConstraintName(AlterTableCmd *command, uint64 shardId)
char **constraintName = &(constraint->conname);
AppendShardIdToName(constraintName, shardId);
}
else if (command->subtype == AT_DropConstraint)
else if (command->subtype == AT_DropConstraint ||
command->subtype == AT_ValidateConstraint)
{
char **constraintName = &(command->name);
AppendShardIdToName(constraintName, shardId);

View File

@ -1,6 +1,13 @@
--
-- FOREIGN_KEY_TO_REFERENCE_TABLE
--
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int > 9 AS version_above_nine;
version_above_nine
--------------------
t
(1 row)
CREATE SCHEMA fkey_reference_table;
SET search_path TO 'fkey_reference_table';
SET citus.shard_replication_factor TO 1;
@ -28,7 +35,9 @@ SELECT
relid::regclass::text,
refd_relid::regclass::text
FROM
table_fkey_cols
table_fkey_cols
WHERE
"schema" = 'fkey_reference_table'
)
d $$ )).RESULT::json )::json )).* ;
CREATE TABLE referenced_table(id int UNIQUE, test_column int);
@ -722,38 +731,6 @@ INSERT INTO referencing_table SELECT x,(random()*1000)::int FROM generate_series
DROP TABLE referenced_table CASCADE;
NOTICE: drop cascades to constraint fkey_ref on table referencing_table
DROP TABLE referencing_table CASCADE;
-- In the following test, we show that Citus currently does not support
-- VALIDATE command.
CREATE TABLE referenced_table(test_column int, test_column2 int, PRIMARY KEY(test_column));
CREATE TABLE referencing_table(id int, ref_id int DEFAULT -1);
SELECT create_reference_table('referenced_table');
create_reference_table
------------------------
(1 row)
SELECT create_distributed_table('referencing_table', 'id');
create_distributed_table
--------------------------
(1 row)
ALTER TABLE referencing_table ADD CONSTRAINT fkey_ref FOREIGN KEY (ref_id) REFERENCES referenced_table(test_column) ON DELETE SET DEFAULT NOT VALID;
-- Even if the foreign constraint is added with "NOT VALID",
-- we make sure that it is still applied to the upcoming inserts.
INSERT INTO referenced_table SELECT x, x FROM generate_series(0,1000) AS f(x);
INSERT INTO referencing_table SELECT x, x FROM generate_series(0,1000) AS f(x);
-- we expect this to fail because of the foreign constraint.
INSERT INTO referencing_table SELECT x, x FROM generate_series(1000,1001) AS f(x);
ERROR: insert or update on table "referencing_table_7000220" violates foreign key constraint "fkey_ref_7000220"
DETAIL: Key (ref_id)=(1001) is not present in table "referenced_table_7000214".
-- currently not supported
ALTER TABLE referencing_table VALIDATE CONSTRAINT fkey_ref;
ERROR: alter table command is currently unsupported
DETAIL: Only ADD|DROP COLUMN, SET|DROP NOT NULL, SET|DROP DEFAULT, ADD|DROP CONSTRAINT, SET (), RESET (), ATTACH|DETACH PARTITION and TYPE subcommands are supported.
DROP TABLE referenced_table CASCADE;
NOTICE: drop cascades to constraint fkey_ref on table referencing_table
DROP TABLE referencing_table CASCADE;
-- In the following tests, we create a foreign constraint with
-- ON UPDATE CASCADE and see if it works properly with cascading upsert
CREATE TABLE referenced_table(test_column int, test_column2 int, PRIMARY KEY(test_column));
@ -845,38 +822,38 @@ ALTER TABLE referencing_table ADD CONSTRAINT foreign_key_2 FOREIGN KEY (id) REFE
SELECT * FROM table_fkeys_in_workers WHERE relid LIKE 'fkey_reference_table.%' AND refd_relid LIKE 'fkey_reference_table.%' ORDER BY 1,2,3;
name | relid | refd_relid
-----------------------+------------------------------------------------+------------------------------------------------
fkey_ref_7000235 | fkey_reference_table.referencing_table_7000235 | fkey_reference_table.referenced_table_7000233
fkey_ref_7000236 | fkey_reference_table.referencing_table_7000236 | fkey_reference_table.referenced_table_7000233
fkey_ref_7000237 | fkey_reference_table.referencing_table_7000237 | fkey_reference_table.referenced_table_7000233
fkey_ref_7000238 | fkey_reference_table.referencing_table_7000238 | fkey_reference_table.referenced_table_7000233
fkey_ref_7000239 | fkey_reference_table.referencing_table_7000239 | fkey_reference_table.referenced_table_7000233
fkey_ref_7000240 | fkey_reference_table.referencing_table_7000240 | fkey_reference_table.referenced_table_7000233
fkey_ref_7000241 | fkey_reference_table.referencing_table_7000241 | fkey_reference_table.referenced_table_7000233
fkey_ref_7000242 | fkey_reference_table.referencing_table_7000242 | fkey_reference_table.referenced_table_7000233
foreign_key_2_7000235 | fkey_reference_table.referencing_table_7000235 | fkey_reference_table.referenced_table2_7000234
foreign_key_2_7000236 | fkey_reference_table.referencing_table_7000236 | fkey_reference_table.referenced_table2_7000234
foreign_key_2_7000237 | fkey_reference_table.referencing_table_7000237 | fkey_reference_table.referenced_table2_7000234
foreign_key_2_7000238 | fkey_reference_table.referencing_table_7000238 | fkey_reference_table.referenced_table2_7000234
foreign_key_2_7000239 | fkey_reference_table.referencing_table_7000239 | fkey_reference_table.referenced_table2_7000234
foreign_key_2_7000240 | fkey_reference_table.referencing_table_7000240 | fkey_reference_table.referenced_table2_7000234
foreign_key_2_7000241 | fkey_reference_table.referencing_table_7000241 | fkey_reference_table.referenced_table2_7000234
foreign_key_2_7000242 | fkey_reference_table.referencing_table_7000242 | fkey_reference_table.referenced_table2_7000234
fkey_ref_7000226 | fkey_reference_table.referencing_table_7000226 | fkey_reference_table.referenced_table_7000224
fkey_ref_7000227 | fkey_reference_table.referencing_table_7000227 | fkey_reference_table.referenced_table_7000224
fkey_ref_7000228 | fkey_reference_table.referencing_table_7000228 | fkey_reference_table.referenced_table_7000224
fkey_ref_7000229 | fkey_reference_table.referencing_table_7000229 | fkey_reference_table.referenced_table_7000224
fkey_ref_7000230 | fkey_reference_table.referencing_table_7000230 | fkey_reference_table.referenced_table_7000224
fkey_ref_7000231 | fkey_reference_table.referencing_table_7000231 | fkey_reference_table.referenced_table_7000224
fkey_ref_7000232 | fkey_reference_table.referencing_table_7000232 | fkey_reference_table.referenced_table_7000224
fkey_ref_7000233 | fkey_reference_table.referencing_table_7000233 | fkey_reference_table.referenced_table_7000224
foreign_key_2_7000226 | fkey_reference_table.referencing_table_7000226 | fkey_reference_table.referenced_table2_7000225
foreign_key_2_7000227 | fkey_reference_table.referencing_table_7000227 | fkey_reference_table.referenced_table2_7000225
foreign_key_2_7000228 | fkey_reference_table.referencing_table_7000228 | fkey_reference_table.referenced_table2_7000225
foreign_key_2_7000229 | fkey_reference_table.referencing_table_7000229 | fkey_reference_table.referenced_table2_7000225
foreign_key_2_7000230 | fkey_reference_table.referencing_table_7000230 | fkey_reference_table.referenced_table2_7000225
foreign_key_2_7000231 | fkey_reference_table.referencing_table_7000231 | fkey_reference_table.referenced_table2_7000225
foreign_key_2_7000232 | fkey_reference_table.referencing_table_7000232 | fkey_reference_table.referenced_table2_7000225
foreign_key_2_7000233 | fkey_reference_table.referencing_table_7000233 | fkey_reference_table.referenced_table2_7000225
(16 rows)
INSERT INTO referenced_table SELECT x, x+1 FROM generate_series(0,1000) AS f(x);
INSERT INTO referenced_table2 SELECT x, x+1 FROM generate_series(500,1500) AS f(x);
-- should fail
INSERT INTO referencing_table SELECT x, x+1 FROM generate_series(0,1500) AS f(x);
ERROR: insert or update on table "referencing_table_7000242" violates foreign key constraint "foreign_key_2_7000242"
DETAIL: Key (id)=(9) is not present in table "referenced_table2_7000234".
ERROR: insert or update on table "referencing_table_7000227" violates foreign key constraint "foreign_key_2_7000227"
DETAIL: Key (id)=(5) is not present in table "referenced_table2_7000225".
-- should fail
INSERT INTO referencing_table SELECT x, x+1 FROM generate_series(0,400) AS f(x);
ERROR: insert or update on table "referencing_table_7000242" violates foreign key constraint "foreign_key_2_7000242"
DETAIL: Key (id)=(9) is not present in table "referenced_table2_7000234".
ERROR: insert or update on table "referencing_table_7000227" violates foreign key constraint "foreign_key_2_7000227"
DETAIL: Key (id)=(5) is not present in table "referenced_table2_7000225".
-- should fail
INSERT INTO referencing_table SELECT x, x+1 FROM generate_series(1000,1400) AS f(x);
ERROR: insert or update on table "referencing_table_7000242" violates foreign key constraint "fkey_ref_7000242"
DETAIL: Key (id)=(1023) is not present in table "referenced_table_7000233".
ERROR: insert or update on table "referencing_table_7000227" violates foreign key constraint "fkey_ref_7000227"
DETAIL: Key (id)=(1005) is not present in table "referenced_table_7000224".
-- should success
INSERT INTO referencing_table SELECT x, x+1 FROM generate_series(600,900) AS f(x);
SELECT count(*) FROM referencing_table;
@ -972,38 +949,38 @@ COMMIT;
SELECT * FROM table_fkeys_in_workers WHERE relid LIKE 'fkey_reference_table.%' AND refd_relid LIKE 'fkey_reference_table.%' ORDER BY 1,2,3;
name | relid | refd_relid
-----------------------+------------------------------------------------+------------------------------------------------
fkey_ref_7000255 | fkey_reference_table.referencing_table_7000255 | fkey_reference_table.referenced_table_7000253
fkey_ref_7000256 | fkey_reference_table.referencing_table_7000256 | fkey_reference_table.referenced_table_7000253
fkey_ref_7000257 | fkey_reference_table.referencing_table_7000257 | fkey_reference_table.referenced_table_7000253
fkey_ref_7000258 | fkey_reference_table.referencing_table_7000258 | fkey_reference_table.referenced_table_7000253
fkey_ref_7000259 | fkey_reference_table.referencing_table_7000259 | fkey_reference_table.referenced_table_7000253
fkey_ref_7000260 | fkey_reference_table.referencing_table_7000260 | fkey_reference_table.referenced_table_7000253
fkey_ref_7000261 | fkey_reference_table.referencing_table_7000261 | fkey_reference_table.referenced_table_7000253
fkey_ref_7000262 | fkey_reference_table.referencing_table_7000262 | fkey_reference_table.referenced_table_7000253
foreign_key_2_7000255 | fkey_reference_table.referencing_table_7000255 | fkey_reference_table.referenced_table2_7000254
foreign_key_2_7000256 | fkey_reference_table.referencing_table_7000256 | fkey_reference_table.referenced_table2_7000254
foreign_key_2_7000257 | fkey_reference_table.referencing_table_7000257 | fkey_reference_table.referenced_table2_7000254
foreign_key_2_7000258 | fkey_reference_table.referencing_table_7000258 | fkey_reference_table.referenced_table2_7000254
foreign_key_2_7000259 | fkey_reference_table.referencing_table_7000259 | fkey_reference_table.referenced_table2_7000254
foreign_key_2_7000260 | fkey_reference_table.referencing_table_7000260 | fkey_reference_table.referenced_table2_7000254
foreign_key_2_7000261 | fkey_reference_table.referencing_table_7000261 | fkey_reference_table.referenced_table2_7000254
foreign_key_2_7000262 | fkey_reference_table.referencing_table_7000262 | fkey_reference_table.referenced_table2_7000254
fkey_ref_7000246 | fkey_reference_table.referencing_table_7000246 | fkey_reference_table.referenced_table_7000244
fkey_ref_7000247 | fkey_reference_table.referencing_table_7000247 | fkey_reference_table.referenced_table_7000244
fkey_ref_7000248 | fkey_reference_table.referencing_table_7000248 | fkey_reference_table.referenced_table_7000244
fkey_ref_7000249 | fkey_reference_table.referencing_table_7000249 | fkey_reference_table.referenced_table_7000244
fkey_ref_7000250 | fkey_reference_table.referencing_table_7000250 | fkey_reference_table.referenced_table_7000244
fkey_ref_7000251 | fkey_reference_table.referencing_table_7000251 | fkey_reference_table.referenced_table_7000244
fkey_ref_7000252 | fkey_reference_table.referencing_table_7000252 | fkey_reference_table.referenced_table_7000244
fkey_ref_7000253 | fkey_reference_table.referencing_table_7000253 | fkey_reference_table.referenced_table_7000244
foreign_key_2_7000246 | fkey_reference_table.referencing_table_7000246 | fkey_reference_table.referenced_table2_7000245
foreign_key_2_7000247 | fkey_reference_table.referencing_table_7000247 | fkey_reference_table.referenced_table2_7000245
foreign_key_2_7000248 | fkey_reference_table.referencing_table_7000248 | fkey_reference_table.referenced_table2_7000245
foreign_key_2_7000249 | fkey_reference_table.referencing_table_7000249 | fkey_reference_table.referenced_table2_7000245
foreign_key_2_7000250 | fkey_reference_table.referencing_table_7000250 | fkey_reference_table.referenced_table2_7000245
foreign_key_2_7000251 | fkey_reference_table.referencing_table_7000251 | fkey_reference_table.referenced_table2_7000245
foreign_key_2_7000252 | fkey_reference_table.referencing_table_7000252 | fkey_reference_table.referenced_table2_7000245
foreign_key_2_7000253 | fkey_reference_table.referencing_table_7000253 | fkey_reference_table.referenced_table2_7000245
(16 rows)
INSERT INTO referenced_table SELECT x, x+1 FROM generate_series(0,1000) AS f(x);
INSERT INTO referenced_table2 SELECT x, x+1 FROM generate_series(500,1500) AS f(x);
-- should fail
INSERT INTO referencing_table SELECT x, x+1 FROM generate_series(0,1500) AS f(x);
ERROR: insert or update on table "referencing_table_7000260" violates foreign key constraint "foreign_key_2_7000260"
DETAIL: Key (ref_id)=(7) is not present in table "referenced_table2_7000254".
ERROR: insert or update on table "referencing_table_7000251" violates foreign key constraint "foreign_key_2_7000251"
DETAIL: Key (ref_id)=(7) is not present in table "referenced_table2_7000245".
-- should fail
INSERT INTO referencing_table SELECT x, x+1 FROM generate_series(0,400) AS f(x);
ERROR: insert or update on table "referencing_table_7000260" violates foreign key constraint "foreign_key_2_7000260"
DETAIL: Key (ref_id)=(7) is not present in table "referenced_table2_7000254".
ERROR: insert or update on table "referencing_table_7000251" violates foreign key constraint "foreign_key_2_7000251"
DETAIL: Key (ref_id)=(7) is not present in table "referenced_table2_7000245".
-- should fail
INSERT INTO referencing_table SELECT x, x+1 FROM generate_series(1000,1400) AS f(x);
ERROR: insert or update on table "referencing_table_7000260" violates foreign key constraint "fkey_ref_7000260"
DETAIL: Key (id)=(1001) is not present in table "referenced_table_7000253".
ERROR: insert or update on table "referencing_table_7000251" violates foreign key constraint "fkey_ref_7000251"
DETAIL: Key (id)=(1001) is not present in table "referenced_table_7000244".
-- should success
INSERT INTO referencing_table SELECT x, x+501 FROM generate_series(0,1000) AS f(x);
SELECT count(*) FROM referencing_table;
@ -1105,43 +1082,43 @@ COMMIT;
SELECT * FROM table_fkeys_in_workers WHERE relid LIKE 'fkey_reference_table.%' AND refd_relid LIKE 'fkey_reference_table.%' ORDER BY 1,2,3;
name | relid | refd_relid
--------------------------+-------------------------------------------------+------------------------------------------------
fkey_ref_7000274 | fkey_reference_table.referencing_table_7000274 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000275 | fkey_reference_table.referencing_table_7000275 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000276 | fkey_reference_table.referencing_table_7000276 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000277 | fkey_reference_table.referencing_table_7000277 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000278 | fkey_reference_table.referencing_table_7000278 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000279 | fkey_reference_table.referencing_table_7000279 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000280 | fkey_reference_table.referencing_table_7000280 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000281 | fkey_reference_table.referencing_table_7000281 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000282 | fkey_reference_table.referencing_table2_7000282 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000283 | fkey_reference_table.referencing_table2_7000283 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000284 | fkey_reference_table.referencing_table2_7000284 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000285 | fkey_reference_table.referencing_table2_7000285 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000286 | fkey_reference_table.referencing_table2_7000286 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000287 | fkey_reference_table.referencing_table2_7000287 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000288 | fkey_reference_table.referencing_table2_7000288 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000289 | fkey_reference_table.referencing_table2_7000289 | fkey_reference_table.referenced_table_7000273
fkey_ref_to_dist_7000282 | fkey_reference_table.referencing_table2_7000282 | fkey_reference_table.referencing_table_7000274
fkey_ref_to_dist_7000283 | fkey_reference_table.referencing_table2_7000283 | fkey_reference_table.referencing_table_7000275
fkey_ref_to_dist_7000284 | fkey_reference_table.referencing_table2_7000284 | fkey_reference_table.referencing_table_7000276
fkey_ref_to_dist_7000285 | fkey_reference_table.referencing_table2_7000285 | fkey_reference_table.referencing_table_7000277
fkey_ref_to_dist_7000286 | fkey_reference_table.referencing_table2_7000286 | fkey_reference_table.referencing_table_7000278
fkey_ref_to_dist_7000287 | fkey_reference_table.referencing_table2_7000287 | fkey_reference_table.referencing_table_7000279
fkey_ref_to_dist_7000288 | fkey_reference_table.referencing_table2_7000288 | fkey_reference_table.referencing_table_7000280
fkey_ref_to_dist_7000289 | fkey_reference_table.referencing_table2_7000289 | fkey_reference_table.referencing_table_7000281
fkey_ref_7000265 | fkey_reference_table.referencing_table_7000265 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000266 | fkey_reference_table.referencing_table_7000266 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000267 | fkey_reference_table.referencing_table_7000267 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000268 | fkey_reference_table.referencing_table_7000268 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000269 | fkey_reference_table.referencing_table_7000269 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000270 | fkey_reference_table.referencing_table_7000270 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000271 | fkey_reference_table.referencing_table_7000271 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000272 | fkey_reference_table.referencing_table_7000272 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000273 | fkey_reference_table.referencing_table2_7000273 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000274 | fkey_reference_table.referencing_table2_7000274 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000275 | fkey_reference_table.referencing_table2_7000275 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000276 | fkey_reference_table.referencing_table2_7000276 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000277 | fkey_reference_table.referencing_table2_7000277 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000278 | fkey_reference_table.referencing_table2_7000278 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000279 | fkey_reference_table.referencing_table2_7000279 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000280 | fkey_reference_table.referencing_table2_7000280 | fkey_reference_table.referenced_table_7000264
fkey_ref_to_dist_7000273 | fkey_reference_table.referencing_table2_7000273 | fkey_reference_table.referencing_table_7000265
fkey_ref_to_dist_7000274 | fkey_reference_table.referencing_table2_7000274 | fkey_reference_table.referencing_table_7000266
fkey_ref_to_dist_7000275 | fkey_reference_table.referencing_table2_7000275 | fkey_reference_table.referencing_table_7000267
fkey_ref_to_dist_7000276 | fkey_reference_table.referencing_table2_7000276 | fkey_reference_table.referencing_table_7000268
fkey_ref_to_dist_7000277 | fkey_reference_table.referencing_table2_7000277 | fkey_reference_table.referencing_table_7000269
fkey_ref_to_dist_7000278 | fkey_reference_table.referencing_table2_7000278 | fkey_reference_table.referencing_table_7000270
fkey_ref_to_dist_7000279 | fkey_reference_table.referencing_table2_7000279 | fkey_reference_table.referencing_table_7000271
fkey_ref_to_dist_7000280 | fkey_reference_table.referencing_table2_7000280 | fkey_reference_table.referencing_table_7000272
(24 rows)
INSERT INTO referenced_table SELECT x, x+1 FROM generate_series(0,1000) AS f(x);
-- should fail
INSERT INTO referencing_table2 SELECT x, x+1 FROM generate_series(0,100) AS f(x);
ERROR: insert or update on table "referencing_table2_7000284" violates foreign key constraint "fkey_ref_to_dist_7000284"
DETAIL: Key (id)=(4) is not present in table "referencing_table_7000276".
ERROR: insert or update on table "referencing_table2_7000274" violates foreign key constraint "fkey_ref_to_dist_7000274"
DETAIL: Key (id)=(5) is not present in table "referencing_table_7000266".
-- should success
INSERT INTO referencing_table SELECT x, x+1 FROM generate_series(0,400) AS f(x);
-- should fail
INSERT INTO referencing_table2 SELECT x, x+1 FROM generate_series(200,500) AS f(x);
ERROR: insert or update on table "referencing_table2_7000284" violates foreign key constraint "fkey_ref_to_dist_7000284"
DETAIL: Key (id)=(408) is not present in table "referencing_table_7000276".
ERROR: insert or update on table "referencing_table2_7000274" violates foreign key constraint "fkey_ref_to_dist_7000274"
DETAIL: Key (id)=(403) is not present in table "referencing_table_7000266".
-- should success
INSERT INTO referencing_table2 SELECT x, x+1 FROM generate_series(0,300) AS f(x);
DELETE FROM referenced_table WHERE test_column < 200;
@ -1239,22 +1216,22 @@ ALTER TABLE referencing_table ADD CONSTRAINT fkey_ref FOREIGN KEY (ref_id, ref_i
SELECT * FROM table_fkeys_in_workers WHERE relid LIKE 'fkey_reference_table.referencing%' ORDER BY 1,2,3;
name | relid | refd_relid
-----------------------------------------------+------------------------------------------------------------+------------------------------------------------
fkey_ref_7000308 | fkey_reference_table.referencing_table_7000308 | fkey_reference_table.referenced_table_7000307
fkey_ref_7000309 | fkey_reference_table.referencing_table_7000309 | fkey_reference_table.referenced_table_7000307
fkey_ref_7000310 | fkey_reference_table.referencing_table_7000310 | fkey_reference_table.referenced_table_7000307
fkey_ref_7000311 | fkey_reference_table.referencing_table_7000311 | fkey_reference_table.referenced_table_7000307
fkey_ref_7000312 | fkey_reference_table.referencing_table_7000312 | fkey_reference_table.referenced_table_7000307
fkey_ref_7000313 | fkey_reference_table.referencing_table_7000313 | fkey_reference_table.referenced_table_7000307
fkey_ref_7000314 | fkey_reference_table.referencing_table_7000314 | fkey_reference_table.referenced_table_7000307
fkey_ref_7000315 | fkey_reference_table.referencing_table_7000315 | fkey_reference_table.referenced_table_7000307
referencing_referencing_table_id_fkey_7000316 | fkey_reference_table.referencing_referencing_table_7000316 | fkey_reference_table.referencing_table_7000308
referencing_referencing_table_id_fkey_7000317 | fkey_reference_table.referencing_referencing_table_7000317 | fkey_reference_table.referencing_table_7000309
referencing_referencing_table_id_fkey_7000318 | fkey_reference_table.referencing_referencing_table_7000318 | fkey_reference_table.referencing_table_7000310
referencing_referencing_table_id_fkey_7000319 | fkey_reference_table.referencing_referencing_table_7000319 | fkey_reference_table.referencing_table_7000311
referencing_referencing_table_id_fkey_7000320 | fkey_reference_table.referencing_referencing_table_7000320 | fkey_reference_table.referencing_table_7000312
referencing_referencing_table_id_fkey_7000321 | fkey_reference_table.referencing_referencing_table_7000321 | fkey_reference_table.referencing_table_7000313
referencing_referencing_table_id_fkey_7000322 | fkey_reference_table.referencing_referencing_table_7000322 | fkey_reference_table.referencing_table_7000314
referencing_referencing_table_id_fkey_7000323 | fkey_reference_table.referencing_referencing_table_7000323 | fkey_reference_table.referencing_table_7000315
fkey_ref_7000299 | fkey_reference_table.referencing_table_7000299 | fkey_reference_table.referenced_table_7000298
fkey_ref_7000300 | fkey_reference_table.referencing_table_7000300 | fkey_reference_table.referenced_table_7000298
fkey_ref_7000301 | fkey_reference_table.referencing_table_7000301 | fkey_reference_table.referenced_table_7000298
fkey_ref_7000302 | fkey_reference_table.referencing_table_7000302 | fkey_reference_table.referenced_table_7000298
fkey_ref_7000303 | fkey_reference_table.referencing_table_7000303 | fkey_reference_table.referenced_table_7000298
fkey_ref_7000304 | fkey_reference_table.referencing_table_7000304 | fkey_reference_table.referenced_table_7000298
fkey_ref_7000305 | fkey_reference_table.referencing_table_7000305 | fkey_reference_table.referenced_table_7000298
fkey_ref_7000306 | fkey_reference_table.referencing_table_7000306 | fkey_reference_table.referenced_table_7000298
referencing_referencing_table_id_fkey_7000307 | fkey_reference_table.referencing_referencing_table_7000307 | fkey_reference_table.referencing_table_7000299
referencing_referencing_table_id_fkey_7000308 | fkey_reference_table.referencing_referencing_table_7000308 | fkey_reference_table.referencing_table_7000300
referencing_referencing_table_id_fkey_7000309 | fkey_reference_table.referencing_referencing_table_7000309 | fkey_reference_table.referencing_table_7000301
referencing_referencing_table_id_fkey_7000310 | fkey_reference_table.referencing_referencing_table_7000310 | fkey_reference_table.referencing_table_7000302
referencing_referencing_table_id_fkey_7000311 | fkey_reference_table.referencing_referencing_table_7000311 | fkey_reference_table.referencing_table_7000303
referencing_referencing_table_id_fkey_7000312 | fkey_reference_table.referencing_referencing_table_7000312 | fkey_reference_table.referencing_table_7000304
referencing_referencing_table_id_fkey_7000313 | fkey_reference_table.referencing_referencing_table_7000313 | fkey_reference_table.referencing_table_7000305
referencing_referencing_table_id_fkey_7000314 | fkey_reference_table.referencing_referencing_table_7000314 | fkey_reference_table.referencing_table_7000306
(16 rows)
INSERT INTO referenced_table SELECT x, x+1 FROM generate_series(1,1000) AS f(x);
@ -1866,8 +1843,8 @@ ALTER TABLE referencing_table_4 ADD CONSTRAINT fkey FOREIGN KEY (id) REFERENCES
ALTER TABLE referencing_table_4 ADD CONSTRAINT fkey_to_ref FOREIGN KEY (value_1) REFERENCES referenced_table;
-- should fail since the data will flow to partitioning_test_4 and it has a foreign constraint to partitioning_test_0 on id column
INSERT INTO referencing_table VALUES (0, 5);
ERROR: insert or update on table "referencing_table_4_7000549" violates foreign key constraint "fkey_7000549"
DETAIL: Key (id)=(0) is not present in table "referencing_table_0_7000533".
ERROR: insert or update on table "referencing_table_4_7000540" violates foreign key constraint "fkey_7000540"
DETAIL: Key (id)=(0) is not present in table "referencing_table_0_7000524".
CONTEXT: while executing command on localhost:57638
-- should succeed on partitioning_test_0
INSERT INTO referencing_table VALUES (0, 1);
@ -1879,8 +1856,8 @@ SELECT * FROM referencing_table;
-- should fail since partitioning_test_4 has foreign constraint to referenced_table on value_1 column
INSERT INTO referencing_table VALUES (0, 5);
ERROR: insert or update on table "referencing_table_4_7000549" violates foreign key constraint "fkey_to_ref_7000549"
DETAIL: Key (value_1)=(5) is not present in table "referenced_table_7000521".
ERROR: insert or update on table "referencing_table_4_7000540" violates foreign key constraint "fkey_to_ref_7000540"
DETAIL: Key (value_1)=(5) is not present in table "referenced_table_7000512".
CONTEXT: while executing command on localhost:57638
INSERT INTO referenced_table VALUES(5,5);
-- should succeed since both of the foreign constraints are positive

View File

@ -1,6 +1,13 @@
--
-- FOREIGN_KEY_TO_REFERENCE_TABLE
--
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int > 9 AS version_above_nine;
version_above_nine
--------------------
f
(1 row)
CREATE SCHEMA fkey_reference_table;
SET search_path TO 'fkey_reference_table';
SET citus.shard_replication_factor TO 1;
@ -28,7 +35,9 @@ SELECT
relid::regclass::text,
refd_relid::regclass::text
FROM
table_fkey_cols
table_fkey_cols
WHERE
"schema" = 'fkey_reference_table'
)
d $$ )).RESULT::json )::json )).* ;
CREATE TABLE referenced_table(id int UNIQUE, test_column int);
@ -722,38 +731,6 @@ INSERT INTO referencing_table SELECT x,(random()*1000)::int FROM generate_series
DROP TABLE referenced_table CASCADE;
NOTICE: drop cascades to constraint fkey_ref on table referencing_table
DROP TABLE referencing_table CASCADE;
-- In the following test, we show that Citus currently does not support
-- VALIDATE command.
CREATE TABLE referenced_table(test_column int, test_column2 int, PRIMARY KEY(test_column));
CREATE TABLE referencing_table(id int, ref_id int DEFAULT -1);
SELECT create_reference_table('referenced_table');
create_reference_table
------------------------
(1 row)
SELECT create_distributed_table('referencing_table', 'id');
create_distributed_table
--------------------------
(1 row)
ALTER TABLE referencing_table ADD CONSTRAINT fkey_ref FOREIGN KEY (ref_id) REFERENCES referenced_table(test_column) ON DELETE SET DEFAULT NOT VALID;
-- Even if the foreign constraint is added with "NOT VALID",
-- we make sure that it is still applied to the upcoming inserts.
INSERT INTO referenced_table SELECT x, x FROM generate_series(0,1000) AS f(x);
INSERT INTO referencing_table SELECT x, x FROM generate_series(0,1000) AS f(x);
-- we expect this to fail because of the foreign constraint.
INSERT INTO referencing_table SELECT x, x FROM generate_series(1000,1001) AS f(x);
ERROR: insert or update on table "referencing_table_7000220" violates foreign key constraint "fkey_ref_7000220"
DETAIL: Key (ref_id)=(1001) is not present in table "referenced_table_7000214".
-- currently not supported
ALTER TABLE referencing_table VALIDATE CONSTRAINT fkey_ref;
ERROR: alter table command is currently unsupported
DETAIL: Only ADD|DROP COLUMN, SET|DROP NOT NULL, SET|DROP DEFAULT, ADD|DROP CONSTRAINT, SET (), RESET (), ATTACH|DETACH PARTITION and TYPE subcommands are supported.
DROP TABLE referenced_table CASCADE;
NOTICE: drop cascades to constraint fkey_ref on table referencing_table
DROP TABLE referencing_table CASCADE;
-- In the following tests, we create a foreign constraint with
-- ON UPDATE CASCADE and see if it works properly with cascading upsert
CREATE TABLE referenced_table(test_column int, test_column2 int, PRIMARY KEY(test_column));
@ -845,38 +822,38 @@ ALTER TABLE referencing_table ADD CONSTRAINT foreign_key_2 FOREIGN KEY (id) REFE
SELECT * FROM table_fkeys_in_workers WHERE relid LIKE 'fkey_reference_table.%' AND refd_relid LIKE 'fkey_reference_table.%' ORDER BY 1,2,3;
name | relid | refd_relid
-----------------------+------------------------------------------------+------------------------------------------------
fkey_ref_7000235 | fkey_reference_table.referencing_table_7000235 | fkey_reference_table.referenced_table_7000233
fkey_ref_7000236 | fkey_reference_table.referencing_table_7000236 | fkey_reference_table.referenced_table_7000233
fkey_ref_7000237 | fkey_reference_table.referencing_table_7000237 | fkey_reference_table.referenced_table_7000233
fkey_ref_7000238 | fkey_reference_table.referencing_table_7000238 | fkey_reference_table.referenced_table_7000233
fkey_ref_7000239 | fkey_reference_table.referencing_table_7000239 | fkey_reference_table.referenced_table_7000233
fkey_ref_7000240 | fkey_reference_table.referencing_table_7000240 | fkey_reference_table.referenced_table_7000233
fkey_ref_7000241 | fkey_reference_table.referencing_table_7000241 | fkey_reference_table.referenced_table_7000233
fkey_ref_7000242 | fkey_reference_table.referencing_table_7000242 | fkey_reference_table.referenced_table_7000233
foreign_key_2_7000235 | fkey_reference_table.referencing_table_7000235 | fkey_reference_table.referenced_table2_7000234
foreign_key_2_7000236 | fkey_reference_table.referencing_table_7000236 | fkey_reference_table.referenced_table2_7000234
foreign_key_2_7000237 | fkey_reference_table.referencing_table_7000237 | fkey_reference_table.referenced_table2_7000234
foreign_key_2_7000238 | fkey_reference_table.referencing_table_7000238 | fkey_reference_table.referenced_table2_7000234
foreign_key_2_7000239 | fkey_reference_table.referencing_table_7000239 | fkey_reference_table.referenced_table2_7000234
foreign_key_2_7000240 | fkey_reference_table.referencing_table_7000240 | fkey_reference_table.referenced_table2_7000234
foreign_key_2_7000241 | fkey_reference_table.referencing_table_7000241 | fkey_reference_table.referenced_table2_7000234
foreign_key_2_7000242 | fkey_reference_table.referencing_table_7000242 | fkey_reference_table.referenced_table2_7000234
fkey_ref_7000226 | fkey_reference_table.referencing_table_7000226 | fkey_reference_table.referenced_table_7000224
fkey_ref_7000227 | fkey_reference_table.referencing_table_7000227 | fkey_reference_table.referenced_table_7000224
fkey_ref_7000228 | fkey_reference_table.referencing_table_7000228 | fkey_reference_table.referenced_table_7000224
fkey_ref_7000229 | fkey_reference_table.referencing_table_7000229 | fkey_reference_table.referenced_table_7000224
fkey_ref_7000230 | fkey_reference_table.referencing_table_7000230 | fkey_reference_table.referenced_table_7000224
fkey_ref_7000231 | fkey_reference_table.referencing_table_7000231 | fkey_reference_table.referenced_table_7000224
fkey_ref_7000232 | fkey_reference_table.referencing_table_7000232 | fkey_reference_table.referenced_table_7000224
fkey_ref_7000233 | fkey_reference_table.referencing_table_7000233 | fkey_reference_table.referenced_table_7000224
foreign_key_2_7000226 | fkey_reference_table.referencing_table_7000226 | fkey_reference_table.referenced_table2_7000225
foreign_key_2_7000227 | fkey_reference_table.referencing_table_7000227 | fkey_reference_table.referenced_table2_7000225
foreign_key_2_7000228 | fkey_reference_table.referencing_table_7000228 | fkey_reference_table.referenced_table2_7000225
foreign_key_2_7000229 | fkey_reference_table.referencing_table_7000229 | fkey_reference_table.referenced_table2_7000225
foreign_key_2_7000230 | fkey_reference_table.referencing_table_7000230 | fkey_reference_table.referenced_table2_7000225
foreign_key_2_7000231 | fkey_reference_table.referencing_table_7000231 | fkey_reference_table.referenced_table2_7000225
foreign_key_2_7000232 | fkey_reference_table.referencing_table_7000232 | fkey_reference_table.referenced_table2_7000225
foreign_key_2_7000233 | fkey_reference_table.referencing_table_7000233 | fkey_reference_table.referenced_table2_7000225
(16 rows)
INSERT INTO referenced_table SELECT x, x+1 FROM generate_series(0,1000) AS f(x);
INSERT INTO referenced_table2 SELECT x, x+1 FROM generate_series(500,1500) AS f(x);
-- should fail
INSERT INTO referencing_table SELECT x, x+1 FROM generate_series(0,1500) AS f(x);
ERROR: insert or update on table "referencing_table_7000242" violates foreign key constraint "foreign_key_2_7000242"
DETAIL: Key (id)=(9) is not present in table "referenced_table2_7000234".
ERROR: insert or update on table "referencing_table_7000227" violates foreign key constraint "foreign_key_2_7000227"
DETAIL: Key (id)=(5) is not present in table "referenced_table2_7000225".
-- should fail
INSERT INTO referencing_table SELECT x, x+1 FROM generate_series(0,400) AS f(x);
ERROR: insert or update on table "referencing_table_7000242" violates foreign key constraint "foreign_key_2_7000242"
DETAIL: Key (id)=(9) is not present in table "referenced_table2_7000234".
ERROR: insert or update on table "referencing_table_7000227" violates foreign key constraint "foreign_key_2_7000227"
DETAIL: Key (id)=(5) is not present in table "referenced_table2_7000225".
-- should fail
INSERT INTO referencing_table SELECT x, x+1 FROM generate_series(1000,1400) AS f(x);
ERROR: insert or update on table "referencing_table_7000242" violates foreign key constraint "fkey_ref_7000242"
DETAIL: Key (id)=(1023) is not present in table "referenced_table_7000233".
ERROR: insert or update on table "referencing_table_7000227" violates foreign key constraint "fkey_ref_7000227"
DETAIL: Key (id)=(1005) is not present in table "referenced_table_7000224".
-- should success
INSERT INTO referencing_table SELECT x, x+1 FROM generate_series(600,900) AS f(x);
SELECT count(*) FROM referencing_table;
@ -972,38 +949,38 @@ COMMIT;
SELECT * FROM table_fkeys_in_workers WHERE relid LIKE 'fkey_reference_table.%' AND refd_relid LIKE 'fkey_reference_table.%' ORDER BY 1,2,3;
name | relid | refd_relid
-----------------------+------------------------------------------------+------------------------------------------------
fkey_ref_7000255 | fkey_reference_table.referencing_table_7000255 | fkey_reference_table.referenced_table_7000253
fkey_ref_7000256 | fkey_reference_table.referencing_table_7000256 | fkey_reference_table.referenced_table_7000253
fkey_ref_7000257 | fkey_reference_table.referencing_table_7000257 | fkey_reference_table.referenced_table_7000253
fkey_ref_7000258 | fkey_reference_table.referencing_table_7000258 | fkey_reference_table.referenced_table_7000253
fkey_ref_7000259 | fkey_reference_table.referencing_table_7000259 | fkey_reference_table.referenced_table_7000253
fkey_ref_7000260 | fkey_reference_table.referencing_table_7000260 | fkey_reference_table.referenced_table_7000253
fkey_ref_7000261 | fkey_reference_table.referencing_table_7000261 | fkey_reference_table.referenced_table_7000253
fkey_ref_7000262 | fkey_reference_table.referencing_table_7000262 | fkey_reference_table.referenced_table_7000253
foreign_key_2_7000255 | fkey_reference_table.referencing_table_7000255 | fkey_reference_table.referenced_table2_7000254
foreign_key_2_7000256 | fkey_reference_table.referencing_table_7000256 | fkey_reference_table.referenced_table2_7000254
foreign_key_2_7000257 | fkey_reference_table.referencing_table_7000257 | fkey_reference_table.referenced_table2_7000254
foreign_key_2_7000258 | fkey_reference_table.referencing_table_7000258 | fkey_reference_table.referenced_table2_7000254
foreign_key_2_7000259 | fkey_reference_table.referencing_table_7000259 | fkey_reference_table.referenced_table2_7000254
foreign_key_2_7000260 | fkey_reference_table.referencing_table_7000260 | fkey_reference_table.referenced_table2_7000254
foreign_key_2_7000261 | fkey_reference_table.referencing_table_7000261 | fkey_reference_table.referenced_table2_7000254
foreign_key_2_7000262 | fkey_reference_table.referencing_table_7000262 | fkey_reference_table.referenced_table2_7000254
fkey_ref_7000246 | fkey_reference_table.referencing_table_7000246 | fkey_reference_table.referenced_table_7000244
fkey_ref_7000247 | fkey_reference_table.referencing_table_7000247 | fkey_reference_table.referenced_table_7000244
fkey_ref_7000248 | fkey_reference_table.referencing_table_7000248 | fkey_reference_table.referenced_table_7000244
fkey_ref_7000249 | fkey_reference_table.referencing_table_7000249 | fkey_reference_table.referenced_table_7000244
fkey_ref_7000250 | fkey_reference_table.referencing_table_7000250 | fkey_reference_table.referenced_table_7000244
fkey_ref_7000251 | fkey_reference_table.referencing_table_7000251 | fkey_reference_table.referenced_table_7000244
fkey_ref_7000252 | fkey_reference_table.referencing_table_7000252 | fkey_reference_table.referenced_table_7000244
fkey_ref_7000253 | fkey_reference_table.referencing_table_7000253 | fkey_reference_table.referenced_table_7000244
foreign_key_2_7000246 | fkey_reference_table.referencing_table_7000246 | fkey_reference_table.referenced_table2_7000245
foreign_key_2_7000247 | fkey_reference_table.referencing_table_7000247 | fkey_reference_table.referenced_table2_7000245
foreign_key_2_7000248 | fkey_reference_table.referencing_table_7000248 | fkey_reference_table.referenced_table2_7000245
foreign_key_2_7000249 | fkey_reference_table.referencing_table_7000249 | fkey_reference_table.referenced_table2_7000245
foreign_key_2_7000250 | fkey_reference_table.referencing_table_7000250 | fkey_reference_table.referenced_table2_7000245
foreign_key_2_7000251 | fkey_reference_table.referencing_table_7000251 | fkey_reference_table.referenced_table2_7000245
foreign_key_2_7000252 | fkey_reference_table.referencing_table_7000252 | fkey_reference_table.referenced_table2_7000245
foreign_key_2_7000253 | fkey_reference_table.referencing_table_7000253 | fkey_reference_table.referenced_table2_7000245
(16 rows)
INSERT INTO referenced_table SELECT x, x+1 FROM generate_series(0,1000) AS f(x);
INSERT INTO referenced_table2 SELECT x, x+1 FROM generate_series(500,1500) AS f(x);
-- should fail
INSERT INTO referencing_table SELECT x, x+1 FROM generate_series(0,1500) AS f(x);
ERROR: insert or update on table "referencing_table_7000260" violates foreign key constraint "foreign_key_2_7000260"
DETAIL: Key (ref_id)=(7) is not present in table "referenced_table2_7000254".
ERROR: insert or update on table "referencing_table_7000251" violates foreign key constraint "foreign_key_2_7000251"
DETAIL: Key (ref_id)=(7) is not present in table "referenced_table2_7000245".
-- should fail
INSERT INTO referencing_table SELECT x, x+1 FROM generate_series(0,400) AS f(x);
ERROR: insert or update on table "referencing_table_7000260" violates foreign key constraint "foreign_key_2_7000260"
DETAIL: Key (ref_id)=(7) is not present in table "referenced_table2_7000254".
ERROR: insert or update on table "referencing_table_7000251" violates foreign key constraint "foreign_key_2_7000251"
DETAIL: Key (ref_id)=(7) is not present in table "referenced_table2_7000245".
-- should fail
INSERT INTO referencing_table SELECT x, x+1 FROM generate_series(1000,1400) AS f(x);
ERROR: insert or update on table "referencing_table_7000260" violates foreign key constraint "fkey_ref_7000260"
DETAIL: Key (id)=(1001) is not present in table "referenced_table_7000253".
ERROR: insert or update on table "referencing_table_7000251" violates foreign key constraint "fkey_ref_7000251"
DETAIL: Key (id)=(1001) is not present in table "referenced_table_7000244".
-- should success
INSERT INTO referencing_table SELECT x, x+501 FROM generate_series(0,1000) AS f(x);
SELECT count(*) FROM referencing_table;
@ -1105,43 +1082,43 @@ COMMIT;
SELECT * FROM table_fkeys_in_workers WHERE relid LIKE 'fkey_reference_table.%' AND refd_relid LIKE 'fkey_reference_table.%' ORDER BY 1,2,3;
name | relid | refd_relid
--------------------------+-------------------------------------------------+------------------------------------------------
fkey_ref_7000274 | fkey_reference_table.referencing_table_7000274 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000275 | fkey_reference_table.referencing_table_7000275 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000276 | fkey_reference_table.referencing_table_7000276 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000277 | fkey_reference_table.referencing_table_7000277 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000278 | fkey_reference_table.referencing_table_7000278 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000279 | fkey_reference_table.referencing_table_7000279 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000280 | fkey_reference_table.referencing_table_7000280 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000281 | fkey_reference_table.referencing_table_7000281 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000282 | fkey_reference_table.referencing_table2_7000282 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000283 | fkey_reference_table.referencing_table2_7000283 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000284 | fkey_reference_table.referencing_table2_7000284 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000285 | fkey_reference_table.referencing_table2_7000285 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000286 | fkey_reference_table.referencing_table2_7000286 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000287 | fkey_reference_table.referencing_table2_7000287 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000288 | fkey_reference_table.referencing_table2_7000288 | fkey_reference_table.referenced_table_7000273
fkey_ref_7000289 | fkey_reference_table.referencing_table2_7000289 | fkey_reference_table.referenced_table_7000273
fkey_ref_to_dist_7000282 | fkey_reference_table.referencing_table2_7000282 | fkey_reference_table.referencing_table_7000274
fkey_ref_to_dist_7000283 | fkey_reference_table.referencing_table2_7000283 | fkey_reference_table.referencing_table_7000275
fkey_ref_to_dist_7000284 | fkey_reference_table.referencing_table2_7000284 | fkey_reference_table.referencing_table_7000276
fkey_ref_to_dist_7000285 | fkey_reference_table.referencing_table2_7000285 | fkey_reference_table.referencing_table_7000277
fkey_ref_to_dist_7000286 | fkey_reference_table.referencing_table2_7000286 | fkey_reference_table.referencing_table_7000278
fkey_ref_to_dist_7000287 | fkey_reference_table.referencing_table2_7000287 | fkey_reference_table.referencing_table_7000279
fkey_ref_to_dist_7000288 | fkey_reference_table.referencing_table2_7000288 | fkey_reference_table.referencing_table_7000280
fkey_ref_to_dist_7000289 | fkey_reference_table.referencing_table2_7000289 | fkey_reference_table.referencing_table_7000281
fkey_ref_7000265 | fkey_reference_table.referencing_table_7000265 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000266 | fkey_reference_table.referencing_table_7000266 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000267 | fkey_reference_table.referencing_table_7000267 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000268 | fkey_reference_table.referencing_table_7000268 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000269 | fkey_reference_table.referencing_table_7000269 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000270 | fkey_reference_table.referencing_table_7000270 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000271 | fkey_reference_table.referencing_table_7000271 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000272 | fkey_reference_table.referencing_table_7000272 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000273 | fkey_reference_table.referencing_table2_7000273 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000274 | fkey_reference_table.referencing_table2_7000274 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000275 | fkey_reference_table.referencing_table2_7000275 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000276 | fkey_reference_table.referencing_table2_7000276 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000277 | fkey_reference_table.referencing_table2_7000277 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000278 | fkey_reference_table.referencing_table2_7000278 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000279 | fkey_reference_table.referencing_table2_7000279 | fkey_reference_table.referenced_table_7000264
fkey_ref_7000280 | fkey_reference_table.referencing_table2_7000280 | fkey_reference_table.referenced_table_7000264
fkey_ref_to_dist_7000273 | fkey_reference_table.referencing_table2_7000273 | fkey_reference_table.referencing_table_7000265
fkey_ref_to_dist_7000274 | fkey_reference_table.referencing_table2_7000274 | fkey_reference_table.referencing_table_7000266
fkey_ref_to_dist_7000275 | fkey_reference_table.referencing_table2_7000275 | fkey_reference_table.referencing_table_7000267
fkey_ref_to_dist_7000276 | fkey_reference_table.referencing_table2_7000276 | fkey_reference_table.referencing_table_7000268
fkey_ref_to_dist_7000277 | fkey_reference_table.referencing_table2_7000277 | fkey_reference_table.referencing_table_7000269
fkey_ref_to_dist_7000278 | fkey_reference_table.referencing_table2_7000278 | fkey_reference_table.referencing_table_7000270
fkey_ref_to_dist_7000279 | fkey_reference_table.referencing_table2_7000279 | fkey_reference_table.referencing_table_7000271
fkey_ref_to_dist_7000280 | fkey_reference_table.referencing_table2_7000280 | fkey_reference_table.referencing_table_7000272
(24 rows)
INSERT INTO referenced_table SELECT x, x+1 FROM generate_series(0,1000) AS f(x);
-- should fail
INSERT INTO referencing_table2 SELECT x, x+1 FROM generate_series(0,100) AS f(x);
ERROR: insert or update on table "referencing_table2_7000284" violates foreign key constraint "fkey_ref_to_dist_7000284"
DETAIL: Key (id)=(4) is not present in table "referencing_table_7000276".
ERROR: insert or update on table "referencing_table2_7000274" violates foreign key constraint "fkey_ref_to_dist_7000274"
DETAIL: Key (id)=(5) is not present in table "referencing_table_7000266".
-- should success
INSERT INTO referencing_table SELECT x, x+1 FROM generate_series(0,400) AS f(x);
-- should fail
INSERT INTO referencing_table2 SELECT x, x+1 FROM generate_series(200,500) AS f(x);
ERROR: insert or update on table "referencing_table2_7000284" violates foreign key constraint "fkey_ref_to_dist_7000284"
DETAIL: Key (id)=(408) is not present in table "referencing_table_7000276".
ERROR: insert or update on table "referencing_table2_7000274" violates foreign key constraint "fkey_ref_to_dist_7000274"
DETAIL: Key (id)=(403) is not present in table "referencing_table_7000266".
-- should success
INSERT INTO referencing_table2 SELECT x, x+1 FROM generate_series(0,300) AS f(x);
DELETE FROM referenced_table WHERE test_column < 200;
@ -1239,22 +1216,22 @@ ALTER TABLE referencing_table ADD CONSTRAINT fkey_ref FOREIGN KEY (ref_id, ref_i
SELECT * FROM table_fkeys_in_workers WHERE relid LIKE 'fkey_reference_table.referencing%' ORDER BY 1,2,3;
name | relid | refd_relid
-----------------------------------------------+------------------------------------------------------------+------------------------------------------------
fkey_ref_7000308 | fkey_reference_table.referencing_table_7000308 | fkey_reference_table.referenced_table_7000307
fkey_ref_7000309 | fkey_reference_table.referencing_table_7000309 | fkey_reference_table.referenced_table_7000307
fkey_ref_7000310 | fkey_reference_table.referencing_table_7000310 | fkey_reference_table.referenced_table_7000307
fkey_ref_7000311 | fkey_reference_table.referencing_table_7000311 | fkey_reference_table.referenced_table_7000307
fkey_ref_7000312 | fkey_reference_table.referencing_table_7000312 | fkey_reference_table.referenced_table_7000307
fkey_ref_7000313 | fkey_reference_table.referencing_table_7000313 | fkey_reference_table.referenced_table_7000307
fkey_ref_7000314 | fkey_reference_table.referencing_table_7000314 | fkey_reference_table.referenced_table_7000307
fkey_ref_7000315 | fkey_reference_table.referencing_table_7000315 | fkey_reference_table.referenced_table_7000307
referencing_referencing_table_id_fkey_7000316 | fkey_reference_table.referencing_referencing_table_7000316 | fkey_reference_table.referencing_table_7000308
referencing_referencing_table_id_fkey_7000317 | fkey_reference_table.referencing_referencing_table_7000317 | fkey_reference_table.referencing_table_7000309
referencing_referencing_table_id_fkey_7000318 | fkey_reference_table.referencing_referencing_table_7000318 | fkey_reference_table.referencing_table_7000310
referencing_referencing_table_id_fkey_7000319 | fkey_reference_table.referencing_referencing_table_7000319 | fkey_reference_table.referencing_table_7000311
referencing_referencing_table_id_fkey_7000320 | fkey_reference_table.referencing_referencing_table_7000320 | fkey_reference_table.referencing_table_7000312
referencing_referencing_table_id_fkey_7000321 | fkey_reference_table.referencing_referencing_table_7000321 | fkey_reference_table.referencing_table_7000313
referencing_referencing_table_id_fkey_7000322 | fkey_reference_table.referencing_referencing_table_7000322 | fkey_reference_table.referencing_table_7000314
referencing_referencing_table_id_fkey_7000323 | fkey_reference_table.referencing_referencing_table_7000323 | fkey_reference_table.referencing_table_7000315
fkey_ref_7000299 | fkey_reference_table.referencing_table_7000299 | fkey_reference_table.referenced_table_7000298
fkey_ref_7000300 | fkey_reference_table.referencing_table_7000300 | fkey_reference_table.referenced_table_7000298
fkey_ref_7000301 | fkey_reference_table.referencing_table_7000301 | fkey_reference_table.referenced_table_7000298
fkey_ref_7000302 | fkey_reference_table.referencing_table_7000302 | fkey_reference_table.referenced_table_7000298
fkey_ref_7000303 | fkey_reference_table.referencing_table_7000303 | fkey_reference_table.referenced_table_7000298
fkey_ref_7000304 | fkey_reference_table.referencing_table_7000304 | fkey_reference_table.referenced_table_7000298
fkey_ref_7000305 | fkey_reference_table.referencing_table_7000305 | fkey_reference_table.referenced_table_7000298
fkey_ref_7000306 | fkey_reference_table.referencing_table_7000306 | fkey_reference_table.referenced_table_7000298
referencing_referencing_table_id_fkey_7000307 | fkey_reference_table.referencing_referencing_table_7000307 | fkey_reference_table.referencing_table_7000299
referencing_referencing_table_id_fkey_7000308 | fkey_reference_table.referencing_referencing_table_7000308 | fkey_reference_table.referencing_table_7000300
referencing_referencing_table_id_fkey_7000309 | fkey_reference_table.referencing_referencing_table_7000309 | fkey_reference_table.referencing_table_7000301
referencing_referencing_table_id_fkey_7000310 | fkey_reference_table.referencing_referencing_table_7000310 | fkey_reference_table.referencing_table_7000302
referencing_referencing_table_id_fkey_7000311 | fkey_reference_table.referencing_referencing_table_7000311 | fkey_reference_table.referencing_table_7000303
referencing_referencing_table_id_fkey_7000312 | fkey_reference_table.referencing_referencing_table_7000312 | fkey_reference_table.referencing_table_7000304
referencing_referencing_table_id_fkey_7000313 | fkey_reference_table.referencing_referencing_table_7000313 | fkey_reference_table.referencing_table_7000305
referencing_referencing_table_id_fkey_7000314 | fkey_reference_table.referencing_referencing_table_7000314 | fkey_reference_table.referencing_table_7000306
(16 rows)
INSERT INTO referenced_table SELECT x, x+1 FROM generate_series(1,1000) AS f(x);

View File

@ -0,0 +1,59 @@
Parsed test spec with 2 sessions
starting permutation: s1-initialize s1-add-constraint s1-begin s2-begin s1-validate s2-insert s1-commit s2-commit
create_distributed_table
step s1-initialize: INSERT INTO constrained_table VALUES (0, 0), (1, 1), (2, 2), (3, 4);
step s1-add-constraint: ALTER TABLE constrained_table ADD CONSTRAINT check_constraint CHECK(int_data<30) NOT VALID;
step s1-begin: BEGIN;
step s2-begin: BEGIN;
step s1-validate: ALTER TABLE constrained_table VALIDATE CONSTRAINT check_constraint;
step s2-insert: INSERT INTO constrained_table VALUES(10, 10);
step s1-commit: COMMIT;
step s2-commit: COMMIT;
starting permutation: s1-initialize s1-add-constraint s1-begin s2-begin s1-validate s2-select s1-commit s2-commit
create_distributed_table
step s1-initialize: INSERT INTO constrained_table VALUES (0, 0), (1, 1), (2, 2), (3, 4);
step s1-add-constraint: ALTER TABLE constrained_table ADD CONSTRAINT check_constraint CHECK(int_data<30) NOT VALID;
step s1-begin: BEGIN;
step s2-begin: BEGIN;
step s1-validate: ALTER TABLE constrained_table VALIDATE CONSTRAINT check_constraint;
step s2-select: SELECT sum(int_data) FROM constrained_table;
sum
7
step s1-commit: COMMIT;
step s2-commit: COMMIT;
starting permutation: s1-initialize s1-add-constraint s1-begin s2-begin s2-insert s1-validate s1-commit s2-commit
create_distributed_table
step s1-initialize: INSERT INTO constrained_table VALUES (0, 0), (1, 1), (2, 2), (3, 4);
step s1-add-constraint: ALTER TABLE constrained_table ADD CONSTRAINT check_constraint CHECK(int_data<30) NOT VALID;
step s1-begin: BEGIN;
step s2-begin: BEGIN;
step s2-insert: INSERT INTO constrained_table VALUES(10, 10);
step s1-validate: ALTER TABLE constrained_table VALIDATE CONSTRAINT check_constraint;
step s1-commit: COMMIT;
step s2-commit: COMMIT;
starting permutation: s1-initialize s1-add-constraint s1-begin s2-begin s2-select s1-validate s1-commit s2-commit
create_distributed_table
step s1-initialize: INSERT INTO constrained_table VALUES (0, 0), (1, 1), (2, 2), (3, 4);
step s1-add-constraint: ALTER TABLE constrained_table ADD CONSTRAINT check_constraint CHECK(int_data<30) NOT VALID;
step s1-begin: BEGIN;
step s2-begin: BEGIN;
step s2-select: SELECT sum(int_data) FROM constrained_table;
sum
7
step s1-validate: ALTER TABLE constrained_table VALIDATE CONSTRAINT check_constraint;
step s1-commit: COMMIT;
step s2-commit: COMMIT;

View File

@ -1385,7 +1385,7 @@ SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='reference_sche
-- as we expect, setting WITH OIDS does not work for reference tables
ALTER TABLE reference_schema.reference_table_ddl SET WITH OIDS;
ERROR: alter table command is currently unsupported
DETAIL: Only ADD|DROP COLUMN, SET|DROP NOT NULL, SET|DROP DEFAULT, ADD|DROP CONSTRAINT, SET (), RESET (), ATTACH|DETACH PARTITION and TYPE subcommands are supported.
DETAIL: Only ADD|DROP COLUMN, SET|DROP NOT NULL, SET|DROP DEFAULT, ADD|DROP|VALIDATE CONSTRAINT, SET (), RESET (), ATTACH|DETACH PARTITION and TYPE subcommands are supported.
-- now test the renaming of the table, and back to the expected name
ALTER TABLE reference_schema.reference_table_ddl RENAME TO reference_table_ddl_test;
ALTER TABLE reference_schema.reference_table_ddl_test RENAME TO reference_table_ddl;

View File

@ -17,7 +17,8 @@ SELECT rc.constraint_name AS "name",
kcu.column_name AS "column_name",
uc_kcu.column_name AS "refd_column_name",
format('%I.%I', kcu.table_schema, kcu.table_name)::regclass::oid AS relid,
format('%I.%I', uc_kcu.table_schema, uc_kcu.table_name)::regclass::oid AS refd_relid
format('%I.%I', uc_kcu.table_schema, uc_kcu.table_name)::regclass::oid AS refd_relid,
rc.constraint_schema AS "schema"
FROM information_schema.referential_constraints rc,
information_schema.key_column_usage kcu,
information_schema.key_column_usage uc_kcu

View File

@ -0,0 +1,150 @@
--
-- VALIDATE_CONSTRAINT
--
-- PostgreSQL 11 Docs Excerpt:
-- The queries that can have 'NOT VALID' option are of the form:
-- ALTER TABLE [ IF EXISTS ] [ ONLY ] name [ * ] ADD table_constraint NOT VALID [, ...]
--
-- where table_constraint is:
-- [ CONSTRAINT constraint_name ]
-- { CHECK ( expression ) [ NO INHERIT ] |
-- UNIQUE ( column_name [, ... ] ) index_parameters |
-- PRIMARY KEY ( column_name [, ... ] ) index_parameters |
-- EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] ) index_parameters [ WHERE ( predicate ) ] |
-- FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ]
-- [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ] }
-- [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
-- This form adds a new constraint to a table using the same syntax as CREATE TABLE, plus the option NOT VALID, which is
-- currently only allowed for foreign key and CHECK constraints. If the constraint is marked NOT VALID, the
-- potentially-lengthy initial check to verify that all rows in the table satisfy the constraint is skipped.
-- The constraint will still be enforced against subsequent inserts or updates (that is, they'll fail unless there is a
-- matching row in the referenced table, in the case of foreign keys; and they'll fail unless the new row matches the
-- specified check constraints). But the database will not assume that the constraint holds for all rows in the table,
-- until it is validated by using the VALIDATE CONSTRAINT option.
CREATE SCHEMA validate_constraint;
SET search_path TO 'validate_constraint';
SET citus.shard_replication_factor TO 1;
SET citus.shard_count TO 8;
SET citus.next_shard_id TO 8000000;
SET citus.next_placement_id TO 8000000;
CREATE TYPE constraint_validity AS (name text, validated bool);
SELECT run_command_on_workers(
$$CREATE TYPE constraint_validity AS (name text, validated bool)$$);
run_command_on_workers
-----------------------------------
(localhost,57637,t,"CREATE TYPE")
(localhost,57638,t,"CREATE TYPE")
(2 rows)
CREATE VIEW constraint_validations_in_workers AS
SELECT (json_populate_record(NULL :: constraint_validity,
json_array_elements_text((run_command_on_workers($$
SELECT
COALESCE(json_agg(row_to_json(d)), '[]'::json)
FROM
(
SELECT conname as name,
convalidated as validated
FROM pg_catalog.pg_constraint AS con
JOIN pg_catalog.pg_namespace AS ns
ON ns.oid = con.connamespace
WHERE nspname = 'validate_constraint'
AND contype = 'c'
ORDER BY 1,2
)
d $$)).RESULT :: json) :: json)).*
ORDER BY 1,2;
CREATE VIEW constraint_validations AS
SELECT conname as "Constraint",
convalidated as "Validated?"
FROM pg_catalog.pg_constraint AS con
JOIN pg_catalog.pg_namespace AS ns ON ns.oid = con.connamespace
WHERE nspname = 'validate_constraint'
AND contype = 'c';
CREATE TABLE referenced_table (id int UNIQUE, test_column int);
SELECT create_reference_table('referenced_table');
create_reference_table
------------------------
(1 row)
CREATE TABLE referencing_table (id int, ref_id int);
SELECT create_distributed_table('referencing_table', 'ref_id');
create_distributed_table
--------------------------
(1 row)
CREATE TABLE constrained_table (id int, constrained_column int);
SELECT create_distributed_table('constrained_table', 'constrained_column');
create_distributed_table
--------------------------
(1 row)
-- The two constraint types that are allowed to be NOT VALID
BEGIN;
ALTER TABLE constrained_table
ADD CONSTRAINT check_constraint CHECK (constrained_column > 100) NOT VALID;
ALTER TABLE constrained_table
VALIDATE CONSTRAINT check_constraint;
ROLLBACK;
BEGIN;
ALTER TABLE referencing_table
ADD CONSTRAINT fk_constraint FOREIGN KEY (ref_id) REFERENCES referenced_table (id) NOT VALID;
ALTER TABLE referencing_table
VALIDATE CONSTRAINT fk_constraint;
ROLLBACK;
-- It is possible that some other table_constraint commands will support NOT VALID option in the future
-- These should fail as Postgres does not yet allow these constraints to be NOT VALID
-- If one of these queries are not failing on a future Postgres version, we will need to test corresponding VALIDATE CONSTRAINT queries
ALTER TABLE constrained_table
ADD CONSTRAINT unique_constraint UNIQUE (constrained_column) NOT VALID;
ERROR: UNIQUE constraints cannot be marked NOT VALID
ALTER TABLE constrained_table
ADD CONSTRAINT pk_constraint PRIMARY KEY (id) NOT VALID;
ERROR: PRIMARY KEY constraints cannot be marked NOT VALID
ALTER TABLE constrained_table
ADD CONSTRAINT exclude_constraint EXCLUDE USING gist (id WITH =, constrained_column WITH <>) NOT VALID;
ERROR: EXCLUDE constraints cannot be marked NOT VALID
INSERT INTO constrained_table
SELECT x, x
from generate_series(1, 1000) as f (x);
-- a constraint that can be validated
ALTER TABLE constrained_table
ADD CONSTRAINT validatable_constraint CHECK (constrained_column < 10000) NOT VALID;
ALTER TABLE constrained_table
VALIDATE CONSTRAINT validatable_constraint;
-- Check which constraints are validated
SELECT *
FROM constraint_validations
ORDER BY 1, 2;
Constraint | Validated?
------------------------+------------
validatable_constraint | t
(1 row)
SELECT *
FROM constraint_validations_in_workers
ORDER BY 1, 2;
name | validated
--------------------------------+-----------
validatable_constraint_8000009 | t
validatable_constraint_8000010 | t
validatable_constraint_8000011 | t
validatable_constraint_8000012 | t
validatable_constraint_8000013 | t
validatable_constraint_8000014 | t
validatable_constraint_8000015 | t
validatable_constraint_8000016 | t
(8 rows)
DROP TABLE constrained_table;
DROP TABLE referenced_table CASCADE;
DROP TABLE referencing_table;
DROP SCHEMA validate_constraint CASCADE;
NOTICE: drop cascades to 3 other objects
DETAIL: drop cascades to type constraint_validity
drop cascades to view constraint_validations_in_workers
drop cascades to view constraint_validations
SET search_path TO DEFAULT;

View File

@ -43,6 +43,7 @@ test: isolation_truncate_vs_all
test: isolation_drop_vs_all
test: isolation_ddl_vs_all
test: isolation_citus_dist_activity
test: isolation_validate_vs_insert
# MX tests
test: isolation_reference_on_mx

View File

@ -173,7 +173,7 @@ test: multi_modifications
test: multi_distribution_metadata
test: multi_generate_ddl_commands multi_create_shards multi_prune_shard_list multi_repair_shards
test: multi_upsert multi_simple_queries multi_create_insert_proxy multi_data_types
test: multi_utilities foreign_key_to_reference_table
test: multi_utilities foreign_key_to_reference_table validate_constraint
test: multi_modifying_xacts
test: multi_repartition_udt multi_repartitioned_subquery_udf multi_subtransactions
test: multi_transaction_recovery

View File

@ -344,7 +344,7 @@ SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineite
ALTER TABLE lineitem_alter ADD COLUMN int_column3 INTEGER,
ALTER COLUMN int_column1 SET STATISTICS 10;
ERROR: alter table command is currently unsupported
DETAIL: Only ADD|DROP COLUMN, SET|DROP NOT NULL, SET|DROP DEFAULT, ADD|DROP CONSTRAINT, SET (), RESET (), ATTACH|DETACH PARTITION and TYPE subcommands are supported.
DETAIL: Only ADD|DROP COLUMN, SET|DROP NOT NULL, SET|DROP DEFAULT, ADD|DROP|VALIDATE CONSTRAINT, SET (), RESET (), ATTACH|DETACH PARTITION and TYPE subcommands are supported.
ALTER TABLE lineitem_alter DROP COLUMN int_column1, DROP COLUMN int_column2;
SELECT "Column", "Type", "Modifiers" FROM table_desc WHERE relid='public.lineitem_alter'::regclass;
Column | Type | Modifiers
@ -376,12 +376,12 @@ ERROR: cannot execute ALTER TABLE command involving partition column
-- Verify that we error out on unsupported statement types
ALTER TABLE lineitem_alter ALTER COLUMN l_orderkey SET STATISTICS 100;
ERROR: alter table command is currently unsupported
DETAIL: Only ADD|DROP COLUMN, SET|DROP NOT NULL, SET|DROP DEFAULT, ADD|DROP CONSTRAINT, SET (), RESET (), ATTACH|DETACH PARTITION and TYPE subcommands are supported.
DETAIL: Only ADD|DROP COLUMN, SET|DROP NOT NULL, SET|DROP DEFAULT, ADD|DROP|VALIDATE CONSTRAINT, SET (), RESET (), ATTACH|DETACH PARTITION and TYPE subcommands are supported.
ALTER TABLE lineitem_alter DROP CONSTRAINT IF EXISTS non_existent_contraint;
NOTICE: constraint "non_existent_contraint" of relation "lineitem_alter" does not exist, skipping
ALTER TABLE lineitem_alter SET WITHOUT OIDS;
ERROR: alter table command is currently unsupported
DETAIL: Only ADD|DROP COLUMN, SET|DROP NOT NULL, SET|DROP DEFAULT, ADD|DROP CONSTRAINT, SET (), RESET (), ATTACH|DETACH PARTITION and TYPE subcommands are supported.
DETAIL: Only ADD|DROP COLUMN, SET|DROP NOT NULL, SET|DROP DEFAULT, ADD|DROP|VALIDATE CONSTRAINT, SET (), RESET (), ATTACH|DETACH PARTITION and TYPE subcommands are supported.
-- Verify that we error out in case of postgres errors on supported statement
-- types
ALTER TABLE lineitem_alter ADD COLUMN new_column non_existent_type;

View File

@ -0,0 +1,39 @@
#
# How we organize this isolation test spec, is explained at README.md file in this directory.
#
# create distributed table to test behavior of VALIDATE in concurrent operations
setup
{
SET citus.shard_replication_factor TO 1;
CREATE TABLE constrained_table(id integer, int_data int);
SELECT create_distributed_table('constrained_table', 'id');
}
# drop distributed table
teardown
{
DROP TABLE IF EXISTS constrained_table CASCADE;
}
# session 1
session "s1"
step "s1-initialize" { INSERT INTO constrained_table VALUES (0, 0), (1, 1), (2, 2), (3, 4); }
step "s1-begin" { BEGIN; }
step "s1-add-constraint" { ALTER TABLE constrained_table ADD CONSTRAINT check_constraint CHECK(int_data<30) NOT VALID; }
step "s1-validate" { ALTER TABLE constrained_table VALIDATE CONSTRAINT check_constraint; }
step "s1-commit" { COMMIT; }
# session 2
session "s2"
step "s2-begin" { BEGIN; }
step "s2-insert" { INSERT INTO constrained_table VALUES(10, 10); }
step "s2-insert-invalid" { INSERT INTO constrained_table VALUES(100, 100); }
step "s2-select" { SELECT sum(int_data) FROM constrained_table; }
step "s2-commit" { COMMIT; }
# permutations - check read and write are not blocked during validate queries
permutation "s1-initialize" "s1-add-constraint" "s1-begin" "s2-begin" "s1-validate" "s2-insert" "s1-commit" "s2-commit"
permutation "s1-initialize" "s1-add-constraint" "s1-begin" "s2-begin" "s1-validate" "s2-select" "s1-commit" "s2-commit"
permutation "s1-initialize" "s1-add-constraint" "s1-begin" "s2-begin" "s2-insert" "s1-validate" "s1-commit" "s2-commit"
permutation "s1-initialize" "s1-add-constraint" "s1-begin" "s2-begin" "s2-select" "s1-validate" "s1-commit" "s2-commit"

View File

@ -1,6 +1,8 @@
--
-- FOREIGN_KEY_TO_REFERENCE_TABLE
--
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int > 9 AS version_above_nine;
CREATE SCHEMA fkey_reference_table;
SET search_path TO 'fkey_reference_table';
@ -25,7 +27,9 @@ SELECT
relid::regclass::text,
refd_relid::regclass::text
FROM
table_fkey_cols
table_fkey_cols
WHERE
"schema" = 'fkey_reference_table'
)
d $$ )).RESULT::json )::json )).* ;
@ -362,27 +366,6 @@ INSERT INTO referencing_table SELECT x,(random()*1000)::int FROM generate_series
DROP TABLE referenced_table CASCADE;
DROP TABLE referencing_table CASCADE;
-- In the following test, we show that Citus currently does not support
-- VALIDATE command.
CREATE TABLE referenced_table(test_column int, test_column2 int, PRIMARY KEY(test_column));
CREATE TABLE referencing_table(id int, ref_id int DEFAULT -1);
SELECT create_reference_table('referenced_table');
SELECT create_distributed_table('referencing_table', 'id');
ALTER TABLE referencing_table ADD CONSTRAINT fkey_ref FOREIGN KEY (ref_id) REFERENCES referenced_table(test_column) ON DELETE SET DEFAULT NOT VALID;
-- Even if the foreign constraint is added with "NOT VALID",
-- we make sure that it is still applied to the upcoming inserts.
INSERT INTO referenced_table SELECT x, x FROM generate_series(0,1000) AS f(x);
INSERT INTO referencing_table SELECT x, x FROM generate_series(0,1000) AS f(x);
-- we expect this to fail because of the foreign constraint.
INSERT INTO referencing_table SELECT x, x FROM generate_series(1000,1001) AS f(x);
-- currently not supported
ALTER TABLE referencing_table VALIDATE CONSTRAINT fkey_ref;
DROP TABLE referenced_table CASCADE;
DROP TABLE referencing_table CASCADE;
-- In the following tests, we create a foreign constraint with
-- ON UPDATE CASCADE and see if it works properly with cascading upsert
CREATE TABLE referenced_table(test_column int, test_column2 int, PRIMARY KEY(test_column));

View File

@ -19,7 +19,8 @@ SELECT rc.constraint_name AS "name",
kcu.column_name AS "column_name",
uc_kcu.column_name AS "refd_column_name",
format('%I.%I', kcu.table_schema, kcu.table_name)::regclass::oid AS relid,
format('%I.%I', uc_kcu.table_schema, uc_kcu.table_name)::regclass::oid AS refd_relid
format('%I.%I', uc_kcu.table_schema, uc_kcu.table_name)::regclass::oid AS refd_relid,
rc.constraint_schema AS "schema"
FROM information_schema.referential_constraints rc,
information_schema.key_column_usage kcu,
information_schema.key_column_usage uc_kcu

View File

@ -0,0 +1,126 @@
--
-- VALIDATE_CONSTRAINT
--
-- PostgreSQL 11 Docs Excerpt:
-- The queries that can have 'NOT VALID' option are of the form:
-- ALTER TABLE [ IF EXISTS ] [ ONLY ] name [ * ] ADD table_constraint NOT VALID [, ...]
--
-- where table_constraint is:
-- [ CONSTRAINT constraint_name ]
-- { CHECK ( expression ) [ NO INHERIT ] |
-- UNIQUE ( column_name [, ... ] ) index_parameters |
-- PRIMARY KEY ( column_name [, ... ] ) index_parameters |
-- EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] ) index_parameters [ WHERE ( predicate ) ] |
-- FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ]
-- [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ] }
-- [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
-- This form adds a new constraint to a table using the same syntax as CREATE TABLE, plus the option NOT VALID, which is
-- currently only allowed for foreign key and CHECK constraints. If the constraint is marked NOT VALID, the
-- potentially-lengthy initial check to verify that all rows in the table satisfy the constraint is skipped.
-- The constraint will still be enforced against subsequent inserts or updates (that is, they'll fail unless there is a
-- matching row in the referenced table, in the case of foreign keys; and they'll fail unless the new row matches the
-- specified check constraints). But the database will not assume that the constraint holds for all rows in the table,
-- until it is validated by using the VALIDATE CONSTRAINT option.
CREATE SCHEMA validate_constraint;
SET search_path TO 'validate_constraint';
SET citus.shard_replication_factor TO 1;
SET citus.shard_count TO 8;
SET citus.next_shard_id TO 8000000;
SET citus.next_placement_id TO 8000000;
CREATE TYPE constraint_validity AS (name text, validated bool);
SELECT run_command_on_workers(
$$CREATE TYPE constraint_validity AS (name text, validated bool)$$);
CREATE VIEW constraint_validations_in_workers AS
SELECT (json_populate_record(NULL :: constraint_validity,
json_array_elements_text((run_command_on_workers($$
SELECT
COALESCE(json_agg(row_to_json(d)), '[]'::json)
FROM
(
SELECT conname as name,
convalidated as validated
FROM pg_catalog.pg_constraint AS con
JOIN pg_catalog.pg_namespace AS ns
ON ns.oid = con.connamespace
WHERE nspname = 'validate_constraint'
AND contype = 'c'
ORDER BY 1,2
)
d $$)).RESULT :: json) :: json)).*
ORDER BY 1,2;
CREATE VIEW constraint_validations AS
SELECT conname as "Constraint",
convalidated as "Validated?"
FROM pg_catalog.pg_constraint AS con
JOIN pg_catalog.pg_namespace AS ns ON ns.oid = con.connamespace
WHERE nspname = 'validate_constraint'
AND contype = 'c';
CREATE TABLE referenced_table (id int UNIQUE, test_column int);
SELECT create_reference_table('referenced_table');
CREATE TABLE referencing_table (id int, ref_id int);
SELECT create_distributed_table('referencing_table', 'ref_id');
CREATE TABLE constrained_table (id int, constrained_column int);
SELECT create_distributed_table('constrained_table', 'constrained_column');
-- The two constraint types that are allowed to be NOT VALID
BEGIN;
ALTER TABLE constrained_table
ADD CONSTRAINT check_constraint CHECK (constrained_column > 100) NOT VALID;
ALTER TABLE constrained_table
VALIDATE CONSTRAINT check_constraint;
ROLLBACK;
BEGIN;
ALTER TABLE referencing_table
ADD CONSTRAINT fk_constraint FOREIGN KEY (ref_id) REFERENCES referenced_table (id) NOT VALID;
ALTER TABLE referencing_table
VALIDATE CONSTRAINT fk_constraint;
ROLLBACK;
-- It is possible that some other table_constraint commands will support NOT VALID option in the future
-- These should fail as Postgres does not yet allow these constraints to be NOT VALID
-- If one of these queries are not failing on a future Postgres version, we will need to test corresponding VALIDATE CONSTRAINT queries
ALTER TABLE constrained_table
ADD CONSTRAINT unique_constraint UNIQUE (constrained_column) NOT VALID;
ALTER TABLE constrained_table
ADD CONSTRAINT pk_constraint PRIMARY KEY (id) NOT VALID;
ALTER TABLE constrained_table
ADD CONSTRAINT exclude_constraint EXCLUDE USING gist (id WITH =, constrained_column WITH <>) NOT VALID;
INSERT INTO constrained_table
SELECT x, x
from generate_series(1, 1000) as f (x);
-- a constraint that can be validated
ALTER TABLE constrained_table
ADD CONSTRAINT validatable_constraint CHECK (constrained_column < 10000) NOT VALID;
ALTER TABLE constrained_table
VALIDATE CONSTRAINT validatable_constraint;
-- Check which constraints are validated
SELECT *
FROM constraint_validations
ORDER BY 1, 2;
SELECT *
FROM constraint_validations_in_workers
ORDER BY 1, 2;
DROP TABLE constrained_table;
DROP TABLE referenced_table CASCADE;
DROP TABLE referencing_table;
DROP SCHEMA validate_constraint CASCADE;
SET search_path TO DEFAULT;