[tarantool-patches] [PATCH 06/10] sql: completely remove support of partial indexes

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


We banned opportunity to create partial indexes long ago, but internal
routine implementing this feature still remains. This patch completely
removes it.

Part of #3561
---
 src/box/sql/build.c     | 23 ++++++-----------------
 src/box/sql/delete.c    | 17 +++--------------
 src/box/sql/insert.c    | 12 ------------
 src/box/sql/parse.y     |  6 +++---
 src/box/sql/pragma.c    |  5 +----
 src/box/sql/sqliteInt.h |  7 ++-----
 src/box/sql/update.c    |  2 +-
 src/box/sql/where.c     | 31 -------------------------------
 8 files changed, 16 insertions(+), 87 deletions(-)

diff --git a/src/box/sql/build.c b/src/box/sql/build.c
index ead3e4f19..01d4d52a3 100644
--- a/src/box/sql/build.c
+++ b/src/box/sql/build.c
@@ -210,7 +210,6 @@ sqlite3LocateIndex(sqlite3 * db, const char *zName, const char *zTable)
 static void
 freeIndex(sqlite3 * db, Index * p)
 {
-	sql_expr_delete(db, p->pPartIdxWhere, false);
 	if (p->def != NULL)
 		index_def_delete(p->def);
 	sqlite3DbFree(db, p);
@@ -927,9 +926,8 @@ sqlite3AddPrimaryKey(Parse * pParse,	/* Parsing context */
 							     &token, 0));
 		if (list == NULL)
 			goto primary_key_exit;
-		sql_create_index(pParse, 0, 0, list, onError, 0, 0,
-				 SORT_ORDER_ASC, false,
-				 SQL_INDEX_TYPE_CONSTRAINT_PK);
+		sql_create_index(pParse, 0, 0, list, onError, 0, SORT_ORDER_ASC,
+				 false, SQL_INDEX_TYPE_CONSTRAINT_PK);
 		if (db->mallocFailed)
 			goto primary_key_exit;
 	} else if (autoInc) {
@@ -937,9 +935,8 @@ sqlite3AddPrimaryKey(Parse * pParse,	/* Parsing context */
 				"INTEGER PRIMARY KEY or INT PRIMARY KEY");
 		goto primary_key_exit;
 	} else {
-		sql_create_index(pParse, 0, 0, pList, onError, 0,
-				 0, sortOrder, false,
-				 SQL_INDEX_TYPE_CONSTRAINT_PK);
+		sql_create_index(pParse, 0, 0, pList, onError, 0, sortOrder,
+				 false, SQL_INDEX_TYPE_CONSTRAINT_PK);
 		pList = 0;
 		if (pParse->nErr > 0)
 			goto primary_key_exit;
@@ -2756,8 +2753,8 @@ void
 sql_create_index(struct Parse *parse, struct Token *token,
 		 struct SrcList *tbl_name, struct ExprList *col_list,
 		 enum on_conflict_action on_error, struct Token *start,
-		 struct Expr *where, enum sort_order sort_order,
-		 bool if_not_exist, enum sql_index_type idx_type) {
+		 enum sort_order sort_order, bool if_not_exist,
+		 enum sql_index_type idx_type) {
 	/* The index to be created. */
 	struct Index *index = NULL;
 	/* Name of the index. */
@@ -2917,13 +2914,6 @@ sql_create_index(struct Parse *parse, struct Token *token,
 	index->pTable = table;
 	index->onError = (u8) on_error;
 	index->index_type = idx_type;
-	/* Tarantool have access to each column by any index. */
-	if (where != NULL) {
-		sql_resolve_self_reference(parse, table, NC_PartIdx, where,
-					   NULL);
-		index->pPartIdxWhere = where;
-		where = NULL;
-	}
 
 	/*
 	 * TODO: Issue a warning if two or more columns of the
@@ -3132,7 +3122,6 @@ sql_create_index(struct Parse *parse, struct Token *token,
  exit_create_index:
 	if (index != NULL)
 		freeIndex(db, index);
-	sql_expr_delete(db, where, false);
 	sql_expr_list_delete(db, col_list);
 	sqlite3SrcListDelete(db, tbl_name);
 	sqlite3DbFree(db, name);
diff --git a/src/box/sql/delete.c b/src/box/sql/delete.c
index cb16a7c0d..99b49d63c 100644
--- a/src/box/sql/delete.c
+++ b/src/box/sql/delete.c
@@ -587,22 +587,11 @@ sql_generate_index_key(struct Parse *parse, struct Index *index, int cursor,
 {
 	struct Vdbe *v = parse->pVdbe;
 
-	if (part_idx_label != NULL) {
-		if (index->pPartIdxWhere != NULL) {
-			*part_idx_label = sqlite3VdbeMakeLabel(v);
-			parse->iSelfTab = cursor;
-			sqlite3ExprCachePush(parse);
-			sqlite3ExprIfFalseDup(parse, index->pPartIdxWhere,
-					      *part_idx_label,
-					      SQLITE_JUMPIFNULL);
-		} else {
-			*part_idx_label = 0;
-		}
-	}
+	if (part_idx_label != NULL)
+		*part_idx_label = 0;
 	int col_cnt = index->def->key_def->part_count;
 	int reg_base = sqlite3GetTempRange(parse, col_cnt);
-	if (prev != NULL && (reg_base != reg_prev ||
-			     prev->pPartIdxWhere != NULL))
+	if (prev != NULL && reg_base != reg_prev)
 		prev = NULL;
 	for (int j = 0; j < col_cnt; j++) {
 		if (prev != NULL && prev->def->key_def->parts[j].fieldno ==
diff --git a/src/box/sql/insert.c b/src/box/sql/insert.c
index 2b6100ad5..853265ead 100644
--- a/src/box/sql/insert.c
+++ b/src/box/sql/insert.c
@@ -1131,15 +1131,6 @@ sqlite3GenerateConstraintChecks(Parse * pParse,		/* The parser context */
 		iThisCur = iIdxCur + ix;
 		addrUniqueOk = sqlite3VdbeMakeLabel(v);
 
-		/* Skip partial indices for which the WHERE clause is not true */
-		if (pIdx->pPartIdxWhere) {
-			sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[ix]);
-			pParse->ckBase = regNewData + 1;
-			sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere,
-					      addrUniqueOk, SQLITE_JUMPIFNULL);
-			pParse->ckBase = 0;
-		}
-
 		/* Create a record for this index entry as it should appear after
 		 * the insert or update.  Store that record in the aRegIdx[ix] register
 		 */
@@ -1568,9 +1559,6 @@ xferCompatibleIndex(Index * pDest, Index * pSrc)
 		if (src_part->coll != dest_part->coll)
 			return 0;	/* Different collating sequences */
 	}
