prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  bug(bigquery): memtable and string literals not escaping `\n` or `\` which results in invalid syntax
  ### What happened?
  
  Code:
  
  ```python
  import ibis
  
  ibis_client = ibis.bigquery.connect()
  table = ibis.memtable(
      {
          "col1": ["a\tb\nc", "d e f", "g'e\"h"],
      }
  )
  print(ibis_client.compile(table))
  ```
  
  Output:
  
  ```
  SELECT t0.*
  FROM UNNEST(ARRAY<STRUCT<col1 STRING>>[STRUCT('a        b
  c' AS col1), STRUCT('d e f' AS col1), STRUCT('g\'e"h' AS col1)]) t0
  ```
  
  Note, the following SQL works as expected:
  
  ```
  SELECT t0.*
  FROM UNNEST(ARRAY<STRUCT<col1 STRING>>[STRUCT('a        b\nc' AS col1), STRUCT('d e f' AS col1), STRUCT('g\'e"h' AS col1)]) t0
  ```
  
  Therefore, we should really be escaping `\n` in addition to `'`. Though, perhaps there are other characters that could break BigQuery syntax? See: https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#string_and_bytes_literals
  
  Alternatively, using triple-quoted strings allows for newline characters in the string literal itself.
  
  ### What version of ibis are you using?
  
  6.1.0
  
  also tested on latest commit: 15f8d9575
  
  ### What backend(s) are you using, if any?
  
  BigQuery
  
  ### Relevant log output
  
  ```sh
  BigQuery API: Syntax error: Unclosed string literal at [2:47]
  ```
  
  
  ### Code of Conduct
  
  - [X] I agree to follow this project's Code of Conduct
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `ibis/backends/base/sql/registry/literal.py`
  Content:
  ```
  1 from __future__ import annotations
  2 
  3 import datetime
  4 import math
  5 
  6 import ibis.expr.types as ir
  7 
  8 
  9 def _set_literal_format(translator, expr):
  10     value_type = expr.type().value_type
  11 
  12     formatted = [
  13         translator.translate(ir.literal(x, type=value_type)) for x in expr.op().value
  14     ]
  15 
  16     return "(" + ", ".join(formatted) + ")"
  17 
  18 
  19 def _boolean_literal_format(translator, op):
  20     return "TRUE" if op.value else "FALSE"
  21 
  22 
  23 def _string_literal_format(translator, op):
  24     return "'{}'".format(op.value.replace("'", "\\'"))
  25 
  26 
  27 def _number_literal_format(translator, op):
  28     if math.isfinite(op.value):
  29         formatted = repr(op.value)
  30     else:
  31         if math.isnan(op.value):
  32             formatted_val = "NaN"
  33         elif math.isinf(op.value):
  34             if op.value > 0:
  35                 formatted_val = "Infinity"
  36             else:
  37                 formatted_val = "-Infinity"
  38         formatted = f"CAST({formatted_val!r} AS DOUBLE)"
  39 
  40     return formatted
  41 
  42 
  43 def _interval_literal_format(translator, op):
  44     return f"INTERVAL {op.value} {op.dtype.resolution.upper()}"
  45 
  46 
  47 def _date_literal_format(translator, op):
  48     value = op.value
  49     if isinstance(value, datetime.date):
  50         value = value.strftime("%Y-%m-%d")
  51 
  52     return repr(value)
  53 
  54 
  55 def _timestamp_literal_format(translator, op):
  56     value = op.value
  57     if isinstance(value, datetime.datetime):
  58         value = value.isoformat()
  59 
  60     return repr(value)
  61 
  62 
  63 literal_formatters = {
  64     "boolean": _boolean_literal_format,
  65     "number": _number_literal_format,
  66     "string": _string_literal_format,
  67     "interval": _interval_literal_format,
  68     "timestamp": _timestamp_literal_format,
  69     "date": _date_literal_format,
  70     "set": _set_literal_format,
  71 }
  72 
  73 
  74 def literal(translator, op):
  75     """Return the expression as its literal value."""
  76 
  77     dtype = op.dtype
  78 
  79     if op.value is None:
  80         return "NULL"
  81 
  82     if dtype.is_boolean():
  83         typeclass = "boolean"
  84     elif dtype.is_string():
  85         typeclass = "string"
  86     elif dtype.is_date():
  87         typeclass = "date"
  88     elif dtype.is_numeric():
  89         typeclass = "number"
  90     elif dtype.is_timestamp():
  91         typeclass = "timestamp"
  92     elif dtype.is_interval():
  93         typeclass = "interval"
  94     else:
  95         raise NotImplementedError(f"Unsupported type: {dtype!r}")
  96 
  97     return literal_formatters[typeclass](translator, op)
  98
  ```
  --- 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/ibis/backends/base/sql/registry/literal.py b/ibis/backends/base/sql/registry/literal.py
  --- a/ibis/backends/base/sql/registry/literal.py
  +++ b/ibis/backends/base/sql/registry/literal.py
  @@ -21,7 +21,22 @@
   
   
   def _string_literal_format(translator, op):
  -    return "'{}'".format(op.value.replace("'", "\\'"))
  +    return "'{}'".format(
  +        op.value
  +        # Escape \ first so we don't double escape other characters.
  +        .replace("\\", "\\\\")
  +        # Escape ' since we're using those for the string literal.
  +        .replace("'", "\\'")
  +        # ASCII escape sequences that are recognized in Python:
  +        # https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals
  +        .replace("\a", "\\a")  # Bell
  +        .replace("\b", "\\b")  # Backspace
  +        .replace("\f", "\\f")  # Formfeed
  +        .replace("\n", "\\n")  # Newline / Linefeed
  +        .replace("\r", "\\r")  # Carriage return
  +        .replace("\t", "\\t")  # Tab
  +        .replace("\v", "\\v")  # Vertical tab
  +    )
   
   
   def _number_literal_format(translator, op):
  
