@@ -2,6 +2,7 @@ local ddl_get = require('ddl.get')
2
2
local ddl_set = require (' ddl.set' )
3
3
local ddl_check = require (' ddl.check' )
4
4
local ddl_db = require (' ddl.db' )
5
+ local ddl_compare = require (' ddl.compare' )
5
6
local utils = require (' ddl.utils' )
6
7
7
8
local function check_schema_format (schema )
@@ -22,12 +23,14 @@ local function check_schema_format(schema)
22
23
return nil , string.format (" functions: not supported" )
23
24
end
24
25
25
- if type (schema .sequences ) ~= ' nil' then
26
- return nil , string.format (" sequences: not supported" )
26
+ if type (schema .sequences ) ~= ' nil' and type (schema .sequences ) ~= ' table' then
27
+ return nil , string.format (
28
+ " sequences: must be a table or nil, got %s" , type (schema .sequences )
29
+ )
27
30
end
28
31
29
32
do -- check redundant keys
30
- local k = utils .redundant_key (schema , {' spaces' })
33
+ local k = utils .redundant_key (schema , {' spaces' , ' sequences ' })
31
34
if k ~= nil then
32
35
return nil , string.format (
33
36
" Invalid schema: redundant key %q" , k
@@ -38,12 +41,47 @@ local function check_schema_format(schema)
38
41
return true
39
42
end
40
43
41
- local function _check_schema (schema )
42
- for space_name , space_schema in pairs (schema .spaces ) do
43
- local ok , err = ddl_check .check_space (space_name , space_schema )
44
+ local function _check_and_dry_run_sequences (sequences )
45
+ for sequence_name , sequence_schema in pairs (sequences ) do
46
+ local ok , err = ddl_check .check_sequence (sequence_name , sequence_schema )
47
+ if not ok then
48
+ return nil , err
49
+ end
50
+
51
+ if box .sequence [sequence_name ] ~= nil then
52
+ local current_schema = ddl_get .get_sequence_schema (sequence_name )
53
+ local _ , err = ddl_compare .assert_equiv_sequence_schema (sequence_schema , current_schema )
54
+ if err ~= nil then
55
+ return nil , string.format (
56
+ " Incompatible schema: sequences[%q] %s" , sequence_name , err )
57
+ end
58
+ else
59
+ local ok , err = pcall (
60
+ ddl_set .create_sequence ,
61
+ sequence_name , sequence_schema , {dummy = true }
62
+ )
63
+
64
+ local dummy = box .sequence [' _ddl_dummy' ]
65
+ if dummy then
66
+ pcall (box .schema .sequence .drop , dummy .id )
67
+ end
68
+
69
+ if not ok then
70
+ return nil , tostring (err ):gsub (' _ddl_dummy' , sequence_name )
71
+ end
72
+ end
73
+ end
74
+
75
+ return true
76
+ end
77
+
78
+ local function _check_and_dry_run_spaces (spaces , sequences )
79
+ for space_name , space_schema in pairs (spaces ) do
80
+ local ok , err = ddl_check .check_space (space_name , space_schema , sequences )
44
81
if not ok then
45
82
return nil , err
46
83
end
84
+
47
85
if box .space [space_name ] ~= nil then
48
86
local diff = {}
49
87
local current_schema = ddl_get .get_space_schema (space_name )
@@ -75,6 +113,23 @@ local function _check_schema(schema)
75
113
return true
76
114
end
77
115
116
+ local function _check_and_dry_run_schema (schema )
117
+ -- Create dry-run sequences before spaces since space indexes use sequences.
118
+ local sequences = schema .sequences or {}
119
+ local ok , err = _check_and_dry_run_sequences (sequences )
120
+ if not ok then
121
+ return nil , err
122
+ end
123
+
124
+ local spaces = schema .spaces
125
+ local ok , err = _check_and_dry_run_spaces (spaces , sequences )
126
+ if not ok then
127
+ return nil , err
128
+ end
129
+
130
+ return true
131
+ end
132
+
78
133
local function check_schema (schema )
79
134
local ok , err = check_schema_format (schema )
80
135
if not ok then
@@ -89,7 +144,7 @@ local function check_schema(schema)
89
144
return nil , " Instance is read-only (check box.cfg.read_only and box.info.status)"
90
145
end
91
146
92
- return ddl_db .call_dry_run (_check_schema , schema )
147
+ return ddl_db .call_dry_run (_check_and_dry_run_schema , schema )
93
148
end
94
149
95
150
local function set_metadata_space (metadata_name , space_format )
@@ -127,6 +182,12 @@ local function _set_schema(schema)
127
182
}
128
183
)
129
184
185
+ for sequence_name , sequence_schema in pairs (schema .sequences or {}) do
186
+ if box .sequence [sequence_name ] == nil then
187
+ ddl_set .create_sequence (sequence_name , sequence_schema )
188
+ end
189
+ end
190
+
130
191
for space_name , space_schema in pairs (schema .spaces ) do
131
192
if box .space [space_name ] == nil then
132
193
ddl_set .create_space (space_name , space_schema )
@@ -153,8 +214,22 @@ local function get_schema()
153
214
end
154
215
end
155
216
217
+ local sequences = {}
218
+ for _ , sequence in box .space ._sequence :pairs () do
219
+ sequences [sequence .name ] = ddl_get .get_sequence_schema (sequence .name )
220
+ end
221
+
222
+ local next_k = next (sequences )
223
+ local no_sequences = next_k == nil
224
+
225
+ if no_sequences then
226
+ -- For backward compatibility.
227
+ sequences = nil
228
+ end
229
+
156
230
return {
157
231
spaces = spaces ,
232
+ sequences = sequences ,
158
233
}
159
234
end
160
235
0 commit comments