Edit on GitHub

sqlglot.dialects.bigquery

  1from __future__ import annotations
  2
  3import typing as t
  4
  5
  6from sqlglot.optimizer.annotate_types import TypeAnnotator
  7
  8from sqlglot import exp, jsonpath, tokens
  9from sqlglot._typing import E
 10from sqlglot.parsers.bigquery import BigQueryParser
 11from sqlglot.generators.bigquery import BigQueryGenerator
 12from sqlglot.dialects.dialect import (
 13    ASCII_LOWER,
 14    Dialect,
 15    NormalizationStrategy,
 16)
 17from sqlglot.tokens import TokenType
 18from sqlglot.typing.bigquery import EXPRESSION_METADATA
 19
 20if t.TYPE_CHECKING:
 21    from sqlglot.optimizer.annotate_types import TypeAnnotator
 22
 23
 24class BigQuery(Dialect):
 25    WEEK_OFFSET = -1
 26    UNNEST_COLUMN_ONLY = True
 27    SUPPORTS_USER_DEFINED_TYPES = False
 28    LOG_BASE_FIRST = False
 29    HEX_LOWERCASE = True
 30    FORCE_EARLY_ALIAS_REF_EXPANSION = True
 31    EXPAND_ONLY_GROUP_ALIAS_REF = True
 32    PRESERVE_ORIGINAL_NAMES = True
 33    HEX_STRING_IS_INTEGER_TYPE = True
 34    BYTE_STRING_IS_BYTES_TYPE = True
 35    UUID_IS_STRING_TYPE = True
 36    ANNOTATE_ALL_SCOPES = True
 37    PROJECTION_ALIASES_SHADOW_SOURCE_NAMES = True
 38    TABLES_REFERENCEABLE_AS_COLUMNS = True
 39    SUPPORTS_STRUCT_STAR_EXPANSION = True
 40    EXCLUDES_PSEUDOCOLUMNS_FROM_STAR = True
 41    QUERY_RESULTS_ARE_STRUCTS = True
 42    JSON_EXTRACT_SCALAR_SCALAR_ONLY = True
 43    JSON_PATH_SINGLE_DOT_IS_WILDCARD = True
 44    LEAST_GREATEST_IGNORES_NULLS = False
 45    DEFAULT_NULL_TYPE = exp.DType.BIGINT
 46    PRIORITIZE_NON_LITERAL_TYPES = True
 47    ALIAS_POST_VERSION = False
 48
 49    # https://docs.cloud.google.com/bigquery/docs/reference/standard-sql/string_functions#initcap
 50    INITCAP_DEFAULT_DELIMITER_CHARS = ' \t\n\r\f\v\\[\\](){}/|<>!?@"^#$&~_,.:;*%+\\-'
 51
 52    # https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#case_sensitivity
 53    NORMALIZATION_STRATEGY = NormalizationStrategy.CASE_INSENSITIVE
 54    ASCII_ONLY_NORMALIZATION = True
 55
 56    # bigquery udfs are case sensitive
 57    NORMALIZE_FUNCTIONS = False
 58
 59    # https://cloud.google.com/bigquery/docs/reference/standard-sql/format-elements#format_elements_date_time
 60    TIME_MAPPING = {
 61        "%x": "%m/%d/%y",
 62        "%D": "%m/%d/%y",
 63        "%E6S": "%S.%f",
 64        "%e": "%-d",
 65        "%F": "%Y-%m-%d",
 66        "%T": "%H:%M:%S",
 67        "%c": "%a %b %e %H:%M:%S %Y",
 68    }
 69
 70    INVERSE_TIME_MAPPING = {
 71        # Preserve %E6S instead of expanding to %T.%f - since both %E6S & %T.%f are semantically different in BigQuery
 72        # %E6S is semantically different from %T.%f: %E6S works as a single atomic specifier for seconds with microseconds, while %T.%f expands incorrectly and fails to parse.
 73        "%H:%M:%S.%f": "%H:%M:%E6S",
 74    }
 75
 76    FORMAT_MAPPING = {
 77        "dd": "%d",
 78        "DD": "%d",
 79        "mm": "%m",
 80        "MM": "%m",
 81        "mon": "%b",
 82        "MON": "%b",
 83        "month": "%B",
 84        "MONTH": "%B",
 85        "yyyy": "%Y",
 86        "YYYY": "%Y",
 87        "yy": "%y",
 88        "YY": "%y",
 89        "HH": "%I",
 90        "HH12": "%I",
 91        "hh24": "%H",
 92        "HH24": "%H",
 93        "mi": "%M",
 94        "MI": "%M",
 95        "ss": "%S",
 96        "SS": "%S",
 97        "SSSSS": "%f",
 98        "tzh": "%z",
 99        "TZH": "%z",
100    }
101
102    # The _PARTITIONTIME and _PARTITIONDATE pseudo-columns are not returned by a SELECT * statement
103    # https://cloud.google.com/bigquery/docs/querying-partitioned-tables#query_an_ingestion-time_partitioned_table
104    # https://cloud.google.com/bigquery/docs/querying-wildcard-tables#scanning_a_range_of_tables_using_table_suffix
105    # https://cloud.google.com/bigquery/docs/query-cloud-storage-data#query_the_file_name_pseudo-column
106    PSEUDOCOLUMNS = {
107        "_PARTITIONTIME",
108        "_PARTITIONDATE",
109        "_TABLE_SUFFIX",
110        "_FILE_NAME",
111        "_DBT_MAX_PARTITION",
112    }
113
114    # All set operations require either a DISTINCT or ALL specifier
115    SET_OP_DISTINCT_BY_DEFAULT = dict.fromkeys((exp.Except, exp.Intersect, exp.Union), None)
116
117    # https://cloud.google.com/bigquery/docs/reference/standard-sql/navigation_functions#percentile_cont
118    COERCES_TO = {
119        **TypeAnnotator.COERCES_TO,
120        exp.DType.BIGDECIMAL: {exp.DType.DOUBLE},
121    }
122    COERCES_TO[exp.DType.DECIMAL] |= {exp.DType.BIGDECIMAL}
123    COERCES_TO[exp.DType.BIGINT] |= {exp.DType.BIGDECIMAL}
124    COERCES_TO[exp.DType.VARCHAR] |= {
125        exp.DType.DATE,
126        exp.DType.DATETIME,
127        exp.DType.TIME,
128        exp.DType.TIMESTAMP,
129        exp.DType.TIMESTAMPTZ,
130    }
131
132    EXPRESSION_METADATA = EXPRESSION_METADATA.copy()
133
134    def normalize_identifier(self, expression: E) -> E:
135        if (
136            isinstance(expression, exp.Identifier)
137            and self.normalization_strategy is NormalizationStrategy.CASE_INSENSITIVE
138        ):
139            parent = expression.parent
140            while isinstance(parent, exp.Dot):
141                parent = parent.parent
142
143            # In BigQuery, CTEs are case-insensitive, but UDF and table names are case-sensitive
144            # by default. The following check uses a heuristic to detect tables based on whether
145            # they are qualified. This should generally be correct, because tables in BigQuery
146            # must be qualified with at least a dataset, unless @@dataset_id is set.
147            case_sensitive = (
148                isinstance(parent, exp.UserDefinedFunction)
149                or (
150                    isinstance(parent, exp.Table)
151                    and parent.db
152                    and (parent.meta_get("quoted_table") or not parent.meta_get("maybe_column"))
153                )
154                or expression.meta_get("is_table")
155            )
156            if not case_sensitive:
157                expression.set("this", expression.this.translate(ASCII_LOWER))
158
159            return t.cast(E, expression)
160
161        return super().normalize_identifier(expression)
162
163    class JSONPathTokenizer(jsonpath.JSONPathTokenizer):
164        VAR_TOKENS = {
165            *jsonpath.JSONPathTokenizer.VAR_TOKENS,
166            TokenType.DASH,
167            TokenType.NUMBER,
168        }
169
170    class Tokenizer(tokens.Tokenizer):
171        QUOTES = ["'", '"', '"""', "'''"]
172        COMMENTS = ["--", "#", ("/*", "*/")]
173        IDENTIFIERS = ["`"]
174        STRING_ESCAPES = ["\\"]
175
176        HEX_STRINGS = [("0x", ""), ("0X", "")]
177
178        BYTE_STRINGS = [(prefix + q, q) for q in t.cast(list[str], QUOTES) for prefix in ("b", "B")]
179
180        RAW_STRINGS = [(prefix + q, q) for q in t.cast(list[str], QUOTES) for prefix in ("r", "R")]
181
182        NESTED_COMMENTS = False
183
184        KEYWORDS = {
185            **tokens.Tokenizer.KEYWORDS,
186            "ANY TYPE": TokenType.VARIANT,
187            "BEGIN": TokenType.COMMAND,
188            "BEGIN TRANSACTION": TokenType.BEGIN,
189            "BYTEINT": TokenType.INT,
190            "BYTES": TokenType.BINARY,
191            "CURRENT_DATETIME": TokenType.CURRENT_DATETIME,
192            "DATETIME": TokenType.TIMESTAMP,
193            "DECLARE": TokenType.DECLARE,
194            "ELSEIF": TokenType.COMMAND,
195            "EXCEPTION": TokenType.COMMAND,
196            "EXPORT": TokenType.EXPORT,
197            "FLOAT64": TokenType.DOUBLE,
198            "LOOP": TokenType.COMMAND,
199            "MODEL": TokenType.MODEL,
200            "RECORD": TokenType.STRUCT,
201            "REPEAT": TokenType.COMMAND,
202            "TIMESTAMP": TokenType.TIMESTAMPTZ,
203            "WHILE": TokenType.COMMAND,
204        }
205        KEYWORDS.pop("DIV")
206        KEYWORDS.pop("VALUES")
207        KEYWORDS.pop("/*+")
208
209    Parser = BigQueryParser
210
211    Generator = BigQueryGenerator
class BigQuery(sqlglot.dialects.dialect.Dialect):
 25class BigQuery(Dialect):
 26    WEEK_OFFSET = -1
 27    UNNEST_COLUMN_ONLY = True
 28    SUPPORTS_USER_DEFINED_TYPES = False
 29    LOG_BASE_FIRST = False
 30    HEX_LOWERCASE = True
 31    FORCE_EARLY_ALIAS_REF_EXPANSION = True
 32    EXPAND_ONLY_GROUP_ALIAS_REF = True
 33    PRESERVE_ORIGINAL_NAMES = True
 34    HEX_STRING_IS_INTEGER_TYPE = True
 35    BYTE_STRING_IS_BYTES_TYPE = True
 36    UUID_IS_STRING_TYPE = True
 37    ANNOTATE_ALL_SCOPES = True
 38    PROJECTION_ALIASES_SHADOW_SOURCE_NAMES = True
 39    TABLES_REFERENCEABLE_AS_COLUMNS = True
 40    SUPPORTS_STRUCT_STAR_EXPANSION = True
 41    EXCLUDES_PSEUDOCOLUMNS_FROM_STAR = True
 42    QUERY_RESULTS_ARE_STRUCTS = True
 43    JSON_EXTRACT_SCALAR_SCALAR_ONLY = True
 44    JSON_PATH_SINGLE_DOT_IS_WILDCARD = True
 45    LEAST_GREATEST_IGNORES_NULLS = False
 46    DEFAULT_NULL_TYPE = exp.DType.BIGINT
 47    PRIORITIZE_NON_LITERAL_TYPES = True
 48    ALIAS_POST_VERSION = False
 49
 50    # https://docs.cloud.google.com/bigquery/docs/reference/standard-sql/string_functions#initcap
 51    INITCAP_DEFAULT_DELIMITER_CHARS = ' \t\n\r\f\v\\[\\](){}/|<>!?@"^#$&~_,.:;*%+\\-'
 52
 53    # https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#case_sensitivity
 54    NORMALIZATION_STRATEGY = NormalizationStrategy.CASE_INSENSITIVE
 55    ASCII_ONLY_NORMALIZATION = True
 56
 57    # bigquery udfs are case sensitive
 58    NORMALIZE_FUNCTIONS = False
 59
 60    # https://cloud.google.com/bigquery/docs/reference/standard-sql/format-elements#format_elements_date_time
 61    TIME_MAPPING = {
 62        "%x": "%m/%d/%y",
 63        "%D": "%m/%d/%y",
 64        "%E6S": "%S.%f",
 65        "%e": "%-d",
 66        "%F": "%Y-%m-%d",
 67        "%T": "%H:%M:%S",
 68        "%c": "%a %b %e %H:%M:%S %Y",
 69    }
 70
 71    INVERSE_TIME_MAPPING = {
 72        # Preserve %E6S instead of expanding to %T.%f - since both %E6S & %T.%f are semantically different in BigQuery
 73        # %E6S is semantically different from %T.%f: %E6S works as a single atomic specifier for seconds with microseconds, while %T.%f expands incorrectly and fails to parse.
 74        "%H:%M:%S.%f": "%H:%M:%E6S",
 75    }
 76
 77    FORMAT_MAPPING = {
 78        "dd": "%d",
 79        "DD": "%d",
 80        "mm": "%m",
 81        "MM": "%m",
 82        "mon": "%b",
 83        "MON": "%b",
 84        "month": "%B",
 85        "MONTH": "%B",
 86        "yyyy": "%Y",
 87        "YYYY": "%Y",
 88        "yy": "%y",
 89        "YY": "%y",
 90        "HH": "%I",
 91        "HH12": "%I",
 92        "hh24": "%H",
 93        "HH24": "%H",
 94        "mi": "%M",
 95        "MI": "%M",
 96        "ss": "%S",
 97        "SS": "%S",
 98        "SSSSS": "%f",
 99        "tzh": "%z",
100        "TZH": "%z",
101    }
102
103    # The _PARTITIONTIME and _PARTITIONDATE pseudo-columns are not returned by a SELECT * statement
104    # https://cloud.google.com/bigquery/docs/querying-partitioned-tables#query_an_ingestion-time_partitioned_table
105    # https://cloud.google.com/bigquery/docs/querying-wildcard-tables#scanning_a_range_of_tables_using_table_suffix
106    # https://cloud.google.com/bigquery/docs/query-cloud-storage-data#query_the_file_name_pseudo-column
107    PSEUDOCOLUMNS = {
108        "_PARTITIONTIME",
109        "_PARTITIONDATE",
110        "_TABLE_SUFFIX",
111        "_FILE_NAME",
112        "_DBT_MAX_PARTITION",
113    }
114
115    # All set operations require either a DISTINCT or ALL specifier
116    SET_OP_DISTINCT_BY_DEFAULT = dict.fromkeys((exp.Except, exp.Intersect, exp.Union), None)
117
118    # https://cloud.google.com/bigquery/docs/reference/standard-sql/navigation_functions#percentile_cont
119    COERCES_TO = {
120        **TypeAnnotator.COERCES_TO,
121        exp.DType.BIGDECIMAL: {exp.DType.DOUBLE},
122    }
123    COERCES_TO[exp.DType.DECIMAL] |= {exp.DType.BIGDECIMAL}
124    COERCES_TO[exp.DType.BIGINT] |= {exp.DType.BIGDECIMAL}
125    COERCES_TO[exp.DType.VARCHAR] |= {
126        exp.DType.DATE,
127        exp.DType.DATETIME,
128        exp.DType.TIME,
129        exp.DType.TIMESTAMP,
130        exp.DType.TIMESTAMPTZ,
131    }
132
133    EXPRESSION_METADATA = EXPRESSION_METADATA.copy()
134
135    def normalize_identifier(self, expression: E) -> E:
136        if (
137            isinstance(expression, exp.Identifier)
138            and self.normalization_strategy is NormalizationStrategy.CASE_INSENSITIVE
139        ):
140            parent = expression.parent
141            while isinstance(parent, exp.Dot):
142                parent = parent.parent
143
144            # In BigQuery, CTEs are case-insensitive, but UDF and table names are case-sensitive
145            # by default. The following check uses a heuristic to detect tables based on whether
146            # they are qualified. This should generally be correct, because tables in BigQuery
147            # must be qualified with at least a dataset, unless @@dataset_id is set.
148            case_sensitive = (
149                isinstance(parent, exp.UserDefinedFunction)
150                or (
151                    isinstance(parent, exp.Table)
152                    and parent.db
153                    and (parent.meta_get("quoted_table") or not parent.meta_get("maybe_column"))
154                )
155                or expression.meta_get("is_table")
156            )
157            if not case_sensitive:
158                expression.set("this", expression.this.translate(ASCII_LOWER))
159
160            return t.cast(E, expression)
161
162        return super().normalize_identifier(expression)
163
164    class JSONPathTokenizer(jsonpath.JSONPathTokenizer):
165        VAR_TOKENS = {
166            *jsonpath.JSONPathTokenizer.VAR_TOKENS,
167            TokenType.DASH,
168            TokenType.NUMBER,
169        }
170
171    class Tokenizer(tokens.Tokenizer):
172        QUOTES = ["'", '"', '"""', "'''"]
173        COMMENTS = ["--", "#", ("/*", "*/")]
174        IDENTIFIERS = ["`"]
175        STRING_ESCAPES = ["\\"]
176
177        HEX_STRINGS = [("0x", ""), ("0X", "")]
178
179        BYTE_STRINGS = [(prefix + q, q) for q in t.cast(list[str], QUOTES) for prefix in ("b", "B")]
180
181        RAW_STRINGS = [(prefix + q, q) for q in t.cast(list[str], QUOTES) for prefix in ("r", "R")]
182
183        NESTED_COMMENTS = False
184
185        KEYWORDS = {
186            **tokens.Tokenizer.KEYWORDS,
187            "ANY TYPE": TokenType.VARIANT,
188            "BEGIN": TokenType.COMMAND,
189            "BEGIN TRANSACTION": TokenType.BEGIN,
190            "BYTEINT": TokenType.INT,
191            "BYTES": TokenType.BINARY,
192            "CURRENT_DATETIME": TokenType.CURRENT_DATETIME,
193            "DATETIME": TokenType.TIMESTAMP,
194            "DECLARE": TokenType.DECLARE,
195            "ELSEIF": TokenType.COMMAND,
196            "EXCEPTION": TokenType.COMMAND,
197            "EXPORT": TokenType.EXPORT,
198            "FLOAT64": TokenType.DOUBLE,
199            "LOOP": TokenType.COMMAND,
200            "MODEL": TokenType.MODEL,
201            "RECORD": TokenType.STRUCT,
202            "REPEAT": TokenType.COMMAND,
203            "TIMESTAMP": TokenType.TIMESTAMPTZ,
204            "WHILE": TokenType.COMMAND,
205        }
206        KEYWORDS.pop("DIV")
207        KEYWORDS.pop("VALUES")
208        KEYWORDS.pop("/*+")
209
210    Parser = BigQueryParser
211
212    Generator = BigQueryGenerator
WEEK_OFFSET = -1

