From 91c535752332f2c6ee35f61fd97408a5c2425855 Mon Sep 17 00:00:00 2001 From: Ilya Grishnov Date: Wed, 29 Mar 2023 11:58:11 +0300 Subject: [PATCH] feature: add noreturn opt for some DML operations This patch introduces `noreturn` opt for some DML operarions (`insert`, `replace`, `update`, `delete`, `insert_many`, `replace_many`, `upsert_many`) which suppress returning successfully processed tuple(s). Closes #267 --- CHANGELOG.md | 5 ++ README.md | 7 ++ crud/common/schema.lua | 4 +- crud/delete.lua | 8 ++ crud/insert.lua | 9 +++ crud/insert_many.lua | 6 ++ crud/replace.lua | 9 +++ crud/replace_many.lua | 6 ++ crud/update.lua | 8 ++ crud/upsert_many.lua | 8 ++ test/integration/insert_many_test.lua | 90 +++++++++++++++++++++ test/integration/replace_many_test.lua | 90 +++++++++++++++++++++ test/integration/simple_operations_test.lua | 86 ++++++++++++++++++++ test/integration/upsert_many_test.lua | 90 +++++++++++++++++++++ 14 files changed, 425 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf8884db..dd043bb6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## Unreleased + +### Added +* Add `noreturn` opt for some DML operations (PR #356). + ## [1.1.1] - 24-03-23 ### Changed diff --git a/README.md b/README.md index 2a4051a6..a874ed1a 100644 --- a/README.md +++ b/README.md @@ -234,6 +234,7 @@ where: since each replicaset has its own sequence. If sequence field is a part of the sharding key (which is true by default), choosing the bucket id is the sole responsibility of the developer + * `noreturn` (`?boolean`) - suppress returning successfully processed tuple Returns metadata and array contains one inserted row, error. @@ -299,6 +300,7 @@ where: since each replicaset has its own sequence. If sequence field is a part of the sharding key (which is true by default), choosing the bucket id is the sole responsibility of the developer + * `noreturn` (`?boolean`) - suppress returning successfully processed tuples Returns metadata and array with inserted rows, array of errors. Each error object can contain field `operation_data`. @@ -474,6 +476,7 @@ where: * `vshard_router` (`?string|table`) - Cartridge vshard group name or vshard router instance. Set this parameter if your space is not a part of the default vshard cluster + * `noreturn` (`?boolean`) - suppress returning successfully processed tuple Returns metadata and array contains one updated row, error. @@ -510,6 +513,7 @@ where: * `vshard_router` (`?string|table`) - Cartridge vshard group name or vshard router instance. Set this parameter if your space is not a part of the default vshard cluster + * `noreturn` (`?boolean`) - suppress returning successfully processed tuple Returns metadata and array contains one deleted row (empty for vinyl), error. @@ -557,6 +561,7 @@ where: since each replicaset has its own sequence. If sequence field is a part of the sharding key (which is true by default), choosing the bucket id is the sole responsibility of the developer + * `noreturn` (`?boolean`) - suppress returning successfully processed tuple Returns inserted or replaced rows and metadata or nil with error. @@ -622,6 +627,7 @@ where: since each replicaset has its own sequence. If sequence field is a part of the sharding key (which is true by default), choosing the bucket id is the sole responsibility of the developer + * `noreturn` (`?boolean`) - suppress returning successfully processed tuples Returns metadata and array with inserted/replaced rows, array of errors. Each error object can contain field `operation_data`. @@ -819,6 +825,7 @@ where: * `vshard_router` (`?string|table`) - Cartridge vshard group name or vshard router instance. Set this parameter if your space is not a part of the default vshard cluster + * `noreturn` (`?boolean`) - suppress returning successfully processed tuples Returns metadata and array of errors. Each error object can contain field `operation_data`. diff --git a/crud/common/schema.lua b/crud/common/schema.lua index 1cbc01f1..bfb74c9d 100644 --- a/crud/common/schema.lua +++ b/crud/common/schema.lua @@ -216,7 +216,9 @@ function schema.wrap_func_result(space, func, args, opts) result.space_schema_hash = get_space_schema_hash(space) end else - result.res = filter_tuple_fields(func_res, opts.field_names) + if opts.noreturn ~= true then + result.res = filter_tuple_fields(func_res, opts.field_names) + end end return result diff --git a/crud/delete.lua b/crud/delete.lua index 5ec51e3e..860179ef 100644 --- a/crud/delete.lua +++ b/crud/delete.lua @@ -21,6 +21,7 @@ local function delete_on_storage(space_name, key, field_names, opts) sharding_key_hash = '?number', sharding_func_hash = '?number', skip_sharding_hash_check = '?boolean', + noreturn = '?boolean', }) opts = opts or {} @@ -44,6 +45,7 @@ local function delete_on_storage(space_name, key, field_names, opts) return schema.wrap_box_space_func_result(space, 'delete', {key}, { add_space_schema_hash = false, field_names = field_names, + noreturn = opts.noreturn, }) end @@ -60,6 +62,7 @@ local function call_delete_on_router(vshard_router, space_name, key, opts) bucket_id = '?number|cdata', fields = '?table', vshard_router = '?string|table', + noreturn = '?boolean', }) local space, err = utils.get_space(space_name, vshard_router, opts.timeout) @@ -108,6 +111,7 @@ local function call_delete_on_router(vshard_router, space_name, key, opts) sharding_func_hash = bucket_id_data.sharding_func_hash, sharding_key_hash = sharding_key_hash, skip_sharding_hash_check = skip_sharding_hash_check, + noreturn = opts.noreturn, } local call_opts = { @@ -162,6 +166,9 @@ end -- Set this parameter if your space is not a part of the -- default vshard cluster. -- +-- @tparam ?boolean opts.noreturn +-- Suppress returning successfully processed tuple. +-- -- @return[1] object -- @treturn[2] nil -- @treturn[2] table Error description @@ -172,6 +179,7 @@ function delete.call(space_name, key, opts) bucket_id = '?number|cdata', fields = '?table', vshard_router = '?string|table', + noreturn = '?boolean', }) opts = opts or {} diff --git a/crud/insert.lua b/crud/insert.lua index 7660457c..72c592fe 100644 --- a/crud/insert.lua +++ b/crud/insert.lua @@ -21,6 +21,7 @@ local function insert_on_storage(space_name, tuple, opts) sharding_key_hash = '?number', sharding_func_hash = '?number', skip_sharding_hash_check = '?boolean', + noreturn = '?boolean', }) opts = opts or {} @@ -45,6 +46,7 @@ local function insert_on_storage(space_name, tuple, opts) return schema.wrap_box_space_func_result(space, 'insert', {tuple}, { add_space_schema_hash = opts.add_space_schema_hash, field_names = opts.fields, + noreturn = opts.noreturn, }) end @@ -62,6 +64,7 @@ local function call_insert_on_router(vshard_router, space_name, original_tuple, add_space_schema_hash = '?boolean', fields = '?table', vshard_router = '?string|table', + noreturn = '?boolean', }) local space, err = utils.get_space(space_name, vshard_router, opts.timeout) @@ -85,6 +88,7 @@ local function call_insert_on_router(vshard_router, space_name, original_tuple, sharding_func_hash = sharding_data.sharding_func_hash, sharding_key_hash = sharding_data.sharding_key_hash, skip_sharding_hash_check = sharding_data.skip_sharding_hash_check, + noreturn = opts.noreturn, } local call_opts = { @@ -145,6 +149,9 @@ end -- Set this parameter if your space is not a part of the -- default vshard cluster. -- +-- @tparam ?boolean opts.noreturn +-- Suppress returning successfully processed tuple. +-- -- @return[1] tuple -- @treturn[2] nil -- @treturn[2] table Error description @@ -156,6 +163,7 @@ function insert.tuple(space_name, tuple, opts) add_space_schema_hash = '?boolean', fields = '?table', vshard_router = '?string|table', + noreturn = '?boolean', }) opts = opts or {} @@ -194,6 +202,7 @@ function insert.object(space_name, obj, opts) fields = '?table', vshard_router = '?string|table', skip_nullability_check_on_flatten = '?boolean', + noreturn = '?boolean', }) opts = opts or {} diff --git a/crud/insert_many.lua b/crud/insert_many.lua index f7fc54e6..fb1f0e48 100644 --- a/crud/insert_many.lua +++ b/crud/insert_many.lua @@ -27,6 +27,7 @@ local function insert_many_on_storage(space_name, tuples, opts) sharding_key_hash = '?number', sharding_func_hash = '?number', skip_sharding_hash_check = '?boolean', + noreturn = '?boolean', }) opts = opts or {} @@ -56,6 +57,7 @@ local function insert_many_on_storage(space_name, tuples, opts) local insert_result = schema.wrap_box_space_func_result(space, 'insert', {tuple}, { add_space_schema_hash = opts.add_space_schema_hash, field_names = opts.fields, + noreturn = opts.noreturn, }) if insert_result.err ~= nil then @@ -129,6 +131,7 @@ local function call_insert_many_on_router(vshard_router, space_name, original_tu stop_on_error = '?boolean', rollback_on_error = '?boolean', vshard_router = '?string|table', + noreturn = '?boolean', }) local space, err = utils.get_space(space_name, vshard_router, opts.timeout) @@ -148,6 +151,7 @@ local function call_insert_many_on_router(vshard_router, space_name, original_tu fields = opts.fields, stop_on_error = opts.stop_on_error, rollback_on_error = opts.rollback_on_error, + noreturn = opts.noreturn, } local iter, err = BatchInsertIterator:new({ @@ -219,6 +223,7 @@ function insert_many.tuples(space_name, tuples, opts) stop_on_error = '?boolean', rollback_on_error = '?boolean', vshard_router = '?string|table', + noreturn = '?boolean', }) opts = opts or {} @@ -257,6 +262,7 @@ function insert_many.objects(space_name, objs, opts) rollback_on_error = '?boolean', vshard_router = '?string|table', skip_nullability_check_on_flatten = '?boolean', + noreturn = '?boolean', }) opts = opts or {} diff --git a/crud/replace.lua b/crud/replace.lua index 3ffc0548..aa9e19e4 100644 --- a/crud/replace.lua +++ b/crud/replace.lua @@ -21,6 +21,7 @@ local function replace_on_storage(space_name, tuple, opts) sharding_key_hash = '?number', sharding_func_hash = '?number', skip_sharding_hash_check = '?boolean', + noreturn = '?boolean', }) opts = opts or {} @@ -45,6 +46,7 @@ local function replace_on_storage(space_name, tuple, opts) return schema.wrap_box_space_func_result(space, 'replace', {tuple}, { add_space_schema_hash = opts.add_space_schema_hash, field_names = opts.fields, + noreturn = opts.noreturn, }) end @@ -62,6 +64,7 @@ local function call_replace_on_router(vshard_router, space_name, original_tuple, add_space_schema_hash = '?boolean', fields = '?table', vshard_router = '?string|table', + noreturn = '?boolean', }) local space, err = utils.get_space(space_name, vshard_router, opts.timeout) @@ -85,6 +88,7 @@ local function call_replace_on_router(vshard_router, space_name, original_tuple, sharding_func_hash = sharding_data.sharding_func_hash, sharding_key_hash = sharding_data.sharding_key_hash, skip_sharding_hash_check = sharding_data.skip_sharding_hash_check, + noreturn = opts.noreturn, } local call_opts = { @@ -144,6 +148,9 @@ end -- Set this parameter if your space is not a part of the -- default vshard cluster. -- +-- @tparam ?boolean opts.noreturn +-- Suppress returning successfully processed tuple. +-- -- @return[1] object -- @treturn[2] nil -- @treturn[2] table Error description @@ -155,6 +162,7 @@ function replace.tuple(space_name, tuple, opts) add_space_schema_hash = '?boolean', fields = '?table', vshard_router = '?string|table', + noreturn = '?boolean', }) opts = opts or {} @@ -193,6 +201,7 @@ function replace.object(space_name, obj, opts) fields = '?table', vshard_router = '?string|table', skip_nullability_check_on_flatten = '?boolean', + noreturn = '?boolean', }) opts = opts or {} diff --git a/crud/replace_many.lua b/crud/replace_many.lua index 73f44b9a..7224d94b 100644 --- a/crud/replace_many.lua +++ b/crud/replace_many.lua @@ -27,6 +27,7 @@ local function replace_many_on_storage(space_name, tuples, opts) sharding_key_hash = '?number', sharding_func_hash = '?number', skip_sharding_hash_check = '?boolean', + noreturn = '?boolean', }) opts = opts or {} @@ -56,6 +57,7 @@ local function replace_many_on_storage(space_name, tuples, opts) local insert_result = schema.wrap_box_space_func_result(space, 'replace', {tuple}, { add_space_schema_hash = opts.add_space_schema_hash, field_names = opts.fields, + noreturn = opts.noreturn, }) table.insert(errs, err) @@ -131,6 +133,7 @@ local function call_replace_many_on_router(vshard_router, space_name, original_t stop_on_error = '?boolean', rollback_on_error = '?boolean', vshard_router = '?string|table', + noreturn = '?boolean', }) local space, err = utils.get_space(space_name, vshard_router, opts.timeout) @@ -150,6 +153,7 @@ local function call_replace_many_on_router(vshard_router, space_name, original_t fields = opts.fields, stop_on_error = opts.stop_on_error, rollback_on_error = opts.rollback_on_error, + noreturn = opts.noreturn, } local iter, err = BatchInsertIterator:new({ @@ -221,6 +225,7 @@ function replace_many.tuples(space_name, tuples, opts) stop_on_error = '?boolean', rollback_on_error = '?boolean', vshard_router = '?string|table', + noreturn = '?boolean', }) opts = opts or {} @@ -259,6 +264,7 @@ function replace_many.objects(space_name, objs, opts) rollback_on_error = '?boolean', vshard_router = '?string|table', skip_nullability_check_on_flatten = '?boolean', + noreturn = '?boolean', }) opts = opts or {} diff --git a/crud/update.lua b/crud/update.lua index cfb39431..9927b5e7 100644 --- a/crud/update.lua +++ b/crud/update.lua @@ -21,6 +21,7 @@ local function update_on_storage(space_name, key, operations, field_names, opts) sharding_key_hash = '?number', sharding_func_hash = '?number', skip_sharding_hash_check = '?boolean', + noreturn = '?boolean', }) opts = opts or {} @@ -44,6 +45,7 @@ local function update_on_storage(space_name, key, operations, field_names, opts) local res, err = schema.wrap_box_space_func_result(space, 'update', {key, operations}, { add_space_schema_hash = false, field_names = field_names, + noreturn = opts.noreturn, }) if err ~= nil then @@ -82,6 +84,7 @@ local function call_update_on_router(vshard_router, space_name, key, user_operat bucket_id = '?number|cdata', fields = '?table', vshard_router = '?string|table', + noreturn = '?boolean', }) local space, err = utils.get_space(space_name, vshard_router, opts.timeout) @@ -140,6 +143,7 @@ local function call_update_on_router(vshard_router, space_name, key, user_operat sharding_func_hash = bucket_id_data.sharding_func_hash, sharding_key_hash = sharding_key_hash, skip_sharding_hash_check = skip_sharding_hash_check, + noreturn = opts.noreturn, } local call_opts = { @@ -198,6 +202,9 @@ end -- Set this parameter if your space is not a part of the -- default vshard cluster. -- +-- @tparam ?boolean opts.noreturn +-- Suppress returning successfully processed tuple. +-- -- @return[1] object -- @treturn[2] nil -- @treturn[2] table Error description @@ -208,6 +215,7 @@ function update.call(space_name, key, user_operations, opts) bucket_id = '?number|cdata', fields = '?table', vshard_router = '?string|table', + noreturn = '?boolean', }) opts = opts or {} diff --git a/crud/upsert_many.lua b/crud/upsert_many.lua index c27294de..c815c0de 100644 --- a/crud/upsert_many.lua +++ b/crud/upsert_many.lua @@ -26,6 +26,7 @@ local function upsert_many_on_storage(space_name, tuples, operations, opts) sharding_key_hash = '?number', sharding_func_hash = '?number', skip_sharding_hash_check = '?boolean', + noreturn = '?boolean', }) opts = opts or {} @@ -127,6 +128,7 @@ local function call_upsert_many_on_router(vshard_router, space_name, original_tu stop_on_error = '?boolean', rollback_on_error = '?boolean', vshard_router = '?string|table', + noreturn = '?boolean', }) local space, err = utils.get_space(space_name, vshard_router, opts.timeout) @@ -200,6 +202,10 @@ local function call_upsert_many_on_router(vshard_router, space_name, original_tu end end + if opts.noreturn == true then + return nil, errs + end + local res, err = utils.format_result(nil, space, opts.fields) if err ~= nil then errs = errs or {} @@ -236,6 +242,7 @@ function upsert_many.tuples(space_name, tuples_operation_data, opts) stop_on_error = '?boolean', rollback_on_error = '?boolean', vshard_router = '?string|table', + noreturn = '?boolean', }) opts = opts or {} @@ -274,6 +281,7 @@ function upsert_many.objects(space_name, objs_operation_data, opts) stop_on_error = '?boolean', rollback_on_error = '?boolean', vshard_router = '?string|table', + noreturn = '?boolean', }) opts = opts or {} diff --git a/test/integration/insert_many_test.lua b/test/integration/insert_many_test.lua index e5f34faf..aa947855 100644 --- a/test/integration/insert_many_test.lua +++ b/test/integration/insert_many_test.lua @@ -1952,3 +1952,93 @@ pgroup.test_opts_not_damaged = function(g) t.assert_equals(err, nil) t.assert_equals(new_batch_insert_opts, batch_insert_opts) end + +pgroup.test_noreturn_opt = function(g) + -- insert_many with noreturn, all tuples are correct + local result, errs = g.cluster.main_server.net_box:call('crud.insert_many', { + 'customers', + { + {1, box.NULL, 'Fedor', 59}, + {2, box.NULL, 'Anna', 23}, + {3, box.NULL, 'Daria', 18} + }, + {noreturn = true}, + }) + + t.assert_equals(errs, nil) + t.assert_equals(result, nil) + + -- insert_many with noreturn, some tuples are correct + local result, errs = g.cluster.main_server.net_box:call('crud.insert_many', { + 'customers', + { + {1, box.NULL, 'Fedor', 59}, + {4, box.NULL, 'Rom', 23}, + {5, box.NULL, 'Max', 18} + }, + {noreturn = true}, + }) + + t.assert_not_equals(errs, nil) + t.assert_equals(#errs, 1) + t.assert_equals(result, nil) + + -- insert_many with noreturn, all tuples are not correct + local result, errs = g.cluster.main_server.net_box:call('crud.insert_many', { + 'customers', + { + {1, box.NULL, 'Fedor', 59}, + {2, box.NULL, 'Anna', 23}, + {3, box.NULL, 'Daria', 18} + }, + {noreturn = true}, + }) + + t.assert_not_equals(errs, nil) + t.assert_equals(#errs, 3) + t.assert_equals(result, nil) + + -- insert_object_many with noreturn, all tuples are correct + local result, errs = g.cluster.main_server.net_box:call('crud.insert_object_many', { + 'customers', + { + {id = 10, name = 'Fedor', age = 59}, + {id = 20, name = 'Anna', age = 23}, + {id = 30, name = 'Daria', age = 18} + }, + {noreturn = true}, + }) + + t.assert_equals(errs, nil) + t.assert_equals(result, nil) + + -- insert_object_many with noreturn, some tuples are correct + local result, errs = g.cluster.main_server.net_box:call('crud.insert_object_many', { + 'customers', + { + {id = 40, name = 'Fedor', age = 59}, + {id = box.NULL, name = 'Anna', age = 23}, + {id = box.NULL, name = 'Daria', age = 18} + }, + {noreturn = true}, + }) + + t.assert_not_equals(errs, nil) + t.assert_equals(#errs, 2) + t.assert_equals(result, nil) + + -- insert_object_many with noreturn, all tuples are not correct + local result, errs = g.cluster.main_server.net_box:call('crud.insert_object_many', { + 'customers', + { + {id = box.NULL, name = 'Fedor', age = 59}, + {id = box.NULL, name = 'Anna', age = 23}, + {id = box.NULL, name = 'Daria', age = 18} + }, + {noreturn = true}, + }) + + t.assert_not_equals(errs, nil) + t.assert_equals(#errs, 3) + t.assert_equals(result, nil) +end diff --git a/test/integration/replace_many_test.lua b/test/integration/replace_many_test.lua index 193d7dbf..adcdd3e3 100644 --- a/test/integration/replace_many_test.lua +++ b/test/integration/replace_many_test.lua @@ -1962,3 +1962,93 @@ pgroup.test_opts_not_damaged = function(g) t.assert_equals(err, nil) t.assert_equals(new_batch_replace_opts, batch_replace_opts) end + +pgroup.test_noreturn_opt = function(g) + -- replace_many with noreturn, all tuples are correct + local result, errs = g.cluster.main_server.net_box:call('crud.replace_many', { + 'customers', + { + {1, box.NULL, 'Fedor', 59}, + {2, box.NULL, 'Anna', 23}, + {3, box.NULL, 'Daria', 18} + }, + {noreturn = true}, + }) + + t.assert_equals(errs, nil) + t.assert_equals(result, nil) + + -- replace_many with noreturn, some tuples are correct + local result, errs = g.cluster.main_server.net_box:call('crud.replace_many', { + 'customers', + { + {1, box.NULL, 'Fedor', 59}, + {box.NULL, box.NULL, 'Anna', 23}, + {box.NULL, box.NULL, 'Daria', 18} + }, + {noreturn = true}, + }) + + t.assert_not_equals(errs, nil) + t.assert_equals(#errs, 2) + t.assert_equals(result, nil) + + -- replace_many with noreturn, all tuples are not correct + local result, errs = g.cluster.main_server.net_box:call('crud.replace_many', { + 'customers', + { + {box.NULL, box.NULL, 'Fedor', 59}, + {box.NULL, box.NULL, 'Anna', 23}, + {box.NULL, box.NULL, 'Daria', 18} + }, + {noreturn = true}, + }) + + t.assert_not_equals(errs, nil) + t.assert_equals(#errs, 3) + t.assert_equals(result, nil) + + -- replace_object_many with noreturn, all tuples are correct + local result, errs = g.cluster.main_server.net_box:call('crud.replace_object_many', { + 'customers', + { + {id = 1, name = 'Fedor', age = 100}, + {id = 2, name = 'Anna', age = 100}, + {id = 3, name = 'Daria', age = 100} + }, + {noreturn = true}, + }) + + t.assert_equals(errs, nil) + t.assert_equals(result, nil) + + -- replace_object_many with noreturn, some tuples are correct + local result, errs = g.cluster.main_server.net_box:call('crud.replace_object_many', { + 'customers', + { + {id = 1, name = 'Fedor', age = 100}, + {id = box.NULL, name = 'Anna', age = 100}, + {id = box.NULL, name = 'Daria', age = 100} + }, + {noreturn = true}, + }) + + t.assert_not_equals(errs, nil) + t.assert_equals(#errs, 2) + t.assert_equals(result, nil) + + -- replace_object_many with noreturn, all tuples are not correct + local result, errs = g.cluster.main_server.net_box:call('crud.replace_object_many', { + 'customers', + { + {id = box.NULL, name = 'Fedor', age = 100}, + {id = box.NULL, name = 'Anna', age = 100}, + {id = box.NULL, name = 'Daria', age = 100} + }, + {noreturn = true}, + }) + + t.assert_not_equals(errs, nil) + t.assert_equals(#errs, 3) + t.assert_equals(result, nil) +end diff --git a/test/integration/simple_operations_test.lua b/test/integration/simple_operations_test.lua index 088cfddc..45f22e90 100644 --- a/test/integration/simple_operations_test.lua +++ b/test/integration/simple_operations_test.lua @@ -1337,3 +1337,89 @@ for op, case in pairs(gh_328_error_cases) do end end end + +pgroup.test_noreturn_opt = function(g) + -- correct insert with noreturn + local result, err = g.cluster.main_server.net_box:call( 'crud.insert', { + 'customers', {1, box.NULL, 'Elizabeth', 24}, {noreturn = true} + }) + t.assert_equals(err, nil) + t.assert_equals(result.rows, {}) + + -- incorrect insert with noreturn + local result, err = g.cluster.main_server.net_box:call( 'crud.insert', { + 'customers', {1, box.NULL, 'Elizabeth', 24}, {noreturn = true} + }) + t.assert_not_equals(err, nil) + t.assert_equals(result, box.NULL) + + -- correct insert_object with noreturn + local result, err = g.cluster.main_server.net_box:call( 'crud.insert_object', { + 'customers', {id = 0, name = 'Fedor', age = 59}, {noreturn = true} + }) + t.assert_equals(err, nil) + t.assert_equals(result.rows, {}) + + -- incorrect insert_object with noreturn + local result, err = g.cluster.main_server.net_box:call( 'crud.insert_object', { + 'customers', {id = 0, name = 'Fedor', age = 59}, {noreturn = true} + }) + t.assert_not_equals(err, nil) + t.assert_equals(result, box.NULL) + + -- correct replace with noreturn + local result, err = g.cluster.main_server.net_box:call( 'crud.replace', { + 'customers', {1, box.NULL, 'Elizabeth', 24}, {noreturn = true} + }) + t.assert_equals(err, nil) + t.assert_equals(result.rows, {}) + + -- incorrect replace with noreturn + local result, err = g.cluster.main_server.net_box:call( 'crud.replace', { + 'customers', {box.NULL, box.NULL, 'Elizabeth', 24}, {noreturn = true} + }) + t.assert_not_equals(err, nil) + t.assert_equals(result, box.NULL) + + -- correct replace_object with noreturn + local result, err = g.cluster.main_server.net_box:call( 'crud.replace_object', { + 'customers', {id = 0, name = 'Fedor', age = 59}, {noreturn = true} + }) + t.assert_equals(err, nil) + t.assert_equals(result.rows, {}) + + -- incorrect replace_object with noreturn + local result, err = g.cluster.main_server.net_box:call( 'crud.replace_object', { + 'customers', {id = box.NULL, name = 'Fedor', age = 59}, {noreturn = true} + }) + t.assert_not_equals(err, nil) + t.assert_equals(result, box.NULL) + + -- correct update with noreturn + local result, err = g.cluster.main_server.net_box:call( 'crud.update', { + 'customers', 1, {{'+', 'age', 1},}, {noreturn = true} + }) + t.assert_equals(err, nil) + t.assert_equals(result.rows, {}) + + -- incorrect update with noreturn + local result, err = g.cluster.main_server.net_box:call( 'crud.update', { + 'customers', {box.NULL, box.NULL, 'Elizabeth', 24}, {noreturn = true} + }) + t.assert_not_equals(err, nil) + t.assert_equals(result, box.NULL) + + -- correct delete with noreturn + local result, err = g.cluster.main_server.net_box:call( 'crud.delete', { + 'customers', 1, {noreturn = true} + }) + t.assert_equals(err, nil) + t.assert_equals(result.rows, {}) + + -- incorrect delete with noreturn + local result, err = g.cluster.main_server.net_box:call( 'crud.delete', { + 'customers', {box.NULL, box.NULL, 'Elizabeth', 24}, {noreturn = true} + }) + t.assert_not_equals(err, nil) + t.assert_equals(result, box.NULL) +end diff --git a/test/integration/upsert_many_test.lua b/test/integration/upsert_many_test.lua index 5d608623..76749476 100644 --- a/test/integration/upsert_many_test.lua +++ b/test/integration/upsert_many_test.lua @@ -1964,3 +1964,93 @@ pgroup.test_opts_not_damaged = function(g) t.assert_equals(err, nil) t.assert_equals(new_batch_upsert_opts, batch_upsert_opts) end + +pgroup.test_noreturn_opt = function(g) + -- upsert_many with noreturn, all tuples are correct + local result, errs = g.cluster.main_server.net_box:call('crud.upsert_many', { + 'customers', + { + {{1, box.NULL, 'Alex', 59}, {{'+', 'age', 1}}}, + {{2, box.NULL, 'Anna', 23}, {{'+', 'age', 1}}}, + {{3, box.NULL, 'Daria', 18}, {{'+', 'age', 1}}} + }, + {noreturn = true}, + }) + + t.assert_equals(errs, nil) + t.assert_equals(result, nil) + + -- upsert_many with noreturn, some tuples are correct + local result, errs = g.cluster.main_server.net_box:call('crud.upsert_many', { + 'customers', + { + {{1, box.NULL, 'Alex', 59}, {{'+', 'age', 1}}}, + {{box.NULL, box.NULL, 'Anna', 23}, {{'+', 'age', 1}}}, + {{box.NULL, box.NULL, 'Daria', 18}, {{'+', 'age', 1}}} + }, + {noreturn = true}, + }) + + t.assert_not_equals(errs, nil) + t.assert_equals(#errs, 2) + t.assert_equals(result, nil) + + -- upsert_many with noreturn, all tuples are not correct + local result, errs = g.cluster.main_server.net_box:call('crud.upsert_many', { + 'customers', + { + {{box.NULL, box.NULL, 'Alex', 59}, {{'+', 'age', 1}}}, + {{box.NULL, box.NULL, 'Anna', 23}, {{'+', 'age', 1}}}, + {{box.NULL, box.NULL, 'Daria', 18}, {{'+', 'age', 1}}} + }, + {noreturn = true}, + }) + + t.assert_not_equals(errs, nil) + t.assert_equals(#errs, 3) + t.assert_equals(result, nil) + + -- upsert_object_many with noreturn, all tuples are correct + local result, errs = g.cluster.main_server.net_box:call('crud.upsert_object_many', { + 'customers', + { + {{id = 1, name = 'Fedor', age = 59}, {{'+', 'age', 1}}}, + {{id = 2, name = 'Anna', age = 23}, {{'+', 'age', 1}}}, + {{id = 3, name = 'Daria', age = 18}, {{'+', 'age', 1}}}, + }, + {noreturn = true}, + }) + + t.assert_equals(errs, nil) + t.assert_equals(result, nil) + + -- upsert_object_many with noreturn, some tuples are correct + local result, errs = g.cluster.main_server.net_box:call('crud.upsert_object_many', { + 'customers', + { + {{id = 1, name = 'Fedor', age = 59}, {{'+', 'age', 1}}}, + {{id = box.NULL, name = 'Anna', age = 23}, {{'+', 'age', 1}}}, + {{id = box.NULL, name = 'Daria', age = 18}, {{'+', 'age', 1}}}, + }, + {noreturn = true}, + }) + + t.assert_not_equals(errs, nil) + t.assert_equals(#errs, 2) + t.assert_equals(result, nil) + + -- upsert_object_many with noreturn, all tuples are not correct + local result, errs = g.cluster.main_server.net_box:call('crud.upsert_object_many', { + 'customers', + { + {{id = box.NULL, name = 'Fedor', age = 59}, {{'+', 'age', 1}}}, + {{id = box.NULL, name = 'Anna', age = 23}, {{'+', 'age', 1}}}, + {{id = box.NULL, name = 'Daria', age = 18}, {{'+', 'age', 1}}}, + }, + {noreturn = true}, + }) + + t.assert_not_equals(errs, nil) + t.assert_equals(#errs, 3) + t.assert_equals(result, nil) +end