[tarantool-patches] [PATCH 05/10] sql: remove affinity string of columns from Index

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


Part of #3561
---
 src/box/sql/build.c     |  1 -
 src/box/sql/delete.c    |  3 ++-
 src/box/sql/insert.c    | 42 +++++++++++-------------------------------
 src/box/sql/sqliteInt.h | 16 +++++++++++-----
 src/box/sql/update.c    |  2 +-
 src/box/sql/vdbemem.c   |  3 +--
 src/box/sql/where.c     | 21 ++++++++-------------
 src/box/sql/wherecode.c |  3 ++-
 8 files changed, 36 insertions(+), 55 deletions(-)

diff --git a/src/box/sql/build.c b/src/box/sql/build.c
index 31b91a4e2..ead3e4f19 100644
--- a/src/box/sql/build.c
+++ b/src/box/sql/build.c
@@ -213,7 +213,6 @@ freeIndex(sqlite3 * db, Index * p)
 	sql_expr_delete(db, p->pPartIdxWhere, false);
 	if (p->def != NULL)
 		index_def_delete(p->def);
-	sqlite3DbFree(db, p->zColAff);
 	sqlite3DbFree(db, p);
 }
 
diff --git a/src/box/sql/delete.c b/src/box/sql/delete.c
index 0be68830a..cb16a7c0d 100644
--- a/src/box/sql/delete.c
+++ b/src/box/sql/delete.c
@@ -352,7 +352,8 @@ sql_table_delete_from(struct Parse *parse, struct SrcList *tab_list,
 			key_len = 0;
 			struct Index *pk = sqlite3PrimaryKeyIndex(table);
 			const char *zAff = is_view ? NULL :
-					  sqlite3IndexAffinityStr(parse->db, pk);
+					  sql_index_affinity_str(parse->db,
+								 pk->def);
 			sqlite3VdbeAddOp4(v, OP_MakeRecord, reg_pk, pk_len,
 					  reg_key, zAff, pk_len);
 			/* Set flag to save memory allocating one
diff --git a/src/box/sql/insert.c b/src/box/sql/insert.c
index ddd7f932b..2b6100ad5 100644
--- a/src/box/sql/insert.c
+++ b/src/box/sql/insert.c
@@ -75,34 +75,6 @@ sqlite3OpenTable(Parse * pParse,	/* Generate code into this VDBE */
  * is managed along with the rest of the Index structure. It will be
  * released when sqlite3DeleteIndex() is called.
  */
-const char *
-sqlite3IndexAffinityStr(sqlite3 *db, Index *index)
-{
-	if (index->zColAff != NULL)
-		return index->zColAff;
-	/*
-	 * The first time a column affinity string for a
-	 * particular index is required, it is allocated and
-	 * populated here. It is then stored as a member of the
-	 * Index structure for subsequent use. The column affinity
-	 * string will eventually be deleted by
-	 * sqliteDeleteIndex() when the Index structure itself is
-	 * cleaned up.
-	 */
-	int column_count = index->def->key_def->part_count;
-	index->zColAff = (char *) sqlite3DbMallocRaw(0, column_count + 1);
-	if (index->zColAff == NULL) {
-		sqlite3OomFault(db);
-		return NULL;
-	}
-	for (int n = 0; n < column_count; n++) {
-		uint16_t x = index->def->key_def->parts[n].fieldno;
-		index->zColAff[n] = index->pTable->def->fields[x].affinity;
-	}
-	index->zColAff[column_count] = 0;
-	return index->zColAff;
-}
-
 char *
 sql_index_affinity_str(struct sqlite3 *db, struct index_def *def)
 {
@@ -112,15 +84,23 @@ sql_index_affinity_str(struct sqlite3 *db, struct index_def *def)
 		return NULL;
 	struct space *space = space_by_id(def->space_id);
 	assert(space != NULL);
-
+	/*
+	 * Table may occasionally come from Lua, so lets
+	 * gentle process this case by setting default
+	 * affinity for it.
+	 */
+	if (space->def->fields == NULL) {
+		memset(aff, AFFINITY_BLOB, column_count);
+		goto exit;
+	}
 	for (uint32_t i = 0; i < column_count; i++) {
 		uint32_t x = def->key_def->parts[i].fieldno;
 		aff[i] = space->def->fields[x].affinity;
 		if (aff[i] == AFFINITY_UNDEFINED)
-			aff[i] = 'A';
+			aff[i] = AFFINITY_BLOB;
 	}
+exit:
 	aff[column_count] = '\0';
-
 	return aff;
 }
 
diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h
index e13e6ad34..c9c4965f9 100644
--- a/src/box/sql/sqliteInt.h
+++ b/src/box/sql/sqliteInt.h
@@ -2007,8 +2007,6 @@ enum sql_index_type {
 struct Index {
 	/** The SQL table being indexed. */
 	Table *pTable;
-	/** String defining the affinity of each column. */
-	char *zColAff;
 	/** The next index associated with the same table. */
 	Index *pNext;
 	/** WHERE clause for partial indices. */
@@ -4281,8 +4279,6 @@ int sqlite3VarintLen(u64 v);
 #define getVarint    sqlite3GetVarint
 #define putVarint    sqlite3PutVarint
 
-const char *sqlite3IndexAffinityStr(sqlite3 *, Index *);
-
 /**
  * Return a pointer to the column affinity string associated with
  * given index. A column affinity string has one character for
@@ -4611,7 +4607,17 @@ void sqlite3Stat4ProbeFree(UnpackedRecord *);
 int
 sql_stat4_column(struct sqlite3 *db, const char *record, uint32_t col_num,
 		 sqlite3_value **res);
-char sqlite3IndexColumnAffinity(sqlite3 *, Index *, int);
+
+/**
+ * Return the affinity for a single column of an index.
+ *
+ * @param idx Index to be investigated.
+ * @param partno Affinity of this part to be returned.
+ *
+ * @retval Affinity of @partno index part.
+ */
+enum affinity_type
+sql_index_part_affinity(struct index_def *idx, uint32_t partno);
 
 /*
  * The interface to the LEMON-generated parser
diff --git a/src/box/sql/update.c b/src/box/sql/update.c
index e2324c354..decd216c6 100644
--- a/src/box/sql/update.c
+++ b/src/box/sql/update.c
@@ -347,7 +347,7 @@ sqlite3Update(Parse * pParse,		/* The parser context */
 		regKey = iPk;
 	} else {
 		const char *zAff = is_view ? 0 :
-				   sqlite3IndexAffinityStr(pParse->db, pPk);
+				   sql_index_affinity_str(pParse->db, pPk->def);
 		sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, pk_part_count,
 				  regKey, zAff, pk_part_count);
 		sqlite3VdbeAddOp2(v, OP_IdxInsert, iEph, regKey);
diff --git a/src/box/sql/vdbemem.c b/src/box/sql/vdbemem.c
index ec2d8cb6b..64902b133 100644
--- a/src/box/sql/vdbemem.c
+++ b/src/box/sql/vdbemem.c
@@ -1553,8 +1553,7 @@ sqlite3Stat4ProbeSetValue(Parse * pParse,	/* Parse context */
 			Expr *pElem =
 			    (pExpr ? sqlite3VectorFieldSubexpr(pExpr, i) : 0);
 			u8 aff =
-			    sqlite3IndexColumnAffinity(pParse->db, pIdx,
-						       iVal + i);
+				sql_index_part_affinity(pIdx->def, iVal + i);
 			alloc.iVal = iVal + i;
 			rc = stat4ValueFromExpr(pParse, pElem, aff, &alloc,
 						&pVal);
diff --git a/src/box/sql/where.c b/src/box/sql/where.c
index db8d0bf80..794db0302 100644
--- a/src/box/sql/where.c
+++ b/src/box/sql/where.c
@@ -1158,18 +1158,14 @@ whereRangeAdjust(WhereTerm * pTerm, LogEst nNew)
 	return nRet;
 }
 
-/*
- * Return the affinity for a single column of an index.
- */
-char
-sqlite3IndexColumnAffinity(sqlite3 * db, Index * pIdx, int iCol)
+enum affinity_type
+sql_index_part_affinity(struct index_def *idx, uint32_t partno)
 {
-	assert(iCol >= 0 && iCol < (int) pIdx->def->key_def->part_count);
-	if (!pIdx->zColAff) {
-		if (sqlite3IndexAffinityStr(db, pIdx) == 0)
-			return AFFINITY_BLOB;
-	}
-	return pIdx->zColAff[iCol];
+	assert(partno < idx->key_def->part_count);
+	struct space *space = space_by_id(idx->space_id);
+	assert(space != NULL);
+	uint32_t fieldno = idx->key_def->parts[partno].fieldno;
+	return space->def->fields[fieldno].affinity;
 }
 
 /*
@@ -1224,7 +1220,7 @@ whereRangeSkipScanEst(Parse * pParse,		/* Parsing & code generating context */
 	int nLower = -1;
 	int nUpper = index->def->opts.stat->sample_count + 1;
 	int rc = SQLITE_OK;
-	u8 aff = sqlite3IndexColumnAffinity(db, p, nEq);
+	u8 aff = sql_index_part_affinity(p->def, nEq);
 
 	sqlite3_value *p1 = 0;	/* Value extracted from pLower */
 	sqlite3_value *p2 = 0;	/* Value extracted from pUpper */
@@ -1774,7 +1770,6 @@ whereLoopClearUnion(sqlite3 * db, WhereLoop * p)
 {
 	if ((p->wsFlags & WHERE_AUTO_INDEX) != 0 &&
 	    (p->wsFlags & WHERE_AUTO_INDEX) != 0 && p->pIndex != 0) {
-		sqlite3DbFree(db, p->pIndex->zColAff);
 		sqlite3DbFree(db, p->pIndex);
 		p->pIndex = 0;
 	}
diff --git a/src/box/sql/wherecode.c b/src/box/sql/wherecode.c
index 1976583fa..6b3f2f78a 100644
--- a/src/box/sql/wherecode.c
+++ b/src/box/sql/wherecode.c
@@ -725,7 +725,8 @@ codeAllEqualityTerms(Parse * pParse,	/* Parsing context */
 	char *zAff;
 	if (pIdx != NULL) {
 		zAff = sqlite3DbStrDup(pParse->db,
-				       sqlite3IndexAffinityStr(pParse->db, pIdx));
+				       sql_index_affinity_str(pParse->db,
+							      pIdx->def));
 	} else {
 		zAff = sql_index_affinity_str(pParse->db, idx_def);
 	}
-- 
2.15.1





More information about the Tarantool-patches mailing list