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 ESCAPE_LINE_BREAK = True 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"))
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 ESCAPE_LINE_BREAK = True 364 365 TRANSFORMS = { 366 **generator.Generator.TRANSFORMS, 367 exp.ApproxDistinct: rename_func("APPROX_COUNT_DISTINCT"), 368 exp.ArraySize: rename_func("ARRAY_LENGTH"), 369 exp.Cast: transforms.preprocess([transforms.remove_precision_parameterized_types]), 370 exp.CTE: transforms.preprocess([_pushdown_cte_column_names]), 371 exp.DateAdd: _date_add_sql("DATE", "ADD"), 372 exp.DateSub: _date_add_sql("DATE", "SUB"), 373 exp.DatetimeAdd: _date_add_sql("DATETIME", "ADD"), 374 exp.DatetimeSub: _date_add_sql("DATETIME", "SUB"), 375 exp.DateDiff: lambda self, e: f"DATE_DIFF({self.sql(e, 'this')}, {self.sql(e, 'expression')}, {self.sql(e.args.get('unit', 'DAY'))})", 376 exp.DateStrToDate: datestrtodate_sql, 377 exp.DateTrunc: lambda self, e: self.func("DATE_TRUNC", e.this, e.text("unit")), 378 exp.JSONFormat: rename_func("TO_JSON_STRING"), 379 exp.GenerateSeries: rename_func("GENERATE_ARRAY"), 380 exp.GroupConcat: rename_func("STRING_AGG"), 381 exp.ILike: no_ilike_sql, 382 exp.IntDiv: rename_func("DIV"), 383 exp.Max: max_or_greatest, 384 exp.Min: min_or_least, 385 exp.RegexpExtract: lambda self, e: self.func( 386 "REGEXP_EXTRACT", 387 e.this, 388 e.expression, 389 e.args.get("position"), 390 e.args.get("occurrence"), 391 ), 392 exp.RegexpLike: rename_func("REGEXP_CONTAINS"), 393 exp.Select: transforms.preprocess( 394 [ 395 transforms.explode_to_unnest, 396 _unqualify_unnest, 397 transforms.eliminate_distinct_on, 398 _alias_ordered_group, 399 ] 400 ), 401 exp.StrToDate: lambda self, e: f"PARSE_DATE({self.format_time(e)}, {self.sql(e, 'this')})", 402 exp.StrToTime: lambda self, e: f"PARSE_TIMESTAMP({self.format_time(e)}, {self.sql(e, 'this')})", 403 exp.TimeAdd: _date_add_sql("TIME", "ADD"), 404 exp.TimeSub: _date_add_sql("TIME", "SUB"), 405 exp.TimestampAdd: _date_add_sql("TIMESTAMP", "ADD"), 406 exp.TimestampSub: _date_add_sql("TIMESTAMP", "SUB"), 407 exp.TimeStrToTime: timestrtotime_sql, 408 exp.TsOrDsToDate: ts_or_ds_to_date_sql("bigquery"), 409 exp.TsOrDsAdd: _date_add_sql("DATE", "ADD"), 410 exp.PartitionedByProperty: lambda self, e: f"PARTITION BY {self.sql(e, 'this')}", 411 exp.VariancePop: rename_func("VAR_POP"), 412 exp.Values: _derived_table_values_to_unnest, 413 exp.ReturnsProperty: _returnsproperty_sql, 414 exp.Create: _create_sql, 415 exp.Trim: lambda self, e: self.func(f"TRIM", e.this, e.expression), 416 exp.StabilityProperty: lambda self, e: f"DETERMINISTIC" 417 if e.name == "IMMUTABLE" 418 else "NOT DETERMINISTIC", 419 } 420 421 TYPE_MAPPING = { 422 **generator.Generator.TYPE_MAPPING, 423 exp.DataType.Type.BIGDECIMAL: "BIGNUMERIC", 424 exp.DataType.Type.BIGINT: "INT64", 425 exp.DataType.Type.BINARY: "BYTES", 426 exp.DataType.Type.BOOLEAN: "BOOL", 427 exp.DataType.Type.CHAR: "STRING", 428 exp.DataType.Type.DECIMAL: "NUMERIC", 429 exp.DataType.Type.DOUBLE: "FLOAT64", 430 exp.DataType.Type.FLOAT: "FLOAT64", 431 exp.DataType.Type.INT: "INT64", 432 exp.DataType.Type.NCHAR: "STRING", 433 exp.DataType.Type.NVARCHAR: "STRING", 434 exp.DataType.Type.SMALLINT: "INT64", 435 exp.DataType.Type.TEXT: "STRING", 436 exp.DataType.Type.TIMESTAMP: "DATETIME", 437 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", 438 exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP", 439 exp.DataType.Type.TINYINT: "INT64", 440 exp.DataType.Type.VARBINARY: "BYTES", 441 exp.DataType.Type.VARCHAR: "STRING", 442 exp.DataType.Type.VARIANT: "ANY TYPE", 443 } 444 445 PROPERTIES_LOCATION = { 446 **generator.Generator.PROPERTIES_LOCATION, 447 exp.PartitionedByProperty: exp.Properties.Location.POST_SCHEMA, 448 exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, 449 } 450 451 # from: https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#reserved_keywords 452 RESERVED_KEYWORDS = { 453 *generator.Generator.RESERVED_KEYWORDS, 454 "all", 455 "and", 456 "any", 457 "array", 458 "as", 459 "asc", 460 "assert_rows_modified", 461 "at", 462 "between", 463 "by", 464 "case", 465 "cast", 466 "collate", 467 "contains", 468 "create", 469 "cross", 470 "cube", 471 "current", 472 "default", 473 "define", 474 "desc", 475 "distinct", 476 "else", 477 "end", 478 "enum", 479 "escape", 480 "except", 481 "exclude", 482 "exists", 483 "extract", 484 "false", 485 "fetch", 486 "following", 487 "for", 488 "from", 489 "full", 490 "group", 491 "grouping", 492 "groups", 493 "hash", 494 "having", 495 "if", 496 "ignore", 497 "in", 498 "inner", 499 "intersect", 500 "interval", 501 "into", 502 "is", 503 "join", 504 "lateral", 505 "left", 506 "like", 507 "limit", 508 "lookup", 509 "merge", 510 "natural", 511 "new", 512 "no", 513 "not", 514 "null", 515 "nulls", 516 "of", 517 "on", 518 "or", 519 "order", 520 "outer", 521 "over", 522 "partition", 523 "preceding", 524 "proto", 525 "qualify", 526 "range", 527 "recursive", 528 "respect", 529 "right", 530 "rollup", 531 "rows", 532 "select", 533 "set", 534 "some", 535 "struct", 536 "tablesample", 537 "then", 538 "to", 539 "treat", 540 "true", 541 "unbounded", 542 "union", 543 "unnest", 544 "using", 545 "when", 546 "where", 547 "window", 548 "with", 549 "within", 550 } 551 552 def attimezone_sql(self, expression: exp.AtTimeZone) -> str: 553 if not isinstance(expression.parent, exp.Cast): 554 return self.func( 555 "TIMESTAMP", self.func("DATETIME", expression.this, expression.args.get("zone")) 556 ) 557 return super().attimezone_sql(expression) 558 559 def trycast_sql(self, expression: exp.TryCast) -> str: 560 return self.cast_sql(expression, safe_prefix="SAFE_") 561 562 def cte_sql(self, expression: exp.CTE) -> str: 563 if expression.alias_column_names: 564 self.unsupported("Column names in CTE definition are not supported.") 565 return super().cte_sql(expression) 566 567 def array_sql(self, expression: exp.Array) -> str: 568 first_arg = seq_get(expression.expressions, 0) 569 if isinstance(first_arg, exp.Subqueryable): 570 return f"ARRAY{self.wrap(self.sql(first_arg))}" 571 572 return inline_array_sql(self, expression) 573 574 def transaction_sql(self, *_) -> str: 575 return "BEGIN TRANSACTION" 576 577 def commit_sql(self, *_) -> str: 578 return "COMMIT TRANSACTION" 579 580 def rollback_sql(self, *_) -> str: 581 return "ROLLBACK TRANSACTION" 582 583 def in_unnest_op(self, expression: exp.Unnest) -> str: 584 return self.sql(expression) 585 586 def except_op(self, expression: exp.Except) -> str: 587 if not expression.args.get("distinct", False): 588 self.unsupported("EXCEPT without DISTINCT is not supported in BigQuery") 589 return f"EXCEPT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}" 590 591 def intersect_op(self, expression: exp.Intersect) -> str: 592 if not expression.args.get("distinct", False): 593 self.unsupported("INTERSECT without DISTINCT is not supported in BigQuery") 594 return f"INTERSECT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}" 595 596 def with_properties(self, properties: exp.Properties) -> str: 597 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.NULLABLE: 'NULLABLE'>, <TokenType.TABLE: 'TABLE'>, <TokenType.MAP: 'MAP'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.ARRAY: 'ARRAY'>}
ID_VAR_TOKENS =
{<TokenType.VAR: 'VAR'>, <TokenType.ORDINALITY: 'ORDINALITY'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.LEFT: 'LEFT'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.NATURAL: 'NATURAL'>, <TokenType.CASE: 'CASE'>, <TokenType.CACHE: 'CACHE'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.COLLATE: 'COLLATE'>, <TokenType.DEFAULT: 'DEFAULT'>, <TokenType.TEXT: 'TEXT'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.IS: 'IS'>, <TokenType.EXISTS: 'EXISTS'>, <TokenType.INDEX: 'INDEX'>, <TokenType.FUNCTION: 'FUNCTION'>, <TokenType.SETTINGS: 'SETTINGS'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.DELETE: 'DELETE'>, <TokenType.AUTO_INCREMENT: 'AUTO_INCREMENT'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.CHAR: 'CHAR'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.OFFSET: 'OFFSET'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.SUPER: 'SUPER'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.VOLATILE: 'VOLATILE'>, <TokenType.UNIQUE: 'UNIQUE'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.ENUM: 'ENUM'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.COMMAND: 'COMMAND'>, <TokenType.EXECUTE: 'EXECUTE'>, <TokenType.LOAD: 'LOAD'>, <TokenType.RANGE: 'RANGE'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>, <TokenType.SHOW: 'SHOW'>, <TokenType.TOP: 'TOP'>, <TokenType.UPDATE: 'UPDATE'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.FILTER: 'FILTER'>, <TokenType.COLUMN: 'COLUMN'>, <TokenType.UINT: 'UINT'>, <TokenType.ROWS: 'ROWS'>, <TokenType.TIME: 'TIME'>, <TokenType.INET: 'INET'>, <TokenType.ANY: 'ANY'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.END: 'END'>, <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.DATE: 'DATE'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.CURRENT_DATE: 'CURRENT_DATE'>, <TokenType.SEMI: 'SEMI'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.MONEY: 'MONEY'>, <TokenType.CURRENT_DATETIME: 'CURRENT_DATETIME'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.SET: 'SET'>, <TokenType.UINT256: 'UINT256'>, <TokenType.COMMIT: 'COMMIT'>, <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.FORMAT: 'FORMAT'>, <TokenType.INT128: 'INT128'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.BIT: 'BIT'>, <TokenType.ROW: 'ROW'>, <TokenType.UNPIVOT: 'UNPIVOT'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.APPLY: 'APPLY'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.ANTI: 'ANTI'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.TRUE: 'TRUE'>, <TokenType.VIEW: 'VIEW'>, <TokenType.WINDOW: 'WINDOW'>, <TokenType.JSON: 'JSON'>, <TokenType.BINARY: 'BINARY'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.DESC: 'DESC'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.NEXT: 'NEXT'>, <TokenType.BEGIN: 'BEGIN'>, <TokenType.COMMENT: 'COMMENT'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.UUID: 'UUID'>, <TokenType.TABLE: 'TABLE'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.CURRENT_USER: 'CURRENT_USER'>, <TokenType.DATABASE: 'DATABASE'>, <TokenType.UINT128: 'UINT128'>, <TokenType.PERCENT: 'PERCENT'>, <TokenType.INT: 'INT'>, <TokenType.MAP: 'MAP'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.MERGE: 'MERGE'>, <TokenType.PROCEDURE: 'PROCEDURE'>, <TokenType.OVERWRITE: 'OVERWRITE'>, <TokenType.DICTIONARY: 'DICTIONARY'>, <TokenType.RIGHT: 'RIGHT'>, <TokenType.ASC: 'ASC'>, <TokenType.ALL: 'ALL'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.KEEP: 'KEEP'>, <TokenType.PARTITION: 'PARTITION'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.TEMPORARY: 'TEMPORARY'>, <TokenType.VALUES: 'VALUES'>, <TokenType.FIRST: 'FIRST'>, <TokenType.XML: 'XML'>, <TokenType.SCHEMA: 'SCHEMA'>, <TokenType.PRAGMA: 'PRAGMA'>, <TokenType.JSONB: 'JSONB'>, <TokenType.ISNULL: 'ISNULL'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.SOME: 'SOME'>, <TokenType.FULL: 'FULL'>, <TokenType.IF: 'IF'>, <TokenType.REFERENCES: 'REFERENCES'>, <TokenType.DESCRIBE: 'DESCRIBE'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.FALSE: 'FALSE'>, <TokenType.PIVOT: 'PIVOT'>, <TokenType.DIV: 'DIV'>, <TokenType.ESCAPE: 'ESCAPE'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.INT256: 'INT256'>, <TokenType.CONSTRAINT: 'CONSTRAINT'>}
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 ESCAPE_LINE_BREAK = True 364 365 TRANSFORMS = { 366 **generator.Generator.TRANSFORMS, 367 exp.ApproxDistinct: rename_func("APPROX_COUNT_DISTINCT"), 368 exp.ArraySize: rename_func("ARRAY_LENGTH"), 369 exp.Cast: transforms.preprocess([transforms.remove_precision_parameterized_types]), 370 exp.CTE: transforms.preprocess([_pushdown_cte_column_names]), 371 exp.DateAdd: _date_add_sql("DATE", "ADD"), 372 exp.DateSub: _date_add_sql("DATE", "SUB"), 373 exp.DatetimeAdd: _date_add_sql("DATETIME", "ADD"), 374 exp.DatetimeSub: _date_add_sql("DATETIME", "SUB"), 375 exp.DateDiff: lambda self, e: f"DATE_DIFF({self.sql(e, 'this')}, {self.sql(e, 'expression')}, {self.sql(e.args.get('unit', 'DAY'))})", 376 exp.DateStrToDate: datestrtodate_sql, 377 exp.DateTrunc: lambda self, e: self.func("DATE_TRUNC", e.this, e.text("unit")), 378 exp.JSONFormat: rename_func("TO_JSON_STRING"), 379 exp.GenerateSeries: rename_func("GENERATE_ARRAY"), 380 exp.GroupConcat: rename_func("STRING_AGG"), 381 exp.ILike: no_ilike_sql, 382 exp.IntDiv: rename_func("DIV"), 383 exp.Max: max_or_greatest, 384 exp.Min: min_or_least, 385 exp.RegexpExtract: lambda self, e: self.func( 386 "REGEXP_EXTRACT", 387 e.this, 388 e.expression, 389 e.args.get("position"), 390 e.args.get("occurrence"), 391 ), 392 exp.RegexpLike: rename_func("REGEXP_CONTAINS"), 393 exp.Select: transforms.preprocess( 394 [ 395 transforms.explode_to_unnest, 396 _unqualify_unnest, 397 transforms.eliminate_distinct_on, 398 _alias_ordered_group, 399 ] 400 ), 401 exp.StrToDate: lambda self, e: f"PARSE_DATE({self.format_time(e)}, {self.sql(e, 'this')})", 402 exp.StrToTime: lambda self, e: f"PARSE_TIMESTAMP({self.format_time(e)}, {self.sql(e, 'this')})", 403 exp.TimeAdd: _date_add_sql("TIME", "ADD"), 404 exp.TimeSub: _date_add_sql("TIME", "SUB"), 405 exp.TimestampAdd: _date_add_sql("TIMESTAMP", "ADD"), 406 exp.TimestampSub: _date_add_sql("TIMESTAMP", "SUB"), 407 exp.TimeStrToTime: timestrtotime_sql, 408 exp.TsOrDsToDate: ts_or_ds_to_date_sql("bigquery"), 409 exp.TsOrDsAdd: _date_add_sql("DATE", "ADD"), 410 exp.PartitionedByProperty: lambda self, e: f"PARTITION BY {self.sql(e, 'this')}", 411 exp.VariancePop: rename_func("VAR_POP"), 412 exp.Values: _derived_table_values_to_unnest, 413 exp.ReturnsProperty: _returnsproperty_sql, 414 exp.Create: _create_sql, 415 exp.Trim: lambda self, e: self.func(f"TRIM", e.this, e.expression), 416 exp.StabilityProperty: lambda self, e: f"DETERMINISTIC" 417 if e.name == "IMMUTABLE" 418 else "NOT DETERMINISTIC", 419 } 420 421 TYPE_MAPPING = { 422 **generator.Generator.TYPE_MAPPING, 423 exp.DataType.Type.BIGDECIMAL: "BIGNUMERIC", 424 exp.DataType.Type.BIGINT: "INT64", 425 exp.DataType.Type.BINARY: "BYTES", 426 exp.DataType.Type.BOOLEAN: "BOOL", 427 exp.DataType.Type.CHAR: "STRING", 428 exp.DataType.Type.DECIMAL: "NUMERIC", 429 exp.DataType.Type.DOUBLE: "FLOAT64", 430 exp.DataType.Type.FLOAT: "FLOAT64", 431 exp.DataType.Type.INT: "INT64", 432 exp.DataType.Type.NCHAR: "STRING", 433 exp.DataType.Type.NVARCHAR: "STRING", 434 exp.DataType.Type.SMALLINT: "INT64", 435 exp.DataType.Type.TEXT: "STRING", 436 exp.DataType.Type.TIMESTAMP: "DATETIME", 437 exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", 438 exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP", 439 exp.DataType.Type.TINYINT: "INT64", 440 exp.DataType.Type.VARBINARY: "BYTES", 441 exp.DataType.Type.VARCHAR: "STRING", 442 exp.DataType.Type.VARIANT: "ANY TYPE", 443 } 444 445 PROPERTIES_LOCATION = { 446 **generator.Generator.PROPERTIES_LOCATION, 447 exp.PartitionedByProperty: exp.Properties.Location.POST_SCHEMA, 448 exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, 449 } 450 451 # from: https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#reserved_keywords 452 RESERVED_KEYWORDS = { 453 *generator.Generator.RESERVED_KEYWORDS, 454 "all", 455 "and", 456 "any", 457 "array", 458 "as", 459 "asc", 460 "assert_rows_modified", 461 "at", 462 "between", 463 "by", 464 "case", 465 "cast", 466 "collate", 467 "contains", 468 "create", 469 "cross", 470 "cube", 471 "current", 472 "default", 473 "define", 474 "desc", 475 "distinct", 476 "else", 477 "end", 478 "enum", 479 "escape", 480 "except", 481 "exclude", 482 "exists", 483 "extract", 484 "false", 485 "fetch", 486 "following", 487 "for", 488 "from", 489 "full", 490 "group", 491 "grouping", 492 "groups", 493 "hash", 494 "having", 495 "if", 496 "ignore", 497 "in", 498 "inner", 499 "intersect", 500 "interval", 501 "into", 502 "is", 503 "join", 504 "lateral", 505 "left", 506 "like", 507 "limit", 508 "lookup", 509 "merge", 510 "natural", 511 "new", 512 "no", 513 "not", 514 "null", 515 "nulls", 516 "of", 517 "on", 518 "or", 519 "order", 520 "outer", 521 "over", 522 "partition", 523 "preceding", 524 "proto", 525 "qualify", 526 "range", 527 "recursive", 528 "respect", 529 "right", 530 "rollup", 531 "rows", 532 "select", 533 "set", 534 "some", 535 "struct", 536 "tablesample", 537 "then", 538 "to", 539 "treat", 540 "true", 541 "unbounded", 542 "union", 543 "unnest", 544 "using", 545 "when", 546 "where", 547 "window", 548 "with", 549 "within", 550 } 551 552 def attimezone_sql(self, expression: exp.AtTimeZone) -> str: 553 if not isinstance(expression.parent, exp.Cast): 554 return self.func( 555 "TIMESTAMP", self.func("DATETIME", expression.this, expression.args.get("zone")) 556 ) 557 return super().attimezone_sql(expression) 558 559 def trycast_sql(self, expression: exp.TryCast) -> str: 560 return self.cast_sql(expression, safe_prefix="SAFE_") 561 562 def cte_sql(self, expression: exp.CTE) -> str: 563 if expression.alias_column_names: 564 self.unsupported("Column names in CTE definition are not supported.") 565 return super().cte_sql(expression) 566 567 def array_sql(self, expression: exp.Array) -> str: 568 first_arg = seq_get(expression.expressions, 0) 569 if isinstance(first_arg, exp.Subqueryable): 570 return f"ARRAY{self.wrap(self.sql(first_arg))}" 571 572 return inline_array_sql(self, expression) 573 574 def transaction_sql(self, *_) -> str: 575 return "BEGIN TRANSACTION" 576 577 def commit_sql(self, *_) -> str: 578 return "COMMIT TRANSACTION" 579 580 def rollback_sql(self, *_) -> str: 581 return "ROLLBACK TRANSACTION" 582 583 def in_unnest_op(self, expression: exp.Unnest) -> str: 584 return self.sql(expression) 585 586 def except_op(self, expression: exp.Except) -> str: 587 if not expression.args.get("distinct", False): 588 self.unsupported("EXCEPT without DISTINCT is not supported in BigQuery") 589 return f"EXCEPT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}" 590 591 def intersect_op(self, expression: exp.Intersect) -> str: 592 if not expression.args.get("distinct", False): 593 self.unsupported("INTERSECT without DISTINCT is not supported in BigQuery") 594 return f"INTERSECT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}" 595 596 def with_properties(self, properties: exp.Properties) -> str: 597 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 =
{'preceding', 'create', 'case', 'for', 'qualify', 'if', 'grouping', 'select', 'at', 'between', 'full', 'assert_rows_modified', 'escape', 'lateral', 'using', 'groups', 'nulls', 'define', 'cast', 'where', 'set', 'in', 'array', 'current', 'rollup', 'on', 'all', 'merge', 'recursive', 'within', 'true', 'right', 'treat', 'end', 'group', 'intersect', 'to', 'following', 'and', 'exists', 'or', 'null', 'desc', 'having', 'join', 'when', 'range', 'unbounded', 'as', 'ignore', 'union', 'interval', 'natural', 'false', 'no', 'some', 'then', 'default', 'left', 'inner', 'cube', 'extract', 'fetch', 'of', 'else', 'window', 'with', 'by', 'exclude', 'distinct', 'new', 'contains', 'not', 'struct', 'over', 'tablesample', 'outer', 'hash', 'unnest', 'from', 'is', 'proto', 'into', 'limit', 'rows', 'cross', 'except', 'enum', 'partition', 'asc', 'respect', 'any', 'like', 'lookup', 'collate', 'order'}
@classmethod
def
can_identify(text: str, identify: str | bool = 'safe') -> bool:
246 @classmethod 247 def can_identify(cls, text: str, identify: str | bool = "safe") -> bool: 248 """Checks if text can be identified given an identify option. 249 250 Args: 251 text: The text to check. 252 identify: 253 "always" or `True`: Always returns true. 254 "safe": True if the identifier is case-insensitive. 255 256 Returns: 257 Whether or not the given text can be identified. 258 """ 259 if identify is True or identify == "always": 260 return True 261 262 if identify == "safe": 263 return not cls.case_sensitive(text) 264 265 return False
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