sqlglot.dialects.bigquery API documentation

Edit on GitHub

# sqlglot.dialects.bigquery

View Source

      1from __future__ import annotations
      2
      3import re
      4import typing as t
      5
      6from sqlglot import exp, generator, parser, tokens, transforms
      7from sqlglot._typing import E
      8from sqlglot.dialects.dialect import (
      9    Dialect,
     10    datestrtodate_sql,
     11    format_time_lambda,
     12    inline_array_sql,
     13    max_or_greatest,
     14    min_or_least,
     15    no_ilike_sql,
     16    parse_date_delta_with_interval,
     17    rename_func,
     18    timestrtotime_sql,
     19    ts_or_ds_to_date_sql,
     20)
     21from sqlglot.helper import seq_get, split_num_words
     22from sqlglot.tokens import TokenType
     23
     24
     25def _date_add_sql(
     26    data_type: str, kind: str
     27) -> t.Callable[[generator.Generator, exp.Expression], str]:
     28    def func(self, expression):
     29        this = self.sql(expression, "this")
     30        unit = expression.args.get("unit")
     31        unit = exp.var(unit.name.upper() if unit else "DAY")
     32        interval = exp.Interval(this=expression.expression, unit=unit)
     33        return f"{data_type}_{kind}({this}, {self.sql(interval)})"
     34
     35    return func
     36
     37
     38def _derived_table_values_to_unnest(self: generator.Generator, expression: exp.Values) -> str:
     39    if not isinstance(expression.unnest().parent, exp.From):
     40        return self.values_sql(expression)
     41
     42    alias = expression.args.get("alias")
     43
     44    structs = [
     45        exp.Struct(
     46            expressions=[
     47                exp.alias_(value, column_name)
     48                for value, column_name in zip(
     49                    t.expressions,
     50                    alias.columns
     51                    if alias and alias.columns
     52                    else (f"_c{i}" for i in range(len(t.expressions))),
     53                )
     54            ]
     55        )
     56        for t in expression.find_all(exp.Tuple)
     57    ]
     58
     59    return self.unnest_sql(exp.Unnest(expressions=[exp.Array(expressions=structs)]))
     60
     61
     62def _returnsproperty_sql(self: generator.Generator, expression: exp.ReturnsProperty) -> str:
     63    this = expression.this
     64    if isinstance(this, exp.Schema):
     65        this = f"{this.this} <{self.expressions(this)}>"
     66    else:
     67        this = self.sql(this)
     68    return f"RETURNS {this}"
     69
     70
     71def _create_sql(self: generator.Generator, expression: exp.Create) -> str:
     72    kind = expression.args["kind"]
     73    returns = expression.find(exp.ReturnsProperty)
     74    if kind.upper() == "FUNCTION" and returns and returns.args.get("is_table"):
     75        expression = expression.copy()
     76        expression.set("kind", "TABLE FUNCTION")
     77        if isinstance(
     78            expression.expression,
     79            (
     80                exp.Subquery,
     81                exp.Literal,
     82            ),
     83        ):
     84            expression.set("expression", expression.expression.this)
     85
     86        return self.create_sql(expression)
     87
     88    return self.create_sql(expression)
     89
     90
     91def _unqualify_unnest(expression: exp.Expression) -> exp.Expression:
     92    """Remove references to unnest table aliases since bigquery doesn't allow them.
     93
     94    These are added by the optimizer's qualify_column step.
     95    """
     96    if isinstance(expression, exp.Select):
     97        for unnest in expression.find_all(exp.Unnest):
     98            if isinstance(unnest.parent, (exp.From, exp.Join)) and unnest.alias:
     99                for select in expression.selects:
    100                    for column in select.find_all(exp.Column):
    101                        if column.table == unnest.alias:
    102                            column.set("table", None)
    103
    104    return expression
    105
    106
    107class BigQuery(Dialect):
    108    UNNEST_COLUMN_ONLY = True
    109
    110    # https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#case_sensitivity
    111    RESOLVES_IDENTIFIERS_AS_UPPERCASE = None
    112
    113    # bigquery udfs are case sensitive
    114    NORMALIZE_FUNCTIONS = False
    115
    116    TIME_MAPPING = {
    117        "%D": "%m/%d/%y",
    118    }
    119
    120    FORMAT_MAPPING = {
    121        "DD": "%d",
    122        "MM": "%m",
    123        "MON": "%b",
    124        "MONTH": "%B",
    125        "YYYY": "%Y",
    126        "YY": "%y",
    127        "HH": "%I",
    128        "HH12": "%I",
    129        "HH24": "%H",
    130        "MI": "%M",
    131        "SS": "%S",
    132        "SSSSS": "%f",
    133        "TZH": "%z",
    134    }
    135
    136    @classmethod
    137    def normalize_identifier(cls, expression: E) -> E:
    138        # In BigQuery, CTEs aren't case-sensitive, but table names are (by default, at least).
    139        # The following check is essentially a heuristic to detect tables based on whether or
    140        # not they're qualified.
    141        if isinstance(expression, exp.Identifier):
    142            parent = expression.parent
    143
    144            while isinstance(parent, exp.Dot):
    145                parent = parent.parent
    146
    147            if not (isinstance(parent, exp.Table) and parent.db) and not expression.meta.get(
    148                "is_table"
    149            ):
    150                expression.set("this", expression.this.lower())
    151
    152        return expression
    153
    154    class Tokenizer(tokens.Tokenizer):
    155        QUOTES = ["'", '"', '"""', "'''"]
    156        COMMENTS = ["--", "#", ("/*", "*/")]
    157        IDENTIFIERS = ["`"]
    158        STRING_ESCAPES = ["\\"]
    159
    160        HEX_STRINGS = [("0x", ""), ("0X", "")]
    161
    162        BYTE_STRINGS = [
    163            (prefix + q, q) for q in t.cast(t.List[str], QUOTES) for prefix in ("b", "B")
    164        ]
    165
    166        RAW_STRINGS = [
    167            (prefix + q, q) for q in t.cast(t.List[str], QUOTES) for prefix in ("r", "R")
    168        ]
    169
    170        KEYWORDS = {
    171            **tokens.Tokenizer.KEYWORDS,
    172            "ANY TYPE": TokenType.VARIANT,
    173            "BEGIN": TokenType.COMMAND,
    174            "BEGIN TRANSACTION": TokenType.BEGIN,
    175            "CURRENT_DATETIME": TokenType.CURRENT_DATETIME,
    176            "BYTES": TokenType.BINARY,
    177            "DECLARE": TokenType.COMMAND,
    178            "FLOAT64": TokenType.DOUBLE,
    179            "INT64": TokenType.BIGINT,
    180            "RECORD": TokenType.STRUCT,
    181            "TIMESTAMP": TokenType.TIMESTAMPTZ,
    182            "NOT DETERMINISTIC": TokenType.VOLATILE,
    183            "UNKNOWN": TokenType.NULL,
    184        }
    185        KEYWORDS.pop("DIV")
    186
    187    class Parser(parser.Parser):
    188        PREFIXED_PIVOT_COLUMNS = True
    189
    190        LOG_BASE_FIRST = False
    191        LOG_DEFAULTS_TO_LN = True
    192
    193        FUNCTIONS = {
    194            **parser.Parser.FUNCTIONS,
    195            "DATE_ADD": parse_date_delta_with_interval(exp.DateAdd),
    196            "DATE_SUB": parse_date_delta_with_interval(exp.DateSub),
    197            "DATE_TRUNC": lambda args: exp.DateTrunc(
    198                unit=exp.Literal.string(str(seq_get(args, 1))),
    199                this=seq_get(args, 0),
    200            ),
    201            "DATETIME_ADD": parse_date_delta_with_interval(exp.DatetimeAdd),
    202            "DATETIME_SUB": parse_date_delta_with_interval(exp.DatetimeSub),
    203            "DIV": lambda args: exp.IntDiv(this=seq_get(args, 0), expression=seq_get(args, 1)),
    204            "GENERATE_ARRAY": exp.GenerateSeries.from_arg_list,
    205            "PARSE_DATE": lambda args: format_time_lambda(exp.StrToDate, "bigquery")(
    206                [seq_get(args, 1), seq_get(args, 0)]
    207            ),
    208            "PARSE_TIMESTAMP": lambda args: format_time_lambda(exp.StrToTime, "bigquery")(
    209                [seq_get(args, 1), seq_get(args, 0)]
    210            ),
    211            "REGEXP_CONTAINS": exp.RegexpLike.from_arg_list,
    212            "REGEXP_EXTRACT": lambda args: exp.RegexpExtract(
    213                this=seq_get(args, 0),
    214                expression=seq_get(args, 1),
    215                position=seq_get(args, 2),
    216                occurrence=seq_get(args, 3),
    217                group=exp.Literal.number(1)
    218                if re.compile(str(seq_get(args, 1))).groups == 1
    219                else None,
    220            ),
    221            "SPLIT": lambda args: exp.Split(
    222                # https://cloud.google.com/bigquery/docs/reference/standard-sql/string_functions#split
    223                this=seq_get(args, 0),
    224                expression=seq_get(args, 1) or exp.Literal.string(","),
    225            ),
    226            "TIME_ADD": parse_date_delta_with_interval(exp.TimeAdd),
    227            "TIME_SUB": parse_date_delta_with_interval(exp.TimeSub),
    228            "TIMESTAMP_ADD": parse_date_delta_with_interval(exp.TimestampAdd),
    229            "TIMESTAMP_SUB": parse_date_delta_with_interval(exp.TimestampSub),
    230            "TO_JSON_STRING": exp.JSONFormat.from_arg_list,
    231        }
    232
    233        FUNCTION_PARSERS = {
    234            **parser.Parser.FUNCTION_PARSERS,
    235            "ARRAY": lambda self: self.expression(exp.Array, expressions=[self._parse_statement()]),
    236        }
    237        FUNCTION_PARSERS.pop("TRIM")
    238
    239        NO_PAREN_FUNCTIONS = {
    240            **parser.Parser.NO_PAREN_FUNCTIONS,
    241            TokenType.CURRENT_DATETIME: exp.CurrentDatetime,
    242        }
    243
    244        NESTED_TYPE_TOKENS = {
    245            *parser.Parser.NESTED_TYPE_TOKENS,
    246            TokenType.TABLE,
    247        }
    248
    249        ID_VAR_TOKENS = {
    250            *parser.Parser.ID_VAR_TOKENS,
    251            TokenType.VALUES,
    252        }
    253
    254        PROPERTY_PARSERS = {
    255            **parser.Parser.PROPERTY_PARSERS,
    256            "NOT DETERMINISTIC": lambda self: self.expression(
    257                exp.StabilityProperty, this=exp.Literal.string("VOLATILE")
    258            ),
    259            "OPTIONS": lambda self: self._parse_with_property(),
    260        }
    261
    262        CONSTRAINT_PARSERS = {
    263            **parser.Parser.CONSTRAINT_PARSERS,
    264            "OPTIONS": lambda self: exp.Properties(expressions=self._parse_with_property()),
    265        }
    266
    267        def _parse_table_part(self, schema: bool = False) -> t.Optional[exp.Expression]:
    268            this = super()._parse_table_part(schema=schema)
    269
    270            # https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#table_names
    271            if isinstance(this, exp.Identifier):
    272                table_name = this.name
    273                while self._match(TokenType.DASH, advance=False) and self._next:
    274                    self._advance(2)
    275                    table_name += f"-{self._prev.text}"
    276
    277                this = exp.Identifier(this=table_name, quoted=this.args.get("quoted"))
    278
    279            return this
    280
    281        def _parse_table_parts(self, schema: bool = False) -> exp.Table:
    282            table = super()._parse_table_parts(schema=schema)
    283            if isinstance(table.this, exp.Identifier) and "." in table.name:
    284                catalog, db, this, *rest = (
    285                    t.cast(t.Optional[exp.Expression], exp.to_identifier(x))
    286                    for x in split_num_words(table.name, ".", 3)
    287                )
    288
    289                if rest and this:
    290                    this = exp.Dot.build(t.cast(t.List[exp.Expression], [this, *rest]))
    291
    292                table = exp.Table(this=this, db=db, catalog=catalog)
    293
    294            return table
    295
    296    class Generator(generator.Generator):
    297        EXPLICIT_UNION = True
    298        INTERVAL_ALLOWS_PLURAL_FORM = False
    299        JOIN_HINTS = False
    300        TABLE_HINTS = False
    301        LIMIT_FETCH = "LIMIT"
    302        RENAME_TABLE_WITH_DB = False
    303
    304        TRANSFORMS = {
    305            **generator.Generator.TRANSFORMS,
    306            exp.ApproxDistinct: rename_func("APPROX_COUNT_DISTINCT"),
    307            exp.ArraySize: rename_func("ARRAY_LENGTH"),
    308            exp.AtTimeZone: lambda self, e: self.func(
    309                "TIMESTAMP", self.func("DATETIME", e.this, e.args.get("zone"))
    310            ),
    311            exp.Cast: transforms.preprocess([transforms.remove_precision_parameterized_types]),
    312            exp.DateAdd: _date_add_sql("DATE", "ADD"),
    313            exp.DateSub: _date_add_sql("DATE", "SUB"),
    314            exp.DatetimeAdd: _date_add_sql("DATETIME", "ADD"),
    315            exp.DatetimeSub: _date_add_sql("DATETIME", "SUB"),
    316            exp.DateDiff: lambda self, e: f"DATE_DIFF({self.sql(e, 'this')}, {self.sql(e, 'expression')}, {self.sql(e.args.get('unit', 'DAY'))})",
    317            exp.DateStrToDate: datestrtodate_sql,
    318            exp.DateTrunc: lambda self, e: self.func("DATE_TRUNC", e.this, e.text("unit")),
    319            exp.JSONFormat: rename_func("TO_JSON_STRING"),
    320            exp.GenerateSeries: rename_func("GENERATE_ARRAY"),
    321            exp.GroupConcat: rename_func("STRING_AGG"),
    322            exp.ILike: no_ilike_sql,
    323            exp.IntDiv: rename_func("DIV"),
    324            exp.Max: max_or_greatest,
    325            exp.Min: min_or_least,
    326            exp.RegexpExtract: lambda self, e: self.func(
    327                "REGEXP_EXTRACT",
    328                e.this,
    329                e.expression,
    330                e.args.get("position"),
    331                e.args.get("occurrence"),
    332            ),
    333            exp.RegexpLike: rename_func("REGEXP_CONTAINS"),
    334            exp.Select: transforms.preprocess(
    335                [transforms.explode_to_unnest, _unqualify_unnest, transforms.eliminate_distinct_on]
    336            ),
    337            exp.StrToDate: lambda self, e: f"PARSE_DATE({self.format_time(e)}, {self.sql(e, 'this')})",
    338            exp.StrToTime: lambda self, e: f"PARSE_TIMESTAMP({self.format_time(e)}, {self.sql(e, 'this')})",
    339            exp.TimeAdd: _date_add_sql("TIME", "ADD"),
    340            exp.TimeSub: _date_add_sql("TIME", "SUB"),
    341            exp.TimestampAdd: _date_add_sql("TIMESTAMP", "ADD"),
    342            exp.TimestampSub: _date_add_sql("TIMESTAMP", "SUB"),
    343            exp.TimeStrToTime: timestrtotime_sql,
    344            exp.TryCast: lambda self, e: f"SAFE_CAST({self.sql(e, 'this')} AS {self.sql(e, 'to')})",
    345            exp.TsOrDsToDate: ts_or_ds_to_date_sql("bigquery"),
    346            exp.TsOrDsAdd: _date_add_sql("DATE", "ADD"),
    347            exp.PartitionedByProperty: lambda self, e: f"PARTITION BY {self.sql(e, 'this')}",
    348            exp.VariancePop: rename_func("VAR_POP"),
    349            exp.Values: _derived_table_values_to_unnest,
    350            exp.ReturnsProperty: _returnsproperty_sql,
    351            exp.Create: _create_sql,
    352            exp.Trim: lambda self, e: self.func(f"TRIM", e.this, e.expression),
    353            exp.StabilityProperty: lambda self, e: f"DETERMINISTIC"
    354            if e.name == "IMMUTABLE"
    355            else "NOT DETERMINISTIC",
    356        }
    357
    358        TYPE_MAPPING = {
    359            **generator.Generator.TYPE_MAPPING,
    360            exp.DataType.Type.BIGDECIMAL: "BIGNUMERIC",
    361            exp.DataType.Type.BIGINT: "INT64",
    362            exp.DataType.Type.BINARY: "BYTES",
    363            exp.DataType.Type.BOOLEAN: "BOOL",
    364            exp.DataType.Type.CHAR: "STRING",
    365            exp.DataType.Type.DECIMAL: "NUMERIC",
    366            exp.DataType.Type.DOUBLE: "FLOAT64",
    367            exp.DataType.Type.FLOAT: "FLOAT64",
    368            exp.DataType.Type.INT: "INT64",
    369            exp.DataType.Type.NCHAR: "STRING",
    370            exp.DataType.Type.NVARCHAR: "STRING",
    371            exp.DataType.Type.SMALLINT: "INT64",
    372            exp.DataType.Type.TEXT: "STRING",
    373            exp.DataType.Type.TIMESTAMP: "DATETIME",
    374            exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP",
    375            exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP",
    376            exp.DataType.Type.TINYINT: "INT64",
    377            exp.DataType.Type.VARBINARY: "BYTES",
    378            exp.DataType.Type.VARCHAR: "STRING",
    379            exp.DataType.Type.VARIANT: "ANY TYPE",
    380        }
    381
    382        PROPERTIES_LOCATION = {
    383            **generator.Generator.PROPERTIES_LOCATION,
    384            exp.PartitionedByProperty: exp.Properties.Location.POST_SCHEMA,
    385            exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED,
    386        }
    387
    388        # from: https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#reserved_keywords
    389        RESERVED_KEYWORDS = {
    390            *generator.Generator.RESERVED_KEYWORDS,
    391            "all",
    392            "and",
    393            "any",
    394            "array",
    395            "as",
    396            "asc",
    397            "assert_rows_modified",
    398            "at",
    399            "between",
    400            "by",
    401            "case",
    402            "cast",
    403            "collate",
    404            "contains",
    405            "create",
    406            "cross",
    407            "cube",
    408            "current",
    409            "default",
    410            "define",
    411            "desc",
    412            "distinct",
    413            "else",
    414            "end",
    415            "enum",
    416            "escape",
    417            "except",
    418            "exclude",
    419            "exists",
    420            "extract",
    421            "false",
    422            "fetch",
    423            "following",
    424            "for",
    425            "from",
    426            "full",
    427            "group",
    428            "grouping",
    429            "groups",
    430            "hash",
    431            "having",
    432            "if",
    433            "ignore",
    434            "in",
    435            "inner",
    436            "intersect",
    437            "interval",
    438            "into",
    439            "is",
    440            "join",
    441            "lateral",
    442            "left",
    443            "like",
    444            "limit",
    445            "lookup",
    446            "merge",
    447            "natural",
    448            "new",
    449            "no",
    450            "not",
    451            "null",
    452            "nulls",
    453            "of",
    454            "on",
    455            "or",
    456            "order",
    457            "outer",
    458            "over",
    459            "partition",
    460            "preceding",
    461            "proto",
    462            "qualify",
    463            "range",
    464            "recursive",
    465            "respect",
    466            "right",
    467            "rollup",
    468            "rows",
    469            "select",
    470            "set",
    471            "some",
    472            "struct",
    473            "tablesample",
    474            "then",
    475            "to",
    476            "treat",
    477            "true",
    478            "unbounded",
    479            "union",
    480            "unnest",
    481            "using",
    482            "when",
    483            "where",
    484            "window",
    485            "with",
    486            "within",
    487        }
    488
    489        def array_sql(self, expression: exp.Array) -> str:
    490            first_arg = seq_get(expression.expressions, 0)
    491            if isinstance(first_arg, exp.Subqueryable):
    492                return f"ARRAY{self.wrap(self.sql(first_arg))}"
    493
    494            return inline_array_sql(self, expression)
    495
    496        def transaction_sql(self, *_) -> str:
    497            return "BEGIN TRANSACTION"
    498
    499        def commit_sql(self, *_) -> str:
    500            return "COMMIT TRANSACTION"
    501
    502        def rollback_sql(self, *_) -> str:
    503            return "ROLLBACK TRANSACTION"
    504
    505        def in_unnest_op(self, expression: exp.Unnest) -> str:
    506            return self.sql(expression)
    507
    508        def except_op(self, expression: exp.Except) -> str:
    509            if not expression.args.get("distinct", False):
    510                self.unsupported("EXCEPT without DISTINCT is not supported in BigQuery")
    511            return f"EXCEPT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}"
    512
    513        def intersect_op(self, expression: exp.Intersect) -> str:
    514            if not expression.args.get("distinct", False):
    515                self.unsupported("INTERSECT without DISTINCT is not supported in BigQuery")
    516            return f"INTERSECT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}"
    517
    518        def with_properties(self, properties: exp.Properties) -> str:
    519            return self.properties(properties, prefix=self.seg("OPTIONS"))

