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

tarantool / crud / 19959665764

05 Dec 2025 10:11AM UTC coverage: 88.424%. First build
19959665764

Pull #463

github

Satbek
Fix tests after fast/safe mode changes

* add access to _bucket space in privillage tests
* fix select_readview_test
* enable double buckets test
* add safe_mode_disable for cartirdge reload test: test_storage
* add safe_mode_disable for test_any_vshard_call_timeout
Pull Request #463: TNTP-2109: call bucket_ref/bucket_unref on crud operations

205 of 269 new or added lines in 16 files covered. (76.21%)

5217 of 5900 relevant lines covered (88.42%)

12766.29 hits per line

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

97.06
/crud/insert.lua
1
local checks = require('checks')
593✔
2
local errors = require('errors')
593✔
3

4
local call = require('crud.common.call')
593✔
5
local const = require('crud.common.const')
593✔
6
local utils = require('crud.common.utils')
593✔
7
local sharding = require('crud.common.sharding')
593✔
8
local dev_checks = require('crud.common.dev_checks')
593✔
9
local schema = require('crud.common.schema')
593✔
10
local bucket_ref_unref = require('crud.common.sharding.bucket_ref_unref')
593✔
11

12
local InsertError = errors.new_class('InsertError', {capture_stack = false})
593✔
13

14
local insert = {}
593✔
15

16
local INSERT_FUNC_NAME = 'insert_on_storage'
593✔
17
local CRUD_INSERT_FUNC_NAME = utils.get_storage_call(INSERT_FUNC_NAME)
593✔
18

19
local function insert_on_storage(space_name, tuple, opts)
20
    dev_checks('string', 'table', {
128,135✔
21
        add_space_schema_hash = '?boolean',
22
        fields = '?table',
23
        sharding_key_hash = '?number',
24
        sharding_func_hash = '?number',
25
        skip_sharding_hash_check = '?boolean',
26
        noreturn = '?boolean',
27
        fetch_latest_metadata = '?boolean',
28
    })
29

30
    opts = opts or {}
128,135✔
31

32
    local space = box.space[space_name]
128,135✔
33
    if space == nil then
128,135✔
34
        return nil, InsertError:new("Space %q doesn't exist", space_name)
92✔
35
    end
36

37
    local _, err = sharding.check_sharding_hash(space_name,
256,178✔
38
                                                opts.sharding_func_hash,
128,089✔
39
                                                opts.sharding_key_hash,
128,089✔
40
                                                opts.skip_sharding_hash_check)
128,089✔
41

42
    if err ~= nil then
128,089✔
43
        return nil, err
144✔
44
    end
45

46
    local function make_insert()
47
        local bucket_id = tuple[utils.get_bucket_id_fieldno(space)]
255,890✔
48
        local ref_ok, bucket_ref_err = bucket_ref_unref.bucket_refrw(bucket_id)
127,945✔
49

50
        if not ref_ok then
127,945✔
NEW
51
            return nil, bucket_ref_err
×
52
        end
53

54
        -- add_space_schema_hash is true only in case of insert_object
55
        -- the only one case when reloading schema can avoid insert error
56
        -- is flattening object on router
57
        local result = schema.wrap_box_space_func_result(space, 'insert', {tuple}, {
255,890✔
58
            add_space_schema_hash = opts.add_space_schema_hash,
127,945✔
59
            field_names = opts.fields,
127,945✔
60
            noreturn = opts.noreturn,
127,945✔
61
            fetch_latest_metadata = opts.fetch_latest_metadata,
127,945✔
62
        })
63

64
        local unref_ok, err_unref = bucket_ref_unref.bucket_unrefrw(bucket_id)
127,945✔
65
        if not unref_ok then
127,945✔
NEW
66
            return nil, err_unref
×
67
        end
68

69
        return result
127,945✔
70
    end
71

72
    return box.atomic(make_insert)
127,945✔
73
end
74

