Changeset: 1bbdf0111cba for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/1bbdf0111cba Modified Files: sql/server/rel_select.c sql/storage/store.c sql/test/SQLancer/Tests/sqlancer22.test Branch: default Log Message:
Merged with Jan2022 diffs (255 lines): diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c --- a/sql/server/rel_select.c +++ b/sql/server/rel_select.c @@ -2480,7 +2480,8 @@ rel_logical_value_exp(sql_query *query, return NULL; if (ek.card <= card_set && is_project(sq->op) && list_length(sq->exps) > 1) return sql_error(sql, 02, SQLSTATE(42000) "SELECT: subquery must return only one column"); - if (ek.card < card_set && sq->card >= CARD_AGGR && (is_sql_sel(f) | is_sql_having(f) | ( is_sql_where(f) && rel && (!*rel || is_basetable((*rel)->op) || is_simple_project((*rel)->op) || is_joinop((*rel)->op))))) + if (ek.card < card_set && sq->card >= CARD_AGGR && (is_sql_sel(f) | is_sql_having(f) | is_sql_farg(f) | + ( is_sql_where(f) && rel && (!*rel || is_basetable((*rel)->op) || is_simple_project((*rel)->op) || is_joinop((*rel)->op))))) sq = rel_zero_or_one(sql, sq, ek); return exp_rel(sql, sq); } 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 @@ -630,7 +630,7 @@ mvc_rollback(mvc *m, int chain, const ch if (name && name[0] != '\0') { while (tr && (!tr->name || strcmp(tr->name, name) != 0)) tr = tr->parent; - if (!tr) { + if (!tr || !tr->name || strcmp(tr->name, name) != 0) { msg = createException(SQL, "sql.rollback", SQLSTATE(42000) "ROLLBACK TO SAVEPOINT: no such savepoint: '%s'", name); m->session->status = -1; return msg; @@ -642,14 +642,15 @@ mvc_rollback(mvc *m, int chain, const ch tr->status = 1; tr = sql_trans_destroy(tr); } - m->session->tr = tr; /* restart at savepoint */ - m->session->status = tr->status; - if (tr->name) { - _DELETE(tr->name); - tr->name = NULL; + /* start a new transaction after rolling back */ + if (!(m->session->tr = tr = sql_trans_create(m->store, tr, name))) { + msg = createException(SQL, "sql.rollback", SQLSTATE(HY013) "ROLLBACK TO SAVEPOINT: allocation failure while restarting savepoint"); + m->session->status = -1; + return msg; } - if (!(m->session->schema = find_sql_schema(m->session->tr, m->session->schema_name))) { - msg = createException(SQL, "sql.rollback", SQLSTATE(40000) "ROLLBACK: finished successfully, but the session's schema could not be found on the current transaction"); + m->session->status = tr->parent->status; + if (!(m->session->schema = find_sql_schema(tr, m->session->schema_name))) { + msg = createException(SQL, "sql.rollback", SQLSTATE(40000) "ROLLBACK TO SAVEPOINT: finished successfully, but the session's schema could not be found on the current transaction"); m->session->status = -1; return msg; } @@ -691,12 +692,10 @@ mvc_rollback(mvc *m, int chain, const ch str mvc_release(mvc *m, const char *name) { - int ok = SQL_OK; sql_trans *tr = m->session->tr; str msg = MAL_SUCCEED; - assert(tr); - assert(m->session->tr->active); /* only release active transactions */ + assert(tr && tr->active); /* only release active transactions */ TRC_DEBUG(SQL_TRANS, "Release: %s\n", (name) ? name : ""); @@ -708,20 +707,20 @@ mvc_release(mvc *m, const char *name) while (tr && (!tr->name || strcmp(tr->name, name) != 0)) tr = tr->parent; if (!tr || !tr->name || strcmp(tr->name, name) != 0) { - msg = createException(SQL, "sql.release", SQLSTATE(42000) "Release savepoint %s doesn't exist", name); + msg = createException(SQL, "sql.release", SQLSTATE(42000) "RELEASE: no such savepoint: '%s'", name); m->session->status = -1; return msg; } tr = m->session->tr; - while (ok == SQL_OK && (!tr->name || strcmp(tr->name, name) != 0)) { + while (!tr->name || strcmp(tr->name, name) != 0) { /* commit all intermediate savepoints */ if (sql_trans_commit(tr) != SQL_OK) GDKfatal("release savepoints should not fail"); tr = sql_trans_destroy(tr); } - _DELETE(tr->name); - tr->name = NULL; + _DELETE(tr->name); /* name will no longer be used */ m->session->tr = tr; + m->session->status = tr->status; if (!(m->session->schema = find_sql_schema(m->session->tr, m->session->schema_name))) { msg = createException(SQL, "sql.release", SQLSTATE(40000) "RELEASE: finished successfully, but the session's schema could not be found on the current transaction"); m->session->status = -1; diff --git a/sql/storage/store.c b/sql/storage/store.c --- a/sql/storage/store.c +++ b/sql/storage/store.c @@ -3697,10 +3697,7 @@ sql_trans_destroy(sql_trans *tr) sql_trans *res = tr->parent; TRC_DEBUG(SQL_STORE, "Destroy transaction: %p\n", tr); - if (tr->name) { - _DELETE(tr->name); - tr->name = NULL; - } + _DELETE(tr->name); if (!list_empty(tr->changes)) sql_trans_rollback(tr, false); sqlstore *store = tr->store; @@ -3734,7 +3731,8 @@ sql_trans_create_(sqlstore *store, sql_t sql_trans_destroy(tr); return NULL; } - parent->name = SA_STRDUP(parent->sa, name); + _DELETE(parent->name); + parent->name = _STRDUP(name); } store_lock(store); @@ -7007,9 +7005,9 @@ sql_trans_begin(sql_session *s) (void) ATOMIC_INC(&store->nr_active); list_append(store->active, s); - s->status = 0; TRC_DEBUG(SQL_STORE, "Exit sql_trans_begin for transaction: " ULLFMT "\n", tr->tid); store_unlock(store); + s->status = tr->status = 0; return 0; } @@ -7024,6 +7022,7 @@ sql_trans_end(sql_session *s, int ok) } assert(s->tr->active); s->tr->active = 0; + s->tr->status = 0; s->auto_commit = s->ac_on_commit; sqlstore *store = s->tr->store; store_lock(store); diff --git a/sql/test/SQLancer/Tests/sqlancer22.test b/sql/test/SQLancer/Tests/sqlancer22.test --- a/sql/test/SQLancer/Tests/sqlancer22.test +++ b/sql/test/SQLancer/Tests/sqlancer22.test @@ -80,18 +80,6 @@ select 1 from mct20 inner join (select x on true and greatest(((select nort0.norc0) intersect (select true)), true) ---- -statement error GDK reported error: BATsubcross: more than one match -select 1 from mct20 inner join (select x.x from (values (true)) x(x)) as nort0(norc0) -on true and greatest(((select nort0.norc0) union all (select true)), true) - -statement error GDK reported error: BATsubcross: more than one match -select 1 from mct20 inner join (select x.x from (values (true)) x(x)) as nort0(norc0) -on ((select nort0.norc0) union all (select true)) - -statement error GDK reported error: BATsubcross: more than one match -select 1 from mct20 inner join (select x.x from (values (true)) x(x)) as nort0(norc0) -on true where ((select nort0.norc0) union all (select true)) - # these are right query I nosort select rank() over (order by ((select mct20.c0) union all (select interval '1' day))) from mct20 @@ -112,6 +100,21 @@ select max(((select mct20.c0) union all statement ok rowcount 1 INSERT INTO mct20 VALUES (INTERVAL '1' DAY, DATE '2010-01-01') +statement error GDK reported error: BATsubcross: more than one match +select 1 from mct20 where ((select true) union all (select true)) + +statement error GDK reported error: mergejoin: more than one match +select 1 from mct20 inner join (select x.x from (values (true)) x(x)) as nort0(norc0) +on true and greatest(((select nort0.norc0) union all (select true)), true) + +statement error GDK reported error: mergejoin: more than one match +select 1 from mct20 inner join (select x.x from (values (true)) x(x)) as nort0(norc0) +on ((select nort0.norc0) union all (select true)) + +statement error GDK reported error: mergejoin: more than one match +select 1 from mct20 inner join (select x.x from (values (true)) x(x)) as nort0(norc0) +on true where ((select nort0.norc0) union all (select true)) + statement error GDK reported error: mergejoin: more than one match select rank() over (order by ((select mct20.c0) union all (select interval '1' day))) from mct20 ---- diff --git a/sql/test/Tests/savepoints2.test b/sql/test/Tests/savepoints2.test --- a/sql/test/Tests/savepoints2.test +++ b/sql/test/Tests/savepoints2.test @@ -81,3 +81,64 @@ select * from savepointtest statement error commit +statement ok +start transaction + +statement ok +create table x(x int) + +statement ok rowcount 1 +insert into x values (1) + +query I rowsort +SELECT x FROM x +---- +1 + +statement ok +savepoint sp1 + +statement ok rowcount 1 +insert into x values (2) + +query I rowsort +SELECT x FROM x +---- +1 +2 + +# give one error +statement error +ups + +statement ok +rollback to savepoint sp1 + +query I rowsort +SELECT x FROM x +---- +1 + +statement ok rowcount 1 +insert into x values (3) + +query I rowsort +SELECT x FROM x +---- +1 +3 + +# give another error +statement error +mistake + +statement ok +rollback to savepoint sp1 + +query I rowsort +SELECT x FROM x +---- +1 + +statement ok +rollback diff --git a/sql/test/transactions/Tests/transaction_isolation5.SQL.py b/sql/test/transactions/Tests/transaction_isolation5.SQL.py --- a/sql/test/transactions/Tests/transaction_isolation5.SQL.py +++ b/sql/test/transactions/Tests/transaction_isolation5.SQL.py @@ -6,7 +6,7 @@ with SQLTestCase() as mdb1: 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 successfully, but the session's schema could not be found on the current transaction") + mdb1.execute('ROLLBACK TO SAVEPOINT mys;').assertFailed(err_code="40000", err_message="ROLLBACK TO SAVEPOINT: finished successfully, but the session's schema could not be found on the current transaction") mdb1.execute('rollback;').assertFailed() with SQLTestCase() as mdb1: _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list