Skip to content

Commit

Permalink
select: fix processing storage error for tuple-merger
Browse files Browse the repository at this point in the history
Storage select/pairs method responds with `nil, err` if something went
wrong. tuple-merger implementation of select/pairs do not support this
type of response, resulting in fail while trying to subscribe nil value.
The patch fixes this behavior by extracting second return value in case
of `nil, err` and wrapping it with errors wrapper to restore errors
metatable.

Closes #271
  • Loading branch information
DifferentialOrange committed Apr 8, 2022
1 parent 249690a commit c8d496b
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 3 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
* Optimize select with known bucket_id (#234).

### Fixed
* Fix processing storage error for tuple-merger implementation of
select/pairs (#271).

## [0.10.0] - 01-12-21

Expand Down
16 changes: 13 additions & 3 deletions crud/select/merger.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
local buffer = require('buffer')
local errors = require('errors')
local msgpack = require('msgpack')
local ffi = require('ffi')
local call = require('crud.common.call')
Expand Down Expand Up @@ -80,9 +81,14 @@ local function decode_metainfo(buf)
buf.rpos = decode_response_headers(buf)

-- Decode a first return value (metainfo).
local res
local res, err
res, buf.rpos = msgpack.decode(buf.rpos, buf:size())
return res

-- If res is nil, decode second return value (error).
if res == nil then
err, buf.rpos = msgpack.decode(buf.rpos, buf:size())
end
return res, err
end

--- Wait for a data chunk and request for the next data chunk.
Expand All @@ -109,7 +115,11 @@ local function fetch_chunk(context, state)
end

-- Decode metainfo, leave data to be processed by the merger.
local cursor = decode_metainfo(buf)
local cursor, err = decode_metainfo(buf)
if cursor == nil then
-- Wrap net.box errors error to restore metatable.
error(errors.wrap(err))
end

-- Extract stats info.
-- Stats extracted with callback here and not passed
Expand Down
36 changes: 36 additions & 0 deletions test/integration/select_test.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1654,3 +1654,39 @@ pgroup.test_select_no_map_reduce = function(g)
local diff_2 = map_reduces_after_2 - map_reduces_after_1
t.assert_equals(diff_2, 0, 'Select request was not a map reduce')
end

pgroup.before_test('test_storage_nil_err_is_processed', function(g)
helpers.call_on_storages(g.cluster, function(server)
server.net_box:eval([[
local errors = require('errors')
local StorageError = errors.new_class("StorageError")
local _crud = rawget(_G, '_crud')
rawset(_G, '_real_crud_select', _crud.select_on_storage)
local return_err = function()
return nil, StorageError:new('My storage error')
end
_crud.select_on_storage = return_err
]])
end)
end)

pgroup.after_test('test_storage_nil_err_is_processed', function(g)
helpers.call_on_storages(g.cluster, function(server)
server.net_box:eval([[
local _crud = rawget(_G, '_crud')
_crud.select_on_storage = rawget(_G, '_real_crud_select')
rawset(_G, '_real_crud_select', nil)
]])
end)
end)

pgroup.test_storage_nil_err_is_processed = function(g)
local obj, err = g.cluster.main_server.net_box:call('crud.select', {
'customers', {{'==', 'age', 101}}
})
t.assert_equals(obj, nil)
t.assert_str_contains(err.str, 'StorageError', 'Storage error class is preserved')
t.assert_str_contains(err.str, 'My storage error', 'Storage error msg is preserved')
end

0 comments on commit c8d496b

Please sign in to comment.