Changeset: a66f329dff3a for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/a66f329dff3a
Modified Files:
        sql/backends/monet5/sql_cat.c
        sql/server/rel_psm.c
        sql/server/rel_schema.c
        sql/server/sql_mvc.c
        sql/server/sql_mvc.h
        sql/storage/sql_storage.h
        sql/storage/store.c
        sql/test/miscellaneous/Tests/transaction_isolation2.SQL.py
Branch: Jul2021
Log Message:

More transaction conflict detections


diffs (truncated from 312 to 300 lines):

diff --git a/sql/backends/monet5/sql_cat.c b/sql/backends/monet5/sql_cat.c
--- a/sql/backends/monet5/sql_cat.c
+++ b/sql/backends/monet5/sql_cat.c
@@ -512,8 +512,7 @@ create_trigger(mvc *sql, char *sname, ch
        if (isView(t))
                throw(SQL,"sql.create_trigger",SQLSTATE(3F000) "CREATE TRIGGER: 
cannot create trigger on view '%s'", tname);
 
-       tri = mvc_create_trigger(sql, t, triggername, time, orientation, event, 
old_name, new_name, condition, query);
-       if (tri) {
+       if ((tri = mvc_create_trigger(sql, t, triggername, time, orientation, 
event, old_name, new_name, condition, query))) {
                char *buf;
                sql_rel *r = NULL;
                sql_allocator *sa = sql->sa;
@@ -539,6 +538,8 @@ create_trigger(mvc *sql, char *sname, ch
                        else
                                throw(SQL, "sql.create_trigger", 
SQLSTATE(42000) "%s", sql->errstr);
                }
+       } else {
+               throw(SQL,"sql.create_trigger", SQLSTATE(42000) "CREATE 
TRIGGER: transaction conflict detected");
        }
        return MAL_SUCCEED;
 }
@@ -746,7 +747,8 @@ create_seq(mvc *sql, char *sname, char *
                throw(SQL,"sql.create_seq", SQLSTATE(42000) "CREATE SEQUENCE: 
start value is higher than the maximum ("LLFMT" > "LLFMT")", seq->start, 
seq->maxvalue);
        if (seq->minvalue && seq->maxvalue && seq->maxvalue < seq->minvalue)
                throw(SQL,"sql.create_seq", SQLSTATE(42000) "CREATE SEQUENCE: 
maximum value is lesser than the minimum ("LLFMT" < "LLFMT")", seq->maxvalue, 
seq->minvalue);
-       sql_trans_create_sequence(sql->session->tr, s, seq->base.name, 
seq->start, seq->minvalue, seq->maxvalue, seq->increment, seq->cacheinc, 
seq->cycle, seq->bedropped);
+       if (!sql_trans_create_sequence(sql->session->tr, s, seq->base.name, 
seq->start, seq->minvalue, seq->maxvalue, seq->increment, seq->cacheinc, 
seq->cycle, seq->bedropped))
+               throw(SQL,"sql.create_seq",SQLSTATE(42000) "CREATE SEQUENCE: 
transaction conflict detected");
        return NULL;
 }
 
@@ -897,8 +899,8 @@ create_func(mvc *sql, char *sname, char 
                throw(SQL,"sql.create_func", SQLSTATE(42000) "CREATE %s: access 
denied for %s to schema '%s'", F, get_string_global_var(sql, "current_user"), 
s->base.name);
        if (strlen(fname) >= IDLENGTH)
                throw(SQL,"sql.create_func", SQLSTATE(42000) "CREATE %s: name 
'%s' too large for the backend", F, fname);
-       nf = mvc_create_func(sql, NULL, s, f->base.name, f->ops, f->res, 
f->type, f->lang, f->mod, f->imp, f->query, f->varres, f->vararg, f->system);
-       assert(nf);
+       if (!(nf = mvc_create_func(sql, NULL, s, f->base.name, f->ops, f->res, 
f->type, f->lang, f->mod, f->imp, f->query, f->varres, f->vararg, f->system)))
+               throw(SQL,"sql.create_func", SQLSTATE(42000) "CREATE %s: 
transaction conflict detected", F);
        switch (nf->lang) {
        case FUNC_LANG_INT:
        case FUNC_LANG_MAL: /* shouldn't be reachable, but leave it here */
@@ -1253,7 +1255,8 @@ SQLcreate_schema(Client cntxt, MalBlkPtr
                throw(SQL,"sql.create_schema", SQLSTATE(42000) "CREATE SCHEMA: 
insufficient privileges for user '%s'", get_string_global_var(sql, 
"current_user"));
        if (mvc_bind_schema(sql, sname))
                throw(SQL,"sql.create_schema", SQLSTATE(3F000) "CREATE SCHEMA: 
name '%s' already in use", sname);
-       (void) mvc_create_schema(sql, sname, auth_id, sql->user_id);
+       if (!mvc_create_schema(sql, sname, auth_id, sql->user_id))
+               throw(SQL,"sql.create_schema",SQLSTATE(42000) "CREATE SCHEMA: 
transaction conflict detected");
        return msg;
 }
 
@@ -1401,8 +1404,17 @@ SQLcreate_type(Client cntxt, MalBlkPtr m
                throw(SQL,"sql.create_type", SQLSTATE(42000) "CREATE TYPE: 
access denied for %s to schema '%s'", get_string_global_var(sql, 
"current_user"), s->base.name);
        if (schema_bind_type(sql, s, name))
                throw(SQL,"sql.create_type", SQLSTATE(42S02) "CREATE TYPE: type 
'%s' already exists", name);
-       if (!mvc_create_type(sql, s, name, 0, 0, 0, impl))
-               throw(SQL,"sql.create_type", SQLSTATE(0D000) "CREATE TYPE: 
unknown external type '%s'", impl);
+       switch (mvc_create_type(sql, s, name, 0, 0, 0, impl)) {
+               case -1:
+                       throw(SQL,"sql.create_type", SQLSTATE(HY013) 
MAL_MALLOC_FAIL);
+               case -2:
+               case -3:
+                       throw(SQL,"sql.create_type", SQLSTATE(42000) "CREATE 
TYPE: transaction conflict detected");
+               case -4:
+                       throw(SQL,"sql.create_type", SQLSTATE(0D000) "CREATE 
TYPE: unknown external type '%s'", impl);
+               default:
+                       break;
+       }
        return msg;
 }
 
diff --git a/sql/server/rel_psm.c b/sql/server/rel_psm.c
--- a/sql/server/rel_psm.c
+++ b/sql/server/rel_psm.c
@@ -990,7 +990,8 @@ rel_create_func(sql_query *query, dlist 
 
                        sql->params = NULL;
                        if (create) {
-                               f = mvc_create_func(sql, sql->sa, s, fname, l, 
restype, type, lang, mod, fname, lang_body, (type == F_LOADER)?TRUE:FALSE, 
vararg, FALSE);
+                               if (!(f = mvc_create_func(sql, sql->sa, s, 
fname, l, restype, type, lang, mod, fname, lang_body, (type == 
F_LOADER)?TRUE:FALSE, vararg, FALSE)))
+                                       return sql_error(sql, 01, 
SQLSTATE(42000) "CREATE %s: transaction conflict detected", F);
                        } else if (!sf) {
                                return sql_error(sql, 01, SQLSTATE(42000) 
"CREATE %s: %s function %s.%s not bound", F, slang, s->base.name, fname);
                        }
@@ -1001,7 +1002,8 @@ rel_create_func(sql_query *query, dlist 
 
                        if (create) { /* needed for recursive functions */
                                q = query_cleaned(sql->ta, q);
-                               sql->forward = f = mvc_create_func(sql, 
sql->sa, s, fname, l, restype, type, lang, sql_shared_module_name, q, q, FALSE, 
vararg, FALSE);
+                               if (!(sql->forward = f = mvc_create_func(sql, 
sql->sa, s, fname, l, restype, type, lang, sql_shared_module_name, q, q, FALSE, 
vararg, FALSE)))
+                                       return sql_error(sql, 01, 
SQLSTATE(42000) "CREATE %s: transaction conflict detected", F);
                        }
                        sql->session->schema = s;
                        b = sequential_block(query, (ra)?&ra->type:NULL, 
ra?NULL:restype, body, NULL, is_func);
@@ -1029,7 +1031,8 @@ rel_create_func(sql_query *query, dlist 
                        sql->params = NULL;
                        if (create) {
                                q = query_cleaned(sql->ta, q);
-                               f = mvc_create_func(sql, sql->sa, s, fname, l, 
restype, type, lang, fmod, fnme, q, FALSE, vararg, FALSE);
+                               if (!(f = mvc_create_func(sql, sql->sa, s, 
fname, l, restype, type, lang, fmod, fnme, q, FALSE, vararg, FALSE)))
+                                       return sql_error(sql, 01, 
SQLSTATE(42000) "CREATE %s: transaction conflict detected", F);
                        } else if (!sf) {
                                return sql_error(sql, 01, SQLSTATE(42000) 
"CREATE %s: external name %s.%s not bound (%s.%s)", F, fmod, fnme, 
s->base.name, fname );
                        } else {
diff --git a/sql/server/rel_schema.c b/sql/server/rel_schema.c
--- a/sql/server/rel_schema.c
+++ b/sql/server/rel_schema.c
@@ -314,11 +314,17 @@ column_constraint_type(mvc *sql, const c
                        (void) sql_error(sql, 02, SQLSTATE(42000) "CONSTRAINT 
%s: key %s already exists", (kt == pkey) ? "PRIMARY KEY" : "UNIQUE", name);
                        return res;
                }
-               k = (sql_key*)mvc_create_ukey(sql, t, name, kt);
+               if (!(k = (sql_key*)mvc_create_ukey(sql, t, name, kt))) {
+                       (void) sql_error(sql, 02, SQLSTATE(42000) "CONSTRAINT 
%s: transaction conflict detected", (kt == pkey) ? "PRIMARY KEY" : "UNIQUE");
+                       return res;
+               }
                k->base.new = 1;
 
                mvc_create_kc(sql, k, cs);
-               mvc_create_ukey_done(sql, k);
+               if (!mvc_create_ukey_done(sql, k)) {
+                       (void) sql_error(sql, 02, SQLSTATE(42000) "CONSTRAINT 
%s: transaction conflict detected", (kt == pkey) ? "PRIMARY KEY" : "UNIQUE");
+                       return res;
+               }
                res = SQL_OK;
        }       break;
        case SQL_FOREIGN_KEY: {
@@ -372,7 +378,10 @@ column_constraint_type(mvc *sql, const c
                                                         cs->base.name, tp1, 
rk->type == pkey ? "PRIMARY" : "UNIQUE", tp2);
                        return res;
                }
-               fk = mvc_create_fkey(sql, t, name, fkey, rk, ref_actions & 255, 
(ref_actions>>8) & 255);
+               if (!(fk = mvc_create_fkey(sql, t, name, fkey, rk, ref_actions 
& 255, (ref_actions>>8) & 255))) {
+                       (void) sql_error(sql, 02, SQLSTATE(42000) "CONSTRAINT 
FOREIGN KEY: transaction conflict detected");
+                       return res;
+               }
                fk->k.base.new = 1;
                mvc_create_fkc(sql, fk, cs);
                res = SQL_OK;
@@ -568,7 +577,10 @@ table_foreign_key(mvc *sql, char *name, 
                        sql_error(sql, 02, SQLSTATE(42000) "CONSTRAINT FOREIGN 
KEY: could not find referenced PRIMARY KEY in table '%s'\n", ft->base.name);
                        return SQL_ERR;
                }
-               fk = mvc_create_fkey(sql, t, name, fkey, rk, ref_actions & 255, 
(ref_actions>>8) & 255);
+               if (!(fk = mvc_create_fkey(sql, t, name, fkey, rk, ref_actions 
& 255, (ref_actions>>8) & 255))) {
+                       sql_error(sql, 02, SQLSTATE(42000) "CONSTRAINT FOREIGN 
KEY: transaction conflict detected");
+                       return SQL_ERR;
+               }
                fk->k.base.new = 1;
 
                for (fnms = rk->columns->h; nms && fnms; nms = nms->next, fnms 
= fnms->next) {
@@ -618,7 +630,10 @@ table_constraint_type(mvc *sql, char *na
                        return SQL_ERR;
                }
 
-               k = (sql_key*)mvc_create_ukey(sql, t, name, kt);
+               if (!(k = (sql_key*)mvc_create_ukey(sql, t, name, kt))) {
+                       (void) sql_error(sql, 02, SQLSTATE(42000) "CONSTRAINT 
%s: transaction conflict detected", (kt == pkey) ? "PRIMARY KEY" : "UNIQUE");
+                       return SQL_ERR;
+               }
                k->base.new = 1;
                for (; nms; nms = nms->next) {
                        char *nm = nms->data.sval;
@@ -632,7 +647,10 @@ table_constraint_type(mvc *sql, char *na
                        }
                        (void) mvc_create_kc(sql, k, c);
                }
-               mvc_create_ukey_done(sql, k);
+               if (!mvc_create_ukey_done(sql, k)) {
+                       (void) sql_error(sql, 02, SQLSTATE(42000) "CONSTRAINT 
%s: transaction conflict detected", (kt == pkey) ? "PRIMARY KEY" : "UNIQUE");
+                       return SQL_ERR;
+               }
        }       break;
        case SQL_FOREIGN_KEY:
                res = table_foreign_key(sql, name, s, ss, t);
@@ -1926,7 +1944,8 @@ rel_create_index(mvc *sql, char *iname, 
                sname = t->s->base.name;
 
        /* add index here */
-       i = mvc_create_idx(sql, nt, iname, itype);
+       if (!(i = mvc_create_idx(sql, nt, iname, itype)))
+               return sql_error(sql, 02, SQLSTATE(42000) "CREATE INDEX: 
transaction conflict detected");
        i->base.new = 1;
        for (n = column_list->h; n; n = n->next) {
                sql_column *c = mvc_bind_column(sql, nt, n->data.sval);
diff --git a/sql/server/sql_mvc.c b/sql/server/sql_mvc.c
--- a/sql/server/sql_mvc.c
+++ b/sql/server/sql_mvc.c
@@ -1035,14 +1035,11 @@ mvc_bind_trigger(mvc *m, sql_schema *s, 
        return trigger;
 }
 
-sql_type *
+int
 mvc_create_type(mvc *sql, sql_schema *s, const char *name, unsigned int 
digits, unsigned int scale, int radix, const char *impl)
 {
-       sql_type *t = NULL;
-
        TRC_DEBUG(SQL_TRANS, "Create type: %s\n", name);
-       t = sql_trans_create_type(sql->session->tr, s, name, digits, scale, 
radix, impl);
-       return t;
+       return sql_trans_create_type(sql->session->tr, s, name, digits, scale, 
radix, impl);
 }
 
 int
diff --git a/sql/server/sql_mvc.h b/sql/server/sql_mvc.h
--- a/sql/server/sql_mvc.h
+++ b/sql/server/sql_mvc.h
@@ -195,7 +195,7 @@ extern sql_key *mvc_bind_key(mvc *c, sql
 extern sql_key *mvc_bind_ukey(sql_table *t, list *cols);
 extern sql_trigger *mvc_bind_trigger(mvc *c, sql_schema *s, const char *tname);
 
-extern sql_type *mvc_create_type(mvc *sql, sql_schema *s, const char *sqlname, 
unsigned int digits, unsigned int scale, int radix, const char *impl);
+extern int mvc_create_type(mvc *sql, sql_schema *s, const char *sqlname, 
unsigned int digits, unsigned int scale, int radix, const char *impl);
 extern int mvc_drop_type(mvc *sql, sql_schema *s, sql_type *t, int 
drop_action);
 
 extern sql_func *mvc_create_func(mvc *sql, sql_allocator *sa, sql_schema *s, 
const char *name, list *args, list *res, sql_ftype type, sql_flang lang, const 
char *mod, const char *impl, const char *query, bit varres, bit vararg, bit 
system);
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
@@ -320,7 +320,7 @@ extern sql_trans *sql_trans_destroy(sql_
 //extern bool sql_trans_validate(sql_trans *tr);
 extern int sql_trans_commit(sql_trans *tr);
 
-extern sql_type *sql_trans_create_type(sql_trans *tr, sql_schema *s, const 
char *sqlname, unsigned int digits, unsigned int scale, int radix, const char 
*impl);
+extern int sql_trans_create_type(sql_trans *tr, sql_schema *s, const char 
*sqlname, unsigned int digits, unsigned int scale, int radix, const char *impl);
 extern int sql_trans_drop_type(sql_trans *tr, sql_schema * s, sqlid id, int 
drop_action);
 
 extern sql_func *sql_trans_create_func(sql_trans *tr, sql_schema *s, const 
char *func, list *args, list *res, sql_ftype type, sql_flang lang, const char 
*mod, const char *impl, const char *query, bit varres, bit vararg, bit system);
diff --git a/sql/storage/store.c b/sql/storage/store.c
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -4158,7 +4158,7 @@ sys_drop_sequences(sql_trans *tr, sql_sc
        return 0;
 }
 
-sql_type *
+int
 sql_trans_create_type(sql_trans *tr, sql_schema *s, const char *sqlname, 
unsigned int digits, unsigned int scale, int radix, const char *impl)
 {
        sqlstore *store = tr->store;
@@ -4166,10 +4166,10 @@ sql_trans_create_type(sql_trans *tr, sql
        sql_table *systype;
        int localtype = ATOMindex(impl);
        sql_class eclass = EC_EXTERNAL;
-       int eclass_cast = (int) eclass;
+       int eclass_cast = (int) eclass, res = 0;
 
        if (localtype < 0)
-               return NULL;
+               return -4;
        t = SA_ZNEW(tr->sa, sql_type);
        systype = find_sql_table(tr, find_sql_schema(tr, "sys"), "types");
        base_init(tr->sa, &t->base, next_oid(tr->store), TR_NEW, impl);
@@ -4181,12 +4181,11 @@ sql_trans_create_type(sql_trans *tr, sql
        t->localtype = localtype;
        t->s = s;
 
-       if (os_add(s->types, tr, t->base.name, &t->base)) {
-               return NULL;
-       }
-       if (store->table_api.table_insert(tr, systype, &t->base.id, 
&t->base.name, &t->sqlname, &t->digits, &t->scale, &radix, &eclass_cast, 
&s->base.id))
-               return NULL;
-       return t;
+       if ((res = os_add(s->types, tr, t->base.name, &t->base)))
+               return res;
+       if ((res = store->table_api.table_insert(tr, systype, &t->base.id, 
&t->base.name, &t->sqlname, &t->digits, &t->scale, &radix, &eclass_cast, 
&s->base.id)))
+               return res;
+       return 0;
 }
 
 int
@@ -5619,7 +5618,8 @@ sql_trans_create_fkey(sql_trans *tr, sql
        nk->type = kt;
        nk->columns = list_new(tr->sa, (fdestroy) &kc_destroy);
        nk->t = t;
-       nk->idx = sql_trans_create_idx(tr, t, name, (nk->type == fkey) ? 
join_idx : hash_idx);
+       if (!(nk->idx = sql_trans_create_idx(tr, t, name, (nk->type == fkey) ? 
join_idx : hash_idx)))
+               return NULL;
        nk->idx->key = nk;
 
        fk = (sql_fkey *) nk;
@@ -5786,7 +5786,8 @@ sql_trans_key_done(sql_trans *tr, sql_ke
        }
 
        /* we need to create an index */
-       k->idx = sql_trans_create_idx(tr, k->t, k->base.name, hash_idx);
+       if (!(k->idx = sql_trans_create_idx(tr, k->t, k->base.name, hash_idx)))
+               return NULL;
        k->idx->key = k;
 
        for (n=k->columns->h; n; n = n->next) {
diff --git a/sql/test/miscellaneous/Tests/transaction_isolation2.SQL.py 
b/sql/test/miscellaneous/Tests/transaction_isolation2.SQL.py
--- a/sql/test/miscellaneous/Tests/transaction_isolation2.SQL.py
+++ b/sql/test/miscellaneous/Tests/transaction_isolation2.SQL.py
@@ -52,6 +52,14 @@ with SQLTestCase() as mdb1:
         mdb2.execute('rollback;').assertSucceeded()
 
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to