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 4/6] sql: don't add string of 'CREATE TABLE...' to space opts Date: Mon, 10 Dec 2018 00:30:24 +0300 [thread overview] Message-ID: <8d774a673688db0503e67b05be1ece319bfd9ea4.1544387419.git.korablev@tarantool.org> (raw) In-Reply-To: <cover.1544387419.git.korablev@tarantool.org> In-Reply-To: <cover.1544387419.git.korablev@tarantool.org> We don't rely no more on this string anymore and it can be removed for ordinary tables. However, it is still used to hold SELECT body for view. Part of #2647 --- src/box/sql.c | 8 +- src/box/sql/analyze.c | 2 +- src/box/sql/build.c | 242 ++---------------------------------------------- src/box/sql/pragma.c | 2 - src/box/sql/sqliteInt.h | 1 - test/sql/upgrade.result | 8 +- test/sql/view.result | 3 + test/sql/view.test.lua | 1 + 8 files changed, 19 insertions(+), 248 deletions(-) diff --git a/src/box/sql.c b/src/box/sql.c index e9fa89df9..e79265823 100644 --- a/src/box/sql.c +++ b/src/box/sql.c @@ -1070,7 +1070,6 @@ char * sql_encode_table_opts(struct region *region, struct Table *table, const char *sql, uint32_t *size) { - assert(sql != NULL); size_t used = region_used(region); struct mpstream stream; bool is_error = false; @@ -1087,11 +1086,12 @@ sql_encode_table_opts(struct region *region, struct Table *table, a = checks->a; } } - mpstream_encode_map(&stream, 1 + is_view + (checks_cnt > 0)); + assert(is_view || sql == NULL); + mpstream_encode_map(&stream, 2 * is_view + (checks_cnt > 0)); - mpstream_encode_str(&stream, "sql"); - mpstream_encode_str(&stream, sql); if (is_view) { + mpstream_encode_str(&stream, "sql"); + mpstream_encode_str(&stream, sql); mpstream_encode_str(&stream, "view"); mpstream_encode_bool(&stream, true); } diff --git a/src/box/sql/analyze.c b/src/box/sql/analyze.c index 3f492800c..8f8b6eb5d 100644 --- a/src/box/sql/analyze.c +++ b/src/box/sql/analyze.c @@ -1056,7 +1056,7 @@ loadAnalysis(Parse * pParse) static int sql_space_foreach_analyze(struct space *space, void *data) { - if (space->def->opts.sql == NULL || space->def->opts.is_view) + if (space->def->opts.is_view) return 0; vdbe_emit_analyze_space((struct Parse*)data, space); return 0; diff --git a/src/box/sql/build.c b/src/box/sql/build.c index 52f0bde15..fd1666c6d 100644 --- a/src/box/sql/build.c +++ b/src/box/sql/build.c @@ -595,102 +595,6 @@ sql_column_add_nullable_action(struct Parse *parser, field->is_nullable = action_is_nullable(nullable_action); } -/* - * Scan the column type name zType (length nType) and return the - * associated affinity type. - * - * This routine does a case-independent search of zType for the - * substrings in the following table. If one of the substrings is - * found, the corresponding affinity is returned. If zType contains - * more than one of the substrings, entries toward the top of - * the table take priority. For example, if zType is 'BLOBINT', - * AFFINITY_INTEGER is returned. - * - * Substring | Affinity - * -------------------------------- - * 'INT' | AFFINITY_INTEGER - * 'CHAR' | AFFINITY_TEXT - * 'CLOB' | AFFINITY_TEXT - * 'TEXT' | AFFINITY_TEXT - * 'BLOB' | AFFINITY_BLOB - * 'REAL' | AFFINITY_REAL - * 'FLOA' | AFFINITY_REAL - * 'DOUB' | AFFINITY_REAL - * - * If none of the substrings in the above table are found, - * AFFINITY_NUMERIC is returned. - */ -char -sqlite3AffinityType(const char *zIn, u8 * pszEst) -{ - u32 h = 0; - char aff = AFFINITY_NUMERIC; - const char *zChar = 0; - - assert(zIn != 0); - while (zIn[0]) { - h = (h << 8) + sqlite3UpperToLower[(*zIn) & 0xff]; - zIn++; - if (h == (('c' << 24) + ('h' << 16) + ('a' << 8) + 'r')) { /* CHAR */ - aff = AFFINITY_TEXT; - zChar = zIn; - } else if (h == (('c' << 24) + ('l' << 16) + ('o' << 8) + 'b')) { /* CLOB */ - aff = AFFINITY_TEXT; - } else if (h == (('t' << 24) + ('e' << 16) + ('x' << 8) + 't')) { /* TEXT */ - aff = AFFINITY_TEXT; - } else if (h == (('b' << 24) + ('l' << 16) + ('o' << 8) + 'b') /* BLOB */ - &&(aff == AFFINITY_NUMERIC - || aff == AFFINITY_REAL)) { - aff = AFFINITY_BLOB; - if (zIn[0] == '(') - zChar = zIn; -#ifndef SQLITE_OMIT_FLOATING_POINT - } else if (h == (('r' << 24) + ('e' << 16) + ('a' << 8) + 'l') /* REAL */ - &&aff == AFFINITY_NUMERIC) { - aff = AFFINITY_REAL; - } else if (h == (('f' << 24) + ('l' << 16) + ('o' << 8) + 'a') /* FLOA */ - &&aff == AFFINITY_NUMERIC) { - aff = AFFINITY_REAL; - } else if (h == (('d' << 24) + ('o' << 16) + ('u' << 8) + 'b') /* DOUB */ - &&aff == AFFINITY_NUMERIC) { - aff = AFFINITY_REAL; -#endif - } else if ((h & 0x00FFFFFF) == (('i' << 16) + ('n' << 8) + 't')) { /* INT */ - aff = AFFINITY_INTEGER; - break; - } - } - - /* If pszEst is not NULL, store an estimate of the field size. The - * estimate is scaled so that the size of an integer is 1. - */ - if (pszEst) { - *pszEst = 1; /* default size is approx 4 bytes - */ - if (aff < AFFINITY_NUMERIC) { - if (zChar) { - while (zChar[0]) { - if (sqlite3Isdigit(zChar[0])) { - int v = 0; - sqlite3GetInt32(zChar, &v); - v = v / 4 + 1; - if (v > 255) - v = 255; - *pszEst = v; /* BLOB(k), VARCHAR(k), CHAR(k) -> r=(k/4+1) - */ - break; - } - zChar++; - } - } else { - *pszEst = 5; /* BLOB, TEXT, CLOB -> r=5 (approx 20 bytes) - */ - } - } - } - return aff; -} - /* * The expression is the default value for the most recently added column * of the table currently under construction. @@ -959,136 +863,6 @@ vdbe_emit_open_cursor(struct Parse *parse_context, int cursor, int index_id, index_id, 0, (void *) space, P4_SPACEPTR); } -/* - * Measure the number of characters needed to output the given - * identifier. The number returned includes any quotes used - * but does not include the null terminator. - * - * The estimate is conservative. It might be larger that what is - * really needed. - */ -static int -identLength(const char *z) -{ - int n; - for (n = 0; *z; n++, z++) { - if (*z == '"') { - n++; - } - } - return n + 2; -} - -/* - * The first parameter is a pointer to an output buffer. The second - * parameter is a pointer to an integer that contains the offset at - * which to write into the output buffer. This function copies the - * nul-terminated string pointed to by the third parameter, zSignedIdent, - * to the specified offset in the buffer and updates *pIdx to refer - * to the first byte after the last byte written before returning. - * - * If the string zSignedIdent consists entirely of alpha-numeric - * characters, does not begin with a digit and is not an SQL keyword, - * then it is copied to the output buffer exactly as it is. Otherwise, - * it is quoted using double-quotes. - */ -static void -identPut(char *z, int *pIdx, char *zSignedIdent) -{ - unsigned char *zIdent = (unsigned char *)zSignedIdent; - int i, j, needQuote; - i = *pIdx; - - for (j = 0; zIdent[j]; j++) { - if (!sqlite3Isalnum(zIdent[j]) && zIdent[j] != '_') - break; - } - needQuote = sqlite3Isdigit(zIdent[0]) - || sqlite3KeywordCode(zIdent, j) != TK_ID - || zIdent[j] != 0 || j == 0; - - if (needQuote) - z[i++] = '"'; - for (j = 0; zIdent[j]; j++) { - z[i++] = zIdent[j]; - if (zIdent[j] == '"') - z[i++] = '"'; - } - if (needQuote) - z[i++] = '"'; - z[i] = 0; - *pIdx = i; -} - -/* - * Generate a CREATE TABLE statement appropriate for the given - * table. Memory to hold the text of the statement is obtained - * from sqliteMalloc() and must be freed by the calling function. - */ -static char * -createTableStmt(sqlite3 * db, Table * p) -{ - char *zStmt; - char *zSep, *zSep2, *zEnd; - int n = 0; - for (uint32_t i = 0; i < p->def->field_count; i++) - n += identLength(p->def->fields[i].name) + 5; - n += identLength(p->def->name); - if (n < 50) { - zSep = ""; - zSep2 = ","; - zEnd = ")"; - } else { - zSep = "\n "; - zSep2 = ",\n "; - zEnd = "\n)"; - } - n += 35 + 6 * p->def->field_count; - zStmt = sqlite3DbMallocRaw(0, n); - if (zStmt == 0) { - sqlite3OomFault(db); - return 0; - } - sqlite3_snprintf(n, zStmt, "CREATE TABLE "); - int k = sqlite3Strlen30(zStmt); - identPut(zStmt, &k, p->def->name); - zStmt[k++] = '('; - for (uint32_t i = 0; i < p->def->field_count; i++) { - static const char *const azType[] = { - /* AFFINITY_BLOB */ "", - /* AFFINITY_TEXT */ " TEXT", - /* AFFINITY_NUMERIC */ " NUM", - /* AFFINITY_INTEGER */ " INT", - /* AFFINITY_REAL */ " REAL" - }; - int len; - const char *zType; - - sqlite3_snprintf(n - k, &zStmt[k], zSep); - k += sqlite3Strlen30(&zStmt[k]); - zSep = zSep2; - identPut(zStmt, &k, p->def->fields[i].name); - char affinity = p->def->fields[i].affinity; - assert(affinity - AFFINITY_BLOB >= 0); - assert(affinity - AFFINITY_BLOB < ArraySize(azType)); - testcase(affinity == AFFINITY_BLOB); - testcase(affinity == AFFINITY_TEXT); - testcase(affinity == AFFINITY_NUMERIC); - testcase(affinity == AFFINITY_INTEGER); - testcase(affinity == AFFINITY_REAL); - - zType = azType[affinity - AFFINITY_BLOB]; - len = sqlite3Strlen30(zType); - assert(affinity == AFFINITY_BLOB || - affinity == sqlite3AffinityType(zType, 0)); - memcpy(&zStmt[k], zType, len); - k += len; - assert(k <= n); - } - sqlite3_snprintf(n - k, &zStmt[k], "%s", zEnd); - return zStmt; -} - /* * Generate code to determine the new space Id. * Fetch the max space id seen so far from _schema and increment it. @@ -1524,19 +1298,15 @@ sqlite3EndTable(Parse * pParse, /* Parse context */ if (NEVER(v == 0)) return; - /* Text of the CREATE TABLE or CREATE VIEW statement. */ - char *stmt; - if (pSelect) { - stmt = createTableStmt(db, p); - } else { - struct Token *pEnd2 = p->def->opts.is_view ? - &pParse->sLastToken : pEnd; + /* Text of the CREATE VIEW statement. */ + char *stmt = NULL; + if (p->def->opts.is_view) { + struct Token *pEnd2 = &pParse->sLastToken; int n = pEnd2->z - pParse->sNameToken.z; if (pEnd2->z[0] != ';') n += pEnd2->n; - stmt = sqlite3MPrintf(db, "CREATE %s %.*s", - p->def->opts.is_view ? "VIEW" : "TABLE", - n, pParse->sNameToken.z); + stmt = sqlite3MPrintf(db, "CREATE VIEW %.*s", n, + pParse->sNameToken.z); } int reg_space_id = getNewSpaceId(pParse); createSpace(pParse, reg_space_id, stmt); diff --git a/src/box/sql/pragma.c b/src/box/sql/pragma.c index 5c3501702..325c272b0 100644 --- a/src/box/sql/pragma.c +++ b/src/box/sql/pragma.c @@ -347,8 +347,6 @@ sql_pragma_index_info(struct Parse *parse, struct space *space = space_by_name(tbl_name); if (space == NULL) return; - if (space->def->opts.sql == NULL) - return; uint32_t iid = box_index_id_by_name(space->def->id, idx_name, strlen(idx_name)); if (iid == BOX_ID_NIL) diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h index dbf58d967..ae6886685 100644 --- a/src/box/sql/sqliteInt.h +++ b/src/box/sql/sqliteInt.h @@ -4474,7 +4474,6 @@ char* rename_trigger(sqlite3 *, char const *, char const *, bool *); */ struct coll * sql_get_coll_seq(Parse *parser, const char *name, uint32_t *coll_id); -char sqlite3AffinityType(const char *, u8 *); void sqlite3Analyze(Parse *, Token *); /** diff --git a/test/sql/upgrade.result b/test/sql/upgrade.result index 5e7d85109..79c7eb245 100644 --- a/test/sql/upgrade.result +++ b/test/sql/upgrade.result @@ -80,13 +80,13 @@ box.sql.execute("CREATE TRIGGER t2t AFTER INSERT ON t BEGIN INSERT INTO t_out VA ... box.space._space.index['name']:get('T') --- -- [513, 1, 'T', 'memtx', 1, {'sql': 'CREATE TABLE t(x INTEGER PRIMARY KEY)'}, [{'affinity': 68, - 'type': 'integer', 'nullable_action': 'abort', 'name': 'X', 'is_nullable': false}]] +- [513, 1, 'T', 'memtx', 1, {}, [{'affinity': 68, 'type': 'integer', 'nullable_action': 'abort', + 'name': 'X', 'is_nullable': false}]] ... box.space._space.index['name']:get('T_OUT') --- -- [514, 1, 'T_OUT', 'memtx', 1, {'sql': 'CREATE TABLE t_out(x INTEGER PRIMARY KEY)'}, - [{'affinity': 68, 'type': 'integer', 'nullable_action': 'abort', 'name': 'X', 'is_nullable': false}]] +- [514, 1, 'T_OUT', 'memtx', 1, {}, [{'affinity': 68, 'type': 'integer', 'nullable_action': 'abort', + 'name': 'X', 'is_nullable': false}]] ... t1t = box.space._trigger:get('T1T') --- diff --git a/test/sql/view.result b/test/sql/view.result index b211bcb2e..3d2569524 100644 --- a/test/sql/view.result +++ b/test/sql/view.result @@ -49,6 +49,9 @@ t1 = box.space._space.index[2]:select('T1')[1]:totable(); t1[6]['view'] = true; --- ... +t1[6]['sql'] = 'SELECT * FROM t1;' +--- +... box.space._space:replace(t1); --- - error: 'Can''t modify space ''T1'': can not convert a space to a view and vice versa' diff --git a/test/sql/view.test.lua b/test/sql/view.test.lua index a6269a1bf..239e4ce5e 100644 --- a/test/sql/view.test.lua +++ b/test/sql/view.test.lua @@ -23,6 +23,7 @@ box.space._space:replace(v1); t1 = box.space._space.index[2]:select('T1')[1]:totable(); t1[6]['view'] = true; +t1[6]['sql'] = 'SELECT * FROM t1;' box.space._space:replace(t1); -- View can't exist without SQL statement. -- 2.15.1
next prev parent reply other threads:[~2018-12-09 21:30 UTC|newest] Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-12-09 21:30 [tarantool-patches] [PATCH 0/6] Remove string of SQL statement from opts Nikita Pettik 2018-12-09 21:30 ` [tarantool-patches] [PATCH 1/6] sql: avoid calling sql_encode_table_opts() during trigger creation Nikita Pettik 2018-12-10 14:17 ` [tarantool-patches] " Vladislav Shpilevoy 2018-12-11 18:29 ` n.pettik 2018-12-09 21:30 ` [tarantool-patches] [PATCH 2/6] sql: don't update SQL string during renaming Nikita Pettik 2018-12-10 14:16 ` [tarantool-patches] " Vladislav Shpilevoy 2018-12-11 18:29 ` n.pettik 2018-12-12 12:36 ` Vladislav Shpilevoy 2018-12-13 12:42 ` n.pettik 2018-12-09 21:30 ` [tarantool-patches] [PATCH 3/6] test: fix sqltester methods to drop all tables/views Nikita Pettik 2018-12-10 14:16 ` [tarantool-patches] " Vladislav Shpilevoy 2018-12-11 18:29 ` n.pettik 2018-12-09 21:30 ` Nikita Pettik [this message] 2018-12-10 14:17 ` [tarantool-patches] Re: [PATCH 4/6] sql: don't add string of 'CREATE TABLE...' to space opts Vladislav Shpilevoy 2018-12-11 18:29 ` n.pettik 2018-12-09 21:30 ` [tarantool-patches] [PATCH 5/6] sql: don't add string of 'CREATE INDEX ...' to index opts Nikita Pettik 2018-12-10 14:18 ` [tarantool-patches] " Vladislav Shpilevoy 2018-12-11 18:29 ` n.pettik 2018-12-09 21:30 ` [tarantool-patches] [PATCH 6/6] Remove SQL string from " Nikita Pettik 2018-12-25 13:45 ` [tarantool-patches] Re: [PATCH 0/6] Remove string of SQL statement from opts Kirill Yukhin
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=8d774a673688db0503e67b05be1ece319bfd9ea4.1544387419.git.korablev@tarantool.org \ --to=korablev@tarantool.org \ --cc=tarantool-patches@freelists.org \ --cc=v.shpilevoy@tarantool.org \ --subject='Re: [tarantool-patches] [PATCH 4/6] sql: don'\''t add string of '\''CREATE TABLE...'\'' to space opts' \ /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