static bool wsrep_mysql_parse(THD *thd, char *rawbuf, uint length,
                              Parser_state *parser_state,
                              bool is_com_multi,
                              bool is_next_command)
{
  bool is_autocommit=
    !thd->in_multi_stmt_transaction_mode()                  &&
    wsrep_read_only_option(thd, thd->lex->query_tables);
  bool retry_autocommit;
  do
  {
    retry_autocommit= false;
    mysql_parse(thd, rawbuf, length, parser_state, is_com_multi, is_next_command);

    /*
      Convert all ER_QUERY_INTERRUPTED errors to ER_LOCK_DEADLOCK
      if the transaction was BF aborted. This can happen when the
      transaction is being BF aborted via thd->awake() while it is
      still executing.

      Note that this must be done before wsrep_after_statement() call
      since it clears the transaction for autocommit queries.
     */
    if (((thd->get_stmt_da()->is_error() &&
          thd->get_stmt_da()->sql_errno() == ER_QUERY_INTERRUPTED) ||
         !thd->get_stmt_da()->is_set()) &&
        thd->wsrep_trx().bf_aborted())
    {
      WSREP_DEBUG("overriding error: %d with DEADLOCK",
                  (thd->get_stmt_da()->is_error()) ?
                   thd->get_stmt_da()->sql_errno() : 0);

      thd->reset_kill_query();
      wsrep_override_error(thd, ER_LOCK_DEADLOCK);
    }

#ifdef ENABLED_DEBUG_SYNC
    /* we need the test otherwise we get stuck in the "SET DEBUG_SYNC" itself */
    if (thd->lex->sql_command != SQLCOM_SET_OPTION)
      DEBUG_SYNC(thd, "wsrep_after_statement_enter");
#endif

    if (wsrep_after_statement(thd) &&
        is_autocommit              &&
        thd_is_connection_alive(thd))
    {
      thd->reset_for_next_command();
      thd->reset_kill_query();
      if (is_autocommit                           &&
          thd->lex->sql_command != SQLCOM_SELECT  &&
          thd->wsrep_retry_counter < thd->variables.wsrep_retry_autocommit)
      {
	DBUG_EXECUTE_IF("sync.wsrep_retry_autocommit",
                    {
                      const char act[]=
                        "now "
                        "SIGNAL wsrep_retry_autocommit_reached "
                        "WAIT_FOR wsrep_retry_autocommit_continue";
                      DBUG_ASSERT(!debug_sync_set_action(thd, STRING_WITH_LEN(act)));
                    });
        WSREP_DEBUG("wsrep retrying AC query: %lu  %s",
                    thd->wsrep_retry_counter, wsrep_thd_query(thd));
        wsrep_prepare_for_autocommit_retry(thd, rawbuf, length, parser_state);
        if (thd->lex->explain)
          delete_explain_query(thd->lex);
        retry_autocommit= true;
      }
      else
      {
        WSREP_DEBUG("%s, thd: %llu is_AC: %d, retry: %lu - %lu SQL: %s",
                    wsrep_thd_transaction_state_str(thd),
                    thd->thread_id,
                    is_autocommit,
                    thd->wsrep_retry_counter,
                    thd->variables.wsrep_retry_autocommit,
                    wsrep_thd_query(thd));
        my_error(ER_LOCK_DEADLOCK, MYF(0));
        thd->reset_kill_query();
        thd->wsrep_retry_counter= 0;             //  reset
      }
    }
    else
    {
      set_if_smaller(thd->wsrep_retry_counter, 0); // reset; eventually ok
    }
  }  while (retry_autocommit);

  if (thd->wsrep_retry_query)
  {
    WSREP_DEBUG("releasing retry_query: "
                "conf %s sent %d kill %d  errno %d SQL %s",
                wsrep_thd_transaction_state_str(thd),
                thd->get_stmt_da()->is_sent(),
                thd->killed,
                thd->get_stmt_da()->is_error() ?
                thd->get_stmt_da()->sql_errno() : 0,
                thd->wsrep_retry_query);
    my_free(thd->wsrep_retry_query);
    thd->wsrep_retry_query      = NULL;
    thd->wsrep_retry_query_len  = 0;
    thd->wsrep_retry_command    = COM_CONNECT;
  }
  return false;
}