First day of the week in DATE_TRUNC(week). Defaults to 0 (Monday). -1 would be Sunday.

UNNEST_COLUMN_ONLY = True

Whether UNNEST table aliases are treated as column aliases.

SUPPORTS_USER_DEFINED_TYPES = False

Whether user-defined data types are supported.

LOG_BASE_FIRST: bool | None = False

Whether the base comes first in the LOG function. Possible values: True, False, None (two arguments are not supported by LOG)

HEX_LOWERCASE = True

Whether the HEX function returns a lowercase hexadecimal string.

FORCE_EARLY_ALIAS_REF_EXPANSION = True

Whether alias reference expansion (_expand_alias_refs()) should run before column qualification (_qualify_columns()).

For example:

WITH data AS ( SELECT 1 AS id, 2 AS my_id ) SELECT id AS my_id FROM data WHERE my_id = 1 GROUP BY my_id, HAVING my_id = 1

In most dialects, "my_id" would refer to "data.my_id" across the query, except: - BigQuery, which will forward the alias to GROUP BY + HAVING clauses i.e it resolves to "WHERE my_id = 1 GROUP BY id HAVING id = 1" - Clickhouse, which will forward the alias across the query i.e it resolves to "WHERE id = 1 GROUP BY id HAVING id = 1"

