code: func DetachCondAndBuildRangeForIndex(sctx sessionctx.Context, conditions []expression.Expression, cols []*expression.Column,
  	lengths []int) (*DetachRangeResult, error) {
  	res := &DetachRangeResult{}
  	newTpSlice := make([]*types.FieldType, 0, len(cols))
  	for _, col := range cols {
  		newTpSlice = append(newTpSlice, newFieldType(col.RetType))
  	}
  	if len(conditions) == 1 {
  		if sf, ok := conditions[0].(*expression.ScalarFunction); ok && sf.FuncName.L == ast.LogicOr {
  			ranges, accesses, hasResidual, err := detachDNFCondAndBuildRangeForIndex(sctx, sf, cols, newTpSlice, lengths)
  			if err != nil {
  				return res, errors.Trace(err)
  			}
  			res.Ranges = ranges
  			res.AccessConds = accesses
  			res.IsDNFCond = true
  			// If this DNF have something cannot be to calculate range, then all this DNF should be pushed as filter condition.
  			if hasResidual {
  				res.RemainedConds = conditions
  				return res, nil
  			}
  			return res, nil
  		}
  	}
  	return detachCNFCondAndBuildRangeForIndex(sctx, conditions, cols, newTpSlice, lengths, true)
  }
docs: // DetachCondAndBuildRangeForIndex will detach the index filters from table filters.
  // The returned values are encapsulated into a struct DetachRangeResult, see its comments for explanation.