2424
2525from __future__ import annotations
2626
27+ from sqlglot import exp
2728from sqlglot .dialects .mysql import MySQL
29+ from sqlglot .tokens import TokenType
2830
2931
3032class Pinot (MySQL ):
@@ -41,3 +43,55 @@ class Tokenizer(MySQL.Tokenizer):
4143 QUOTES = ["'" ] # Only single quotes for strings
4244 IDENTIFIERS = ['"' , "`" ] # Backticks and double quotes for identifiers
4345 STRING_ESCAPES = ["'" , "\\ " ] # Remove double quote from string escapes
46+ KEYWORDS = {
47+ ** MySQL .Tokenizer .KEYWORDS ,
48+ "STRING" : TokenType .TEXT ,
49+ "LONG" : TokenType .BIGINT ,
50+ "BYTES" : TokenType .VARBINARY ,
51+ }
52+
53+ class Generator (MySQL .Generator ):
54+ TYPE_MAPPING = {
55+ ** MySQL .Generator .TYPE_MAPPING ,
56+ exp .DataType .Type .TINYINT : "INT" ,
57+ exp .DataType .Type .SMALLINT : "INT" ,
58+ exp .DataType .Type .INT : "INT" ,
59+ exp .DataType .Type .BIGINT : "LONG" ,
60+ exp .DataType .Type .FLOAT : "FLOAT" ,
61+ exp .DataType .Type .DOUBLE : "DOUBLE" ,
62+ exp .DataType .Type .BOOLEAN : "BOOLEAN" ,
63+ exp .DataType .Type .TIMESTAMP : "TIMESTAMP" ,
64+ exp .DataType .Type .TIMESTAMPTZ : "TIMESTAMP" ,
65+ exp .DataType .Type .VARCHAR : "STRING" ,
66+ exp .DataType .Type .CHAR : "STRING" ,
67+ exp .DataType .Type .TEXT : "STRING" ,
68+ exp .DataType .Type .BINARY : "BYTES" ,
69+ exp .DataType .Type .VARBINARY : "BYTES" ,
70+ exp .DataType .Type .JSON : "JSON" ,
71+ }
72+
73+ # Override MySQL's CAST_MAPPING - don't convert integer or string types
74+ CAST_MAPPING = {
75+ exp .DataType .Type .LONGBLOB : exp .DataType .Type .VARBINARY ,
76+ exp .DataType .Type .MEDIUMBLOB : exp .DataType .Type .VARBINARY ,
77+ exp .DataType .Type .TINYBLOB : exp .DataType .Type .VARBINARY ,
78+ exp .DataType .Type .UBIGINT : "UNSIGNED" ,
79+ }
80+
81+ def datatype_sql (self , expression : exp .DataType ) -> str :
82+ # Don't use MySQL's VARCHAR size requirement logic
83+ # Just use TYPE_MAPPING for all types
84+ type_value = expression .this
85+ type_sql = (
86+ self .TYPE_MAPPING .get (type_value , type_value .value )
87+ if isinstance (type_value , exp .DataType .Type )
88+ else type_value
89+ )
90+
91+ interior = self .expressions (expression , flat = True )
92+ nested = f"({ interior } )" if interior else ""
93+
94+ if expression .this in self .UNSIGNED_TYPE_MAPPING :
95+ return f"{ type_sql } UNSIGNED{ nested } "
96+
97+ return f"{ type_sql } { nested } "
0 commit comments