From: Nikita Pettik <korablev@tarantool.org> To: tarantool-patches@freelists.org Cc: v.shpilevoy@tarantool.org, Nikita Pettik <korablev@tarantool.org> Subject: [tarantool-patches] [PATCH] Introduce 'view' space option Date: Mon, 26 Mar 2018 16:11:39 +0300 [thread overview] Message-ID: <20180326131139.94448-1-korablev@tarantool.org> (raw) Now, space can feature SQL specific option 'view'. In SQL view is a space without any functional parts except for 'SELECT' statement. In this respect, creation of any indexes is prohibited on views; views must have SQL statement; transofrmation from space to view is also banned. It is worth mentioning, that setting 'view' option isn't available via Lua interface. Closes #3268 --- Branch: https://github.com/tarantool/tarantool/tree/np/gh-3268-introduce-view Issue: https://github.com/tarantool/tarantool/issues/3268 src/box/alter.cc | 7 ++++++ src/box/errcode.h | 3 ++- src/box/space_def.c | 7 ++++++ src/box/space_def.h | 6 +++++ src/box/sql.c | 9 ++++++- test/box/misc.result | 1 + test/sql/view.result | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++ test/sql/view.test.lua | 33 +++++++++++++++++++++++++ 8 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 test/sql/view.result create mode 100644 test/sql/view.test.lua diff --git a/src/box/alter.cc b/src/box/alter.cc index bd87d2f54..a93ea5918 100644 --- a/src/box/alter.cc +++ b/src/box/alter.cc @@ -496,6 +496,9 @@ space_def_new_from_tuple(struct tuple *tuple, uint32_t errcode, } struct space_opts opts; space_opts_decode(&opts, space_opts, region); + if (opts.view && opts.sql == NULL) { + tnt_raise(ClientError, ER_VIEW_MISSING_SQL); + } struct space_def *def = space_def_new_xc(id, uid, exact_field_count, name, name_len, engine_name, engine_name_len, &opts, fields, @@ -1590,6 +1593,10 @@ on_replace_dd_index(struct trigger * /* trigger */, void *event) uint32_t iid = tuple_field_u32_xc(old_tuple ? old_tuple : new_tuple, BOX_INDEX_FIELD_ID); struct space *old_space = space_cache_find_xc(id); + if (old_space->def->opts.view) { + tnt_raise(ClientError, ER_ALTER_SPACE, space_name(old_space), + "can not alter indexes on view"); + } enum priv_type priv_type = new_tuple ? PRIV_C : PRIV_D; if (old_tuple && new_tuple) priv_type = PRIV_A; diff --git a/src/box/errcode.h b/src/box/errcode.h index beb37aa2f..e5d882df8 100644 --- a/src/box/errcode.h +++ b/src/box/errcode.h @@ -212,7 +212,8 @@ struct errcode_record { /*157 */_(ER_SQL_EXECUTE, "Failed to execute SQL statement: %s") \ /*158 */_(ER_SQL, "SQL error: %s") \ /*159 */_(ER_SQL_BIND_NOT_FOUND, "Parameter %s was not found in the statement") \ - /*160 */_(ER_ACTION_MISMATCH, "Field %d contains %s on conflict action, but %s in index parts") + /*160 */_(ER_ACTION_MISMATCH, "Field %d contains %s on conflict action, but %s in index parts") \ + /*161 */_(ER_VIEW_MISSING_SQL, "Space declared as a view must have SQL statement") \ /* * !IMPORTANT! Please follow instructions at start of the file diff --git a/src/box/space_def.c b/src/box/space_def.c index 340cf27f2..304f904a6 100644 --- a/src/box/space_def.c +++ b/src/box/space_def.c @@ -35,11 +35,13 @@ const struct space_opts space_opts_default = { /* .temporary = */ false, + /* .view = */ false, /* .sql = */ NULL, }; const struct opt_def space_opts_reg[] = { OPT_DEF("temporary", OPT_BOOL, struct space_opts, temporary), + OPT_DEF("view", OPT_BOOL, struct space_opts, view), OPT_DEF("sql", OPT_STRPTR, struct space_opts, sql), OPT_END, }; @@ -177,6 +179,11 @@ space_def_check_compatibility(const struct space_def *old_def, "space id is immutable"); return -1; } + if (new_def->opts.view != old_def->opts.view) { + diag_set(ClientError, ER_ALTER_SPACE, old_def->name, + "can not transform space to view and visa versa"); + return -1; + } if (is_space_empty) return 0; diff --git a/src/box/space_def.h b/src/box/space_def.h index 8425ff6d3..bdf697437 100644 --- a/src/box/space_def.h +++ b/src/box/space_def.h @@ -49,6 +49,12 @@ struct space_opts { * - changes are not part of a snapshot */ bool temporary; + /** + * If the space is a view, then it can't feature any + * indexes, and must have SQL statement. Moreover, + * this flag can't be changed after space creation. + */ + bool view; /** * SQL statement that produced this space. */ diff --git a/src/box/sql.c b/src/box/sql.c index 224747157..1e5f551ae 100644 --- a/src/box/sql.c +++ b/src/box/sql.c @@ -1592,9 +1592,16 @@ int tarantoolSqlite3MakeTableOpts(Table *pTable, const char *zSql, void *buf) const struct Enc *enc = get_enc(buf); char *base = buf, *p; - p = enc->encode_map(base, 1); + bool is_view = false; + if (pTable != NULL) + is_view = pTable->pSelect != NULL; + p = enc->encode_map(base, is_view ? 2 : 1); p = enc->encode_str(p, "sql", 3); p = enc->encode_str(p, zSql, strlen(zSql)); + if (is_view) { + p = enc->encode_str(p, "view", 4); + p = enc->encode_bool(p, true); + } return (int)(p - base); } diff --git a/test/box/misc.result b/test/box/misc.result index aeee42930..298e6a9ba 100644 --- a/test/box/misc.result +++ b/test/box/misc.result @@ -329,6 +329,7 @@ t; - 'box.error.ROLE_LOOP : 87' - 'box.error.TUPLE_NOT_FOUND : 4' - 'box.error.LOADING : 116' + - 'box.error.VIEW_MISSING_SQL : 161' - 'box.error.BACKUP_IN_PROGRESS : 129' - 'box.error.DROP_USER : 44' - 'box.error.MODIFY_INDEX : 14' diff --git a/test/sql/view.result b/test/sql/view.result new file mode 100644 index 000000000..9fc2ffe10 --- /dev/null +++ b/test/sql/view.result @@ -0,0 +1,67 @@ +test_run = require('test_run').new() +--- +... +-- Verify that constraints on 'view' option are working. +-- box.cfg() +-- Create space and view. +box.sql.execute("CREATE TABLE t1(a, b, PRIMARY KEY(a, b));"); +--- +... +box.sql.execute("CREATE VIEW v1 AS SELECT a+b FROM t1;"); +--- +... +-- View can't have any indexes. +box.sql.execute("CREATE INDEX i1 on v1(a);"); +--- +- error: views may not be indexed +... +v1 = box.space.V1; +--- +... +v1:create_index('primary', {parts = {1, 'string'}}) +--- +- error: 'Can''t modify space ''V1'': can not alter indexes on view' +... +v1:create_index('secondary', {parts = {1, 'string'}}) +--- +- error: 'Can''t modify space ''V1'': can not alter indexes on view' +... +-- View option can't be changed. +v1 = box.space._space.index[2]:select('V1')[1]:totable(); +--- +... +v1[6]['view'] = false; +--- +... +box.space._space:replace(v1); +--- +- error: 'Can''t modify space ''V1'': can not transform space to view and visa versa' +... +t1 = box.space._space.index[2]:select('T1')[1]:totable(); +--- +... +t1[6]['view'] = true; +--- +... +box.space._space:replace(t1); +--- +- error: 'Can''t modify space ''T1'': can not transform space to view and visa versa' +... +-- View can't exist without SQL statement. +v1[6] = {}; +--- +... +v1[6]['view'] = true; +--- +... +box.space._space:replace(v1); +--- +- error: Space declared as a view must have SQL statement +... +-- Cleanup +box.sql.execute("DROP TABLE t1;"); +--- +... +box.sql.execute("DROP VIEW v1;"); +--- +... diff --git a/test/sql/view.test.lua b/test/sql/view.test.lua new file mode 100644 index 000000000..8e1f96ece --- /dev/null +++ b/test/sql/view.test.lua @@ -0,0 +1,33 @@ +test_run = require('test_run').new() + +-- Verify that constraints on 'view' option are working. + +-- box.cfg() + +-- Create space and view. +box.sql.execute("CREATE TABLE t1(a, b, PRIMARY KEY(a, b));"); +box.sql.execute("CREATE VIEW v1 AS SELECT a+b FROM t1;"); + +-- View can't have any indexes. +box.sql.execute("CREATE INDEX i1 on v1(a);"); +v1 = box.space.V1; +v1:create_index('primary', {parts = {1, 'string'}}) +v1:create_index('secondary', {parts = {1, 'string'}}) + +-- View option can't be changed. +v1 = box.space._space.index[2]:select('V1')[1]:totable(); +v1[6]['view'] = false; +box.space._space:replace(v1); + +t1 = box.space._space.index[2]:select('T1')[1]:totable(); +t1[6]['view'] = true; +box.space._space:replace(t1); + +-- View can't exist without SQL statement. +v1[6] = {}; +v1[6]['view'] = true; +box.space._space:replace(v1); + +-- Cleanup +box.sql.execute("DROP TABLE t1;"); +box.sql.execute("DROP VIEW v1;"); -- 2.15.1
next reply other threads:[~2018-03-26 13:11 UTC|newest] Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-03-26 13:11 Nikita Pettik [this message] 2018-03-26 13:30 ` [tarantool-patches] " v.shpilevoy
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20180326131139.94448-1-korablev@tarantool.org \ --to=korablev@tarantool.org \ --cc=tarantool-patches@freelists.org \ --cc=v.shpilevoy@tarantool.org \ --subject='Re: [tarantool-patches] [PATCH] Introduce '\''view'\'' space option' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox