Skip to content

Commit

Permalink
ddl: support sequences
Browse files Browse the repository at this point in the history
This patch adds the support of sequences through new schema section,
as well as proper support of sequence option for indexes. Before this
patch, ddl had half-baked support of sequences: one could provide
`sequence` as sequence name in indexes and it would be created. This
approach was broken in basic `set_schema(get_schema)` scenario since
there wasn't any sequences support in get. Current design is inspired
by existing "not implemented yet" tests and documentation examples.

Closes #122
  • Loading branch information
DifferentialOrange committed Mar 28, 2024
1 parent 88251b9 commit 4b02448
Show file tree
Hide file tree
Showing 15 changed files with 869 additions and 60 deletions.
2 changes: 2 additions & 0 deletions .luacheckrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
redefined = false
globals = {"box", "_TARANTOOL", "tonumber64", "utf8", "table"}
include_files = {"**/*.lua", "*.rockspec", "*.luacheckrc"}
exclude_files = {".rocks/", "tmp/", ".history/"}
max_line_length = 120
max_comment_line_length = 150
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## Unreleased

### Added

- Added support of sequences in schema and space indexes (#122).

## [1.6.5] - 2023-10-23

### Added
Expand Down
69 changes: 56 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,17 +205,16 @@ format = {
},
...
},
sequences = { -- Not implemented yet
[seqence_name] = {
start
min
max
cycle
cache
step

}
}
sequences = {
[sequence_name] = {
start = start,
min = min,
max = max,
cycle = cycle,
cache = cache,
step = step,
},
},
}
```

Expand Down Expand Up @@ -292,8 +291,52 @@ local schema = {
}},
sharding_key = {'customer_id'},
sharding_func = 'vshard.router.bucket_id_mpcrc32',
}
}
},
tickets = {
engine = 'memtx',
is_local = false,
temporary = false,
format = {
{name = 'ticket_id', is_nullable = false, type = 'unsigned'},
{name = 'customer_id', is_nullable = false, type = 'unsigned'},
{name = 'bucket_id', is_nullable = false, type = 'unsigned'},
{name = 'contents', is_nullable = false, type = 'string'},
},
indexes = {{
name = 'ticket_id',
type = 'TREE',
unique = true,
parts = {
{path = 'ticket_id', is_nullable = false, type = 'unsigned'}
},
sequence = 'ticket_seq',
}, {,
name = 'customer_id',
type = 'TREE',
unique = false,
parts = {
{path = 'customer_id', is_nullable = false, type = 'unsigned'}
}
}, {
name = 'bucket_id',
type = 'TREE',
unique = false,
parts = {
{path = 'bucket_id', is_nullable = false, type = 'unsigned'}
}
}},
sharding_key = {'customer_id'},
sharding_func = 'vshard.router.bucket_id_mpcrc32',
},
},
sequences = {
ticket_seq = {
start = 1,
min = 1,
max = 10000,
cycle = false,
},
},
}
```

Expand Down
87 changes: 81 additions & 6 deletions ddl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ local ddl_get = require('ddl.get')
local ddl_set = require('ddl.set')
local ddl_check = require('ddl.check')
local ddl_db = require('ddl.db')
local ddl_compare = require('ddl.compare')
local utils = require('ddl.utils')

local function check_schema_format(schema)
Expand All @@ -22,12 +23,14 @@ local function check_schema_format(schema)
return nil, string.format("functions: not supported")
end

if type(schema.sequences) ~= 'nil' then
return nil, string.format("sequences: not supported")
if type(schema.sequences) ~= 'nil' and type(schema.sequences) ~= 'table' then
return nil, string.format(
"sequences: must be a table or nil, got %s", type(schema.sequences)
)
end

do -- check redundant keys
local k = utils.redundant_key(schema, {'spaces'})
local k = utils.redundant_key(schema, {'spaces', 'sequences'})
if k ~= nil then
return nil, string.format(
"Invalid schema: redundant key %q", k
Expand All @@ -38,12 +41,47 @@ local function check_schema_format(schema)
return true
end

local function _check_schema(schema)
for space_name, space_schema in pairs(schema.spaces) do
local ok, err = ddl_check.check_space(space_name, space_schema)
local function _check_and_dry_run_sequences(sequences)
for sequence_name, sequence_schema in pairs(sequences) do
local ok, err = ddl_check.check_sequence(sequence_name, sequence_schema)
if not ok then
return nil, err
end

if box.sequence[sequence_name] ~= nil then
local current_schema = ddl_get.get_sequence_schema(sequence_name)
local _, err = ddl_compare.assert_equiv_sequence_schema(sequence_schema, current_schema)
if err ~= nil then
return nil, string.format(
"Incompatible schema: sequences[%q] %s", sequence_name, err)
end
else
local ok, err = pcall(
ddl_set.create_sequence,
sequence_name, sequence_schema, {dummy = true}
)

local dummy = box.sequence['_ddl_dummy']
if dummy then
pcall(box.schema.sequence.drop, dummy.id)
end

if not ok then
return nil, tostring(err):gsub('_ddl_dummy', sequence_name)
end
end
end

return true
end

local function _check_and_dry_run_spaces(spaces, sequences)
for space_name, space_schema in pairs(spaces) do
local ok, err = ddl_check.check_space(space_name, space_schema, sequences)
if not ok then
return nil, err
end

if box.space[space_name] ~= nil then
local diff = {}
local current_schema = ddl_get.get_space_schema(space_name)
Expand Down Expand Up @@ -75,6 +113,23 @@ local function _check_schema(schema)
return true
end

local function _check_schema(schema)
-- Create dry-run sequences before spaces since space indexes use sequences.
local sequences = schema.sequences or {}
local ok, err = _check_and_dry_run_sequences(sequences)
if not ok then
return nil, err
end

local spaces = schema.spaces
local ok, err = _check_and_dry_run_spaces(spaces, sequences)
if not ok then
return nil, err
end

return true
end

local function check_schema(schema)
local ok, err = check_schema_format(schema)
if not ok then
Expand Down Expand Up @@ -127,6 +182,12 @@ local function _set_schema(schema)
}
)

for sequence_name, sequence_schema in pairs(schema.sequences or {}) do
if box.sequence[sequence_name] == nil then
ddl_set.create_sequence(sequence_name, sequence_schema)
end
end

for space_name, space_schema in pairs(schema.spaces) do
if box.space[space_name] == nil then
ddl_set.create_space(space_name, space_schema)
Expand All @@ -153,8 +214,22 @@ local function get_schema()
end
end

local sequences = {}
for _, sequence in box.space._sequence:pairs() do
sequences[sequence.name] = ddl_get.get_sequence_schema(sequence.name)
end

local next_k = next(sequences)
local no_sequences = next_k == nil

if no_sequences then
-- For backward compatibility.
sequences = nil
end

return {
spaces = spaces,
sequences = sequences,
}
end

Expand Down
Loading

0 comments on commit 4b02448

Please sign in to comment.