Skip to content

Commit ac36c76

Browse files
Gumixlocker
authored andcommitted
box: introduce index layout option
It is intended to be used by `memcs` engine to specify the layout options. Needed for tarantool/tarantool-ee#1089 NO_DOC=will be done EE NO_CHANGELOG=does not work with CE engines
1 parent 715b9a5 commit ac36c76

File tree

7 files changed

+114
-1
lines changed

7 files changed

+114
-1
lines changed

src/box/index_def.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ const struct index_opts index_opts_default = {
5454
/* .hint = */ INDEX_HINT_DEFAULT,
5555
/* .covered_fields = */ NULL,
5656
/* .covered_field_count = */ 0,
57+
/* .layout = */ NULL,
5758
};
5859

5960
/**
@@ -113,6 +114,24 @@ index_opts_parse_covered_fields(const char **data, void *opts,
113114
return 0;
114115
}
115116

117+
/** Parse index layout option given as MsgPack in `data' into `opts'. */
118+
static int
119+
index_opts_parse_layout(const char **data, void *opts, struct region *region)
120+
{
121+
struct index_opts *index_opts = (struct index_opts *)opts;
122+
if (mp_typeof(**data) != MP_STR) {
123+
diag_set(IllegalParams, "'layout' must be string");
124+
return -1;
125+
}
126+
uint32_t len = 0;
127+
const char *str = mp_decode_str(data, &len);
128+
if (len > 0) {
129+
index_opts->layout = xregion_alloc(region, len + 1);
130+
strlcpy(index_opts->layout, str, len + 1);
131+
}
132+
return 0;
133+
}
134+
116135
const struct opt_def index_opts_reg[] = {
117136
OPT_DEF("unique", OPT_BOOL, struct index_opts, is_unique),
118137
OPT_DEF("dimension", OPT_INT64, struct index_opts, dimension),
@@ -128,6 +147,7 @@ const struct opt_def index_opts_reg[] = {
128147
OPT_DEF_LEGACY("sql"),
129148
OPT_DEF_CUSTOM("hint", index_opts_parse_hint),
130149
OPT_DEF_CUSTOM("covers", index_opts_parse_covered_fields),
150+
OPT_DEF_CUSTOM("layout", index_opts_parse_layout),
131151
OPT_END,
132152
};
133153

@@ -144,6 +164,9 @@ const struct opt_def index_opts_reg[] = {
144164
static void
145165
index_opts_normalize(struct index_opts *opts, const struct key_def *cmp_def)
146166
{
167+
if (opts->layout != NULL)
168+
opts->layout = xstrdup(opts->layout);
169+
147170
if (opts->covered_field_count == 0)
148171
return;
149172
uint32_t *fields = xmalloc(sizeof(*fields) * opts->covered_field_count);
@@ -213,6 +236,8 @@ index_opts_dup(const struct index_opts *opts, struct index_opts *dup)
213236
dup->covered_field_count *
214237
sizeof(*dup->covered_fields));
215238
}
239+
if (dup->layout != NULL)
240+
dup->layout = xstrdup(dup->layout);
216241
}
217242

218243
struct index_def *
@@ -235,7 +260,6 @@ index_def_dup(const struct index_def *def)
235260
void
236261
index_def_delete(struct index_def *index_def)
237262
{
238-
free(index_def->opts.covered_fields);
239263
index_opts_destroy(&index_def->opts);
240264
free(index_def->name);
241265
free(index_def->space_name);

src/box/index_def.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,11 @@ struct index_opts {
120120
* Number of covered fields.
121121
*/
122122
uint32_t covered_field_count;
123+
/**
124+
* Engine dependent. For engines supporting various layouts means a
125+
* string with the layout options.
126+
*/
127+
char *layout;
123128
};
124129

125130
extern const struct index_opts index_opts_default;
@@ -140,6 +145,8 @@ index_opts_create(struct index_opts *opts)
140145
static inline void
141146
index_opts_destroy(struct index_opts *opts)
142147
{
148+
free(opts->covered_fields);
149+
free(opts->layout);
143150
TRASH(opts);
144151
}
145152

@@ -172,6 +179,12 @@ index_opts_is_equal(const struct index_opts *o1, const struct index_opts *o2)
172179
if (o1->covered_fields[i] != o2->covered_fields[i])
173180
return false;
174181
}
182+
if (o1->layout != NULL && o2->layout != NULL) {
183+
if (strcmp(o1->layout, o2->layout) != 0)
184+
return false;
185+
} else if (o1->layout != NULL || o2->layout != NULL) {
186+
return false;
187+
}
175188
return true;
176189
}
177190

