Changeset: 669f28bd74f7 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/669f28bd74f7
Modified Files:
        sql/storage/bat/bat_storage.c
        sql/storage/sql_storage.h
        sql/storage/store.c
        sql/test/miscellaneous/Tests/transaction_isolation3.SQL.py
Branch: iso
Log Message:

Let's be more cruel with keys and parts. Also added missing lock and don't 
forget to rollback on error


diffs (114 lines):

diff --git a/sql/storage/bat/bat_storage.c b/sql/storage/bat/bat_storage.c
--- a/sql/storage/bat/bat_storage.c
+++ b/sql/storage/bat/bat_storage.c
@@ -3643,24 +3643,36 @@ static void *
 key_claim_tab(sql_trans *tr, sql_table *t, size_t cnt)
 {
        storage *s;
+       int ok = LOG_OK;
 
        /* we have a single segment structure for each persistent table
         * for temporary tables each has its own */
-       if ((s = bind_del_data(tr, t, NULL)) == NULL || segments_conflict(tr, 
s->segs, 1))
+       if ((s = bind_del_data(tr, t, NULL)) == NULL)
                /* TODO check for other inserts ! */
                return NULL;
 
+       lock_table(tr->store, t->base.id);
+       ok = segments_conflict(tr, s->segs, 1);
+       unlock_table(tr->store, t->base.id);
+
+       if (ok != LOG_OK)
+               return NULL;
        return claim_segments(tr, t, s, cnt); /* find slot(s) */
 }
 
 static int
-tab_validate(sql_trans *tr, sql_table *t)
+tab_validate(sql_trans *tr, sql_table *t, int uncommitted)
 {
        storage *s;
+       int ok = LOG_OK;
 
        if ((s = bind_del_data(tr, t, NULL)) == NULL)
                return LOG_ERR;
-       return segments_conflict(tr, s->segs, 0);
+
+       lock_table(tr->store, t->base.id);
+       ok = segments_conflict(tr, s->segs, uncommitted);
+       unlock_table(tr->store, t->base.id);
+       return ok;
 }
 
 static BAT *
diff --git a/sql/storage/sql_storage.h b/sql/storage/sql_storage.h
--- a/sql/storage/sql_storage.h
+++ b/sql/storage/sql_storage.h
@@ -142,7 +142,7 @@ typedef int (*update_idx_fptr) (sql_tran
 
 typedef int (*delete_tab_fptr) (sql_trans *tr, sql_table *t, void *d, int tpe);
 typedef void * (*claim_tab_fptr) (sql_trans *tr, sql_table *t, size_t cnt);
-typedef int (*tab_validate_fptr) (sql_trans *tr, sql_table *t);
+typedef int (*tab_validate_fptr) (sql_trans *tr, sql_table *t, int 
uncommitted);
 
 /*
 -- count number of rows in column (excluding the deletes)
diff --git a/sql/storage/store.c b/sql/storage/store.c
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -268,13 +268,13 @@ key_validate(sql_trans *tr, sql_key *k) 
        sqlstore *store = tr->store;
 
        if (k->t && isTable(k->t) && !isNew(k->t) && !isTempTable(k->t))
-               if ((ok = store->storage_api.tab_validate(tr, k->t)))
+               if ((ok = store->storage_api.tab_validate(tr, k->t, 1)))
                        return ok;
 
        if (k->type == fkey) {
                sql_key *rk = (sql_key*)os_find_id(tr->cat->objects, tr, 
((sql_fkey*)k)->rkey);
                if (rk && rk->t && isTable(rk->t) && !isNew(rk->t) && 
!isTempTable(rk->t))
-                       if ((ok = store->storage_api.tab_validate(tr, rk->t)))
+                       if ((ok = store->storage_api.tab_validate(tr, rk->t, 
1)))
                                return ok;
        }
        return ok;
@@ -288,7 +288,7 @@ part_validate(sql_trans *tr, sql_part *p
        sql_table *t = find_sql_table_id(tr, pt->t->s, pt->member);
 
        if (t && isTable(t) && !isNew(t) && !isTempTable(t))
-               if ((ok = store->storage_api.tab_validate(tr, t)))
+               if ((ok = store->storage_api.tab_validate(tr, t, 1)))
                        return ok;
        return ok;
 }
@@ -3471,7 +3471,7 @@ sql_trans_valid(sql_trans *tr)
                        sql_column *c = p->c;
 
                        if (c->t && isTable(c->t) && !isNew(c->t) && 
!isTempTable(c->t)) {
-                               if ((ok = store->storage_api.tab_validate(tr, 
c->t)))
+                               if ((ok = store->storage_api.tab_validate(tr, 
c->t, 0)))
                                        break;
                        }
                }
@@ -3519,6 +3519,7 @@ sql_trans_commit(sql_trans *tr)
                                break;
                }
                if (ok != LOG_OK) {
+                       sql_trans_rollback(tr, 1);
                        store_unlock(store);
                        MT_lock_unset(&store->commit);
                        return ok == LOG_CONFLICT ? SQL_CONFLICT : SQL_ERR;
diff --git a/sql/test/miscellaneous/Tests/transaction_isolation3.SQL.py 
b/sql/test/miscellaneous/Tests/transaction_isolation3.SQL.py
--- a/sql/test/miscellaneous/Tests/transaction_isolation3.SQL.py
+++ b/sql/test/miscellaneous/Tests/transaction_isolation3.SQL.py
@@ -18,8 +18,8 @@ with SQLTestCase() as mdb1:
         mdb2.execute('start transaction;').assertSucceeded()
         mdb1.execute('alter table integers add primary key 
(i);').assertSucceeded()
         mdb2.execute('insert into integers values 
(5,1),(5,2),(5,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('commit;').assertFailed(err_code="40000", 
err_message="COMMIT: transaction is aborted because of concurrency conflicts, 
will ROLLBACK instead")
+        mdb2.execute('commit;').assertSucceeded()
 
         mdb1.execute('start transaction;').assertSucceeded()
         mdb2.execute('start transaction;').assertSucceeded()
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to