class BigQuery(sqlglot.dialects.dialect.Dialect): View Source

    108class BigQuery(Dialect):
    109    UNNEST_COLUMN_ONLY = True
    110
    111    # https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#case_sensitivity
    112    RESOLVES_IDENTIFIERS_AS_UPPERCASE = None
    113
    114    # bigquery udfs are case sensitive
    115    NORMALIZE_FUNCTIONS = False
    116
    117    TIME_MAPPING = {
    118        "%D": "%m/%d/%y",
    119    }
    120
    121    FORMAT_MAPPING = {
    122        "DD": "%d",
    123        "MM": "%m",
    124        "MON": "%b",
    125        "MONTH": "%B",
    126        "YYYY": "%Y",
    127        "YY": "%y",
    128        "HH": "%I",
    129        "HH12": "%I",
    130        "HH24": "%H",
    131        "MI": "%M",
    132        "SS": "%S",
    133        "SSSSS": "%f",
    134        "TZH": "%z",
    135    }
    136
    137    @classmethod
    138    def normalize_identifier(cls, expression: E) -> E:
    139        # In BigQuery, CTEs aren't case-sensitive, but table names are (by default, at least).
    140        # The following check is essentially a heuristic to detect tables based on whether or
    141        # not they're qualified.
    142        if isinstance(expression, exp.Identifier):
    143            parent = expression.parent
    144
    145            while isinstance(parent, exp.Dot):
    146                parent = parent.parent
    147
    148            if not (isinstance(parent, exp.Table) and parent.db) and not expression.meta.get(
    149                "is_table"
    150            ):
    151                expression.set("this", expression.this.lower())
    152
    153        return expression
    154
    155    class Tokenizer(tokens.Tokenizer):
    156        QUOTES = ["'", '"', '"""', "'''"]
    157        COMMENTS = ["--", "#", ("/*", "*/")]
    158        IDENTIFIERS = ["`"]
    159        STRING_ESCAPES = ["\\"]
    160
    161        HEX_STRINGS = [("0x", ""), ("0X", "")]
    162
    163        BYTE_STRINGS = [
    164            (prefix + q, q) for q in t.cast(t.List[str], QUOTES) for prefix in ("b", "B")
    165        ]
    166
    167        RAW_STRINGS = [
    168            (prefix + q, q) for q in t.cast(t.List[str], QUOTES) for prefix in ("r", "R")
    169        ]
    170
    171        KEYWORDS = {
    172            **tokens.Tokenizer.KEYWORDS,
    173            "ANY TYPE": TokenType.VARIANT,
    174            "BEGIN": TokenType.COMMAND,
    175            "BEGIN TRANSACTION": TokenType.BEGIN,
    176            "CURRENT_DATETIME": TokenType.CURRENT_DATETIME,
    177            "BYTES": TokenType.BINARY,
    178            "DECLARE": TokenType.COMMAND,
    179            "FLOAT64": TokenType.DOUBLE,
    180            "INT64": TokenType.BIGINT,
    181            "RECORD": TokenType.STRUCT,
    182            "TIMESTAMP": TokenType.TIMESTAMPTZ,
    183            "NOT DETERMINISTIC": TokenType.VOLATILE,
    184            "UNKNOWN": TokenType.NULL,
    185        }
    186        KEYWORDS.pop("DIV")
    187
    188    class Parser(parser.Parser):
    189        PREFIXED_PIVOT_COLUMNS = True
    190
    191        LOG_BASE_FIRST = False
    192        LOG_DEFAULTS_TO_LN = True
    193
    194        FUNCTIONS = {
    195            **parser.Parser.FUNCTIONS,
    196            "DATE_ADD": parse_date_delta_with_interval(exp.DateAdd),
    197            "DATE_SUB": parse_date_delta_with_interval(exp.DateSub),
    198            "DATE_TRUNC": lambda args: exp.DateTrunc(
    199                unit=exp.Literal.string(str(seq_get(args, 1))),
    200                this=seq_get(args, 0),
    201            ),
    202            "DATETIME_ADD": parse_date_delta_with_interval(exp.DatetimeAdd),
    203            "DATETIME_SUB": parse_date_delta_with_interval(exp.DatetimeSub),
    204            "DIV": lambda args: exp.IntDiv(this=seq_get(args, 0), expression=seq_get(args, 1)),
    205            "GENERATE_ARRAY": exp.GenerateSeries.from_arg_list,
    206            "PARSE_DATE": lambda args: format_time_lambda(exp.StrToDate, "bigquery")(
    207                [seq_get(args, 1), seq_get(args, 0)]
    208            ),
    209            "PARSE_TIMESTAMP": lambda args: format_time_lambda(exp.StrToTime, "bigquery")(
    210                [seq_get(args, 1), seq_get(args, 0)]
    211            ),
    212            "REGEXP_CONTAINS": exp.RegexpLike.from_arg_list,
    213            "REGEXP_EXTRACT": lambda args: exp.RegexpExtract(
    214                this=seq_get(args, 0),
    215                expression=seq_get(args, 1),
    216                position=seq_get(args, 2),
    217                occurrence=seq_get(args, 3),
    218                group=exp.Literal.number(1)
    219                if re.compile(str(seq_get(args, 1))).groups == 1
    220                else None,
    221            ),
    222            "SPLIT": lambda args: exp.Split(
    223                # https://cloud.google.com/bigquery/docs/reference/standard-sql/string_functions#split
    224                this=seq_get(args, 0),
    225                expression=seq_get(args, 1) or exp.Literal.string(","),
    226            ),
    227            "TIME_ADD": parse_date_delta_with_interval(exp.TimeAdd),
    228            "TIME_SUB": parse_date_delta_with_interval(exp.TimeSub),
    229            "TIMESTAMP_ADD": parse_date_delta_with_interval(exp.TimestampAdd),
    230            "TIMESTAMP_SUB": parse_date_delta_with_interval(exp.TimestampSub),
    231            "TO_JSON_STRING": exp.JSONFormat.from_arg_list,
    232        }
    233
    234        FUNCTION_PARSERS = {
    235            **parser.Parser.FUNCTION_PARSERS,
    236            "ARRAY": lambda self: self.expression(exp.Array, expressions=[self._parse_statement()]),
    237        }
    238        FUNCTION_PARSERS.pop("TRIM")
    239
    240        NO_PAREN_FUNCTIONS = {
    241            **parser.Parser.NO_PAREN_FUNCTIONS,
    242            TokenType.CURRENT_DATETIME: exp.CurrentDatetime,
    243        }
    244
    245        NESTED_TYPE_TOKENS = {
    246            *parser.Parser.NESTED_TYPE_TOKENS,
    247            TokenType.TABLE,
    248        }
    249
    250        ID_VAR_TOKENS = {
    251            *parser.Parser.ID_VAR_TOKENS,
    252            TokenType.VALUES,
    253        }
    254
    255        PROPERTY_PARSERS = {
    256            **parser.Parser.PROPERTY_PARSERS,
    257            "NOT DETERMINISTIC": lambda self: self.expression(
    258                exp.StabilityProperty, this=exp.Literal.string("VOLATILE")
    259            ),
    260            "OPTIONS": lambda self: self._parse_with_property(),
    261        }
    262
    263        CONSTRAINT_PARSERS = {
    264            **parser.Parser.CONSTRAINT_PARSERS,
    265            "OPTIONS": lambda self: exp.Properties(expressions=self._parse_with_property()),
    266        }
    267
    268        def _parse_table_part(self, schema: bool = False) -> t.Optional[exp.Expression]:
    269            this = super()._parse_table_part(schema=schema)
    270
    271            # https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#table_names
    272            if isinstance(this, exp.Identifier):
    273                table_name = this.name
    274                while self._match(TokenType.DASH, advance=False) and self._next:
    275                    self._advance(2)
    276                    table_name += f"-{self._prev.text}"
    277
    278                this = exp.Identifier(this=table_name, quoted=this.args.get("quoted"))
    279
    280            return this
    281
    282        def _parse_table_parts(self, schema: bool = False) -> exp.Table:
    283            table = super()._parse_table_parts(schema=schema)
    284            if isinstance(table.this, exp.Identifier) and "." in table.name:
    285                catalog, db, this, *rest = (
    286                    t.cast(t.Optional[exp.Expression], exp.to_identifier(x))
    287                    for x in split_num_words(table.name, ".", 3)
    288                )
    289
    290                if rest and this:
    291                    this = exp.Dot.build(t.cast(t.List[exp.Expression], [this, *rest]))
    292
    293                table = exp.Table(this=this, db=db, catalog=catalog)
    294
    295            return table
    296
    297    class Generator(generator.Generator):
    298        EXPLICIT_UNION = True
    299        INTERVAL_ALLOWS_PLURAL_FORM = False
    300        JOIN_HINTS = False
    301        TABLE_HINTS = False
    302        LIMIT_FETCH = "LIMIT"
    303        RENAME_TABLE_WITH_DB = False
    304
    305        TRANSFORMS = {
    306            **generator.Generator.TRANSFORMS,
    307            exp.ApproxDistinct: rename_func("APPROX_COUNT_DISTINCT"),
    308            exp.ArraySize: rename_func("ARRAY_LENGTH"),
    309            exp.AtTimeZone: lambda self, e: self.func(
    310                "TIMESTAMP", self.func("DATETIME", e.this, e.args.get("zone"))
    311            ),
    312            exp.Cast: transforms.preprocess([transforms.remove_precision_parameterized_types]),
    313            exp.DateAdd: _date_add_sql("DATE", "ADD"),
    314            exp.DateSub: _date_add_sql("DATE", "SUB"),
    315            exp.DatetimeAdd: _date_add_sql("DATETIME", "ADD"),
    316            exp.DatetimeSub: _date_add_sql("DATETIME", "SUB"),
    317            exp.DateDiff: lambda self, e: f"DATE_DIFF({self.sql(e, 'this')}, {self.sql(e, 'expression')}, {self.sql(e.args.get('unit', 'DAY'))})",
    318            exp.DateStrToDate: datestrtodate_sql,
    319            exp.DateTrunc: lambda self, e: self.func("DATE_TRUNC", e.this, e.text("unit")),
    320            exp.JSONFormat: rename_func("TO_JSON_STRING"),
    321            exp.GenerateSeries: rename_func("GENERATE_ARRAY"),
    322            exp.GroupConcat: rename_func("STRING_AGG"),
    323            exp.ILike: no_ilike_sql,
    324            exp.IntDiv: rename_func("DIV"),
    325            exp.Max: max_or_greatest,
    326            exp.Min: min_or_least,
    327            exp.RegexpExtract: lambda self, e: self.func(
    328                "REGEXP_EXTRACT",
    329                e.this,
    330                e.expression,
    331                e.args.get("position"),
    332                e.args.get("occurrence"),
    333            ),
    334            exp.RegexpLike: rename_func("REGEXP_CONTAINS"),
    335            exp.Select: transforms.preprocess(
    336                [transforms.explode_to_unnest, _unqualify_unnest, transforms.eliminate_distinct_on]
    337            ),
    338            exp.StrToDate: lambda self, e: f"PARSE_DATE({self.format_time(e)}, {self.sql(e, 'this')})",
    339            exp.StrToTime: lambda self, e: f"PARSE_TIMESTAMP({self.format_time(e)}, {self.sql(e, 'this')})",
    340            exp.TimeAdd: _date_add_sql("TIME", "ADD"),
    341            exp.TimeSub: _date_add_sql("TIME", "SUB"),
    342            exp.TimestampAdd: _date_add_sql("TIMESTAMP", "ADD"),
    343            exp.TimestampSub: _date_add_sql("TIMESTAMP", "SUB"),
    344            exp.TimeStrToTime: timestrtotime_sql,
    345            exp.TryCast: lambda self, e: f"SAFE_CAST({self.sql(e, 'this')} AS {self.sql(e, 'to')})",
    346            exp.TsOrDsToDate: ts_or_ds_to_date_sql("bigquery"),
    347            exp.TsOrDsAdd: _date_add_sql("DATE", "ADD"),
    348            exp.PartitionedByProperty: lambda self, e: f"PARTITION BY {self.sql(e, 'this')}",
    349            exp.VariancePop: rename_func("VAR_POP"),
    350            exp.Values: _derived_table_values_to_unnest,
    351            exp.ReturnsProperty: _returnsproperty_sql,
    352            exp.Create: _create_sql,
    353            exp.Trim: lambda self, e: self.func(f"TRIM", e.this, e.expression),
    354            exp.StabilityProperty: lambda self, e: f"DETERMINISTIC"
    355            if e.name == "IMMUTABLE"
    356            else "NOT DETERMINISTIC",
    357        }
    358
    359        TYPE_MAPPING = {
    360            **generator.Generator.TYPE_MAPPING,
    361            exp.DataType.Type.BIGDECIMAL: "BIGNUMERIC",
    362            exp.DataType.Type.BIGINT: "INT64",
    363            exp.DataType.Type.BINARY: "BYTES",
    364            exp.DataType.Type.BOOLEAN: "BOOL",
    365            exp.DataType.Type.CHAR: "STRING",
    366            exp.DataType.Type.DECIMAL: "NUMERIC",
    367            exp.DataType.Type.DOUBLE: "FLOAT64",
    368            exp.DataType.Type.FLOAT: "FLOAT64",
    369            exp.DataType.Type.INT: "INT64",
    370            exp.DataType.Type.NCHAR: "STRING",
    371            exp.DataType.Type.NVARCHAR: "STRING",
    372            exp.DataType.Type.SMALLINT: "INT64",
    373            exp.DataType.Type.TEXT: "STRING",
    374            exp.DataType.Type.TIMESTAMP: "DATETIME",
    375            exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP",
    376            exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP",
    377            exp.DataType.Type.TINYINT: "INT64",
    378            exp.DataType.Type.VARBINARY: "BYTES",
    379            exp.DataType.Type.VARCHAR: "STRING",
    380            exp.DataType.Type.VARIANT: "ANY TYPE",
    381        }
    382
    383        PROPERTIES_LOCATION = {
    384            **generator.Generator.PROPERTIES_LOCATION,
    385            exp.PartitionedByProperty: exp.Properties.Location.POST_SCHEMA,
    386            exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED,
    387        }
    388
    389        # from: https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#reserved_keywords
    390        RESERVED_KEYWORDS = {
    391            *generator.Generator.RESERVED_KEYWORDS,
    392            "all",
    393            "and",
    394            "any",
    395            "array",
    396            "as",
    397            "asc",
    398            "assert_rows_modified",
    399            "at",
    400            "between",
    401            "by",
    402            "case",
    403            "cast",
    404            "collate",
    405            "contains",
    406            "create",
    407            "cross",
    408            "cube",
    409            "current",
    410            "default",
    411            "define",
    412            "desc",
    413            "distinct",
    414            "else",
    415            "end",
    416            "enum",
    417            "escape",
    418            "except",
    419            "exclude",
    420            "exists",
    421            "extract",
    422            "false",
    423            "fetch",
    424            "following",
    425            "for",
    426            "from",
    427            "full",
    428            "group",
    429            "grouping",
    430            "groups",
    431            "hash",
    432            "having",
    433            "if",
    434            "ignore",
    435            "in",
    436            "inner",
    437            "intersect",
    438            "interval",
    439            "into",
    440            "is",
    441            "join",
    442            "lateral",
    443            "left",
    444            "like",
    445            "limit",
    446            "lookup",
    447            "merge",
    448            "natural",
    449            "new",
    450            "no",
    451            "not",
    452            "null",
    453            "nulls",
    454            "of",
    455            "on",
    456            "or",
    457            "order",
    458            "outer",
    459            "over",
    460            "partition",
    461            "preceding",
    462            "proto",
    463            "qualify",
    464            "range",
    465            "recursive",
    466            "respect",
    467            "right",
    468            "rollup",
    469            "rows",
    470            "select",
    471            "set",
    472            "some",
    473            "struct",
    474            "tablesample",
    475            "then",
    476            "to",
    477            "treat",
    478            "true",
    479            "unbounded",
    480            "union",
    481            "unnest",
    482            "using",
    483            "when",
    484            "where",
    485            "window",
    486            "with",
    487            "within",
    488        }
    489
    490        def array_sql(self, expression: exp.Array) -> str:
    491            first_arg = seq_get(expression.expressions, 0)
    492            if isinstance(first_arg, exp.Subqueryable):
    493                return f"ARRAY{self.wrap(self.sql(first_arg))}"
    494
    495            return inline_array_sql(self, expression)
    496
    497        def transaction_sql(self, *_) -> str:
    498            return "BEGIN TRANSACTION"
    499
    500        def commit_sql(self, *_) -> str:
    501            return "COMMIT TRANSACTION"
    502
    503        def rollback_sql(self, *_) -> str:
    504            return "ROLLBACK TRANSACTION"
    505
    506        def in_unnest_op(self, expression: exp.Unnest) -> str:
    507            return self.sql(expression)
    508
    509        def except_op(self, expression: exp.Except) -> str:
    510            if not expression.args.get("distinct", False):
    511                self.unsupported("EXCEPT without DISTINCT is not supported in BigQuery")
    512            return f"EXCEPT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}"
    513
    514        def intersect_op(self, expression: exp.Intersect) -> str:
    515            if not expression.args.get("distinct", False):
    516                self.unsupported("INTERSECT without DISTINCT is not supported in BigQuery")
    517            return f"INTERSECT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}"
    518
    519        def with_properties(self, properties: exp.Properties) -> str:
    520            return self.properties(properties, prefix=self.seg("OPTIONS"))

