private function rewriteCountQuery(string $sql) : string
    {
        if (preg_match('/^\s*SELECT\s+\bDISTINCT\b/is', $sql) || preg_match('/\s+GROUP\s+BY\s+/is', $sql)) {
            throw new CountQueryException($sql);
        }
        $openParenthesis = '(?:\()';
        $closeParenthesis = '(?:\))';
        $subQueryInSelect = $openParenthesis . '.*\bFROM\b.*' . $closeParenthesis;
        $pattern = '/(?:.*' . $subQueryInSelect . '.*)\bFROM\b\s+/Uims';
        if (preg_match($pattern, $sql)) {
            throw new CountQueryException($sql);
        }
        $subQueryWithLimitOrder = $openParenthesis . '.*\b(LIMIT|ORDER)\b.*' . $closeParenthesis;
        $pattern = '/.*\bFROM\b.*(?:.*' . $subQueryWithLimitOrder . '.*).*/Uims';
        if (preg_match($pattern, $sql)) {
            throw new CountQueryException($sql);
        }
        $queryCount = preg_replace('/(?:.*)\bFROM\b\s+/Uims', 'SELECT COUNT(*) FROM ', $sql, 1);
        if (! is_string($queryCount)) {
            throw new CountQueryException($sql);
        }
        list($queryCount) = preg_split('/\s+ORDER\s+BY\s+/is', $queryCount);
        if (! is_string($queryCount)) {
            throw new CountQueryException($sql);
        }
        list($queryCount) = preg_split('/\bLIMIT\b/is', $queryCount);
        if (! is_string($queryCount)) {
            throw new CountQueryException($sql);
        }

        return trim($queryCount);
    }