Tarantool development patches archive
 help / color / mirror / Atom feed
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

  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