Repository: pingcap/tidb
File: pkg/planner/core/operator/logicalop/logical_datasource.go (Go)

Code before:
			columnNames = make(types.NameSlice, 0, ds.schema.Len())
			for i := range ds.Schema().Columns {
				columnNames = append(columnNames, &types.FieldName{
					TblName: ds.TableInfo.Name,
					ColName: ds.Columns[i].Name,
				})
			}
		}
		// Convert the raw string expression to Expression.
		expr, err := expression.ParseSimpleExpr(ds.SCtx().GetExprCtx(), path.Index.ConditionExprString, expression.WithInputSchemaAndNames(ds.schema, columnNames, ds.TableInfo))
		cnfExprs := expression.SplitCNFItems(expr)
		if err != nil || !partidx.CheckConstraints(ds.SCtx(), cnfExprs, ds.PushedDownConds) {
			if removedPaths == nil {
				removedPaths = make(map[int64]struct{})
			}
			removedPaths[path.Index.ID] = struct{}{}
			continue
		}
		if path.Forced {
			partialIndexUsedHint = true
		}
		// A special handler for plan cache.
		// We only do it for single IS NOT NULL constraint now.
		if ds.SCtx().GetSessionVars().StmtCtx.UseCache() {
			if !partidx.AlwaysMeetConstraints(ds.SCtx(), cnfExprs, ds.PushedDownConds) {
				path.NoncacheableReason = "IndexScan of partial index is un-cacheable"
			}
		}
	}
	// 1. No partial index,
	// 2. Or no partial index is removed and no partial index is used by hint.
	// In these cases, we don't need to do anything.
	if !hasPartialIndex || (len(removedPaths) == 0 && !partialIndexUsedHint) {
		return
	}
	checkIndex := func(path *util.AccessPath, checkForced bool) bool {
		isRemoved := false
		if path.Index != nil {
			_, isRemoved = removedPaths[path.Index.ID]
		}
		return isRemoved || (checkForced && !path.Forced)
	}
	if partialIndexUsedHint {
		ds.AllPossibleAccessPaths = slices.DeleteFunc(ds.AllPossibleAccessPaths, func(path *util.AccessPath) bool {
			return checkIndex(path, true)
		})
		ds.PossibleAccessPaths = slices.DeleteFunc(ds.PossibleAccessPaths, func(path *util.AccessPath) bool {
			return checkIndex(path, true)
		})
	} else {
		ds.AllPossibleAccessPaths = slices.DeleteFunc(ds.AllPossibleAccessPaths, func(path *util.AccessPath) bool {

Review comment (performance):
Corrected spelling of 'un-cacheable' to 'uncacheable'.
```suggestion
				path.NoncacheableReason = "IndexScan of partial index is uncacheable"
```

Code after:
			columnNames = make(types.NameSlice, 0, ds.schema.Len())
			for i := range ds.Schema().Columns {
				columnNames = append(columnNames, &types.FieldName{
					TblName: ds.TableInfo.Name,
					ColName: ds.Columns[i].Name,
				})
			}
		}
		// Convert the raw string expression to Expression.
		expr, err := expression.ParseSimpleExpr(ds.SCtx().GetExprCtx(), path.Index.ConditionExprString, expression.WithInputSchemaAndNames(ds.schema, columnNames, ds.TableInfo))
		cnfExprs := expression.SplitCNFItems(expr)
		if err != nil || !partidx.CheckConstraints(ds.SCtx(), cnfExprs, ds.PushedDownConds) {
			if removedPaths == nil {
				removedPaths = make(map[int64]struct{})
			}
			removedPaths[path.Index.ID] = struct{}{}
			continue
		}
		if path.Forced {
			partialIndexUsedHint = true
		}
		// A special handler for plan cache.
		// We only do it for single IS NOT NULL constraint now.
		if ds.SCtx().GetSessionVars().StmtCtx.UseCache() {
			if !partidx.AlwaysMeetConstraints(ds.SCtx(), cnfExprs, ds.PushedDownConds) {
				path.NoncacheableReason = "IndexScan of partial index is uncacheable"
			}
		}
	}
	// 1. No partial index,
	// 2. Or no partial index is removed and no partial index is used by hint.
	// In these cases, we don't need to do anything.
	if !hasPartialIndex || (len(removedPaths) == 0 && !partialIndexUsedHint) {
		return
	}
	checkIndex := func(path *util.AccessPath, checkForced bool) bool {
		isRemoved := false
		if path.Index != nil {
			_, isRemoved = removedPaths[path.Index.ID]
		}
		return isRemoved || (checkForced && !path.Forced)
	}
	if partialIndexUsedHint {
		ds.AllPossibleAccessPaths = slices.DeleteFunc(ds.AllPossibleAccessPaths, func(path *util.AccessPath) bool {
			return checkIndex(path, true)
		})
		ds.PossibleAccessPaths = slices.DeleteFunc(ds.PossibleAccessPaths, func(path *util.AccessPath) bool {
			return checkIndex(path, true)
		})
	} else {
		ds.AllPossibleAccessPaths = slices.DeleteFunc(ds.AllPossibleAccessPaths, func(path *util.AccessPath) bool {