@@ -9,6 +9,7 @@ local sharding_key_module = require('crud.common.sharding.sharding_key')
99local sharding_metadata_module = require (' crud.common.sharding.sharding_metadata' )
1010local dev_checks = require (' crud.common.dev_checks' )
1111local schema = require (' crud.common.schema' )
12+ local bucket_ref_unref = require (' crud.common.sharding.bucket_ref_unref' )
1213
1314local UpdateError = errors .new_class (' UpdateError' , {capture_stack = false })
1415
@@ -19,6 +20,7 @@ local CRUD_UPDATE_FUNC_NAME = utils.get_storage_call(UPDATE_FUNC_NAME)
1920
2021local function update_on_storage (space_name , key , operations , field_names , opts )
2122 dev_checks (' string' , ' ?' , ' table' , ' ?table' , {
23+ bucket_id = ' number|cdata' ,
2224 sharding_key_hash = ' ?number' ,
2325 sharding_func_hash = ' ?number' ,
2426 skip_sharding_hash_check = ' ?boolean' ,
@@ -42,39 +44,45 @@ local function update_on_storage(space_name, key, operations, field_names, opts)
4244 return nil , err
4345 end
4446
45- -- add_space_schema_hash is false because
46- -- reloading space format on router can't avoid update error on storage
47- local res , err = schema .wrap_box_space_func_result (space , ' update' , {key , operations }, {
48- add_space_schema_hash = false ,
49- field_names = field_names ,
50- noreturn = opts .noreturn ,
51- fetch_latest_metadata = opts .fetch_latest_metadata ,
52- })
53-
54- if err ~= nil then
55- return nil , err
56- end
57-
58- if res .err == nil then
59- return res , nil
60- end
47+ local function make_update ()
48+ local ref_ok , err_ref = bucket_ref_unref .bucket_refrw (opts .bucket_id )
49+ if not ref_ok then
50+ return nil , err_ref
51+ end
6152
62- -- Relevant for Tarantool older than 2.8.1.
63- -- We can only add fields to end of the tuple.
64- -- If schema is updated and nullable fields are added, then we will get error.
65- -- Therefore, we need to add filling of intermediate nullable fields.
66- -- More details: https://github.com/tarantool/tarantool/issues/3378
67- if utils .is_field_not_found (res .err .code ) then
68- operations = utils .add_intermediate_nullable_fields (operations , space :format (), space :get (key ))
69- res , err = schema .wrap_box_space_func_result (space , ' update' , {key , operations }, {
53+ -- add_space_schema_hash is false because
54+ -- reloading space format on router can't avoid update error on storage
55+ local res , err = schema .wrap_box_space_func_result (space , ' update' , {key , operations }, {
7056 add_space_schema_hash = false ,
7157 field_names = field_names ,
7258 noreturn = opts .noreturn ,
7359 fetch_latest_metadata = opts .fetch_latest_metadata ,
7460 })
61+
62+ if err == nil and res .err ~= nil and utils .is_field_not_found (res .err .code ) then
63+ -- Relevant for Tarantool older than 2.8.1.
64+ -- We can only add fields to end of the tuple.
65+ -- If schema is updated and nullable fields are added, then we will get error.
66+ -- Therefore, we need to add filling of intermediate nullable fields.
67+ -- More details: https://github.com/tarantool/tarantool/issues/3378
68+ operations = utils .add_intermediate_nullable_fields (operations , space :format (), space :get (key ))
69+ res , err = schema .wrap_box_space_func_result (space , ' update' , {key , operations }, {
70+ add_space_schema_hash = false ,
71+ field_names = field_names ,
72+ noreturn = opts .noreturn ,
73+ fetch_latest_metadata = opts .fetch_latest_metadata ,
74+ })
75+ end
76+
77+ local unref_ok , err_unref = bucket_ref_unref .bucket_unrefrw (opts .bucket_id )
78+ if not unref_ok then
79+ return nil , err_unref
80+ end
81+
82+ return res , err
7583 end
7684
77- return res , err
85+ return box . atomic ( make_update )
7886end
7987
8088update .storage_api = {[UPDATE_FUNC_NAME ] = update_on_storage }
@@ -148,6 +156,7 @@ local function call_update_on_router(vshard_router, space_name, key, user_operat
148156 sharding .fill_bucket_id_pk (space , key , bucket_id_data .bucket_id )
149157
150158 local update_on_storage_opts = {
159+ bucket_id = bucket_id_data .bucket_id ,
151160 sharding_func_hash = bucket_id_data .sharding_func_hash ,
152161 sharding_key_hash = sharding_key_hash ,
153162 skip_sharding_hash_check = skip_sharding_hash_check ,
0 commit comments