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

tarantool / crud / 20718295386

05 Jan 2026 02:20PM UTC coverage: 88.545% (+0.1%) from 88.405%
20718295386

Pull #475

github

Satbek
try with decorator
Pull Request #475: safe/fast mode: remove fiber kill

162 of 184 new or added lines in 12 files covered. (88.04%)

80 existing lines in 10 files now uncovered.

5233 of 5910 relevant lines covered (88.54%)

14101.88 hits per line

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

97.09
/crud/insert.lua
1
local checks = require('checks')
593✔
2
local errors = require('errors')
593✔
3
local yield_checks = require('crud.common.yield_checks')
593✔
4

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

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

15
local insert = {}
593✔
16

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

20
local function insert_on_storage(space_name, tuple, opts)
21
    dev_checks('string', 'table', {
128,211✔
22
        add_space_schema_hash = '?boolean',
23
        fields = '?table',
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
    -- no-yield guard for tests (TARANTOOL_CRUD_ENABLE_INTERNAL_CHECKS)
31

32
    opts = opts or {}
128,211✔
33

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

39
    local _, err = sharding.check_sharding_hash(space_name,
256,322✔
40
                                                opts.sharding_func_hash,
128,161✔
41
                                                opts.sharding_key_hash,
128,161✔
42
                                                opts.skip_sharding_hash_check)
128,161✔
43

44
    if err ~= nil then
128,161✔
45
        return nil, err
144✔
46
    end
47

48
    local bucket_id = tuple[utils.get_bucket_id_fieldno(space)]
256,034✔
49
    local ref_ok, bucket_ref_err, unref = bucket_ref_unref.bucket_refrw(bucket_id)
128,017✔
50

51
    if not ref_ok then
128,017✔
UNCOV
52
        return nil, bucket_ref_err
×
53
    end
54

55
    -- add_space_schema_hash is true only in case of insert_object
56
    -- the only one case when reloading schema can avoid insert error
57
    -- is flattening object on router
58
    local result = schema.wrap_func_result(space, space.insert, {
256,034✔
59
        add_space_schema_hash = opts.add_space_schema_hash,
128,017✔
60
        field_names = opts.fields,
128,017✔
61
        noreturn = opts.noreturn,
128,017✔
62
        fetch_latest_metadata = opts.fetch_latest_metadata,
128,017✔
63
    }, space, tuple)
128,017✔
64

65
    local unref_ok, err_unref = unref(bucket_id)
128,017✔
66
    if not unref_ok then
128,017✔
UNCOV
67
        return nil, err_unref
×
68
    end
69

70
    return result
128,017✔
71
end
72

73
insert.storage_api = {[INSERT_FUNC_NAME] = insert_on_storage}
593✔
74

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

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

98
    local tuple = table.deepcopy(original_tuple)
128,147✔
99

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

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

115
    local call_opts = {
128,116✔
116
        mode = 'write',
117
        timeout = opts.timeout,
128,116✔
118
    }
119

120
    local storage_result, err = call.single(vshard_router,
256,232✔
121
        sharding_data.bucket_id, CRUD_INSERT_FUNC_NAME,
128,116✔
122
        {space_name, tuple, insert_on_storage_opts},
128,116✔
123
        call_opts
124
    )
128,116✔
125

126
    if err ~= nil then
128,116✔
127
        local err_wrapped = InsertError:new("Failed to call insert on storage-side: %s", err)
99✔
128

129
        if sharding.result_needs_sharding_reload(err) then
198✔
130
            return nil, err_wrapped, const.NEED_SHARDING_RELOAD
72✔
131
        end
132

133
        return nil, err_wrapped
27✔
134
    end
135

136
    if storage_result.err ~= nil then
128,017✔
137
        local err_wrapped = InsertError:new("Failed to insert: %s", storage_result.err)
1,248✔
138

139
        if schema.result_needs_reload(space, storage_result) then
2,496✔
140
            return nil, err_wrapped, const.NEED_SCHEMA_RELOAD
12✔
141
        end
142

143
        return nil, err_wrapped
1,236✔
144
    end
145

146
    if opts.noreturn == true then
126,769✔
147
        return nil
4✔
148
    end
149

150
    local tuple = storage_result.res
126,765✔
151

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

160
    return utils.format_result({tuple}, space, opts.fields)
126,765✔
161
end
162

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

203
    opts = opts or {}
120,226✔
204

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

210
    return schema.wrap_func_reload(vshard_router, sharding.wrap_method, call_insert_on_router,
120,222✔
211
                                   space_name, tuple, opts)
120,222✔
212
end
213

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

243
    opts = opts or {}
7,886✔
244

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

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

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

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

263
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