code: func EvalBool(ctx sessionctx.Context, exprList CNFExprs, row chunk.Row) (bool, bool, error) {
  	hasNull := false
  	for _, expr := range exprList {
  		data, err := expr.Eval(row)
  		if err != nil {
  			return false, false, err
  		}
  		if data.IsNull() {
  			// For queries like `select a in (select a from s where t.b = s.b) from t`,
  			// if result of `t.a = s.a` is null, we cannot return immediately until
  			// we have checked if `t.b = s.b` is null or false, because it means
  			// subquery is empty, and we should return false as the result of the whole
  			// exprList in that case, instead of null.
  			if !IsEQCondFromIn(expr) {
  				return false, false, nil
  			}
  			hasNull = true
  			continue
  		}
  
  		i, err := data.ToBool(ctx.GetSessionVars().StmtCtx)
  		if err != nil {
  			return false, false, err
  		}
  		if i == 0 {
  			return false, false, nil
  		}
  	}
  	if hasNull {
  		return false, true, nil
  	}
  	return true, false, nil
  }
docs: // EvalBool evaluates expression list to a boolean value. The first returned value
  // indicates bool result of the expression list, the second returned value indicates
  // whether the result of the expression list is null, it can only be true when the
  // first returned values is false.