Skip to content

Commit f790d54

Browse files
scan: forbid interval conditions
As for Tarantool 3.0 and older, datetime intervals are not comparable [1]. They are also don't supported in indexes. This patch explicitly forbids to use them in conditions. 1. tarantool/tarantool#7659 Closes #373
1 parent 1f3b28f commit f790d54

File tree

11 files changed

+103
-14
lines changed

11 files changed

+103
-14
lines changed

CHANGELOG.md

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

88
## Unreleased
99

10+
### Changed
11+
* Explicitly forbid datetime interval conditions (#373).
12+
1013
### Fixed
1114
* Working with datetime conditions in case of non-indexed fields or
1215
non-iterating indexes (#373).

crud/common/utils.lua

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
local bit = require('bit')
12
local errors = require('errors')
3+
local fiber = require('fiber')
24
local ffi = require('ffi')
3-
local vshard = require('vshard')
45
local fun = require('fun')
5-
local bit = require('bit')
6+
local vshard = require('vshard')
67
local log = require('log')
78

9+
local datetime_supported, datetime = pcall(require, 'datetime')
10+
811
local is_cartridge, cartridge = pcall(require, 'cartridge')
912
local is_cartridge_hotreload, cartridge_hotreload = pcall(require, 'cartridge.hotreload')
1013

@@ -23,7 +26,6 @@ local NotInitializedError = errors.new_class('NotInitialized')
2326
local StorageInfoError = errors.new_class('StorageInfoError')
2427
local VshardRouterError = errors.new_class('VshardRouterError', {capture_stack = false})
2528
local UtilsInternalError = errors.new_class('UtilsInternalError', {capture_stack = false})
26-
local fiber = require('fiber')
2729

2830
local utils = {}
2931

@@ -1335,6 +1337,21 @@ function utils.is_cartridge_hotreload_supported()
13351337
return true, cartridge_hotreload
13361338
end
13371339

1340+
local interval_supported = datetime_supported and (datetime.interval ~= nil)
1341+
1342+
if interval_supported then
1343+
-- https://github.com/tarantool/tarantool/blob/0510ffa07afd84a70c9c6f1a4c28aacd73a393d6/src/lua/datetime.lua#L175-179
1344+
local interval_t = ffi.typeof('struct interval')
1345+
1346+
utils.is_interval = function(o)
1347+
return ffi.istype(interval_t, o)
1348+
end
1349+
else
1350+
utils.is_interval = function()
1351+
return false
1352+
end
1353+
end
1354+
13381355
for k, v in pairs(require('crud.common.vshard_utils')) do
13391356
utils[k] = v
13401357
end

crud/compare/filters.lua

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,10 +167,16 @@ local function format_value(value)
167167
return ("%q"):format(value)
168168
elseif datetime_supported and datetime.is_datetime(value) then
169169
return ("%q"):format(value:format())
170+
elseif utils.is_interval(value) then
171+
-- As for Tarantool 3.0 and older, datetime intervals
172+
-- are not comparable. It's better to explicitly forbid them
173+
-- for now.
174+
-- https://github.com/tarantool/tarantool/issues/7659
175+
GenFiltersError:assert(false, ('datetime interval conditions are not supported'))
170176
elseif type(value) == 'cdata' then
171177
return tostring(value)
172178
end
173-
assert(false, ('Unexpected value %s (type %s)'):format(value, type(value)))
179+
GenFiltersError:assert(false, ('Unexpected value %s (type %s)'):format(value, type(value)))
174180
end
175181

176182
local PARSE_ARGS_TEMPLATE = 'local tuple = ...'

test/entrypoint/srv_select/storage_init.lua

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
local datetime_supported, _ = pcall(require, 'datetime')
1+
local datetime_supported, datetime = pcall(require, 'datetime')
22
local decimal_supported, _ = pcall(require, 'decimal')
33

44
local crud_utils = require('crud.common.utils')
@@ -422,4 +422,30 @@ return function()
422422
if_not_exists = true,
423423
})
424424
end
425+
426+
local interval_supported = datetime_supported and (datetime.interval ~= nil)
427+
if interval_supported then
428+
-- Interval is non-indexable.
429+
local interval_space = box.schema.space.create('interval', {
430+
if_not_exists = true,
431+
engine = engine,
432+
})
433+
434+
interval_space:format({
435+
{name = 'id', type = 'unsigned'},
436+
{name = 'bucket_id', type = 'unsigned'},
437+
{name = 'interval_field', type = 'interval'},
438+
})
439+
440+
interval_space:create_index('id_index', {
441+
parts = { 'id' },
442+
if_not_exists = true,
443+
})
444+
445+
interval_space:create_index('bucket_id', {
446+
parts = { 'bucket_id' },
447+
unique = false,
448+
if_not_exists = true,
449+
})
450+
end
425451
end

test/helper.lua

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -968,6 +968,12 @@ function helpers.skip_datetime_unsupported()
968968
t.skip_if(not module_available, 'datetime is not supported')
969969
end
970970

971+
function helpers.skip_interval_unsupported()
972+
local datetime_supported, datetime = pcall(require, 'datetime')
973+
local interval_supported = datetime_supported and (datetime.interval ~= nil)
974+
t.skip_if(not interval_supported, 'interval is not supported')
975+
end
976+
971977
function helpers.merge_tables(t1, t2, ...)
972978
if t2 == nil then
973979
return t1