75
insert.storage_api = {[INSERT_FUNC_NAME] = insert_on_storage}
593✔
76

77
-- returns result, err, need_reload
78
-- need_reload indicates if reloading schema could help
79
-- see crud.common.schema.wrap_func_reload()
80
local function call_insert_on_router(vshard_router, space_name, original_tuple, opts)
81
    dev_checks('table', 'string', 'table', {
128,121✔
82
        timeout = '?number',
83
        bucket_id = '?',
84
        add_space_schema_hash = '?boolean',
85
        fields = '?table',
86
        vshard_router = '?string|table',
87
        skip_nullability_check_on_flatten = '?boolean',
88
        noreturn = '?boolean',
89
        fetch_latest_metadata = '?boolean',
90
    })
91

92
    local space, err, netbox_schema_version = utils.get_space(space_name, vshard_router, opts.timeout)
128,121✔
93
    if err ~= nil then
128,121✔
94
        return nil, InsertError:new("An error occurred during the operation: %s", err), const.NEED_SCHEMA_RELOAD
×
95
    end
96
    if space == nil then
128,121✔
97
        return nil, InsertError:new("Space %q doesn't exist", space_name), const.NEED_SCHEMA_RELOAD
98✔
98
    end
99

100
    local tuple = table.deepcopy(original_tuple)
128,072✔
101

102
    local sharding_data, err = sharding.tuple_set_and_return_bucket_id(vshard_router, tuple, space, opts.bucket_id)
128,072✔
103
    if err ~= nil then
128,072✔
104
        return nil, InsertError:new("Failed to get bucket ID: %s", err), const.NEED_SCHEMA_RELOAD
60✔
105
    end
106

107
    local insert_on_storage_opts = {
128,042✔
108
        add_space_schema_hash = opts.add_space_schema_hash,
128,042✔
109
        fields = opts.fields,
128,042✔
110
        sharding_func_hash = sharding_data.sharding_func_hash,
128,042✔
111
        sharding_key_hash = sharding_data.sharding_key_hash,
128,042✔
112
        skip_sharding_hash_check = sharding_data.skip_sharding_hash_check,
128,042✔
113
        noreturn = opts.noreturn,
128,042✔
114
        fetch_latest_metadata = opts.fetch_latest_metadata,
128,042✔
115
    }
116

117
    local call_opts = {
128,042✔
118
        mode = 'write',
119
        timeout = opts.timeout,
128,042✔
120
    }
121

122
    local storage_result, err = call.single(vshard_router,
256,084✔
123
        sharding_data.bucket_id, CRUD_INSERT_FUNC_NAME,
128,042✔
124
        {space_name, tuple, insert_on_storage_opts},
128,042✔
125
        call_opts
126
    )
128,042✔
127

128
    if err ~= nil then
128,042✔
129
        local err_wrapped = InsertError:new("Failed to call insert on storage-side: %s", err)
97✔
130

131
        if sharding.result_needs_sharding_reload(err) then
194✔
132
            return nil, err_wrapped, const.NEED_SHARDING_RELOAD
72✔
133
        end
134

135
        return nil, err_wrapped
25✔
136
    end
137

138
    if storage_result.err ~= nil then
127,945✔
139
        local err_wrapped = InsertError:new("Failed to insert: %s", storage_result.err)
1,249✔
140

141
        if schema.result_needs_reload(space, storage_result) then
2,498✔
142
            return nil, err_wrapped, const.NEED_SCHEMA_RELOAD
13✔
143
        end
144

145
        return nil, err_wrapped
1,236✔
146
    end
147

148
    if opts.noreturn == true then
126,696✔
149
        return nil
4✔
150
    end
151

152
    local tuple = storage_result.res
126,692✔
153

154
    if opts.fetch_latest_metadata == true then
126,692✔
155
        -- This option is temporary and is related to [1], [2].
156
        -- [1] https://github.com/tarantool/crud/issues/236
157
        -- [2] https://github.com/tarantool/crud/issues/361
