mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-09-13 17:39:36 +02:00
981a7d32d1
I believe this should fix the issue that Philip Warner noticed about the check for unique constraints meeting the referenced keys of a foreign key constraint allowing the specification of a subset of a foreign key instead of rejecting it. I also added tests for a base case of this to the foreign key and alter table tests and patches for expected output.
316 lines
8.1 KiB
Plaintext
316 lines
8.1 KiB
Plaintext
--
|
|
-- ALTER_TABLE
|
|
-- add attribute
|
|
--
|
|
CREATE TABLE tmp (initial int4);
|
|
ALTER TABLE tmp ADD COLUMN a int4;
|
|
ALTER TABLE tmp ADD COLUMN b name;
|
|
ALTER TABLE tmp ADD COLUMN c text;
|
|
ALTER TABLE tmp ADD COLUMN d float8;
|
|
ALTER TABLE tmp ADD COLUMN e float4;
|
|
ALTER TABLE tmp ADD COLUMN f int2;
|
|
ALTER TABLE tmp ADD COLUMN g polygon;
|
|
ALTER TABLE tmp ADD COLUMN h abstime;
|
|
ALTER TABLE tmp ADD COLUMN i char;
|
|
ALTER TABLE tmp ADD COLUMN j abstime[];
|
|
ALTER TABLE tmp ADD COLUMN k dt;
|
|
ERROR: Unable to locate type name 'dt' in catalog
|
|
ALTER TABLE tmp ADD COLUMN l tid;
|
|
ALTER TABLE tmp ADD COLUMN m xid;
|
|
ALTER TABLE tmp ADD COLUMN n oidvector;
|
|
--ALTER TABLE tmp ADD COLUMN o lock;
|
|
ALTER TABLE tmp ADD COLUMN p smgr;
|
|
ALTER TABLE tmp ADD COLUMN q point;
|
|
ALTER TABLE tmp ADD COLUMN r lseg;
|
|
ALTER TABLE tmp ADD COLUMN s path;
|
|
ALTER TABLE tmp ADD COLUMN t box;
|
|
ALTER TABLE tmp ADD COLUMN u tinterval;
|
|
ALTER TABLE tmp ADD COLUMN v datetime;
|
|
ALTER TABLE tmp ADD COLUMN w timespan;
|
|
ALTER TABLE tmp ADD COLUMN x float8[];
|
|
ALTER TABLE tmp ADD COLUMN y float4[];
|
|
ALTER TABLE tmp ADD COLUMN z int2[];
|
|
INSERT INTO tmp (a, b, c, d, e, f, g, h, i, j, k, l, m, n, p, q, r, s, t, u,
|
|
v, w, x, y, z)
|
|
VALUES (4, 'name', 'text', 4.1, 4.1, 2, '(4.1,4.1,3.1,3.1)',
|
|
'Mon May 1 00:30:30 1995', 'c', '{Mon May 1 00:30:30 1995, Monday Aug 24 14:43:07 1992, epoch}',
|
|
314159, '(1,1)', 512,
|
|
'1 2 3 4 5 6 7 8', 'magnetic disk', '(1.1,1.1)', '(4.1,4.1,3.1,3.1)',
|
|
'(0,2,4.1,4.1,3.1,3.1)', '(4.1,4.1,3.1,3.1)', '["current" "infinity"]',
|
|
'1/3', '1,name', '{1.0,2.0,3.0,4.0}', '{1.0,2.0,3.0,4.0}', '{1,2,3,4}');
|
|
ERROR: Relation 'tmp' does not have attribute 'k'
|
|
SELECT * FROM tmp;
|
|
initial | a | b | c | d | e | f | g | h | i | j | l | m | n | p | q | r | s | t | u | v | w | x | y | z
|
|
---------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---
|
|
(0 rows)
|
|
|
|
DROP TABLE tmp;
|
|
-- the wolf bug - schema mods caused inconsistent row descriptors
|
|
CREATE TABLE tmp (
|
|
initial int4
|
|
);
|
|
ALTER TABLE tmp ADD COLUMN a int4;
|
|
ALTER TABLE tmp ADD COLUMN b name;
|
|
ALTER TABLE tmp ADD COLUMN c text;
|
|
ALTER TABLE tmp ADD COLUMN d float8;
|
|
ALTER TABLE tmp ADD COLUMN e float4;
|
|
ALTER TABLE tmp ADD COLUMN f int2;
|
|
ALTER TABLE tmp ADD COLUMN g polygon;
|
|
ALTER TABLE tmp ADD COLUMN h abstime;
|
|
ALTER TABLE tmp ADD COLUMN i char;
|
|
ALTER TABLE tmp ADD COLUMN j abstime[];
|
|
ALTER TABLE tmp ADD COLUMN k dt;
|
|
ERROR: Unable to locate type name 'dt' in catalog
|
|
ALTER TABLE tmp ADD COLUMN l tid;
|
|
ALTER TABLE tmp ADD COLUMN m xid;
|
|
ALTER TABLE tmp ADD COLUMN n oidvector;
|
|
--ALTER TABLE tmp ADD COLUMN o lock;
|
|
ALTER TABLE tmp ADD COLUMN p smgr;
|
|
ALTER TABLE tmp ADD COLUMN q point;
|
|
ALTER TABLE tmp ADD COLUMN r lseg;
|
|
ALTER TABLE tmp ADD COLUMN s path;
|
|
ALTER TABLE tmp ADD COLUMN t box;
|
|
ALTER TABLE tmp ADD COLUMN u tinterval;
|
|
ALTER TABLE tmp ADD COLUMN v datetime;
|
|
ALTER TABLE tmp ADD COLUMN w timespan;
|
|
ALTER TABLE tmp ADD COLUMN x float8[];
|
|
ALTER TABLE tmp ADD COLUMN y float4[];
|
|
ALTER TABLE tmp ADD COLUMN z int2[];
|
|
INSERT INTO tmp (a, b, c, d, e, f, g, h, i, j, k, l, m, n, p, q, r, s, t, u,
|
|
v, w, x, y, z)
|
|
VALUES (4, 'name', 'text', 4.1, 4.1, 2, '(4.1,4.1,3.1,3.1)',
|
|
'Mon May 1 00:30:30 1995', 'c', '{Mon May 1 00:30:30 1995, Monday Aug 24 14:43:07 1992, epoch}',
|
|
314159, '(1,1)', 512,
|
|
'1 2 3 4 5 6 7 8', 'magnetic disk', '(1.1,1.1)', '(4.1,4.1,3.1,3.1)',
|
|
'(0,2,4.1,4.1,3.1,3.1)', '(4.1,4.1,3.1,3.1)', '["current" "infinity"]',
|
|
'1/3', '1,name', '{1.0,2.0,3.0,4.0}', '{1.0,2.0,3.0,4.0}', '{1,2,3,4}');
|
|
ERROR: Relation 'tmp' does not have attribute 'k'
|
|
SELECT * FROM tmp;
|
|
initial | a | b | c | d | e | f | g | h | i | j | l | m | n | p | q | r | s | t | u | v | w | x | y | z
|
|
---------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---
|
|
(0 rows)
|
|
|
|
DROP TABLE tmp;
|
|
--
|
|
-- rename -
|
|
-- should preserve indices, which we can check by seeing if a SELECT
|
|
-- chooses an indexscan; however, in the absence of vacuum statistics
|
|
-- it might not. Therefore, vacuum first.
|
|
--
|
|
VACUUM ANALYZE tenk1;
|
|
ALTER TABLE tenk1 RENAME TO ten_k;
|
|
-- 20 values, sorted
|
|
SELECT unique1 FROM ten_k WHERE unique1 < 20;
|
|
unique1
|
|
---------
|
|
0
|
|
1
|
|
2
|
|
3
|
|
4
|
|
5
|
|
6
|
|
7
|
|
8
|
|
9
|
|
10
|
|
11
|
|
12
|
|
13
|
|
14
|
|
15
|
|
16
|
|
17
|
|
18
|
|
19
|
|
(20 rows)
|
|
|
|
-- 20 values, sorted
|
|
SELECT unique2 FROM ten_k WHERE unique2 < 20;
|
|
unique2
|
|
---------
|
|
0
|
|
1
|
|
2
|
|
3
|
|
4
|
|
5
|
|
6
|
|
7
|
|
8
|
|
9
|
|
10
|
|
11
|
|
12
|
|
13
|
|
14
|
|
15
|
|
16
|
|
17
|
|
18
|
|
19
|
|
(20 rows)
|
|
|
|
-- 100 values, sorted
|
|
SELECT hundred FROM ten_k WHERE hundred = 50;
|
|
hundred
|
|
---------
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
50
|
|
(100 rows)
|
|
|
|
ALTER TABLE ten_k RENAME TO tenk1;
|
|
-- 5 values, sorted
|
|
SELECT unique1 FROM tenk1 WHERE unique1 < 5;
|
|
unique1
|
|
---------
|
|
0
|
|
1
|
|
2
|
|
3
|
|
4
|
|
(5 rows)
|
|
|
|
-- FOREIGN KEY CONSTRAINT adding TEST
|
|
CREATE TABLE tmp2 (a int primary key);
|
|
NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'tmp2_pkey' for table 'tmp2'
|
|
CREATE TABLE tmp3 (a int, b int);
|
|
CREATE TABLE tmp4 (a int, b int, unique(a,b));
|
|
NOTICE: CREATE TABLE/UNIQUE will create implicit index 'tmp4_a_key' for table 'tmp4'
|
|
CREATE TABLE tmp5 (a int, b int);
|
|
-- Insert rows into tmp2 (pktable)
|
|
INSERT INTO tmp2 values (1);
|
|
INSERT INTO tmp2 values (2);
|
|
INSERT INTO tmp2 values (3);
|
|
INSERT INTO tmp2 values (4);
|
|
-- Insert rows into tmp3
|
|
INSERT INTO tmp3 values (1,10);
|
|
INSERT INTO tmp3 values (1,20);
|
|
INSERT INTO tmp3 values (5,50);
|
|
-- Try (and fail) to add constraint due to invalid source columns
|
|
ALTER TABLE tmp3 add constraint tmpconstr foreign key(c) references tmp2 match full;
|
|
NOTICE: ALTER TABLE ... ADD CONSTRAINT will create implicit trigger(s) for FOREIGN KEY check(s)
|
|
ERROR: columns referenced in foreign key constraint not found.
|
|
-- Try (and fail) to add constraint due to invalide destination columns explicitly given
|
|
ALTER TABLE tmp3 add constraint tmpconstr foreign key(a) references tmp2(b) match full;
|
|
NOTICE: ALTER TABLE ... ADD CONSTRAINT will create implicit trigger(s) for FOREIGN KEY check(s)
|
|
ERROR: UNIQUE constraint matching given keys for referenced table "tmp2" not found
|
|
-- Try (and fail) to add constraint due to invalid data
|
|
ALTER TABLE tmp3 add constraint tmpconstr foreign key (a) references tmp2 match full;
|
|
NOTICE: ALTER TABLE ... ADD CONSTRAINT will create implicit trigger(s) for FOREIGN KEY check(s)
|
|
ERROR: tmpconstr referential integrity violation - key referenced from tmp3 not found in tmp2
|
|
-- Delete failing row
|
|
DELETE FROM tmp3 where a=5;
|
|
-- Try (and succeed)
|
|
ALTER TABLE tmp3 add constraint tmpconstr foreign key (a) references tmp2 match full;
|
|
NOTICE: ALTER TABLE ... ADD CONSTRAINT will create implicit trigger(s) for FOREIGN KEY check(s)
|
|
-- Try (and fail) to create constraint from tmp5(a) to tmp4(a) - unique constraint on
|
|
-- tmp4 is a,b
|
|
ALTER TABLE tmp5 add constraint tmpconstr foreign key(a) references tmp4(a) match full;
|
|
NOTICE: ALTER TABLE ... ADD CONSTRAINT will create implicit trigger(s) for FOREIGN KEY check(s)
|
|
ERROR: UNIQUE constraint matching given keys for referenced table "tmp4" not found
|
|
DROP TABLE tmp5;
|
|
DROP TABLE tmp4;
|
|
DROP TABLE tmp3;
|
|
NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "tmp2"
|
|
NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "tmp2"
|
|
DROP TABLE tmp2;
|