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

Code before:
) error {
	// Fulltext index must be used. So we prune all other possible access paths.
	ds.PossibleAccessPaths = slices.DeleteFunc(ds.PossibleAccessPaths, func(path *util.AccessPath) bool {
		return path.Index == nil || path.Index.ID != index.ID
	})
	if ds.HasForceHints && !ds.PossibleAccessPaths[0].Forced {
		ds.SCtx().GetSessionVars().StmtCtx.AppendWarning(plannererrors.ErrWarnConflictingHint.FastGenByArgs("USE_INDEX"))
	}

	remainedFilters := make([]expression.Expression, len(ds.PushedDownConds))
	copy(remainedFilters, ds.PushedDownConds)
	// Remove the matched search functions from pushed down conditions.
	remainedFilters = slices.DeleteFunc(remainedFilters, func(cond expression.Expression) bool {
		sf, ok := cond.(*expression.ScalarFunction)
		if !ok {
			return false
		}
		_, ok = matchedFuncs[sf]
		return ok
	})

	evalCtx := ds.SCtx().GetExprCtx().GetEvalCtx()
	client := ds.SCtx().GetBuildPBCtx().Client
	pbConverter := expression.NewPBConverterForTiCI(client, evalCtx)
	pbExprs := make([]tipb.Expr, 0, len(matchedFuncs))
	// It represets the TiCI search functions currently.
	ds.PossibleAccessPaths[0].AccessConds = ds.PossibleAccessPaths[0].AccessConds[:0]
	for ftsFunc := range matchedFuncs {
		newF, _, err := expression.RewriteMySQLMatchAgainstRecursively(ds.SCtx().GetExprCtx(), ftsFunc)
		if err != nil {
			return err
		}
		pbExpr := pbConverter.ExprToPB(newF)
		if pbExpr == nil {
			// If the expression is not converted to PB, we should return an error.
			return errors.New("Failed to convert FTS function to PB expression")
		}
		pbExprs = append(pbExprs, *pbExpr)
		ds.PossibleAccessPaths[0].AccessConds = append(ds.PossibleAccessPaths[0].AccessConds, newF)
	}

	// Build tipb protobuf info for the matched index.
	tokenizer := ""
	if index.FullTextInfo != nil {
		tokenizer = string(index.FullTextInfo.ParserType)
	}
	ds.PossibleAccessPaths[0].FtsQueryInfo = &tipb.FTSQueryInfo{
		QueryType:      tipb.FTSQueryType_FTSQueryTypeNoScore,
		IndexId:        index.ID,
		QueryTokenizer: tokenizer,
		MatchExpr:      pbExprs,

Review comment (suggestion):
There is a spelling error in the comment. "represets" should be "represents".
```suggestion
	// It represents the TiCI search functions currently.
```

Code after:
) error {
	// Fulltext index must be used. So we prune all other possible access paths.
	ds.PossibleAccessPaths = slices.DeleteFunc(ds.PossibleAccessPaths, func(path *util.AccessPath) bool {
		return path.Index == nil || path.Index.ID != index.ID
	})
	if ds.HasForceHints && !ds.PossibleAccessPaths[0].Forced {
		ds.SCtx().GetSessionVars().StmtCtx.AppendWarning(plannererrors.ErrWarnConflictingHint.FastGenByArgs("USE_INDEX"))
	}

	remainedFilters := make([]expression.Expression, len(ds.PushedDownConds))
	copy(remainedFilters, ds.PushedDownConds)
	// Remove the matched search functions from pushed down conditions.
	remainedFilters = slices.DeleteFunc(remainedFilters, func(cond expression.Expression) bool {
		sf, ok := cond.(*expression.ScalarFunction)
		if !ok {
			return false
		}
		_, ok = matchedFuncs[sf]
		return ok
	})

	evalCtx := ds.SCtx().GetExprCtx().GetEvalCtx()
	client := ds.SCtx().GetBuildPBCtx().Client
	pbConverter := expression.NewPBConverterForTiCI(client, evalCtx)
	pbExprs := make([]tipb.Expr, 0, len(matchedFuncs))
	// It represents the TiCI search functions currently.
	ds.PossibleAccessPaths[0].AccessConds = ds.PossibleAccessPaths[0].AccessConds[:0]
	for ftsFunc := range matchedFuncs {
		pbExpr := pbConverter.ExprToPB(ftsFunc)
		if pbExpr == nil {
			// If the expression is not converted to PB, we should return an error.
			return errors.New("Failed to convert FTS function to PB expression")
		}
		pbExprs = append(pbExprs, *pbExpr)
		ds.PossibleAccessPaths[0].AccessConds = append(ds.PossibleAccessPaths[0].AccessConds, ftsFunc)
	}

	// Build tipb protobuf info for the matched index.
	tokenizer := ""
	if index.FullTextInfo != nil {
		tokenizer = string(index.FullTextInfo.ParserType)
	}
	ds.PossibleAccessPaths[0].FtsQueryInfo = &tipb.FTSQueryInfo{
		QueryType:      tipb.FTSQueryType_FTSQueryTypeNoScore,
		IndexId:        index.ID,
		QueryTokenizer: tokenizer,
		MatchExpr:      pbExprs,
	}

	ds.PossibleAccessPaths[0].TableFilters = remainedFilters
	return nil