[tarantool-patches] [PATCH 02/10] sql: remove string of fields collation from Table

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


Part of #3561
---
 src/box/sql/build.c     |  1 -
 src/box/sql/insert.c    | 71 +++++++++++--------------------------------------
 src/box/sql/sqliteInt.h | 14 +++++++---
 src/box/sql/update.c    |  2 +-
 4 files changed, 28 insertions(+), 60 deletions(-)

diff --git a/src/box/sql/build.c b/src/box/sql/build.c
index f3546b794..48ced1766 100644
--- a/src/box/sql/build.c
+++ b/src/box/sql/build.c
@@ -344,7 +344,6 @@ deleteTable(sqlite3 * db, Table * pTable)
 	/* Delete the Table structure itself.
 	 */
 	sqlite3HashClear(&pTable->idxHash);
-	sqlite3DbFree(db, pTable->zColAff);
 	assert(pTable->def != NULL);
 	/* Do not delete pTable->def allocated on region. */
 	if (!pTable->def->opts.is_temporary)
diff --git a/src/box/sql/insert.c b/src/box/sql/insert.c
index 13cb61ecf..50c30fd82 100644
--- a/src/box/sql/insert.c
+++ b/src/box/sql/insert.c
@@ -124,59 +124,21 @@ sql_index_affinity_str(struct sqlite3 *db, struct index_def *def)
 	return aff;
 }
 
-/*
- * Compute the affinity string for table pTab, if it has not already been
- * computed.  As an optimization, omit trailing AFFINITY_BLOB affinities.
- *
- * If the affinity exists (if it is no entirely AFFINITY_BLOB values) and
- * if iReg>0 then code an OP_Affinity opcode that will set the affinities
- * for register iReg and following.  Or if affinities exists and iReg==0,
- * then just set the P4 operand of the previous opcode (which should  be
- * an OP_MakeRecord) to the affinity string.
- *
- * A column affinity string has one character per column:
- *
- *  Character      Column affinity
- *  ------------------------------
- *  'A'            BLOB
- *  'B'            TEXT
- *  'C'            NUMERIC
- *  'D'            INTEGER
- *  'E'            REAL
- */
 void
-sqlite3TableAffinity(Vdbe * v, Table * pTab, int iReg)
+sql_emit_table_affinity(struct Vdbe *v, struct space_def *def, int reg)
 {
-	int i;
-	char *zColAff = pTab->zColAff;
-	if (zColAff == 0) {
-		sqlite3 *db = sqlite3VdbeDb(v);
-		zColAff =
-			(char *)sqlite3DbMallocRaw(0,
-						   pTab->def->field_count + 1);
-		if (!zColAff) {
-			sqlite3OomFault(db);
-			return;
-		}
-
-		for (i = 0; i < (int)pTab->def->field_count; i++) {
-			char affinity = pTab->def->fields[i].affinity;
-			zColAff[i] = affinity;
-		}
-		do {
-			zColAff[i--] = 0;
-		} while (i >= 0 && zColAff[i] == AFFINITY_BLOB);
-		pTab->zColAff = zColAff;
-	}
-	i = sqlite3Strlen30(zColAff);
-	if (i) {
-		if (iReg) {
-			sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff,
-					  i);
-		} else {
-			sqlite3VdbeChangeP4(v, -1, zColAff, i);
-		}
+	assert(reg > 0);
+	sqlite3 *db = sqlite3VdbeDb(v);
+	uint32_t field_count = def->field_count;
+	char *colls_aff = (char *)sqlite3DbMallocZero(db, field_count + 1);
+	if (colls_aff == NULL) {
+		sqlite3OomFault(db);
+		return;
 	}
+	for (uint32_t i = 0; i < field_count; ++i)
+		colls_aff[i] = def->fields[i].affinity;
+	sqlite3VdbeAddOp4(v, OP_Affinity, reg, field_count, 0, colls_aff,
+			  P4_DYNAMIC);
 }
 
 /**
@@ -704,9 +666,8 @@ sqlite3Insert(Parse * pParse,	/* Parser context */
 		 * If this is a real table, attempt conversions as required by the
 		 * table column affinities.
 		 */
