From 9d3f87e7c779aa84c1bd2964255a2600cf763e47 Mon Sep 17 00:00:00 2001
From: Arseniy Volynets <vol0ncar@yandex.ru>
Date: Thu, 23 May 2024 20:08:27 +0000
Subject: [PATCH] fix: update for bucket_id in the middle

---
 .../test_app/test/integration/update_test.lua | 67 +++++++++++++++++++
 .../src/ir/transformation/redistribution.rs   | 13 +++-
 2 files changed, 79 insertions(+), 1 deletion(-)

diff --git a/sbroad-cartridge/test_app/test/integration/update_test.lua b/sbroad-cartridge/test_app/test/integration/update_test.lua
index 95d8c515d..dd5480d3c 100644
--- a/sbroad-cartridge/test_app/test/integration/update_test.lua
+++ b/sbroad-cartridge/test_app/test/integration/update_test.lua
@@ -84,6 +84,21 @@ update_queries.before_each(
             })
             t.assert_equals(err, nil)
             t.assert_equals(r, {row_count = 2})
+
+            r, err = api:call("sbroad.execute", {
+                [[INSERT INTO "testing_space_bucket_in_the_middle" ("id", "name", "product_units") VALUES
+                (?, ?, ?),
+                (?, ?, ?),
+                (?, ?, ?)
+                ]],
+                {
+                    1, "1", 1,
+                    2, "1", 1,
+                    3, "1", 1,
+                }
+            })
+            t.assert_equals(err, nil)
+            t.assert_equals(r, {row_count = 3})
         end
 )
 
@@ -93,12 +108,14 @@ update_queries.after_each(function()
     storage1:call("box.execute", { [[TRUNCATE TABLE "arithmetic_space"]] })
     storage1:call("box.execute", { [[TRUNCATE TABLE "arithmetic_space2"]] })
     storage1:call("box.execute", { [[TRUNCATE TABLE "double_t"]] })
+    storage1:call("box.execute", { [[TRUNCATE TABLE "testing_space_bucket_in_the_middle"]] })
 
     local storage2 = cluster:server("storage-2-1").net_box
     storage2:call("box.execute", { [[TRUNCATE TABLE "testing_space"]] })
     storage2:call("box.execute", { [[TRUNCATE TABLE "arithmetic_space"]] })
     storage2:call("box.execute", { [[TRUNCATE TABLE "arithmetic_space2"]] })
     storage2:call("box.execute", { [[TRUNCATE TABLE "double_t"]] })
+    storage2:call("box.execute", { [[TRUNCATE TABLE "testing_space_bucket_in_the_middle"]] })
 end)
 
 update_queries.after_all(function()
@@ -487,3 +504,53 @@ update_queries.test_type_conversion = function()
         { 2, 3.14, 2.7 },
     })
 end
+
+update_queries.test_bucket_id_in_the_middle = function()
+    local api = cluster:server("api-1").net_box
+
+    -- sharded update
+    local r, err = api:call("sbroad.execute", { [[
+    update "testing_space_bucket_in_the_middle"
+    set "name" = '2'
+    ]], {} })
+    t.assert_equals(err, nil)
+    t.assert_equals(r, {row_count = 3})
+
+    -- check that table was updated
+    r, err = api:call("sbroad.execute", { [[
+        SELECT "name"
+        FROM "testing_space_bucket_in_the_middle"
+    ]], {} })
+    t.assert_equals(err, nil)
+    t.assert_equals(r.metadata, {
+        { name = "name", type = "string" },
+    })
+    t.assert_items_equals(r.rows, {
+        { "2" },
+        { "2" },
+        { "2" },
+    })
+
+    -- local update
+    r, err = api:call("sbroad.execute", { [[
+    update "testing_space_bucket_in_the_middle"
+    set "product_units" = 42
+    ]], {} })
+    t.assert_equals(err, nil)
+    t.assert_equals(r, {row_count = 3})
+
+    -- check that table was updated
+    r, err = api:call("sbroad.execute", { [[
+        SELECT "product_units"
+        FROM "testing_space_bucket_in_the_middle"
+    ]], {} })
+    t.assert_equals(err, nil)
+    t.assert_equals(r.metadata, {
+        { name = "product_units", type = "integer" },
+    })
+    t.assert_items_equals(r.rows, {
+        { 42 },
+        { 42 },
+        { 42 },
+    })
+end
diff --git a/sbroad-core/src/ir/transformation/redistribution.rs b/sbroad-core/src/ir/transformation/redistribution.rs
index c6ed46c46..f7ba50d70 100644
--- a/sbroad-core/src/ir/transformation/redistribution.rs
+++ b/sbroad-core/src/ir/transformation/redistribution.rs
@@ -1695,7 +1695,18 @@ impl Plan {
             }
             match kind {
                 UpdateStrategy::ShardedUpdate { .. } => {
-                    let new_shard_cols_positions = table.get_sk()?.to_vec();
+                    let new_shard_cols_positions = {
+                        let mut positions = table.get_sk()?.to_vec();
+                        let bucket_id_pos = table
+                            .get_bucket_id_position()?
+                            .expect("wrong update strategy");
+                        for pos in &mut positions {
+                            if *pos > bucket_id_pos {
+                                *pos -= 1;
+                            }
+                        }
+                        positions
+                    };
                     let op = MotionOpcode::RearrangeForShardedUpdate {
                         update_id,
                         old_shard_columns_len: table.get_sk()?.len(),
-- 
GitLab