prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  cast to map with clickhouse dialect ignores case
  Yet another clickhouse case sensitivity bug :)
  
  
  ClickHouse CLI:
  
  ```
  albatross :) select cast(map('a', 1, 'b', 2) as Map(String, Int8));
  
  SELECT CAST(map('a', 1, 'b', 2), 'Map(String, Int8)')
  
  Query id: bab188fb-69f7-4c0f-9bde-ac524a08f6e8
  
  ┌─CAST(map('a', 1, 'b', 2), 'Map(String, Int8)')─┐
  │ {'a':1,'b':2}                                  │
  └────────────────────────────────────────────────┘
  
  1 row in set. Elapsed: 0.001 sec.
  ```
  
  sqlglot:
  
  ```
  In [7]: sg.parse_one("cast(map('a', 1, 'b', 2) as Map(String, Int8))", read="clickhouse").sql(dialect="clickhouse")
  Out[7]: "CAST(map('a', 1, 'b', 2) AS MAP(TEXT, TINYINT))"
  ```
  
  Perhaps there's a way to disable all case transformations for the clickhouse dialect.
  
  </issue>
  <code>
  [start of sqlglot/dialects/clickhouse.py]
  1 from sqlglot import exp
  2 from sqlglot.dialects.dialect import Dialect, inline_array_sql, var_map_sql
  3 from sqlglot.generator import Generator
  4 from sqlglot.helper import csv
  5 from sqlglot.parser import Parser, parse_var_map
  6 from sqlglot.tokens import Tokenizer, TokenType
  7 
  8 
  9 def _lower_func(sql):
  10     index = sql.index("(")
  11     return sql[:index].lower() + sql[index:]
  12 
  13 
  14 class ClickHouse(Dialect):
  15     normalize_functions = None
  16     null_ordering = "nulls_are_last"
  17 
  18     class Tokenizer(Tokenizer):
  19         IDENTIFIERS = ['"', "`"]
  20 
  21         KEYWORDS = {
  22             **Tokenizer.KEYWORDS,
  23             "NULLABLE": TokenType.NULLABLE,
  24             "FINAL": TokenType.FINAL,
  25             "DATETIME64": TokenType.DATETIME,
  26             "INT8": TokenType.TINYINT,
  27             "INT16": TokenType.SMALLINT,
  28             "INT32": TokenType.INT,
  29             "INT64": TokenType.BIGINT,
  30             "FLOAT32": TokenType.FLOAT,
  31             "FLOAT64": TokenType.DOUBLE,
  32         }
  33 
  34     class Parser(Parser):
  35         FUNCTIONS = {
  36             **Parser.FUNCTIONS,
  37             "MAP": parse_var_map,
  38         }
  39 
  40         def _parse_table(self, schema=False):
  41             this = super()._parse_table(schema)
  42 
  43             if self._match(TokenType.FINAL):
  44                 this = self.expression(exp.Final, this=this)
  45 
  46             return this
  47 
  48     class Generator(Generator):
  49         STRUCT_DELIMITER = ("(", ")")
  50 
  51         TYPE_MAPPING = {
  52             **Generator.TYPE_MAPPING,
  53             exp.DataType.Type.NULLABLE: "Nullable",
  54             exp.DataType.Type.DATETIME: "DateTime64",
  55         }
  56 
  57         TRANSFORMS = {
  58             **Generator.TRANSFORMS,
  59             exp.Array: inline_array_sql,
  60             exp.StrPosition: lambda self, e: f"position({csv(self.sql(e, 'this'), self.sql(e, 'substr'), self.sql(e, 'position'))})",
  61             exp.Final: lambda self, e: f"{self.sql(e, 'this')} FINAL",
  62             exp.Map: lambda self, e: _lower_func(var_map_sql(self, e)),
  63             exp.VarMap: lambda self, e: _lower_func(var_map_sql(self, e)),
  64         }
  65 
  66         EXPLICIT_UNION = True
  67
  [end of sqlglot/dialects/clickhouse.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/sqlglot/dialects/clickhouse.py b/sqlglot/dialects/clickhouse.py
  --- a/sqlglot/dialects/clickhouse.py
  +++ b/sqlglot/dialects/clickhouse.py
  @@ -51,6 +51,9 @@
               **Generator.TYPE_MAPPING,
               exp.DataType.Type.NULLABLE: "Nullable",
               exp.DataType.Type.DATETIME: "DateTime64",
  +            exp.DataType.Type.MAP: "Map",
  +            exp.DataType.Type.ARRAY: "Array",
  +            exp.DataType.Type.STRUCT: "Tuple",
           }
   
           TRANSFORMS = {
  
verification_info: {"golden_diff": "diff --git a/sqlglot/dialects/clickhouse.py b/sqlglot/dialects/clickhouse.py\n--- a/sqlglot/dialects/clickhouse.py\n+++ b/sqlglot/dialects/clickhouse.py\n@@ -51,6 +51,9 @@\n             **Generator.TYPE_MAPPING,\n             exp.DataType.Type.NULLABLE: \"Nullable\",\n             exp.DataType.Type.DATETIME: \"DateTime64\",\n+            exp.DataType.Type.MAP: \"Map\",\n+            exp.DataType.Type.ARRAY: \"Array\",\n+            exp.DataType.Type.STRUCT: \"Tuple\",\n         }\n \n         TRANSFORMS = {\n", "issue": "cast to map with clickhouse dialect ignores case\nYet another clickhouse case sensitivity bug :)\r\n\r\n\r\nClickHouse CLI:\r\n\r\n```\r\nalbatross :) select cast(map('a', 1, 'b', 2) as Map(String, Int8));\r\n\r\nSELECT CAST(map('a', 1, 'b', 2), 'Map(String, Int8)')\r\n\r\nQuery id: bab188fb-69f7-4c0f-9bde-ac524a08f6e8\r\n\r\n\u250c\u2500CAST(map('a', 1, 'b', 2), 'Map(String, Int8)')\u2500\u2510\r\n\u2502 {'a':1,'b':2}                                  \u2502\r\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\r\n\r\n1 row in set. Elapsed: 0.001 sec.\r\n```\r\n\r\nsqlglot:\r\n\r\n```\r\nIn [7]: sg.parse_one(\"cast(map('a', 1, 'b', 2) as Map(String, Int8))\", read=\"clickhouse\").sql(dialect=\"clickhouse\")\r\nOut[7]: \"CAST(map('a', 1, 'b', 2) AS MAP(TEXT, TINYINT))\"\r\n```\r\n\r\nPerhaps there's a way to disable all case transformations for the clickhouse dialect.\n", "before_files": [{"content": "from sqlglot import exp\nfrom sqlglot.dialects.dialect import Dialect, inline_array_sql, var_map_sql\nfrom sqlglot.generator import Generator\nfrom sqlglot.helper import csv\nfrom sqlglot.parser import Parser, parse_var_map\nfrom sqlglot.tokens import Tokenizer, TokenType\n\n\ndef _lower_func(sql):\n    index = sql.index(\"(\")\n    return sql[:index].lower() + sql[index:]\n\n\nclass ClickHouse(Dialect):\n    normalize_functions = None\n    null_ordering = \"nulls_are_last\"\n\n    class Tokenizer(Tokenizer):\n        IDENTIFIERS = ['\"', \"`\"]\n\n        KEYWORDS = {\n            **Tokenizer.KEYWORDS,\n            \"NULLABLE\": TokenType.NULLABLE,\n            \"FINAL\": TokenType.FINAL,\n            \"DATETIME64\": TokenType.DATETIME,\n            \"INT8\": TokenType.TINYINT,\n            \"INT16\": TokenType.SMALLINT,\n            \"INT32\": TokenType.INT,\n            \"INT64\": TokenType.BIGINT,\n            \"FLOAT32\": TokenType.FLOAT,\n            \"FLOAT64\": TokenType.DOUBLE,\n        }\n\n    class Parser(Parser):\n        FUNCTIONS = {\n            **Parser.FUNCTIONS,\n            \"MAP\": parse_var_map,\n        }\n\n        def _parse_table(self, schema=False):\n            this = super()._parse_table(schema)\n\n            if self._match(TokenType.FINAL):\n                this = self.expression(exp.Final, this=this)\n\n            return this\n\n    class Generator(Generator):\n        STRUCT_DELIMITER = (\"(\", \")\")\n\n        TYPE_MAPPING = {\n            **Generator.TYPE_MAPPING,\n            exp.DataType.Type.NULLABLE: \"Nullable\",\n            exp.DataType.Type.DATETIME: \"DateTime64\",\n        }\n\n        TRANSFORMS = {\n            **Generator.TRANSFORMS,\n            exp.Array: inline_array_sql,\n            exp.StrPosition: lambda self, e: f\"position({csv(self.sql(e, 'this'), self.sql(e, 'substr'), self.sql(e, 'position'))})\",\n            exp.Final: lambda self, e: f\"{self.sql(e, 'this')} FINAL\",\n            exp.Map: lambda self, e: _lower_func(var_map_sql(self, e)),\n            exp.VarMap: lambda self, e: _lower_func(var_map_sql(self, e)),\n        }\n\n        EXPLICIT_UNION = True\n", "path": "sqlglot/dialects/clickhouse.py"}]}