Skip to content
Snippets Groups Projects
Commit 0cc62cf7 authored by Roman Tsisyk's avatar Roman Tsisyk
Browse files

Fix error messages in tuple_update

parent 345dd14a
No related branches found
No related tags found
No related merge requests found
......@@ -182,33 +182,49 @@ update_field_init(struct update_field *field,
field->tail_len = tail_len;
}
static inline uint32_t
mp_read_int(const char **expr, const char *where)
static inline int64_t
mp_read_int(struct tuple_update *update, struct update_op *op,
const char **expr)
{
uint32_t field_no;
int64_t field_no;
if (mp_typeof(**expr) == MP_UINT)
field_no = mp_decode_uint(expr);
else if (mp_typeof(**expr) == MP_INT)
field_no = (int32_t) mp_decode_int(expr);
field_no = mp_decode_int(expr);
else
tnt_raise(ClientError, ER_INVALID_MSGPACK, where);
tnt_raise(ClientError, ER_ARG_TYPE, (char ) op->opcode,
update->index_base + op->field_no, "UINT");
return field_no;
}
static inline const char *
mp_read_str(struct tuple_update *update, struct update_op *op,
const char **expr, uint32_t *len)
{
if (mp_typeof(**expr) != MP_STR) {
tnt_raise(ClientError, ER_ARG_TYPE, (char) op->opcode,
update->index_base + op->field_no, "STR");
}
return mp_decode_str(expr, len); /* value */
}
static inline void
op_check_field_no(uint32_t field_no, uint32_t field_max)
op_check_field_no(struct tuple_update *update, uint32_t field_no,
uint32_t field_max)
{
if (field_no > field_max)
tnt_raise(ClientError, ER_NO_SUCH_FIELD, field_no);
tnt_raise(ClientError, ER_NO_SUCH_FIELD, update->index_base +
field_no);
}
static inline void
op_adjust_field_no(struct update_op *op, uint32_t field_max)
op_adjust_field_no(struct tuple_update *update, struct update_op *op,
uint32_t field_max)
{
if (op->field_no == UINT32_MAX)
op->field_no = field_max;
else
op_check_field_no(op->field_no, field_max);
op_check_field_no(update, op->field_no, field_max);
}
static inline void
......@@ -225,7 +241,7 @@ static void
do_op_insert(struct tuple_update *update, struct update_op *op,
const char **expr)
{
op_adjust_field_no(op, rope_size(update->rope));
op_adjust_field_no(update, op, rope_size(update->rope));
op_set_read(op, expr);
struct update_field *field = (struct update_field *)
update->alloc(update->alloc_ctx, sizeof(*field));
......@@ -253,17 +269,16 @@ static void
do_op_delete(struct tuple_update *update, struct update_op *op,
const char **expr)
{
op_adjust_field_no(op, rope_size(update->rope) - 1);
if (mp_typeof(**expr) != MP_UINT)
tnt_raise(ClientError, ER_ARG_TYPE, op->field_no, "UINT");
uint32_t delete_count = mp_decode_uint(expr);
op_adjust_field_no(update, op, rope_size(update->rope) - 1);
uint32_t delete_count = mp_read_int(update, op, expr);
if ((uint64_t) op->field_no + delete_count > rope_size(update->rope))
delete_count = rope_size(update->rope) - op->field_no;
if (delete_count == 0)
tnt_raise(ClientError, ER_UPDATE_FIELD,
if (delete_count == 0) {
tnt_raise(ClientError, ER_UPDATE_FIELD, update->index_base +
op->field_no, "cannot delete 0 fields");
}
for (uint32_t u = 0; u < delete_count; u++)
rope_erase(update->rope, op->field_no);
......@@ -273,7 +288,7 @@ static void
do_op_arith(struct tuple_update *update, struct update_op *op,
const char **expr)
{
op_check_field_no(op->field_no, rope_size(update->rope) - 1);
op_check_field_no(update, op->field_no, rope_size(update->rope) - 1);
struct update_field *field = (struct update_field *)
rope_extract(update->rope, op->field_no);
......@@ -281,16 +296,14 @@ do_op_arith(struct tuple_update *update, struct update_op *op,
/* TODO: signed int & float support */
struct op_arith_arg *arg = &op->arg.arith;
arg->val = mp_read_int(expr, "expected an argument of arithmetic operation (integer)");
arg->val = mp_read_int(update, op, expr);
if (field->op) {
tnt_raise(ClientError, ER_UPDATE_FIELD,
tnt_raise(ClientError, ER_UPDATE_FIELD, update->index_base +
op->field_no, "double update of the same field");
}
field->op = op;
const char *old = field->old;
if (mp_typeof(*old) != MP_UINT)
tnt_raise(ClientError, ER_ARG_TYPE, op->field_no, "UINT");
uint64_t val = mp_decode_uint(&old);
uint64_t val = mp_read_int(update, op, &old);
switch (op->opcode) {
case '+': arg->val += val; break;
case '&': arg->val &= val; break;
......@@ -306,41 +319,39 @@ static void
do_op_splice(struct tuple_update *update, struct update_op *op,
const char **expr)
{
op_check_field_no(op->field_no, rope_size(update->rope) - 1);
op_check_field_no(update, op->field_no, rope_size(update->rope) - 1);
struct update_field *field = (struct update_field *)
rope_extract(update->rope, op->field_no);
if (field->op) {
tnt_raise(ClientError, ER_UPDATE_FIELD,
op->field_no, "double update of the same field");
update->index_base + op->field_no,
"double update of the same field");
}
struct op_splice_arg *arg = &op->arg.splice;
arg->offset = mp_read_int(expr, "expected splice offset (integer)");
arg->cut_length = mp_read_int(expr, "expected splice cut length (integer)"); /* cut length */
arg->offset = mp_read_int(update, op, expr);
arg->cut_length = mp_read_int(update, op, expr); /* cut length */
if (mp_typeof(**expr) != MP_STR)
tnt_raise(ClientError, ER_ARG_TYPE, op->field_no, "STR");
arg->paste = mp_decode_str(expr, &arg->paste_length); /* value */
arg->paste = mp_read_str(update, op, expr, &arg->paste_length); /* value */
const char *in = field->old;
if (mp_typeof(*in) != MP_STR)
tnt_raise(ClientError, ER_ARG_TYPE, op->field_no, "STR");
uint32_t str_len;
in = mp_decode_str(&in, &str_len);
in = mp_read_str(update, op, &in, &str_len);
if (arg->offset < 0) {
if (-arg->offset > str_len + 1)
tnt_raise(ClientError, ER_SPLICE,
"offset is out of bound");
if (-arg->offset > str_len + 1) {
tnt_raise(ClientError, ER_SPLICE, update->index_base +
op->field_no, "offset is out of bound");
}
arg->offset = arg->offset + str_len + 1;
} else if (arg->offset >= update->index_base){
arg->offset -= update->index_base;
if (arg->offset > str_len)
arg->offset = str_len;
} else {
tnt_raise(ClientError, ER_SPLICE, "offset is out of bound");
tnt_raise(ClientError, ER_SPLICE, update->index_base +
op->field_no, "offset is out of bound");
}
assert(arg->offset >= 0 && arg->offset <= str_len);
......@@ -603,7 +614,7 @@ update_read_ops(struct tuple_update *update, const char *expr,
}
if (args != op->meta->args)
tnt_raise(ClientError, ER_UNKNOWN_UPDATE_OP);
op->field_no = mp_read_int(&expr, "expected a field no (integer)");
op->field_no = mp_read_int(update, op, &expr);
if (op->field_no != UINT32_MAX) {
/* Check that field_no is not zero for Lua (base = 1) */
if (op->field_no < update->index_base) {
......
......@@ -74,8 +74,8 @@ enum { TNT_ERRMSG_MAX = 512 };
/* 22 */_(ER_TUPLE_NOT_ARRAY, 2, "Tuple/Key must be MsgPack array") \
/* 23 */_(ER_FIELD_TYPE, 2, "Tuple field %u type does not match one required by operation: expected %s") \
/* 24 */_(ER_FIELD_TYPE_MISMATCH, 2, "Ambiguous field type in index %u, key part %u. Requested type is %s but the field has previously been defined as %s") \
/* 25 */_(ER_SPLICE, 2, "Field SPLICE error: %s") \
/* 26 */_(ER_ARG_TYPE, 2, "Argument type in operation on field %u does not match field type: expected a %s") \
/* 25 */_(ER_SPLICE, 2, "SPLICE error on field %u: %s") \
/* 26 */_(ER_ARG_TYPE, 2, "Argument type in operation '%c' on field %u does not match field type: expected a %s") \
/* 27 */_(ER_TUPLE_IS_TOO_LONG, 2, "Tuple is too long %u") \
/* 28 */_(ER_UNKNOWN_UPDATE_OP, 2, "Unknown UPDATE operation") \
/* 29 */_(ER_UPDATE_FIELD, 2, "Field %u UPDATE error: %s") \
......
......@@ -87,11 +87,11 @@ s:insert{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
...
s:update({0}, {{'#', 42, 1}})
---
- error: Field 41 was not found in the tuple
- error: Field 42 was not found in the tuple
...
s:update({0}, {{'#', 4, 'abirvalg'}})
---
- error: 'Argument type in operation on field 3 does not match field type: expected
- error: 'Argument type in operation ''#'' on field 4 does not match field type: expected
a UINT'
...
s:update({0}, {{'#', 2, 1}, {'#', 4, 2}, {'#', 6, 1}})
......@@ -112,7 +112,7 @@ s:update({0}, {{'#', 3, 4294967295}})
...
s:update({0}, {{'#', 2, 0}})
---
- error: 'Field 1 UPDATE error: cannot delete 0 fields'
- error: 'Field 2 UPDATE error: cannot delete 0 fields'
...
s:truncate()
---
......@@ -175,7 +175,7 @@ s:update({1}, {{'=', 2, 'new field string value'}, {'=', 3, 42}, {'=', 4, 0xdead
-- test multiple update opearations on the same field
s:update({1}, {{'+', 3, 16}, {'&', 4, 0xffff0000}, {'|', 4, 0x0000a0a0}, {'^', 4, 0xffff00aa}})
---
- error: 'Field 3 UPDATE error: double update of the same field'
- error: 'Field 4 UPDATE error: double update of the same field'
...
-- test update splice operation
s:replace{1953719668, 'something to splice'}
......@@ -197,7 +197,7 @@ s:update(1953719668, {{':', 2, 100, 2, 'every'}})
...
s:update(1953719668, {{':', 2, -100, 2, 'every'}})
---
- error: 'Field SPLICE error: offset is out of bound'
- error: 'SPLICE error on field 2: offset is out of bound'
...
s:truncate()
---
......@@ -230,7 +230,7 @@ s:replace({10, 'abcde'})
...
s:update(10, {{':', 2, 0, 0, '!'}})
---
- error: 'Field SPLICE error: offset is out of bound'
- error: 'SPLICE error on field 2: offset is out of bound'
...
s:update(10, {{':', 2, 1, 0, '('}})
---
......@@ -278,7 +278,7 @@ s:insert{1684234849}
...
s:update({1684234849}, {{'#', 2, 1}})
---
- error: Field 1 was not found in the tuple
- error: Field 2 was not found in the tuple
...
s:update({1684234849}, {{'=', -1, 'push1'}})
---
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment