protected function statement(string $query, array $parameters = [], bool $retry = null): Statement
    {
        if (is_null($retry)) {
            $retry = $this->options['reconnect'];
        }

        try {
            $flatten = $this->flattenParameters($parameters);

            //Mounting all input parameters
            $statement = $this->bindParameters($this->prepare($query), $flatten);
            $statement->execute();

            if ($this->isProfiling()) {
                $this->getLogger()->info(
                    Interpolator::interpolate($query, $parameters),
                    compact('query', 'parameters')
                );
            }
        } catch (\PDOException $e) {
            $queryString = Interpolator::interpolate($query, $parameters);

            $this->getLogger()->error($queryString, compact('query', 'parameters'));
            $this->getLogger()->alert($e->getMessage());

            //Converting exception into query or integrity exception
            $e = $this->mapException($e, $queryString);

            if (
                $e instanceof StatementException\ConnectionException
                && $this->transactionLevel === 0
                && $retry
            ) {
                // retrying
                return $this->statement($query, $parameters, false);
            }
            throw $e;
        }

        return $statement;
    }