From 4911c85e86a8491e97032515dee59a9612ba7e3a Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Wed, 31 Oct 2001 04:49:44 +0000 Subject: [PATCH] Add ALTER TABLE ADD UNIQUE regression tests from Christopher Kings-Lynne. Add space between slash for ALTER TABLE / ADD .... Regression and *.po updates to follow. --- doc/src/sgml/ref/cluster.sgml | 4 +- src/backend/commands/command.c | 6 +- src/backend/parser/analyze.c | 8 +-- src/backend/parser/gram.y | 18 +++--- src/interfaces/ecpg/lib/connect.c | 4 +- src/interfaces/ecpg/preproc/preproc.y | 12 ++-- src/test/regress/expected/alter_table.out | 67 ++++++++++++++++++++-- src/test/regress/expected/create_misc.out | 2 +- src/test/regress/expected/foreign_key.out | 50 ++++++++-------- src/test/regress/output/constraints.source | 8 +-- src/test/regress/sql/alter_table.sql | 53 +++++++++++++++++ 11 files changed, 172 insertions(+), 60 deletions(-) diff --git a/doc/src/sgml/ref/cluster.sgml b/doc/src/sgml/ref/cluster.sgml index de6dfa3af6..72dc803367 100644 --- a/doc/src/sgml/ref/cluster.sgml +++ b/doc/src/sgml/ref/cluster.sgml @@ -1,5 +1,5 @@ @@ -189,7 +189,7 @@ SELECT columnlist INTO TABLE Postgres sorting code in the ORDER BY clause to match the index, and which is much faster for unordered data. You then drop the old table, use - ALTER TABLE/RENAME + ALTER TABLE...RENAME to rename temp to the old name, and recreate any indexes. The only problem is that OIDs will not be preserved. From then on, CLUSTER should be diff --git a/src/backend/commands/command.c b/src/backend/commands/command.c index 4100e77557..b9cfee96e4 100644 --- a/src/backend/commands/command.c +++ b/src/backend/commands/command.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.147 2001/10/28 06:25:42 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.148 2001/10/31 04:49:43 momjian Exp $ * * NOTES * The PerformAddAttribute() code, like most of the relation @@ -1432,7 +1432,7 @@ AlterTableAddConstraint(char *relationName, 0, 0, 0); if (!HeapTupleIsValid(indexTuple)) - elog(ERROR, "ALTER TABLE/ADD CONSTRAINT: Index \"%u\" not found", + elog(ERROR, "ALTER TABLE / ADD CONSTRAINT: Index \"%u\" not found", indexoid); indexStruct = (Form_pg_index) GETSTRUCT(indexTuple); @@ -1510,7 +1510,7 @@ AlterTableAddConstraint(char *relationName, NIL); /* Issue notice */ - elog(NOTICE, "ALTER TABLE/ADD UNIQUE will create implicit index '%s' for table '%s'", + elog(NOTICE, "ALTER TABLE / ADD UNIQUE will create implicit index '%s' for table '%s'", iname, relationName); if (index_found) elog(NOTICE, "Unique constraint supercedes existing index on relation \"%s\". Drop the existing index to remove redundancy.", relationName); diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 5a4534644c..5b2f4362fb 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.205 2001/10/28 06:25:46 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.206 2001/10/31 04:49:43 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -1062,7 +1062,7 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt) if (cxt->pkey != NULL || (OidIsValid(cxt->relOid) && relationHasPrimaryKey(cxt->relname))) - elog(ERROR, "%s/PRIMARY KEY multiple primary keys" + elog(ERROR, "%s / PRIMARY KEY multiple primary keys" " for table '%s' are not allowed", cxt->stmtType, cxt->relname); cxt->pkey = index; @@ -1291,8 +1291,8 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt) elog(ERROR, "%s: failed to make implicit index name", cxt->stmtType); - elog(NOTICE, "%s/%s will create implicit index '%s' for table '%s'", - cxt->stmtType, (index->primary ? "PRIMARY KEY" : "UNIQUE"), + elog(NOTICE, "%s / %s will create implicit index '%s' for table '%s'", + cxt->stmtType, (index->primary ? "ADD PRIMARY KEY" : "ADD UNIQUE"), index->idxname, cxt->relname); } } diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index fafe11b127..c97c9da509 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.270 2001/10/23 02:50:41 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.271 2001/10/31 04:49:43 momjian Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -1300,7 +1300,7 @@ columnDef: ColId Typename ColQualList opt_collate n->constraints = $3; if ($4 != NULL) - elog(NOTICE,"CREATE TABLE/COLLATE %s not yet implemented" + elog(NOTICE,"CREATE TABLE / COLLATE %s not yet implemented" "; clause ignored", $4); $$ = (Node *)n; @@ -1611,7 +1611,7 @@ CreateAsStmt: CREATE OptTemp TABLE relation_name OptCreateAs AS SelectStmt */ SelectStmt *n = findLeftmostSelect((SelectStmt *) $7); if (n->into != NULL) - elog(ERROR,"CREATE TABLE/AS SELECT may not specify INTO"); + elog(ERROR,"CREATE TABLE / AS SELECT may not specify INTO"); n->istemp = $2; n->into = $4; if ($5 != NIL) @@ -2171,7 +2171,7 @@ FetchStmt: FETCH direction fetch_how_many from_in name if ($2 == RELATIVE) { if ($3 == 0) - elog(ERROR,"FETCH/RELATIVE at current position is not supported"); + elog(ERROR,"FETCH / RELATIVE at current position is not supported"); $2 = FORWARD; } if ($3 < 0) @@ -2299,7 +2299,7 @@ direction: FORWARD { $$ = FORWARD; } | RELATIVE { $$ = RELATIVE; } | ABSOLUTE { - elog(NOTICE,"FETCH/ABSOLUTE not supported, using RELATIVE"); + elog(NOTICE,"FETCH / ABSOLUTE not supported, using RELATIVE"); $$ = RELATIVE; } ; @@ -2605,12 +2605,12 @@ opt_arg: IN } | OUT { - elog(ERROR, "CREATE FUNCTION/OUT parameters are not supported"); + elog(ERROR, "CREATE FUNCTION / OUT parameters are not supported"); $$ = TRUE; } | INOUT { - elog(ERROR, "CREATE FUNCTION/INOUT parameters are not supported"); + elog(ERROR, "CREATE FUNCTION / INOUT parameters are not supported"); $$ = FALSE; } ; @@ -2955,7 +2955,7 @@ opt_chain: AND NO CHAIN * if they don't support it. So we can't just ignore it. * - thomas 2000-08-06 */ - elog(ERROR, "COMMIT/CHAIN not yet supported"); + elog(ERROR, "COMMIT / CHAIN not yet supported"); $$ = TRUE; } ; @@ -6113,7 +6113,7 @@ mapTargetColumns(List *src, List *dst) ResTarget *d; if (length(src) != length(dst)) - elog(ERROR,"CREATE TABLE/AS SELECT has mismatched column count"); + elog(ERROR,"CREATE TABLE / AS SELECT has mismatched column count"); while ((src != NIL) && (dst != NIL)) { diff --git a/src/interfaces/ecpg/lib/connect.c b/src/interfaces/ecpg/lib/connect.c index 239c766d7c..da4b8a3d7e 100644 --- a/src/interfaces/ecpg/lib/connect.c +++ b/src/interfaces/ecpg/lib/connect.c @@ -1,4 +1,4 @@ -/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/connect.c,v 1.13 2001/10/25 05:50:11 momjian Exp $ */ +/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/connect.c,v 1.14 2001/10/31 04:49:44 momjian Exp $ */ #include "postgres_fe.h" @@ -205,7 +205,7 @@ ECPGnoticeProcessor(void *arg, const char *message) /* these are harmless - do nothing */ /* - * NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index '*' + * NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index '*' * for table '*' */ diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y index c5cf4d1921..1d2982ad5f 100644 --- a/src/interfaces/ecpg/preproc/preproc.y +++ b/src/interfaces/ecpg/preproc/preproc.y @@ -1087,11 +1087,11 @@ OptTemp: TEMPORARY { $$ = make_str("temporary"); } | LOCAL TEMPORARY { $$ = make_str("local temporary"); } | LOCAL TEMP { $$ = make_str("local temp"); } | GLOBAL TEMPORARY { - mmerror(ET_NOTICE, "Currently unsupported CREATE TABLE/GLOBAL TEMPORARY will be passed to backend"); + mmerror(ET_NOTICE, "Currently unsupported CREATE TABLE / GLOBAL TEMPORARY will be passed to backend"); $$ = make_str("global temporary"); } | GLOBAL TEMP { - mmerror(ET_NOTICE, "Currently unsupported CREATE TABLE/GLOBAL TEMP will be passed to backend"); + mmerror(ET_NOTICE, "Currently unsupported CREATE TABLE / GLOBAL TEMP will be passed to backend"); $$ = make_str("global temp"); } | /*EMPTY*/ { $$ = EMPTY; } @@ -1116,7 +1116,7 @@ columnDef: ColId Typename ColQualList opt_collate { if (strlen($4) > 0) { - sprintf(errortext, "Currently unsupported CREATE TABLE/COLLATE %s will be passed to backend", $4); + sprintf(errortext, "Currently unsupported CREATE TABLE / COLLATE %s will be passed to backend", $4); mmerror(ET_NOTICE, errortext); } $$ = cat_str(4, $1, $2, $3, $4); @@ -1278,7 +1278,7 @@ CreateAsStmt: CREATE OptTemp TABLE relation_name OptCreateAs AS { FoundInto = 0; } SelectStmt { if (FoundInto == 1) - mmerror(ET_ERROR, "CREATE TABLE/AS SELECT may not specify INTO"); + mmerror(ET_ERROR, "CREATE TABLE / AS SELECT may not specify INTO"); $$ = cat_str(7, make_str("create"), $2, make_str("table"), $4, $5, make_str("as"), $8); } @@ -2626,12 +2626,12 @@ OptTempTableName: TEMPORARY opt_table relation_name } | GLOBAL TEMPORARY opt_table relation_name { - mmerror(ET_NOTICE, "Currently unsupported CREATE TABLE/GLOBAL TEMPORARY will be passed to backend"); + mmerror(ET_NOTICE, "Currently unsupported CREATE TABLE / GLOBAL TEMPORARY will be passed to backend"); $$ = cat_str(3, make_str("global temporary"), $3, $4); } | GLOBAL TEMP opt_table relation_name { - mmerror(ET_NOTICE, "Currently unsupported CREATE TABLE/GLOBAL TEMP will be passed to backend"); + mmerror(ET_NOTICE, "Currently unsupported CREATE TABLE / GLOBAL TEMP will be passed to backend"); $$ = cat_str(3, make_str("global temp"), $3, $4); } | TABLE relation_name diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index eb9d17ae0d..d5b5df2c18 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -271,10 +271,10 @@ SELECT unique1 FROM tenk1 WHERE unique1 < 5; -- 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' +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' +NOTICE: CREATE TABLE / ADD 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); @@ -317,7 +317,7 @@ DROP TABLE tmp2; -- Note: these tables are TEMP to avoid name conflicts when this test -- is run in parallel with foreign_key.sql. CREATE TEMP TABLE PKTABLE (ptest1 int PRIMARY KEY); -NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' CREATE TEMP TABLE FKTABLE (ftest1 text); -- This next should fail, because text=int does not exist ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable; @@ -345,7 +345,7 @@ NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "f DROP TABLE fktable; CREATE TEMP TABLE PKTABLE (ptest1 int, ptest2 text, PRIMARY KEY(ptest1, ptest2)); -NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' -- This should fail, because we just chose really odd types CREATE TEMP TABLE FKTABLE (ftest1 cidr, ftest2 datetime); ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2) references pktable; @@ -448,3 +448,62 @@ insert into atacc3 (test2) values (3); drop table atacc3; drop table atacc2; drop table atacc1; +-- test unique constraint adding +create table atacc1 ( test int ); +-- add a unique constraint +alter table atacc1 add constraint atacc_test1 unique (test); +NOTICE: ALTER TABLE/UNIQUE will create implicit index 'atacc_test1' for table 'atacc1' +-- insert first value +insert into atacc1 (test) values (2); +-- should fail +insert into atacc1 (test) values (2); +ERROR: Cannot insert a duplicate key into unique index atacc_test1 +-- should succeed +insert into atacc1 (test) values (4); +-- try adding a unique oid constraint +alter table atacc1 add constraint atacc_oid1 unique(oid); +NOTICE: ALTER TABLE/UNIQUE will create implicit index 'atacc_oid1' for table 'atacc1' +drop table atacc1; +-- let's do one where the unique constraint fails when added +create table atacc1 ( test int ); +-- insert soon to be failing rows +insert into atacc1 (test) values (2); +insert into atacc1 (test) values (2); +-- add a unique constraint (fails) +alter table atacc1 add constraint atacc_test1 unique (test); + NOTICE: ALTER TABLE/UNIQUE will create implicit index 'atacc_test1' for table 'atacc1' +ERROR: Cannot create unique index. Table contains non-unique values +insert into atacc1 (test) values (3); +drop table atacc1; +-- let's do one where the unique contsraint fails +-- because the column doesn't exist +create table atacc1 ( test int ); +-- add a unique constraint (fails) +alter table atacc1 add constraint atacc_test1 unique (test1); +ERROR: ALTER TABLE: column "test1" named in key does not exist +drop table atacc1; +-- something a little more complicated +create table atacc1 ( test int, test2 int); +-- add a unique constraint +alter table atacc1 add constraint atacc_test1 unique (test, test2); +NOTICE: ALTER TABLE/UNIQUE will create implicit index 'atacc_test1' for table 'atacc1' +-- insert initial value +insert into atacc1 (test,test2) values (4,4); +-- should fail +insert into atacc1 (test,test2) values (4,4); +ERROR: Cannot insert a duplicate key into unique index atacc_test1 +-- should all succeed +insert into atacc1 (test,test2) values (4,5); +insert into atacc1 (test,test2) values (5,4); +insert into atacc1 (test,test2) values (5,5); +drop table atacc1; +-- lets do some naming tests +create table atacc1 (test int, test2 int, unique(test)); +NOTICE: CREATE TABLE/UNIQUE will create implicit index 'atacc1_test_key' for table 'atacc1' +alter table atacc1 add unique (test2); +NOTICE: ALTER TABLE/UNIQUE will create implicit index 'atacc1_test2_key' for table 'atacc1' +-- should fail for @@ second one @@ +insert into atacc1 (test2, test) values (3, 3); +insert into atacc1 (test2, test) values (2, 3); +ERROR: Cannot insert a duplicate key into unique index atacc1_test_key +drop table atacc1; diff --git a/src/test/regress/expected/create_misc.out b/src/test/regress/expected/create_misc.out index c7600fd13f..dcfc9abdbc 100644 --- a/src/test/regress/expected/create_misc.out +++ b/src/test/regress/expected/create_misc.out @@ -137,7 +137,7 @@ INSERT INTO iportaltest (i, d, p) --- CREATE TABLE serialTest (f1 text, f2 serial); NOTICE: CREATE TABLE will create implicit sequence 'serialtest_f2_seq' for SERIAL column 'serialtest.f2' -NOTICE: CREATE TABLE/UNIQUE will create implicit index 'serialtest_f2_key' for table 'serialtest' +NOTICE: CREATE TABLE / ADD UNIQUE will create implicit index 'serialtest_f2_key' for table 'serialtest' INSERT INTO serialTest VALUES ('foo'); INSERT INTO serialTest VALUES ('bar'); INSERT INTO serialTest VALUES ('force', 100); diff --git a/src/test/regress/expected/foreign_key.out b/src/test/regress/expected/foreign_key.out index 95e6684156..c2bf5f8063 100644 --- a/src/test/regress/expected/foreign_key.out +++ b/src/test/regress/expected/foreign_key.out @@ -6,7 +6,7 @@ -- First test, check and cascade -- CREATE TABLE PKTABLE ( ptest1 int PRIMARY KEY, ptest2 text ); -NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' CREATE TABLE FKTABLE ( ftest1 int REFERENCES PKTABLE MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE, ftest2 int ); NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s) -- Insert test data into PKTABLE @@ -62,7 +62,7 @@ DROP TABLE FKTABLE; -- check set NULL and table constraint on multiple columns -- CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 text, PRIMARY KEY(ptest1, ptest2) ); -NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' CREATE TABLE FKTABLE ( ftest1 int, ftest2 int, ftest3 int, CONSTRAINT constrname FOREIGN KEY(ftest1, ftest2) REFERENCES PKTABLE MATCH FULL ON DELETE SET NULL ON UPDATE SET NULL); NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s) @@ -145,7 +145,7 @@ DROP TABLE FKTABLE; -- check set default and table constraint on multiple columns -- CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 text, PRIMARY KEY(ptest1, ptest2) ); -NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' CREATE TABLE FKTABLE ( ftest1 int DEFAULT -1, ftest2 int DEFAULT -2, ftest3 int, CONSTRAINT constrname2 FOREIGN KEY(ftest1, ftest2) REFERENCES PKTABLE MATCH FULL ON DELETE SET DEFAULT ON UPDATE SET DEFAULT); NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s) @@ -230,7 +230,7 @@ DROP TABLE FKTABLE; -- First test, check with no on delete or on update -- CREATE TABLE PKTABLE ( ptest1 int PRIMARY KEY, ptest2 text ); -NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' CREATE TABLE FKTABLE ( ftest1 int REFERENCES PKTABLE MATCH FULL, ftest2 int ); NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s) -- Insert test data into PKTABLE @@ -304,7 +304,7 @@ DROP TABLE FKTABLE; -- MATCH unspecified -- Base test restricting update/delete CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2, ptest3) ); -NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' CREATE TABLE FKTABLE ( ftest1 int, ftest2 int, ftest3 int, ftest4 int, CONSTRAINT constrname3 FOREIGN KEY(ftest1, ftest2, ftest3) REFERENCES PKTABLE); NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s) @@ -368,7 +368,7 @@ NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "p DROP TABLE PKTABLE; -- cascade update/delete CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2, ptest3) ); -NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' CREATE TABLE FKTABLE ( ftest1 int, ftest2 int, ftest3 int, ftest4 int, CONSTRAINT constrname3 FOREIGN KEY(ftest1, ftest2, ftest3) REFERENCES PKTABLE ON DELETE CASCADE ON UPDATE CASCADE); @@ -467,7 +467,7 @@ NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "p DROP TABLE PKTABLE; -- set null update / set default delete CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2, ptest3) ); -NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' CREATE TABLE FKTABLE ( ftest1 int DEFAULT 0, ftest2 int, ftest3 int, ftest4 int, CONSTRAINT constrname3 FOREIGN KEY(ftest1, ftest2, ftest3) REFERENCES PKTABLE ON DELETE SET DEFAULT ON UPDATE SET NULL); @@ -573,7 +573,7 @@ NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "p DROP TABLE PKTABLE; -- set default update / set null delete CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2, ptest3) ); -NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' CREATE TABLE FKTABLE ( ftest1 int DEFAULT 0, ftest2 int DEFAULT -1, ftest3 int, ftest4 int, CONSTRAINT constrname3 FOREIGN KEY(ftest1, ftest2, ftest3) REFERENCES PKTABLE ON DELETE SET NULL ON UPDATE SET DEFAULT); @@ -691,7 +691,7 @@ NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "p NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "pktable" DROP TABLE PKTABLE; CREATE TABLE PKTABLE (ptest1 int PRIMARY KEY); -NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' CREATE TABLE FKTABLE_FAIL1 ( ftest1 int, CONSTRAINT fkfail1 FOREIGN KEY (ftest2) REFERENCES PKTABLE); NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s) ERROR: CREATE TABLE: column "ftest2" referenced in foreign key constraint does not exist @@ -705,7 +705,7 @@ ERROR: table "fktable_fail2" does not exist DROP TABLE PKTABLE; -- Test for referencing column number smaller than referenced constraint CREATE TABLE PKTABLE (ptest1 int, ptest2 int, UNIQUE(ptest1, ptest2)); -NOTICE: CREATE TABLE/UNIQUE will create implicit index 'pktable_ptest1_key' for table 'pktable' +NOTICE: CREATE TABLE / ADD UNIQUE will create implicit index 'pktable_ptest1_key' for table 'pktable' CREATE TABLE FKTABLE_FAIL1 (ftest1 int REFERENCES pktable(ptest1)); NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s) ERROR: UNIQUE constraint matching given keys for referenced table "pktable" not found @@ -717,7 +717,7 @@ DROP TABLE PKTABLE; -- -- Basic one column, two table setup CREATE TABLE PKTABLE (ptest1 int PRIMARY KEY); -NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' -- This next should fail, because text=int does not exist CREATE TABLE FKTABLE (ftest1 text REFERENCES pktable); NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s) @@ -745,7 +745,7 @@ NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "p DROP TABLE PKTABLE; -- Two columns, two tables CREATE TABLE PKTABLE (ptest1 int, ptest2 text, PRIMARY KEY(ptest1, ptest2)); -NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' -- This should fail, because we just chose really odd types CREATE TABLE FKTABLE (ftest1 cidr, ftest2 datetime, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable); NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s) @@ -788,33 +788,33 @@ DROP TABLE PKTABLE; -- Make sure this still works... CREATE TABLE PKTABLE (ptest1 int, ptest2 text, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest3, ptest4) REFERENCES pktable(ptest1, ptest2)); -NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s) DROP TABLE PKTABLE; -- And this, CREATE TABLE PKTABLE (ptest1 int, ptest2 text, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest3, ptest4) REFERENCES pktable); -NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s) DROP TABLE PKTABLE; -- This shouldn't (mixed up columns) CREATE TABLE PKTABLE (ptest1 int, ptest2 text, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest3, ptest4) REFERENCES pktable(ptest2, ptest1)); -NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s) ERROR: Unable to identify an operator '=' for types 'integer' and 'text' You will have to retype this query using an explicit cast -- Nor should this... (same reason, we have 4,3 referencing 1,2 which mismatches types CREATE TABLE PKTABLE (ptest1 int, ptest2 text, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest4, ptest3) REFERENCES pktable(ptest1, ptest2)); -NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s) ERROR: Unable to identify an operator '=' for types 'text' and 'integer' You will have to retype this query using an explicit cast -- Not this one either... Same as the last one except we didn't defined the columns being referenced. CREATE TABLE PKTABLE (ptest1 int, ptest2 text, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest4, ptest3) REFERENCES pktable); -NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s) ERROR: Unable to identify an operator '=' for types 'text' and 'integer' You will have to retype this query using an explicit cast @@ -823,8 +823,8 @@ ERROR: Unable to identify an operator '=' for types 'text' and 'integer' -- Basic 2 table case: 1 column of matching types. create table pktable_base (base1 int not null); create table pktable (ptest1 int, primary key(base1), unique(base1, ptest1)) inherits (pktable_base); -NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' -NOTICE: CREATE TABLE/UNIQUE will create implicit index 'pktable_base1_key' for table 'pktable' +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' +NOTICE: CREATE TABLE / ADD UNIQUE will create implicit index 'pktable_base1_key' for table 'pktable' create table fktable (ftest1 int references pktable(base1)); NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s) -- now some ins, upd, del @@ -885,7 +885,7 @@ drop table pktable_base; create table pktable_base(base1 int not null, base2 int); create table pktable(ptest1 int, ptest2 int, primary key(base1, ptest1), foreign key(base2, ptest2) references pktable(base1, ptest1)) inherits (pktable_base); -NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s) insert into pktable (base1, ptest1, base2, ptest2) values (1, 1, 1, 1); insert into pktable (base1, ptest1, base2, ptest2) values (2, 1, 1, 1); @@ -908,7 +908,7 @@ drop table pktable_base; -- 2 columns (2 tables), mismatched types create table pktable_base(base1 int not null); create table pktable(ptest1 text, primary key(base1, ptest1)) inherits (pktable_base); -NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' -- just generally bad types (with and without column references on the referenced table) create table fktable(ftest1 cidr, ftest2 int[], foreign key (ftest1, ftest2) references pktable); NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s) @@ -937,25 +937,25 @@ drop table pktable_base; create table pktable_base(base1 int not null, base2 int); create table pktable(ptest1 text, ptest2 text[], primary key(base1, ptest1), foreign key(base2, ptest2) references pktable(base1, ptest1)) inherits (pktable_base); -NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s) ERROR: Unable to identify an operator '=' for types 'text[]' and 'text' You will have to retype this query using an explicit cast create table pktable(ptest1 text, ptest2 text, primary key(base1, ptest1), foreign key(base2, ptest2) references pktable(ptest1, base1)) inherits (pktable_base); -NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s) ERROR: Unable to identify an operator '=' for types 'integer' and 'text' You will have to retype this query using an explicit cast create table pktable(ptest1 text, ptest2 text, primary key(base1, ptest1), foreign key(ptest2, base2) references pktable(base1, ptest1)) inherits (pktable_base); -NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s) ERROR: Unable to identify an operator '=' for types 'text' and 'integer' You will have to retype this query using an explicit cast create table pktable(ptest1 text, ptest2 text, primary key(base1, ptest1), foreign key(ptest2, base2) references pktable(base1, ptest1)) inherits (pktable_base); -NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable' NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s) ERROR: Unable to identify an operator '=' for types 'text' and 'integer' You will have to retype this query using an explicit cast diff --git a/src/test/regress/output/constraints.source b/src/test/regress/output/constraints.source index 4732a8852b..c5b19b822e 100644 --- a/src/test/regress/output/constraints.source +++ b/src/test/regress/output/constraints.source @@ -286,7 +286,7 @@ SELECT * FROM COPY_TBL; -- Primary keys -- CREATE TABLE PRIMARY_TBL (i int PRIMARY KEY, t text); -NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'primary_tbl_pkey' for table 'primary_tbl' +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'primary_tbl_pkey' for table 'primary_tbl' INSERT INTO PRIMARY_TBL VALUES (1, 'one'); INSERT INTO PRIMARY_TBL VALUES (2, 'two'); INSERT INTO PRIMARY_TBL VALUES (1, 'three'); @@ -307,7 +307,7 @@ SELECT '' AS four, * FROM PRIMARY_TBL; DROP TABLE PRIMARY_TBL; CREATE TABLE PRIMARY_TBL (i int, t text, PRIMARY KEY(i,t)); -NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'primary_tbl_pkey' for table 'primary_tbl' +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'primary_tbl_pkey' for table 'primary_tbl' INSERT INTO PRIMARY_TBL VALUES (1, 'one'); INSERT INTO PRIMARY_TBL VALUES (2, 'two'); INSERT INTO PRIMARY_TBL VALUES (1, 'three'); @@ -330,7 +330,7 @@ DROP TABLE PRIMARY_TBL; -- Unique keys -- CREATE TABLE UNIQUE_TBL (i int UNIQUE, t text); -NOTICE: CREATE TABLE/UNIQUE will create implicit index 'unique_tbl_i_key' for table 'unique_tbl' +NOTICE: CREATE TABLE / ADD UNIQUE will create implicit index 'unique_tbl_i_key' for table 'unique_tbl' INSERT INTO UNIQUE_TBL VALUES (1, 'one'); INSERT INTO UNIQUE_TBL VALUES (2, 'two'); INSERT INTO UNIQUE_TBL VALUES (1, 'three'); @@ -353,7 +353,7 @@ SELECT '' AS five, * FROM UNIQUE_TBL; DROP TABLE UNIQUE_TBL; CREATE TABLE UNIQUE_TBL (i int, t text, UNIQUE(i,t)); -NOTICE: CREATE TABLE/UNIQUE will create implicit index 'unique_tbl_i_key' for table 'unique_tbl' +NOTICE: CREATE TABLE / ADD UNIQUE will create implicit index 'unique_tbl_i_key' for table 'unique_tbl' INSERT INTO UNIQUE_TBL VALUES (1, 'one'); INSERT INTO UNIQUE_TBL VALUES (2, 'two'); INSERT INTO UNIQUE_TBL VALUES (1, 'three'); diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index 50a611f83f..48d0bcc55d 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -329,3 +329,56 @@ drop table atacc3; drop table atacc2; drop table atacc1; +-- test unique constraint adding + +create table atacc1 ( test int ); +-- add a unique constraint +alter table atacc1 add constraint atacc_test1 unique (test); +-- insert first value +insert into atacc1 (test) values (2); +-- should fail +insert into atacc1 (test) values (2); +-- should succeed +insert into atacc1 (test) values (4); +-- try adding a unique oid constraint +alter table atacc1 add constraint atacc_oid1 unique(oid); +drop table atacc1; + +-- let's do one where the unique constraint fails when added +create table atacc1 ( test int ); +-- insert soon to be failing rows +insert into atacc1 (test) values (2); +insert into atacc1 (test) values (2); +-- add a unique constraint (fails) +alter table atacc1 add constraint atacc_test1 unique (test); +insert into atacc1 (test) values (3); +drop table atacc1; + +-- let's do one where the unique contsraint fails +-- because the column doesn't exist +create table atacc1 ( test int ); +-- add a unique constraint (fails) +alter table atacc1 add constraint atacc_test1 unique (test1); +drop table atacc1; + +-- something a little more complicated +create table atacc1 ( test int, test2 int); +-- add a unique constraint +alter table atacc1 add constraint atacc_test1 unique (test, test2); +-- insert initial value +insert into atacc1 (test,test2) values (4,4); +-- should fail +insert into atacc1 (test,test2) values (4,4); +-- should all succeed +insert into atacc1 (test,test2) values (4,5); +insert into atacc1 (test,test2) values (5,4); +insert into atacc1 (test,test2) values (5,5); +drop table atacc1; + +-- lets do some naming tests +create table atacc1 (test int, test2 int, unique(test)); +alter table atacc1 add unique (test2); +-- should fail for @@ second one @@ +insert into atacc1 (test2, test) values (3, 3); +insert into atacc1 (test2, test) values (2, 3); +drop table atacc1; -- 2.40.0