verification_info: {"golden_diff": "diff --git a/ibis/backends/base/sql/registry/literal.py b/ibis/backends/base/sql/registry/literal.py\n--- a/ibis/backends/base/sql/registry/literal.py\n+++ b/ibis/backends/base/sql/registry/literal.py\n@@ -21,7 +21,22 @@\n \n \n def _string_literal_format(translator, op):\n-    return \"'{}'\".format(op.value.replace(\"'\", \"\\\\'\"))\n+    return \"'{}'\".format(\n+        op.value\n+        # Escape \\ first so we don't double escape other characters.\n+        .replace(\"\\\\\", \"\\\\\\\\\")\n+        # Escape ' since we're using those for the string literal.\n+        .replace(\"'\", \"\\\\'\")\n+        # ASCII escape sequences that are recognized in Python:\n+        # https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals\n+        .replace(\"\\a\", \"\\\\a\")  # Bell\n+        .replace(\"\\b\", \"\\\\b\")  # Backspace\n+        .replace(\"\\f\", \"\\\\f\")  # Formfeed\n+        .replace(\"\\n\", \"\\\\n\")  # Newline / Linefeed\n+        .replace(\"\\r\", \"\\\\r\")  # Carriage return\n+        .replace(\"\\t\", \"\\\\t\")  # Tab\n+        .replace(\"\\v\", \"\\\\v\")  # Vertical tab\n+    )\n \n \n def _number_literal_format(translator, op):\n", "issue": "bug(bigquery): memtable and string literals not escaping `\\n` or `\\` which results in invalid syntax\n### What happened?\n\nCode:\r\n\r\n```python\r\nimport ibis\r\n\r\nibis_client = ibis.bigquery.connect()\r\ntable = ibis.memtable(\r\n    {\r\n        \"col1\": [\"a\\tb\\nc\", \"d e f\", \"g'e\\\"h\"],\r\n    }\r\n)\r\nprint(ibis_client.compile(table))\r\n```\r\n\r\nOutput:\r\n\r\n```\r\nSELECT t0.*\r\nFROM UNNEST(ARRAY<STRUCT<col1 STRING>>[STRUCT('a        b\r\nc' AS col1), STRUCT('d e f' AS col1), STRUCT('g\\'e\"h' AS col1)]) t0\r\n```\r\n\r\nNote, the following SQL works as expected:\r\n\r\n```\r\nSELECT t0.*\r\nFROM UNNEST(ARRAY<STRUCT<col1 STRING>>[STRUCT('a        b\\nc' AS col1), STRUCT('d e f' AS col1), STRUCT('g\\'e\"h' AS col1)]) t0\r\n```\r\n\r\nTherefore, we should really be escaping `\\n` in addition to `'`. Though, perhaps there are other characters that could break BigQuery syntax? See: https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#string_and_bytes_literals\r\n\r\nAlternatively, using triple-quoted strings allows for newline characters in the string literal itself.\n\n### What version of ibis are you using?\n\n6.1.0\r\n\r\nalso tested on latest commit: 15f8d9575\n\n### What backend(s) are you using, if any?\n\nBigQuery\n\n### Relevant log output\n\n```sh\nBigQuery API: Syntax error: Unclosed string literal at [2:47]\n```\n\n\n### Code of Conduct\n\n- [X] I agree to follow this project's Code of Conduct\n", "before_files": [{"content": "from __future__ import annotations\n\nimport datetime\nimport math\n\nimport ibis.expr.types as ir\n\n\ndef _set_literal_format(translator, expr):\n    value_type = expr.type().value_type\n\n    formatted = [\n        translator.translate(ir.literal(x, type=value_type)) for x in expr.op().value\n    ]\n\n    return \"(\" + \", \".join(formatted) + \")\"\n\n\ndef _boolean_literal_format(translator, op):\n    return \"TRUE\" if op.value else \"FALSE\"\n\n\ndef _string_literal_format(translator, op):\n    return \"'{}'\".format(op.value.replace(\"'\", \"\\\\'\"))\n\n\ndef _number_literal_format(translator, op):\n    if math.isfinite(op.value):\n        formatted = repr(op.value)\n    else:\n        if math.isnan(op.value):\n            formatted_val = \"NaN\"\n        elif math.isinf(op.value):\n            if op.value > 0:\n                formatted_val = \"Infinity\"\n            else:\n                formatted_val = \"-Infinity\"\n        formatted = f\"CAST({formatted_val!r} AS DOUBLE)\"\n\n    return formatted\n\n\ndef _interval_literal_format(translator, op):\n    return f\"INTERVAL {op.value} {op.dtype.resolution.upper()}\"\n\n\ndef _date_literal_format(translator, op):\n    value = op.value\n    if isinstance(value, datetime.date):\n        value = value.strftime(\"%Y-%m-%d\")\n\n    return repr(value)\n\n\ndef _timestamp_literal_format(translator, op):\n    value = op.value\n    if isinstance(value, datetime.datetime):\n        value = value.isoformat()\n\n    return repr(value)\n\n\nliteral_formatters = {\n    \"boolean\": _boolean_literal_format,\n    \"number\": _number_literal_format,\n    \"string\": _string_literal_format,\n    \"interval\": _interval_literal_format,\n    \"timestamp\": _timestamp_literal_format,\n    \"date\": _date_literal_format,\n    \"set\": _set_literal_format,\n}\n\n\ndef literal(translator, op):\n    \"\"\"Return the expression as its literal value.\"\"\"\n\n    dtype = op.dtype\n\n    if op.value is None:\n        return \"NULL\"\n\n    if dtype.is_boolean():\n        typeclass = \"boolean\"\n    elif dtype.is_string():\n        typeclass = \"string\"\n    elif dtype.is_date():\n        typeclass = \"date\"\n    elif dtype.is_numeric():\n        typeclass = \"number\"\n    elif dtype.is_timestamp():\n        typeclass = \"timestamp\"\n    elif dtype.is_interval():\n        typeclass = \"interval\"\n    else:\n        raise NotImplementedError(f\"Unsupported type: {dtype!r}\")\n\n    return literal_formatters[typeclass](translator, op)\n", "path": "ibis/backends/base/sql/registry/literal.py"}], "after_files": [{"content": "from __future__ import annotations\n\nimport datetime\nimport math\n\nimport ibis.expr.types as ir\n\n\ndef _set_literal_format(translator, expr):\n    value_type = expr.type().value_type\n\n    formatted = [\n        translator.translate(ir.literal(x, type=value_type)) for x in expr.op().value\n    ]\n\n    return \"(\" + \", \".join(formatted) + \")\"\n\n\ndef _boolean_literal_format(translator, op):\n    return \"TRUE\" if op.value else \"FALSE\"\n\n\ndef _string_literal_format(translator, op):\n    return \"'{}'\".format(\n        op.value\n        # Escape \\ first so we don't double escape other characters.\n        .replace(\"\\\\\", \"\\\\\\\\\")\n        # Escape ' since we're using those for the string literal.\n        .replace(\"'\", \"\\\\'\")\n        # ASCII escape sequences that are recognized in Python:\n        # https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals\n        .replace(\"\\a\", \"\\\\a\")  # Bell\n        .replace(\"\\b\", \"\\\\b\")  # Backspace\n        .replace(\"\\f\", \"\\\\f\")  # Formfeed\n        .replace(\"\\n\", \"\\\\n\")  # Newline / Linefeed\n        .replace(\"\\r\", \"\\\\r\")  # Carriage return\n        .replace(\"\\t\", \"\\\\t\")  # Tab\n        .replace(\"\\v\", \"\\\\v\")  # Vertical tab\n    )\n\n\ndef _number_literal_format(translator, op):\n    if math.isfinite(op.value):\n        formatted = repr(op.value)\n    else:\n        if math.isnan(op.value):\n            formatted_val = \"NaN\"\n        elif math.isinf(op.value):\n            if op.value > 0:\n                formatted_val = \"Infinity\"\n            else:\n                formatted_val = \"-Infinity\"\n        formatted = f\"CAST({formatted_val!r} AS DOUBLE)\"\n\n    return formatted\n\n\ndef _interval_literal_format(translator, op):\n    return f\"INTERVAL {op.value} {op.dtype.resolution.upper()}\"\n\n\ndef _date_literal_format(translator, op):\n    value = op.value\n    if isinstance(value, datetime.date):\n        value = value.strftime(\"%Y-%m-%d\")\n\n    return repr(value)\n\n\ndef _timestamp_literal_format(translator, op):\n    value = op.value\n    if isinstance(value, datetime.datetime):\n        value = value.isoformat()\n\n    return repr(value)\n\n\nliteral_formatters = {\n    \"boolean\": _boolean_literal_format,\n    \"number\": _number_literal_format,\n    \"string\": _string_literal_format,\n    \"interval\": _interval_literal_format,\n    \"timestamp\": _timestamp_literal_format,\n    \"date\": _date_literal_format,\n    \"set\": _set_literal_format,\n}\n\n\ndef literal(translator, op):\n    \"\"\"Return the expression as its literal value.\"\"\"\n\n    dtype = op.dtype\n\n    if op.value is None:\n        return \"NULL\"\n\n    if dtype.is_boolean():\n        typeclass = \"boolean\"\n    elif dtype.is_string():\n        typeclass = \"string\"\n    elif dtype.is_date():\n        typeclass = \"date\"\n    elif dtype.is_numeric():\n        typeclass = \"number\"\n    elif dtype.is_timestamp():\n        typeclass = \"timestamp\"\n    elif dtype.is_interval():\n        typeclass = \"interval\"\n    else:\n        raise NotImplementedError(f\"Unsupported type: {dtype!r}\")\n\n    return literal_formatters[typeclass](translator, op)\n", "path": "ibis/backends/base/sql/registry/literal.py"}]}