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