-		if (!is_view) {
-			sqlite3TableAffinity(v, pTab, regCols + 1);
-		}
+		if (!is_view)
+			sql_emit_table_affinity(v, pTab->def, regCols + 1);
 
 		/* Fire BEFORE or INSTEAD OF triggers */
 		vdbe_code_row_trigger(pParse, trigger, TK_INSERT, 0,
@@ -1188,7 +1149,7 @@ sqlite3GenerateConstraintChecks(Parse * pParse,		/* The parser context */
 		if (aRegIdx[ix] == 0)
 			continue;	/* Skip indices that do not change */
 		if (bAffinityDone == 0) {
-			sqlite3TableAffinity(v, pTab, regNewData+1);
+			sql_emit_table_affinity(v, pTab->def, regNewData + 1);
 			bAffinityDone = 1;
 		}
 		iThisCur = iIdxCur + ix;
@@ -1239,7 +1200,7 @@ sqlite3GenerateConstraintChecks(Parse * pParse,		/* The parser context */
 					pIdx->def->key_def->parts[0].fieldno;
 				reg_pk = regNewData + 1 + fieldno;
 
-				if (pTab->zColAff[fieldno] ==
+				if (pTab->def->fields[fieldno].affinity ==
 				    AFFINITY_INTEGER) {
 					int skip_if_null = sqlite3VdbeMakeLabel(v);
 					if ((pTab->tabFlags & TF_Autoincrement) != 0) {
diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h
index ddedfbcb4..9c861518f 100644
--- a/src/box/sql/sqliteInt.h
+++ b/src/box/sql/sqliteInt.h
@@ -1874,8 +1874,6 @@ struct Savepoint {
  */
 struct Table {
 	Index *pIndex;		/* List of SQL indexes on this table. */
-	char *zColAff;		/* String defining the affinity of each column */
-	/*   ... also used as column name list in a VIEW */
 	Hash idxHash;		/* All (named) indices indexed by name */
 	u32 nTabRef;		/* Number of pointers to this Table */
 	i16 iAutoIncPKey;	/* If PK is marked INTEGER PRIMARY KEY AUTOINCREMENT, store
@@ -4318,7 +4316,17 @@ const char *sqlite3IndexAffinityStr(sqlite3 *, Index *);
 char *
 sql_index_affinity_str(struct sqlite3 *db, struct index_def *def);
 
-void sqlite3TableAffinity(Vdbe *, Table *, int);
+/**
+ * Code an OP_Affinity opcode that will set affinities
+ * for given range of register starting from @reg.
+ *
+ * @param v VDBE.
+ * @param def Definition of table to be used.
+ * @param reg Register where affinities will be placed.
+ */
+void
+sql_emit_table_affinity(struct Vdbe *v, struct space_def *def, int reg);
+
 char sqlite3CompareAffinity(Expr * pExpr, char aff2);
 int sqlite3IndexAffinityOk(Expr * pExpr, char idx_affinity);
 
diff --git a/src/box/sql/update.c b/src/box/sql/update.c
index 9e9fa3a79..e2324c354 100644
--- a/src/box/sql/update.c
+++ b/src/box/sql/update.c
@@ -494,7 +494,7 @@ sqlite3Update(Parse * pParse,		/* The parser context */
 	 * verified. One could argue that this is wrong.
 	 */
 	if (tmask & TRIGGER_BEFORE) {
-		sqlite3TableAffinity(v, pTab, regNew);
+		sql_emit_table_affinity(v, pTab->def, regNew);
 		vdbe_code_row_trigger(pParse, trigger, TK_UPDATE, pChanges,
 				      TRIGGER_BEFORE, pTab, regOldPk,
 				      on_error, labelContinue);
-- 
2.15.1





More information about the Tarantool-patches mailing list