Changeset: 25610bd0191e for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/25610bd0191e
Branch: default
Log Message:

Merged with Jan2022


diffs (176 lines):

diff --git a/sql/storage/store.c b/sql/storage/store.c
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -3412,6 +3412,12 @@ sql_trans_copy_idx( sql_trans *tr, sql_t
        if ((res = store_reset_sql_functions(tr, t->base.id))) /* reset sql 
functions depending on the table */
                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;
+
        if (isDeclaredTable(i->t))
                if (!isDeclaredTable(t) && isTable(ni->t) && 
idx_has_column(ni->type))
                        if ((res = store->storage_api.create_idx(tr, ni))) {
@@ -3518,6 +3524,12 @@ 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;
+
        ATOMIC_PTR_INIT(&col->data, NULL);
        if (isDeclaredTable(c->t))
                if (isTable(t))
@@ -3535,11 +3547,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;
@@ -6056,6 +6073,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;
                if ((res = store_reset_sql_functions(tr, col->t->base.id))) /* 
reset sql functions depending on the table */
@@ -6582,8 +6602,10 @@ sql_trans_create_idx(sql_idx **i, sql_tr
 
        ATOMIC_PTR_INIT(&ni->data, NULL);
        if (!isDeclaredTable(t) && isTable(ni->t) && idx_has_column(ni->type))
-               if ((res = store->storage_api.create_idx(tr, ni)))
+               if ((res = store->storage_api.create_idx(tr, ni))) {
+                       ATOMIC_PTR_DESTROY(&ni->data);
                        return res;
+               }
        if (!isDeclaredTable(t))
                if ((res = store->table_api.table_insert(tr, sysidx, 
&ni->base.id, &t->base.id, &ni->type, &ni->base.name))) {
                        ATOMIC_PTR_DESTROY(&ni->data);
diff --git a/sql/test/BugTracker-2021/Tests/All 
b/sql/test/BugTracker-2021/Tests/All
--- a/sql/test/BugTracker-2021/Tests/All
+++ b/sql/test/BugTracker-2021/Tests/All
@@ -33,3 +33,4 @@ remote-table-large.Bug-7178
 groupby-subquery.Bug-7180
 grouping-sets-aliases.Bug-7185
 copyinto-copyfrom.Bug-7186
+concurrent-add-column.Bug-7196
diff --git 
a/sql/test/BugTracker-2021/Tests/concurrent-add-column.Bug-7196.SQL.py 
b/sql/test/BugTracker-2021/Tests/concurrent-add-column.Bug-7196.SQL.py
new file mode 100644
--- /dev/null
+++ b/sql/test/BugTracker-2021/Tests/concurrent-add-column.Bug-7196.SQL.py
@@ -0,0 +1,30 @@
+from MonetDBtesting.sqltest import SQLTestCase
+
+with SQLTestCase() as mdb1:
+    with SQLTestCase() as mdb2:
+        mdb1.connect(username="monetdb", password="monetdb")
+        mdb2.connect(username="monetdb", password="monetdb")
+
+        mdb1.execute('create table test (id bigint);').assertSucceeded()
+        mdb1.execute("insert into test values (1);").assertSucceeded()
+        mdb1.execute('start transaction;').assertSucceeded()
+        mdb2.execute('start transaction;').assertSucceeded()
+        mdb1.execute('alter table test add column data int;').assertSucceeded()
+        mdb2.execute("insert into test values (2);").assertSucceeded()
+        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 test;').assertDataResultMatch([(1,None)])
+        mdb2.execute('select * from test;').assertDataResultMatch([(1,None)])
+
+        mdb1.execute('start transaction;').assertSucceeded()
+        mdb2.execute('start transaction;').assertSucceeded()
+        mdb1.execute('alter table test drop column data;').assertSucceeded()
+        mdb2.execute("insert into test values (3,4);").assertSucceeded()
+        mdb1.execute('commit;').assertSucceeded()
+        mdb2.execute('commit;').assertSucceeded()
+
+        mdb1.execute('select * from test;').assertDataResultMatch([(1,),(3,)])
+        mdb2.execute('select * from test;').assertDataResultMatch([(1,),(3,)])
+
+        mdb1.execute('drop table test;').assertSucceeded()
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
@@ -71,6 +71,60 @@ with SQLTestCase() as mdb1:
         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()
+
+with SQLTestCase() as mdb1:
+    with SQLTestCase() as mdb2:
+        mdb1.connect(username="monetdb", password="monetdb")
+        mdb2.connect(username="monetdb", password="monetdb")
+
         # Test different instantiations of SQL functions and views on 
different transactions
         mdb1.execute('start transaction;').assertSucceeded()
         mdb1.execute('CREATE MERGE TABLE parent(a int)').assertSucceeded()
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to