code: @Override
    public ServerPrepareResult prepare(String sql, boolean executeOnMaster) throws SQLException {
  
      cmdPrologue();
      lock.lock();
      try {
        if (options.cachePrepStmts && options.useServerPrepStmts) {
  
          ServerPrepareResult pr = serverPrepareStatementCache.get(database + "-" + sql);
  
          if (pr != null && pr.incrementShareCounter()) {
            return pr;
          }
  
        }
        writer.startPacket(0);
        writer.write(COM_STMT_PREPARE);
        writer.write(sql);
        writer.flush();
  
        ComStmtPrepare comStmtPrepare = new ComStmtPrepare(this, sql);
        return comStmtPrepare.read(reader, eofDeprecated);
      } catch (IOException e) {
        throw handleIoException(e);
      } finally {
        lock.unlock();
      }
    }
docs: Prepare query on server side. Will permit to know the parameter number of the query, and permit
  to send only the data on next results.
  
  <p>For failover, two additional information are in the result-set object : - current
  connection : Since server maintain a state of this prepare statement, all query will be
  executed on this particular connection. - executeOnMaster : state of current connection when
  creating this prepareStatement (if was on master, will only be executed on master. If was on a
  slave, can be execute temporary on master, but we keep this flag, so when a slave is connected
  back to relaunch this query on slave)</p>
  
  @param sql             the query
  @param executeOnMaster state of current connection when creating this prepareStatement
  @return a ServerPrepareResult object that contain prepare result information.
  @throws SQLException if any error occur on connection.