Repository: tobymao/sqlglot

Issue:
Support for parsing clickhouse Enum, Enum8 and Enum16 types
**Is your feature request related to a problem? Please describe.**

Not related to a problem.

**Describe the solution you'd like**

I'd like sqlglot to support parsing the ClickHouse [`Enum` types](https://clickhouse.com/docs/en/sql-reference/data-types/enum).

**Describe alternatives you've considered**

I haven't considered any alternatives

**Additional context**

N/A

Discussion:

Patch:
diff --git a/sqlglot/dialects/clickhouse.py b/sqlglot/dialects/clickhouse.py
index 708965ba..53bcf5e7 100644
--- a/sqlglot/dialects/clickhouse.py
+++ b/sqlglot/dialects/clickhouse.py
@@ -37,6 +37,9 @@ class ClickHouse(Dialect):
             "ATTACH": TokenType.COMMAND,
             "DATETIME64": TokenType.DATETIME64,
             "DICTIONARY": TokenType.DICTIONARY,
+            "ENUM": TokenType.ENUM,
+            "ENUM8": TokenType.ENUM8,
+            "ENUM16": TokenType.ENUM16,
             "FINAL": TokenType.FINAL,
             "FIXEDSTRING": TokenType.FIXEDSTRING,
             "FLOAT32": TokenType.FLOAT,
@@ -295,6 +298,9 @@ class ClickHouse(Dialect):
             exp.DataType.Type.BIGINT: "Int64",
             exp.DataType.Type.DATETIME64: "DateTime64",
             exp.DataType.Type.DOUBLE: "Float64",
+            exp.DataType.Type.ENUM: "Enum",
+            exp.DataType.Type.ENUM8: "Enum8",
+            exp.DataType.Type.ENUM16: "Enum16",
             exp.DataType.Type.FIXEDSTRING: "FixedString",
             exp.DataType.Type.FLOAT: "Float32",
             exp.DataType.Type.INT: "Int32",
diff --git a/sqlglot/expressions.py b/sqlglot/expressions.py
index 3292e9fc..d4b4cd44 100644
--- a/sqlglot/expressions.py
+++ b/sqlglot/expressions.py
@@ -3405,6 +3405,8 @@ class DataType(Expression):
         DECIMAL = auto()
         DOUBLE = auto()
         ENUM = auto()
+        ENUM8 = auto()
+        ENUM16 = auto()
         FIXEDSTRING = auto()
         FLOAT = auto()
         GEOGRAPHY = auto()
diff --git a/sqlglot/parser.py b/sqlglot/parser.py
index 99bf631c..00f13b19 100644
--- a/sqlglot/parser.py
+++ b/sqlglot/parser.py
@@ -112,6 +112,8 @@ class Parser(metaclass=_Parser):
 
     ENUM_TYPE_TOKENS = {
         TokenType.ENUM,
+        TokenType.ENUM8,
+        TokenType.ENUM16,
     }
 
     TYPE_TOKENS = {
@@ -189,7 +191,7 @@ class Parser(metaclass=_Parser):
         TokenType.INET,
         TokenType.IPADDRESS,
         TokenType.IPPREFIX,
-        TokenType.ENUM,
+        *ENUM_TYPE_TOKENS,
         *NESTED_TYPE_TOKENS,
     }
 
@@ -3127,7 +3129,7 @@ class Parser(metaclass=_Parser):
                     lambda: self._parse_types(check_func=check_func, schema=schema)
                 )
             elif type_token in self.ENUM_TYPE_TOKENS:
-                expressions = self._parse_csv(self._parse_primary)
+                expressions = self._parse_csv(self._parse_equality)
             else:
                 expressions = self._parse_csv(self._parse_type_size)
 
diff --git a/sqlglot/tokens.py b/sqlglot/tokens.py
index 513d8aa9..0b427062 100644
--- a/sqlglot/tokens.py
+++ b/sqlglot/tokens.py
@@ -151,6 +151,8 @@ class TokenType(AutoName):
     IPADDRESS = auto()
     IPPREFIX = auto()
     ENUM = auto()
+    ENUM8 = auto()
+    ENUM16 = auto()
     FIXEDSTRING = auto()
     LOWCARDINALITY = auto()
 


Test patch:
diff --git a/tests/dialects/test_clickhouse.py b/tests/dialects/test_clickhouse.py
index 114a0782..4b1406df 100644
--- a/tests/dialects/test_clickhouse.py
+++ b/tests/dialects/test_clickhouse.py
@@ -10,6 +10,10 @@ class TestClickhouse(Validator):
         self.assertEqual(expr.sql(dialect="clickhouse"), "COUNT(x)")
         self.assertIsNone(expr._meta)
 
+        self.validate_identity("CAST(x AS Enum('hello' = 1, 'world' = 2))")
+        self.validate_identity("CAST(x AS Enum('hello', 'world'))")
+        self.validate_identity("CAST(x AS Enum('hello' = 1, 'world'))")
+        self.validate_identity("CAST(x AS Enum8('hello' = -123, 'world'))")
         self.validate_identity("CAST(x AS FixedString(1))")
         self.validate_identity("CAST(x AS LowCardinality(FixedString))")
         self.validate_identity("SELECT isNaN(1.0)")