158
        space = utils.fetch_latest_metadata_when_single_storage(space, space_name, netbox_schema_version,
8✔
159
                                                                vshard_router, opts, storage_result.storage_info)
8✔
160
    end
161

162
    return utils.format_result({tuple}, space, opts.fields)
126,692✔
163
end
164

165
--- Inserts a tuple to the specified space
166
--
167
-- @function tuple
168
--
169
-- @param string space_name
170
--  A space name
171
--
172
-- @param table tuple
173
--  Tuple
174
--
175
-- @tparam ?number opts.timeout
176
--  Function call timeout
177
--
178
-- @tparam ?number opts.bucket_id
179
--  Bucket ID
180
--  (by default, it's vshard.router.bucket_id_strcrc32 of primary key)
181
--
182
-- @tparam ?string|table opts.vshard_router
183
--  Cartridge vshard group name or vshard router instance.
184
--  Set this parameter if your space is not a part of the
185
--  default vshard cluster.
186
--
187
-- @tparam ?boolean opts.noreturn
188
--  Suppress returning successfully processed tuple.
189
--
190
-- @return[1] tuple
191
-- @treturn[2] nil
192
-- @treturn[2] table Error description
193
--
194
function insert.tuple(space_name, tuple, opts)
593✔
195
    checks('string', 'table', {
120,153✔
196
        timeout = '?number',
197
        bucket_id = '?',
198
        add_space_schema_hash = '?boolean',
199
        fields = '?table',
200
        vshard_router = '?string|table',
201
        noreturn = '?boolean',
202
        fetch_latest_metadata = '?boolean',
203
    })
204

205
    opts = opts or {}
120,153✔
206

207
    local vshard_router, err = utils.get_vshard_router_instance(opts.vshard_router)
120,153✔
208
    if err ~= nil then
120,153✔
209
        return nil, InsertError:new(err)
8✔
210
    end
211

212
    return schema.wrap_func_reload(vshard_router, sharding.wrap_method, call_insert_on_router,
120,149✔
213
                                   space_name, tuple, opts)
120,149✔
214
end
215

216
--- Inserts an object to the specified space
217
--
218
-- @function object
219
--
220
-- @param string space_name
221
--  A space name
222
--
223
-- @param table obj
224
--  Object
225
--
226
-- @tparam ?table opts
227
--  Options of insert.tuple
228
--
229
-- @return[1] object
230
-- @treturn[2] nil
231
-- @treturn[2] table Error description
232
--
233
function insert.object(space_name, obj, opts)
593✔
234
    checks('string', 'table', {
7,886✔
235
        timeout = '?number',
236
        bucket_id = '?',
237
        add_space_schema_hash = '?boolean',
238
        fields = '?table',
239
        vshard_router = '?string|table',
240
        skip_nullability_check_on_flatten = '?boolean',
241
        noreturn = '?boolean',
242
        fetch_latest_metadata = '?boolean',
243
    })
244

245
    opts = opts or {}
7,886✔
246

247
    local vshard_router, err = utils.get_vshard_router_instance(opts.vshard_router)
7,886✔
248
    if err ~= nil then
7,886✔
249
        return nil, InsertError:new(err)
8✔
250
    end
251

252
    -- insert can fail if router uses outdated schema to flatten object
253
    opts = utils.merge_options(opts, {add_space_schema_hash = true})
15,764✔
254

255
    local tuple, err = utils.flatten_obj_reload(vshard_router, space_name, obj,
15,764✔
256
                                                opts.skip_nullability_check_on_flatten)
7,882✔
257
    if err ~= nil then
7,882✔
258
        return nil, InsertError:new("Failed to flatten object: %s", err)
80✔
259
    end
260

261
    return schema.wrap_func_reload(vshard_router, sharding.wrap_method, call_insert_on_router,
7,842✔
262
                                   space_name, tuple, opts)
7,842✔
263
end
264

265
return insert
593✔
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