Changeset: c2e3aa57817b for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/c2e3aa57817b
Modified Files:
        sql/server/rel_schema.c
        sql/test/miscellaneous/Tests/simple_selects.test
Branch: default
Log Message:

Merged with Jan2022


diffs (145 lines):

diff --git a/sql/server/rel_schema.c b/sql/server/rel_schema.c
--- a/sql/server/rel_schema.c
+++ b/sql/server/rel_schema.c
@@ -378,6 +378,10 @@ column_constraint_type(mvc *sql, const c
                        (void) sql_error(sql, 02, SQLSTATE(42000) "CONSTRAINT 
%s: key %s already exists", (kt == pkey) ? "PRIMARY KEY" : "UNIQUE", name);
                        return res;
                }
+               if (ol_find_name(t->idxs, name) || mvc_bind_idx(sql, ss, name)) 
{
+                       (void) sql_error(sql, 02, SQLSTATE(42000) "CONSTRAINT 
%s: an index named '%s' already exists, and it would conflict with the key", kt 
== pkey ? "PRIMARY KEY" : "UNIQUE", name);
+                       return res;
+               }
                switch (mvc_create_ukey(&k, sql, t, name, kt)) {
                        case -1:
                                (void) sql_error(sql, 02, SQLSTATE(HY013) 
MAL_MALLOC_FAIL);
@@ -461,6 +465,10 @@ column_constraint_type(mvc *sql, const c
                        (void) sql_error(sql, 02, SQLSTATE(42000) "CONSTRAINT 
FOREIGN KEY: key '%s' already exists", name);
                        return res;
                }
+               if (ol_find_name(t->idxs, name) || mvc_bind_idx(sql, ss, name)) 
{
+                       (void) sql_error(sql, 02, SQLSTATE(42000) "CONSTRAINT 
FOREIGN KEY: an index named '%s' already exists, and it would conflict with the 
key", name);
+                       return res;
+               }
 
                /* find unique referenced key */
                if (n->next->data.lval) {
@@ -719,6 +727,10 @@ table_foreign_key(mvc *sql, const char *
                        (void) sql_error(sql, 02, SQLSTATE(42000) "CONSTRAINT 
FOREIGN KEY: key '%s' already exists", name);
                        return SQL_ERR;
                }
+               if (ol_find_name(t->idxs, name) || mvc_bind_idx(sql, ss, name)) 
{
+                       (void) sql_error(sql, 02, SQLSTATE(42000) "CONSTRAINT 
FOREIGN KEY: an index named '%s' already exists, and it would conflict with the 
key", name);
+                       return SQL_ERR;
+               }
                if (n->next->next->data.lval) { /* find unique referenced key */
                        dnode *rnms = n->next->next->data.lval->h;
                        list *cols = sa_list(sql->sa);
@@ -825,6 +837,10 @@ table_constraint_type(mvc *sql, const ch
                        (void) sql_error(sql, 02, SQLSTATE(42000) "CONSTRAINT 
%s: key '%s' already exists", kt == pkey ? "PRIMARY KEY" : "UNIQUE", name);
                        return SQL_ERR;
                }
+               if (ol_find_name(t->idxs, name) || mvc_bind_idx(sql, ss, name)) 
{
+                       (void) sql_error(sql, 02, SQLSTATE(42000) "CONSTRAINT 
%s: an index named '%s' already exists, and it would conflict with the key", kt 
== pkey ? "PRIMARY KEY" : "UNIQUE", name);
+                       return SQL_ERR;
+               }
 
                switch (mvc_create_ukey(&k, sql, t, name, kt)) {
                        case -1:
@@ -2200,6 +2216,8 @@ rel_create_index(mvc *sql, char *iname, 
                return sql_error(sql, 02, SQLSTATE(42000) "CREATE INDEX: index 
name cannot contain just digit characters (0 through 9)");
        if ((i = mvc_bind_idx(sql, t->s, iname)))
                return sql_error(sql, 02, SQLSTATE(42S11) "CREATE INDEX: name 
'%s' already in use", iname);
+       if (ol_find_name(t->keys, iname) || mvc_bind_key(sql, t->s, iname))
+               return sql_error(sql, 02, SQLSTATE(42000) "CREATE INDEX: a key 
named '%s' already exists, and it would conflict with the index", iname);
        if (!isTable(t))
                return sql_error(sql, 02, SQLSTATE(42S02) "CREATE INDEX: cannot 
create index on %s '%s'", TABLE_TYPE_DESCRIPTION(t->type, t->properties), 
tname);
        nt = dup_sql_table(sql->sa, t);
diff --git a/sql/test/miscellaneous/Tests/simple_selects.test 
b/sql/test/miscellaneous/Tests/simple_selects.test
--- a/sql/test/miscellaneous/Tests/simple_selects.test
+++ b/sql/test/miscellaneous/Tests/simple_selects.test
@@ -1034,6 +1034,42 @@ statement ok
 START TRANSACTION
 
 statement ok
+create table x (x int primary key)
+
+statement ok
+create table y (y int)
+
+statement ok
+create index ups on y(y)
+
+statement error 42000!CONSTRAINT FOREIGN KEY: an index named 'ups' already 
exists, and it would conflict with the key
+alter table y add constraint ups foreign key (y) references x (x)
+
+statement ok
+ROLLBACK
+
+statement ok
+START TRANSACTION
+
+statement ok
+create table x (x int primary key)
+
+statement ok
+create table y (y int)
+
+statement ok
+alter table y add constraint ups2 foreign key (y) references x (x)
+
+statement error 42S11!CREATE INDEX: name 'ups2' already in use
+create index ups2 on y(y)
+
+statement ok
+ROLLBACK
+
+statement ok
+START TRANSACTION
+
+statement ok
 create unlogged table foo (i int primary key)
 
 statement error 42000!CONSTRAINT FOREIGN KEY: cannot create foreign key 
between logged and unlogged tables
diff --git a/sql/test/transactions/Tests/transaction_isolation5.SQL.py 
b/sql/test/transactions/Tests/transaction_isolation5.SQL.py
--- a/sql/test/transactions/Tests/transaction_isolation5.SQL.py
+++ b/sql/test/transactions/Tests/transaction_isolation5.SQL.py
@@ -235,3 +235,39 @@ with SQLTestCase() as mdb1:
         mdb1.execute('drop procedure ups;').assertSucceeded()
         mdb1.execute('drop table x;').assertSucceeded()
         mdb1.execute('commit;').assertSucceeded()
+
+# Test concurrent index and constraints with the same name on the same table, 
ugh
+with SQLTestCase() as mdb1:
+    with SQLTestCase() as mdb2:
+        mdb1.connect(username="monetdb", password="monetdb")
+        mdb2.connect(username="monetdb", password="monetdb")
+
+        mdb1.execute('start transaction;').assertSucceeded()
+        mdb1.execute('create table x (x int primary key);').assertSucceeded()
+        mdb1.execute('create table y (y int);').assertSucceeded()
+        mdb1.execute('commit;').assertSucceeded()
+        mdb1.execute('start transaction;').assertSucceeded()
+        mdb2.execute('start transaction;').assertSucceeded()
+        mdb1.execute('create index ups on y(y);').assertSucceeded()
+        mdb2.execute('alter table y add constraint ups foreign key (y) 
references x (x);').assertFailed(err_code="42000", err_message="ALTER TABLE: 
sys_y_ups conflicts with another transaction")
+        mdb1.execute('commit;').assertSucceeded()
+        mdb2.execute('commit;').assertFailed()
+        mdb1.execute('start transaction;').assertSucceeded()
+        mdb1.execute('drop table x;').assertSucceeded()
+        mdb1.execute('drop table y;').assertSucceeded()
+        mdb1.execute('commit;').assertSucceeded()
+
+        mdb1.execute('start transaction;').assertSucceeded()
+        mdb1.execute('create table x (x int primary key);').assertSucceeded()
+        mdb1.execute('create table y (y int);').assertSucceeded()
+        mdb1.execute('commit;').assertSucceeded()
+        mdb1.execute('start transaction;').assertSucceeded()
+        mdb2.execute('start transaction;').assertSucceeded()
+        mdb1.execute('alter table y add constraint ups2 foreign key (y) 
references x (x);').assertSucceeded()
+        mdb2.execute('create index ups2 on 
y(y);').assertFailed(err_code="42000", err_message="ALTER TABLE: sys_y_ups2 
conflicts with another transaction")
+        mdb1.execute('commit;').assertSucceeded()
+        mdb2.execute('commit;').assertFailed()
+        mdb1.execute('start transaction;').assertSucceeded()
+        mdb1.execute('drop table y;').assertSucceeded()
+        mdb1.execute('drop table x;').assertSucceeded()
+        mdb1.execute('commit;').assertSucceeded()
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to