From 36db14f4c6c28209371d563d76697df0172e337f Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 24 Jul 2023 10:03:48 +0200 Subject: Merging upstream version 17.7.0. Signed-off-by: Daniel Baumann --- docs/sqlglot/dialects/presto.html | 1612 +++++++++++++++++++------------------ 1 file changed, 813 insertions(+), 799 deletions(-) (limited to 'docs/sqlglot/dialects/presto.html') diff --git a/docs/sqlglot/dialects/presto.html b/docs/sqlglot/dialects/presto.html index 241ad47..37abe8a 100644 --- a/docs/sqlglot/dialects/presto.html +++ b/docs/sqlglot/dialects/presto.html @@ -282,380 +282,385 @@ 5from sqlglot import exp, generator, parser, tokens, transforms 6from sqlglot.dialects.dialect import ( 7 Dialect, - 8 date_trunc_to_time, - 9 format_time_lambda, - 10 if_sql, - 11 left_to_substring_sql, - 12 no_ilike_sql, - 13 no_pivot_sql, - 14 no_safe_divide_sql, - 15 regexp_extract_sql, - 16 rename_func, - 17 right_to_substring_sql, - 18 struct_extract_sql, - 19 timestamptrunc_sql, - 20 timestrtotime_sql, - 21) - 22from sqlglot.dialects.mysql import MySQL - 23from sqlglot.errors import UnsupportedError - 24from sqlglot.helper import apply_index_offset, seq_get - 25from sqlglot.tokens import TokenType - 26 + 8 binary_from_function, + 9 date_trunc_to_time, + 10 format_time_lambda, + 11 if_sql, + 12 left_to_substring_sql, + 13 no_ilike_sql, + 14 no_pivot_sql, + 15 no_safe_divide_sql, + 16 regexp_extract_sql, + 17 rename_func, + 18 right_to_substring_sql, + 19 struct_extract_sql, + 20 timestamptrunc_sql, + 21 timestrtotime_sql, + 22) + 23from sqlglot.dialects.mysql import MySQL + 24from sqlglot.errors import UnsupportedError + 25from sqlglot.helper import apply_index_offset, seq_get + 26from sqlglot.tokens import TokenType 27 - 28def _approx_distinct_sql(self: generator.Generator, expression: exp.ApproxDistinct) -> str: - 29 accuracy = expression.args.get("accuracy") - 30 accuracy = ", " + self.sql(accuracy) if accuracy else "" - 31 return f"APPROX_DISTINCT({self.sql(expression, 'this')}{accuracy})" - 32 + 28 + 29def _approx_distinct_sql(self: generator.Generator, expression: exp.ApproxDistinct) -> str: + 30 accuracy = expression.args.get("accuracy") + 31 accuracy = ", " + self.sql(accuracy) if accuracy else "" + 32 return f"APPROX_DISTINCT({self.sql(expression, 'this')}{accuracy})" 33 - 34def _datatype_sql(self: generator.Generator, expression: exp.DataType) -> str: - 35 sql = self.datatype_sql(expression) - 36 if expression.is_type("timestamptz"): - 37 sql = f"{sql} WITH TIME ZONE" - 38 return sql - 39 + 34 + 35def _datatype_sql(self: generator.Generator, expression: exp.DataType) -> str: + 36 sql = self.datatype_sql(expression) + 37 if expression.is_type("timestamptz"): + 38 sql = f"{sql} WITH TIME ZONE" + 39 return sql 40 - 41def _explode_to_unnest_sql(self: generator.Generator, expression: exp.Lateral) -> str: - 42 if isinstance(expression.this, (exp.Explode, exp.Posexplode)): - 43 return self.sql( - 44 exp.Join( - 45 this=exp.Unnest( - 46 expressions=[expression.this.this], - 47 alias=expression.args.get("alias"), - 48 ordinality=isinstance(expression.this, exp.Posexplode), - 49 ), - 50 kind="cross", - 51 ) - 52 ) - 53 return self.lateral_sql(expression) - 54 + 41 + 42def _explode_to_unnest_sql(self: generator.Generator, expression: exp.Lateral) -> str: + 43 if isinstance(expression.this, (exp.Explode, exp.Posexplode)): + 44 return self.sql( + 45 exp.Join( + 46 this=exp.Unnest( + 47 expressions=[expression.this.this], + 48 alias=expression.args.get("alias"), + 49 ordinality=isinstance(expression.this, exp.Posexplode), + 50 ), + 51 kind="cross", + 52 ) + 53 ) + 54 return self.lateral_sql(expression) 55 - 56def _initcap_sql(self: generator.Generator, expression: exp.Initcap) -> str: - 57 regex = r"(\w)(\w*)" - 58 return f"REGEXP_REPLACE({self.sql(expression, 'this')}, '{regex}', x -> UPPER(x[1]) || LOWER(x[2]))" - 59 + 56 + 57def _initcap_sql(self: generator.Generator, expression: exp.Initcap) -> str: + 58 regex = r"(\w)(\w*)" + 59 return f"REGEXP_REPLACE({self.sql(expression, 'this')}, '{regex}', x -> UPPER(x[1]) || LOWER(x[2]))" 60 - 61def _decode_sql(self: generator.Generator, expression: exp.Decode) -> str: - 62 _ensure_utf8(expression.args["charset"]) - 63 return self.func("FROM_UTF8", expression.this, expression.args.get("replace")) - 64 + 61 + 62def _decode_sql(self: generator.Generator, expression: exp.Decode) -> str: + 63 _ensure_utf8(expression.args["charset"]) + 64 return self.func("FROM_UTF8", expression.this, expression.args.get("replace")) 65 - 66def _encode_sql(self: generator.Generator, expression: exp.Encode) -> str: - 67 _ensure_utf8(expression.args["charset"]) - 68 return f"TO_UTF8({self.sql(expression, 'this')})" - 69 + 66 + 67def _encode_sql(self: generator.Generator, expression: exp.Encode) -> str: + 68 _ensure_utf8(expression.args["charset"]) + 69 return f"TO_UTF8({self.sql(expression, 'this')})" 70 - 71def _no_sort_array(self: generator.Generator, expression: exp.SortArray) -> str: - 72 if expression.args.get("asc") == exp.false(): - 73 comparator = "(a, b) -> CASE WHEN a < b THEN 1 WHEN a > b THEN -1 ELSE 0 END" - 74 else: - 75 comparator = None - 76 return self.func("ARRAY_SORT", expression.this, comparator) - 77 + 71 + 72def _no_sort_array(self: generator.Generator, expression: exp.SortArray) -> str: + 73 if expression.args.get("asc") == exp.false(): + 74 comparator = "(a, b) -> CASE WHEN a < b THEN 1 WHEN a > b THEN -1 ELSE 0 END" + 75 else: + 76 comparator = None + 77 return self.func("ARRAY_SORT", expression.this, comparator) 78 - 79def _schema_sql(self: generator.Generator, expression: exp.Schema) -> str: - 80 if isinstance(expression.parent, exp.Property): - 81 columns = ", ".join(f"'{c.name}'" for c in expression.expressions) - 82 return f"ARRAY[{columns}]" - 83 - 84 if expression.parent: - 85 for schema in expression.parent.find_all(exp.Schema): - 86 if isinstance(schema.parent, exp.Property): - 87 expression = expression.copy() - 88 expression.expressions.extend(schema.expressions) - 89 - 90 return self.schema_sql(expression) - 91 + 79 + 80def _schema_sql(self: generator.Generator, expression: exp.Schema) -> str: + 81 if isinstance(expression.parent, exp.Property): + 82 columns = ", ".join(f"'{c.name}'" for c in expression.expressions) + 83 return f"ARRAY[{columns}]" + 84 + 85 if expression.parent: + 86 for schema in expression.parent.find_all(exp.Schema): + 87 if isinstance(schema.parent, exp.Property): + 88 expression = expression.copy() + 89 expression.expressions.extend(schema.expressions) + 90 + 91 return self.schema_sql(expression) 92 - 93def _quantile_sql(self: generator.Generator, expression: exp.Quantile) -> str: - 94 self.unsupported("Presto does not support exact quantiles") - 95 return f"APPROX_PERCENTILE({self.sql(expression, 'this')}, {self.sql(expression, 'quantile')})" - 96 + 93 + 94def _quantile_sql(self: generator.Generator, expression: exp.Quantile) -> str: + 95 self.unsupported("Presto does not support exact quantiles") + 96 return f"APPROX_PERCENTILE({self.sql(expression, 'this')}, {self.sql(expression, 'quantile')})" 97 - 98def _str_to_time_sql( - 99 self: generator.Generator, expression: exp.StrToDate | exp.StrToTime | exp.TsOrDsToDate -100) -> str: -101 return f"DATE_PARSE({self.sql(expression, 'this')}, {self.format_time(expression)})" -102 + 98 + 99def _str_to_time_sql( +100 self: generator.Generator, expression: exp.StrToDate | exp.StrToTime | exp.TsOrDsToDate +101) -> str: +102 return f"DATE_PARSE({self.sql(expression, 'this')}, {self.format_time(expression)})" 103 -104def _ts_or_ds_to_date_sql(self: generator.Generator, expression: exp.TsOrDsToDate) -> str: -105 time_format = self.format_time(expression) -106 if time_format and time_format not in (Presto.TIME_FORMAT, Presto.DATE_FORMAT): -107 return exp.cast(_str_to_time_sql(self, expression), "DATE").sql(dialect="presto") -108 return exp.cast(exp.cast(expression.this, "TIMESTAMP"), "DATE").sql(dialect="presto") -109 +104 +105def _ts_or_ds_to_date_sql(self: generator.Generator, expression: exp.TsOrDsToDate) -> str: +106 time_format = self.format_time(expression) +107 if time_format and time_format not in (Presto.TIME_FORMAT, Presto.DATE_FORMAT): +108 return exp.cast(_str_to_time_sql(self, expression), "DATE").sql(dialect="presto") +109 return exp.cast(exp.cast(expression.this, "TIMESTAMP"), "DATE").sql(dialect="presto") 110 -111def _ts_or_ds_add_sql(self: generator.Generator, expression: exp.TsOrDsAdd) -> str: -112 this = expression.this -113 -114 if not isinstance(this, exp.CurrentDate): -115 this = exp.cast(exp.cast(expression.this, "TIMESTAMP"), "DATE") -116 -117 return self.func( -118 "DATE_ADD", -119 exp.Literal.string(expression.text("unit") or "day"), -120 expression.expression, -121 this, -122 ) -123 +111 +112def _ts_or_ds_add_sql(self: generator.Generator, expression: exp.TsOrDsAdd) -> str: +113 this = expression.this +114 +115 if not isinstance(this, exp.CurrentDate): +116 this = exp.cast(exp.cast(expression.this, "TIMESTAMP"), "DATE") +117 +118 return self.func( +119 "DATE_ADD", +120 exp.Literal.string(expression.text("unit") or "day"), +121 expression.expression, +122 this, +123 ) 124 -125def _ensure_utf8(charset: exp.Literal) -> None: -126 if charset.name.lower() != "utf-8": -127 raise UnsupportedError(f"Unsupported charset {charset}") -128 +125 +126def _ensure_utf8(charset: exp.Literal) -> None: +127 if charset.name.lower() != "utf-8": +128 raise UnsupportedError(f"Unsupported charset {charset}") 129 -130def _approx_percentile(args: t.List) -> exp.Expression: -131 if len(args) == 4: -132 return exp.ApproxQuantile( -133 this=seq_get(args, 0), -134 weight=seq_get(args, 1), -135 quantile=seq_get(args, 2), -136 accuracy=seq_get(args, 3), -137 ) -138 if len(args) == 3: -139 return exp.ApproxQuantile( -140 this=seq_get(args, 0), quantile=seq_get(args, 1), accuracy=seq_get(args, 2) -141 ) -142 return exp.ApproxQuantile.from_arg_list(args) -143 +130 +131def _approx_percentile(args: t.List) -> exp.Expression: +132 if len(args) == 4: +133 return exp.ApproxQuantile( +134 this=seq_get(args, 0), +135 weight=seq_get(args, 1), +136 quantile=seq_get(args, 2), +137 accuracy=seq_get(args, 3), +138 ) +139 if len(args) == 3: +140 return exp.ApproxQuantile( +141 this=seq_get(args, 0), quantile=seq_get(args, 1), accuracy=seq_get(args, 2) +142 ) +143 return exp.ApproxQuantile.from_arg_list(args) 144 -145def _from_unixtime(args: t.List) -> exp.Expression: -146 if len(args) == 3: -147 return exp.UnixToTime( -148 this=seq_get(args, 0), -149 hours=seq_get(args, 1), -150 minutes=seq_get(args, 2), -151 ) -152 if len(args) == 2: -153 return exp.UnixToTime(this=seq_get(args, 0), zone=seq_get(args, 1)) -154 -155 return exp.UnixToTime.from_arg_list(args) -156 +145 +146def _from_unixtime(args: t.List) -> exp.Expression: +147 if len(args) == 3: +148 return exp.UnixToTime( +149 this=seq_get(args, 0), +150 hours=seq_get(args, 1), +151 minutes=seq_get(args, 2), +152 ) +153 if len(args) == 2: +154 return exp.UnixToTime(this=seq_get(args, 0), zone=seq_get(args, 1)) +155 +156 return exp.UnixToTime.from_arg_list(args) 157 -158def _parse_element_at(args: t.List) -> exp.SafeBracket: -159 this = seq_get(args, 0) -160 index = seq_get(args, 1) -161 assert isinstance(this, exp.Expression) and isinstance(index, exp.Expression) -162 return exp.SafeBracket(this=this, expressions=apply_index_offset(this, [index], -1)) -163 +158 +159def _parse_element_at(args: t.List) -> exp.SafeBracket: +160 this = seq_get(args, 0) +161 index = seq_get(args, 1) +162 assert isinstance(this, exp.Expression) and isinstance(index, exp.Expression) +163 return exp.SafeBracket(this=this, expressions=apply_index_offset(this, [index], -1)) 164 -165def _unnest_sequence(expression: exp.Expression) -> exp.Expression: -166 if isinstance(expression, exp.Table): -167 if isinstance(expression.this, exp.GenerateSeries): -168 unnest = exp.Unnest(expressions=[expression.this]) -169 -170 if expression.alias: -171 return exp.alias_(unnest, alias="_u", table=[expression.alias], copy=False) -172 return unnest -173 return expression -174 +165 +166def _unnest_sequence(expression: exp.Expression) -> exp.Expression: +167 if isinstance(expression, exp.Table): +168 if isinstance(expression.this, exp.GenerateSeries): +169 unnest = exp.Unnest(expressions=[expression.this]) +170 +171 if expression.alias: +172 return exp.alias_(unnest, alias="_u", table=[expression.alias], copy=False) +173 return unnest +174 return expression 175 -176class Presto(Dialect): -177 INDEX_OFFSET = 1 -178 NULL_ORDERING = "nulls_are_last" -179 TIME_FORMAT = MySQL.TIME_FORMAT -180 TIME_MAPPING = MySQL.TIME_MAPPING -181 STRICT_STRING_CONCAT = True -182 -183 # https://github.com/trinodb/trino/issues/17 -184 # https://github.com/trinodb/trino/issues/12289 -185 # https://github.com/prestodb/presto/issues/2863 -186 RESOLVES_IDENTIFIERS_AS_UPPERCASE = None -187 -188 class Tokenizer(tokens.Tokenizer): -189 KEYWORDS = { -190 **tokens.Tokenizer.KEYWORDS, -191 "START": TokenType.BEGIN, -192 "MATCH_RECOGNIZE": TokenType.MATCH_RECOGNIZE, -193 "ROW": TokenType.STRUCT, -194 } -195 -196 class Parser(parser.Parser): -197 FUNCTIONS = { -198 **parser.Parser.FUNCTIONS, -199 "APPROX_DISTINCT": exp.ApproxDistinct.from_arg_list, -200 "APPROX_PERCENTILE": _approx_percentile, -201 "CARDINALITY": exp.ArraySize.from_arg_list, -202 "CONTAINS": exp.ArrayContains.from_arg_list, -203 "DATE_ADD": lambda args: exp.DateAdd( -204 this=seq_get(args, 2), expression=seq_get(args, 1), unit=seq_get(args, 0) -205 ), -206 "DATE_DIFF": lambda args: exp.DateDiff( -207 this=seq_get(args, 2), expression=seq_get(args, 1), unit=seq_get(args, 0) -208 ), -209 "DATE_FORMAT": format_time_lambda(exp.TimeToStr, "presto"), -210 "DATE_PARSE": format_time_lambda(exp.StrToTime, "presto"), -211 "DATE_TRUNC": date_trunc_to_time, -212 "ELEMENT_AT": _parse_element_at, -213 "FROM_HEX": exp.Unhex.from_arg_list, -214 "FROM_UNIXTIME": _from_unixtime, -215 "FROM_UTF8": lambda args: exp.Decode( -216 this=seq_get(args, 0), replace=seq_get(args, 1), charset=exp.Literal.string("utf-8") -217 ), -218 "NOW": exp.CurrentTimestamp.from_arg_list, -219 "REGEXP_EXTRACT": lambda args: exp.RegexpExtract( -220 this=seq_get(args, 0), expression=seq_get(args, 1), group=seq_get(args, 2) -221 ), -222 "SEQUENCE": exp.GenerateSeries.from_arg_list, -223 "STRPOS": lambda args: exp.StrPosition( -224 this=seq_get(args, 0), substr=seq_get(args, 1), instance=seq_get(args, 2) -225 ), -226 "TO_UNIXTIME": exp.TimeToUnix.from_arg_list, -227 "TO_HEX": exp.Hex.from_arg_list, -228 "TO_UTF8": lambda args: exp.Encode( -229 this=seq_get(args, 0), charset=exp.Literal.string("utf-8") +176 +177class Presto(Dialect): +178 INDEX_OFFSET = 1 +179 NULL_ORDERING = "nulls_are_last" +180 TIME_FORMAT = MySQL.TIME_FORMAT +181 TIME_MAPPING = MySQL.TIME_MAPPING +182 STRICT_STRING_CONCAT = True +183 +184 # https://github.com/trinodb/trino/issues/17 +185 # https://github.com/trinodb/trino/issues/12289 +186 # https://github.com/prestodb/presto/issues/2863 +187 RESOLVES_IDENTIFIERS_AS_UPPERCASE = None +188 +189 class Tokenizer(tokens.Tokenizer): +190 KEYWORDS = { +191 **tokens.Tokenizer.KEYWORDS, +192 "START": TokenType.BEGIN, +193 "MATCH_RECOGNIZE": TokenType.MATCH_RECOGNIZE, +194 "ROW": TokenType.STRUCT, +195 } +196 +197 class Parser(parser.Parser): +198 FUNCTIONS = { +199 **parser.Parser.FUNCTIONS, +200 "APPROX_DISTINCT": exp.ApproxDistinct.from_arg_list, +201 "APPROX_PERCENTILE": _approx_percentile, +202 "BITWISE_AND": binary_from_function(exp.BitwiseAnd), +203 "BITWISE_NOT": lambda args: exp.BitwiseNot(this=seq_get(args, 0)), +204 "BITWISE_OR": binary_from_function(exp.BitwiseOr), +205 "BITWISE_XOR": binary_from_function(exp.BitwiseXor), +206 "CARDINALITY": exp.ArraySize.from_arg_list, +207 "CONTAINS": exp.ArrayContains.from_arg_list, +208 "DATE_ADD": lambda args: exp.DateAdd( +209 this=seq_get(args, 2), expression=seq_get(args, 1), unit=seq_get(args, 0) +210 ), +211 "DATE_DIFF": lambda args: exp.DateDiff( +212 this=seq_get(args, 2), expression=seq_get(args, 1), unit=seq_get(args, 0) +213 ), +214 "DATE_FORMAT": format_time_lambda(exp.TimeToStr, "presto"), +215 "DATE_PARSE": format_time_lambda(exp.StrToTime, "presto"), +216 "DATE_TRUNC": date_trunc_to_time, +217 "ELEMENT_AT": _parse_element_at, +218 "FROM_HEX": exp.Unhex.from_arg_list, +219 "FROM_UNIXTIME": _from_unixtime, +220 "FROM_UTF8": lambda args: exp.Decode( +221 this=seq_get(args, 0), replace=seq_get(args, 1), charset=exp.Literal.string("utf-8") +222 ), +223 "NOW": exp.CurrentTimestamp.from_arg_list, +224 "REGEXP_EXTRACT": lambda args: exp.RegexpExtract( +225 this=seq_get(args, 0), expression=seq_get(args, 1), group=seq_get(args, 2) +226 ), +227 "SEQUENCE": exp.GenerateSeries.from_arg_list, +228 "STRPOS": lambda args: exp.StrPosition( +229 this=seq_get(args, 0), substr=seq_get(args, 1), instance=seq_get(args, 2) 230 ), -231 } -232 FUNCTION_PARSERS = parser.Parser.FUNCTION_PARSERS.copy() -233 FUNCTION_PARSERS.pop("TRIM") -234 -235 class Generator(generator.Generator): -236 INTERVAL_ALLOWS_PLURAL_FORM = False -237 JOIN_HINTS = False -238 TABLE_HINTS = False -239 QUERY_HINTS = False -240 IS_BOOL_ALLOWED = False -241 STRUCT_DELIMITER = ("(", ")") -242 -243 PROPERTIES_LOCATION = { -244 **generator.Generator.PROPERTIES_LOCATION, -245 exp.LocationProperty: exp.Properties.Location.UNSUPPORTED, -246 exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, -247 } -248 -249 TYPE_MAPPING = { -250 **generator.Generator.TYPE_MAPPING, -251 exp.DataType.Type.INT: "INTEGER", -252 exp.DataType.Type.FLOAT: "REAL", -253 exp.DataType.Type.BINARY: "VARBINARY", -254 exp.DataType.Type.TEXT: "VARCHAR", -255 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", -256 exp.DataType.Type.STRUCT: "ROW", -257 } -258 -259 TRANSFORMS = { -260 **generator.Generator.TRANSFORMS, -261 exp.ApproxDistinct: _approx_distinct_sql, -262 exp.ApproxQuantile: rename_func("APPROX_PERCENTILE"), -263 exp.Array: lambda self, e: f"ARRAY[{self.expressions(e, flat=True)}]", -264 exp.ArrayConcat: rename_func("CONCAT"), -265 exp.ArrayContains: rename_func("CONTAINS"), -266 exp.ArraySize: rename_func("CARDINALITY"), -267 exp.BitwiseAnd: lambda self, e: f"BITWISE_AND({self.sql(e, 'this')}, {self.sql(e, 'expression')})", -268 exp.BitwiseLeftShift: lambda self, e: f"BITWISE_ARITHMETIC_SHIFT_LEFT({self.sql(e, 'this')}, {self.sql(e, 'expression')})", -269 exp.BitwiseNot: lambda self, e: f"BITWISE_NOT({self.sql(e, 'this')})", -270 exp.BitwiseOr: lambda self, e: f"BITWISE_OR({self.sql(e, 'this')}, {self.sql(e, 'expression')})", -271 exp.BitwiseRightShift: lambda self, e: f"BITWISE_ARITHMETIC_SHIFT_RIGHT({self.sql(e, 'this')}, {self.sql(e, 'expression')})", -272 exp.BitwiseXor: lambda self, e: f"BITWISE_XOR({self.sql(e, 'this')}, {self.sql(e, 'expression')})", -273 exp.Cast: transforms.preprocess([transforms.epoch_cast_to_ts]), -274 exp.CurrentTimestamp: lambda *_: "CURRENT_TIMESTAMP", -275 exp.DataType: _datatype_sql, -276 exp.DateAdd: lambda self, e: self.func( -277 "DATE_ADD", exp.Literal.string(e.text("unit") or "day"), e.expression, e.this -278 ), -279 exp.DateDiff: lambda self, e: self.func( -280 "DATE_DIFF", exp.Literal.string(e.text("unit") or "day"), e.expression, e.this -281 ), -282 exp.DateStrToDate: lambda self, e: f"CAST(DATE_PARSE({self.sql(e, 'this')}, {Presto.DATE_FORMAT}) AS DATE)", -283 exp.DateToDi: lambda self, e: f"CAST(DATE_FORMAT({self.sql(e, 'this')}, {Presto.DATEINT_FORMAT}) AS INT)", -284 exp.Decode: _decode_sql, -285 exp.DiToDate: lambda self, e: f"CAST(DATE_PARSE(CAST({self.sql(e, 'this')} AS VARCHAR), {Presto.DATEINT_FORMAT}) AS DATE)", -286 exp.Encode: _encode_sql, -287 exp.FileFormatProperty: lambda self, e: f"FORMAT='{e.name.upper()}'", -288 exp.Group: transforms.preprocess([transforms.unalias_group]), -289 exp.Hex: rename_func("TO_HEX"), -290 exp.If: if_sql, -291 exp.ILike: no_ilike_sql, -292 exp.Initcap: _initcap_sql, -293 exp.Lateral: _explode_to_unnest_sql, -294 exp.Left: left_to_substring_sql, -295 exp.Levenshtein: rename_func("LEVENSHTEIN_DISTANCE"), -296 exp.LogicalAnd: rename_func("BOOL_AND"), -297 exp.LogicalOr: rename_func("BOOL_OR"), -298 exp.Pivot: no_pivot_sql, -299 exp.Quantile: _quantile_sql, -300 exp.RegexpExtract: regexp_extract_sql, -301 exp.Right: right_to_substring_sql, -302 exp.SafeBracket: lambda self, e: self.func( -303 "ELEMENT_AT", e.this, seq_get(apply_index_offset(e.this, e.expressions, 1), 0) -304 ), -305 exp.SafeDivide: no_safe_divide_sql, -306 exp.Schema: _schema_sql, -307 exp.Select: transforms.preprocess( -308 [ -309 transforms.eliminate_qualify, -310 transforms.eliminate_distinct_on, -311 transforms.explode_to_unnest, -312 ] -313 ), -314 exp.SortArray: _no_sort_array, -315 exp.StrPosition: rename_func("STRPOS"), -316 exp.StrToDate: lambda self, e: f"CAST({_str_to_time_sql(self, e)} AS DATE)", -317 exp.StrToTime: _str_to_time_sql, -318 exp.StrToUnix: lambda self, e: f"TO_UNIXTIME(DATE_PARSE({self.sql(e, 'this')}, {self.format_time(e)}))", -319 exp.StructExtract: struct_extract_sql, -320 exp.Table: transforms.preprocess([_unnest_sequence]), -321 exp.TimestampTrunc: timestamptrunc_sql, -322 exp.TimeStrToDate: timestrtotime_sql, -323 exp.TimeStrToTime: timestrtotime_sql, -324 exp.TimeStrToUnix: lambda self, e: f"TO_UNIXTIME(DATE_PARSE({self.sql(e, 'this')}, {Presto.TIME_FORMAT}))", -325 exp.TimeToStr: lambda self, e: f"DATE_FORMAT({self.sql(e, 'this')}, {self.format_time(e)})", -326 exp.TimeToUnix: rename_func("TO_UNIXTIME"), -327 exp.TryCast: transforms.preprocess([transforms.epoch_cast_to_ts]), -328 exp.TsOrDiToDi: lambda self, e: f"CAST(SUBSTR(REPLACE(CAST({self.sql(e, 'this')} AS VARCHAR), '-', ''), 1, 8) AS INT)", -329 exp.TsOrDsAdd: _ts_or_ds_add_sql, -330 exp.TsOrDsToDate: _ts_or_ds_to_date_sql, -331 exp.Unhex: rename_func("FROM_HEX"), -332 exp.UnixToStr: lambda self, e: f"DATE_FORMAT(FROM_UNIXTIME({self.sql(e, 'this')}), {self.format_time(e)})", -333 exp.UnixToTime: rename_func("FROM_UNIXTIME"), -334 exp.UnixToTimeStr: lambda self, e: f"CAST(FROM_UNIXTIME({self.sql(e, 'this')}) AS VARCHAR)", -335 exp.VariancePop: rename_func("VAR_POP"), -336 exp.With: transforms.preprocess([transforms.add_recursive_cte_column_names]), -337 exp.WithinGroup: transforms.preprocess( -338 [transforms.remove_within_group_for_percentiles] -339 ), -340 } -341 -342 def interval_sql(self, expression: exp.Interval) -> str: -343 unit = self.sql(expression, "unit") -344 if expression.this and unit.lower().startswith("week"): -345 return f"({expression.this.name} * INTERVAL '7' day)" -346 return super().interval_sql(expression) -347 -348 def transaction_sql(self, expression: exp.Transaction) -> str: -349 modes = expression.args.get("modes") -350 modes = f" {', '.join(modes)}" if modes else "" -351 return f"START TRANSACTION{modes}" +231 "TO_UNIXTIME": exp.TimeToUnix.from_arg_list, +232 "TO_HEX": exp.Hex.from_arg_list, +233 "TO_UTF8": lambda args: exp.Encode( +234 this=seq_get(args, 0), charset=exp.Literal.string("utf-8") +235 ), +236 } +237 FUNCTION_PARSERS = parser.Parser.FUNCTION_PARSERS.copy() +238 FUNCTION_PARSERS.pop("TRIM") +239 +240 class Generator(generator.Generator): +241 INTERVAL_ALLOWS_PLURAL_FORM = False +242 JOIN_HINTS = False +243 TABLE_HINTS = False +244 QUERY_HINTS = False +245 IS_BOOL_ALLOWED = False +246 STRUCT_DELIMITER = ("(", ")") +247 +248 PROPERTIES_LOCATION = { +249 **generator.Generator.PROPERTIES_LOCATION, +250 exp.LocationProperty: exp.Properties.Location.UNSUPPORTED, +251 exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, +252 } +253 +254 TYPE_MAPPING = { +255 **generator.Generator.TYPE_MAPPING, +256 exp.DataType.Type.INT: "INTEGER", +257 exp.DataType.Type.FLOAT: "REAL", +258 exp.DataType.Type.BINARY: "VARBINARY", +259 exp.DataType.Type.TEXT: "VARCHAR", +260 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", +261 exp.DataType.Type.STRUCT: "ROW", +262 } +263 +264 TRANSFORMS = { +265 **generator.Generator.TRANSFORMS, +266 exp.ApproxDistinct: _approx_distinct_sql, +267 exp.ApproxQuantile: rename_func("APPROX_PERCENTILE"), +268 exp.Array: lambda self, e: f"ARRAY[{self.expressions(e, flat=True)}]", +269 exp.ArrayConcat: rename_func("CONCAT"), +270 exp.ArrayContains: rename_func("CONTAINS"), +271 exp.ArraySize: rename_func("CARDINALITY"), +272 exp.BitwiseAnd: lambda self, e: f"BITWISE_AND({self.sql(e, 'this')}, {self.sql(e, 'expression')})", +273 exp.BitwiseLeftShift: lambda self, e: f"BITWISE_ARITHMETIC_SHIFT_LEFT({self.sql(e, 'this')}, {self.sql(e, 'expression')})", +274 exp.BitwiseNot: lambda self, e: f"BITWISE_NOT({self.sql(e, 'this')})", +275 exp.BitwiseOr: lambda self, e: f"BITWISE_OR({self.sql(e, 'this')}, {self.sql(e, 'expression')})", +276 exp.BitwiseRightShift: lambda self, e: f"BITWISE_ARITHMETIC_SHIFT_RIGHT({self.sql(e, 'this')}, {self.sql(e, 'expression')})", +277 exp.BitwiseXor: lambda self, e: f"BITWISE_XOR({self.sql(e, 'this')}, {self.sql(e, 'expression')})", +278 exp.Cast: transforms.preprocess([transforms.epoch_cast_to_ts]), +279 exp.CurrentTimestamp: lambda *_: "CURRENT_TIMESTAMP", +280 exp.DataType: _datatype_sql, +281 exp.DateAdd: lambda self, e: self.func( +282 "DATE_ADD", exp.Literal.string(e.text("unit") or "day"), e.expression, e.this +283 ), +284 exp.DateDiff: lambda self, e: self.func( +285 "DATE_DIFF", exp.Literal.string(e.text("unit") or "day"), e.expression, e.this +286 ), +287 exp.DateStrToDate: lambda self, e: f"CAST(DATE_PARSE({self.sql(e, 'this')}, {Presto.DATE_FORMAT}) AS DATE)", +288 exp.DateToDi: lambda self, e: f"CAST(DATE_FORMAT({self.sql(e, 'this')}, {Presto.DATEINT_FORMAT}) AS INT)", +289 exp.Decode: _decode_sql, +290 exp.DiToDate: lambda self, e: f"CAST(DATE_PARSE(CAST({self.sql(e, 'this')} AS VARCHAR), {Presto.DATEINT_FORMAT}) AS DATE)", +291 exp.Encode: _encode_sql, +292 exp.FileFormatProperty: lambda self, e: f"FORMAT='{e.name.upper()}'", +293 exp.Group: transforms.preprocess([transforms.unalias_group]), +294 exp.Hex: rename_func("TO_HEX"), +295 exp.If: if_sql, +296 exp.ILike: no_ilike_sql, +297 exp.Initcap: _initcap_sql, +298 exp.Lateral: _explode_to_unnest_sql, +299 exp.Left: left_to_substring_sql, +300 exp.Levenshtein: rename_func("LEVENSHTEIN_DISTANCE"), +301 exp.LogicalAnd: rename_func("BOOL_AND"), +302 exp.LogicalOr: rename_func("BOOL_OR"), +303 exp.Pivot: no_pivot_sql, +304 exp.Quantile: _quantile_sql, +305 exp.RegexpExtract: regexp_extract_sql, +306 exp.Right: right_to_substring_sql, +307 exp.SafeBracket: lambda self, e: self.func( +308 "ELEMENT_AT", e.this, seq_get(apply_index_offset(e.this, e.expressions, 1), 0) +309 ), +310 exp.SafeDivide: no_safe_divide_sql, +311 exp.Schema: _schema_sql, +312 exp.Select: transforms.preprocess( +313 [ +314 transforms.eliminate_qualify, +315 transforms.eliminate_distinct_on, +316 transforms.explode_to_unnest, +317 ] +318 ), +319 exp.SortArray: _no_sort_array, +320 exp.StrPosition: rename_func("STRPOS"), +321 exp.StrToDate: lambda self, e: f"CAST({_str_to_time_sql(self, e)} AS DATE)", +322 exp.StrToTime: _str_to_time_sql, +323 exp.StrToUnix: lambda self, e: f"TO_UNIXTIME(DATE_PARSE({self.sql(e, 'this')}, {self.format_time(e)}))", +324 exp.StructExtract: struct_extract_sql, +325 exp.Table: transforms.preprocess([_unnest_sequence]), +326 exp.TimestampTrunc: timestamptrunc_sql, +327 exp.TimeStrToDate: timestrtotime_sql, +328 exp.TimeStrToTime: timestrtotime_sql, +329 exp.TimeStrToUnix: lambda self, e: f"TO_UNIXTIME(DATE_PARSE({self.sql(e, 'this')}, {Presto.TIME_FORMAT}))", +330 exp.TimeToStr: lambda self, e: f"DATE_FORMAT({self.sql(e, 'this')}, {self.format_time(e)})", +331 exp.TimeToUnix: rename_func("TO_UNIXTIME"), +332 exp.TryCast: transforms.preprocess([transforms.epoch_cast_to_ts]), +333 exp.TsOrDiToDi: lambda self, e: f"CAST(SUBSTR(REPLACE(CAST({self.sql(e, 'this')} AS VARCHAR), '-', ''), 1, 8) AS INT)", +334 exp.TsOrDsAdd: _ts_or_ds_add_sql, +335 exp.TsOrDsToDate: _ts_or_ds_to_date_sql, +336 exp.Unhex: rename_func("FROM_HEX"), +337 exp.UnixToStr: lambda self, e: f"DATE_FORMAT(FROM_UNIXTIME({self.sql(e, 'this')}), {self.format_time(e)})", +338 exp.UnixToTime: rename_func("FROM_UNIXTIME"), +339 exp.UnixToTimeStr: lambda self, e: f"CAST(FROM_UNIXTIME({self.sql(e, 'this')}) AS VARCHAR)", +340 exp.VariancePop: rename_func("VAR_POP"), +341 exp.With: transforms.preprocess([transforms.add_recursive_cte_column_names]), +342 exp.WithinGroup: transforms.preprocess( +343 [transforms.remove_within_group_for_percentiles] +344 ), +345 } +346 +347 def interval_sql(self, expression: exp.Interval) -> str: +348 unit = self.sql(expression, "unit") +349 if expression.this and unit.lower().startswith("week"): +350 return f"({expression.this.name} * INTERVAL '7' day)" +351 return super().interval_sql(expression) 352 -353 def generateseries_sql(self, expression: exp.GenerateSeries) -> str: -354 start = expression.args["start"] -355 end = expression.args["end"] -356 step = expression.args.get("step") +353 def transaction_sql(self, expression: exp.Transaction) -> str: +354 modes = expression.args.get("modes") +355 modes = f" {', '.join(modes)}" if modes else "" +356 return f"START TRANSACTION{modes}" 357 -358 if isinstance(start, exp.Cast): -359 target_type = start.to -360 elif isinstance(end, exp.Cast): -361 target_type = end.to -362 else: -363 target_type = None -364 -365 if target_type and target_type.is_type("timestamp"): -366 to = target_type.copy() -367 -368 if target_type is start.to: -369 end = exp.cast(end, to) -370 else: -371 start = exp.cast(start, to) +358 def generateseries_sql(self, expression: exp.GenerateSeries) -> str: +359 start = expression.args["start"] +360 end = expression.args["end"] +361 step = expression.args.get("step") +362 +363 if isinstance(start, exp.Cast): +364 target_type = start.to +365 elif isinstance(end, exp.Cast): +366 target_type = end.to +367 else: +368 target_type = None +369 +370 if target_type and target_type.is_type("timestamp"): +371 to = target_type.copy() 372 -373 return self.func("SEQUENCE", start, end, step) -374 -375 def offset_limit_modifiers( -376 self, expression: exp.Expression, fetch: bool, limit: t.Optional[exp.Fetch | exp.Limit] -377 ) -> t.List[str]: -378 return [ -379 self.sql(expression, "offset"), -380 self.sql(limit), -381 ] +373 if target_type is start.to: +374 end = exp.cast(end, to) +375 else: +376 start = exp.cast(start, to) +377 +378 return self.func("SEQUENCE", start, end, step) +379 +380 def offset_limit_modifiers( +381 self, expression: exp.Expression, fetch: bool, limit: t.Optional[exp.Fetch | exp.Limit] +382 ) -> t.List[str]: +383 return [ +384 self.sql(expression, "offset"), +385 self.sql(limit), +386 ] @@ -671,212 +676,216 @@ -
177class Presto(Dialect):
-178    INDEX_OFFSET = 1
-179    NULL_ORDERING = "nulls_are_last"
-180    TIME_FORMAT = MySQL.TIME_FORMAT
-181    TIME_MAPPING = MySQL.TIME_MAPPING
-182    STRICT_STRING_CONCAT = True
-183
-184    # https://github.com/trinodb/trino/issues/17
-185    # https://github.com/trinodb/trino/issues/12289
-186    # https://github.com/prestodb/presto/issues/2863
-187    RESOLVES_IDENTIFIERS_AS_UPPERCASE = None
-188
-189    class Tokenizer(tokens.Tokenizer):
-190        KEYWORDS = {
-191            **tokens.Tokenizer.KEYWORDS,
-192            "START": TokenType.BEGIN,
-193            "MATCH_RECOGNIZE": TokenType.MATCH_RECOGNIZE,
-194            "ROW": TokenType.STRUCT,
-195        }
-196
-197    class Parser(parser.Parser):
-198        FUNCTIONS = {
-199            **parser.Parser.FUNCTIONS,
-200            "APPROX_DISTINCT": exp.ApproxDistinct.from_arg_list,
-201            "APPROX_PERCENTILE": _approx_percentile,
-202            "CARDINALITY": exp.ArraySize.from_arg_list,
-203            "CONTAINS": exp.ArrayContains.from_arg_list,
-204            "DATE_ADD": lambda args: exp.DateAdd(
-205                this=seq_get(args, 2), expression=seq_get(args, 1), unit=seq_get(args, 0)
-206            ),
-207            "DATE_DIFF": lambda args: exp.DateDiff(
-208                this=seq_get(args, 2), expression=seq_get(args, 1), unit=seq_get(args, 0)
-209            ),
-210            "DATE_FORMAT": format_time_lambda(exp.TimeToStr, "presto"),
-211            "DATE_PARSE": format_time_lambda(exp.StrToTime, "presto"),
-212            "DATE_TRUNC": date_trunc_to_time,
-213            "ELEMENT_AT": _parse_element_at,
-214            "FROM_HEX": exp.Unhex.from_arg_list,
-215            "FROM_UNIXTIME": _from_unixtime,
-216            "FROM_UTF8": lambda args: exp.Decode(
-217                this=seq_get(args, 0), replace=seq_get(args, 1), charset=exp.Literal.string("utf-8")
-218            ),
-219            "NOW": exp.CurrentTimestamp.from_arg_list,
-220            "REGEXP_EXTRACT": lambda args: exp.RegexpExtract(
-221                this=seq_get(args, 0), expression=seq_get(args, 1), group=seq_get(args, 2)
-222            ),
-223            "SEQUENCE": exp.GenerateSeries.from_arg_list,
-224            "STRPOS": lambda args: exp.StrPosition(
-225                this=seq_get(args, 0), substr=seq_get(args, 1), instance=seq_get(args, 2)
-226            ),
-227            "TO_UNIXTIME": exp.TimeToUnix.from_arg_list,
-228            "TO_HEX": exp.Hex.from_arg_list,
-229            "TO_UTF8": lambda args: exp.Encode(
-230                this=seq_get(args, 0), charset=exp.Literal.string("utf-8")
+            
178class Presto(Dialect):
+179    INDEX_OFFSET = 1
+180    NULL_ORDERING = "nulls_are_last"
+181    TIME_FORMAT = MySQL.TIME_FORMAT
+182    TIME_MAPPING = MySQL.TIME_MAPPING
+183    STRICT_STRING_CONCAT = True
+184
+185    # https://github.com/trinodb/trino/issues/17
+186    # https://github.com/trinodb/trino/issues/12289
+187    # https://github.com/prestodb/presto/issues/2863
+188    RESOLVES_IDENTIFIERS_AS_UPPERCASE = None
+189
+190    class Tokenizer(tokens.Tokenizer):
+191        KEYWORDS = {
+192            **tokens.Tokenizer.KEYWORDS,
+193            "START": TokenType.BEGIN,
+194            "MATCH_RECOGNIZE": TokenType.MATCH_RECOGNIZE,
+195            "ROW": TokenType.STRUCT,
+196        }
+197
+198    class Parser(parser.Parser):
+199        FUNCTIONS = {
+200            **parser.Parser.FUNCTIONS,
+201            "APPROX_DISTINCT": exp.ApproxDistinct.from_arg_list,
+202            "APPROX_PERCENTILE": _approx_percentile,
+203            "BITWISE_AND": binary_from_function(exp.BitwiseAnd),
+204            "BITWISE_NOT": lambda args: exp.BitwiseNot(this=seq_get(args, 0)),
+205            "BITWISE_OR": binary_from_function(exp.BitwiseOr),
+206            "BITWISE_XOR": binary_from_function(exp.BitwiseXor),
+207            "CARDINALITY": exp.ArraySize.from_arg_list,
+208            "CONTAINS": exp.ArrayContains.from_arg_list,
+209            "DATE_ADD": lambda args: exp.DateAdd(
+210                this=seq_get(args, 2), expression=seq_get(args, 1), unit=seq_get(args, 0)
+211            ),
+212            "DATE_DIFF": lambda args: exp.DateDiff(
+213                this=seq_get(args, 2), expression=seq_get(args, 1), unit=seq_get(args, 0)
+214            ),
+215            "DATE_FORMAT": format_time_lambda(exp.TimeToStr, "presto"),
+216            "DATE_PARSE": format_time_lambda(exp.StrToTime, "presto"),
+217            "DATE_TRUNC": date_trunc_to_time,
+218            "ELEMENT_AT": _parse_element_at,
+219            "FROM_HEX": exp.Unhex.from_arg_list,
+220            "FROM_UNIXTIME": _from_unixtime,
+221            "FROM_UTF8": lambda args: exp.Decode(
+222                this=seq_get(args, 0), replace=seq_get(args, 1), charset=exp.Literal.string("utf-8")
+223            ),
+224            "NOW": exp.CurrentTimestamp.from_arg_list,
+225            "REGEXP_EXTRACT": lambda args: exp.RegexpExtract(
+226                this=seq_get(args, 0), expression=seq_get(args, 1), group=seq_get(args, 2)
+227            ),
+228            "SEQUENCE": exp.GenerateSeries.from_arg_list,
+229            "STRPOS": lambda args: exp.StrPosition(
+230                this=seq_get(args, 0), substr=seq_get(args, 1), instance=seq_get(args, 2)
 231            ),
-232        }
-233        FUNCTION_PARSERS = parser.Parser.FUNCTION_PARSERS.copy()
-234        FUNCTION_PARSERS.pop("TRIM")
-235
-236    class Generator(generator.Generator):
-237        INTERVAL_ALLOWS_PLURAL_FORM = False
-238        JOIN_HINTS = False
-239        TABLE_HINTS = False
-240        QUERY_HINTS = False
-241        IS_BOOL_ALLOWED = False
-242        STRUCT_DELIMITER = ("(", ")")
-243
-244        PROPERTIES_LOCATION = {
-245            **generator.Generator.PROPERTIES_LOCATION,
-246            exp.LocationProperty: exp.Properties.Location.UNSUPPORTED,
-247            exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED,
-248        }
-249
-250        TYPE_MAPPING = {
-251            **generator.Generator.TYPE_MAPPING,
-252            exp.DataType.Type.INT: "INTEGER",
-253            exp.DataType.Type.FLOAT: "REAL",
-254            exp.DataType.Type.BINARY: "VARBINARY",
-255            exp.DataType.Type.TEXT: "VARCHAR",
-256            exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP",
-257            exp.DataType.Type.STRUCT: "ROW",
-258        }
-259
-260        TRANSFORMS = {
-261            **generator.Generator.TRANSFORMS,
-262            exp.ApproxDistinct: _approx_distinct_sql,
-263            exp.ApproxQuantile: rename_func("APPROX_PERCENTILE"),
-264            exp.Array: lambda self, e: f"ARRAY[{self.expressions(e, flat=True)}]",
-265            exp.ArrayConcat: rename_func("CONCAT"),
-266            exp.ArrayContains: rename_func("CONTAINS"),
-267            exp.ArraySize: rename_func("CARDINALITY"),
-268            exp.BitwiseAnd: lambda self, e: f"BITWISE_AND({self.sql(e, 'this')}, {self.sql(e, 'expression')})",
-269            exp.BitwiseLeftShift: lambda self, e: f"BITWISE_ARITHMETIC_SHIFT_LEFT({self.sql(e, 'this')}, {self.sql(e, 'expression')})",
-270            exp.BitwiseNot: lambda self, e: f"BITWISE_NOT({self.sql(e, 'this')})",
-271            exp.BitwiseOr: lambda self, e: f"BITWISE_OR({self.sql(e, 'this')}, {self.sql(e, 'expression')})",
-272            exp.BitwiseRightShift: lambda self, e: f"BITWISE_ARITHMETIC_SHIFT_RIGHT({self.sql(e, 'this')}, {self.sql(e, 'expression')})",
-273            exp.BitwiseXor: lambda self, e: f"BITWISE_XOR({self.sql(e, 'this')}, {self.sql(e, 'expression')})",
-274            exp.Cast: transforms.preprocess([transforms.epoch_cast_to_ts]),
-275            exp.CurrentTimestamp: lambda *_: "CURRENT_TIMESTAMP",
-276            exp.DataType: _datatype_sql,
-277            exp.DateAdd: lambda self, e: self.func(
-278                "DATE_ADD", exp.Literal.string(e.text("unit") or "day"), e.expression, e.this
-279            ),
-280            exp.DateDiff: lambda self, e: self.func(
-281                "DATE_DIFF", exp.Literal.string(e.text("unit") or "day"), e.expression, e.this
-282            ),
-283            exp.DateStrToDate: lambda self, e: f"CAST(DATE_PARSE({self.sql(e, 'this')}, {Presto.DATE_FORMAT}) AS DATE)",
-284            exp.DateToDi: lambda self, e: f"CAST(DATE_FORMAT({self.sql(e, 'this')}, {Presto.DATEINT_FORMAT}) AS INT)",
-285            exp.Decode: _decode_sql,
-286            exp.DiToDate: lambda self, e: f"CAST(DATE_PARSE(CAST({self.sql(e, 'this')} AS VARCHAR), {Presto.DATEINT_FORMAT}) AS DATE)",
-287            exp.Encode: _encode_sql,
-288            exp.FileFormatProperty: lambda self, e: f"FORMAT='{e.name.upper()}'",
-289            exp.Group: transforms.preprocess([transforms.unalias_group]),
-290            exp.Hex: rename_func("TO_HEX"),
-291            exp.If: if_sql,
-292            exp.ILike: no_ilike_sql,
-293            exp.Initcap: _initcap_sql,
-294            exp.Lateral: _explode_to_unnest_sql,
-295            exp.Left: left_to_substring_sql,
-296            exp.Levenshtein: rename_func("LEVENSHTEIN_DISTANCE"),
-297            exp.LogicalAnd: rename_func("BOOL_AND"),
-298            exp.LogicalOr: rename_func("BOOL_OR"),
-299            exp.Pivot: no_pivot_sql,
-300            exp.Quantile: _quantile_sql,
-301            exp.RegexpExtract: regexp_extract_sql,
-302            exp.Right: right_to_substring_sql,
-303            exp.SafeBracket: lambda self, e: self.func(
-304                "ELEMENT_AT", e.this, seq_get(apply_index_offset(e.this, e.expressions, 1), 0)
-305            ),
-306            exp.SafeDivide: no_safe_divide_sql,
-307            exp.Schema: _schema_sql,
-308            exp.Select: transforms.preprocess(
-309                [
-310                    transforms.eliminate_qualify,
-311                    transforms.eliminate_distinct_on,
-312                    transforms.explode_to_unnest,
-313                ]
-314            ),
-315            exp.SortArray: _no_sort_array,
-316            exp.StrPosition: rename_func("STRPOS"),
-317            exp.StrToDate: lambda self, e: f"CAST({_str_to_time_sql(self, e)} AS DATE)",
-318            exp.StrToTime: _str_to_time_sql,
-319            exp.StrToUnix: lambda self, e: f"TO_UNIXTIME(DATE_PARSE({self.sql(e, 'this')}, {self.format_time(e)}))",
-320            exp.StructExtract: struct_extract_sql,
-321            exp.Table: transforms.preprocess([_unnest_sequence]),
-322            exp.TimestampTrunc: timestamptrunc_sql,
-323            exp.TimeStrToDate: timestrtotime_sql,
-324            exp.TimeStrToTime: timestrtotime_sql,
-325            exp.TimeStrToUnix: lambda self, e: f"TO_UNIXTIME(DATE_PARSE({self.sql(e, 'this')}, {Presto.TIME_FORMAT}))",
-326            exp.TimeToStr: lambda self, e: f"DATE_FORMAT({self.sql(e, 'this')}, {self.format_time(e)})",
-327            exp.TimeToUnix: rename_func("TO_UNIXTIME"),
-328            exp.TryCast: transforms.preprocess([transforms.epoch_cast_to_ts]),
-329            exp.TsOrDiToDi: lambda self, e: f"CAST(SUBSTR(REPLACE(CAST({self.sql(e, 'this')} AS VARCHAR), '-', ''), 1, 8) AS INT)",
-330            exp.TsOrDsAdd: _ts_or_ds_add_sql,
-331            exp.TsOrDsToDate: _ts_or_ds_to_date_sql,
-332            exp.Unhex: rename_func("FROM_HEX"),
-333            exp.UnixToStr: lambda self, e: f"DATE_FORMAT(FROM_UNIXTIME({self.sql(e, 'this')}), {self.format_time(e)})",
-334            exp.UnixToTime: rename_func("FROM_UNIXTIME"),
-335            exp.UnixToTimeStr: lambda self, e: f"CAST(FROM_UNIXTIME({self.sql(e, 'this')}) AS VARCHAR)",
-336            exp.VariancePop: rename_func("VAR_POP"),
-337            exp.With: transforms.preprocess([transforms.add_recursive_cte_column_names]),
-338            exp.WithinGroup: transforms.preprocess(
-339                [transforms.remove_within_group_for_percentiles]
-340            ),
-341        }
-342
-343        def interval_sql(self, expression: exp.Interval) -> str:
-344            unit = self.sql(expression, "unit")
-345            if expression.this and unit.lower().startswith("week"):
-346                return f"({expression.this.name} * INTERVAL '7' day)"
-347            return super().interval_sql(expression)
-348
-349        def transaction_sql(self, expression: exp.Transaction) -> str:
-350            modes = expression.args.get("modes")
-351            modes = f" {', '.join(modes)}" if modes else ""
-352            return f"START TRANSACTION{modes}"
+232            "TO_UNIXTIME": exp.TimeToUnix.from_arg_list,
+233            "TO_HEX": exp.Hex.from_arg_list,
+234            "TO_UTF8": lambda args: exp.Encode(
+235                this=seq_get(args, 0), charset=exp.Literal.string("utf-8")
+236            ),
+237        }
+238        FUNCTION_PARSERS = parser.Parser.FUNCTION_PARSERS.copy()
+239        FUNCTION_PARSERS.pop("TRIM")
+240
+241    class Generator(generator.Generator):
+242        INTERVAL_ALLOWS_PLURAL_FORM = False
+243        JOIN_HINTS = False
+244        TABLE_HINTS = False
+245        QUERY_HINTS = False
+246        IS_BOOL_ALLOWED = False
+247        STRUCT_DELIMITER = ("(", ")")
+248
+249        PROPERTIES_LOCATION = {
+250            **generator.Generator.PROPERTIES_LOCATION,
+251            exp.LocationProperty: exp.Properties.Location.UNSUPPORTED,
+252            exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED,
+253        }
+254
+255        TYPE_MAPPING = {
+256            **generator.Generator.TYPE_MAPPING,
+257            exp.DataType.Type.INT: "INTEGER",
+258            exp.DataType.Type.FLOAT: "REAL",
+259            exp.DataType.Type.BINARY: "VARBINARY",
+260            exp.DataType.Type.TEXT: "VARCHAR",
+261            exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP",
+262            exp.DataType.Type.STRUCT: "ROW",
+263        }
+264
+265        TRANSFORMS = {
+266            **generator.Generator.TRANSFORMS,
+267            exp.ApproxDistinct: _approx_distinct_sql,
+268            exp.ApproxQuantile: rename_func("APPROX_PERCENTILE"),
+269            exp.Array: lambda self, e: f"ARRAY[{self.expressions(e, flat=True)}]",
+270            exp.ArrayConcat: rename_func("CONCAT"),
+271            exp.ArrayContains: rename_func("CONTAINS"),
+272            exp.ArraySize: rename_func("CARDINALITY"),
+273            exp.BitwiseAnd: lambda self, e: f"BITWISE_AND({self.sql(e, 'this')}, {self.sql(e, 'expression')})",
+274            exp.BitwiseLeftShift: lambda self, e: f"BITWISE_ARITHMETIC_SHIFT_LEFT({self.sql(e, 'this')}, {self.sql(e, 'expression')})",
+275            exp.BitwiseNot: lambda self, e: f"BITWISE_NOT({self.sql(e, 'this')})",
+276            exp.BitwiseOr: lambda self, e: f"BITWISE_OR({self.sql(e, 'this')}, {self.sql(e, 'expression')})",
+277            exp.BitwiseRightShift: lambda self, e: f"BITWISE_ARITHMETIC_SHIFT_RIGHT({self.sql(e, 'this')}, {self.sql(e, 'expression')})",
+278            exp.BitwiseXor: lambda self, e: f"BITWISE_XOR({self.sql(e, 'this')}, {self.sql(e, 'expression')})",
+279            exp.Cast: transforms.preprocess([transforms.epoch_cast_to_ts]),
+280            exp.CurrentTimestamp: lambda *_: "CURRENT_TIMESTAMP",
+281            exp.DataType: _datatype_sql,
+282            exp.DateAdd: lambda self, e: self.func(
+283                "DATE_ADD", exp.Literal.string(e.text("unit") or "day"), e.expression, e.this
+284            ),
+285            exp.DateDiff: lambda self, e: self.func(
+286                "DATE_DIFF", exp.Literal.string(e.text("unit") or "day"), e.expression, e.this
+287            ),
+288            exp.DateStrToDate: lambda self, e: f"CAST(DATE_PARSE({self.sql(e, 'this')}, {Presto.DATE_FORMAT}) AS DATE)",
+289            exp.DateToDi: lambda self, e: f"CAST(DATE_FORMAT({self.sql(e, 'this')}, {Presto.DATEINT_FORMAT}) AS INT)",
+290            exp.Decode: _decode_sql,
+291            exp.DiToDate: lambda self, e: f"CAST(DATE_PARSE(CAST({self.sql(e, 'this')} AS VARCHAR), {Presto.DATEINT_FORMAT}) AS DATE)",
+292            exp.Encode: _encode_sql,
+293            exp.FileFormatProperty: lambda self, e: f"FORMAT='{e.name.upper()}'",
+294            exp.Group: transforms.preprocess([transforms.unalias_group]),
+295            exp.Hex: rename_func("TO_HEX"),
+296            exp.If: if_sql,
+297            exp.ILike: no_ilike_sql,
+298            exp.Initcap: _initcap_sql,
+299            exp.Lateral: _explode_to_unnest_sql,
+300            exp.Left: left_to_substring_sql,
+301            exp.Levenshtein: rename_func("LEVENSHTEIN_DISTANCE"),
+302            exp.LogicalAnd: rename_func("BOOL_AND"),
+303            exp.LogicalOr: rename_func("BOOL_OR"),
+304            exp.Pivot: no_pivot_sql,
+305            exp.Quantile: _quantile_sql,
+306            exp.RegexpExtract: regexp_extract_sql,
+307            exp.Right: right_to_substring_sql,
+308            exp.SafeBracket: lambda self, e: self.func(
+309                "ELEMENT_AT", e.this, seq_get(apply_index_offset(e.this, e.expressions, 1), 0)
+310            ),
+311            exp.SafeDivide: no_safe_divide_sql,
+312            exp.Schema: _schema_sql,
+313            exp.Select: transforms.preprocess(
+314                [
+315                    transforms.eliminate_qualify,
+316                    transforms.eliminate_distinct_on,
+317                    transforms.explode_to_unnest,
+318                ]
+319            ),
+320            exp.SortArray: _no_sort_array,
+321            exp.StrPosition: rename_func("STRPOS"),
+322            exp.StrToDate: lambda self, e: f"CAST({_str_to_time_sql(self, e)} AS DATE)",
+323            exp.StrToTime: _str_to_time_sql,
+324            exp.StrToUnix: lambda self, e: f"TO_UNIXTIME(DATE_PARSE({self.sql(e, 'this')}, {self.format_time(e)}))",
+325            exp.StructExtract: struct_extract_sql,
+326            exp.Table: transforms.preprocess([_unnest_sequence]),
+327            exp.TimestampTrunc: timestamptrunc_sql,
+328            exp.TimeStrToDate: timestrtotime_sql,
+329            exp.TimeStrToTime: timestrtotime_sql,
+330            exp.TimeStrToUnix: lambda self, e: f"TO_UNIXTIME(DATE_PARSE({self.sql(e, 'this')}, {Presto.TIME_FORMAT}))",
+331            exp.TimeToStr: lambda self, e: f"DATE_FORMAT({self.sql(e, 'this')}, {self.format_time(e)})",
+332            exp.TimeToUnix: rename_func("TO_UNIXTIME"),
+333            exp.TryCast: transforms.preprocess([transforms.epoch_cast_to_ts]),
+334            exp.TsOrDiToDi: lambda self, e: f"CAST(SUBSTR(REPLACE(CAST({self.sql(e, 'this')} AS VARCHAR), '-', ''), 1, 8) AS INT)",
+335            exp.TsOrDsAdd: _ts_or_ds_add_sql,
+336            exp.TsOrDsToDate: _ts_or_ds_to_date_sql,
+337            exp.Unhex: rename_func("FROM_HEX"),
+338            exp.UnixToStr: lambda self, e: f"DATE_FORMAT(FROM_UNIXTIME({self.sql(e, 'this')}), {self.format_time(e)})",
+339            exp.UnixToTime: rename_func("FROM_UNIXTIME"),
+340            exp.UnixToTimeStr: lambda self, e: f"CAST(FROM_UNIXTIME({self.sql(e, 'this')}) AS VARCHAR)",
+341            exp.VariancePop: rename_func("VAR_POP"),
+342            exp.With: transforms.preprocess([transforms.add_recursive_cte_column_names]),
+343            exp.WithinGroup: transforms.preprocess(
+344                [transforms.remove_within_group_for_percentiles]
+345            ),
+346        }
+347
+348        def interval_sql(self, expression: exp.Interval) -> str:
+349            unit = self.sql(expression, "unit")
+350            if expression.this and unit.lower().startswith("week"):
+351                return f"({expression.this.name} * INTERVAL '7' day)"
+352            return super().interval_sql(expression)
 353
-354        def generateseries_sql(self, expression: exp.GenerateSeries) -> str:
-355            start = expression.args["start"]
-356            end = expression.args["end"]
-357            step = expression.args.get("step")
+354        def transaction_sql(self, expression: exp.Transaction) -> str:
+355            modes = expression.args.get("modes")
+356            modes = f" {', '.join(modes)}" if modes else ""
+357            return f"START TRANSACTION{modes}"
 358
-359            if isinstance(start, exp.Cast):
-360                target_type = start.to
-361            elif isinstance(end, exp.Cast):
-362                target_type = end.to
-363            else:
-364                target_type = None
-365
-366            if target_type and target_type.is_type("timestamp"):
-367                to = target_type.copy()
-368
-369                if target_type is start.to:
-370                    end = exp.cast(end, to)
-371                else:
-372                    start = exp.cast(start, to)
+359        def generateseries_sql(self, expression: exp.GenerateSeries) -> str:
+360            start = expression.args["start"]
+361            end = expression.args["end"]
+362            step = expression.args.get("step")
+363
+364            if isinstance(start, exp.Cast):
+365                target_type = start.to
+366            elif isinstance(end, exp.Cast):
+367                target_type = end.to
+368            else:
+369                target_type = None
+370
+371            if target_type and target_type.is_type("timestamp"):
+372                to = target_type.copy()
 373
-374            return self.func("SEQUENCE", start, end, step)
-375
-376        def offset_limit_modifiers(
-377            self, expression: exp.Expression, fetch: bool, limit: t.Optional[exp.Fetch | exp.Limit]
-378        ) -> t.List[str]:
-379            return [
-380                self.sql(expression, "offset"),
-381                self.sql(limit),
-382            ]
+374                if target_type is start.to:
+375                    end = exp.cast(end, to)
+376                else:
+377                    start = exp.cast(start, to)
+378
+379            return self.func("SEQUENCE", start, end, step)
+380
+381        def offset_limit_modifiers(
+382            self, expression: exp.Expression, fetch: bool, limit: t.Optional[exp.Fetch | exp.Limit]
+383        ) -> t.List[str]:
+384            return [
+385                self.sql(expression, "offset"),
+386                self.sql(limit),
+387            ]
 
@@ -1204,13 +1213,13 @@
-
189    class Tokenizer(tokens.Tokenizer):
-190        KEYWORDS = {
-191            **tokens.Tokenizer.KEYWORDS,
-192            "START": TokenType.BEGIN,
-193            "MATCH_RECOGNIZE": TokenType.MATCH_RECOGNIZE,
-194            "ROW": TokenType.STRUCT,
-195        }
+            
190    class Tokenizer(tokens.Tokenizer):
+191        KEYWORDS = {
+192            **tokens.Tokenizer.KEYWORDS,
+193            "START": TokenType.BEGIN,
+194            "MATCH_RECOGNIZE": TokenType.MATCH_RECOGNIZE,
+195            "ROW": TokenType.STRUCT,
+196        }
 
@@ -1272,44 +1281,48 @@
-
197    class Parser(parser.Parser):
-198        FUNCTIONS = {
-199            **parser.Parser.FUNCTIONS,
-200            "APPROX_DISTINCT": exp.ApproxDistinct.from_arg_list,
-201            "APPROX_PERCENTILE": _approx_percentile,
-202            "CARDINALITY": exp.ArraySize.from_arg_list,
-203            "CONTAINS": exp.ArrayContains.from_arg_list,
-204            "DATE_ADD": lambda args: exp.DateAdd(
-205                this=seq_get(args, 2), expression=seq_get(args, 1), unit=seq_get(args, 0)
-206            ),
-207            "DATE_DIFF": lambda args: exp.DateDiff(
-208                this=seq_get(args, 2), expression=seq_get(args, 1), unit=seq_get(args, 0)
-209            ),
-210            "DATE_FORMAT": format_time_lambda(exp.TimeToStr, "presto"),
-211            "DATE_PARSE": format_time_lambda(exp.StrToTime, "presto"),
-212            "DATE_TRUNC": date_trunc_to_time,
-213            "ELEMENT_AT": _parse_element_at,
-214            "FROM_HEX": exp.Unhex.from_arg_list,
-215            "FROM_UNIXTIME": _from_unixtime,
-216            "FROM_UTF8": lambda args: exp.Decode(
-217                this=seq_get(args, 0), replace=seq_get(args, 1), charset=exp.Literal.string("utf-8")
-218            ),
-219            "NOW": exp.CurrentTimestamp.from_arg_list,
-220            "REGEXP_EXTRACT": lambda args: exp.RegexpExtract(
-221                this=seq_get(args, 0), expression=seq_get(args, 1), group=seq_get(args, 2)
-222            ),
-223            "SEQUENCE": exp.GenerateSeries.from_arg_list,
-224            "STRPOS": lambda args: exp.StrPosition(
-225                this=seq_get(args, 0), substr=seq_get(args, 1), instance=seq_get(args, 2)
-226            ),
-227            "TO_UNIXTIME": exp.TimeToUnix.from_arg_list,
-228            "TO_HEX": exp.Hex.from_arg_list,
-229            "TO_UTF8": lambda args: exp.Encode(
-230                this=seq_get(args, 0), charset=exp.Literal.string("utf-8")
+            
198    class Parser(parser.Parser):
+199        FUNCTIONS = {
+200            **parser.Parser.FUNCTIONS,
+201            "APPROX_DISTINCT": exp.ApproxDistinct.from_arg_list,
+202            "APPROX_PERCENTILE": _approx_percentile,
+203            "BITWISE_AND": binary_from_function(exp.BitwiseAnd),
+204            "BITWISE_NOT": lambda args: exp.BitwiseNot(this=seq_get(args, 0)),
+205            "BITWISE_OR": binary_from_function(exp.BitwiseOr),
+206            "BITWISE_XOR": binary_from_function(exp.BitwiseXor),
+207            "CARDINALITY": exp.ArraySize.from_arg_list,
+208            "CONTAINS": exp.ArrayContains.from_arg_list,
+209            "DATE_ADD": lambda args: exp.DateAdd(
+210                this=seq_get(args, 2), expression=seq_get(args, 1), unit=seq_get(args, 0)
+211            ),
+212            "DATE_DIFF": lambda args: exp.DateDiff(
+213                this=seq_get(args, 2), expression=seq_get(args, 1), unit=seq_get(args, 0)
+214            ),
+215            "DATE_FORMAT": format_time_lambda(exp.TimeToStr, "presto"),
+216            "DATE_PARSE": format_time_lambda(exp.StrToTime, "presto"),
+217            "DATE_TRUNC": date_trunc_to_time,
+218            "ELEMENT_AT": _parse_element_at,
+219            "FROM_HEX": exp.Unhex.from_arg_list,
+220            "FROM_UNIXTIME": _from_unixtime,
+221            "FROM_UTF8": lambda args: exp.Decode(
+222                this=seq_get(args, 0), replace=seq_get(args, 1), charset=exp.Literal.string("utf-8")
+223            ),
+224            "NOW": exp.CurrentTimestamp.from_arg_list,
+225            "REGEXP_EXTRACT": lambda args: exp.RegexpExtract(
+226                this=seq_get(args, 0), expression=seq_get(args, 1), group=seq_get(args, 2)
+227            ),
+228            "SEQUENCE": exp.GenerateSeries.from_arg_list,
+229            "STRPOS": lambda args: exp.StrPosition(
+230                this=seq_get(args, 0), substr=seq_get(args, 1), instance=seq_get(args, 2)
 231            ),
-232        }
-233        FUNCTION_PARSERS = parser.Parser.FUNCTION_PARSERS.copy()
-234        FUNCTION_PARSERS.pop("TRIM")
+232            "TO_UNIXTIME": exp.TimeToUnix.from_arg_list,
+233            "TO_HEX": exp.Hex.from_arg_list,
+234            "TO_UTF8": lambda args: exp.Encode(
+235                this=seq_get(args, 0), charset=exp.Literal.string("utf-8")
+236            ),
+237        }
+238        FUNCTION_PARSERS = parser.Parser.FUNCTION_PARSERS.copy()
+239        FUNCTION_PARSERS.pop("TRIM")
 
@@ -1334,7 +1347,7 @@ Default: 3
FUNCTIONS = - {'ABS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Abs'>>, 'ANY_VALUE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.AnyValue'>>, 'APPROX_DISTINCT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxDistinct'>>, 'APPROX_COUNT_DISTINCT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxDistinct'>>, 'APPROX_QUANTILE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxQuantile'>>, 'ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Array'>>, 'ARRAY_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayAgg'>>, 'ARRAY_ALL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayAll'>>, 'ARRAY_ANY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayAny'>>, 'ARRAY_CONCAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayConcat'>>, 'ARRAY_CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayContains'>>, 'FILTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayFilter'>>, 'ARRAY_FILTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayFilter'>>, 'ARRAY_JOIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayJoin'>>, 'ARRAY_SIZE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArraySize'>>, 'ARRAY_SORT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArraySort'>>, 'ARRAY_SUM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArraySum'>>, 'ARRAY_UNION_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayUnionAgg'>>, 'AVG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Avg'>>, 'CASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Case'>>, 'CAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Cast'>>, 'CAST_TO_STR_TYPE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CastToStrType'>>, 'CEIL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ceil'>>, 'CEILING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ceil'>>, 'COALESCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Coalesce'>>, 'IFNULL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Coalesce'>>, 'NVL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Coalesce'>>, 'CONCAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Concat'>>, 'CONCAT_WS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ConcatWs'>>, 'COUNT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Count'>>, 'COUNT_IF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CountIf'>>, 'CURRENT_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentDate'>>, 'CURRENT_DATETIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentDatetime'>>, 'CURRENT_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentTime'>>, 'CURRENT_TIMESTAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentTimestamp'>>, 'CURRENT_USER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentUser'>>, 'DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Date'>>, 'DATE_ADD': <function Presto.Parser.<lambda>>, 'DATEDIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateDiff'>>, 'DATE_DIFF': <function Presto.Parser.<lambda>>, 'DATEFROMPARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateFromParts'>>, 'DATE_STR_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateStrToDate'>>, 'DATE_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateSub'>>, 'DATE_TO_DATE_STR': <function Parser.<lambda>>, 'DATE_TO_DI': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateToDi'>>, 'DATE_TRUNC': <function date_trunc_to_time>, 'DATETIME_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeAdd'>>, 'DATETIME_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeDiff'>>, 'DATETIME_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeSub'>>, 'DATETIME_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeTrunc'>>, 'DAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Day'>>, 'DAY_OF_MONTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfMonth'>>, 'DAYOFMONTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfMonth'>>, 'DAY_OF_WEEK': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfWeek'>>, 'DAYOFWEEK': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfWeek'>>, 'DAY_OF_YEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfYear'>>, 'DAYOFYEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfYear'>>, 'DECODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Decode'>>, 'DI_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DiToDate'>>, 'ENCODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Encode'>>, 'EXP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Exp'>>, 'EXPLODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Explode'>>, 'EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Extract'>>, 'FLOOR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Floor'>>, 'FROM_BASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FromBase'>>, 'FROM_BASE64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FromBase64'>>, 'GENERATE_SERIES': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GenerateSeries'>>, 'GREATEST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Greatest'>>, 'GROUP_CONCAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GroupConcat'>>, 'HEX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Hex'>>, 'HLL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Hll'>>, 'IF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.If'>>, 'INITCAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Initcap'>>, 'JSON_ARRAY_CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONArrayContains'>>, 'JSONB_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBExtract'>>, 'JSONB_EXTRACT_SCALAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBExtractScalar'>>, 'JSON_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONExtract'>>, 'JSON_EXTRACT_SCALAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONExtractScalar'>>, 'JSON_FORMAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONFormat'>>, 'J_S_O_N_OBJECT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONObject'>>, 'LAST_DATE_OF_MONTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LastDateOfMonth'>>, 'LEAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Least'>>, 'LEFT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Left'>>, 'LENGTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Length'>>, 'LEN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Length'>>, 'LEVENSHTEIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Levenshtein'>>, 'LN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ln'>>, 'LOG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Log'>>, 'LOG10': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Log10'>>, 'LOG2': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Log2'>>, 'LOGICAL_AND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalAnd'>>, 'BOOL_AND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalAnd'>>, 'BOOLAND_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalAnd'>>, 'LOGICAL_OR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalOr'>>, 'BOOL_OR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalOr'>>, 'BOOLOR_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalOr'>>, 'LOWER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Lower'>>, 'LCASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Lower'>>, 'MD5': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MD5'>>, 'MD5_DIGEST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MD5Digest'>>, 'MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Map'>>, 'MAP_FROM_ENTRIES': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MapFromEntries'>>, 'MATCH_AGAINST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MatchAgainst'>>, 'MAX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Max'>>, 'MIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Min'>>, 'MONTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Month'>>, 'NEXT_VALUE_FOR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.NextValueFor'>>, 'NUMBER_TO_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.NumberToStr'>>, 'NVL2': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Nvl2'>>, 'OPEN_J_S_O_N': <bound method Func.from_arg_list of <class 'sqlglot.expressions.OpenJSON'>>, 'PARAMETERIZED_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParameterizedAgg'>>, 'PERCENTILE_CONT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.PercentileCont'>>, 'PERCENTILE_DISC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.PercentileDisc'>>, 'POSEXPLODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Posexplode'>>, 'POWER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Pow'>>, 'POW': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Pow'>>, 'QUANTILE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Quantile'>>, 'RANGE_N': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RangeN'>>, 'READ_CSV': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ReadCSV'>>, 'REDUCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Reduce'>>, 'REGEXP_EXTRACT': <function Presto.Parser.<lambda>>, 'REGEXP_I_LIKE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpILike'>>, 'REGEXP_LIKE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpLike'>>, 'REGEXP_SPLIT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpSplit'>>, 'REPEAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Repeat'>>, 'RIGHT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Right'>>, 'ROUND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Round'>>, 'ROW_NUMBER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RowNumber'>>, 'SHA': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA'>>, 'SHA1': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA'>>, 'SHA2': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA2'>>, 'SAFE_CONCAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SafeConcat'>>, 'SAFE_DIVIDE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SafeDivide'>>, 'SET_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SetAgg'>>, 'SORT_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SortArray'>>, 'SPLIT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Split'>>, 'SQRT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sqrt'>>, 'STANDARD_HASH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StandardHash'>>, 'STAR_MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StarMap'>>, 'STDDEV': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Stddev'>>, 'STDDEV_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StddevPop'>>, 'STDDEV_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StddevSamp'>>, 'STR_POSITION': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrPosition'>>, 'STR_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrToDate'>>, 'STR_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrToTime'>>, 'STR_TO_UNIX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrToUnix'>>, 'STRUCT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Struct'>>, 'STRUCT_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StructExtract'>>, 'SUBSTRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Substring'>>, 'SUM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sum'>>, 'TIME_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeAdd'>>, 'TIME_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeDiff'>>, 'TIME_STR_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeStrToDate'>>, 'TIME_STR_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeStrToTime'>>, 'TIME_STR_TO_UNIX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeStrToUnix'>>, 'TIME_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeSub'>>, 'TIME_TO_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeToStr'>>, 'TIME_TO_TIME_STR': <function Parser.<lambda>>, 'TIME_TO_UNIX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeToUnix'>>, 'TIME_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeTrunc'>>, 'TIMESTAMP_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampAdd'>>, 'TIMESTAMP_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampDiff'>>, 'TIMESTAMP_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampSub'>>, 'TIMESTAMP_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampTrunc'>>, 'TO_BASE64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToBase64'>>, 'TO_CHAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToChar'>>, 'TRIM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Trim'>>, 'TRY_CAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TryCast'>>, 'TS_OR_DI_TO_DI': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDiToDi'>>, 'TS_OR_DS_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsAdd'>>, 'TS_OR_DS_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsToDate'>>, 'TS_OR_DS_TO_DATE_STR': <function Parser.<lambda>>, 'UNHEX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Unhex'>>, 'UNIX_TO_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToStr'>>, 'UNIX_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToTime'>>, 'UNIX_TO_TIME_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToTimeStr'>>, 'UPPER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Upper'>>, 'UCASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Upper'>>, 'VAR_MAP': <function parse_var_map>, 'VARIANCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Variance'>>, 'VARIANCE_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Variance'>>, 'VAR_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Variance'>>, 'VARIANCE_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.VariancePop'>>, 'VAR_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.VariancePop'>>, 'WEEK': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Week'>>, 'WEEK_OF_YEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.WeekOfYear'>>, 'WEEKOFYEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.WeekOfYear'>>, 'WHEN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.When'>>, 'X_M_L_TABLE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.XMLTable'>>, 'YEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Year'>>, 'GLOB': <function Parser.<lambda>>, 'LIKE': <function parse_like>, 'APPROX_PERCENTILE': <function _approx_percentile>, 'CARDINALITY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArraySize'>>, 'CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayContains'>>, 'DATE_FORMAT': <function format_time_lambda.<locals>._format_time>, 'DATE_PARSE': <function format_time_lambda.<locals>._format_time>, 'ELEMENT_AT': <function _parse_element_at>, 'FROM_HEX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Unhex'>>, 'FROM_UNIXTIME': <function _from_unixtime>, 'FROM_UTF8': <function Presto.Parser.<lambda>>, 'NOW': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentTimestamp'>>, 'SEQUENCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GenerateSeries'>>, 'STRPOS': <function Presto.Parser.<lambda>>, 'TO_UNIXTIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeToUnix'>>, 'TO_HEX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Hex'>>, 'TO_UTF8': <function Presto.Parser.<lambda>>} + {'ABS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Abs'>>, 'ANY_VALUE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.AnyValue'>>, 'APPROX_DISTINCT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxDistinct'>>, 'APPROX_COUNT_DISTINCT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxDistinct'>>, 'APPROX_QUANTILE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ApproxQuantile'>>, 'ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Array'>>, 'ARRAY_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayAgg'>>, 'ARRAY_ALL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayAll'>>, 'ARRAY_ANY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayAny'>>, 'ARRAY_CONCAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayConcat'>>, 'ARRAY_CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayContains'>>, 'FILTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayFilter'>>, 'ARRAY_FILTER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayFilter'>>, 'ARRAY_JOIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayJoin'>>, 'ARRAY_SIZE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArraySize'>>, 'ARRAY_SORT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArraySort'>>, 'ARRAY_SUM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArraySum'>>, 'ARRAY_UNION_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayUnionAgg'>>, 'AVG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Avg'>>, 'CASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Case'>>, 'CAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Cast'>>, 'CAST_TO_STR_TYPE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CastToStrType'>>, 'CEIL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ceil'>>, 'CEILING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ceil'>>, 'COALESCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Coalesce'>>, 'IFNULL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Coalesce'>>, 'NVL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Coalesce'>>, 'CONCAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Concat'>>, 'CONCAT_WS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ConcatWs'>>, 'COUNT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Count'>>, 'COUNT_IF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CountIf'>>, 'CURRENT_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentDate'>>, 'CURRENT_DATETIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentDatetime'>>, 'CURRENT_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentTime'>>, 'CURRENT_TIMESTAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentTimestamp'>>, 'CURRENT_USER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentUser'>>, 'DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Date'>>, 'DATE_ADD': <function Presto.Parser.<lambda>>, 'DATEDIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateDiff'>>, 'DATE_DIFF': <function Presto.Parser.<lambda>>, 'DATEFROMPARTS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateFromParts'>>, 'DATE_STR_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateStrToDate'>>, 'DATE_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateSub'>>, 'DATE_TO_DATE_STR': <function Parser.<lambda>>, 'DATE_TO_DI': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateToDi'>>, 'DATE_TRUNC': <function date_trunc_to_time>, 'DATETIME_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeAdd'>>, 'DATETIME_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeDiff'>>, 'DATETIME_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeSub'>>, 'DATETIME_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeTrunc'>>, 'DAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Day'>>, 'DAY_OF_MONTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfMonth'>>, 'DAYOFMONTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfMonth'>>, 'DAY_OF_WEEK': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfWeek'>>, 'DAYOFWEEK': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfWeek'>>, 'DAY_OF_YEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfYear'>>, 'DAYOFYEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DayOfYear'>>, 'DECODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Decode'>>, 'DI_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DiToDate'>>, 'ENCODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Encode'>>, 'EXP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Exp'>>, 'EXPLODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Explode'>>, 'EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Extract'>>, 'FLOOR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Floor'>>, 'FROM_BASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FromBase'>>, 'FROM_BASE64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.FromBase64'>>, 'GENERATE_SERIES': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GenerateSeries'>>, 'GREATEST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Greatest'>>, 'GROUP_CONCAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GroupConcat'>>, 'HEX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Hex'>>, 'HLL': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Hll'>>, 'IF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.If'>>, 'INITCAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Initcap'>>, 'JSON_ARRAY_CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONArrayContains'>>, 'JSONB_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBExtract'>>, 'JSONB_EXTRACT_SCALAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONBExtractScalar'>>, 'JSON_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONExtract'>>, 'JSON_EXTRACT_SCALAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONExtractScalar'>>, 'JSON_FORMAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONFormat'>>, 'J_S_O_N_OBJECT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONObject'>>, 'LAST_DATE_OF_MONTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LastDateOfMonth'>>, 'LEAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Least'>>, 'LEFT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Left'>>, 'LENGTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Length'>>, 'LEN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Length'>>, 'LEVENSHTEIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Levenshtein'>>, 'LN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Ln'>>, 'LOG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Log'>>, 'LOG10': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Log10'>>, 'LOG2': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Log2'>>, 'LOGICAL_AND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalAnd'>>, 'BOOL_AND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalAnd'>>, 'BOOLAND_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalAnd'>>, 'LOGICAL_OR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalOr'>>, 'BOOL_OR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalOr'>>, 'BOOLOR_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.LogicalOr'>>, 'LOWER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Lower'>>, 'LCASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Lower'>>, 'MD5': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MD5'>>, 'MD5_DIGEST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MD5Digest'>>, 'MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Map'>>, 'MAP_FROM_ENTRIES': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MapFromEntries'>>, 'MATCH_AGAINST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MatchAgainst'>>, 'MAX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Max'>>, 'MIN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Min'>>, 'MONTH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Month'>>, 'MONTHS_BETWEEN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.MonthsBetween'>>, 'NEXT_VALUE_FOR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.NextValueFor'>>, 'NUMBER_TO_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.NumberToStr'>>, 'NVL2': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Nvl2'>>, 'OPEN_J_S_O_N': <bound method Func.from_arg_list of <class 'sqlglot.expressions.OpenJSON'>>, 'PARAMETERIZED_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ParameterizedAgg'>>, 'PERCENTILE_CONT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.PercentileCont'>>, 'PERCENTILE_DISC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.PercentileDisc'>>, 'POSEXPLODE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Posexplode'>>, 'POWER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Pow'>>, 'POW': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Pow'>>, 'QUANTILE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Quantile'>>, 'RANGE_N': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RangeN'>>, 'READ_CSV': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ReadCSV'>>, 'REDUCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Reduce'>>, 'REGEXP_EXTRACT': <function Presto.Parser.<lambda>>, 'REGEXP_I_LIKE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpILike'>>, 'REGEXP_LIKE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpLike'>>, 'REGEXP_REPLACE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpReplace'>>, 'REGEXP_SPLIT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpSplit'>>, 'REPEAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Repeat'>>, 'RIGHT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Right'>>, 'ROUND': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Round'>>, 'ROW_NUMBER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RowNumber'>>, 'SHA': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA'>>, 'SHA1': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA'>>, 'SHA2': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SHA2'>>, 'SAFE_CONCAT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SafeConcat'>>, 'SAFE_DIVIDE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SafeDivide'>>, 'SET_AGG': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SetAgg'>>, 'SORT_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.SortArray'>>, 'SPLIT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Split'>>, 'SQRT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sqrt'>>, 'STANDARD_HASH': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StandardHash'>>, 'STAR_MAP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StarMap'>>, 'STDDEV': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Stddev'>>, 'STDDEV_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StddevPop'>>, 'STDDEV_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StddevSamp'>>, 'STR_POSITION': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrPosition'>>, 'STR_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrToDate'>>, 'STR_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrToTime'>>, 'STR_TO_UNIX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StrToUnix'>>, 'STRUCT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Struct'>>, 'STRUCT_EXTRACT': <bound method Func.from_arg_list of <class 'sqlglot.expressions.StructExtract'>>, 'SUBSTRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Substring'>>, 'SUM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Sum'>>, 'TIME_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeAdd'>>, 'TIME_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeDiff'>>, 'TIME_STR_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeStrToDate'>>, 'TIME_STR_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeStrToTime'>>, 'TIME_STR_TO_UNIX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeStrToUnix'>>, 'TIME_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeSub'>>, 'TIME_TO_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeToStr'>>, 'TIME_TO_TIME_STR': <function Parser.<lambda>>, 'TIME_TO_UNIX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeToUnix'>>, 'TIME_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeTrunc'>>, 'TIMESTAMP_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampAdd'>>, 'TIMESTAMP_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampDiff'>>, 'TIMESTAMP_SUB': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampSub'>>, 'TIMESTAMP_TRUNC': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampTrunc'>>, 'TO_BASE64': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToBase64'>>, 'TO_CHAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ToChar'>>, 'TRANSFORM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Transform'>>, 'TRIM': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Trim'>>, 'TRY_CAST': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TryCast'>>, 'TS_OR_DI_TO_DI': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDiToDi'>>, 'TS_OR_DS_ADD': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsAdd'>>, 'TS_OR_DS_TO_DATE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TsOrDsToDate'>>, 'TS_OR_DS_TO_DATE_STR': <function Parser.<lambda>>, 'UNHEX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Unhex'>>, 'UNIX_TO_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToStr'>>, 'UNIX_TO_TIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToTime'>>, 'UNIX_TO_TIME_STR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.UnixToTimeStr'>>, 'UPPER': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Upper'>>, 'UCASE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Upper'>>, 'VAR_MAP': <function parse_var_map>, 'VARIANCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Variance'>>, 'VARIANCE_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Variance'>>, 'VAR_SAMP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Variance'>>, 'VARIANCE_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.VariancePop'>>, 'VAR_POP': <bound method Func.from_arg_list of <class 'sqlglot.expressions.VariancePop'>>, 'WEEK': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Week'>>, 'WEEK_OF_YEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.WeekOfYear'>>, 'WEEKOFYEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.WeekOfYear'>>, 'WHEN': <bound method Func.from_arg_list of <class 'sqlglot.expressions.When'>>, 'X_M_L_TABLE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.XMLTable'>>, 'XOR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Xor'>>, 'YEAR': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Year'>>, 'GLOB': <function Parser.<lambda>>, 'LIKE': <function parse_like>, 'APPROX_PERCENTILE': <function _approx_percentile>, 'BITWISE_AND': <function binary_from_function.<locals>.<lambda>>, 'BITWISE_NOT': <function Presto.Parser.<lambda>>, 'BITWISE_OR': <function binary_from_function.<locals>.<lambda>>, 'BITWISE_XOR': <function binary_from_function.<locals>.<lambda>>, 'CARDINALITY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArraySize'>>, 'CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.ArrayContains'>>, 'DATE_FORMAT': <function format_time_lambda.<locals>._format_time>, 'DATE_PARSE': <function format_time_lambda.<locals>._format_time>, 'ELEMENT_AT': <function _parse_element_at>, 'FROM_HEX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Unhex'>>, 'FROM_UNIXTIME': <function _from_unixtime>, 'FROM_UTF8': <function Presto.Parser.<lambda>>, 'NOW': <bound method Func.from_arg_list of <class 'sqlglot.expressions.CurrentTimestamp'>>, 'SEQUENCE': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GenerateSeries'>>, 'STRPOS': <function Presto.Parser.<lambda>>, 'TO_UNIXTIME': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimeToUnix'>>, 'TO_HEX': <bound method Func.from_arg_list of <class 'sqlglot.expressions.Hex'>>, 'TO_UTF8': <function Presto.Parser.<lambda>>}
@@ -1554,153 +1567,153 @@ Default: 3
-
236    class Generator(generator.Generator):
-237        INTERVAL_ALLOWS_PLURAL_FORM = False
-238        JOIN_HINTS = False
-239        TABLE_HINTS = False
-240        QUERY_HINTS = False
-241        IS_BOOL_ALLOWED = False
-242        STRUCT_DELIMITER = ("(", ")")
-243
-244        PROPERTIES_LOCATION = {
-245            **generator.Generator.PROPERTIES_LOCATION,
-246            exp.LocationProperty: exp.Properties.Location.UNSUPPORTED,
-247            exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED,
-248        }
-249
-250        TYPE_MAPPING = {
-251            **generator.Generator.TYPE_MAPPING,
-252            exp.DataType.Type.INT: "INTEGER",
-253            exp.DataType.Type.FLOAT: "REAL",
-254            exp.DataType.Type.BINARY: "VARBINARY",
-255            exp.DataType.Type.TEXT: "VARCHAR",
-256            exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP",
-257            exp.DataType.Type.STRUCT: "ROW",
-258        }
-259
-260        TRANSFORMS = {
-261            **generator.Generator.TRANSFORMS,
-262            exp.ApproxDistinct: _approx_distinct_sql,
-263            exp.ApproxQuantile: rename_func("APPROX_PERCENTILE"),
-264            exp.Array: lambda self, e: f"ARRAY[{self.expressions(e, flat=True)}]",
-265            exp.ArrayConcat: rename_func("CONCAT"),
-266            exp.ArrayContains: rename_func("CONTAINS"),
-267            exp.ArraySize: rename_func("CARDINALITY"),
-268            exp.BitwiseAnd: lambda self, e: f"BITWISE_AND({self.sql(e, 'this')}, {self.sql(e, 'expression')})",
-269            exp.BitwiseLeftShift: lambda self, e: f"BITWISE_ARITHMETIC_SHIFT_LEFT({self.sql(e, 'this')}, {self.sql(e, 'expression')})",
-270            exp.BitwiseNot: lambda self, e: f"BITWISE_NOT({self.sql(e, 'this')})",
-271            exp.BitwiseOr: lambda self, e: f"BITWISE_OR({self.sql(e, 'this')}, {self.sql(e, 'expression')})",
-272            exp.BitwiseRightShift: lambda self, e: f"BITWISE_ARITHMETIC_SHIFT_RIGHT({self.sql(e, 'this')}, {self.sql(e, 'expression')})",
-273            exp.BitwiseXor: lambda self, e: f"BITWISE_XOR({self.sql(e, 'this')}, {self.sql(e, 'expression')})",
-274            exp.Cast: transforms.preprocess([transforms.epoch_cast_to_ts]),
-275            exp.CurrentTimestamp: lambda *_: "CURRENT_TIMESTAMP",
-276            exp.DataType: _datatype_sql,
-277            exp.DateAdd: lambda self, e: self.func(
-278                "DATE_ADD", exp.Literal.string(e.text("unit") or "day"), e.expression, e.this
-279            ),
-280            exp.DateDiff: lambda self, e: self.func(
-281                "DATE_DIFF", exp.Literal.string(e.text("unit") or "day"), e.expression, e.this
-282            ),
-283            exp.DateStrToDate: lambda self, e: f"CAST(DATE_PARSE({self.sql(e, 'this')}, {Presto.DATE_FORMAT}) AS DATE)",
-284            exp.DateToDi: lambda self, e: f"CAST(DATE_FORMAT({self.sql(e, 'this')}, {Presto.DATEINT_FORMAT}) AS INT)",
-285            exp.Decode: _decode_sql,
-286            exp.DiToDate: lambda self, e: f"CAST(DATE_PARSE(CAST({self.sql(e, 'this')} AS VARCHAR), {Presto.DATEINT_FORMAT}) AS DATE)",
-287            exp.Encode: _encode_sql,
-288            exp.FileFormatProperty: lambda self, e: f"FORMAT='{e.name.upper()}'",
-289            exp.Group: transforms.preprocess([transforms.unalias_group]),
-290            exp.Hex: rename_func("TO_HEX"),
-291            exp.If: if_sql,
-292            exp.ILike: no_ilike_sql,
-293            exp.Initcap: _initcap_sql,
-294            exp.Lateral: _explode_to_unnest_sql,
-295            exp.Left: left_to_substring_sql,
-296            exp.Levenshtein: rename_func("LEVENSHTEIN_DISTANCE"),
-297            exp.LogicalAnd: rename_func("BOOL_AND"),
-298            exp.LogicalOr: rename_func("BOOL_OR"),
-299            exp.Pivot: no_pivot_sql,
-300            exp.Quantile: _quantile_sql,
-301            exp.RegexpExtract: regexp_extract_sql,
-302            exp.Right: right_to_substring_sql,
-303            exp.SafeBracket: lambda self, e: self.func(
-304                "ELEMENT_AT", e.this, seq_get(apply_index_offset(e.this, e.expressions, 1), 0)
-305            ),
-306            exp.SafeDivide: no_safe_divide_sql,
-307            exp.Schema: _schema_sql,
-308            exp.Select: transforms.preprocess(
-309                [
-310                    transforms.eliminate_qualify,
-311                    transforms.eliminate_distinct_on,
-312                    transforms.explode_to_unnest,
-313                ]
-314            ),
-315            exp.SortArray: _no_sort_array,
-316            exp.StrPosition: rename_func("STRPOS"),
-317            exp.StrToDate: lambda self, e: f"CAST({_str_to_time_sql(self, e)} AS DATE)",
-318            exp.StrToTime: _str_to_time_sql,
-319            exp.StrToUnix: lambda self, e: f"TO_UNIXTIME(DATE_PARSE({self.sql(e, 'this')}, {self.format_time(e)}))",
-320            exp.StructExtract: struct_extract_sql,
-321            exp.Table: transforms.preprocess([_unnest_sequence]),
-322            exp.TimestampTrunc: timestamptrunc_sql,
-323            exp.TimeStrToDate: timestrtotime_sql,
-324            exp.TimeStrToTime: timestrtotime_sql,
-325            exp.TimeStrToUnix: lambda self, e: f"TO_UNIXTIME(DATE_PARSE({self.sql(e, 'this')}, {Presto.TIME_FORMAT}))",
-326            exp.TimeToStr: lambda self, e: f"DATE_FORMAT({self.sql(e, 'this')}, {self.format_time(e)})",
-327            exp.TimeToUnix: rename_func("TO_UNIXTIME"),
-328            exp.TryCast: transforms.preprocess([transforms.epoch_cast_to_ts]),
-329            exp.TsOrDiToDi: lambda self, e: f"CAST(SUBSTR(REPLACE(CAST({self.sql(e, 'this')} AS VARCHAR), '-', ''), 1, 8) AS INT)",
-330            exp.TsOrDsAdd: _ts_or_ds_add_sql,
-331            exp.TsOrDsToDate: _ts_or_ds_to_date_sql,
-332            exp.Unhex: rename_func("FROM_HEX"),
-333            exp.UnixToStr: lambda self, e: f"DATE_FORMAT(FROM_UNIXTIME({self.sql(e, 'this')}), {self.format_time(e)})",
-334            exp.UnixToTime: rename_func("FROM_UNIXTIME"),
-335            exp.UnixToTimeStr: lambda self, e: f"CAST(FROM_UNIXTIME({self.sql(e, 'this')}) AS VARCHAR)",
-336            exp.VariancePop: rename_func("VAR_POP"),
-337            exp.With: transforms.preprocess([transforms.add_recursive_cte_column_names]),
-338            exp.WithinGroup: transforms.preprocess(
-339                [transforms.remove_within_group_for_percentiles]
-340            ),
-341        }
-342
-343        def interval_sql(self, expression: exp.Interval) -> str:
-344            unit = self.sql(expression, "unit")
-345            if expression.this and unit.lower().startswith("week"):
-346                return f"({expression.this.name} * INTERVAL '7' day)"
-347            return super().interval_sql(expression)
-348
-349        def transaction_sql(self, expression: exp.Transaction) -> str:
-350            modes = expression.args.get("modes")
-351            modes = f" {', '.join(modes)}" if modes else ""
-352            return f"START TRANSACTION{modes}"
+            
241    class Generator(generator.Generator):
+242        INTERVAL_ALLOWS_PLURAL_FORM = False
+243        JOIN_HINTS = False
+244        TABLE_HINTS = False
+245        QUERY_HINTS = False
+246        IS_BOOL_ALLOWED = False
+247        STRUCT_DELIMITER = ("(", ")")
+248
+249        PROPERTIES_LOCATION = {
+250            **generator.Generator.PROPERTIES_LOCATION,
+251            exp.LocationProperty: exp.Properties.Location.UNSUPPORTED,
+252            exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED,
+253        }
+254
+255        TYPE_MAPPING = {
+256            **generator.Generator.TYPE_MAPPING,
+257            exp.DataType.Type.INT: "INTEGER",
+258            exp.DataType.Type.FLOAT: "REAL",
+259            exp.DataType.Type.BINARY: "VARBINARY",
+260            exp.DataType.Type.TEXT: "VARCHAR",
+261            exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP",
+262            exp.DataType.Type.STRUCT: "ROW",
+263        }
+264
+265        TRANSFORMS = {
+266            **generator.Generator.TRANSFORMS,
+267            exp.ApproxDistinct: _approx_distinct_sql,
+268            exp.ApproxQuantile: rename_func("APPROX_PERCENTILE"),
+269            exp.Array: lambda self, e: f"ARRAY[{self.expressions(e, flat=True)}]",
+270            exp.ArrayConcat: rename_func("CONCAT"),
+271            exp.ArrayContains: rename_func("CONTAINS"),
+272            exp.ArraySize: rename_func("CARDINALITY"),
+273            exp.BitwiseAnd: lambda self, e: f"BITWISE_AND({self.sql(e, 'this')}, {self.sql(e, 'expression')})",
+274            exp.BitwiseLeftShift: lambda self, e: f"BITWISE_ARITHMETIC_SHIFT_LEFT({self.sql(e, 'this')}, {self.sql(e, 'expression')})",
+275            exp.BitwiseNot: lambda self, e: f"BITWISE_NOT({self.sql(e, 'this')})",
+276            exp.BitwiseOr: lambda self, e: f"BITWISE_OR({self.sql(e, 'this')}, {self.sql(e, 'expression')})",
+277            exp.BitwiseRightShift: lambda self, e: f"BITWISE_ARITHMETIC_SHIFT_RIGHT({self.sql(e, 'this')}, {self.sql(e, 'expression')})",
+278            exp.BitwiseXor: lambda self, e: f"BITWISE_XOR({self.sql(e, 'this')}, {self.sql(e, 'expression')})",
+279            exp.Cast: transforms.preprocess([transforms.epoch_cast_to_ts]),
+280            exp.CurrentTimestamp: lambda *_: "CURRENT_TIMESTAMP",
+281            exp.DataType: _datatype_sql,
+282            exp.DateAdd: lambda self, e: self.func(
+283                "DATE_ADD", exp.Literal.string(e.text("unit") or "day"), e.expression, e.this
+284            ),
+285            exp.DateDiff: lambda self, e: self.func(
+286                "DATE_DIFF", exp.Literal.string(e.text("unit") or "day"), e.expression, e.this
+287            ),
+288            exp.DateStrToDate: lambda self, e: f"CAST(DATE_PARSE({self.sql(e, 'this')}, {Presto.DATE_FORMAT}) AS DATE)",
+289            exp.DateToDi: lambda self, e: f"CAST(DATE_FORMAT({self.sql(e, 'this')}, {Presto.DATEINT_FORMAT}) AS INT)",
+290            exp.Decode: _decode_sql,
+291            exp.DiToDate: lambda self, e: f"CAST(DATE_PARSE(CAST({self.sql(e, 'this')} AS VARCHAR), {Presto.DATEINT_FORMAT}) AS DATE)",
+292            exp.Encode: _encode_sql,
+293            exp.FileFormatProperty: lambda self, e: f"FORMAT='{e.name.upper()}'",
+294            exp.Group: transforms.preprocess([transforms.unalias_group]),
+295            exp.Hex: rename_func("TO_HEX"),
+296            exp.If: if_sql,
+297            exp.ILike: no_ilike_sql,
+298            exp.Initcap: _initcap_sql,
+299            exp.Lateral: _explode_to_unnest_sql,
+300            exp.Left: left_to_substring_sql,
+301            exp.Levenshtein: rename_func("LEVENSHTEIN_DISTANCE"),
+302            exp.LogicalAnd: rename_func("BOOL_AND"),
+303            exp.LogicalOr: rename_func("BOOL_OR"),
+304            exp.Pivot: no_pivot_sql,
+305            exp.Quantile: _quantile_sql,
+306            exp.RegexpExtract: regexp_extract_sql,
+307            exp.Right: right_to_substring_sql,
+308            exp.SafeBracket: lambda self, e: self.func(
+309                "ELEMENT_AT", e.this, seq_get(apply_index_offset(e.this, e.expressions, 1), 0)
+310            ),
+311            exp.SafeDivide: no_safe_divide_sql,
+312            exp.Schema: _schema_sql,
+313            exp.Select: transforms.preprocess(
+314                [
+315                    transforms.eliminate_qualify,
+316                    transforms.eliminate_distinct_on,
+317                    transforms.explode_to_unnest,
+318                ]
+319            ),
+320            exp.SortArray: _no_sort_array,
+321            exp.StrPosition: rename_func("STRPOS"),
+322            exp.StrToDate: lambda self, e: f"CAST({_str_to_time_sql(self, e)} AS DATE)",
+323            exp.StrToTime: _str_to_time_sql,
+324            exp.StrToUnix: lambda self, e: f"TO_UNIXTIME(DATE_PARSE({self.sql(e, 'this')}, {self.format_time(e)}))",
+325            exp.StructExtract: struct_extract_sql,
+326            exp.Table: transforms.preprocess([_unnest_sequence]),
+327            exp.TimestampTrunc: timestamptrunc_sql,
+328            exp.TimeStrToDate: timestrtotime_sql,
+329            exp.TimeStrToTime: timestrtotime_sql,
+330            exp.TimeStrToUnix: lambda self, e: f"TO_UNIXTIME(DATE_PARSE({self.sql(e, 'this')}, {Presto.TIME_FORMAT}))",
+331            exp.TimeToStr: lambda self, e: f"DATE_FORMAT({self.sql(e, 'this')}, {self.format_time(e)})",
+332            exp.TimeToUnix: rename_func("TO_UNIXTIME"),
+333            exp.TryCast: transforms.preprocess([transforms.epoch_cast_to_ts]),
+334            exp.TsOrDiToDi: lambda self, e: f"CAST(SUBSTR(REPLACE(CAST({self.sql(e, 'this')} AS VARCHAR), '-', ''), 1, 8) AS INT)",
+335            exp.TsOrDsAdd: _ts_or_ds_add_sql,
+336            exp.TsOrDsToDate: _ts_or_ds_to_date_sql,
+337            exp.Unhex: rename_func("FROM_HEX"),
+338            exp.UnixToStr: lambda self, e: f"DATE_FORMAT(FROM_UNIXTIME({self.sql(e, 'this')}), {self.format_time(e)})",
+339            exp.UnixToTime: rename_func("FROM_UNIXTIME"),
+340            exp.UnixToTimeStr: lambda self, e: f"CAST(FROM_UNIXTIME({self.sql(e, 'this')}) AS VARCHAR)",
+341            exp.VariancePop: rename_func("VAR_POP"),
+342            exp.With: transforms.preprocess([transforms.add_recursive_cte_column_names]),
+343            exp.WithinGroup: transforms.preprocess(
+344                [transforms.remove_within_group_for_percentiles]
+345            ),
+346        }
+347
+348        def interval_sql(self, expression: exp.Interval) -> str:
+349            unit = self.sql(expression, "unit")
+350            if expression.this and unit.lower().startswith("week"):
+351                return f"({expression.this.name} * INTERVAL '7' day)"
+352            return super().interval_sql(expression)
 353
-354        def generateseries_sql(self, expression: exp.GenerateSeries) -> str:
-355            start = expression.args["start"]
-356            end = expression.args["end"]
-357            step = expression.args.get("step")
+354        def transaction_sql(self, expression: exp.Transaction) -> str:
+355            modes = expression.args.get("modes")
+356            modes = f" {', '.join(modes)}" if modes else ""
+357            return f"START TRANSACTION{modes}"
 358
-359            if isinstance(start, exp.Cast):
-360                target_type = start.to
-361            elif isinstance(end, exp.Cast):
-362                target_type = end.to
-363            else:
-364                target_type = None
-365
-366            if target_type and target_type.is_type("timestamp"):
-367                to = target_type.copy()
-368
-369                if target_type is start.to:
-370                    end = exp.cast(end, to)
-371                else:
-372                    start = exp.cast(start, to)
+359        def generateseries_sql(self, expression: exp.GenerateSeries) -> str:
+360            start = expression.args["start"]
+361            end = expression.args["end"]
+362            step = expression.args.get("step")
+363
+364            if isinstance(start, exp.Cast):
+365                target_type = start.to
+366            elif isinstance(end, exp.Cast):
+367                target_type = end.to
+368            else:
+369                target_type = None
+370
+371            if target_type and target_type.is_type("timestamp"):
+372                to = target_type.copy()
 373
-374            return self.func("SEQUENCE", start, end, step)
-375
-376        def offset_limit_modifiers(
-377            self, expression: exp.Expression, fetch: bool, limit: t.Optional[exp.Fetch | exp.Limit]
-378        ) -> t.List[str]:
-379            return [
-380                self.sql(expression, "offset"),
-381                self.sql(limit),
-382            ]
+374                if target_type is start.to:
+375                    end = exp.cast(end, to)
+376                else:
+377                    start = exp.cast(start, to)
+378
+379            return self.func("SEQUENCE", start, end, step)
+380
+381        def offset_limit_modifiers(
+382            self, expression: exp.Expression, fetch: bool, limit: t.Optional[exp.Fetch | exp.Limit]
+383        ) -> t.List[str]:
+384            return [
+385                self.sql(expression, "offset"),
+386                self.sql(limit),
+387            ]
 
@@ -1865,11 +1878,11 @@ Default: True
-
343        def interval_sql(self, expression: exp.Interval) -> str:
-344            unit = self.sql(expression, "unit")
-345            if expression.this and unit.lower().startswith("week"):
-346                return f"({expression.this.name} * INTERVAL '7' day)"
-347            return super().interval_sql(expression)
+            
348        def interval_sql(self, expression: exp.Interval) -> str:
+349            unit = self.sql(expression, "unit")
+350            if expression.this and unit.lower().startswith("week"):
+351                return f"({expression.this.name} * INTERVAL '7' day)"
+352            return super().interval_sql(expression)
 
@@ -1887,10 +1900,10 @@ Default: True
-
349        def transaction_sql(self, expression: exp.Transaction) -> str:
-350            modes = expression.args.get("modes")
-351            modes = f" {', '.join(modes)}" if modes else ""
-352            return f"START TRANSACTION{modes}"
+            
354        def transaction_sql(self, expression: exp.Transaction) -> str:
+355            modes = expression.args.get("modes")
+356            modes = f" {', '.join(modes)}" if modes else ""
+357            return f"START TRANSACTION{modes}"
 
@@ -1908,27 +1921,27 @@ Default: True
-
354        def generateseries_sql(self, expression: exp.GenerateSeries) -> str:
-355            start = expression.args["start"]
-356            end = expression.args["end"]
-357            step = expression.args.get("step")
-358
-359            if isinstance(start, exp.Cast):
-360                target_type = start.to
-361            elif isinstance(end, exp.Cast):
-362                target_type = end.to
-363            else:
-364                target_type = None
-365
-366            if target_type and target_type.is_type("timestamp"):
-367                to = target_type.copy()
-368
-369                if target_type is start.to:
-370                    end = exp.cast(end, to)
-371                else:
-372                    start = exp.cast(start, to)
+            
359        def generateseries_sql(self, expression: exp.GenerateSeries) -> str:
+360            start = expression.args["start"]
+361            end = expression.args["end"]
+362            step = expression.args.get("step")
+363
+364            if isinstance(start, exp.Cast):
+365                target_type = start.to
+366            elif isinstance(end, exp.Cast):
+367                target_type = end.to
+368            else:
+369                target_type = None
+370
+371            if target_type and target_type.is_type("timestamp"):
+372                to = target_type.copy()
 373
-374            return self.func("SEQUENCE", start, end, step)
+374                if target_type is start.to:
+375                    end = exp.cast(end, to)
+376                else:
+377                    start = exp.cast(start, to)
+378
+379            return self.func("SEQUENCE", start, end, step)
 
@@ -1946,13 +1959,13 @@ Default: True
-
376        def offset_limit_modifiers(
-377            self, expression: exp.Expression, fetch: bool, limit: t.Optional[exp.Fetch | exp.Limit]
-378        ) -> t.List[str]:
-379            return [
-380                self.sql(expression, "offset"),
-381                self.sql(limit),
-382            ]
+            
381        def offset_limit_modifiers(
+382            self, expression: exp.Expression, fetch: bool, limit: t.Optional[exp.Fetch | exp.Limit]
+383        ) -> t.List[str]:
+384            return [
+385                self.sql(expression, "offset"),
+386                self.sql(limit),
+387            ]
 
@@ -2045,26 +2058,26 @@ Default: True
-
246    @classmethod
-247    def can_identify(cls, text: str, identify: str | bool = "safe") -> bool:
-248        """Checks if text can be identified given an identify option.
-249
-250        Args:
-251            text: The text to check.
-252            identify:
-253                "always" or `True`: Always returns true.
-254                "safe": True if the identifier is case-insensitive.
-255
-256        Returns:
-257            Whether or not the given text can be identified.
-258        """
-259        if identify is True or identify == "always":
-260            return True
-261
-262        if identify == "safe":
-263            return not cls.case_sensitive(text)
-264
-265        return False
+            
248    @classmethod
+249    def can_identify(cls, text: str, identify: str | bool = "safe") -> bool:
+250        """Checks if text can be identified given an identify option.
+251
+252        Args:
+253            text: The text to check.
+254            identify:
+255                "always" or `True`: Always returns true.
+256                "safe": True if the identifier is case-insensitive.
+257
+258        Returns:
+259            Whether or not the given text can be identified.
+260        """
+261        if identify is True or identify == "always":
+262            return True
+263
+264        if identify == "safe":
+265            return not cls.case_sensitive(text)
+266
+267        return False
 
@@ -2520,6 +2533,7 @@ Default: True
oncluster_sql
clusteredbyproperty_sql
anyvalue_sql
+
querytransform_sql
-- cgit v1.2.3