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