From 8cdac9d2d5c93900c35a4a81c3eb9c3a778b25b6 Mon Sep 17 00:00:00 2001 From: Nikita Zheleztsov Date: Tue, 21 Nov 2023 22:37:11 +0300 Subject: [PATCH] storage: fix local_call not finding persistent func Currently, if function was created as C stored procedure or as Lua persistent function (with body argument) via box.schema.func.create, all types of router.call and router.map_callrw cannot find it and return `Procedure 'name' is not defined` error. This is cased by the fact that both of these function use local_call, which invokes net_box.self.call, which doesn't currently work with C stored procedures due to the bug. Let's use box.func, where it's possible instead of net_box.self.call in local_call. Closes #436 NO_DOC=bugfix --- test/storage-luatest/storage_1_test.lua | 14 ++++++++++++++ vshard/storage/init.lua | 12 +++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/test/storage-luatest/storage_1_test.lua b/test/storage-luatest/storage_1_test.lua index ef2a453f..2739bc80 100644 --- a/test/storage-luatest/storage_1_test.lua +++ b/test/storage-luatest/storage_1_test.lua @@ -168,3 +168,17 @@ test_group.test_recovery_bucket_stat = function(g) vtest.cluster_cfg(g, global_cfg) end + +test_group.test_local_call = function(g) + -- box.func was introduced in 2.2.0. + t.run_only_if(vutil.version_is_at_least(2, 2, 0, nil, 0, 0)) + g.replica_1_a:exec(function() + local body = [[function(a, b) return a + b end]] + box.schema.func.create('sum', {body = body}) + local bid = _G.get_first_bucket() + local ok, ret = ivshard.storage.call(bid, 'read', 'sum', {1, 2}) + ilt.assert_equals(ret, 3) + ilt.assert_equals(ok, true) + box.func.sum:drop() + end) +end diff --git a/vshard/storage/init.lua b/vshard/storage/init.lua index 68bc9eff..5c0703ad 100644 --- a/vshard/storage/init.lua +++ b/vshard/storage/init.lua @@ -266,7 +266,17 @@ end -- exceptions are not allowed. -- local function local_call(func_name, args) - return pcall(netbox_self_call, netbox_self, func_name, args) + -- If function was created with box.schema.func we call it via + -- func.call API, as net_box.self.call doesn't work with C stored + -- procedures up to Tarantool 3.X. If box.func is inaccessible, + -- which is true for all versions below 2.2, we fallback to + -- net_box.self.call too. + if box.func == nil or box.func[func_name] == nil then + return pcall(netbox_self_call, netbox_self, func_name, args) + end + + local func = box.func[func_name] + return pcall(func.call, func, args) end local function master_call(replicaset, func, args, opts)