@@ -22,6 +22,7 @@ local FilterFieldsError = errors.new_class('FilterFieldsError', {capture_stack =
22
22
local NotInitializedError = errors .new_class (' NotInitialized' )
23
23
local StorageInfoError = errors .new_class (' StorageInfoError' )
24
24
local VshardRouterError = errors .new_class (' VshardRouterError' , {capture_stack = false })
25
+ local UtilsInternalError = errors .new_class (' UtilsInternalError' , {capture_stack = false })
25
26
local fiber = require (' fiber' )
26
27
27
28
local utils = {}
@@ -294,25 +295,153 @@ function utils.enrich_field_names_with_cmp_key(field_names, key_parts, space_for
294
295
return enriched_field_names
295
296
end
296
297
297
- local enabled_tarantool_features = {}
298
298
299
- local function determine_enabled_features ()
300
- local major_minor_patch = _G ._TARANTOOL :split (' -' , 1 )[1 ]
301
- local major_minor_patch_parts = major_minor_patch :split (' .' , 2 )
299
+ local function get_version_suffix (suffix_candidate )
300
+ if type (suffix_candidate ) ~= ' string' then
301
+ return nil
302
+ end
303
+
304
+ if suffix_candidate :find (' ^entrypoint$' )
305
+ or suffix_candidate :find (' ^alpha%d$' )
306
+ or suffix_candidate :find (' ^beta%d$' )
307
+ or suffix_candidate :find (' ^rc%d$' ) then
308
+ return suffix_candidate
309
+ end
310
+
311
+ return nil
312
+ end
313
+
314
+ utils .get_version_suffix = get_version_suffix
315
+
316
+
317
+ local suffix_with_digit_weight = {
318
+ alpha = - 3000 ,
319
+ beta = - 2000 ,
320
+ rc = - 1000 ,
321
+ }
322
+
323
+ local function get_version_suffix_weight (suffix )
324
+ if suffix == nil then
325
+ return 0
326
+ end
327
+
328
+ if suffix :find (' ^entrypoint$' ) then
329
+ return - math.huge
330
+ end
331
+
332
+ for header , weight in pairs (suffix_with_digit_weight ) do
333
+ local pos , _ , digits = suffix :find (' ^' .. header .. ' (%d)$' )
334
+ if pos ~= nil then
335
+ return weight + tonumber (digits )
336
+ end
337
+ end
338
+
339
+ UtilsInternalError :assert (false ,
340
+ ' Unexpected suffix %q, parse with "utils.get_version_suffix" first' , suffix )
341
+ end
342
+
343
+ utils .get_version_suffix_weight = get_version_suffix_weight
344
+
345
+
346
+ local function is_version_ge (major , minor ,
347
+ patch , suffix ,
348
+ major_to_compare , minor_to_compare ,
349
+ patch_to_compare , suffix_to_compare )
350
+ major = major or 0
351
+ minor = minor or 0
352
+ patch = patch or 0
353
+ local suffix_weight = get_version_suffix_weight (suffix )
354
+
355
+ major_to_compare = major_to_compare or 0
356
+ minor_to_compare = minor_to_compare or 0
357
+ patch_to_compare = patch_to_compare or 0
358
+ local suffix_weight_to_compare = get_version_suffix_weight (suffix_to_compare )
359
+
360
+ if major > major_to_compare then return true end
361
+ if major < major_to_compare then return false end
302
362
363
+ if minor > minor_to_compare then return true end
364
+ if minor < minor_to_compare then return false end
365
+
366
+ if patch > patch_to_compare then return true end
367
+ if patch < patch_to_compare then return false end
368
+
369
+ if suffix_weight > suffix_weight_to_compare then return true end
370
+ if suffix_weight < suffix_weight_to_compare then return false end
371
+
372
+ return true
373
+ end
374
+
375
+ utils .is_version_ge = is_version_ge
376
+
377
+
378
+ local function is_version_in_range (major , minor ,
379
+ patch , suffix ,
380
+ major_left_side , minor_left_side ,
381
+ patch_left_side , suffix_left_side ,
382
+ major_right_side , minor_right_side ,
383
+ patch_right_side , suffix_right_side )
384
+ return is_version_ge (major , minor ,
385
+ patch , suffix ,
386
+ major_left_side , minor_left_side ,
387
+ patch_left_side , suffix_left_side )
388
+ and is_version_ge (major_right_side , minor_right_side ,
389
+ patch_right_side , suffix_right_side ,
390
+ major , minor ,
391
+ patch , suffix )
392
+ end
393
+
394
+ utils .is_version_in_range = is_version_in_range
395
+
396
+
397
+ local function get_tarantool_version ()
398
+ local version_parts = rawget (_G , ' _TARANTOOL' ):split (' -' , 1 )
399
+
400
+ local major_minor_patch_parts = version_parts [1 ]:split (' .' , 2 )
303
401
local major = tonumber (major_minor_patch_parts [1 ])
304
402
local minor = tonumber (major_minor_patch_parts [2 ])
305
403
local patch = tonumber (major_minor_patch_parts [3 ])
306
404
307
- -- since Tarantool 2.3
308
- enabled_tarantool_features .fieldpaths = major >= 2 and (minor > 3 or minor == 3 and patch >= 1 )
405
+ local suffix = get_version_suffix (version_parts [2 ])
406
+
407
+ return major , minor , patch , suffix
408
+ end
409
+
410
+ utils .get_tarantool_version = get_tarantool_version
411
+
412
+
413
+ local function tarantool_version_at_least (wanted_major , wanted_minor , wanted_patch )
414
+ local major , minor , patch , suffix = get_tarantool_version ()
415
+
416
+ return is_version_ge (major , minor , patch , suffix ,
417
+ wanted_major , wanted_minor , wanted_patch , nil )
418
+ end
419
+
420
+ utils .tarantool_version_at_least = tarantool_version_at_least
421
+
422
+
423
+ local enabled_tarantool_features = {}
424
+
425
+ local function determine_enabled_features ()
426
+ local major , minor , patch , suffix = get_tarantool_version ()
427
+
428
+ -- since Tarantool 2.3.1
429
+ enabled_tarantool_features .fieldpaths = is_version_ge (major , minor , patch , suffix ,
430
+ 2 , 3 , 1 , nil )
309
431
310
- -- since Tarantool 2.4
311
- enabled_tarantool_features .uuids = major >= 2 and (minor > 4 or minor == 4 and patch >= 1 )
432
+ -- since Tarantool 2.4.1
433
+ enabled_tarantool_features .uuids = is_version_ge (major , minor , patch , suffix ,
434
+ 2 , 4 , 1 , nil )
312
435
313
436
-- since Tarantool 2.6.3 / 2.7.2 / 2.8.1
314
- enabled_tarantool_features .jsonpath_indexes = major >= 3 or (major >= 2 and ((minor >= 6 and patch >= 3 )
315
- or (minor >= 7 and patch >= 2 ) or (minor >= 8 and patch >= 1 ) or minor >= 9 ))
437
+ enabled_tarantool_features .jsonpath_indexes = is_version_ge (major , minor , patch , suffix ,
438
+ 2 , 8 , 1 , nil )
439
+ or is_version_in_range (major , minor , patch , suffix ,
440
+ 2 , 7 , 2 , nil ,
441
+ 2 , 7 , math.huge , nil )
442
+ or is_version_in_range (major , minor , patch , suffix ,
443
+ 2 , 6 , 3 , nil ,
444
+ 2 , 6 , math.huge , nil )
316
445
317
446
-- The merger module was implemented in 2.2.1, see [1].
318
447
-- However it had the critical problem [2], which leads to
@@ -322,26 +451,38 @@ local function determine_enabled_features()
322
451
--
323
452
-- [1]: https://github.com/tarantool/tarantool/issues/3276
324
453
-- [2]: https://github.com/tarantool/tarantool/issues/4954
325
- enabled_tarantool_features .builtin_merger =
326
- (major == 2 and minor == 3 and patch >= 3 ) or
327
- (major == 2 and minor == 4 and patch >= 2 ) or
328
- (major == 2 and minor == 5 and patch >= 1 ) or
329
- (major >= 2 and minor >= 6 ) or
330
- (major >= 3 )
454
+ enabled_tarantool_features .builtin_merger = is_version_ge (major , minor , patch , suffix ,
455
+ 2 , 6 , 0 , nil )
456
+ or is_version_in_range (major , minor , patch , suffix ,
457
+ 2 , 5 , 1 , nil ,
458
+ 2 , 5 , math.huge , nil )
459
+ or is_version_in_range (major , minor , patch , suffix ,
460
+ 2 , 4 , 2 , nil ,
461
+ 2 , 4 , math.huge , nil )
462
+ or is_version_in_range (major , minor , patch , suffix ,
463
+ 2 , 3 , 3 , nil ,
464
+ 2 , 3 , math.huge , nil )
331
465
332
466
-- The external merger module leans on a set of relatively
333
467
-- new APIs in tarantool. So it works only on tarantool
334
468
-- versions, which offer those APIs.
335
469
--
336
470
-- See README of the module:
337
471
-- https://github.com/tarantool/tuple-merger
338
- enabled_tarantool_features .external_merger =
339
- (major == 1 and minor == 10 and patch >= 8 ) or
340
- (major == 2 and minor == 4 and patch >= 3 ) or
341
- (major == 2 and minor == 5 and patch >= 2 ) or
342
- (major == 2 and minor == 6 and patch >= 1 ) or
343
- (major == 2 and minor >= 7 ) or
344
- (major >= 3 )
472
+ enabled_tarantool_features .external_merger = is_version_ge (major , minor , patch , suffix ,
473
+ 2 , 7 , 0 , nil )
474
+ or is_version_in_range (major , minor , patch , suffix ,
475
+ 2 , 6 , 1 , nil ,
476
+ 2 , 6 , math.huge , nil )
477
+ or is_version_in_range (major , minor , patch , suffix ,
478
+ 2 , 5 , 2 , nil ,
479
+ 2 , 5 , math.huge , nil )
480
+ or is_version_in_range (major , minor , patch , suffix ,
481
+ 2 , 4 , 3 , nil ,
482
+ 2 , 4 , math.huge , nil )
483
+ or is_version_in_range (major , minor , patch , suffix ,
484
+ 1 , 10 , 8 , nil ,
485
+ 1 , 10 , math.huge , nil )
345
486
end
346
487
347
488
function utils .tarantool_supports_fieldpaths ()
@@ -398,7 +539,7 @@ local function add_nullable_fields_recursive(operations, operations_map, space_f
398
539
end
399
540
400
541
-- Tarantool < 2.1 has no fields `box.error.NO_SUCH_FIELD_NO` and `box.error.NO_SUCH_FIELD_NAME`.
401
- if _TARANTOOL >= " 2.1 " then
542
+ if tarantool_version_at_least ( 2 , 1 , 0 , nil ) then
402
543
function utils .is_field_not_found (err_code )
403
544
return err_code == box .error .NO_SUCH_FIELD_NO or err_code == box .error .NO_SUCH_FIELD_NAME
404
545
end
0 commit comments