test/integration/count_test.lua

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -873,10 +873,7 @@ local read_impl = function(cg, space, conditions, opts)
873873
opts = table.deepcopy(opts) or {}
874874
opts.mode = 'write'
875875

876-
local resp, err = cg.cluster.main_server:call('crud.count', {space, conditions, opts})
877-
t.assert_equals(err, nil)
878-
879-
return resp
876+
return cg.cluster.main_server:call('crud.count', {space, conditions, opts})
880877
end
881878

882879
pgroup.test_gh_418_count_with_secondary_noneq_index_condition = function(g)
@@ -885,7 +882,8 @@ end
885882

886883
local gh_373_types_cases = helpers.merge_tables(
887884
read_scenario.gh_373_read_with_decimal_condition_cases,
888-
read_scenario.gh_373_read_with_datetime_condition_cases
885+
read_scenario.gh_373_read_with_datetime_condition_cases,
886+
read_scenario.gh_373_read_with_interval_condition_cases
889887
)
890888

891889
for case_name_template, case in pairs(gh_373_types_cases) do

test/integration/pairs_readview_test.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -911,7 +911,8 @@ end
911911

912912
local gh_373_types_cases = helpers.merge_tables(
913913
read_scenario.gh_373_read_with_decimal_condition_cases,
914-
read_scenario.gh_373_read_with_datetime_condition_cases
914+
read_scenario.gh_373_read_with_datetime_condition_cases,
915+
read_scenario.gh_373_read_with_interval_condition_cases
915916
)
916917

917918
for case_name_template, case in pairs(gh_373_types_cases) do

test/integration/pairs_test.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -919,7 +919,8 @@ end
919919

920920
local gh_373_types_cases = helpers.merge_tables(
921921
read_scenario.gh_373_read_with_decimal_condition_cases,
922-
read_scenario.gh_373_read_with_datetime_condition_cases
922+
read_scenario.gh_373_read_with_datetime_condition_cases,
923+
read_scenario.gh_373_read_with_interval_condition_cases
923924
)
924925

925926
for case_name_template, case in pairs(gh_373_types_cases) do

test/integration/read_scenario.lua

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,34 @@ for space_kind, space_option in pairs(datetime_condition_space_options) do
548548
end
549549

550550

551+
local gh_373_read_with_interval_condition_cases = {
552+
['gh_373_%s_with_interval_single_condition_is_forbidden'] = function(cg, read)
553+
helpers.skip_interval_unsupported()
554+
555+
local _, err = read(cg,
556+
'interval',
557+
{{'>=', 'interval_field', datetime.interval.new{}}}
558+
)
559+
t.assert_not_equals(err, nil)
560+
561+
local err_msg = err.err or tostring(err)
562+
t.assert_str_contains(err_msg, "datetime interval conditions are not supported")
563+
end,
564+
['gh_373_%s_with_interval_second_condition_is_forbidden'] = function(cg, read)
565+
helpers.skip_interval_unsupported()
566+
567+
local _, err = read(cg,
568+
'interval',
569+
{{'>=', 'id', 1}, {'>=', 'interval_field', datetime.interval.new{}}}
570+
)
571+
t.assert_not_equals(err, nil)
572+
573+
local err_msg = err.err or tostring(err)
574+
t.assert_str_contains(err_msg, "datetime interval conditions are not supported")
575+
end,
576+
}
577+
578+
551579
local function before_merger_process_storage_error(cg)
552580
helpers.call_on_storages(cg.cluster, function(server)
553581
server:exec(function()
@@ -631,6 +659,7 @@ return {
631659
gh_418_read_with_secondary_noneq_index_condition = gh_418_read_with_secondary_noneq_index_condition,
632660
gh_373_read_with_decimal_condition_cases = gh_373_read_with_decimal_condition_cases,
633661
gh_373_read_with_datetime_condition_cases = gh_373_read_with_datetime_condition_cases,
662+
gh_373_read_with_interval_condition_cases = gh_373_read_with_interval_condition_cases,
634663
before_merger_process_storage_error = before_merger_process_storage_error,
635664
merger_process_storage_error = merger_process_storage_error,
636665
after_merger_process_storage_error = after_merger_process_storage_error,

test/integration/select_readview_test.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2509,7 +2509,8 @@ end
25092509

25102510
local gh_373_types_cases = helpers.merge_tables(
25112511
read_scenario.gh_373_read_with_decimal_condition_cases,
2512-
read_scenario.gh_373_read_with_datetime_condition_cases
2512+
read_scenario.gh_373_read_with_datetime_condition_cases,
2513+
read_scenario.gh_373_read_with_interval_condition_cases
25132514
)
25142515

25152516
for case_name_template, case in pairs(gh_373_types_cases) do

test/integration/select_test.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2287,7 +2287,8 @@ end
22872287

22882288
local gh_373_types_cases = helpers.merge_tables(
22892289
read_scenario.gh_373_read_with_decimal_condition_cases,
2290-
read_scenario.gh_373_read_with_datetime_condition_cases
2290+
read_scenario.gh_373_read_with_datetime_condition_cases,
2291+
read_scenario.gh_373_read_with_interval_condition_cases
22912292
)
22922293

22932294
for case_name_template, case in pairs(gh_373_types_cases) do

0 commit comments

Comments
 (0)