Skip to content

Commit c0a7295

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 b4ca442 commit c0a7295

File tree

11 files changed

+98
-11
lines changed

11 files changed

+98
-11
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: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ local vshard = require('vshard')
44
local fun = require('fun')
55
local bit = require('bit')
66
local log = require('log')
7+
local datetime_supported, datetime = pcall(require, 'datetime')
78

89
local is_cartridge, cartridge = pcall(require, 'cartridge')
910
local is_cartridge_hotreload, cartridge_hotreload = pcall(require, 'cartridge.hotreload')
@@ -1335,6 +1336,21 @@ function utils.is_cartridge_hotreload_supported()
13351336
return true, cartridge_hotreload
13361337
end
13371338

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

@@ -421,4 +421,30 @@ return function()
421421
if_not_exists = true,
422422
})
423423
end
424+
425+
local interval_supported = datetime_supported and (datetime.interval ~= nil)
426+
if interval_supported then
427+
-- Interval is non-indexable.
428+
local interval_space = box.schema.space.create('interval', {
429+
if_not_exists = true,
430+
engine = engine,
431+
})
432+
433+
interval_space:format({
434+
{name = 'id', type = 'unsigned'},
435+
{name = 'bucket_id', type = 'unsigned'},
436+
{name = 'interval_field', type = 'interval'},
437+
})
438+
439+
interval_space:create_index('id_index', {
440+
parts = { 'id' },
441+
if_not_exists = true,
442+
})
443+
444+
interval_space:create_index('bucket_id', {
445+
parts = { 'bucket_id' },
446+
unique = false,
447+
if_not_exists = true,
448+
})
449+
end
424450
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
@@ -920,7 +920,8 @@ end
920920

921921
local gh_373_types_cases = helpers.merge_tables(
922922
read_scenario.gh_373_read_with_decimal_condition_cases,
923-
read_scenario.gh_373_read_with_datetime_condition_cases
923+
read_scenario.gh_373_read_with_datetime_condition_cases,
924+
read_scenario.gh_373_read_with_interval_condition_cases
924925
)
925926

926927
for case_name_template, case in pairs(gh_373_types_cases) do

test/integration/read_scenario.lua

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,33 @@ for space_kind, space_option in pairs(datetime_condition_space_options) do
555555
end
556556
end
557557

558+
local gh_373_read_with_interval_condition_cases = {
559+
['gh_373_%s_with_interval_single_condition_is_forbidden'] = function(cg, read)
560+
helpers.skip_interval_unsupported()
561+
562+
local _, err = read(cg,
563+
'interval',
564+
{{'>=', 'interval_field', datetime.interval.new{}}}
565+
)
566+
t.assert_not_equals(err, nil)
567+
568+
local err_msg = err.err or tostring(err)
569+
t.assert_str_contains(err_msg, "datetime interval conditions are not supported")
570+
end,
571+
['gh_373_%s_with_interval_second_condition_is_forbidden'] = function(cg, read)
572+
helpers.skip_interval_unsupported()
573+
574+
local _, err = read(cg,
575+
'interval',
576+
{{'>=', 'id', 1}, {'>=', 'interval_field', datetime.interval.new{}}}
577+
)
578+
t.assert_not_equals(err, nil)
579+
580+
local err_msg = err.err or tostring(err)
581+
t.assert_str_contains(err_msg, "datetime interval conditions are not supported")
582+
end,
583+
}
584+
558585

559586
local function before_merger_process_storage_error(cg)
560587
helpers.call_on_storages(cg.cluster, function(server)
@@ -639,6 +666,7 @@ return {
639666
gh_418_read_with_secondary_noneq_index_condition = gh_418_read_with_secondary_noneq_index_condition,
640667
gh_373_read_with_decimal_condition_cases = gh_373_read_with_decimal_condition_cases,
641668
gh_373_read_with_datetime_condition_cases = gh_373_read_with_datetime_condition_cases,
669+
gh_373_read_with_interval_condition_cases = gh_373_read_with_interval_condition_cases,
642670
before_merger_process_storage_error = before_merger_process_storage_error,
643671
merger_process_storage_error = merger_process_storage_error,
644672
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
@@ -2510,7 +2510,8 @@ end
25102510

25112511
local gh_373_types_cases = helpers.merge_tables(
25122512
read_scenario.gh_373_read_with_decimal_condition_cases,
2513-
read_scenario.gh_373_read_with_datetime_condition_cases
2513+
read_scenario.gh_373_read_with_datetime_condition_cases,
2514+
read_scenario.gh_373_read_with_interval_condition_cases
25142515
)
25152516

25162517
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
@@ -2288,7 +2288,8 @@ end
22882288

22892289
local gh_373_types_cases = helpers.merge_tables(
22902290
read_scenario.gh_373_read_with_decimal_condition_cases,
2291-
read_scenario.gh_373_read_with_datetime_condition_cases
2291+
read_scenario.gh_373_read_with_datetime_condition_cases,
2292+
read_scenario.gh_373_read_with_interval_condition_cases
22922293
)
22932294

22942295
for case_name_template, case in pairs(gh_373_types_cases) do

0 commit comments

Comments
 (0)