EXPAND_ONLY_GROUP_ALIAS_REF = True

Whether alias reference expansion before qualification should only happen for the GROUP BY clause.

PRESERVE_ORIGINAL_NAMES: bool = True

Whether the name of the function should be preserved inside the node's metadata, can be useful for roundtripping deprecated vs new functions that share an AST node e.g JSON_VALUE vs JSON_EXTRACT_SCALAR in BigQuery

HEX_STRING_IS_INTEGER_TYPE: bool = True

Whether hex strings such as x'CC' evaluate to integer or binary/blob type

BYTE_STRING_IS_BYTES_TYPE: bool = True

Whether byte string literals (ex: BigQuery's b'...') are typed as BYTES/BINARY

UUID_IS_STRING_TYPE: bool = True

Whether a UUID is considered a string or a UUID type.

ANNOTATE_ALL_SCOPES = True

Whether to annotate all scopes during optimization. Used by BigQuery for UNNEST support.

PROJECTION_ALIASES_SHADOW_SOURCE_NAMES = True

Whether projection alias names can shadow table/source names in GROUP BY and HAVING clauses.

In BigQuery, when a projection alias has the same name as a source table, the alias takes precedence in GROUP BY and HAVING clauses, and the table becomes inaccessible by that name.

For example, in BigQuery: SELECT id, ARRAY_AGG(col) AS custom_fields FROM custom_fields GROUP BY id HAVING id >= 1

The "custom_fields" source is shadowed by the projection alias, so we cannot qualify "id" with "custom_fields" in GROUP BY/HAVING.

TABLES_REFERENCEABLE_AS_COLUMNS = True

Whether table names can be referenced as columns (treated as structs).

BigQuery allows tables to be referenced as columns in queries, automatically treating them as struct values containing all the table's columns.

For example, in BigQuery: SELECT t FROM my_table AS t -- Returns entire row as a struct

SUPPORTS_STRUCT_STAR_EXPANSION = True

Whether the dialect supports expanding struct fields using star notation (e.g., struct_col.*).

BigQuery allows struct fields to be expanded with the star operator:

SELECT t.struct_col.* FROM table t

RisingWave also allows struct field expansion with the star operator using parentheses:

SELECT (t.struct_col).* FROM table t

This expands to all fields within the struct.

EXCLUDES_PSEUDOCOLUMNS_FROM_STAR = True

Whether pseudocolumns should be excluded from star expansion (SELECT *).

Pseudocolumns are special dialect-specific columns (e.g., Oracle's ROWNUM, ROWID, LEVEL, or BigQuery's _PARTITIONTIME, _PARTITIONDATE) that are implicitly available but not part of the table schema. When this is True, SELECT * will not include these pseudocolumns; they must be explicitly selected.

QUERY_RESULTS_ARE_STRUCTS = True

Whether query results are typed as structs in metadata for type inference.

In BigQuery, subqueries store their column types as a STRUCT in metadata, enabling special type inference for ARRAY(SELECT ...) expressions: ARRAY(SELECT x, y FROM t) → ARRAY

For single column subqueries, BigQuery unwraps the struct: ARRAY(SELECT x FROM t) → ARRAY

This is metadata-only for type inference.

JSON_EXTRACT_SCALAR_SCALAR_ONLY = True

Whether JSON_EXTRACT_SCALAR returns null if a non-scalar value is selected.

JSON_PATH_SINGLE_DOT_IS_WILDCARD = True

Whether a single DOT in a JSON path (e.g. $.) is treated as a valid wildcard key.

LEAST_GREATEST_IGNORES_NULLS = False

Whether LEAST/GREATEST functions ignore NULL values, e.g:

  • BigQuery, Snowflake, MySQL, Presto/Trino: LEAST(1, NULL, 2) -> NULL
  • Spark, Postgres, DuckDB, TSQL: LEAST(1, NULL, 2) -> 1
DEFAULT_NULL_TYPE = <DType.BIGINT: 'BIGINT'>

The default type of NULL for producing the correct projection type.

For example, in BigQuery the default type of the NULL value is INT64.

PRIORITIZE_NON_LITERAL_TYPES = True

Whether to prioritize non-literal types over literals during type annotation.

ALIAS_POST_VERSION = False

Whether the table alias comes after version (timestamp or iceberg snapshot).

INITCAP_DEFAULT_DELIMITER_CHARS = ' \t\n\r\x0c\x0b\\[\\](){}/|<>!?@"^#$&~_,.:;*%+\\-'
NORMALIZATION_STRATEGY = <NormalizationStrategy.CASE_INSENSITIVE: 'CASE_INSENSITIVE'>

Specifies the strategy according to which identifiers should be normalized.

ASCII_ONLY_NORMALIZATION = True

Whether identifiers are only normalized with respect to ASCII characters, e.g. Ä and ä are different identifiers in DuckDB, but the same identifier in Spark.

NORMALIZE_FUNCTIONS: bool | str = False

Determines how function names are going to be normalized.

Possible values:

"upper" or True: Convert names to uppercase. "lower": Convert names to lowercase. False: Disables function name normalization.

TIME_MAPPING: dict[str, str] = {'%x': '%m/%d/%y', '%D': '%m/%d/%y', '%E6S': '%S.%f', '%e': '%-d', '%F': '%Y-%m-%d', '%T': '%H:%M:%S', '%c': '%a %b %e %H:%M:%S %Y'}

Associates this dialect's time formats with their equivalent Python strftime formats.

INVERSE_TIME_MAPPING: dict[str, str] = {'%m/%d/%y': '%D', '%S.%f': '%E6S', '%-d': '%e', '%Y-%m-%d': '%F', '%H:%M:%S': '%T', '%a %b %e %H:%M:%S %Y': '%c', '%H:%M:%S.%f': '%H:%M:%E6S', '%mstrict': '%m', '%dstrict': '%d', '%Hstrict': '%H', '%Istrict': '%I', '%Mstrict': '%M', '%Sstrict': '%S'}
FORMAT_MAPPING: dict[str, str] = {'dd': '%d', 'DD': '%d', 'mm': '%m', 'MM': '%m', 'mon': '%b', 'MON': '%b', 'month': '%B', 'MONTH': '%B', 'yyyy': '%Y', 'YYYY': '%Y', 'yy': '%y', 'YY': '%y', 'HH': '%I', 'HH12': '%I', 'hh24': '%H', 'HH24': '%H', 'mi': '%M', 'MI': '%M', 'ss': '%S', 'SS': '%S', 'SSSSS': '%f', 'tzh': '%z', 'TZH': '%z'}

Helper which is used for parsing the special syntax CAST(x AS DATE FORMAT 'yyyy'). If empty, the corresponding trie will be constructed off of TIME_MAPPING.

PSEUDOCOLUMNS: set[str] = {'_PARTITIONDATE', '_TABLE_SUFFIX', '_DBT_MAX_PARTITION', '_FILE_NAME', '_PARTITIONTIME'}

Columns that are auto-generated by the engine corresponding to this dialect. For example, such columns may be excluded from SELECT * queries.

SET_OP_DISTINCT_BY_DEFAULT: dict[type[sqlglot.expressions.core.Expr], bool | None] = {<class 'sqlglot.expressions.query.Except'>: None, <class 'sqlglot.expressions.query.Intersect'>: None, <class 'sqlglot.expressions.query.Union'>: None}

Whether a set operation uses DISTINCT by default. This is None when either DISTINCT or ALL must be explicitly specified.

COERCES_TO: dict[sqlglot.expressions.datatypes.DType, set[sqlglot.expressions.datatypes.DType]] = {<DType.TEXT: 'TEXT'>: set(), <DType.NVARCHAR: 'NVARCHAR'>: {<DType.TEXT: 'TEXT'>}, <DType.VARCHAR: 'VARCHAR'>: {<DType.DATE: 'DATE'>, <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <DType.TEXT: 'TEXT'>, <DType.NVARCHAR: 'NVARCHAR'>, <DType.TIMESTAMP: 'TIMESTAMP'>, <DType.TIME: 'TIME'>, <DType.DATETIME: 'DATETIME'>}, <DType.NCHAR: 'NCHAR'>: {<DType.VARCHAR: 'VARCHAR'>, <DType.TEXT: 'TEXT'>, <DType.NVARCHAR: 'NVARCHAR'>}, <DType.CHAR: 'CHAR'>: {<DType.NCHAR: 'NCHAR'>, <DType.VARCHAR: 'VARCHAR'>, <DType.TEXT: 'TEXT'>, <DType.NVARCHAR: 'NVARCHAR'>}, <DType.DECFLOAT: 'DECFLOAT'>: set(), <DType.DOUBLE: 'DOUBLE'>: {<DType.DECFLOAT: 'DECFLOAT'>}, <DType.FLOAT: 'FLOAT'>: {<DType.DOUBLE: 'DOUBLE'>, <DType.DECFLOAT: 'DECFLOAT'>}, <DType.BIGDECIMAL: 'BIGDECIMAL'>: {<DType.DOUBLE: 'DOUBLE'>}, <DType.DECIMAL: 'DECIMAL'>: {<DType.DOUBLE: 'DOUBLE'>, <DType.BIGDECIMAL: 'BIGDECIMAL'>, <DType.DECFLOAT: 'DECFLOAT'>, <DType.FLOAT: 'FLOAT'>}, <DType.BIGINT: 'BIGINT'>: {<DType.DECIMAL: 'DECIMAL'>, <DType.DOUBLE: 'DOUBLE'>, <DType.BIGDECIMAL: 'BIGDECIMAL'>, <DType.DECFLOAT: 'DECFLOAT'>, <DType.FLOAT: 'FLOAT'>}, <DType.INT: 'INT'>: {<DType.BIGINT: 'BIGINT'>, <DType.DECIMAL: 'DECIMAL'>, <DType.DOUBLE: 'DOUBLE'>, <DType.BIGDECIMAL: 'BIGDECIMAL'>, <DType.DECFLOAT: 'DECFLOAT'>, <DType.FLOAT: 'FLOAT'>}, <DType.SMALLINT: 'SMALLINT'>: {<DType.BIGINT: 'BIGINT'>, <DType.INT: 'INT'>, <DType.DECIMAL: 'DECIMAL'>, <DType.DOUBLE: 'DOUBLE'>, <DType.BIGDECIMAL: 'BIGDECIMAL'>, <DType.DECFLOAT: 'DECFLOAT'>, <DType.FLOAT: 'FLOAT'>}, <DType.TINYINT: 'TINYINT'>: {<DType.FLOAT: 'FLOAT'>, <DType.SMALLINT: 'SMALLINT'>, <DType.INT: 'INT'>, <DType.BIGINT: 'BIGINT'>, <DType.DOUBLE: 'DOUBLE'>, <DType.BIGDECIMAL: 'BIGDECIMAL'>, <DType.DECIMAL: 'DECIMAL'>, <DType.DECFLOAT: 'DECFLOAT'>}, <DType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>: set(), <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>: {<DType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>}, <DType.TIMESTAMP: 'TIMESTAMP'>: {<DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <DType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>}, <DType.DATETIME: 'DATETIME'>: {<DType.TIMESTAMP: 'TIMESTAMP'>, <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <DType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>}, <DType.DATE: 'DATE'>: {<DType.DATETIME: 'DATETIME'>, <DType.TIMESTAMP: 'TIMESTAMP'>, <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <DType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>}}
EXPRESSION_METADATA = {<class 'sqlglot.expressions.core.Add'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.Adjacent'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.And'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.array.ArrayContainedBy'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.array.ArrayContains'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.array.ArrayContainsAll'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.array.ArrayOverlaps'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.array.ArrayPosition'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.Binary'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.BitwiseAnd'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.BitwiseLeftShift'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.BitwiseOr'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.BitwiseRightShift'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.BitwiseXor'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.functions.Collate'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.Connector'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.Corr'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.core.DPipe'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.core.Distance'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.DistanceNd'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.Div'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.core.Dot'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.core.EQ'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.Escape'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.ExtendsLeft'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.ExtendsRight'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.GT'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.GTE'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.Glob'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.ILike'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.IntDiv'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.Is'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.json.JSONArrayContains'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.json.JSONBContains'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.json.JSONBContainsAllTopKeys'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.json.JSONBContainsAnyTopKeys'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.json.JSONBContainsTopKey'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.json.JSONBDeleteAtPath'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.json.JSONBExtract'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.json.JSONBExtractScalar'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.json.JSONBPathExists'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.json.JSONExtract'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.json.JSONExtractScalar'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.core.Kwarg'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.LT'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.LTE'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.Like'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.Match'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.Mod'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.Mul'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.NEQ'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.NestedJSONSelect'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.NullSafeEQ'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.NullSafeNEQ'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.Operator'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.Or'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.Overlaps'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.Pow'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.core.PropertyEQ'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.string.RegexpFullMatch'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.RegexpILike'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.RegexpLike'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.SimilarTo'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.Sub'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.Xor'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.Alias'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.BitwiseNot'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.IgnoreNulls'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.Neg'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.Not'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.Paren'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.PivotAlias'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.RespectNulls'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.Unary'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.DenseRank'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.aggregate.RowNumber'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.temporal.UnixSeconds'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.array.ArraySize'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.temporal.UnixMillis'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.functions.Int64'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.temporal.UnixMicros'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.core.ApproxDistinct'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.aggregate.CountIf'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.aggregate.Rank'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.aggregate.Ntile'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.string.FromBase64'>: {'returns': <DType.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.string.FromBase32'>: {'returns': <DType.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.math.IsNan'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.math.IsInf'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.core.Any'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.string.EndsWith'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.string.StartsWith'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.core.Between'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.core.All'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.core.Boolean'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.aggregate.LogicalOr'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.string.Contains'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.aggregate.LogicalAnd'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.functions.Exists'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.core.In'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.temporal.CurrentDate'>: {'returns': <DType.DATE: 'DATE'>}, <class 'sqlglot.expressions.temporal.TimeStrToDate'>: {'returns': <DType.DATE: 'DATE'>}, <class 'sqlglot.expressions.temporal.DiToDate'>: {'returns': <DType.DATE: 'DATE'>}, <class 'sqlglot.expressions.temporal.TsOrDsToDate'>: {'returns': <DType.DATE: 'DATE'>}, <class 'sqlglot.expressions.temporal.LastDay'>: {'returns': <DType.DATE: 'DATE'>}, <class 'sqlglot.expressions.temporal.StrToDate'>: {'returns': <DType.DATE: 'DATE'>}, <class 'sqlglot.expressions.temporal.DateFromParts'>: {'returns': <DType.DATE: 'DATE'>}, <class 'sqlglot.expressions.temporal.DateStrToDate'>: {'returns': <DType.DATE: 'DATE'>}, <class 'sqlglot.expressions.temporal.Date'>: {'returns': <DType.DATE: 'DATE'>}, <class 'sqlglot.expressions.temporal.Datetime'>: {'returns': <DType.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.temporal.DatetimeAdd'>: {'returns': <DType.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.temporal.DatetimeSub'>: {'returns': <DType.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.temporal.CurrentDatetime'>: {'returns': <DType.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.math.Asinh'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Radians'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Sqrt'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.ToDouble'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Cosh'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Round'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.Kurtosis'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Asin'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Pi'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.StddevPop'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.Quantile'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Ln'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.math.Acos'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.Skewness'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.CumeDist'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.VariancePop'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.CovarPop'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Tan'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Atan'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Sin'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.Avg'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.functions.Rand'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.SafeDivide'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.math.Degrees'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.Variance'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Cot'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.StddevSamp'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Exp'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.math.Cos'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.ApproxQuantile'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Log'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.math.Acosh'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Cbrt'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.Stddev'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.PercentRank'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.CovarSamp'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.PercentileCont'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.math.Tanh'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Atanh'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Sinh'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.temporal.DayOfWeek'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.math.Floor'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.Levenshtein'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.math.Ceil'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.temporal.DateToDi'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.string.Unicode'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.Quarter'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.string.BitLength'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.Hour'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.string.StrPosition'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.DayOfMonth'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.DatetimeDiff'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.math.Getbit'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.math.Sign'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.temporal.UnixDate'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.string.Ascii'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.DayOfYear'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.string.Length'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.temporal.TsOrDiToDi'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.TimeDiff'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.TimestampDiff'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.datatypes.Interval'>: {'returns': <DType.INTERVAL: 'INTERVAL'>}, <class 'sqlglot.expressions.temporal.MakeInterval'>: {'returns': <DType.INTERVAL: 'INTERVAL'>}, <class 'sqlglot.expressions.temporal.JustifyInterval'>: {'returns': <DType.INTERVAL: 'INTERVAL'>}, <class 'sqlglot.expressions.temporal.JustifyHours'>: {'returns': <DType.INTERVAL: 'INTERVAL'>}, <class 'sqlglot.expressions.temporal.JustifyDays'>: {'returns': <DType.INTERVAL: 'INTERVAL'>}, <class 'sqlglot.expressions.json.ParseJSON'>: {'returns': <DType.JSON: 'JSON'>}, <class 'sqlglot.expressions.temporal.TimeAdd'>: {'returns': <DType.TIME: 'TIME'>}, <class 'sqlglot.expressions.temporal.Time'>: {'returns': <DType.TIME: 'TIME'>}, <class 'sqlglot.expressions.temporal.TimeSub'>: {'returns': <DType.TIME: 'TIME'>}, <class 'sqlglot.expressions.temporal.Localtime'>: {'returns': <DType.TIME: 'TIME'>}, <class 'sqlglot.expressions.temporal.CurrentTime'>: {'returns': <DType.TIME: 'TIME'>}, <class 'sqlglot.expressions.temporal.TimestampLtzFromParts'>: {'returns': <DType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>}, <class 'sqlglot.expressions.temporal.CurrentTimestampLTZ'>: {'returns': <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.temporal.TimestampTzFromParts'>: {'returns': <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.temporal.TimeStrToTime'>: {'returns': <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.temporal.UnixToTime'>: {'returns': <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.temporal.StrToTime'>: {'returns': <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.temporal.TimestampSub'>: {'returns': <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.temporal.CurrentTimestamp'>: {'returns': <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.temporal.TimestampAdd'>: {'returns': <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.temporal.Month'>: {'returns': <DType.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.temporal.YearOfWeek'>: {'returns': <DType.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.temporal.Year'>: {'returns': <DType.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.temporal.DayOfWeekIso'>: {'returns': <DType.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.temporal.WeekOfYear'>: {'returns': <DType.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.temporal.Week'>: {'returns': <DType.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.temporal.Day'>: {'returns': <DType.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.temporal.YearOfWeekIso'>: {'returns': <DType.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.array.ArrayToString'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.functions.CurrentCatalog'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.functions.CurrentUser'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.temporal.UnixToTimeStr'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Repeat'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.temporal.Dayname'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.aggregate.GroupConcat'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.functions.CurrentSchema'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Space'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.functions.CurrentRole'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Initcap'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.query.RawString'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.ToBase32'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.core.Typeof'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Chr'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.ConcatWs'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.temporal.TimeToStr'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Translate'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.SHA2'>: {'returns': <DType.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.string.Substring'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.SHA'>: {'returns': <DType.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.temporal.UnixToStr'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.String'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.MD5'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Lower'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.Trim'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.temporal.TsOrDsToDateStr'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.ToBase64'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Upper'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.Concat'>: {'annotator': <function _annotate_concat>}, <class 'sqlglot.expressions.temporal.DateToDateStr'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.functions.SessionUser'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.temporal.TimeToTimeStr'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.temporal.Monthname'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.functions.CurrentVersion'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.aggregate.LastValue'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.math.Abs'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.Filter'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.ArrayConcatAgg'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.query.Limit'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.query.Window'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.array.ArraySlice'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.HavingMax'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.NthValue'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.array.SortArray'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.array.ArrayReverse'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.AnyValue'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.query.Order'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.FirstValue'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.Min'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.functions.Coalesce'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.Max'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.array.ArrayConcat'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.functions.Least'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.functions.Greatest'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.array.ArrayFirst'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.array.ArrayLast'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.Anonymous'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.temporal.DateTrunc'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.temporal.DateAdd'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.temporal.DateSub'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.functions.Cast'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.functions.TryCast'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.array.Map'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.array.VarMap'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.array.Array'>: {'annotator': <function _annotate_array>}, <class 'sqlglot.expressions.aggregate.ArrayAgg'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.core.Bracket'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.functions.Case'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.aggregate.Count'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.temporal.DateDiff'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.datatypes.DataType'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.core.Distinct'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.array.Explode'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.temporal.Extract'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.query.HexString'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.array.GenerateSeries'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.temporal.GenerateDateArray'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.temporal.GenerateTimestampArray'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.functions.If'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.aggregate.Lag'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.aggregate.Lead'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.core.Literal'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.core.Null'>: {'returns': <DType.NULL: 'NULL'>}, <class 'sqlglot.expressions.functions.Nullif'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.array.Struct'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.aggregate.Sum'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.temporal.Timestamp'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.array.ToMap'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.array.Unnest'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.core.WithinGroup'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.query.Subquery'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.string.RegexpReplace'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.RegexpExtract'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.functions.NetFunc'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.Left'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.PercentileDisc'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.Right'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.Replace'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.ArgMax'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.math.SafeNegate'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.Pad'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.Reverse'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.ArgMin'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.SafeFunc'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.temporal.DatetimeTrunc'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.temporal.TimestampTrunc'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.functions.RangeBucket'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.string.RegexpInstr'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.math.BitwiseXorAgg'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.math.BitwiseOrAgg'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.math.BitwiseCount'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.math.BitwiseAndAgg'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.string.FarmFingerprint'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.string.ByteLength'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.aggregate.Grouping'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.functions.LaxInt64'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.string.SHA1Digest'>: {'returns': <DType.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.string.CodePointsToBytes'>: {'returns': <DType.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.query.ByteString'>: {'returns': <DType.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.string.MD5Digest'>: {'returns': <DType.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.string.Unhex'>: {'returns': <DType.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.string.SHA2Digest'>: {'returns': <DType.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.json.JSONBool'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.functions.LaxBool'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.temporal.ParseDatetime'>: {'returns': <DType.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.temporal.TimestampFromParts'>: {'returns': <DType.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.math.Sech'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.functions.LaxFloat64'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.EuclideanDistance'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Sec'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.CosineDistance'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Atan2'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Csch'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.functions.Float64'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Csc'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Coth'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.json.JSONObject'>: {'returns': <DType.JSON: 'JSON'>}, <class 'sqlglot.expressions.json.JSONArrayAppend'>: {'returns': <DType.JSON: 'JSON'>}, <class 'sqlglot.expressions.json.JSONArray'>: {'returns': <DType.JSON: 'JSON'>}, <class 'sqlglot.expressions.json.JSONStripNulls'>: {'returns': <DType.JSON: 'JSON'>}, <class 'sqlglot.expressions.json.JSONArrayInsert'>: {'returns': <DType.JSON: 'JSON'>}, <class 'sqlglot.expressions.json.JSONSet'>: {'returns': <DType.JSON: 'JSON'>}, <class 'sqlglot.expressions.json.JSONRemove'>: {'returns': <DType.JSON: 'JSON'>}, <class 'sqlglot.expressions.temporal.TimeTrunc'>: {'returns': <DType.TIME: 'TIME'>}, <class 'sqlglot.expressions.temporal.TsOrDsToTime'>: {'returns': <DType.TIME: 'TIME'>}, <class 'sqlglot.expressions.temporal.TimeFromParts'>: {'returns': <DType.TIME: 'TIME'>}, <class 'sqlglot.expressions.temporal.ParseTime'>: {'returns': <DType.TIME: 'TIME'>}, <class 'sqlglot.expressions.functions.Uuid'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.functions.RegDomain'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.functions.LaxString'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Format'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Normalize'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.SafeConvertBytesToString'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.json.JSONType'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.LowerHex'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Soundex'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.functions.Host'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.CodePointsToString'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.math.SafeMultiply'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.math.SafeAdd'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.math.SafeSubtract'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.RegexpExtractAll'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.json.JSONExtractArray'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.Split'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.ApproxQuantiles'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.ApproxTopK'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.aggregate.ApproxTopSum'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.temporal.DateFromUnixDate'>: {'returns': <DType.DATE: 'DATE'>}, <class 'sqlglot.expressions.json.JSONFormat'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.json.JSONKeysAtDepth'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.query.JSONValueArray'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.string.ParseBignumeric'>: {'returns': <DType.BIGDECIMAL: 'BIGDECIMAL'>}, <class 'sqlglot.expressions.string.ParseNumeric'>: {'returns': <DType.DECIMAL: 'DECIMAL'>}, <class 'sqlglot.expressions.string.ToCodePoints'>: {'annotator': <function <lambda>>}}
def normalize_identifier(self, expression: ~E) -> ~E:
135    def normalize_identifier(self, expression: E) -> E:
136        if (
137            isinstance(expression, exp.Identifier)
138            and self.normalization_strategy is NormalizationStrategy.CASE_INSENSITIVE
139        ):
140            parent = expression.parent
141            while isinstance(parent, exp.Dot):
142                parent = parent.parent
143
144            # In BigQuery, CTEs are case-insensitive, but UDF and table names are case-sensitive
145            # by default. The following check uses a heuristic to detect tables based on whether
146            # they are qualified. This should generally be correct, because tables in BigQuery
147            # must be qualified with at least a dataset, unless @@dataset_id is set.
148            case_sensitive = (
149                isinstance(parent, exp.UserDefinedFunction)
150                or (
151                    isinstance(parent, exp.Table)
152                    and parent.db
153                    and (parent.meta_get("quoted_table") or not parent.meta_get("maybe_column"))
154                )
155                or expression.meta_get("is_table")
156            )
157            if not case_sensitive:
158                expression.set("this", expression.this.translate(ASCII_LOWER))
159
160            return t.cast(E, expression)
161
162        return super().normalize_identifier(expression)

Transforms an identifier in a way that resembles how it'd be resolved by this dialect.

For example, an identifier like FoO would be resolved as foo in Postgres, because it lowercases all unquoted identifiers. On the other hand, Snowflake uppercases them, so it would resolve it as FOO. If it was quoted, it'd need to be treated as case-sensitive, and so any normalization would be prohibited in order to avoid "breaking" the identifier.

There are also dialects like Spark, which are case-insensitive even when quotes are present, and dialects like MySQL, whose resolution rules match those employed by the underlying operating system, for example they may always be case-sensitive in Linux.

Finally, the normalization behavior of some engines can even be controlled through flags, like in Redshift's case, where users can explicitly set enable_case_sensitive_identifier.

SQLGlot aims to understand and handle all of these different behaviors gracefully, so that it can analyze queries in the optimizer and successfully capture their semantics.

SUPPORTS_COLUMN_JOIN_MARKS = False

Whether the old-style outer join (+) syntax is supported.

UNESCAPED_SEQUENCES: dict[str, str] = {'\\a': '\x07', '\\b': '\x08', '\\f': '\x0c', '\\n': '\n', '\\r': '\r', '\\t': '\t', '\\v': '\x0b', '\\\\': '\\'}

Mapping of an escaped sequence (\n) to its unescaped version ( ).

STRINGS_SUPPORT_ESCAPED_SEQUENCES: bool = True

Whether string literals support escape sequences (e.g. \n). Set by the metaclass based on the tokenizer's STRING_ESCAPES.

BYTE_STRINGS_SUPPORT_ESCAPED_SEQUENCES: bool = True

Whether byte string literals support escape sequences. Set by the metaclass based on the tokenizer's BYTE_STRING_ESCAPES.

tokenizer_class = <class 'BigQuery.Tokenizer'>
jsonpath_tokenizer_class = <class 'BigQuery.JSONPathTokenizer'>
parser_class = <class 'sqlglot.parsers.bigquery.BigQueryParser'>
generator_class = <class 'sqlglot.generators.bigquery.BigQueryGenerator'>
TIME_TRIE: dict = {'%': {'x': {0: True}, 'D': {0: True}, 'E': {'6': {'S': {0: True}}}, 'e': {0: True}, 'F': {0: True}, 'T': {0: True}, 'c': {0: True}}}
FORMAT_TRIE: dict = {'d': {'d': {0: True}}, 'D': {'D': {0: True}}, 'm': {'m': {0: True}, 'o': {'n': {0: True, 't': {'h': {0: True}}}}, 'i': {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}}, 'Y': {'Y': {'Y': {'Y': {0: True}}, 0: True}}, 'H': {'H': {0: True, '1': {'2': {0: True}}, '2': {'4': {0: True}}}}, 'h': {'h': {'2': {'4': {0: True}}}}, 's': {'s': {0: True}}, 'S': {'S': {0: True, 'S': {'S': {'S': {0: True}}}}}, 't': {'z': {'h': {0: True}}}, 'T': {'Z': {'H': {0: True}}}}
INVERSE_TIME_TRIE: dict = {'%': {'m': {'/': {'%': {'d': {'/': {'%': {'y': {0: True}}}}}}, 's': {'t': {'r': {'i': {'c': {'t': {0: True}}}}}}}, 'S': {'.': {'%': {'f': {0: True}}}, 's': {'t': {'r': {'i': {'c': {'t': {0: True}}}}}}}, '-': {'d': {0: True}}, 'Y': {'-': {'%': {'m': {'-': {'%': {'d': {0: True}}}}}}}, 'H': {':': {'%': {'M': {':': {'%': {'S': {0: True, '.': {'%': {'f': {0: True}}}}}}}}}, 's': {'t': {'r': {'i': {'c': {'t': {0: True}}}}}}}, 'a': {' ': {'%': {'b': {' ': {'%': {'e': {' ': {'%': {'H': {':': {'%': {'M': {':': {'%': {'S': {' ': {'%': {'Y': {0: True}}}}}}}}}}}}}}}}}}}, 'd': {'s': {'t': {'r': {'i': {'c': {'t': {0: True}}}}}}}, 'I': {'s': {'t': {'r': {'i': {'c': {'t': {0: True}}}}}}}, 'M': {'s': {'t': {'r': {'i': {'c': {'t': {0: True}}}}}}}}}
INVERSE_FORMAT_MAPPING: dict[str, str] = {'%d': 'DD', '%m': 'MM', '%b': 'MON', '%B': 'MONTH', '%Y': 'YYYY', '%y': 'YY', '%I': 'HH12', '%H': 'HH24', '%M': 'MI', '%S': 'SS', '%f': 'SSSSS', '%z': 'TZH', '%mstrict': 'MM', '%dstrict': 'DD', '%Hstrict': 'HH24', '%Istrict': 'HH12', '%Mstrict': 'MI', '%Sstrict': 'SS'}
INVERSE_FORMAT_TRIE: dict = {'%': {'d': {0: True, 's': {'t': {'r': {'i': {'c': {'t': {0: True}}}}}}}, 'm': {0: True, 's': {'t': {'r': {'i': {'c': {'t': {0: True}}}}}}}, 'b': {0: True}, 'B': {0: True}, 'Y': {0: True}, 'y': {0: True}, 'I': {0: True, 's': {'t': {'r': {'i': {'c': {'t': {0: True}}}}}}}, 'H': {0: True, 's': {'t': {'r': {'i': {'c': {'t': {0: True}}}}}}}, 'M': {0: True, 's': {'t': {'r': {'i': {'c': {'t': {0: True}}}}}}}, 'S': {0: True, 's': {'t': {'r': {'i': {'c': {'t': {0: True}}}}}}}, 'f': {0: True}, 'z': {0: True}}}
INVERSE_CREATABLE_KIND_MAPPING: dict[str, str] = {}
ESCAPED_SEQUENCES: dict[str, str] = {'\x07': '\\a', '\x08': '\\b', '\x0c': '\\f', '\n': '\\n', '\r': '\\r', '\t': '\\t', '\x0b': '\\v', '\\': '\\\\'}
QUOTE_START = "'"
QUOTE_END = "'"
IDENTIFIER_START = '`'
IDENTIFIER_END = '`'
VALID_INTERVAL_UNITS: set[str] = {'MICROSECS', 'MINUTES', 'YEAR', 'WY', 'DAYOFMONTH', 'DOW', 'MONTH', 'MICROSECOND', 'TIMEZONE_MINUTE', 'EPOCH_MICROSECONDS', 'MINUTE', 'DAYOFWEEK_ISO', 'TZH', 'Y', 'DW', 'WEEK', 'MM', 'DAYOFWEEK', 'QUARTER', 'MSEC', 'NSEC', 'M', 'USECS', 'NANOSECS', 'WEEKDAY', 'DW_ISO', 'MONTHS', 'D', 'MINS', 'DY', 'DAYOFYEAR', 'WK', 'HH', 'MS', 'TIMEZONE_HOUR', 'MIL', 'S', 'YYYY', 'DECADES', 'MON', 'NANOSECOND', 'WEEKOFYEAR', 'HOUR', 'TZM', 'MILLENNIUM', 'SECONDS', 'DOW_ISO', 'DAY OF WEEK', 'USECOND', 'H', 'MILLISECON', 'QTRS', 'MILLISECS', 'DOY', 'SECOND', 'EPOCH_MILLISECOND', 'HRS', 'DEC', 'EPOCH_SECONDS', 'YYY', 'YY', 'YRS', 'MSECONDS', 'SEC', 'USEC', 'MILLISECOND', 'HOURS', 'DAY OF YEAR', 'MILLISEC', 'C', 'MSECOND', 'WEEKDAY_ISO', 'EPOCH_NANOSECOND', 'NANOSEC', 'SECS', 'CENTURY', 'MILS', 'US', 'WEEKOFYEAR_ISO', 'WEEKOFYEARISO', 'QUARTERS', 'YR', 'EPOCH', 'EPOCH_MILLISECONDS', 'MONS', 'MILLISECONDS', 'MICROSECONDS', 'MI', 'WEEK_ISO', 'MIN', 'MILLENIA', 'WOY', 'CENTS', 'EPOCH_MICROSECOND', 'DAYS', 'MSECS', 'CENT', 'W', 'MICROSEC', 'HR', 'NS', 'DD', 'EPOCH_NANOSECONDS', 'DECADE', 'NSECONDS', 'DAY', 'DECS', 'DAYOFWEEKISO', 'USECONDS', 'YEARS', 'NSECOND', 'CENTURIES', 'WEEKISO', 'QTR', 'Q', 'EPOCH_SECOND'}
BIT_START: str | None = None
BIT_END: str | None = None
HEX_START: str | None = '0x'
HEX_END: str | None = ''
BYTE_START: str | None = "b'"
BYTE_END: str | None = "'"
UNICODE_START: str | None = None
UNICODE_END: str | None = None
class BigQuery.JSONPathTokenizer(sqlglot.jsonpath.JSONPathTokenizer):
164    class JSONPathTokenizer(jsonpath.JSONPathTokenizer):
165        VAR_TOKENS = {
166            *jsonpath.JSONPathTokenizer.VAR_TOKENS,
167            TokenType.DASH,
168            TokenType.NUMBER,
169        }
VAR_TOKENS = {<TokenType.VAR: 89>, <TokenType.DASH: 9>, <TokenType.NUMBER: 78>}
BYTE_STRING_ESCAPES: ClassVar[list[str]] = ['\\']
class BigQuery.Tokenizer(sqlglot.tokens.Tokenizer):
171    class Tokenizer(tokens.Tokenizer):
172        QUOTES = ["'", '"', '"""', "'''"]
173        COMMENTS = ["--", "#", ("/*", "*/")]
174        IDENTIFIERS = ["`"]
175        STRING_ESCAPES = ["\\"]
176
177        HEX_STRINGS = [("0x", ""), ("0X", "")]
178
179        BYTE_STRINGS = [(prefix + q, q) for q in t.cast(list[str], QUOTES) for prefix in ("b", "B")]
180
181        RAW_STRINGS = [(prefix + q, q) for q in t.cast(list[str], QUOTES) for prefix in ("r", "R")]
182
183        NESTED_COMMENTS = False
184
185        KEYWORDS = {
186            **tokens.Tokenizer.KEYWORDS,
187            "ANY TYPE": TokenType.VARIANT,
188            "BEGIN": TokenType.COMMAND,
189            "BEGIN TRANSACTION": TokenType.BEGIN,
190            "BYTEINT": TokenType.INT,
191            "BYTES": TokenType.BINARY,
192            "CURRENT_DATETIME": TokenType.CURRENT_DATETIME,
193            "DATETIME": TokenType.TIMESTAMP,
194            "DECLARE": TokenType.DECLARE,
195            "ELSEIF": TokenType.COMMAND,
196            "EXCEPTION": TokenType.COMMAND,
197            "EXPORT": TokenType.EXPORT,
198            "FLOAT64": TokenType.DOUBLE,
199            "LOOP": TokenType.COMMAND,
200            "MODEL": TokenType.MODEL,
201            "RECORD": TokenType.STRUCT,
202            "REPEAT": TokenType.COMMAND,
203            "TIMESTAMP": TokenType.TIMESTAMPTZ,
204            "WHILE": TokenType.COMMAND,
205        }
206        KEYWORDS.pop("DIV")
207        KEYWORDS.pop("VALUES")
208        KEYWORDS.pop("/*+")
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'''", "'''")]
NESTED_COMMENTS = False
KEYWORDS = {'{%': <TokenType.BLOCK_START: 73>, '{%+': <TokenType.BLOCK_START: 73>, '{%-': <TokenType.BLOCK_START: 73>, '%}': <TokenType.BLOCK_END: 74>, '+%}': <TokenType.BLOCK_END: 74>, '-%}': <TokenType.BLOCK_END: 74>, '{{+': <TokenType.BLOCK_START: 73>, '{{-': <TokenType.BLOCK_START: 73>, '+}}': <TokenType.BLOCK_END: 74>, '-}}': <TokenType.BLOCK_END: 74>, '&<': <TokenType.AMP_LT: 63>, '&>': <TokenType.AMP_GT: 64>, '==': <TokenType.EQ: 28>, '::': <TokenType.DCOLON: 14>, '?::': <TokenType.QDCOLON: 370>, '||': <TokenType.DPIPE: 37>, '|>': <TokenType.PIPE_GT: 38>, '>=': <TokenType.GTE: 26>, '<=': <TokenType.LTE: 24>, '<>': <TokenType.NEQ: 29>, '!=': <TokenType.NEQ: 29>, ':=': <TokenType.COLON_EQ: 31>, '<=>': <TokenType.NULLSAFE_EQ: 30>, '->': <TokenType.ARROW: 45>, '->>': <TokenType.DARROW: 46>, '=>': <TokenType.FARROW: 47>, '#>': <TokenType.HASH_ARROW: 49>, '#>>': <TokenType.DHASH_ARROW: 50>, '<->': <TokenType.LR_ARROW: 51>, '<<->>': <TokenType.LLRR_ARROW: 52>, '&&': <TokenType.DAMP: 62>, '??': <TokenType.DQMARK: 18>, '~~~': <TokenType.GLOB: 287>, '~~': <TokenType.LIKE: 318>, '~~*': <TokenType.ILIKE: 295>, '~*': <TokenType.IRLIKE: 307>, '-|-': <TokenType.ADJACENT: 65>, 'ALL': <TokenType.ALL: 220>, 'AND': <TokenType.AND: 34>, 'ANTI': <TokenType.ANTI: 221>, 'ANY': <TokenType.ANY: 222>, 'ASC': <TokenType.ASC: 225>, 'AS': <TokenType.ALIAS: 218>, 'ASOF': <TokenType.ASOF: 226>, 'AUTOINCREMENT': <TokenType.AUTO_INCREMENT: 228>, 'AUTO_INCREMENT': <TokenType.AUTO_INCREMENT: 228>, 'BEGIN': <TokenType.COMMAND: 237>, 'BETWEEN': <TokenType.BETWEEN: 230>, 'CACHE': <TokenType.CACHE: 232>, 'UNCACHE': <TokenType.UNCACHE: 414>, 'CASE': <TokenType.CASE: 233>, 'CLUSTER BY': <TokenType.CLUSTER_BY: 235>, 'COLLATE': <TokenType.COLLATE: 236>, 'COLUMN': <TokenType.COLUMN: 81>, 'COMMIT': <TokenType.COMMIT: 239>, 'CONNECT BY': <TokenType.CONNECT_BY: 240>, 'CONSTRAINT': <TokenType.CONSTRAINT: 241>, 'COPY': <TokenType.COPY: 242>, 'CREATE': <TokenType.CREATE: 243>, 'CROSS': <TokenType.CROSS: 244>, 'CUBE': <TokenType.CUBE: 245>, 'CURRENT_DATE': <TokenType.CURRENT_DATE: 246>, 'CURRENT_SCHEMA': <TokenType.CURRENT_SCHEMA: 248>, 'CURRENT_TIME': <TokenType.CURRENT_TIME: 249>, 'CURRENT_TIMESTAMP': <TokenType.CURRENT_TIMESTAMP: 250>, 'CURRENT_USER': <TokenType.CURRENT_USER: 251>, 'CURRENT_CATALOG': <TokenType.CURRENT_CATALOG: 254>, 'DATABASE': <TokenType.DATABASE: 80>, 'DEFAULT': <TokenType.DEFAULT: 256>, 'DELETE': <TokenType.DELETE: 257>, 'DESC': <TokenType.DESC: 258>, 'DESCRIBE': <TokenType.DESCRIBE: 259>, 'DISTINCT': <TokenType.DISTINCT: 262>, 'DISTRIBUTE BY': <TokenType.DISTRIBUTE_BY: 263>, 'DROP': <TokenType.DROP: 265>, 'ELSE': <TokenType.ELSE: 266>, 'END': <TokenType.END: 267>, 'ENUM': <TokenType.ENUM: 205>, 'ESCAPE': <TokenType.ESCAPE: 268>, 'EXCEPT': <TokenType.EXCEPT: 269>, 'EXECUTE': <TokenType.EXECUTE: 270>, 'EXISTS': <TokenType.EXISTS: 271>, 'FALSE': <TokenType.FALSE: 272>, 'FETCH': <TokenType.FETCH: 273>, 'FILTER': <TokenType.FILTER: 276>, 'FILE': <TokenType.FILE: 274>, 'FIRST': <TokenType.FIRST: 278>, 'FULL': <TokenType.FULL: 284>, 'FUNCTION': <TokenType.FUNCTION: 285>, 'FOR': <TokenType.FOR: 279>, 'FOREIGN KEY': <TokenType.FOREIGN_KEY: 281>, 'FORMAT': <TokenType.FORMAT: 282>, 'FROM': <TokenType.FROM: 283>, 'GEOGRAPHY': <TokenType.GEOGRAPHY: 172>, 'GEOMETRY': <TokenType.GEOMETRY: 175>, 'GLOB': <TokenType.GLOB: 287>, 'GROUP BY': <TokenType.GROUP_BY: 290>, 'GROUPING SETS': <TokenType.GROUPING_SETS: 291>, 'HAVING': <TokenType.HAVING: 292>, 'ILIKE': <TokenType.ILIKE: 295>, 'IN': <TokenType.IN: 296>, 'INDEX': <TokenType.INDEX: 297>, 'INET': <TokenType.INET: 200>, 'INNER': <TokenType.INNER: 299>, 'INSERT': <TokenType.INSERT: 300>, 'INTERVAL': <TokenType.INTERVAL: 304>, 'INTERSECT': <TokenType.INTERSECT: 303>, 'INTO': <TokenType.INTO: 305>, 'IS': <TokenType.IS: 308>, 'ISNULL': <TokenType.ISNULL: 309>, 'JOIN': <TokenType.JOIN: 310>, 'KEEP': <TokenType.KEEP: 312>, 'KILL': <TokenType.KILL: 314>, 'LATERAL': <TokenType.LATERAL: 316>, 'LEFT': <TokenType.LEFT: 317>, 'LIKE': <TokenType.LIKE: 318>, 'LIMIT': <TokenType.LIMIT: 319>, 'LOAD': <TokenType.LOAD: 321>, 'LOCALTIME': <TokenType.LOCALTIME: 179>, 'LOCALTIMESTAMP': <TokenType.LOCALTIMESTAMP: 180>, 'LOCK': <TokenType.LOCK: 322>, 'MERGE': <TokenType.MERGE: 328>, 'NAMESPACE': <TokenType.NAMESPACE: 440>, 'NATURAL': <TokenType.NATURAL: 331>, 'NEXT': <TokenType.NEXT: 332>, 'NOT': <TokenType.NOT: 27>, 'NOTNULL': <TokenType.NOTNULL: 334>, 'NULL': <TokenType.NULL: 335>, 'OBJECT': <TokenType.OBJECT: 199>, 'OFFSET': <TokenType.OFFSET: 337>, 'ON': <TokenType.ON: 338>, 'OR': <TokenType.OR: 35>, 'XOR': <TokenType.XOR: 66>, 'ORDER BY': <TokenType.ORDER_BY: 341>, 'ORDINALITY': <TokenType.ORDINALITY: 344>, 'OUT': <TokenType.OUT: 345>, 'OUTER': <TokenType.OUTER: 347>, 'OVER': <TokenType.OVER: 348>, 'OVERLAPS': <TokenType.OVERLAPS: 349>, 'OVERWRITE': <TokenType.OVERWRITE: 350>, 'PARTITION': <TokenType.PARTITION: 352>, 'PARTITION BY': <TokenType.PARTITION_BY: 353>, 'PARTITIONED BY': <TokenType.PARTITION_BY: 353>, 'PARTITIONED_BY': <TokenType.PARTITION_BY: 353>, 'PERCENT': <TokenType.PERCENT: 354>, 'PIVOT': <TokenType.PIVOT: 355>, 'PRAGMA': <TokenType.PRAGMA: 360>, 'PRIMARY KEY': <TokenType.PRIMARY_KEY: 362>, 'PROCEDURE': <TokenType.PROCEDURE: 363>, 'OPERATOR': <TokenType.OPERATOR: 340>, 'QUALIFY': <TokenType.QUALIFY: 368>, 'RANGE': <TokenType.RANGE: 371>, 'RECURSIVE': <TokenType.RECURSIVE: 372>, 'REGEXP': <TokenType.RLIKE: 380>, 'RENAME': <TokenType.RENAME: 374>, 'REPLACE': <TokenType.REPLACE: 375>, 'RETURNING': <TokenType.RETURNING: 376>, 'REFERENCES': <TokenType.REFERENCES: 378>, 'RIGHT': <TokenType.RIGHT: 379>, 'RLIKE': <TokenType.RLIKE: 380>, 'ROLLBACK': <TokenType.ROLLBACK: 382>, 'ROLLUP': <TokenType.ROLLUP: 383>, 'ROW': <TokenType.ROW: 384>, 'ROWS': <TokenType.ROWS: 385>, 'SCHEMA': <TokenType.SCHEMA: 83>, 'SELECT': <TokenType.SELECT: 387>, 'SEMI': <TokenType.SEMI: 388>, 'SESSION': <TokenType.SESSION: 59>, 'SESSION_USER': <TokenType.SESSION_USER: 61>, 'SET': <TokenType.SET: 392>, 'SETTINGS': <TokenType.SETTINGS: 393>, 'SHOW': <TokenType.SHOW: 394>, 'SIMILAR TO': <TokenType.SIMILAR_TO: 395>, 'SOME': <TokenType.SOME: 396>, 'SORT BY': <TokenType.SORT_BY: 397>, 'SQL SECURITY': <TokenType.SQL_SECURITY: 399>, 'STRAIGHT_JOIN': <TokenType.STRAIGHT_JOIN: 402>, 'TABLE': <TokenType.TABLE: 84>, 'TABLESAMPLE': <TokenType.TABLE_SAMPLE: 405>, 'TEMP': <TokenType.TEMPORARY: 407>, 'TEMPORARY': <TokenType.TEMPORARY: 407>, 'THEN': <TokenType.THEN: 409>, 'TRUE': <TokenType.TRUE: 410>, 'TRUNCATE': <TokenType.TRUNCATE: 411>, 'TRIGGER': <TokenType.TRIGGER: 412>, 'UNION': <TokenType.UNION: 416>, 'UNKNOWN': <TokenType.UNKNOWN: 214>, 'UNNEST': <TokenType.UNNEST: 417>, 'UNPIVOT': <TokenType.UNPIVOT: 418>, 'UPDATE': <TokenType.UPDATE: 419>, 'USE': <TokenType.USE: 420>, 'USING': <TokenType.USING: 421>, 'UUID': <TokenType.UUID: 171>, 'VIEW': <TokenType.VIEW: 424>, 'VOLATILE': <TokenType.VOLATILE: 426>, 'WHEN': <TokenType.WHEN: 428>, 'WHERE': <TokenType.WHERE: 429>, 'WINDOW': <TokenType.WINDOW: 430>, 'WITH': <TokenType.WITH: 431>, 'APPLY': <TokenType.APPLY: 223>, 'ARRAY': <TokenType.ARRAY: 224>, 'BIT': <TokenType.BIT: 97>, 'BOOL': <TokenType.BOOLEAN: 98>, 'BOOLEAN': <TokenType.BOOLEAN: 98>, 'BYTE': <TokenType.TINYINT: 99>, 'MEDIUMINT': <TokenType.MEDIUMINT: 103>, 'INT1': <TokenType.TINYINT: 99>, 'TINYINT': <TokenType.TINYINT: 99>, 'INT16': <TokenType.SMALLINT: 101>, 'SHORT': <TokenType.SMALLINT: 101>, 'SMALLINT': <TokenType.SMALLINT: 101>, 'HUGEINT': <TokenType.INT128: 110>, 'UHUGEINT': <TokenType.UINT128: 111>, 'INT2': <TokenType.SMALLINT: 101>, 'INTEGER': <TokenType.INT: 105>, 'INT': <TokenType.INT: 105>, 'INT4': <TokenType.INT: 105>, 'INT32': <TokenType.INT: 105>, 'INT64': <TokenType.BIGINT: 107>, 'INT128': <TokenType.INT128: 110>, 'INT256': <TokenType.INT256: 112>, 'LONG': <TokenType.BIGINT: 107>, 'BIGINT': <TokenType.BIGINT: 107>, 'INT8': <TokenType.TINYINT: 99>, 'UINT': <TokenType.UINT: 106>, 'UINT128': <TokenType.UINT128: 111>, 'UINT256': <TokenType.UINT256: 113>, 'DEC': <TokenType.DECIMAL: 117>, 'DECIMAL': <TokenType.DECIMAL: 117>, 'DECIMAL32': <TokenType.DECIMAL32: 118>, 'DECIMAL64': <TokenType.DECIMAL64: 119>, 'DECIMAL128': <TokenType.DECIMAL128: 120>, 'DECIMAL256': <TokenType.DECIMAL256: 121>, 'DECFLOAT': <TokenType.DECFLOAT: 122>, 'BIGDECIMAL': <TokenType.BIGDECIMAL: 124>, 'BIGNUMERIC': <TokenType.BIGDECIMAL: 124>, 'BIGNUM': <TokenType.BIGNUM: 109>, 'LIST': <TokenType.LIST: 320>, 'MAP': <TokenType.MAP: 323>, 'NULLABLE': <TokenType.NULLABLE: 174>, 'NUMBER': <TokenType.DECIMAL: 117>, 'NUMERIC': <TokenType.DECIMAL: 117>, 'FIXED': <TokenType.DECIMAL: 117>, 'REAL': <TokenType.FLOAT: 114>, 'FLOAT': <TokenType.FLOAT: 114>, 'FLOAT4': <TokenType.FLOAT: 114>, 'FLOAT8': <TokenType.DOUBLE: 115>, 'DOUBLE': <TokenType.DOUBLE: 115>, 'DOUBLE PRECISION': <TokenType.DOUBLE: 115>, 'JSON': <TokenType.JSON: 141>, 'JSONB': <TokenType.JSONB: 142>, 'CHAR': <TokenType.CHAR: 125>, 'CHARACTER': <TokenType.CHAR: 125>, 'CHAR VARYING': <TokenType.VARCHAR: 127>, 'CHARACTER VARYING': <TokenType.VARCHAR: 127>, 'NCHAR': <TokenType.NCHAR: 126>, 'VARCHAR': <TokenType.VARCHAR: 127>, 'VARCHAR2': <TokenType.VARCHAR: 127>, 'NVARCHAR': <TokenType.NVARCHAR: 128>, 'NVARCHAR2': <TokenType.NVARCHAR: 128>, 'BPCHAR': <TokenType.BPCHAR: 129>, 'STR': <TokenType.TEXT: 130>, 'STRING': <TokenType.TEXT: 130>, 'TEXT': <TokenType.TEXT: 130>, 'LONGTEXT': <TokenType.LONGTEXT: 132>, 'MEDIUMTEXT': <TokenType.MEDIUMTEXT: 131>, 'TINYTEXT': <TokenType.TINYTEXT: 137>, 'CLOB': <TokenType.TEXT: 130>, 'LONGVARCHAR': <TokenType.TEXT: 130>, 'BINARY': <TokenType.BINARY: 139>, 'BLOB': <TokenType.VARBINARY: 140>, 'LONGBLOB': <TokenType.LONGBLOB: 135>, 'MEDIUMBLOB': <TokenType.MEDIUMBLOB: 134>, 'TINYBLOB': <TokenType.TINYBLOB: 136>, 'BYTEA': <TokenType.VARBINARY: 140>, 'VARBINARY': <TokenType.VARBINARY: 140>, 'TIME': <TokenType.TIME: 143>, 'TIMETZ': <TokenType.TIMETZ: 144>, 'TIME_NS': <TokenType.TIME_NS: 145>, 'TIMESTAMP': <TokenType.TIMESTAMPTZ: 147>, 'TIMESTAMPTZ': <TokenType.TIMESTAMPTZ: 147>, 'TIMESTAMPLTZ': <TokenType.TIMESTAMPLTZ: 148>, 'TIMESTAMP_LTZ': <TokenType.TIMESTAMPLTZ: 148>, 'TIMESTAMPNTZ': <TokenType.TIMESTAMPNTZ: 149>, 'TIMESTAMP_NTZ': <TokenType.TIMESTAMPNTZ: 149>, 'DATE': <TokenType.DATE: 157>, 'DATETIME': <TokenType.TIMESTAMP: 146>, 'INT4RANGE': <TokenType.INT4RANGE: 159>, 'INT4MULTIRANGE': <TokenType.INT4MULTIRANGE: 160>, 'INT8RANGE': <TokenType.INT8RANGE: 161>, 'INT8MULTIRANGE': <TokenType.INT8MULTIRANGE: 162>, 'NUMRANGE': <TokenType.NUMRANGE: 163>, 'NUMMULTIRANGE': <TokenType.NUMMULTIRANGE: 164>, 'TSRANGE': <TokenType.TSRANGE: 165>, 'TSMULTIRANGE': <TokenType.TSMULTIRANGE: 166>, 'TSTZRANGE': <TokenType.TSTZRANGE: 167>, 'TSTZMULTIRANGE': <TokenType.TSTZMULTIRANGE: 168>, 'DATERANGE': <TokenType.DATERANGE: 169>, 'DATEMULTIRANGE': <TokenType.DATEMULTIRANGE: 170>, 'UNIQUE': <TokenType.UNIQUE: 432>, 'VECTOR': <TokenType.VECTOR: 215>, 'STRUCT': <TokenType.STRUCT: 403>, 'SEQUENCE': <TokenType.SEQUENCE: 390>, 'VARIANT': <TokenType.VARIANT: 198>, 'ALTER': <TokenType.ALTER: 219>, 'ANALYZE': <TokenType.ANALYZE: 439>, 'CALL': <TokenType.COMMAND: 237>, 'COMMENT': <TokenType.COMMENT: 238>, 'EXPLAIN': <TokenType.COMMAND: 237>, 'GRANT': <TokenType.GRANT: 289>, 'REVOKE': <TokenType.REVOKE: 377>, 'OPTIMIZE': <TokenType.COMMAND: 237>, 'PREPARE': <TokenType.COMMAND: 237>, 'VACUUM': <TokenType.COMMAND: 237>, 'USER-DEFINED': <TokenType.USERDEFINED: 193>, 'ANY TYPE': <TokenType.VARIANT: 198>, 'BEGIN TRANSACTION': <TokenType.BEGIN: 229>, 'BYTEINT': <TokenType.INT: 105>, 'BYTES': <TokenType.BINARY: 139>, 'CURRENT_DATETIME': <TokenType.CURRENT_DATETIME: 247>, 'DECLARE': <TokenType.DECLARE: 255>, 'ELSEIF': <TokenType.COMMAND: 237>, 'EXCEPTION': <TokenType.COMMAND: 237>, 'EXPORT': <TokenType.EXPORT: 441>, 'FLOAT64': <TokenType.DOUBLE: 115>, 'LOOP': <TokenType.COMMAND: 237>, 'MODEL': <TokenType.MODEL: 330>, 'RECORD': <TokenType.STRUCT: 403>, 'REPEAT': <TokenType.COMMAND: 237>, 'WHILE': <TokenType.COMMAND: 237>}
BYTE_STRING_ESCAPES: ClassVar[list[str]] = ['\\']