[tarantool-patches] [PATCH 10/10] sql: move autoincrement field number to server

Nikita Pettik korablev at tarantool.org
Sun Aug 12 17:13:06 MSK 2018


During INSERT SQL statement execution we may need to know field which
stores INTEGER AUTOINCREMENT PRIMARY KEY. Since we are going to get rid
of struct Table, lets move this member to space's opts.

Part of #3561
---
 src/box/space_def.c     |  3 +++
 src/box/space_def.h     |  5 +++++
 src/box/sql.c           | 11 +++++++++--
 src/box/sql/build.c     |  6 +++---
 src/box/sql/insert.c    | 20 +++++++++++++-------
 src/box/sql/sqliteInt.h |  2 --
 6 files changed, 33 insertions(+), 14 deletions(-)

diff --git a/src/box/space_def.c b/src/box/space_def.c
index f5ca0b59a..d81546413 100644
--- a/src/box/space_def.c
+++ b/src/box/space_def.c
@@ -56,6 +56,7 @@ const struct space_opts space_opts_default = {
 	/* .view = */ false,
 	/* .sql        = */ NULL,
 	/* .checks     = */ NULL,
+	/* .sql_autoinc_fieldno = */ UINT32_MAX,
 };
 
 const struct opt_def space_opts_reg[] = {
@@ -65,6 +66,8 @@ const struct opt_def space_opts_reg[] = {
 	OPT_DEF("sql", OPT_STRPTR, struct space_opts, sql),
 	OPT_DEF_ARRAY("checks", struct space_opts, checks,
 		      checks_array_decode),
+	OPT_DEF("sql_autoinc", OPT_UINT32, struct space_opts,
+		sql_autoinc_fieldno),
 	OPT_END,
 };
 
diff --git a/src/box/space_def.h b/src/box/space_def.h
index 0d1e90233..c5d305bf6 100644
--- a/src/box/space_def.h
+++ b/src/box/space_def.h
@@ -68,6 +68,11 @@ struct space_opts {
 	char *sql;
 	/** SQL Checks expressions list. */
 	struct ExprList *checks;
+	/**
+	 * If SQL table is created with AUTOINCREMENT primary
+	 * key then this member contains its ordinal number.
+	 */
+	uint32_t sql_autoinc_fieldno;
 };
 
 extern const struct space_opts space_opts_default;
diff --git a/src/box/sql.c b/src/box/sql.c
index 1f59946f0..d169b18ed 100644
--- a/src/box/sql.c
+++ b/src/box/sql.c
@@ -749,7 +749,7 @@ sql_rename_table(uint32_t space_id, const char *new_name, char **sql_stmt)
 	if (sql_stmt_map == NULL || mp_typeof(*sql_stmt_map) != MP_MAP)
 		goto rename_fail;
 	uint32_t map_size = mp_decode_map(&sql_stmt_map);
-	if (map_size != 1)
+	if (map_size == 0)
 		goto rename_fail;
 	const char *sql_str = mp_decode_str(&sql_stmt_map, &key_len);
 
@@ -1358,8 +1358,11 @@ tarantoolSqlite3MakeTableOpts(Table *pTable, const char *zSql, char *buf)
 	const struct Enc *enc = get_enc(buf);
 	bool is_view = pTable != NULL && pTable->def->opts.is_view;
 	bool has_checks = pTable != NULL && pTable->def->opts.checks != NULL;
+	bool has_autoinc = pTable != NULL &&
+			   pTable->def->opts.sql_autoinc_fieldno != UINT32_MAX;
 	int checks_cnt = has_checks ? pTable->def->opts.checks->nExpr : 0;
-	char *p = enc->encode_map(buf, 1 + is_view + (checks_cnt > 0));
+	char *p = enc->encode_map(buf, 1 + is_view + has_autoinc +
+				  (checks_cnt > 0));
 
 	p = enc->encode_str(p, "sql", 3);
 	p = enc->encode_str(p, zSql, strlen(zSql));
@@ -1367,6 +1370,10 @@ tarantoolSqlite3MakeTableOpts(Table *pTable, const char *zSql, char *buf)
 		p = enc->encode_str(p, "view", 4);
 		p = enc->encode_bool(p, true);
 	}
+	if (has_autoinc) {
+		p = enc->encode_str(p, "sql_autoinc", strlen("sql_autoinc"));
+		p = enc->encode_uint(p, pTable->def->opts.sql_autoinc_fieldno);
+	}
 	if (checks_cnt == 0)
 		return p - buf;
 	/* Encode checks. */
diff --git a/src/box/sql/build.c b/src/box/sql/build.c
index 9d7f0a4e0..dbd911585 100644
--- a/src/box/sql/build.c
+++ b/src/box/sql/build.c
@@ -401,7 +401,7 @@ sql_table_new(Parse *parser, char *name)
 	strcpy(table->def->engine_name,
 	       sql_storage_engine_strs[current_session()->sql_default_engine]);
 
-	table->iAutoIncPKey = -1;
+	table->def->opts.sql_autoinc_fieldno = UINT32_MAX;
 	table->pSchema = db->pSchema;
 	table->nTabRef = 1;
 	return table;
