Changeset: 2eb9dee7d193 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/2eb9dee7d193 Added Files: sql/test/transactions/Tests/transaction_isolation5.SQL.py Modified Files: sql/backends/monet5/sql_cat.c sql/backends/monet5/sql_scenario.c sql/server/sql_mvc.c sql/test/transactions/Tests/All Branch: Jul2021 Log Message:
Be carefull with savepoints and be more defensive validating against the session's schema. The assertion I removed is now invalid. diffs (130 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 @@ -1305,9 +1305,11 @@ SQLdrop_schema(Client cntxt, MalBlkPtr m return MAL_SUCCEED; } sql_trans *tr = sql->session->tr; + sql_schema *cur = cur_schema(sql); + if (!mvc_schema_privs(sql, s)) throw(SQL,"sql.drop_schema",SQLSTATE(42000) "DROP SCHEMA: access denied for %s to schema '%s'", get_string_global_var(sql, "current_user"), s->base.name); - if (s == cur_schema(sql)) + if (cur && s->base.id == cur->base.id) throw(SQL,"sql.drop_schema",SQLSTATE(42000) "DROP SCHEMA: cannot drop current schema"); if (s->system) throw(SQL,"sql.drop_schema",SQLSTATE(42000) "DROP SCHEMA: access denied for '%s'", sname); @@ -1876,6 +1878,8 @@ SQLrename_schema(Client cntxt, MalBlkPtr initcontext(); sql_trans *tr = sql->session->tr; + sql_schema *cur = cur_schema(sql); + if (!(s = mvc_bind_schema(sql, old_name))) throw(SQL, "sql.rename_schema", SQLSTATE(42S02) "ALTER SCHEMA: no such schema '%s'", old_name); if (!mvc_schema_privs(sql, s)) @@ -1898,7 +1902,7 @@ SQLrename_schema(Client cntxt, MalBlkPtr default: break; } - if (s == cur_schema(sql)) /* change current session schema name */ + if (cur && s->base.id == cur->base.id) /* change current session schema name */ if (!mvc_set_schema(sql, new_name)) throw(SQL, "sql.rename_schema",SQLSTATE(HY013) MAL_MALLOC_FAIL); return msg; diff --git a/sql/backends/monet5/sql_scenario.c b/sql/backends/monet5/sql_scenario.c --- a/sql/backends/monet5/sql_scenario.c +++ b/sql/backends/monet5/sql_scenario.c @@ -1098,7 +1098,6 @@ SQLparser(Client c) sqlcleanup(be, err); goto finalize; } - assert(m->session->schema); /* * We have dealt with the first parsing step and advanced the input reader * to the next statement (if any). 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 @@ -499,15 +499,14 @@ mvc_commit(mvc *m, int chain, const char if (name && name[0] != '\0') { sql_trans *tr = m->session->tr; TRC_DEBUG(SQL_TRANS, "Savepoint\n"); - m->session->tr = sql_trans_create(m->store, tr, name); - if (!m->session->tr) { - msg = createException(SQL, "sql.commit", SQLSTATE(HY013) "%s allocation failure while committing the transaction, will ROLLBACK instead", operation); - if ((other = mvc_rollback(m, chain, name, false)) != MAL_SUCCEED) - freeException(other); - return msg; + if (!(m->session->tr = sql_trans_create(m->store, tr, name))) + return createException(SQL, "sql.commit", SQLSTATE(HY013) "%s allocation failure while committing the transaction, will ROLLBACK instead", operation); + + if (!(m->session->schema = find_sql_schema(m->session->tr, m->session->schema_name))) { + m->session->tr = sql_trans_destroy(m->session->tr); + return createException(SQL, "sql.commit", SQLSTATE(40000) "%s finished sucessfuly, but the session's schema could not be found while starting the next transaction", operation); } m->type = Q_TRANS; - m->session->schema = find_sql_schema(m->session->tr, m->session->schema_name); TRC_INFO(SQL_TRANS, "Savepoint commit '%s' done\n", name); return msg; } @@ -608,7 +607,11 @@ mvc_rollback(mvc *m, int chain, const ch _DELETE(tr->name); tr->name = NULL; } - m->session->schema = find_sql_schema(m->session->tr, m->session->schema_name); + if (!(m->session->schema = find_sql_schema(m->session->tr, m->session->schema_name))) { + msg = createException(SQL, "sql.rollback", SQLSTATE(40000) "ROLLBACK: finished sucessfuly, but the session's schema could not be found while starting the next transaction"); + m->session->status = -1; + return msg; + } } else { /* first release all intermediate savepoints */ while (tr->parent != NULL) @@ -672,7 +675,11 @@ mvc_release(mvc *m, const char *name) _DELETE(tr->name); tr->name = NULL; m->session->tr = tr; - m->session->schema = find_sql_schema(m->session->tr, m->session->schema_name); + if (!(m->session->schema = find_sql_schema(m->session->tr, m->session->schema_name))) { + msg = createException(SQL, "sql.rollback", SQLSTATE(40000) "RELEASE: finished sucessfuly, but the session's schema could not be found while starting the next transaction"); + m->session->status = -1; + return msg; + } m->type = Q_TRANS; return msg; diff --git a/sql/test/transactions/Tests/All b/sql/test/transactions/Tests/All --- a/sql/test/transactions/Tests/All +++ b/sql/test/transactions/Tests/All @@ -2,5 +2,6 @@ transaction_isolation transaction_isolation2 transaction_isolation3 transaction_isolation4 +transaction_isolation5 mergetable-deps-crash view-deps diff --git a/sql/test/transactions/Tests/transaction_isolation5.SQL.py b/sql/test/transactions/Tests/transaction_isolation5.SQL.py new file mode 100644 --- /dev/null +++ b/sql/test/transactions/Tests/transaction_isolation5.SQL.py @@ -0,0 +1,19 @@ +from MonetDBtesting.sqltest import SQLTestCase + +with SQLTestCase() as mdb1: + mdb1.connect(username="monetdb", password="monetdb") + mdb1.execute('START TRANSACTION;').assertSucceeded() + mdb1.execute('SAVEPOINT mys;').assertSucceeded() + mdb1.execute('CREATE SCHEMA ups;').assertSucceeded() + mdb1.execute('SET SCHEMA ups;').assertSucceeded() + mdb1.execute('ROLLBACK TO SAVEPOINT mys;').assertFailed(err_code="40000", err_message="ROLLBACK: finished sucessfuly, but the session's schema could not be found while starting the next transaction") + mdb1.execute('rollback;').assertFailed() + +with SQLTestCase() as mdb1: + mdb1.connect(username="monetdb", password="monetdb") + mdb1.execute('START TRANSACTION;').assertSucceeded() + mdb1.execute('SAVEPOINT mys2;').assertSucceeded() + mdb1.execute('CREATE SCHEMA ups2;').assertSucceeded() + mdb1.execute('SET SCHEMA ups2;').assertSucceeded() + mdb1.execute('RELEASE SAVEPOINT mys2;').assertSucceeded() + mdb1.execute('rollback;').assertFailed() _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list