Skip to content

Commit b26166a

Browse files
committed
Use DDL sharding key in select operation
Part of #166
1 parent da31fca commit b26166a

File tree

3 files changed

+61
-5
lines changed

3 files changed

+61
-5
lines changed

crud/common/sharding.lua

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ local utils = require('crud.common.utils')
77

88
local sharding = {}
99

10+
local sharding_key_cache = nil
11+
1012
function sharding.key_get_bucket_id(key, specified_bucket_id)
1113
if specified_bucket_id ~= nil then
1214
return specified_bucket_id
@@ -51,4 +53,22 @@ function sharding.tuple_set_and_return_bucket_id(tuple, space, specified_bucket_
5153
return bucket_id
5254
end
5355

56+
-- Get sharding key (actually field names) for all spaces in schema
57+
-- and cache it's value to speedup access.
58+
function sharding.get_ddl_sharding_key(space_name)
59+
if box.space._ddl_sharding_key == nil then
60+
return nil
61+
end
62+
63+
if sharding_key_cache == nil then
64+
sharding_key_cache = box.space._ddl_sharding_key:select{}
65+
end
66+
67+
if space_name ~= nil then
68+
return sharding_key_cache[space_name]
69+
else
70+
return sharding_key_cache
71+
end
72+
end
73+
5474
return sharding

crud/common/utils.lua

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,24 @@ function utils.get_bucket_id_fieldno(space, shard_index_name)
375375
return bucket_id_index.parts[1].fieldno
376376
end
377377

378+
-- NOTE: it is like get_bucket_id_fieldno()
379+
-- but it uses space's format instead of index
380+
function utils.get_fieldno_by_name(space_format, field_name)
381+
field_name = field_name or 'bucket_id'
382+
local field_idx
383+
for i, field_format in ipairs(space_format) do
384+
if field_format.name == field_name then
385+
field_idx = i
386+
break
387+
end
388+
end
389+
if field_idx == nil then
390+
return nil, ShardingError:new('%q field is not found in a space format', field_name)
391+
end
392+
393+
return field_idx
394+
end
395+
378396
local uuid_t = ffi.typeof('struct tt_uuid')
379397
function utils.is_uuid(value)
380398
return ffi.istype(uuid_t, value)

crud/select/plan.lua

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ local errors = require('errors')
33
local compare_conditions = require('crud.compare.conditions')
44
local utils = require('crud.common.utils')
55
local dev_checks = require('crud.common.dev_checks')
6+
local sharding = require('crud.common.sharding')
67

78
local compat = require('crud.common.compat')
89
local has_keydef = compat.exists('tuple.keydef', 'key_def')
@@ -48,7 +49,7 @@ local function get_index_for_condition(space_indexes, space_format, condition)
4849
end
4950
end
5051

51-
local function extract_sharding_key_from_scan_value(scan_value, scan_index, sharding_index)
52+
local function extract_sharding_key_from_scan_value(scan_value, scan_index, sharding_index, space_format, space_name)
5253
if #scan_value < #sharding_index.parts then
5354
return nil
5455
end
@@ -62,6 +63,9 @@ local function extract_sharding_key_from_scan_value(scan_value, scan_index, shar
6263
scan_value_fields_values[scan_index_part.fieldno] = scan_value[i]
6364
end
6465

66+
-- getting sharding_key specified in DDL schema
67+
local ddl_sharding_key = sharding.get_ddl_sharding_key(space_name)
68+
6569
-- check that sharding key is included in the scan index fields
6670
local sharding_key = {}
6771
for _, sharding_key_part in ipairs(sharding_index.parts) do
@@ -79,7 +83,20 @@ local function extract_sharding_key_from_scan_value(scan_value, scan_index, shar
7983
return nil
8084
end
8185

82-
table.insert(sharding_key, field_value)
86+
-- check if a field is a part of DDL sharding key
87+
local is_sharding_key_found = false
88+
if ddl_sharding_key ~= nil then
89+
for _, field_name in ipairs(ddl_sharding_key) do
90+
if fieldno == utils.get_fieldno_by_name(space_format, field_name) then
91+
is_sharding_key_found = true
92+
break
93+
end
94+
end
95+
end
96+
97+
if ddl_sharding_key == nil or is_sharding_key_found == true then
98+
table.insert(sharding_key, field_value)
99+
end
83100
end
84101

85102
return sharding_key
@@ -226,12 +243,13 @@ function select_plan.new(space, conditions, opts)
226243
end
227244
end
228245

229-
local sharding_index = primary_index -- XXX: only sharding by primary key is supported
230-
246+
-- getting sharding_key used in primary_index
247+
local sharding_index = primary_index
231248
-- get sharding key value
232249
local sharding_key
233250
if scan_value ~= nil and (scan_iter == box.index.EQ or scan_iter == box.index.REQ) then
234-
sharding_key = extract_sharding_key_from_scan_value(scan_value, scan_index, sharding_index)
251+
sharding_key = extract_sharding_key_from_scan_value(scan_value, scan_index,
252+
sharding_index, space_format, space_name)
235253
end
236254

237255
if sharding_key ~= nil and opts.force_map_call ~= true then

0 commit comments

Comments
 (0)