UNNEST_COLUMN_ONLY = True
RESOLVES_IDENTIFIERS_AS_UPPERCASE: Optional[bool] = None
NORMALIZE_FUNCTIONS: bool | str = False
TIME_MAPPING: Dict[str, str] = {'%D': '%m/%d/%y'}
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: View Source

    137    @classmethod
    138    def normalize_identifier(cls, expression: E) -> E:
    139        # In BigQuery, CTEs aren't case-sensitive, but table names are (by default, at least).
    140        # The following check is essentially a heuristic to detect tables based on whether or
    141        # not they're qualified.
    142        if isinstance(expression, exp.Identifier):
    143            parent = expression.parent
    144
    145            while isinstance(parent, exp.Dot):
    146                parent = parent.parent
    147
    148            if not (isinstance(parent, exp.Table) and parent.db) and not expression.meta.get(
    149                "is_table"
    150            ):
    151                expression.set("this", expression.this.lower())
    152
    153        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'>
TIME_TRIE: Dict = {'%': {'D': {0: True}}}
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}}}}
INVERSE_TIME_MAPPING: Dict[str, str] = {'%m/%d/%y': '%D'}
INVERSE_TIME_TRIE: Dict = {'%': {'m': {'/': {'%': {'d': {'/': {'%': {'y': {0: True}}}}}}}}}
QUOTE_START = "'"
QUOTE_END = "'"
IDENTIFIER_START = '`'
IDENTIFIER_END = '`'
BIT_START = None
BIT_END = None
HEX_START = '0x'
HEX_END = ''
BYTE_START = "b'"
BYTE_END = "'"
RAW_START = "r'"
RAW_END = "'"

