@@ -230,6 +230,17 @@ strnindex(const char **haystack, const char *needle, uint32_t len, uint32_t hmax
230230 return hmax ;
231231}
232232
233+ /**
234+ * Strict compare a null-terminated string with a length specified
235+ * string.
236+ */
237+ static inline bool
238+ strncmp_strict (const char * str , size_t str_len , const char * str_null_term )
239+ {
240+ return (strncmp (str , str_null_term , str_len ) == 0 &&
241+ strlen (str_null_term ) == str_len );
242+ }
243+
233244static enum field_type
234245field_type_by_name (const char * name , size_t len )
235246{
@@ -275,6 +286,18 @@ parse_schema_space_value_value(struct schema_field_value *fld,
275286 return -1 ;
276287}
277288
289+ /**
290+ * Initialization value.
291+ */
292+ static const struct schema_field_value field_val_def = {
293+ .field_number = 0 ,
294+ .field_name_len = 0 ,
295+ .field_name = NULL ,
296+ .field_type = field_type_MAX ,
297+ .coll_id = COLL_NONE ,
298+ .is_nullable = false
299+ };
300+
278301static int
279302parse_schema_space_value (struct schema_space_value * space_string ,
280303 const char * * tuple ) {
@@ -314,6 +337,7 @@ decode_index_parts_166(struct schema_field_value *parts, uint32_t part_count,
314337{
315338 for (uint32_t i = 0 ; i < part_count ; ++ i ) {
316339 struct schema_field_value * part = & parts [i ];
340+ * part = field_val_def ;
317341 if (mp_typeof (* * data ) != MP_ARRAY )
318342 return -1 ;
319343 uint32_t item_count = mp_decode_array (data );
@@ -332,9 +356,69 @@ decode_index_parts_166(struct schema_field_value *parts, uint32_t part_count,
332356
333357 for (uint32_t j = 2 ; j < item_count ; ++ j )
334358 mp_next (data );
335- /* Set default values. */
336- part -> is_nullable = false;
337- part -> coll_id = COLL_NONE ;
359+ }
360+ return 0 ;
361+ }
362+
363+ static int
364+ decode_index_part (struct schema_field_value * part , uint32_t map_size ,
365+ const char * * data )
366+ {
367+ * part = field_val_def ;
368+ for (uint32_t i = 0 ; i < map_size ; ++ i ) {
369+ if (mp_typeof (* * data ) != MP_STR )
370+ return -1 ;
371+
372+ uint32_t k_len ;
373+ const char * key = mp_decode_str (data , & k_len );
374+ if (strncmp_strict (key , k_len , "type" )) {
375+ if (mp_typeof (* * data ) != MP_STR )
376+ return -1 ;
377+ uint32_t v_len ;
378+ const char * val = mp_decode_str (data , & v_len );
379+ part -> field_type = field_type_by_name (val , v_len );
380+ } else if (strncmp_strict (key , k_len , "field" )) {
381+ if (mp_typeof (* * data ) != MP_UINT )
382+ return -1 ;
383+ part -> field_number = mp_decode_uint (data );
384+ } else if (strncmp_strict (key , k_len , "collation" )) {
385+ if (mp_typeof (* * data ) != MP_UINT )
386+ return -1 ;
387+ part -> coll_id = mp_decode_uint (data );
388+ } else if (strncmp_strict (key , k_len , "is_nullable" )) {
389+ if (mp_typeof (* * data ) != MP_BOOL )
390+ return -1 ;
391+ part -> is_nullable = mp_decode_bool (data );
392+ } else {
393+ mp_next (data );
394+ }
395+ }
396+
397+ /* Collation is reasonable only for string and scalar parts. */
398+ if (part -> coll_id != COLL_NONE &&
399+ part -> field_type != FIELD_TYPE_STRING &&
400+ part -> field_type != FIELD_TYPE_SCALAR ) {
401+ return -1 ;
402+ }
403+
404+ return 0 ;
405+ }
406+
407+ /**
408+ * Decode parts array from tuple field.
409+ */
410+ static int
411+ decode_index_parts (struct schema_field_value * parts , uint32_t part_count ,
412+ const char * * data )
413+ {
414+ for (uint32_t i = 0 ; i < part_count ; ++ i ) {
415+ struct schema_field_value * part = & parts [i ];
416+ if (mp_typeof (* * data ) != MP_MAP )
417+ return -1 ;
418+
419+ uint32_t map_size = mp_decode_map (data );
420+ if (decode_index_part (part , map_size , data ) != 0 )
421+ return -1 ;
338422 }
339423 return 0 ;
340424}
@@ -355,8 +439,13 @@ parse_schema_index_value(struct schema_index_value *index_string,
355439 sizeof (struct schema_field_value ));
356440
357441 if (mp_typeof (* * tuple ) == MP_ARRAY ) {
442+ /* Base coding format is used. */
358443 return decode_index_parts_166 (index_string -> index_parts ,
359444 part_count , tuple );
445+ } else {
446+ /* Extended coding format is used. */
447+ return decode_index_parts (index_string -> index_parts ,
448+ part_count , tuple );
360449 }
361450
362451error :
0 commit comments