From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id C7AB12B2FF for ; Thu, 20 Sep 2018 22:24:49 -0400 (EDT) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 6owWKbuGDycl for ; Thu, 20 Sep 2018 22:24:49 -0400 (EDT) Received: from smtp47.i.mail.ru (smtp47.i.mail.ru [94.100.177.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id E1CB22A411 for ; Thu, 20 Sep 2018 22:24:48 -0400 (EDT) From: Alexander Turenko Subject: [tarantool-patches] [PATCH] sql: change of PRAGMA INDEX_INFO syntax Date: Fri, 21 Sep 2018 05:24:36 +0300 Message-Id: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-help: List-unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-subscribe: List-owner: List-post: List-archive: To: Nikita Pettik Cc: Ivan Ilyin , tarantool-patches@freelists.org From: Ivan Ilyin This change removes 'pragma index_xinfo' syntax. 'pragma index_info' now works as 'pragma index_xinfo' and also displays type of columns in index. Cleaned up pragma column names array (pragma.h::pragCName). Fixes #3194 --- branch: https://github.com/tarantool/tarantool/tree/gh-3194-pragma-index_info-syntax issue: https://github.com/tarantool/tarantool/issues/3194 src/box/sql/parse.y | 2 +- src/box/sql/pragma.c | 37 +++++-------- src/box/sql/pragma.h | 95 +++++++++++++------------------- test/sql-tap/index-info.test.lua | 90 ++++++++++++++++++------------ test/sql-tap/index7.test.lua | 8 ++- 5 files changed, 114 insertions(+), 118 deletions(-) diff --git a/src/box/sql/parse.y b/src/box/sql/parse.y index 473cf89d8..042823267 100644 --- a/src/box/sql/parse.y +++ b/src/box/sql/parse.y @@ -1286,7 +1286,7 @@ cmd ::= PRAGMA nm(X) EQ minus_num(Y). { cmd ::= PRAGMA nm(X) LP minus_num(Y) RP. { sqlite3Pragma(pParse,&X,&Y,0,1); } -cmd ::= PRAGMA nm(X) EQ nm(Z) DOT nm(Y). { +cmd ::= PRAGMA nm(X) LP nm(Z) DOT nm(Y) RP. { sqlite3Pragma(pParse,&X,&Y,&Z,0); } cmd ::= PRAGMA . { diff --git a/src/box/sql/pragma.c b/src/box/sql/pragma.c index 4f64ab6f2..0eacef5c0 100644 --- a/src/box/sql/pragma.c +++ b/src/box/sql/pragma.c @@ -322,8 +322,7 @@ sql_pragma_table_stats(struct space *space, void *data) } /** - * This function handles PRAGMA INDEX_INFO and PRAGMA INDEX_XINFO - * statements. + * This function handles PRAGMA INDEX_INFO statement. * * @param parse Current parsing content. * @param pragma Definition of index_info pragma. @@ -349,32 +348,26 @@ sql_pragma_index_info(struct Parse *parse, const PragmaName *pragma, return; struct index *idx = space_index(space, iid); assert(idx != NULL); - /* PRAGMA index_xinfo (more informative version). */ - if (pragma->iArg > 0) { - parse->nMem = 6; - } else { - /* PRAGMA index_info ... */ - parse->nMem = 3; - } + parse->nMem = 7; struct Vdbe *v = sqlite3GetVdbe(parse); assert(v != NULL); uint32_t part_count = idx->def->key_def->part_count; assert(parse->nMem <= pragma->nPragCName); struct key_part *part = idx->def->key_def->parts; for (uint32_t i = 0; i < part_count; i++, part++) { - sqlite3VdbeMultiLoad(v, 1, "iis", i, part->fieldno, - space->def->fields[part->fieldno].name); - if (pragma->iArg > 0) { - const char *c_n; - uint32_t id = part->coll_id; - struct coll *coll = part->coll; - if (coll != NULL) - c_n = coll_by_id(id)->name; - else - c_n = "BINARY"; - sqlite3VdbeMultiLoad(v, 4, "isi", part->sort_order, - c_n, i < part_count); - } + const char *c_n; + uint32_t id = part->coll_id; + struct coll *coll = part->coll; + if (coll != NULL) + c_n = coll_by_id(id)->name; + else + c_n = "BINARY"; + uint32_t fieldno = part->fieldno; + enum field_type type = space->def->fields[fieldno].type; + sqlite3VdbeMultiLoad(v, 1, "iisisis", i, fieldno, + space->def->fields[fieldno].name, + part->sort_order, c_n, i < part_count, + field_type_strs[type]); sqlite3VdbeAddOp2(v, OP_ResultRow, 1, parse->nMem); } } diff --git a/src/box/sql/pragma.h b/src/box/sql/pragma.h index ecc9ee879..50c7d164d 100644 --- a/src/box/sql/pragma.h +++ b/src/box/sql/pragma.h @@ -31,61 +31,46 @@ * result column is different from the name of the pragma */ static const char *const pragCName[] = { - /* 0 */ "cid", - /* Used by: table_info */ + /* Used by: table_info */ + /* 0 */ "cid", /* 1 */ "name", /* 2 */ "type", /* 3 */ "notnull", /* 4 */ "dflt_value", /* 5 */ "pk", - /* 6 */ "table", - /* Used by: stats */ + /* Used by: stats */ + /* 6 */ "table", /* 7 */ "index", /* 8 */ "width", /* 9 */ "height", - /* 10 */ "seqno", - /* Used by: index_info */ + /* Used by: index_info */ + /* 10 */ "seqno", /* 11 */ "cid", /* 12 */ "name", - /* 13 */ "seqno", - /* Used by: index_xinfo */ - /* 14 */ "cid", - /* 15 */ "name", - /* 16 */ "desc", - /* 17 */ "coll", - /* 18 */ "key", - /* 19 */ "seq", - /* Used by: index_list */ - /* 20 */ "name", - /* 21 */ "unique", - /* 22 */ "origin", - /* 23 */ "partial", - /* 24 */ "seq", - /* Used by: database_list */ - /* 25 */ "name", - /* 26 */ "file", - /* 27 */ "seq", - /* Used by: collation_list */ - /* 28 */ "name", - /* 29 */ "id", - /* Used by: foreign_key_list */ - /* 30 */ "seq", - /* 31 */ "table", - /* 32 */ "from", - /* 33 */ "to", - /* 34 */ "on_update", - /* 35 */ "on_delete", - /* 36 */ "match", - /* 37 */ "table", - /* 38 */ "rowid", - /* 39 */ "parent", - /* 40 */ "fkid", - /* 41 */ "busy", - /* Used by: wal_checkpoint */ - /* 42 */ "log", - /* 43 */ "checkpointed", - /* 44 */ "timeout", - /* Used by: busy_timeout */ + /* 13 */ "desc", + /* 14 */ "coll", + /* 15 */ "key", + /* 16 */ "type", + /* Used by: index_list */ + /* 17 */ "seq", + /* 18 */ "name", + /* 19 */ "unique", + /* 20 */ "origin", + /* 21 */ "partial", + /* Used by: collation_list */ + /* 22 */ "seq", + /* 23 */ "name", + /* Used by: foreign_key_list */ + /* 24 */ "id", + /* 25 */ "seq", + /* 26 */ "table", + /* 27 */ "from", + /* 28 */ "to", + /* 29 */ "on_update", + /* 30 */ "on_delete", + /* 31 */ "match", + /* Used by: busy_timeout */ + /* 32 */ "timeout", }; /* Definitions of all built-in pragmas */ @@ -97,11 +82,13 @@ typedef struct PragmaName { u8 nPragCName; /* Num of col names. 0 means use pragma name */ u32 iArg; /* Extra argument */ } PragmaName; +/* The order of pragmas in this array is important: it has */ +/* to be sorted. For more info see pragma_locate function. */ static const PragmaName aPragmaName[] = { { /* zName: */ "busy_timeout", /* ePragTyp: */ PragTyp_BUSY_TIMEOUT, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 44, 1, + /* ColNames: */ 32, 1, /* iArg: */ 0}, { /* zName: */ "case_sensitive_like", /* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE, @@ -112,7 +99,7 @@ static const PragmaName aPragmaName[] = { { /* zName: */ "collation_list", /* ePragTyp: */ PragTyp_COLLATION_LIST, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 27, 2, + /* ColNames: */ 22, 2, /* iArg: */ 0}, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) @@ -133,7 +120,7 @@ static const PragmaName aPragmaName[] = { /* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST, /* ePragFlg: */ PragFlg_NeedSchema | PragFlg_Result1 | PragFlg_SchemaOpt, - /* ColNames: */ 29, 8, + /* ColNames: */ 24, 8, /* iArg: */ 0}, #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) { /* zName: */ "foreign_keys", @@ -161,20 +148,14 @@ static const PragmaName aPragmaName[] = { /* ePragTyp: */ PragTyp_INDEX_INFO, /* ePragFlg: */ PragFlg_NeedSchema | PragFlg_Result1 | PragFlg_SchemaOpt, - /* ColNames: */ 10, 3, - /* iArg: */ 0}, + /* ColNames: */ 10, 7, + /* iArg: */ 1}, { /* zName: */ "index_list", /* ePragTyp: */ PragTyp_INDEX_LIST, /* ePragFlg: */ PragFlg_NeedSchema | PragFlg_Result1 | PragFlg_SchemaOpt, - /* ColNames: */ 19, 5, + /* ColNames: */ 17, 5, /* iArg: */ 0}, - { /* zName: */ "index_xinfo", - /* ePragTyp: */ PragTyp_INDEX_INFO, - /* ePragFlg: */ - PragFlg_NeedSchema | PragFlg_Result1 | PragFlg_SchemaOpt, - /* ColNames: */ 13, 6, - /* iArg: */ 1}, #endif #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_PARSER_TRACE) { /* zName: */ "parser_trace", diff --git a/test/sql-tap/index-info.test.lua b/test/sql-tap/index-info.test.lua index d3bb70e2d..198a0092d 100755 --- a/test/sql-tap/index-info.test.lua +++ b/test/sql-tap/index-info.test.lua @@ -1,50 +1,68 @@ #!/usr/bin/env tarantool -test = require("sqltester") -test:plan(4) + +local test = require("sqltester") +test:plan(6) test:execsql([[ - CREATE TABLE t1(a INT PRIMARY KEY, b INT UNIQUE, c INT); - INSERT INTO t1 VALUES (1, 1, 1), (2, 2, 2); - INSERT INTO t1 VALUES (3, 3, 3), (4, 4, 4); - CREATE INDEX t1ix1 ON t1(a); - CREATE INDEX t1ix2 ON t1(a, b); - CREATE INDEX t1ix3 ON t1(a, b, c); + CREATE TABLE t1(a INT PRIMARY KEY, b INT UNIQUE, c INT, d STRING); + INSERT INTO t1 VALUES (1, 1, 1, 'abcd'), (2, 2, 2, 'abcde'); + INSERT INTO t1 VALUES (3, 3, 3, 'abcdef'), (4, 4, 4, 'abcdefg'); + CREATE INDEX a ON t1(a); + CREATE INDEX abc ON t1(a, b, c); + CREATE INDEX cba ON t1(c, b, a); + CREATE INDEX d ON t1(d); ]]) +-- Case: old index_xinfo pragma is banned. +test:do_catchsql_test( + "index-info-1.1", + "PRAGMA index_xinfo (t1.a);", + { + 1, "no such pragma: INDEX_XINFO", + }) + +-- Case: old index_info syntax is banned. +test:do_catchsql_test( + "index-info-1.2", + "PRAGMA index_info = t1.a;", + { + 1, "near \".\": syntax error", + }) + +-- Case: single column index with an integer column. test:do_execsql_test( - "index-info-1.1", - "PRAGMA index_info = t1.t1ix1;", - { - -- - 0, 0, 'A' - -- - }) + "index-info-1.3", + "PRAGMA index_info (t1.a);", + { + 0, 0, 'A', 0, 'BINARY', 1, 'integer', + }) +-- Case: multiple columns index with integer columns. test:do_execsql_test( - "index-info-1.2", - "PRAGMA index_info = t1.t1ix2;", - { - -- - 0, 0, 'A', 1, 1, 'B', - -- - }) + "index-info-1.4", + "PRAGMA index_info (t1.abc);", + { + 0, 0, 'A', 0, 'BINARY', 1, 'integer', + 1, 1, 'B', 0, 'BINARY', 1, 'scalar', + 2, 2, 'C', 0, 'BINARY', 1, 'scalar', + }) +-- Case: multiple columns, reverse columns order. test:do_execsql_test( - "index-info-1.3", - "PRAGMA index_info = t1.t1ix3;", - { - -- - 0, 0, 'A', 1, 1, 'B', 2, 2, 'C' - -- - }) + "index-info-1.5", + "PRAGMA index_info (t1.cba);", + { + 0, 2, 'C', 0, 'BINARY', 1, 'scalar', + 1, 1, 'B', 0, 'BINARY', 1, 'scalar', + 2, 0, 'A', 0, 'BINARY', 1, 'integer', + }) +-- Case: index with a string column. test:do_execsql_test( - "index-info-1.1", - "PRAGMA index_xinfo = t1.t1ix1;", - { - -- - 0, 0, 'A', 0, 'BINARY', 1, - -- - }) + "index-info-1.6", + "PRAGMA index_info (t1.d);", + { + 0, 3, 'D', 0, 'BINARY', 1, 'scalar', + }) test:finish_test() diff --git a/test/sql-tap/index7.test.lua b/test/sql-tap/index7.test.lua index 7d4a54723..9eb644dd5 100755 --- a/test/sql-tap/index7.test.lua +++ b/test/sql-tap/index7.test.lua @@ -307,9 +307,13 @@ test:do_catchsql_test( [[ CREATE TABLE t(a,b,c, PRIMARY KEY(a)); CREATE INDEX i1 ON t(a, a, b, c, c, b, b, b, c, b, c); - pragma index_info = t.i1; + pragma index_info(t.i1); ]], - {0, {0,0,"A",1,1,"B",2,2,"C"}} + {0, { + 0, 0, 'A', 0, 'BINARY', 1, 'scalar', + 1, 1, 'B', 0, 'BINARY', 1, 'scalar', + 2, 2, 'C', 0, 'BINARY', 1, 'scalar', + }} ) -- There was the following bug: -- 2.19.0