##### 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

class BigQuery.Tokenizer(sqlglot.tokens.Tokenizer): View Source

    155    class Tokenizer(tokens.Tokenizer):
    156        QUOTES = ["'", '"', '"""', "'''"]
    157        COMMENTS = ["--", "#", ("/*", "*/")]
    158        IDENTIFIERS = ["`"]
    159        STRING_ESCAPES = ["\\"]
    160
    161        HEX_STRINGS = [("0x", ""), ("0X", "")]
    162
    163        BYTE_STRINGS = [
    164            (prefix + q, q) for q in t.cast(t.List[str], QUOTES) for prefix in ("b", "B")
    165        ]
    166
    167        RAW_STRINGS = [
    168            (prefix + q, q) for q in t.cast(t.List[str], QUOTES) for prefix in ("r", "R")
    169        ]
    170
    171        KEYWORDS = {
    172            **tokens.Tokenizer.KEYWORDS,
    173            "ANY TYPE": TokenType.VARIANT,
    174            "BEGIN": TokenType.COMMAND,
    175            "BEGIN TRANSACTION": TokenType.BEGIN,
    176            "CURRENT_DATETIME": TokenType.CURRENT_DATETIME,
    177            "BYTES": TokenType.BINARY,
    178            "DECLARE": TokenType.COMMAND,
    179            "FLOAT64": TokenType.DOUBLE,
    180            "INT64": TokenType.BIGINT,
    181            "RECORD": TokenType.STRUCT,
    182            "TIMESTAMP": TokenType.TIMESTAMPTZ,
    183            "NOT DETERMINISTIC": TokenType.VOLATILE,
    184            "UNKNOWN": TokenType.NULL,
    185        }
    186        KEYWORDS.pop("DIV")

