[tarantool-patches] [PATCH 2/3] sql: add view column aliases to space format

Nikita Pettik korablev at tarantool.org
Tue Apr 3 17:54:29 MSK 2018


One can create view as: 'CREATE VIEW v(a, b) AS SELECT ...'.
This patch adds these column aliases to space format just as named
fields. It is worth mentioning, that we can't fetch types of columns
from SELECT statement at this stage, since table to select from may not
exist:

    CREATE VIEW v AS SELECT * FROM t1;
    CREATE TABLE t1(id PRIMARY KEY);
    SELECT * FROM v;

Part of #3300
---
 src/box/sql.c              | 22 ++++++++++++++++++++--
 src/box/sql/build.c        | 13 +++++++++----
 src/box/sql/tarantoolInt.h |  2 +-
 3 files changed, 30 insertions(+), 7 deletions(-)

diff --git a/src/box/sql.c b/src/box/sql.c
index c2577abef..acee96d27 100644
--- a/src/box/sql.c
+++ b/src/box/sql.c
@@ -1450,7 +1450,7 @@ static const char *convertSqliteAffinity(int affinity, bool allow_nulls)
  *
  * Ex: [{"name": "col1", "type": "integer"}, ... ]
  */
-int tarantoolSqlite3MakeTableFormat(Table *pTable, void *buf)
+int tarantoolSqlite3MakeTableFormat(Parse *parse, Table *pTable, void *buf)
 {
 	struct Column *aCol = pTable->aCol;
 	const struct Enc *enc = get_enc(buf);
@@ -1459,7 +1459,8 @@ int tarantoolSqlite3MakeTableFormat(Table *pTable, void *buf)
 	char *base = buf, *p;
 	int i, n = pTable->nCol;
 
-	p = enc->encode_array(base, n);
+	if (n != 0 || pTable->pCheck == NULL)
+		p = enc->encode_array(base, n);
 
 	/* If table's PK is single column which is INTEGER, then
 	 * treat it as strict type, not affinity.  */
@@ -1511,6 +1512,23 @@ int tarantoolSqlite3MakeTableFormat(Table *pTable, void *buf)
 			p = enc->encode_str(p, def->u.zToken, strlen(def->u.zToken));
 		}
 	}
+	/* If table is really a view, set only fields names.
+	 * In this case they are encoded as CHECK constraints.
+	 */
+	if (n == 0 && pTable->pCheck != NULL) {
+		Column *cols;
+		i16 col_count;
+		sqlite3ColumnsFromExprList(parse, pTable->pCheck,
+					   &col_count, &cols);
+		p = enc->encode_array(base, col_count);
+		for (i = 0; i < col_count; ++i) {
+			p = enc->encode_map(p, 1);
+			p = enc->encode_str(p, "name", 4);
+			p = enc->encode_str(p, cols[i].zName,
+					    strlen(cols[i].zName));
+		}
+		sqlite3_free(cols);
+	}
 	return (int)(p - base);
 }
 
diff --git a/src/box/sql/build.c b/src/box/sql/build.c
index 75b26a93a..293d88a60 100644
--- a/src/box/sql/build.c
+++ b/src/box/sql/build.c
@@ -1639,7 +1639,7 @@ createSpace(Parse * pParse, int iSpaceId, char *zStmt)
 	int zOptsSz, zFormatSz;
 
 	zOpts = sqlite3DbMallocRaw(pParse->db,
-				   tarantoolSqlite3MakeTableFormat(p, NULL) +
+				   tarantoolSqlite3MakeTableFormat(pParse, p, NULL) +
 				   tarantoolSqlite3MakeTableOpts(p, zStmt,
 								 NULL) + 2);
 	if (!zOpts) {
@@ -1649,7 +1649,7 @@ createSpace(Parse * pParse, int iSpaceId, char *zStmt)
 	} else {
 		zOptsSz = tarantoolSqlite3MakeTableOpts(p, zStmt, zOpts);
 		zFormat = zOpts + zOptsSz + 1;
-		zFormatSz = tarantoolSqlite3MakeTableFormat(p, zFormat);
+		zFormatSz = tarantoolSqlite3MakeTableFormat(pParse, p, zFormat);
 #if SQLITE_DEBUG
 		/* NUL-termination is necessary for VDBE-tracing facility only */
 		zOpts[zOptsSz] = 0;
@@ -1664,8 +1664,13 @@ createSpace(Parse * pParse, int iSpaceId, char *zStmt)
 			  sqlite3DbStrDup(pParse->db, p->zName), P4_DYNAMIC);
 	sqlite3VdbeAddOp4(v, OP_String8, 0, iFirstCol + 3 /* engine */ , 0,
 			  "memtx", P4_STATIC);
-	sqlite3VdbeAddOp2(v, OP_Integer, p->nCol,
-			  iFirstCol + 4 /* field_count */ );
+	/* Add field count. */
+	if (p->pSelect != NULL && p->pCheck != NULL) {
+		sqlite3VdbeAddOp2(v, OP_Integer, p->pCheck->nExpr,
+				  iFirstCol + 4);
+	} else {
+		sqlite3VdbeAddOp2(v, OP_Integer, p->nCol, iFirstCol + 4);
+	}
 	sqlite3VdbeAddOp4(v, OP_Blob, zOptsSz, iFirstCol + 5, MSGPACK_SUBTYPE,
 			  zOpts, P4_DYNAMIC);
 	/* zOpts and zFormat are co-located, hence STATIC */
diff --git a/src/box/sql/tarantoolInt.h b/src/box/sql/tarantoolInt.h
index 65acf1198..5649a9cae 100644
--- a/src/box/sql/tarantoolInt.h
+++ b/src/box/sql/tarantoolInt.h
@@ -126,7 +126,7 @@ tarantoolSqlite3IncrementMaxid(uint64_t *space_max_id);
  * Returns result size.
  * If buf==NULL estimate result size.
  */
-int tarantoolSqlite3MakeTableFormat(Table * pTable, void *buf);
+int tarantoolSqlite3MakeTableFormat(Parse *parse, Table * pTable, void *buf);
 
 /*
  * Format "opts" dictionary for _space entry.
-- 
2.15.1





More information about the Tarantool-patches mailing list