@@ -7,6 +7,7 @@ local dev_checks = require('crud.common.dev_checks')
7
7
local cache = require (' crud.common.sharding_key_cache' )
8
8
local utils = require (' crud.common.utils' )
9
9
10
+ local ShardingKeyError = errors .new_class (" ShardingKeyError" , {capture_stack = false })
10
11
local FetchShardingKeyError = errors .new_class (' FetchShardingKeyError' , {capture_stack = false })
11
12
local GetShardingKeyFieldnosError = errors .new_class (' GetShardingKeyFieldnosError' , {capture_stack = false })
12
13
@@ -115,6 +116,87 @@ function sharding_key_module.fetch_on_router(space_name)
115
116
return cache .sharding_key_def
116
117
end
117
118
119
+ -- Make sure sharding key definition is a part of primary key.
120
+ function sharding_key_module .is_part_of_pk (space_name , space_format ,
121
+ primary_index , sharding_key_def )
122
+ dev_checks (' string' , ' table' , ' table' , ' table' )
123
+
124
+ if cache .as_index_object [space_name ] == nil then
125
+ cache .as_index_object [space_name ] =
126
+ sharding_key_module .as_index_object (space_format , space_name ,
127
+ sharding_key_def )
128
+ end
129
+ local sharding_key_as_index_obj = cache .as_index_object [space_name ]
130
+
131
+ if cache .is_part_of_pk [space_name ] ~= nil then
132
+ return cache .is_part_of_pk [space_name ]
133
+ end
134
+
135
+ local is_part_of_pk = true
136
+ local pk_fieldno_map = utils .get_index_fieldno_map (primary_index .parts )
137
+ for _ , part in ipairs (sharding_key_as_index_obj .parts ) do
138
+ if pk_fieldno_map [part .fieldno ] == nil then
139
+ is_part_of_pk = false
140
+ break
141
+ end
142
+ end
143
+ cache .is_part_of_pk [space_name ] = is_part_of_pk
144
+
145
+ return is_part_of_pk
146
+ end
147
+
148
+ -- Build an array with sharding key values.
149
+ function sharding_key_module .extract_from_index (sharding_key_def ,
150
+ index_parts ,
151
+ sharding_key_fieldno_map )
152
+ dev_checks (' table' , ' table' , ' table' )
153
+
154
+ local sharding_key = {}
155
+ for i , k in ipairs (sharding_key_def ) do
156
+ local fieldno = index_parts [i ].fieldno
157
+ if sharding_key_fieldno_map [fieldno ] == true then
158
+ table.insert (sharding_key , k )
159
+ end
160
+ end
161
+
162
+ return sharding_key
163
+ end
164
+
165
+ -- Extract sharding key from pk.
166
+ -- Returns a table with sharding key or pair of nil and error.
167
+ function sharding_key_module .extract_from_pk (space_obj , sharding_key )
168
+ dev_checks (' table' , ' ?' )
169
+
170
+ local space_name = space_obj .name
171
+ local sharding_key_def , err = sharding_key_module .fetch_on_router (space_name )
172
+ if err ~= nil then
173
+ return nil , err
174
+ end
175
+ if sharding_key_def == nil then
176
+ return sharding_key
177
+ end
178
+
179
+ local primary_index = space_obj .index [0 ]
180
+ local space_format = space_obj :format ()
181
+
182
+ local is_part_of_pk = sharding_key_module .is_part_of_pk (space_name , space_format ,
183
+ primary_index , sharding_key_def )
184
+ if is_part_of_pk == false then
185
+ return nil , ShardingKeyError :new (
186
+ " Sharding key for space %q is missed in primary index, specify bucket_id" ,
187
+ space_name
188
+ )
189
+ end
190
+ if type (sharding_key ) ~= ' table' then
191
+ sharding_key = {sharding_key }
192
+ end
193
+ local sharding_key_as_index_obj = cache .as_index_object [space_name ]
194
+ local sharding_key_fieldno_map = utils .get_index_fieldno_map (sharding_key_as_index_obj .parts )
195
+
196
+ return sharding_key_module .extract_from_index (sharding_key , primary_index .parts ,
197
+ sharding_key_fieldno_map )
198
+ end
199
+
118
200
function sharding_key_module .init ()
119
201
_G ._crud .fetch_on_storage = sharding_key_module .fetch_on_storage
120
202
end
0 commit comments