QUOTES = ["'", '"', '"""', "'''"]
COMMENTS = ['--', '#', ('/*', '*/')]
IDENTIFIERS = ['`']
STRING_ESCAPES = ['\\']
HEX_STRINGS = [('0x', ''), ('0X', '')]
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'>}

##### Inherited Members

sqlglot.tokens.Tokenizer
  SINGLE_TOKENS
  BIT_STRINGS
  IDENTIFIER_ESCAPES
  VAR_SINGLE_TOKENS
  IDENTIFIERS_CAN_START_WITH_DIGIT
  WHITE_SPACE
  COMMANDS
  COMMAND_PREFIX_TOKENS
  NUMERIC_LITERALS
  ENCODE
  reset
  tokenize
  peek
  size
  sql
  tokens

class BigQuery.Parser(sqlglot.parser.Parser): View Source

    188    class Parser(parser.Parser):
    189        PREFIXED_PIVOT_COLUMNS = True
    190
    191        LOG_BASE_FIRST = False
    192        LOG_DEFAULTS_TO_LN = True
    193
    194        FUNCTIONS = {
    195            **parser.Parser.FUNCTIONS,
    196            "DATE_ADD": parse_date_delta_with_interval(exp.DateAdd),
    197            "DATE_SUB": parse_date_delta_with_interval(exp.DateSub),
    198            "DATE_TRUNC": lambda args: exp.DateTrunc(
    199                unit=exp.Literal.string(str(seq_get(args, 1))),
    200                this=seq_get(args, 0),
    201            ),
    202            "DATETIME_ADD": parse_date_delta_with_interval(exp.DatetimeAdd),
    203            "DATETIME_SUB": parse_date_delta_with_interval(exp.DatetimeSub),
    204            "DIV": lambda args: exp.IntDiv(this=seq_get(args, 0), expression=seq_get(args, 1)),
    205            "GENERATE_ARRAY": exp.GenerateSeries.from_arg_list,
    206            "PARSE_DATE": lambda args: format_time_lambda(exp.StrToDate, "bigquery")(
    207                [seq_get(args, 1), seq_get(args, 0)]
    208            ),
    209            "PARSE_TIMESTAMP": lambda args: format_time_lambda(exp.StrToTime, "bigquery")(
    210                [seq_get(args, 1), seq_get(args, 0)]
    211            ),
    212            "REGEXP_CONTAINS": exp.RegexpLike.from_arg_list,
    213            "REGEXP_EXTRACT": lambda args: exp.RegexpExtract(
    214                this=seq_get(args, 0),
    215                expression=seq_get(args, 1),
    216                position=seq_get(args, 2),
    217                occurrence=seq_get(args, 3),
    218                group=exp.Literal.number(1)
    219                if re.compile(str(seq_get(args, 1))).groups == 1
    220                else None,
    221            ),
    222            "SPLIT": lambda args: exp.Split(
    223                # https://cloud.google.com/bigquery/docs/reference/standard-sql/string_functions#split
    224                this=seq_get(args, 0),
    225                expression=seq_get(args, 1) or exp.Literal.string(","),
    226            ),
    227            "TIME_ADD": parse_date_delta_with_interval(exp.TimeAdd),
    228            "TIME_SUB": parse_date_delta_with_interval(exp.TimeSub),
    229            "TIMESTAMP_ADD": parse_date_delta_with_interval(exp.TimestampAdd),
    230            "TIMESTAMP_SUB": parse_date_delta_with_interval(exp.TimestampSub),
    231            "TO_JSON_STRING": exp.JSONFormat.from_arg_list,
    232        }
    233
    234        FUNCTION_PARSERS = {
    235            **parser.Parser.FUNCTION_PARSERS,
    236            "ARRAY": lambda self: self.expression(exp.Array, expressions=[self._parse_statement()]),
    237        }
    238        FUNCTION_PARSERS.pop("TRIM")
    239
    240        NO_PAREN_FUNCTIONS = {
    241            **parser.Parser.NO_PAREN_FUNCTIONS,
    242            TokenType.CURRENT_DATETIME: exp.CurrentDatetime,
    243        }
    244
    245        NESTED_TYPE_TOKENS = {
    246            *parser.Parser.NESTED_TYPE_TOKENS,
    247            TokenType.TABLE,
    248        }
    249
    250        ID_VAR_TOKENS = {
    251            *parser.Parser.ID_VAR_TOKENS,
    252            TokenType.VALUES,
    253        }
    254
    255        PROPERTY_PARSERS = {
    256            **parser.Parser.PROPERTY_PARSERS,
    257            "NOT DETERMINISTIC": lambda self: self.expression(
    258                exp.StabilityProperty, this=exp.Literal.string("VOLATILE")
    259            ),
    260            "OPTIONS": lambda self: self._parse_with_property(),
    261        }
    262
    263        CONSTRAINT_PARSERS = {
    264            **parser.Parser.CONSTRAINT_PARSERS,
    265            "OPTIONS": lambda self: exp.Properties(expressions=self._parse_with_property()),
    266        }
    267
    268        def _parse_table_part(self, schema: bool = False) -> t.Optional[exp.Expression]:
    269            this = super()._parse_table_part(schema=schema)
    270
    271            # https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#table_names
    272            if isinstance(this, exp.Identifier):
    273                table_name = this.name
    274                while self._match(TokenType.DASH, advance=False) and self._next:
    275                    self._advance(2)
    276                    table_name += f"-{self._prev.text}"
    277
    278                this = exp.Identifier(this=table_name, quoted=this.args.get("quoted"))
    279
    280            return this
    281
    282        def _parse_table_parts(self, schema: bool = False) -> exp.Table:
    283            table = super()._parse_table_parts(schema=schema)
    284            if isinstance(table.this, exp.Identifier) and "." in table.name:
    285                catalog, db, this, *rest = (
    286                    t.cast(t.Optional[exp.Expression], exp.to_identifier(x))
    287                    for x in split_num_words(table.name, ".", 3)
    288                )
    289
    290                if rest and this:
    291                    this = exp.Dot.build(t.cast(t.List[exp.Expression], [this, *rest]))
    292
    293                table = exp.Table(this=this, db=db, catalog=catalog)
    294
    295            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

