Changeset: 4f5d9be94e45 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/4f5d9be94e45
Modified Files:
        sql/backends/monet5/sql_scenario.c
        sql/backends/monet5/sql_transaction.c
        sql/backends/monet5/sql_user.c
        sql/server/sql_mvc.c
        sql/storage/store.c
        sql/test/Triggers/Tests/trigger_schema.test
        sql/test/miscellaneous/Tests/transaction_isolation4.SQL.py
Branch: iso
Log Message:

Check if the session's schema is valid at the start of a transaction, if not 
the transaction cannot start


diffs (244 lines):

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
@@ -623,8 +623,14 @@ SQLtrans(mvc *m)
        if (!m->session->tr->active) {
                sql_session *s;
 
-               if (mvc_trans(m) < 0)
-                       throw(SQL, "sql.trans", SQLSTATE(HY013) 
MAL_MALLOC_FAIL);
+               switch (mvc_trans(m)) {
+                       case -1:
+                               throw(SQL, "sql.trans", SQLSTATE(HY013) 
MAL_MALLOC_FAIL);
+                       case -3:
+                               throw(SQL, "sql.trans", SQLSTATE(42000) "The 
session's schema was not found, this transaction won't start");
+                       default:
+                               break;
+               }
                s = m->session;
                if (!s->schema) {
                        if (monet5_user_get_def_schema(m, m->user_id, 
&s->schema_name) < 0) {
@@ -637,7 +643,7 @@ SQLtrans(mvc *m)
                        }
                        if (!(s->schema = find_sql_schema(s->tr, 
s->schema_name))) {
                                mvc_cancel_session(m);
-                               throw(SQL, "sql.trans", SQLSTATE(42000) "The 
user's default schema was not found, this session is going to terminate");
+                               throw(SQL, "sql.trans", SQLSTATE(42000) "The 
session's schema was not found, this session is going to terminate");
                        }
                }
        }
diff --git a/sql/backends/monet5/sql_transaction.c 
b/sql/backends/monet5/sql_transaction.c
--- a/sql/backends/monet5/sql_transaction.c
+++ b/sql/backends/monet5/sql_transaction.c
@@ -100,7 +100,6 @@ SQLtransaction_begin(Client cntxt, MalBl
        str msg;
        int chain = *getArgReference_int(stk, pci, 1);
        str name = *getArgReference_str(stk, pci, 2);
-       int ret = 0;
 
        initcontext();
 
@@ -111,11 +110,16 @@ SQLtransaction_begin(Client cntxt, MalBl
        sql->session->auto_commit = 0;
        sql->session->ac_on_commit = 1;
        sql->session->level = chain;
-       ret = mvc_trans(sql);
-       if(msg)
+       if (msg)
                return msg;
-       else if(ret < 0)
-               throw(SQL, "sql.trans", SQLSTATE(HY013) MAL_MALLOC_FAIL);
+       switch (mvc_trans(sql)) {
+               case -1:
+                       throw(SQL, "sql.trans", SQLSTATE(HY013) 
MAL_MALLOC_FAIL);
+               case -3:
+                       throw(SQL, "sql.trans", SQLSTATE(42000) "The session's 
schema was not found, this transaction won't start");
+               default:
+                       break;
+       }
        return MAL_SUCCEED;
 }
 
@@ -124,7 +128,6 @@ SQLtransaction2(Client cntxt, MalBlkPtr 
 {
        mvc *sql = NULL;
        str msg;
-       int ret = 0;
 
        (void) stk;
        (void) pci;
@@ -140,10 +143,15 @@ SQLtransaction2(Client cntxt, MalBlkPtr 
        sql->session->auto_commit = 0;
        sql->session->ac_on_commit = 1;
        sql->session->level = 0;
-       ret = mvc_trans(sql);
-       if(msg)
+       if (msg)
                return msg;
-       else if(ret < 0)
-               throw(SQL, "sql.trans", SQLSTATE(HY013) MAL_MALLOC_FAIL);
+       switch (mvc_trans(sql)) {
+               case -1:
+                       throw(SQL, "sql.trans", SQLSTATE(HY013) 
MAL_MALLOC_FAIL);
+               case -3:
+                       throw(SQL, "sql.trans", SQLSTATE(42000) "The session's 
schema was not found, this transaction won't start");
+               default:
+                       break;
+       }
        return MAL_SUCCEED;
 }
diff --git a/sql/backends/monet5/sql_user.c b/sql/backends/monet5/sql_user.c
--- a/sql/backends/monet5/sql_user.c
+++ b/sql/backends/monet5/sql_user.c
@@ -618,9 +618,9 @@ monet5_user_set_def_schema(mvc *m, oid u
                return -2;
        }
 
-       if (mvc_trans(m) < 0) {
+       if ((res = mvc_trans(m)) < 0) {
                GDKfree(username);
-               return -1;
+               return res;
        }
 
        sys = find_sql_schema(m->session->tr, "sys");
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
@@ -447,25 +447,23 @@ mvc_cancel_session(mvc *m)
 int
 mvc_trans(mvc *m)
 {
-       int schema_changed = 0, err = m->session->status;
+       int res = 0, err = m->session->status;
        assert(!m->session->tr->active);        /* can only start a new 
transaction */
 
        TRC_INFO(SQL_TRANS, "Starting transaction\n");
-       schema_changed = sql_trans_begin(m->session);
-       if (m->qc && (schema_changed || err)){
-               if (schema_changed || err) {
-                       int seqnr = m->qc->id;
-                       if (m->qc)
-                               qc_destroy(m->qc);
-                       /* TODO Change into recreate all */
-                       m->qc = qc_create(m->pa, m->clientid, seqnr);
-                       if (!m->qc) {
+       res = sql_trans_begin(m->session);
+       if (m->qc && (res || err)) {
+               int seqnr = m->qc->id;
+               if (m->qc)
+                       qc_destroy(m->qc);
+               /* TODO Change into recreate all */
+               if (!(m->qc = qc_create(m->pa, m->clientid, seqnr))) {
+                       if (m->session->tr->active)
                                (void)sql_trans_end(m->session, SQL_ERR);
-                               return -1;
-                       }
+                       return -1;
                }
        }
-       return 0;
+       return res;
 }
 
 str
@@ -473,7 +471,7 @@ mvc_commit(mvc *m, int chain, const char
 {
        sql_trans *tr = m->session->tr;
        int ok = SQL_OK;
-       str msg = NULL, other;
+       str msg = MAL_SUCCEED, other;
        char operation[BUFSIZ];
 
        assert(tr);
@@ -567,8 +565,8 @@ mvc_commit(mvc *m, int chain, const char
        }
        */
        (void)sql_trans_end(m->session, ok);
-       if (chain)
-               sql_trans_begin(m->session);
+       if (chain && sql_trans_begin(m->session) < 0)
+               msg = 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;
        TRC_INFO(SQL_TRANS,
                "Commit done\n");
@@ -578,7 +576,7 @@ mvc_commit(mvc *m, int chain, const char
 str
 mvc_rollback(mvc *m, int chain, const char *name, bool disabling_auto_commit)
 {
-       str msg;
+       str msg = MAL_SUCCEED;
 
        TRC_DEBUG(SQL_TRANS, "Rollback: %s\n", (name) ? name : "");
        (void) disabling_auto_commit;
@@ -616,10 +614,11 @@ mvc_rollback(mvc *m, int chain, const ch
                if (tr->changes)
                        tr->status = 1;
                (void)sql_trans_end(m->session, SQL_ERR);
-               if (chain)
-                       sql_trans_begin(m->session);
+               if (chain && sql_trans_begin(m->session) < 0)
+                       msg = createException(SQL, "sql.rollback", 
SQLSTATE(40000) "ROLLBACK: finished sucessfuly, but the session's schema could 
not be found while starting the next transaction");
        }
-       msg = WLCrollback(m->clientid);
+       if (msg == MAL_SUCCEED)
+               msg = WLCrollback(m->clientid);
        if (msg != MAL_SUCCEED) {
                m->session->status = -1;
                return msg;
diff --git a/sql/storage/store.c b/sql/storage/store.c
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -6748,8 +6748,12 @@ sql_trans_begin(sql_session *s)
        store_lock(store);
        TRC_DEBUG(SQL_STORE, "Enter sql_trans_begin for transaction: " ULLFMT 
"\n", tr->tid);
        tr->ts = store_timestamp(store);
+       if (!(s->schema = find_sql_schema(tr, s->schema_name))) {
+               TRC_DEBUG(SQL_STORE, "Exit sql_trans_begin for transaction: " 
ULLFMT " with error, the schema %s was not found\n", tr->tid, s->schema_name);
+               store_unlock(store);
+               return -3;
+       }
        tr->active = 1;
-       s->schema = find_sql_schema(tr, s->schema_name);
        s->tr = tr;
 
        (void) ATOMIC_INC(&store->nr_active);
diff --git a/sql/test/Triggers/Tests/trigger_schema.test 
b/sql/test/Triggers/Tests/trigger_schema.test
--- a/sql/test/Triggers/Tests/trigger_schema.test
+++ b/sql/test/Triggers/Tests/trigger_schema.test
@@ -70,6 +70,9 @@ select * from foo.t2
 ----
 
 statement ok
+set schema sys
+
+statement ok
 ROLLBACK
 
 statement ok
diff --git a/sql/test/miscellaneous/Tests/transaction_isolation4.SQL.py 
b/sql/test/miscellaneous/Tests/transaction_isolation4.SQL.py
--- a/sql/test/miscellaneous/Tests/transaction_isolation4.SQL.py
+++ b/sql/test/miscellaneous/Tests/transaction_isolation4.SQL.py
@@ -143,5 +143,21 @@ with SQLTestCase() as mdb1:
         mdb1.execute('drop user duser3;').assertSucceeded()
         mdb1.execute('drop schema mys3;').assertSucceeded()
         mdb1.execute('commit;').assertSucceeded()
-        mdb2.execute('start transaction;').assertFailed(err_code="42000", 
err_message="The user was not found in the database, this session is going to 
terminate")
+        mdb2.execute('start transaction;').assertFailed(err_code="42000", 
err_message="The session's schema was not found, this transaction won't start")
         # mbd2 cannot do anything else, the connection was terminated
+
+with SQLTestCase() as mdb1:
+    with SQLTestCase() as mdb2:
+        mdb1.connect(username="monetdb", password="monetdb")
+        mdb1.execute('CREATE schema mys4;').assertSucceeded()
+        mdb1.execute("CREATE USER duser4 WITH PASSWORD 'ups' NAME 'ups' SCHEMA 
mys4;").assertSucceeded()
+        mdb2.connect(username="duser4", password="ups")
+
+        mdb2.execute('start transaction;').assertSucceeded()
+        mdb2.execute('select 1;').assertSucceeded()
+        mdb1.execute('start transaction;').assertSucceeded()
+        mdb1.execute('drop user duser4;').assertSucceeded()
+        mdb1.execute('drop schema mys4;').assertSucceeded()
+        mdb1.execute('commit;').assertSucceeded()
+        mdb2.execute('rollback and chain;').assertFailed() # error: ROLLBACK 
finished sucessfuly, but the session's schema could not be found while starting 
the next transaction
+        # mbd2 cannot do anything else, the connection was terminated
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to