From aa4111ad6ae8f2c4b25e236f63c371eae89ed826 Mon Sep 17 00:00:00 2001 From: Georgy Moshkin <gmoshkin@picodata.io> Date: Mon, 22 Jan 2024 18:13:06 +0300 Subject: [PATCH] fix: support for compat.c_func_iproto_multireturn = 'new' --- sbroad-core/src/core-router.lua | 15 ++++++++++----- sbroad-core/src/helper.lua | 25 +++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/sbroad-core/src/core-router.lua b/sbroad-core/src/core-router.lua index 685c61e4bc..efe14aa4fc 100644 --- a/sbroad-core/src/core-router.lua +++ b/sbroad-core/src/core-router.lua @@ -247,7 +247,8 @@ _G.dql_on_some = function(uuid_to_args, is_readonly, waiting_timeout, vtable_max if err ~= nil then error(err) end - result = res[1][1][1] + -- TODO: explain where this `[1][1]` comes from + result = helper.unwrap_execute_result(res[1][1]) else local err, err_uuid local opts = { map_timeout = waiting_timeout, ref_timeout = waiting_timeout } @@ -320,10 +321,12 @@ _G.dml_on_some = function(tbl_rs_ir, is_readonly, waiting_timeout) error(err) end + -- TODO: explain where this `[1][1]` comes from + local next_result = helper.unwrap_execute_result(res[1][1]) if result == nil then - result = res[1][1][1] + result = next_result else - result.row_count = result.row_count + res[1][1][1].row_count + result.row_count = result.row_count + next_result.row_count end end @@ -369,10 +372,12 @@ _G.dml_on_all = function(required, optional, is_readonly, waiting_timeout) error(err) end + -- TODO: explain where this `[1][1]` comes from + local next_result = helper.unwrap_execute_result(res[1][1]) if result == nil then - result = res[1][1][1] + result = next_result else - result.row_count = result.row_count + res[1][1][1].row_count + result.row_count = result.row_count + next_result.row_count end end diff --git a/sbroad-core/src/helper.lua b/sbroad-core/src/helper.lua index 3e6c18bc8e..56fb73eba7 100644 --- a/sbroad-core/src/helper.lua +++ b/sbroad-core/src/helper.lua @@ -1,3 +1,6 @@ +local compat = require('compat') +local compat_mt = compat ~= nil and getmetatable(compat) or nil + -- Make table read-only local function protect(tbl) return setmetatable({}, { @@ -64,10 +67,32 @@ local function dql_error(err, rs_uuid) error(err) end +local function unwrap_execute_result(result) + if compat_mt == nil then + return result[1] + end + -- We want to just call `compat.c_func_iproto_multireturn:is_new()`, + -- but it throws an exception when the option is unknown. + local ok, opt = pcall(compat_mt.__index, compat, 'c_func_iproto_multireturn') + if ok and opt:is_new() then + -- On older versions of tarantool there was a bug which made all FFI + -- stored procedures' wrap their return values into an additional + -- msgpack array (they call it "multireturn", but you couldn't put + -- multiple values in there, it was hard-coded to be 1 element). But + -- thankfully it was fixed and now we get to rewrite all of our code... + -- Yay! + -- See https://github.com/tarantool/tarantool/issues/4799 + return result + else + return result[1] + end +end + return { module_name = module_name, vtable_limit_exceeded = vtable_limit_exceeded, dql_error = dql_error, format_result = format_result, + unwrap_execute_result = unwrap_execute_result, constants = constants } -- GitLab