PREFIXED_PIVOT_COLUMNS = True
LOG_BASE_FIRST = False
LOG_DEFAULTS_TO_LN = True
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 = {'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.MAP: 'MAP'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.TABLE: 'TABLE'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.STRUCT: 'STRUCT'>}
ID_VAR_TOKENS = {<TokenType.CURRENT_DATETIME: 'CURRENT_DATETIME'>, <TokenType.TIMESTAMP: 'TIMESTAMP'>, <TokenType.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>, <TokenType.TEMPORARY: 'TEMPORARY'>, <TokenType.HLLSKETCH: 'HLLSKETCH'>, <TokenType.FALSE: 'FALSE'>, <TokenType.FIRST: 'FIRST'>, <TokenType.RIGHT: 'RIGHT'>, <TokenType.DOUBLE: 'DOUBLE'>, <TokenType.FORMAT: 'FORMAT'>, <TokenType.USERDEFINED: 'USERDEFINED'>, <TokenType.TSRANGE: 'TSRANGE'>, <TokenType.CASE: 'CASE'>, <TokenType.ANTI: 'ANTI'>, <TokenType.FULL: 'FULL'>, <TokenType.ALL: 'ALL'>, <TokenType.CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'>, <TokenType.OVERWRITE: 'OVERWRITE'>, <TokenType.IF: 'IF'>, <TokenType.CHAR: 'CHAR'>, <TokenType.PERCENT: 'PERCENT'>, <TokenType.COMMIT: 'COMMIT'>, <TokenType.PRAGMA: 'PRAGMA'>, <TokenType.PSEUDO_TYPE: 'PSEUDO_TYPE'>, <TokenType.CONSTRAINT: 'CONSTRAINT'>, <TokenType.DIV: 'DIV'>, <TokenType.SET: 'SET'>, <TokenType.COMMENT: 'COMMENT'>, <TokenType.DATETIME: 'DATETIME'>, <TokenType.CACHE: 'CACHE'>, <TokenType.INT8MULTIRANGE: 'INT8MULTIRANGE'>, <TokenType.CURRENT_USER: 'CURRENT_USER'>, <TokenType.INT4MULTIRANGE: 'INT4MULTIRANGE'>, <TokenType.OBJECT: 'OBJECT'>, <TokenType.PIVOT: 'PIVOT'>, <TokenType.UPDATE: 'UPDATE'>, <TokenType.ROWS: 'ROWS'>, <TokenType.INDEX: 'INDEX'>, <TokenType.COLUMN: 'COLUMN'>, <TokenType.TEXT: 'TEXT'>, <TokenType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <TokenType.TABLE: 'TABLE'>, <TokenType.NULLABLE: 'NULLABLE'>, <TokenType.ESCAPE: 'ESCAPE'>, <TokenType.VARBINARY: 'VARBINARY'>, <TokenType.IMAGE: 'IMAGE'>, <TokenType.XML: 'XML'>, <TokenType.ASC: 'ASC'>, <TokenType.DATE: 'DATE'>, <TokenType.DESC: 'DESC'>, <TokenType.SERIAL: 'SERIAL'>, <TokenType.VARIANT: 'VARIANT'>, <TokenType.BIGDECIMAL: 'BIGDECIMAL'>, <TokenType.TINYINT: 'TINYINT'>, <TokenType.JSONB: 'JSONB'>, <TokenType.INET: 'INET'>, <TokenType.SUPER: 'SUPER'>, <TokenType.SOME: 'SOME'>, <TokenType.FILTER: 'FILTER'>, <TokenType.INT: 'INT'>, <TokenType.UINT128: 'UINT128'>, <TokenType.TSTZRANGE: 'TSTZRANGE'>, <TokenType.EXECUTE: 'EXECUTE'>, <TokenType.TIME: 'TIME'>, <TokenType.BINARY: 'BINARY'>, <TokenType.DATETIME64: 'DATETIME64'>, <TokenType.SHOW: 'SHOW'>, <TokenType.DATABASE: 'DATABASE'>, <TokenType.ARRAY: 'ARRAY'>, <TokenType.END: 'END'>, <TokenType.DECIMAL: 'DECIMAL'>, <TokenType.RANGE: 'RANGE'>, <TokenType.MEDIUMTEXT: 'MEDIUMTEXT'>, <TokenType.BIT: 'BIT'>, <TokenType.SEMI: 'SEMI'>, <TokenType.SETTINGS: 'SETTINGS'>, <TokenType.MONEY: 'MONEY'>, <TokenType.COLLATE: 'COLLATE'>, <TokenType.SMALLINT: 'SMALLINT'>, <TokenType.UNIQUE: 'UNIQUE'>, <TokenType.SMALLSERIAL: 'SMALLSERIAL'>, <TokenType.VARCHAR: 'VARCHAR'>, <TokenType.UBIGINT: 'UBIGINT'>, <TokenType.AUTO_INCREMENT: 'AUTO_INCREMENT'>, <TokenType.VAR: 'VAR'>, <TokenType.MEDIUMBLOB: 'MEDIUMBLOB'>, <TokenType.ISNULL: 'ISNULL'>, <TokenType.DATERANGE: 'DATERANGE'>, <TokenType.INT8RANGE: 'INT8RANGE'>, <TokenType.VALUES: 'VALUES'>, <TokenType.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>, <TokenType.UTINYINT: 'UTINYINT'>, <TokenType.NUMRANGE: 'NUMRANGE'>, <TokenType.DELETE: 'DELETE'>, <TokenType.TSMULTIRANGE: 'TSMULTIRANGE'>, <TokenType.ROWVERSION: 'ROWVERSION'>, <TokenType.ANY: 'ANY'>, <TokenType.DEFAULT: 'DEFAULT'>, <TokenType.REFERENCES: 'REFERENCES'>, <TokenType.MERGE: 'MERGE'>, <TokenType.OFFSET: 'OFFSET'>, <TokenType.BIGINT: 'BIGINT'>, <TokenType.TOP: 'TOP'>, <TokenType.INT128: 'INT128'>, <TokenType.ENUM: 'ENUM'>, <TokenType.UNPIVOT: 'UNPIVOT'>, <TokenType.PARTITION: 'PARTITION'>, <TokenType.NATURAL: 'NATURAL'>, <TokenType.COMMAND: 'COMMAND'>, <TokenType.ORDINALITY: 'ORDINALITY'>, <TokenType.DESCRIBE: 'DESCRIBE'>, <TokenType.GEOMETRY: 'GEOMETRY'>, <TokenType.ROW: 'ROW'>, <TokenType.LONGBLOB: 'LONGBLOB'>, <TokenType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <TokenType.NCHAR: 'NCHAR'>, <TokenType.VIEW: 'VIEW'>, <TokenType.BEGIN: 'BEGIN'>, <TokenType.INT4RANGE: 'INT4RANGE'>, <TokenType.GEOGRAPHY: 'GEOGRAPHY'>, <TokenType.IS: 'IS'>, <TokenType.APPLY: 'APPLY'>, <TokenType.FLOAT: 'FLOAT'>, <TokenType.UUID: 'UUID'>, <TokenType.LEFT: 'LEFT'>, <TokenType.CURRENT_TIME: 'CURRENT_TIME'>, <TokenType.VOLATILE: 'VOLATILE'>, <TokenType.SMALLMONEY: 'SMALLMONEY'>, <TokenType.SCHEMA: 'SCHEMA'>, <TokenType.NVARCHAR: 'NVARCHAR'>, <TokenType.DICTIONARY: 'DICTIONARY'>, <TokenType.CURRENT_DATE: 'CURRENT_DATE'>, <TokenType.JSON: 'JSON'>, <TokenType.LOAD: 'LOAD'>, <TokenType.INTERVAL: 'INTERVAL'>, <TokenType.NUMMULTIRANGE: 'NUMMULTIRANGE'>, <TokenType.LONGTEXT: 'LONGTEXT'>, <TokenType.INT256: 'INT256'>, <TokenType.DATEMULTIRANGE: 'DATEMULTIRANGE'>, <TokenType.UINT256: 'UINT256'>, <TokenType.UINT: 'UINT'>, <TokenType.KEEP: 'KEEP'>, <TokenType.USMALLINT: 'USMALLINT'>, <TokenType.TRUE: 'TRUE'>, <TokenType.EXISTS: 'EXISTS'>, <TokenType.BIGSERIAL: 'BIGSERIAL'>, <TokenType.BOOLEAN: 'BOOLEAN'>, <TokenType.MAP: 'MAP'>, <TokenType.PROCEDURE: 'PROCEDURE'>, <TokenType.FUNCTION: 'FUNCTION'>, <TokenType.STRUCT: 'STRUCT'>, <TokenType.HSTORE: 'HSTORE'>, <TokenType.NEXT: 'NEXT'>, <TokenType.WINDOW: 'WINDOW'>}
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>>}
UNNEST_COLUMN_ONLY: bool = True
SHOW_TRIE: Dict = {}
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}}}}
TIME_MAPPING: Dict[str, str] = {'%D': '%m/%d/%y'}
TIME_TRIE: Dict = {'%': {'D': {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

class BigQuery.Generator(sqlglot.generator.Generator): View Source

    297    class Generator(generator.Generator):
    298        EXPLICIT_UNION = True
    299        INTERVAL_ALLOWS_PLURAL_FORM = False
    300        JOIN_HINTS = False
    301        TABLE_HINTS = False
    302        LIMIT_FETCH = "LIMIT"
    303        RENAME_TABLE_WITH_DB = False
    304
    305        TRANSFORMS = {
    306            **generator.Generator.TRANSFORMS,
    307            exp.ApproxDistinct: rename_func("APPROX_COUNT_DISTINCT"),
    308            exp.ArraySize: rename_func("ARRAY_LENGTH"),
    309            exp.AtTimeZone: lambda self, e: self.func(
    310                "TIMESTAMP", self.func("DATETIME", e.this, e.args.get("zone"))
    311            ),
    312            exp.Cast: transforms.preprocess([transforms.remove_precision_parameterized_types]),
    313            exp.DateAdd: _date_add_sql("DATE", "ADD"),
    314            exp.DateSub: _date_add_sql("DATE", "SUB"),
    315            exp.DatetimeAdd: _date_add_sql("DATETIME", "ADD"),
    316            exp.DatetimeSub: _date_add_sql("DATETIME", "SUB"),
    317            exp.DateDiff: lambda self, e: f"DATE_DIFF({self.sql(e, 'this')}, {self.sql(e, 'expression')}, {self.sql(e.args.get('unit', 'DAY'))})",
    318            exp.DateStrToDate: datestrtodate_sql,
    319            exp.DateTrunc: lambda self, e: self.func("DATE_TRUNC", e.this, e.text("unit")),
    320            exp.JSONFormat: rename_func("TO_JSON_STRING"),
    321            exp.GenerateSeries: rename_func("GENERATE_ARRAY"),
    322            exp.GroupConcat: rename_func("STRING_AGG"),
    323            exp.ILike: no_ilike_sql,
    324            exp.IntDiv: rename_func("DIV"),
    325            exp.Max: max_or_greatest,
    326            exp.Min: min_or_least,
    327            exp.RegexpExtract: lambda self, e: self.func(
    328                "REGEXP_EXTRACT",
    329                e.this,
    330                e.expression,
    331                e.args.get("position"),
    332                e.args.get("occurrence"),
    333            ),
    334            exp.RegexpLike: rename_func("REGEXP_CONTAINS"),
    335            exp.Select: transforms.preprocess(
    336                [transforms.explode_to_unnest, _unqualify_unnest, transforms.eliminate_distinct_on]
    337            ),
    338            exp.StrToDate: lambda self, e: f"PARSE_DATE({self.format_time(e)}, {self.sql(e, 'this')})",
    339            exp.StrToTime: lambda self, e: f"PARSE_TIMESTAMP({self.format_time(e)}, {self.sql(e, 'this')})",
    340            exp.TimeAdd: _date_add_sql("TIME", "ADD"),
    341            exp.TimeSub: _date_add_sql("TIME", "SUB"),
    342            exp.TimestampAdd: _date_add_sql("TIMESTAMP", "ADD"),
    343            exp.TimestampSub: _date_add_sql("TIMESTAMP", "SUB"),
    344            exp.TimeStrToTime: timestrtotime_sql,
    345            exp.TryCast: lambda self, e: f"SAFE_CAST({self.sql(e, 'this')} AS {self.sql(e, 'to')})",
    346            exp.TsOrDsToDate: ts_or_ds_to_date_sql("bigquery"),
    347            exp.TsOrDsAdd: _date_add_sql("DATE", "ADD"),
    348            exp.PartitionedByProperty: lambda self, e: f"PARTITION BY {self.sql(e, 'this')}",
    349            exp.VariancePop: rename_func("VAR_POP"),
    350            exp.Values: _derived_table_values_to_unnest,
    351            exp.ReturnsProperty: _returnsproperty_sql,
    352            exp.Create: _create_sql,
    353            exp.Trim: lambda self, e: self.func(f"TRIM", e.this, e.expression),
    354            exp.StabilityProperty: lambda self, e: f"DETERMINISTIC"
    355            if e.name == "IMMUTABLE"
    356            else "NOT DETERMINISTIC",
    357        }
    358
    359        TYPE_MAPPING = {
    360            **generator.Generator.TYPE_MAPPING,
    361            exp.DataType.Type.BIGDECIMAL: "BIGNUMERIC",
    362            exp.DataType.Type.BIGINT: "INT64",
    363            exp.DataType.Type.BINARY: "BYTES",
    364            exp.DataType.Type.BOOLEAN: "BOOL",
    365            exp.DataType.Type.CHAR: "STRING",
    366            exp.DataType.Type.DECIMAL: "NUMERIC",
    367            exp.DataType.Type.DOUBLE: "FLOAT64",
    368            exp.DataType.Type.FLOAT: "FLOAT64",
    369            exp.DataType.Type.INT: "INT64",
    370            exp.DataType.Type.NCHAR: "STRING",
    371            exp.DataType.Type.NVARCHAR: "STRING",
    372            exp.DataType.Type.SMALLINT: "INT64",
    373            exp.DataType.Type.TEXT: "STRING",
    374            exp.DataType.Type.TIMESTAMP: "DATETIME",
    375            exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP",
    376            exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP",
    377            exp.DataType.Type.TINYINT: "INT64",
    378            exp.DataType.Type.VARBINARY: "BYTES",
    379            exp.DataType.Type.VARCHAR: "STRING",
    380            exp.DataType.Type.VARIANT: "ANY TYPE",
    381        }
    382
    383        PROPERTIES_LOCATION = {
    384            **generator.Generator.PROPERTIES_LOCATION,
    385            exp.PartitionedByProperty: exp.Properties.Location.POST_SCHEMA,
    386            exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED,
    387        }
    388
    389        # from: https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#reserved_keywords
    390        RESERVED_KEYWORDS = {
    391            *generator.Generator.RESERVED_KEYWORDS,
    392            "all",
    393            "and",
    394            "any",
    395            "array",
    396            "as",
    397            "asc",
    398            "assert_rows_modified",
    399            "at",
    400            "between",
    401            "by",
    402            "case",
    403            "cast",
    404            "collate",
    405            "contains",
    406            "create",
    407            "cross",
    408            "cube",
    409            "current",
    410            "default",
    411            "define",
    412            "desc",
    413            "distinct",
    414            "else",
    415            "end",
    416            "enum",
    417            "escape",
    418            "except",
    419            "exclude",
    420            "exists",
    421            "extract",
    422            "false",
    423            "fetch",
    424            "following",
    425            "for",
    426            "from",
    427            "full",
    428            "group",
    429            "grouping",
    430            "groups",
    431            "hash",
    432            "having",
    433            "if",
    434            "ignore",
    435            "in",
    436            "inner",
    437            "intersect",
    438            "interval",
    439            "into",
    440            "is",
    441            "join",
    442            "lateral",
    443            "left",
    444            "like",
    445            "limit",
    446            "lookup",
    447            "merge",
    448            "natural",
    449            "new",
    450            "no",
    451            "not",
    452            "null",
    453            "nulls",
    454            "of",
    455            "on",
    456            "or",
    457            "order",
    458            "outer",
    459            "over",
    460            "partition",
    461            "preceding",
    462            "proto",
    463            "qualify",
    464            "range",
    465            "recursive",
    466            "respect",
    467            "right",
    468            "rollup",
    469            "rows",
    470            "select",
    471            "set",
    472            "some",
    473            "struct",
    474            "tablesample",
    475            "then",
    476            "to",
    477            "treat",
    478            "true",
    479            "unbounded",
    480            "union",
    481            "unnest",
    482            "using",
    483            "when",
    484            "where",
    485            "window",
    486            "with",
    487            "within",
    488        }
    489
    490        def array_sql(self, expression: exp.Array) -> str:
    491            first_arg = seq_get(expression.expressions, 0)
    492            if isinstance(first_arg, exp.Subqueryable):
    493                return f"ARRAY{self.wrap(self.sql(first_arg))}"
    494
    495            return inline_array_sql(self, expression)
    496
    497        def transaction_sql(self, *_) -> str:
    498            return "BEGIN TRANSACTION"
    499
    500        def commit_sql(self, *_) -> str:
    501            return "COMMIT TRANSACTION"
    502
    503        def rollback_sql(self, *_) -> str:
    504            return "ROLLBACK TRANSACTION"
    505
    506        def in_unnest_op(self, expression: exp.Unnest) -> str:
    507            return self.sql(expression)
    508
    509        def except_op(self, expression: exp.Except) -> str:
    510            if not expression.args.get("distinct", False):
    511                self.unsupported("EXCEPT without DISTINCT is not supported in BigQuery")
    512            return f"EXCEPT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}"
    513
    514        def intersect_op(self, expression: exp.Intersect) -> str:
    515            if not expression.args.get("distinct", False):
    516                self.unsupported("INTERSECT without DISTINCT is not supported in BigQuery")
    517            return f"INTERSECT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}"
    518
    519        def with_properties(self, properties: exp.Properties) -> str:
    520            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

EXPLICIT_UNION = True
INTERVAL_ALLOWS_PLURAL_FORM = False
JOIN_HINTS = False
TABLE_HINTS = False
LIMIT_FETCH = 'LIMIT'
RENAME_TABLE_WITH_DB = False
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.AtTimeZone'>: <function BigQuery.Generator.<lambda>>, <class 'sqlglot.expressions.Cast'>: <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.TryCast'>: <function BigQuery.Generator.<lambda>>, <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 = {'fetch', 'enum', 'between', 'extract', 'over', 'then', 'true', 'on', 'within', 'contains', 'hash', 'collate', 'as', 'interval', 'and', 'escape', 'using', 'full', 'lookup', 'partition', 'of', 'like', 'intersect', 'lateral', 'when', 'no', 'struct', 'create', 'rollup', 'if', 'set', 'outer', 'limit', 'asc', 'default', 'is', 'not', 'any', 'from', 'respect', 'except', 'left', 'cube', 'assert_rows_modified', 'desc', 'at', 'distinct', 'recursive', 'unbounded', 'order', 'cross', 'end', 'current', 'unnest', 'false', 'exists', 'into', 'proto', 'nulls', 'preceding', 'grouping', 'exclude', 'null', 'group', 'window', 'range', 'having', 'array', 'merge', 'cast', 'where', 'define', 'groups', 'join', 'rows', 'with', 'else', 'to', 'in', 'union', 'case', 'new', 'tablesample', 'ignore', 'select', 'inner', 'for', 'following', 'right', 'natural', 'treat', 'qualify', 'or', 'all', 'by', 'some'}
def array_sql(self, expression: sqlglot.expressions.Array) -> str: View Source

    490        def array_sql(self, expression: exp.Array) -> str:
    491            first_arg = seq_get(expression.expressions, 0)
    492            if isinstance(first_arg, exp.Subqueryable):
    493                return f"ARRAY{self.wrap(self.sql(first_arg))}"
    494
    495            return inline_array_sql(self, expression)

def transaction_sql(self, *_) -> str: View Source

    497        def transaction_sql(self, *_) -> str:
    498            return "BEGIN TRANSACTION"

def commit_sql(self, *_) -> str: View Source

    500        def commit_sql(self, *_) -> str:
    501            return "COMMIT TRANSACTION"

def rollback_sql(self, *_) -> str: View Source

    503        def rollback_sql(self, *_) -> str:
    504            return "ROLLBACK TRANSACTION"

def in_unnest_op(self, expression: sqlglot.expressions.Unnest) -> str: View Source

    506        def in_unnest_op(self, expression: exp.Unnest) -> str:
    507            return self.sql(expression)

def except_op(self, expression: sqlglot.expressions.Except) -> str: View Source

    509        def except_op(self, expression: exp.Except) -> str:
    510            if not expression.args.get("distinct", False):
    511                self.unsupported("EXCEPT without DISTINCT is not supported in BigQuery")
    512            return f"EXCEPT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}"

def intersect_op(self, expression: sqlglot.expressions.Intersect) -> str: View Source

    514        def intersect_op(self, expression: exp.Intersect) -> str:
    515            if not expression.args.get("distinct", False):
    516                self.unsupported("INTERSECT without DISTINCT is not supported in BigQuery")
    517            return f"INTERSECT{' DISTINCT' if expression.args.get('distinct') else ' ALL'}"

def with_properties(self, properties: sqlglot.expressions.Properties) -> str: View Source

    519        def with_properties(self, properties: exp.Properties) -> str:
    520            return self.properties(properties, prefix=self.seg("OPTIONS"))

INVERSE_TIME_MAPPING: Dict[str, str] = {'%m/%d/%y': '%D'}
INVERSE_TIME_TRIE: Dict = {'%': {'m': {'/': {'%': {'d': {'/': {'%': {'y': {0: True}}}}}}}}}
UNNEST_COLUMN_ONLY = True
NORMALIZE_FUNCTIONS: bool | str = False
@classmethod
def can_identify(text: str, identify: str | bool = 'safe') -> bool: View Source

    247    @classmethod
    248    def can_identify(cls, text: str, identify: str | bool = "safe") -> bool:
    249        """Checks if text can be identified given an identify option.
    250
    251        Args:
    252            text: The text to check.
    253            identify:
    254                "always" or `True`: Always returns true.
    255                "safe": True if the identifier is case-insensitive.
    256
    257        Returns:
    258            Whether or not the given text can be identified.
    259        """
    260        if identify is True or identify == "always":
    261            return True
    262
    263        if identify == "safe":
    264            return not cls.case_sensitive(text)
    265
    266        return False

Checks if text can be identified given an identify option.

###### Arguments:

- text: The text to check.
- identify: "always" or `True`: Always returns true. "safe": True if the identifier is case-insensitive.

###### Returns:

> Whether or not the given text can be identified.

QUOTE_START = "'"
QUOTE_END = "'"
IDENTIFIER_START = '`'
IDENTIFIER_END = '`'
STRING_ESCAPE = '\\'
IDENTIFIER_ESCAPE = '"'
BIT_START: Optional[str] = None
BIT_END: Optional[str] = None
HEX_START: Optional[str] = '0x'
HEX_END: Optional[str] = ''
BYTE_START: Optional[str] = "b'"
BYTE_END: Optional[str] = "'"
RAW_START: Optional[str] = "r'"
RAW_END: Optional[str] = "'"

##### 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
  cte_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
  attimezone_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
  trycast_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