• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tarantool / crud / 19762722361

28 Nov 2025 11:37AM UTC coverage: 88.331% (-0.1%) from 88.469%
19762722361

Pull #463

github

Satbek
change slow to safe in bucket_ref_unref module naming
Pull Request #463: TNTP-2109: call bucket_ref/bucket_unref on crud operations

205 of 268 new or added lines in 16 files covered. (76.49%)

10 existing lines in 1 file now uncovered.

5193 of 5879 relevant lines covered (88.33%)

6428.43 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.31
/crud/delete.lua
1
local checks = require('checks')
258✔
2
local errors = require('errors')
258✔
3

4
local call = require('crud.common.call')
258✔
5
local const = require('crud.common.const')
258✔
6
local utils = require('crud.common.utils')
258✔
7
local sharding = require('crud.common.sharding')
258✔
8
local sharding_key_module = require('crud.common.sharding.sharding_key')
258✔
9
local sharding_metadata_module = require('crud.common.sharding.sharding_metadata')
258✔
10
local dev_checks = require('crud.common.dev_checks')
258✔
11
local schema = require('crud.common.schema')
258✔
12
local bucket_ref_unref = require('crud.common.sharding.bucket_ref_unref')
258✔
13

14
local DeleteError = errors.new_class('DeleteError', {capture_stack = false})
258✔
15

16
local delete = {}
258✔
17

18
local DELETE_FUNC_NAME = 'delete_on_storage'
258✔
19
local CRUD_DELETE_FUNC_NAME = utils.get_storage_call(DELETE_FUNC_NAME)
258✔
20

21
local function delete_on_storage(space_name, key, field_names, opts)
22
    dev_checks('string', '?', '?table', {
77✔
23
        bucket_id = 'number|cdata',
24
        sharding_key_hash = '?number',
25
        sharding_func_hash = '?number',
26
        skip_sharding_hash_check = '?boolean',
27
        noreturn = '?boolean',
28
        fetch_latest_metadata = '?boolean',
29
    })
30

31
    opts = opts or {}
77✔
32

33
    local space = box.space[space_name]
77✔
34
    if space == nil then
77✔
35
        return nil, DeleteError:new("Space %q doesn't exist", space_name)
×
36
    end
37

38
    local _, err = sharding.check_sharding_hash(space_name,
154✔
39
                                                opts.sharding_func_hash,
77✔
40
                                                opts.sharding_key_hash,
77✔
41
                                                opts.skip_sharding_hash_check)
77✔
42

43
    if err ~= nil then
77✔
44
        return nil, err
2✔
45
    end
46

47
    local function make_delete()
48
        local ref_ok, bucket_ref_err = bucket_ref_unref.bucket_refrw(opts.bucket_id)
75✔
49
        if not ref_ok then
75✔
NEW
50
            return nil, bucket_ref_err
×
51
        end
52

53
        -- add_space_schema_hash is false because
54
        -- reloading space format on router can't avoid delete error on storage
55
        local result = schema.wrap_box_space_func_result(space, 'delete', {key}, {
150✔
56
            add_space_schema_hash = false,
57
            field_names = field_names,
75✔
58
            noreturn = opts.noreturn,
75✔
59
            fetch_latest_metadata = opts.fetch_latest_metadata,
75✔
60
        })
61
        local unref_ok, err_unref = bucket_ref_unref.bucket_unrefrw(opts.bucket_id)
75✔
62
        if not unref_ok then
75✔
NEW
63
            return nil, err_unref
×
64
        end
65

66
        return result
75✔
67
    end
68

69
    return box.atomic(make_delete)
75✔
70
end
71

72
delete.storage_api = {[DELETE_FUNC_NAME] = delete_on_storage}
258✔
73

74
-- returns result, err, need_reload
75
-- need_reload indicates if reloading schema could help
76
-- see crud.common.schema.wrap_func_reload()
77
local function call_delete_on_router(vshard_router, space_name, key, opts)
78
    dev_checks('table', 'string', '?', {
90✔
79
        timeout = '?number',
80
        bucket_id = '?',
81
        fields = '?table',
82
        vshard_router = '?string|table',
83
        noreturn = '?boolean',
84
        fetch_latest_metadata = '?boolean',
85
    })
86

87
    local space, err, netbox_schema_version = utils.get_space(space_name, vshard_router, opts.timeout)
90✔
88
    if err ~= nil then
90✔
89
        return nil, DeleteError:new("An error occurred during the operation: %s", err), const.NEED_SCHEMA_RELOAD
×
90
    end
91
    if space == nil then
90✔
92
        return nil, DeleteError:new("Space %q doesn't exist", space_name), const.NEED_SCHEMA_RELOAD
22✔
93
    end
94

95
    if box.tuple.is(key) then
158✔
96
        key = key:totable()
×
97
    end
98

99
    local sharding_key_hash = nil
79✔
100
    local skip_sharding_hash_check = nil
101

102
    local sharding_key = key
79✔
103
    if opts.bucket_id == nil then
79✔
104
        if space.index[0] == nil then
73✔
105
            return nil, DeleteError:new("Cannot fetch primary index parts"), const.NEED_SCHEMA_RELOAD