src/box/lua/schema.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1571,6 +1571,7 @@ local index_options = {
15711571
func = 'number, string',
15721572
hint = 'boolean',
15731573
covers = 'table',
1574+
layout = 'string',
15741575
}
15751576

15761577
local function jsonpaths_from_idx_parts(parts)
@@ -1746,6 +1747,7 @@ box.schema.index.create = atomic_wrapper(function(space_id, name, options)
17461747
func = options.func,
17471748
hint = options.hint,
17481749
covers = options.covers,
1750+
layout = options.layout,
17491751
}
17501752
local field_type_aliases = {
17511753
num = 'unsigned'; -- Deprecated since 1.7.2

src/box/lua/space.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,11 @@ lbox_fillspace(struct lua_State *L, struct space *space, int i)
639639
lua_setfield(L, -2, "covers");
640640
}
641641

642+
if (index_def->opts.layout != NULL) {
643+
lua_pushstring(L, index_def->opts.layout);
644+
lua_setfield(L, -2, "layout");
645+
}
646+
642647
lua_pushstring(L, "sequence_id");
643648
if (k == 0 && space->sequence != NULL) {
644649
lua_pushnumber(L, space->sequence->def->id);

src/box/memtx_space.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -883,6 +883,11 @@ memtx_space_check_index_def(struct space *space, struct index_def *index_def)
883883
"covering index");
884884
return -1;
885885
}
886+
if (index_def->opts.layout != NULL) {
887+
diag_set(ClientError, ER_UNSUPPORTED, "memtx",
888+
"'layout' option");
889+
return -1;
890+
}
886891
return 0;
887892
}
888893

src/box/vinyl.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,11 @@ vinyl_space_check_index_def(struct space *space, struct index_def *index_def)
699699
"covering index");
700700
return -1;
701701
}
702+
if (index_def->opts.layout != NULL) {
703+
diag_set(ClientError, ER_UNSUPPORTED, "vinyl",
704+
"'layout' option");
705+
return -1;
706+
}
702707
return 0;
703708
}
704709

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
local server = require('luatest.server')
2+
local t = require('luatest')
3+
4+
local g = t.group()
5+
6+
g.before_all(function(cg)
7+
cg.server = server:new()
8+
cg.server:start()
9+
end)
10+
11+
g.after_all(function(cg)
12+
cg.server:drop()
13+
end)
14+
15+
g.after_each(function(cg)
16+
cg.server:exec(function()
17+
if box.space.test ~= nil then
18+
box.space.test:drop()
19+
end
20+
end)
21+
end)
22+
23+
g.test_arg_check = function(cg)
24+
cg.server:exec(function()
25+
local s = box.schema.space.create('test')
26+
t.assert_error_covers({
27+
type = 'IllegalParams',
28+
name = 'ILLEGAL_PARAMS',
29+
message = "options parameter 'layout' should be of type string",
30+
}, s.create_index, s, 'pk', {layout = 1234})
31+
32+
t.assert_error_covers({
33+
type = 'ClientError',
34+
name = 'WRONG_INDEX_OPTIONS',
35+
message = "Wrong index options: 'layout' must be string",
36+
}, box.space._index.insert, box.space._index, {
37+
s.id, 0, 'pk', 'tree', {layout = 1234}, {{[0] = 'unsigned'}}
38+
})
39+
end)
40+
end
41+
42+
g.test_unsupported = function(cg)
43+
cg.server:exec(function()
44+
local s = box.schema.space.create('test', {engine = 'memtx'})
45+
t.assert_error_covers({
46+
type = 'ClientError',
47+
name = 'UNSUPPORTED',
48+
message = "memtx does not support 'layout' option",
49+
}, s.create_index, s, 'pk', {layout = 'test'})
50+
s:drop()
51+
52+
s = box.schema.space.create('test', {engine = 'vinyl'})
53+
t.assert_error_covers({
54+
type = 'ClientError',
55+
name = 'UNSUPPORTED',
56+
message = "vinyl does not support 'layout' option",
57+
}, s.create_index, s, 'pk', {layout = 'test'})
58+
end)
59+
end

0 commit comments

Comments
 (0)