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