Skip to content

Commit 1d98a49

Browse files
committed
sharding func: fix specifying vshard sharding funcs
Starting from 0.11.0 user can specify sharding func to calculate bucket_id with sharding func definition as a part of DDL schema or insert manually to the space `_ddl_sharding_func`. Right now ddl fails with setting schema with vshard sharding function. But even if this bug is fixed, there is also a bug on CRUD side. Inserting manually to the space `_ddl_sharding_func` showed that CRUD search vshard sharding func in `_G` but this approach doesn't work with vshard case. This patch allows to specify `vshard` sharding func inserting manually to the space `_ddl_sharding_func`. Closes #314
1 parent a7a3413 commit 1d98a49

File tree

5 files changed

+94
-2
lines changed

5 files changed

+94
-2
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1313

1414
### Fixed
1515

16+
- Fix specifying `vshard` sharding funcs (#314).
17+
1618
## [0.12.1] - 21-07-22
1719

1820
### Fixed

crud/common/sharding/sharding_func.lua

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ local ShardingFuncError = errors.new_class('ShardingFuncError', {capture_stack
99

1010
local sharding_func_module = {}
1111

12+
local sharding_module_names = {
13+
['vshard'] = true,
14+
}
15+
1216
local function is_callable(object)
1317
if type(object) == 'function' then
1418
return true
@@ -43,13 +47,25 @@ end
4347
local function get_function_from_G(func_name)
4448
local chunks = string.split(func_name, '.')
4549
local sharding_func = _G
50+
local sharding_module = false
51+
52+
if sharding_module_names[chunks[1]] then
53+
sharding_func = require(chunks[1])
54+
sharding_module = true
55+
table.remove(chunks, 1)
56+
end
4657

4758
-- check is the each chunk an identifier
4859
for _, chunk in pairs(chunks) do
4960
if not utils.check_name_isident(chunk) or sharding_func == nil then
5061
return nil
5162
end
52-
sharding_func = rawget(sharding_func, chunk)
63+
64+
if sharding_module then
65+
sharding_func = sharding_func[chunk]
66+
else
67+
sharding_func = rawget(sharding_func, chunk)
68+
end
5369
end
5470

5571
return sharding_func

test/entrypoint/srv_ddl.lua

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ package.preload['customers-storage'] = function()
161161
local customers_G_func_schema = table.deepcopy(customers_id_key_schema)
162162
customers_G_func_schema.sharding_func = 'some_module.sharding_func'
163163

164+
local customers_vshard_func_schema = table.deepcopy(customers_id_key_schema)
165+
164166
local schema = {
165167
spaces = {
166168
customers = customers_id_schema,
@@ -173,6 +175,7 @@ package.preload['customers-storage'] = function()
173175
customers_name_age_key_three_fields_index = customers_name_age_key_three_fields_index_schema,
174176
customers_G_func = customers_G_func_schema,
175177
customers_body_func = customers_body_func_schema,
178+
customers_vshard_func = customers_vshard_func_schema,
176179
}
177180
}
178181

@@ -188,7 +191,9 @@ package.preload['customers-storage'] = function()
188191
box.space['_ddl_sharding_key']:update(space_name, {{'=', fieldno_sharding_key, sharding_key_def}})
189192
end)
190193
rawset(_G, 'set_sharding_func', function(space_name, fieldno_sharding_func, sharding_func_def)
191-
box.space['_ddl_sharding_func']:update(space_name, {{'=', fieldno_sharding_func, sharding_func_def}})
194+
local record = {space_name, box.NULL, box.NULL}
195+
record[fieldno_sharding_func] = sharding_func_def
196+
box.space['_ddl_sharding_func']:replace(record)
192197
end)
193198
end,
194199
}

test/integration/ddl_sharding_func_test.lua

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ cache_group.after_all(function(g) helpers.stop_cluster(g.cluster) end)
7575
cache_group.before_each(function(g)
7676
helpers.truncate_space_on_cluster(g.cluster, 'customers_G_func')
7777
helpers.truncate_space_on_cluster(g.cluster, 'customers_body_func')
78+
helpers.truncate_space_on_cluster(g.cluster, 'customers_vshard_func')
7879
end)
7980

8081
pgroup.test_insert_object = function(g)
@@ -938,3 +939,68 @@ pgroup.test_gh_278_count_with_explicit_bucket_id_and_ddl = function(g)
938939
t.assert_is_not(obj, nil)
939940
t.assert_equals(obj, 1)
940941
end
942+
943+
local vshard_cases = {
944+
mpcrc32 = {
945+
sharding_func_name = 'vshard.router.bucket_id_mpcrc32',
946+
bucket_id = 1614,
947+
srv_with_data = 's1-master',
948+
srv_without_data = 's2-master',
949+
},
950+
strcrc32 = {
951+
sharding_func_name = 'vshard.router.bucket_id_strcrc32',
952+
bucket_id = 477,
953+
srv_with_data = 's2-master',
954+
srv_without_data = 's1-master',
955+
}
956+
}
957+
958+
for name, case in pairs(vshard_cases) do
959+
local test_name = ('test_vshard_%s_sharding_func'):format(name)
960+
961+
cache_group[test_name] = function(g)
962+
local fieldno_sharding_func_name = 2
963+
local space_name = 'customers_vshard_func'
964+
965+
helpers.call_on_servers(g.cluster, {'s1-master', 's2-master'}, function(server)
966+
server.net_box:call('set_sharding_func',
967+
{space_name, fieldno_sharding_func_name, case.sharding_func_name})
968+
end)
969+
970+
local record_exist, err = helpers.update_sharding_func_cache(g.cluster, space_name)
971+
t.assert_equals(err, nil)
972+
t.assert_equals(record_exist, true)
973+
974+
-- Insert a tuple.
975+
local result, err = g.cluster.main_server.net_box:call(
976+
'crud.insert', {space_name, {1, box.NULL, 'Ivan', 25}})
977+
t.assert_equals(err, nil)
978+
t.assert_equals(result.metadata, {
979+
{is_nullable = false, name = 'id', type = 'unsigned'},
980+
{is_nullable = false, name = 'bucket_id', type = 'unsigned'},
981+
{is_nullable = false, name = 'name', type = 'string'},
982+
{is_nullable = false, name = 'age', type = 'number'},
983+
})
984+
t.assert_equals(#result.rows, 1)
985+
t.assert_equals(result.rows[1], {1, case.bucket_id, 'Ivan', 25})
986+
987+
-- There is a tuple on server that we inserted before using crud.insert().
988+
local conn_srv_with_data = g.cluster:server(case.srv_with_data).net_box
989+
local result = conn_srv_with_data.space[space_name]:get({1})
990+
t.assert_equals(result, {1, case.bucket_id, 'Ivan', 25})
991+
992+
-- There is no tuple on server that we inserted before using crud.insert().
993+
local conn_srv_without_data = g.cluster:server(case.srv_without_data).net_box
994+
local result = conn_srv_without_data.space[space_name]:get({1})
995+
t.assert_equals(result, nil)
996+
997+
local conditions = {{'==', 'id', 1}}
998+
local result, err = g.cluster.main_server.net_box:call('crud.select', {
999+
space_name, conditions,
1000+
})
1001+
1002+
t.assert_equals(err, nil)
1003+
t.assert_equals(#result.rows, 1)
1004+
t.assert_equals(result.rows[1], {1, case.bucket_id, 'Ivan', 25})
1005+
end
1006+
end

test/integration/ddl_sharding_key_test.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,7 @@ pgroup.test_update_cache_with_incorrect_key = function(g)
898898
customers = {parts = {{fieldno = 1}}},
899899
customers_G_func = {parts = {{fieldno = 1}}},
900900
customers_body_func = {parts = {{fieldno = 1}}},
901+
customers_vshard_func = {parts = {{fieldno = 1}}},
901902
customers_age_key = {parts = {{fieldno = 4}}},
902903
customers_name_age_key_different_indexes = {parts = {{fieldno = 3}, {fieldno = 4}}},
903904
customers_name_age_key_three_fields_index = {parts = {{fieldno = 3}, {fieldno = 4}}},
@@ -925,6 +926,7 @@ pgroup.test_update_cache_with_incorrect_key = function(g)
925926
customers = {parts = {{fieldno = 1}}},
926927
customers_G_func = {parts = {{fieldno = 1}}},
927928
customers_body_func = {parts = {{fieldno = 1}}},
929+
customers_vshard_func = {parts = {{fieldno = 1}}},
928930
customers_age_key = {parts = {{fieldno = 4}}},
929931
customers_name_age_key_different_indexes = {parts = {{fieldno = 3}, {fieldno = 4}}},
930932
customers_name_age_key_three_fields_index = {parts = {{fieldno = 3}, {fieldno = 4}}},
@@ -951,6 +953,7 @@ pgroup.test_update_cache_with_incorrect_key = function(g)
951953
customers = {parts = {{fieldno = 1}}},
952954
customers_G_func = {parts = {{fieldno = 1}}},
953955
customers_body_func = {parts = {{fieldno = 1}}},
956+
customers_vshard_func = {parts = {{fieldno = 1}}},
954957
customers_age_key = {parts = {{fieldno = 4}}},
955958
customers_name_age_key_different_indexes = {parts = {{fieldno = 3}, {fieldno = 4}}},
956959
customers_name_age_key_three_fields_index = {parts = {{fieldno = 3}, {fieldno = 4}}},

0 commit comments

Comments
 (0)