×
106
        end
107
        local primary_index_parts = space.index[0].parts
73✔
108

109
        local sharding_key_data, err = sharding_metadata_module.fetch_sharding_key_on_router(vshard_router, space_name)
73✔
110
        if err ~= nil then
73✔
111
            return nil, err
×
112
        end
113

114
        sharding_key, err = sharding_key_module.extract_from_pk(vshard_router,
146✔
115
                                                                space_name,
73✔
116
                                                                sharding_key_data.value,
73✔
117
                                                                primary_index_parts, key)
146✔
118
        if err ~= nil then
73✔
119
            return nil, err
2✔
120
        end
121

122
        sharding_key_hash = sharding_key_data.hash
71✔
123
    else
124
        skip_sharding_hash_check = true
6✔
125
    end
126

127
    local bucket_id_data, err = sharding.key_get_bucket_id(vshard_router, space_name, sharding_key, opts.bucket_id)
77✔
128
    if err ~= nil then
77✔
129
        return nil, err
1✔
130
    end
131

132
    -- When the sharding index (bucket_id) is the primary index, bucket_id can be passed as box.NULL.
133
    sharding.fill_bucket_id_pk(space, key, bucket_id_data.bucket_id)
76✔
134

135
    local delete_on_storage_opts = {
76✔
136
        bucket_id = bucket_id_data.bucket_id,
76✔
137
        sharding_func_hash = bucket_id_data.sharding_func_hash,
76✔
138
        sharding_key_hash = sharding_key_hash,
76✔
139
        skip_sharding_hash_check = skip_sharding_hash_check,
76✔
140
        noreturn = opts.noreturn,
76✔
141
        fetch_latest_metadata = opts.fetch_latest_metadata,
76✔
142
    }
143

144
    local call_opts = {
76✔
145
        mode = 'write',
146
        timeout = opts.timeout,
76✔
147
    }
148

149
    local storage_result, err = call.single(vshard_router,
152✔
150
        bucket_id_data.bucket_id, CRUD_DELETE_FUNC_NAME,
76✔
151
        {space_name, key, opts.fields, delete_on_storage_opts},
76✔
152
        call_opts
153
    )
76✔
154

155
    if err ~= nil then
76✔
156
        local err_wrapped = DeleteError:new("Failed to call delete on storage-side: %s", err)
1✔
157

158
        if sharding.result_needs_sharding_reload(err) then
2✔
159
            return nil, err_wrapped, const.NEED_SHARDING_RELOAD
1✔
160
        end
161

162
        return nil, err_wrapped
×
163
    end
164

165
    if storage_result.err ~= nil then
75✔
166
        return nil, DeleteError:new("Failed to delete: %s", storage_result.err)
34✔
167
    end
168

169
    if opts.noreturn == true then
58✔
170
        return nil
1✔
171
    end
172

173
    local tuple = storage_result.res
57✔
174

175
    if opts.fetch_latest_metadata == true then
57✔
176
        -- This option is temporary and is related to [1], [2].
177
        -- [1] https://github.com/tarantool/crud/issues/236
178
        -- [2] https://github.com/tarantool/crud/issues/361
179
        space = utils.fetch_latest_metadata_when_single_storage(space, space_name, netbox_schema_version,
2✔
180
                                                                vshard_router, opts, storage_result.storage_info)
2✔
181
    end
182

183
    return utils.format_result({tuple}, space, opts.fields)
57✔
184
end
185

186
--- Deletes tuple from the specified space by key
187
--
188
-- @function call
189
--
190
-- @param string space_name
191
--  A space name
192
--
193
-- @param key
194
--  Primary key value
195
--
196
-- @tparam ?number opts.timeout
197
--  Function call timeout
198
--
199
-- @tparam ?number opts.bucket_id
200
--  Bucket ID
201
--  (by default, it's vshard.router.bucket_id_strcrc32 of primary key)
202
--
203
-- @tparam ?string|table opts.vshard_router
204
--  Cartridge vshard group name or vshard router instance.
205
--  Set this parameter if your space is not a part of the
206
--  default vshard cluster.
207
--
208
-- @tparam ?boolean opts.noreturn
209
--  Suppress returning successfully processed tuple.
210
--
211
-- @return[1] object
212
-- @treturn[2] nil
213
-- @treturn[2] table Error description
214
--
215
function delete.call(space_name, key, opts)
258✔
216
    checks('string', '?', {
86✔
217
        timeout = '?number',
218
        bucket_id = '?',
219
        fields = '?table',
220
        vshard_router = '?string|table',
221
        noreturn = '?boolean',
222
        fetch_latest_metadata = '?boolean',
223
    })
224

225
    opts = opts or {}
86✔
226

227
    local vshard_router, err = utils.get_vshard_router_instance(opts.vshard_router)
86✔
228
    if err ~= nil then
86✔
229
        return nil, DeleteError:new(err)
8✔
230
    end
231

232
    return schema.wrap_func_reload(vshard_router, sharding.wrap_method, call_delete_on_router,
82✔
233
                                   space_name, key, opts)
82✔
234
end
235

236
return delete
258✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc