Changeset: 5ab61d4b2a3e for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/5ab61d4b2a3e
Modified Files:
        sql/storage/store.c
        sql/test/transactions/Tests/transaction_isolation5.SQL.py
Branch: Jul2021
Log Message:

More ddl dependencies I forgot. Adding columns/indexes to tables will conflict 
if the table is added to a merge table. Same happens for NOT NULL constraint


diffs (112 lines):

diff --git a/sql/storage/store.c b/sql/storage/store.c
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -3279,6 +3279,9 @@ sql_trans_copy_idx( sql_trans *tr, sql_t
        if ((res = os_add(t->s->idxs, tr, ni->base.name, dup_base(&ni->base))))
                return res;
 
+       /* this dependency is needed for merge tables */
+       if (!isNew(t) && (res = sql_trans_add_dependency(tr, t->base.id, ddl)))
+               return res;
        if (!isNew(t) && isGlobal(t) && !isGlobalTemp(t) && (res = 
sql_trans_add_dependency(tr, t->base.id, dml)))
                return res;
 
@@ -3386,6 +3389,9 @@ sql_trans_copy_column( sql_trans *tr, sq
        if ((res = ol_add(t->columns, &col->base)))
                return res;
 
+       /* this dependency is needed for merge tables */
+       if (!isNew(t) && (res = sql_trans_add_dependency(tr, t->base.id, ddl)))
+               return res;
        if (!isNew(t) && isGlobal(t) && !isGlobalTemp(t) && (res = 
sql_trans_add_dependency(tr, t->base.id, dml)))
                return res;
 
@@ -3406,11 +3412,16 @@ sql_trans_copy_column( sql_trans *tr, sq
                        ATOMIC_PTR_DESTROY(&col->data);
                        return res;
                }
-               if (c->type.type->s) /* column depends on type */
+               if (c->type.type->s) { /* column depends on type */
                        if ((res = sql_trans_create_dependency(tr, 
c->type.type->base.id, col->base.id, TYPE_DEPENDENCY))) {
                                ATOMIC_PTR_DESTROY(&col->data);
                                return res;
                        }
+                       if (!isNew(c->type.type) && (res = 
sql_trans_add_dependency(tr, c->type.type->base.id, ddl))) {
+                               ATOMIC_PTR_DESTROY(&col->data);
+                               return res;
+                       }
+               }
        }
        if (cres)
                *cres = col;
@@ -5895,6 +5906,9 @@ sql_trans_alter_null(sql_trans *tr, sql_
                dup->null = isnull;
 
                /* disallow concurrent updates on the column if not null is set 
*/
+               /* this dependency is needed for merge tables */
+               if (!isNew(col) && (res = sql_trans_add_dependency(tr, 
col->t->base.id, ddl)))
+                       return res;
                if (!isnull && !isNew(col) && isGlobal(col->t) && 
!isGlobalTemp(col->t) && (res = sql_trans_add_dependency(tr, col->t->base.id, 
dml)))
                        return res;
        }
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
@@ -65,3 +65,57 @@ with SQLTestCase() as mdb1:
         mdb1.execute('drop schema mysch;').assertSucceeded()
         mdb1.execute('drop role myrole;').assertSucceeded()
         mdb1.execute('commit;').assertSucceeded()
+
+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 merge table parent(a int, b 
int);').assertSucceeded()
+        mdb1.execute('create table child1(a int, b int);').assertSucceeded()
+        mdb1.execute("insert into child1 values (1,1);").assertSucceeded()
+        mdb1.execute('create table child2(a int, b int);').assertSucceeded()
+        mdb1.execute("insert into child2 values (2,2);").assertSucceeded()
+        mdb1.execute('commit;').assertSucceeded()
+        mdb1.execute('start transaction;').assertSucceeded()
+        mdb2.execute('start transaction;').assertSucceeded()
+        mdb1.execute("alter table parent add table child1;").assertSucceeded()
+        mdb2.execute('alter table child1 add column data 
int;').assertSucceeded() # number of columns must match
+        mdb1.execute('commit;').assertSucceeded()
+        mdb2.execute('commit;').assertFailed(err_code="40000", 
err_message="COMMIT: transaction is aborted because of concurrency conflicts, 
will ROLLBACK instead")
+
+        mdb1.execute('select * from parent;').assertDataResultMatch([(1,1)])
+        mdb2.execute('select * from parent;').assertDataResultMatch([(1,1)])
+
+        mdb1.execute("alter table parent drop table child1;").assertSucceeded()
+        mdb1.execute("alter table parent add table child2;").assertSucceeded()
+        mdb1.execute('start transaction;').assertSucceeded()
+        mdb2.execute('start transaction;').assertSucceeded()
+        mdb1.execute("alter table parent add table child1;").assertSucceeded()
+        mdb2.execute('alter table child1 alter column a set not 
null;').assertSucceeded() # null constraints must match
+        mdb1.execute('commit;').assertSucceeded()
+        mdb2.execute('commit;').assertFailed(err_code="40000", 
err_message="COMMIT: transaction is aborted because of concurrency conflicts, 
will ROLLBACK instead")
+
+        mdb1.execute('select * from 
parent;').assertDataResultMatch([(1,1),(2,2)])
+        mdb2.execute('select * from 
parent;').assertDataResultMatch([(1,1),(2,2)])
+
+        mdb1.execute('alter table parent drop table child1;').assertSucceeded()
+
+        mdb1.execute('start transaction;').assertSucceeded()
+        mdb2.execute('start transaction;').assertSucceeded()
+        mdb1.execute("alter table parent add table child1;").assertSucceeded()
+        mdb2.execute('alter table child1 drop column b;').assertSucceeded() # 
number of columns must match
+        mdb1.execute('commit;').assertSucceeded()
+        mdb2.execute('commit;').assertFailed(err_code="40000", 
err_message="COMMIT: transaction is aborted because of concurrency conflicts, 
will ROLLBACK instead")
+
+        mdb1.execute('select * from 
parent;').assertDataResultMatch([(1,1),(2,2)])
+        mdb2.execute('select * from 
parent;').assertDataResultMatch([(1,1),(2,2)])
+
+        mdb1.execute('start transaction;').assertSucceeded()
+        mdb1.execute('alter table parent drop table child1;').assertSucceeded()
+        mdb1.execute('alter table parent drop table child2;').assertSucceeded()
+        mdb1.execute('drop table parent;').assertSucceeded()
+        mdb1.execute('drop table child1;').assertSucceeded()
+        mdb1.execute('drop table child2;').assertSucceeded()
+        mdb1.execute('commit;').assertSucceeded()
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to