# Buggy code
def set_pattern(self, pattern):
    """Set the pattern used to filter results.

    Args:
        pattern: string pattern to filter by.
    """
    # escape to treat a user input % or _ as a literal, not a wildcard
    pattern = pattern.replace("%", "\\%")
    pattern = pattern.replace("_", "\\_")
    words = ["%{}%".format(w) for w in pattern.split(" ")]

    # build a where clause to match all of the words in any order
    # given the search term "a b", the WHERE clause would be:
    # ((url || ' ' || title) LIKE '%a%') AND
    # ((url || ' ' || title) LIKE '%b%')
    where_clause = " AND ".join(
        "(url || ' ' || title) LIKE :{} escape '\\'".format(i)
        for i in range(len(words))
    )

    # replace ' in timestamp-format to avoid breaking the query
    timestamp_format = config.val.completion.timestamp_format or ""
    timefmt = "strftime('{}', last_atime, 'unixepoch', 'localtime')".format(
        timestamp_format.replace("'", "`")
    )

    try:
        if not self._query or len(words) != len(self._query.bound_values()):
            # if the number of words changed, we need to generate a new
            # query otherwise, we can reuse the prepared query for
            # performance
            self._query = sql.Query(
                " ".join(
                    [
                        "SELECT url, title, {}".format(timefmt),
                        "FROM CompletionHistory",
                        # the incoming pattern will have literal % and _ escaped we
                        # need to tell sql to treat '\' as an escape character
                        "WHERE ({})".format(where_clause),
                        self._atime_expr(),
                        "ORDER BY last_atime DESC",
                    ]
                ),
                forward_only=False,
            )

        with debug.log_time("sql", "Running completion query"):
            self._query.run(**{str(i): w for i, w in enumerate(words)})
    except sql.SqlKnownError as e:
        # Sometimes, the query we built up was invalid, for example,
        # due to a large amount of words.
        message.error("Error with SQL Query: {}".format(e.text()))
        return
    self.setQuery(self._query.query)


# Traceback (qutebrowser.misc.sql.SqlBugError)
23:32:01 DEBUG    completion completionmodel:set_pattern:179 Setting completion pattern 'x x [...]'
23:32:01 DEBUG    sql        sql:__init__:169 Preparing SQL query: "SELECT url, title, strftime('%Y-%m-%d', last_atime, 'unixepoch', 'localtime') FROM CompletionHistory WHERE ((url || ' ' || title) LIKE :0 escape '\' AND [...] AND (url || ' ' || title) LIKE :9999 escape '\')  ORDER BY last_atime DESC"
23:32:01 DEBUG    sql        sql:raise_sqlite_error:90 SQL error:
23:32:01 DEBUG    sql        sql:raise_sqlite_error:92 type: StatementError
23:32:01 DEBUG    sql        sql:raise_sqlite_error:93 database text: Expression tree is too large (maximum depth 10000)
23:32:01 DEBUG    sql        sql:raise_sqlite_error:94 driver text: Unable to execute statement
23:32:01 DEBUG    sql        sql:raise_sqlite_error:95 error code: 1
23:32:01 DEBUG    completion debug:__exit__:265 Set pattern x x [...] took 0.259335 seconds.
23:32:01 ERROR    misc       crashsignal:exception_hook:214 Uncaught exception
Traceback (most recent call last):
File "/home/florian/proj/qutebrowser/git/qutebrowser/completion/completer.py", line 261, in _update_completion
completion.set_pattern(pattern)
File "/home/florian/proj/qutebrowser/git/qutebrowser/completion/completionwidget.py", line 320, in set_pattern
self.model().set_pattern(pattern)
File "/home/florian/proj/qutebrowser/git/qutebrowser/completion/models/completionmodel.py", line 185, in set_pattern
cat.set_pattern(pattern)
File "/home/florian/proj/qutebrowser/git/qutebrowser/completion/models/histcategory.py", line 99, in set_pattern
]), forward_only=False)
File "/home/florian/proj/qutebrowser/git/qutebrowser/misc/sql.py", line 171, in __init__
self._check_ok('prepare', ok)
File "/home/florian/proj/qutebrowser/git/qutebrowser/misc/sql.py", line 191, in _check_ok
raise_sqlite_error(msg, error)
File "/home/florian/proj/qutebrowser/git/qutebrowser/misc/sql.py", line 115, in raise_sqlite_error
raise SqlBugError(msg, error)
qutebrowser.misc.sql.SqlBugError: Failed to prepare query "SELECT url, title, strftime('%Y-%m-%d', last_atime, 'unixepoch', 'localtime') FROM CompletionHistory WHERE ((url || ' ' || title) LIKE :0 escape '\' AND [...] AND (url || ' ' || title) LIKE :9997 escape '\' AND (url || ' ' || title) LIKE :9998 escape '\' AND (url || ' ' || title) LIKE :9999 escape '\')  ORDER BY last_atime DESC": "Expression tree is too large (maximum depth 10000) Unable to execute statement"

# Fixed code
def set_pattern(self, pattern):
    """Set the pattern used to filter results.

    Args:
        pattern: string pattern to filter by.
    """
    # escape to treat a user input % or _ as a literal, not a wildcard
    pattern = pattern.replace("%", "\\%")
    pattern = pattern.replace("_", "\\_")
    words = ["%{}%".format(w) for w in pattern.split(" ")]

    # build a where clause to match all of the words in any order
    # given the search term "a b", the WHERE clause would be:
    # ((url || ' ' || title) LIKE '%a%') AND
    # ((url || ' ' || title) LIKE '%b%')
    where_clause = " AND ".join(
        "(url || ' ' || title) LIKE :{} escape '\\'".format(i)
        for i in range(len(words))
    )

    # replace ' in timestamp-format to avoid breaking the query
    timestamp_format = config.val.completion.timestamp_format or ""
    timefmt = "strftime('{}', last_atime, 'unixepoch', 'localtime')".format(
        timestamp_format.replace("'", "`")
    )

    try:
        if not self._query or len(words) != len(self._query.bound_values()):
            # if the number of words changed, we need to generate a new
            # query otherwise, we can reuse the prepared query for
            # performance
            self._query = sql.Query(
                " ".join(
                    [
                        "SELECT url, title, {}".format(timefmt),
                        "FROM CompletionHistory",
                        # the incoming pattern will have literal % and _ escaped we
                        # need to tell sql to treat '\' as an escape character
                        "WHERE ({})".format(where_clause),
                        self._atime_expr(),
                        "ORDER BY last_atime DESC",
                    ]
                ),
                forward_only=False,
            )

        with debug.log_time("sql", "Running completion query"):
            self._query.run(**{str(i): w for i, w in enumerate(words)})
    except sql.SqlKnownError as e:
        # Sometimes, the query we built up was invalid, for example,
        # due to a large amount of words.
        # Also catches failures in the DB we can't solve.
        message.error("Error with SQL Query: {}".format(e.text()))
        return
    self.setQuery(self._query.query)