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 2/3] sql: add view column aliases to space format
Date: Tue,  3 Apr 2018 17:54:29 +0300	[thread overview]
Message-ID: <9e29014676ddcc7eb8852421d212eef8e8a33d6d.1522763649.git.korablev@tarantool.org> (raw)
In-Reply-To: <cover.1522763649.git.korablev@tarantool.org>
In-Reply-To: <cover.1522763649.git.korablev@tarantool.org>

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

  parent reply	other threads:[~2018-04-03 14:54 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-03 14:54 [tarantool-patches] [PATCH 0/3] Rework VIEW processing Nikita Pettik
2018-04-03 14:54 ` [tarantool-patches] [PATCH 1/3] sql: remove usless #ifdef directives Nikita Pettik
2018-04-03 17:23   ` [tarantool-patches] " Vladislav Shpilevoy
2018-04-03 14:54 ` Nikita Pettik [this message]
2018-04-03 14:54 ` [tarantool-patches] [PATCH 3/3] sql: load SELECT from 'CREATE VIEW ...' string Nikita Pettik

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=9e29014676ddcc7eb8852421d212eef8e8a33d6d.1522763649.git.korablev@tarantool.org \
    --to=korablev@tarantool.org \
    --cc=tarantool-patches@freelists.org \
    --cc=v.shpilevoy@tarantool.org \
    --subject='Re: [tarantool-patches] [PATCH 2/3] sql: add view column aliases to space format' \
    /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