@@ -869,7 +869,7 @@ sqlite3AddPrimaryKey(Parse * pParse,	/* Parsing context */
 	    sortOrder != SORT_ORDER_DESC) {
 		assert(autoInc == 0 || autoInc == 1);
 		if (autoInc)
-			pTab->iAutoIncPKey = iCol;
+			pTab->def->opts.sql_autoinc_fieldno = iCol;
 		struct sqlite3 *db = pParse->db;
 		struct ExprList *list;
 		struct Token token;
@@ -1698,7 +1698,7 @@ sqlite3EndTable(Parse * pParse,	/* Parse context */
 	 * Check to see if we need to create an _sequence table
 	 * for keeping track of autoincrement keys.
 	 */
-	if (p->iAutoIncPKey >= 0) {
+	if (p->def->opts.sql_autoinc_fieldno != UINT32_MAX) {
 		assert(reg_space_id != 0);
 		/* Do an insertion into _sequence. */
 		int reg_seq_id = ++pParse->nMem;
diff --git a/src/box/sql/insert.c b/src/box/sql/insert.c
index 271886ec6..e53cbf05a 100644
--- a/src/box/sql/insert.c
+++ b/src/box/sql/insert.c
@@ -595,7 +595,8 @@ sqlite3Insert(Parse * pParse,	/* Parser context */
 			}
 			if ((!useTempTable && !pList)
 			    || (pColumn && j >= pColumn->nId)) {
-				if (i == pTab->iAutoIncPKey) {
+				if (i ==
+				    (int) pTab->def->opts.sql_autoinc_fieldno) {
 					sqlite3VdbeAddOp2(v, OP_Integer, -1,
 							  regCols + i + 1);
 				} else {
@@ -658,7 +659,8 @@ sqlite3Insert(Parse * pParse,	/* Parser context */
 			}
 			if (j < 0 || nColumn == 0
 			    || (pColumn && j >= pColumn->nId)) {
-				if (i == pTab->iAutoIncPKey) {
+				if (i ==
+				    (int) pTab->def->opts.sql_autoinc_fieldno) {
 					sqlite3VdbeAddOp2(v,
 							  OP_NextAutoincValue,
 							  pTab->def->id,
@@ -673,7 +675,8 @@ sqlite3Insert(Parse * pParse,	/* Parser context */
 							  dflt,
 							  iRegStore);
 			} else if (useTempTable) {
-				if (i == pTab->iAutoIncPKey) {
+				if (i ==
+				    (int) pTab->def->opts.sql_autoinc_fieldno) {
 					int regTmp = ++pParse->nMem;
 					/* Emit code which doesn't override
 					 * autoinc-ed value with select result
@@ -692,7 +695,8 @@ sqlite3Insert(Parse * pParse,	/* Parser context */
 				}
 			} else if (pSelect) {
 				if (regFromSelect != regData) {
-					if (i == pTab->iAutoIncPKey) {
+					if (i ==
+					    (int) pTab->def->opts.sql_autoinc_fieldno) {
 						/* Emit code which doesn't override
 						 * autoinc-ed value with select result
 						 * in case that result is NULL
@@ -714,7 +718,8 @@ sqlite3Insert(Parse * pParse,	/* Parser context */
 				}
 			} else {
 
-				if (i == pTab->iAutoIncPKey) {
+				if (i ==
+				    (int) pTab->def->opts.sql_autoinc_fieldno) {
 					if (pList->a[j].pExpr->op == TK_NULL) {
 						sqlite3VdbeAddOp2(v, OP_Null, 0, iRegStore);
 						continue;
@@ -876,7 +881,8 @@ vdbe_emit_constraint_checks(struct Parse *parse_context, struct Table *tab,
 		if (is_update && upd_cols[i] < 0)
 			continue;
 		/* This column is allowed to be NULL. */
-		if (def->fields[i].is_nullable || tab->iAutoIncPKey == (int) i)
+		if (def->fields[i].is_nullable ||
+		    def->opts.sql_autoinc_fieldno == i)
 			continue;
 		enum on_conflict_action on_conflict_nullable =
 			on_conflict != ON_CONFLICT_ACTION_DEFAULT ?
@@ -973,7 +979,7 @@ vdbe_emit_constraint_checks(struct Parse *parse_context, struct Table *tab,
 		int reg_pk = new_tuple_reg + fieldno;
 		if (tab->def->fields[fieldno].affinity == AFFINITY_INTEGER) {
 			int skip_if_null = sqlite3VdbeMakeLabel(v);
-			if (tab->iAutoIncPKey >= 0) {
+			if (def->opts.sql_autoinc_fieldno != UINT32_MAX) {
 				sqlite3VdbeAddOp2(v, OP_IsNull, reg_pk,
 						  skip_if_null);
 			}
diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h
index 45dab0be4..2d29a10f1 100644
--- a/src/box/sql/sqliteInt.h
+++ b/src/box/sql/sqliteInt.h
@@ -1850,8 +1850,6 @@ struct Savepoint {
 struct Table {
 	Index *pIndex;		/* List of SQL indexes on this table. */
 	u32 nTabRef;		/* Number of pointers to this Table */
-	i16 iAutoIncPKey;	/* If PK is marked INTEGER PRIMARY KEY AUTOINCREMENT, store
-				   column number here, -1 otherwise Tarantool specifics */
 	/**
 	 * Estimated number of entries in table.
 	 * Used only when table represents temporary objects,
-- 
2.15.1





More information about the Tarantool-patches mailing list