sqlglot.dialects.bigquery
1from __future__ import annotations 2 3import logging 4import re 5import typing as t 6 7from sqlglot import exp, generator, parser, tokens, transforms 8from sqlglot._typing import E 9from sqlglot.dialects.dialect import ( 10 Dialect, 11 datestrtodate_sql, 12 format_time_lambda, 13 inline_array_sql, 14 max_or_greatest, 15 min_or_least, 16 no_ilike_sql, 17 parse_date_delta_with_interval, 18 rename_func, 19 timestrtotime_sql, 20 ts_or_ds_to_date_sql, 21) 22from sqlglot.helper import seq_get, split_num_words 23from sqlglot.tokens import TokenType 24 25logger = logging.getLogger("sqlglot") 26 27 28def _date_add_sql( 29 data_type: str, kind: str 30) -> t.Callable[[generator.Generator, exp.Expression], str]: 31 def func(self, expression): 32 this = self.sql(expression, "this") 33 unit = expression.args.get("unit") 34 unit = exp.var(unit.name.upper() if unit else "DAY") 35 interval = exp.Interval(this=expression.expression, unit=unit) 36 return f"{data_type}_{kind}({this}, {self.sql(interval)})" 37 38 return func 39 40 41def _derived_table_values_to_unnest(self: generator.Generator, expression: exp.Values) -> str: 42 if not isinstance(expression.unnest().parent, exp.From): 43 return self.values_sql(expression) 44 45 alias = expression.args.get("alias") 46 47 structs = [ 48 exp.Struct( 49 expressions=[ 50 exp.alias_(value, column_name) 51 for value, column_name in zip( 52 t.expressions, 53 alias.columns 54 if alias and alias.columns 55 else (f"_c{i}" for i in range(len(t.expressions))), 56 ) 57 ] 58 ) 59 for t in expression.find_all(exp.Tuple) 60 ] 61 62 return self.unnest_sql(exp.Unnest(expressions=[exp.Array(expressions=structs)])) 63 64 65def _returnsproperty_sql(self: generator.Generator, expression: exp.ReturnsProperty) -> str: 66 this = expression.this 67 if isinstance(this, exp.Schema): 68 this = f"{this.this} <{self.expressions(this)}>" 69 else: 70 this = self.sql(this) 71 return f"RETURNS {this}" 72 73 74def _create_sql(self: generator.Generator, expression: exp.Create) -> str: 75 kind = expression.args["kind"] 76 returns = expression.find(exp.ReturnsProperty) 77 if kind.upper() == "FUNCTION" and returns and returns.args.get("is_table"): 78 expression = expression.copy() 79 expression.set("kind", "TABLE FUNCTION") 80 if isinstance( 81 expression.expression, 82 ( 83 exp.Subquery, 84 exp.Literal, 85 ), 86 ): 87 expression.set("expression", expression.expression.this) 88 89 return self.create_sql(expression) 90 91 return self.create_sql(expression) 92 93 94def _unqualify_unnest(expression: exp.Expression) -> exp.Expression: 95 """Remove references to unnest table aliases since bigquery doesn't allow them. 96 97 These are added by the optimizer's qualify_column step. 98 """ 99 from sqlglot.optimizer.scope import Scope 100 101 if isinstance(expression, exp.Select): 102 for unnest in expression.find_all(exp.Unnest): 103 if isinstance(unnest.parent, (exp.From, exp.Join)) and unnest.alias: 104 for column in Scope(expression).find_all(exp.Column): 105 if column.table == unnest.alias: 106 column.set("table", None) 107 108 return expression 109 110 111# https://issuetracker.google.com/issues/162294746 112# workaround for bigquery bug when grouping by an expression and then ordering 113# WITH x AS (SELECT 1 y) 114# SELECT y + 1 z 115# FROM x 116# GROUP BY x + 1 117# ORDER by z 118def _alias_ordered_group(expression: exp.Expression) -> exp.Expression: 119 if isinstance(expression, exp.Select): 120 group = expression.args.get("group") 121 order = expression.args.get("order") 122 123 if group and order: 124 aliases = { 125 select.this: select.args["alias"] 126 for select in expression.selects 127 if isinstance(select, exp.Alias) 128 } 129 130 for e in group.expressions: 131 alias = aliases.get(e) 132 133 if alias: 134 e.replace(exp.column(alias)) 135 136 return expression 137 138 139def _pushdown_cte_column_names(expression: exp.Expression) -> exp.Expression: 140 """BigQuery doesn't allow column names when defining a CTE, so we try to push them down.""" 141 if isinstance(expression, exp.CTE) and expression.alias_column_names: 142 cte_query = expression.this 143 144 if cte_query.is_star: 145 logger.warning( 146 "Can't push down CTE column names for star queries. Run the query through" 147 " the optimizer or use 'qualify' to expand the star projections first." 148 ) 149 return expression 150 151 column_names = expression.alias_column_names 152 expression.args["alias"].set("columns", None) 153 154 for name, select in zip(column_names, cte_query.selects): 155 to_replace = select 156 157 if isinstance(select, exp.Alias): 158 select = select.this 159 160 # Inner aliases are shadowed by the CTE column names 161 to_replace.replace(exp.alias_(select, name)) 162 163 return expression 164 165 166class BigQuery(Dialect): 167 UNNEST_COLUMN_ONLY = True 168 169 # https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#case_sensitivity 170 RESOLVES_IDENTIFIERS_AS_UPPERCASE = None 171 172 # bigquery udfs are case sensitive 173 NORMALIZE_FUNCTIONS = False 174 175 TIME_MAPPING = { 176 "%D": "%m/%d/%y", 177 } 178 179 FORMAT_MAPPING = { 180 "DD": "%d", 181 "MM": "%m", 182 "MON": "%b", 183 "MONTH": "%B", 184 "YYYY": "%Y", 185 "YY": "%y", 186 "HH": "%I", 187 "HH12": "%I", 188 "HH24": "%H", 189 "MI": "%M", 190 "SS": "%S", 191 "SSSSS": "%f", 192 "TZH": "%z", 193 } 194 195 @classmethod 196 def normalize_identifier(cls, expression: E) -> E: 197 # In BigQuery, CTEs aren't case-sensitive, but table names are (by default, at least). 198 # The following check is essentially a heuristic to detect tables based on whether or 199 # not they're qualified. 200 if isinstance(expression, exp.Identifier): 201 parent = expression.parent 202 203 while isinstance(parent, exp.Dot): 204 parent = parent.parent 205 206 if not (isinstance(parent, exp.Table) and parent.db) and not expression.meta.get( 207 "is_table" 208 ): 209 expression.set("this", expression.this.lower()) 210 211 return expression 212 213 class Tokenizer(tokens.Tokenizer): 214 QUOTES = ["'", '"', '"""', "'''"] 215 COMMENTS = ["--", "#", ("/*", "*/")] 216 IDENTIFIERS = ["`"] 217 STRING_ESCAPES = ["\\"] 218 219 HEX_STRINGS = [("0x", ""), ("0X", "")] 220 221 BYTE_STRINGS = [ 222 (prefix + q, q) for q in t.cast(t.List[str], QUOTES) for prefix in ("b", "B") 223 ] 224 225 RAW_STRINGS = [ 226 (prefix + q, q) for q in t.cast(t.List[str], QUOTES) for prefix in ("r", "R") 227 ] 228 229 KEYWORDS = { 230 **tokens.Tokenizer.KEYWORDS, 231 "ANY TYPE": TokenType.VARIANT, 232 "BEGIN": TokenType.COMMAND, 233 "BEGIN TRANSACTION": TokenType.BEGIN, 234 "CURRENT_DATETIME": TokenType.CURRENT_DATETIME, 235 "BYTES": TokenType.BINARY, 236 "DECLARE": TokenType.COMMAND, 237 "FLOAT64": TokenType.DOUBLE, 238 "INT64": TokenType.BIGINT, 239 "RECORD": TokenType.STRUCT, 240 "TIMESTAMP": TokenType.TIMESTAMPTZ, 241 "NOT DETERMINISTIC": TokenType.VOLATILE, 242 "UNKNOWN": TokenType.NULL, 243 } 244 KEYWORDS.pop("DIV") 245 246 class Parser(parser.Parser): 247 PREFIXED_PIVOT_COLUMNS = True 248 249 LOG_BASE_FIRST = False 250 LOG_DEFAULTS_TO_LN = True 251 252 FUNCTIONS = { 253 **parser.Parser.FUNCTIONS, 254 "DATE_ADD": parse_date_delta_with_interval(exp.DateAdd), 255 "DATE_SUB": parse_date_delta_with_interval(exp.DateSub), 256 "DATE_TRUNC": lambda args: exp.DateTrunc( 257 unit=exp.Literal.string(str(seq_get(args, 1))), 258 this=seq_get(args, 0), 259 ), 260 "DATETIME_ADD": parse_date_delta_with_interval(exp.DatetimeAdd), 261 "DATETIME_SUB": parse_date_delta_with_interval(exp.DatetimeSub), 262 "DIV": lambda args: exp.IntDiv(this=seq_get(args, 0), expression=seq_get(args, 1)), 263 "GENERATE_ARRAY": exp.GenerateSeries.from_arg_list, 264 "PARSE_DATE": lambda args: format_time_lambda(exp.StrToDate, "bigquery")( 265 [seq_get(args, 1), seq_get(args, 0)] 266 ), 267 "PARSE_TIMESTAMP": lambda args: format_time_lambda(exp.StrToTime, "bigquery")( 268 [seq_get(args, 1), seq_get(args, 0)] 269 ), 270 "REGEXP_CONTAINS": exp.RegexpLike.from_arg_list, 271 "REGEXP_EXTRACT": lambda args: exp.RegexpExtract( 272 this=seq_get(args, 0), 273 expression=seq_get(args, 1), 274 position=seq_get(args, 2), 275 occurrence=seq_get(args, 3), 276 group=exp.Literal.number(1) 277 if re.compile(str(seq_get(args, 1))).groups == 1 278 else None, 279 ), 280 "SPLIT": lambda args: exp.Split( 281 # https://cloud.google.com/bigquery/docs/reference/standard-sql/string_functions#split 282 this=seq_get(args, 0), 283 expression=seq_get(args, 1) or exp.Literal.string(","), 284 ), 285 "TIME_ADD": parse_date_delta_with_interval(exp.TimeAdd), 286 "TIME_SUB": parse_date_delta_with_interval(exp.TimeSub), 287 "TIMESTAMP_ADD": parse_date_delta_with_interval(exp.TimestampAdd), 288 "TIMESTAMP_SUB": parse_date_delta_with_interval(exp.TimestampSub), 289 "TO_JSON_STRING": exp.JSONFormat.from_arg_list, 290 } 291 292 FUNCTION_PARSERS = { 293 **parser.Parser.FUNCTION_PARSERS, 294 "ARRAY": lambda self: self.expression(exp.Array, expressions=[self._parse_statement()]), 295 } 296 FUNCTION_PARSERS.pop("TRIM") 297 298 NO_PAREN_FUNCTIONS = { 299 **parser.Parser.NO_PAREN_FUNCTIONS, 300 TokenType.CURRENT_DATETIME: exp.CurrentDatetime, 301 } 302 303 NESTED_TYPE_TOKENS = { 304 *parser.Parser.NESTED_TYPE_TOKENS, 305 TokenType.TABLE, 306 } 307 308 ID_VAR_TOKENS = { 309 *parser.Parser.ID_VAR_TOKENS, 310 TokenType.VALUES, 311 } 312 313 PROPERTY_PARSERS = { 314 **parser.Parser.PROPERTY_PARSERS, 315 "NOT DETERMINISTIC": lambda self: self.expression( 316 exp.StabilityProperty, this=exp.Literal.string("VOLATILE") 317 ), 318 "OPTIONS": lambda self: self._parse_with_property(), 319 } 320 321 CONSTRAINT_PARSERS = { 322 **parser.Parser.CONSTRAINT_PARSERS, 323 "OPTIONS": lambda self: exp.Properties(expressions=self._parse_with_property()), 324 } 325 326 def _parse_table_part(self, schema: bool = False) -> t.Optional[exp.Expression]: 327 this = super()._parse_table_part(schema=schema) 328 329 # https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#table_names 330 if isinstance(this, exp.Identifier): 331 table_name = this.name 332 while self._match(TokenType.DASH, advance=False) and self._next: 333 self._advance(2) 334 table_name += f"-{self._prev.text}" 335 336 this = exp.Identifier(this=table_name, quoted=this.args.get("quoted")) 337 338 return this 339 340 def _parse_table_parts(self, schema: bool = False) -> exp.Table: 341 table = super()._parse_table_parts(schema=schema) 342 if isinstance(table.this, exp.Identifier) and "." in table.name: 343 catalog, db, this, *rest = ( 344 t.cast(t.Optional[exp.Expression], exp.to_identifier(x)) 345 for x in split_num_words(table.name, ".", 3) 346 ) 347 348 if rest and this: 349 this = exp.Dot.build(t.cast(t.List[exp.Expression], [this, *rest])) 350 351 table = exp.Table(this=this, db=db, catalog=catalog) 352 353 return table 354 355 class Generator(generator.Generator): 356 EXPLICIT_UNION = True 357 INTERVAL_ALLOWS_PLURAL_FORM = False 358 JOIN_HINTS = False 359 TABLE_HINTS = False 360 LIMIT_FETCH = "LIMIT" 361 RENAME_TABLE_WITH_DB = False 362 363 TRANSFORMS = { 364 **generator.Generator.TRANSFORMS, 365 exp.ApproxDistinct: rename_func("APPROX_COUNT_DISTINCT"), 366 exp.ArraySize: rename_func("ARRAY_LENGTH"), 367 exp.Cast: transforms.preprocess([transforms.remove_precision_parameterized_types]), 368 exp.CTE: transforms.preprocess([_pushdown_cte_column_names]), 369 exp.DateAdd: _date_add_sql("DATE", "ADD"), 370 exp.DateSub: _date_add_sql("DATE", "SUB"), 371 exp.DatetimeAdd: _date_add_sql("DATETIME", "ADD"), 372 exp.DatetimeSub: _date_add_sql("DATETIME", "SUB"), 373 exp.DateDiff: lambda self, e: f"DATE_DIFF({self.sql(e, 'this')}, {self.sql(e, 'expression')}, {self.sql(e.args.get('unit', 'DAY'))})", 374 exp.DateStrToDate: datestrtodate_sql, 375 exp.DateTrunc: lambda self, e: self.func("DATE_TRUNC", e.this, e.text("unit")), 376 exp.JSONFormat: rename_func("TO_JSON_STRING"), 377 exp.GenerateSeries: rename_func("GENERATE_ARRAY"), 378 exp.GroupConcat: rename_func("STRING_AGG"), 379 exp.ILike: no_ilike_sql, 380 exp.IntDiv: rename_func("DIV"), 381 exp.Max: max_or_greatest, 382 exp.Min: min_or_least, 383 exp.RegexpExtract: lambda self, e: self.func( 384 "REGEXP_EXTRACT", 385 e.this, 386 e.expression, 387 e.args.get("position"), 388 e.args.get("occurrence"), 389 ), 390 exp.RegexpLike: rename_func("REGEXP_CONTAINS"), 391 exp.Select: transforms.preprocess( 392 [ 393 transforms.explode_to_unnest, 394 _unqualify_unnest, 395 transforms.eliminate_distinct_on, 396 _alias_ordered_group, 397 ] 398 ), 399 exp.StrToDate: lambda self, e: f"PARSE_DATE({self.format_time(e)}, {self.sql(e, 'this')})", 400 exp.StrToTime: lambda self, e: f"PARSE_TIMESTAMP({self.format_time(e)}, {self.sql(e, 'this')})", 401 exp.TimeAdd: _date_add_sql("TIME", "ADD"), 402 exp.TimeSub: _date_add_sql("TIME", "SUB"), 403 exp.TimestampAdd: _date_add_sql("TIMESTAMP", "ADD"), 404 exp.TimestampSub: _date_add_sql("TIMESTAMP", "SUB"), 405 exp.TimeStrToTime: timestrtotime_sql, 406 exp.TsOrDsToDate: ts_or_ds_to_date_sql("bigquery"), 407 exp.TsOrDsAdd: _date_add_sql("DATE", "ADD"), 408 exp.PartitionedByProperty: lambda self, e: f"PARTITION BY {self.sql(e, 'this')}", 409 exp.VariancePop: rename_func("VAR_POP"), 410 exp.Values: _derived_table_values_to_unnest, 411 exp.ReturnsProperty: _returnsproperty_sql, 412 exp.Create: _create_sql, 413 exp.Trim: lambda self, e: self.func(f"TRIM", e.this, e.expression), 414 exp.StabilityProperty: lambda self, e: f"DETERMINISTIC" 415 if e.name == "IMMUTABLE" 416 else "NOT DETERMINISTIC", 417 } 418 419 TYPE_MAPPING = { 420 **generator.Generator.TYPE_MAPPING, 421 exp.DataType.Type.BIGDECIMAL: "BIGNUMERIC", 422 exp.DataType.Type.BIGINT: "INT64", 423 exp.DataType.Type.BINARY: "BYTES", 424 exp.DataType.Type.BOOLEAN: "BOOL", 425 exp.DataType.Type.CHAR: "STRING", 426 exp.DataType.Type.DECIMAL: "NUMERIC", 427 exp.DataType.Type.DOUBLE: "FLOAT64", 428 exp.DataType.Type.FLOAT: "FLOAT64", 429 exp.DataType.Type.INT: "INT64", 430 exp.DataType.Type.NCHAR: "STRING", 431 exp.DataType.Type.NVARCHAR: "STRING", 432 exp.DataType.Type.SMALLINT: "INT64", 433 exp.DataType.Type.TEXT: "STRING", 434 exp.DataType.Type.TIMESTAMP: "DATETIME", 435 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", 436 exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP", 437 exp.DataType.Type.TINYINT: "INT64", 438 exp.DataType.Type.VARBINARY: "BYTES", 439 exp.DataType.Type.VARCHAR: "STRING", 440 exp.DataType.Type.VARIANT: "ANY TYPE", 441 } 442 443 PROPERTIES_LOCATION = { 444 **generator.Generator.PROPERTIES_LOCATION, 445 exp.PartitionedByProperty: exp.Properties.Location.POST_SCHEMA, 446 exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, 447 } 448 449 # from: https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#reserved_keywords 450 RESERVED_KEYWORDS = { 451 *generator.Generator.RESERVED_KEYWORDS, 452 "all", 453 "and", 454 "any", 455 "array", 456 "as", 457 "asc", 458 "assert_rows_modified", 459 "at", 460 "between", 461 "by", 462 "case", 463 "cast", 464 "collate", 465 "contains", 466 "create", 467 "cross", 468 "cube", 469 "current", 470 "default", 471 "define", 472 "desc", 473 "distinct", 474 "else", 475 "end", 476 "enum", 477 "escape", 478 "except", 479 "exclude", 480 "exists", 481 "extract", 482 "false", 483 "fetch", 484 "following", 485 "for", 486 "from", 487 "full", 488 "group", 489 "grouping", 490 "groups", 491 "hash", 492 "having", 493 "if", 494 "ignore", 495 "in", 496 "inner", 497 "intersect", 498 "interval", 499 "into", 500 "is", 501 "join", 502 "lateral", 503 "left", 504 "like", 505 "limit", 506 "lookup", 507 "merge", 508 "natural", 509 "new", 510 "no", 511 "not", 512 "null", 513 "nulls", 514 "of", 515 "on", 516 "or", 517 "order", 518 "outer", 519 "over", 520 "partition", 521 "preceding", 522 "proto", 523 "qualify", 524 "range", 525 "recursive", 526 "respect", 527 "right", 528 "rollup", 529 "rows", 530 "select", 531 "set", 532 "some", 533 "struct", 534 "tablesample", 535 "then", 536 "to", 537 "treat", 538 "true", 539 "unbounded", 540 "union", 541 "unnest", 542 "using", 543 "when", 544 "where", 545 "window", 546 "with", 547 "within", 548 } 549 550 def attimezone_sql(self, expression: exp.AtTimeZone) -> str: 551 if not isinstance(expression.parent, exp.Cast): 552 return self.func( 553 "TIMESTAMP", self.func("DATETIME", expression.this, expression.args.get("zone")) 554 ) 555 return super().attimezone_sql(expression) 556 557 def trycast_sql(self, expression: exp.TryCast) -> str: 558 return self.cast_sql(expression, safe_prefix="SAFE_") 559 560 def cte_sql(self, expression: exp.CTE) -> str: 561 if expression.alias_column_names: 562 self.unsupported("Column names in CTE definition are not supported.") 563 return super().cte_sql(expression) 564 565 def array_sql(self, expression: exp.Array) -> str: 566 first_arg = seq_get(expression.expressions, 0) 567 if isinstance(first_arg, exp.Subqueryable): 568 return f"ARRAY{self.wrap(self.sql(first_arg))}" 569 570 return inline_array_sql(self, expression) 571 572 def transaction_sql(self, *_) -> str: 573 return "BEGIN TRANSACTION" 574 575 def commit_sql(self, *_) -> str: 576 return "COMMIT TRANSACTION" 577 578 def rollback_sql(self, *_) -> str: 579 return "ROLLBACK TRANSACTION" 580 581 def in_unnest_op(self, expression: exp.Unnest) -> str: 582 return self.sql(expression) 583 584 def except_op(self, expression: exp.Except) -> str: 585 if not expression.args.get("distinct", False): 586 self.unsupported("EXCEPT without DISTINCT is not supported in BigQuery") 587 return f"EXCEPT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}" 588 589 def intersect_op(self, expression: exp.Intersect) -> str: 590 if not expression.args.get("distinct", False): 591 self.unsupported("INTERSECT without DISTINCT is not supported in BigQuery") 592 return f"INTERSECT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}" 593 594 def with_properties(self, properties: exp.Properties) -> str: 595 return self.properties(properties, prefix=self.seg("OPTIONS"))
logger =
<Logger sqlglot (WARNING)>
167class BigQuery(Dialect): 168 UNNEST_COLUMN_ONLY = True 169 170 # https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#case_sensitivity 171 RESOLVES_IDENTIFIERS_AS_UPPERCASE = None 172 173 # bigquery udfs are case sensitive 174 NORMALIZE_FUNCTIONS = False 175 176 TIME_MAPPING = { 177 "%D": "%m/%d/%y", 178 } 179 180 FORMAT_MAPPING = { 181 "DD": "%d", 182 "MM": "%m", 183 "MON": "%b", 184 "MONTH": "%B", 185 "YYYY": "%Y", 186 "YY": "%y", 187 "HH": "%I", 188 "HH12": "%I", 189 "HH24": "%H", 190 "MI": "%M", 191 "SS": "%S", 192 "SSSSS": "%f", 193 "TZH": "%z", 194 } 195 196 @classmethod 197 def normalize_identifier(cls, expression: E) -> E: 198 # In BigQuery, CTEs aren't case-sensitive, but table names are (by default, at least). 199 # The following check is essentially a heuristic to detect tables based on whether or 200 # not they're qualified. 201 if isinstance(expression, exp.Identifier): 202 parent = expression.parent 203 204 while isinstance(parent, exp.Dot): 205 parent = parent.parent 206 207 if not (isinstance(parent, exp.Table) and parent.db) and not expression.meta.get( 208 "is_table" 209 ): 210 expression.set("this", expression.this.lower()) 211 212 return expression 213 214 class Tokenizer(tokens.Tokenizer): 215 QUOTES = ["'", '"', '"""', "'''"] 216 COMMENTS = ["--", "#", ("/*", "*/")] 217 IDENTIFIERS = ["`"] 218 STRING_ESCAPES = ["\\"] 219 220 HEX_STRINGS = [("0x", ""), ("0X", "")] 221 222 BYTE_STRINGS = [ 223 (prefix + q, q) for q in t.cast(t.List[str], QUOTES) for prefix in ("b", "B") 224 ] 225 226 RAW_STRINGS = [ 227 (prefix + q, q) for q in t.cast(t.List[str], QUOTES) for prefix in ("r", "R") 228 ] 229 230 KEYWORDS = { 231 **tokens.Tokenizer.KEYWORDS, 232 "ANY TYPE": TokenType.VARIANT, 233 "BEGIN": TokenType.COMMAND, 234 "BEGIN TRANSACTION": TokenType.BEGIN, 235 "CURRENT_DATETIME": TokenType.CURRENT_DATETIME, 236 "BYTES": TokenType.BINARY, 237 "DECLARE": TokenType.COMMAND, 238 "FLOAT64": TokenType.DOUBLE, 239 "INT64": TokenType.BIGINT, 240 "RECORD": TokenType.STRUCT, 241 "TIMESTAMP": TokenType.TIMESTAMPTZ, 242 "NOT DETERMINISTIC": TokenType.VOLATILE, 243 "UNKNOWN": TokenType.NULL, 244 } 245 KEYWORDS.pop("DIV") 246 247 class Parser(parser.Parser): 248 PREFIXED_PIVOT_COLUMNS = True 249 250 LOG_BASE_FIRST = False 251 LOG_DEFAULTS_TO_LN = True 252 253 FUNCTIONS = { 254 **parser.Parser.FUNCTIONS, 255 "DATE_ADD": parse_date_delta_with_interval(exp.DateAdd), 256 "DATE_SUB": parse_date_delta_with_interval(exp.DateSub), 257 "DATE_TRUNC": lambda args: exp.DateTrunc( 258 unit=exp.Literal.string(str(seq_get(args, 1))), 259 this=seq_get(args, 0), 260 ), 261 "DATETIME_ADD": parse_date_delta_with_interval(exp.DatetimeAdd), 262 "DATETIME_SUB": parse_date_delta_with_interval(exp.DatetimeSub), 263 "DIV": lambda args: exp.IntDiv(this=seq_get(args, 0), expression=seq_get(args, 1)), 264 "GENERATE_ARRAY": exp.GenerateSeries.from_arg_list, 265 "PARSE_DATE": lambda args: format_time_lambda(exp.StrToDate, "bigquery")( 266 [seq_get(args, 1), seq_get(args, 0)] 267 ), 268 "PARSE_TIMESTAMP": lambda args: format_time_lambda(exp.StrToTime, "bigquery")( 269 [seq_get(args, 1), seq_get(args, 0)] 270 ), 271 "REGEXP_CONTAINS": exp.RegexpLike.from_arg_list, 272 "REGEXP_EXTRACT": lambda args: exp.RegexpExtract( 273 this=seq_get(args, 0), 274 expression=seq_get(args, 1), 275 position=seq_get(args, 2), 276 occurrence=seq_get(args, 3), 277 group=exp.Literal.number(1) 278 if re.compile(str(seq_get(args, 1))).groups == 1 279 else None, 280 ), 281 "SPLIT": lambda args: exp.Split( 282 # https://cloud.google.com/bigquery/docs/reference/standard-sql/string_functions#split 283 this=seq_get(args, 0), 284 expression=seq_get(args, 1) or exp.Literal.string(","), 285 ), 286 "TIME_ADD": parse_date_delta_with_interval(exp.TimeAdd), 287 "TIME_SUB": parse_date_delta_with_interval(exp.TimeSub), 288 "TIMESTAMP_ADD": parse_date_delta_with_interval(exp.TimestampAdd), 289 "TIMESTAMP_SUB": parse_date_delta_with_interval(exp.TimestampSub), 290 "TO_JSON_STRING": exp.JSONFormat.from_arg_list, 291 } 292 293 FUNCTION_PARSERS = { 294 **parser.Parser.FUNCTION_PARSERS, 295 "ARRAY": lambda self: self.expression(exp.Array, expressions=[self._parse_statement()]), 296 } 297 FUNCTION_PARSERS.pop("TRIM") 298 299 NO_PAREN_FUNCTIONS = { 300 **parser.Parser.NO_PAREN_FUNCTIONS, 301 TokenType.CURRENT_DATETIME: exp.CurrentDatetime, 302 } 303 304 NESTED_TYPE_TOKENS = { 305 *parser.Parser.NESTED_TYPE_TOKENS, 306 TokenType.TABLE, 307 } 308 309 ID_VAR_TOKENS = { 310 *parser.Parser.ID_VAR_TOKENS, 311 TokenType.VALUES, 312 } 313 314 PROPERTY_PARSERS = { 315 **parser.Parser.PROPERTY_PARSERS, 316 "NOT DETERMINISTIC": lambda self: self.expression( 317 exp.StabilityProperty, this=exp.Literal.string("VOLATILE") 318 ), 319 "OPTIONS": lambda self: self._parse_with_property(), 320 } 321 322 CONSTRAINT_PARSERS = { 323 **parser.Parser.CONSTRAINT_PARSERS, 324 "OPTIONS": lambda self: exp.Properties(expressions=self._parse_with_property()), 325 } 326 327 def _parse_table_part(self, schema: bool = False) -> t.Optional[exp.Expression]: 328 this = super()._parse_table_part(schema=schema) 329 330 # https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#table_names 331 if isinstance(this, exp.Identifier): 332 table_name = this.name 333 while self._match(TokenType.DASH, advance=False) and self._next: 334 self._advance(2) 335 table_name += f"-{self._prev.text}" 336 337 this = exp.Identifier(this=table_name, quoted=this.args.get("quoted")) 338 339 return this 340 341 def _parse_table_parts(self, schema: bool = False) -> exp.Table: 342 table = super()._parse_table_parts(schema=schema) 343 if isinstance(table.this, exp.Identifier) and "." in table.name: 344 catalog, db, this, *rest = ( 345 t.cast(t.Optional[exp.Expression], exp.to_identifier(x)) 346 for x in split_num_words(table.name, ".", 3) 347 ) 348 349 if rest and this: 350 this = exp.Dot.build(t.cast(t.List[exp.Expression], [this, *rest])) 351 352 table = exp.Table(this=this, db=db, catalog=catalog) 353 354 return table 355 356 class Generator(generator.Generator): 357 EXPLICIT_UNION = True 358 INTERVAL_ALLOWS_PLURAL_FORM = False 359 JOIN_HINTS = False 360 TABLE_HINTS = False 361 LIMIT_FETCH = "LIMIT" 362 RENAME_TABLE_WITH_DB = False 363 364 TRANSFORMS = { 365 **generator.Generator.TRANSFORMS, 366 exp.ApproxDistinct: rename_func("APPROX_COUNT_DISTINCT"), 367 exp.ArraySize: rename_func("ARRAY_LENGTH"), 368 exp.Cast: transforms.preprocess([transforms.remove_precision_parameterized_types]), 369 exp.CTE: transforms.preprocess([_pushdown_cte_column_names]), 370 exp.DateAdd: _date_add_sql("DATE", "ADD"), 371 exp.DateSub: _date_add_sql("DATE", "SUB"), 372 exp.DatetimeAdd: _date_add_sql("DATETIME", "ADD"), 373 exp.DatetimeSub: _date_add_sql("DATETIME", "SUB"), 374 exp.DateDiff: lambda self, e: f"DATE_DIFF({self.sql(e, 'this')}, {self.sql(e, 'expression')}, {self.sql(e.args.get('unit', 'DAY'))})", 375 exp.DateStrToDate: datestrtodate_sql, 376 exp.DateTrunc: lambda self, e: self.func("DATE_TRUNC", e.this, e.text("unit")), 377 exp.JSONFormat: rename_func("TO_JSON_STRING"), 378 exp.GenerateSeries: rename_func("GENERATE_ARRAY"), 379 exp.GroupConcat: rename_func("STRING_AGG"), 380 exp.ILike: no_ilike_sql, 381 exp.IntDiv: rename_func("DIV"), 382 exp.Max: max_or_greatest, 383 exp.Min: min_or_least, 384 exp.RegexpExtract: lambda self, e: self.func( 385 "REGEXP_EXTRACT", 386 e.this, 387 e.expression, 388 e.args.get("position"), 389 e.args.get("occurrence"), 390 ), 391 exp.RegexpLike: rename_func("REGEXP_CONTAINS"), 392 exp.Select: transforms.preprocess( 393 [ 394 transforms.explode_to_unnest, 395 _unqualify_unnest, 396 transforms.eliminate_distinct_on, 397 _alias_ordered_group, 398 ] 399 ), 400 exp.StrToDate: lambda self, e: f"PARSE_DATE({self.format_time(e)}, {self.sql(e, 'this')})", 401 exp.StrToTime: lambda self, e: f"PARSE_TIMESTAMP({self.format_time(e)}, {self.sql(e, 'this')})", 402 exp.TimeAdd: _date_add_sql("TIME", "ADD"), 403 exp.TimeSub: _date_add_sql("TIME", "SUB"), 404 exp.TimestampAdd: _date_add_sql("TIMESTAMP", "ADD"), 405 exp.TimestampSub: _date_add_sql("TIMESTAMP", "SUB"), 406 exp.TimeStrToTime: timestrtotime_sql, 407 exp.TsOrDsToDate: ts_or_ds_to_date_sql("bigquery"), 408 exp.TsOrDsAdd: _date_add_sql("DATE", "ADD"), 409 exp.PartitionedByProperty: lambda self, e: f"PARTITION BY {self.sql(e, 'this')}", 410 exp.VariancePop: rename_func("VAR_POP"), 411 exp.Values: _derived_table_values_to_unnest, 412 exp.ReturnsProperty: _returnsproperty_sql, 413 exp.Create: _create_sql, 414 exp.Trim: lambda self, e: self.func(f"TRIM", e.this, e.expression), 415 exp.StabilityProperty: lambda self, e: f"DETERMINISTIC" 416 if e.name == "IMMUTABLE" 417 else "NOT DETERMINISTIC", 418 } 419 420 TYPE_MAPPING = { 421 **generator.Generator.TYPE_MAPPING, 422 exp.DataType.Type.BIGDECIMAL: "BIGNUMERIC", 423 exp.DataType.Type.BIGINT: "INT64", 424 exp.DataType.Type.BINARY: "BYTES", 425 exp.DataType.Type.BOOLEAN: "BOOL", 426 exp.DataType.Type.CHAR: "STRING", 427 exp.DataType.Type.DECIMAL: "NUMERIC", 428 exp.DataType.Type.DOUBLE: "FLOAT64", 429 exp.DataType.Type.FLOAT: "FLOAT64", 430 exp.DataType.Type.INT: "INT64", 431 exp.DataType.Type.NCHAR: "STRING", 432 exp.DataType.Type.NVARCHAR: "STRING", 433 exp.DataType.Type.SMALLINT: "INT64", 434 exp.DataType.Type.TEXT: "STRING", 435 exp.DataType.Type.TIMESTAMP: "DATETIME", 436 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", 437 exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP", 438 exp.DataType.Type.TINYINT: "INT64", 439 exp.DataType.Type.VARBINARY: "BYTES", 440 exp.DataType.Type.VARCHAR: "STRING", 441 exp.DataType.Type.VARIANT: "ANY TYPE", 442 } 443 444 PROPERTIES_LOCATION = { 445 **generator.Generator.PROPERTIES_LOCATION, 446 exp.PartitionedByProperty: exp.Properties.Location.POST_SCHEMA, 447 exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, 448 } 449 450 # from: https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#reserved_keywords 451 RESERVED_KEYWORDS = { 452 *generator.Generator.RESERVED_KEYWORDS, 453 "all", 454 "and", 455 "any", 456 "array", 457 "as", 458 "asc", 459 "assert_rows_modified", 460 "at", 461 "between", 462 "by", 463 "case", 464 "cast", 465 "collate", 466 "contains", 467 "create", 468 "cross", 469 "cube", 470 "current", 471 "default", 472 "define", 473 "desc", 474 "distinct", 475 "else", 476 "end", 477 "enum", 478 "escape", 479 "except", 480 "exclude", 481 "exists", 482 "extract", 483 "false", 484 "fetch", 485 "following", 486 "for", 487 "from", 488 "full", 489 "group", 490 "grouping", 491 "groups", 492 "hash", 493 "having", 494 "if", 495 "ignore", 496 "in", 497 "inner", 498 "intersect", 499 "interval", 500 "into", 501 "is", 502 "join", 503 "lateral", 504 "left", 505 "like", 506 "limit", 507 "lookup", 508 "merge", 509 "natural", 510 "new", 511 "no", 512 "not", 513 "null", 514 "nulls", 515 "of", 516 "on", 517 "or", 518 "order", 519 "outer", 520 "over", 521 "partition", 522 "preceding", 523 "proto", 524 "qualify", 525 "range", 526 "recursive", 527 "respect", 528 "right", 529 "rollup", 530 "rows", 531 "select", 532 "set", 533 "some", 534 "struct", 535 "tablesample", 536 "then", 537 "to", 538 "treat", 539 "true", 540 "unbounded", 541 "union", 542 "unnest", 543 "using", 544 "when", 545 "where", 546 "window", 547 "with", 548 "within", 549 } 550 551 def attimezone_sql(self, expression: exp.AtTimeZone) -> str: 552 if not isinstance(expression.parent, exp.Cast): 553 return self.func( 554 "TIMESTAMP", self.func("DATETIME", expression.this, expression.args.get("zone")) 555 ) 556 return super().attimezone_sql(expression) 557 558 def trycast_sql(self, expression: exp.TryCast) -> str: 559 return self.cast_sql(expression, safe_prefix="SAFE_") 560 561 def cte_sql(self, expression: exp.CTE) -> str: 562 if expression.alias_column_names: 563 self.unsupported("Column names in CTE definition are not supported.") 564 return super().cte_sql(expression) 565 566 def array_sql(self, expression: exp.Array) -> str: 567 first_arg = seq_get(expression.expressions, 0) 568 if isinstance(first_arg, exp.Subqueryable): 569 return f"ARRAY{self.wrap(self.sql(first_arg))}" 570 571 return inline_array_sql(self, expression) 572 573 def transaction_sql(self, *_) -> str: 574 return "BEGIN TRANSACTION" 575 576 def commit_sql(self, *_) -> str: 577 return "COMMIT TRANSACTION" 578 579 def rollback_sql(self, *_) -> str: 580 return "ROLLBACK TRANSACTION" 581 582 def in_unnest_op(self, expression: exp.Unnest) -> str: 583 return self.sql(expression) 584 585 def except_op(self, expression: exp.Except) -> str: 586 if not expression.args.get("distinct", False): 587 self.unsupported("EXCEPT without DISTINCT is not supported in BigQuery") 588 return f"EXCEPT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}" 589 590 def intersect_op(self, expression: exp.Intersect) -> str: 591 if not expression.args.get("distinct", False): 592 self.unsupported("INTERSECT without DISTINCT is not supported in BigQuery") 593 return f"INTERSECT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}" 594 595 def with_properties(self, properties: exp.Properties) -> str: 596 return self.properties(properties, prefix=self.seg("OPTIONS"))
FORMAT_MAPPING: Dict[str, str] =
{'DD': '%d', 'MM': '%m', 'MON': '%b', 'MONTH': '%B', 'YYYY': '%Y', 'YY': '%y', 'HH': '%I', 'HH12': '%I', 'HH24': '%H', 'MI': '%M', 'SS': '%S', 'SSSSS': '%f', 'TZH': '%z'}
@classmethod
def
normalize_identifier(cls, expression: ~E) -> ~E:
196 @classmethod 197 def normalize_identifier(cls, expression: E) -> E: 198 # In BigQuery, CTEs aren't case-sensitive, but table names are (by default, at least). 199 # The following check is essentially a heuristic to detect tables based on whether or 200 # not they're qualified. 201 if isinstance(expression, exp.Identifier): 202 parent = expression.parent 203 204 while isinstance(parent, exp.Dot): 205 parent = parent.parent 206 207 if not (isinstance(parent, exp.Table) and parent.db) and not expression.meta.get( 208 "is_table" 209 ): 210 expression.set("this", expression.this.lower()) 211 212 return expression
Normalizes an unquoted identifier to either lower or upper case, thus essentially making it case-insensitive. If a dialect treats all identifiers as case-insensitive, they will be normalized regardless of being quoted or not.
tokenizer_class =
<class 'sqlglot.dialects.bigquery.BigQuery.Tokenizer'>
parser_class =
<class 'sqlglot.dialects.bigquery.BigQuery.Parser'>
generator_class =
<class 'sqlglot.dialects.bigquery.BigQuery.Generator'>
FORMAT_TRIE: Dict =
{'D': {'D': {0: True}}, 'M': {'M': {0: True}, 'O': {'N': {0: True, 'T': {'H': {0: True}}}}, 'I': {0: True}}, 'Y': {'Y': {'Y': {'Y': {0: True}}, 0: True}}, 'H': {'H': {0: True, '1': {'2': {0: True}}, '2': {'4': {0: True}}}}, 'S': {'S': {0: True, 'S': {'S': {'S': {0: True}}}}}, 'T': {'Z': {'H': {0: True}}}}
Inherited Members
- sqlglot.dialects.dialect.Dialect
- INDEX_OFFSET
- ALIAS_POST_TABLESAMPLE
- IDENTIFIERS_CAN_START_WITH_DIGIT
- STRICT_STRING_CONCAT
- NULL_ORDERING
- DATE_FORMAT
- DATEINT_FORMAT
- TIME_FORMAT
- get_or_raise
- format_time
- case_sensitive
- can_identify
- quote_identifier
- parse
- parse_into
- generate
- transpile
- tokenize
- tokenizer
- parser
- generator
214 class Tokenizer(tokens.Tokenizer): 215 QUOTES = ["'", '"', '"""', "'''"] 216 COMMENTS = ["--", "#", ("/*", "*/")] 217 IDENTIFIERS = ["`"] 218 STRING_ESCAPES = ["\\"] 219 220 HEX_STRINGS = [("0x", ""), ("0X", "")] 221 222 BYTE_STRINGS = [ 223 (prefix + q, q) for q in t.cast(t.List[str], QUOTES) for prefix in ("b", "B") 224 ] 225 226 RAW_STRINGS = [ 227 (prefix + q, q) for q in t.cast(t.List[str], QUOTES) for prefix in ("r", "R") 228 ] 229 230 KEYWORDS = { 231 **tokens.Tokenizer.KEYWORDS, 232 "ANY TYPE": TokenType.VARIANT, 233 "BEGIN": TokenType.COMMAND, 234 "BEGIN TRANSACTION": TokenType.BEGIN, 235 "CURRENT_DATETIME": TokenType.CURRENT_DATETIME, 236 "BYTES": TokenType.BINARY, 237 "DECLARE": TokenType.COMMAND, 238 "FLOAT64": TokenType.DOUBLE, 239 "INT64": TokenType.BIGINT, 240 "RECORD": TokenType.STRUCT, 241 "TIMESTAMP": TokenType.TIMESTAMPTZ, 242 "NOT DETERMINISTIC": TokenType.VOLATILE, 243 "UNKNOWN": TokenType.NULL, 244 } 245 KEYWORDS.pop("DIV")
BYTE_STRINGS =
[("b'", "'"), ("B'", "'"), ('b"', '"'), ('B"', '"'), ('b"""', '"""'), ('B"""', '"""'), ("b'''", "'''"), ("B'''", "'''")]
RAW_STRINGS =
[("r'", "'"), ("R'", "'"), ('r"', '"'), ('R"', '"'), ('r"""', '"""'), ('R"""', '"""'), ("r'''", "'''"), ("R'''", "'''")]
KEYWORDS =
{'{%': <TokenType.BLOCK_START: 'BLOCK_START'>, '{%+': <TokenType.BLOCK_START: 'BLOCK_START'>, '{%-': <TokenType.BLOCK_START: 'BLOCK_START'>, '%}': <TokenType.BLOCK_END: 'BLOCK_END'>, '+%}': <TokenType.BLOCK_END: 'BLOCK_END'>, '-%}': <TokenType.BLOCK_END: 'BLOCK_END'>, '{{+': <TokenType.BLOCK_START: 'BLOCK_START'>, '{{-': <TokenType.BLOCK_START: 'BLOCK_START'>, '+}}': <TokenType.BLOCK_END: 'BLOCK_END'>, '-}}': <TokenType.BLOCK_END: 'BLOCK_END'>, '/*+': <TokenType.HINT: 'HINT'>, '==': <TokenType.EQ: 'EQ'>, '::': <TokenType.DCOLON: 'DCOLON'>, '||': <TokenType.DPIPE: 'DPIPE'>, '>=': <TokenType.GTE: 'GTE'>, '<=': <TokenType.LTE: 'LTE'>, '<>': <TokenType.NEQ: 'NEQ'>, '!=': <TokenType.NEQ: 'NEQ'>, '<=>': <TokenType.NULLSAFE_EQ: 'NULLSAFE_EQ'>, '->': <TokenType.ARROW: 'ARROW'>, '->>': <TokenType.DARROW: 'DARROW'>, '=>': <TokenType.FARROW: 'FARROW'>, '#>': <TokenType.HASH_ARROW: 'HASH_ARROW'>, '#>>': <TokenType.DHASH_ARROW: 'DHASH_ARROW'>, '<->': <TokenType.LR_ARROW: 'LR_ARROW'>, '&&': <TokenType.DAMP: 'DAMP'>, 'ALL': <TokenType.ALL: 'ALL'>, 'ALWAYS': <TokenType.ALWAYS: 'ALWAYS'>, 'AND': <TokenType.AND: 'AND'>, 'ANTI': <TokenType.ANTI: 'ANTI'>, 'ANY': <TokenType.ANY: 'ANY'>, 'ASC': <TokenType.ASC: 'ASC'>, 'AS': <TokenType.ALIAS: 'ALIAS'>, 'ASOF': <TokenType.ASOF: 'ASOF'>, 'AUTOINCREMENT': <TokenType.AUTO_INCREMENT: 'AUTO_INCREMENT'>, 'AUTO_INCREMENT': <TokenType.AUTO_INCREMENT: 'AUTO_INCREMENT'>, 'BEGIN': <TokenType.COMMAND: 'COMMAND'>, 'BETWEEN': <TokenType.BETWEEN: 'BETWEEN'>, 'CACHE': <TokenType.CACHE: 'CACHE'>, 'UNCACHE': <TokenType.UNCACHE: 'UNCACHE'>, 'CASE': <TokenType.CASE: 'CASE'>, 'CHARACTER SET': <TokenType.CHARACTER_SET: 'CHARACTER_SET'>, 'CLUSTER BY': <TokenType.CLUSTER_BY: 'CLUSTER_BY'>, 'COLLATE': <TokenType.COLLATE: 'COLLATE'>, 'COLUMN': <TokenType.COLUMN: 'COLUMN'>, 'COMMIT': <TokenType.COMMIT: 'COMMIT'>, 'CONSTRAINT': <TokenType.CONSTRAINT: 'CONSTRAINT'>, 'CREATE': <TokenType.CREATE: 'CREATE'>, 'CROSS': <TokenType.CROSS: 'CROSS'>, 'CUBE': <TokenType.CUBE: 'CUBE'>, 'CURRENT_DATE': <TokenType.CURRENT_DATE: 'CURRENT_DATE'>, 'CURRENT_TIME': <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, 'CURRENT_TIMESTAMP': <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>, 'CURRENT_USER': <TokenType.CURRENT_USER: 'CURRENT_USER'>, 'DATABASE': <TokenType.DATABASE: 'DATABASE'>, 'DEFAULT': <TokenType.DEFAULT: 'DEFAULT'>, 'DELETE': <TokenType.DELETE: 'DELETE'>, 'DESC': <TokenType.DESC: 'DESC'>, 'DESCRIBE': <TokenType.DESCRIBE: 'DESCRIBE'>, 'DISTINCT': <TokenType.DISTINCT: 'DISTINCT'>, 'DISTRIBUTE BY': <TokenType.DISTRIBUTE_BY: 'DISTRIBUTE_BY'>, 'DROP': <TokenType.DROP: 'DROP'>, 'ELSE': <TokenType.ELSE: 'ELSE'>, 'END': <TokenType.END: 'END'>, 'ESCAPE': <TokenType.ESCAPE: 'ESCAPE'>, 'EXCEPT': <TokenType.EXCEPT: 'EXCEPT'>, 'EXECUTE': <TokenType.EXECUTE: 'EXECUTE'>, 'EXISTS': <TokenType.EXISTS: 'EXISTS'>, 'FALSE': <TokenType.FALSE: 'FALSE'>, 'FETCH': <TokenType.FETCH: 'FETCH'>, 'FILTER': <TokenType.FILTER: 'FILTER'>, 'FIRST': <TokenType.FIRST: 'FIRST'>, 'FULL': <TokenType.FULL: 'FULL'>, 'FUNCTION': <TokenType.FUNCTION: 'FUNCTION'>, 'FOR': <TokenType.FOR: 'FOR'>, 'FOREIGN KEY': <TokenType.FOREIGN_KEY: 'FOREIGN_KEY'>, 'FORMAT': <TokenType.FORMAT: 'FORMAT'>, 'FROM': <TokenType.FROM: 'FROM'>, 'GEOGRAPHY': <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, 'GEOMETRY': <TokenType.GEOMETRY: 'GEOMETRY'>, 'GLOB': <TokenType.GLOB: 'GLOB'>, 'GROUP BY': <TokenType.GROUP_BY: 'GROUP_BY'>, 'GROUPING SETS': <TokenType.GROUPING_SETS: 'GROUPING_SETS'>, 'HAVING': <TokenType.HAVING: 'HAVING'>, 'IF': <TokenType.IF: 'IF'>, 'ILIKE': <TokenType.ILIKE: 'ILIKE'>, 'IN': <TokenType.IN: 'IN'>, 'INDEX': <TokenType.INDEX: 'INDEX'>, 'INET': <TokenType.INET: 'INET'>, 'INNER': <TokenType.INNER: 'INNER'>, 'INSERT': <TokenType.INSERT: 'INSERT'>, 'INTERVAL': <TokenType.INTERVAL: 'INTERVAL'>, 'INTERSECT': <TokenType.INTERSECT: 'INTERSECT'>, 'INTO': <TokenType.INTO: 'INTO'>, 'IS': <TokenType.IS: 'IS'>, 'ISNULL': <TokenType.ISNULL: 'ISNULL'>, 'JOIN': <TokenType.JOIN: 'JOIN'>, 'KEEP': <TokenType.KEEP: 'KEEP'>, 'LATERAL': <TokenType.LATERAL: 'LATERAL'>, 'LEFT': <TokenType.LEFT: 'LEFT'>, 'LIKE': <TokenType.LIKE: 'LIKE'>, 'LIMIT': <TokenType.LIMIT: 'LIMIT'>, 'LOAD': <TokenType.LOAD: 'LOAD'>, 'LOCK': <TokenType.LOCK: 'LOCK'>, 'MERGE': <TokenType.MERGE: 'MERGE'>, 'NATURAL': <TokenType.NATURAL: 'NATURAL'>, 'NEXT': <TokenType.NEXT: 'NEXT'>, 'NEXT VALUE FOR': <TokenType.NEXT_VALUE_FOR: 'NEXT_VALUE_FOR'>, 'NOT': <TokenType.NOT: 'NOT'>, 'NOTNULL': <TokenType.NOTNULL: 'NOTNULL'>, 'NULL': <TokenType.NULL: 'NULL'>, 'OBJECT': <TokenType.OBJECT: 'OBJECT'>, 'OFFSET': <TokenType.OFFSET: 'OFFSET'>, 'ON': <TokenType.ON: 'ON'>, 'OR': <TokenType.OR: 'OR'>, 'ORDER BY': <TokenType.ORDER_BY: 'ORDER_BY'>, 'ORDINALITY': <TokenType.ORDINALITY: 'ORDINALITY'>, 'OUTER': <TokenType.OUTER: 'OUTER'>, 'OVER': <TokenType.OVER: 'OVER'>, 'OVERLAPS': <TokenType.OVERLAPS: 'OVERLAPS'>, 'OVERWRITE': <TokenType.OVERWRITE: 'OVERWRITE'>, 'PARTITION': <TokenType.PARTITION: 'PARTITION'>, 'PARTITION BY': <TokenType.PARTITION_BY: 'PARTITION_BY'>, 'PARTITIONED BY': <TokenType.PARTITION_BY: 'PARTITION_BY'>, 'PARTITIONED_BY': <TokenType.PARTITION_BY: 'PARTITION_BY'>, 'PERCENT': <TokenType.PERCENT: 'PERCENT'>, 'PIVOT': <TokenType.PIVOT: 'PIVOT'>, 'PRAGMA': <TokenType.PRAGMA: 'PRAGMA'>, 'PRIMARY KEY': <TokenType.PRIMARY_KEY: 'PRIMARY_KEY'>, 'PROCEDURE': <TokenType.PROCEDURE: 'PROCEDURE'>, 'QUALIFY': <TokenType.QUALIFY: 'QUALIFY'>, 'RANGE': <TokenType.RANGE: 'RANGE'>, 'RECURSIVE': <TokenType.RECURSIVE: 'RECURSIVE'>, 'REGEXP': <TokenType.RLIKE: 'RLIKE'>, 'REPLACE': <TokenType.REPLACE: 'REPLACE'>, 'RETURNING': <TokenType.RETURNING: 'RETURNING'>, 'REFERENCES': <TokenType.REFERENCES: 'REFERENCES'>, 'RIGHT': <TokenType.RIGHT: 'RIGHT'>, 'RLIKE': <TokenType.RLIKE: 'RLIKE'>, 'ROLLBACK': <TokenType.ROLLBACK: 'ROLLBACK'>, 'ROLLUP': <TokenType.ROLLUP: 'ROLLUP'>, 'ROW': <TokenType.ROW: 'ROW'>, 'ROWS': <TokenType.ROWS: 'ROWS'>, 'SCHEMA': <TokenType.SCHEMA: 'SCHEMA'>, 'SELECT': <TokenType.SELECT: 'SELECT'>, 'SEMI': <TokenType.SEMI: 'SEMI'>, 'SET': <TokenType.SET: 'SET'>, 'SETTINGS': <TokenType.SETTINGS: 'SETTINGS'>, 'SHOW': <TokenType.SHOW: 'SHOW'>, 'SIMILAR TO': <TokenType.SIMILAR_TO: 'SIMILAR_TO'>, 'SOME': <TokenType.SOME: 'SOME'>, 'SORT BY': <TokenType.SORT_BY: 'SORT_BY'>, 'TABLE': <TokenType.TABLE: 'TABLE'>, 'TABLESAMPLE': <TokenType.TABLE_SAMPLE: 'TABLE_SAMPLE'>, 'TEMP': <TokenType.TEMPORARY: 'TEMPORARY'>, 'TEMPORARY': <TokenType.TEMPORARY: 'TEMPORARY'>, 'THEN': <TokenType.THEN: 'THEN'>, 'TRUE': <TokenType.TRUE: 'TRUE'>, 'UNION': <TokenType.UNION: 'UNION'>, 'UNNEST': <TokenType.UNNEST: 'UNNEST'>, 'UNPIVOT': <TokenType.UNPIVOT: 'UNPIVOT'>, 'UPDATE': <TokenType.UPDATE: 'UPDATE'>, 'USE': <TokenType.USE: 'USE'>, 'USING': <TokenType.USING: 'USING'>, 'UUID': <TokenType.UUID: 'UUID'>, 'VALUES': <TokenType.VALUES: 'VALUES'>, 'VIEW': <TokenType.VIEW: 'VIEW'>, 'VOLATILE': <TokenType.VOLATILE: 'VOLATILE'>, 'WHEN': <TokenType.WHEN: 'WHEN'>, 'WHERE': <TokenType.WHERE: 'WHERE'>, 'WINDOW': <TokenType.WINDOW: 'WINDOW'>, 'WITH': <TokenType.WITH: 'WITH'>, 'APPLY': <TokenType.APPLY: 'APPLY'>, 'ARRAY': <TokenType.ARRAY: 'ARRAY'>, 'BIT': <TokenType.BIT: 'BIT'>, 'BOOL': <TokenType.BOOLEAN: 'BOOLEAN'>, 'BOOLEAN': <TokenType.BOOLEAN: 'BOOLEAN'>, 'BYTE': <TokenType.TINYINT: 'TINYINT'>, 'TINYINT': <TokenType.TINYINT: 'TINYINT'>, 'SHORT': <TokenType.SMALLINT: 'SMALLINT'>, 'SMALLINT': <TokenType.SMALLINT: 'SMALLINT'>, 'INT2': <TokenType.SMALLINT: 'SMALLINT'>, 'INTEGER': <TokenType.INT: 'INT'>, 'INT': <TokenType.INT: 'INT'>, 'INT4': <TokenType.INT: 'INT'>, 'LONG': <TokenType.BIGINT: 'BIGINT'>, 'BIGINT': <TokenType.BIGINT: 'BIGINT'>, 'INT8': <TokenType.BIGINT: 'BIGINT'>, 'DEC': <TokenType.DECIMAL: 'DECIMAL'>, 'DECIMAL': <TokenType.DECIMAL: 'DECIMAL'>, 'BIGDECIMAL': <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, 'BIGNUMERIC': <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, 'MAP': <TokenType.MAP: 'MAP'>, 'NULLABLE': <TokenType.NULLABLE: 'NULLABLE'>, 'NUMBER': <TokenType.DECIMAL: 'DECIMAL'>, 'NUMERIC': <TokenType.DECIMAL: 'DECIMAL'>, 'FIXED': <TokenType.DECIMAL: 'DECIMAL'>, 'REAL': <TokenType.FLOAT: 'FLOAT'>, 'FLOAT': <TokenType.FLOAT: 'FLOAT'>, 'FLOAT4': <TokenType.FLOAT: 'FLOAT'>, 'FLOAT8': <TokenType.DOUBLE: 'DOUBLE'>, 'DOUBLE': <TokenType.DOUBLE: 'DOUBLE'>, 'DOUBLE PRECISION': <TokenType.DOUBLE: 'DOUBLE'>, 'JSON': <TokenType.JSON: 'JSON'>, 'CHAR': <TokenType.CHAR: 'CHAR'>, 'CHARACTER': <TokenType.CHAR: 'CHAR'>, 'NCHAR': <TokenType.NCHAR: 'NCHAR'>, 'VARCHAR': <TokenType.VARCHAR: 'VARCHAR'>, 'VARCHAR2': <TokenType.VARCHAR: 'VARCHAR'>, 'NVARCHAR': <TokenType.NVARCHAR: 'NVARCHAR'>, 'NVARCHAR2': <TokenType.NVARCHAR: 'NVARCHAR'>, 'STR': <TokenType.TEXT: 'TEXT'>, 'STRING': <TokenType.TEXT: 'TEXT'>, 'TEXT': <TokenType.TEXT: 'TEXT'>, 'CLOB': <TokenType.TEXT: 'TEXT'>, 'LONGVARCHAR': <TokenType.TEXT: 'TEXT'>, 'BINARY': <TokenType.BINARY: 'BINARY'>, 'BLOB': <TokenType.VARBINARY: 'VARBINARY'>, 'BYTEA': <TokenType.VARBINARY: 'VARBINARY'>, 'VARBINARY': <TokenType.VARBINARY: 'VARBINARY'>, 'TIME': <TokenType.TIME: 'TIME'>, 'TIMESTAMP': <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, 'TIMESTAMPTZ': <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, 'TIMESTAMPLTZ': <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, 'DATE': <TokenType.DATE: 'DATE'>, 'DATETIME': <TokenType.DATETIME: 'DATETIME'>, 'INT4RANGE': <TokenType.INT4RANGE: 'INT4RANGE'>, 'INT4MULTIRANGE': <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, 'INT8RANGE': <TokenType.INT8RANGE: 'INT8RANGE'>, 'INT8MULTIRANGE': <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, 'NUMRANGE': <TokenType.NUMRANGE: 'NUMRANGE'>, 'NUMMULTIRANGE': <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, 'TSRANGE': <TokenType.TSRANGE: 'TSRANGE'>, 'TSMULTIRANGE': <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, 'TSTZRANGE': <TokenType.TSTZRANGE: 'TSTZRANGE'>, 'TSTZMULTIRANGE': <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, 'DATERANGE': <TokenType.DATERANGE: 'DATERANGE'>, 'DATEMULTIRANGE': <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, 'UNIQUE': <TokenType.UNIQUE: 'UNIQUE'>, 'STRUCT': <TokenType.STRUCT: 'STRUCT'>, 'VARIANT': <TokenType.VARIANT: 'VARIANT'>, 'ALTER': <TokenType.ALTER: 'ALTER'>, 'ANALYZE': <TokenType.COMMAND: 'COMMAND'>, 'CALL': <TokenType.COMMAND: 'COMMAND'>, 'COMMENT': <TokenType.COMMENT: 'COMMENT'>, 'COPY': <TokenType.COMMAND: 'COMMAND'>, 'EXPLAIN': <TokenType.COMMAND: 'COMMAND'>, 'GRANT': <TokenType.COMMAND: 'COMMAND'>, 'OPTIMIZE': <TokenType.COMMAND: 'COMMAND'>, 'PREPARE': <TokenType.COMMAND: 'COMMAND'>, 'TRUNCATE': <TokenType.COMMAND: 'COMMAND'>, 'VACUUM': <TokenType.COMMAND: 'COMMAND'>, 'USER-DEFINED': <TokenType.USERDEFINED: 'USERDEFINED'>, 'ANY TYPE': <TokenType.VARIANT: 'VARIANT'>, 'BEGIN TRANSACTION': <TokenType.BEGIN: 'BEGIN'>, 'CURRENT_DATETIME': <TokenType.CURRENT_DATETIME: 'CURRENT_DATETIME'>, 'BYTES': <TokenType.BINARY: 'BINARY'>, 'DECLARE': <TokenType.COMMAND: 'COMMAND'>, 'FLOAT64': <TokenType.DOUBLE: 'DOUBLE'>, 'INT64': <TokenType.BIGINT: 'BIGINT'>, 'RECORD': <TokenType.STRUCT: 'STRUCT'>, 'NOT DETERMINISTIC': <TokenType.VOLATILE: 'VOLATILE'>, 'UNKNOWN': <TokenType.NULL: 'NULL'>}
247 class Parser(parser.Parser): 248 PREFIXED_PIVOT_COLUMNS = True 249 250 LOG_BASE_FIRST = False 251 LOG_DEFAULTS_TO_LN = True 252 253 FUNCTIONS = { 254 **parser.Parser.FUNCTIONS, 255 "DATE_ADD": parse_date_delta_with_interval(exp.DateAdd), 256 "DATE_SUB": parse_date_delta_with_interval(exp.DateSub), 257 "DATE_TRUNC": lambda args: exp.DateTrunc( 258 unit=exp.Literal.string(str(seq_get(args, 1))), 259 this=seq_get(args, 0), 260 ), 261 "DATETIME_ADD": parse_date_delta_with_interval(exp.DatetimeAdd), 262 "DATETIME_SUB": parse_date_delta_with_interval(exp.DatetimeSub), 263 "DIV": lambda args: exp.IntDiv(this=seq_get(args, 0), expression=seq_get(args, 1)), 264 "GENERATE_ARRAY": exp.GenerateSeries.from_arg_list, 265 "PARSE_DATE": lambda args: format_time_lambda(exp.StrToDate, "bigquery")( 266 [seq_get(args, 1), seq_get(args, 0)] 267 ), 268 "PARSE_TIMESTAMP": lambda args: format_time_lambda(exp.StrToTime, "bigquery")( 269 [seq_get(args, 1), seq_get(args, 0)] 270 ), 271 "REGEXP_CONTAINS": exp.RegexpLike.from_arg_list, 272 "REGEXP_EXTRACT": lambda args: exp.RegexpExtract( 273 this=seq_get(args, 0), 274 expression=seq_get(args, 1), 275 position=seq_get(args, 2), 276 occurrence=seq_get(args, 3), 277 group=exp.Literal.number(1) 278 if re.compile(str(seq_get(args, 1))).groups == 1 279 else None, 280 ), 281 "SPLIT": lambda args: exp.Split( 282 # https://cloud.google.com/bigquery/docs/reference/standard-sql/string_functions#split 283 this=seq_get(args, 0), 284 expression=seq_get(args, 1) or exp.Literal.string(","), 285 ), 286 "TIME_ADD": parse_date_delta_with_interval(exp.TimeAdd), 287 "TIME_SUB": parse_date_delta_with_interval(exp.TimeSub), 288 "TIMESTAMP_ADD": parse_date_delta_with_interval(exp.TimestampAdd), 289 "TIMESTAMP_SUB": parse_date_delta_with_interval(exp.TimestampSub), 290 "TO_JSON_STRING": exp.JSONFormat.from_arg_list, 291 } 292 293 FUNCTION_PARSERS = { 294 **parser.Parser.FUNCTION_PARSERS, 295 "ARRAY": lambda self: self.expression(exp.Array, expressions=[self._parse_statement()]), 296 } 297 FUNCTION_PARSERS.pop("TRIM") 298 299 NO_PAREN_FUNCTIONS = { 300 **parser.Parser.NO_PAREN_FUNCTIONS, 301 TokenType.CURRENT_DATETIME: exp.CurrentDatetime, 302 } 303 304 NESTED_TYPE_TOKENS = { 305 *parser.Parser.NESTED_TYPE_TOKENS, 306 TokenType.TABLE, 307 } 308 309 ID_VAR_TOKENS = { 310 *parser.Parser.ID_VAR_TOKENS, 311 TokenType.VALUES, 312 } 313 314 PROPERTY_PARSERS = { 315 **parser.Parser.PROPERTY_PARSERS, 316 "NOT DETERMINISTIC": lambda self: self.expression( 317 exp.StabilityProperty, this=exp.Literal.string("VOLATILE") 318 ), 319 "OPTIONS": lambda self: self._parse_with_property(), 320 } 321 322 CONSTRAINT_PARSERS = { 323 **parser.Parser.CONSTRAINT_PARSERS, 324 "OPTIONS": lambda self: exp.Properties(expressions=self._parse_with_property()), 325 } 326 327 def _parse_table_part(self, schema: bool = False) -> t.Optional[exp.Expression]: 328 this = super()._parse_table_part(schema=schema) 329 330 # https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#table_names 331 if isinstance(this, exp.Identifier): 332 table_name = this.name 333 while self._match(TokenType.DASH, advance=False) and self._next: 334 self._advance(2) 335 table_name += f"-{self._prev.text}" 336 337 this = exp.Identifier(this=table_name, quoted=this.args.get("quoted")) 338 339 return this 340 341 def _parse_table_parts(self, schema: bool = False) -> exp.Table: 342 table = super()._parse_table_parts(schema=schema) 343 if isinstance(table.this, exp.Identifier) and "." in table.name: 344 catalog, db, this, *rest = ( 345 t.cast(t.Optional[exp.Expression], exp.to_identifier(x)) 346 for x in split_num_words(table.name, ".", 3) 347 ) 348 349 if rest and this: 350 this = exp.Dot.build(t.cast(t.List[exp.Expression], [this, *rest])) 351 352 table = exp.Table(this=this, db=db, catalog=catalog) 353 354 return table
Parser consumes a list of tokens produced by the Tokenizer and produces a parsed syntax tree.
Arguments:
- error_level: The desired error level. Default: ErrorLevel.IMMEDIATE
- error_message_context: Determines the amount of context to capture from a query string when displaying the error message (in number of characters). Default: 100
- max_errors: Maximum number of error messages to include in a raised ParseError. This is only relevant if error_level is ErrorLevel.RAISE. 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 parse_date_delta_with_interval.<locals>.func>, 'DATEDIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateDiff'>>, 'DATE_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateDiff'>>, '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': <function parse_date_delta_with_interval.<locals>.func>, 'DATE_TO_DATE_STR': <function Parser.<lambda>>, 'DATE_TO_DI': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DateToDi'>>, 'DATE_TRUNC': <function BigQuery.Parser.<lambda>>, 'DATETIME_ADD': <function parse_date_delta_with_interval.<locals>.func>, 'DATETIME_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.DatetimeDiff'>>, 'DATETIME_SUB': <function parse_date_delta_with_interval.<locals>.func>, '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'>>, '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'>>, '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 BigQuery.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': <function BigQuery.Parser.<lambda>>, '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': <function parse_date_delta_with_interval.<locals>.func>, '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': <function parse_date_delta_with_interval.<locals>.func>, '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': <function parse_date_delta_with_interval.<locals>.func>, 'TIMESTAMP_DIFF': <bound method Func.from_arg_list of <class 'sqlglot.expressions.TimestampDiff'>>, 'TIMESTAMP_SUB': <function parse_date_delta_with_interval.<locals>.func>, '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>, 'DIV': <function BigQuery.Parser.<lambda>>, 'GENERATE_ARRAY': <bound method Func.from_arg_list of <class 'sqlglot.expressions.GenerateSeries'>>, 'PARSE_DATE': <function BigQuery.Parser.<lambda>>, 'PARSE_TIMESTAMP': <function BigQuery.Parser.<lambda>>, 'REGEXP_CONTAINS': <bound method Func.from_arg_list of <class 'sqlglot.expressions.RegexpLike'>>, 'TO_JSON_STRING': <bound method Func.from_arg_list of <class 'sqlglot.expressions.JSONFormat'>>}
FUNCTION_PARSERS =
{'ANY_VALUE': <function Parser.<lambda>>, 'CAST': <function Parser.<lambda>>, 'CONCAT': <function Parser.<lambda>>, 'CONVERT': <function Parser.<lambda>>, 'DECODE': <function Parser.<lambda>>, 'EXTRACT': <function Parser.<lambda>>, 'JSON_OBJECT': <function Parser.<lambda>>, 'LOG': <function Parser.<lambda>>, 'MATCH': <function Parser.<lambda>>, 'OPENJSON': <function Parser.<lambda>>, 'POSITION': <function Parser.<lambda>>, 'SAFE_CAST': <function Parser.<lambda>>, 'STRING_AGG': <function Parser.<lambda>>, 'SUBSTRING': <function Parser.<lambda>>, 'TRY_CAST': <function Parser.<lambda>>, 'TRY_CONVERT': <function Parser.<lambda>>, 'ARRAY': <function BigQuery.Parser.<lambda>>}
NO_PAREN_FUNCTIONS =
{<TokenType.CURRENT_DATE: 'CURRENT_DATE'>: <class 'sqlglot.expressions.CurrentDate'>, <TokenType.CURRENT_DATETIME: 'CURRENT_DATETIME'>: <class 'sqlglot.expressions.CurrentDatetime'>, <TokenType.CURRENT_TIME: 'CURRENT_TIME'>: <class 'sqlglot.expressions.CurrentTime'>, <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>: <class 'sqlglot.expressions.CurrentTimestamp'>, <TokenType.CURRENT_USER: 'CURRENT_USER'>: <class 'sqlglot.expressions.CurrentUser'>}
NESTED_TYPE_TOKENS =
{<TokenType.STRUCT: 'STRUCT'>, <TokenType.TABLE: 'TABLE'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.MAP: 'MAP'>, <TokenType.ARRAY: 'ARRAY'>}
ID_VAR_TOKENS =
{<TokenType.PRAGMA: 'PRAGMA'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.COMMENT: 'COMMENT'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.FILTER: 'FILTER'>, <TokenType.UINT128: 'UINT128'>, <TokenType.CURRENT_DATE: 'CURRENT_DATE'>, <TokenType.FUNCTION: 'FUNCTION'>, <TokenType.COMMAND: 'COMMAND'>, <TokenType.CASE: 'CASE'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.MERGE: 'MERGE'>, <TokenType.CONSTRAINT: 'CONSTRAINT'>, <TokenType.RIGHT: 'RIGHT'>, <TokenType.CHAR: 'CHAR'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.SET: 'SET'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.VIEW: 'VIEW'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.UNPIVOT: 'UNPIVOT'>, <TokenType.INET: 'INET'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.TIME: 'TIME'>, <TokenType.COMMIT: 'COMMIT'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.MAP: 'MAP'>, <TokenType.SEMI: 'SEMI'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.END: 'END'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.TOP: 'TOP'>, <TokenType.LOAD: 'LOAD'>, <TokenType.VOLATILE: 'VOLATILE'>, <TokenType.CURRENT_DATETIME: 'CURRENT_DATETIME'>, <TokenType.KEEP: 'KEEP'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.UUID: 'UUID'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.VALUES: 'VALUES'>, <TokenType.BEGIN: 'BEGIN'>, <TokenType.DESC: 'DESC'>, <TokenType.ASC: 'ASC'>, <TokenType.DIV: 'DIV'>, <TokenType.FORMAT: 'FORMAT'>, <TokenType.TRUE: 'TRUE'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.SUPER: 'SUPER'>, <TokenType.DATABASE: 'DATABASE'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.APPLY: 'APPLY'>, <TokenType.SHOW: 'SHOW'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.CACHE: 'CACHE'>, <TokenType.IF: 'IF'>, <TokenType.INT128: 'INT128'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.INT256: 'INT256'>, <TokenType.DICTIONARY: 'DICTIONARY'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.DATE: 'DATE'>, <TokenType.SOME: 'SOME'>, <TokenType.ROWS: 'ROWS'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.TABLE: 'TABLE'>, <TokenType.TEXT: 'TEXT'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.OVERWRITE: 'OVERWRITE'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.UNIQUE: 'UNIQUE'>, <TokenType.AUTO_INCREMENT: 'AUTO_INCREMENT'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.SETTINGS: 'SETTINGS'>, <TokenType.XML: 'XML'>, <TokenType.ROW: 'ROW'>, <TokenType.OFFSET: 'OFFSET'>, <TokenType.DELETE: 'DELETE'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.NEXT: 'NEXT'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.UINT256: 'UINT256'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.JSONB: 'JSONB'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.UINT: 'UINT'>, <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, <TokenType.FIRST: 'FIRST'>, <TokenType.ISNULL: 'ISNULL'>, <TokenType.FALSE: 'FALSE'>, <TokenType.PIVOT: 'PIVOT'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.ALL: 'ALL'>, <TokenType.COLUMN: 'COLUMN'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>, <TokenType.SCHEMA: 'SCHEMA'>, <TokenType.REFERENCES: 'REFERENCES'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.ANY: 'ANY'>, <TokenType.DEFAULT: 'DEFAULT'>, <TokenType.CURRENT_USER: 'CURRENT_USER'>, <TokenType.ESCAPE: 'ESCAPE'>, <TokenType.NATURAL: 'NATURAL'>, <TokenType.PERCENT: 'PERCENT'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.WINDOW: 'WINDOW'>, <TokenType.MONEY: 'MONEY'>, <TokenType.JSON: 'JSON'>, <TokenType.PARTITION: 'PARTITION'>, <TokenType.IS: 'IS'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.EXISTS: 'EXISTS'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.COLLATE: 'COLLATE'>, <TokenType.UPDATE: 'UPDATE'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.INT: 'INT'>, <TokenType.BINARY: 'BINARY'>, <TokenType.RANGE: 'RANGE'>, <TokenType.ANTI: 'ANTI'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.VAR: 'VAR'>, <TokenType.LEFT: 'LEFT'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>, <TokenType.TEMPORARY: 'TEMPORARY'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.ENUM: 'ENUM'>, <TokenType.DESCRIBE: 'DESCRIBE'>, <TokenType.FULL: 'FULL'>, <TokenType.BIT: 'BIT'>, <TokenType.INDEX: 'INDEX'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.PROCEDURE: 'PROCEDURE'>, <TokenType.ORDINALITY: 'ORDINALITY'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.EXECUTE: 'EXECUTE'>}
PROPERTY_PARSERS =
{'ALGORITHM': <function Parser.<lambda>>, 'AUTO_INCREMENT': <function Parser.<lambda>>, 'BLOCKCOMPRESSION': <function Parser.<lambda>>, 'CHARACTER SET': <function Parser.<lambda>>, 'CHECKSUM': <function Parser.<lambda>>, 'CLUSTER BY': <function Parser.<lambda>>, 'CLUSTERED': <function Parser.<lambda>>, 'COLLATE': <function Parser.<lambda>>, 'COMMENT': <function Parser.<lambda>>, 'COPY': <function Parser.<lambda>>, 'DATABLOCKSIZE': <function Parser.<lambda>>, 'DEFINER': <function Parser.<lambda>>, 'DETERMINISTIC': <function Parser.<lambda>>, 'DISTKEY': <function Parser.<lambda>>, 'DISTSTYLE': <function Parser.<lambda>>, 'ENGINE': <function Parser.<lambda>>, 'EXECUTE': <function Parser.<lambda>>, 'EXTERNAL': <function Parser.<lambda>>, 'FALLBACK': <function Parser.<lambda>>, 'FORMAT': <function Parser.<lambda>>, 'FREESPACE': <function Parser.<lambda>>, 'IMMUTABLE': <function Parser.<lambda>>, 'JOURNAL': <function Parser.<lambda>>, 'LANGUAGE': <function Parser.<lambda>>, 'LAYOUT': <function Parser.<lambda>>, 'LIFETIME': <function Parser.<lambda>>, 'LIKE': <function Parser.<lambda>>, 'LOCATION': <function Parser.<lambda>>, 'LOCK': <function Parser.<lambda>>, 'LOCKING': <function Parser.<lambda>>, 'LOG': <function Parser.<lambda>>, 'MATERIALIZED': <function Parser.<lambda>>, 'MERGEBLOCKRATIO': <function Parser.<lambda>>, 'MULTISET': <function Parser.<lambda>>, 'NO': <function Parser.<lambda>>, 'ON': <function Parser.<lambda>>, 'ORDER BY': <function Parser.<lambda>>, 'PARTITION BY': <function Parser.<lambda>>, 'PARTITIONED BY': <function Parser.<lambda>>, 'PARTITIONED_BY': <function Parser.<lambda>>, 'PRIMARY KEY': <function Parser.<lambda>>, 'RANGE': <function Parser.<lambda>>, 'RETURNS': <function Parser.<lambda>>, 'ROW': <function Parser.<lambda>>, 'ROW_FORMAT': <function Parser.<lambda>>, 'SET': <function Parser.<lambda>>, 'SETTINGS': <function Parser.<lambda>>, 'SORTKEY': <function Parser.<lambda>>, 'SOURCE': <function Parser.<lambda>>, 'STABLE': <function Parser.<lambda>>, 'STORED': <function Parser.<lambda>>, 'TBLPROPERTIES': <function Parser.<lambda>>, 'TEMP': <function Parser.<lambda>>, 'TEMPORARY': <function Parser.<lambda>>, 'TO': <function Parser.<lambda>>, 'TRANSIENT': <function Parser.<lambda>>, 'TTL': <function Parser.<lambda>>, 'USING': <function Parser.<lambda>>, 'VOLATILE': <function Parser.<lambda>>, 'WITH': <function Parser.<lambda>>, 'NOT DETERMINISTIC': <function BigQuery.Parser.<lambda>>, 'OPTIONS': <function BigQuery.Parser.<lambda>>}
CONSTRAINT_PARSERS =
{'AUTOINCREMENT': <function Parser.<lambda>>, 'AUTO_INCREMENT': <function Parser.<lambda>>, 'CASESPECIFIC': <function Parser.<lambda>>, 'CHARACTER SET': <function Parser.<lambda>>, 'CHECK': <function Parser.<lambda>>, 'COLLATE': <function Parser.<lambda>>, 'COMMENT': <function Parser.<lambda>>, 'COMPRESS': <function Parser.<lambda>>, 'DEFAULT': <function Parser.<lambda>>, 'ENCODE': <function Parser.<lambda>>, 'FOREIGN KEY': <function Parser.<lambda>>, 'FORMAT': <function Parser.<lambda>>, 'GENERATED': <function Parser.<lambda>>, 'IDENTITY': <function Parser.<lambda>>, 'INLINE': <function Parser.<lambda>>, 'LIKE': <function Parser.<lambda>>, 'NOT': <function Parser.<lambda>>, 'NULL': <function Parser.<lambda>>, 'ON': <function Parser.<lambda>>, 'PATH': <function Parser.<lambda>>, 'PRIMARY KEY': <function Parser.<lambda>>, 'REFERENCES': <function Parser.<lambda>>, 'TITLE': <function Parser.<lambda>>, 'TTL': <function Parser.<lambda>>, 'UNIQUE': <function Parser.<lambda>>, 'UPPERCASE': <function Parser.<lambda>>, 'OPTIONS': <function BigQuery.Parser.<lambda>>}
SET_TRIE: Dict =
{'GLOBAL': {0: True}, 'LOCAL': {0: True}, 'SESSION': {0: True}, 'TRANSACTION': {0: True}}
FORMAT_MAPPING: Dict[str, str] =
{'DD': '%d', 'MM': '%m', 'MON': '%b', 'MONTH': '%B', 'YYYY': '%Y', 'YY': '%y', 'HH': '%I', 'HH12': '%I', 'HH24': '%H', 'MI': '%M', 'SS': '%S', 'SSSSS': '%f', 'TZH': '%z'}
FORMAT_TRIE: Dict =
{'D': {'D': {0: True}}, 'M': {'M': {0: True}, 'O': {'N': {0: True, 'T': {'H': {0: True}}}}, 'I': {0: True}}, 'Y': {'Y': {'Y': {'Y': {0: True}}, 0: True}}, 'H': {'H': {0: True, '1': {'2': {0: True}}, '2': {'4': {0: True}}}}, 'S': {'S': {0: True, 'S': {'S': {'S': {0: True}}}}}, 'T': {'Z': {'H': {0: True}}}}
Inherited Members
- sqlglot.parser.Parser
- Parser
- ENUM_TYPE_TOKENS
- TYPE_TOKENS
- SUBQUERY_PREDICATES
- RESERVED_KEYWORDS
- DB_CREATABLES
- CREATABLES
- INTERVAL_VARS
- TABLE_ALIAS_TOKENS
- COMMENT_TABLE_ALIAS_TOKENS
- UPDATE_ALIAS_TOKENS
- TRIM_TYPES
- FUNC_TOKENS
- CONJUNCTION
- EQUALITY
- COMPARISON
- BITWISE
- TERM
- FACTOR
- TIMESTAMPS
- SET_OPERATIONS
- JOIN_METHODS
- JOIN_SIDES
- JOIN_KINDS
- JOIN_HINTS
- LAMBDAS
- COLUMN_OPERATORS
- EXPRESSION_PARSERS
- STATEMENT_PARSERS
- UNARY_PARSERS
- PRIMARY_PARSERS
- PLACEHOLDER_PARSERS
- RANGE_PARSERS
- ALTER_PARSERS
- SCHEMA_UNNAMED_CONSTRAINTS
- NO_PAREN_FUNCTION_PARSERS
- FUNCTIONS_WITH_ALIASED_ARGS
- QUERY_MODIFIER_PARSERS
- SET_PARSERS
- SHOW_PARSERS
- TYPE_LITERAL_PARSERS
- MODIFIABLES
- DDL_SELECT_TOKENS
- PRE_VOLATILE_TOKENS
- TRANSACTION_KIND
- TRANSACTION_CHARACTERISTICS
- INSERT_ALTERNATIVES
- CLONE_KINDS
- TABLE_INDEX_HINT_TOKENS
- WINDOW_ALIAS_TOKENS
- WINDOW_BEFORE_PAREN_TOKENS
- WINDOW_SIDES
- ADD_CONSTRAINT_TOKENS
- STRICT_CAST
- CONCAT_NULL_OUTPUTS_STRING
- IDENTIFY_PIVOT_STRINGS
- INDEX_OFFSET
- ALIAS_POST_TABLESAMPLE
- STRICT_STRING_CONCAT
- NULL_ORDERING
- error_level
- error_message_context
- max_errors
- reset
- parse
- parse_into
- check_errors
- raise_error
- expression
- validate_expression
- errors
- sql
356 class Generator(generator.Generator): 357 EXPLICIT_UNION = True 358 INTERVAL_ALLOWS_PLURAL_FORM = False 359 JOIN_HINTS = False 360 TABLE_HINTS = False 361 LIMIT_FETCH = "LIMIT" 362 RENAME_TABLE_WITH_DB = False 363 364 TRANSFORMS = { 365 **generator.Generator.TRANSFORMS, 366 exp.ApproxDistinct: rename_func("APPROX_COUNT_DISTINCT"), 367 exp.ArraySize: rename_func("ARRAY_LENGTH"), 368 exp.Cast: transforms.preprocess([transforms.remove_precision_parameterized_types]), 369 exp.CTE: transforms.preprocess([_pushdown_cte_column_names]), 370 exp.DateAdd: _date_add_sql("DATE", "ADD"), 371 exp.DateSub: _date_add_sql("DATE", "SUB"), 372 exp.DatetimeAdd: _date_add_sql("DATETIME", "ADD"), 373 exp.DatetimeSub: _date_add_sql("DATETIME", "SUB"), 374 exp.DateDiff: lambda self, e: f"DATE_DIFF({self.sql(e, 'this')}, {self.sql(e, 'expression')}, {self.sql(e.args.get('unit', 'DAY'))})", 375 exp.DateStrToDate: datestrtodate_sql, 376 exp.DateTrunc: lambda self, e: self.func("DATE_TRUNC", e.this, e.text("unit")), 377 exp.JSONFormat: rename_func("TO_JSON_STRING"), 378 exp.GenerateSeries: rename_func("GENERATE_ARRAY"), 379 exp.GroupConcat: rename_func("STRING_AGG"), 380 exp.ILike: no_ilike_sql, 381 exp.IntDiv: rename_func("DIV"), 382 exp.Max: max_or_greatest, 383 exp.Min: min_or_least, 384 exp.RegexpExtract: lambda self, e: self.func( 385 "REGEXP_EXTRACT", 386 e.this, 387 e.expression, 388 e.args.get("position"), 389 e.args.get("occurrence"), 390 ), 391 exp.RegexpLike: rename_func("REGEXP_CONTAINS"), 392 exp.Select: transforms.preprocess( 393 [ 394 transforms.explode_to_unnest, 395 _unqualify_unnest, 396 transforms.eliminate_distinct_on, 397 _alias_ordered_group, 398 ] 399 ), 400 exp.StrToDate: lambda self, e: f"PARSE_DATE({self.format_time(e)}, {self.sql(e, 'this')})", 401 exp.StrToTime: lambda self, e: f"PARSE_TIMESTAMP({self.format_time(e)}, {self.sql(e, 'this')})", 402 exp.TimeAdd: _date_add_sql("TIME", "ADD"), 403 exp.TimeSub: _date_add_sql("TIME", "SUB"), 404 exp.TimestampAdd: _date_add_sql("TIMESTAMP", "ADD"), 405 exp.TimestampSub: _date_add_sql("TIMESTAMP", "SUB"), 406 exp.TimeStrToTime: timestrtotime_sql, 407 exp.TsOrDsToDate: ts_or_ds_to_date_sql("bigquery"), 408 exp.TsOrDsAdd: _date_add_sql("DATE", "ADD"), 409 exp.PartitionedByProperty: lambda self, e: f"PARTITION BY {self.sql(e, 'this')}", 410 exp.VariancePop: rename_func("VAR_POP"), 411 exp.Values: _derived_table_values_to_unnest, 412 exp.ReturnsProperty: _returnsproperty_sql, 413 exp.Create: _create_sql, 414 exp.Trim: lambda self, e: self.func(f"TRIM", e.this, e.expression), 415 exp.StabilityProperty: lambda self, e: f"DETERMINISTIC" 416 if e.name == "IMMUTABLE" 417 else "NOT DETERMINISTIC", 418 } 419 420 TYPE_MAPPING = { 421 **generator.Generator.TYPE_MAPPING, 422 exp.DataType.Type.BIGDECIMAL: "BIGNUMERIC", 423 exp.DataType.Type.BIGINT: "INT64", 424 exp.DataType.Type.BINARY: "BYTES", 425 exp.DataType.Type.BOOLEAN: "BOOL", 426 exp.DataType.Type.CHAR: "STRING", 427 exp.DataType.Type.DECIMAL: "NUMERIC", 428 exp.DataType.Type.DOUBLE: "FLOAT64", 429 exp.DataType.Type.FLOAT: "FLOAT64", 430 exp.DataType.Type.INT: "INT64", 431 exp.DataType.Type.NCHAR: "STRING", 432 exp.DataType.Type.NVARCHAR: "STRING", 433 exp.DataType.Type.SMALLINT: "INT64", 434 exp.DataType.Type.TEXT: "STRING", 435 exp.DataType.Type.TIMESTAMP: "DATETIME", 436 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", 437 exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP", 438 exp.DataType.Type.TINYINT: "INT64", 439 exp.DataType.Type.VARBINARY: "BYTES", 440 exp.DataType.Type.VARCHAR: "STRING", 441 exp.DataType.Type.VARIANT: "ANY TYPE", 442 } 443 444 PROPERTIES_LOCATION = { 445 **generator.Generator.PROPERTIES_LOCATION, 446 exp.PartitionedByProperty: exp.Properties.Location.POST_SCHEMA, 447 exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, 448 } 449 450 # from: https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#reserved_keywords 451 RESERVED_KEYWORDS = { 452 *generator.Generator.RESERVED_KEYWORDS, 453 "all", 454 "and", 455 "any", 456 "array", 457 "as", 458 "asc", 459 "assert_rows_modified", 460 "at", 461 "between", 462 "by", 463 "case", 464 "cast", 465 "collate", 466 "contains", 467 "create", 468 "cross", 469 "cube", 470 "current", 471 "default", 472 "define", 473 "desc", 474 "distinct", 475 "else", 476 "end", 477 "enum", 478 "escape", 479 "except", 480 "exclude", 481 "exists", 482 "extract", 483 "false", 484 "fetch", 485 "following", 486 "for", 487 "from", 488 "full", 489 "group", 490 "grouping", 491 "groups", 492 "hash", 493 "having", 494 "if", 495 "ignore", 496 "in", 497 "inner", 498 "intersect", 499 "interval", 500 "into", 501 "is", 502 "join", 503 "lateral", 504 "left", 505 "like", 506 "limit", 507 "lookup", 508 "merge", 509 "natural", 510 "new", 511 "no", 512 "not", 513 "null", 514 "nulls", 515 "of", 516 "on", 517 "or", 518 "order", 519 "outer", 520 "over", 521 "partition", 522 "preceding", 523 "proto", 524 "qualify", 525 "range", 526 "recursive", 527 "respect", 528 "right", 529 "rollup", 530 "rows", 531 "select", 532 "set", 533 "some", 534 "struct", 535 "tablesample", 536 "then", 537 "to", 538 "treat", 539 "true", 540 "unbounded", 541 "union", 542 "unnest", 543 "using", 544 "when", 545 "where", 546 "window", 547 "with", 548 "within", 549 } 550 551 def attimezone_sql(self, expression: exp.AtTimeZone) -> str: 552 if not isinstance(expression.parent, exp.Cast): 553 return self.func( 554 "TIMESTAMP", self.func("DATETIME", expression.this, expression.args.get("zone")) 555 ) 556 return super().attimezone_sql(expression) 557 558 def trycast_sql(self, expression: exp.TryCast) -> str: 559 return self.cast_sql(expression, safe_prefix="SAFE_") 560 561 def cte_sql(self, expression: exp.CTE) -> str: 562 if expression.alias_column_names: 563 self.unsupported("Column names in CTE definition are not supported.") 564 return super().cte_sql(expression) 565 566 def array_sql(self, expression: exp.Array) -> str: 567 first_arg = seq_get(expression.expressions, 0) 568 if isinstance(first_arg, exp.Subqueryable): 569 return f"ARRAY{self.wrap(self.sql(first_arg))}" 570 571 return inline_array_sql(self, expression) 572 573 def transaction_sql(self, *_) -> str: 574 return "BEGIN TRANSACTION" 575 576 def commit_sql(self, *_) -> str: 577 return "COMMIT TRANSACTION" 578 579 def rollback_sql(self, *_) -> str: 580 return "ROLLBACK TRANSACTION" 581 582 def in_unnest_op(self, expression: exp.Unnest) -> str: 583 return self.sql(expression) 584 585 def except_op(self, expression: exp.Except) -> str: 586 if not expression.args.get("distinct", False): 587 self.unsupported("EXCEPT without DISTINCT is not supported in BigQuery") 588 return f"EXCEPT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}" 589 590 def intersect_op(self, expression: exp.Intersect) -> str: 591 if not expression.args.get("distinct", False): 592 self.unsupported("INTERSECT without DISTINCT is not supported in BigQuery") 593 return f"INTERSECT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}" 594 595 def with_properties(self, properties: exp.Properties) -> str: 596 return self.properties(properties, prefix=self.seg("OPTIONS"))
Generator converts a given syntax tree to the corresponding SQL string.
Arguments:
- pretty: Whether or not to format the produced SQL string. Default: False.
- identify: Determines when an identifier should be quoted. Possible values are: False (default): Never quote, except in cases where it's mandatory by the dialect. True or 'always': Always quote. 'safe': Only quote identifiers that are case insensitive.
- normalize: Whether or not to normalize identifiers to lowercase. Default: False.
- pad: Determines the pad size in a formatted string. Default: 2.
- indent: Determines the indentation size in a formatted string. Default: 2.
- normalize_functions: Whether or not to normalize all function names. Possible values are: "upper" or True (default): Convert names to uppercase. "lower": Convert names to lowercase. False: Disables function name normalization.
- unsupported_level: Determines the generator's behavior when it encounters unsupported expressions. Default ErrorLevel.WARN.
- max_unsupported: Maximum number of unsupported messages to include in a raised UnsupportedError. This is only relevant if unsupported_level is ErrorLevel.RAISE. Default: 3
- leading_comma: Determines whether or not the comma is leading or trailing in select expressions. This is only relevant when generating in pretty mode. Default: False
- max_text_width: The max number of characters in a segment before creating new lines in pretty mode. The default is on the smaller end because the length only represents a segment and not the true line length. Default: 80
- comments: Whether or not to preserve comments in the output SQL code. Default: True
TRANSFORMS =
{<class 'sqlglot.expressions.DateAdd'>: <function _date_add_sql.<locals>.func>, <class 'sqlglot.expressions.TsOrDsAdd'>: <function _date_add_sql.<locals>.func>, <class 'sqlglot.expressions.CaseSpecificColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CharacterSetColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CharacterSetProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CheckColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CollateColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CopyGrantsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.CommentColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.DateFormatColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.DefaultColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.EncodeColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ExecuteAsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ExternalProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.InlineLengthColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.LanguageProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.LocationProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.LogProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.MaterializedProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.NoPrimaryIndexProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.OnCommitProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.OnUpdateColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.PathColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ReturnsProperty'>: <function _returnsproperty_sql>, <class 'sqlglot.expressions.SetProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SettingsProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.SqlSecurityProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.StabilityProperty'>: <function BigQuery.Generator.<lambda>>, <class 'sqlglot.expressions.TemporaryProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ToTableProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TransientProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.TitleColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.UppercaseColumnConstraint'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.VarMap'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.VolatileProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.WithJournalTableProperty'>: <function Generator.<lambda>>, <class 'sqlglot.expressions.ApproxDistinct'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.ArraySize'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.Cast'>: <function preprocess.<locals>._to_sql>, <class 'sqlglot.expressions.CTE'>: <function preprocess.<locals>._to_sql>, <class 'sqlglot.expressions.DateSub'>: <function _date_add_sql.<locals>.func>, <class 'sqlglot.expressions.DatetimeAdd'>: <function _date_add_sql.<locals>.func>, <class 'sqlglot.expressions.DatetimeSub'>: <function _date_add_sql.<locals>.func>, <class 'sqlglot.expressions.DateDiff'>: <function BigQuery.Generator.<lambda>>, <class 'sqlglot.expressions.DateStrToDate'>: <function datestrtodate_sql>, <class 'sqlglot.expressions.DateTrunc'>: <function BigQuery.Generator.<lambda>>, <class 'sqlglot.expressions.JSONFormat'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.GenerateSeries'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.GroupConcat'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.ILike'>: <function no_ilike_sql>, <class 'sqlglot.expressions.IntDiv'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.Max'>: <function max_or_greatest>, <class 'sqlglot.expressions.Min'>: <function min_or_least>, <class 'sqlglot.expressions.RegexpExtract'>: <function BigQuery.Generator.<lambda>>, <class 'sqlglot.expressions.RegexpLike'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.Select'>: <function preprocess.<locals>._to_sql>, <class 'sqlglot.expressions.StrToDate'>: <function BigQuery.Generator.<lambda>>, <class 'sqlglot.expressions.StrToTime'>: <function BigQuery.Generator.<lambda>>, <class 'sqlglot.expressions.TimeAdd'>: <function _date_add_sql.<locals>.func>, <class 'sqlglot.expressions.TimeSub'>: <function _date_add_sql.<locals>.func>, <class 'sqlglot.expressions.TimestampAdd'>: <function _date_add_sql.<locals>.func>, <class 'sqlglot.expressions.TimestampSub'>: <function _date_add_sql.<locals>.func>, <class 'sqlglot.expressions.TimeStrToTime'>: <function timestrtotime_sql>, <class 'sqlglot.expressions.TsOrDsToDate'>: <function ts_or_ds_to_date_sql.<locals>._ts_or_ds_to_date_sql>, <class 'sqlglot.expressions.PartitionedByProperty'>: <function BigQuery.Generator.<lambda>>, <class 'sqlglot.expressions.VariancePop'>: <function rename_func.<locals>.<lambda>>, <class 'sqlglot.expressions.Values'>: <function _derived_table_values_to_unnest>, <class 'sqlglot.expressions.Create'>: <function _create_sql>, <class 'sqlglot.expressions.Trim'>: <function BigQuery.Generator.<lambda>>}
TYPE_MAPPING =
{<Type.NCHAR: 'NCHAR'>: 'STRING', <Type.NVARCHAR: 'NVARCHAR'>: 'STRING', <Type.MEDIUMTEXT: 'MEDIUMTEXT'>: 'TEXT', <Type.LONGTEXT: 'LONGTEXT'>: 'TEXT', <Type.MEDIUMBLOB: 'MEDIUMBLOB'>: 'BLOB', <Type.LONGBLOB: 'LONGBLOB'>: 'BLOB', <Type.INET: 'INET'>: 'INET', <Type.BIGDECIMAL: 'BIGDECIMAL'>: 'BIGNUMERIC', <Type.BIGINT: 'BIGINT'>: 'INT64', <Type.BINARY: 'BINARY'>: 'BYTES', <Type.BOOLEAN: 'BOOLEAN'>: 'BOOL', <Type.CHAR: 'CHAR'>: 'STRING', <Type.DECIMAL: 'DECIMAL'>: 'NUMERIC', <Type.DOUBLE: 'DOUBLE'>: 'FLOAT64', <Type.FLOAT: 'FLOAT'>: 'FLOAT64', <Type.INT: 'INT'>: 'INT64', <Type.SMALLINT: 'SMALLINT'>: 'INT64', <Type.TEXT: 'TEXT'>: 'STRING', <Type.TIMESTAMP: 'TIMESTAMP'>: 'DATETIME', <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>: 'TIMESTAMP', <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>: 'TIMESTAMP', <Type.TINYINT: 'TINYINT'>: 'INT64', <Type.VARBINARY: 'VARBINARY'>: 'BYTES', <Type.VARCHAR: 'VARCHAR'>: 'STRING', <Type.VARIANT: 'VARIANT'>: 'ANY TYPE'}
PROPERTIES_LOCATION =
{<class 'sqlglot.expressions.AlgorithmProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.AutoIncrementProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.BlockCompressionProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.CharacterSetProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ChecksumProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.CollateProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.CopyGrantsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.Cluster'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ClusteredByProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DataBlocksizeProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.DefinerProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.DictRange'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DictProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DistKeyProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.DistStyleProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.EngineProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ExecuteAsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.ExternalProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.FallbackProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.FileFormatProperty'>: <Location.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.FreespaceProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.IsolatedLoadingProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.JournalProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.LanguageProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.LikeProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.LocationProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.LockingProperty'>: <Location.POST_ALIAS: 'POST_ALIAS'>, <class 'sqlglot.expressions.LogProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.MaterializedProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.MergeBlockRatioProperty'>: <Location.POST_NAME: 'POST_NAME'>, <class 'sqlglot.expressions.NoPrimaryIndexProperty'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.OnCommitProperty'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.Order'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.PartitionedByProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.PrimaryKey'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.Property'>: <Location.POST_WITH: 'POST_WITH'>, <class 'sqlglot.expressions.ReturnsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.RowFormatProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.RowFormatDelimitedProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.RowFormatSerdeProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SchemaCommentProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SerdeProperties'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.Set'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SettingsProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SetProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.SortKeyProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.SqlSecurityProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.StabilityProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.TemporaryProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.ToTableProperty'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.TransientProperty'>: <Location.POST_CREATE: 'POST_CREATE'>, <class 'sqlglot.expressions.MergeTreeTTL'>: <Location.POST_SCHEMA: 'POST_SCHEMA'>, <class 'sqlglot.expressions.VolatileProperty'>: <Location.UNSUPPORTED: 'UNSUPPORTED'>, <class 'sqlglot.expressions.WithDataProperty'>: <Location.POST_EXPRESSION: 'POST_EXPRESSION'>, <class 'sqlglot.expressions.WithJournalTableProperty'>: <Location.POST_NAME: 'POST_NAME'>}
RESERVED_KEYWORDS =
{'between', 'distinct', 'current', 'qualify', 'default', 'when', 'with', 'or', 'new', 'as', 'grouping', 'order', 'except', 'left', 'struct', 'into', 'like', 'tablesample', 'false', 'lookup', 'having', 'range', 'at', 'cross', 'treat', 'group', 'not', 'fetch', 'set', 'unbounded', 'create', 'no', 'if', 'exclude', 'cast', 'some', 'partition', 'end', 'rows', 'for', 'intersect', 'else', 'in', 'any', 'enum', 'window', 'recursive', 'preceding', 'full', 'asc', 'exists', 'select', 'to', 'unnest', 'nulls', 'null', 'outer', 'proto', 'hash', 'from', 'lateral', 'within', 'contains', 'ignore', 'rollup', 'extract', 'then', 'inner', 'cube', 'on', 'of', 'over', 'union', 'following', 'escape', 'using', 'by', 'limit', 'where', 'join', 'right', 'respect', 'natural', 'array', 'define', 'collate', 'interval', 'is', 'true', 'and', 'case', 'groups', 'assert_rows_modified', 'all', 'merge', 'desc'}
@classmethod
def
can_identify(text: str, identify: str | bool = 'safe') -> bool:
247 @classmethod 248 def can_identify(cls, text: str, identify: str | bool = "safe") -> bool: 249 """Checks if text can be identified given an identify option. 250 251 Args: 252 text: The text to check. 253 identify: 254 "always" or `True`: Always returns true. 255 "safe": True if the identifier is case-insensitive. 256 257 Returns: 258 Whether or not the given text can be identified. 259 """ 260 if identify is True or identify == "always": 261 return True 262 263 if identify == "safe": 264 return not cls.case_sensitive(text) 265 266 return False
Checks if text can be identified given an identify option.
Arguments:
- text: The text to check.
- identify: "always" or
True
: Always returns true. "safe": True if the identifier is case-insensitive.
Returns:
Whether or not the given text can be identified.
Inherited Members
- sqlglot.generator.Generator
- Generator
- NULL_ORDERING_SUPPORTED
- LOCKING_READS_SUPPORTED
- WRAP_DERIVED_VALUES
- CREATE_FUNCTION_RETURN_AS
- MATCHED_BY_SOURCE
- SINGLE_STRING_INTERVAL
- TABLESAMPLE_WITH_METHOD
- TABLESAMPLE_SIZE_IS_PERCENT
- GROUPINGS_SEP
- INDEX_ON
- IS_BOOL_ALLOWED
- SELECT_KINDS
- STAR_MAPPING
- TIME_PART_SINGULARS
- TOKEN_MAPPING
- STRUCT_DELIMITER
- PARAMETER_TOKEN
- WITH_SEPARATED_COMMENTS
- UNWRAPPED_INTERVAL_VALUES
- SENTINEL_LINE_BREAK
- INDEX_OFFSET
- ALIAS_POST_TABLESAMPLE
- IDENTIFIERS_CAN_START_WITH_DIGIT
- STRICT_STRING_CONCAT
- NULL_ORDERING
- pretty
- identify
- normalize
- pad
- unsupported_level
- max_unsupported
- leading_comma
- max_text_width
- comments
- normalize_functions
- unsupported_messages
- generate
- unsupported
- sep
- seg
- pad_comment
- maybe_comment
- wrap
- no_identify
- normalize_func
- indent
- sql
- uncache_sql
- cache_sql
- characterset_sql
- column_sql
- columnposition_sql
- columndef_sql
- columnconstraint_sql
- autoincrementcolumnconstraint_sql
- compresscolumnconstraint_sql
- generatedasidentitycolumnconstraint_sql
- notnullcolumnconstraint_sql
- primarykeycolumnconstraint_sql
- uniquecolumnconstraint_sql
- createable_sql
- create_sql
- clone_sql
- describe_sql
- prepend_ctes
- with_sql
- tablealias_sql
- bitstring_sql
- hexstring_sql
- bytestring_sql
- rawstring_sql
- datatypesize_sql
- datatype_sql
- directory_sql
- delete_sql
- drop_sql
- except_sql
- fetch_sql
- filter_sql
- hint_sql
- index_sql
- identifier_sql
- inputoutputformat_sql
- national_sql
- partition_sql
- properties_sql
- root_properties
- properties
- locate_properties
- property_sql
- likeproperty_sql
- fallbackproperty_sql
- journalproperty_sql
- freespaceproperty_sql
- checksumproperty_sql
- mergeblockratioproperty_sql
- datablocksizeproperty_sql
- blockcompressionproperty_sql
- isolatedloadingproperty_sql
- lockingproperty_sql
- withdataproperty_sql
- insert_sql
- intersect_sql
- introducer_sql
- pseudotype_sql
- onconflict_sql
- returning_sql
- rowformatdelimitedproperty_sql
- withtablehint_sql
- indextablehint_sql
- table_sql
- tablesample_sql
- pivot_sql
- tuple_sql
- update_sql
- values_sql
- var_sql
- into_sql
- from_sql
- group_sql
- having_sql
- join_sql
- lambda_sql
- lateral_sql
- limit_sql
- offset_sql
- setitem_sql
- set_sql
- pragma_sql
- lock_sql
- literal_sql
- escape_str
- loaddata_sql
- null_sql
- boolean_sql
- order_sql
- cluster_sql
- distribute_sql
- sort_sql
- ordered_sql
- matchrecognize_sql
- query_modifiers
- offset_limit_modifiers
- after_having_modifiers
- after_limit_modifiers
- select_sql
- schema_sql
- schema_columns_sql
- star_sql
- parameter_sql
- sessionparameter_sql
- placeholder_sql
- subquery_sql
- qualify_sql
- union_sql
- union_op
- unnest_sql
- where_sql
- window_sql
- partition_by_sql
- windowspec_sql
- withingroup_sql
- between_sql
- bracket_sql
- safebracket_sql
- all_sql
- any_sql
- exists_sql
- case_sql
- constraint_sql
- nextvaluefor_sql
- extract_sql
- trim_sql
- safeconcat_sql
- check_sql
- foreignkey_sql
- primarykey_sql
- if_sql
- matchagainst_sql
- jsonkeyvalue_sql
- jsonobject_sql
- openjsoncolumndef_sql
- openjson_sql
- in_sql
- interval_sql
- return_sql
- reference_sql
- anonymous_sql
- paren_sql
- neg_sql
- not_sql
- alias_sql
- aliases_sql
- add_sql
- and_sql
- connector_sql
- bitwiseand_sql
- bitwiseleftshift_sql
- bitwisenot_sql
- bitwiseor_sql
- bitwiserightshift_sql
- bitwisexor_sql
- cast_sql
- currentdate_sql
- collate_sql
- command_sql
- comment_sql
- mergetreettlaction_sql
- mergetreettl_sql
- altercolumn_sql
- renametable_sql
- altertable_sql
- droppartition_sql
- addconstraint_sql
- distinct_sql
- ignorenulls_sql
- respectnulls_sql
- intdiv_sql
- dpipe_sql
- safedpipe_sql
- div_sql
- overlaps_sql
- distance_sql
- dot_sql
- eq_sql
- escape_sql
- glob_sql
- gt_sql
- gte_sql
- ilike_sql
- ilikeany_sql
- is_sql
- like_sql
- likeany_sql
- similarto_sql
- lt_sql
- lte_sql
- mod_sql
- mul_sql
- neq_sql
- nullsafeeq_sql
- nullsafeneq_sql
- or_sql
- slice_sql
- sub_sql
- use_sql
- binary
- function_fallback_sql
- func
- format_args
- text_width
- format_time
- expressions
- op_expressions
- naked_property
- set_operation
- tag_sql
- token_sql
- userdefinedfunction_sql
- joinhint_sql
- kwarg_sql
- when_sql
- merge_sql
- tochar_sql
- dictproperty_sql
- dictrange_sql
- dictsubproperty_sql
- oncluster_sql
- clusteredbyproperty_sql
- anyvalue_sql