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