[tarantool-patches] [PATCH 3/4] sql: allow SAVEPOINT statement outside transaction

Nikita Pettik korablev at tarantool.org
Thu May 3 21:49:24 MSK 2018


Before this patch, usage of SAVEPOINT statement outside transaction or
inside transaction started in Lua, led to assertion fault.
Now, failed assert is substituted with checks to test transaction status.

Closes #3313
---
 src/box/sql/vdbe.c                               |  8 +++++-
 test/sql/gh-3313-savepoints-outside-txn.result   | 32 ++++++++++++++++++++++++
 test/sql/gh-3313-savepoints-outside-txn.test.lua | 18 +++++++++++++
 3 files changed, 57 insertions(+), 1 deletion(-)
 create mode 100644 test/sql/gh-3313-savepoints-outside-txn.result
 create mode 100644 test/sql/gh-3313-savepoints-outside-txn.test.lua

diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index 1192fc399..6ea04901c 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -2867,7 +2867,13 @@ case OP_Savepoint: {
 	Savepoint *pTmp;
 	struct sql_txn *psql_txn = p->psql_txn;
 
-	assert(psql_txn);
+	if (psql_txn == NULL) {
+		assert(!box_txn());
+		sqlite3VdbeError(p, "cannot process savepoint: "
+				    "there is no active transaction");
+		rc = SQLITE_ERROR;
+		goto abort_due_to_error;
+	}
 	p1 = pOp->p1;
 	zName = pOp->p4.z;
 
diff --git a/test/sql/gh-3313-savepoints-outside-txn.result b/test/sql/gh-3313-savepoints-outside-txn.result
new file mode 100644
index 000000000..702d3e815
--- /dev/null
+++ b/test/sql/gh-3313-savepoints-outside-txn.result
@@ -0,0 +1,32 @@
+test_run = require('test_run').new()
+---
+...
+test_run:cmd("setopt delimiter ';'") 
+---
+- true
+...
+-- These tests check that SQL savepoints properly work outside
+-- transactions as well as inside transactions started in Lua.
+--
+-- box.cfg()
+box.sql.execute('SAVEPOINT t1;');
+---
+- error: 'cannot process savepoint: there is no active transaction'
+...
+box.sql.execute('RELEASE SAVEPOINT t1;');
+---
+- error: 'cannot process savepoint: there is no active transaction'
+...
+box.sql.execute('ROLLBACK TO SAVEPOINT t1;');
+---
+- error: 'cannot process savepoint: there is no active transaction'
+...
+box.begin() box.sql.execute('SAVEPOINT t1;') box.sql.execute('RELEASE SAVEPOINT t1;') box.commit();
+---
+...
+box.begin() box.sql.execute('SAVEPOINT t1;') box.sql.execute('ROLLBACK TO t1;') box.commit();
+---
+...
+box.begin() box.sql.execute('SAVEPOINT t1;') box.commit();
+---
+...
diff --git a/test/sql/gh-3313-savepoints-outside-txn.test.lua b/test/sql/gh-3313-savepoints-outside-txn.test.lua
new file mode 100644
index 000000000..61dd9a86b
--- /dev/null
+++ b/test/sql/gh-3313-savepoints-outside-txn.test.lua
@@ -0,0 +1,18 @@
+test_run = require('test_run').new()
+test_run:cmd("setopt delimiter ';'") 
+
+-- These tests check that SQL savepoints properly work outside
+-- transactions as well as inside transactions started in Lua.
+--
+
+-- box.cfg()
+
+box.sql.execute('SAVEPOINT t1;');
+box.sql.execute('RELEASE SAVEPOINT t1;');
+box.sql.execute('ROLLBACK TO SAVEPOINT t1;');
+
+box.begin() box.sql.execute('SAVEPOINT t1;') box.sql.execute('RELEASE SAVEPOINT t1;') box.commit();
+
+box.begin() box.sql.execute('SAVEPOINT t1;') box.sql.execute('ROLLBACK TO t1;') box.commit();
+
+box.begin() box.sql.execute('SAVEPOINT t1;') box.commit();
-- 
2.15.1





More information about the Tarantool-patches mailing list