diff --git a/src/box/sql.c b/src/box/sql.c index 87616e6deaddf3dcf48a88144d9441912fd70872..580f3fa9cc11a1d366bf81fb38416e53c13ffeb1 100644 --- a/src/box/sql.c +++ b/src/box/sql.c @@ -30,6 +30,7 @@ */ #include <assert.h> #include "field_def.h" +#include "cfg.h" #include "sql.h" #include "sql/sqlInt.h" #include "sql/tarantoolInt.h" @@ -1167,18 +1168,44 @@ char * sql_encode_index_opts(struct region *region, const struct index_opts *opts, uint32_t *size) { - int unique_len = strlen("unique"); - *size = mp_sizeof_map(1) + mp_sizeof_str(unique_len) + - mp_sizeof_bool(opts->is_unique); - char *mem = (char *) region_alloc(region, *size); - if (mem == NULL) { - diag_set(OutOfMemory, *size, "region_alloc", "mem"); + size_t used = region_used(region); + struct mpstream stream; + bool is_error = false; + mpstream_init(&stream, region, region_reserve_cb, region_alloc_cb, + set_encode_error, &is_error); + /* + * In case of vinyl engine we must inherit global + * (i.e. set via box.cfg) params such as bloom_fpr, + * page_size etc. + */ + uint8_t current_engine = current_session()->sql_default_engine; + uint32_t map_sz = current_engine == SQL_STORAGE_ENGINE_VINYL ? 6 : 1; + mpstream_encode_map(&stream, map_sz); + mpstream_encode_str(&stream, "unique"); + mpstream_encode_bool(&stream, opts->is_unique); + if (current_engine == SQL_STORAGE_ENGINE_VINYL) { + mpstream_encode_str(&stream, "range_size"); + mpstream_encode_uint(&stream, cfg_geti64("vinyl_range_size")); + mpstream_encode_str(&stream, "page_size"); + mpstream_encode_uint(&stream, cfg_geti64("vinyl_page_size")); + mpstream_encode_str(&stream, "run_count_per_level"); + mpstream_encode_uint(&stream, cfg_geti("vinyl_run_count_per_level")); + mpstream_encode_str(&stream, "run_size_ratio"); + mpstream_encode_double(&stream, cfg_getd("vinyl_run_size_ratio")); + mpstream_encode_str(&stream, "bloom_fpr"); + mpstream_encode_double(&stream, cfg_getd("vinyl_bloom_fpr")); + } + mpstream_flush(&stream); + if (is_error) { + diag_set(OutOfMemory, stream.pos - stream.buf, + "mpstream_flush", "stream"); return NULL; } - char *pos = mp_encode_map(mem, 1); - pos = mp_encode_str(pos, "unique", unique_len); - pos = mp_encode_bool(pos, opts->is_unique); - return mem; + *size = region_used(region) - used; + char *raw = region_join(region, *size); + if (raw == NULL) + diag_set(OutOfMemory, *size, "region_join", "raw"); + return raw; } void diff --git a/test/sql/engine.cfg b/test/sql/engine.cfg index 0007d8d7a80eaa88da49a3cbf0991d299f94304f..d5666a08130f2755e85b9d71237b26aeba3869d3 100644 --- a/test/sql/engine.cfg +++ b/test/sql/engine.cfg @@ -1,4 +1,7 @@ { + "vinyl-opts.test.lua" : { + "vinyl": {"engine": "vinyl"} + }, "*": { "memtx": {"engine": "memtx"}, "vinyl": {"engine": "vinyl"} diff --git a/test/sql/vinyl-opts-cfg.lua b/test/sql/vinyl-opts-cfg.lua new file mode 100644 index 0000000000000000000000000000000000000000..0a8256ca3672f9fce4f23aa68ee0b1789feeb3b8 --- /dev/null +++ b/test/sql/vinyl-opts-cfg.lua @@ -0,0 +1,14 @@ +#!/usr/bin/env tarantool + +-- Set of custom vinyl params, which are used in the test +-- of the same name (vinyl-opts.test.lua). +-- +box.cfg { + vinyl_bloom_fpr = 0.1, + vinyl_page_size = 32 * 1024, + vinyl_range_size = 512 * 1024 * 1024, + vinyl_run_size_ratio = 5, + vinyl_run_count_per_level = 3 +} + +require('console').listen(os.getenv('ADMIN')) diff --git a/test/sql/vinyl-opts.result b/test/sql/vinyl-opts.result new file mode 100644 index 0000000000000000000000000000000000000000..4e6c4bc8545963055531b80881efcedd92ab692a --- /dev/null +++ b/test/sql/vinyl-opts.result @@ -0,0 +1,55 @@ +test_run = require('test_run').new() +--- +... +test_run:cmd("create server test with script='sql/vinyl-opts-cfg.lua'") +--- +- true +... +test_run:cmd("start server test") +--- +- true +... +test_run:cmd("switch test") +--- +- true +... +box.sql.execute('pragma sql_default_engine= \'vinyl\'') +--- +... +box.sql.execute('CREATE TABLE v1 (id INT PRIMARY KEY, b INT);') +--- +... +box.space.V1.index[0].options +--- +- page_size: 32768 + run_count_per_level: 3 + run_size_ratio: 5 + bloom_fpr: 0.1 + range_size: 536870912 +... +box.sql.execute('CREATE INDEX i1 ON v1(b);') +--- +... +box.space.V1.index[1].options +--- +- page_size: 32768 + run_count_per_level: 3 + run_size_ratio: 5 + bloom_fpr: 0.1 + range_size: 536870912 +... +box.space.V1:drop() +--- +... +test_run:cmd('switch default') +--- +- true +... +test_run:cmd("stop server test") +--- +- true +... +test_run:cmd("cleanup server test") +--- +- true +... diff --git a/test/sql/vinyl-opts.test.lua b/test/sql/vinyl-opts.test.lua new file mode 100644 index 0000000000000000000000000000000000000000..843693bca23492226e6b5a1a3b53959beab721af --- /dev/null +++ b/test/sql/vinyl-opts.test.lua @@ -0,0 +1,17 @@ +test_run = require('test_run').new() +test_run:cmd("create server test with script='sql/vinyl-opts-cfg.lua'") +test_run:cmd("start server test") +test_run:cmd("switch test") + +box.sql.execute('pragma sql_default_engine= \'vinyl\'') +box.sql.execute('CREATE TABLE v1 (id INT PRIMARY KEY, b INT);') +box.space.V1.index[0].options + +box.sql.execute('CREATE INDEX i1 ON v1(b);') +box.space.V1.index[1].options + +box.space.V1:drop() + +test_run:cmd('switch default') +test_run:cmd("stop server test") +test_run:cmd("cleanup server test")