prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Freezing in certain strings
  ### Describe the issue
  
  Hi.
  
  We just updated Weblate to 4.15.1, and our instance is hanging when we access certain strings, weird strings (that should be ignored when creating the PO files, I know).
  
  Instance logs, sometimes show this:
  ```
  [2023-01-24 12:54:51,272: DEBUG/90183] git: failure fatal: bad object 93f0b5592a265aa1ba11131707a710dbdcca0040
  [2023-01-24 12:54:51,272: DEBUG/90183] git: failure fatal: bad object 93f0b5592a265aa1ba11131707a710dbdcca0040
  ```
  
  This is an example of the string that cause the issue:
  
  https://github.com/freebsd/freebsd-doc-translate/blob/main/documentation/content/es/articles/serial-uart/_index.po#L38-L52
  
  ```
  #. type: Plain text
  #: documentation/content/en/articles/serial-uart/_index.adoc:48
  msgid "'''"
  msgstr "'''"
  ```
  
  postgres be stuck in selects.
  
  Do you know if there is something we can do here?
  
  Regards.
  
  ### I already tried
  
  - [X] I've read and searched [the documentation](https://docs.weblate.org/).
  - [X] I've searched for similar issues in this repository.
  
  ### Steps to reproduce the behavior
  
  Go to any string like this:
  
  ```
  #. type: Plain text
  #: documentation/content/en/articles/serial-uart/_index.adoc:48
  msgid "'''"
  msgstr "'''"
  ```
  
  ### Expected behavior
  
  _No response_
  
  ### Screenshots
  
  _No response_
  
  ### Exception traceback
  
  ```pytb
  Only this:
  
  
  [2023-01-24 12:54:51,272: DEBUG/90183] git: failure fatal: bad object 93f0b5592a265aa1ba11131707a710dbdcca0040
  [2023-01-24 12:54:51,272: DEBUG/90183] git: failure fatal: bad object 93f0b5592a265aa1ba11131707a710dbdcca0040
  ```
  
  
  ### How do you run Weblate?
  
  weblate.org service
  
  ### Weblate versions
  
  `4.15.1`
  We have updated docker containers from `4.10.1`.
  
  ### Weblate deploy checks
  
  _No response_
  
  ### Additional context
  
  _No response_
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `weblate/utils/db.py`
  Content:
  ```
  1 # Copyright © Michal Čihař <michal@weblate.org>
  2 #
  3 # SPDX-License-Identifier: GPL-3.0-or-later
  4 
  5 """Database specific code to extend Django."""
  6 
  7 from django.db import connection, models
  8 from django.db.models import Case, IntegerField, Sum, When
  9 from django.db.models.lookups import PatternLookup
  10 
  11 ESCAPED = frozenset(".\\+*?[^]$(){}=!<>|:-")
  12 
  13 PG_TRGM = "CREATE INDEX {0}_{1}_fulltext ON trans_{0} USING GIN ({1} gin_trgm_ops {2})"
  14 PG_DROP = "DROP INDEX {0}_{1}_fulltext"
  15 
  16 MY_FTX = "CREATE FULLTEXT INDEX {0}_{1}_fulltext ON trans_{0}({1})"
  17 MY_DROP = "ALTER TABLE trans_{0} DROP INDEX {0}_{1}_fulltext"
  18 
  19 
  20 def conditional_sum(value=1, **cond):
  21     """Wrapper to generate SUM on boolean/enum values."""
  22     return Sum(Case(When(then=value, **cond), default=0, output_field=IntegerField()))
  23 
  24 
  25 def using_postgresql():
  26     return connection.vendor == "postgresql"
  27 
  28 
  29 def adjust_similarity_threshold(value: float):
  30     """
  31     Adjusts pg_trgm.similarity_threshold for the % operator.
  32 
  33     Ideally we would use directly similarity() in the search, but that doesn't seem
  34     to use index, while using % does.
  35     """
  36     if not using_postgresql():
  37         return
  38     with connection.cursor() as cursor:
  39         # The SELECT has to be executed first as othervise the trgm extension
  40         # might not yet be loaded and GUC setting not possible.
  41         if not hasattr(connection, "weblate_similarity"):
  42             cursor.execute("SELECT show_limit()")
  43             connection.weblate_similarity = cursor.fetchone()[0]
  44         # Change setting only for reasonably big difference
  45         if abs(connection.weblate_similarity - value) > 0.01:
  46             cursor.execute("SELECT set_limit(%s)", [value])
  47             connection.weblate_similarity = value
  48 
  49 
  50 class PostgreSQLSearchLookup(PatternLookup):
  51     lookup_name = "search"
  52     param_pattern = "%s"
  53 
  54     def as_sql(self, qn, connection):
  55         lhs, lhs_params = self.process_lhs(qn, connection)
  56         rhs, rhs_params = self.process_rhs(qn, connection)
  57         params = lhs_params + rhs_params
  58         return f"{lhs} %% {rhs} = true", params
  59 
  60 
  61 class MySQLSearchLookup(models.Lookup):
  62     lookup_name = "search"
  63 
  64     def as_sql(self, compiler, connection):
  65         lhs, lhs_params = self.process_lhs(compiler, connection)
  66         rhs, rhs_params = self.process_rhs(compiler, connection)
  67         params = lhs_params + rhs_params
  68         return f"MATCH ({lhs}) AGAINST ({rhs} IN NATURAL LANGUAGE MODE)", params
  69 
  70 
  71 class PostgreSQLSubstringLookup(PatternLookup):
  72     """
  73     Case insensitive substring lookup.
  74 
  75     This is essentially same as icontains in Django, but utilizes ILIKE
  76     operator which can use pg_trgm index.
  77     """
  78 
  79     lookup_name = "substring"
  80 
  81     def as_sql(self, compiler, connection):
  82         lhs, lhs_params = self.process_lhs(compiler, connection)
  83         rhs, rhs_params = self.process_rhs(compiler, connection)
  84         params = lhs_params + rhs_params
  85         return f"{lhs} ILIKE {rhs}", params
  86 
  87 
  88 class PostgreSQLILikeLookup(PostgreSQLSubstringLookup):
  89     """
  90     Case insensitive string lookup.
  91 
  92     This is essentially same as iexact in Django, but utilizes ILIKE
  93     operator which can use pg_trgm index.
  94     """
  95 
  96     lookup_name = "ilike"
  97     param_pattern = "%s"
  98 
  99 
  100 def re_escape(pattern):
  101     """Escape for use in database regexp match.
  102 
  103     This is based on re.escape, but that one escapes too much.
  104     """
  105     string = list(pattern)
  106     for i, char in enumerate(pattern):
  107         if char == "\000":
  108             string[i] = "\\000"
  109         elif char in ESCAPED:
  110             string[i] = "\\" + char
  111     return "".join(string)
  112
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/weblate/utils/db.py b/weblate/utils/db.py
  --- a/weblate/utils/db.py
  +++ b/weblate/utils/db.py
  @@ -6,7 +6,7 @@
   
   from django.db import connection, models
   from django.db.models import Case, IntegerField, Sum, When
  -from django.db.models.lookups import PatternLookup
  +from django.db.models.lookups import IContains, IExact, PatternLookup
   
   ESCAPED = frozenset(".\\+*?[^]$(){}=!<>|:-")
   
  @@ -47,13 +47,27 @@
               connection.weblate_similarity = value
   
   
  -class PostgreSQLSearchLookup(PatternLookup):
  +class PostgreSQLFallbackLookup(PatternLookup):
  +    def __init__(self, lhs, rhs):
  +        self.orig_lhs = lhs
  +        self.orig_rhs = rhs
  +        super().__init__(lhs, rhs)
  +
  +    def needs_fallback(self):
  +        return isinstance(self.orig_rhs, str) and not any(
  +            char.isalnum() for char in self.orig_rhs
  +        )
  +
  +
  +class PostgreSQLSearchLookup(PostgreSQLFallbackLookup):
       lookup_name = "search"
       param_pattern = "%s"
   
  -    def as_sql(self, qn, connection):
  -        lhs, lhs_params = self.process_lhs(qn, connection)
  -        rhs, rhs_params = self.process_rhs(qn, connection)
  +    def as_sql(self, compiler, connection):
  +        if self.needs_fallback():
  +            return IContains(self.orig_lhs, self.orig_rhs).as_sql(compiler, connection)
  +        lhs, lhs_params = self.process_lhs(compiler, connection)
  +        rhs, rhs_params = self.process_rhs(compiler, connection)
           params = lhs_params + rhs_params
           return f"{lhs} %% {rhs} = true", params
   
  @@ -68,7 +82,7 @@
           return f"MATCH ({lhs}) AGAINST ({rhs} IN NATURAL LANGUAGE MODE)", params
   
   
  -class PostgreSQLSubstringLookup(PatternLookup):
  +class PostgreSQLSubstringLookup(PostgreSQLFallbackLookup):
       """
       Case insensitive substring lookup.
   
  @@ -79,6 +93,8 @@
       lookup_name = "substring"
   
       def as_sql(self, compiler, connection):
  +        if self.needs_fallback():
  +            return IContains(self.orig_lhs, self.orig_rhs).as_sql(compiler, connection)
           lhs, lhs_params = self.process_lhs(compiler, connection)
           rhs, rhs_params = self.process_rhs(compiler, connection)
           params = lhs_params + rhs_params
  @@ -96,6 +112,11 @@
       lookup_name = "ilike"
       param_pattern = "%s"
   
  +    def as_sql(self, compiler, connection):
  +        if self.needs_fallback():
  +            return IExact(self.orig_lhs, self.orig_rhs).as_sql(compiler, connection)
  +        return super().as_sql(compiler, connection)
  +
   
   def re_escape(pattern):
       """Escape for use in database regexp match.
  
verification_info: {"golden_diff": "diff --git a/weblate/utils/db.py b/weblate/utils/db.py\n--- a/weblate/utils/db.py\n+++ b/weblate/utils/db.py\n@@ -6,7 +6,7 @@\n \n from django.db import connection, models\n from django.db.models import Case, IntegerField, Sum, When\n-from django.db.models.lookups import PatternLookup\n+from django.db.models.lookups import IContains, IExact, PatternLookup\n \n ESCAPED = frozenset(\".\\\\+*?[^]$(){}=!<>|:-\")\n \n@@ -47,13 +47,27 @@\n             connection.weblate_similarity = value\n \n \n-class PostgreSQLSearchLookup(PatternLookup):\n+class PostgreSQLFallbackLookup(PatternLookup):\n+    def __init__(self, lhs, rhs):\n+        self.orig_lhs = lhs\n+        self.orig_rhs = rhs\n+        super().__init__(lhs, rhs)\n+\n+    def needs_fallback(self):\n+        return isinstance(self.orig_rhs, str) and not any(\n+            char.isalnum() for char in self.orig_rhs\n+        )\n+\n+\n+class PostgreSQLSearchLookup(PostgreSQLFallbackLookup):\n     lookup_name = \"search\"\n     param_pattern = \"%s\"\n \n-    def as_sql(self, qn, connection):\n-        lhs, lhs_params = self.process_lhs(qn, connection)\n-        rhs, rhs_params = self.process_rhs(qn, connection)\n+    def as_sql(self, compiler, connection):\n+        if self.needs_fallback():\n+            return IContains(self.orig_lhs, self.orig_rhs).as_sql(compiler, connection)\n+        lhs, lhs_params = self.process_lhs(compiler, connection)\n+        rhs, rhs_params = self.process_rhs(compiler, connection)\n         params = lhs_params + rhs_params\n         return f\"{lhs} %% {rhs} = true\", params\n \n@@ -68,7 +82,7 @@\n         return f\"MATCH ({lhs}) AGAINST ({rhs} IN NATURAL LANGUAGE MODE)\", params\n \n \n-class PostgreSQLSubstringLookup(PatternLookup):\n+class PostgreSQLSubstringLookup(PostgreSQLFallbackLookup):\n     \"\"\"\n     Case insensitive substring lookup.\n \n@@ -79,6 +93,8 @@\n     lookup_name = \"substring\"\n \n     def as_sql(self, compiler, connection):\n+        if self.needs_fallback():\n+            return IContains(self.orig_lhs, self.orig_rhs).as_sql(compiler, connection)\n         lhs, lhs_params = self.process_lhs(compiler, connection)\n         rhs, rhs_params = self.process_rhs(compiler, connection)\n         params = lhs_params + rhs_params\n@@ -96,6 +112,11 @@\n     lookup_name = \"ilike\"\n     param_pattern = \"%s\"\n \n+    def as_sql(self, compiler, connection):\n+        if self.needs_fallback():\n+            return IExact(self.orig_lhs, self.orig_rhs).as_sql(compiler, connection)\n+        return super().as_sql(compiler, connection)\n+\n \n def re_escape(pattern):\n     \"\"\"Escape for use in database regexp match.\n", "issue": "Freezing in certain strings\n### Describe the issue\r\n\r\nHi.\r\n\r\nWe just updated Weblate to 4.15.1, and our instance is hanging when we access certain strings, weird strings (that should be ignored when creating the PO files, I know).\r\n\r\nInstance logs, sometimes show this:\r\n```\r\n[2023-01-24 12:54:51,272: DEBUG/90183] git: failure fatal: bad object 93f0b5592a265aa1ba11131707a710dbdcca0040\r\n[2023-01-24 12:54:51,272: DEBUG/90183] git: failure fatal: bad object 93f0b5592a265aa1ba11131707a710dbdcca0040\r\n```\r\n\r\nThis is an example of the string that cause the issue:\r\n\r\nhttps://github.com/freebsd/freebsd-doc-translate/blob/main/documentation/content/es/articles/serial-uart/_index.po#L38-L52\r\n\r\n```\r\n#. type: Plain text\r\n#: documentation/content/en/articles/serial-uart/_index.adoc:48\r\nmsgid \"'''\"\r\nmsgstr \"'''\"\r\n```\r\n\r\npostgres be stuck in selects.\r\n\r\nDo you know if there is something we can do here?\r\n\r\nRegards.\r\n\r\n### I already tried\r\n\r\n- [X] I've read and searched [the documentation](https://docs.weblate.org/).\r\n- [X] I've searched for similar issues in this repository.\r\n\r\n### Steps to reproduce the behavior\r\n\r\nGo to any string like this:\r\n\r\n```\r\n#. type: Plain text\r\n#: documentation/content/en/articles/serial-uart/_index.adoc:48\r\nmsgid \"'''\"\r\nmsgstr \"'''\"\r\n```\r\n\r\n### Expected behavior\r\n\r\n_No response_\r\n\r\n### Screenshots\r\n\r\n_No response_\r\n\r\n### Exception traceback\r\n\r\n```pytb\r\nOnly this:\r\n\r\n\r\n[2023-01-24 12:54:51,272: DEBUG/90183] git: failure fatal: bad object 93f0b5592a265aa1ba11131707a710dbdcca0040\r\n[2023-01-24 12:54:51,272: DEBUG/90183] git: failure fatal: bad object 93f0b5592a265aa1ba11131707a710dbdcca0040\r\n```\r\n\r\n\r\n### How do you run Weblate?\r\n\r\nweblate.org service\r\n\r\n### Weblate versions\r\n\r\n`4.15.1`\r\nWe have updated docker containers from `4.10.1`.\r\n\r\n### Weblate deploy checks\r\n\r\n_No response_\r\n\r\n### Additional context\r\n\r\n_No response_\n", "before_files": [{"content": "# Copyright \u00a9 Michal \u010ciha\u0159 <michal@weblate.org>\n#\n# SPDX-License-Identifier: GPL-3.0-or-later\n\n\"\"\"Database specific code to extend Django.\"\"\"\n\nfrom django.db import connection, models\nfrom django.db.models import Case, IntegerField, Sum, When\nfrom django.db.models.lookups import PatternLookup\n\nESCAPED = frozenset(\".\\\\+*?[^]$(){}=!<>|:-\")\n\nPG_TRGM = \"CREATE INDEX {0}_{1}_fulltext ON trans_{0} USING GIN ({1} gin_trgm_ops {2})\"\nPG_DROP = \"DROP INDEX {0}_{1}_fulltext\"\n\nMY_FTX = \"CREATE FULLTEXT INDEX {0}_{1}_fulltext ON trans_{0}({1})\"\nMY_DROP = \"ALTER TABLE trans_{0} DROP INDEX {0}_{1}_fulltext\"\n\n\ndef conditional_sum(value=1, **cond):\n    \"\"\"Wrapper to generate SUM on boolean/enum values.\"\"\"\n    return Sum(Case(When(then=value, **cond), default=0, output_field=IntegerField()))\n\n\ndef using_postgresql():\n    return connection.vendor == \"postgresql\"\n\n\ndef adjust_similarity_threshold(value: float):\n    \"\"\"\n    Adjusts pg_trgm.similarity_threshold for the % operator.\n\n    Ideally we would use directly similarity() in the search, but that doesn't seem\n    to use index, while using % does.\n    \"\"\"\n    if not using_postgresql():\n        return\n    with connection.cursor() as cursor:\n        # The SELECT has to be executed first as othervise the trgm extension\n        # might not yet be loaded and GUC setting not possible.\n        if not hasattr(connection, \"weblate_similarity\"):\n            cursor.execute(\"SELECT show_limit()\")\n            connection.weblate_similarity = cursor.fetchone()[0]\n        # Change setting only for reasonably big difference\n        if abs(connection.weblate_similarity - value) > 0.01:\n            cursor.execute(\"SELECT set_limit(%s)\", [value])\n            connection.weblate_similarity = value\n\n\nclass PostgreSQLSearchLookup(PatternLookup):\n    lookup_name = \"search\"\n    param_pattern = \"%s\"\n\n    def as_sql(self, qn, connection):\n        lhs, lhs_params = self.process_lhs(qn, connection)\n        rhs, rhs_params = self.process_rhs(qn, connection)\n        params = lhs_params + rhs_params\n        return f\"{lhs} %% {rhs} = true\", params\n\n\nclass MySQLSearchLookup(models.Lookup):\n    lookup_name = \"search\"\n\n    def as_sql(self, compiler, connection):\n        lhs, lhs_params = self.process_lhs(compiler, connection)\n        rhs, rhs_params = self.process_rhs(compiler, connection)\n        params = lhs_params + rhs_params\n        return f\"MATCH ({lhs}) AGAINST ({rhs} IN NATURAL LANGUAGE MODE)\", params\n\n\nclass PostgreSQLSubstringLookup(PatternLookup):\n    \"\"\"\n    Case insensitive substring lookup.\n\n    This is essentially same as icontains in Django, but utilizes ILIKE\n    operator which can use pg_trgm index.\n    \"\"\"\n\n    lookup_name = \"substring\"\n\n    def as_sql(self, compiler, connection):\n        lhs, lhs_params = self.process_lhs(compiler, connection)\n        rhs, rhs_params = self.process_rhs(compiler, connection)\n        params = lhs_params + rhs_params\n        return f\"{lhs} ILIKE {rhs}\", params\n\n\nclass PostgreSQLILikeLookup(PostgreSQLSubstringLookup):\n    \"\"\"\n    Case insensitive string lookup.\n\n    This is essentially same as iexact in Django, but utilizes ILIKE\n    operator which can use pg_trgm index.\n    \"\"\"\n\n    lookup_name = \"ilike\"\n    param_pattern = \"%s\"\n\n\ndef re_escape(pattern):\n    \"\"\"Escape for use in database regexp match.\n\n    This is based on re.escape, but that one escapes too much.\n    \"\"\"\n    string = list(pattern)\n    for i, char in enumerate(pattern):\n        if char == \"\\000\":\n            string[i] = \"\\\\000\"\n        elif char in ESCAPED:\n            string[i] = \"\\\\\" + char\n    return \"\".join(string)\n", "path": "weblate/utils/db.py"}], "after_files": [{"content": "# Copyright \u00a9 Michal \u010ciha\u0159 <michal@weblate.org>\n#\n# SPDX-License-Identifier: GPL-3.0-or-later\n\n\"\"\"Database specific code to extend Django.\"\"\"\n\nfrom django.db import connection, models\nfrom django.db.models import Case, IntegerField, Sum, When\nfrom django.db.models.lookups import IContains, IExact, PatternLookup\n\nESCAPED = frozenset(\".\\\\+*?[^]$(){}=!<>|:-\")\n\nPG_TRGM = \"CREATE INDEX {0}_{1}_fulltext ON trans_{0} USING GIN ({1} gin_trgm_ops {2})\"\nPG_DROP = \"DROP INDEX {0}_{1}_fulltext\"\n\nMY_FTX = \"CREATE FULLTEXT INDEX {0}_{1}_fulltext ON trans_{0}({1})\"\nMY_DROP = \"ALTER TABLE trans_{0} DROP INDEX {0}_{1}_fulltext\"\n\n\ndef conditional_sum(value=1, **cond):\n    \"\"\"Wrapper to generate SUM on boolean/enum values.\"\"\"\n    return Sum(Case(When(then=value, **cond), default=0, output_field=IntegerField()))\n\n\ndef using_postgresql():\n    return connection.vendor == \"postgresql\"\n\n\ndef adjust_similarity_threshold(value: float):\n    \"\"\"\n    Adjusts pg_trgm.similarity_threshold for the % operator.\n\n    Ideally we would use directly similarity() in the search, but that doesn't seem\n    to use index, while using % does.\n    \"\"\"\n    if not using_postgresql():\n        return\n    with connection.cursor() as cursor:\n        # The SELECT has to be executed first as othervise the trgm extension\n        # might not yet be loaded and GUC setting not possible.\n        if not hasattr(connection, \"weblate_similarity\"):\n            cursor.execute(\"SELECT show_limit()\")\n            connection.weblate_similarity = cursor.fetchone()[0]\n        # Change setting only for reasonably big difference\n        if abs(connection.weblate_similarity - value) > 0.01:\n            cursor.execute(\"SELECT set_limit(%s)\", [value])\n            connection.weblate_similarity = value\n\n\nclass PostgreSQLFallbackLookup(PatternLookup):\n    def __init__(self, lhs, rhs):\n        self.orig_lhs = lhs\n        self.orig_rhs = rhs\n        super().__init__(lhs, rhs)\n\n    def needs_fallback(self):\n        return isinstance(self.orig_rhs, str) and not any(\n            char.isalnum() for char in self.orig_rhs\n        )\n\n\nclass PostgreSQLSearchLookup(PostgreSQLFallbackLookup):\n    lookup_name = \"search\"\n    param_pattern = \"%s\"\n\n    def as_sql(self, compiler, connection):\n        if self.needs_fallback():\n            return IContains(self.orig_lhs, self.orig_rhs).as_sql(compiler, connection)\n        lhs, lhs_params = self.process_lhs(compiler, connection)\n        rhs, rhs_params = self.process_rhs(compiler, connection)\n        params = lhs_params + rhs_params\n        return f\"{lhs} %% {rhs} = true\", params\n\n\nclass MySQLSearchLookup(models.Lookup):\n    lookup_name = \"search\"\n\n    def as_sql(self, compiler, connection):\n        lhs, lhs_params = self.process_lhs(compiler, connection)\n        rhs, rhs_params = self.process_rhs(compiler, connection)\n        params = lhs_params + rhs_params\n        return f\"MATCH ({lhs}) AGAINST ({rhs} IN NATURAL LANGUAGE MODE)\", params\n\n\nclass PostgreSQLSubstringLookup(PostgreSQLFallbackLookup):\n    \"\"\"\n    Case insensitive substring lookup.\n\n    This is essentially same as icontains in Django, but utilizes ILIKE\n    operator which can use pg_trgm index.\n    \"\"\"\n\n    lookup_name = \"substring\"\n\n    def as_sql(self, compiler, connection):\n        if self.needs_fallback():\n            return IContains(self.orig_lhs, self.orig_rhs).as_sql(compiler, connection)\n        lhs, lhs_params = self.process_lhs(compiler, connection)\n        rhs, rhs_params = self.process_rhs(compiler, connection)\n        params = lhs_params + rhs_params\n        return f\"{lhs} ILIKE {rhs}\", params\n\n\nclass PostgreSQLILikeLookup(PostgreSQLSubstringLookup):\n    \"\"\"\n    Case insensitive string lookup.\n\n    This is essentially same as iexact in Django, but utilizes ILIKE\n    operator which can use pg_trgm index.\n    \"\"\"\n\n    lookup_name = \"ilike\"\n    param_pattern = \"%s\"\n\n    def as_sql(self, compiler, connection):\n        if self.needs_fallback():\n            return IExact(self.orig_lhs, self.orig_rhs).as_sql(compiler, connection)\n        return super().as_sql(compiler, connection)\n\n\ndef re_escape(pattern):\n    \"\"\"Escape for use in database regexp match.\n\n    This is based on re.escape, but that one escapes too much.\n    \"\"\"\n    string = list(pattern)\n    for i, char in enumerate(pattern):\n        if char == \"\\000\":\n            string[i] = \"\\\\000\"\n        elif char in ESCAPED:\n            string[i] = \"\\\\\" + char\n    return \"\".join(string)\n", "path": "weblate/utils/db.py"}]}