Changeset: 4246a959b00b for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/4246a959b00b
Modified Files:
        sql/storage/store.c
        sql/test/miscellaneous/Tests/transaction_isolation4.SQL.py
Branch: iso
Log Message:

Look for nested merge tables


diffs (142 lines):

diff --git a/sql/storage/store.c b/sql/storage/store.c
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -4936,6 +4936,45 @@ sql_trans_drop_schema(sql_trans *tr, sql
        return 0;
 }
 
+static int
+sql_trans_propagate_dependencies_parents(sql_trans *tr, sql_table *mt)
+{
+       int res = LOG_OK;
+       sql_part *pt = NULL;
+
+       for (; mt; mt = pt?pt->t:NULL) {
+               if (!isNew(mt) && (res = sql_trans_add_dependency(tr, 
mt->base.id, ddl))) /* protect from another transaction changing the table's 
schema */
+                       return res;
+               pt = partition_find_part(tr, mt, NULL);
+       }
+       return res;
+}
+
+static int
+sql_trans_propagate_dependencies_children(sql_trans *tr, sql_table *pt)
+{
+       int res = LOG_OK;
+
+       if (!isNew(pt)) {
+               if ((res = sql_trans_add_dependency(tr, pt->base.id, ddl))) /* 
protect from another transaction changing the table's schema */
+                       return res;
+               if ((res = sql_trans_add_dependency_change(tr, pt->base.id, 
ddl))) /* protect from being added twice */
+                       return res;
+               if (isTable(pt) && (res = sql_trans_add_dependency(tr, 
pt->base.id, dml))) /* disallow concurrent updates on pt */
+                       return res;
+       }
+       if (isMergeTable(pt) && !list_empty(pt->members)) {
+               for (node *nt = pt->members->h; nt; nt = nt->next) {
+                       sql_part *pd = nt->data;
+                       sql_table *t = find_sql_table_id(tr, pt->s, pd->member);
+
+                       if ((res = 
sql_trans_propagate_dependencies_children(tr, t)))
+                               return res;
+               }
+       }
+       return res;
+}
+
 int
 sql_trans_add_table(sql_trans *tr, sql_table *mt, sql_table *pt)
 {
@@ -4965,11 +5004,9 @@ sql_trans_add_table(sql_trans *tr, sql_t
                return res;
        if ((res = os_add(mt->s->parts, tr, p->base.name, dup_base(&p->base))))
                return res;
-       if (!isNew(pt) && (res = sql_trans_add_dependency(tr, pt->base.id, 
ddl))) /* protect from another transaction changing the table's schema */
+       if ((res = sql_trans_propagate_dependencies_parents(tr, mt)))
                return res;
-       if (!isNew(mt) && (res = sql_trans_add_dependency(tr, mt->base.id, 
ddl))) /* protect from another transaction changing the table's schema */
-               return res;
-       if (!isNew(pt) && (res = sql_trans_add_dependency_change(tr, 
pt->base.id, ddl))) /* protect from being added twice */
+       if ((res = sql_trans_propagate_dependencies_children(tr, pt)))
                return res;
        return res;
 }
@@ -5103,13 +5140,9 @@ sql_trans_add_range_partition(sql_trans 
 
        if (!update)
                res = os_add(mt->s->parts, tr, p->base.name, 
dup_base(&p->base));
-       if (!isNew(pt) && (res = sql_trans_add_dependency(tr, pt->base.id, 
ddl))) /* protect from another transaction changing the table's schema */
-               return res;
-       if (!isNew(mt) && (res = sql_trans_add_dependency(tr, mt->base.id, 
ddl))) /* protect from another transaction changing the table's schema */
+       if ((res = sql_trans_propagate_dependencies_parents(tr, mt)))
                return res;
-       if (!isNew(pt) && (res = sql_trans_add_dependency_change(tr, 
pt->base.id, ddl))) /* protect from being added twice */
-               return res;
-       if (!isNew(pt) && (res = sql_trans_add_dependency(tr, pt->base.id, 
dml))) /* disallow concurrent updates on pt */
+       if ((res = sql_trans_propagate_dependencies_children(tr, pt)))
                return res;
 finish:
        VALclear(&vmin);
@@ -5235,13 +5268,9 @@ sql_trans_add_value_partition(sql_trans 
                if ((res = os_add(mt->s->parts, tr, p->base.name, 
dup_base(&p->base))))
                        return res;
        }
-       if (!isNew(pt) && (res = sql_trans_add_dependency(tr, pt->base.id, 
ddl))) /* protect from another transaction changing the table's schema */
-               return res;
-       if (!isNew(mt) && (res = sql_trans_add_dependency(tr, mt->base.id, 
ddl))) /* protect from another transaction changing the table's schema */
+       if ((res = sql_trans_propagate_dependencies_parents(tr, mt)))
                return res;
-       if (!isNew(pt) && (res = sql_trans_add_dependency_change(tr, 
pt->base.id, ddl))) /* protect from being added twice */
-               return res;
-       if (!isNew(pt) && (res = sql_trans_add_dependency(tr, pt->base.id, 
dml))) /* disallow concurrent updates on pt */
+       if ((res = sql_trans_propagate_dependencies_children(tr, pt)))
                return res;
        return 0;
 }
diff --git a/sql/test/miscellaneous/Tests/transaction_isolation4.SQL.py 
b/sql/test/miscellaneous/Tests/transaction_isolation4.SQL.py
--- a/sql/test/miscellaneous/Tests/transaction_isolation4.SQL.py
+++ b/sql/test/miscellaneous/Tests/transaction_isolation4.SQL.py
@@ -49,11 +49,43 @@ with SQLTestCase() as mdb1:
         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('create merge table parent1(a int) PARTITION BY RANGE ON 
(a);').assertSucceeded()
+        mdb1.execute('create merge table parent2(a int);').assertSucceeded()
+        mdb1.execute('create table child1(a int);').assertSucceeded()
+        mdb1.execute('alter table parent2 add table child1;').assertSucceeded()
+        mdb1.execute('start transaction;').assertSucceeded()
+        mdb2.execute('start transaction;').assertSucceeded()
+        mdb1.execute("ALTER TABLE parent1 ADD TABLE parent2 AS PARTITION FROM 
'1' TO '2';").assertSucceeded()
+        mdb2.execute("insert into child1 values (3);").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('create merge table parent3(a int) PARTITION BY RANGE ON 
(a);').assertSucceeded()
+        mdb1.execute('create merge table parent4(a int);').assertSucceeded()
+        mdb1.execute('create table child2(a int);').assertSucceeded()
+        mdb1.execute('alter table parent4 add table child2;').assertSucceeded()
+        mdb1.execute('start transaction;').assertSucceeded()
+        mdb2.execute('start transaction;').assertSucceeded()
+        mdb1.execute("ALTER TABLE parent3 ADD TABLE parent4 AS PARTITION FROM 
'1' TO '2';").assertSucceeded()
+        mdb2.execute("alter table parent3 set schema 
mys2;").assertFailed(err_code="42000", err_message="ALTER TABLE: transaction 
conflict detected")
+        mdb1.execute('commit;').assertSucceeded()
+        mdb2.execute('rollback;').assertSucceeded()
+
         mdb1.execute('start transaction;').assertSucceeded()
         mdb1.execute('drop table myt;').assertSucceeded()
         mdb1.execute('drop user duser;').assertSucceeded()
         mdb1.execute('drop role myrole;').assertSucceeded()
         mdb1.execute('drop schema mys cascade;').assertSucceeded()
         mdb1.execute('drop user duser2;').assertSucceeded()
+        mdb1.execute('alter table parent1 drop table 
parent2;').assertSucceeded()
+        mdb1.execute('alter table parent2 drop table 
child1;').assertSucceeded()
+        mdb1.execute('alter table parent3 drop table 
parent4;').assertSucceeded()
+        mdb1.execute('alter table parent4 drop table 
child2;').assertSucceeded()
+        mdb1.execute('drop table child1;').assertSucceeded()
+        mdb1.execute('drop table child2;').assertSucceeded()
+        mdb1.execute('drop table parent1;').assertSucceeded()
+        mdb1.execute('drop table parent2;').assertSucceeded()
+        mdb1.execute('drop table parent3;').assertSucceeded()
+        mdb1.execute('drop table parent4;').assertSucceeded()
         mdb1.execute('drop schema mys2;').assertSucceeded()
         mdb1.execute('commit;').assertSucceeded()
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to