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

tarantool / crud / 5199459215

pending completion
5199459215

push

github

DifferentialOrange
Release 1.2.0

Overview

  This release add two new flags: `noreturn` to ignore return values
  excessive transfer and encoding/decoding for insert/replace/etc
  (performance improvement up to 10% for batch requests) and
  `fetch_latest_metadata` to force fetching latest space format metadata
  right after a live migration (performance overhead may be up to 15%).

New features
  * Add `noreturn` option for operations:
    `insert`, `insert_object`, `insert_many`, `insert_object_many`,
    `replace`, `replace_object`, `replace_many`, `insert_object_many`,
    `upsert`, `upsert_object`, `upsert_many`, `upsert_object_many`,
    `update`, `delete` (#267).

Bugfixes
  * Crud DML operations returning stale schema for metadata generation.
    Now you may use `fetch_latest_metadata` flag to work with latest
    schema (#236).

1 of 1 new or added line in 1 file covered. (100.0%)

4549 of 4888 relevant lines covered (93.06%)

18261.17 hits per line

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

94.62
/crud/get.lua
1
local checks = require('checks')
404✔
2
local errors = require('errors')
404✔
3

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

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

15
local get = {}
404✔
16

17
local GET_FUNC_NAME = '_crud.get_on_storage'
404✔
18

19
local function get_on_storage(space_name, key, field_names, opts)
20
    dev_checks('string', '?', '?table', {
210✔
21
        sharding_key_hash = '?number',
22
        sharding_func_hash = '?number',
23
        skip_sharding_hash_check = '?boolean',
24
        fetch_latest_metadata = '?boolean',
25
    })
26

27
    opts = opts or {}
210✔
28

29
    local space = box.space[space_name]
210✔
30
    if space == nil then
210✔
31
        return nil, GetError:new("Space %q doesn't exist", space_name)
×
32
    end
33

34
    local _, err = sharding.check_sharding_hash(space_name,
420✔
35
                                                opts.sharding_func_hash,
210✔
36
                                                opts.sharding_key_hash,
210✔
37
                                                opts.skip_sharding_hash_check)
210✔
38

39
    if err ~= nil then
210✔
40
        return nil, err
2✔
41
    end
42

43
    -- add_space_schema_hash is false because
44
    -- reloading space format on router can't avoid get error on storage
45
    return schema.wrap_box_space_func_result(space, 'get', {key}, {
208✔
46
        add_space_schema_hash = false,
47
        field_names = field_names,
208✔
48
        fetch_latest_metadata = opts.fetch_latest_metadata,
208✔
49
    })
208✔
50
end
51

52
function get.init()
404✔
53
   _G._crud.get_on_storage = get_on_storage
302✔
54
end
55

56
-- returns result, err, need_reload
57
-- need_reload indicates if reloading schema could help
58
-- see crud.common.schema.wrap_func_reload()
59
local function call_get_on_router(vshard_router, space_name, key, opts)
60
    dev_checks('table', 'string', '?', {
246✔
61
        timeout = '?number',
62
        bucket_id = '?number|cdata',
63
        fields = '?table',
64
        prefer_replica = '?boolean',
65
        balance = '?boolean',
66
        mode = '?string',
67
        vshard_router = '?string|table',
68
        fetch_latest_metadata = '?boolean',
69
    })
70

71
    local space, err, netbox_schema_version = utils.get_space(space_name, vshard_router, opts.timeout)
246✔
72
    if err ~= nil then
246✔
73
        return nil, GetError:new("An error occurred during the operation: %s", err), const.NEED_SCHEMA_RELOAD
×
74
    end
75
    if space == nil then
246✔
76
        return nil, GetError:new("Space %q doesn't exist", space_name), const.NEED_SCHEMA_RELOAD
60✔
77
    end
78

79
    if box.tuple.is(key) then
432✔
80
        key = key:totable()
×
81
    end
82

83
    local sharding_key = key
216✔
84
    local sharding_key_hash = nil
216✔
85
    local skip_sharding_hash_check = nil
86

87
    if opts.bucket_id == nil then
216✔
88
        local primary_index_parts = space.index[0].parts
168✔
89

90
        local sharding_key_data, err = sharding_metadata_module.fetch_sharding_key_on_router(vshard_router, space_name)
168✔
91
        if err ~= nil then
168✔
92
            return nil, err
×
93
        end
94

95
        sharding_key, err = sharding_key_module.extract_from_pk(vshard_router,
336✔
96
                                                                space_name,
168✔
97
                                                                sharding_key_data.value,
168✔
98
                                                                primary_index_parts, key)
336✔
99
        if err ~= nil then
168✔
100
            return nil, err
4✔
101
        end
102

103
        sharding_key_hash = sharding_key_data.hash
164✔
104
    else
105
        skip_sharding_hash_check = true
48✔
106
    end
107

108
    local bucket_id_data, err = sharding.key_get_bucket_id(vshard_router, space_name, sharding_key, opts.bucket_id)
212✔
109
    if err ~= nil then
212✔
110
        return nil, err
×
111
    end
112

113
    local get_on_storage_opts = {
212✔
114
        sharding_func_hash = bucket_id_data.sharding_func_hash,
212✔
115
        sharding_key_hash = sharding_key_hash,
212✔
116
        skip_sharding_hash_check = skip_sharding_hash_check,
212✔
117
        fetch_latest_metadata = opts.fetch_latest_metadata,
212✔
118
    }
119

120
    local call_opts = {
212✔
121
        mode = opts.mode or 'read',
212✔
122
        prefer_replica = opts.prefer_replica,
212✔
123
        balance = opts.balance,
212✔
124
        timeout = opts.timeout,
212✔
125
    }
126

127
    local storage_result, err = call.single(vshard_router,
424✔
128
        bucket_id_data.bucket_id, GET_FUNC_NAME,
212✔
129
        {space_name, key, opts.fields, get_on_storage_opts},
212✔
130
        call_opts
131
    )
212✔
132

133
    if err ~= nil then
212✔
134
        local err_wrapped = GetError:new("Failed to call get on storage-side: %s", err)
4✔
135

136
        if sharding.result_needs_sharding_reload(err) then
8✔
137
            return nil, err_wrapped, const.NEED_SHARDING_RELOAD
2✔
138
        end
139

140
        return nil, err_wrapped
2✔
141
    end
142

143
    if storage_result.err ~= nil then
208✔
144
        return nil, GetError:new("Failed to get: %s", storage_result.err)
60✔
145
    end
146

147
    local tuple = storage_result.res
178✔
148

149
    -- protect against box.NULL
150
    if tuple == nil then
178✔
151
        tuple = nil
90✔
152
    end
153

154
    if opts.fetch_latest_metadata == true then
178✔
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,
4✔
159
                                                                vshard_router, opts, storage_result.storage_info)
4✔
160
    end
161

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

165
--- Get tuple from the specified space by key
166
--
167
-- @function call
168
--
169
-- @param string space_name
170
--  A space name
171
--
172
-- @param key
173
--  Primary key value
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 ?boolean opts.prefer_replica
183
--  Call on replica if it's possible
184
--
185
-- @tparam ?boolean opts.balance
186
--  Use replica according to round-robin load balancing
187
--
188
-- @tparam ?string|table opts.vshard_router
189
--  Cartridge vshard group name or vshard router instance.
190
--  Set this parameter if your space is not a part of the
191
--  default vshard cluster.
192
--
193
-- @return[1] object
194
-- @treturn[2] nil
195
-- @treturn[2] table Error description
196
--
197
function get.call(space_name, key, opts)
404✔
198
    checks('string', '?', {
236✔
199
        timeout = '?number',
200
        bucket_id = '?number|cdata',
201
        fields = '?table',
202
        prefer_replica = '?boolean',
203
        balance = '?boolean',
204
        mode = '?string',
205
        vshard_router = '?string|table',
206
        fetch_latest_metadata = '?boolean',
207
    })
208

209
    opts = opts or {}
236✔
210

211
    local vshard_router, err = utils.get_vshard_router_instance(opts.vshard_router)
236✔
212
    if err ~= nil then
236✔
213
        return nil, GetError:new(err)
16✔
214
    end
215

216
    return schema.wrap_func_reload(vshard_router, sharding.wrap_method, call_get_on_router,
228✔
217
                                   space_name, key, opts)
228✔
218
end
219

220
return get
404✔
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