Changeset: 59925200c480 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/59925200c480
Modified Files:
        sql/backends/monet5/sql.c
        sql/backends/monet5/wlr.c
        sql/storage/bat/bat_storage.c
        sql/storage/sql_storage.h
        sql/storage/store.c
        sql/test/miscellaneous/Tests/transaction_isolation.SQL.py
Branch: Jul2021
Log Message:

Use the new LOG_CONFLICT macro to detect deletion conflicts on the storage and 
throw a better error message on those cases


diffs (truncated from 356 to 300 lines):

diff --git a/sql/backends/monet5/sql.c b/sql/backends/monet5/sql.c
--- a/sql/backends/monet5/sql.c
+++ b/sql/backends/monet5/sql.c
@@ -1855,6 +1855,7 @@ mvc_clear_table_wrap(Client cntxt, MalBl
        sql_table *t;
        mvc *m = NULL;
        str msg;
+       BUN clear_res;
        lng *res = getArgReference_lng(stk, pci, 0);
        const char *sname = *getArgReference_str(stk, pci, 1);
        const char *tname = *getArgReference_str(stk, pci, 2);
@@ -1869,9 +1870,10 @@ mvc_clear_table_wrap(Client cntxt, MalBl
        t = mvc_bind_table(m, s, tname);
        if (t == NULL)
                throw(SQL, "sql.clear_table", SQLSTATE(42S02) "Table missing 
%s.%s", sname,tname);
-       *res = mvc_clear_table(m, t);
-       if (*res == BUN_NONE)
-               throw(SQL, "sql.clear_table", SQLSTATE(42S02) "clear failed");
+       clear_res = mvc_clear_table(m, t);
+       if (clear_res >= BUN_NONE - 1)
+               throw(SQL, "sql.clear_table", SQLSTATE(42000) "Table clear 
failed%s", clear_res == (BUN_NONE - 1) ? " due to conflict with another 
transaction" : "");
+       *res = (lng) clear_res;
        return MAL_SUCCEED;
 }
 
@@ -1885,9 +1887,8 @@ mvc_delete_wrap(Client cntxt, MalBlkPtr 
        const char *sname = *getArgReference_str(stk, pci, 2);
        const char *tname = *getArgReference_str(stk, pci, 3);
        ptr ins = getArgReference(stk, pci, 4);
-       int tpe = getArgType(mb, pci, 4);
+       int tpe = getArgType(mb, pci, 4), log_res;
        BAT *b = NULL;
-
        sql_schema *s;
        sql_table *t;
 
@@ -1920,10 +1921,11 @@ mvc_delete_wrap(Client cntxt, MalBlkPtr 
        if( b && BATcount(b) > 4096 && !b->batTransient)
                BATmsync(b);
        sqlstore *store = m->session->tr->store;
-       if (store->storage_api.delete_tab(m->session->tr, t, b, tpe) != LOG_OK)
-               throw(SQL, "sql.delete", SQLSTATE(3F000) "delete failed");
+       log_res = store->storage_api.delete_tab(m->session->tr, t, b, tpe);
        if (b)
                BBPunfix(b->batCacheid);
+       if (log_res != LOG_OK)
+               throw(SQL, "sql.delete", SQLSTATE(42000) "Delete failed%s", 
log_res == LOG_CONFLICT ? " due to conflict with another transaction" : "");
        return MAL_SUCCEED;
 }
 
diff --git a/sql/backends/monet5/wlr.c b/sql/backends/monet5/wlr.c
--- a/sql/backends/monet5/wlr.c
+++ b/sql/backends/monet5/wlr.c
@@ -925,7 +925,7 @@ str
 WLRdelete(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
 {
        str sname, tname;
-       int i;
+       int i, log_res;
        mvc *m=NULL;
        sql_schema *s;
        sql_table *t;
@@ -965,7 +965,9 @@ WLRdelete(Client cntxt, MalBlkPtr mb, Ma
                }
        }
 
-       store->storage_api.delete_tab(m->session->tr, t, ins, TYPE_bat);
+       log_res = store->storage_api.delete_tab(m->session->tr, t, ins, 
TYPE_bat);
+       if (log_res != LOG_OK)
+               msg = createException(MAL, "WLRdelete", SQLSTATE(42000) "Delete 
failed%s", log_res == LOG_CONFLICT ? " due to conflict with another 
transaction" : "");
 cleanup:
        BBPunfix(((BAT *) ins)->batCacheid);
        return msg;
@@ -1082,6 +1084,7 @@ WLRclear_table(Client cntxt, MalBlkPtr m
        str msg= MAL_SUCCEED;
        str *sname = getArgReference_str(stk, pci, 1);
        str *tname = getArgReference_str(stk, pci, 2);
+       BUN res;
 
        if( cntxt->wlc_kind == WLC_ROLLBACK || cntxt->wlc_kind == WLC_ERROR)
                return msg;
@@ -1095,6 +1098,8 @@ WLRclear_table(Client cntxt, MalBlkPtr m
        t = mvc_bind_table(m, s, *tname);
        if (t == NULL)
                throw(SQL, "sql.clear_table", SQLSTATE(42S02) "Table missing 
%s.%s",*sname,*tname);
-       (void) mvc_clear_table(m, t);
+       res = mvc_clear_table(m, t);
+       if (res >= BUN_NONE - 1)
+               throw(SQL, "sql.clear_table", SQLSTATE(42000) "Table clear 
failed%s", res == (BUN_NONE - 1) ? " due to conflict with another transaction" 
: "");
        return MAL_SUCCEED;
 }
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
@@ -768,7 +768,7 @@ cs_update_bat( sql_trans *tr, column_sto
        if (!is_new && !cs->cleared) {
                BAT *ui, *uv;
 
-               if (cs_real_update_bats(cs, &ui, &uv) == LOG_ERR)
+               if (cs_real_update_bats(cs, &ui, &uv) != LOG_OK)
                        return LOG_ERR;
 
                /* handle updates on just inserted bits */
@@ -899,7 +899,7 @@ cs_update_val( sql_trans *tr, column_sto
        if (!inplace) {
                BAT *ui, *uv;
 
-               if (cs_real_update_bats(cs, &ui, &uv) == LOG_ERR)
+               if (cs_real_update_bats(cs, &ui, &uv) != LOG_OK)
                        return LOG_ERR;
 
                assert(BATcount(ui) == BATcount(uv));
@@ -1015,7 +1015,7 @@ bind_col_data(sql_trans *tr, sql_column 
        if(!bat)
                return NULL;
        bat->cs.refcnt = 1;
-       if(dup_bat(tr, c->t, obat, bat, c->type.type->localtype) == LOG_ERR)
+       if(dup_bat(tr, c->t, obat, bat, c->type.type->localtype) != LOG_OK)
                return NULL;
        bat->cs.ts = tr->tid;
        /* only one writer else abort */
@@ -1277,7 +1277,7 @@ storage_delete_val(sql_trans *tr, sql_ta
        for (; seg; p = seg, seg = seg->next) {
                if (seg->start <= rid && seg->end > rid) {
                        if (!SEG_VALID_4_DELETE(seg,tr))
-                                       return LOG_ERR;
+                               return LOG_CONFLICT;
                        (void)split_segment(s->segs, seg, p, tr, rid, 1, true);
                        break;
                }
@@ -1301,7 +1301,7 @@ delete_range(sql_trans *tr, storage *s, 
                                cnt -= lcnt;
                                continue;
                        } else if (!SEG_VALID_4_DELETE(seg, tr))
-                               return LOG_ERR;
+                               return LOG_CONFLICT;
                        seg = split_segment(s->segs, seg, p, tr, start, lcnt, 
true);
                        start += lcnt;
                        cnt -= lcnt;
@@ -1309,7 +1309,7 @@ delete_range(sql_trans *tr, storage *s, 
                if (start+cnt <= seg->end)
                        break;
        }
-       return LOG_OK;;
+       return LOG_OK;
 }
 
 static int
@@ -1338,12 +1338,11 @@ storage_delete_bat(sql_trans *tr, sql_ta
                                                cur++;
                                                continue;
                                        }
-                                       if (delete_range(tr, s, f, cur-f) == 
LOG_ERR)
-                                               ok = LOG_ERR;
+                                       ok = delete_range(tr, s, f, cur-f);
                                        f = cur = l;
                                }
-                               if (ok == LOG_OK && delete_range(tr, s, f, 
cur-f) == LOG_ERR)
-                                       ok = LOG_ERR;
+                               if (ok == LOG_OK)
+                                       ok = delete_range(tr, s, f, cur-f);
                        }
                } else {
                        if (!BATtordered(i)) {
@@ -1363,8 +1362,7 @@ storage_delete_bat(sql_trans *tr, sql_ta
                                        lcnt++;
                                        n++;
                                } else {
-                                       if (delete_range(tr, s, n-lcnt, lcnt) 
== LOG_ERR)
-                                               ok = LOG_ERR;
+                                       ok = delete_range(tr, s, n-lcnt, lcnt);
                                        lcnt = 0;
                                }
                                if (!lcnt) {
@@ -1372,16 +1370,14 @@ storage_delete_bat(sql_trans *tr, sql_ta
                                        lcnt = 1;
                                }
                        }
-                       if (lcnt && ok == LOG_OK) {
-                               if (delete_range(tr, s, n-lcnt, lcnt) == 
LOG_ERR)
-                                       ok = LOG_ERR;
-                       }
+                       if (lcnt && ok == LOG_OK)
+                               ok = delete_range(tr, s, n-lcnt, lcnt);
                }
        }
        if (i != oi)
                bat_destroy(i);
-       if (ok == LOG_ERR)
-               return LOG_ERR;
+       if (ok != LOG_OK)
+               return ok;
        if ((!inTransaction(tr, t) && !in_transaction && isGlobal(t)) || 
(!isNew(t) && isLocalTemp(t)))
                trans_add(tr, &t->base, s, &tc_gc_del, &commit_update_del, 
isLocalTemp(t)?NULL:&log_update_del);
        return ok;
@@ -1906,10 +1902,13 @@ static int
 load_storage(sql_trans *tr, storage *s, sqlid id)
 {
        int ok = load_cs(tr, &s->cs, TYPE_msk, id);
-       BAT *b = temp_descriptor(s->cs.bid), *ib = b;
-
-       if (!b)
+       BAT *b = NULL, *ib = NULL;
+
+       if (ok != LOG_OK)
+               return ok;
+       if (!(b = temp_descriptor(s->cs.bid)))
                return LOG_ERR;
+       ib = b;
 
        if (b->ttype == TYPE_msk || mask_cand(b))
                b = BATunmask(b);
@@ -1920,8 +1919,7 @@ load_storage(sql_trans *tr, storage *s, 
                if (BATtdense(b)) {
                        size_t start = b->tseqbase;
                        size_t cnt = BATcount(b);
-                       if (delete_range(tr, s, start, cnt) == LOG_ERR)
-                               return LOG_ERR;
+                       ok = delete_range(tr, s, start, cnt);
                } else {
                        assert(BATtordered(b));
                        BUN icnt = BATcount(b);
@@ -1932,8 +1930,8 @@ load_storage(sql_trans *tr, storage *s, 
                                        lcnt++;
                                        n++;
                                } else {
-                                       if (delete_range(tr, s, n-lcnt, lcnt) 
== LOG_ERR)
-                                               return LOG_ERR;
+                                       if ((ok = delete_range(tr, s, n-lcnt, 
lcnt)) != LOG_OK)
+                                               break;
                                        lcnt = 0;
                                }
                                if (!lcnt) {
@@ -1941,14 +1939,13 @@ load_storage(sql_trans *tr, storage *s, 
                                        lcnt = 1;
                                }
                        }
-                       if (lcnt) {
-                               if (delete_range(tr, s, n-lcnt, lcnt) == 
LOG_ERR)
-                                       return LOG_ERR;
-                       }
+                       if (lcnt && ok == LOG_OK)
+                               ok = delete_range(tr, s, n-lcnt, lcnt);
                }
-               for (segment *seg = s->segs->h; seg; seg = seg->next)
-                       if (seg->ts == tr->tid)
-                               seg->ts = 1;
+               if (ok == LOG_OK)
+                       for (segment *seg = s->segs->h; seg; seg = seg->next)
+                               if (seg->ts == tr->tid)
+                                       seg->ts = 1;
        } else {
                if (ok == LOG_OK) {
                        s->segs = new_segments(tr, 
BATcount(quick_descriptor(s->cs.bid)));
@@ -2318,19 +2315,24 @@ clear_storage(sql_trans *tr, storage *s)
        return sz;
 }
 
+/* this function returns BUN_NONE on LOG_ERR and BUN_NONE - 1 on LOG_CONFLICT 
*/
 static BUN
 clear_del(sql_trans *tr, sql_table *t)
 {
-       int in_transaction = segments_in_transaction(tr, t);
+       int in_transaction = segments_in_transaction(tr, t), ok;
        storage *bat;
 
        if ((bat = bind_del_data(tr, t)) == NULL)
                return BUN_NONE;
        if (!isTempTable(t)) {
                lock_table(tr->store, t->base.id);
-               if (delete_range(tr, bat, 0, bat->segs->t->end) == LOG_ERR) {
+               if ((ok = delete_range(tr, bat, 0, bat->segs->t->end)) != 
LOG_OK) {
                        unlock_table(tr->store, t->base.id);
-                       return LOG_ERR;
+                       if (ok == LOG_ERR)
+                               return BUN_NONE;
+                       if (ok == LOG_CONFLICT)
+                               return BUN_NONE - 1;
+                       assert(0);
                }
                unlock_table(tr->store, t->base.id);
        }
@@ -2341,19 +2343,19 @@ clear_del(sql_trans *tr, sql_table *t)
        return LOG_OK;
 }
 
+/* this function returns BUN_NONE on LOG_ERR and BUN_NONE - 1 on LOG_CONFLICT 
*/
 static BUN
 clear_table(sql_trans *tr, sql_table *t)
 {
-
        node *n = ol_first_node(t->columns);
        sql_column *c = n->data;
-       BUN sz = count_col(tr, c, 0);
+       BUN sz = count_col(tr, c, 0), clear_ok;
 
        //sz -= count_del(tr, t, 0);
        storage *d = tab_timestamp_storage(tr, t);
        sz -= count_deletes_in_range(d->segs->h, tr, 0, sz);
-       if ((clear_del(tr, t)) == BUN_NONE)
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to