code: func detachColumnCNFConditions(sctx sessionctx.Context, conditions []expression.Expression, checker *conditionChecker) ([]expression.Expression, []expression.Expression) {
  	var accessConditions, filterConditions []expression.Expression
  	for _, cond := range conditions {
  		if sf, ok := cond.(*expression.ScalarFunction); ok && sf.FuncName.L == ast.LogicOr {
  			dnfItems := expression.FlattenDNFConditions(sf)
  			colulmnDNFItems, hasResidual := detachColumnDNFConditions(sctx, dnfItems, checker)
  			// If this CNF has expression that cannot be resolved as access condition, then the total DNF expression
  			// should be also appended into filter condition.
  			if hasResidual {
  				filterConditions = append(filterConditions, cond)
  			}
  			if len(colulmnDNFItems) == 0 {
  				continue
  			}
  			rebuildDNF := expression.ComposeDNFCondition(sctx, colulmnDNFItems...)
  			accessConditions = append(accessConditions, rebuildDNF)
  			continue
  		}
  		if !checker.check(cond) {
  			filterConditions = append(filterConditions, cond)
  			continue
  		}
  		accessConditions = append(accessConditions, cond)
  		if checker.shouldReserve {
  			filterConditions = append(filterConditions, cond)
  			checker.shouldReserve = checker.length != types.UnspecifiedLength
  		}
  	}
  	return accessConditions, filterConditions
  }
docs: // detachColumnCNFConditions detaches the condition for calculating range from the other conditions.
  // Please make sure that the top level is CNF form.