-	if (sqlite3ExprCompare(pSrc->pPartIdxWhere, pDest->pPartIdxWhere, -1)) {
-		return 0;	/* Different WHERE clauses */
-	}
 
 	/* If no test above fails then the indices must be compatible */
 	return 1;
diff --git a/src/box/sql/parse.y b/src/box/sql/parse.y
index 58a6bf39a..66ad84ce2 100644
--- a/src/box/sql/parse.y
+++ b/src/box/sql/parse.y
@@ -282,7 +282,7 @@ ccons ::= NULL onconf(R).        {
 ccons ::= NOT NULL onconf(R).    {sql_column_add_nullable_action(pParse, R);}
 ccons ::= PRIMARY KEY sortorder(Z) onconf(R) autoinc(I).
                                  {sqlite3AddPrimaryKey(pParse,0,R,I,Z);}
-ccons ::= UNIQUE index_onconf(R). {sql_create_index(pParse,0,0,0,R,0,0,
+ccons ::= UNIQUE index_onconf(R). {sql_create_index(pParse,0,0,0,R,0,
 						   SORT_ORDER_ASC, false,
 						   SQL_INDEX_TYPE_CONSTRAINT_UNIQUE);}
 ccons ::= CHECK LP expr(X) RP.   {sql_add_check_constraint(pParse,&X);}
@@ -337,7 +337,7 @@ tcons ::= CONSTRAINT nm(X).      {pParse->constraintName = X;}
 tcons ::= PRIMARY KEY LP sortlist(X) autoinc(I) RP onconf(R).
                                  {sqlite3AddPrimaryKey(pParse,X,R,I,0);}
 tcons ::= UNIQUE LP sortlist(X) RP index_onconf(R).
-                                 {sql_create_index(pParse,0,0,X,R,0,0,
+                                 {sql_create_index(pParse,0,0,X,R,0,
 						   SORT_ORDER_ASC,false,
 						   SQL_INDEX_TYPE_CONSTRAINT_UNIQUE);}
 tcons ::= CHECK LP expr(E) RP onconf.
@@ -1203,7 +1203,7 @@ cmd ::= createkw(S) uniqueflag(U) INDEX ifnotexists(NE) nm(X)
   enum on_conflict_action on_error =
           U ? ON_CONFLICT_ACTION_ABORT : ON_CONFLICT_ACTION_NONE;
   sql_create_index(pParse, &X, sqlite3SrcListAppend(pParse->db,0,&Y), Z,
-                   on_error, &S, NULL, SORT_ORDER_ASC, NE, U);
+                   on_error, &S, SORT_ORDER_ASC, NE, U);
 }
 
 %type uniqueflag {int}
diff --git a/src/box/sql/pragma.c b/src/box/sql/pragma.c
index f7e6053eb..0ba651567 100644
--- a/src/box/sql/pragma.c
+++ b/src/box/sql/pragma.c
@@ -514,10 +514,7 @@ sqlite3Pragma(Parse * pParse, Token * pId,	/* First part of [schema.]id field */
 								     pIdx->def->opts.is_unique,
 								     azOrigin
 								     [pIdx->
-								      index_type],
-								     pIdx->
-								     pPartIdxWhere
-								     != 0);
+								      index_type]);
 						sqlite3VdbeAddOp2(v,
 								  OP_ResultRow,
 								  1, 5);
diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h
index c9c4965f9..eb20fb31a 100644
--- a/src/box/sql/sqliteInt.h
+++ b/src/box/sql/sqliteInt.h
@@ -2009,8 +2009,6 @@ struct Index {
 	Table *pTable;
 	/** The next index associated with the same table. */
 	Index *pNext;
-	/** WHERE clause for partial indices. */
-	Expr *pPartIdxWhere;
 	/**
 	 * Conflict resolution algorithm to employ whenever an
 	 * attempt is made to insert a non-unique element in
@@ -3591,7 +3589,6 @@ void sqlite3SrcListDelete(sqlite3 *, SrcList *);
  * @param on_error One of ON_CONFLICT_ACTION_ABORT, _IGNORE,
  *        _REPLACE, or _NONE.
  * @param start The CREATE token that begins this statement.
- * @param where WHERE clause for partial indices.
  * @param sort_order Sort order of primary key when pList==NULL.
  * @param if_not_exist Omit error if index already exists.
  * @param idx_type The index type.
@@ -3600,8 +3597,8 @@ void
 sql_create_index(struct Parse *parse, struct Token *token,
 		 struct SrcList *tbl_name, struct ExprList *col_list,
 		 enum on_conflict_action on_error, struct Token *start,
-		 struct Expr *where, enum sort_order sort_order,
-		 bool if_not_exist, enum sql_index_type idx_type);
+		 enum sort_order sort_order, bool if_not_exist,
+		 enum sql_index_type idx_type);
 
 /**
  * This routine will drop an existing named index.  This routine
diff --git a/src/box/sql/update.c b/src/box/sql/update.c
index decd216c6..54b30705a 100644
--- a/src/box/sql/update.c
+++ b/src/box/sql/update.c
@@ -239,7 +239,7 @@ sqlite3Update(Parse * pParse,		/* The parser context */
 	for (j = 0, pIdx = pTab->pIndex; pIdx; pIdx = pIdx->pNext, j++) {
 		int reg;
 		uint32_t part_count = pIdx->def->key_def->part_count;
-		if (chngPk || hasFK || pIdx->pPartIdxWhere || pIdx == pPk) {
+		if (chngPk || hasFK || pIdx == pPk) {
 			reg = ++pParse->nMem;
 			pParse->nMem += part_count;
 		} else {
diff --git a/src/box/sql/where.c b/src/box/sql/where.c
index 794db0302..a57bad5b7 100644
--- a/src/box/sql/where.c
+++ b/src/box/sql/where.c
@@ -2781,31 +2781,6 @@ indexMightHelpWithOrderBy(WhereLoopBuilder * pBuilder,
 	return 0;
 }
 
-/* Check to see if a partial index with pPartIndexWhere can be used
- * in the current query.  Return true if it can be and false if not.
- */
-static int
-whereUsablePartialIndex(int iTab, WhereClause * pWC, Expr * pWhere)
-{
-	int i;
-	WhereTerm *pTerm;
-	while (pWhere->op == TK_AND) {
-		if (!whereUsablePartialIndex(iTab, pWC, pWhere->pLeft))
-			return 0;
-		pWhere = pWhere->pRight;
-	}
-	for (i = 0, pTerm = pWC->a; i < pWC->nTerm; i++, pTerm++) {
-		Expr *pExpr = pTerm->pExpr;
-		if (sqlite3ExprImpliesExpr(pExpr, pWhere, iTab)
-		    && (!ExprHasProperty(pExpr, EP_FromJoin)
-			|| pExpr->iRightJoinTable == iTab)
-		    ) {
-			return 1;
-		}
-	}
-	return 0;
-}
-
 /*
  * Add all WhereLoop objects for a single table of the join where the table
  * is identified by pBuilder->pNew->iTab.
@@ -2992,12 +2967,6 @@ whereLoopAddBtree(WhereLoopBuilder * pBuilder,	/* WHERE clause information */
 	/* Loop over all indices
 	 */
 	for (; rc == SQLITE_OK && pProbe; pProbe = pProbe->pNext, iSortIdx++) {
-		if (pProbe->pPartIdxWhere != 0
-		    && !whereUsablePartialIndex(pSrc->iCursor, pWC,
-						pProbe->pPartIdxWhere)) {
-			testcase(pNew->iTab != pSrc->iCursor);	/* See ticket [98d973b8f5] */
-			continue;	/* Partial index inappropriate for this query */
-		}
 		rSize = index_field_tuple_est(pProbe, 0);
 		pNew->nEq = 0;
 		pNew->nBtm = 0;
-- 
2.15.1





More information about the Tarantool-patches mailing list