Skip to content

Fix plan in case of select operation with custom sharding key #213

@ligurio

Description

@ligurio

Cases:

  • pk with fields id and 'name', select with condition by field name with operator == triggered map-reduce if there is no a separate index by filed 'name' and name 'name'
  • pk = {id1, id3}, sk1={id1, id2}, sk2={id3, id4}. When condition uses sk1 and sk2, then we can recover sharding key too (pair of id1, id3)

rough patch:

diff --git a/crud/select/plan.lua b/crud/select/plan.lua
index 528ac54..7990fb4 100644
--- a/crud/select/plan.lua
+++ b/crud/select/plan.lua
@@ -49,6 +49,34 @@ local function get_index_for_condition(space_indexes, space_format, condition)
     end
 end
 
+-- Check that if fields that included in sharding key and conditions
+-- have iterator equal to box.index.EQ or box.index.REQ.
+local function extract_sharding_key_from_conditions(conditions, ddl_sharding_key)
+    if ddl_sharding_key == nil then
+        return nil
+    end
+
+    local conditions_map = {}
+    for _, condition in ipairs(conditions) do
+        conditions_map[condition.operand] = {
+            iter = condition.operator,
+            values = condition.values,
+        }
+    end
+
+    local sharding_key_values = {}
+    for _, field_name in ipairs(ddl_sharding_key) do
+        local condition = conditions_map[field_name]
+        if condition ~= nil and condition.iter == '==' then
+            table.insert(sharding_key_values, condition.values)
+        end
+    end
+
+        local inspect = require('inspect')
+        print(inspect.inspect(sharding_key_values))
+    return sharding_key_values
+end
+
 local function extract_sharding_key_from_scan_value(scan_value, scan_index, sharding_index)
     if #scan_value < #sharding_index.parts then
         return nil
@@ -241,6 +269,9 @@ function select_plan.new(space, conditions, opts)
     if scan_value ~= nil and (scan_iter == box.index.EQ or scan_iter == box.index.REQ) then
         sharding_key = extract_sharding_key_from_scan_value(scan_value, scan_index, sharding_index)
     end
+    if sharding_key == nil then
+        sharding_key = extract_sharding_key_from_conditions(conditions, ddl_sharding_key)
+    end
 
     if sharding_key ~= nil and opts.force_map_call ~= true then
         total_tuples_count = 1

Part of #166

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions