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