@@ -230,6 +230,17 @@ strnindex(const char **haystack, const char *needle, uint32_t len, uint32_t hmax
230
230
return hmax ;
231
231
}
232
232
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
+
233
244
static enum field_type
234
245
field_type_by_name (const char * name , size_t len )
235
246
{
@@ -275,6 +286,18 @@ parse_schema_space_value_value(struct schema_field_value *fld,
275
286
return -1 ;
276
287
}
277
288
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
+
278
301
static int
279
302
parse_schema_space_value (struct schema_space_value * space_string ,
280
303
const char * * tuple ) {
@@ -314,6 +337,7 @@ decode_index_parts_166(struct schema_field_value *parts, uint32_t part_count,
314
337
{
315
338
for (uint32_t i = 0 ; i < part_count ; ++ i ) {
316
339
struct schema_field_value * part = & parts [i ];
340
+ * part = field_val_def ;
317
341
if (mp_typeof (* * data ) != MP_ARRAY )
318
342
return -1 ;
319
343
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,
332
356
333
357
for (uint32_t j = 2 ; j < item_count ; ++ j )
334
358
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 ;
338
422
}
339
423
return 0 ;
340
424
}
@@ -355,8 +439,13 @@ parse_schema_index_value(struct schema_index_value *index_string,
355
439
sizeof (struct schema_field_value ));
356
440
357
441
if (mp_typeof (* * tuple ) == MP_ARRAY ) {
442
+ /* Base coding format is used. */
358
443
return decode_index_parts_166 (index_string -> index_parts ,
359
444
part_count , tuple );
445
+ } else {
446
+ /* Extended coding format is used. */
447
+ return decode_index_parts (index_string -> index_parts ,
448
+ part_count , tuple );
360
449
}
361
450
362
451
error :
0 commit comments