code: func (a *ExecStmt) IsReadOnly(vars *variable.SessionVars) bool {
  	if execStmt, ok := a.StmtNode.(*ast.ExecuteStmt); ok {
  		s, err := getPreparedStmt(execStmt, vars)
  		if err != nil {
  			logutil.Logger(context.Background()).Error("getPreparedStmt failed", zap.Error(err))
  			return false
  		}
  		return ast.IsReadOnly(s)
  	}
  	return ast.IsReadOnly(a.StmtNode)
  }
docs: // IsReadOnly returns true if a statement is read only.
  // If current StmtNode is an ExecuteStmt, we can get its prepared stmt,
  // then using ast.IsReadOnly function to determine a statement is read only or not.