* [tarantool-patches] [PATCH v1 01/12] sql: remove errors SQL_TARANTOOL_*_FAIL
2019-05-05 12:17 [tarantool-patches] [PATCH v1 00/12] sql: set errors in VDBE using diag_set() imeevma
@ 2019-05-05 12:17 ` imeevma
2019-05-15 13:18 ` [tarantool-patches] " n.pettik
2019-05-05 12:17 ` [tarantool-patches] [PATCH v1 02/12] sql: remove error ER_SQL imeevma
` (10 subsequent siblings)
11 siblings, 1 reply; 31+ messages in thread
From: imeevma @ 2019-05-05 12:17 UTC (permalink / raw)
To: korablev; +Cc: tarantool-patches
Errors SQL_TARANTOOL_DELETE_FAIL, SQL_TARANTOOL_ITERATOR_FAIL and
SQL_TARANTOOL_INSERT_FAIL have almost no functionality, but can
lead to incorrect behavior. This patch replaces them with
SQL_TARANTOOL_ERROR. It will simplify work with the errors.
---
src/box/sql.c | 37 ++++++++--------------
src/box/sql/main.c | 3 --
src/box/sql/sqlInt.h | 3 --
src/box/sql/tarantoolInt.h | 5 +--
src/box/sql/vdbe.c | 2 +-
test/sql-tap/autoinc.test.lua | 2 +-
test/sql-tap/gh-2931-savepoints.test.lua | 4 +--
.../gh-3307-xfer-optimization-issue.test.lua | 10 +++---
test/sql-tap/gh2259-in-stmt-trans.test.lua | 8 ++---
test/sql-tap/gh2964-abort.test.lua | 2 +-
test/sql-tap/intpkey.test.lua | 2 +-
test/sql-tap/misc1.test.lua | 2 +-
test/sql-tap/table.test.lua | 8 ++---
test/sql-tap/tkt-4a03edc4c8.test.lua | 2 +-
test/sql-tap/trigger1.test.lua | 6 ++--
test/sql-tap/unique.test.lua | 10 +++---
test/sql/collation.result | 18 ++++-------
test/sql/errinj.result | 6 ++--
test/sql/foreign-keys.result | 3 +-
test/sql/insert-unique.result | 6 ++--
test/sql/iproto.result | 3 +-
test/sql/persistency.result | 6 ++--
test/sql/transition.result | 6 ++--
test/sql/triggers.result | 2 +-
24 files changed, 62 insertions(+), 94 deletions(-)
diff --git a/src/box/sql.c b/src/box/sql.c
index 1fb93e1..3593242 100644
--- a/src/box/sql.c
+++ b/src/box/sql.c
@@ -162,15 +162,6 @@ const char *tarantoolErrorMessage()
return box_error_message(box_error_last());
}
-int
-is_tarantool_error(int rc)
-{
- return (rc == SQL_TARANTOOL_ERROR ||
- rc == SQL_TARANTOOL_ITERATOR_FAIL ||
- rc == SQL_TARANTOOL_DELETE_FAIL ||
- rc == SQL_TARANTOOL_INSERT_FAIL);
-}
-
const void *tarantoolsqlPayloadFetch(BtCursor *pCur, u32 *pAmt)
{
assert(pCur->curFlags & BTCF_TaCursor ||
@@ -421,7 +412,7 @@ int tarantoolsqlEphemeralInsert(struct space *space, const char *tuple,
assert(space != NULL);
mp_tuple_assert(tuple, tuple_end);
if (space_ephemeral_replace(space, tuple, tuple_end) != 0)
- return SQL_TARANTOOL_INSERT_FAIL;
+ return SQL_TARANTOOL_ERROR;
return SQL_OK;
}
@@ -448,7 +439,7 @@ insertOrReplace(struct space *space, const char *tuple, const char *tuple_end,
request.type = type;
mp_tuple_assert(request.tuple, request.tuple_end);
int rc = box_process_rw(&request, space, NULL);
- return rc == 0 ? SQL_OK : SQL_TARANTOOL_INSERT_FAIL;
+ return rc == 0 ? SQL_OK : SQL_TARANTOOL_ERROR;
}
int tarantoolsqlInsert(struct space *space, const char *tuple,
@@ -483,12 +474,12 @@ int tarantoolsqlEphemeralDelete(BtCursor *pCur)
pCur->iter->index->def->key_def,
&key_size);
if (key == NULL)
- return SQL_TARANTOOL_DELETE_FAIL;
+ return SQL_TARANTOOL_ERROR;
int rc = space_ephemeral_delete(pCur->space, key);
if (rc != 0) {
diag_log();
- return SQL_TARANTOOL_DELETE_FAIL;
+ return SQL_TARANTOOL_ERROR;
}
return SQL_OK;
}
@@ -509,11 +500,11 @@ int tarantoolsqlDelete(BtCursor *pCur, u8 flags)
pCur->iter->index->def->key_def,
&key_size);
if (key == NULL)
- return SQL_TARANTOOL_DELETE_FAIL;
+ return SQL_TARANTOOL_ERROR;
rc = sql_delete_by_key(pCur->space, pCur->index->def->iid, key,
key_size);
- return rc == 0 ? SQL_OK : SQL_TARANTOOL_DELETE_FAIL;
+ return rc == 0 ? SQL_OK : SQL_TARANTOOL_ERROR;
}
int
@@ -531,7 +522,7 @@ sql_delete_by_key(struct space *space, uint32_t iid, char *key,
assert(space_index(space, iid)->def->opts.is_unique);
int rc = box_process_rw(&request, space, &unused);
- return rc == 0 ? SQL_OK : SQL_TARANTOOL_DELETE_FAIL;
+ return rc == 0 ? SQL_OK : SQL_TARANTOOL_ERROR;
}
/*
@@ -553,7 +544,7 @@ int tarantoolsqlEphemeralClearTable(BtCursor *pCur)
0 /* part_count */);
if (it == NULL) {
pCur->eState = CURSOR_INVALID;
- return SQL_TARANTOOL_ITERATOR_FAIL;
+ return SQL_TARANTOOL_ERROR;
}
struct tuple *tuple;
@@ -565,7 +556,7 @@ int tarantoolsqlEphemeralClearTable(BtCursor *pCur)
&key_size);
if (space_ephemeral_delete(pCur->space, key) != 0) {
iterator_delete(it);
- return SQL_TARANTOOL_DELETE_FAIL;
+ return SQL_TARANTOOL_ERROR;
}
}
iterator_delete(it);
@@ -592,7 +583,7 @@ int tarantoolsqlClearTable(struct space *space, uint32_t *tuple_count)
struct index *pk = space_index(space, 0 /* PK */);
struct iterator *iter = index_create_iterator(pk, ITER_ALL, nil_key, 0);
if (iter == NULL)
- return SQL_TARANTOOL_ITERATOR_FAIL;
+ return SQL_TARANTOOL_ERROR;
while (iterator_next(iter, &tuple) == 0 && tuple != NULL) {
request.key = tuple_extract_key(tuple, pk->def->key_def,
&key_size);
@@ -600,7 +591,7 @@ int tarantoolsqlClearTable(struct space *space, uint32_t *tuple_count)
rc = box_process_rw(&request, space, &unused);
if (rc != 0) {
iterator_delete(iter);
- return SQL_TARANTOOL_DELETE_FAIL;
+ return SQL_TARANTOOL_ERROR;
}
(*tuple_count)++;
}
@@ -899,7 +890,7 @@ cursor_seek(BtCursor *pCur, int *pRes)
uint32_t part_count = mp_decode_array(&key);
if (key_validate(pCur->index->def, pCur->iter_type, key, part_count)) {
diag_log();
- return SQL_TARANTOOL_ITERATOR_FAIL;
+ return SQL_TARANTOOL_ERROR;
}
struct space *space = pCur->space;
@@ -913,7 +904,7 @@ cursor_seek(BtCursor *pCur, int *pRes)
if (txn != NULL)
txn_rollback_stmt();
pCur->eState = CURSOR_INVALID;
- return SQL_TARANTOOL_ITERATOR_FAIL;
+ return SQL_TARANTOOL_ERROR;
}
if (txn != NULL)
txn_commit_ro_stmt(txn);
@@ -940,7 +931,7 @@ cursor_advance(BtCursor *pCur, int *pRes)
struct tuple *tuple;
if (iterator_next(pCur->iter, &tuple) != 0)
- return SQL_TARANTOOL_ITERATOR_FAIL;
+ return SQL_TARANTOOL_ERROR;
if (pCur->last_tuple)
box_tuple_unref(pCur->last_tuple);
if (tuple) {
diff --git a/src/box/sql/main.c b/src/box/sql/main.c
index fe1135a..ed07553 100644
--- a/src/box/sql/main.c
+++ b/src/box/sql/main.c
@@ -383,9 +383,6 @@ sqlErrStr(int rc)
/* SQL_MISUSE */
"library routine called out of sequence",
/* SQL_RANGE */ "bind or column index out of range",
- /* SQL_TARANTOOL_ITERATOR_FAIL */ "Tarantool's iterator failed",
- /* SQL_TARANTOOL_INSERT_FAIL */ "Tarantool's insert failed",
- /* SQL_TARANTOOL_DELETE_FAIL */ "Tarantool's delete failed",
/* SQL_TARANTOOL_ERROR */ "SQL-/Tarantool error",
};
const char *zErr = "unknown error";
diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
index e59b57f..05a4042 100644
--- a/src/box/sql/sqlInt.h
+++ b/src/box/sql/sqlInt.h
@@ -392,9 +392,6 @@ enum sql_ret_code {
SQL_MISUSE,
/** 2nd parameter to sql_bind out of range. */
SQL_RANGE,
- SQL_TARANTOOL_ITERATOR_FAIL,
- SQL_TARANTOOL_INSERT_FAIL,
- SQL_TARANTOOL_DELETE_FAIL,
SQL_TARANTOOL_ERROR,
/** Warnings from sql_log(). */
SQL_WARNING,
diff --git a/src/box/sql/tarantoolInt.h b/src/box/sql/tarantoolInt.h
index 2b04d96..f15e147 100644
--- a/src/box/sql/tarantoolInt.h
+++ b/src/box/sql/tarantoolInt.h
@@ -13,8 +13,6 @@ struct fk_constraint_def;
/* Misc */
const char *tarantoolErrorMessage();
-int is_tarantool_error(int rc);
-
/* Storage interface. */
const void *tarantoolsqlPayloadFetch(BtCursor * pCur, u32 * pAmt);
@@ -51,8 +49,7 @@ int tarantoolsqlDelete(BtCursor * pCur, u8 flags);
* @param key Key of record to be deleted.
* @param key_size Size of key.
*
- * @retval SQL_OK on success, SQL_TARANTOOL_DELETE_FAIL
- * otherwise.
+ * @retval SQL_OK on success, SQL_TARANTOOL_ERROR otherwise.
*/
int
sql_delete_by_key(struct space *space, uint32_t iid, char *key,
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index 3bd8223..5222a4e 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -5469,7 +5469,7 @@ abort_due_to_error:
/* Avoiding situation when Tarantool error is set,
* but error message isn't.
*/
- if (is_tarantool_error(rc) && tarantoolErrorMessage()) {
+ if (rc == SQL_TARANTOOL_ERROR && tarantoolErrorMessage()) {
msg = tarantoolErrorMessage();
} else {
msg = sqlErrStr(rc);
diff --git a/test/sql-tap/autoinc.test.lua b/test/sql-tap/autoinc.test.lua
index 4db2783..257621b 100755
--- a/test/sql-tap/autoinc.test.lua
+++ b/test/sql-tap/autoinc.test.lua
@@ -531,7 +531,7 @@ test:do_catchsql_test(
INSERT INTO t6 VALUES(NULL,1);
]], {
-- <autoinc-6.2>
- 1, "Failed to execute SQL statement: Sequence 'T6' has overflowed"
+ 1, "Sequence 'T6' has overflowed"
-- </autoinc-6.2>
})
diff --git a/test/sql-tap/gh-2931-savepoints.test.lua b/test/sql-tap/gh-2931-savepoints.test.lua
index 5c0daef..6123fc4 100755
--- a/test/sql-tap/gh-2931-savepoints.test.lua
+++ b/test/sql-tap/gh-2931-savepoints.test.lua
@@ -81,13 +81,13 @@ local testcases = {
{0,{1,2,10,11,1,2,4,10,11}}},
{"14",
[[insert into t1 values(4);]],
- {1,"Failed to execute SQL statement: Duplicate key exists in unique index 'pk_unnamed_T2_1' in space 'T2'"}},
+ {1,"Duplicate key exists in unique index 'pk_unnamed_T2_1' in space 'T2'"}},
{"15",
[[select * from t1 union all select * from t2;]],
{0,{1,2,10,11,1,2,4,10,11}}},
{"16",
[[insert or rollback into t1 values(4);]],
- {1,"Failed to execute SQL statement: Duplicate key exists in unique index 'pk_unnamed_T2_1' in space 'T2'"}},
+ {1,"Duplicate key exists in unique index 'pk_unnamed_T2_1' in space 'T2'"}},
{"17", -- should work as transaction is rolled back
[[insert or rollback into t1 values(4);
select * from t1 union all select * from t2;]],
diff --git a/test/sql-tap/gh-3307-xfer-optimization-issue.test.lua b/test/sql-tap/gh-3307-xfer-optimization-issue.test.lua
index 859a6ff..bb8a498 100755
--- a/test/sql-tap/gh-3307-xfer-optimization-issue.test.lua
+++ b/test/sql-tap/gh-3307-xfer-optimization-issue.test.lua
@@ -139,7 +139,7 @@ test:do_catchsql_xfer_test(
INSERT INTO t2 SELECT * FROM t1;
]], {
-- <xfer-optimization-1.9>
- 1, "Failed to execute SQL statement: Duplicate key exists in unique index 'pk_unnamed_T2_1' in space 'T2'"
+ 1, "Duplicate key exists in unique index 'pk_unnamed_T2_1' in space 'T2'"
-- <xfer-optimization-1.9>
}, {
exp_xfer_count = 0
@@ -210,7 +210,7 @@ test:do_catchsql_xfer_test(
INSERT INTO t2 SELECT * FROM t1;
]], {
-- <xfer-optimization-1.13>
- 1, "Failed to execute SQL statement: Duplicate key exists in unique index 'pk_unnamed_T2_1' in space 'T2'"
+ 1, "Duplicate key exists in unique index 'pk_unnamed_T2_1' in space 'T2'"
-- <xfer-optimization-1.13>
}, {
exp_xfer_count = 0
@@ -245,7 +245,7 @@ test:do_catchsql_xfer_test(
INSERT OR ABORT INTO t2 SELECT * FROM t1;
]], {
-- <xfer-optimization-1.20>
- 1, "Failed to execute SQL statement: Duplicate key exists in unique index 'pk_unnamed_T2_1' in space 'T2'"
+ 1, "Duplicate key exists in unique index 'pk_unnamed_T2_1' in space 'T2'"
-- <xfer-optimization-1.20>
}, {
exp_xfer_count = 1
@@ -313,7 +313,7 @@ test:do_catchsql_xfer_test(
INSERT OR ROLLBACK INTO t2 SELECT * FROM t1;
]], {
-- <xfer-optimization-1.24>
- 1, "Failed to execute SQL statement: Duplicate key exists in unique index 'pk_unnamed_T2_1' in space 'T2'"
+ 1, "Duplicate key exists in unique index 'pk_unnamed_T2_1' in space 'T2'"
-- <xfer-optimization-1.24>
}, {
exp_xfer_count = 0
@@ -381,7 +381,7 @@ test:do_catchsql_xfer_test(
INSERT OR FAIL INTO t2 SELECT * FROM t1;
]], {
-- <xfer-optimization-1.28>
- 1, "Failed to execute SQL statement: Duplicate key exists in unique index 'pk_unnamed_T2_1' in space 'T2'"
+ 1, "Duplicate key exists in unique index 'pk_unnamed_T2_1' in space 'T2'"
-- <xfer-optimization-1.28>
}, {
exp_xfer_count = 1
diff --git a/test/sql-tap/gh2259-in-stmt-trans.test.lua b/test/sql-tap/gh2259-in-stmt-trans.test.lua
index 36f5e90..6bd0550 100755
--- a/test/sql-tap/gh2259-in-stmt-trans.test.lua
+++ b/test/sql-tap/gh2259-in-stmt-trans.test.lua
@@ -18,7 +18,7 @@ for _, prefix in pairs({"BEFORE", "AFTER"}) do
test:do_catchsql_test(prefix..'_insert1',
'INSERT INTO t1 VALUES(1, 2)',
- {1,"Failed to execute SQL statement: Duplicate key exists in unique index 'pk_unnamed_T2_2' in space 'T2'"})
+ {1,"Duplicate key exists in unique index 'pk_unnamed_T2_2' in space 'T2'"})
test:do_execsql_test(prefix..'_insert1_check1',
'SELECT * FROM t1',
@@ -34,7 +34,7 @@ for _, prefix in pairs({"BEFORE", "AFTER"}) do
test:do_catchsql_test(prefix..'_update1',
'UPDATE t1 SET s1=1',
- {1,"Failed to execute SQL statement: Duplicate key exists in unique index 'pk_unnamed_T2_2' in space 'T2'"})
+ {1,"Duplicate key exists in unique index 'pk_unnamed_T2_2' in space 'T2'"})
test:do_execsql_test(prefix..'_update1_check1',
'SELECT * FROM t1',
@@ -52,7 +52,7 @@ for _, prefix in pairs({"BEFORE", "AFTER"}) do
test:do_catchsql_test(prefix..'delete1',
'DELETE FROM t1;',
- {1, "Failed to execute SQL statement: Duplicate key exists in unique index 'pk_unnamed_T2_2' in space 'T2'"})
+ {1, "Duplicate key exists in unique index 'pk_unnamed_T2_2' in space 'T2'"})
-- Nothing should be inserted due to abort
test:do_execsql_test('delete1_check1',
@@ -69,7 +69,7 @@ end
-- Check multi-insert
test:do_catchsql_test('insert2',
'INSERT INTO t1 VALUES (5, 6), (6, 7)',
- {1, "Failed to execute SQL statement: Duplicate key exists in unique index 'pk_unnamed_T2_2' in space 'T2'"})
+ {1, "Duplicate key exists in unique index 'pk_unnamed_T2_2' in space 'T2'"})
test:do_execsql_test('insert2_check',
'SELECT * FROM t1;',
{3, 3})
diff --git a/test/sql-tap/gh2964-abort.test.lua b/test/sql-tap/gh2964-abort.test.lua
index db9a111..3bce569 100755
--- a/test/sql-tap/gh2964-abort.test.lua
+++ b/test/sql-tap/gh2964-abort.test.lua
@@ -12,7 +12,7 @@ test:do_catchsql_test(
test_prefix.."1.0.2",
"CREATE TABLE t2 (a int primary key);")
-local insert_err = {1, "Failed to execute SQL statement: Duplicate key exists in unique index 'pk_unnamed_T2_1' in space 'T2'"}
+local insert_err = {1, "Duplicate key exists in unique index 'pk_unnamed_T2_1' in space 'T2'"}
local data = {
--id|TRIG TYPE|INSERT TYPE|insert error|commit error| result
{1, "AFTER", "or abort", insert_err, {0}, {1,1,2}},
diff --git a/test/sql-tap/intpkey.test.lua b/test/sql-tap/intpkey.test.lua
index b2e8084..bec2670 100755
--- a/test/sql-tap/intpkey.test.lua
+++ b/test/sql-tap/intpkey.test.lua
@@ -96,7 +96,7 @@ test:do_catchsql_test(
INSERT INTO t1 VALUES(5,'second','entry');
]], {
-- <intpkey-1.6>
- 1, "Failed to execute SQL statement: Duplicate key exists in unique index 'pk_unnamed_T1_1' in space 'T1'"
+ 1, "Duplicate key exists in unique index 'pk_unnamed_T1_1' in space 'T1'"
-- </intpkey-1.6>
})
diff --git a/test/sql-tap/misc1.test.lua b/test/sql-tap/misc1.test.lua
index cd0e103..dbc0699 100755
--- a/test/sql-tap/misc1.test.lua
+++ b/test/sql-tap/misc1.test.lua
@@ -383,7 +383,7 @@ test:do_catchsql_test(
INSERT INTO t5 VALUES(1,2,4);
]], {
-- <misc1-7.4>
- 1, "Failed to execute SQL statement: Duplicate key exists in unique index 'pk_unnamed_T5_1' in space 'T5'"
+ 1, "Duplicate key exists in unique index 'pk_unnamed_T5_1' in space 'T5'"
-- </misc1-7.4>
})
diff --git a/test/sql-tap/table.test.lua b/test/sql-tap/table.test.lua
index 5b793c0..04fd175 100755
--- a/test/sql-tap/table.test.lua
+++ b/test/sql-tap/table.test.lua
@@ -1211,7 +1211,7 @@ test:do_catchsql_test(
INSERT INTO T21 VALUES(1, 2, 2);
]], {
-- <table-21.2>
- 1, "Failed to execute SQL statement: Duplicate key exists in unique index 'pk_unnamed_T21_1' in space 'T21'"
+ 1, "Duplicate key exists in unique index 'pk_unnamed_T21_1' in space 'T21'"
-- </table-21.2>
})
@@ -1283,7 +1283,7 @@ test:do_catchsql_test(
INSERT INTO T22 VALUES(2, 1, 1);
]], {
-- <table-22.3>
- 1,"Failed to execute SQL statement: Duplicate key exists in unique index 'unique_ONE_2' in space 'T22'"
+ 1,"Duplicate key exists in unique index 'unique_ONE_2' in space 'T22'"
-- </table-22.3>
})
@@ -1308,7 +1308,7 @@ test:do_catchsql_test(
INSERT INTO T24 VALUES(2, 1, 1);
]], {
-- <table-22.5>
- 1, "Failed to execute SQL statement: Duplicate key exists in unique index 'unique_TWO_2' in space 'T24'"
+ 1, "Duplicate key exists in unique index 'unique_TWO_2' in space 'T24'"
-- </table-22.5>
})
@@ -1362,7 +1362,7 @@ test:do_catchsql_test(
INSERT INTO T28 VALUES(11);
]], {
-- <table-22.9>
- 1,"Failed to execute SQL statement: Duplicate key exists in unique index 'pk_unnamed_T28_1' in space 'T28'"
+ 1,"Duplicate key exists in unique index 'pk_unnamed_T28_1' in space 'T28'"
-- </table-22.9>
})
diff --git a/test/sql-tap/tkt-4a03edc4c8.test.lua b/test/sql-tap/tkt-4a03edc4c8.test.lua
index 0f44d4f..cb7a982 100755
--- a/test/sql-tap/tkt-4a03edc4c8.test.lua
+++ b/test/sql-tap/tkt-4a03edc4c8.test.lua
@@ -38,7 +38,7 @@ test:do_test(
]]
end, {
-- <tkt-4a03ed-1.1>
- 1, "Failed to execute SQL statement: Duplicate key exists in unique index 'pk_unnamed_T1_1' in space 'T1'"
+ 1, "Duplicate key exists in unique index 'pk_unnamed_T1_1' in space 'T1'"
-- </tkt-4a03ed-1.1>
})
diff --git a/test/sql-tap/trigger1.test.lua b/test/sql-tap/trigger1.test.lua
index dfc2822..64763fa 100755
--- a/test/sql-tap/trigger1.test.lua
+++ b/test/sql-tap/trigger1.test.lua
@@ -260,7 +260,7 @@ test:do_catchsql_test(
end;
]], {
-- <trigger1-1.12>
- 1, "Failed to execute SQL statement: SQL error: cannot create INSTEAD OF trigger on space: T1"
+ 1, "SQL error: cannot create INSTEAD OF trigger on space: T1"
-- </trigger1-1.12>
})
@@ -274,7 +274,7 @@ test:do_catchsql_test(
end;
]], {
-- <trigger1-1.13>
- 1, "Failed to execute SQL statement: SQL error: cannot create BEFORE trigger on view: V1"
+ 1, "SQL error: cannot create BEFORE trigger on view: V1"
-- </trigger1-1.13>
})
@@ -289,7 +289,7 @@ test:do_catchsql_test(
end;
]], {
-- <trigger1-1.14>
- 1, "Failed to execute SQL statement: SQL error: cannot create AFTER trigger on view: V1"
+ 1, "SQL error: cannot create AFTER trigger on view: V1"
-- </trigger1-1.14>
})
diff --git a/test/sql-tap/unique.test.lua b/test/sql-tap/unique.test.lua
index a9add83..fbd73a6 100755
--- a/test/sql-tap/unique.test.lua
+++ b/test/sql-tap/unique.test.lua
@@ -70,7 +70,7 @@ test:do_catchsql_test(
INSERT INTO t1(a,b,c) VALUES(1,3,4)
]], {
-- <unique-1.3>
- 1, "Failed to execute SQL statement: Duplicate key exists in unique index 'pk_unnamed_T1_1' in space 'T1'"
+ 1, "Duplicate key exists in unique index 'pk_unnamed_T1_1' in space 'T1'"
-- </unique-1.3>
})
@@ -91,7 +91,7 @@ test:do_catchsql_test(
INSERT INTO t1(a,b,c) VALUES(3,2,4)
]], {
-- <unique-1.5>
- 1, "Failed to execute SQL statement: Duplicate key exists in unique index 'unique_unnamed_T1_2' in space 'T1'"
+ 1, "Duplicate key exists in unique index 'unique_unnamed_T1_2' in space 'T1'"
-- </unique-1.5>
})
@@ -167,7 +167,7 @@ test:do_catchsql_test(
INSERT INTO t2 VALUES(3, 1,5);
]], {
-- <unique-2.3>
- 1, "Failed to execute SQL statement: Duplicate key exists in unique index 'I2' in space 'T2'"
+ 1, "Duplicate key exists in unique index 'I2' in space 'T2'"
-- </unique-2.3>
})
@@ -287,7 +287,7 @@ test:do_catchsql_test(
SELECT a,b,c,d FROM t3 ORDER BY a,b,c,d;
]], {
-- <unique-3.4>
- 1, "Failed to execute SQL statement: Duplicate key exists in unique index 'unique_unnamed_T3_2' in space 'T3'"
+ 1, "Duplicate key exists in unique index 'unique_unnamed_T3_2' in space 'T3'"
-- </unique-3.4>
})
@@ -444,7 +444,7 @@ test:do_catchsql_test(
INSERT INTO t5 VALUES(2, 1,2,3,4,5,6);
]], {
-- <unique-5.2>
- 1, "Failed to execute SQL statement: Duplicate key exists in unique index 'unique_unnamed_T5_2' in space 'T5'"
+ 1, "Duplicate key exists in unique index 'unique_unnamed_T5_2' in space 'T5'"
-- </unique-5.2>
})
diff --git a/test/sql/collation.result b/test/sql/collation.result
index 6f14d1e..5a931b8 100644
--- a/test/sql/collation.result
+++ b/test/sql/collation.result
@@ -676,8 +676,7 @@ box.execute("INSERT INTO t3b VALUES ('A');")
...
box.execute("INSERT INTO t3b VALUES ('a');")
---
-- error: 'Failed to execute SQL statement: Duplicate key exists in unique index ''pk_unnamed_T3B_1''
- in space ''T3B'''
+- error: Duplicate key exists in unique index 'pk_unnamed_T3B_1' in space 'T3B'
...
box.execute("SELECT * FROM t3b;")
---
@@ -741,8 +740,7 @@ box.execute("INSERT INTO t3c VALUES ('A');")
...
box.execute("INSERT INTO t3c VALUES ('a');")
---
-- error: 'Failed to execute SQL statement: Duplicate key exists in unique index ''pk_unnamed_T3C_1''
- in space ''T3C'''
+- error: Duplicate key exists in unique index 'pk_unnamed_T3C_1' in space 'T3C'
...
box.execute("SELECT * FROM t3c;")
---
@@ -806,8 +804,7 @@ box.execute("INSERT INTO t3d VALUES ('A');")
...
box.execute("INSERT INTO t3d VALUES ('a');")
---
-- error: 'Failed to execute SQL statement: Duplicate key exists in unique index ''pk_unnamed_T3D_1''
- in space ''T3D'''
+- error: Duplicate key exists in unique index 'pk_unnamed_T3D_1' in space 'T3D'
...
box.execute("SELECT * FROM t3d;")
---
@@ -837,8 +834,7 @@ box.execute("INSERT INTO t3e VALUES ('a');")
...
box.execute("INSERT INTO t3e VALUES ('A');")
---
-- error: 'Failed to execute SQL statement: Duplicate key exists in unique index ''pk_unnamed_T3E_1''
- in space ''T3E'''
+- error: Duplicate key exists in unique index 'pk_unnamed_T3E_1' in space 'T3E'
...
box.execute("SELECT * FROM t3e;")
---
@@ -901,8 +897,7 @@ box.execute("INSERT INTO t3f VALUES ('A');")
...
box.execute("INSERT INTO t3f VALUES ('a');")
---
-- error: 'Failed to execute SQL statement: Duplicate key exists in unique index ''pk_unnamed_T3F_1''
- in space ''T3F'''
+- error: Duplicate key exists in unique index 'pk_unnamed_T3F_1' in space 'T3F'
...
box.execute("SELECT * FROM t3f;")
---
@@ -932,8 +927,7 @@ box.execute("INSERT INTO t3g VALUES ('a');")
...
box.execute("INSERT INTO t3g VALUES ('A');")
---
-- error: 'Failed to execute SQL statement: Duplicate key exists in unique index ''pk_unnamed_T3G_1''
- in space ''T3G'''
+- error: Duplicate key exists in unique index 'pk_unnamed_T3G_1' in space 'T3G'
...
box.execute("SELECT * FROM t3g;")
---
diff --git a/test/sql/errinj.result b/test/sql/errinj.result
index ee36a38..75faad1 100644
--- a/test/sql/errinj.result
+++ b/test/sql/errinj.result
@@ -189,7 +189,7 @@ box.error.injection.set("ERRINJ_WAL_IO", true)
...
box.execute("CREATE TRIGGER t1t INSERT ON t1 FOR EACH ROW BEGIN INSERT INTO t2 VALUES (1, 1); END;")
---
-- error: 'Failed to execute SQL statement: Failed to write to disk'
+- error: Failed to write to disk
...
box.execute("CREATE INDEX t1a ON t1(a);")
---
@@ -257,7 +257,7 @@ box.error.injection.set("ERRINJ_WAL_IO", true)
...
box.execute("DROP TRIGGER t1t;")
---
-- error: 'Failed to execute SQL statement: Failed to write to disk'
+- error: Failed to write to disk
...
box.error.injection.set("ERRINJ_WAL_IO", false)
---
@@ -374,7 +374,7 @@ errinj.set("ERRINJ_WAL_IO", true)
...
box.execute("ALTER TABLE t3 DROP CONSTRAINT fk1;")
---
-- error: 'Failed to execute SQL statement: Failed to write to disk'
+- error: Failed to write to disk
...
box.execute("INSERT INTO t3 VALUES(1, 1, 3);")
---
diff --git a/test/sql/foreign-keys.result b/test/sql/foreign-keys.result
index 66eb94b..f3cca5c 100644
--- a/test/sql/foreign-keys.result
+++ b/test/sql/foreign-keys.result
@@ -181,8 +181,7 @@ t = box.space._fk_constraint:insert(t)
--
box.execute("DROP INDEX i1 on t1;")
---
-- error: 'Failed to execute SQL statement: Can''t modify space ''T1'': can not drop
- a referenced index'
+- error: 'Can''t modify space ''T1'': can not drop a referenced index'
...
-- Referenced index can't be altered as well, if alter leads to
-- rebuild of index (e.g. index still can be renamed).
diff --git a/test/sql/insert-unique.result b/test/sql/insert-unique.result
index 61b35a3..236046f 100644
--- a/test/sql/insert-unique.result
+++ b/test/sql/insert-unique.result
@@ -28,14 +28,12 @@ box.execute("INSERT INTO zoobar VALUES (111, 222, 'c3', 444)")
-- PK must be unique
box.execute("INSERT INTO zoobar VALUES (112, 222, 'c3', 444)")
---
-- error: 'Failed to execute SQL statement: Duplicate key exists in unique index ''pk_unnamed_ZOOBAR_1''
- in space ''ZOOBAR'''
+- error: Duplicate key exists in unique index 'pk_unnamed_ZOOBAR_1' in space 'ZOOBAR'
...
-- Unique index must be respected
box.execute("INSERT INTO zoobar VALUES (111, 223, 'c3', 444)")
---
-- error: 'Failed to execute SQL statement: Duplicate key exists in unique index ''ZOOBAR2''
- in space ''ZOOBAR'''
+- error: Duplicate key exists in unique index 'ZOOBAR2' in space 'ZOOBAR'
...
-- Cleanup
box.execute("DROP INDEX zoobar2 ON zoobar")
diff --git a/test/sql/iproto.result b/test/sql/iproto.result
index e734872..73497b4 100644
--- a/test/sql/iproto.result
+++ b/test/sql/iproto.result
@@ -437,8 +437,7 @@ future1:wait_result()
future2:wait_result()
---
- null
-- 'Failed to execute SQL statement: Duplicate key exists in unique index ''pk_unnamed_TEST_1''
- in space ''TEST'''
+- Duplicate key exists in unique index 'pk_unnamed_TEST_1' in space 'TEST'
...
future3:wait_result()
---
diff --git a/test/sql/persistency.result b/test/sql/persistency.result
index 3f85725..3508a22 100644
--- a/test/sql/persistency.result
+++ b/test/sql/persistency.result
@@ -31,8 +31,7 @@ box.execute("INSERT INTO foobar VALUES (1000, 'foobar')")
...
box.execute("INSERT INTO foobar VALUES (1, 'duplicate')")
---
-- error: 'Failed to execute SQL statement: Duplicate key exists in unique index ''pk_unnamed_FOOBAR_1''
- in space ''FOOBAR'''
+- error: Duplicate key exists in unique index 'pk_unnamed_FOOBAR_1' in space 'FOOBAR'
...
-- simple select
box.execute("SELECT bar, foo, 42, 'awesome' FROM foobar")
@@ -416,8 +415,7 @@ box.execute("SELECT \"name\", \"opts\" FROM \"_trigger\"")
-- prove barfoo2 still exists
box.execute("INSERT INTO barfoo VALUES ('xfoo', 1)")
---
-- error: 'Failed to execute SQL statement: Duplicate key exists in unique index ''pk_unnamed_BARFOO_1''
- in space ''BARFOO'''
+- error: Duplicate key exists in unique index 'pk_unnamed_BARFOO_1' in space 'BARFOO'
...
box.execute("SELECT * FROM barfoo")
---
diff --git a/test/sql/transition.result b/test/sql/transition.result
index dec5474..6f5e763 100644
--- a/test/sql/transition.result
+++ b/test/sql/transition.result
@@ -28,8 +28,7 @@ box.execute("INSERT INTO foobar VALUES (1000, 'foobar')")
...
box.execute("INSERT INTO foobar VALUES (1, 'duplicate')")
---
-- error: 'Failed to execute SQL statement: Duplicate key exists in unique index ''pk_unnamed_FOOBAR_1''
- in space ''FOOBAR'''
+- error: Duplicate key exists in unique index 'pk_unnamed_FOOBAR_1' in space 'FOOBAR'
...
-- simple select
box.execute("SELECT bar, foo, 42, 'awesome' FROM foobar")
@@ -312,8 +311,7 @@ box.execute("INSERT INTO barfoo VALUES ('foobar', 1000)")
-- prove barfoo2 was created
box.execute("INSERT INTO barfoo VALUES ('xfoo', 1)")
---
-- error: 'Failed to execute SQL statement: Duplicate key exists in unique index ''pk_unnamed_BARFOO_1''
- in space ''BARFOO'''
+- error: Duplicate key exists in unique index 'pk_unnamed_BARFOO_1' in space 'BARFOO'
...
box.execute("SELECT foo, bar FROM barfoo")
---
diff --git a/test/sql/triggers.result b/test/sql/triggers.result
index 77b88f4..16df1fb 100644
--- a/test/sql/triggers.result
+++ b/test/sql/triggers.result
@@ -480,7 +480,7 @@ space_id = box.space.T1.id
...
box.execute("CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW WHEN new.a = ? BEGIN SELECT 1; END;")
---
-- error: 'Failed to execute SQL statement: bindings are not allowed in DDL'
+- error: bindings are not allowed in DDL
...
tuple = {"TR1", space_id, {sql = [[CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW WHEN new.a = ? BEGIN SELECT 1; END;]]}}
---
--
2.7.4
^ permalink raw reply [flat|nested] 31+ messages in thread
* [tarantool-patches] Re: [PATCH v1 01/12] sql: remove errors SQL_TARANTOOL_*_FAIL
2019-05-05 12:17 ` [tarantool-patches] [PATCH v1 01/12] sql: remove errors SQL_TARANTOOL_*_FAIL imeevma
@ 2019-05-15 13:18 ` n.pettik
2019-05-25 9:16 ` Imeev Mergen
0 siblings, 1 reply; 31+ messages in thread
From: n.pettik @ 2019-05-15 13:18 UTC (permalink / raw)
To: tarantool-patches; +Cc: Imeev Mergen
> On 5 May 2019, at 15:17, imeevma@tarantool.org wrote:
>
> Errors SQL_TARANTOOL_DELETE_FAIL, SQL_TARANTOOL_ITERATOR_FAIL and
> SQL_TARANTOOL_INSERT_FAIL have almost no functionality, but can
Nit: they are not errors, but rather error codes.
> diff --git a/src/box/sql.c b/src/box/sql.c
> index 1fb93e1..3593242 100644
> --- a/src/box/sql.c
> +++ b/src/box/sql.c
> @@ -162,15 +162,6 @@ const char *tarantoolErrorMessage()
> return box_error_message(box_error_last());
> }
>
> const void *tarantoolsqlPayloadFetch(BtCursor *pCur, u32 *pAmt)
> {
> assert(pCur->curFlags & BTCF_TaCursor ||
> @@ -421,7 +412,7 @@ int tarantoolsqlEphemeralInsert(struct space *space, const char *tuple,
> assert(space != NULL);
> mp_tuple_assert(tuple, tuple_end);
> if (space_ephemeral_replace(space, tuple, tuple_end) != 0)
> - return SQL_TARANTOOL_INSERT_FAIL;
> + return SQL_TARANTOOL_ERROR;
Let’s return -1 and set tarantool_error only in VDBE.
Later, we are going to replace tarantool_error with -1 everywhere.
The same concerns other tarantool_error usages in sql.c
> diff --git a/src/box/sql/tarantoolInt.h b/src/box/sql/tarantoolInt.h
> index 2b04d96..f15e147 100644
> --- a/src/box/sql/tarantoolInt.h
> +++ b/src/box/sql/tarantoolInt.h
> @@ -13,8 +13,6 @@ struct fk_constraint_def;
> /* Misc */
> const char *tarantoolErrorMessage();
>
> -int is_tarantool_error(int rc);
> -
> /* Storage interface. */
> const void *tarantoolsqlPayloadFetch(BtCursor * pCur, u32 * pAmt);
>
> @@ -51,8 +49,7 @@ int tarantoolsqlDelete(BtCursor * pCur, u8 flags);
> * @param key Key of record to be deleted.
> * @param key_size Size of key.
> *
> - * @retval SQL_OK on success, SQL_TARANTOOL_DELETE_FAIL
> - * otherwise.
> + * @retval SQL_OK on success, SQL_TARANTOOL_ERROR otherwise.
> */
> int
> sql_delete_by_key(struct space *space, uint32_t iid, char *key,
> diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
> index 3bd8223..5222a4e 100644
> --- a/src/box/sql/vdbe.c
> +++ b/src/box/sql/vdbe.c
> @@ -5469,7 +5469,7 @@ abort_due_to_error:
> /* Avoiding situation when Tarantool error is set,
> * but error message isn't.
> */
> - if (is_tarantool_error(rc) && tarantoolErrorMessage()) {
> + if (rc == SQL_TARANTOOL_ERROR && tarantoolErrorMessage()) {
Isn’t tarantoolErrorMessage redundant check? Is it possible
to use SQL_TARANTOOL_ERROR without set diag?
^ permalink raw reply [flat|nested] 31+ messages in thread
* [tarantool-patches] Re: [PATCH v1 01/12] sql: remove errors SQL_TARANTOOL_*_FAIL
2019-05-15 13:18 ` [tarantool-patches] " n.pettik
@ 2019-05-25 9:16 ` Imeev Mergen
0 siblings, 0 replies; 31+ messages in thread
From: Imeev Mergen @ 2019-05-25 9:16 UTC (permalink / raw)
To: n.pettik, tarantool-patches
Hi! Thank you for review! My answers below.
On 5/15/19 4:18 PM, n.pettik wrote:
>
>> On 5 May 2019, at 15:17, imeevma@tarantool.org wrote:
>>
>> Errors SQL_TARANTOOL_DELETE_FAIL, SQL_TARANTOOL_ITERATOR_FAIL and
>> SQL_TARANTOOL_INSERT_FAIL have almost no functionality, but can
> Nit: they are not errors, but rather error codes.
Fixed.
>
>> diff --git a/src/box/sql.c b/src/box/sql.c
>> index 1fb93e1..3593242 100644
>> --- a/src/box/sql.c
>> +++ b/src/box/sql.c
>> @@ -162,15 +162,6 @@ const char *tarantoolErrorMessage()
>> return box_error_message(box_error_last());
>> }
>>
>> const void *tarantoolsqlPayloadFetch(BtCursor *pCur, u32 *pAmt)
>> {
>> assert(pCur->curFlags & BTCF_TaCursor ||
>> @@ -421,7 +412,7 @@ int tarantoolsqlEphemeralInsert(struct space *space, const char *tuple,
>> assert(space != NULL);
>> mp_tuple_assert(tuple, tuple_end);
>> if (space_ephemeral_replace(space, tuple, tuple_end) != 0)
>> - return SQL_TARANTOOL_INSERT_FAIL;
>> + return SQL_TARANTOOL_ERROR;
> Let’s return -1 and set tarantool_error only in VDBE.
> Later, we are going to replace tarantool_error with -1 everywhere.
> The same concerns other tarantool_error usages in sql.c
I think it's better to leave it as it is. A bit later there will
be a patch-set, in which all SQL error codes will be replaced with
either 0 or -1.
>
>> diff --git a/src/box/sql/tarantoolInt.h b/src/box/sql/tarantoolInt.h
>> index 2b04d96..f15e147 100644
>> --- a/src/box/sql/tarantoolInt.h
>> +++ b/src/box/sql/tarantoolInt.h
>> @@ -13,8 +13,6 @@ struct fk_constraint_def;
>> /* Misc */
>> const char *tarantoolErrorMessage();
>>
>> -int is_tarantool_error(int rc);
>> -
>> /* Storage interface. */
>> const void *tarantoolsqlPayloadFetch(BtCursor * pCur, u32 * pAmt);
>>
>> @@ -51,8 +49,7 @@ int tarantoolsqlDelete(BtCursor * pCur, u8 flags);
>> * @param key Key of record to be deleted.
>> * @param key_size Size of key.
>> *
>> - * @retval SQL_OK on success, SQL_TARANTOOL_DELETE_FAIL
>> - * otherwise.
>> + * @retval SQL_OK on success, SQL_TARANTOOL_ERROR otherwise.
>> */
>> int
>> sql_delete_by_key(struct space *space, uint32_t iid, char *key,
>> diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
>> index 3bd8223..5222a4e 100644
>> --- a/src/box/sql/vdbe.c
>> +++ b/src/box/sql/vdbe.c
>> @@ -5469,7 +5469,7 @@ abort_due_to_error:
>> /* Avoiding situation when Tarantool error is set,
>> * but error message isn't.
>> */
>> - if (is_tarantool_error(rc) && tarantoolErrorMessage()) {
>> + if (rc == SQL_TARANTOOL_ERROR && tarantoolErrorMessage()) {
> Isn’t tarantoolErrorMessage redundant check? Is it possible
> to use SQL_TARANTOOL_ERROR without set diag?
It is technically possible to install SQL_TARANTOOL_ERROR without
set diag. This code will be fixed in one of the following patches
of this patch-set.
^ permalink raw reply [flat|nested] 31+ messages in thread
* [tarantool-patches] [PATCH v1 02/12] sql: remove error ER_SQL
2019-05-05 12:17 [tarantool-patches] [PATCH v1 00/12] sql: set errors in VDBE using diag_set() imeevma
2019-05-05 12:17 ` [tarantool-patches] [PATCH v1 01/12] sql: remove errors SQL_TARANTOOL_*_FAIL imeevma
@ 2019-05-05 12:17 ` imeevma
2019-05-15 13:18 ` [tarantool-patches] " n.pettik
2019-05-05 12:17 ` [tarantool-patches] [PATCH v1 03/12] sql: rework diag_set() in OP_Halt imeevma
` (9 subsequent siblings)
11 siblings, 1 reply; 31+ messages in thread
From: imeevma @ 2019-05-05 12:17 UTC (permalink / raw)
To: korablev; +Cc: tarantool-patches
The ER_SQL error code is very similar to the ER_SQL_EXECUTE error
code: they have almost identical description and usage. To avoid
misunderstandings, it is better to remove one of them. The ER_SQL
error code has a slightly more vague description, so it was
decided to remove it.
---
src/box/alter.cc | 4 ++--
src/box/errcode.h | 2 +-
src/box/sql/build.c | 2 +-
src/box/sql/delete.c | 4 ++--
src/box/sql/resolve.c | 2 +-
src/box/sql/trigger.c | 6 +++---
test/box/misc.result | 1 -
test/sql-tap/select3.test.lua | 2 +-
test/sql-tap/select5.test.lua | 10 +++++-----
test/sql-tap/trigger1.test.lua | 6 +++---
test/sql/delete.result | 7 ++++---
test/sql/on-conflict.result | 4 ++--
test/sql/triggers.result | 19 +++++++++++--------
13 files changed, 36 insertions(+), 33 deletions(-)
diff --git a/src/box/alter.cc b/src/box/alter.cc
index 9279426..fbcff69 100644
--- a/src/box/alter.cc
+++ b/src/box/alter.cc
@@ -3550,7 +3550,7 @@ on_replace_dd_trigger(struct trigger * /* trigger */, void *event)
if (strlen(trigger_name) != trigger_name_len ||
memcmp(trigger_name_src, trigger_name,
trigger_name_len) != 0) {
- tnt_raise(ClientError, ER_SQL,
+ tnt_raise(ClientError, ER_SQL_EXECUTE,
"trigger name does not match extracted "
"from SQL");
}
@@ -3558,7 +3558,7 @@ on_replace_dd_trigger(struct trigger * /* trigger */, void *event)
tuple_field_u32_xc(new_tuple,
BOX_TRIGGER_FIELD_SPACE_ID);
if (space_id != sql_trigger_space_id(new_trigger)) {
- tnt_raise(ClientError, ER_SQL,
+ tnt_raise(ClientError, ER_SQL_EXECUTE,
"trigger space_id does not match the value "
"resolved on AST building from SQL");
}
diff --git a/src/box/errcode.h b/src/box/errcode.h
index 3f8cb8e..6c9bcc4 100644
--- a/src/box/errcode.h
+++ b/src/box/errcode.h
@@ -212,7 +212,7 @@ struct errcode_record {
/*157 */_(ER_SQL_BIND_TYPE, "Bind value type %s for parameter %s is not supported") \
/*158 */_(ER_SQL_BIND_PARAMETER_MAX, "SQL bind parameter limit reached: %d") \
/*159 */_(ER_SQL_EXECUTE, "Failed to execute SQL statement: %s") \
- /*160 */_(ER_SQL, "SQL error: %s") \
+ /*160 */_(ER_UNUSED, "") \
/*161 */_(ER_SQL_BIND_NOT_FOUND, "Parameter %s was not found in the statement") \
/*162 */_(ER_ACTION_MISMATCH, "Field %s contains %s on conflict action, but %s in index parts") \
/*163 */_(ER_VIEW_MISSING_SQL, "Space declared as a view must have SQL statement") \
diff --git a/src/box/sql/build.c b/src/box/sql/build.c
index 72be410..1151425 100644
--- a/src/box/sql/build.c
+++ b/src/box/sql/build.c
@@ -467,7 +467,7 @@ sql_column_add_nullable_action(struct Parse *parser,
const char *action =
on_conflict_action_strs[field->nullable_action];
err = tt_sprintf(err, field->name, def->name, action);
- diag_set(ClientError, ER_SQL, err);
+ diag_set(ClientError, ER_SQL_EXECUTE, err);
parser->is_aborted = true;
return;
}
diff --git a/src/box/sql/delete.c b/src/box/sql/delete.c
index a95b071..ca59abc 100644
--- a/src/box/sql/delete.c
+++ b/src/box/sql/delete.c
@@ -104,7 +104,7 @@ sql_table_truncate(struct Parse *parse, struct SrcList *tab_list)
if (! rlist_empty(&space->parent_fk_constraint)) {
const char *err = "can not truncate space '%s' because other "
"objects depend on it";
- diag_set(ClientError, ER_SQL,
+ diag_set(ClientError, ER_SQL_EXECUTE,
tt_sprintf(err, space->def->name));
goto tarantool_error;
}
@@ -112,7 +112,7 @@ sql_table_truncate(struct Parse *parse, struct SrcList *tab_list)
const char *err_msg =
tt_sprintf("can not truncate space '%s' because space "\
"is a view", space->def->name);
- diag_set(ClientError, ER_SQL, err_msg);
+ diag_set(ClientError, ER_SQL_EXECUTE, err_msg);
goto tarantool_error;
}
sqlVdbeAddOp2(v, OP_Clear, space->def->id, true);
diff --git a/src/box/sql/resolve.c b/src/box/sql/resolve.c
index 504096e..e136312 100644
--- a/src/box/sql/resolve.c
+++ b/src/box/sql/resolve.c
@@ -1333,7 +1333,7 @@ resolveSelectStep(Walker * pWalker, Select * p)
return WRC_Abort;
if ((sNC.ncFlags & NC_HasAgg) == 0 ||
(sNC.ncFlags & NC_HasUnaggregatedId) != 0) {
- diag_set(ClientError, ER_SQL, "HAVING "
+ diag_set(ClientError, ER_SQL_EXECUTE, "HAVING "
"argument must appear in the GROUP BY "
"clause or be used in an aggregate "
"function");
diff --git a/src/box/sql/trigger.c b/src/box/sql/trigger.c
index 14e4198..4fdbb60 100644
--- a/src/box/sql/trigger.c
+++ b/src/box/sql/trigger.c
@@ -445,7 +445,7 @@ sql_trigger_replace(const char *name, uint32_t space_id,
if (trigger != NULL) {
/* Do not create a trigger on a system space. */
if (space_is_system(space)) {
- diag_set(ClientError, ER_SQL,
+ diag_set(ClientError, ER_SQL_EXECUTE,
"cannot create trigger on system table");
return -1;
}
@@ -454,7 +454,7 @@ sql_trigger_replace(const char *name, uint32_t space_id,
* views only support INSTEAD of triggers.
*/
if (space->def->opts.is_view && trigger->tr_tm != TK_INSTEAD) {
- diag_set(ClientError, ER_SQL,
+ diag_set(ClientError, ER_SQL_EXECUTE,
tt_sprintf("cannot create %s "\
"trigger on view: %s", trigger->tr_tm == TK_BEFORE ?
"BEFORE" : "AFTER",
@@ -462,7 +462,7 @@ sql_trigger_replace(const char *name, uint32_t space_id,
return -1;
}
if (!space->def->opts.is_view && trigger->tr_tm == TK_INSTEAD) {
- diag_set(ClientError, ER_SQL,
+ diag_set(ClientError, ER_SQL_EXECUTE,
tt_sprintf("cannot create "\
"INSTEAD OF trigger on space: %s", space->def->name));
return -1;
diff --git a/test/box/misc.result b/test/box/misc.result
index a1f7a09..8eabc57 100644
--- a/test/box/misc.result
+++ b/test/box/misc.result
@@ -489,7 +489,6 @@ t;
157: box.error.SQL_BIND_TYPE
158: box.error.SQL_BIND_PARAMETER_MAX
159: box.error.SQL_EXECUTE
- 160: box.error.SQL
161: box.error.SQL_BIND_NOT_FOUND
162: box.error.ACTION_MISMATCH
163: box.error.VIEW_MISSING_SQL
diff --git a/test/sql-tap/select3.test.lua b/test/sql-tap/select3.test.lua
index cb97363..2807d42 100755
--- a/test/sql-tap/select3.test.lua
+++ b/test/sql-tap/select3.test.lua
@@ -200,7 +200,7 @@ test:do_catchsql_test("select3-3.1", [[
SELECT log, count(*) FROM t1 HAVING log>=4
]], {
-- <select3-3.1>
- 1, "SQL error: HAVING argument must appear in the GROUP BY clause or be used in an aggregate function"
+ 1, "Failed to execute SQL statement: HAVING argument must appear in the GROUP BY clause or be used in an aggregate function"
-- </select3-3.1>
})
diff --git a/test/sql-tap/select5.test.lua b/test/sql-tap/select5.test.lua
index 1353b39..d34de31 100755
--- a/test/sql-tap/select5.test.lua
+++ b/test/sql-tap/select5.test.lua
@@ -424,7 +424,7 @@ test:do_catchsql_test(
SELECT s1 FROM te40 HAVING s1 = 1;
]], {
-- <select5-9.1>
- 1, "SQL error: HAVING argument must appear in the GROUP BY clause or be used in an aggregate function"
+ 1, "Failed to execute SQL statement: HAVING argument must appear in the GROUP BY clause or be used in an aggregate function"
-- </select5-9.1>
})
@@ -434,7 +434,7 @@ test:do_catchsql_test(
SELECT SUM(s1) FROM te40 HAVING s1 = 2;
]], {
-- <select5-9.2>
- 1, "SQL error: HAVING argument must appear in the GROUP BY clause or be used in an aggregate function"
+ 1, "Failed to execute SQL statement: HAVING argument must appear in the GROUP BY clause or be used in an aggregate function"
-- </select5-9.2>
})
@@ -444,7 +444,7 @@ test:do_catchsql_test(
SELECT s1 FROM te40 HAVING SUM(s1) = 2;
]], {
-- <select5-9.3>
- 1, "SQL error: HAVING argument must appear in the GROUP BY clause or be used in an aggregate function"
+ 1, "Failed to execute SQL statement: HAVING argument must appear in the GROUP BY clause or be used in an aggregate function"
-- </select5-9.3>
})
@@ -484,7 +484,7 @@ test:do_catchsql_test(
SELECT SUM(s1),s2 FROM te40 HAVING SUM(s1) > 0;
]], {
-- <select5-9.7>
- 1, "SQL error: HAVING argument must appear in the GROUP BY clause or be used in an aggregate function"
+ 1, "Failed to execute SQL statement: HAVING argument must appear in the GROUP BY clause or be used in an aggregate function"
-- </select5-9.7>
})
@@ -494,7 +494,7 @@ test:do_catchsql_test(
SELECT SUM(s1) FROM te40 HAVING SUM(s1) > 0 and s2 > 0;
]], {
-- <select5-9.8>
- 1, "SQL error: HAVING argument must appear in the GROUP BY clause or be used in an aggregate function"
+ 1, "Failed to execute SQL statement: HAVING argument must appear in the GROUP BY clause or be used in an aggregate function"
-- </select5-9.8>
})
diff --git a/test/sql-tap/trigger1.test.lua b/test/sql-tap/trigger1.test.lua
index 64763fa..38d7c55 100755
--- a/test/sql-tap/trigger1.test.lua
+++ b/test/sql-tap/trigger1.test.lua
@@ -260,7 +260,7 @@ test:do_catchsql_test(
end;
]], {
-- <trigger1-1.12>
- 1, "SQL error: cannot create INSTEAD OF trigger on space: T1"
+ 1, "Failed to execute SQL statement: cannot create INSTEAD OF trigger on space: T1"
-- </trigger1-1.12>
})
@@ -274,7 +274,7 @@ test:do_catchsql_test(
end;
]], {
-- <trigger1-1.13>
- 1, "SQL error: cannot create BEFORE trigger on view: V1"
+ 1, "Failed to execute SQL statement: cannot create BEFORE trigger on view: V1"
-- </trigger1-1.13>
})
@@ -289,7 +289,7 @@ test:do_catchsql_test(
end;
]], {
-- <trigger1-1.14>
- 1, "SQL error: cannot create AFTER trigger on view: V1"
+ 1, "Failed to execute SQL statement: cannot create AFTER trigger on view: V1"
-- </trigger1-1.14>
})
diff --git a/test/sql/delete.result b/test/sql/delete.result
index 0e442e5..0bc389f 100644
--- a/test/sql/delete.result
+++ b/test/sql/delete.result
@@ -128,7 +128,8 @@ box.execute("CREATE VIEW v1 AS SELECT * FROM t1;")
...
box.execute("TRUNCATE TABLE v1;")
---
-- error: 'SQL error: can not truncate space ''V1'' because space is a view'
+- error: 'Failed to execute SQL statement: can not truncate space ''V1'' because space
+ is a view'
...
-- Can't truncate table with FK.
box.execute("CREATE TABLE t2(x INT PRIMARY KEY REFERENCES t1(id));")
@@ -137,8 +138,8 @@ box.execute("CREATE TABLE t2(x INT PRIMARY KEY REFERENCES t1(id));")
...
box.execute("TRUNCATE TABLE t1;")
---
-- error: 'SQL error: can not truncate space ''T1'' because other objects depend on
- it'
+- error: 'Failed to execute SQL statement: can not truncate space ''T1'' because other
+ objects depend on it'
...
-- Table triggers should be ignored.
box.execute("DROP TABLE t2;")
diff --git a/test/sql/on-conflict.result b/test/sql/on-conflict.result
index 2f29f5b..be89caf 100644
--- a/test/sql/on-conflict.result
+++ b/test/sql/on-conflict.result
@@ -59,8 +59,8 @@ box.execute("CREATE TABLE te17 (s1 INT NULL PRIMARY KEY);")
...
box.execute("CREATE TABLE test (a int PRIMARY KEY, b int NULL ON CONFLICT IGNORE);")
---
-- error: 'SQL error: NULL declaration for column ''B'' of table ''TEST'' has been
- already set to ''none'''
+- error: 'Failed to execute SQL statement: NULL declaration for column ''B'' of table
+ ''TEST'' has been already set to ''none'''
...
box.execute("CREATE TABLE test (a int, b int NULL, c int, PRIMARY KEY(a, b, c))")
---
diff --git a/test/sql/triggers.result b/test/sql/triggers.result
index 16df1fb..a4c927c 100644
--- a/test/sql/triggers.result
+++ b/test/sql/triggers.result
@@ -45,22 +45,24 @@ tuple = {"T1t", space_id, {sql = "CREATE TRIGGER t1t AFTER INSERT ON t1 FOR EACH
...
box.space._trigger:insert(tuple)
---
-- error: 'SQL error: trigger name does not match extracted from SQL'
+- error: 'Failed to execute SQL statement: trigger name does not match extracted from
+ SQL'
...
tuple = {"T1t", space_id, {sql = "CREATE TRIGGER t12t AFTER INSERT ON t1 FOR EACH ROW BEGIN INSERT INTO t2 VALUES(1); END;"}}
---
...
box.space._trigger:insert(tuple)
---
-- error: 'SQL error: trigger name does not match extracted from SQL'
+- error: 'Failed to execute SQL statement: trigger name does not match extracted from
+ SQL'
...
tuple = {"T2T", box.space.T1.id + 1, {sql = "CREATE TRIGGER t2t AFTER INSERT ON t1 FOR EACH ROW BEGIN INSERT INTO t2 VALUES(1); END;"}}
---
...
box.space._trigger:insert(tuple)
---
-- error: 'SQL error: trigger space_id does not match the value resolved on AST building
- from SQL'
+- error: 'Failed to execute SQL statement: trigger space_id does not match the value
+ resolved on AST building from SQL'
...
immutable_part(box.space._trigger:select())
---
@@ -244,7 +246,8 @@ tuple = {"T1T", space_id, {sql = [[create trigger t1t instead of update on t1 fo
...
box.space._trigger:insert(tuple)
---
-- error: 'SQL error: cannot create INSTEAD OF trigger on space: T1'
+- error: 'Failed to execute SQL statement: cannot create INSTEAD OF trigger on space:
+ T1'
...
box.execute("CREATE VIEW V1 AS SELECT * FROM t1;")
---
@@ -258,14 +261,14 @@ tuple = {"V1T", space_id, {sql = [[create trigger v1t before update on v1 for ea
...
box.space._trigger:insert(tuple)
---
-- error: 'SQL error: cannot create BEFORE trigger on view: V1'
+- error: 'Failed to execute SQL statement: cannot create BEFORE trigger on view: V1'
...
tuple = {"V1T", space_id, {sql = [[create trigger v1t AFTER update on v1 for each row begin delete from t1 WHERE a=old.a+2; end;]]}}
---
...
box.space._trigger:insert(tuple)
---
-- error: 'SQL error: cannot create AFTER trigger on view: V1'
+- error: 'Failed to execute SQL statement: cannot create AFTER trigger on view: V1'
...
space_id = box.space._fk_constraint.id
---
@@ -275,7 +278,7 @@ tuple = {"T1T", space_id, {sql = [[create trigger t1t instead of update on "_fk_
...
box.space._trigger:insert(tuple)
---
-- error: 'SQL error: cannot create trigger on system table'
+- error: 'Failed to execute SQL statement: cannot create trigger on system table'
...
box.execute("DROP VIEW V1;")
---
--
2.7.4
^ permalink raw reply [flat|nested] 31+ messages in thread
* [tarantool-patches] [PATCH v1 03/12] sql: rework diag_set() in OP_Halt
2019-05-05 12:17 [tarantool-patches] [PATCH v1 00/12] sql: set errors in VDBE using diag_set() imeevma
2019-05-05 12:17 ` [tarantool-patches] [PATCH v1 01/12] sql: remove errors SQL_TARANTOOL_*_FAIL imeevma
2019-05-05 12:17 ` [tarantool-patches] [PATCH v1 02/12] sql: remove error ER_SQL imeevma
@ 2019-05-05 12:17 ` imeevma
2019-05-15 13:18 ` [tarantool-patches] " n.pettik
2019-05-05 12:17 ` [tarantool-patches] [PATCH v1 04/12] sql: make SQL_TARANTOOL_ERROR the only errcode of OP_Halt imeevma
` (8 subsequent siblings)
11 siblings, 1 reply; 31+ messages in thread
From: imeevma @ 2019-05-05 12:17 UTC (permalink / raw)
To: korablev; +Cc: tarantool-patches
Prior to this patch, the way to set Tarantool error in OP_Halt was
too universal. It was possible to set a description of the error
that does not match its errcode. This change will also make it
easier to work with an error in OP_Halt, since you no longer need
to create a complete error message.
Example of wrong error code:
...
tarantool> box.execute('select 1 limit true')
---
- error: Only positive integers are allowed in the LIMIT clause
...
tarantool> box.error.last().code
---
- 0
...
---
src/box/sql/build.c | 9 ++-------
src/box/sql/select.c | 13 ++++++-------
src/box/sql/trigger.c | 12 ++++--------
src/box/sql/vdbe.c | 9 +++------
test/sql-tap/e_select1.test.lua | 4 ++--
test/sql-tap/limit.test.lua | 26 +++++++++++++-------------
test/sql-tap/select4.test.lua | 8 ++++----
test/sql-tap/subselect.test.lua | 6 +++---
test/sql-tap/tkt1473.test.lua | 36 ++++++++++++++++++------------------
test/sql/iproto.result | 18 ++++++++++++------
test/sql/types.result | 9 ++++++---
11 files changed, 73 insertions(+), 77 deletions(-)
diff --git a/src/box/sql/build.c b/src/box/sql/build.c
index 1151425..28dcbc3 100644
--- a/src/box/sql/build.c
+++ b/src/box/sql/build.c
@@ -1004,12 +1004,10 @@ vdbe_emit_fk_constraint_create(struct Parse *parse_context,
* Lets check that constraint with this name hasn't
* been created before.
*/
- const char *error_msg =
- tt_sprintf(tnt_errcode_desc(ER_CONSTRAINT_EXISTS), name_copy);
if (vdbe_emit_halt_with_presence_test(parse_context,
BOX_FK_CONSTRAINT_ID, 0,
constr_tuple_reg, 2,
- ER_CONSTRAINT_EXISTS, error_msg,
+ ER_CONSTRAINT_EXISTS, name_copy,
false, OP_NoConflict) != 0)
return;
sqlVdbeAddOp2(vdbe, OP_Bool, fk->is_deferred, constr_tuple_reg + 3);
@@ -1392,13 +1390,10 @@ vdbe_emit_fk_constraint_drop(struct Parse *parse_context, char *constraint_name,
sqlVdbeAddOp4(vdbe, OP_String8, 0, key_reg, 0, constraint_name,
P4_DYNAMIC);
sqlVdbeAddOp2(vdbe, OP_Integer, child_id, key_reg + 1);
- const char *error_msg =
- tt_sprintf(tnt_errcode_desc(ER_NO_SUCH_CONSTRAINT),
- constraint_name);
if (vdbe_emit_halt_with_presence_test(parse_context,
BOX_FK_CONSTRAINT_ID, 0,
key_reg, 2, ER_NO_SUCH_CONSTRAINT,
- error_msg, false,
+ constraint_name, false,
OP_Found) != 0) {
sqlDbFree(parse_context->db, constraint_name);
return;
diff --git a/src/box/sql/select.c b/src/box/sql/select.c
index d3472a9..3f0b540 100644
--- a/src/box/sql/select.c
+++ b/src/box/sql/select.c
@@ -2116,6 +2116,7 @@ computeLimitRegisters(Parse * pParse, Select * p, int iBreak)
0, 0,
wrong_limit_error,
P4_STATIC);
+ sqlVdbeChangeP5(v, ER_SQL_EXECUTE);
sqlVdbeResolveLabel(v, positive_limit_label);
VdbeCoverage(v);
@@ -2142,9 +2143,8 @@ computeLimitRegisters(Parse * pParse, Select * p, int iBreak)
sqlVdbeAddOp2(v, OP_Integer, 1, r1);
int no_err = sqlVdbeMakeLabel(v);
sqlVdbeAddOp3(v, OP_Eq, iLimit, no_err, r1);
- const char *error =
- "SQL error: Expression subquery could "
- "be limited only with 1";
+ const char *error = "Expression subquery could "
+ "be limited only with 1";
sqlVdbeAddOp4(v, OP_Halt,
SQL_TARANTOOL_ERROR,
0, 0, error, P4_STATIC);
@@ -2178,6 +2178,7 @@ computeLimitRegisters(Parse * pParse, Select * p, int iBreak)
0, 0,
wrong_offset_error,
P4_STATIC);
+ sqlVdbeChangeP5(v, ER_SQL_EXECUTE);
sqlVdbeResolveLabel(v, positive_offset_label);
sqlReleaseTempReg(pParse, r1);
@@ -5446,10 +5447,8 @@ vdbe_code_raise_on_multiple_rows(struct Parse *parser, int limit_reg, int end_ma
int r1 = sqlGetTempReg(parser);
sqlVdbeAddOp2(v, OP_Integer, 0, r1);
sqlVdbeAddOp3(v, OP_Ne, r1, end_mark, limit_reg);
- const char *error =
- "SQL error: Expression subquery returned more than 1 row";
- sqlVdbeAddOp4(v, OP_Halt, SQL_TARANTOOL_ERROR, 0, 0, error,
- P4_STATIC);
+ const char *error = "Expression subquery returned more than 1 row";
+ sqlVdbeAddOp4(v, OP_Halt, SQL_TARANTOOL_ERROR, 0, 0, error, P4_STATIC);
sqlVdbeChangeP5(v, ER_SQL_EXECUTE);
sqlReleaseTempReg(parser, r1);
}
diff --git a/src/box/sql/trigger.c b/src/box/sql/trigger.c
index 4fdbb60..3005362 100644
--- a/src/box/sql/trigger.c
+++ b/src/box/sql/trigger.c
@@ -100,9 +100,6 @@ sql_trigger_begin(struct Parse *parse)
struct Vdbe *v = sqlGetVdbe(parse);
if (v != NULL)
sqlVdbeCountChanges(v);
- const char *error_msg =
- tt_sprintf(tnt_errcode_desc(ER_TRIGGER_EXISTS),
- trigger_name);
char *name_copy = sqlDbStrDup(db, trigger_name);
if (name_copy == NULL)
goto trigger_cleanup;
@@ -113,7 +110,8 @@ sql_trigger_begin(struct Parse *parse)
if (vdbe_emit_halt_with_presence_test(parse, BOX_TRIGGER_ID, 0,
name_reg, 1,
ER_TRIGGER_EXISTS,
- error_msg, (no_err != 0),
+ trigger_name,
+ (no_err != 0),
OP_NoConflict) != 0)
goto trigger_cleanup;
}
@@ -412,9 +410,6 @@ sql_drop_trigger(struct Parse *parser)
assert(name->nSrc == 1);
const char *trigger_name = name->a[0].zName;
- const char *error_msg =
- tt_sprintf(tnt_errcode_desc(ER_NO_SUCH_TRIGGER),
- trigger_name);
char *name_copy = sqlDbStrDup(db, trigger_name);
if (name_copy == NULL)
goto drop_trigger_cleanup;
@@ -422,7 +417,8 @@ sql_drop_trigger(struct Parse *parser)
sqlVdbeAddOp4(v, OP_String8, 0, name_reg, 0, name_copy, P4_DYNAMIC);
if (vdbe_emit_halt_with_presence_test(parser, BOX_TRIGGER_ID, 0,
name_reg, 1, ER_NO_SUCH_TRIGGER,
- error_msg, no_err, OP_Found) != 0)
+ trigger_name,
+ no_err, OP_Found) != 0)
goto drop_trigger_cleanup;
vdbe_code_drop_trigger(parser, trigger_name, true);
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index 5222a4e..9f0d760 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -1032,12 +1032,9 @@ case OP_Halt: {
p->pc = pcx;
if (p->rc) {
if (p->rc == SQL_TARANTOOL_ERROR) {
- if (pOp->p4.z == NULL) {
- assert(! diag_is_empty(diag_get()));
- } else {
- box_error_set(__FILE__, __LINE__, pOp->p5,
- pOp->p4.z);
- }
+ if (pOp->p4.z != NULL)
+ diag_set(ClientError, pOp->p5, pOp->p4.z);
+ assert(! diag_is_empty(diag_get()));
} else if (pOp->p5 != 0) {
static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK",
"FOREIGN KEY" };
diff --git a/test/sql-tap/e_select1.test.lua b/test/sql-tap/e_select1.test.lua
index c4724e6..0c626c9 100755
--- a/test/sql-tap/e_select1.test.lua
+++ b/test/sql-tap/e_select1.test.lua
@@ -2170,7 +2170,7 @@ for _, val in ipairs({
"e_select-9.2."..tn,
select,
{
- 1, "Only positive integers are allowed in the LIMIT clause"})
+ 1, "Failed to execute SQL statement: Only positive integers are allowed in the LIMIT clause"})
end
-- EVIDENCE-OF: R-03014-26414 If the LIMIT expression evaluates to a
@@ -2224,7 +2224,7 @@ for _, val in ipairs({
test:do_catchsql_test(
"e_select-9.7."..tn,
select, {
- 1, "Only positive integers are allowed in the OFFSET clause"
+ 1, "Failed to execute SQL statement: Only positive integers are allowed in the OFFSET clause"
})
end
diff --git a/test/sql-tap/limit.test.lua b/test/sql-tap/limit.test.lua
index 9b728d8..40b787b 100755
--- a/test/sql-tap/limit.test.lua
+++ b/test/sql-tap/limit.test.lua
@@ -84,7 +84,7 @@ test:do_catchsql_test(
SELECT x FROM t1 ORDER BY x+1 LIMIT 5 OFFSET -2
]], {
-- <limit-1.2.13>
- 1 ,"Only positive integers are allowed in the OFFSET clause"
+ 1 ,"Failed to execute SQL statement: Only positive integers are allowed in the OFFSET clause"
-- </limit-1.2.13>
})
@@ -94,7 +94,7 @@ test:do_catchsql_test(
SELECT x FROM t1 ORDER BY x+1 LIMIT 2, -5
]], {
-- <limit-1.2.4>
- 1, "Only positive integers are allowed in the LIMIT clause"
+ 1, "Failed to execute SQL statement: Only positive integers are allowed in the LIMIT clause"
-- </limit-1.2.4>
})
@@ -115,7 +115,7 @@ test:do_catchsql_test(
SELECT x FROM t1 ORDER BY x+1 LIMIT -2, 5
]], {
-- <limit-1.2.6>
- 1, "Only positive integers are allowed in the OFFSET clause"
+ 1, "Failed to execute SQL statement: Only positive integers are allowed in the OFFSET clause"
-- </limit-1.2.6>
})
@@ -135,7 +135,7 @@ test:do_catchsql_test(
SELECT x FROM t1 ORDER BY x+1 LIMIT -2, -5
]], {
-- <limit-1.2.8>
- 1, "Only positive integers are allowed in the LIMIT clause"
+ 1, "Failed to execute SQL statement: Only positive integers are allowed in the LIMIT clause"
-- </limit-1.2.8>
})
@@ -384,7 +384,7 @@ test:do_catchsql_test(
SELECT * FROM t6 LIMIT -1 OFFSET -1;
]], {
-- <limit-6.2>
- 1, "Only positive integers are allowed in the LIMIT clause"
+ 1, "Failed to execute SQL statement: Only positive integers are allowed in the LIMIT clause"
-- </limit-6.2>
})
@@ -394,7 +394,7 @@ test:do_catchsql_test(
SELECT * FROM t6 LIMIT 2 OFFSET -123;
]], {
-- <limit-6.3>
- 1, "Only positive integers are allowed in the OFFSET clause"
+ 1, "Failed to execute SQL statement: Only positive integers are allowed in the OFFSET clause"
-- </limit-6.3>
})
@@ -414,7 +414,7 @@ test:do_catchsql_test(
SELECT * FROM t6 LIMIT -432 OFFSET 2;
]], {
-- <limit-6.4>
- 1, "Only positive integers are allowed in the LIMIT clause"
+ 1, "Failed to execute SQL statement: Only positive integers are allowed in the LIMIT clause"
-- </limit-6.4>
})
@@ -434,7 +434,7 @@ test:do_catchsql_test(
SELECT * FROM t6 LIMIT -1
]], {
-- <limit-6.5>
- 1, "Only positive integers are allowed in the LIMIT clause"
+ 1, "Failed to execute SQL statement: Only positive integers are allowed in the LIMIT clause"
-- </limit-6.5>
})
@@ -454,7 +454,7 @@ test:do_catchsql_test(
SELECT * FROM t6 LIMIT -1 OFFSET 1
]], {
-- <limit-6.6>
- 1, "Only positive integers are allowed in the LIMIT clause"
+ 1, "Failed to execute SQL statement: Only positive integers are allowed in the LIMIT clause"
-- </limit-6.6>
})
@@ -734,7 +734,7 @@ test:do_test(
return test:catchsql("SELECT x FROM t1 WHERE x<10 LIMIT "..limit)
end, {
-- <limit-10.4>
- 1, "Only positive integers are allowed in the LIMIT clause"
+ 1, "Failed to execute SQL statement: Only positive integers are allowed in the LIMIT clause"
-- </limit-10.4>
})
@@ -745,7 +745,7 @@ test:do_test(
return test:catchsql("SELECT x FROM t1 WHERE x<10 LIMIT "..limit)
end, {
-- <limit-10.5>
- 1, "Only positive integers are allowed in the LIMIT clause"
+ 1, "Failed to execute SQL statement: Only positive integers are allowed in the LIMIT clause"
-- </limit-10.5>
})
@@ -1320,7 +1320,7 @@ test:do_catchsql_test(
SELECT 123 LIMIT -1 OFFSET 0
]], {
-- <limit-14.6.1>
- 1, "Only positive integers are allowed in the LIMIT clause"
+ 1, "Failed to execute SQL statement: Only positive integers are allowed in the LIMIT clause"
-- </limit-14.6.1>
})
@@ -1340,7 +1340,7 @@ test:do_catchsql_test(
SELECT 123 LIMIT -1 OFFSET 1
]], {
-- <limit-14.7.1>
- 1, "Only positive integers are allowed in the LIMIT clause"
+ 1, "Failed to execute SQL statement: Only positive integers are allowed in the LIMIT clause"
-- </limit-14.7.1>
})
diff --git a/test/sql-tap/select4.test.lua b/test/sql-tap/select4.test.lua
index b78091b..1c0804b 100755
--- a/test/sql-tap/select4.test.lua
+++ b/test/sql-tap/select4.test.lua
@@ -990,7 +990,7 @@ test:do_catchsql_test(
SELECT DISTINCT log FROM t1 ORDER BY log LIMIT -1
]], {
-- <select4-10.4.1>
- 1,"Only positive integers are allowed in the LIMIT clause"
+ 1,"Failed to execute SQL statement: Only positive integers are allowed in the LIMIT clause"
-- </select4-10.4.1>
})
test:do_execsql_test(
@@ -1009,7 +1009,7 @@ test:do_catchsql_test(
SELECT DISTINCT log FROM t1 ORDER BY log LIMIT -1 OFFSET 2
]], {
-- <select4-10.5.1>
- 1,"Only positive integers are allowed in the LIMIT clause"
+ 1,"Failed to execute SQL statement: Only positive integers are allowed in the LIMIT clause"
-- </select4-10.5.1>
})
test:do_execsql_test(
@@ -1402,7 +1402,7 @@ test:do_catchsql_test(
SELECT (VALUES(1),(2),(3),(4))
]], {
-- <select4-14.10>
- 1, "SQL error: Expression subquery returned more than 1 row"
+ 1, "Failed to execute SQL statement: Expression subquery returned more than 1 row"
-- </select4-14.10>
})
@@ -1412,7 +1412,7 @@ test:do_catchsql_test(
SELECT (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4)
]], {
-- <select4-14.11>
- 1, "SQL error: Expression subquery returned more than 1 row"
+ 1, "Failed to execute SQL statement: Expression subquery returned more than 1 row"
-- </select4-14.11>
})
diff --git a/test/sql-tap/subselect.test.lua b/test/sql-tap/subselect.test.lua
index 5b71390..ebfdf43 100755
--- a/test/sql-tap/subselect.test.lua
+++ b/test/sql-tap/subselect.test.lua
@@ -350,7 +350,7 @@ test:do_catchsql_test(
SELECT (SELECT a FROM t5);
]], {
-- <subselect-5.1>
- 1, "SQL error: Expression subquery returned more than 1 row"
+ 1, "Failed to execute SQL statement: Expression subquery returned more than 1 row"
-- </subselect-5.1>
})
@@ -360,7 +360,7 @@ test:do_catchsql_test(
SELECT b FROM t5 WHERE a = (SELECT a FROM t5 WHERE b=6);
]], {
-- <subselect-5.2>
- 1, "SQL error: Expression subquery returned more than 1 row"
+ 1, "Failed to execute SQL statement: Expression subquery returned more than 1 row"
-- </subselect-5.2>
})
@@ -380,7 +380,7 @@ test:do_catchsql_test(
SELECT b FROM t1 WHERE a = (SELECT a FROM t1 WHERE b=6 LIMIT (SELECT b FROM t1 WHERE a =1));
]], {
-- <subselect-5.2>
- 1, "SQL error: Expression subquery could be limited only with 1"
+ 1, "Failed to execute SQL statement: Expression subquery could be limited only with 1"
-- </subselect-5.2>
})
diff --git a/test/sql-tap/tkt1473.test.lua b/test/sql-tap/tkt1473.test.lua
index 3e93203..ada18d0 100755
--- a/test/sql-tap/tkt1473.test.lua
+++ b/test/sql-tap/tkt1473.test.lua
@@ -125,7 +125,7 @@ test:do_catchsql_test(
SELECT (SELECT 1 FROM t1 WHERE a=1 UNION ALL SELECT 2 FROM t1 WHERE b=0)
]], {
-- <tkt1473-2.2>
- 1, "SQL error: Expression subquery returned more than 1 row"
+ 1, "Failed to execute SQL statement: Expression subquery returned more than 1 row"
-- </tkt1473-2.2>
})
@@ -145,7 +145,7 @@ test:do_catchsql_test(
SELECT (SELECT 1 FROM t1 WHERE a=1 UNION ALL SELECT 2 FROM t1 WHERE b=4)
]], {
-- <tkt1473-2.4>
- 1, "SQL error: Expression subquery returned more than 1 row"
+ 1, "Failed to execute SQL statement: Expression subquery returned more than 1 row"
-- </tkt1473-2.4>
})
@@ -155,7 +155,7 @@ test:do_catchsql_test(
SELECT (SELECT 1 FROM t1 WHERE a=1 UNION SELECT 2 FROM t1 WHERE b=4)
]], {
-- <tkt1473-2.5>
- 1, "SQL error: Expression subquery returned more than 1 row"
+ 1, "Failed to execute SQL statement: Expression subquery returned more than 1 row"
-- </tkt1473-2.5>
})
@@ -165,7 +165,7 @@ test:do_catchsql_test(
SELECT (SELECT 1 FROM t1 WHERE a=0 UNION ALL SELECT 2 FROM t1 WHERE b=4)
]], {
-- <tkt1473-2.6>
- 1, "SQL error: Expression subquery returned more than 1 row"
+ 1, "Failed to execute SQL statement: Expression subquery returned more than 1 row"
-- </tkt1473-2.6>
})
@@ -206,7 +206,7 @@ test:do_catchsql_test(
(SELECT 1 FROM t1 WHERE a=1 UNION ALL SELECT 2 FROM t1 WHERE b=0)
]], {
-- <tkt1473-3.2>
- 1, "SQL error: Expression subquery returned more than 1 row"
+ 1, "Failed to execute SQL statement: Expression subquery returned more than 1 row"
-- </tkt1473-3.2>
})
@@ -228,7 +228,7 @@ test:do_catchsql_test(
(SELECT 1 FROM t1 WHERE a=1 UNION ALL SELECT 2 FROM t1 WHERE b=4)
]], {
-- <tkt1473-3.4>
- 1, "SQL error: Expression subquery returned more than 1 row"
+ 1, "Failed to execute SQL statement: Expression subquery returned more than 1 row"
-- </tkt1473-3.4>
})
@@ -239,7 +239,7 @@ test:do_catchsql_test(
(SELECT 1 FROM t1 WHERE a=1 UNION SELECT 2 FROM t1 WHERE b=4)
]], {
-- <tkt1473-3.5>
- 1, "SQL error: Expression subquery returned more than 1 row"
+ 1, "Failed to execute SQL statement: Expression subquery returned more than 1 row"
-- </tkt1473-3.5>
})
@@ -250,7 +250,7 @@ test:do_catchsql_test(
(SELECT 1 FROM t1 WHERE a=0 UNION ALL SELECT 2 FROM t1 WHERE b=4)
]], {
-- <tkt1473-3.6>
- 1, "SQL error: Expression subquery returned more than 1 row"
+ 1, "Failed to execute SQL statement: Expression subquery returned more than 1 row"
-- </tkt1473-3.6>
})
@@ -359,7 +359,7 @@ test:do_catchsql_test(
)
]], {
-- <tkt1473-4.3>
- 1, "SQL error: Expression subquery returned more than 1 row"
+ 1, "Failed to execute SQL statement: Expression subquery returned more than 1 row"
-- </tkt1473-4.3>
})
@@ -389,7 +389,7 @@ test:do_catchsql_test(
)
]], {
-- <tkt1473-4.4>
- 1, "SQL error: Expression subquery returned more than 1 row"
+ 1, "Failed to execute SQL statement: Expression subquery returned more than 1 row"
-- </tkt1473-4.4>
})
@@ -419,7 +419,7 @@ test:do_catchsql_test(
)
]], {
-- <tkt1473-4.5>
- 1, "SQL error: Expression subquery returned more than 1 row"
+ 1, "Failed to execute SQL statement: Expression subquery returned more than 1 row"
-- </tkt1473-4.5>
})
@@ -449,7 +449,7 @@ test:do_catchsql_test(
)
]], {
-- <tkt1473-4.6>
- 1, "SQL error: Expression subquery returned more than 1 row"
+ 1, "Failed to execute SQL statement: Expression subquery returned more than 1 row"
-- </tkt1473-4.6>
})
@@ -509,7 +509,7 @@ test:do_catchsql_test(
)
]], {
-- <tkt1473-5.3>
- 1, "SQL error: Expression subquery returned more than 1 row"
+ 1, "Failed to execute SQL statement: Expression subquery returned more than 1 row"
-- </tkt1473-5.3>
})
@@ -539,7 +539,7 @@ test:do_catchsql_test(
)
]], {
-- <tkt1473-5.4>
- 1, "SQL error: Expression subquery returned more than 1 row"
+ 1, "Failed to execute SQL statement: Expression subquery returned more than 1 row"
-- </tkt1473-5.4>
})
@@ -569,7 +569,7 @@ test:do_catchsql_test(
)
]], {
-- <tkt1473-5.5>
- 1, "SQL error: Expression subquery returned more than 1 row"
+ 1, "Failed to execute SQL statement: Expression subquery returned more than 1 row"
-- </tkt1473-5.5>
})
@@ -599,7 +599,7 @@ test:do_catchsql_test(
)
]], {
-- <tkt1473-5.6>
- 1, "SQL error: Expression subquery returned more than 1 row"
+ 1, "Failed to execute SQL statement: Expression subquery returned more than 1 row"
-- </tkt1473-5.6>
})
@@ -659,7 +659,7 @@ test:do_catchsql_test(
)
]], {
-- <tkt1473-6.3>
- 1, "SQL error: Expression subquery returned more than 1 row"
+ 1, "Failed to execute SQL statement: Expression subquery returned more than 1 row"
-- </tkt1473-6.3>
})
@@ -689,7 +689,7 @@ test:do_catchsql_test(
)
]], {
-- <tkt1473-6.4>
- 1, "SQL error: Expression subquery returned more than 1 row"
+ 1, "Failed to execute SQL statement: Expression subquery returned more than 1 row"
-- </tkt1473-6.4>
})
diff --git a/test/sql/iproto.result b/test/sql/iproto.result
index 73497b4..9639ba7 100644
--- a/test/sql/iproto.result
+++ b/test/sql/iproto.result
@@ -164,15 +164,18 @@ cn:execute('select * from test limit ?', {2})
...
cn:execute('select * from test limit ?', {-2})
---
-- error: Only positive integers are allowed in the LIMIT clause
+- error: 'Failed to execute SQL statement: Only positive integers are allowed in the
+ LIMIT clause'
...
cn:execute('select * from test limit ?', {2.7})
---
-- error: Only positive integers are allowed in the LIMIT clause
+- error: 'Failed to execute SQL statement: Only positive integers are allowed in the
+ LIMIT clause'
...
cn:execute('select * from test limit ?', {'Hello'})
---
-- error: Only positive integers are allowed in the LIMIT clause
+- error: 'Failed to execute SQL statement: Only positive integers are allowed in the
+ LIMIT clause'
...
cn:execute('select * from test limit 1 offset ?', {2})
---
@@ -188,15 +191,18 @@ cn:execute('select * from test limit 1 offset ?', {2})
...
cn:execute('select * from test limit 1 offset ?', {-2})
---
-- error: Only positive integers are allowed in the OFFSET clause
+- error: 'Failed to execute SQL statement: Only positive integers are allowed in the
+ OFFSET clause'
...
cn:execute('select * from test limit 1 offset ?', {2.7})
---
-- error: Only positive integers are allowed in the OFFSET clause
+- error: 'Failed to execute SQL statement: Only positive integers are allowed in the
+ OFFSET clause'
...
cn:execute('select * from test limit 1 offset ?', {'Hello'})
---
-- error: Only positive integers are allowed in the OFFSET clause
+- error: 'Failed to execute SQL statement: Only positive integers are allowed in the
+ OFFSET clause'
...
-- gh-2608 SQL iproto DDL
cn:execute('create table test2(id int primary key, a int, b int, c int)')
diff --git a/test/sql/types.result b/test/sql/types.result
index bc4518c..f05b856 100644
--- a/test/sql/types.result
+++ b/test/sql/types.result
@@ -351,11 +351,13 @@ box.execute("SELECT true IN (1, 'abc', false)")
...
box.execute("SELECT 1 LIMIT true;")
---
-- error: Only positive integers are allowed in the LIMIT clause
+- error: 'Failed to execute SQL statement: Only positive integers are allowed in the
+ LIMIT clause'
...
box.execute("SELECT 1 LIMIT 1 OFFSET true;")
---
-- error: Only positive integers are allowed in the OFFSET clause
+- error: 'Failed to execute SQL statement: Only positive integers are allowed in the
+ OFFSET clause'
...
box.execute("SELECT 'abc' || true;")
---
@@ -519,7 +521,8 @@ box.execute("SELECT b FROM t GROUP BY b LIMIT 1;")
...
box.execute("SELECT b FROM t LIMIT true;")
---
-- error: Only positive integers are allowed in the LIMIT clause
+- error: 'Failed to execute SQL statement: Only positive integers are allowed in the
+ LIMIT clause'
...
-- Most of aggregates don't accept boolean arguments.
--
--
2.7.4
^ permalink raw reply [flat|nested] 31+ messages in thread
* [tarantool-patches] [PATCH v1 04/12] sql: make SQL_TARANTOOL_ERROR the only errcode of OP_Halt
2019-05-05 12:17 [tarantool-patches] [PATCH v1 00/12] sql: set errors in VDBE using diag_set() imeevma
` (2 preceding siblings ...)
2019-05-05 12:17 ` [tarantool-patches] [PATCH v1 03/12] sql: rework diag_set() in OP_Halt imeevma
@ 2019-05-05 12:17 ` imeevma
2019-05-15 13:18 ` [tarantool-patches] " n.pettik
2019-05-05 12:17 ` [tarantool-patches] [PATCH v1 05/12] sql: remove error SQL_INTERRUPT imeevma
` (7 subsequent siblings)
11 siblings, 1 reply; 31+ messages in thread
From: imeevma @ 2019-05-05 12:17 UTC (permalink / raw)
To: korablev; +Cc: tarantool-patches
Currently, in OP_Halt, you can get a SQL error other than
SQL_TARANTOOL_ERROR, for example, the SQL_CONSTRAINT error. After
this patch, all errors going through OP_Halt will have SQL error
code SQL_TARANTOOL_ERROR and have diag set.
Part of #4074
---
src/box/sql/build.c | 20 --------------------
src/box/sql/expr.c | 7 ++++---
src/box/sql/fk_constraint.c | 7 +++----
src/box/sql/insert.c | 29 ++++++++++++++---------------
src/box/sql/sqlInt.h | 1 -
src/box/sql/vdbe.c | 23 ++++-------------------
6 files changed, 25 insertions(+), 62 deletions(-)
diff --git a/src/box/sql/build.c b/src/box/sql/build.c
index 28dcbc3..32c101d 100644
--- a/src/box/sql/build.c
+++ b/src/box/sql/build.c
@@ -2972,26 +2972,6 @@ sql_set_multi_write(struct Parse *parse_context, bool is_set)
pToplevel->isMultiWrite |= is_set;
}
-/*
- * Code an OP_Halt that causes the vdbe to return an SQL_CONSTRAINT
- * error. The onError parameter determines which (if any) of the statement
- * and/or current transaction is rolled back.
- */
-void
-sqlHaltConstraint(Parse * pParse, /* Parsing context */
- int errCode, /* extended error code */
- int onError, /* Constraint type */
- char *p4, /* Error message */
- i8 p4type, /* P4_STATIC or P4_TRANSIENT */
- u8 p5Errmsg /* P5_ErrMsg type */
- )
-{
- Vdbe *v = sqlGetVdbe(pParse);
- assert((errCode & 0xff) == SQL_CONSTRAINT);
- sqlVdbeAddOp4(v, OP_Halt, errCode, onError, 0, p4, p4type);
- sqlVdbeChangeP5(v, p5Errmsg);
-}
-
#ifndef SQL_OMIT_CTE
/*
* This routine is invoked once per CTE by the parser while parsing a
diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c
index 6ac42d7..a4a2d71 100644
--- a/src/box/sql/expr.c
+++ b/src/box/sql/expr.c
@@ -4386,9 +4386,10 @@ sqlExprCodeTarget(Parse * pParse, Expr * pExpr, int target)
ON_CONFLICT_ACTION_IGNORE, 0,
pExpr->u.zToken, 0);
} else {
- sqlHaltConstraint(pParse, SQL_CONSTRAINT_TRIGGER,
- pExpr->on_conflict_action,
- pExpr->u.zToken, 0, 0);
+ sqlVdbeAddOp4(v, OP_Halt, SQL_TARANTOOL_ERROR,
+ pExpr->on_conflict_action, 0,
+ pExpr->u.zToken, 0);
+ sqlVdbeChangeP5(v, ER_SQL_EXECUTE);
}
break;
}
diff --git a/src/box/sql/fk_constraint.c b/src/box/sql/fk_constraint.c
index 7d36edc..602f439 100644
--- a/src/box/sql/fk_constraint.c
+++ b/src/box/sql/fk_constraint.c
@@ -287,10 +287,9 @@ fk_constraint_lookup_parent(struct Parse *parse_context, struct space *parent,
* transaction.
*/
assert(incr_count == 1);
- sqlHaltConstraint(parse_context,
- SQL_CONSTRAINT_FOREIGNKEY,
- ON_CONFLICT_ACTION_ABORT, 0, P4_STATIC,
- P5_ConstraintFK);
+ sqlVdbeAddOp4(v, OP_Halt, SQL_TARANTOOL_ERROR, 0, 0, "FOREIGN "\
+ "KEY constraint failed", P4_STATIC);
+ sqlVdbeChangeP5(v, ER_SQL_EXECUTE);
} else {
sqlVdbeAddOp2(v, OP_FkCounter, fk_def->is_deferred,
incr_count);
diff --git a/src/box/sql/insert.c b/src/box/sql/insert.c
index f725478..dcadd7c 100644
--- a/src/box/sql/insert.c
+++ b/src/box/sql/insert.c
@@ -865,7 +865,6 @@ vdbe_emit_constraint_checks(struct Parse *parse_context, struct space *space,
enum on_conflict_action on_conflict,
int ignore_label, int *upd_cols)
{
- struct sql *db = parse_context->db;
struct Vdbe *v = sqlGetVdbe(parse_context);
assert(v != NULL);
bool is_update = upd_cols != NULL;
@@ -895,20 +894,18 @@ vdbe_emit_constraint_checks(struct Parse *parse_context, struct space *space,
if (on_conflict_nullable == ON_CONFLICT_ACTION_REPLACE &&
dflt == NULL)
on_conflict_nullable = ON_CONFLICT_ACTION_ABORT;
- char *err_msg;
+ const char *err;
int addr;
switch (on_conflict_nullable) {
case ON_CONFLICT_ACTION_ABORT:
case ON_CONFLICT_ACTION_ROLLBACK:
case ON_CONFLICT_ACTION_FAIL:
- err_msg = sqlMPrintf(db, "%s.%s", def->name,
- def->fields[i].name);
- sqlVdbeAddOp3(v, OP_HaltIfNull,
- SQL_CONSTRAINT_NOTNULL,
- on_conflict_nullable,
- new_tuple_reg + i);
- sqlVdbeAppendP4(v, err_msg, P4_DYNAMIC);
- sqlVdbeChangeP5(v, P5_ConstraintNotNull);
+ err = tt_sprintf("NOT NULL constraint failed: %s.%s",
+ def->name, def->fields[i].name);
+ sqlVdbeAddOp4(v, OP_HaltIfNull, SQL_TARANTOOL_ERROR,
+ on_conflict_nullable, new_tuple_reg + i,
+ err, P4_STATIC);
+ sqlVdbeChangeP5(v, ER_SQL_EXECUTE);
break;
case ON_CONFLICT_ACTION_IGNORE:
sqlVdbeAddOp2(v, OP_IsNull, new_tuple_reg + i,
@@ -951,11 +948,13 @@ vdbe_emit_constraint_checks(struct Parse *parse_context, struct space *space,
char *name = checks->a[i].zName;
if (name == NULL)
name = def->name;
- sqlHaltConstraint(parse_context,
- SQL_CONSTRAINT_CHECK,
- on_conflict_check, name,
- P4_TRANSIENT,
- P5_ConstraintCheck);
+ const char *err =
+ tt_sprintf("CHECK constraint failed: "\
+ "%s", name);
+ sqlVdbeAddOp4(v, OP_Halt, SQL_TARANTOOL_ERROR,
+ on_conflict_check, 0, err,
+ P4_STATIC);
+ sqlVdbeChangeP5(v, ER_SQL_EXECUTE);
}
sqlVdbeResolveLabel(v, all_ok);
}
diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
index 05a4042..5c71c51 100644
--- a/src/box/sql/sqlInt.h
+++ b/src/box/sql/sqlInt.h
@@ -3912,7 +3912,6 @@ vdbe_emit_insertion_completion(struct Vdbe *v, struct space *space,
void
sql_set_multi_write(Parse *, bool);
-void sqlHaltConstraint(Parse *, int, int, char *, i8, u8);
Expr *sqlExprDup(sql *, Expr *, int);
SrcList *sqlSrcListDup(sql *, SrcList *, int);
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index 9f0d760..85cec85 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -1031,25 +1031,10 @@ case OP_Halt: {
p->errorAction = (u8)pOp->p2;
p->pc = pcx;
if (p->rc) {
- if (p->rc == SQL_TARANTOOL_ERROR) {
- if (pOp->p4.z != NULL)
- diag_set(ClientError, pOp->p5, pOp->p4.z);
- assert(! diag_is_empty(diag_get()));
- } else if (pOp->p5 != 0) {
- static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK",
- "FOREIGN KEY" };
- testcase( pOp->p5==1);
- testcase( pOp->p5==2);
- testcase( pOp->p5==3);
- testcase( pOp->p5==4);
- sqlVdbeError(p, "%s constraint failed", azType[pOp->p5-1]);
- if (pOp->p4.z) {
- p->zErrMsg = sqlMPrintf(db, "%z: %s", p->zErrMsg, pOp->p4.z);
- }
- } else {
- sqlVdbeError(p, "%s", pOp->p4.z);
- }
- sql_log(pOp->p1, "abort at %d in [%s]: %s", pcx, p->zSql, p->zErrMsg);
+ assert(p->rc == SQL_TARANTOOL_ERROR);
+ if (pOp->p4.z != NULL)
+ diag_set(ClientError, pOp->p5, pOp->p4.z);
+ assert(! diag_is_empty(diag_get()));
}
rc = sqlVdbeHalt(p);
assert(rc==SQL_BUSY || rc==SQL_OK || rc==SQL_ERROR);
--
2.7.4
^ permalink raw reply [flat|nested] 31+ messages in thread
* [tarantool-patches] Re: [PATCH v1 04/12] sql: make SQL_TARANTOOL_ERROR the only errcode of OP_Halt
2019-05-05 12:17 ` [tarantool-patches] [PATCH v1 04/12] sql: make SQL_TARANTOOL_ERROR the only errcode of OP_Halt imeevma
@ 2019-05-15 13:18 ` n.pettik
2019-05-25 9:18 ` Imeev Mergen
0 siblings, 1 reply; 31+ messages in thread
From: n.pettik @ 2019-05-15 13:18 UTC (permalink / raw)
To: tarantool-patches; +Cc: Imeev Mergen
> On 5 May 2019, at 15:17, imeevma@tarantool.org wrote:
>
> Currently, in OP_Halt, you can get a SQL error other than
> SQL_TARANTOOL_ERROR, for example, the SQL_CONSTRAINT error. After
> this patch, all errors going through OP_Halt will have SQL error
> code SQL_TARANTOOL_ERROR and have diag set.
>
> diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
> index 9f0d760..85cec85 100644
> --- a/src/box/sql/vdbe.c
> +++ b/src/box/sql/vdbe.c
> @@ -1031,25 +1031,10 @@ case OP_Halt: {
> p->errorAction = (u8)pOp->p2;
> p->pc = pcx;
> if (p->rc) {
> - if (p->rc == SQL_TARANTOOL_ERROR) {
> - if (pOp->p4.z != NULL)
> - diag_set(ClientError, pOp->p5, pOp->p4.z);
> - assert(! diag_is_empty(diag_get()));
> - } else if (pOp->p5 != 0) {
> - static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK",
> - "FOREIGN KEY" };
> - testcase( pOp->p5==1);
> - testcase( pOp->p5==2);
> - testcase( pOp->p5==3);
> - testcase( pOp->p5==4);
> - sqlVdbeError(p, "%s constraint failed", azType[pOp->p5-1]);
> - if (pOp->p4.z) {
> - p->zErrMsg = sqlMPrintf(db, "%z: %s", p->zErrMsg, pOp->p4.z);
> - }
> - } else {
> - sqlVdbeError(p, "%s", pOp->p4.z);
> - }
> - sql_log(pOp->p1, "abort at %d in [%s]: %s", pcx, p->zSql, p->zErrMsg);
> + assert(p->rc == SQL_TARANTOOL_ERROR);
Still don’t understand why can’t we use only 0/-1 for rc.
> + if (pOp->p4.z != NULL)
> + diag_set(ClientError, pOp->p5, pOp->p4.z);
> + assert(! diag_is_empty(diag_get()));
> }
> rc = sqlVdbeHalt(p);
> assert(rc==SQL_BUSY || rc==SQL_OK || rc==SQL_ERROR);
> --
> 2.7.4
>
>
^ permalink raw reply [flat|nested] 31+ messages in thread
* [tarantool-patches] Re: [PATCH v1 04/12] sql: make SQL_TARANTOOL_ERROR the only errcode of OP_Halt
2019-05-15 13:18 ` [tarantool-patches] " n.pettik
@ 2019-05-25 9:18 ` Imeev Mergen
0 siblings, 0 replies; 31+ messages in thread
From: Imeev Mergen @ 2019-05-25 9:18 UTC (permalink / raw)
To: n.pettik, tarantool-patches
On 5/15/19 4:18 PM, n.pettik wrote:
>
>> On 5 May 2019, at 15:17, imeevma@tarantool.org wrote:
>>
>> Currently, in OP_Halt, you can get a SQL error other than
>> SQL_TARANTOOL_ERROR, for example, the SQL_CONSTRAINT error. After
>> this patch, all errors going through OP_Halt will have SQL error
>> code SQL_TARANTOOL_ERROR and have diag set.
>>
>> diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
>> index 9f0d760..85cec85 100644
>> --- a/src/box/sql/vdbe.c
>> +++ b/src/box/sql/vdbe.c
>> @@ -1031,25 +1031,10 @@ case OP_Halt: {
>> p->errorAction = (u8)pOp->p2;
>> p->pc = pcx;
>> if (p->rc) {
>> - if (p->rc == SQL_TARANTOOL_ERROR) {
>> - if (pOp->p4.z != NULL)
>> - diag_set(ClientError, pOp->p5, pOp->p4.z);
>> - assert(! diag_is_empty(diag_get()));
>> - } else if (pOp->p5 != 0) {
>> - static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK",
>> - "FOREIGN KEY" };
>> - testcase( pOp->p5==1);
>> - testcase( pOp->p5==2);
>> - testcase( pOp->p5==3);
>> - testcase( pOp->p5==4);
>> - sqlVdbeError(p, "%s constraint failed", azType[pOp->p5-1]);
>> - if (pOp->p4.z) {
>> - p->zErrMsg = sqlMPrintf(db, "%z: %s", p->zErrMsg, pOp->p4.z);
>> - }
>> - } else {
>> - sqlVdbeError(p, "%s", pOp->p4.z);
>> - }
>> - sql_log(pOp->p1, "abort at %d in [%s]: %s", pcx, p->zSql, p->zErrMsg);
>> + assert(p->rc == SQL_TARANTOOL_ERROR);
> Still don’t understand why can’t we use only 0/-1 for rc.
This is done in one of the following patches.
^ permalink raw reply [flat|nested] 31+ messages in thread
* [tarantool-patches] [PATCH v1 05/12] sql: remove error SQL_INTERRUPT
2019-05-05 12:17 [tarantool-patches] [PATCH v1 00/12] sql: set errors in VDBE using diag_set() imeevma
` (3 preceding siblings ...)
2019-05-05 12:17 ` [tarantool-patches] [PATCH v1 04/12] sql: make SQL_TARANTOOL_ERROR the only errcode of OP_Halt imeevma
@ 2019-05-05 12:17 ` imeevma
2019-05-15 13:18 ` [tarantool-patches] " n.pettik
2019-05-05 12:17 ` [tarantool-patches] [PATCH v1 06/12] sql: remove error SQL_MISMATCH imeevma
` (6 subsequent siblings)
11 siblings, 1 reply; 31+ messages in thread
From: imeevma @ 2019-05-05 12:17 UTC (permalink / raw)
To: korablev; +Cc: tarantool-patches
Since the interrupt system is no longer used in SQL, the
SQL_INTERRUPT error is out of date and should be removed. Also
this patch removes currently unused progress callback system.
---
src/box/sql/main.c | 1 -
src/box/sql/malloc.c | 4 ---
src/box/sql/sqlInt.h | 11 -------
src/box/sql/tokenize.c | 3 --
src/box/sql/vdbe.c | 84 ++------------------------------------------------
src/box/sql/vdbeapi.c | 7 -----
src/box/sql/vdbeaux.c | 41 ++++++++++--------------
7 files changed, 19 insertions(+), 132 deletions(-)
diff --git a/src/box/sql/main.c b/src/box/sql/main.c
index ed07553..0c6ad47 100644
--- a/src/box/sql/main.c
+++ b/src/box/sql/main.c
@@ -371,7 +371,6 @@ sqlErrStr(int rc)
/* SQL_BUSY */ "database is locked",
/* SQL_LOCKED */ "database table is locked",
/* SQL_NOMEM */ "out of memory",
- /* SQL_INTERRUPT */ "interrupted",
/* SQL_IOERR */ "disk I/O error",
/* SQL_NOTFOUND */ "unknown operation",
/* SQL_FULL */ "database or disk is full",
diff --git a/src/box/sql/malloc.c b/src/box/sql/malloc.c
index d6f99b4..dbc6846 100644
--- a/src/box/sql/malloc.c
+++ b/src/box/sql/malloc.c
@@ -898,9 +898,6 @@ sqlOomFault(sql * db)
{
if (db->mallocFailed == 0 && db->bBenignMalloc == 0) {
db->mallocFailed = 1;
- if (db->nVdbeExec > 0) {
- db->u1.isInterrupted = 1;
- }
db->lookaside.bDisable++;
}
}
@@ -917,7 +914,6 @@ sqlOomClear(sql * db)
{
if (db->mallocFailed && db->nVdbeExec == 0) {
db->mallocFailed = 0;
- db->u1.isInterrupted = 0;
assert(db->lookaside.bDisable > 0);
db->lookaside.bDisable--;
}
diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
index 5c71c51..7f47da6 100644
--- a/src/box/sql/sqlInt.h
+++ b/src/box/sql/sqlInt.h
@@ -370,8 +370,6 @@ enum sql_ret_code {
SQL_LOCKED,
/** A malloc() failed. */
SQL_NOMEM,
- /** Operation terminated by sql_interrupt(). */
- SQL_INTERRUPT,
/** Some kind of disk I/O error occurred. */
SQL_IOERR,
/** Unknown opcode in sql_file_control(). */
@@ -1468,16 +1466,7 @@ struct sql {
void (*xUpdateCallback) (void *, int, const char *, const char *,
sql_int64);
sql_value *pErr; /* Most recent error message */
- union {
- volatile int isInterrupted; /* True if sql_interrupt has been called */
- double notUsed1; /* Spacer */
- } u1;
Lookaside lookaside; /* Lookaside malloc configuration */
-#ifndef SQL_OMIT_PROGRESS_CALLBACK
- int (*xProgress) (void *); /* The progress callback */
- void *pProgressArg; /* Argument to the progress callback */
- unsigned nProgressOps; /* Number of opcodes for progress callback */
-#endif
Hash aFunc; /* Hash table of connection functions */
int *pnBytesFreed; /* If not NULL, increment this in DbFree() */
};
diff --git a/src/box/sql/tokenize.c b/src/box/sql/tokenize.c
index 8cc3532..5cb4b7a 100644
--- a/src/box/sql/tokenize.c
+++ b/src/box/sql/tokenize.c
@@ -457,9 +457,6 @@ sqlRunParser(Parse * pParse, const char *zSql)
assert(zSql != 0);
mxSqlLen = db->aLimit[SQL_LIMIT_SQL_LENGTH];
- if (db->nVdbeActive == 0) {
- db->u1.isInterrupted = 0;
- }
pParse->zTail = zSql;
i = 0;
/* sqlParserTrace(stdout, "parser: "); */
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index 85cec85..c2eec93 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -92,18 +92,6 @@ int sql_xfer_count = 0;
#endif
/*
- * When this global variable is positive, it gets decremented once before
- * each instruction in the VDBE. When it reaches zero, the u1.isInterrupted
- * field of the sql structure is set in order to simulate an interrupt.
- *
- * This facility is used for testing purposes only. It does not function
- * in an ordinary build.
- */
-#ifdef SQL_TEST
-int sql_interrupt_count = 0;
-#endif
-
-/*
* The next global variable is incremented each type the OP_Sort opcode
* is executed. The test procedures use this information to make sure that
* sorting is occurring or not occurring at appropriate times. This variable
@@ -631,9 +619,6 @@ int sqlVdbeExec(Vdbe *p)
sql *db = p->db; /* The database */
int iCompare = 0; /* Result of last comparison */
unsigned nVmStep = 0; /* Number of virtual machine steps */
-#ifndef SQL_OMIT_PROGRESS_CALLBACK
- unsigned nProgressLimit = 0;/* Invoke xProgress() when nVmStep reaches this */
-#endif
Mem *aMem = p->aMem; /* Copy of p->aMem */
Mem *pIn1 = 0; /* 1st input operand */
Mem *pIn2 = 0; /* 2nd input operand */
@@ -658,15 +643,7 @@ int sqlVdbeExec(Vdbe *p)
p->iCurrentTime = 0;
assert(p->explain==0);
p->pResultSet = 0;
- if (db->u1.isInterrupted) goto abort_due_to_interrupt;
sqlVdbeIOTraceSql(p);
-#ifndef SQL_OMIT_PROGRESS_CALLBACK
- if (db->xProgress) {
- u32 iPrior = p->aCounter[SQL_STMTSTATUS_VM_STEP];
- assert(0 < db->nProgressOps);
- nProgressLimit = db->nProgressOps - (iPrior % db->nProgressOps);
- }
-#endif
#ifdef SQL_DEBUG
sqlBeginBenignMalloc();
if (p->pc==0
@@ -810,40 +787,7 @@ int sqlVdbeExec(Vdbe *p)
* to the current line should be indented for EXPLAIN output.
*/
case OP_Goto: { /* jump */
- jump_to_p2_and_check_for_interrupt:
- pOp = &aOp[pOp->p2 - 1];
-
- /* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev,
- * OP_RowSetNext, or OP_SorterNext) all jump here upon
- * completion. Check to see if sql_interrupt() has been called
- * or if the progress callback needs to be invoked.
- *
- * This code uses unstructured "goto" statements and does not look clean.
- * But that is not due to sloppy coding habits. The code is written this
- * way for performance, to avoid having to run the interrupt and progress
- * checks on every opcode. This helps sql_step() to run about 1.5%
- * faster according to "valgrind --tool=cachegrind"
- */
- check_for_interrupt:
- if (db->u1.isInterrupted) goto abort_due_to_interrupt;
-#ifndef SQL_OMIT_PROGRESS_CALLBACK
- /* Call the progress callback if it is configured and the required number
- * of VDBE ops have been executed (either since this invocation of
- * sqlVdbeExec() or since last time the progress callback was called).
- * If the progress callback returns non-zero, exit the virtual machine with
- * a return code SQL_ABORT.
- */
- if (db->xProgress!=0 && nVmStep>=nProgressLimit) {
- assert(db->nProgressOps!=0);
- nProgressLimit = nVmStep + db->nProgressOps - (nVmStep%db->nProgressOps);
- if (db->xProgress(db->pProgressArg)) {
- rc = SQL_INTERRUPT;
- goto abort_due_to_error;
- }
- }
-#endif
-
- break;
+ goto jump_to_p2;
}
/* Opcode: Gosub P1 P2 * * *
@@ -1387,18 +1331,6 @@ case OP_ResultRow: {
assert(pOp->p1>0);
assert(pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1);
-#ifndef SQL_OMIT_PROGRESS_CALLBACK
- /* Run the progress counter just before returning.
- */
- if (db->xProgress!=0
- && nVmStep>=nProgressLimit
- && db->xProgress(db->pProgressArg)!=0
- ) {
- rc = SQL_INTERRUPT;
- goto abort_due_to_error;
- }
-#endif
-
/* If this statement has violated immediate foreign key constraints, do
* not return the number of rows modified. And do not RELEASE the statement
* transaction. It needs to be rolled back.
@@ -4340,11 +4272,11 @@ case OP_Next: /* jump */
#ifdef SQL_TEST
sql_search_count++;
#endif
- goto jump_to_p2_and_check_for_interrupt;
+ goto jump_to_p2;
} else {
pC->nullRow = 1;
}
- goto check_for_interrupt;
+ break;
}
/* Opcode: SorterInsert P1 P2 * * *
@@ -5491,14 +5423,4 @@ no_mem:
sqlVdbeError(p, "out of memory");
rc = SQL_NOMEM;
goto abort_due_to_error;
-
- /* Jump to here if the sql_interrupt() API sets the interrupt
- * flag.
- */
-abort_due_to_interrupt:
- assert(db->u1.isInterrupted);
- rc = db->mallocFailed ? SQL_NOMEM : SQL_INTERRUPT;
- p->rc = rc;
- sqlVdbeError(p, "%s", sqlErrStr(rc));
- goto abort_due_to_error;
}
diff --git a/src/box/sql/vdbeapi.c b/src/box/sql/vdbeapi.c
index d286856..909db8c 100644
--- a/src/box/sql/vdbeapi.c
+++ b/src/box/sql/vdbeapi.c
@@ -537,13 +537,6 @@ sqlStep(Vdbe * p)
goto end_of_step;
}
if (p->pc < 0) {
- /* If there are no other statements currently running, then
- * reset the interrupt flag. This prevents a call to sql_interrupt
- * from interrupting a statement that has not yet started.
- */
- if (db->nVdbeActive == 0) {
- db->u1.isInterrupted = 0;
- }
#ifndef SQL_OMIT_TRACE
if ((db->xProfile || (db->mTrace & SQL_TRACE_PROFILE) != 0)
diff --git a/src/box/sql/vdbeaux.c b/src/box/sql/vdbeaux.c
index 140bb97..27fa5b2 100644
--- a/src/box/sql/vdbeaux.c
+++ b/src/box/sql/vdbeaux.c
@@ -1486,10 +1486,6 @@ sqlVdbeList(Vdbe * p)
if (i >= nRow) {
p->rc = SQL_OK;
rc = SQL_DONE;
- } else if (db->u1.isInterrupted) {
- p->rc = SQL_INTERRUPT;
- rc = SQL_ERROR;
- sqlVdbeError(p, sqlErrStr(p->rc));
} else {
char *zP4;
Op *pOp;
@@ -2208,7 +2204,6 @@ sqlVdbeHalt(Vdbe * p)
* SQL_NOMEM
* SQL_IOERR
* SQL_FULL
- * SQL_INTERRUPT
*
* Then the internal cache might have been left in an inconsistent
* state. We need to rollback the statement transaction, if there is
@@ -2234,13 +2229,11 @@ sqlVdbeHalt(Vdbe * p)
/* Check for one of the special errors */
mrc = p->rc & 0xff;
- isSpecialError = mrc == SQL_NOMEM || mrc == SQL_IOERR
- || mrc == SQL_INTERRUPT || mrc == SQL_FULL;
+ isSpecialError = mrc == SQL_NOMEM || mrc == SQL_IOERR ||
+ mrc == SQL_FULL;
if (isSpecialError) {
- /* If the query was read-only and the error code is SQL_INTERRUPT,
- * no rollback is necessary. Otherwise, at least a savepoint
- * transaction must be rolled back to restore the database to a
- * consistent state.
+ /* At least a savepoint transaction must be rolled back
+ * to restore the database to a consistent state.
*
* Even if the statement is read-only, it is important to perform
* a statement or transaction rollback operation. If the error
@@ -2249,20 +2242,18 @@ sqlVdbeHalt(Vdbe * p)
* pagerStress() in pager.c), the rollback is required to restore
* the pager to a consistent state.
*/
- if (mrc != SQL_INTERRUPT) {
- if ((mrc == SQL_NOMEM || mrc == SQL_FULL)
- && box_txn()) {
- eStatementOp = SAVEPOINT_ROLLBACK;
- } else {
- /* We are forced to roll back the active transaction. Before doing
- * so, abort any other statements this handle currently has active.
- */
- box_txn_rollback();
- closeCursorsAndFree(p);
- sqlRollbackAll(p);
- sqlCloseSavepoints(p);
- p->nChange = 0;
- }
+ if ((mrc == SQL_NOMEM || mrc == SQL_FULL)
+ && box_txn()) {
+ eStatementOp = SAVEPOINT_ROLLBACK;
+ } else {
+ /* We are forced to roll back the active transaction. Before doing
+ * so, abort any other statements this handle currently has active.
+ */
+ box_txn_rollback();
+ closeCursorsAndFree(p);
+ sqlRollbackAll(p);
+ sqlCloseSavepoints(p);
+ p->nChange = 0;
}
}
--
2.7.4
^ permalink raw reply [flat|nested] 31+ messages in thread
* [tarantool-patches] [PATCH v1 06/12] sql: remove error SQL_MISMATCH
2019-05-05 12:17 [tarantool-patches] [PATCH v1 00/12] sql: set errors in VDBE using diag_set() imeevma
` (4 preceding siblings ...)
2019-05-05 12:17 ` [tarantool-patches] [PATCH v1 05/12] sql: remove error SQL_INTERRUPT imeevma
@ 2019-05-05 12:17 ` imeevma
2019-05-15 13:19 ` [tarantool-patches] " n.pettik
2019-05-05 12:17 ` [tarantool-patches] [PATCH v1 07/12] sql: set errors in VDBE using diag_set() imeevma
` (5 subsequent siblings)
11 siblings, 1 reply; 31+ messages in thread
From: imeevma @ 2019-05-05 12:17 UTC (permalink / raw)
To: korablev; +Cc: tarantool-patches
This patch replaces SQL error SQL_MISMATCH by Tarantool error
ER_SQL_TYPE_MISMATCH.
---
src/box/sql/main.c | 1 -
src/box/sql/sqlInt.h | 2 --
src/box/sql/vdbe.c | 6 ++++--
test/sql-tap/autoinc.test.lua | 2 +-
4 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/src/box/sql/main.c b/src/box/sql/main.c
index 0c6ad47..a3c6aa1 100644
--- a/src/box/sql/main.c
+++ b/src/box/sql/main.c
@@ -378,7 +378,6 @@ sqlErrStr(int rc)
/* SQL_SCHEMA */ "database schema has changed",
/* SQL_TOOBIG */ "string or blob too big",
/* SQL_CONSTRAINT */ "constraint failed",
- /* SQL_MISMATCH */ "datatype mismatch",
/* SQL_MISUSE */
"library routine called out of sequence",
/* SQL_RANGE */ "bind or column index out of range",
diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
index 7f47da6..3981fbf 100644
--- a/src/box/sql/sqlInt.h
+++ b/src/box/sql/sqlInt.h
@@ -384,8 +384,6 @@ enum sql_ret_code {
SQL_TOOBIG,
/** Abort due to constraint violation. */
SQL_CONSTRAINT,
- /** Data type mismatch. */
- SQL_MISMATCH,
/** Library used incorrectly. */
SQL_MISUSE,
/** 2nd parameter to sql_bind out of range. */
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index c2eec93..bdf7429 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -1853,7 +1853,7 @@ case OP_AddImm: { /* in1 */
* Force the value in register P1 to be an integer. If the value
* in P1 is not an integer and cannot be converted into an integer
* without data loss, then jump immediately to P2, or if P2==0
- * raise an SQL_MISMATCH exception.
+ * raise an ER_SQL_TYPE_MISMATCH error.
*/
case OP_MustBeInt: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
@@ -1862,7 +1862,9 @@ case OP_MustBeInt: { /* jump, in1 */
VdbeBranchTaken((pIn1->flags&MEM_Int)==0, 2);
if ((pIn1->flags & MEM_Int)==0) {
if (pOp->p2==0) {
- rc = SQL_MISMATCH;
+ diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
+ sql_value_text(pIn1), "integer");
+ rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
} else {
goto jump_to_p2;
diff --git a/test/sql-tap/autoinc.test.lua b/test/sql-tap/autoinc.test.lua
index 257621b..3e3eaad 100755
--- a/test/sql-tap/autoinc.test.lua
+++ b/test/sql-tap/autoinc.test.lua
@@ -810,7 +810,7 @@ test:do_catchsql_test(
INSERT INTO t1 SELECT s2, s2 FROM t1;
]], {
-- <autoinc-gh-3670>
- 1, "Failed to execute SQL statement: datatype mismatch"
+ 1, "Type mismatch: can not convert a to integer"
-- </autoinc-gh-3670>
})
--
2.7.4
^ permalink raw reply [flat|nested] 31+ messages in thread
* [tarantool-patches] [PATCH v1 07/12] sql: set errors in VDBE using diag_set()
2019-05-05 12:17 [tarantool-patches] [PATCH v1 00/12] sql: set errors in VDBE using diag_set() imeevma
` (5 preceding siblings ...)
2019-05-05 12:17 ` [tarantool-patches] [PATCH v1 06/12] sql: remove error SQL_MISMATCH imeevma
@ 2019-05-05 12:17 ` imeevma
2019-05-15 13:26 ` [tarantool-patches] " n.pettik
2019-05-05 12:17 ` [tarantool-patches] [PATCH v1 08/12] sql: remove field zErrMsg from struct Vdbe imeevma
` (4 subsequent siblings)
11 siblings, 1 reply; 31+ messages in thread
From: imeevma @ 2019-05-05 12:17 UTC (permalink / raw)
To: korablev; +Cc: tarantool-patches
After this patch, all errors in VDBE will be set using diag_set().
Part of #4074
---
src/box/execute.c | 23 +---
src/box/sql/vdbe.c | 331 +++++++++++++++++++++-----------------------------
src/box/sql/vdbeInt.h | 10 --
src/box/sql/vdbeapi.c | 34 +-----
src/box/sql/vdbeaux.c | 20 +--
5 files changed, 148 insertions(+), 270 deletions(-)
diff --git a/src/box/execute.c b/src/box/execute.c
index a3d4a92..e81cc32 100644
--- a/src/box/execute.c
+++ b/src/box/execute.c
@@ -410,8 +410,7 @@ port_sql_dump_msgpack(struct port *port, struct obuf *out)
* @retval -1 Error.
*/
static inline int
-sql_execute(sql *db, struct sql_stmt *stmt, struct port *port,
- struct region *region)
+sql_execute(struct sql_stmt *stmt, struct port *port, struct region *region)
{
int rc, column_count = sql_column_count(stmt);
if (column_count > 0) {
@@ -427,15 +426,8 @@ sql_execute(sql *db, struct sql_stmt *stmt, struct port *port,
rc = sql_step(stmt);
assert(rc != SQL_ROW && rc != SQL_OK);
}
- if (rc != SQL_DONE) {
- if (db->errCode != SQL_TARANTOOL_ERROR) {
- const char *err = (char *)sql_value_text(db->pErr);
- if (err == NULL)
- err = sqlErrStr(db->errCode);
- diag_set(ClientError, ER_SQL_EXECUTE, err);
- }
+ if (rc != SQL_DONE)
return -1;
- }
return 0;
}
@@ -446,19 +438,12 @@ sql_prepare_and_execute(const char *sql, int len, const struct sql_bind *bind,
{
struct sql_stmt *stmt;
struct sql *db = sql_get();
- if (sql_prepare_v2(db, sql, len, &stmt, NULL) != SQL_OK) {
- if (db->errCode != SQL_TARANTOOL_ERROR) {
- const char *err = (char *)sql_value_text(db->pErr);
- if (err == NULL)
- err = sqlErrStr(db->errCode);
- diag_set(ClientError, ER_SQL_EXECUTE, err);
- }
+ if (sql_prepare_v2(db, sql, len, &stmt, NULL) != SQL_OK)
return -1;
- }
assert(stmt != NULL);
port_sql_create(port, stmt);
if (sql_bind(stmt, bind, bind_count) == 0 &&
- sql_execute(db, stmt, port, region) == 0)
+ sql_execute(stmt, port, region) == 0)
return 0;
port_destroy(port);
return -1;
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index bdf7429..115f22e 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -986,7 +986,7 @@ case OP_Halt: {
p->rc = SQL_BUSY;
} else {
assert(rc==SQL_OK || (p->rc&0xff)==SQL_CONSTRAINT);
- rc = p->rc ? SQL_ERROR : SQL_DONE;
+ rc = p->rc ? SQL_TARANTOOL_ERROR : SQL_DONE;
}
goto vdbe_return;
}
@@ -1098,17 +1098,13 @@ case OP_NextAutoincValue: {
assert(pOp->p2 > 0);
struct space *space = space_by_id(pOp->p1);
- if (space == NULL) {
- rc = SQL_TARANTOOL_ERROR;
+ if (space == NULL)
goto abort_due_to_error;
- }
int64_t value;
struct sequence *sequence = space->sequence;
- if (sequence == NULL || sequence_next(sequence, &value) != 0) {
- rc = SQL_TARANTOOL_ERROR;
+ if (sequence == NULL || sequence_next(sequence, &value) != 0)
goto abort_due_to_error;
- }
pOut = out2Prerelease(p, pOp);
pOut->flags = MEM_Int;
@@ -1335,7 +1331,8 @@ case OP_ResultRow: {
* not return the number of rows modified. And do not RELEASE the statement
* transaction. It needs to be rolled back.
*/
- if (SQL_OK!=(rc = sqlVdbeCheckFk(p, 0))) {
+ rc = sqlVdbeCheckFk(p, 0);
+ if (rc != SQL_OK) {
assert(user_session->sql_flags&SQL_CountRows);
goto abort_due_to_error;
}
@@ -1427,7 +1424,6 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
mem_type_to_str(pIn2);
diag_set(ClientError, ER_INCONSISTENT_TYPES, "TEXT or BLOB",
inconsistent_type);
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
@@ -1435,10 +1431,10 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
if (str_type_p1 != str_type_p2) {
diag_set(ClientError, ER_INCONSISTENT_TYPES,
mem_type_to_str(pIn2), mem_type_to_str(pIn1));
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
- if (ExpandBlob(pIn1) || ExpandBlob(pIn2)) goto no_mem;
+ if (ExpandBlob(pIn1) != SQL_OK || ExpandBlob(pIn2) != SQL_OK)
+ goto abort_due_to_error;
nByte = pIn1->n + pIn2->n;
if (nByte>db->aLimit[SQL_LIMIT_LENGTH]) {
goto too_big;
@@ -1551,13 +1547,11 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
if (sqlVdbeRealValue(pIn1, &rA) != 0) {
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
sql_value_text(pIn1), "numeric");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
if (sqlVdbeRealValue(pIn2, &rB) != 0) {
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
sql_value_text(pIn2), "numeric");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
switch( pOp->opcode) {
@@ -1597,11 +1591,9 @@ arithmetic_result_is_null:
division_by_zero:
diag_set(ClientError, ER_SQL_EXECUTE, "division by zero");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
integer_overflow:
diag_set(ClientError, ER_SQL_EXECUTE, "integer is overflowed");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
@@ -1723,11 +1715,15 @@ case OP_Function: {
/* If the function returned an error, throw an exception */
if (pCtx->fErrorOrAux) {
if (pCtx->isError) {
- sqlVdbeError(p, "%s", sql_value_text(pCtx->pOut));
- rc = pCtx->isError;
+ if (pCtx->isError != SQL_TARANTOOL_ERROR) {
+ diag_set(ClientError, ER_SQL_EXECUTE,
+ sql_value_text(pCtx->pOut));
+ }
+ rc = SQL_TARANTOOL_ERROR;
}
sqlVdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1);
- if (rc) goto abort_due_to_error;
+ if (rc != SQL_OK)
+ goto abort_due_to_error;
}
/* Copy the result of the function into register P3 */
@@ -1789,13 +1785,11 @@ case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */
if (sqlVdbeIntValue(pIn2, (int64_t *) &iA) != 0) {
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
sql_value_text(pIn2), "integer");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
if (sqlVdbeIntValue(pIn1, (int64_t *) &iB) != 0) {
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
sql_value_text(pIn1), "integer");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
op = pOp->opcode;
@@ -1864,7 +1858,6 @@ case OP_MustBeInt: { /* jump, in1 */
if (pOp->p2==0) {
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
sql_value_text(pIn1), "integer");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
} else {
goto jump_to_p2;
@@ -1910,8 +1903,7 @@ case OP_Realify: { /* in1 */
*/
case OP_Cast: { /* in1 */
pIn1 = &aMem[pOp->p1];
- rc = ExpandBlob(pIn1);
- if (rc != 0)
+ if (ExpandBlob(pIn1) != SQL_OK)
goto abort_due_to_error;
rc = sqlVdbeMemCast(pIn1, pOp->p2);
UPDATE_MAX_BLOBSIZE(pIn1);
@@ -1919,7 +1911,6 @@ case OP_Cast: { /* in1 */
break;
diag_set(ClientError, ER_SQL_TYPE_MISMATCH, sql_value_text(pIn1),
field_type_strs[pOp->p2]);
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
#endif /* SQL_OMIT_CAST */
@@ -2072,7 +2063,6 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
mem_type_to_str(pIn3);
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
inconsistent_type, "boolean");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
res = sqlMemCompare(pIn3, pIn1, NULL);
@@ -2091,7 +2081,6 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
ER_SQL_TYPE_MISMATCH,
sql_value_text(pIn3),
"numeric");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
@@ -2333,7 +2322,6 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */
} else {
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
sql_value_text(pIn1), "boolean");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
pIn2 = &aMem[pOp->p2];
@@ -2344,7 +2332,6 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */
} else {
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
sql_value_text(pIn2), "boolean");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
if (pOp->opcode==OP_And) {
@@ -2378,7 +2365,6 @@ case OP_Not: { /* same as TK_NOT, in1, out2 */
if ((pIn1->flags & MEM_Bool) == 0) {
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
sql_value_text(pIn1), "boolean");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
mem_set_bool(pOut, ! pIn1->u.b);
@@ -2402,7 +2388,6 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */
if (sqlVdbeIntValue(pIn1, &i) != 0) {
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
sql_value_text(pIn1), "integer");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
pOut->flags = MEM_Int;
@@ -2450,7 +2435,6 @@ case OP_IfNot: { /* jump, in1 */
} else {
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
sql_value_text(pIn1), "boolean");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
VdbeBranchTaken(c!=0, 2);
@@ -2590,8 +2574,9 @@ case OP_Column: {
zEnd = zData + pC->payloadSize;
} else {
memset(&sMem, 0, sizeof(sMem));
- rc = sqlVdbeMemFromBtree(pC->uc.pCursor, 0, pC->payloadSize, &sMem);
- if (rc!=SQL_OK) goto abort_due_to_error;
+ if (sqlVdbeMemFromBtree(pC->uc.pCursor, 0, pC->payloadSize,
+ &sMem) != SQL_OK)
+ goto abort_due_to_error;
zData = (u8*)sMem.z;
zEnd = zData + pC->payloadSize;
}
@@ -2650,10 +2635,8 @@ case OP_Column: {
}
uint32_t unused;
if (vdbe_decode_msgpack_into_mem((const char *)(zData + aOffset[p2]),
- pDest, &unused) != 0) {
- rc = SQL_TARANTOOL_ERROR;
+ pDest, &unused) != 0)
goto abort_due_to_error;
- }
/* MsgPack map, array or extension (unsupported in sql).
* Wrap it in a blob verbatim.
*/
@@ -2687,7 +2670,11 @@ case OP_Column: {
if ((pDest->flags & (MEM_Ephem | MEM_Str)) == (MEM_Ephem | MEM_Str)) {
int len = pDest->n;
if (pDest->szMalloc<len+1) {
- if (sqlVdbeMemGrow(pDest, len+1, 1)) goto op_column_error;
+ if (sqlVdbeMemGrow(pDest, len + 1, 1)) {
+ if (zData != pC->aRow)
+ sqlVdbeMemRelease(&sMem);
+ goto abort_due_to_error;
+ }
} else {
pDest->z = memcpy(pDest->zMalloc, pDest->z, len);
pDest->flags &= ~MEM_Ephem;
@@ -2701,10 +2688,6 @@ case OP_Column: {
UPDATE_MAX_BLOBSIZE(pDest);
REGISTER_TRACE(pOp->p3, pDest);
break;
-
- op_column_error:
- if (zData!=pC->aRow) sqlVdbeMemRelease(&sMem);
- goto abort_due_to_error;
}
/* Opcode: ApplyType P1 P2 * P4 *
@@ -2729,7 +2712,6 @@ case OP_ApplyType: {
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
sql_value_text(pIn1),
field_type_strs[type]);
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
pIn1++;
@@ -2802,10 +2784,8 @@ case OP_MakeRecord: {
uint32_t tuple_size;
char *tuple =
sql_vdbe_mem_encode_tuple(pData0, nField, &tuple_size, region);
- if (tuple == NULL) {
- rc = SQL_TARANTOOL_ERROR;
+ if (tuple == NULL)
goto abort_due_to_error;
- }
if ((int64_t)tuple_size > db->aLimit[SQL_LIMIT_LENGTH])
goto too_big;
@@ -2860,13 +2840,14 @@ case OP_Count: { /* out2 */
assert(pCrsr);
nEntry = 0; /* Not needed. Only used to silence a warning. */
if (pCrsr->curFlags & BTCF_TaCursor) {
- rc = tarantoolsqlCount(pCrsr, &nEntry);
+ if (tarantoolsqlCount(pCrsr, &nEntry) != SQL_OK)
+ goto abort_due_to_error;
} else if (pCrsr->curFlags & BTCF_TEphemCursor) {
- rc = tarantoolsqlEphemeralCount(pCrsr, &nEntry);
+ if (tarantoolsqlEphemeralCount(pCrsr, &nEntry) != SQL_OK)
+ goto abort_due_to_error;
} else {
unreachable();
}
- if (rc) goto abort_due_to_error;
pOut = out2Prerelease(p, pOp);
pOut->u.i = nEntry;
break;
@@ -2890,7 +2871,6 @@ case OP_Savepoint: {
if (psql_txn == NULL) {
assert(!box_txn());
diag_set(ClientError, ER_SAVEPOINT_NO_TRANSACTION);
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
p1 = pOp->p1;
@@ -2918,8 +2898,10 @@ case OP_Savepoint: {
pSavepoint = pSavepoint->pNext
);
if (!pSavepoint) {
- sqlVdbeError(p, "no such savepoint: %s", zName);
- rc = SQL_ERROR;
+ const char *err =
+ tt_sprintf("no such savepoint: %s", zName);
+ diag_set(ClientError, ER_SQL_EXECUTE, err);
+ goto abort_due_to_error;
} else {
/* Determine whether or not this is a transaction savepoint. If so,
@@ -2936,7 +2918,8 @@ case OP_Savepoint: {
p->rc = rc = SQL_BUSY;
goto vdbe_return;
}
- rc = p->rc;
+ if (p->rc != SQL_OK)
+ goto abort_due_to_error;
} else {
if (p1==SAVEPOINT_ROLLBACK)
box_txn_rollback_to_savepoint(pSavepoint->tnt_savepoint);
@@ -2968,7 +2951,6 @@ case OP_Savepoint: {
}
}
}
- if (rc) goto abort_due_to_error;
break;
}
@@ -2991,7 +2973,6 @@ case OP_CheckViewReferences: {
if (space->def->view_ref_count > 0) {
diag_set(ClientError, ER_DROP_SPACE, space->def->name,
"other views depend on this space");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
break;
@@ -3004,10 +2985,8 @@ case OP_CheckViewReferences: {
* Otherwise, raise an error with appropriate error message.
*/
case OP_TransactionBegin: {
- if (sql_txn_begin(p) != 0) {
- rc = SQL_TARANTOOL_ERROR;
+ if (sql_txn_begin(p) != 0)
goto abort_due_to_error;
- }
p->auto_commit = false ;
break;
}
@@ -3023,13 +3002,11 @@ case OP_TransactionBegin: {
case OP_TransactionCommit: {
struct txn *txn = in_txn();
if (txn != NULL) {
- if (txn_commit(txn) != 0) {
- rc = SQL_TARANTOOL_ERROR;
+ if (txn_commit(txn) != 0)
goto abort_due_to_error;
- }
} else {
- sqlVdbeError(p, "cannot commit - no transaction is active");
- rc = SQL_ERROR;
+ diag_set(ClientError, ER_SQL_EXECUTE, "cannot commit - no "\
+ "transaction is active");
goto abort_due_to_error;
}
break;
@@ -3042,14 +3019,11 @@ case OP_TransactionCommit: {
*/
case OP_TransactionRollback: {
if (box_txn()) {
- if (box_txn_rollback() != 0) {
- rc = SQL_TARANTOOL_ERROR;
+ if (box_txn_rollback() != 0)
goto abort_due_to_error;
- }
} else {
- sqlVdbeError(p, "cannot rollback - no "
- "transaction is active");
- rc = SQL_ERROR;
+ diag_set(ClientError, ER_SQL_EXECUTE, "cannot rollback - no "\
+ "transaction is active");
goto abort_due_to_error;
}
break;
@@ -3067,16 +3041,12 @@ case OP_TransactionRollback: {
*/
case OP_TTransaction: {
if (!box_txn()) {
- if (sql_txn_begin(p) != 0) {
- rc = SQL_TARANTOOL_ERROR;
+ if (sql_txn_begin(p) != 0)
goto abort_due_to_error;
- }
} else {
p->anonymous_savepoint = sql_savepoint(p, NULL);
- if (p->anonymous_savepoint == NULL) {
- rc = SQL_TARANTOOL_ERROR;
+ if (p->anonymous_savepoint == NULL)
goto abort_due_to_error;
- }
}
break;
}
@@ -3115,9 +3085,8 @@ case OP_IteratorOpen:
if (box_schema_version() != p->schema_ver &&
(pOp->p5 & OPFLAG_SYSTEMSP) == 0) {
p->expired = 1;
- rc = SQL_ERROR;
- sqlVdbeError(p, "schema version has changed: " \
- "need to re-compile SQL statement");
+ diag_set(ClientError, ER_SQL_EXECUTE, "schema version has "\
+ "changed: need to re-compile SQL statement");
goto abort_due_to_error;
}
struct space *space;
@@ -3126,10 +3095,8 @@ case OP_IteratorOpen:
else
space = aMem[pOp->p3].u.p;
assert(space != NULL);
- if (access_check_space(space, PRIV_R) != 0) {
- rc = SQL_TARANTOOL_ERROR;
+ if (access_check_space(space, PRIV_R) != 0)
goto abort_due_to_error;
- }
struct index *index = space_index(space, pOp->p2);
assert(index != NULL);
@@ -3152,8 +3119,6 @@ case OP_IteratorOpen:
cur->nullRow = 1;
open_cursor_set_hints:
cur->uc.pCursor->hints = pOp->p5 & OPFLAG_SEEKEQ;
- if (rc != 0)
- goto abort_due_to_error;
break;
}
@@ -3175,10 +3140,8 @@ case OP_OpenTEphemeral: {
struct space *space = sql_ephemeral_space_create(pOp->p2,
pOp->p4.key_info);
- if (space == NULL) {
- rc = SQL_TARANTOOL_ERROR;
+ if (space == NULL)
goto abort_due_to_error;
- }
aMem[pOp->p1].u.p = space;
aMem[pOp->p1].flags = MEM_Ptr;
break;
@@ -3204,8 +3167,8 @@ case OP_SorterOpen: {
pCx = allocateCursor(p, pOp->p1, pOp->p2, CURTYPE_SORTER);
if (pCx==0) goto no_mem;
pCx->key_def = def;
- rc = sqlVdbeSorterInit(db, pCx);
- if (rc) goto abort_due_to_error;
+ if (sqlVdbeSorterInit(db, pCx) != SQL_OK)
+ goto abort_due_to_error;
break;
}
@@ -3437,7 +3400,6 @@ case OP_SeekGT: { /* jump, in3 */
} else {
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
sql_value_text(pIn3), "integer");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
iKey = i;
@@ -3518,10 +3480,8 @@ case OP_SeekGT: { /* jump, in3 */
#endif
r.eqSeen = 0;
r.opcode = oc;
- rc = sqlCursorMovetoUnpacked(pC->uc.pCursor, &r, &res);
- if (rc!=SQL_OK) {
+ if (sqlCursorMovetoUnpacked(pC->uc.pCursor, &r, &res) != SQL_OK)
goto abort_due_to_error;
- }
if (eqOnly && r.eqSeen==0) {
assert(res!=0);
goto seek_not_found;
@@ -3533,8 +3493,8 @@ case OP_SeekGT: { /* jump, in3 */
if (oc>=OP_SeekGE) { assert(oc==OP_SeekGE || oc==OP_SeekGT);
if (res<0 || (res==0 && oc==OP_SeekGT)) {
res = 0;
- rc = sqlCursorNext(pC->uc.pCursor, &res);
- if (rc!=SQL_OK) goto abort_due_to_error;
+ if (sqlCursorNext(pC->uc.pCursor, &res) != SQL_OK)
+ goto abort_due_to_error;
} else {
res = 0;
}
@@ -3542,8 +3502,8 @@ case OP_SeekGT: { /* jump, in3 */
assert(oc==OP_SeekLT || oc==OP_SeekLE);
if (res>0 || (res==0 && oc==OP_SeekLT)) {
res = 0;
- rc = sqlCursorPrevious(pC->uc.pCursor, &res);
- if (rc!=SQL_OK) goto abort_due_to_error;
+ if (sqlCursorPrevious(pC->uc.pCursor, &res) != SQL_OK)
+ goto abort_due_to_error;
} else {
/* res might be negative because the table is empty. Check to
* see if this is the case.
@@ -3685,10 +3645,11 @@ case OP_Found: { /* jump, in3 */
}
}
rc = sqlCursorMovetoUnpacked(pC->uc.pCursor, pIdxKey, &res);
- if (pFree) sqlDbFree(db, pFree);
- if (rc!=SQL_OK) {
+ if (pFree)
+ sqlDbFree(db, pFree);
+ assert(rc == SQL_OK || rc == SQL_TARANTOOL_ERROR);
+ if (rc != SQL_OK)
goto abort_due_to_error;
- }
pC->seekResult = res;
alreadyExists = (res==0);
pC->nullRow = 1-alreadyExists;
@@ -3748,10 +3709,8 @@ case OP_NextIdEphemeral: {
struct space *space = (struct space*)p->aMem[pOp->p1].u.p;
assert(space->def->id == 0);
uint64_t rowid;
- if (space->vtab->ephemeral_rowid_next(space, &rowid) != 0) {
- rc = SQL_TARANTOOL_ERROR;
+ if (space->vtab->ephemeral_rowid_next(space, &rowid) != 0)
goto abort_due_to_error;
- }
/*
* FIXME: since memory cell can comprise only 32-bit
* integer, make sure it can fit in. This check should
@@ -3760,7 +3719,6 @@ case OP_NextIdEphemeral: {
*/
if (rowid > INT32_MAX) {
diag_set(ClientError, ER_ROWID_OVERFLOW);
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
pOut = &aMem[pOp->p2];
@@ -3860,7 +3818,9 @@ case OP_Delete: {
}
pC->cacheStatus = CACHE_STALE;
pC->seekResult = 0;
- if (rc) goto abort_due_to_error;
+ assert(rc == SQL_OK || rc == SQL_TARANTOOL_ERROR);
+ if (rc != SQL_OK)
+ goto abort_due_to_error;
if (opflags & OPFLAG_NCHANGE)
p->nChange++;
@@ -3907,9 +3867,12 @@ case OP_SorterCompare: {
pIn3 = &aMem[pOp->p3];
nKeyCol = pOp->p4.i;
res = 0;
- rc = sqlVdbeSorterCompare(pC, pIn3, nKeyCol, &res);
+ if (sqlVdbeSorterCompare(pC, pIn3, nKeyCol, &res) != 0)
+ rc = SQL_TARANTOOL_ERROR;
VdbeBranchTaken(res!=0,2);
- if (rc) goto abort_due_to_error;
+ assert(rc == SQL_OK || rc == SQL_TARANTOOL_ERROR);
+ if (rc != SQL_OK)
+ goto abort_due_to_error;
if (res) goto jump_to_p2;
break;
};
@@ -3932,10 +3895,10 @@ case OP_SorterData: {
pOut = &aMem[pOp->p2];
pC = p->apCsr[pOp->p1];
assert(isSorter(pC));
- rc = sqlVdbeSorterRowkey(pC, pOut);
- assert(rc!=SQL_OK || (pOut->flags & MEM_Blob));
+ if (sqlVdbeSorterRowkey(pC, pOut) != SQL_OK)
+ goto abort_due_to_error;
+ assert(pOut->flags & MEM_Blob);
assert(pOp->p1>=0 && pOp->p1<p->nCursor);
- if (rc) goto abort_due_to_error;
p->apCsr[pOp->p3]->cacheStatus = CACHE_STALE;
break;
}
@@ -4002,11 +3965,9 @@ case OP_RowData: {
testcase( n==0);
sqlVdbeMemRelease(pOut);
- rc = sql_vdbe_mem_alloc_region(pOut, n);
- if (rc)
- goto no_mem;
- rc = sqlCursorPayload(pCrsr, 0, n, pOut->z);
- if (rc) goto abort_due_to_error;
+ if (sql_vdbe_mem_alloc_region(pOut, n) != SQL_OK ||
+ sqlCursorPayload(pCrsr, 0, n, pOut->z) != SQL_OK)
+ goto abort_due_to_error;
UPDATE_MAX_BLOBSIZE(pOut);
REGISTER_TRACE(pOp->p2, pOut);
break;
@@ -4072,7 +4033,9 @@ case OP_Last: { /* jump */
rc = tarantoolsqlLast(pCrsr, &res);
pC->nullRow = (u8)res;
pC->cacheStatus = CACHE_STALE;
- if (rc) goto abort_due_to_error;
+ assert(rc == SQL_OK || rc == SQL_TARANTOOL_ERROR);
+ if (rc != SQL_OK)
+ goto abort_due_to_error;
if (pOp->p2>0) {
VdbeBranchTaken(res!=0,2);
if (res) goto jump_to_p2;
@@ -4141,15 +4104,18 @@ case OP_Rewind: { /* jump */
pC->seekOp = OP_Rewind;
#endif
if (isSorter(pC)) {
- rc = sqlVdbeSorterRewind(pC, &res);
+ if (sqlVdbeSorterRewind(pC, &res) != SQL_OK)
+ goto abort_due_to_error;
} else {
assert(pC->eCurType==CURTYPE_TARANTOOL);
pCrsr = pC->uc.pCursor;
assert(pCrsr);
- rc = tarantoolsqlFirst(pCrsr, &res);
+ if (tarantoolsqlFirst(pCrsr, &res) != SQL_OK)
+ rc = SQL_TARANTOOL_ERROR;
pC->cacheStatus = CACHE_STALE;
+ if (rc != SQL_OK)
+ goto abort_due_to_error;
}
- if (rc) goto abort_due_to_error;
pC->nullRow = (u8)res;
assert(pOp->p2>0 && pOp->p2<p->nOp);
VdbeBranchTaken(res!=0,2);
@@ -4267,7 +4233,9 @@ case OP_Next: /* jump */
next_tail:
pC->cacheStatus = CACHE_STALE;
VdbeBranchTaken(res==0,2);
- if (rc) goto abort_due_to_error;
+ assert(rc == SQL_OK || rc == SQL_TARANTOOL_ERROR);
+ if (rc != SQL_OK)
+ goto abort_due_to_error;
if (res==0) {
pC->nullRow = 0;
p->aCounter[pOp->p5]++;
@@ -4295,11 +4263,8 @@ case OP_SorterInsert: { /* in2 */
assert(isSorter(cursor));
pIn2 = &aMem[pOp->p2];
assert((pIn2->flags & MEM_Blob) != 0);
- rc = ExpandBlob(pIn2);
- if (rc != 0)
- goto abort_due_to_error;
- rc = sqlVdbeSorterWrite(cursor, pIn2);
- if (rc != 0)
+ if (ExpandBlob(pIn2) != SQL_OK ||
+ sqlVdbeSorterWrite(cursor, pIn2) != SQL_OK)
goto abort_due_to_error;
break;
}
@@ -4329,8 +4294,7 @@ case OP_IdxInsert: {
assert((pIn2->flags & MEM_Blob) != 0);
if (pOp->p5 & OPFLAG_NCHANGE)
p->nChange++;
- rc = ExpandBlob(pIn2);
- if (rc != 0)
+ if (ExpandBlob(pIn2) != SQL_OK)
goto abort_due_to_error;
struct space *space;
if (pOp->p4type == P4_SPACEPTR)
@@ -4364,6 +4328,7 @@ case OP_IdxInsert: {
} else if (pOp->p5 & OPFLAG_OE_ROLLBACK) {
p->errorAction = ON_CONFLICT_ACTION_ROLLBACK;
}
+ assert(rc == SQL_OK || rc == SQL_TARANTOOL_ERROR);
if (rc != 0)
goto abort_due_to_error;
break;
@@ -4431,14 +4396,12 @@ case OP_Update: {
if (is_error) {
diag_set(OutOfMemory, stream.pos - stream.buf,
"mpstream_flush", "stream");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
uint32_t ops_size = region_used(region) - used;
const char *ops = region_join(region, ops_size);
if (ops == NULL) {
diag_set(OutOfMemory, ops_size, "region_join", "raw");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
@@ -4464,6 +4427,7 @@ case OP_Update: {
} else if (pOp->p5 & OPFLAG_OE_ROLLBACK) {
p->errorAction = ON_CONFLICT_ACTION_ROLLBACK;
}
+ assert(rc == SQL_OK || rc == SQL_TARANTOOL_ERROR);
if (rc != 0)
goto abort_due_to_error;
break;
@@ -4514,8 +4478,7 @@ case OP_SDelete: {
struct space *space = space_by_id(pOp->p1);
assert(space != NULL);
assert(space_is_system(space));
- rc = sql_delete_by_key(space, 0, pIn2->z, pIn2->n);
- if (rc)
+ if (sql_delete_by_key(space, 0, pIn2->z, pIn2->n) != SQL_OK)
goto abort_due_to_error;
if (pOp->p5 & OPFLAG_NCHANGE)
p->nChange++;
@@ -4549,18 +4512,19 @@ case OP_IdxDelete: {
r.default_rc = 0;
r.aMem = &aMem[pOp->p2];
r.opcode = OP_IdxDelete;
- rc = sqlCursorMovetoUnpacked(pCrsr, &r, &res);
- if (rc) goto abort_due_to_error;
+ if (sqlCursorMovetoUnpacked(pCrsr, &r, &res) != SQL_OK)
+ goto abort_due_to_error;
if (res==0) {
assert(pCrsr->eState == CURSOR_VALID);
if (pCrsr->curFlags & BTCF_TaCursor) {
- rc = tarantoolsqlDelete(pCrsr, 0);
+ if (tarantoolsqlDelete(pCrsr, 0) != SQL_OK)
+ goto abort_due_to_error;
} else if (pCrsr->curFlags & BTCF_TEphemCursor) {
- rc = tarantoolsqlEphemeralDelete(pCrsr);
+ if (tarantoolsqlEphemeralDelete(pCrsr) != SQL_OK)
+ goto abort_due_to_error;
} else {
unreachable();
}
- if (rc) goto abort_due_to_error;
}
pC->cacheStatus = CACHE_STALE;
pC->seekResult = 0;
@@ -4672,14 +4636,14 @@ case OP_Clear: {
rc = 0;
if (pOp->p2 > 0) {
if (box_truncate(space_id) != 0)
- rc = SQL_TARANTOOL_ERROR;
+ goto abort_due_to_error;
} else {
uint32_t tuple_count;
- rc = tarantoolsqlClearTable(space, &tuple_count);
- if (rc == 0 && (pOp->p5 & OPFLAG_NCHANGE) != 0)
+ if (tarantoolsqlClearTable(space, &tuple_count) != SQL_OK)
+ goto abort_due_to_error;
+ if ((pOp->p5 & OPFLAG_NCHANGE) != 0)
p->nChange += tuple_count;
}
- if (rc) goto abort_due_to_error;
break;
}
@@ -4702,8 +4666,8 @@ case OP_ResetSorter: {
} else {
assert(pC->eCurType==CURTYPE_TARANTOOL);
assert(pC->uc.pCursor->curFlags & BTCF_TEphemCursor);
- rc = tarantoolsqlEphemeralClearTable(pC->uc.pCursor);
- if (rc) goto abort_due_to_error;
+ if (tarantoolsqlEphemeralClearTable(pC->uc.pCursor) != SQL_OK)
+ goto abort_due_to_error;
}
break;
}
@@ -4736,8 +4700,8 @@ case OP_RenameTable: {
zNewTableName = pOp->p4.z;
zOldTableName = sqlDbStrNDup(db, zOldTableName,
sqlStrlen30(zOldTableName));
- rc = sql_rename_table(space_id, zNewTableName);
- if (rc) goto abort_due_to_error;
+ if (sql_rename_table(space_id, zNewTableName) != SQL_OK)
+ goto abort_due_to_error;
/*
* Rebuild 'CREATE TRIGGER' expressions of all triggers
* created on this table. Sure, this action is not atomic
@@ -4747,20 +4711,18 @@ case OP_RenameTable: {
for (struct sql_trigger *trigger = triggers; trigger != NULL; ) {
/* Store pointer as trigger will be destructed. */
struct sql_trigger *next_trigger = trigger->next;
- rc = tarantoolsqlRenameTrigger(trigger->zName,
- zOldTableName, zNewTableName);
- if (rc != SQL_OK) {
- /*
- * FIXME: In the case of error,
- * part of triggers would have invalid
- * space name in tuple so can not been
- * persisted.
- * Server could be restarted.
- * In this case, rename table back and
- * try again.
- */
+ /*
+ * FIXME: In the case of error,
+ * part of triggers would have invalid
+ * space name in tuple so can not been
+ * persisted.
+ * Server could be restarted.
+ * In this case, rename table back and
+ * try again.
+ */
+ if (tarantoolsqlRenameTrigger(trigger->zName, zOldTableName,
+ zNewTableName) != SQL_OK)
goto abort_due_to_error;
- }
trigger = next_trigger;
}
sqlDbFree(db, (void*)zOldTableName);
@@ -4775,8 +4737,8 @@ case OP_RenameTable: {
*/
case OP_LoadAnalysis: {
assert(pOp->p1==0 );
- rc = sql_analysis_load(db);
- if (rc) goto abort_due_to_error;
+ if (sql_analysis_load(db) != SQL_OK)
+ goto abort_due_to_error;
break;
}
@@ -4832,8 +4794,8 @@ case OP_Program: { /* jump */
}
if (p->nFrame>=db->aLimit[SQL_LIMIT_TRIGGER_DEPTH]) {
- rc = SQL_ERROR;
- sqlVdbeError(p, "too many levels of trigger recursion");
+ diag_set(ClientError, ER_SQL_EXECUTE, "too many levels of "\
+ "trigger recursion");
goto abort_due_to_error;
}
@@ -5164,11 +5126,16 @@ case OP_AggStep: {
(pCtx->pFunc->xSFunc)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */
if (pCtx->fErrorOrAux) {
if (pCtx->isError) {
- sqlVdbeError(p, "%s", sql_value_text(&t));
- rc = pCtx->isError;
+ if (pCtx->isError != SQL_TARANTOOL_ERROR) {
+ diag_set(ClientError, ER_SQL_EXECUTE,
+ sql_value_text(&t));
+ }
+ rc = SQL_TARANTOOL_ERROR;
}
sqlVdbeMemRelease(&t);
- if (rc) goto abort_due_to_error;
+ assert(rc == SQL_OK || rc == SQL_TARANTOOL_ERROR);
+ if (rc != SQL_OK)
+ goto abort_due_to_error;
} else {
assert(t.flags==MEM_Null);
}
@@ -5199,8 +5166,11 @@ case OP_AggFinal: {
pMem = &aMem[pOp->p1];
assert((pMem->flags & ~(MEM_Null|MEM_Agg))==0);
rc = sqlVdbeMemFinalize(pMem, pOp->p4.pFunc);
- if (rc) {
- sqlVdbeError(p, "%s", sql_value_text(pMem));
+ if (rc != SQL_OK) {
+ if (rc != SQL_TARANTOOL_ERROR) {
+ diag_set(ClientError, ER_SQL_EXECUTE,
+ sql_value_text(pMem));
+ }
goto abort_due_to_error;
}
UPDATE_MAX_BLOBSIZE(pMem);
@@ -5311,10 +5281,8 @@ case OP_IncMaxid: {
assert(pOp->p1 > 0);
pOut = &aMem[pOp->p1];
- rc = tarantoolsqlIncrementMaxid((uint64_t*) &pOut->u.i);
- if (rc!=SQL_OK) {
+ if (tarantoolsqlIncrementMaxid((uint64_t*) &pOut->u.i) != SQL_OK)
goto abort_due_to_error;
- }
pOut->flags = MEM_Int;
break;
}
@@ -5378,28 +5346,8 @@ default: { /* This is really OP_Noop and OP_Explain */
* an error of some kind.
*/
abort_due_to_error:
- if (db->mallocFailed) rc = SQL_NOMEM;
- assert(rc);
- if (p->zErrMsg==0 && rc!=SQL_IOERR_NOMEM) {
- const char *msg;
- /* Avoiding situation when Tarantool error is set,
- * but error message isn't.
- */
- if (rc == SQL_TARANTOOL_ERROR && tarantoolErrorMessage()) {
- msg = tarantoolErrorMessage();
- } else {
- msg = sqlErrStr(rc);
- }
- sqlVdbeError(p, "%s", msg);
- }
+ rc = SQL_TARANTOOL_ERROR;
p->rc = rc;
- sqlSystemError(db, rc);
- testcase( sqlGlobalConfig.xLog!=0);
- sql_log(rc, "statement aborts at %d: [%s] %s",
- (int)(pOp - aOp), p->zSql, p->zErrMsg);
- sqlVdbeHalt(p);
- if (rc==SQL_IOERR_NOMEM) sqlOomFault(db);
- rc = SQL_ERROR;
/* This is the only way out of this procedure. */
vdbe_return:
@@ -5408,21 +5356,20 @@ vdbe_return:
assert(rc!=SQL_OK || nExtraDelete==0
|| sql_strlike_ci("DELETE%", p->zSql, 0) != 0
);
+ assert(rc == SQL_OK || rc == SQL_BUSY || rc >= SQL_TARANTOOL_ERROR ||
+ rc == SQL_ROW || rc == SQL_DONE);
return rc;
/* Jump to here if a string or blob larger than SQL_MAX_LENGTH
* is encountered.
*/
too_big:
- sqlVdbeError(p, "string or blob too big");
- rc = SQL_TOOBIG;
+ diag_set(ClientError, ER_SQL_EXECUTE, "string or blob too big");
goto abort_due_to_error;
/* Jump to here if a malloc() fails.
*/
no_mem:
sqlOomFault(db);
- sqlVdbeError(p, "out of memory");
- rc = SQL_NOMEM;
goto abort_due_to_error;
}
diff --git a/src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h
index a3100e5..b655b5a 100644
--- a/src/box/sql/vdbeInt.h
+++ b/src/box/sql/vdbeInt.h
@@ -248,10 +248,6 @@ struct Mem {
#define MEM_Agg 0x4000 /* Mem.z points to an agg function context */
#define MEM_Zero 0x8000 /* Mem.i contains count of 0s appended to blob */
#define MEM_Subtype 0x10000 /* Mem.eSubtype is valid */
-#ifdef SQL_OMIT_INCRBLOB
-#undef MEM_Zero
-#define MEM_Zero 0x0000
-#endif
/**
* In contrast to Mem_TypeMask, this one allows to get
@@ -467,7 +463,6 @@ struct Vdbe {
/*
* Function prototypes
*/
-void sqlVdbeError(Vdbe *, const char *, ...);
void sqlVdbeFreeCursor(Vdbe *, VdbeCursor *);
void sqlVdbePopStack(Vdbe *, int);
int sqlVdbeCursorRestore(VdbeCursor *);
@@ -550,13 +545,8 @@ void sqlVdbeMemPrettyPrint(Mem * pMem, char *zBuf);
#endif
int sqlVdbeMemHandleBom(Mem * pMem);
-#ifndef SQL_OMIT_INCRBLOB
int sqlVdbeMemExpandBlob(Mem *);
#define ExpandBlob(P) (((P)->flags&MEM_Zero)?sqlVdbeMemExpandBlob(P):0)
-#else
-#define sqlVdbeMemExpandBlob(x) SQL_OK
-#define ExpandBlob(P) SQL_OK
-#endif
/**
* Perform comparison of two keys: one is packed and one is not.
diff --git a/src/box/sql/vdbeapi.c b/src/box/sql/vdbeapi.c
index 909db8c..34fa5c8 100644
--- a/src/box/sql/vdbeapi.c
+++ b/src/box/sql/vdbeapi.c
@@ -569,15 +569,6 @@ sqlStep(Vdbe * p)
p->rc = SQL_NOMEM;
}
end_of_step:
- /* At this point local variable rc holds the value that should be
- * returned if this statement was compiled using the legacy
- * sql_prepare() interface. According to the docs, this can only
- * be one of the values in the first assert() below. Variable p->rc
- * contains the value that would be returned if sql_finalize()
- * were called on statement p.
- */
- assert(rc == SQL_ROW || rc == SQL_DONE || rc == SQL_ERROR
- || (rc & 0xff) == SQL_BUSY || rc == SQL_MISUSE);
if (p->isPrepareV2 && rc != SQL_ROW && rc != SQL_DONE) {
/* If this statement was prepared using sql_prepare_v2(), and an
* error has occurred, then return the error code in p->rc to the
@@ -597,20 +588,17 @@ int
sql_step(sql_stmt * pStmt)
{
int rc; /* Result from sqlStep() */
- int rc2 = SQL_OK; /* Result from sqlReprepare() */
Vdbe *v = (Vdbe *) pStmt; /* the prepared statement */
int cnt = 0; /* Counter to prevent infinite loop of reprepares */
- sql *db; /* The database connection */
if (vdbeSafetyNotNull(v)) {
return SQL_MISUSE;
}
- db = v->db;
v->doingRerun = 0;
while ((rc = sqlStep(v)) == SQL_SCHEMA
&& cnt++ < SQL_MAX_SCHEMA_RETRY) {
int savedPc = v->pc;
- rc2 = rc = sqlReprepare(v);
+ rc = sqlReprepare(v);
if (rc != SQL_OK)
break;
sql_reset(pStmt);
@@ -618,26 +606,6 @@ sql_step(sql_stmt * pStmt)
v->doingRerun = 1;
assert(v->expired == 0);
}
- if (rc2 != SQL_OK) {
- /* This case occurs after failing to recompile an sql statement.
- * The error message from the SQL compiler has already been loaded
- * into the database handle. This block copies the error message
- * from the database handle into the statement and sets the statement
- * program counter to 0 to ensure that when the statement is
- * finalized or reset the parser error message is available via
- * sql_errmsg() and sql_errcode().
- */
- const char *zErr = (const char *)sql_value_text(db->pErr);
- sqlDbFree(db, v->zErrMsg);
- if (!db->mallocFailed) {
- v->zErrMsg = sqlDbStrDup(db, zErr);
- v->rc = rc2;
- } else {
- v->zErrMsg = 0;
- v->rc = rc = SQL_NOMEM;
- }
- }
- rc = sqlApiExit(db, rc);
return rc;
}
diff --git a/src/box/sql/vdbeaux.c b/src/box/sql/vdbeaux.c
index 27fa5b2..48c2a81 100644
--- a/src/box/sql/vdbeaux.c
+++ b/src/box/sql/vdbeaux.c
@@ -116,19 +116,6 @@ sql_vdbe_prepare(struct Vdbe *vdbe)
}
/*
- * Change the error string stored in Vdbe.zErrMsg
- */
-void
-sqlVdbeError(Vdbe * p, const char *zFormat, ...)
-{
- va_list ap;
- sqlDbFree(p->db, p->zErrMsg);
- va_start(ap, zFormat);
- p->zErrMsg = sqlVMPrintf(p->db, zFormat, ap);
- va_end(ap);
-}
-
-/*
* Remember the SQL string for a prepared statement.
*/
void
@@ -2124,10 +2111,11 @@ sqlVdbeCheckFk(Vdbe * p, int deferred)
if ((deferred && txn != NULL && txn->psql_txn != NULL &&
txn->psql_txn->fk_deferred_count > 0) ||
(!deferred && p->nFkConstraint > 0)) {
- p->rc = SQL_CONSTRAINT_FOREIGNKEY;
+ p->rc = SQL_TARANTOOL_ERROR;
p->errorAction = ON_CONFLICT_ACTION_ABORT;
- sqlVdbeError(p, "FOREIGN KEY constraint failed");
- return SQL_ERROR;
+ diag_set(ClientError, ER_SQL_EXECUTE, "FOREIGN KEY constraint "\
+ "failed");
+ return SQL_TARANTOOL_ERROR;
}
return SQL_OK;
}
--
2.7.4
^ permalink raw reply [flat|nested] 31+ messages in thread
* [tarantool-patches] Re: [PATCH v1 07/12] sql: set errors in VDBE using diag_set()
2019-05-05 12:17 ` [tarantool-patches] [PATCH v1 07/12] sql: set errors in VDBE using diag_set() imeevma
@ 2019-05-15 13:26 ` n.pettik
2019-05-25 10:24 ` Mergen Imeev
0 siblings, 1 reply; 31+ messages in thread
From: n.pettik @ 2019-05-15 13:26 UTC (permalink / raw)
To: tarantool-patches; +Cc: Imeev Mergen
> On 5 May 2019, at 15:17, imeevma@tarantool.org wrote:
>
> After this patch, all errors in VDBE will be set using diag_set().
>
> Part of #4074
> ---
> src/box/execute.c | 23 +---
> src/box/sql/vdbe.c | 331 +++++++++++++++++++++-----------------------------
> src/box/sql/vdbeInt.h | 10 --
> src/box/sql/vdbeapi.c | 34 +-----
> src/box/sql/vdbeaux.c | 20 +--
> 5 files changed, 148 insertions(+), 270 deletions(-)
Please, remove whole sqlErrStr(), tarantoolErrorMessage() -
they are unused now. The same concerns sql_ret_code() -
I see no reason keeping it. Please, remove all legacy routines
connected with error codes.
> diff --git a/src/box/execute.c b/src/box/execute.c
> index a3d4a92..e81cc32 100644
> --- a/src/box/execute.c
> +++ b/src/box/execute.c
>
> @@ -1335,7 +1331,8 @@ case OP_ResultRow: {
> * not return the number of rows modified. And do not RELEASE the statement
> * transaction. It needs to be rolled back.
> */
> - if (SQL_OK!=(rc = sqlVdbeCheckFk(p, 0))) {
> + rc = sqlVdbeCheckFk(p, 0);
> + if (rc != SQL_OK) {
-> if (sqlVdbeCheckFk() != 0)
> assert(user_session->sql_flags&SQL_CountRows);
> goto abort_due_to_error;
> }
>
> @@ -1435,10 +1431,10 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
> if (str_type_p1 != str_type_p2) {
> diag_set(ClientError, ER_INCONSISTENT_TYPES,
> mem_type_to_str(pIn2), mem_type_to_str(pIn1));
> - rc = SQL_TARANTOOL_ERROR;
> goto abort_due_to_error;
> }
> - if (ExpandBlob(pIn1) || ExpandBlob(pIn2)) goto no_mem;
> + if (ExpandBlob(pIn1) != SQL_OK || ExpandBlob(pIn2) != SQL_OK)
> + goto abort_due_to_error;
!= 0
Still need to call sqlOomFault(db); by jumping to no_mem label.
> nByte = pIn1->n + pIn2->n;
> if (nByte>db->aLimit[SQL_LIMIT_LENGTH]) {
> goto too_big;
>
>
> @@ -1723,11 +1715,15 @@ case OP_Function: {
> /* If the function returned an error, throw an exception */
> if (pCtx->fErrorOrAux) {
> if (pCtx->isError) {
> - sqlVdbeError(p, "%s", sql_value_text(pCtx->pOut));
> - rc = pCtx->isError;
> + if (pCtx->isError != SQL_TARANTOOL_ERROR) {
How it can be different from SQL_TARANTOOL_ERROR?
> + diag_set(ClientError, ER_SQL_EXECUTE,
> + sql_value_text(pCtx->pOut));
> + }
> + rc = SQL_TARANTOOL_ERROR;
> }
> sqlVdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1);
> - if (rc) goto abort_due_to_error;
> + if (rc != SQL_OK)
> + goto abort_due_to_error;
This diff seems to be redundant
> @@ -1910,8 +1903,7 @@ case OP_Realify: { /* in1 */
> */
> case OP_Cast: { /* in1 */
> pIn1 = &aMem[pOp->p1];
> - rc = ExpandBlob(pIn1);
> - if (rc != 0)
> + if (ExpandBlob(pIn1) != SQL_OK)
!= 0
Please, don’t use SQL_OK value anywhere.
>
> @@ -2802,10 +2784,8 @@ case OP_MakeRecord: {
> uint32_t tuple_size;
> char *tuple =
> sql_vdbe_mem_encode_tuple(pData0, nField, &tuple_size, region);
> - if (tuple == NULL) {
> - rc = SQL_TARANTOOL_ERROR;
> + if (tuple == NULL)
> goto abort_due_to_error;
> - }
> if ((int64_t)tuple_size > db->aLimit[SQL_LIMIT_LENGTH])
> goto too_big;
>
>
> @@ -2918,8 +2898,10 @@ case OP_Savepoint: {
> pSavepoint = pSavepoint->pNext
> );
> if (!pSavepoint) {
> - sqlVdbeError(p, "no such savepoint: %s", zName);
> - rc = SQL_ERROR;
> + const char *err =
> + tt_sprintf("no such savepoint: %s", zName);
> + diag_set(ClientError, ER_SQL_EXECUTE, err);
We already have ER_NO_SUCH_SAVEPOINT.
> @@ -3685,10 +3645,11 @@ case OP_Found: { /* jump, in3 */
> }
> }
> rc = sqlCursorMovetoUnpacked(pC->uc.pCursor, pIdxKey, &res);
> - if (pFree) sqlDbFree(db, pFree);
> - if (rc!=SQL_OK) {
> + if (pFree)
!= NULL
>
> @@ -5164,11 +5126,16 @@ case OP_AggStep: {
> (pCtx->pFunc->xSFunc)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */
> if (pCtx->fErrorOrAux) {
> if (pCtx->isError) {
> - sqlVdbeError(p, "%s", sql_value_text(&t));
> - rc = pCtx->isError;
> + if (pCtx->isError != SQL_TARANTOOL_ERROR) {
> + diag_set(ClientError, ER_SQL_EXECUTE,
> + sql_value_text(&t));
> + }
> + rc = SQL_TARANTOOL_ERROR;
> }
> sqlVdbeMemRelease(&t);
> - if (rc) goto abort_due_to_error;
> + assert(rc == SQL_OK || rc == SQL_TARANTOOL_ERROR);
> + if (rc != SQL_OK)
> + goto abort_due_to_error;
Looks like redundant diff
> } else {
> assert(t.flags==MEM_Null);
> }
> @@ -5199,8 +5166,11 @@ case OP_AggFinal: {
> pMem = &aMem[pOp->p1];
> assert((pMem->flags & ~(MEM_Null|MEM_Agg))==0);
> rc = sqlVdbeMemFinalize(pMem, pOp->p4.pFunc);
> - if (rc) {
> - sqlVdbeError(p, "%s", sql_value_text(pMem));
> + if (rc != SQL_OK) {
> + if (rc != SQL_TARANTOOL_ERROR) {
> + diag_set(ClientError, ER_SQL_EXECUTE,
> + sql_value_text(pMem));
Could you please clarify what does this error mean?
It would just print value of memory to string…
The same relates to error in OP_AggStep.
> @@ -5311,10 +5281,8 @@ case OP_IncMaxid: {
> assert(pOp->p1 > 0);
> pOut = &aMem[pOp->p1];
>
> - rc = tarantoolsqlIncrementMaxid((uint64_t*) &pOut->u.i);
> - if (rc!=SQL_OK) {
> + if (tarantoolsqlIncrementMaxid((uint64_t*) &pOut->u.i) != SQL_OK)
> goto abort_due_to_error;
> - }
> pOut->flags = MEM_Int;
> break;
> }
>
> too_big:
> - sqlVdbeError(p, "string or blob too big");
> - rc = SQL_TOOBIG;
> + diag_set(ClientError, ER_SQL_EXECUTE, "string or blob too big”);
-> is too big
> goto abort_due_to_error;
>
> /* Jump to here if a malloc() fails.
> */
> no_mem:
> sqlOomFault(db);
> - sqlVdbeError(p, "out of memory");
> - rc = SQL_NOMEM;
> goto abort_due_to_error;
> }
> diff --git a/src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h
> index a3100e5..b655b5a 100644
> --- a/src/box/sql/vdbeInt.h
> +++ b/src/box/sql/vdbeInt.h
> @@ -248,10 +248,6 @@ struct Mem {
> #define MEM_Agg 0x4000 /* Mem.z points to an agg function context */
> #define MEM_Zero 0x8000 /* Mem.i contains count of 0s appended to blob */
> #define MEM_Subtype 0x10000 /* Mem.eSubtype is valid */
> -#ifdef SQL_OMIT_INCRBLOB
> -#undef MEM_Zero
> -#define MEM_Zero 0x0000
> -#endif
>
>
> @@ -550,13 +545,8 @@ void sqlVdbeMemPrettyPrint(Mem * pMem, char *zBuf);
> #endif
> int sqlVdbeMemHandleBom(Mem * pMem);
>
> -#ifndef SQL_OMIT_INCRBLOB
Still see usage of this macro in code: vdbemem.c : 213
> int sqlVdbeMemExpandBlob(Mem *);
> #define ExpandBlob(P) (((P)->flags&MEM_Zero)?sqlVdbeMemExpandBlob(P):0)
> -#else
> -#define sqlVdbeMemExpandBlob(x) SQL_OK
> -#define ExpandBlob(P) SQL_OK
> -#endif
>
> /**
> * Perform comparison of two keys: one is packed and one is not.
>
>
> diff --git a/src/box/sql/vdbeaux.c b/src/box/sql/vdbeaux.c
> index 27fa5b2..48c2a81 100644
> --- a/src/box/sql/vdbeaux.c
> +++ b/src/box/sql/vdbeaux.c
> void
> @@ -2124,10 +2111,11 @@ sqlVdbeCheckFk(Vdbe * p, int deferred)
> if ((deferred && txn != NULL && txn->psql_txn != NULL &&
> txn->psql_txn->fk_deferred_count > 0) ||
> (!deferred && p->nFkConstraint > 0)) {
> - p->rc = SQL_CONSTRAINT_FOREIGNKEY;
> + p->rc = SQL_TARANTOOL_ERROR;
> p->errorAction = ON_CONFLICT_ACTION_ABORT;
> - sqlVdbeError(p, "FOREIGN KEY constraint failed");
> - return SQL_ERROR;
> + diag_set(ClientError, ER_SQL_EXECUTE, "FOREIGN KEY constraint "\
> + "failed”);
Please, reserve separate error code for this violation.
> + return SQL_TARANTOOL_ERROR;
> }
> return SQL_OK;
Return 0/-1
^ permalink raw reply [flat|nested] 31+ messages in thread
* [tarantool-patches] Re: [PATCH v1 07/12] sql: set errors in VDBE using diag_set()
2019-05-15 13:26 ` [tarantool-patches] " n.pettik
@ 2019-05-25 10:24 ` Mergen Imeev
2019-05-25 10:36 ` Imeev Mergen
0 siblings, 1 reply; 31+ messages in thread
From: Mergen Imeev @ 2019-05-25 10:24 UTC (permalink / raw)
To: n.pettik; +Cc: tarantool-patches
I moved patch "sql: use diag_set() to set an error in SQL
functions" to position before this patch. It allowed to
simplify this patch. New patch below.
On Wed, May 15, 2019 at 04:26:54PM +0300, n.pettik wrote:
>
>
> > On 5 May 2019, at 15:17, imeevma@tarantool.org wrote:
> >
> > After this patch, all errors in VDBE will be set using diag_set().
> >
> > Part of #4074
> > ---
> > src/box/execute.c | 23 +---
> > src/box/sql/vdbe.c | 331 +++++++++++++++++++++-----------------------------
> > src/box/sql/vdbeInt.h | 10 --
> > src/box/sql/vdbeapi.c | 34 +-----
> > src/box/sql/vdbeaux.c | 20 +--
> > 5 files changed, 148 insertions(+), 270 deletions(-)
>
> Please, remove whole sqlErrStr(), tarantoolErrorMessage() -
> they are unused now. The same concerns sql_ret_code() -
> I see no reason keeping it. Please, remove all legacy routines
> connected with error codes.
>
These functions are removed in the following patches.
> > diff --git a/src/box/execute.c b/src/box/execute.c
> > index a3d4a92..e81cc32 100644
> > --- a/src/box/execute.c
> > +++ b/src/box/execute.c
> >
> > @@ -1335,7 +1331,8 @@ case OP_ResultRow: {
> > * not return the number of rows modified. And do not RELEASE the statement
> > * transaction. It needs to be rolled back.
> > */
> > - if (SQL_OK!=(rc = sqlVdbeCheckFk(p, 0))) {
> > + rc = sqlVdbeCheckFk(p, 0);
> > + if (rc != SQL_OK) {
>
> -> if (sqlVdbeCheckFk() != 0)
>
Fixed. I used SQL_OK but it will be replaced by 0 in the
following patches.
> > assert(user_session->sql_flags&SQL_CountRows);
> > goto abort_due_to_error;
> > }
> >
> > @@ -1435,10 +1431,10 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
> > if (str_type_p1 != str_type_p2) {
> > diag_set(ClientError, ER_INCONSISTENT_TYPES,
> > mem_type_to_str(pIn2), mem_type_to_str(pIn1));
> > - rc = SQL_TARANTOOL_ERROR;
> > goto abort_due_to_error;
> > }
> > - if (ExpandBlob(pIn1) || ExpandBlob(pIn2)) goto no_mem;
> > + if (ExpandBlob(pIn1) != SQL_OK || ExpandBlob(pIn2) != SQL_OK)
> > + goto abort_due_to_error;
>
> != 0
> Still need to call sqlOomFault(db); by jumping to no_mem label.
>
Fixed.
> > nByte = pIn1->n + pIn2->n;
> > if (nByte>db->aLimit[SQL_LIMIT_LENGTH]) {
> > goto too_big;
> >
> >
> > @@ -1723,11 +1715,15 @@ case OP_Function: {
> > /* If the function returned an error, throw an exception */
> > if (pCtx->fErrorOrAux) {
> > if (pCtx->isError) {
> > - sqlVdbeError(p, "%s", sql_value_text(pCtx->pOut));
> > - rc = pCtx->isError;
> > + if (pCtx->isError != SQL_TARANTOOL_ERROR) {
>
> How it can be different from SQL_TARANTOOL_ERROR?
>
It was possible, but this part of code was completely
changed after i moved patch "sql: use diag_set() to set an
error in SQL functions" to position before this patch.
> > + diag_set(ClientError, ER_SQL_EXECUTE,
> > + sql_value_text(pCtx->pOut));
> > + }
> > + rc = SQL_TARANTOOL_ERROR;
> > }
> > sqlVdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1);
> > - if (rc) goto abort_due_to_error;
> > + if (rc != SQL_OK)
> > + goto abort_due_to_error;
>
> This diff seems to be redundant
>
Fixed.
> > @@ -1910,8 +1903,7 @@ case OP_Realify: { /* in1 */
> > */
> > case OP_Cast: { /* in1 */
> > pIn1 = &aMem[pOp->p1];
> > - rc = ExpandBlob(pIn1);
> > - if (rc != 0)
> > + if (ExpandBlob(pIn1) != SQL_OK)
>
> != 0
> Please, don’t use SQL_OK value anywhere.
>
I think it's better to use SQL_OK here for integrity. It is
replaced with 0 in one of the following patches.
> >
> > @@ -2802,10 +2784,8 @@ case OP_MakeRecord: {
> > uint32_t tuple_size;
> > char *tuple =
> > sql_vdbe_mem_encode_tuple(pData0, nField, &tuple_size, region);
> > - if (tuple == NULL) {
> > - rc = SQL_TARANTOOL_ERROR;
> > + if (tuple == NULL)
> > goto abort_due_to_error;
> > - }
> > if ((int64_t)tuple_size > db->aLimit[SQL_LIMIT_LENGTH])
> > goto too_big;
> >
> >
> > @@ -2918,8 +2898,10 @@ case OP_Savepoint: {
> > pSavepoint = pSavepoint->pNext
> > );
> > if (!pSavepoint) {
> > - sqlVdbeError(p, "no such savepoint: %s", zName);
> > - rc = SQL_ERROR;
> > + const char *err =
> > + tt_sprintf("no such savepoint: %s", zName);
> > + diag_set(ClientError, ER_SQL_EXECUTE, err);
>
> We already have ER_NO_SUCH_SAVEPOINT.
>
Fixed.
> > @@ -3685,10 +3645,11 @@ case OP_Found: { /* jump, in3 */
> > }
> > }
> > rc = sqlCursorMovetoUnpacked(pC->uc.pCursor, pIdxKey, &res);
> > - if (pFree) sqlDbFree(db, pFree);
> > - if (rc!=SQL_OK) {
> > + if (pFree)
>
> != NULL
>
Fixed.
> >
> > @@ -5164,11 +5126,16 @@ case OP_AggStep: {
> > (pCtx->pFunc->xSFunc)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */
> > if (pCtx->fErrorOrAux) {
> > if (pCtx->isError) {
> > - sqlVdbeError(p, "%s", sql_value_text(&t));
> > - rc = pCtx->isError;
> > + if (pCtx->isError != SQL_TARANTOOL_ERROR) {
> > + diag_set(ClientError, ER_SQL_EXECUTE,
> > + sql_value_text(&t));
> > + }
> > + rc = SQL_TARANTOOL_ERROR;
> > }
> > sqlVdbeMemRelease(&t);
> > - if (rc) goto abort_due_to_error;
> > + assert(rc == SQL_OK || rc == SQL_TARANTOOL_ERROR);
> > + if (rc != SQL_OK)
> > + goto abort_due_to_error;
>
> Looks like redundant diff
>
Fixed.
> > } else {
> > assert(t.flags==MEM_Null);
> > }
> > @@ -5199,8 +5166,11 @@ case OP_AggFinal: {
> > pMem = &aMem[pOp->p1];
> > assert((pMem->flags & ~(MEM_Null|MEM_Agg))==0);
> > rc = sqlVdbeMemFinalize(pMem, pOp->p4.pFunc);
> > - if (rc) {
> > - sqlVdbeError(p, "%s", sql_value_text(pMem));
> > + if (rc != SQL_OK) {
> > + if (rc != SQL_TARANTOOL_ERROR) {
> > + diag_set(ClientError, ER_SQL_EXECUTE,
> > + sql_value_text(pMem));
>
> Could you please clarify what does this error mean?
> It would just print value of memory to string…
> The same relates to error in OP_AggStep.
>
If result was returned using sql_result_error() then it was
possible that diag is not set. This was fixed in patch that
now right before this patch.
> > @@ -5311,10 +5281,8 @@ case OP_IncMaxid: {
> > assert(pOp->p1 > 0);
> > pOut = &aMem[pOp->p1];
> >
> > - rc = tarantoolsqlIncrementMaxid((uint64_t*) &pOut->u.i);
> > - if (rc!=SQL_OK) {
> > + if (tarantoolsqlIncrementMaxid((uint64_t*) &pOut->u.i) != SQL_OK)
> > goto abort_due_to_error;
> > - }
> > pOut->flags = MEM_Int;
> > break;
> > }
> >
> > too_big:
> > - sqlVdbeError(p, "string or blob too big");
> > - rc = SQL_TOOBIG;
> > + diag_set(ClientError, ER_SQL_EXECUTE, "string or blob too big”);
>
> -> is too big
>
Fixed here. Still, it is possible to find this error in
other places. I think it will be fixed when we create error
code for such errors.
> > goto abort_due_to_error;
> >
> > /* Jump to here if a malloc() fails.
> > */
> > no_mem:
> > sqlOomFault(db);
> > - sqlVdbeError(p, "out of memory");
> > - rc = SQL_NOMEM;
> > goto abort_due_to_error;
> > }
> > diff --git a/src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h
> > index a3100e5..b655b5a 100644
> > --- a/src/box/sql/vdbeInt.h
> > +++ b/src/box/sql/vdbeInt.h
> > @@ -248,10 +248,6 @@ struct Mem {
> > #define MEM_Agg 0x4000 /* Mem.z points to an agg function context */
> > #define MEM_Zero 0x8000 /* Mem.i contains count of 0s appended to blob */
> > #define MEM_Subtype 0x10000 /* Mem.eSubtype is valid */
> > -#ifdef SQL_OMIT_INCRBLOB
> > -#undef MEM_Zero
> > -#define MEM_Zero 0x0000
> > -#endif
> >
> >
> > @@ -550,13 +545,8 @@ void sqlVdbeMemPrettyPrint(Mem * pMem, char *zBuf);
> > #endif
> > int sqlVdbeMemHandleBom(Mem * pMem);
> >
> > -#ifndef SQL_OMIT_INCRBLOB
>
> Still see usage of this macro in code: vdbemem.c : 213
>
Fixed.
> > int sqlVdbeMemExpandBlob(Mem *);
> > #define ExpandBlob(P) (((P)->flags&MEM_Zero)?sqlVdbeMemExpandBlob(P):0)
> > -#else
> > -#define sqlVdbeMemExpandBlob(x) SQL_OK
> > -#define ExpandBlob(P) SQL_OK
> > -#endif
> >
> > /**
> > * Perform comparison of two keys: one is packed and one is not.
> >
> >
> > diff --git a/src/box/sql/vdbeaux.c b/src/box/sql/vdbeaux.c
> > index 27fa5b2..48c2a81 100644
> > --- a/src/box/sql/vdbeaux.c
> > +++ b/src/box/sql/vdbeaux.c
> > void
> > @@ -2124,10 +2111,11 @@ sqlVdbeCheckFk(Vdbe * p, int deferred)
> > if ((deferred && txn != NULL && txn->psql_txn != NULL &&
> > txn->psql_txn->fk_deferred_count > 0) ||
> > (!deferred && p->nFkConstraint > 0)) {
> > - p->rc = SQL_CONSTRAINT_FOREIGNKEY;
> > + p->rc = SQL_TARANTOOL_ERROR;
> > p->errorAction = ON_CONFLICT_ACTION_ABORT;
> > - sqlVdbeError(p, "FOREIGN KEY constraint failed");
> > - return SQL_ERROR;
> > + diag_set(ClientError, ER_SQL_EXECUTE, "FOREIGN KEY constraint "\
> > + "failed”);
>
> Please, reserve separate error code for this violation.
>
I am going to do this a bit later, in a different patch.
> > + return SQL_TARANTOOL_ERROR;
> > }
> > return SQL_OK;
>
> Return 0/-1
>
>
Left as it as for now, will be fixed in following patches.
New patch:
From 85cfbe96609b66379631c8d4534c8a9329fb3a47 Mon Sep 17 00:00:00 2001
Date: Mon, 22 Apr 2019 19:41:46 +0300
Subject: [PATCH] sql: set errors in VDBE using diag_set()
After this patch, all errors in VDBE will be set using diag_set().
Part of #4074
diff --git a/src/box/execute.c b/src/box/execute.c
index a3d4a92..e81cc32 100644
--- a/src/box/execute.c
+++ b/src/box/execute.c
@@ -410,8 +410,7 @@ port_sql_dump_msgpack(struct port *port, struct obuf *out)
* @retval -1 Error.
*/
static inline int
-sql_execute(sql *db, struct sql_stmt *stmt, struct port *port,
- struct region *region)
+sql_execute(struct sql_stmt *stmt, struct port *port, struct region *region)
{
int rc, column_count = sql_column_count(stmt);
if (column_count > 0) {
@@ -427,15 +426,8 @@ sql_execute(sql *db, struct sql_stmt *stmt, struct port *port,
rc = sql_step(stmt);
assert(rc != SQL_ROW && rc != SQL_OK);
}
- if (rc != SQL_DONE) {
- if (db->errCode != SQL_TARANTOOL_ERROR) {
- const char *err = (char *)sql_value_text(db->pErr);
- if (err == NULL)
- err = sqlErrStr(db->errCode);
- diag_set(ClientError, ER_SQL_EXECUTE, err);
- }
+ if (rc != SQL_DONE)
return -1;
- }
return 0;
}
@@ -446,19 +438,12 @@ sql_prepare_and_execute(const char *sql, int len, const struct sql_bind *bind,
{
struct sql_stmt *stmt;
struct sql *db = sql_get();
- if (sql_prepare_v2(db, sql, len, &stmt, NULL) != SQL_OK) {
- if (db->errCode != SQL_TARANTOOL_ERROR) {
- const char *err = (char *)sql_value_text(db->pErr);
- if (err == NULL)
- err = sqlErrStr(db->errCode);
- diag_set(ClientError, ER_SQL_EXECUTE, err);
- }
+ if (sql_prepare_v2(db, sql, len, &stmt, NULL) != SQL_OK)
return -1;
- }
assert(stmt != NULL);
port_sql_create(port, stmt);
if (sql_bind(stmt, bind, bind_count) == 0 &&
- sql_execute(db, stmt, port, region) == 0)
+ sql_execute(stmt, port, region) == 0)
return 0;
port_destroy(port);
return -1;
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index 7d85959..b64293a 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -986,7 +986,7 @@ case OP_Halt: {
p->rc = SQL_BUSY;
} else {
assert(rc==SQL_OK || (p->rc&0xff)==SQL_CONSTRAINT);
- rc = p->rc ? SQL_ERROR : SQL_DONE;
+ rc = p->rc ? SQL_TARANTOOL_ERROR : SQL_DONE;
}
goto vdbe_return;
}
@@ -1098,17 +1098,13 @@ case OP_NextAutoincValue: {
assert(pOp->p2 > 0);
struct space *space = space_by_id(pOp->p1);
- if (space == NULL) {
- rc = SQL_TARANTOOL_ERROR;
+ if (space == NULL)
goto abort_due_to_error;
- }
int64_t value;
struct sequence *sequence = space->sequence;
- if (sequence == NULL || sequence_next(sequence, &value) != 0) {
- rc = SQL_TARANTOOL_ERROR;
+ if (sequence == NULL || sequence_next(sequence, &value) != 0)
goto abort_due_to_error;
- }
pOut = out2Prerelease(p, pOp);
pOut->flags = MEM_Int;
@@ -1335,7 +1331,7 @@ case OP_ResultRow: {
* not return the number of rows modified. And do not RELEASE the statement
* transaction. It needs to be rolled back.
*/
- if (SQL_OK!=(rc = sqlVdbeCheckFk(p, 0))) {
+ if (sqlVdbeCheckFk(p, 0) != SQL_OK) {
assert(user_session->sql_flags&SQL_CountRows);
goto abort_due_to_error;
}
@@ -1427,7 +1423,6 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
mem_type_to_str(pIn2);
diag_set(ClientError, ER_INCONSISTENT_TYPES, "TEXT or BLOB",
inconsistent_type);
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
@@ -1435,10 +1430,10 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
if (str_type_p1 != str_type_p2) {
diag_set(ClientError, ER_INCONSISTENT_TYPES,
mem_type_to_str(pIn2), mem_type_to_str(pIn1));
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
- if (ExpandBlob(pIn1) || ExpandBlob(pIn2)) goto no_mem;
+ if (ExpandBlob(pIn1) != SQL_OK || ExpandBlob(pIn2) != SQL_OK)
+ goto abort_due_to_error;
nByte = pIn1->n + pIn2->n;
if (nByte>db->aLimit[SQL_LIMIT_LENGTH]) {
goto too_big;
@@ -1551,13 +1546,11 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
if (sqlVdbeRealValue(pIn1, &rA) != 0) {
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
sql_value_text(pIn1), "numeric");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
if (sqlVdbeRealValue(pIn2, &rB) != 0) {
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
sql_value_text(pIn2), "numeric");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
switch( pOp->opcode) {
@@ -1597,11 +1590,9 @@ arithmetic_result_is_null:
division_by_zero:
diag_set(ClientError, ER_SQL_EXECUTE, "division by zero");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
integer_overflow:
diag_set(ClientError, ER_SQL_EXECUTE, "integer is overflowed");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
@@ -1721,10 +1712,8 @@ case OP_Function: {
(*pCtx->pFunc->xSFunc)(pCtx, pCtx->argc, pCtx->argv);/* IMP: R-24505-23230 */
/* If the function returned an error, throw an exception */
- if (pCtx->is_aborted) {
- rc = SQL_TARANTOOL_ERROR;
+ if (pCtx->is_aborted)
goto abort_due_to_error;
- }
/* Copy the result of the function into register P3 */
if (pOut->flags & (MEM_Str|MEM_Blob)) {
@@ -1785,13 +1774,11 @@ case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */
if (sqlVdbeIntValue(pIn2, (int64_t *) &iA) != 0) {
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
sql_value_text(pIn2), "integer");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
if (sqlVdbeIntValue(pIn1, (int64_t *) &iB) != 0) {
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
sql_value_text(pIn1), "integer");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
op = pOp->opcode;
@@ -1860,7 +1847,6 @@ case OP_MustBeInt: { /* jump, in1 */
if (pOp->p2==0) {
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
sql_value_text(pIn1), "integer");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
} else {
goto jump_to_p2;
@@ -1906,8 +1892,7 @@ case OP_Realify: { /* in1 */
*/
case OP_Cast: { /* in1 */
pIn1 = &aMem[pOp->p1];
- rc = ExpandBlob(pIn1);
- if (rc != 0)
+ if (ExpandBlob(pIn1) != SQL_OK)
goto abort_due_to_error;
rc = sqlVdbeMemCast(pIn1, pOp->p2);
UPDATE_MAX_BLOBSIZE(pIn1);
@@ -1915,7 +1900,6 @@ case OP_Cast: { /* in1 */
break;
diag_set(ClientError, ER_SQL_TYPE_MISMATCH, sql_value_text(pIn1),
field_type_strs[pOp->p2]);
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
#endif /* SQL_OMIT_CAST */
@@ -2068,7 +2052,6 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
mem_type_to_str(pIn3);
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
inconsistent_type, "boolean");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
res = sqlMemCompare(pIn3, pIn1, NULL);
@@ -2087,7 +2070,6 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
ER_SQL_TYPE_MISMATCH,
sql_value_text(pIn3),
"numeric");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
@@ -2329,7 +2311,6 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */
} else {
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
sql_value_text(pIn1), "boolean");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
pIn2 = &aMem[pOp->p2];
@@ -2340,7 +2321,6 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */
} else {
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
sql_value_text(pIn2), "boolean");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
if (pOp->opcode==OP_And) {
@@ -2374,7 +2354,6 @@ case OP_Not: { /* same as TK_NOT, in1, out2 */
if ((pIn1->flags & MEM_Bool) == 0) {
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
sql_value_text(pIn1), "boolean");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
mem_set_bool(pOut, ! pIn1->u.b);
@@ -2398,7 +2377,6 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */
if (sqlVdbeIntValue(pIn1, &i) != 0) {
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
sql_value_text(pIn1), "integer");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
pOut->flags = MEM_Int;
@@ -2446,7 +2424,6 @@ case OP_IfNot: { /* jump, in1 */
} else {
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
sql_value_text(pIn1), "boolean");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
VdbeBranchTaken(c!=0, 2);
@@ -2586,8 +2563,9 @@ case OP_Column: {
zEnd = zData + pC->payloadSize;
} else {
memset(&sMem, 0, sizeof(sMem));
- rc = sqlVdbeMemFromBtree(pC->uc.pCursor, 0, pC->payloadSize, &sMem);
- if (rc!=SQL_OK) goto abort_due_to_error;
+ if (sqlVdbeMemFromBtree(pC->uc.pCursor, 0, pC->payloadSize,
+ &sMem) != SQL_OK)
+ goto abort_due_to_error;
zData = (u8*)sMem.z;
zEnd = zData + pC->payloadSize;
}
@@ -2646,10 +2624,8 @@ case OP_Column: {
}
uint32_t unused;
if (vdbe_decode_msgpack_into_mem((const char *)(zData + aOffset[p2]),
- pDest, &unused) != 0) {
- rc = SQL_TARANTOOL_ERROR;
+ pDest, &unused) != 0)
goto abort_due_to_error;
- }
/* MsgPack map, array or extension (unsupported in sql).
* Wrap it in a blob verbatim.
*/
@@ -2683,7 +2659,11 @@ case OP_Column: {
if ((pDest->flags & (MEM_Ephem | MEM_Str)) == (MEM_Ephem | MEM_Str)) {
int len = pDest->n;
if (pDest->szMalloc<len+1) {
- if (sqlVdbeMemGrow(pDest, len+1, 1)) goto op_column_error;
+ if (sqlVdbeMemGrow(pDest, len + 1, 1)) {
+ if (zData != pC->aRow)
+ sqlVdbeMemRelease(&sMem);
+ goto abort_due_to_error;
+ }
} else {
pDest->z = memcpy(pDest->zMalloc, pDest->z, len);
pDest->flags &= ~MEM_Ephem;
@@ -2697,10 +2677,6 @@ case OP_Column: {
UPDATE_MAX_BLOBSIZE(pDest);
REGISTER_TRACE(pOp->p3, pDest);
break;
-
- op_column_error:
- if (zData!=pC->aRow) sqlVdbeMemRelease(&sMem);
- goto abort_due_to_error;
}
/* Opcode: ApplyType P1 P2 * P4 *
@@ -2725,7 +2701,6 @@ case OP_ApplyType: {
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
sql_value_text(pIn1),
field_type_strs[type]);
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
pIn1++;
@@ -2798,10 +2773,8 @@ case OP_MakeRecord: {
uint32_t tuple_size;
char *tuple =
sql_vdbe_mem_encode_tuple(pData0, nField, &tuple_size, region);
- if (tuple == NULL) {
- rc = SQL_TARANTOOL_ERROR;
+ if (tuple == NULL)
goto abort_due_to_error;
- }
if ((int64_t)tuple_size > db->aLimit[SQL_LIMIT_LENGTH])
goto too_big;
@@ -2856,13 +2829,14 @@ case OP_Count: { /* out2 */
assert(pCrsr);
nEntry = 0; /* Not needed. Only used to silence a warning. */
if (pCrsr->curFlags & BTCF_TaCursor) {
- rc = tarantoolsqlCount(pCrsr, &nEntry);
+ if (tarantoolsqlCount(pCrsr, &nEntry) != SQL_OK)
+ goto abort_due_to_error;
} else if (pCrsr->curFlags & BTCF_TEphemCursor) {
- rc = tarantoolsqlEphemeralCount(pCrsr, &nEntry);
+ if (tarantoolsqlEphemeralCount(pCrsr, &nEntry) != SQL_OK)
+ goto abort_due_to_error;
} else {
unreachable();
}
- if (rc) goto abort_due_to_error;
pOut = out2Prerelease(p, pOp);
pOut->u.i = nEntry;
break;
@@ -2886,7 +2860,6 @@ case OP_Savepoint: {
if (psql_txn == NULL) {
assert(!box_txn());
diag_set(ClientError, ER_NO_TRANSACTION);
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
p1 = pOp->p1;
@@ -2914,8 +2887,8 @@ case OP_Savepoint: {
pSavepoint = pSavepoint->pNext
);
if (!pSavepoint) {
- sqlVdbeError(p, "no such savepoint: %s", zName);
- rc = SQL_ERROR;
+ diag_set(ClientError, ER_NO_SUCH_SAVEPOINT);
+ goto abort_due_to_error;
} else {
/* Determine whether or not this is a transaction savepoint. If so,
@@ -2932,7 +2905,8 @@ case OP_Savepoint: {
p->rc = rc = SQL_BUSY;
goto vdbe_return;
}
- rc = p->rc;
+ if (p->rc != SQL_OK)
+ goto abort_due_to_error;
} else {
if (p1==SAVEPOINT_ROLLBACK)
box_txn_rollback_to_savepoint(pSavepoint->tnt_savepoint);
@@ -2964,7 +2938,6 @@ case OP_Savepoint: {
}
}
}
- if (rc) goto abort_due_to_error;
break;
}
@@ -2987,7 +2960,6 @@ case OP_CheckViewReferences: {
if (space->def->view_ref_count > 0) {
diag_set(ClientError, ER_DROP_SPACE, space->def->name,
"other views depend on this space");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
break;
@@ -3000,10 +2972,8 @@ case OP_CheckViewReferences: {
* Otherwise, raise an error with appropriate error message.
*/
case OP_TransactionBegin: {
- if (sql_txn_begin(p) != 0) {
- rc = SQL_TARANTOOL_ERROR;
+ if (sql_txn_begin(p) != 0)
goto abort_due_to_error;
- }
p->auto_commit = false ;
break;
}
@@ -3019,13 +2989,11 @@ case OP_TransactionBegin: {
case OP_TransactionCommit: {
struct txn *txn = in_txn();
if (txn != NULL) {
- if (txn_commit(txn) != 0) {
- rc = SQL_TARANTOOL_ERROR;
+ if (txn_commit(txn) != 0)
goto abort_due_to_error;
- }
} else {
- sqlVdbeError(p, "cannot commit - no transaction is active");
- rc = SQL_ERROR;
+ diag_set(ClientError, ER_SQL_EXECUTE, "cannot commit - no "\
+ "transaction is active");
goto abort_due_to_error;
}
break;
@@ -3038,14 +3006,11 @@ case OP_TransactionCommit: {
*/
case OP_TransactionRollback: {
if (box_txn()) {
- if (box_txn_rollback() != 0) {
- rc = SQL_TARANTOOL_ERROR;
+ if (box_txn_rollback() != 0)
goto abort_due_to_error;
- }
} else {
- sqlVdbeError(p, "cannot rollback - no "
- "transaction is active");
- rc = SQL_ERROR;
+ diag_set(ClientError, ER_SQL_EXECUTE, "cannot rollback - no "\
+ "transaction is active");
goto abort_due_to_error;
}
break;
@@ -3063,16 +3028,12 @@ case OP_TransactionRollback: {
*/
case OP_TTransaction: {
if (!box_txn()) {
- if (sql_txn_begin(p) != 0) {
- rc = SQL_TARANTOOL_ERROR;
+ if (sql_txn_begin(p) != 0)
goto abort_due_to_error;
- }
} else {
p->anonymous_savepoint = sql_savepoint(p, NULL);
- if (p->anonymous_savepoint == NULL) {
- rc = SQL_TARANTOOL_ERROR;
+ if (p->anonymous_savepoint == NULL)
goto abort_due_to_error;
- }
}
break;
}
@@ -3111,9 +3072,8 @@ case OP_IteratorOpen:
if (box_schema_version() != p->schema_ver &&
(pOp->p5 & OPFLAG_SYSTEMSP) == 0) {
p->expired = 1;
- rc = SQL_ERROR;
- sqlVdbeError(p, "schema version has changed: " \
- "need to re-compile SQL statement");
+ diag_set(ClientError, ER_SQL_EXECUTE, "schema version has "\
+ "changed: need to re-compile SQL statement");
goto abort_due_to_error;
}
struct space *space;
@@ -3122,10 +3082,8 @@ case OP_IteratorOpen:
else
space = aMem[pOp->p3].u.p;
assert(space != NULL);
- if (access_check_space(space, PRIV_R) != 0) {
- rc = SQL_TARANTOOL_ERROR;
+ if (access_check_space(space, PRIV_R) != 0)
goto abort_due_to_error;
- }
struct index *index = space_index(space, pOp->p2);
assert(index != NULL);
@@ -3148,8 +3106,6 @@ case OP_IteratorOpen:
cur->nullRow = 1;
open_cursor_set_hints:
cur->uc.pCursor->hints = pOp->p5 & OPFLAG_SEEKEQ;
- if (rc != 0)
- goto abort_due_to_error;
break;
}
@@ -3171,10 +3127,8 @@ case OP_OpenTEphemeral: {
struct space *space = sql_ephemeral_space_create(pOp->p2,
pOp->p4.key_info);
- if (space == NULL) {
- rc = SQL_TARANTOOL_ERROR;
+ if (space == NULL)
goto abort_due_to_error;
- }
aMem[pOp->p1].u.p = space;
aMem[pOp->p1].flags = MEM_Ptr;
break;
@@ -3200,8 +3154,8 @@ case OP_SorterOpen: {
pCx = allocateCursor(p, pOp->p1, pOp->p2, CURTYPE_SORTER);
if (pCx==0) goto no_mem;
pCx->key_def = def;
- rc = sqlVdbeSorterInit(db, pCx);
- if (rc) goto abort_due_to_error;
+ if (sqlVdbeSorterInit(db, pCx) != SQL_OK)
+ goto abort_due_to_error;
break;
}
@@ -3433,7 +3387,6 @@ case OP_SeekGT: { /* jump, in3 */
} else {
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
sql_value_text(pIn3), "integer");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
iKey = i;
@@ -3514,10 +3467,8 @@ case OP_SeekGT: { /* jump, in3 */
#endif
r.eqSeen = 0;
r.opcode = oc;
- rc = sqlCursorMovetoUnpacked(pC->uc.pCursor, &r, &res);
- if (rc!=SQL_OK) {
+ if (sqlCursorMovetoUnpacked(pC->uc.pCursor, &r, &res) != SQL_OK)
goto abort_due_to_error;
- }
if (eqOnly && r.eqSeen==0) {
assert(res!=0);
goto seek_not_found;
@@ -3529,8 +3480,8 @@ case OP_SeekGT: { /* jump, in3 */
if (oc>=OP_SeekGE) { assert(oc==OP_SeekGE || oc==OP_SeekGT);
if (res<0 || (res==0 && oc==OP_SeekGT)) {
res = 0;
- rc = sqlCursorNext(pC->uc.pCursor, &res);
- if (rc!=SQL_OK) goto abort_due_to_error;
+ if (sqlCursorNext(pC->uc.pCursor, &res) != SQL_OK)
+ goto abort_due_to_error;
} else {
res = 0;
}
@@ -3538,8 +3489,8 @@ case OP_SeekGT: { /* jump, in3 */
assert(oc==OP_SeekLT || oc==OP_SeekLE);
if (res>0 || (res==0 && oc==OP_SeekLT)) {
res = 0;
- rc = sqlCursorPrevious(pC->uc.pCursor, &res);
- if (rc!=SQL_OK) goto abort_due_to_error;
+ if (sqlCursorPrevious(pC->uc.pCursor, &res) != SQL_OK)
+ goto abort_due_to_error;
} else {
/* res might be negative because the table is empty. Check to
* see if this is the case.
@@ -3681,10 +3632,11 @@ case OP_Found: { /* jump, in3 */
}
}
rc = sqlCursorMovetoUnpacked(pC->uc.pCursor, pIdxKey, &res);
- if (pFree) sqlDbFree(db, pFree);
- if (rc!=SQL_OK) {
+ if (pFree != NULL)
+ sqlDbFree(db, pFree);
+ assert(rc == SQL_OK || rc == SQL_TARANTOOL_ERROR);
+ if (rc != SQL_OK)
goto abort_due_to_error;
- }
pC->seekResult = res;
alreadyExists = (res==0);
pC->nullRow = 1-alreadyExists;
@@ -3744,10 +3696,8 @@ case OP_NextIdEphemeral: {
struct space *space = (struct space*)p->aMem[pOp->p1].u.p;
assert(space->def->id == 0);
uint64_t rowid;
- if (space->vtab->ephemeral_rowid_next(space, &rowid) != 0) {
- rc = SQL_TARANTOOL_ERROR;
+ if (space->vtab->ephemeral_rowid_next(space, &rowid) != 0)
goto abort_due_to_error;
- }
/*
* FIXME: since memory cell can comprise only 32-bit
* integer, make sure it can fit in. This check should
@@ -3756,7 +3706,6 @@ case OP_NextIdEphemeral: {
*/
if (rowid > INT32_MAX) {
diag_set(ClientError, ER_ROWID_OVERFLOW);
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
pOut = &aMem[pOp->p2];
@@ -3903,7 +3852,8 @@ case OP_SorterCompare: {
pIn3 = &aMem[pOp->p3];
nKeyCol = pOp->p4.i;
res = 0;
- rc = sqlVdbeSorterCompare(pC, pIn3, nKeyCol, &res);
+ if (sqlVdbeSorterCompare(pC, pIn3, nKeyCol, &res) != 0)
+ rc = SQL_TARANTOOL_ERROR;
VdbeBranchTaken(res!=0,2);
if (rc) goto abort_due_to_error;
if (res) goto jump_to_p2;
@@ -3928,10 +3878,10 @@ case OP_SorterData: {
pOut = &aMem[pOp->p2];
pC = p->apCsr[pOp->p1];
assert(isSorter(pC));
- rc = sqlVdbeSorterRowkey(pC, pOut);
- assert(rc!=SQL_OK || (pOut->flags & MEM_Blob));
+ if (sqlVdbeSorterRowkey(pC, pOut) != SQL_OK)
+ goto abort_due_to_error;
+ assert(pOut->flags & MEM_Blob);
assert(pOp->p1>=0 && pOp->p1<p->nCursor);
- if (rc) goto abort_due_to_error;
p->apCsr[pOp->p3]->cacheStatus = CACHE_STALE;
break;
}
@@ -3998,11 +3948,9 @@ case OP_RowData: {
testcase( n==0);
sqlVdbeMemRelease(pOut);
- rc = sql_vdbe_mem_alloc_region(pOut, n);
- if (rc)
- goto no_mem;
- rc = sqlCursorPayload(pCrsr, 0, n, pOut->z);
- if (rc) goto abort_due_to_error;
+ if (sql_vdbe_mem_alloc_region(pOut, n) != SQL_OK ||
+ sqlCursorPayload(pCrsr, 0, n, pOut->z) != SQL_OK)
+ goto abort_due_to_error;
UPDATE_MAX_BLOBSIZE(pOut);
REGISTER_TRACE(pOp->p2, pOut);
break;
@@ -4137,15 +4085,18 @@ case OP_Rewind: { /* jump */
pC->seekOp = OP_Rewind;
#endif
if (isSorter(pC)) {
- rc = sqlVdbeSorterRewind(pC, &res);
+ if (sqlVdbeSorterRewind(pC, &res) != SQL_OK)
+ goto abort_due_to_error;
} else {
assert(pC->eCurType==CURTYPE_TARANTOOL);
pCrsr = pC->uc.pCursor;
assert(pCrsr);
- rc = tarantoolsqlFirst(pCrsr, &res);
+ if (tarantoolsqlFirst(pCrsr, &res) != SQL_OK)
+ rc = SQL_TARANTOOL_ERROR;
pC->cacheStatus = CACHE_STALE;
+ if (rc != SQL_OK)
+ goto abort_due_to_error;
}
- if (rc) goto abort_due_to_error;
pC->nullRow = (u8)res;
assert(pOp->p2>0 && pOp->p2<p->nOp);
VdbeBranchTaken(res!=0,2);
@@ -4291,11 +4242,8 @@ case OP_SorterInsert: { /* in2 */
assert(isSorter(cursor));
pIn2 = &aMem[pOp->p2];
assert((pIn2->flags & MEM_Blob) != 0);
- rc = ExpandBlob(pIn2);
- if (rc != 0)
- goto abort_due_to_error;
- rc = sqlVdbeSorterWrite(cursor, pIn2);
- if (rc != 0)
+ if (ExpandBlob(pIn2) != SQL_OK ||
+ sqlVdbeSorterWrite(cursor, pIn2) != SQL_OK)
goto abort_due_to_error;
break;
}
@@ -4325,8 +4273,7 @@ case OP_IdxInsert: {
assert((pIn2->flags & MEM_Blob) != 0);
if (pOp->p5 & OPFLAG_NCHANGE)
p->nChange++;
- rc = ExpandBlob(pIn2);
- if (rc != 0)
+ if (ExpandBlob(pIn2) != SQL_OK)
goto abort_due_to_error;
struct space *space;
if (pOp->p4type == P4_SPACEPTR)
@@ -4360,6 +4307,7 @@ case OP_IdxInsert: {
} else if (pOp->p5 & OPFLAG_OE_ROLLBACK) {
p->errorAction = ON_CONFLICT_ACTION_ROLLBACK;
}
+ assert(rc == SQL_OK || rc == SQL_TARANTOOL_ERROR);
if (rc != 0)
goto abort_due_to_error;
break;
@@ -4427,14 +4375,12 @@ case OP_Update: {
if (is_error) {
diag_set(OutOfMemory, stream.pos - stream.buf,
"mpstream_flush", "stream");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
uint32_t ops_size = region_used(region) - used;
const char *ops = region_join(region, ops_size);
if (ops == NULL) {
diag_set(OutOfMemory, ops_size, "region_join", "raw");
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
}
@@ -4460,6 +4406,7 @@ case OP_Update: {
} else if (pOp->p5 & OPFLAG_OE_ROLLBACK) {
p->errorAction = ON_CONFLICT_ACTION_ROLLBACK;
}
+ assert(rc == SQL_OK || rc == SQL_TARANTOOL_ERROR);
if (rc != 0)
goto abort_due_to_error;
break;
@@ -4510,8 +4457,7 @@ case OP_SDelete: {
struct space *space = space_by_id(pOp->p1);
assert(space != NULL);
assert(space_is_system(space));
- rc = sql_delete_by_key(space, 0, pIn2->z, pIn2->n);
- if (rc)
+ if (sql_delete_by_key(space, 0, pIn2->z, pIn2->n) != SQL_OK)
goto abort_due_to_error;
if (pOp->p5 & OPFLAG_NCHANGE)
p->nChange++;
@@ -4545,18 +4491,19 @@ case OP_IdxDelete: {
r.default_rc = 0;
r.aMem = &aMem[pOp->p2];
r.opcode = OP_IdxDelete;
- rc = sqlCursorMovetoUnpacked(pCrsr, &r, &res);
- if (rc) goto abort_due_to_error;
+ if (sqlCursorMovetoUnpacked(pCrsr, &r, &res) != SQL_OK)
+ goto abort_due_to_error;
if (res==0) {
assert(pCrsr->eState == CURSOR_VALID);
if (pCrsr->curFlags & BTCF_TaCursor) {
- rc = tarantoolsqlDelete(pCrsr, 0);
+ if (tarantoolsqlDelete(pCrsr, 0) != SQL_OK)
+ goto abort_due_to_error;
} else if (pCrsr->curFlags & BTCF_TEphemCursor) {
- rc = tarantoolsqlEphemeralDelete(pCrsr);
+ if (tarantoolsqlEphemeralDelete(pCrsr) != SQL_OK)
+ goto abort_due_to_error;
} else {
unreachable();
}
- if (rc) goto abort_due_to_error;
}
pC->cacheStatus = CACHE_STALE;
pC->seekResult = 0;
@@ -4668,14 +4615,14 @@ case OP_Clear: {
rc = 0;
if (pOp->p2 > 0) {
if (box_truncate(space_id) != 0)
- rc = SQL_TARANTOOL_ERROR;
+ goto abort_due_to_error;
} else {
uint32_t tuple_count;
- rc = tarantoolsqlClearTable(space, &tuple_count);
- if (rc == 0 && (pOp->p5 & OPFLAG_NCHANGE) != 0)
+ if (tarantoolsqlClearTable(space, &tuple_count) != SQL_OK)
+ goto abort_due_to_error;
+ if ((pOp->p5 & OPFLAG_NCHANGE) != 0)
p->nChange += tuple_count;
}
- if (rc) goto abort_due_to_error;
break;
}
@@ -4698,8 +4645,8 @@ case OP_ResetSorter: {
} else {
assert(pC->eCurType==CURTYPE_TARANTOOL);
assert(pC->uc.pCursor->curFlags & BTCF_TEphemCursor);
- rc = tarantoolsqlEphemeralClearTable(pC->uc.pCursor);
- if (rc) goto abort_due_to_error;
+ if (tarantoolsqlEphemeralClearTable(pC->uc.pCursor) != SQL_OK)
+ goto abort_due_to_error;
}
break;
}
@@ -4732,8 +4679,8 @@ case OP_RenameTable: {
zNewTableName = pOp->p4.z;
zOldTableName = sqlDbStrNDup(db, zOldTableName,
sqlStrlen30(zOldTableName));
- rc = sql_rename_table(space_id, zNewTableName);
- if (rc) goto abort_due_to_error;
+ if (sql_rename_table(space_id, zNewTableName) != SQL_OK)
+ goto abort_due_to_error;
/*
* Rebuild 'CREATE TRIGGER' expressions of all triggers
* created on this table. Sure, this action is not atomic
@@ -4743,20 +4690,18 @@ case OP_RenameTable: {
for (struct sql_trigger *trigger = triggers; trigger != NULL; ) {
/* Store pointer as trigger will be destructed. */
struct sql_trigger *next_trigger = trigger->next;
- rc = tarantoolsqlRenameTrigger(trigger->zName,
- zOldTableName, zNewTableName);
- if (rc != SQL_OK) {
- /*
- * FIXME: In the case of error,
- * part of triggers would have invalid
- * space name in tuple so can not been
- * persisted.
- * Server could be restarted.
- * In this case, rename table back and
- * try again.
- */
+ /*
+ * FIXME: In the case of error,
+ * part of triggers would have invalid
+ * space name in tuple so can not been
+ * persisted.
+ * Server could be restarted.
+ * In this case, rename table back and
+ * try again.
+ */
+ if (tarantoolsqlRenameTrigger(trigger->zName, zOldTableName,
+ zNewTableName) != SQL_OK)
goto abort_due_to_error;
- }
trigger = next_trigger;
}
sqlDbFree(db, (void*)zOldTableName);
@@ -4771,8 +4716,8 @@ case OP_RenameTable: {
*/
case OP_LoadAnalysis: {
assert(pOp->p1==0 );
- rc = sql_analysis_load(db);
- if (rc) goto abort_due_to_error;
+ if (sql_analysis_load(db) != SQL_OK)
+ goto abort_due_to_error;
break;
}
@@ -4828,8 +4773,8 @@ case OP_Program: { /* jump */
}
if (p->nFrame>=db->aLimit[SQL_LIMIT_TRIGGER_DEPTH]) {
- rc = SQL_ERROR;
- sqlVdbeError(p, "too many levels of trigger recursion");
+ diag_set(ClientError, ER_SQL_EXECUTE, "too many levels of "\
+ "trigger recursion");
goto abort_due_to_error;
}
@@ -5157,11 +5102,9 @@ case OP_AggStep: {
(pCtx->pFunc->xSFunc)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */
if (pCtx->is_aborted) {
sqlVdbeMemRelease(&t);
- rc = SQL_TARANTOOL_ERROR;
goto abort_due_to_error;
- } else {
- assert(t.flags==MEM_Null);
}
+ assert(t.flags==MEM_Null);
if (pCtx->skipFlag) {
assert(pOp[-1].opcode==OP_CollSeq);
i = pOp[-1].p1;
@@ -5188,11 +5131,8 @@ case OP_AggFinal: {
assert(pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor));
pMem = &aMem[pOp->p1];
assert((pMem->flags & ~(MEM_Null|MEM_Agg))==0);
- rc = sqlVdbeMemFinalize(pMem, pOp->p4.pFunc);
- if (rc) {
- sqlVdbeError(p, "%s", sql_value_text(pMem));
+ if (sqlVdbeMemFinalize(pMem, pOp->p4.pFunc) != 0)
goto abort_due_to_error;
- }
UPDATE_MAX_BLOBSIZE(pMem);
if (sqlVdbeMemTooBig(pMem)) {
goto too_big;
@@ -5301,10 +5241,8 @@ case OP_IncMaxid: {
assert(pOp->p1 > 0);
pOut = &aMem[pOp->p1];
- rc = tarantoolsqlIncrementMaxid((uint64_t*) &pOut->u.i);
- if (rc!=SQL_OK) {
+ if (tarantoolsqlIncrementMaxid((uint64_t*) &pOut->u.i) != SQL_OK)
goto abort_due_to_error;
- }
pOut->flags = MEM_Int;
break;
}
@@ -5368,28 +5306,8 @@ default: { /* This is really OP_Noop and OP_Explain */
* an error of some kind.
*/
abort_due_to_error:
- if (db->mallocFailed) rc = SQL_NOMEM;
- assert(rc);
- if (p->zErrMsg==0 && rc!=SQL_IOERR_NOMEM) {
- const char *msg;
- /* Avoiding situation when Tarantool error is set,
- * but error message isn't.
- */
- if (rc == SQL_TARANTOOL_ERROR && tarantoolErrorMessage()) {
- msg = tarantoolErrorMessage();
- } else {
- msg = sqlErrStr(rc);
- }
- sqlVdbeError(p, "%s", msg);
- }
+ rc = SQL_TARANTOOL_ERROR;
p->rc = rc;
- sqlSystemError(db, rc);
- testcase( sqlGlobalConfig.xLog!=0);
- sql_log(rc, "statement aborts at %d: [%s] %s",
- (int)(pOp - aOp), p->zSql, p->zErrMsg);
- sqlVdbeHalt(p);
- if (rc==SQL_IOERR_NOMEM) sqlOomFault(db);
- rc = SQL_ERROR;
/* This is the only way out of this procedure. */
vdbe_return:
@@ -5398,21 +5316,20 @@ vdbe_return:
assert(rc!=SQL_OK || nExtraDelete==0
|| sql_strlike_ci("DELETE%", p->zSql, 0) != 0
);
+ assert(rc == SQL_OK || rc == SQL_BUSY || rc == SQL_TARANTOOL_ERROR ||
+ rc == SQL_ROW || rc == SQL_DONE);
return rc;
/* Jump to here if a string or blob larger than SQL_MAX_LENGTH
* is encountered.
*/
too_big:
- sqlVdbeError(p, "string or blob too big");
- rc = SQL_TOOBIG;
+ diag_set(ClientError, ER_SQL_EXECUTE, "string or blob too big");
goto abort_due_to_error;
/* Jump to here if a malloc() fails.
*/
no_mem:
sqlOomFault(db);
- sqlVdbeError(p, "out of memory");
- rc = SQL_NOMEM;
goto abort_due_to_error;
}
diff --git a/src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h
index ee14510..9e6a426 100644
--- a/src/box/sql/vdbeInt.h
+++ b/src/box/sql/vdbeInt.h
@@ -244,10 +244,6 @@ struct Mem {
#define MEM_Agg 0x4000 /* Mem.z points to an agg function context */
#define MEM_Zero 0x8000 /* Mem.i contains count of 0s appended to blob */
#define MEM_Subtype 0x10000 /* Mem.eSubtype is valid */
-#ifdef SQL_OMIT_INCRBLOB
-#undef MEM_Zero
-#define MEM_Zero 0x0000
-#endif
/**
* In contrast to Mem_TypeMask, this one allows to get
@@ -450,7 +446,6 @@ struct Vdbe {
/*
* Function prototypes
*/
-void sqlVdbeError(Vdbe *, const char *, ...);
void sqlVdbeFreeCursor(Vdbe *, VdbeCursor *);
void sqlVdbePopStack(Vdbe *, int);
int sqlVdbeCursorRestore(VdbeCursor *);
@@ -532,13 +527,8 @@ void sqlVdbeMemPrettyPrint(Mem * pMem, char *zBuf);
#endif
int sqlVdbeMemHandleBom(Mem * pMem);
-#ifndef SQL_OMIT_INCRBLOB
int sqlVdbeMemExpandBlob(Mem *);
#define ExpandBlob(P) (((P)->flags&MEM_Zero)?sqlVdbeMemExpandBlob(P):0)
-#else
-#define sqlVdbeMemExpandBlob(x) SQL_OK
-#define ExpandBlob(P) SQL_OK
-#endif
/**
* Perform comparison of two keys: one is packed and one is not.
diff --git a/src/box/sql/vdbeapi.c b/src/box/sql/vdbeapi.c
index 673ccd1..3bdfa7d 100644
--- a/src/box/sql/vdbeapi.c
+++ b/src/box/sql/vdbeapi.c
@@ -536,15 +536,6 @@ sqlStep(Vdbe * p)
p->rc = SQL_NOMEM;
}
end_of_step:
- /* At this point local variable rc holds the value that should be
- * returned if this statement was compiled using the legacy
- * sql_prepare() interface. According to the docs, this can only
- * be one of the values in the first assert() below. Variable p->rc
- * contains the value that would be returned if sql_finalize()
- * were called on statement p.
- */
- assert(rc == SQL_ROW || rc == SQL_DONE || rc == SQL_ERROR
- || (rc & 0xff) == SQL_BUSY || rc == SQL_MISUSE);
if (p->isPrepareV2 && rc != SQL_ROW && rc != SQL_DONE) {
/* If this statement was prepared using sql_prepare_v2(), and an
* error has occurred, then return the error code in p->rc to the
@@ -564,20 +555,17 @@ int
sql_step(sql_stmt * pStmt)
{
int rc; /* Result from sqlStep() */
- int rc2 = SQL_OK; /* Result from sqlReprepare() */
Vdbe *v = (Vdbe *) pStmt; /* the prepared statement */
int cnt = 0; /* Counter to prevent infinite loop of reprepares */
- sql *db; /* The database connection */
if (vdbeSafetyNotNull(v)) {
return SQL_MISUSE;
}
- db = v->db;
v->doingRerun = 0;
while ((rc = sqlStep(v)) == SQL_SCHEMA
&& cnt++ < SQL_MAX_SCHEMA_RETRY) {
int savedPc = v->pc;
- rc2 = rc = sqlReprepare(v);
+ rc = sqlReprepare(v);
if (rc != SQL_OK)
break;
sql_reset(pStmt);
@@ -585,26 +573,6 @@ sql_step(sql_stmt * pStmt)
v->doingRerun = 1;
assert(v->expired == 0);
}
- if (rc2 != SQL_OK) {
- /* This case occurs after failing to recompile an sql statement.
- * The error message from the SQL compiler has already been loaded
- * into the database handle. This block copies the error message
- * from the database handle into the statement and sets the statement
- * program counter to 0 to ensure that when the statement is
- * finalized or reset the parser error message is available via
- * sql_errmsg() and sql_errcode().
- */
- const char *zErr = (const char *)sql_value_text(db->pErr);
- sqlDbFree(db, v->zErrMsg);
- if (!db->mallocFailed) {
- v->zErrMsg = sqlDbStrDup(db, zErr);
- v->rc = rc2;
- } else {
- v->zErrMsg = 0;
- v->rc = rc = SQL_NOMEM;
- }
- }
- rc = sqlApiExit(db, rc);
return rc;
}
diff --git a/src/box/sql/vdbeaux.c b/src/box/sql/vdbeaux.c
index 619b211..3f573d0 100644
--- a/src/box/sql/vdbeaux.c
+++ b/src/box/sql/vdbeaux.c
@@ -116,19 +116,6 @@ sql_vdbe_prepare(struct Vdbe *vdbe)
}
/*
- * Change the error string stored in Vdbe.zErrMsg
- */
-void
-sqlVdbeError(Vdbe * p, const char *zFormat, ...)
-{
- va_list ap;
- sqlDbFree(p->db, p->zErrMsg);
- va_start(ap, zFormat);
- p->zErrMsg = sqlVMPrintf(p->db, zFormat, ap);
- va_end(ap);
-}
-
-/*
* Remember the SQL string for a prepared statement.
*/
void
@@ -2115,10 +2102,11 @@ sqlVdbeCheckFk(Vdbe * p, int deferred)
if ((deferred && txn != NULL && txn->psql_txn != NULL &&
txn->psql_txn->fk_deferred_count > 0) ||
(!deferred && p->nFkConstraint > 0)) {
- p->rc = SQL_CONSTRAINT_FOREIGNKEY;
+ p->rc = SQL_TARANTOOL_ERROR;
p->errorAction = ON_CONFLICT_ACTION_ABORT;
- sqlVdbeError(p, "FOREIGN KEY constraint failed");
- return SQL_ERROR;
+ diag_set(ClientError, ER_SQL_EXECUTE, "FOREIGN KEY constraint "\
+ "failed");
+ return SQL_TARANTOOL_ERROR;
}
return SQL_OK;
}
diff --git a/src/box/sql/vdbemem.c b/src/box/sql/vdbemem.c
index 585dc21..d6375a6 100644
--- a/src/box/sql/vdbemem.c
+++ b/src/box/sql/vdbemem.c
@@ -210,7 +210,6 @@ sqlVdbeMemMakeWriteable(Mem * pMem)
* If the given Mem* has a zero-filled tail, turn it into an ordinary
* blob stored in dynamically allocated space.
*/
-#ifndef SQL_OMIT_INCRBLOB
int
sqlVdbeMemExpandBlob(Mem * pMem)
{
@@ -232,7 +231,6 @@ sqlVdbeMemExpandBlob(Mem * pMem)
pMem->flags &= ~(MEM_Zero | MEM_Term);
return SQL_OK;
}
-#endif
/*
* It is already known that pMem contains an unterminated string.
@@ -315,8 +313,7 @@ sqlVdbeMemStringify(Mem * pMem, u8 bForce)
* This routine calls the finalize method for that function. The
* result of the aggregate is stored back into pMem.
*
- * Return SQL_ERROR if the finalizer reports an error. SQL_OK
- * otherwise.
+ * Return -1 if the finalizer reports an error. 0 otherwise.
*/
int
sqlVdbeMemFinalize(Mem * pMem, FuncDef * pFunc)
@@ -337,9 +334,10 @@ sqlVdbeMemFinalize(Mem * pMem, FuncDef * pFunc)
if (pMem->szMalloc > 0)
sqlDbFree(pMem->db, pMem->zMalloc);
memcpy(pMem, &t, sizeof(t));
- return ctx.is_aborted ? SQL_TARANTOOL_ERROR : SQL_OK;
+ if (ctx.is_aborted)
+ return -1;
}
- return SQL_OK;
+ return 0;
}
/*
diff --git a/test/sql-tap/gh-2931-savepoints.test.lua b/test/sql-tap/gh-2931-savepoints.test.lua
index 6123fc4..be499b6 100755
--- a/test/sql-tap/gh-2931-savepoints.test.lua
+++ b/test/sql-tap/gh-2931-savepoints.test.lua
@@ -39,7 +39,7 @@ local testcases = {
{0,{1,1}}},
{"5",
[[rollback to savepoint s1_2;]],
- {1, "Failed to execute SQL statement: no such savepoint: S1_2"}},
+ {1, "Can not rollback to savepoint: the savepoint does not exist"}},
{"6",
[[insert into t1 values(2);
select * from t1 union all select * from t2;]],
diff --git a/test/sql/savepoints.result b/test/sql/savepoints.result
index bb4a296..d20e0ed 100644
--- a/test/sql/savepoints.result
+++ b/test/sql/savepoints.result
@@ -67,7 +67,7 @@ end;
...
release_sv_fail();
---
-- error: 'Failed to execute SQL statement: no such savepoint: T1'
+- error: 'Can not rollback to savepoint: the savepoint does not exist'
...
box.commit();
---
^ permalink raw reply [flat|nested] 31+ messages in thread
* [tarantool-patches] Re: [PATCH v1 07/12] sql: set errors in VDBE using diag_set()
2019-05-25 10:24 ` Mergen Imeev
@ 2019-05-25 10:36 ` Imeev Mergen
0 siblings, 0 replies; 31+ messages in thread
From: Imeev Mergen @ 2019-05-25 10:36 UTC (permalink / raw)
To: n.pettik; +Cc: tarantool-patches
[-- Attachment #1: Type: text/plain, Size: 47689 bytes --]
Fixed commit-message:
After this patch, all errors in VDBE will be set using diag_set().
Closes #4074 <https://github.com/tarantool/tarantool/issues/4074>
On 5/25/19 1:24 PM, Mergen Imeev wrote:
> I moved patch "sql: use diag_set() to set an error in SQL
> functions" to position before this patch. It allowed to
> simplify this patch. New patch below.
>
> On Wed, May 15, 2019 at 04:26:54PM +0300, n.pettik wrote:
>>
>>> On 5 May 2019, at 15:17, imeevma@tarantool.org wrote:
>>>
>>> After this patch, all errors in VDBE will be set using diag_set().
>>>
>>> Part of #4074
>>> ---
>>> src/box/execute.c | 23 +---
>>> src/box/sql/vdbe.c | 331 +++++++++++++++++++++-----------------------------
>>> src/box/sql/vdbeInt.h | 10 --
>>> src/box/sql/vdbeapi.c | 34 +-----
>>> src/box/sql/vdbeaux.c | 20 +--
>>> 5 files changed, 148 insertions(+), 270 deletions(-)
>> Please, remove whole sqlErrStr(), tarantoolErrorMessage() -
>> they are unused now. The same concerns sql_ret_code() -
>> I see no reason keeping it. Please, remove all legacy routines
>> connected with error codes.
>>
> These functions are removed in the following patches.
>
>>> diff --git a/src/box/execute.c b/src/box/execute.c
>>> index a3d4a92..e81cc32 100644
>>> --- a/src/box/execute.c
>>> +++ b/src/box/execute.c
>>>
>>> @@ -1335,7 +1331,8 @@ case OP_ResultRow: {
>>> * not return the number of rows modified. And do not RELEASE the statement
>>> * transaction. It needs to be rolled back.
>>> */
>>> - if (SQL_OK!=(rc = sqlVdbeCheckFk(p, 0))) {
>>> + rc = sqlVdbeCheckFk(p, 0);
>>> + if (rc != SQL_OK) {
>> -> if (sqlVdbeCheckFk() != 0)
>>
> Fixed. I used SQL_OK but it will be replaced by 0 in the
> following patches.
>
>>> assert(user_session->sql_flags&SQL_CountRows);
>>> goto abort_due_to_error;
>>> }
>>>
>>> @@ -1435,10 +1431,10 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
>>> if (str_type_p1 != str_type_p2) {
>>> diag_set(ClientError, ER_INCONSISTENT_TYPES,
>>> mem_type_to_str(pIn2), mem_type_to_str(pIn1));
>>> - rc = SQL_TARANTOOL_ERROR;
>>> goto abort_due_to_error;
>>> }
>>> - if (ExpandBlob(pIn1) || ExpandBlob(pIn2)) goto no_mem;
>>> + if (ExpandBlob(pIn1) != SQL_OK || ExpandBlob(pIn2) != SQL_OK)
>>> + goto abort_due_to_error;
>> != 0
>> Still need to call sqlOomFault(db); by jumping to no_mem label.
>>
> Fixed.
>
>>> nByte = pIn1->n + pIn2->n;
>>> if (nByte>db->aLimit[SQL_LIMIT_LENGTH]) {
>>> goto too_big;
>>>
>>>
>>> @@ -1723,11 +1715,15 @@ case OP_Function: {
>>> /* If the function returned an error, throw an exception */
>>> if (pCtx->fErrorOrAux) {
>>> if (pCtx->isError) {
>>> - sqlVdbeError(p, "%s", sql_value_text(pCtx->pOut));
>>> - rc = pCtx->isError;
>>> + if (pCtx->isError != SQL_TARANTOOL_ERROR) {
>> How it can be different from SQL_TARANTOOL_ERROR?
>>
> It was possible, but this part of code was completely
> changed after i moved patch "sql: use diag_set() to set an
> error in SQL functions" to position before this patch.
>
>>> + diag_set(ClientError, ER_SQL_EXECUTE,
>>> + sql_value_text(pCtx->pOut));
>>> + }
>>> + rc = SQL_TARANTOOL_ERROR;
>>> }
>>> sqlVdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1);
>>> - if (rc) goto abort_due_to_error;
>>> + if (rc != SQL_OK)
>>> + goto abort_due_to_error;
>> This diff seems to be redundant
>>
> Fixed.
>
>>> @@ -1910,8 +1903,7 @@ case OP_Realify: { /* in1 */
>>> */
>>> case OP_Cast: { /* in1 */
>>> pIn1 = &aMem[pOp->p1];
>>> - rc = ExpandBlob(pIn1);
>>> - if (rc != 0)
>>> + if (ExpandBlob(pIn1) != SQL_OK)
>> != 0
>> Please, don’t use SQL_OK value anywhere.
>>
> I think it's better to use SQL_OK here for integrity. It is
> replaced with 0 in one of the following patches.
>
>>> @@ -2802,10 +2784,8 @@ case OP_MakeRecord: {
>>> uint32_t tuple_size;
>>> char *tuple =
>>> sql_vdbe_mem_encode_tuple(pData0, nField, &tuple_size, region);
>>> - if (tuple == NULL) {
>>> - rc = SQL_TARANTOOL_ERROR;
>>> + if (tuple == NULL)
>>> goto abort_due_to_error;
>>> - }
>>> if ((int64_t)tuple_size > db->aLimit[SQL_LIMIT_LENGTH])
>>> goto too_big;
>>>
>>>
>>> @@ -2918,8 +2898,10 @@ case OP_Savepoint: {
>>> pSavepoint = pSavepoint->pNext
>>> );
>>> if (!pSavepoint) {
>>> - sqlVdbeError(p, "no such savepoint: %s", zName);
>>> - rc = SQL_ERROR;
>>> + const char *err =
>>> + tt_sprintf("no such savepoint: %s", zName);
>>> + diag_set(ClientError, ER_SQL_EXECUTE, err);
>> We already have ER_NO_SUCH_SAVEPOINT.
>>
> Fixed.
>
>>> @@ -3685,10 +3645,11 @@ case OP_Found: { /* jump, in3 */
>>> }
>>> }
>>> rc = sqlCursorMovetoUnpacked(pC->uc.pCursor, pIdxKey, &res);
>>> - if (pFree) sqlDbFree(db, pFree);
>>> - if (rc!=SQL_OK) {
>>> + if (pFree)
>> != NULL
>>
> Fixed.
>>> @@ -5164,11 +5126,16 @@ case OP_AggStep: {
>>> (pCtx->pFunc->xSFunc)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */
>>> if (pCtx->fErrorOrAux) {
>>> if (pCtx->isError) {
>>> - sqlVdbeError(p, "%s", sql_value_text(&t));
>>> - rc = pCtx->isError;
>>> + if (pCtx->isError != SQL_TARANTOOL_ERROR) {
>>> + diag_set(ClientError, ER_SQL_EXECUTE,
>>> + sql_value_text(&t));
>>> + }
>>> + rc = SQL_TARANTOOL_ERROR;
>>> }
>>> sqlVdbeMemRelease(&t);
>>> - if (rc) goto abort_due_to_error;
>>> + assert(rc == SQL_OK || rc == SQL_TARANTOOL_ERROR);
>>> + if (rc != SQL_OK)
>>> + goto abort_due_to_error;
>> Looks like redundant diff
>>
> Fixed.
>
>>> } else {
>>> assert(t.flags==MEM_Null);
>>> }
>>> @@ -5199,8 +5166,11 @@ case OP_AggFinal: {
>>> pMem = &aMem[pOp->p1];
>>> assert((pMem->flags & ~(MEM_Null|MEM_Agg))==0);
>>> rc = sqlVdbeMemFinalize(pMem, pOp->p4.pFunc);
>>> - if (rc) {
>>> - sqlVdbeError(p, "%s", sql_value_text(pMem));
>>> + if (rc != SQL_OK) {
>>> + if (rc != SQL_TARANTOOL_ERROR) {
>>> + diag_set(ClientError, ER_SQL_EXECUTE,
>>> + sql_value_text(pMem));
>> Could you please clarify what does this error mean?
>> It would just print value of memory to string…
>> The same relates to error in OP_AggStep.
>>
> If result was returned using sql_result_error() then it was
> possible that diag is not set. This was fixed in patch that
> now right before this patch.
>
>>> @@ -5311,10 +5281,8 @@ case OP_IncMaxid: {
>>> assert(pOp->p1 > 0);
>>> pOut = &aMem[pOp->p1];
>>>
>>> - rc = tarantoolsqlIncrementMaxid((uint64_t*) &pOut->u.i);
>>> - if (rc!=SQL_OK) {
>>> + if (tarantoolsqlIncrementMaxid((uint64_t*) &pOut->u.i) != SQL_OK)
>>> goto abort_due_to_error;
>>> - }
>>> pOut->flags = MEM_Int;
>>> break;
>>> }
>>>
>>> too_big:
>>> - sqlVdbeError(p, "string or blob too big");
>>> - rc = SQL_TOOBIG;
>>> + diag_set(ClientError, ER_SQL_EXECUTE, "string or blob too big”);
>> -> is too big
>>
> Fixed here. Still, it is possible to find this error in
> other places. I think it will be fixed when we create error
> code for such errors.
>
>>> goto abort_due_to_error;
>>>
>>> /* Jump to here if a malloc() fails.
>>> */
>>> no_mem:
>>> sqlOomFault(db);
>>> - sqlVdbeError(p, "out of memory");
>>> - rc = SQL_NOMEM;
>>> goto abort_due_to_error;
>>> }
>>> diff --git a/src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h
>>> index a3100e5..b655b5a 100644
>>> --- a/src/box/sql/vdbeInt.h
>>> +++ b/src/box/sql/vdbeInt.h
>>> @@ -248,10 +248,6 @@ struct Mem {
>>> #define MEM_Agg 0x4000 /* Mem.z points to an agg function context */
>>> #define MEM_Zero 0x8000 /* Mem.i contains count of 0s appended to blob */
>>> #define MEM_Subtype 0x10000 /* Mem.eSubtype is valid */
>>> -#ifdef SQL_OMIT_INCRBLOB
>>> -#undef MEM_Zero
>>> -#define MEM_Zero 0x0000
>>> -#endif
>>>
>>>
>>> @@ -550,13 +545,8 @@ void sqlVdbeMemPrettyPrint(Mem * pMem, char *zBuf);
>>> #endif
>>> int sqlVdbeMemHandleBom(Mem * pMem);
>>>
>>> -#ifndef SQL_OMIT_INCRBLOB
>> Still see usage of this macro in code: vdbemem.c : 213
>>
> Fixed.
>
>>> int sqlVdbeMemExpandBlob(Mem *);
>>> #define ExpandBlob(P) (((P)->flags&MEM_Zero)?sqlVdbeMemExpandBlob(P):0)
>>> -#else
>>> -#define sqlVdbeMemExpandBlob(x) SQL_OK
>>> -#define ExpandBlob(P) SQL_OK
>>> -#endif
>>>
>>> /**
>>> * Perform comparison of two keys: one is packed and one is not.
>>>
>>>
>>> diff --git a/src/box/sql/vdbeaux.c b/src/box/sql/vdbeaux.c
>>> index 27fa5b2..48c2a81 100644
>>> --- a/src/box/sql/vdbeaux.c
>>> +++ b/src/box/sql/vdbeaux.c
>>> void
>>> @@ -2124,10 +2111,11 @@ sqlVdbeCheckFk(Vdbe * p, int deferred)
>>> if ((deferred && txn != NULL && txn->psql_txn != NULL &&
>>> txn->psql_txn->fk_deferred_count > 0) ||
>>> (!deferred && p->nFkConstraint > 0)) {
>>> - p->rc = SQL_CONSTRAINT_FOREIGNKEY;
>>> + p->rc = SQL_TARANTOOL_ERROR;
>>> p->errorAction = ON_CONFLICT_ACTION_ABORT;
>>> - sqlVdbeError(p, "FOREIGN KEY constraint failed");
>>> - return SQL_ERROR;
>>> + diag_set(ClientError, ER_SQL_EXECUTE, "FOREIGN KEY constraint "\
>>> + "failed”);
>> Please, reserve separate error code for this violation.
>>
> I am going to do this a bit later, in a different patch.
>
>>> + return SQL_TARANTOOL_ERROR;
>>> }
>>> return SQL_OK;
>> Return 0/-1
>>
>>
> Left as it as for now, will be fixed in following patches.
>
>
> New patch:
>
> From 85cfbe96609b66379631c8d4534c8a9329fb3a47 Mon Sep 17 00:00:00 2001
> Date: Mon, 22 Apr 2019 19:41:46 +0300
> Subject: [PATCH] sql: set errors in VDBE using diag_set()
>
> After this patch, all errors in VDBE will be set using diag_set().
>
> Part of #4074
>
> diff --git a/src/box/execute.c b/src/box/execute.c
> index a3d4a92..e81cc32 100644
> --- a/src/box/execute.c
> +++ b/src/box/execute.c
> @@ -410,8 +410,7 @@ port_sql_dump_msgpack(struct port *port, struct obuf *out)
> * @retval -1 Error.
> */
> static inline int
> -sql_execute(sql *db, struct sql_stmt *stmt, struct port *port,
> - struct region *region)
> +sql_execute(struct sql_stmt *stmt, struct port *port, struct region *region)
> {
> int rc, column_count = sql_column_count(stmt);
> if (column_count > 0) {
> @@ -427,15 +426,8 @@ sql_execute(sql *db, struct sql_stmt *stmt, struct port *port,
> rc = sql_step(stmt);
> assert(rc != SQL_ROW && rc != SQL_OK);
> }
> - if (rc != SQL_DONE) {
> - if (db->errCode != SQL_TARANTOOL_ERROR) {
> - const char *err = (char *)sql_value_text(db->pErr);
> - if (err == NULL)
> - err = sqlErrStr(db->errCode);
> - diag_set(ClientError, ER_SQL_EXECUTE, err);
> - }
> + if (rc != SQL_DONE)
> return -1;
> - }
> return 0;
> }
>
> @@ -446,19 +438,12 @@ sql_prepare_and_execute(const char *sql, int len, const struct sql_bind *bind,
> {
> struct sql_stmt *stmt;
> struct sql *db = sql_get();
> - if (sql_prepare_v2(db, sql, len, &stmt, NULL) != SQL_OK) {
> - if (db->errCode != SQL_TARANTOOL_ERROR) {
> - const char *err = (char *)sql_value_text(db->pErr);
> - if (err == NULL)
> - err = sqlErrStr(db->errCode);
> - diag_set(ClientError, ER_SQL_EXECUTE, err);
> - }
> + if (sql_prepare_v2(db, sql, len, &stmt, NULL) != SQL_OK)
> return -1;
> - }
> assert(stmt != NULL);
> port_sql_create(port, stmt);
> if (sql_bind(stmt, bind, bind_count) == 0 &&
> - sql_execute(db, stmt, port, region) == 0)
> + sql_execute(stmt, port, region) == 0)
> return 0;
> port_destroy(port);
> return -1;
> diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
> index 7d85959..b64293a 100644
> --- a/src/box/sql/vdbe.c
> +++ b/src/box/sql/vdbe.c
> @@ -986,7 +986,7 @@ case OP_Halt: {
> p->rc = SQL_BUSY;
> } else {
> assert(rc==SQL_OK || (p->rc&0xff)==SQL_CONSTRAINT);
> - rc = p->rc ? SQL_ERROR : SQL_DONE;
> + rc = p->rc ? SQL_TARANTOOL_ERROR : SQL_DONE;
> }
> goto vdbe_return;
> }
> @@ -1098,17 +1098,13 @@ case OP_NextAutoincValue: {
> assert(pOp->p2 > 0);
>
> struct space *space = space_by_id(pOp->p1);
> - if (space == NULL) {
> - rc = SQL_TARANTOOL_ERROR;
> + if (space == NULL)
> goto abort_due_to_error;
> - }
>
> int64_t value;
> struct sequence *sequence = space->sequence;
> - if (sequence == NULL || sequence_next(sequence, &value) != 0) {
> - rc = SQL_TARANTOOL_ERROR;
> + if (sequence == NULL || sequence_next(sequence, &value) != 0)
> goto abort_due_to_error;
> - }
>
> pOut = out2Prerelease(p, pOp);
> pOut->flags = MEM_Int;
> @@ -1335,7 +1331,7 @@ case OP_ResultRow: {
> * not return the number of rows modified. And do not RELEASE the statement
> * transaction. It needs to be rolled back.
> */
> - if (SQL_OK!=(rc = sqlVdbeCheckFk(p, 0))) {
> + if (sqlVdbeCheckFk(p, 0) != SQL_OK) {
> assert(user_session->sql_flags&SQL_CountRows);
> goto abort_due_to_error;
> }
> @@ -1427,7 +1423,6 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
> mem_type_to_str(pIn2);
> diag_set(ClientError, ER_INCONSISTENT_TYPES, "TEXT or BLOB",
> inconsistent_type);
> - rc = SQL_TARANTOOL_ERROR;
> goto abort_due_to_error;
> }
>
> @@ -1435,10 +1430,10 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
> if (str_type_p1 != str_type_p2) {
> diag_set(ClientError, ER_INCONSISTENT_TYPES,
> mem_type_to_str(pIn2), mem_type_to_str(pIn1));
> - rc = SQL_TARANTOOL_ERROR;
> goto abort_due_to_error;
> }
> - if (ExpandBlob(pIn1) || ExpandBlob(pIn2)) goto no_mem;
> + if (ExpandBlob(pIn1) != SQL_OK || ExpandBlob(pIn2) != SQL_OK)
> + goto abort_due_to_error;
> nByte = pIn1->n + pIn2->n;
> if (nByte>db->aLimit[SQL_LIMIT_LENGTH]) {
> goto too_big;
> @@ -1551,13 +1546,11 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
> if (sqlVdbeRealValue(pIn1, &rA) != 0) {
> diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
> sql_value_text(pIn1), "numeric");
> - rc = SQL_TARANTOOL_ERROR;
> goto abort_due_to_error;
> }
> if (sqlVdbeRealValue(pIn2, &rB) != 0) {
> diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
> sql_value_text(pIn2), "numeric");
> - rc = SQL_TARANTOOL_ERROR;
> goto abort_due_to_error;
> }
> switch( pOp->opcode) {
> @@ -1597,11 +1590,9 @@ arithmetic_result_is_null:
>
> division_by_zero:
> diag_set(ClientError, ER_SQL_EXECUTE, "division by zero");
> - rc = SQL_TARANTOOL_ERROR;
> goto abort_due_to_error;
> integer_overflow:
> diag_set(ClientError, ER_SQL_EXECUTE, "integer is overflowed");
> - rc = SQL_TARANTOOL_ERROR;
> goto abort_due_to_error;
> }
>
> @@ -1721,10 +1712,8 @@ case OP_Function: {
> (*pCtx->pFunc->xSFunc)(pCtx, pCtx->argc, pCtx->argv);/* IMP: R-24505-23230 */
>
> /* If the function returned an error, throw an exception */
> - if (pCtx->is_aborted) {
> - rc = SQL_TARANTOOL_ERROR;
> + if (pCtx->is_aborted)
> goto abort_due_to_error;
> - }
>
> /* Copy the result of the function into register P3 */
> if (pOut->flags & (MEM_Str|MEM_Blob)) {
> @@ -1785,13 +1774,11 @@ case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */
> if (sqlVdbeIntValue(pIn2, (int64_t *) &iA) != 0) {
> diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
> sql_value_text(pIn2), "integer");
> - rc = SQL_TARANTOOL_ERROR;
> goto abort_due_to_error;
> }
> if (sqlVdbeIntValue(pIn1, (int64_t *) &iB) != 0) {
> diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
> sql_value_text(pIn1), "integer");
> - rc = SQL_TARANTOOL_ERROR;
> goto abort_due_to_error;
> }
> op = pOp->opcode;
> @@ -1860,7 +1847,6 @@ case OP_MustBeInt: { /* jump, in1 */
> if (pOp->p2==0) {
> diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
> sql_value_text(pIn1), "integer");
> - rc = SQL_TARANTOOL_ERROR;
> goto abort_due_to_error;
> } else {
> goto jump_to_p2;
> @@ -1906,8 +1892,7 @@ case OP_Realify: { /* in1 */
> */
> case OP_Cast: { /* in1 */
> pIn1 = &aMem[pOp->p1];
> - rc = ExpandBlob(pIn1);
> - if (rc != 0)
> + if (ExpandBlob(pIn1) != SQL_OK)
> goto abort_due_to_error;
> rc = sqlVdbeMemCast(pIn1, pOp->p2);
> UPDATE_MAX_BLOBSIZE(pIn1);
> @@ -1915,7 +1900,6 @@ case OP_Cast: { /* in1 */
> break;
> diag_set(ClientError, ER_SQL_TYPE_MISMATCH, sql_value_text(pIn1),
> field_type_strs[pOp->p2]);
> - rc = SQL_TARANTOOL_ERROR;
> goto abort_due_to_error;
> }
> #endif /* SQL_OMIT_CAST */
> @@ -2068,7 +2052,6 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
> mem_type_to_str(pIn3);
> diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
> inconsistent_type, "boolean");
> - rc = SQL_TARANTOOL_ERROR;
> goto abort_due_to_error;
> }
> res = sqlMemCompare(pIn3, pIn1, NULL);
> @@ -2087,7 +2070,6 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
> ER_SQL_TYPE_MISMATCH,
> sql_value_text(pIn3),
> "numeric");
> - rc = SQL_TARANTOOL_ERROR;
> goto abort_due_to_error;
> }
>
> @@ -2329,7 +2311,6 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */
> } else {
> diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
> sql_value_text(pIn1), "boolean");
> - rc = SQL_TARANTOOL_ERROR;
> goto abort_due_to_error;
> }
> pIn2 = &aMem[pOp->p2];
> @@ -2340,7 +2321,6 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */
> } else {
> diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
> sql_value_text(pIn2), "boolean");
> - rc = SQL_TARANTOOL_ERROR;
> goto abort_due_to_error;
> }
> if (pOp->opcode==OP_And) {
> @@ -2374,7 +2354,6 @@ case OP_Not: { /* same as TK_NOT, in1, out2 */
> if ((pIn1->flags & MEM_Bool) == 0) {
> diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
> sql_value_text(pIn1), "boolean");
> - rc = SQL_TARANTOOL_ERROR;
> goto abort_due_to_error;
> }
> mem_set_bool(pOut, ! pIn1->u.b);
> @@ -2398,7 +2377,6 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */
> if (sqlVdbeIntValue(pIn1, &i) != 0) {
> diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
> sql_value_text(pIn1), "integer");
> - rc = SQL_TARANTOOL_ERROR;
> goto abort_due_to_error;
> }
> pOut->flags = MEM_Int;
> @@ -2446,7 +2424,6 @@ case OP_IfNot: { /* jump, in1 */
> } else {
> diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
> sql_value_text(pIn1), "boolean");
> - rc = SQL_TARANTOOL_ERROR;
> goto abort_due_to_error;
> }
> VdbeBranchTaken(c!=0, 2);
> @@ -2586,8 +2563,9 @@ case OP_Column: {
> zEnd = zData + pC->payloadSize;
> } else {
> memset(&sMem, 0, sizeof(sMem));
> - rc = sqlVdbeMemFromBtree(pC->uc.pCursor, 0, pC->payloadSize, &sMem);
> - if (rc!=SQL_OK) goto abort_due_to_error;
> + if (sqlVdbeMemFromBtree(pC->uc.pCursor, 0, pC->payloadSize,
> + &sMem) != SQL_OK)
> + goto abort_due_to_error;
> zData = (u8*)sMem.z;
> zEnd = zData + pC->payloadSize;
> }
> @@ -2646,10 +2624,8 @@ case OP_Column: {
> }
> uint32_t unused;
> if (vdbe_decode_msgpack_into_mem((const char *)(zData + aOffset[p2]),
> - pDest, &unused) != 0) {
> - rc = SQL_TARANTOOL_ERROR;
> + pDest, &unused) != 0)
> goto abort_due_to_error;
> - }
> /* MsgPack map, array or extension (unsupported in sql).
> * Wrap it in a blob verbatim.
> */
> @@ -2683,7 +2659,11 @@ case OP_Column: {
> if ((pDest->flags & (MEM_Ephem | MEM_Str)) == (MEM_Ephem | MEM_Str)) {
> int len = pDest->n;
> if (pDest->szMalloc<len+1) {
> - if (sqlVdbeMemGrow(pDest, len+1, 1)) goto op_column_error;
> + if (sqlVdbeMemGrow(pDest, len + 1, 1)) {
> + if (zData != pC->aRow)
> + sqlVdbeMemRelease(&sMem);
> + goto abort_due_to_error;
> + }
> } else {
> pDest->z = memcpy(pDest->zMalloc, pDest->z, len);
> pDest->flags &= ~MEM_Ephem;
> @@ -2697,10 +2677,6 @@ case OP_Column: {
> UPDATE_MAX_BLOBSIZE(pDest);
> REGISTER_TRACE(pOp->p3, pDest);
> break;
> -
> - op_column_error:
> - if (zData!=pC->aRow) sqlVdbeMemRelease(&sMem);
> - goto abort_due_to_error;
> }
>
> /* Opcode: ApplyType P1 P2 * P4 *
> @@ -2725,7 +2701,6 @@ case OP_ApplyType: {
> diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
> sql_value_text(pIn1),
> field_type_strs[type]);
> - rc = SQL_TARANTOOL_ERROR;
> goto abort_due_to_error;
> }
> pIn1++;
> @@ -2798,10 +2773,8 @@ case OP_MakeRecord: {
> uint32_t tuple_size;
> char *tuple =
> sql_vdbe_mem_encode_tuple(pData0, nField, &tuple_size, region);
> - if (tuple == NULL) {
> - rc = SQL_TARANTOOL_ERROR;
> + if (tuple == NULL)
> goto abort_due_to_error;
> - }
> if ((int64_t)tuple_size > db->aLimit[SQL_LIMIT_LENGTH])
> goto too_big;
>
> @@ -2856,13 +2829,14 @@ case OP_Count: { /* out2 */
> assert(pCrsr);
> nEntry = 0; /* Not needed. Only used to silence a warning. */
> if (pCrsr->curFlags & BTCF_TaCursor) {
> - rc = tarantoolsqlCount(pCrsr, &nEntry);
> + if (tarantoolsqlCount(pCrsr, &nEntry) != SQL_OK)
> + goto abort_due_to_error;
> } else if (pCrsr->curFlags & BTCF_TEphemCursor) {
> - rc = tarantoolsqlEphemeralCount(pCrsr, &nEntry);
> + if (tarantoolsqlEphemeralCount(pCrsr, &nEntry) != SQL_OK)
> + goto abort_due_to_error;
> } else {
> unreachable();
> }
> - if (rc) goto abort_due_to_error;
> pOut = out2Prerelease(p, pOp);
> pOut->u.i = nEntry;
> break;
> @@ -2886,7 +2860,6 @@ case OP_Savepoint: {
> if (psql_txn == NULL) {
> assert(!box_txn());
> diag_set(ClientError, ER_NO_TRANSACTION);
> - rc = SQL_TARANTOOL_ERROR;
> goto abort_due_to_error;
> }
> p1 = pOp->p1;
> @@ -2914,8 +2887,8 @@ case OP_Savepoint: {
> pSavepoint = pSavepoint->pNext
> );
> if (!pSavepoint) {
> - sqlVdbeError(p, "no such savepoint: %s", zName);
> - rc = SQL_ERROR;
> + diag_set(ClientError, ER_NO_SUCH_SAVEPOINT);
> + goto abort_due_to_error;
> } else {
>
> /* Determine whether or not this is a transaction savepoint. If so,
> @@ -2932,7 +2905,8 @@ case OP_Savepoint: {
> p->rc = rc = SQL_BUSY;
> goto vdbe_return;
> }
> - rc = p->rc;
> + if (p->rc != SQL_OK)
> + goto abort_due_to_error;
> } else {
> if (p1==SAVEPOINT_ROLLBACK)
> box_txn_rollback_to_savepoint(pSavepoint->tnt_savepoint);
> @@ -2964,7 +2938,6 @@ case OP_Savepoint: {
> }
> }
> }
> - if (rc) goto abort_due_to_error;
>
> break;
> }
> @@ -2987,7 +2960,6 @@ case OP_CheckViewReferences: {
> if (space->def->view_ref_count > 0) {
> diag_set(ClientError, ER_DROP_SPACE, space->def->name,
> "other views depend on this space");
> - rc = SQL_TARANTOOL_ERROR;
> goto abort_due_to_error;
> }
> break;
> @@ -3000,10 +2972,8 @@ case OP_CheckViewReferences: {
> * Otherwise, raise an error with appropriate error message.
> */
> case OP_TransactionBegin: {
> - if (sql_txn_begin(p) != 0) {
> - rc = SQL_TARANTOOL_ERROR;
> + if (sql_txn_begin(p) != 0)
> goto abort_due_to_error;
> - }
> p->auto_commit = false ;
> break;
> }
> @@ -3019,13 +2989,11 @@ case OP_TransactionBegin: {
> case OP_TransactionCommit: {
> struct txn *txn = in_txn();
> if (txn != NULL) {
> - if (txn_commit(txn) != 0) {
> - rc = SQL_TARANTOOL_ERROR;
> + if (txn_commit(txn) != 0)
> goto abort_due_to_error;
> - }
> } else {
> - sqlVdbeError(p, "cannot commit - no transaction is active");
> - rc = SQL_ERROR;
> + diag_set(ClientError, ER_SQL_EXECUTE, "cannot commit - no "\
> + "transaction is active");
> goto abort_due_to_error;
> }
> break;
> @@ -3038,14 +3006,11 @@ case OP_TransactionCommit: {
> */
> case OP_TransactionRollback: {
> if (box_txn()) {
> - if (box_txn_rollback() != 0) {
> - rc = SQL_TARANTOOL_ERROR;
> + if (box_txn_rollback() != 0)
> goto abort_due_to_error;
> - }
> } else {
> - sqlVdbeError(p, "cannot rollback - no "
> - "transaction is active");
> - rc = SQL_ERROR;
> + diag_set(ClientError, ER_SQL_EXECUTE, "cannot rollback - no "\
> + "transaction is active");
> goto abort_due_to_error;
> }
> break;
> @@ -3063,16 +3028,12 @@ case OP_TransactionRollback: {
> */
> case OP_TTransaction: {
> if (!box_txn()) {
> - if (sql_txn_begin(p) != 0) {
> - rc = SQL_TARANTOOL_ERROR;
> + if (sql_txn_begin(p) != 0)
> goto abort_due_to_error;
> - }
> } else {
> p->anonymous_savepoint = sql_savepoint(p, NULL);
> - if (p->anonymous_savepoint == NULL) {
> - rc = SQL_TARANTOOL_ERROR;
> + if (p->anonymous_savepoint == NULL)
> goto abort_due_to_error;
> - }
> }
> break;
> }
> @@ -3111,9 +3072,8 @@ case OP_IteratorOpen:
> if (box_schema_version() != p->schema_ver &&
> (pOp->p5 & OPFLAG_SYSTEMSP) == 0) {
> p->expired = 1;
> - rc = SQL_ERROR;
> - sqlVdbeError(p, "schema version has changed: " \
> - "need to re-compile SQL statement");
> + diag_set(ClientError, ER_SQL_EXECUTE, "schema version has "\
> + "changed: need to re-compile SQL statement");
> goto abort_due_to_error;
> }
> struct space *space;
> @@ -3122,10 +3082,8 @@ case OP_IteratorOpen:
> else
> space = aMem[pOp->p3].u.p;
> assert(space != NULL);
> - if (access_check_space(space, PRIV_R) != 0) {
> - rc = SQL_TARANTOOL_ERROR;
> + if (access_check_space(space, PRIV_R) != 0)
> goto abort_due_to_error;
> - }
>
> struct index *index = space_index(space, pOp->p2);
> assert(index != NULL);
> @@ -3148,8 +3106,6 @@ case OP_IteratorOpen:
> cur->nullRow = 1;
> open_cursor_set_hints:
> cur->uc.pCursor->hints = pOp->p5 & OPFLAG_SEEKEQ;
> - if (rc != 0)
> - goto abort_due_to_error;
> break;
> }
>
> @@ -3171,10 +3127,8 @@ case OP_OpenTEphemeral: {
> struct space *space = sql_ephemeral_space_create(pOp->p2,
> pOp->p4.key_info);
>
> - if (space == NULL) {
> - rc = SQL_TARANTOOL_ERROR;
> + if (space == NULL)
> goto abort_due_to_error;
> - }
> aMem[pOp->p1].u.p = space;
> aMem[pOp->p1].flags = MEM_Ptr;
> break;
> @@ -3200,8 +3154,8 @@ case OP_SorterOpen: {
> pCx = allocateCursor(p, pOp->p1, pOp->p2, CURTYPE_SORTER);
> if (pCx==0) goto no_mem;
> pCx->key_def = def;
> - rc = sqlVdbeSorterInit(db, pCx);
> - if (rc) goto abort_due_to_error;
> + if (sqlVdbeSorterInit(db, pCx) != SQL_OK)
> + goto abort_due_to_error;
> break;
> }
>
> @@ -3433,7 +3387,6 @@ case OP_SeekGT: { /* jump, in3 */
> } else {
> diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
> sql_value_text(pIn3), "integer");
> - rc = SQL_TARANTOOL_ERROR;
> goto abort_due_to_error;
> }
> iKey = i;
> @@ -3514,10 +3467,8 @@ case OP_SeekGT: { /* jump, in3 */
> #endif
> r.eqSeen = 0;
> r.opcode = oc;
> - rc = sqlCursorMovetoUnpacked(pC->uc.pCursor, &r, &res);
> - if (rc!=SQL_OK) {
> + if (sqlCursorMovetoUnpacked(pC->uc.pCursor, &r, &res) != SQL_OK)
> goto abort_due_to_error;
> - }
> if (eqOnly && r.eqSeen==0) {
> assert(res!=0);
> goto seek_not_found;
> @@ -3529,8 +3480,8 @@ case OP_SeekGT: { /* jump, in3 */
> if (oc>=OP_SeekGE) { assert(oc==OP_SeekGE || oc==OP_SeekGT);
> if (res<0 || (res==0 && oc==OP_SeekGT)) {
> res = 0;
> - rc = sqlCursorNext(pC->uc.pCursor, &res);
> - if (rc!=SQL_OK) goto abort_due_to_error;
> + if (sqlCursorNext(pC->uc.pCursor, &res) != SQL_OK)
> + goto abort_due_to_error;
> } else {
> res = 0;
> }
> @@ -3538,8 +3489,8 @@ case OP_SeekGT: { /* jump, in3 */
> assert(oc==OP_SeekLT || oc==OP_SeekLE);
> if (res>0 || (res==0 && oc==OP_SeekLT)) {
> res = 0;
> - rc = sqlCursorPrevious(pC->uc.pCursor, &res);
> - if (rc!=SQL_OK) goto abort_due_to_error;
> + if (sqlCursorPrevious(pC->uc.pCursor, &res) != SQL_OK)
> + goto abort_due_to_error;
> } else {
> /* res might be negative because the table is empty. Check to
> * see if this is the case.
> @@ -3681,10 +3632,11 @@ case OP_Found: { /* jump, in3 */
> }
> }
> rc = sqlCursorMovetoUnpacked(pC->uc.pCursor, pIdxKey, &res);
> - if (pFree) sqlDbFree(db, pFree);
> - if (rc!=SQL_OK) {
> + if (pFree != NULL)
> + sqlDbFree(db, pFree);
> + assert(rc == SQL_OK || rc == SQL_TARANTOOL_ERROR);
> + if (rc != SQL_OK)
> goto abort_due_to_error;
> - }
> pC->seekResult = res;
> alreadyExists = (res==0);
> pC->nullRow = 1-alreadyExists;
> @@ -3744,10 +3696,8 @@ case OP_NextIdEphemeral: {
> struct space *space = (struct space*)p->aMem[pOp->p1].u.p;
> assert(space->def->id == 0);
> uint64_t rowid;
> - if (space->vtab->ephemeral_rowid_next(space, &rowid) != 0) {
> - rc = SQL_TARANTOOL_ERROR;
> + if (space->vtab->ephemeral_rowid_next(space, &rowid) != 0)
> goto abort_due_to_error;
> - }
> /*
> * FIXME: since memory cell can comprise only 32-bit
> * integer, make sure it can fit in. This check should
> @@ -3756,7 +3706,6 @@ case OP_NextIdEphemeral: {
> */
> if (rowid > INT32_MAX) {
> diag_set(ClientError, ER_ROWID_OVERFLOW);
> - rc = SQL_TARANTOOL_ERROR;
> goto abort_due_to_error;
> }
> pOut = &aMem[pOp->p2];
> @@ -3903,7 +3852,8 @@ case OP_SorterCompare: {
> pIn3 = &aMem[pOp->p3];
> nKeyCol = pOp->p4.i;
> res = 0;
> - rc = sqlVdbeSorterCompare(pC, pIn3, nKeyCol, &res);
> + if (sqlVdbeSorterCompare(pC, pIn3, nKeyCol, &res) != 0)
> + rc = SQL_TARANTOOL_ERROR;
> VdbeBranchTaken(res!=0,2);
> if (rc) goto abort_due_to_error;
> if (res) goto jump_to_p2;
> @@ -3928,10 +3878,10 @@ case OP_SorterData: {
> pOut = &aMem[pOp->p2];
> pC = p->apCsr[pOp->p1];
> assert(isSorter(pC));
> - rc = sqlVdbeSorterRowkey(pC, pOut);
> - assert(rc!=SQL_OK || (pOut->flags & MEM_Blob));
> + if (sqlVdbeSorterRowkey(pC, pOut) != SQL_OK)
> + goto abort_due_to_error;
> + assert(pOut->flags & MEM_Blob);
> assert(pOp->p1>=0 && pOp->p1<p->nCursor);
> - if (rc) goto abort_due_to_error;
> p->apCsr[pOp->p3]->cacheStatus = CACHE_STALE;
> break;
> }
> @@ -3998,11 +3948,9 @@ case OP_RowData: {
> testcase( n==0);
>
> sqlVdbeMemRelease(pOut);
> - rc = sql_vdbe_mem_alloc_region(pOut, n);
> - if (rc)
> - goto no_mem;
> - rc = sqlCursorPayload(pCrsr, 0, n, pOut->z);
> - if (rc) goto abort_due_to_error;
> + if (sql_vdbe_mem_alloc_region(pOut, n) != SQL_OK ||
> + sqlCursorPayload(pCrsr, 0, n, pOut->z) != SQL_OK)
> + goto abort_due_to_error;
> UPDATE_MAX_BLOBSIZE(pOut);
> REGISTER_TRACE(pOp->p2, pOut);
> break;
> @@ -4137,15 +4085,18 @@ case OP_Rewind: { /* jump */
> pC->seekOp = OP_Rewind;
> #endif
> if (isSorter(pC)) {
> - rc = sqlVdbeSorterRewind(pC, &res);
> + if (sqlVdbeSorterRewind(pC, &res) != SQL_OK)
> + goto abort_due_to_error;
> } else {
> assert(pC->eCurType==CURTYPE_TARANTOOL);
> pCrsr = pC->uc.pCursor;
> assert(pCrsr);
> - rc = tarantoolsqlFirst(pCrsr, &res);
> + if (tarantoolsqlFirst(pCrsr, &res) != SQL_OK)
> + rc = SQL_TARANTOOL_ERROR;
> pC->cacheStatus = CACHE_STALE;
> + if (rc != SQL_OK)
> + goto abort_due_to_error;
> }
> - if (rc) goto abort_due_to_error;
> pC->nullRow = (u8)res;
> assert(pOp->p2>0 && pOp->p2<p->nOp);
> VdbeBranchTaken(res!=0,2);
> @@ -4291,11 +4242,8 @@ case OP_SorterInsert: { /* in2 */
> assert(isSorter(cursor));
> pIn2 = &aMem[pOp->p2];
> assert((pIn2->flags & MEM_Blob) != 0);
> - rc = ExpandBlob(pIn2);
> - if (rc != 0)
> - goto abort_due_to_error;
> - rc = sqlVdbeSorterWrite(cursor, pIn2);
> - if (rc != 0)
> + if (ExpandBlob(pIn2) != SQL_OK ||
> + sqlVdbeSorterWrite(cursor, pIn2) != SQL_OK)
> goto abort_due_to_error;
> break;
> }
> @@ -4325,8 +4273,7 @@ case OP_IdxInsert: {
> assert((pIn2->flags & MEM_Blob) != 0);
> if (pOp->p5 & OPFLAG_NCHANGE)
> p->nChange++;
> - rc = ExpandBlob(pIn2);
> - if (rc != 0)
> + if (ExpandBlob(pIn2) != SQL_OK)
> goto abort_due_to_error;
> struct space *space;
> if (pOp->p4type == P4_SPACEPTR)
> @@ -4360,6 +4307,7 @@ case OP_IdxInsert: {
> } else if (pOp->p5 & OPFLAG_OE_ROLLBACK) {
> p->errorAction = ON_CONFLICT_ACTION_ROLLBACK;
> }
> + assert(rc == SQL_OK || rc == SQL_TARANTOOL_ERROR);
> if (rc != 0)
> goto abort_due_to_error;
> break;
> @@ -4427,14 +4375,12 @@ case OP_Update: {
> if (is_error) {
> diag_set(OutOfMemory, stream.pos - stream.buf,
> "mpstream_flush", "stream");
> - rc = SQL_TARANTOOL_ERROR;
> goto abort_due_to_error;
> }
> uint32_t ops_size = region_used(region) - used;
> const char *ops = region_join(region, ops_size);
> if (ops == NULL) {
> diag_set(OutOfMemory, ops_size, "region_join", "raw");
> - rc = SQL_TARANTOOL_ERROR;
> goto abort_due_to_error;
> }
>
> @@ -4460,6 +4406,7 @@ case OP_Update: {
> } else if (pOp->p5 & OPFLAG_OE_ROLLBACK) {
> p->errorAction = ON_CONFLICT_ACTION_ROLLBACK;
> }
> + assert(rc == SQL_OK || rc == SQL_TARANTOOL_ERROR);
> if (rc != 0)
> goto abort_due_to_error;
> break;
> @@ -4510,8 +4457,7 @@ case OP_SDelete: {
> struct space *space = space_by_id(pOp->p1);
> assert(space != NULL);
> assert(space_is_system(space));
> - rc = sql_delete_by_key(space, 0, pIn2->z, pIn2->n);
> - if (rc)
> + if (sql_delete_by_key(space, 0, pIn2->z, pIn2->n) != SQL_OK)
> goto abort_due_to_error;
> if (pOp->p5 & OPFLAG_NCHANGE)
> p->nChange++;
> @@ -4545,18 +4491,19 @@ case OP_IdxDelete: {
> r.default_rc = 0;
> r.aMem = &aMem[pOp->p2];
> r.opcode = OP_IdxDelete;
> - rc = sqlCursorMovetoUnpacked(pCrsr, &r, &res);
> - if (rc) goto abort_due_to_error;
> + if (sqlCursorMovetoUnpacked(pCrsr, &r, &res) != SQL_OK)
> + goto abort_due_to_error;
> if (res==0) {
> assert(pCrsr->eState == CURSOR_VALID);
> if (pCrsr->curFlags & BTCF_TaCursor) {
> - rc = tarantoolsqlDelete(pCrsr, 0);
> + if (tarantoolsqlDelete(pCrsr, 0) != SQL_OK)
> + goto abort_due_to_error;
> } else if (pCrsr->curFlags & BTCF_TEphemCursor) {
> - rc = tarantoolsqlEphemeralDelete(pCrsr);
> + if (tarantoolsqlEphemeralDelete(pCrsr) != SQL_OK)
> + goto abort_due_to_error;
> } else {
> unreachable();
> }
> - if (rc) goto abort_due_to_error;
> }
> pC->cacheStatus = CACHE_STALE;
> pC->seekResult = 0;
> @@ -4668,14 +4615,14 @@ case OP_Clear: {
> rc = 0;
> if (pOp->p2 > 0) {
> if (box_truncate(space_id) != 0)
> - rc = SQL_TARANTOOL_ERROR;
> + goto abort_due_to_error;
> } else {
> uint32_t tuple_count;
> - rc = tarantoolsqlClearTable(space, &tuple_count);
> - if (rc == 0 && (pOp->p5 & OPFLAG_NCHANGE) != 0)
> + if (tarantoolsqlClearTable(space, &tuple_count) != SQL_OK)
> + goto abort_due_to_error;
> + if ((pOp->p5 & OPFLAG_NCHANGE) != 0)
> p->nChange += tuple_count;
> }
> - if (rc) goto abort_due_to_error;
> break;
> }
>
> @@ -4698,8 +4645,8 @@ case OP_ResetSorter: {
> } else {
> assert(pC->eCurType==CURTYPE_TARANTOOL);
> assert(pC->uc.pCursor->curFlags & BTCF_TEphemCursor);
> - rc = tarantoolsqlEphemeralClearTable(pC->uc.pCursor);
> - if (rc) goto abort_due_to_error;
> + if (tarantoolsqlEphemeralClearTable(pC->uc.pCursor) != SQL_OK)
> + goto abort_due_to_error;
> }
> break;
> }
> @@ -4732,8 +4679,8 @@ case OP_RenameTable: {
> zNewTableName = pOp->p4.z;
> zOldTableName = sqlDbStrNDup(db, zOldTableName,
> sqlStrlen30(zOldTableName));
> - rc = sql_rename_table(space_id, zNewTableName);
> - if (rc) goto abort_due_to_error;
> + if (sql_rename_table(space_id, zNewTableName) != SQL_OK)
> + goto abort_due_to_error;
> /*
> * Rebuild 'CREATE TRIGGER' expressions of all triggers
> * created on this table. Sure, this action is not atomic
> @@ -4743,20 +4690,18 @@ case OP_RenameTable: {
> for (struct sql_trigger *trigger = triggers; trigger != NULL; ) {
> /* Store pointer as trigger will be destructed. */
> struct sql_trigger *next_trigger = trigger->next;
> - rc = tarantoolsqlRenameTrigger(trigger->zName,
> - zOldTableName, zNewTableName);
> - if (rc != SQL_OK) {
> - /*
> - * FIXME: In the case of error,
> - * part of triggers would have invalid
> - * space name in tuple so can not been
> - * persisted.
> - * Server could be restarted.
> - * In this case, rename table back and
> - * try again.
> - */
> + /*
> + * FIXME: In the case of error,
> + * part of triggers would have invalid
> + * space name in tuple so can not been
> + * persisted.
> + * Server could be restarted.
> + * In this case, rename table back and
> + * try again.
> + */
> + if (tarantoolsqlRenameTrigger(trigger->zName, zOldTableName,
> + zNewTableName) != SQL_OK)
> goto abort_due_to_error;
> - }
> trigger = next_trigger;
> }
> sqlDbFree(db, (void*)zOldTableName);
> @@ -4771,8 +4716,8 @@ case OP_RenameTable: {
> */
> case OP_LoadAnalysis: {
> assert(pOp->p1==0 );
> - rc = sql_analysis_load(db);
> - if (rc) goto abort_due_to_error;
> + if (sql_analysis_load(db) != SQL_OK)
> + goto abort_due_to_error;
> break;
> }
>
> @@ -4828,8 +4773,8 @@ case OP_Program: { /* jump */
> }
>
> if (p->nFrame>=db->aLimit[SQL_LIMIT_TRIGGER_DEPTH]) {
> - rc = SQL_ERROR;
> - sqlVdbeError(p, "too many levels of trigger recursion");
> + diag_set(ClientError, ER_SQL_EXECUTE, "too many levels of "\
> + "trigger recursion");
> goto abort_due_to_error;
> }
>
> @@ -5157,11 +5102,9 @@ case OP_AggStep: {
> (pCtx->pFunc->xSFunc)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */
> if (pCtx->is_aborted) {
> sqlVdbeMemRelease(&t);
> - rc = SQL_TARANTOOL_ERROR;
> goto abort_due_to_error;
> - } else {
> - assert(t.flags==MEM_Null);
> }
> + assert(t.flags==MEM_Null);
> if (pCtx->skipFlag) {
> assert(pOp[-1].opcode==OP_CollSeq);
> i = pOp[-1].p1;
> @@ -5188,11 +5131,8 @@ case OP_AggFinal: {
> assert(pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor));
> pMem = &aMem[pOp->p1];
> assert((pMem->flags & ~(MEM_Null|MEM_Agg))==0);
> - rc = sqlVdbeMemFinalize(pMem, pOp->p4.pFunc);
> - if (rc) {
> - sqlVdbeError(p, "%s", sql_value_text(pMem));
> + if (sqlVdbeMemFinalize(pMem, pOp->p4.pFunc) != 0)
> goto abort_due_to_error;
> - }
> UPDATE_MAX_BLOBSIZE(pMem);
> if (sqlVdbeMemTooBig(pMem)) {
> goto too_big;
> @@ -5301,10 +5241,8 @@ case OP_IncMaxid: {
> assert(pOp->p1 > 0);
> pOut = &aMem[pOp->p1];
>
> - rc = tarantoolsqlIncrementMaxid((uint64_t*) &pOut->u.i);
> - if (rc!=SQL_OK) {
> + if (tarantoolsqlIncrementMaxid((uint64_t*) &pOut->u.i) != SQL_OK)
> goto abort_due_to_error;
> - }
> pOut->flags = MEM_Int;
> break;
> }
> @@ -5368,28 +5306,8 @@ default: { /* This is really OP_Noop and OP_Explain */
> * an error of some kind.
> */
> abort_due_to_error:
> - if (db->mallocFailed) rc = SQL_NOMEM;
> - assert(rc);
> - if (p->zErrMsg==0 && rc!=SQL_IOERR_NOMEM) {
> - const char *msg;
> - /* Avoiding situation when Tarantool error is set,
> - * but error message isn't.
> - */
> - if (rc == SQL_TARANTOOL_ERROR && tarantoolErrorMessage()) {
> - msg = tarantoolErrorMessage();
> - } else {
> - msg = sqlErrStr(rc);
> - }
> - sqlVdbeError(p, "%s", msg);
> - }
> + rc = SQL_TARANTOOL_ERROR;
> p->rc = rc;
> - sqlSystemError(db, rc);
> - testcase( sqlGlobalConfig.xLog!=0);
> - sql_log(rc, "statement aborts at %d: [%s] %s",
> - (int)(pOp - aOp), p->zSql, p->zErrMsg);
> - sqlVdbeHalt(p);
> - if (rc==SQL_IOERR_NOMEM) sqlOomFault(db);
> - rc = SQL_ERROR;
>
> /* This is the only way out of this procedure. */
> vdbe_return:
> @@ -5398,21 +5316,20 @@ vdbe_return:
> assert(rc!=SQL_OK || nExtraDelete==0
> || sql_strlike_ci("DELETE%", p->zSql, 0) != 0
> );
> + assert(rc == SQL_OK || rc == SQL_BUSY || rc == SQL_TARANTOOL_ERROR ||
> + rc == SQL_ROW || rc == SQL_DONE);
> return rc;
>
> /* Jump to here if a string or blob larger than SQL_MAX_LENGTH
> * is encountered.
> */
> too_big:
> - sqlVdbeError(p, "string or blob too big");
> - rc = SQL_TOOBIG;
> + diag_set(ClientError, ER_SQL_EXECUTE, "string or blob too big");
> goto abort_due_to_error;
>
> /* Jump to here if a malloc() fails.
> */
> no_mem:
> sqlOomFault(db);
> - sqlVdbeError(p, "out of memory");
> - rc = SQL_NOMEM;
> goto abort_due_to_error;
> }
> diff --git a/src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h
> index ee14510..9e6a426 100644
> --- a/src/box/sql/vdbeInt.h
> +++ b/src/box/sql/vdbeInt.h
> @@ -244,10 +244,6 @@ struct Mem {
> #define MEM_Agg 0x4000 /* Mem.z points to an agg function context */
> #define MEM_Zero 0x8000 /* Mem.i contains count of 0s appended to blob */
> #define MEM_Subtype 0x10000 /* Mem.eSubtype is valid */
> -#ifdef SQL_OMIT_INCRBLOB
> -#undef MEM_Zero
> -#define MEM_Zero 0x0000
> -#endif
>
> /**
> * In contrast to Mem_TypeMask, this one allows to get
> @@ -450,7 +446,6 @@ struct Vdbe {
> /*
> * Function prototypes
> */
> -void sqlVdbeError(Vdbe *, const char *, ...);
> void sqlVdbeFreeCursor(Vdbe *, VdbeCursor *);
> void sqlVdbePopStack(Vdbe *, int);
> int sqlVdbeCursorRestore(VdbeCursor *);
> @@ -532,13 +527,8 @@ void sqlVdbeMemPrettyPrint(Mem * pMem, char *zBuf);
> #endif
> int sqlVdbeMemHandleBom(Mem * pMem);
>
> -#ifndef SQL_OMIT_INCRBLOB
> int sqlVdbeMemExpandBlob(Mem *);
> #define ExpandBlob(P) (((P)->flags&MEM_Zero)?sqlVdbeMemExpandBlob(P):0)
> -#else
> -#define sqlVdbeMemExpandBlob(x) SQL_OK
> -#define ExpandBlob(P) SQL_OK
> -#endif
>
> /**
> * Perform comparison of two keys: one is packed and one is not.
> diff --git a/src/box/sql/vdbeapi.c b/src/box/sql/vdbeapi.c
> index 673ccd1..3bdfa7d 100644
> --- a/src/box/sql/vdbeapi.c
> +++ b/src/box/sql/vdbeapi.c
> @@ -536,15 +536,6 @@ sqlStep(Vdbe * p)
> p->rc = SQL_NOMEM;
> }
> end_of_step:
> - /* At this point local variable rc holds the value that should be
> - * returned if this statement was compiled using the legacy
> - * sql_prepare() interface. According to the docs, this can only
> - * be one of the values in the first assert() below. Variable p->rc
> - * contains the value that would be returned if sql_finalize()
> - * were called on statement p.
> - */
> - assert(rc == SQL_ROW || rc == SQL_DONE || rc == SQL_ERROR
> - || (rc & 0xff) == SQL_BUSY || rc == SQL_MISUSE);
> if (p->isPrepareV2 && rc != SQL_ROW && rc != SQL_DONE) {
> /* If this statement was prepared using sql_prepare_v2(), and an
> * error has occurred, then return the error code in p->rc to the
> @@ -564,20 +555,17 @@ int
> sql_step(sql_stmt * pStmt)
> {
> int rc; /* Result from sqlStep() */
> - int rc2 = SQL_OK; /* Result from sqlReprepare() */
> Vdbe *v = (Vdbe *) pStmt; /* the prepared statement */
> int cnt = 0; /* Counter to prevent infinite loop of reprepares */
> - sql *db; /* The database connection */
>
> if (vdbeSafetyNotNull(v)) {
> return SQL_MISUSE;
> }
> - db = v->db;
> v->doingRerun = 0;
> while ((rc = sqlStep(v)) == SQL_SCHEMA
> && cnt++ < SQL_MAX_SCHEMA_RETRY) {
> int savedPc = v->pc;
> - rc2 = rc = sqlReprepare(v);
> + rc = sqlReprepare(v);
> if (rc != SQL_OK)
> break;
> sql_reset(pStmt);
> @@ -585,26 +573,6 @@ sql_step(sql_stmt * pStmt)
> v->doingRerun = 1;
> assert(v->expired == 0);
> }
> - if (rc2 != SQL_OK) {
> - /* This case occurs after failing to recompile an sql statement.
> - * The error message from the SQL compiler has already been loaded
> - * into the database handle. This block copies the error message
> - * from the database handle into the statement and sets the statement
> - * program counter to 0 to ensure that when the statement is
> - * finalized or reset the parser error message is available via
> - * sql_errmsg() and sql_errcode().
> - */
> - const char *zErr = (const char *)sql_value_text(db->pErr);
> - sqlDbFree(db, v->zErrMsg);
> - if (!db->mallocFailed) {
> - v->zErrMsg = sqlDbStrDup(db, zErr);
> - v->rc = rc2;
> - } else {
> - v->zErrMsg = 0;
> - v->rc = rc = SQL_NOMEM;
> - }
> - }
> - rc = sqlApiExit(db, rc);
> return rc;
> }
>
> diff --git a/src/box/sql/vdbeaux.c b/src/box/sql/vdbeaux.c
> index 619b211..3f573d0 100644
> --- a/src/box/sql/vdbeaux.c
> +++ b/src/box/sql/vdbeaux.c
> @@ -116,19 +116,6 @@ sql_vdbe_prepare(struct Vdbe *vdbe)
> }
>
> /*
> - * Change the error string stored in Vdbe.zErrMsg
> - */
> -void
> -sqlVdbeError(Vdbe * p, const char *zFormat, ...)
> -{
> - va_list ap;
> - sqlDbFree(p->db, p->zErrMsg);
> - va_start(ap, zFormat);
> - p->zErrMsg = sqlVMPrintf(p->db, zFormat, ap);
> - va_end(ap);
> -}
> -
> -/*
> * Remember the SQL string for a prepared statement.
> */
> void
> @@ -2115,10 +2102,11 @@ sqlVdbeCheckFk(Vdbe * p, int deferred)
> if ((deferred && txn != NULL && txn->psql_txn != NULL &&
> txn->psql_txn->fk_deferred_count > 0) ||
> (!deferred && p->nFkConstraint > 0)) {
> - p->rc = SQL_CONSTRAINT_FOREIGNKEY;
> + p->rc = SQL_TARANTOOL_ERROR;
> p->errorAction = ON_CONFLICT_ACTION_ABORT;
> - sqlVdbeError(p, "FOREIGN KEY constraint failed");
> - return SQL_ERROR;
> + diag_set(ClientError, ER_SQL_EXECUTE, "FOREIGN KEY constraint "\
> + "failed");
> + return SQL_TARANTOOL_ERROR;
> }
> return SQL_OK;
> }
> diff --git a/src/box/sql/vdbemem.c b/src/box/sql/vdbemem.c
> index 585dc21..d6375a6 100644
> --- a/src/box/sql/vdbemem.c
> +++ b/src/box/sql/vdbemem.c
> @@ -210,7 +210,6 @@ sqlVdbeMemMakeWriteable(Mem * pMem)
> * If the given Mem* has a zero-filled tail, turn it into an ordinary
> * blob stored in dynamically allocated space.
> */
> -#ifndef SQL_OMIT_INCRBLOB
> int
> sqlVdbeMemExpandBlob(Mem * pMem)
> {
> @@ -232,7 +231,6 @@ sqlVdbeMemExpandBlob(Mem * pMem)
> pMem->flags &= ~(MEM_Zero | MEM_Term);
> return SQL_OK;
> }
> -#endif
>
> /*
> * It is already known that pMem contains an unterminated string.
> @@ -315,8 +313,7 @@ sqlVdbeMemStringify(Mem * pMem, u8 bForce)
> * This routine calls the finalize method for that function. The
> * result of the aggregate is stored back into pMem.
> *
> - * Return SQL_ERROR if the finalizer reports an error. SQL_OK
> - * otherwise.
> + * Return -1 if the finalizer reports an error. 0 otherwise.
> */
> int
> sqlVdbeMemFinalize(Mem * pMem, FuncDef * pFunc)
> @@ -337,9 +334,10 @@ sqlVdbeMemFinalize(Mem * pMem, FuncDef * pFunc)
> if (pMem->szMalloc > 0)
> sqlDbFree(pMem->db, pMem->zMalloc);
> memcpy(pMem, &t, sizeof(t));
> - return ctx.is_aborted ? SQL_TARANTOOL_ERROR : SQL_OK;
> + if (ctx.is_aborted)
> + return -1;
> }
> - return SQL_OK;
> + return 0;
> }
>
> /*
> diff --git a/test/sql-tap/gh-2931-savepoints.test.lua b/test/sql-tap/gh-2931-savepoints.test.lua
> index 6123fc4..be499b6 100755
> --- a/test/sql-tap/gh-2931-savepoints.test.lua
> +++ b/test/sql-tap/gh-2931-savepoints.test.lua
> @@ -39,7 +39,7 @@ local testcases = {
> {0,{1,1}}},
> {"5",
> [[rollback to savepoint s1_2;]],
> - {1, "Failed to execute SQL statement: no such savepoint: S1_2"}},
> + {1, "Can not rollback to savepoint: the savepoint does not exist"}},
> {"6",
> [[insert into t1 values(2);
> select * from t1 union all select * from t2;]],
> diff --git a/test/sql/savepoints.result b/test/sql/savepoints.result
> index bb4a296..d20e0ed 100644
> --- a/test/sql/savepoints.result
> +++ b/test/sql/savepoints.result
> @@ -67,7 +67,7 @@ end;
> ...
> release_sv_fail();
> ---
> -- error: 'Failed to execute SQL statement: no such savepoint: T1'
> +- error: 'Can not rollback to savepoint: the savepoint does not exist'
> ...
> box.commit();
> ---
>
>
>
>
[-- Attachment #2: Type: text/html, Size: 49753 bytes --]
^ permalink raw reply [flat|nested] 31+ messages in thread
* [tarantool-patches] [PATCH v1 08/12] sql: remove field zErrMsg from struct Vdbe
2019-05-05 12:17 [tarantool-patches] [PATCH v1 00/12] sql: set errors in VDBE using diag_set() imeevma
` (6 preceding siblings ...)
2019-05-05 12:17 ` [tarantool-patches] [PATCH v1 07/12] sql: set errors in VDBE using diag_set() imeevma
@ 2019-05-05 12:17 ` imeevma
2019-05-15 13:30 ` [tarantool-patches] " n.pettik
2019-05-05 12:17 ` [tarantool-patches] [PATCH v1 09/12] sql: remove field pErr from struct sql imeevma
` (3 subsequent siblings)
11 siblings, 1 reply; 31+ messages in thread
From: imeevma @ 2019-05-05 12:17 UTC (permalink / raw)
To: korablev; +Cc: tarantool-patches
This field become unused and should be removed.
---
src/box/sql/vdbeInt.h | 1 -
src/box/sql/vdbeaux.c | 29 ++++-------------------------
2 files changed, 4 insertions(+), 26 deletions(-)
diff --git a/src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h
index b655b5a..de9dbd6 100644
--- a/src/box/sql/vdbeInt.h
+++ b/src/box/sql/vdbeInt.h
@@ -404,7 +404,6 @@ struct Vdbe {
Mem **apArg; /* Arguments to currently executing user function */
Mem *aColName; /* Column names to return */
Mem *pResultSet; /* Pointer to an array of results */
- char *zErrMsg; /* Error message written here */
VdbeCursor **apCsr; /* One element of this array for each open cursor */
Mem *aVar; /* Values for the OP_Variable opcode. */
/**
diff --git a/src/box/sql/vdbeaux.c b/src/box/sql/vdbeaux.c
index 48c2a81..300a44b 100644
--- a/src/box/sql/vdbeaux.c
+++ b/src/box/sql/vdbeaux.c
@@ -1966,7 +1966,6 @@ closeCursorsAndFree(Vdbe * p)
static void
Cleanup(Vdbe * p)
{
- sql *db = p->db;
#ifdef SQL_DEBUG
/* Execute assert() statements to ensure that the Vdbe.apCsr[] and
@@ -1982,8 +1981,6 @@ Cleanup(Vdbe * p)
}
#endif
- sqlDbFree(db, p->zErrMsg);
- p->zErrMsg = 0;
p->pResultSet = 0;
}
@@ -2326,8 +2323,6 @@ sqlVdbeHalt(Vdbe * p)
if (p->rc == SQL_OK
|| (p->rc & 0xff) == SQL_CONSTRAINT) {
p->rc = rc;
- sqlDbFree(db, p->zErrMsg);
- p->zErrMsg = 0;
}
closeCursorsAndFree(p);
sqlRollbackAll(p);
@@ -2390,24 +2385,13 @@ sqlVdbeTransferError(Vdbe * p)
{
sql *db = p->db;
int rc = p->rc;
- if (p->zErrMsg) {
- db->bBenignMalloc++;
- sqlBeginBenignMalloc();
- if (db->pErr == 0)
- db->pErr = sqlValueNew(db);
- sqlValueSetStr(db->pErr, -1, p->zErrMsg, SQL_TRANSIENT);
- sqlEndBenignMalloc();
- db->bBenignMalloc--;
- db->errCode = rc;
- } else {
- sqlError(db, rc);
- }
+ sqlError(db, rc);
return rc;
}
/*
* Clean up a VDBE after execution but do not delete the VDBE just yet.
- * Write any error messages into *pzErrMsg. Return the result code.
+ * Return the result code.
*
* After this routine is run, the VDBE should be ready to be executed
* again.
@@ -2435,8 +2419,6 @@ sqlVdbeReset(Vdbe * p)
*/
if (p->pc >= 0) {
sqlVdbeTransferError(p);
- sqlDbFree(db, p->zErrMsg);
- p->zErrMsg = 0;
if (p->runOnlyOnce)
p->expired = 1;
} else if (p->rc && p->expired) {
@@ -2444,10 +2426,7 @@ sqlVdbeReset(Vdbe * p)
* to sql_step(). For consistency (since sql_step() was
* called), set the database error in this case as well.
*/
- sqlErrorWithMsg(db, p->rc, p->zErrMsg ? "%s" : 0,
- p->zErrMsg);
- sqlDbFree(db, p->zErrMsg);
- p->zErrMsg = 0;
+ sqlErrorWithMsg(db, p->rc, NULL);
}
/* Reclaim all memory used by the VDBE
@@ -2501,7 +2480,7 @@ sqlVdbeReset(Vdbe * p)
/*
* Clean up and delete a VDBE after execution. Return an integer which is
- * the result code. Write any error message text into *pzErrMsg.
+ * the result code.
*/
int
sqlVdbeFinalize(Vdbe * p)
--
2.7.4
^ permalink raw reply [flat|nested] 31+ messages in thread
* [tarantool-patches] [PATCH v1 09/12] sql: remove field pErr from struct sql
2019-05-05 12:17 [tarantool-patches] [PATCH v1 00/12] sql: set errors in VDBE using diag_set() imeevma
` (7 preceding siblings ...)
2019-05-05 12:17 ` [tarantool-patches] [PATCH v1 08/12] sql: remove field zErrMsg from struct Vdbe imeevma
@ 2019-05-05 12:17 ` imeevma
2019-05-05 12:17 ` [tarantool-patches] [PATCH v1 10/12] sql: remove field errCode " imeevma
` (2 subsequent siblings)
11 siblings, 0 replies; 31+ messages in thread
From: imeevma @ 2019-05-05 12:17 UTC (permalink / raw)
To: korablev; +Cc: tarantool-patches
This field became unused and should be removed.
---
src/box/sql/sqlInt.h | 1 -
src/box/sql/util.c | 14 ++------------
2 files changed, 2 insertions(+), 13 deletions(-)
diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
index 3981fbf..1af5457 100644
--- a/src/box/sql/sqlInt.h
+++ b/src/box/sql/sqlInt.h
@@ -1463,7 +1463,6 @@ struct sql {
void *pUpdateArg;
void (*xUpdateCallback) (void *, int, const char *, const char *,
sql_int64);
- sql_value *pErr; /* Most recent error message */
Lookaside lookaside; /* Lookaside malloc configuration */
Hash aFunc; /* Hash table of connection functions */
int *pnBytesFreed; /* If not NULL, increment this in DbFree() */
diff --git a/src/box/sql/util.c b/src/box/sql/util.c
index d5c93f8..62c29ce 100644
--- a/src/box/sql/util.c
+++ b/src/box/sql/util.c
@@ -138,8 +138,6 @@ sqlStrlen30(const char *z)
static SQL_NOINLINE void
sqlErrorFinish(sql * db, int err_code)
{
- if (db->pErr)
- sqlValueSetNull(db->pErr);
sqlSystemError(db, err_code);
}
@@ -153,7 +151,7 @@ sqlError(sql * db, int err_code)
{
assert(db != 0);
db->errCode = err_code;
- if (err_code || db->pErr)
+ if (err_code)
sqlErrorFinish(db, err_code);
}
@@ -199,16 +197,8 @@ sqlErrorWithMsg(sql * db, int err_code, const char *zFormat, ...)
assert(db != 0);
db->errCode = err_code;
sqlSystemError(db, err_code);
- if (zFormat == 0) {
+ if (zFormat == 0)
sqlError(db, err_code);
- } else if (db->pErr || (db->pErr = sqlValueNew(db)) != 0) {
- char *z;
- va_list ap;
- va_start(ap, zFormat);
- z = sqlVMPrintf(db, zFormat, ap);
- va_end(ap);
- sqlValueSetStr(db->pErr, -1, z, SQL_DYNAMIC);
- }
}
/*
--
2.7.4
^ permalink raw reply [flat|nested] 31+ messages in thread
* [tarantool-patches] [PATCH v1 10/12] sql: remove field errCode from struct sql
2019-05-05 12:17 [tarantool-patches] [PATCH v1 00/12] sql: set errors in VDBE using diag_set() imeevma
` (8 preceding siblings ...)
2019-05-05 12:17 ` [tarantool-patches] [PATCH v1 09/12] sql: remove field pErr from struct sql imeevma
@ 2019-05-05 12:17 ` imeevma
2019-05-15 13:32 ` [tarantool-patches] " n.pettik
2019-05-05 12:17 ` [tarantool-patches] [PATCH v1 11/12] sql: remove sqlError() and remove sqlErrorWithMsg() imeevma
2019-05-05 12:17 ` [tarantool-patches] [PATCH v1 12/12] sql: use diag_set() to set an error in SQL functions imeevma
11 siblings, 1 reply; 31+ messages in thread
From: imeevma @ 2019-05-05 12:17 UTC (permalink / raw)
To: korablev; +Cc: tarantool-patches
This field became unusued and should be removed.
---
src/box/sql/main.c | 18 ------------------
src/box/sql/prepare.c | 2 --
src/box/sql/sqlInt.h | 1 -
src/box/sql/util.c | 2 --
src/box/sql/vdbeapi.c | 1 -
5 files changed, 24 deletions(-)
diff --git a/src/box/sql/main.c b/src/box/sql/main.c
index a3c6aa1..155cbcc 100644
--- a/src/box/sql/main.c
+++ b/src/box/sql/main.c
@@ -568,22 +568,6 @@ sqlTempInMemory(const sql * db)
}
/*
- * Return the most recent error code generated by an sql routine. If NULL is
- * passed to this function, we assume a malloc() failed during sql_open().
- */
-int
-sql_errcode(sql * db)
-{
- if (db && !sqlSafetyCheckSickOrOk(db)) {
- return SQL_MISUSE;
- }
- if (!db || db->mallocFailed) {
- return SQL_NOMEM;
- }
- return db->errCode & db->errMask;
-}
-
-/*
* This array defines hard upper bounds on limit values. The
* initializer must be kept in sync with the SQL_LIMIT_*
* #defines in sql.h.
@@ -734,7 +718,6 @@ sql_init_db(sql **out_db)
*/
sqlError(db, SQL_OK);
sqlRegisterPerConnectionBuiltinFunctions(db);
- rc = sql_errcode(db);
if (rc)
sqlError(db, rc);
@@ -744,7 +727,6 @@ sql_init_db(sql **out_db)
sqlGlobalConfig.nLookaside);
opendb_out:
- rc = sql_errcode(db);
assert(db != 0 || rc == SQL_NOMEM);
if (rc == SQL_NOMEM) {
sql_close(db);
diff --git a/src/box/sql/prepare.c b/src/box/sql/prepare.c
index 3df6b5c..3f1e1e0 100644
--- a/src/box/sql/prepare.c
+++ b/src/box/sql/prepare.c
@@ -166,8 +166,6 @@ sqlPrepare(sql * db, /* Database handle. */
*ppStmt = (sql_stmt *) sParse.pVdbe;
}
- db->errCode = rc;
-
/* Delete any TriggerPrg structures allocated while parsing this statement. */
while (sParse.pTriggerPrg) {
TriggerPrg *pT = sParse.pTriggerPrg;
diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
index 1af5457..e6de71c 100644
--- a/src/box/sql/sqlInt.h
+++ b/src/box/sql/sqlInt.h
@@ -1428,7 +1428,6 @@ struct sql {
struct Vdbe *pVdbe; /* List of active virtual machines */
struct coll *pDfltColl; /* The default collating sequence (BINARY) */
i64 szMmap; /* Default mmap_size setting */
- int errCode; /* Most recent error code (sql_*) */
int errMask; /* & result codes with this before returning */
int iSysErrno; /* Errno value from last system error */
u16 dbOptFlags; /* Flags to enable/disable optimizations */
diff --git a/src/box/sql/util.c b/src/box/sql/util.c
index 62c29ce..819f7fa 100644
--- a/src/box/sql/util.c
+++ b/src/box/sql/util.c
@@ -150,7 +150,6 @@ void
sqlError(sql * db, int err_code)
{
assert(db != 0);
- db->errCode = err_code;
if (err_code)
sqlErrorFinish(db, err_code);
}
@@ -195,7 +194,6 @@ void
sqlErrorWithMsg(sql * db, int err_code, const char *zFormat, ...)
{
assert(db != 0);
- db->errCode = err_code;
sqlSystemError(db, err_code);
if (zFormat == 0)
sqlError(db, err_code);
diff --git a/src/box/sql/vdbeapi.c b/src/box/sql/vdbeapi.c
index 34fa5c8..5a859fe 100644
--- a/src/box/sql/vdbeapi.c
+++ b/src/box/sql/vdbeapi.c
@@ -564,7 +564,6 @@ sqlStep(Vdbe * p)
checkProfileCallback(db, p);
#endif
- db->errCode = rc;
if (SQL_NOMEM == sqlApiExit(p->db, p->rc)) {
p->rc = SQL_NOMEM;
}
--
2.7.4
^ permalink raw reply [flat|nested] 31+ messages in thread
* [tarantool-patches] Re: [PATCH v1 10/12] sql: remove field errCode from struct sql
2019-05-05 12:17 ` [tarantool-patches] [PATCH v1 10/12] sql: remove field errCode " imeevma
@ 2019-05-15 13:32 ` n.pettik
2019-05-25 9:25 ` Imeev Mergen
0 siblings, 1 reply; 31+ messages in thread
From: n.pettik @ 2019-05-15 13:32 UTC (permalink / raw)
To: tarantool-patches; +Cc: Imeev Mergen
> On 5 May 2019, at 15:17, imeevma@tarantool.org wrote:
>
> This field became unusued and should be removed.
> ---
>
> diff --git a/src/box/sql/main.c b/src/box/sql/main.c
> index a3c6aa1..155cbcc 100644
> --- a/src/box/sql/main.c
> +++ b/src/box/sql/main.c
> @@ -568,22 +568,6 @@ sqlTempInMemory(const sql * db)
> }
>
> /*
> - * Return the most recent error code generated by an sql routine. If NULL is
> - * passed to this function, we assume a malloc() failed during sql_open().
> - */
> -int
> -sql_errcode(sql * db)
Still see several mentions of this function in comments.
^ permalink raw reply [flat|nested] 31+ messages in thread
* [tarantool-patches] Re: [PATCH v1 10/12] sql: remove field errCode from struct sql
2019-05-15 13:32 ` [tarantool-patches] " n.pettik
@ 2019-05-25 9:25 ` Imeev Mergen
0 siblings, 0 replies; 31+ messages in thread
From: Imeev Mergen @ 2019-05-25 9:25 UTC (permalink / raw)
To: n.pettik, tarantool-patches
On 5/15/19 4:32 PM, n.pettik wrote:
>
>> On 5 May 2019, at 15:17, imeevma@tarantool.org wrote:
>>
>> This field became unusued and should be removed.
>> ---
>>
>> diff --git a/src/box/sql/main.c b/src/box/sql/main.c
>> index a3c6aa1..155cbcc 100644
>> --- a/src/box/sql/main.c
>> +++ b/src/box/sql/main.c
>> @@ -568,22 +568,6 @@ sqlTempInMemory(const sql * db)
>> }
>>
>> /*
>> - * Return the most recent error code generated by an sql routine. If NULL is
>> - * passed to this function, we assume a malloc() failed during sql_open().
>> - */
>> -int
>> -sql_errcode(sql * db)
> Still see several mentions of this function in comments.
Fixed.
>
^ permalink raw reply [flat|nested] 31+ messages in thread
* [tarantool-patches] [PATCH v1 11/12] sql: remove sqlError() and remove sqlErrorWithMsg()
2019-05-05 12:17 [tarantool-patches] [PATCH v1 00/12] sql: set errors in VDBE using diag_set() imeevma
` (9 preceding siblings ...)
2019-05-05 12:17 ` [tarantool-patches] [PATCH v1 10/12] sql: remove field errCode " imeevma
@ 2019-05-05 12:17 ` imeevma
2019-05-05 12:17 ` [tarantool-patches] [PATCH v1 12/12] sql: use diag_set() to set an error in SQL functions imeevma
11 siblings, 0 replies; 31+ messages in thread
From: imeevma @ 2019-05-05 12:17 UTC (permalink / raw)
To: korablev; +Cc: tarantool-patches
These functions are part of the SQL error system, which is
replaced by the Tarantool error system. They are not needed now,
so they will be deleted.
---
src/box/lua/lua_sql.c | 2 +-
src/box/sql/legacy.c | 2 --
src/box/sql/main.c | 83 +++++++------------------------------------
src/box/sql/malloc.c | 1 -
src/box/sql/prepare.c | 6 ++--
src/box/sql/sqlInt.h | 6 ----
src/box/sql/util.c | 69 -----------------------------------
src/box/sql/vdbeInt.h | 1 -
src/box/sql/vdbeapi.c | 7 +---
src/box/sql/vdbeaux.c | 31 +++++-----------
test/sql/func-recreate.result | 3 +-
11 files changed, 27 insertions(+), 184 deletions(-)
diff --git a/src/box/lua/lua_sql.c b/src/box/lua/lua_sql.c
index 36b75ff..d28045a 100644
--- a/src/box/lua/lua_sql.c
+++ b/src/box/lua/lua_sql.c
@@ -196,6 +196,6 @@ lbox_sql_create_function(struct lua_State *L)
func_info, lua_sql_call, NULL, NULL,
lua_sql_destroy);
if (rc != 0)
- return luaL_error(L, sqlErrStr(rc));
+ return luaT_error(L);
return 0;
}
diff --git a/src/box/sql/legacy.c b/src/box/sql/legacy.c
index ee680ef..b6e8f6e 100644
--- a/src/box/sql/legacy.c
+++ b/src/box/sql/legacy.c
@@ -70,7 +70,6 @@ sql_exec(sql * db, /* The database on which the SQL executes */
if (zSql == 0)
zSql = "";
- sqlError(db, SQL_OK);
while (rc == SQL_OK && zSql[0]) {
int nCol;
char **azVals = 0;
@@ -145,7 +144,6 @@ sql_exec(sql * db, /* The database on which the SQL executes */
rc = SQL_ABORT;
sqlVdbeFinalize((Vdbe *) pStmt);
pStmt = 0;
- sqlError(db, SQL_ABORT);
goto exec_out;
}
}
diff --git a/src/box/sql/main.c b/src/box/sql/main.c
index 155cbcc..f35c84f 100644
--- a/src/box/sql/main.c
+++ b/src/box/sql/main.c
@@ -284,61 +284,6 @@ functionDestroy(sql * db, FuncDef * p)
}
/*
- * Return TRUE if database connection db has unfinalized prepared
- * statement.
- */
-static int
-connectionIsBusy(sql * db)
-{
- if (db->pVdbe)
- return 1;
- return 0;
-}
-
-/*
- * Close an existing sql database
- */
-static int
-sqlClose(sql * db, int forceZombie)
-{
- assert(db);
- if (!sqlSafetyCheckSickOrOk(db)) {
- return SQL_MISUSE;
- }
- if (db->mTrace & SQL_TRACE_CLOSE) {
- db->xTrace(SQL_TRACE_CLOSE, db->pTraceArg, db, 0);
- }
-
- /* Legacy behavior (sql_close() behavior) is to return
- * SQL_BUSY if the connection can not be closed immediately.
- */
- if (!forceZombie && connectionIsBusy(db)) {
- sqlErrorWithMsg(db, SQL_BUSY,
- "unable to close due to unfinalized "
- "statements");
- return SQL_BUSY;
- }
-
- /* Convert the connection into a zombie and then close it.
- */
- db->magic = SQL_MAGIC_ZOMBIE;
-
- return SQL_OK;
-}
-
-/*
- * Two variations on the public interface for closing a database
- * connection. The sql_close() version returns SQL_BUSY and
- * leaves the connection option if there are unfinalized prepared
- * statements.
- */
-int
-sql_close(sql * db)
-{
- return sqlClose(db, 0);
-}
-
-/*
* Rollback all database files. If tripCode is not SQL_OK, then
* any write cursors are invalidated ("tripped" - as in "tripping a circuit
* breaker") and made to return tripCode if there are any further
@@ -417,7 +362,9 @@ sqlCreateFunc(sql * db,
(!xSFunc && (!xFinal && xStep)) ||
(nArg < -1 || nArg > SQL_MAX_FUNCTION_ARG) ||
(255 < (sqlStrlen30(zFunctionName)))) {
- return SQL_MISUSE;
+ diag_set(ClientError, ER_CREATE_FUNCTION, zFunctionName,
+ "wrong function definition");
+ return SQL_TARANTOOL_ERROR;
}
assert(SQL_FUNC_CONSTANT == SQL_DETERMINISTIC);
@@ -432,10 +379,10 @@ sqlCreateFunc(sql * db,
p = sqlFindFunction(db, zFunctionName, nArg, 0);
if (p && p->nArg == nArg) {
if (db->nVdbeActive) {
- sqlErrorWithMsg(db, SQL_BUSY,
- "unable to delete/modify user-function due to active statements");
- assert(!db->mallocFailed);
- return SQL_BUSY;
+ diag_set(ClientError, ER_CREATE_FUNCTION, zFunctionName,
+ "unable to create function due to active "\
+ "statements");
+ return SQL_TARANTOOL_ERROR;
} else {
sqlExpirePreparedStatements(db);
}
@@ -443,9 +390,8 @@ sqlCreateFunc(sql * db,
p = sqlFindFunction(db, zFunctionName, nArg, 1);
assert(p || db->mallocFailed);
- if (!p) {
- return SQL_NOMEM;
- }
+ if (p == NULL)
+ return SQL_TARANTOOL_ERROR;
/* If an older version of the function with a configured destructor is
* being replaced invoke the destructor function here.
@@ -716,22 +662,17 @@ sql_init_db(sql **out_db)
* database schema yet. This is delayed until the first time the database
* is accessed.
*/
- sqlError(db, SQL_OK);
sqlRegisterPerConnectionBuiltinFunctions(db);
- if (rc)
- sqlError(db, rc);
-
/* Enable the lookaside-malloc subsystem */
setupLookaside(db, 0, sqlGlobalConfig.szLookaside,
sqlGlobalConfig.nLookaside);
opendb_out:
assert(db != 0 || rc == SQL_NOMEM);
- if (rc == SQL_NOMEM) {
- sql_close(db);
- db = 0;
- } else if (rc != SQL_OK)
+ if (rc == SQL_NOMEM)
+ db = NULL;
+ else if (rc != SQL_OK)
db->magic = SQL_MAGIC_SICK;
*out_db = db;
diff --git a/src/box/sql/malloc.c b/src/box/sql/malloc.c
index dbc6846..a531a8c 100644
--- a/src/box/sql/malloc.c
+++ b/src/box/sql/malloc.c
@@ -926,7 +926,6 @@ static SQL_NOINLINE int
apiOomError(sql * db)
{
sqlOomClear(db);
- sqlError(db, SQL_NOMEM);
return SQL_NOMEM;
}
diff --git a/src/box/sql/prepare.c b/src/box/sql/prepare.c
index 3f1e1e0..5e0faa1 100644
--- a/src/box/sql/prepare.c
+++ b/src/box/sql/prepare.c
@@ -81,9 +81,9 @@ sqlPrepare(sql * db, /* Database handle. */
testcase(nBytes == mxLen);
testcase(nBytes == mxLen + 1);
if (nBytes > mxLen) {
- sqlErrorWithMsg(db, SQL_TOOBIG,
- "statement too long");
- rc = sqlApiExit(db, SQL_TOOBIG);
+ diag_set(ClientError, ER_SQL_PARSER_LIMIT,
+ "SQL command length", nBytes, mxLen);
+ rc = SQL_TARANTOOL_ERROR;
goto end_prepare;
}
zSqlCopy = sqlDbStrNDup(db, zSql, nBytes);
diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
index e6de71c..c757fb5 100644
--- a/src/box/sql/sqlInt.h
+++ b/src/box/sql/sqlInt.h
@@ -922,9 +922,6 @@ sql_stmt_busy(sql_stmt *);
int
sql_init_db(sql **db);
-int
-sql_close(sql *);
-
/**
* Get number of the named parameter in the prepared sql
@@ -1429,7 +1426,6 @@ struct sql {
struct coll *pDfltColl; /* The default collating sequence (BINARY) */
i64 szMmap; /* Default mmap_size setting */
int errMask; /* & result codes with this before returning */
- int iSysErrno; /* Errno value from last system error */
u16 dbOptFlags; /* Flags to enable/disable optimizations */
u8 enc; /* Text encoding */
u8 temp_store; /* 1: file 2: memory 0: default */
@@ -4431,8 +4427,6 @@ sql_atoi64(const char *z, int64_t *val, int length);
int
sql_dec_or_hex_to_i64(const char *z, int64_t *val);
-void sqlErrorWithMsg(sql *, int, const char *, ...);
-void sqlError(sql *, int);
void sqlSystemError(sql *, int);
void *sqlHexToBlob(sql *, const char *z, int n);
u8 sqlHexToInt(int h);
diff --git a/src/box/sql/util.c b/src/box/sql/util.c
index 819f7fa..d5f6447 100644
--- a/src/box/sql/util.c
+++ b/src/box/sql/util.c
@@ -131,75 +131,6 @@ sqlStrlen30(const char *z)
}
/*
- * Helper function for sqlError() - called rarely. Broken out into
- * a separate routine to avoid unnecessary register saves on entry to
- * sqlError().
- */
-static SQL_NOINLINE void
-sqlErrorFinish(sql * db, int err_code)
-{
- sqlSystemError(db, err_code);
-}
-
-/*
- * Set the current error code to err_code and clear any prior error message.
- * Also set iSysErrno (by calling sqlSystem) if the err_code indicates
- * that would be appropriate.
- */
-void
-sqlError(sql * db, int err_code)
-{
- assert(db != 0);
- if (err_code)
- sqlErrorFinish(db, err_code);
-}
-
-/*
- * Load the sql.iSysErrno field if that is an appropriate thing
- * to do based on the sql error code in rc.
- */
-void
-sqlSystemError(sql * db, int rc)
-{
- if (rc == SQL_IOERR_NOMEM)
- return;
- rc &= 0xff;
- if (rc == SQL_CANTOPEN || rc == SQL_IOERR) {
- db->iSysErrno = sqlOsGetLastError(db->pVfs);
- }
-}
-
-/*
- * Set the most recent error code and error string for the sql
- * handle "db". The error code is set to "err_code".
- *
- * If it is not NULL, string zFormat specifies the format of the
- * error string in the style of the printf functions: The following
- * format characters are allowed:
- *
- * %s Insert a string
- * %z A string that should be freed after use
- * %d Insert an integer
- * %T Insert a token
- * %S Insert the first element of a SrcList
- *
- * zFormat and any string tokens that follow it are assumed to be
- * encoded in UTF-8.
- *
- * To clear the most recent error for sql handle "db", sqlError
- * should be called with err_code set to SQL_OK and zFormat set
- * to NULL.
- */
-void
-sqlErrorWithMsg(sql * db, int err_code, const char *zFormat, ...)
-{
- assert(db != 0);
- sqlSystemError(db, err_code);
- if (zFormat == 0)
- sqlError(db, err_code);
-}
-
-/*
* Convert an SQL-style quoted string into a normal string by removing
* the quote characters. The conversion is done in-place. If the
* input does not begin with a quote character, then this routine
diff --git a/src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h
index de9dbd6..6aadca2 100644
--- a/src/box/sql/vdbeInt.h
+++ b/src/box/sql/vdbeInt.h
@@ -519,7 +519,6 @@ int sqlVdbeMemClearAndResize(Mem * pMem, int n);
int sqlVdbeCloseStatement(Vdbe *, int);
void sqlVdbeFrameDelete(VdbeFrame *);
int sqlVdbeFrameRestore(VdbeFrame *);
-int sqlVdbeTransferError(Vdbe * p);
int sqlVdbeSorterInit(struct sql *db, struct VdbeCursor *cursor);
void sqlVdbeSorterReset(sql *, VdbeSorter *);
diff --git a/src/box/sql/vdbeapi.c b/src/box/sql/vdbeapi.c
index 5a859fe..d9dd28f 100644
--- a/src/box/sql/vdbeapi.c
+++ b/src/box/sql/vdbeapi.c
@@ -573,7 +573,7 @@ sqlStep(Vdbe * p)
* error has occurred, then return the error code in p->rc to the
* caller. Set the error code in the database handle to the same value.
*/
- rc = sqlVdbeTransferError(p);
+ rc = p->rc;
}
return (rc & db->errMask);
}
@@ -877,7 +877,6 @@ columnMem(sql_stmt * pStmt, int i)
if (pVm->pResultSet != 0 && i < pVm->nResColumn && i >= 0) {
pOut = &pVm->pResultSet[i];
} else {
- sqlError(pVm->db, SQL_RANGE);
pOut = (Mem *) columnNullValue();
}
return pOut;
@@ -1148,20 +1147,17 @@ vdbeUnbind(Vdbe * p, int i)
return SQL_MISUSE;
}
if (p->magic != VDBE_MAGIC_RUN || p->pc >= 0) {
- sqlError(p->db, SQL_MISUSE);
sql_log(SQL_MISUSE,
"bind on a busy prepared statement: [%s]", p->zSql);
return SQL_MISUSE;
}
if (i < 1 || i > p->nVar) {
- sqlError(p->db, SQL_RANGE);
return SQL_RANGE;
}
i--;
pVar = &p->aVar[i];
sqlVdbeMemRelease(pVar);
pVar->flags = MEM_Null;
- sqlError(p->db, SQL_OK);
/* If the bit corresponding to this variable in Vdbe.expmask is set, then
* binding a new value to this variable invalidates the current query plan.
@@ -1247,7 +1243,6 @@ bindText(sql_stmt * pStmt, /* The statement to bind against */
rc = sqlVdbeMemSetStr(pVar, zData, nData, 1, xDel);
if (rc == SQL_OK)
rc = sql_bind_type(p, i, "TEXT");
- sqlError(p->db, rc);
rc = sqlApiExit(p->db, rc);
}
} else if (xDel != SQL_STATIC && xDel != SQL_TRANSIENT) {
diff --git a/src/box/sql/vdbeaux.c b/src/box/sql/vdbeaux.c
index 300a44b..38cd195 100644
--- a/src/box/sql/vdbeaux.c
+++ b/src/box/sql/vdbeaux.c
@@ -2373,23 +2373,6 @@ sqlVdbeResetStepResult(Vdbe * p)
}
/*
- * Copy the error code and error message belonging to the VDBE passed
- * as the first argument to its database handle (so that they will be
- * returned by calls to sql_errcode() and sql_errmsg()).
- *
- * This function does not clear the VDBE error code or message, just
- * copies them to the database handle.
- */
-int
-sqlVdbeTransferError(Vdbe * p)
-{
- sql *db = p->db;
- int rc = p->rc;
- sqlError(db, rc);
- return rc;
-}
-
-/*
* Clean up a VDBE after execution but do not delete the VDBE just yet.
* Return the result code.
*
@@ -2418,15 +2401,17 @@ sqlVdbeReset(Vdbe * p)
* instructions yet, leave the main database error information unchanged.
*/
if (p->pc >= 0) {
- sqlVdbeTransferError(p);
if (p->runOnlyOnce)
p->expired = 1;
- } else if (p->rc && p->expired) {
- /* The expired flag was set on the VDBE before the first call
- * to sql_step(). For consistency (since sql_step() was
- * called), set the database error in this case as well.
+ } else {
+ /*
+ * An error should be thrown here if the expired
+ * flag is set on the VDBE flag with the first
+ * call to sql_step(). However, the expired flag
+ * is currently disabled, so this error has been
+ * replaced with assert.
*/
- sqlErrorWithMsg(db, p->rc, NULL);
+ assert(p->rc == 0 || p->expired == 0);
}
/* Reclaim all memory used by the VDBE
diff --git a/test/sql/func-recreate.result b/test/sql/func-recreate.result
index d713292..73fb03c 100644
--- a/test/sql/func-recreate.result
+++ b/test/sql/func-recreate.result
@@ -26,7 +26,8 @@ fiber.sleep(0.1)
...
box.internal.sql_create_function('WAITFOR', 'INT', function (n) require('fiber').sleep(n) return n end)
---
-- error: database is locked
+- error: 'Failed to create function ''WAITFOR'': unable to create function due to
+ active statements'
...
ch:get()
---
--
2.7.4
^ permalink raw reply [flat|nested] 31+ messages in thread
* [tarantool-patches] [PATCH v1 12/12] sql: use diag_set() to set an error in SQL functions
2019-05-05 12:17 [tarantool-patches] [PATCH v1 00/12] sql: set errors in VDBE using diag_set() imeevma
` (10 preceding siblings ...)
2019-05-05 12:17 ` [tarantool-patches] [PATCH v1 11/12] sql: remove sqlError() and remove sqlErrorWithMsg() imeevma
@ 2019-05-05 12:17 ` imeevma
2019-05-15 14:12 ` [tarantool-patches] " n.pettik
11 siblings, 1 reply; 31+ messages in thread
From: imeevma @ 2019-05-05 12:17 UTC (permalink / raw)
To: korablev; +Cc: tarantool-patches
After this patch, all errors in the SQL functions will be set
using diag_set().
Closes #4074
---
src/box/lua/lua_sql.c | 13 +++--
src/box/sql/analyze.c | 6 +--
src/box/sql/func.c | 104 ++++++++++++++++++----------------------
src/box/sql/sqlInt.h | 13 -----
src/box/sql/vdbe.c | 34 +++----------
src/box/sql/vdbeInt.h | 28 ++---------
src/box/sql/vdbeapi.c | 129 +++++---------------------------------------------
src/box/sql/vdbeaux.c | 46 ------------------
src/box/sql/vdbemem.c | 9 ++--
9 files changed, 84 insertions(+), 298 deletions(-)
diff --git a/src/box/lua/lua_sql.c b/src/box/lua/lua_sql.c
index d28045a..afe4732 100644
--- a/src/box/lua/lua_sql.c
+++ b/src/box/lua/lua_sql.c
@@ -77,13 +77,15 @@ lua_sql_call(sql_context *pCtx, int nVal, sql_value **apVal) {
lua_pushboolean(L, sql_value_boolean(param));
break;
default:
- sql_result_error(pCtx, "Unsupported type passed "
- "to Lua", -1);
+ diag_set(ClientError, ER_SQL_EXECUTE, "Unsupported "\
+ "type passed to Lua");
+ pCtx->is_error = true;
goto error;
}
}
if (lua_pcall(L, lua_gettop(L) - 1, 1, 0) != 0){
- sql_result_error(pCtx, lua_tostring(L, -1), -1);
+ diag_set(ClientError, ER_SQL_EXECUTE, lua_tostring(L, -1));
+ pCtx->is_error = true;
goto error;
}
switch(lua_type(L, -1)) {
@@ -101,8 +103,9 @@ lua_sql_call(sql_context *pCtx, int nVal, sql_value **apVal) {
sql_result_null(pCtx);
break;
default:
- sql_result_error(pCtx, "Unsupported type returned from Lua",
- -1);
+ diag_set(ClientError, ER_SQL_EXECUTE, "Unsupported type "\
+ "passed from Lua");
+ pCtx->is_error = true;
goto error;
}
error:
diff --git a/src/box/sql/analyze.c b/src/box/sql/analyze.c
index 0c02050..46ea10e 100644
--- a/src/box/sql/analyze.c
+++ b/src/box/sql/analyze.c
@@ -298,7 +298,7 @@ statInit(sql_context * context, int argc, sql_value ** argv)
db = sql_context_db_handle(context);
p = sqlDbMallocZero(db, n);
if (p == 0) {
- sql_result_error_nomem(context);
+ context->is_error = true;
return;
}
@@ -669,7 +669,7 @@ statGet(sql_context * context, int argc, sql_value ** argv)
char *zRet = sqlMallocZero((p->nKeyCol + 1) * 25);
if (zRet == 0) {
- sql_result_error_nomem(context);
+ context->is_error = true;
return;
}
@@ -715,7 +715,7 @@ statGet(sql_context * context, int argc, sql_value ** argv)
char *zRet = sqlMallocZero(p->nCol * 25);
if (zRet == 0) {
- sql_result_error_nomem(context);
+ context->is_error = true;
} else {
int i;
char *z = zRet;
diff --git a/src/box/sql/func.c b/src/box/sql/func.c
index bb7405e..16c02f1 100644
--- a/src/box/sql/func.c
+++ b/src/box/sql/func.c
@@ -181,13 +181,9 @@ absFunc(sql_context * context, int argc, sql_value ** argv)
i64 iVal = sql_value_int64(argv[0]);
if (iVal < 0) {
if (iVal == SMALLEST_INT64) {
- /* IMP: R-31676-45509 If X is the integer -9223372036854775808
- * then abs(X) throws an integer overflow error since there is no
- * equivalent positive 64-bit two complement value.
- */
- sql_result_error(context,
- "integer overflow",
- -1);
+ diag_set(ClientError, ER_SQL_EXECUTE,
+ "integer overflow");
+ context->is_error = true;
return;
}
iVal = -iVal;
@@ -203,8 +199,7 @@ absFunc(sql_context * context, int argc, sql_value ** argv)
case MP_BOOL: {
diag_set(ClientError, ER_INCONSISTENT_TYPES, "number",
"boolean");
- context->isError = SQL_TARANTOOL_ERROR;
- context->fErrorOrAux = 1;
+ context->is_error = true;
return;
}
default:{
@@ -256,8 +251,7 @@ position_func(struct sql_context *context, int argc, struct Mem **argv)
if (inconsistent_type_arg != NULL) {
diag_set(ClientError, ER_INCONSISTENT_TYPES, "TEXT or BLOB",
mem_type_to_str(inconsistent_type_arg));
- context->isError = SQL_TARANTOOL_ERROR;
- context->fErrorOrAux = 1;
+ context->is_error = true;
return;
}
/*
@@ -267,8 +261,7 @@ position_func(struct sql_context *context, int argc, struct Mem **argv)
if (haystack_type != needle_type) {
diag_set(ClientError, ER_INCONSISTENT_TYPES,
mem_type_to_str(needle), mem_type_to_str(haystack));
- context->isError = SQL_TARANTOOL_ERROR;
- context->fErrorOrAux = 1;
+ context->is_error = true;
return;
}
@@ -513,7 +506,6 @@ roundFunc(sql_context * context, int argc, sql_value ** argv)
{
int n = 0;
double r;
- char *zBuf;
assert(argc == 1 || argc == 2);
if (argc == 2) {
if (sql_value_is_null(argv[1]))
@@ -534,23 +526,17 @@ roundFunc(sql_context * context, int argc, sql_value ** argv)
} else if (n == 0 && r < 0 && (-r) < LARGEST_INT64 - 1) {
r = -(double)((sql_int64) ((-r) + 0.5));
} else {
- zBuf = sql_mprintf("%.*f", n, r);
- if (zBuf == 0) {
- sql_result_error_nomem(context);
- return;
- }
- sqlAtoF(zBuf, &r, sqlStrlen30(zBuf));
- sql_free(zBuf);
+ const char *rounded_value = tt_sprintf("%.*f", n, r);
+ sqlAtoF(rounded_value, &r, sqlStrlen30(rounded_value));
}
sql_result_double(context, r);
}
/*
* Allocate nByte bytes of space using sqlMalloc(). If the
- * allocation fails, call sql_result_error_nomem() to notify
- * the database handle that malloc() has failed and return NULL.
- * If nByte is larger than the maximum string or blob length, then
- * raise an SQL_TOOBIG exception and return NULL.
+ * allocation fails, return NULL. If nByte is larger than the
+ * maximum string or blob length, then raise an error and return
+ * NULL.
*/
static void *
contextMalloc(sql_context * context, i64 nByte)
@@ -561,13 +547,13 @@ contextMalloc(sql_context * context, i64 nByte)
testcase(nByte == db->aLimit[SQL_LIMIT_LENGTH]);
testcase(nByte == db->aLimit[SQL_LIMIT_LENGTH] + 1);
if (nByte > db->aLimit[SQL_LIMIT_LENGTH]) {
- sql_result_error_toobig(context);
+ diag_set(ClientError, ER_SQL_EXECUTE, "string or blob too big");
+ context->is_error = true;
z = 0;
} else {
z = sqlMalloc(nByte);
- if (!z) {
- sql_result_error_nomem(context);
- }
+ if (z == NULL)
+ context->is_error = true;
}
return z;
}
@@ -591,11 +577,11 @@ case_type##ICUFunc(sql_context *context, int argc, sql_value **argv) \
* does not invalidate the _text() pointer. \
*/ \
assert(z2 == (char *)sql_value_text(argv[0])); \
- if (!z2) \
+ if (z2 == NULL) \
return; \
z1 = contextMalloc(context, ((i64) n) + 1); \
- if (!z1) { \
- sql_result_error_nomem(context); \
+ if (z1 == NULL) { \
+ context->is_error = true; \
return; \
} \
UErrorCode status = U_ZERO_ERROR; \
@@ -612,8 +598,8 @@ case_type##ICUFunc(sql_context *context, int argc, sql_value **argv) \
status = U_ZERO_ERROR; \
sql_free(z1); \
z1 = contextMalloc(context, ((i64) len) + 1); \
- if (!z1) { \
- sql_result_error_nomem(context); \
+ if (z1 == NULL) { \
+ context->is_error = true; \
return; \
} \
ucasemap_utf8To##case_type(case_map, z1, len, z2, n, &status); \
@@ -919,8 +905,7 @@ likeFunc(sql_context *context, int argc, sql_value **argv)
mem_type_to_str(argv[1]);
diag_set(ClientError, ER_INCONSISTENT_TYPES, "TEXT",
inconsistent_type);
- context->fErrorOrAux = 1;
- context->isError = SQL_TARANTOOL_ERROR;
+ context->is_error = true;
return;
}
const char *zB = (const char *) sql_value_text(argv[0]);
@@ -937,8 +922,9 @@ likeFunc(sql_context *context, int argc, sql_value **argv)
testcase(nPat == db->aLimit[SQL_LIMIT_LIKE_PATTERN_LENGTH]);
testcase(nPat == db->aLimit[SQL_LIMIT_LIKE_PATTERN_LENGTH] + 1);
if (nPat > db->aLimit[SQL_LIMIT_LIKE_PATTERN_LENGTH]) {
- sql_result_error(context,
- "LIKE pattern is too complex", -1);
+ diag_set(ClientError, ER_SQL_EXECUTE, "LIKE pattern is too "\
+ "complex");
+ context->is_error = true;
return;
}
/* Encoding did not change */
@@ -953,10 +939,10 @@ likeFunc(sql_context *context, int argc, sql_value **argv)
const unsigned char *zEsc = sql_value_text(argv[2]);
if (zEsc == 0)
return;
- const char *const err_msg =
- "ESCAPE expression must be a single character";
if (sql_utf8_char_count(zEsc, sql_value_bytes(argv[2])) != 1) {
- sql_result_error(context, err_msg, -1);
+ diag_set(ClientError, ER_SQL_EXECUTE, "ESCAPE "\
+ "expression must be a single character");
+ context->is_error = true;
return;
}
escape = sqlUtf8Read(&zEsc);
@@ -967,9 +953,9 @@ likeFunc(sql_context *context, int argc, sql_value **argv)
res = sql_utf8_pattern_compare(zB, zA, zB_end, zA_end,
is_like_ci, escape);
if (res == INVALID_PATTERN) {
- const char *const err_msg =
- "LIKE pattern can only contain UTF-8 characters";
- sql_result_error(context, err_msg, -1);
+ diag_set(ClientError, ER_SQL_EXECUTE, "LIKE pattern can only "\
+ "contain UTF-8 characters");
+ context->is_error = true;
return;
}
sql_result_bool(context, res == MATCH);
@@ -1136,8 +1122,8 @@ charFunc(sql_context * context, int argc, sql_value ** argv)
unsigned char *z, *zOut;
int i;
zOut = z = sql_malloc64(argc * 4 + 1);
- if (z == 0) {
- sql_result_error_nomem(context);
+ if (z == NULL) {
+ context->is_error = true;
return;
}
for (i = 0; i < argc; i++) {
@@ -1200,15 +1186,14 @@ static void
zeroblobFunc(sql_context * context, int argc, sql_value ** argv)
{
i64 n;
- int rc;
assert(argc == 1);
UNUSED_PARAMETER(argc);
n = sql_value_int64(argv[0]);
if (n < 0)
n = 0;
- rc = sql_result_zeroblob64(context, n); /* IMP: R-00293-64994 */
- if (rc) {
- sql_result_error_code(context, rc);
+ if (sql_result_zeroblob64(context, n) != SQL_OK) {
+ diag_set(ClientError, ER_SQL_EXECUTE, "string or blob too big");
+ context->is_error = true;
}
}
@@ -1275,14 +1260,16 @@ replaceFunc(sql_context * context, int argc, sql_value ** argv)
testcase(nOut - 1 == db->aLimit[SQL_LIMIT_LENGTH]);
testcase(nOut - 2 == db->aLimit[SQL_LIMIT_LENGTH]);
if (nOut - 1 > db->aLimit[SQL_LIMIT_LENGTH]) {
- sql_result_error_toobig(context);
+ diag_set(ClientError, ER_SQL_EXECUTE, "string "\
+ "or blob too big");
+ context->is_error = true;
sql_free(zOut);
return;
}
zOld = zOut;
zOut = sql_realloc64(zOut, (int)nOut);
if (zOut == 0) {
- sql_result_error_nomem(context);
+ context->is_error = true;
sql_free(zOld);
return;
}
@@ -1605,8 +1592,7 @@ sum_step(struct sql_context *context, int argc, sql_value **argv)
if (mem_apply_numeric_type(argv[0]) != 0) {
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
sql_value_text(argv[0]), "number");
- context->fErrorOrAux = 1;
- context->isError = SQL_TARANTOOL_ERROR;
+ context->is_error = true;
return;
}
type = sql_value_type(argv[0]);
@@ -1632,7 +1618,9 @@ sumFinalize(sql_context * context)
p = sql_aggregate_context(context, 0);
if (p && p->cnt > 0) {
if (p->overflow) {
- sql_result_error(context, "integer overflow", -1);
+ diag_set(ClientError, ER_SQL_EXECUTE, "integer "\
+ "overflow");
+ context->is_error = true;
} else if (p->approx) {
sql_result_double(context, p->rSum);
} else {
@@ -1789,9 +1777,11 @@ groupConcatFinalize(sql_context * context)
pAccum = sql_aggregate_context(context, 0);
if (pAccum) {
if (pAccum->accError == STRACCUM_TOOBIG) {
- sql_result_error_toobig(context);
+ diag_set(ClientError, ER_SQL_EXECUTE, "string or blob "\
+ "too big");
+ context->is_error = true;
} else if (pAccum->accError == STRACCUM_NOMEM) {
- sql_result_error_nomem(context);
+ context->is_error = true;
} else {
sql_result_text(context,
sqlStrAccumFinish(pAccum),
diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
index c757fb5..511f504 100644
--- a/src/box/sql/sqlInt.h
+++ b/src/box/sql/sqlInt.h
@@ -476,19 +476,6 @@ void
sql_result_double(sql_context *, double);
void
-sql_result_error(sql_context *, const char *,
- int);
-
-void
-sql_result_error_toobig(sql_context *);
-
-void
-sql_result_error_nomem(sql_context *);
-
-void
-sql_result_error_code(sql_context *, int);
-
-void
sql_result_int(sql_context *, int);
void
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index 115f22e..a4d82e1 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -1709,22 +1709,12 @@ case OP_Function: {
}
#endif
MemSetTypeFlag(pCtx->pOut, MEM_Null);
- pCtx->fErrorOrAux = 0;
+ pCtx->is_error = false;
(*pCtx->pFunc->xSFunc)(pCtx, pCtx->argc, pCtx->argv);/* IMP: R-24505-23230 */
/* If the function returned an error, throw an exception */
- if (pCtx->fErrorOrAux) {
- if (pCtx->isError) {
- if (pCtx->isError != SQL_TARANTOOL_ERROR) {
- diag_set(ClientError, ER_SQL_EXECUTE,
- sql_value_text(pCtx->pOut));
- }
- rc = SQL_TARANTOOL_ERROR;
- }
- sqlVdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1);
- if (rc != SQL_OK)
- goto abort_due_to_error;
- }
+ if (pCtx->is_error)
+ goto abort_due_to_error;
/* Copy the result of the function into register P3 */
if (pOut->flags & (MEM_Str|MEM_Blob)) {
@@ -4856,9 +4846,6 @@ case OP_Program: { /* jump */
pFrame->pParent = p->pFrame;
pFrame->nChange = p->nChange;
pFrame->nDbChange = p->db->nChange;
- assert(pFrame->pAuxData==0);
- pFrame->pAuxData = p->pAuxData;
- p->pAuxData = 0;
p->nChange = 0;
p->pFrame = pFrame;
p->aMem = aMem = VdbeFrameMem(pFrame);
@@ -5121,21 +5108,12 @@ case OP_AggStep: {
pMem->n++;
sqlVdbeMemInit(&t, db, MEM_Null);
pCtx->pOut = &t;
- pCtx->fErrorOrAux = 0;
+ pCtx->is_error = false;
pCtx->skipFlag = 0;
(pCtx->pFunc->xSFunc)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */
- if (pCtx->fErrorOrAux) {
- if (pCtx->isError) {
- if (pCtx->isError != SQL_TARANTOOL_ERROR) {
- diag_set(ClientError, ER_SQL_EXECUTE,
- sql_value_text(&t));
- }
- rc = SQL_TARANTOOL_ERROR;
- }
+ if (pCtx->is_error) {
sqlVdbeMemRelease(&t);
- assert(rc == SQL_OK || rc == SQL_TARANTOOL_ERROR);
- if (rc != SQL_OK)
- goto abort_due_to_error;
+ goto abort_due_to_error;
} else {
assert(t.flags==MEM_Null);
}
diff --git a/src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h
index 6aadca2..70a0bab 100644
--- a/src/box/sql/vdbeInt.h
+++ b/src/box/sql/vdbeInt.h
@@ -62,9 +62,6 @@ typedef unsigned Bool;
/* Opaque type used by code in vdbesort.c */
typedef struct VdbeSorter VdbeSorter;
-/* Elements of the linked list at Vdbe.pAuxData */
-typedef struct AuxData AuxData;
-
/* Types of VDBE cursors */
#define CURTYPE_TARANTOOL 0
#define CURTYPE_SORTER 1
@@ -161,7 +158,6 @@ struct VdbeFrame {
Mem *aMem; /* Array of memory cells for parent frame */
VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */
void *token; /* Copy of SubProgram.token */
- AuxData *pAuxData; /* Linked list of auxdata allocations */
int nCursor; /* Number of entries in apCsr */
int pc; /* Program Counter in parent (calling) frame */
int nOp; /* Size of aOp array */
@@ -300,21 +296,6 @@ mem_apply_numeric_type(struct Mem *record);
#endif
/*
- * Each auxiliary data pointer stored by a user defined function
- * implementation calling sql_set_auxdata() is stored in an instance
- * of this structure. All such structures associated with a single VM
- * are stored in a linked list headed at Vdbe.pAuxData. All are destroyed
- * when the VM is halted (if not before).
- */
-struct AuxData {
- int iOp; /* Instruction number of OP_Function opcode */
- int iArg; /* Index of function argument. */
- void *pAux; /* Aux data pointer */
- void (*xDelete) (void *); /* Destructor for the aux data */
- AuxData *pNext; /* Next element in list */
-};
-
-/*
* The "context" argument for an installable function. A pointer to an
* instance of this structure is the first argument to the routines used
* implement the SQL functions.
@@ -333,9 +314,12 @@ struct sql_context {
Mem *pMem; /* Memory cell used to store aggregate context */
Vdbe *pVdbe; /* The VM that owns this context */
int iOp; /* Instruction number of OP_Function */
- int isError; /* Error code returned by the function. */
+ /*
+ * True, if an error occurred during the execution of the
+ * function.
+ */
+ bool is_error;
u8 skipFlag; /* Skip accumulator loading if true */
- u8 fErrorOrAux; /* isError!=0 or pVdbe->pAuxData modified */
u8 argc; /* Number of arguments */
sql_value *argv[1]; /* Argument set */
};
@@ -440,7 +424,6 @@ struct Vdbe {
int nFrame; /* Number of frames in pFrame list */
u32 expmask; /* Binding to these vars invalidates VM */
SubProgram *pProgram; /* Linked list of all sub-programs used by VM */
- AuxData *pAuxData; /* Linked list of auxdata allocations */
/* Anonymous savepoint for aborts only */
Savepoint *anonymous_savepoint;
#ifdef SQL_ENABLE_STMT_SCANSTATUS
@@ -472,7 +455,6 @@ u32 sqlVdbeSerialTypeLen(u32);
u32 sqlVdbeSerialType(Mem *, int, u32 *);
u32 sqlVdbeSerialPut(unsigned char *, Mem *, u32);
u32 sqlVdbeSerialGet(const unsigned char *, u32, Mem *);
-void sqlVdbeDeleteAuxData(sql *, AuxData **, int, int);
int sqlVdbeExec(Vdbe *);
int sqlVdbeList(Vdbe *);
diff --git a/src/box/sql/vdbeapi.c b/src/box/sql/vdbeapi.c
index d9dd28f..cf96e2d 100644
--- a/src/box/sql/vdbeapi.c
+++ b/src/box/sql/vdbeapi.c
@@ -319,7 +319,8 @@ setResultStrOrError(sql_context * pCtx, /* Function context */
)
{
if (sqlVdbeMemSetStr(pCtx->pOut, z, n,1, xDel) == SQL_TOOBIG) {
- sql_result_error_toobig(pCtx);
+ diag_set(ClientError, ER_SQL_EXECUTE, "string or blob too big");
+ pCtx->is_error = true;
}
}
@@ -337,8 +338,10 @@ invokeValueDestructor(const void *p, /* Value to destroy */
} else {
xDel((void *)p);
}
- if (pCtx)
- sql_result_error_toobig(pCtx);
+ if (pCtx) {
+ diag_set(ClientError, ER_SQL_EXECUTE, "string or blob too big");
+ pCtx->is_error = true;
+ }
return SQL_TOOBIG;
}
@@ -349,7 +352,8 @@ sql_result_blob(sql_context * pCtx,
{
assert(n >= 0);
if (sqlVdbeMemSetStr(pCtx->pOut, z, n,0, xDel) == SQL_TOOBIG) {
- sql_result_error_toobig(pCtx);
+ diag_set(ClientError, ER_SQL_EXECUTE, "string or blob too big");
+ pCtx->is_error = true;
}
}
@@ -373,14 +377,6 @@ sql_result_double(sql_context * pCtx, double rVal)
}
void
-sql_result_error(sql_context * pCtx, const char *z, int n)
-{
- pCtx->isError = SQL_ERROR;
- pCtx->fErrorOrAux = 1;
- sqlVdbeMemSetStr(pCtx->pOut, z, n, 1, SQL_TRANSIENT);
-}
-
-void
sql_result_int(sql_context * pCtx, int iVal)
{
sqlVdbeMemSetInt64(pCtx->pOut, (i64) iVal);
@@ -449,37 +445,6 @@ sql_result_zeroblob64(sql_context * pCtx, u64 n)
return SQL_OK;
}
-void
-sql_result_error_code(sql_context * pCtx, int errCode)
-{
- pCtx->isError = errCode;
- pCtx->fErrorOrAux = 1;
- if (pCtx->pOut->flags & MEM_Null) {
- sqlVdbeMemSetStr(pCtx->pOut, sqlErrStr(errCode), -1, 1,
- SQL_STATIC);
- }
-}
-
-/* Force an SQL_TOOBIG error. */
-void
-sql_result_error_toobig(sql_context * pCtx)
-{
- pCtx->isError = SQL_TOOBIG;
- pCtx->fErrorOrAux = 1;
- sqlVdbeMemSetStr(pCtx->pOut, "string or blob too big", -1, 1,
- SQL_STATIC);
-}
-
-/* An SQL_NOMEM error. */
-void
-sql_result_error_nomem(sql_context * pCtx)
-{
- sqlVdbeMemSetNull(pCtx->pOut);
- pCtx->isError = SQL_NOMEM;
- pCtx->fErrorOrAux = 1;
- sqlOomFault(pCtx->pOut->db);
-}
-
/*
* Execute the statement pStmt, either until a row of data is ready, the
* statement is completely executed or an error occurs.
@@ -677,13 +642,10 @@ sqlInvalidFunction(sql_context * context, /* The function calling context */
)
{
const char *zName = context->pFunc->zName;
- char *zErr;
UNUSED_PARAMETER2(NotUsed, NotUsed2);
- zErr =
- sql_mprintf
- ("unable to use function %s in the requested context", zName);
- sql_result_error(context, zErr, -1);
- sql_free(zErr);
+ const char *err = "unable to use function %s in the requested context";
+ diag_set(ClientError, ER_SQL_EXECUTE, tt_sprintf(err, zName));
+ context->is_error = true;
}
/*
@@ -727,75 +689,6 @@ sql_aggregate_context(sql_context * p, int nByte)
}
/*
- * Return the auxiliary data pointer, if any, for the iArg'th argument to
- * the user-function defined by pCtx.
- */
-void *
-sql_get_auxdata(sql_context * pCtx, int iArg)
-{
- AuxData *pAuxData;
-
- if (pCtx->pVdbe == 0)
- return 0;
-
- for (pAuxData = pCtx->pVdbe->pAuxData; pAuxData;
- pAuxData = pAuxData->pNext) {
- if (pAuxData->iOp == pCtx->iOp && pAuxData->iArg == iArg)
- break;
- }
-
- return (pAuxData ? pAuxData->pAux : 0);
-}
-
-/*
- * Set the auxiliary data pointer and delete function, for the iArg'th
- * argument to the user-function defined by pCtx. Any previous value is
- * deleted by calling the delete function specified when it was set.
- */
-void
-sql_set_auxdata(sql_context * pCtx,
- int iArg, void *pAux, void (*xDelete) (void *)
- )
-{
- AuxData *pAuxData;
- Vdbe *pVdbe = pCtx->pVdbe;
-
- if (iArg < 0)
- goto failed;
- if (pVdbe == 0)
- goto failed;
-
- for (pAuxData = pVdbe->pAuxData; pAuxData; pAuxData = pAuxData->pNext) {
- if (pAuxData->iOp == pCtx->iOp && pAuxData->iArg == iArg)
- break;
- }
- if (pAuxData == 0) {
- pAuxData = sqlDbMallocZero(pVdbe->db, sizeof(AuxData));
- if (!pAuxData)
- goto failed;
- pAuxData->iOp = pCtx->iOp;
- pAuxData->iArg = iArg;
- pAuxData->pNext = pVdbe->pAuxData;
- pVdbe->pAuxData = pAuxData;
- if (pCtx->fErrorOrAux == 0) {
- pCtx->isError = 0;
- pCtx->fErrorOrAux = 1;
- }
- } else if (pAuxData->xDelete) {
- pAuxData->xDelete(pAuxData->pAux);
- }
-
- pAuxData->pAux = pAux;
- pAuxData->xDelete = xDelete;
- return;
-
- failed:
- if (xDelete) {
- xDelete(pAux);
- }
-}
-
-/*
* Return the number of columns in the result set for the statement pStmt.
*/
int
diff --git a/src/box/sql/vdbeaux.c b/src/box/sql/vdbeaux.c
index 38cd195..697dffd 100644
--- a/src/box/sql/vdbeaux.c
+++ b/src/box/sql/vdbeaux.c
@@ -1388,7 +1388,6 @@ sqlVdbeFrameDelete(VdbeFrame * p)
sqlVdbeFreeCursor(p->v, apCsr[i]);
}
releaseMemArray(aMem, p->nChildMem);
- sqlVdbeDeleteAuxData(p->v->db, &p->pAuxData, -1, 0);
sqlDbFree(p->v->db, p);
}
@@ -1907,9 +1906,6 @@ sqlVdbeFrameRestore(VdbeFrame * pFrame)
v->nCursor = pFrame->nCursor;
v->nChange = pFrame->nChange;
v->db->nChange = pFrame->nDbChange;
- sqlVdbeDeleteAuxData(v->db, &v->pAuxData, -1, 0);
- v->pAuxData = pFrame->pAuxData;
- pFrame->pAuxData = 0;
return pFrame->pc;
}
@@ -1953,11 +1949,6 @@ closeCursorsAndFree(Vdbe * p)
p->pDelFrame = pDel->pParent;
sqlVdbeFrameDelete(pDel);
}
-
- /* Delete any auxdata allocations made by the VM */
- if (p->pAuxData)
- sqlVdbeDeleteAuxData(p->db, &p->pAuxData, -1, 0);
- assert(p->pAuxData == 0);
}
/*
@@ -2480,43 +2471,6 @@ sqlVdbeFinalize(Vdbe * p)
}
/*
- * If parameter iOp is less than zero, then invoke the destructor for
- * all auxiliary data pointers currently cached by the VM passed as
- * the first argument.
- *
- * Or, if iOp is greater than or equal to zero, then the destructor is
- * only invoked for those auxiliary data pointers created by the user
- * function invoked by the OP_Function opcode at instruction iOp of
- * VM pVdbe, and only then if:
- *
- * * the associated function parameter is the 32nd or later (counting
- * from left to right), or
- *
- * * the corresponding bit in argument mask is clear (where the first
- * function parameter corresponds to bit 0 etc.).
- */
-void
-sqlVdbeDeleteAuxData(sql * db, AuxData ** pp, int iOp, int mask)
-{
- while (*pp) {
- AuxData *pAux = *pp;
- if ((iOp < 0)
- || (pAux->iOp == iOp
- && (pAux->iArg > 31 || !(mask & MASKBIT32(pAux->iArg))))
- ) {
- testcase(pAux->iArg == 31);
- if (pAux->xDelete) {
- pAux->xDelete(pAux->pAux);
- }
- *pp = pAux->pNext;
- sqlDbFree(db, pAux);
- } else {
- pp = &pAux->pNext;
- }
- }
-}
-
-/*
* Free all memory associated with the Vdbe passed as the second argument,
* except for object itself, which is preserved.
*
diff --git a/src/box/sql/vdbemem.c b/src/box/sql/vdbemem.c
index f73ea0a..ce0c641 100644
--- a/src/box/sql/vdbemem.c
+++ b/src/box/sql/vdbemem.c
@@ -321,7 +321,6 @@ sqlVdbeMemStringify(Mem * pMem, u8 bForce)
int
sqlVdbeMemFinalize(Mem * pMem, FuncDef * pFunc)
{
- int rc = SQL_OK;
if (ALWAYS(pFunc && pFunc->xFinalize)) {
sql_context ctx;
Mem t;
@@ -338,9 +337,9 @@ sqlVdbeMemFinalize(Mem * pMem, FuncDef * pFunc)
if (pMem->szMalloc > 0)
sqlDbFree(pMem->db, pMem->zMalloc);
memcpy(pMem, &t, sizeof(t));
- rc = ctx.isError;
+ return ctx.is_error ? SQL_TARANTOOL_ERROR : SQL_OK;
}
- return rc;
+ return SQL_OK;
}
/*
@@ -1281,7 +1280,7 @@ valueFromFunction(sql * db, /* The database connection */
ctx.pOut = pVal;
ctx.pFunc = pFunc;
pFunc->xSFunc(&ctx, nVal, apVal);
- assert(!ctx.isError);
+ assert(!ctx.is_error);
sql_value_apply_type(pVal, type);
assert(rc == SQL_OK);
@@ -1486,7 +1485,7 @@ recordFunc(sql_context * context, int argc, sql_value ** argv)
nRet = 1 + nSerial + nVal;
aRet = sqlDbMallocRawNN(db, nRet);
if (aRet == 0) {
- sql_result_error_nomem(context);
+ context->is_error = true;
} else {
aRet[0] = nSerial + 1;
putVarint32(&aRet[1], iSerial);
--
2.7.4
^ permalink raw reply [flat|nested] 31+ messages in thread
* [tarantool-patches] Re: [PATCH v1 12/12] sql: use diag_set() to set an error in SQL functions
2019-05-05 12:17 ` [tarantool-patches] [PATCH v1 12/12] sql: use diag_set() to set an error in SQL functions imeevma
@ 2019-05-15 14:12 ` n.pettik
2019-05-25 9:45 ` Mergen Imeev
0 siblings, 1 reply; 31+ messages in thread
From: n.pettik @ 2019-05-15 14:12 UTC (permalink / raw)
To: tarantool-patches; +Cc: Imeev Mergen
> After this patch, all errors in the SQL functions will be set
> using diag_set().
>
> Closes #4074
> ---
> src/box/lua/lua_sql.c | 13 +++--
> src/box/sql/analyze.c | 6 +--
> src/box/sql/func.c | 104 ++++++++++++++++++----------------------
> src/box/sql/sqlInt.h | 13 -----
> src/box/sql/vdbe.c | 34 +++----------
> src/box/sql/vdbeInt.h | 28 ++---------
> src/box/sql/vdbeapi.c | 129 +++++---------------------------------------------
> src/box/sql/vdbeaux.c | 46 ------------------
> src/box/sql/vdbemem.c | 9 ++--
> 9 files changed, 84 insertions(+), 298 deletions(-)
>
> diff --git a/src/box/lua/lua_sql.c b/src/box/lua/lua_sql.c
> index d28045a..afe4732 100644
> --- a/src/box/lua/lua_sql.c
> +++ b/src/box/lua/lua_sql.c
> @@ -77,13 +77,15 @@ lua_sql_call(sql_context *pCtx, int nVal, sql_value **apVal) {
> lua_pushboolean(L, sql_value_boolean(param));
> break;
> default:
> - sql_result_error(pCtx, "Unsupported type passed "
> - "to Lua", -1);
Please, remove sql_result_error at all: I grepped several
usages among dead code.
> + diag_set(ClientError, ER_SQL_EXECUTE, "Unsupported "\
> + "type passed to Lua");
> + pCtx->is_error = true;
> goto error;
> }
>
> diff --git a/src/box/sql/func.c b/src/box/sql/func.c
> index bb7405e..16c02f1 100644
> --- a/src/box/sql/func.c
> +++ b/src/box/sql/func.c
> @@ -181,13 +181,9 @@ absFunc(sql_context * context, int argc, sql_value ** argv)
> i64 iVal = sql_value_int64(argv[0]);
> if (iVal < 0) {
> if (iVal == SMALLEST_INT64) {
> - /* IMP: R-31676-45509 If X is the integer -9223372036854775808
> - * then abs(X) throws an integer overflow error since there is no
> - * equivalent positive 64-bit two complement value.
> - */
> - sql_result_error(context,
> - "integer overflow",
> - -1);
> + diag_set(ClientError, ER_SQL_EXECUTE,
> + "integer overflow”);
-> integer is overflowed.
> + context->is_error = true;
> return;
> }
> iVal = -iVal;
>
>
>
> @@ -591,11 +577,11 @@ case_type##ICUFunc(sql_context *context, int argc, sql_value **argv) \
> * does not invalidate the _text() pointer. \
> */ \
> assert(z2 == (char *)sql_value_text(argv[0])); \
> - if (!z2) \
> + if (z2 == NULL) \
> return; \
Redundant diff.
> src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h
> index 6aadca2..70a0bab 100644
> --- a/src/box/sql/vdbeInt.h
> +++ b/src/box/sql/vdbeInt.h
>
> @@ -300,21 +296,6 @@ mem_apply_numeric_type(struct Mem *record);
> #endif
>
>
> -/*
> * The "context" argument for an installable function. A pointer to an
> * instance of this structure is the first argument to the routines used
> * implement the SQL functions.
> @@ -333,9 +314,12 @@ struct sql_context {
> Mem *pMem; /* Memory cell used to store aggregate context */
> Vdbe *pVdbe; /* The VM that owns this context */
> int iOp; /* Instruction number of OP_Function */
> - int isError; /* Error code returned by the function. */
> + /*
> + * True, if an error occurred during the execution of the
> + * function.
> + */
> + bool is_error;
I’d better use is_abotred name.
> diff --git a/src/box/sql/vdbemem.c b/src/box/sql/vdbemem.c
> index f73ea0a..ce0c641 100644
> --- a/src/box/sql/vdbemem.c
> +++ b/src/box/sql/vdbemem.c
> @@ -321,7 +321,6 @@ sqlVdbeMemStringify(Mem * pMem, u8 bForce)
> int
> sqlVdbeMemFinalize(Mem * pMem, FuncDef * pFunc)
> {
> - int rc = SQL_OK;
> if (ALWAYS(pFunc && pFunc->xFinalize)) {
> sql_context ctx;
> Mem t;
> @@ -338,9 +337,9 @@ sqlVdbeMemFinalize(Mem * pMem, FuncDef * pFunc)
> if (pMem->szMalloc > 0)
> sqlDbFree(pMem->db, pMem->zMalloc);
> memcpy(pMem, &t, sizeof(t));
> - rc = ctx.isError;
> + return ctx.is_error ? SQL_TARANTOOL_ERROR : SQL_OK;
> }
> - return rc;
> + return SQL_OK;
Return 0/-1
^ permalink raw reply [flat|nested] 31+ messages in thread
* [tarantool-patches] Re: [PATCH v1 12/12] sql: use diag_set() to set an error in SQL functions
2019-05-15 14:12 ` [tarantool-patches] " n.pettik
@ 2019-05-25 9:45 ` Mergen Imeev
2019-05-25 10:36 ` Imeev Mergen
0 siblings, 1 reply; 31+ messages in thread
From: Mergen Imeev @ 2019-05-25 9:45 UTC (permalink / raw)
To: n.pettik; +Cc: tarantool-patches
I moved this patch to the position before "sql: set errors
in VDBE using diag_set()". New patch below.
On Wed, May 15, 2019 at 05:12:09PM +0300, n.pettik wrote:
>
> > After this patch, all errors in the SQL functions will be set
> > using diag_set().
> >
> > Closes #4074
> > ---
> > src/box/lua/lua_sql.c | 13 +++--
> > src/box/sql/analyze.c | 6 +--
> > src/box/sql/func.c | 104 ++++++++++++++++++----------------------
> > src/box/sql/sqlInt.h | 13 -----
> > src/box/sql/vdbe.c | 34 +++----------
> > src/box/sql/vdbeInt.h | 28 ++---------
> > src/box/sql/vdbeapi.c | 129 +++++---------------------------------------------
> > src/box/sql/vdbeaux.c | 46 ------------------
> > src/box/sql/vdbemem.c | 9 ++--
> > 9 files changed, 84 insertions(+), 298 deletions(-)
> >
> > diff --git a/src/box/lua/lua_sql.c b/src/box/lua/lua_sql.c
> > index d28045a..afe4732 100644
> > --- a/src/box/lua/lua_sql.c
> > +++ b/src/box/lua/lua_sql.c
> > @@ -77,13 +77,15 @@ lua_sql_call(sql_context *pCtx, int nVal, sql_value **apVal) {
> > lua_pushboolean(L, sql_value_boolean(param));
> > break;
> > default:
> > - sql_result_error(pCtx, "Unsupported type passed "
> > - "to Lua", -1);
>
> Please, remove sql_result_error at all: I grepped several
> usages among dead code.
>
Fixed.
> > + diag_set(ClientError, ER_SQL_EXECUTE, "Unsupported "\
> > + "type passed to Lua");
> > + pCtx->is_error = true;
> > goto error;
> > }
> >
> > diff --git a/src/box/sql/func.c b/src/box/sql/func.c
> > index bb7405e..16c02f1 100644
> > --- a/src/box/sql/func.c
> > +++ b/src/box/sql/func.c
> > @@ -181,13 +181,9 @@ absFunc(sql_context * context, int argc, sql_value ** argv)
> > i64 iVal = sql_value_int64(argv[0]);
> > if (iVal < 0) {
> > if (iVal == SMALLEST_INT64) {
> > - /* IMP: R-31676-45509 If X is the integer -9223372036854775808
> > - * then abs(X) throws an integer overflow error since there is no
> > - * equivalent positive 64-bit two complement value.
> > - */
> > - sql_result_error(context,
> > - "integer overflow",
> > - -1);
> > + diag_set(ClientError, ER_SQL_EXECUTE,
> > + "integer overflow”);
>
> -> integer is overflowed.
>
Fixed.
> > + context->is_error = true;
> > return;
> > }
> > iVal = -iVal;
> >
> >
> >
> > @@ -591,11 +577,11 @@ case_type##ICUFunc(sql_context *context, int argc, sql_value **argv) \
> > * does not invalidate the _text() pointer. \
> > */ \
> > assert(z2 == (char *)sql_value_text(argv[0])); \
> > - if (!z2) \
> > + if (z2 == NULL) \
> > return; \
>
> Redundant diff.
>
Fixed.
> > src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h
> > index 6aadca2..70a0bab 100644
> > --- a/src/box/sql/vdbeInt.h
> > +++ b/src/box/sql/vdbeInt.h
> >
> > @@ -300,21 +296,6 @@ mem_apply_numeric_type(struct Mem *record);
> > #endif
> >
> >
> > -/*
> > * The "context" argument for an installable function. A pointer to an
> > * instance of this structure is the first argument to the routines used
> > * implement the SQL functions.
> > @@ -333,9 +314,12 @@ struct sql_context {
> > Mem *pMem; /* Memory cell used to store aggregate context */
> > Vdbe *pVdbe; /* The VM that owns this context */
> > int iOp; /* Instruction number of OP_Function */
> > - int isError; /* Error code returned by the function. */
> > + /*
> > + * True, if an error occurred during the execution of the
> > + * function.
> > + */
> > + bool is_error;
>
> I’d better use is_abotred name.
>
FIxed. Renamed to is_aborted.
> > diff --git a/src/box/sql/vdbemem.c b/src/box/sql/vdbemem.c
> > index f73ea0a..ce0c641 100644
> > --- a/src/box/sql/vdbemem.c
> > +++ b/src/box/sql/vdbemem.c
> > @@ -321,7 +321,6 @@ sqlVdbeMemStringify(Mem * pMem, u8 bForce)
> > int
> > sqlVdbeMemFinalize(Mem * pMem, FuncDef * pFunc)
> > {
> > - int rc = SQL_OK;
> > if (ALWAYS(pFunc && pFunc->xFinalize)) {
> > sql_context ctx;
> > Mem t;
> > @@ -338,9 +337,9 @@ sqlVdbeMemFinalize(Mem * pMem, FuncDef * pFunc)
> > if (pMem->szMalloc > 0)
> > sqlDbFree(pMem->db, pMem->zMalloc);
> > memcpy(pMem, &t, sizeof(t));
> > - rc = ctx.isError;
> > + return ctx.is_error ? SQL_TARANTOOL_ERROR : SQL_OK;
> > }
> > - return rc;
> > + return SQL_OK;
>
> Return 0/-1
>
It is fixed in one of following patches.
New patch:
From bb66ac8360ee312cf8d2047143139bb46441ddf0 Mon Sep 17 00:00:00 2001
Date: Sat, 27 Apr 2019 21:17:19 +0300
Subject: [PATCH] sql: use diag_set() to set an error in SQL functions
After this patch, all errors in the SQL functions will be set
using diag_set().
Closes #4074
diff --git a/src/box/lua/lua_sql.c b/src/box/lua/lua_sql.c
index 36b75ff..529ee59 100644
--- a/src/box/lua/lua_sql.c
+++ b/src/box/lua/lua_sql.c
@@ -77,13 +77,15 @@ lua_sql_call(sql_context *pCtx, int nVal, sql_value **apVal) {
lua_pushboolean(L, sql_value_boolean(param));
break;
default:
- sql_result_error(pCtx, "Unsupported type passed "
- "to Lua", -1);
+ diag_set(ClientError, ER_SQL_EXECUTE, "Unsupported "\
+ "type passed to Lua");
+ pCtx->is_aborted = true;
goto error;
}
}
if (lua_pcall(L, lua_gettop(L) - 1, 1, 0) != 0){
- sql_result_error(pCtx, lua_tostring(L, -1), -1);
+ diag_set(ClientError, ER_SQL_EXECUTE, lua_tostring(L, -1));
+ pCtx->is_aborted = true;
goto error;
}
switch(lua_type(L, -1)) {
@@ -101,8 +103,9 @@ lua_sql_call(sql_context *pCtx, int nVal, sql_value **apVal) {
sql_result_null(pCtx);
break;
default:
- sql_result_error(pCtx, "Unsupported type returned from Lua",
- -1);
+ diag_set(ClientError, ER_SQL_EXECUTE, "Unsupported type "\
+ "passed from Lua");
+ pCtx->is_aborted = true;
goto error;
}
error:
diff --git a/src/box/sql/analyze.c b/src/box/sql/analyze.c
index d2d29c5..9795429 100644
--- a/src/box/sql/analyze.c
+++ b/src/box/sql/analyze.c
@@ -298,7 +298,7 @@ statInit(sql_context * context, int argc, sql_value ** argv)
db = sql_context_db_handle(context);
p = sqlDbMallocZero(db, n);
if (p == 0) {
- sql_result_error_nomem(context);
+ context->is_aborted = true;
return;
}
@@ -669,7 +669,7 @@ statGet(sql_context * context, int argc, sql_value ** argv)
char *zRet = sqlMallocZero((p->nKeyCol + 1) * 25);
if (zRet == 0) {
- sql_result_error_nomem(context);
+ context->is_aborted = true;
return;
}
@@ -715,7 +715,7 @@ statGet(sql_context * context, int argc, sql_value ** argv)
char *zRet = sqlMallocZero(p->nCol * 25);
if (zRet == 0) {
- sql_result_error_nomem(context);
+ context->is_aborted = true;
} else {
int i;
char *z = zRet;
diff --git a/src/box/sql/date.c b/src/box/sql/date.c
index 07a57ab..6d3a2b0 100644
--- a/src/box/sql/date.c
+++ b/src/box/sql/date.c
@@ -617,7 +617,8 @@ localtimeOffset(DateTime * p, /* Date at which to calculate offset */
computeJD(&x);
t = (time_t) (x.iJD / 1000 - 21086676 * (i64) 10000);
if (osLocaltime(&t, &sLocal)) {
- sql_result_error(pCtx, "local time unavailable", -1);
+ diag_set(ClientError, ER_SQL_EXECUTE, "local time unavailable");
+ pCtx->is_aborted = true;
*pRc = SQL_ERROR;
return 0;
}
@@ -1108,12 +1109,13 @@ strftimeFunc(sql_context * context, int argc, sql_value ** argv)
if (n < sizeof(zBuf)) {
z = zBuf;
} else if (n > (u64) db->aLimit[SQL_LIMIT_LENGTH]) {
- sql_result_error_toobig(context);
+ diag_set(ClientError, ER_SQL_EXECUTE, "string or blob too big");
+ context->is_aborted = true;
return;
} else {
z = sqlDbMallocRawNN(db, (int)n);
if (z == 0) {
- sql_result_error_nomem(context);
+ context->is_aborted = true;
return;
}
}
diff --git a/src/box/sql/func.c b/src/box/sql/func.c
index bb7405e..593aa94 100644
--- a/src/box/sql/func.c
+++ b/src/box/sql/func.c
@@ -181,13 +181,9 @@ absFunc(sql_context * context, int argc, sql_value ** argv)
i64 iVal = sql_value_int64(argv[0]);
if (iVal < 0) {
if (iVal == SMALLEST_INT64) {
- /* IMP: R-31676-45509 If X is the integer -9223372036854775808
- * then abs(X) throws an integer overflow error since there is no
- * equivalent positive 64-bit two complement value.
- */
- sql_result_error(context,
- "integer overflow",
- -1);
+ diag_set(ClientError, ER_SQL_EXECUTE,
+ "integer is overflowed");
+ context->is_aborted = true;
return;
}
iVal = -iVal;
@@ -203,8 +199,7 @@ absFunc(sql_context * context, int argc, sql_value ** argv)
case MP_BOOL: {
diag_set(ClientError, ER_INCONSISTENT_TYPES, "number",
"boolean");
- context->isError = SQL_TARANTOOL_ERROR;
- context->fErrorOrAux = 1;
+ context->is_aborted = true;
return;
}
default:{
@@ -256,8 +251,7 @@ position_func(struct sql_context *context, int argc, struct Mem **argv)
if (inconsistent_type_arg != NULL) {
diag_set(ClientError, ER_INCONSISTENT_TYPES, "TEXT or BLOB",
mem_type_to_str(inconsistent_type_arg));
- context->isError = SQL_TARANTOOL_ERROR;
- context->fErrorOrAux = 1;
+ context->is_aborted = true;
return;
}
/*
@@ -267,8 +261,7 @@ position_func(struct sql_context *context, int argc, struct Mem **argv)
if (haystack_type != needle_type) {
diag_set(ClientError, ER_INCONSISTENT_TYPES,
mem_type_to_str(needle), mem_type_to_str(haystack));
- context->isError = SQL_TARANTOOL_ERROR;
- context->fErrorOrAux = 1;
+ context->is_aborted = true;
return;
}
@@ -513,7 +506,6 @@ roundFunc(sql_context * context, int argc, sql_value ** argv)
{
int n = 0;
double r;
- char *zBuf;
assert(argc == 1 || argc == 2);
if (argc == 2) {
if (sql_value_is_null(argv[1]))
@@ -534,23 +526,17 @@ roundFunc(sql_context * context, int argc, sql_value ** argv)
} else if (n == 0 && r < 0 && (-r) < LARGEST_INT64 - 1) {
r = -(double)((sql_int64) ((-r) + 0.5));
} else {
- zBuf = sql_mprintf("%.*f", n, r);
- if (zBuf == 0) {
- sql_result_error_nomem(context);
- return;
- }
- sqlAtoF(zBuf, &r, sqlStrlen30(zBuf));
- sql_free(zBuf);
+ const char *rounded_value = tt_sprintf("%.*f", n, r);
+ sqlAtoF(rounded_value, &r, sqlStrlen30(rounded_value));
}
sql_result_double(context, r);
}
/*
* Allocate nByte bytes of space using sqlMalloc(). If the
- * allocation fails, call sql_result_error_nomem() to notify
- * the database handle that malloc() has failed and return NULL.
- * If nByte is larger than the maximum string or blob length, then
- * raise an SQL_TOOBIG exception and return NULL.
+ * allocation fails, return NULL. If nByte is larger than the
+ * maximum string or blob length, then raise an error and return
+ * NULL.
*/
static void *
contextMalloc(sql_context * context, i64 nByte)
@@ -561,13 +547,13 @@ contextMalloc(sql_context * context, i64 nByte)
testcase(nByte == db->aLimit[SQL_LIMIT_LENGTH]);
testcase(nByte == db->aLimit[SQL_LIMIT_LENGTH] + 1);
if (nByte > db->aLimit[SQL_LIMIT_LENGTH]) {
- sql_result_error_toobig(context);
+ diag_set(ClientError, ER_SQL_EXECUTE, "string or blob too big");
+ context->is_aborted = true;
z = 0;
} else {
z = sqlMalloc(nByte);
- if (!z) {
- sql_result_error_nomem(context);
- }
+ if (z == NULL)
+ context->is_aborted = true;
}
return z;
}
@@ -594,8 +580,8 @@ case_type##ICUFunc(sql_context *context, int argc, sql_value **argv) \
if (!z2) \
return; \
z1 = contextMalloc(context, ((i64) n) + 1); \
- if (!z1) { \
- sql_result_error_nomem(context); \
+ if (z1 == NULL) { \
+ context->is_aborted = true; \
return; \
} \
UErrorCode status = U_ZERO_ERROR; \
@@ -612,8 +598,8 @@ case_type##ICUFunc(sql_context *context, int argc, sql_value **argv) \
status = U_ZERO_ERROR; \
sql_free(z1); \
z1 = contextMalloc(context, ((i64) len) + 1); \
- if (!z1) { \
- sql_result_error_nomem(context); \
+ if (z1 == NULL) { \
+ context->is_aborted = true; \
return; \
} \
ucasemap_utf8To##case_type(case_map, z1, len, z2, n, &status); \
@@ -919,8 +905,7 @@ likeFunc(sql_context *context, int argc, sql_value **argv)
mem_type_to_str(argv[1]);
diag_set(ClientError, ER_INCONSISTENT_TYPES, "TEXT",
inconsistent_type);
- context->fErrorOrAux = 1;
- context->isError = SQL_TARANTOOL_ERROR;
+ context->is_aborted = true;
return;
}
const char *zB = (const char *) sql_value_text(argv[0]);
@@ -937,8 +922,9 @@ likeFunc(sql_context *context, int argc, sql_value **argv)
testcase(nPat == db->aLimit[SQL_LIMIT_LIKE_PATTERN_LENGTH]);
testcase(nPat == db->aLimit[SQL_LIMIT_LIKE_PATTERN_LENGTH] + 1);
if (nPat > db->aLimit[SQL_LIMIT_LIKE_PATTERN_LENGTH]) {
- sql_result_error(context,
- "LIKE pattern is too complex", -1);
+ diag_set(ClientError, ER_SQL_EXECUTE, "LIKE pattern is too "\
+ "complex");
+ context->is_aborted = true;
return;
}
/* Encoding did not change */
@@ -953,10 +939,10 @@ likeFunc(sql_context *context, int argc, sql_value **argv)
const unsigned char *zEsc = sql_value_text(argv[2]);
if (zEsc == 0)
return;
- const char *const err_msg =
- "ESCAPE expression must be a single character";
if (sql_utf8_char_count(zEsc, sql_value_bytes(argv[2])) != 1) {
- sql_result_error(context, err_msg, -1);
+ diag_set(ClientError, ER_SQL_EXECUTE, "ESCAPE "\
+ "expression must be a single character");
+ context->is_aborted = true;
return;
}
escape = sqlUtf8Read(&zEsc);
@@ -967,9 +953,9 @@ likeFunc(sql_context *context, int argc, sql_value **argv)
res = sql_utf8_pattern_compare(zB, zA, zB_end, zA_end,
is_like_ci, escape);
if (res == INVALID_PATTERN) {
- const char *const err_msg =
- "LIKE pattern can only contain UTF-8 characters";
- sql_result_error(context, err_msg, -1);
+ diag_set(ClientError, ER_SQL_EXECUTE, "LIKE pattern can only "\
+ "contain UTF-8 characters");
+ context->is_aborted = true;
return;
}
sql_result_bool(context, res == MATCH);
@@ -1136,8 +1122,8 @@ charFunc(sql_context * context, int argc, sql_value ** argv)
unsigned char *z, *zOut;
int i;
zOut = z = sql_malloc64(argc * 4 + 1);
- if (z == 0) {
- sql_result_error_nomem(context);
+ if (z == NULL) {
+ context->is_aborted = true;
return;
}
for (i = 0; i < argc; i++) {
@@ -1200,15 +1186,14 @@ static void
zeroblobFunc(sql_context * context, int argc, sql_value ** argv)
{
i64 n;
- int rc;
assert(argc == 1);
UNUSED_PARAMETER(argc);
n = sql_value_int64(argv[0]);
if (n < 0)
n = 0;
- rc = sql_result_zeroblob64(context, n); /* IMP: R-00293-64994 */
- if (rc) {
- sql_result_error_code(context, rc);
+ if (sql_result_zeroblob64(context, n) != SQL_OK) {
+ diag_set(ClientError, ER_SQL_EXECUTE, "string or blob too big");
+ context->is_aborted = true;
}
}
@@ -1275,14 +1260,16 @@ replaceFunc(sql_context * context, int argc, sql_value ** argv)
testcase(nOut - 1 == db->aLimit[SQL_LIMIT_LENGTH]);
testcase(nOut - 2 == db->aLimit[SQL_LIMIT_LENGTH]);
if (nOut - 1 > db->aLimit[SQL_LIMIT_LENGTH]) {
- sql_result_error_toobig(context);
+ diag_set(ClientError, ER_SQL_EXECUTE, "string "\
+ "or blob too big");
+ context->is_aborted = true;
sql_free(zOut);
return;
}
zOld = zOut;
zOut = sql_realloc64(zOut, (int)nOut);
if (zOut == 0) {
- sql_result_error_nomem(context);
+ context->is_aborted = true;
sql_free(zOld);
return;
}
@@ -1605,8 +1592,7 @@ sum_step(struct sql_context *context, int argc, sql_value **argv)
if (mem_apply_numeric_type(argv[0]) != 0) {
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
sql_value_text(argv[0]), "number");
- context->fErrorOrAux = 1;
- context->isError = SQL_TARANTOOL_ERROR;
+ context->is_aborted = true;
return;
}
type = sql_value_type(argv[0]);
@@ -1632,7 +1618,9 @@ sumFinalize(sql_context * context)
p = sql_aggregate_context(context, 0);
if (p && p->cnt > 0) {
if (p->overflow) {
- sql_result_error(context, "integer overflow", -1);
+ diag_set(ClientError, ER_SQL_EXECUTE, "integer "\
+ "overflow");
+ context->is_aborted = true;
} else if (p->approx) {
sql_result_double(context, p->rSum);
} else {
@@ -1789,9 +1777,11 @@ groupConcatFinalize(sql_context * context)
pAccum = sql_aggregate_context(context, 0);
if (pAccum) {
if (pAccum->accError == STRACCUM_TOOBIG) {
- sql_result_error_toobig(context);
+ diag_set(ClientError, ER_SQL_EXECUTE, "string or blob "\
+ "too big");
+ context->is_aborted = true;
} else if (pAccum->accError == STRACCUM_NOMEM) {
- sql_result_error_nomem(context);
+ context->is_aborted = true;
} else {
sql_result_text(context,
sqlStrAccumFinish(pAccum),
diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
index 3981fbf..9c0659b 100644
--- a/src/box/sql/sqlInt.h
+++ b/src/box/sql/sqlInt.h
@@ -476,19 +476,6 @@ void
sql_result_double(sql_context *, double);
void
-sql_result_error(sql_context *, const char *,
- int);
-
-void
-sql_result_error_toobig(sql_context *);
-
-void
-sql_result_error_nomem(sql_context *);
-
-void
-sql_result_error_code(sql_context *, int);
-
-void
sql_result_int(sql_context *, int);
void
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index 1559f01..7d85959 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -1717,17 +1717,13 @@ case OP_Function: {
}
#endif
MemSetTypeFlag(pCtx->pOut, MEM_Null);
- pCtx->fErrorOrAux = 0;
+ pCtx->is_aborted = false;
(*pCtx->pFunc->xSFunc)(pCtx, pCtx->argc, pCtx->argv);/* IMP: R-24505-23230 */
/* If the function returned an error, throw an exception */
- if (pCtx->fErrorOrAux) {
- if (pCtx->isError) {
- sqlVdbeError(p, "%s", sql_value_text(pCtx->pOut));
- rc = pCtx->isError;
- }
- sqlVdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1);
- if (rc) goto abort_due_to_error;
+ if (pCtx->is_aborted) {
+ rc = SQL_TARANTOOL_ERROR;
+ goto abort_due_to_error;
}
/* Copy the result of the function into register P3 */
@@ -4894,9 +4890,6 @@ case OP_Program: { /* jump */
pFrame->pParent = p->pFrame;
pFrame->nChange = p->nChange;
pFrame->nDbChange = p->db->nChange;
- assert(pFrame->pAuxData==0);
- pFrame->pAuxData = p->pAuxData;
- p->pAuxData = 0;
p->nChange = 0;
p->pFrame = pFrame;
p->aMem = aMem = VdbeFrameMem(pFrame);
@@ -5159,16 +5152,13 @@ case OP_AggStep: {
pMem->n++;
sqlVdbeMemInit(&t, db, MEM_Null);
pCtx->pOut = &t;
- pCtx->fErrorOrAux = 0;
+ pCtx->is_aborted = false;
pCtx->skipFlag = 0;
(pCtx->pFunc->xSFunc)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */
- if (pCtx->fErrorOrAux) {
- if (pCtx->isError) {
- sqlVdbeError(p, "%s", sql_value_text(&t));
- rc = pCtx->isError;
- }
+ if (pCtx->is_aborted) {
sqlVdbeMemRelease(&t);
- if (rc) goto abort_due_to_error;
+ rc = SQL_TARANTOOL_ERROR;
+ goto abort_due_to_error;
} else {
assert(t.flags==MEM_Null);
}
diff --git a/src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h
index a3100e5..ee14510 100644
--- a/src/box/sql/vdbeInt.h
+++ b/src/box/sql/vdbeInt.h
@@ -62,9 +62,6 @@ typedef unsigned Bool;
/* Opaque type used by code in vdbesort.c */
typedef struct VdbeSorter VdbeSorter;
-/* Elements of the linked list at Vdbe.pAuxData */
-typedef struct AuxData AuxData;
-
/* Types of VDBE cursors */
#define CURTYPE_TARANTOOL 0
#define CURTYPE_SORTER 1
@@ -161,7 +158,6 @@ struct VdbeFrame {
Mem *aMem; /* Array of memory cells for parent frame */
VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */
void *token; /* Copy of SubProgram.token */
- AuxData *pAuxData; /* Linked list of auxdata allocations */
int nCursor; /* Number of entries in apCsr */
int pc; /* Program Counter in parent (calling) frame */
int nOp; /* Size of aOp array */
@@ -304,21 +300,6 @@ mem_apply_numeric_type(struct Mem *record);
#endif
/*
- * Each auxiliary data pointer stored by a user defined function
- * implementation calling sql_set_auxdata() is stored in an instance
- * of this structure. All such structures associated with a single VM
- * are stored in a linked list headed at Vdbe.pAuxData. All are destroyed
- * when the VM is halted (if not before).
- */
-struct AuxData {
- int iOp; /* Instruction number of OP_Function opcode */
- int iArg; /* Index of function argument. */
- void *pAux; /* Aux data pointer */
- void (*xDelete) (void *); /* Destructor for the aux data */
- AuxData *pNext; /* Next element in list */
-};
-
-/*
* The "context" argument for an installable function. A pointer to an
* instance of this structure is the first argument to the routines used
* implement the SQL functions.
@@ -337,9 +318,12 @@ struct sql_context {
Mem *pMem; /* Memory cell used to store aggregate context */
Vdbe *pVdbe; /* The VM that owns this context */
int iOp; /* Instruction number of OP_Function */
- int isError; /* Error code returned by the function. */
+ /*
+ * True, if an error occurred during the execution of the
+ * function.
+ */
+ bool is_aborted;
u8 skipFlag; /* Skip accumulator loading if true */
- u8 fErrorOrAux; /* isError!=0 or pVdbe->pAuxData modified */
u8 argc; /* Number of arguments */
sql_value *argv[1]; /* Argument set */
};
@@ -445,7 +429,6 @@ struct Vdbe {
int nFrame; /* Number of frames in pFrame list */
u32 expmask; /* Binding to these vars invalidates VM */
SubProgram *pProgram; /* Linked list of all sub-programs used by VM */
- AuxData *pAuxData; /* Linked list of auxdata allocations */
/* Anonymous savepoint for aborts only */
Savepoint *anonymous_savepoint;
#ifdef SQL_ENABLE_STMT_SCANSTATUS
@@ -478,7 +461,6 @@ u32 sqlVdbeSerialTypeLen(u32);
u32 sqlVdbeSerialType(Mem *, int, u32 *);
u32 sqlVdbeSerialPut(unsigned char *, Mem *, u32);
u32 sqlVdbeSerialGet(const unsigned char *, u32, Mem *);
-void sqlVdbeDeleteAuxData(sql *, AuxData **, int, int);
int sqlVdbeExec(Vdbe *);
int sqlVdbeList(Vdbe *);
diff --git a/src/box/sql/vdbeapi.c b/src/box/sql/vdbeapi.c
index 597d37e..673ccd1 100644
--- a/src/box/sql/vdbeapi.c
+++ b/src/box/sql/vdbeapi.c
@@ -321,7 +321,8 @@ setResultStrOrError(sql_context * pCtx, /* Function context */
)
{
if (sqlVdbeMemSetStr(pCtx->pOut, z, n,1, xDel) == SQL_TOOBIG) {
- sql_result_error_toobig(pCtx);
+ diag_set(ClientError, ER_SQL_EXECUTE, "string or blob too big");
+ pCtx->is_aborted = true;
}
}
@@ -339,8 +340,10 @@ invokeValueDestructor(const void *p, /* Value to destroy */
} else {
xDel((void *)p);
}
- if (pCtx)
- sql_result_error_toobig(pCtx);
+ if (pCtx) {
+ diag_set(ClientError, ER_SQL_EXECUTE, "string or blob too big");
+ pCtx->is_aborted = true;
+ }
return SQL_TOOBIG;
}
@@ -351,7 +354,8 @@ sql_result_blob(sql_context * pCtx,
{
assert(n >= 0);
if (sqlVdbeMemSetStr(pCtx->pOut, z, n,0, xDel) == SQL_TOOBIG) {
- sql_result_error_toobig(pCtx);
+ diag_set(ClientError, ER_SQL_EXECUTE, "string or blob too big");
+ pCtx->is_aborted = true;
}
}
@@ -375,14 +379,6 @@ sql_result_double(sql_context * pCtx, double rVal)
}
void
-sql_result_error(sql_context * pCtx, const char *z, int n)
-{
- pCtx->isError = SQL_ERROR;
- pCtx->fErrorOrAux = 1;
- sqlVdbeMemSetStr(pCtx->pOut, z, n, 1, SQL_TRANSIENT);
-}
-
-void
sql_result_int(sql_context * pCtx, int iVal)
{
sqlVdbeMemSetInt64(pCtx->pOut, (i64) iVal);
@@ -451,37 +447,6 @@ sql_result_zeroblob64(sql_context * pCtx, u64 n)
return SQL_OK;
}
-void
-sql_result_error_code(sql_context * pCtx, int errCode)
-{
- pCtx->isError = errCode;
- pCtx->fErrorOrAux = 1;
- if (pCtx->pOut->flags & MEM_Null) {
- sqlVdbeMemSetStr(pCtx->pOut, sqlErrStr(errCode), -1, 1,
- SQL_STATIC);
- }
-}
-
-/* Force an SQL_TOOBIG error. */
-void
-sql_result_error_toobig(sql_context * pCtx)
-{
- pCtx->isError = SQL_TOOBIG;
- pCtx->fErrorOrAux = 1;
- sqlVdbeMemSetStr(pCtx->pOut, "string or blob too big", -1, 1,
- SQL_STATIC);
-}
-
-/* An SQL_NOMEM error. */
-void
-sql_result_error_nomem(sql_context * pCtx)
-{
- sqlVdbeMemSetNull(pCtx->pOut);
- pCtx->isError = SQL_NOMEM;
- pCtx->fErrorOrAux = 1;
- sqlOomFault(pCtx->pOut->db);
-}
-
/*
* Execute the statement pStmt, either until a row of data is ready, the
* statement is completely executed or an error occurs.
@@ -712,13 +677,10 @@ sqlInvalidFunction(sql_context * context, /* The function calling context */
)
{
const char *zName = context->pFunc->zName;
- char *zErr;
UNUSED_PARAMETER2(NotUsed, NotUsed2);
- zErr =
- sql_mprintf
- ("unable to use function %s in the requested context", zName);
- sql_result_error(context, zErr, -1);
- sql_free(zErr);
+ const char *err = "unable to use function %s in the requested context";
+ diag_set(ClientError, ER_SQL_EXECUTE, tt_sprintf(err, zName));
+ context->is_aborted = true;
}
/*
@@ -762,75 +724,6 @@ sql_aggregate_context(sql_context * p, int nByte)
}
/*
- * Return the auxiliary data pointer, if any, for the iArg'th argument to
- * the user-function defined by pCtx.
- */
-void *
-sql_get_auxdata(sql_context * pCtx, int iArg)
-{
- AuxData *pAuxData;
-
- if (pCtx->pVdbe == 0)
- return 0;
-
- for (pAuxData = pCtx->pVdbe->pAuxData; pAuxData;
- pAuxData = pAuxData->pNext) {
- if (pAuxData->iOp == pCtx->iOp && pAuxData->iArg == iArg)
- break;
- }
-
- return (pAuxData ? pAuxData->pAux : 0);
-}
-
-/*
- * Set the auxiliary data pointer and delete function, for the iArg'th
- * argument to the user-function defined by pCtx. Any previous value is
- * deleted by calling the delete function specified when it was set.
- */
-void
-sql_set_auxdata(sql_context * pCtx,
- int iArg, void *pAux, void (*xDelete) (void *)
- )
-{
- AuxData *pAuxData;
- Vdbe *pVdbe = pCtx->pVdbe;
-
- if (iArg < 0)
- goto failed;
- if (pVdbe == 0)
- goto failed;
-
- for (pAuxData = pVdbe->pAuxData; pAuxData; pAuxData = pAuxData->pNext) {
- if (pAuxData->iOp == pCtx->iOp && pAuxData->iArg == iArg)
- break;
- }
- if (pAuxData == 0) {
- pAuxData = sqlDbMallocZero(pVdbe->db, sizeof(AuxData));
- if (!pAuxData)
- goto failed;
- pAuxData->iOp = pCtx->iOp;
- pAuxData->iArg = iArg;
- pAuxData->pNext = pVdbe->pAuxData;
- pVdbe->pAuxData = pAuxData;
- if (pCtx->fErrorOrAux == 0) {
- pCtx->isError = 0;
- pCtx->fErrorOrAux = 1;
- }
- } else if (pAuxData->xDelete) {
- pAuxData->xDelete(pAuxData->pAux);
- }
-
- pAuxData->pAux = pAux;
- pAuxData->xDelete = xDelete;
- return;
-
- failed:
- if (xDelete) {
- xDelete(pAux);
- }
-}
-
-/*
* Return the number of columns in the result set for the statement pStmt.
*/
int
diff --git a/src/box/sql/vdbeaux.c b/src/box/sql/vdbeaux.c
index 27fa5b2..619b211 100644
--- a/src/box/sql/vdbeaux.c
+++ b/src/box/sql/vdbeaux.c
@@ -1401,7 +1401,6 @@ sqlVdbeFrameDelete(VdbeFrame * p)
sqlVdbeFreeCursor(p->v, apCsr[i]);
}
releaseMemArray(aMem, p->nChildMem);
- sqlVdbeDeleteAuxData(p->v->db, &p->pAuxData, -1, 0);
sqlDbFree(p->v->db, p);
}
@@ -1920,9 +1919,6 @@ sqlVdbeFrameRestore(VdbeFrame * pFrame)
v->nCursor = pFrame->nCursor;
v->nChange = pFrame->nChange;
v->db->nChange = pFrame->nDbChange;
- sqlVdbeDeleteAuxData(v->db, &v->pAuxData, -1, 0);
- v->pAuxData = pFrame->pAuxData;
- pFrame->pAuxData = 0;
return pFrame->pc;
}
@@ -1966,11 +1962,6 @@ closeCursorsAndFree(Vdbe * p)
p->pDelFrame = pDel->pParent;
sqlVdbeFrameDelete(pDel);
}
-
- /* Delete any auxdata allocations made by the VM */
- if (p->pAuxData)
- sqlVdbeDeleteAuxData(p->db, &p->pAuxData, -1, 0);
- assert(p->pAuxData == 0);
}
/*
@@ -2528,43 +2519,6 @@ sqlVdbeFinalize(Vdbe * p)
}
/*
- * If parameter iOp is less than zero, then invoke the destructor for
- * all auxiliary data pointers currently cached by the VM passed as
- * the first argument.
- *
- * Or, if iOp is greater than or equal to zero, then the destructor is
- * only invoked for those auxiliary data pointers created by the user
- * function invoked by the OP_Function opcode at instruction iOp of
- * VM pVdbe, and only then if:
- *
- * * the associated function parameter is the 32nd or later (counting
- * from left to right), or
- *
- * * the corresponding bit in argument mask is clear (where the first
- * function parameter corresponds to bit 0 etc.).
- */
-void
-sqlVdbeDeleteAuxData(sql * db, AuxData ** pp, int iOp, int mask)
-{
- while (*pp) {
- AuxData *pAux = *pp;
- if ((iOp < 0)
- || (pAux->iOp == iOp
- && (pAux->iArg > 31 || !(mask & MASKBIT32(pAux->iArg))))
- ) {
- testcase(pAux->iArg == 31);
- if (pAux->xDelete) {
- pAux->xDelete(pAux->pAux);
- }
- *pp = pAux->pNext;
- sqlDbFree(db, pAux);
- } else {
- pp = &pAux->pNext;
- }
- }
-}
-
-/*
* Free all memory associated with the Vdbe passed as the second argument,
* except for object itself, which is preserved.
*
diff --git a/src/box/sql/vdbemem.c b/src/box/sql/vdbemem.c
index f73ea0a..585dc21 100644
--- a/src/box/sql/vdbemem.c
+++ b/src/box/sql/vdbemem.c
@@ -321,7 +321,6 @@ sqlVdbeMemStringify(Mem * pMem, u8 bForce)
int
sqlVdbeMemFinalize(Mem * pMem, FuncDef * pFunc)
{
- int rc = SQL_OK;
if (ALWAYS(pFunc && pFunc->xFinalize)) {
sql_context ctx;
Mem t;
@@ -338,9 +337,9 @@ sqlVdbeMemFinalize(Mem * pMem, FuncDef * pFunc)
if (pMem->szMalloc > 0)
sqlDbFree(pMem->db, pMem->zMalloc);
memcpy(pMem, &t, sizeof(t));
- rc = ctx.isError;
+ return ctx.is_aborted ? SQL_TARANTOOL_ERROR : SQL_OK;
}
- return rc;
+ return SQL_OK;
}
/*
@@ -1281,7 +1280,7 @@ valueFromFunction(sql * db, /* The database connection */
ctx.pOut = pVal;
ctx.pFunc = pFunc;
pFunc->xSFunc(&ctx, nVal, apVal);
- assert(!ctx.isError);
+ assert(!ctx.is_aborted);
sql_value_apply_type(pVal, type);
assert(rc == SQL_OK);
@@ -1486,7 +1485,7 @@ recordFunc(sql_context * context, int argc, sql_value ** argv)
nRet = 1 + nSerial + nVal;
aRet = sqlDbMallocRawNN(db, nRet);
if (aRet == 0) {
- sql_result_error_nomem(context);
+ context->is_aborted = true;
} else {
aRet[0] = nSerial + 1;
putVarint32(&aRet[1], iSerial);
diff --git a/test/sql-tap/func.test.lua b/test/sql-tap/func.test.lua
index 09b1cf9..f9044ad 100755
--- a/test/sql-tap/func.test.lua
+++ b/test/sql-tap/func.test.lua
@@ -1730,7 +1730,7 @@ test:do_catchsql_test(
SELECT abs(-9223372036854775807-1);
]], {
-- <func-18.32>
- 1, "Failed to execute SQL statement: integer overflow"
+ 1, "Failed to execute SQL statement: integer is overflowed"
-- </func-18.32>
})
^ permalink raw reply [flat|nested] 31+ messages in thread
* [tarantool-patches] Re: [PATCH v1 12/12] sql: use diag_set() to set an error in SQL functions
2019-05-25 9:45 ` Mergen Imeev
@ 2019-05-25 10:36 ` Imeev Mergen
0 siblings, 0 replies; 31+ messages in thread
From: Imeev Mergen @ 2019-05-25 10:36 UTC (permalink / raw)
To: n.pettik; +Cc: tarantool-patches
[-- Attachment #1: Type: text/plain, Size: 33695 bytes --]
Fixed commit-message:
After this patch, all errors in the SQL functions will be set
using diag_set().
Part of#4074 <https://github.com/tarantool/tarantool/issues/4074>
On 5/25/19 12:45 PM, Mergen Imeev wrote:
> I moved this patch to the position before "sql: set errors
> in VDBE using diag_set()". New patch below.
>
> On Wed, May 15, 2019 at 05:12:09PM +0300, n.pettik wrote:
>>> After this patch, all errors in the SQL functions will be set
>>> using diag_set().
>>>
>>> Closes #4074
>>> ---
>>> src/box/lua/lua_sql.c | 13 +++--
>>> src/box/sql/analyze.c | 6 +--
>>> src/box/sql/func.c | 104 ++++++++++++++++++----------------------
>>> src/box/sql/sqlInt.h | 13 -----
>>> src/box/sql/vdbe.c | 34 +++----------
>>> src/box/sql/vdbeInt.h | 28 ++---------
>>> src/box/sql/vdbeapi.c | 129 +++++---------------------------------------------
>>> src/box/sql/vdbeaux.c | 46 ------------------
>>> src/box/sql/vdbemem.c | 9 ++--
>>> 9 files changed, 84 insertions(+), 298 deletions(-)
>>>
>>> diff --git a/src/box/lua/lua_sql.c b/src/box/lua/lua_sql.c
>>> index d28045a..afe4732 100644
>>> --- a/src/box/lua/lua_sql.c
>>> +++ b/src/box/lua/lua_sql.c
>>> @@ -77,13 +77,15 @@ lua_sql_call(sql_context *pCtx, int nVal, sql_value **apVal) {
>>> lua_pushboolean(L, sql_value_boolean(param));
>>> break;
>>> default:
>>> - sql_result_error(pCtx, "Unsupported type passed "
>>> - "to Lua", -1);
>> Please, remove sql_result_error at all: I grepped several
>> usages among dead code.
>>
> Fixed.
>
>>> + diag_set(ClientError, ER_SQL_EXECUTE, "Unsupported "\
>>> + "type passed to Lua");
>>> + pCtx->is_error = true;
>>> goto error;
>>> }
>>>
>>> diff --git a/src/box/sql/func.c b/src/box/sql/func.c
>>> index bb7405e..16c02f1 100644
>>> --- a/src/box/sql/func.c
>>> +++ b/src/box/sql/func.c
>>> @@ -181,13 +181,9 @@ absFunc(sql_context * context, int argc, sql_value ** argv)
>>> i64 iVal = sql_value_int64(argv[0]);
>>> if (iVal < 0) {
>>> if (iVal == SMALLEST_INT64) {
>>> - /* IMP: R-31676-45509 If X is the integer -9223372036854775808
>>> - * then abs(X) throws an integer overflow error since there is no
>>> - * equivalent positive 64-bit two complement value.
>>> - */
>>> - sql_result_error(context,
>>> - "integer overflow",
>>> - -1);
>>> + diag_set(ClientError, ER_SQL_EXECUTE,
>>> + "integer overflow”);
>> -> integer is overflowed.
>>
> Fixed.
>
>>> + context->is_error = true;
>>> return;
>>> }
>>> iVal = -iVal;
>>>
>>>
>>>
>>> @@ -591,11 +577,11 @@ case_type##ICUFunc(sql_context *context, int argc, sql_value **argv) \
>>> * does not invalidate the _text() pointer. \
>>> */ \
>>> assert(z2 == (char *)sql_value_text(argv[0])); \
>>> - if (!z2) \
>>> + if (z2 == NULL) \
>>> return; \
>> Redundant diff.
>>
> Fixed.
>
>>> src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h
>>> index 6aadca2..70a0bab 100644
>>> --- a/src/box/sql/vdbeInt.h
>>> +++ b/src/box/sql/vdbeInt.h
>>>
>>> @@ -300,21 +296,6 @@ mem_apply_numeric_type(struct Mem *record);
>>> #endif
>>>
>>>
>>> -/*
>>> * The "context" argument for an installable function. A pointer to an
>>> * instance of this structure is the first argument to the routines used
>>> * implement the SQL functions.
>>> @@ -333,9 +314,12 @@ struct sql_context {
>>> Mem *pMem; /* Memory cell used to store aggregate context */
>>> Vdbe *pVdbe; /* The VM that owns this context */
>>> int iOp; /* Instruction number of OP_Function */
>>> - int isError; /* Error code returned by the function. */
>>> + /*
>>> + * True, if an error occurred during the execution of the
>>> + * function.
>>> + */
>>> + bool is_error;
>> I’d better use is_abotred name.
>>
> FIxed. Renamed to is_aborted.
>
>>> diff --git a/src/box/sql/vdbemem.c b/src/box/sql/vdbemem.c
>>> index f73ea0a..ce0c641 100644
>>> --- a/src/box/sql/vdbemem.c
>>> +++ b/src/box/sql/vdbemem.c
>>> @@ -321,7 +321,6 @@ sqlVdbeMemStringify(Mem * pMem, u8 bForce)
>>> int
>>> sqlVdbeMemFinalize(Mem * pMem, FuncDef * pFunc)
>>> {
>>> - int rc = SQL_OK;
>>> if (ALWAYS(pFunc && pFunc->xFinalize)) {
>>> sql_context ctx;
>>> Mem t;
>>> @@ -338,9 +337,9 @@ sqlVdbeMemFinalize(Mem * pMem, FuncDef * pFunc)
>>> if (pMem->szMalloc > 0)
>>> sqlDbFree(pMem->db, pMem->zMalloc);
>>> memcpy(pMem, &t, sizeof(t));
>>> - rc = ctx.isError;
>>> + return ctx.is_error ? SQL_TARANTOOL_ERROR : SQL_OK;
>>> }
>>> - return rc;
>>> + return SQL_OK;
>> Return 0/-1
>>
> It is fixed in one of following patches.
>
>
> New patch:
>
> From bb66ac8360ee312cf8d2047143139bb46441ddf0 Mon Sep 17 00:00:00 2001
> Date: Sat, 27 Apr 2019 21:17:19 +0300
> Subject: [PATCH] sql: use diag_set() to set an error in SQL functions
>
> After this patch, all errors in the SQL functions will be set
> using diag_set().
>
> Closes #4074
>
> diff --git a/src/box/lua/lua_sql.c b/src/box/lua/lua_sql.c
> index 36b75ff..529ee59 100644
> --- a/src/box/lua/lua_sql.c
> +++ b/src/box/lua/lua_sql.c
> @@ -77,13 +77,15 @@ lua_sql_call(sql_context *pCtx, int nVal, sql_value **apVal) {
> lua_pushboolean(L, sql_value_boolean(param));
> break;
> default:
> - sql_result_error(pCtx, "Unsupported type passed "
> - "to Lua", -1);
> + diag_set(ClientError, ER_SQL_EXECUTE, "Unsupported "\
> + "type passed to Lua");
> + pCtx->is_aborted = true;
> goto error;
> }
> }
> if (lua_pcall(L, lua_gettop(L) - 1, 1, 0) != 0){
> - sql_result_error(pCtx, lua_tostring(L, -1), -1);
> + diag_set(ClientError, ER_SQL_EXECUTE, lua_tostring(L, -1));
> + pCtx->is_aborted = true;
> goto error;
> }
> switch(lua_type(L, -1)) {
> @@ -101,8 +103,9 @@ lua_sql_call(sql_context *pCtx, int nVal, sql_value **apVal) {
> sql_result_null(pCtx);
> break;
> default:
> - sql_result_error(pCtx, "Unsupported type returned from Lua",
> - -1);
> + diag_set(ClientError, ER_SQL_EXECUTE, "Unsupported type "\
> + "passed from Lua");
> + pCtx->is_aborted = true;
> goto error;
> }
> error:
> diff --git a/src/box/sql/analyze.c b/src/box/sql/analyze.c
> index d2d29c5..9795429 100644
> --- a/src/box/sql/analyze.c
> +++ b/src/box/sql/analyze.c
> @@ -298,7 +298,7 @@ statInit(sql_context * context, int argc, sql_value ** argv)
> db = sql_context_db_handle(context);
> p = sqlDbMallocZero(db, n);
> if (p == 0) {
> - sql_result_error_nomem(context);
> + context->is_aborted = true;
> return;
> }
>
> @@ -669,7 +669,7 @@ statGet(sql_context * context, int argc, sql_value ** argv)
>
> char *zRet = sqlMallocZero((p->nKeyCol + 1) * 25);
> if (zRet == 0) {
> - sql_result_error_nomem(context);
> + context->is_aborted = true;
> return;
> }
>
> @@ -715,7 +715,7 @@ statGet(sql_context * context, int argc, sql_value ** argv)
>
> char *zRet = sqlMallocZero(p->nCol * 25);
> if (zRet == 0) {
> - sql_result_error_nomem(context);
> + context->is_aborted = true;
> } else {
> int i;
> char *z = zRet;
> diff --git a/src/box/sql/date.c b/src/box/sql/date.c
> index 07a57ab..6d3a2b0 100644
> --- a/src/box/sql/date.c
> +++ b/src/box/sql/date.c
> @@ -617,7 +617,8 @@ localtimeOffset(DateTime * p, /* Date at which to calculate offset */
> computeJD(&x);
> t = (time_t) (x.iJD / 1000 - 21086676 * (i64) 10000);
> if (osLocaltime(&t, &sLocal)) {
> - sql_result_error(pCtx, "local time unavailable", -1);
> + diag_set(ClientError, ER_SQL_EXECUTE, "local time unavailable");
> + pCtx->is_aborted = true;
> *pRc = SQL_ERROR;
> return 0;
> }
> @@ -1108,12 +1109,13 @@ strftimeFunc(sql_context * context, int argc, sql_value ** argv)
> if (n < sizeof(zBuf)) {
> z = zBuf;
> } else if (n > (u64) db->aLimit[SQL_LIMIT_LENGTH]) {
> - sql_result_error_toobig(context);
> + diag_set(ClientError, ER_SQL_EXECUTE, "string or blob too big");
> + context->is_aborted = true;
> return;
> } else {
> z = sqlDbMallocRawNN(db, (int)n);
> if (z == 0) {
> - sql_result_error_nomem(context);
> + context->is_aborted = true;
> return;
> }
> }
> diff --git a/src/box/sql/func.c b/src/box/sql/func.c
> index bb7405e..593aa94 100644
> --- a/src/box/sql/func.c
> +++ b/src/box/sql/func.c
> @@ -181,13 +181,9 @@ absFunc(sql_context * context, int argc, sql_value ** argv)
> i64 iVal = sql_value_int64(argv[0]);
> if (iVal < 0) {
> if (iVal == SMALLEST_INT64) {
> - /* IMP: R-31676-45509 If X is the integer -9223372036854775808
> - * then abs(X) throws an integer overflow error since there is no
> - * equivalent positive 64-bit two complement value.
> - */
> - sql_result_error(context,
> - "integer overflow",
> - -1);
> + diag_set(ClientError, ER_SQL_EXECUTE,
> + "integer is overflowed");
> + context->is_aborted = true;
> return;
> }
> iVal = -iVal;
> @@ -203,8 +199,7 @@ absFunc(sql_context * context, int argc, sql_value ** argv)
> case MP_BOOL: {
> diag_set(ClientError, ER_INCONSISTENT_TYPES, "number",
> "boolean");
> - context->isError = SQL_TARANTOOL_ERROR;
> - context->fErrorOrAux = 1;
> + context->is_aborted = true;
> return;
> }
> default:{
> @@ -256,8 +251,7 @@ position_func(struct sql_context *context, int argc, struct Mem **argv)
> if (inconsistent_type_arg != NULL) {
> diag_set(ClientError, ER_INCONSISTENT_TYPES, "TEXT or BLOB",
> mem_type_to_str(inconsistent_type_arg));
> - context->isError = SQL_TARANTOOL_ERROR;
> - context->fErrorOrAux = 1;
> + context->is_aborted = true;
> return;
> }
> /*
> @@ -267,8 +261,7 @@ position_func(struct sql_context *context, int argc, struct Mem **argv)
> if (haystack_type != needle_type) {
> diag_set(ClientError, ER_INCONSISTENT_TYPES,
> mem_type_to_str(needle), mem_type_to_str(haystack));
> - context->isError = SQL_TARANTOOL_ERROR;
> - context->fErrorOrAux = 1;
> + context->is_aborted = true;
> return;
> }
>
> @@ -513,7 +506,6 @@ roundFunc(sql_context * context, int argc, sql_value ** argv)
> {
> int n = 0;
> double r;
> - char *zBuf;
> assert(argc == 1 || argc == 2);
> if (argc == 2) {
> if (sql_value_is_null(argv[1]))
> @@ -534,23 +526,17 @@ roundFunc(sql_context * context, int argc, sql_value ** argv)
> } else if (n == 0 && r < 0 && (-r) < LARGEST_INT64 - 1) {
> r = -(double)((sql_int64) ((-r) + 0.5));
> } else {
> - zBuf = sql_mprintf("%.*f", n, r);
> - if (zBuf == 0) {
> - sql_result_error_nomem(context);
> - return;
> - }
> - sqlAtoF(zBuf, &r, sqlStrlen30(zBuf));
> - sql_free(zBuf);
> + const char *rounded_value = tt_sprintf("%.*f", n, r);
> + sqlAtoF(rounded_value, &r, sqlStrlen30(rounded_value));
> }
> sql_result_double(context, r);
> }
>
> /*
> * Allocate nByte bytes of space using sqlMalloc(). If the
> - * allocation fails, call sql_result_error_nomem() to notify
> - * the database handle that malloc() has failed and return NULL.
> - * If nByte is larger than the maximum string or blob length, then
> - * raise an SQL_TOOBIG exception and return NULL.
> + * allocation fails, return NULL. If nByte is larger than the
> + * maximum string or blob length, then raise an error and return
> + * NULL.
> */
> static void *
> contextMalloc(sql_context * context, i64 nByte)
> @@ -561,13 +547,13 @@ contextMalloc(sql_context * context, i64 nByte)
> testcase(nByte == db->aLimit[SQL_LIMIT_LENGTH]);
> testcase(nByte == db->aLimit[SQL_LIMIT_LENGTH] + 1);
> if (nByte > db->aLimit[SQL_LIMIT_LENGTH]) {
> - sql_result_error_toobig(context);
> + diag_set(ClientError, ER_SQL_EXECUTE, "string or blob too big");
> + context->is_aborted = true;
> z = 0;
> } else {
> z = sqlMalloc(nByte);
> - if (!z) {
> - sql_result_error_nomem(context);
> - }
> + if (z == NULL)
> + context->is_aborted = true;
> }
> return z;
> }
> @@ -594,8 +580,8 @@ case_type##ICUFunc(sql_context *context, int argc, sql_value **argv) \
> if (!z2) \
> return; \
> z1 = contextMalloc(context, ((i64) n) + 1); \
> - if (!z1) { \
> - sql_result_error_nomem(context); \
> + if (z1 == NULL) { \
> + context->is_aborted = true; \
> return; \
> } \
> UErrorCode status = U_ZERO_ERROR; \
> @@ -612,8 +598,8 @@ case_type##ICUFunc(sql_context *context, int argc, sql_value **argv) \
> status = U_ZERO_ERROR; \
> sql_free(z1); \
> z1 = contextMalloc(context, ((i64) len) + 1); \
> - if (!z1) { \
> - sql_result_error_nomem(context); \
> + if (z1 == NULL) { \
> + context->is_aborted = true; \
> return; \
> } \
> ucasemap_utf8To##case_type(case_map, z1, len, z2, n, &status); \
> @@ -919,8 +905,7 @@ likeFunc(sql_context *context, int argc, sql_value **argv)
> mem_type_to_str(argv[1]);
> diag_set(ClientError, ER_INCONSISTENT_TYPES, "TEXT",
> inconsistent_type);
> - context->fErrorOrAux = 1;
> - context->isError = SQL_TARANTOOL_ERROR;
> + context->is_aborted = true;
> return;
> }
> const char *zB = (const char *) sql_value_text(argv[0]);
> @@ -937,8 +922,9 @@ likeFunc(sql_context *context, int argc, sql_value **argv)
> testcase(nPat == db->aLimit[SQL_LIMIT_LIKE_PATTERN_LENGTH]);
> testcase(nPat == db->aLimit[SQL_LIMIT_LIKE_PATTERN_LENGTH] + 1);
> if (nPat > db->aLimit[SQL_LIMIT_LIKE_PATTERN_LENGTH]) {
> - sql_result_error(context,
> - "LIKE pattern is too complex", -1);
> + diag_set(ClientError, ER_SQL_EXECUTE, "LIKE pattern is too "\
> + "complex");
> + context->is_aborted = true;
> return;
> }
> /* Encoding did not change */
> @@ -953,10 +939,10 @@ likeFunc(sql_context *context, int argc, sql_value **argv)
> const unsigned char *zEsc = sql_value_text(argv[2]);
> if (zEsc == 0)
> return;
> - const char *const err_msg =
> - "ESCAPE expression must be a single character";
> if (sql_utf8_char_count(zEsc, sql_value_bytes(argv[2])) != 1) {
> - sql_result_error(context, err_msg, -1);
> + diag_set(ClientError, ER_SQL_EXECUTE, "ESCAPE "\
> + "expression must be a single character");
> + context->is_aborted = true;
> return;
> }
> escape = sqlUtf8Read(&zEsc);
> @@ -967,9 +953,9 @@ likeFunc(sql_context *context, int argc, sql_value **argv)
> res = sql_utf8_pattern_compare(zB, zA, zB_end, zA_end,
> is_like_ci, escape);
> if (res == INVALID_PATTERN) {
> - const char *const err_msg =
> - "LIKE pattern can only contain UTF-8 characters";
> - sql_result_error(context, err_msg, -1);
> + diag_set(ClientError, ER_SQL_EXECUTE, "LIKE pattern can only "\
> + "contain UTF-8 characters");
> + context->is_aborted = true;
> return;
> }
> sql_result_bool(context, res == MATCH);
> @@ -1136,8 +1122,8 @@ charFunc(sql_context * context, int argc, sql_value ** argv)
> unsigned char *z, *zOut;
> int i;
> zOut = z = sql_malloc64(argc * 4 + 1);
> - if (z == 0) {
> - sql_result_error_nomem(context);
> + if (z == NULL) {
> + context->is_aborted = true;
> return;
> }
> for (i = 0; i < argc; i++) {
> @@ -1200,15 +1186,14 @@ static void
> zeroblobFunc(sql_context * context, int argc, sql_value ** argv)
> {
> i64 n;
> - int rc;
> assert(argc == 1);
> UNUSED_PARAMETER(argc);
> n = sql_value_int64(argv[0]);
> if (n < 0)
> n = 0;
> - rc = sql_result_zeroblob64(context, n); /* IMP: R-00293-64994 */
> - if (rc) {
> - sql_result_error_code(context, rc);
> + if (sql_result_zeroblob64(context, n) != SQL_OK) {
> + diag_set(ClientError, ER_SQL_EXECUTE, "string or blob too big");
> + context->is_aborted = true;
> }
> }
>
> @@ -1275,14 +1260,16 @@ replaceFunc(sql_context * context, int argc, sql_value ** argv)
> testcase(nOut - 1 == db->aLimit[SQL_LIMIT_LENGTH]);
> testcase(nOut - 2 == db->aLimit[SQL_LIMIT_LENGTH]);
> if (nOut - 1 > db->aLimit[SQL_LIMIT_LENGTH]) {
> - sql_result_error_toobig(context);
> + diag_set(ClientError, ER_SQL_EXECUTE, "string "\
> + "or blob too big");
> + context->is_aborted = true;
> sql_free(zOut);
> return;
> }
> zOld = zOut;
> zOut = sql_realloc64(zOut, (int)nOut);
> if (zOut == 0) {
> - sql_result_error_nomem(context);
> + context->is_aborted = true;
> sql_free(zOld);
> return;
> }
> @@ -1605,8 +1592,7 @@ sum_step(struct sql_context *context, int argc, sql_value **argv)
> if (mem_apply_numeric_type(argv[0]) != 0) {
> diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
> sql_value_text(argv[0]), "number");
> - context->fErrorOrAux = 1;
> - context->isError = SQL_TARANTOOL_ERROR;
> + context->is_aborted = true;
> return;
> }
> type = sql_value_type(argv[0]);
> @@ -1632,7 +1618,9 @@ sumFinalize(sql_context * context)
> p = sql_aggregate_context(context, 0);
> if (p && p->cnt > 0) {
> if (p->overflow) {
> - sql_result_error(context, "integer overflow", -1);
> + diag_set(ClientError, ER_SQL_EXECUTE, "integer "\
> + "overflow");
> + context->is_aborted = true;
> } else if (p->approx) {
> sql_result_double(context, p->rSum);
> } else {
> @@ -1789,9 +1777,11 @@ groupConcatFinalize(sql_context * context)
> pAccum = sql_aggregate_context(context, 0);
> if (pAccum) {
> if (pAccum->accError == STRACCUM_TOOBIG) {
> - sql_result_error_toobig(context);
> + diag_set(ClientError, ER_SQL_EXECUTE, "string or blob "\
> + "too big");
> + context->is_aborted = true;
> } else if (pAccum->accError == STRACCUM_NOMEM) {
> - sql_result_error_nomem(context);
> + context->is_aborted = true;
> } else {
> sql_result_text(context,
> sqlStrAccumFinish(pAccum),
> diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
> index 3981fbf..9c0659b 100644
> --- a/src/box/sql/sqlInt.h
> +++ b/src/box/sql/sqlInt.h
> @@ -476,19 +476,6 @@ void
> sql_result_double(sql_context *, double);
>
> void
> -sql_result_error(sql_context *, const char *,
> - int);
> -
> -void
> -sql_result_error_toobig(sql_context *);
> -
> -void
> -sql_result_error_nomem(sql_context *);
> -
> -void
> -sql_result_error_code(sql_context *, int);
> -
> -void
> sql_result_int(sql_context *, int);
>
> void
> diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
> index 1559f01..7d85959 100644
> --- a/src/box/sql/vdbe.c
> +++ b/src/box/sql/vdbe.c
> @@ -1717,17 +1717,13 @@ case OP_Function: {
> }
> #endif
> MemSetTypeFlag(pCtx->pOut, MEM_Null);
> - pCtx->fErrorOrAux = 0;
> + pCtx->is_aborted = false;
> (*pCtx->pFunc->xSFunc)(pCtx, pCtx->argc, pCtx->argv);/* IMP: R-24505-23230 */
>
> /* If the function returned an error, throw an exception */
> - if (pCtx->fErrorOrAux) {
> - if (pCtx->isError) {
> - sqlVdbeError(p, "%s", sql_value_text(pCtx->pOut));
> - rc = pCtx->isError;
> - }
> - sqlVdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1);
> - if (rc) goto abort_due_to_error;
> + if (pCtx->is_aborted) {
> + rc = SQL_TARANTOOL_ERROR;
> + goto abort_due_to_error;
> }
>
> /* Copy the result of the function into register P3 */
> @@ -4894,9 +4890,6 @@ case OP_Program: { /* jump */
> pFrame->pParent = p->pFrame;
> pFrame->nChange = p->nChange;
> pFrame->nDbChange = p->db->nChange;
> - assert(pFrame->pAuxData==0);
> - pFrame->pAuxData = p->pAuxData;
> - p->pAuxData = 0;
> p->nChange = 0;
> p->pFrame = pFrame;
> p->aMem = aMem = VdbeFrameMem(pFrame);
> @@ -5159,16 +5152,13 @@ case OP_AggStep: {
> pMem->n++;
> sqlVdbeMemInit(&t, db, MEM_Null);
> pCtx->pOut = &t;
> - pCtx->fErrorOrAux = 0;
> + pCtx->is_aborted = false;
> pCtx->skipFlag = 0;
> (pCtx->pFunc->xSFunc)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */
> - if (pCtx->fErrorOrAux) {
> - if (pCtx->isError) {
> - sqlVdbeError(p, "%s", sql_value_text(&t));
> - rc = pCtx->isError;
> - }
> + if (pCtx->is_aborted) {
> sqlVdbeMemRelease(&t);
> - if (rc) goto abort_due_to_error;
> + rc = SQL_TARANTOOL_ERROR;
> + goto abort_due_to_error;
> } else {
> assert(t.flags==MEM_Null);
> }
> diff --git a/src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h
> index a3100e5..ee14510 100644
> --- a/src/box/sql/vdbeInt.h
> +++ b/src/box/sql/vdbeInt.h
> @@ -62,9 +62,6 @@ typedef unsigned Bool;
> /* Opaque type used by code in vdbesort.c */
> typedef struct VdbeSorter VdbeSorter;
>
> -/* Elements of the linked list at Vdbe.pAuxData */
> -typedef struct AuxData AuxData;
> -
> /* Types of VDBE cursors */
> #define CURTYPE_TARANTOOL 0
> #define CURTYPE_SORTER 1
> @@ -161,7 +158,6 @@ struct VdbeFrame {
> Mem *aMem; /* Array of memory cells for parent frame */
> VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */
> void *token; /* Copy of SubProgram.token */
> - AuxData *pAuxData; /* Linked list of auxdata allocations */
> int nCursor; /* Number of entries in apCsr */
> int pc; /* Program Counter in parent (calling) frame */
> int nOp; /* Size of aOp array */
> @@ -304,21 +300,6 @@ mem_apply_numeric_type(struct Mem *record);
> #endif
>
> /*
> - * Each auxiliary data pointer stored by a user defined function
> - * implementation calling sql_set_auxdata() is stored in an instance
> - * of this structure. All such structures associated with a single VM
> - * are stored in a linked list headed at Vdbe.pAuxData. All are destroyed
> - * when the VM is halted (if not before).
> - */
> -struct AuxData {
> - int iOp; /* Instruction number of OP_Function opcode */
> - int iArg; /* Index of function argument. */
> - void *pAux; /* Aux data pointer */
> - void (*xDelete) (void *); /* Destructor for the aux data */
> - AuxData *pNext; /* Next element in list */
> -};
> -
> -/*
> * The "context" argument for an installable function. A pointer to an
> * instance of this structure is the first argument to the routines used
> * implement the SQL functions.
> @@ -337,9 +318,12 @@ struct sql_context {
> Mem *pMem; /* Memory cell used to store aggregate context */
> Vdbe *pVdbe; /* The VM that owns this context */
> int iOp; /* Instruction number of OP_Function */
> - int isError; /* Error code returned by the function. */
> + /*
> + * True, if an error occurred during the execution of the
> + * function.
> + */
> + bool is_aborted;
> u8 skipFlag; /* Skip accumulator loading if true */
> - u8 fErrorOrAux; /* isError!=0 or pVdbe->pAuxData modified */
> u8 argc; /* Number of arguments */
> sql_value *argv[1]; /* Argument set */
> };
> @@ -445,7 +429,6 @@ struct Vdbe {
> int nFrame; /* Number of frames in pFrame list */
> u32 expmask; /* Binding to these vars invalidates VM */
> SubProgram *pProgram; /* Linked list of all sub-programs used by VM */
> - AuxData *pAuxData; /* Linked list of auxdata allocations */
> /* Anonymous savepoint for aborts only */
> Savepoint *anonymous_savepoint;
> #ifdef SQL_ENABLE_STMT_SCANSTATUS
> @@ -478,7 +461,6 @@ u32 sqlVdbeSerialTypeLen(u32);
> u32 sqlVdbeSerialType(Mem *, int, u32 *);
> u32 sqlVdbeSerialPut(unsigned char *, Mem *, u32);
> u32 sqlVdbeSerialGet(const unsigned char *, u32, Mem *);
> -void sqlVdbeDeleteAuxData(sql *, AuxData **, int, int);
>
> int sqlVdbeExec(Vdbe *);
> int sqlVdbeList(Vdbe *);
> diff --git a/src/box/sql/vdbeapi.c b/src/box/sql/vdbeapi.c
> index 597d37e..673ccd1 100644
> --- a/src/box/sql/vdbeapi.c
> +++ b/src/box/sql/vdbeapi.c
> @@ -321,7 +321,8 @@ setResultStrOrError(sql_context * pCtx, /* Function context */
> )
> {
> if (sqlVdbeMemSetStr(pCtx->pOut, z, n,1, xDel) == SQL_TOOBIG) {
> - sql_result_error_toobig(pCtx);
> + diag_set(ClientError, ER_SQL_EXECUTE, "string or blob too big");
> + pCtx->is_aborted = true;
> }
> }
>
> @@ -339,8 +340,10 @@ invokeValueDestructor(const void *p, /* Value to destroy */
> } else {
> xDel((void *)p);
> }
> - if (pCtx)
> - sql_result_error_toobig(pCtx);
> + if (pCtx) {
> + diag_set(ClientError, ER_SQL_EXECUTE, "string or blob too big");
> + pCtx->is_aborted = true;
> + }
> return SQL_TOOBIG;
> }
>
> @@ -351,7 +354,8 @@ sql_result_blob(sql_context * pCtx,
> {
> assert(n >= 0);
> if (sqlVdbeMemSetStr(pCtx->pOut, z, n,0, xDel) == SQL_TOOBIG) {
> - sql_result_error_toobig(pCtx);
> + diag_set(ClientError, ER_SQL_EXECUTE, "string or blob too big");
> + pCtx->is_aborted = true;
> }
> }
>
> @@ -375,14 +379,6 @@ sql_result_double(sql_context * pCtx, double rVal)
> }
>
> void
> -sql_result_error(sql_context * pCtx, const char *z, int n)
> -{
> - pCtx->isError = SQL_ERROR;
> - pCtx->fErrorOrAux = 1;
> - sqlVdbeMemSetStr(pCtx->pOut, z, n, 1, SQL_TRANSIENT);
> -}
> -
> -void
> sql_result_int(sql_context * pCtx, int iVal)
> {
> sqlVdbeMemSetInt64(pCtx->pOut, (i64) iVal);
> @@ -451,37 +447,6 @@ sql_result_zeroblob64(sql_context * pCtx, u64 n)
> return SQL_OK;
> }
>
> -void
> -sql_result_error_code(sql_context * pCtx, int errCode)
> -{
> - pCtx->isError = errCode;
> - pCtx->fErrorOrAux = 1;
> - if (pCtx->pOut->flags & MEM_Null) {
> - sqlVdbeMemSetStr(pCtx->pOut, sqlErrStr(errCode), -1, 1,
> - SQL_STATIC);
> - }
> -}
> -
> -/* Force an SQL_TOOBIG error. */
> -void
> -sql_result_error_toobig(sql_context * pCtx)
> -{
> - pCtx->isError = SQL_TOOBIG;
> - pCtx->fErrorOrAux = 1;
> - sqlVdbeMemSetStr(pCtx->pOut, "string or blob too big", -1, 1,
> - SQL_STATIC);
> -}
> -
> -/* An SQL_NOMEM error. */
> -void
> -sql_result_error_nomem(sql_context * pCtx)
> -{
> - sqlVdbeMemSetNull(pCtx->pOut);
> - pCtx->isError = SQL_NOMEM;
> - pCtx->fErrorOrAux = 1;
> - sqlOomFault(pCtx->pOut->db);
> -}
> -
> /*
> * Execute the statement pStmt, either until a row of data is ready, the
> * statement is completely executed or an error occurs.
> @@ -712,13 +677,10 @@ sqlInvalidFunction(sql_context * context, /* The function calling context */
> )
> {
> const char *zName = context->pFunc->zName;
> - char *zErr;
> UNUSED_PARAMETER2(NotUsed, NotUsed2);
> - zErr =
> - sql_mprintf
> - ("unable to use function %s in the requested context", zName);
> - sql_result_error(context, zErr, -1);
> - sql_free(zErr);
> + const char *err = "unable to use function %s in the requested context";
> + diag_set(ClientError, ER_SQL_EXECUTE, tt_sprintf(err, zName));
> + context->is_aborted = true;
> }
>
> /*
> @@ -762,75 +724,6 @@ sql_aggregate_context(sql_context * p, int nByte)
> }
>
> /*
> - * Return the auxiliary data pointer, if any, for the iArg'th argument to
> - * the user-function defined by pCtx.
> - */
> -void *
> -sql_get_auxdata(sql_context * pCtx, int iArg)
> -{
> - AuxData *pAuxData;
> -
> - if (pCtx->pVdbe == 0)
> - return 0;
> -
> - for (pAuxData = pCtx->pVdbe->pAuxData; pAuxData;
> - pAuxData = pAuxData->pNext) {
> - if (pAuxData->iOp == pCtx->iOp && pAuxData->iArg == iArg)
> - break;
> - }
> -
> - return (pAuxData ? pAuxData->pAux : 0);
> -}
> -
> -/*
> - * Set the auxiliary data pointer and delete function, for the iArg'th
> - * argument to the user-function defined by pCtx. Any previous value is
> - * deleted by calling the delete function specified when it was set.
> - */
> -void
> -sql_set_auxdata(sql_context * pCtx,
> - int iArg, void *pAux, void (*xDelete) (void *)
> - )
> -{
> - AuxData *pAuxData;
> - Vdbe *pVdbe = pCtx->pVdbe;
> -
> - if (iArg < 0)
> - goto failed;
> - if (pVdbe == 0)
> - goto failed;
> -
> - for (pAuxData = pVdbe->pAuxData; pAuxData; pAuxData = pAuxData->pNext) {
> - if (pAuxData->iOp == pCtx->iOp && pAuxData->iArg == iArg)
> - break;
> - }
> - if (pAuxData == 0) {
> - pAuxData = sqlDbMallocZero(pVdbe->db, sizeof(AuxData));
> - if (!pAuxData)
> - goto failed;
> - pAuxData->iOp = pCtx->iOp;
> - pAuxData->iArg = iArg;
> - pAuxData->pNext = pVdbe->pAuxData;
> - pVdbe->pAuxData = pAuxData;
> - if (pCtx->fErrorOrAux == 0) {
> - pCtx->isError = 0;
> - pCtx->fErrorOrAux = 1;
> - }
> - } else if (pAuxData->xDelete) {
> - pAuxData->xDelete(pAuxData->pAux);
> - }
> -
> - pAuxData->pAux = pAux;
> - pAuxData->xDelete = xDelete;
> - return;
> -
> - failed:
> - if (xDelete) {
> - xDelete(pAux);
> - }
> -}
> -
> -/*
> * Return the number of columns in the result set for the statement pStmt.
> */
> int
> diff --git a/src/box/sql/vdbeaux.c b/src/box/sql/vdbeaux.c
> index 27fa5b2..619b211 100644
> --- a/src/box/sql/vdbeaux.c
> +++ b/src/box/sql/vdbeaux.c
> @@ -1401,7 +1401,6 @@ sqlVdbeFrameDelete(VdbeFrame * p)
> sqlVdbeFreeCursor(p->v, apCsr[i]);
> }
> releaseMemArray(aMem, p->nChildMem);
> - sqlVdbeDeleteAuxData(p->v->db, &p->pAuxData, -1, 0);
> sqlDbFree(p->v->db, p);
> }
>
> @@ -1920,9 +1919,6 @@ sqlVdbeFrameRestore(VdbeFrame * pFrame)
> v->nCursor = pFrame->nCursor;
> v->nChange = pFrame->nChange;
> v->db->nChange = pFrame->nDbChange;
> - sqlVdbeDeleteAuxData(v->db, &v->pAuxData, -1, 0);
> - v->pAuxData = pFrame->pAuxData;
> - pFrame->pAuxData = 0;
> return pFrame->pc;
> }
>
> @@ -1966,11 +1962,6 @@ closeCursorsAndFree(Vdbe * p)
> p->pDelFrame = pDel->pParent;
> sqlVdbeFrameDelete(pDel);
> }
> -
> - /* Delete any auxdata allocations made by the VM */
> - if (p->pAuxData)
> - sqlVdbeDeleteAuxData(p->db, &p->pAuxData, -1, 0);
> - assert(p->pAuxData == 0);
> }
>
> /*
> @@ -2528,43 +2519,6 @@ sqlVdbeFinalize(Vdbe * p)
> }
>
> /*
> - * If parameter iOp is less than zero, then invoke the destructor for
> - * all auxiliary data pointers currently cached by the VM passed as
> - * the first argument.
> - *
> - * Or, if iOp is greater than or equal to zero, then the destructor is
> - * only invoked for those auxiliary data pointers created by the user
> - * function invoked by the OP_Function opcode at instruction iOp of
> - * VM pVdbe, and only then if:
> - *
> - * * the associated function parameter is the 32nd or later (counting
> - * from left to right), or
> - *
> - * * the corresponding bit in argument mask is clear (where the first
> - * function parameter corresponds to bit 0 etc.).
> - */
> -void
> -sqlVdbeDeleteAuxData(sql * db, AuxData ** pp, int iOp, int mask)
> -{
> - while (*pp) {
> - AuxData *pAux = *pp;
> - if ((iOp < 0)
> - || (pAux->iOp == iOp
> - && (pAux->iArg > 31 || !(mask & MASKBIT32(pAux->iArg))))
> - ) {
> - testcase(pAux->iArg == 31);
> - if (pAux->xDelete) {
> - pAux->xDelete(pAux->pAux);
> - }
> - *pp = pAux->pNext;
> - sqlDbFree(db, pAux);
> - } else {
> - pp = &pAux->pNext;
> - }
> - }
> -}
> -
> -/*
> * Free all memory associated with the Vdbe passed as the second argument,
> * except for object itself, which is preserved.
> *
> diff --git a/src/box/sql/vdbemem.c b/src/box/sql/vdbemem.c
> index f73ea0a..585dc21 100644
> --- a/src/box/sql/vdbemem.c
> +++ b/src/box/sql/vdbemem.c
> @@ -321,7 +321,6 @@ sqlVdbeMemStringify(Mem * pMem, u8 bForce)
> int
> sqlVdbeMemFinalize(Mem * pMem, FuncDef * pFunc)
> {
> - int rc = SQL_OK;
> if (ALWAYS(pFunc && pFunc->xFinalize)) {
> sql_context ctx;
> Mem t;
> @@ -338,9 +337,9 @@ sqlVdbeMemFinalize(Mem * pMem, FuncDef * pFunc)
> if (pMem->szMalloc > 0)
> sqlDbFree(pMem->db, pMem->zMalloc);
> memcpy(pMem, &t, sizeof(t));
> - rc = ctx.isError;
> + return ctx.is_aborted ? SQL_TARANTOOL_ERROR : SQL_OK;
> }
> - return rc;
> + return SQL_OK;
> }
>
> /*
> @@ -1281,7 +1280,7 @@ valueFromFunction(sql * db, /* The database connection */
> ctx.pOut = pVal;
> ctx.pFunc = pFunc;
> pFunc->xSFunc(&ctx, nVal, apVal);
> - assert(!ctx.isError);
> + assert(!ctx.is_aborted);
> sql_value_apply_type(pVal, type);
> assert(rc == SQL_OK);
>
> @@ -1486,7 +1485,7 @@ recordFunc(sql_context * context, int argc, sql_value ** argv)
> nRet = 1 + nSerial + nVal;
> aRet = sqlDbMallocRawNN(db, nRet);
> if (aRet == 0) {
> - sql_result_error_nomem(context);
> + context->is_aborted = true;
> } else {
> aRet[0] = nSerial + 1;
> putVarint32(&aRet[1], iSerial);
> diff --git a/test/sql-tap/func.test.lua b/test/sql-tap/func.test.lua
> index 09b1cf9..f9044ad 100755
> --- a/test/sql-tap/func.test.lua
> +++ b/test/sql-tap/func.test.lua
> @@ -1730,7 +1730,7 @@ test:do_catchsql_test(
> SELECT abs(-9223372036854775807-1);
> ]], {
> -- <func-18.32>
> - 1, "Failed to execute SQL statement: integer overflow"
> + 1, "Failed to execute SQL statement: integer is overflowed"
> -- </func-18.32>
> })
>
>
>
[-- Attachment #2: Type: text/html, Size: 34029 bytes --]
^ permalink raw reply [flat|nested] 31+ messages in thread