[Tarantool-patches] [PATCH 1/2] vinyl: validate resulting tuple after upsert is applied
Nikita Pettik
korablev at tarantool.org
Tue Apr 14 00:55:44 MSK 2020
There's no check that the result of upsert squashing will feature
correct format. As a consequence one is able to get tuples in space
which do not respect format. For instance:
box.schema.space.create('vinyl',{engine='vinyl',field_count=1})
box.space.vinyl:insert{1}
box.space.vinyl:upsert({1},{{'=',2,5}})
The last statement does not raise any errors. So upsert is applied and
now there's [1, 5] tuple in space (which violates 'field_count' format
restriction).
To avoid such situations, let's validate result of upsert application
and check format of resulting tuple.
Part of #1622
---
src/box/vy_upsert.c | 4 +++
.../vinyl/gh-1622-skip-invalid-upserts.result | 26 +++++++++++++++++++
.../gh-1622-skip-invalid-upserts.test.lua | 11 ++++++++
3 files changed, 41 insertions(+)
create mode 100644 test/vinyl/gh-1622-skip-invalid-upserts.result
create mode 100644 test/vinyl/gh-1622-skip-invalid-upserts.test.lua
diff --git a/src/box/vy_upsert.c b/src/box/vy_upsert.c
index ebea2789c..6855b9820 100644
--- a/src/box/vy_upsert.c
+++ b/src/box/vy_upsert.c
@@ -134,6 +134,10 @@ vy_apply_upsert(const struct tuple *new_stmt, const struct tuple *old_stmt,
&mp_size, 0, suppress_error,
&column_mask);
result_mp_end = result_mp + mp_size;
+ if (tuple_validate_raw(format, result_mp) != 0) {
+ region_truncate(region, region_svp);
+ return NULL;
+ }
if (old_type != IPROTO_UPSERT) {
assert(old_type == IPROTO_INSERT ||
old_type == IPROTO_REPLACE);
diff --git a/test/vinyl/gh-1622-skip-invalid-upserts.result b/test/vinyl/gh-1622-skip-invalid-upserts.result
new file mode 100644
index 000000000..437ff3c51
--- /dev/null
+++ b/test/vinyl/gh-1622-skip-invalid-upserts.result
@@ -0,0 +1,26 @@
+-- test-run result file version 2
+s = box.schema.space.create('test', { engine = 'vinyl', field_count = 2 })
+ | ---
+ | ...
+pk = s:create_index('pk')
+ | ---
+ | ...
+s:replace{1, 1}
+ | ---
+ | - [1, 1]
+ | ...
+-- Error is logged, upsert is not applied.
+--
+s:upsert({1, 1}, {{'=', 3, 5}})
+ | ---
+ | ...
+-- Invalid upsert still appears during read.
+--
+s:select{}
+ | ---
+ | - error: Tuple field count 3 does not match space field count 2
+ | ...
+
+s:drop()
+ | ---
+ | ...
diff --git a/test/vinyl/gh-1622-skip-invalid-upserts.test.lua b/test/vinyl/gh-1622-skip-invalid-upserts.test.lua
new file mode 100644
index 000000000..952d2bcde
--- /dev/null
+++ b/test/vinyl/gh-1622-skip-invalid-upserts.test.lua
@@ -0,0 +1,11 @@
+s = box.schema.space.create('test', { engine = 'vinyl', field_count = 2 })
+pk = s:create_index('pk')
+s:replace{1, 1}
+-- Error is logged, upsert is not applied.
+--
+s:upsert({1, 1}, {{'=', 3, 5}})
+-- Invalid upsert still appears during read.
+--
+s:select{}
+
+s:drop()
\ No newline at end of file
--
2.17.1
More information about the Tarantool-patches
mailing list