@Override
  public AbstractQueryResult executePreparedQuery(
      String sql,
      ParameterHolder[] parameters,
      PrepareResult prepareResult,
      MariaDbType[] parameterTypeHeader,
      boolean isStreaming)
      throws QueryException {
    this.moreResults = false;
    try {
      int parameterCount = parameters.length;
      // send binary data in a separate stream
      for (int i = 0; i < parameterCount; i++) {
        if (parameters[i].isLongData()) {
          SendPrepareParameterPacket sendPrepareParameterPacket =
              new SendPrepareParameterPacket(
                  i, (LongDataParameterHolder) parameters[i], prepareResult.statementId, charset);
          sendPrepareParameterPacket.send(writer);
        }
      }
      // send execute query
      SendExecutePrepareStatementPacket packet =
          new SendExecutePrepareStatementPacket(
              prepareResult.statementId, parameters, parameterCount, parameterTypeHeader);
      packet.send(writer);

    } catch (MaxAllowedPacketException e) {
      if (e.isMustReconnect()) {
        connect();
      }
      throw new QueryException(
          "Could not send query: " + e.getMessage(),
          -1,
          ExceptionMapper.SqlStates.INTERRUPTED_EXCEPTION.getSqlState(),
          e);
    } catch (IOException e) {
      throw new QueryException(
          "Could not send query: " + e.getMessage(),
          -1,
          ExceptionMapper.SqlStates.CONNECTION_EXCEPTION.getSqlState(),
          e);
    }

    try {
      return getResult(sql, isStreaming, true);
    } catch (QueryException qex) {
      if (qex.getCause() instanceof SocketTimeoutException) {
        throw new QueryException(
            "Connection timed out",
            -1,
            ExceptionMapper.SqlStates.CONNECTION_EXCEPTION.getSqlState(),
            qex);
      } else {
        throw qex;
      }
    }
  }
 private AbstractQueryResult result(Object queriesObj, boolean streaming) throws QueryException {
   try {
     return getResult(queriesObj, streaming, false);
   } catch (QueryException qex) {
     if (qex.getCause() instanceof SocketTimeoutException) {
       throw new QueryException(
           "Connection timed out",
           -1,
           ExceptionMapper.SqlStates.CONNECTION_EXCEPTION.getSqlState(),
           qex);
     }
     throw qex;
   }
 }
  /**
   * Execute queries.
   *
   * @param queries queries list
   * @param streaming is streaming flag
   * @param isRewritable is rewritable flag
   * @param rewriteOffset rewriteoffset
   * @return queryResult
   * @throws QueryException exception
   */
  public AbstractQueryResult executeBatch(
      final List<Query> queries, boolean streaming, boolean isRewritable, int rewriteOffset)
      throws QueryException {
    for (Query query : queries) {
      query.validate();
    }

    this.moreResults = false;
    final SendTextQueryPacket packet =
        new SendTextQueryPacket(queries, isRewritable, rewriteOffset);
    try {
      packet.send(writer);
    } catch (MaxAllowedPacketException e) {
      if (e.isMustReconnect()) {
        connect();
      }
      throw new QueryException(
          "Could not send query: " + e.getMessage(),
          -1,
          ExceptionMapper.SqlStates.INTERRUPTED_EXCEPTION.getSqlState(),
          e);
    } catch (IOException e) {
      throw new QueryException(
          "Could not send query: " + e.getMessage(),
          -1,
          ExceptionMapper.SqlStates.CONNECTION_EXCEPTION.getSqlState(),
          e);
    }

    try {
      return getResult(queries, streaming, false);
    } catch (QueryException qex) {
      if (qex.getCause() instanceof SocketTimeoutException) {
        throw new QueryException(
            "Connection timed out",
            -1,
            ExceptionMapper.SqlStates.CONNECTION_EXCEPTION.getSqlState(),
            qex);
      } else {
        throw qex;
      }
    }
  }