From 0c1346b12cdf3c3ec6e20564724768950ce97473 Mon Sep 17 00:00:00 2001 From: Nikita Zheleztsov Date: Tue, 28 Nov 2023 21:04:37 +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. It didn't work with these type of functions before Tarantool 3.0.0-beta1-18. Let's use box.func, where it's needed 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 | 21 ++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/test/storage-luatest/storage_1_test.lua b/test/storage-luatest/storage_1_test.lua index ef2a453f..1b9d212f 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.1. + t.run_only_if(vutil.version_is_at_least(2, 2, 1, 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..1dad39b1 100644 --- a/vshard/storage/init.lua +++ b/vshard/storage/init.lua @@ -265,10 +265,29 @@ end -- The function returns pcall() as is, because is used from places where -- exceptions are not allowed. -- -local function local_call(func_name, args) +local local_call + +if util.version_is_at_least(3, 0, 0, 'beta', 1, 18) then + +local_call = function(func_name, args) return pcall(netbox_self_call, netbox_self, func_name, args) end +else -- < 3.0.0-beta1-18 + +-- net_box.self.call() doesn't work with C stored and Lua persistent +-- functions before 3.0.0-beta1-18, so we try to call it via func.call +-- API prior to using net_box.self API. +local_call = function(func_name, args) + local func = box.func and box.func[func_name] + if not func then + return pcall(netbox_self_call, netbox_self, func_name, args) + end + return pcall(func.call, func, args) +end + +end + local function master_call(replicaset, func, args, opts) local deadline = fiber_clock() + opts.timeout local did_first_attempt = false