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

ORIGINAL_NAME_META_KEY: str | None = 'bigquery_name'

Dialect-specific metadata key for preserving original function names, or None to disable. Only generators using the same key reuse these names, allowing round trips of aliases 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

TABLE_ALIASES_SHADOW_COLUMN_NAMES = True

Whether a whole-row reference to a table alias takes precedence over a same-named column.

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] = {'_DBT_MAX_PARTITION', '_FILE_NAME', '_PARTITIONDATE', '_TABLE_SUFFIX', '_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.DATETIME: 'DATETIME'>, <DType.TEXT: 'TEXT'>, <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <DType.TIMESTAMP: 'TIMESTAMP'>, <DType.TIME: 'TIME'>, <DType.NVARCHAR: 'NVARCHAR'>}, <DType.NCHAR: 'NCHAR'>: {<DType.TEXT: 'TEXT'>, <DType.NVARCHAR: 'NVARCHAR'>, <DType.VARCHAR: 'VARCHAR'>}, <DType.CHAR: 'CHAR'>: {<DType.NCHAR: 'NCHAR'>, <DType.TEXT: 'TEXT'>, <DType.NVARCHAR: 'NVARCHAR'>, <DType.VARCHAR: 'VARCHAR'>}, <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.BIGDECIMAL: 'BIGDECIMAL'>, <DType.DECFLOAT: 'DECFLOAT'>, <DType.DOUBLE: 'DOUBLE'>, <DType.FLOAT: 'FLOAT'>}, <DType.BIGINT: 'BIGINT'>: {<DType.BIGDECIMAL: 'BIGDECIMAL'>, <DType.DECFLOAT: 'DECFLOAT'>, <DType.DECIMAL: 'DECIMAL'>, <DType.DOUBLE: 'DOUBLE'>, <DType.FLOAT: 'FLOAT'>}, <DType.INT: 'INT'>: {<DType.BIGDECIMAL: 'BIGDECIMAL'>, <DType.DECFLOAT: 'DECFLOAT'>, <DType.DECIMAL: 'DECIMAL'>, <DType.BIGINT: 'BIGINT'>, <DType.DOUBLE: 'DOUBLE'>, <DType.FLOAT: 'FLOAT'>}, <DType.SMALLINT: 'SMALLINT'>: {<DType.INT: 'INT'>, <DType.BIGDECIMAL: 'BIGDECIMAL'>, <DType.DECFLOAT: 'DECFLOAT'>, <DType.DECIMAL: 'DECIMAL'>, <DType.BIGINT: 'BIGINT'>, <DType.DOUBLE: 'DOUBLE'>, <DType.FLOAT: 'FLOAT'>}, <DType.TINYINT: 'TINYINT'>: {<DType.INT: 'INT'>, <DType.BIGDECIMAL: 'BIGDECIMAL'>, <DType.DECFLOAT: 'DECFLOAT'>, <DType.DECIMAL: 'DECIMAL'>, <DType.BIGINT: 'BIGINT'>, <DType.DOUBLE: 'DOUBLE'>, <DType.SMALLINT: 'SMALLINT'>, <DType.FLOAT: 'FLOAT'>}, <DType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>: set(), <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>: {<DType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>}, <DType.TIMESTAMP: 'TIMESTAMP'>: {<DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <DType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>}, <DType.DATETIME: 'DATETIME'>: {<DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <DType.TIMESTAMP: 'TIMESTAMP'>, <DType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>}, <DType.DATE: 'DATE'>: {<DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <DType.TIMESTAMP: 'TIMESTAMP'>, <DType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <DType.DATETIME: 'DATETIME'>}}
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.temporal.UnixSeconds'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.aggregate.Ntile'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.aggregate.Rank'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.temporal.UnixMillis'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.array.ArraySize'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.aggregate.RowNumber'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.temporal.UnixMicros'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.aggregate.DenseRank'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.functions.Int64'>: {'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.string.FromBase32'>: {'returns': <DType.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.string.FromBase64'>: {'returns': <DType.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.aggregate.LogicalOr'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.aggregate.LogicalAnd'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.string.Contains'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.core.In'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.core.Boolean'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.string.StartsWith'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.math.IsInf'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.core.Between'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.core.Any'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.functions.Exists'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.math.IsNan'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.core.All'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.string.EndsWith'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.temporal.TsOrDsToDate'>: {'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.Date'>: {'returns': <DType.DATE: 'DATE'>}, <class 'sqlglot.expressions.temporal.StrToDate'>: {'returns': <DType.DATE: 'DATE'>}, <class 'sqlglot.expressions.temporal.DateStrToDate'>: {'returns': <DType.DATE: 'DATE'>}, <class 'sqlglot.expressions.temporal.LastDay'>: {'returns': <DType.DATE: 'DATE'>}, <class 'sqlglot.expressions.temporal.DateFromParts'>: {'returns': <DType.DATE: 'DATE'>}, <class 'sqlglot.expressions.temporal.CurrentDate'>: {'returns': <DType.DATE: 'DATE'>}, <class 'sqlglot.expressions.temporal.DatetimeSub'>: {'returns': <DType.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.temporal.Datetime'>: {'returns': <DType.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.temporal.DatetimeAdd'>: {'returns': <DType.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.temporal.CurrentDatetime'>: {'returns': <DType.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.aggregate.Kurtosis'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Pi'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Atanh'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Acos'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.Quantile'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Asinh'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.CumeDist'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Ln'>: {'annotator': <function annotate_int_as_double>}, <class 'sqlglot.expressions.math.Exp'>: {'annotator': <function annotate_int_as_double>}, <class 'sqlglot.expressions.math.Radians'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.CovarPop'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.StddevSamp'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Cbrt'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Cosh'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.Stddev'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.SafeDivide'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.aggregate.Avg'>: {'annotator': <function annotate_int_as_double>}, <class 'sqlglot.expressions.math.Tan'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.VariancePop'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.string.ToDouble'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.functions.Rand'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Sin'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.ApproxQuantile'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Acosh'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Atan'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Log'>: {'annotator': <function annotate_int_as_double>}, <class 'sqlglot.expressions.aggregate.PercentRank'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Asin'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.CovarSamp'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Degrees'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.PercentileCont'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.math.Cot'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.StddevPop'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.Variance'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Cos'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.Skewness'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Sqrt'>: {'annotator': <function annotate_int_as_double>}, <class 'sqlglot.expressions.math.Tanh'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Round'>: {'annotator': <function annotate_int_as_double>}, <class 'sqlglot.expressions.math.Sinh'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.temporal.TsOrDiToDi'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.DayOfMonth'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.string.Levenshtein'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.string.BitLength'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.Quarter'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.math.Getbit'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.Hour'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.string.Unicode'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.DateToDi'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.math.Sign'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.temporal.DayOfYear'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.DayOfWeek'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.string.StrPosition'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.string.Length'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.temporal.TimeDiff'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.TimestampDiff'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.string.Ascii'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.DatetimeDiff'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.UnixDate'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.temporal.JustifyDays'>: {'returns': <DType.INTERVAL: 'INTERVAL'>}, <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.json.ParseJSON'>: {'returns': <DType.JSON: 'JSON'>}, <class 'sqlglot.expressions.temporal.Time'>: {'returns': <DType.TIME: 'TIME'>}, <class 'sqlglot.expressions.temporal.TimeSub'>: {'returns': <DType.TIME: 'TIME'>}, <class 'sqlglot.expressions.temporal.CurrentTime'>: {'returns': <DType.TIME: 'TIME'>}, <class 'sqlglot.expressions.temporal.Localtime'>: {'returns': <DType.TIME: 'TIME'>}, <class 'sqlglot.expressions.temporal.TimeAdd'>: {'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.StrToTime'>: {'returns': <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.temporal.TimestampAdd'>: {'returns': <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.temporal.TimestampSub'>: {'returns': <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.temporal.UnixToTime'>: {'returns': <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.temporal.CurrentTimestamp'>: {'returns': <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.temporal.YearOfWeekIso'>: {'returns': <DType.TINYINT: 'TINYINT'>}, <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.WeekOfYear'>: {'returns': <DType.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.temporal.Day'>: {'returns': <DType.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.temporal.Week'>: {'returns': <DType.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.temporal.DayOfWeekIso'>: {'returns': <DType.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.string.MD5'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.temporal.TimeToTimeStr'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Chr'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.aggregate.GroupConcat'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.ToBase64'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Initcap'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.array.ArrayToString'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Space'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.functions.CurrentCatalog'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.ConcatWs'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.query.RawString'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Translate'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.Typeof'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.functions.SessionUser'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Substring'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.functions.CurrentVersion'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.String'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Lower'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.functions.CurrentUser'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.temporal.TimeToStr'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.ToBase32'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Repeat'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.temporal.UnixToStr'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.temporal.Monthname'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.functions.CurrentSchema'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Upper'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.functions.CurrentRole'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.SHA2'>: {'returns': <DType.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.string.Concat'>: {'annotator': <function _annotate_concat>}, <class 'sqlglot.expressions.string.Trim'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.temporal.DateToDateStr'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.temporal.Dayname'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.temporal.UnixToTimeStr'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.SHA'>: {'returns': <DType.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.temporal.TsOrDsToDateStr'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.math.Floor'>: {'annotator': <function annotate_int_as_double>}, <class 'sqlglot.expressions.math.Ceil'>: {'annotator': <function annotate_int_as_double>}, <class 'sqlglot.expressions.core.HavingMax'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.NthValue'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.query.Window'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.FirstValue'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.Filter'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.query.Order'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.AnyValue'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.LastValue'>: {'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.array.ArraySort'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.array.ArraySlice'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.array.ArrayReverse'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.math.Abs'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.array.ArrayConcat'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.functions.Coalesce'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.Min'>: {'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.aggregate.Max'>: {'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.DateSub'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.temporal.DateTrunc'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.temporal.DateAdd'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.functions.TryCast'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.functions.Cast'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.array.VarMap'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.array.Map'>: {'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.aggregate.ArgMin'>: {'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.functions.NetFunc'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.Pad'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.math.SafeNegate'>: {'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.string.RegexpReplace'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.RegexpExtract'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.ArgMax'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.Reverse'>: {'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.math.BitwiseXorAgg'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.aggregate.Grouping'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.math.BitwiseOrAgg'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.string.FarmFingerprint'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.math.BitwiseCount'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.string.RegexpInstr'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.string.ByteLength'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.math.BitwiseAndAgg'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.functions.RangeBucket'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.functions.LaxInt64'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.string.SHA2Digest'>: {'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.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.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.functions.LaxFloat64'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Coth'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Atan2'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Sech'>: {'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.functions.Float64'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Csch'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Csc'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.json.JSONStripNulls'>: {'returns': <DType.JSON: 'JSON'>}, <class 'sqlglot.expressions.json.JSONSet'>: {'returns': <DType.JSON: 'JSON'>}, <class 'sqlglot.expressions.json.JSONArray'>: {'returns': <DType.JSON: 'JSON'>}, <class 'sqlglot.expressions.json.JSONRemove'>: {'returns': <DType.JSON: 'JSON'>}, <class 'sqlglot.expressions.json.JSONObject'>: {'returns': <DType.JSON: 'JSON'>}, <class 'sqlglot.expressions.json.JSONArrayInsert'>: {'returns': <DType.JSON: 'JSON'>}, <class 'sqlglot.expressions.json.JSONArrayAppend'>: {'returns': <DType.JSON: 'JSON'>}, <class 'sqlglot.expressions.temporal.ParseTime'>: {'returns': <DType.TIME: 'TIME'>}, <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.json.JSONType'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.SafeConvertBytesToString'>: {'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.RegDomain'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.CodePointsToString'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.functions.Uuid'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.functions.LaxString'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Normalize'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.functions.Host'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Format'>: {'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.Split'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.json.JSONExtractArray'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.RegexpExtractAll'>: {'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:
136    def normalize_identifier(self, expression: E) -> E:
137        if (
138            isinstance(expression, exp.Identifier)
139            and self.normalization_strategy is NormalizationStrategy.CASE_INSENSITIVE
140        ):
141            parent = expression.parent
142            while isinstance(parent, exp.Dot):
143                parent = parent.parent
144
145            # In BigQuery, CTEs are case-insensitive, but UDF and table names are case-sensitive
146            # by default. The following check uses a heuristic to detect tables based on whether
147            # they are qualified. This should generally be correct, because tables in BigQuery
148            # must be qualified with at least a dataset, unless @@dataset_id is set.
149            case_sensitive = (
150                isinstance(parent, exp.UserDefinedFunction)
151                or (
152                    isinstance(parent, exp.Table)
153                    and parent.db
154                    and (parent.meta_get("quoted_table") or not parent.meta_get("maybe_column"))
155                )
156                or expression.meta_get("is_table")
157            )
158            if not case_sensitive:
159                expression.set("this", expression.this.translate(ASCII_LOWER))
160
161            return t.cast(E, expression)
162
163        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.

IDENTIFIER_ESCAPED_SEQUENCES: dict[str, str] = {}

Mapping of an identifier escape char (\) to its escaped version (\\). Set by the metaclass based on the tokenizer's IDENTIFIER_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', '\\': '\\\\', '\x00': '\\x00', '\x01': '\\x01', '\x02': '\\x02', '\x03': '\\x03', '\x04': '\\x04', '\x05': '\\x05', '\x06': '\\x06', '\x0e': '\\x0e', '\x0f': '\\x0f', '\x10': '\\x10', '\x11': '\\x11', '\x12': '\\x12', '\x13': '\\x13', '\x14': '\\x14', '\x15': '\\x15', '\x16': '\\x16', '\x17': '\\x17', '\x18': '\\x18', '\x19': '\\x19', '\x1a': '\\x1a', '\x1b': '\\x1b', '\x1c': '\\x1c', '\x1d': '\\x1d', '\x1e': '\\x1e', '\x1f': '\\x1f', '\x7f': '\\x7f'}
QUOTE_START = "'"
QUOTE_END = "'"
IDENTIFIER_START = '`'
IDENTIFIER_END = '`'
VALID_INTERVAL_UNITS: set[str] = {'QUARTER', 'D', 'QTR', 'MILLISEC', 'DD', 'WEEKDAY', 'DAYS', 'WEEKISO', 'MONS', 'TZM', 'NS', 'DEC', 'NANOSEC', 'YYY', 'QUARTERS', 'CENTS', 'EPOCH_NANOSECOND', 'MON', 'TIMEZONE_HOUR', 'MONTH', 'HOURS', 'NSEC', 'MSECS', 'MILLENNIUM', 'WOY', 'MILLISECOND', 'EPOCH_MICROSECONDS', 'DAYOFWEEKISO', 'WY', 'WEEKOFYEAR', 'MI', 'H', 'DW_ISO', 'M', 'Y', 'DOY', 'C', 'DAYOFWEEK', 'DAY OF WEEK', 'YYYY', 'USEC', 'TIMEZONE_MINUTE', 'YY', 'WEEKOFYEAR_ISO', 'HRS', 'MINUTES', 'DECS', 'NSECOND', 'MILLENIA', 'MILS', 'DOW_ISO', 'USECONDS', 'MSEC', 'DECADE', 'MICROSEC', 'MINUTE', 'MICROSECS', 'MILLISECONDS', 'YEAR', 'YR', 'NANOSECS', 'CENTURIES', 'CENTURY', 'WK', 'DW', 'YRS', 'DECADES', 'US', 'HH', 'DAY', 'EPOCH_MILLISECOND', 'MIL', 'YEARS', 'DAYOFMONTH', 'WEEKOFYEARISO', 'S', 'WEEK', 'SECS', 'EPOCH', 'MS', 'USECOND', 'QTRS', 'MILLISECON', 'SECOND', 'MINS', 'MSECONDS', 'DAYOFWEEK_ISO', 'SEC', 'MSECOND', 'NSECONDS', 'EPOCH_NANOSECONDS', 'W', 'MM', 'EPOCH_MICROSECOND', 'EPOCH_SECONDS', 'EPOCH_SECOND', 'EPOCH_MILLISECONDS', 'MONTHS', 'SECONDS', 'DAY OF YEAR', 'MILLISECS', 'Q', 'HR', 'DOW', 'MICROSECOND', 'WEEKDAY_ISO', 'HOUR', 'USECS', 'MIN', 'WEEK_ISO', 'MICROSECONDS', 'DAYOFYEAR', 'NANOSECOND', 'TZH', 'CENT', 'DY'}
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):
165    class JSONPathTokenizer(jsonpath.JSONPathTokenizer):
166        VAR_TOKENS = {
167            *jsonpath.JSONPathTokenizer.VAR_TOKENS,
168            TokenType.DASH,
169            TokenType.NUMBER,
170        }
VAR_TOKENS = {<TokenType.VAR: 89>, <TokenType.DASH: 9>, <TokenType.NUMBER: 78>}
class BigQuery.Tokenizer(sqlglot.tokens.Tokenizer):
172    class Tokenizer(tokens.Tokenizer):
173        NUMERIC_ESCAPES = {
174            "x": (16, 2, 2, 0xFF),
175            "X": (16, 2, 2, 0xFF),
176            "u": (16, 4, 4, 0xFFFF),
177            "U": (16, 8, 8, 0x10FFFF),
178            "0": (8, 3, 3, 0xFF),
179        }
180        DROP_UNKNOWN_ESCAPES = True
181        QUOTES = ["'", '"', '"""', "'''"]
182        COMMENTS = ["--", "#", ("/*", "*/")]
183        IDENTIFIERS = ["`"]
184        STRING_ESCAPES = ["\\"]
185
186        HEX_STRINGS = [("0x", ""), ("0X", "")]
187
188        BYTE_STRINGS = [(prefix + q, q) for q in t.cast(list[str], QUOTES) for prefix in ("b", "B")]
189
190        RAW_STRINGS = [(prefix + q, q) for q in t.cast(list[str], QUOTES) for prefix in ("r", "R")]
191
192        NESTED_COMMENTS = False
193
194        KEYWORDS = {
195            **tokens.Tokenizer.KEYWORDS,
196            "ANY TYPE": TokenType.VARIANT,
197            "BEGIN": TokenType.COMMAND,
198            "BEGIN TRANSACTION": TokenType.BEGIN,
199            "BYTEINT": TokenType.INT,
200            "BYTES": TokenType.BINARY,
201            "CURRENT_DATETIME": TokenType.CURRENT_DATETIME,
202            "DATETIME": TokenType.TIMESTAMP,
203            "DECLARE": TokenType.DECLARE,
204            "ELSEIF": TokenType.COMMAND,
205            "EXCEPTION": TokenType.COMMAND,
206            "EXPORT": TokenType.EXPORT,
207            "FLOAT64": TokenType.DOUBLE,
208            "LOOP": TokenType.COMMAND,
209            "MODEL": TokenType.MODEL,
210            "RECORD": TokenType.STRUCT,
211            "REPEAT": TokenType.COMMAND,
212            "TIMESTAMP": TokenType.TIMESTAMPTZ,
213            "WHILE": TokenType.COMMAND,
214        }
215        KEYWORDS.pop("ISNULL")
216        KEYWORDS.pop("DIV")
217        KEYWORDS.pop("VALUES")
218        KEYWORDS.pop("/*+")
NUMERIC_ESCAPES = {'x': (16, 2, 2, 255), 'X': (16, 2, 2, 255), 'u': (16, 4, 4, 65535), 'U': (16, 8, 8, 1114111), '0': (8, 3, 3, 255)}
DROP_UNKNOWN_ESCAPES = True
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: 375>, '||': <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: 291>, '~~': <TokenType.LIKE: 322>, '~~*': <TokenType.ILIKE: 299>, '~*': <TokenType.IRLIKE: 311>, '-|-': <TokenType.ADJACENT: 65>, 'ALL': <TokenType.ALL: 222>, 'AND': <TokenType.AND: 34>, 'ANTI': <TokenType.ANTI: 223>, 'ANY': <TokenType.ANY: 224>, 'ASC': <TokenType.ASC: 227>, 'AS': <TokenType.ALIAS: 220>, 'ASOF': <TokenType.ASOF: 228>, 'AUTOINCREMENT': <TokenType.AUTO_INCREMENT: 230>, 'AUTO_INCREMENT': <TokenType.AUTO_INCREMENT: 230>, 'BEGIN': <TokenType.COMMAND: 239>, 'BETWEEN': <TokenType.BETWEEN: 232>, 'CACHE': <TokenType.CACHE: 234>, 'UNCACHE': <TokenType.UNCACHE: 419>, 'CASE': <TokenType.CASE: 235>, 'CLUSTER BY': <TokenType.CLUSTER_BY: 237>, 'COLLATE': <TokenType.COLLATE: 238>, 'COLUMN': <TokenType.COLUMN: 81>, 'COMMIT': <TokenType.COMMIT: 241>, 'CONNECT BY': <TokenType.CONNECT_BY: 243>, 'CONSTRAINT': <TokenType.CONSTRAINT: 244>, 'COPY': <TokenType.COPY: 245>, 'CREATE': <TokenType.CREATE: 246>, 'CROSS': <TokenType.CROSS: 247>, 'CUBE': <TokenType.CUBE: 248>, 'CURRENT_DATE': <TokenType.CURRENT_DATE: 249>, 'CURRENT_SCHEMA': <TokenType.CURRENT_SCHEMA: 251>, 'CURRENT_TIME': <TokenType.CURRENT_TIME: 252>, 'CURRENT_TIMESTAMP': <TokenType.CURRENT_TIMESTAMP: 253>, 'CURRENT_USER': <TokenType.CURRENT_USER: 254>, 'CURRENT_CATALOG': <TokenType.CURRENT_CATALOG: 257>, 'DATABASE': <TokenType.DATABASE: 80>, 'DEFAULT': <TokenType.DEFAULT: 259>, 'DELETE': <TokenType.DELETE: 260>, 'DESC': <TokenType.DESC: 261>, 'DESCRIBE': <TokenType.DESCRIBE: 262>, 'DISTINCT': <TokenType.DISTINCT: 266>, 'DISTRIBUTE BY': <TokenType.DISTRIBUTE_BY: 267>, 'DROP': <TokenType.DROP: 269>, 'ELSE': <TokenType.ELSE: 270>, 'END': <TokenType.END: 271>, 'ENUM': <TokenType.ENUM: 207>, 'ESCAPE': <TokenType.ESCAPE: 272>, 'EXCEPT': <TokenType.EXCEPT: 273>, 'EXECUTE': <TokenType.EXECUTE: 274>, 'EXISTS': <TokenType.EXISTS: 275>, 'FALSE': <TokenType.FALSE: 276>, 'FETCH': <TokenType.FETCH: 277>, 'FILTER': <TokenType.FILTER: 280>, 'FILE': <TokenType.FILE: 278>, 'FIRST': <TokenType.FIRST: 282>, 'FULL': <TokenType.FULL: 288>, 'FUNCTION': <TokenType.FUNCTION: 289>, 'FOR': <TokenType.FOR: 283>, 'FOREIGN KEY': <TokenType.FOREIGN_KEY: 285>, 'FORMAT': <TokenType.FORMAT: 286>, 'FROM': <TokenType.FROM: 287>, 'GEOGRAPHY': <TokenType.GEOGRAPHY: 173>, 'GEOMETRY': <TokenType.GEOMETRY: 176>, 'GLOB': <TokenType.GLOB: 291>, 'GROUP BY': <TokenType.GROUP_BY: 294>, 'GROUPING SETS': <TokenType.GROUPING_SETS: 295>, 'HAVING': <TokenType.HAVING: 296>, 'ILIKE': <TokenType.ILIKE: 299>, 'IN': <TokenType.IN: 300>, 'INDEX': <TokenType.INDEX: 301>, 'INET': <TokenType.INET: 202>, 'INNER': <TokenType.INNER: 303>, 'INSERT': <TokenType.INSERT: 304>, 'INTERVAL': <TokenType.INTERVAL: 308>, 'INTERSECT': <TokenType.INTERSECT: 307>, 'INTO': <TokenType.INTO: 309>, 'IS': <TokenType.IS: 312>, 'JOIN': <TokenType.JOIN: 314>, 'KEEP': <TokenType.KEEP: 316>, 'KILL': <TokenType.KILL: 318>, 'LATERAL': <TokenType.LATERAL: 320>, 'LEFT': <TokenType.LEFT: 321>, 'LIKE': <TokenType.LIKE: 322>, 'LIMIT': <TokenType.LIMIT: 323>, 'LOAD': <TokenType.LOAD: 325>, 'LOCALTIME': <TokenType.LOCALTIME: 180>, 'LOCALTIMESTAMP': <TokenType.LOCALTIMESTAMP: 181>, 'LOCK': <TokenType.LOCK: 326>, 'MERGE': <TokenType.MERGE: 332>, 'NAMESPACE': <TokenType.NAMESPACE: 445>, 'NATURAL': <TokenType.NATURAL: 335>, 'NEXT': <TokenType.NEXT: 336>, 'NOT': <TokenType.NOT: 27>, 'NOTNULL': <TokenType.NOTNULL: 338>, 'NULL': <TokenType.NULL: 339>, 'OBJECT': <TokenType.OBJECT: 200>, 'REF': <TokenType.REF: 201>, 'OFFSET': <TokenType.OFFSET: 341>, 'ON': <TokenType.ON: 342>, 'OR': <TokenType.OR: 35>, 'XOR': <TokenType.XOR: 66>, 'ORDER BY': <TokenType.ORDER_BY: 345>, 'ORDINALITY': <TokenType.ORDINALITY: 348>, 'OUT': <TokenType.OUT: 349>, 'OUTER': <TokenType.OUTER: 351>, 'OVER': <TokenType.OVER: 352>, 'OVERLAPS': <TokenType.OVERLAPS: 353>, 'OVERWRITE': <TokenType.OVERWRITE: 354>, 'PARTITION': <TokenType.PARTITION: 356>, 'PARTITION BY': <TokenType.PARTITION_BY: 357>, 'PARTITIONED BY': <TokenType.PARTITION_BY: 357>, 'PARTITIONED_BY': <TokenType.PARTITION_BY: 357>, 'PERCENT': <TokenType.PERCENT: 359>, 'PIVOT': <TokenType.PIVOT: 360>, 'PRAGMA': <TokenType.PRAGMA: 365>, 'PRIMARY KEY': <TokenType.PRIMARY_KEY: 367>, 'PROCEDURE': <TokenType.PROCEDURE: 368>, 'OPERATOR': <TokenType.OPERATOR: 344>, 'QUALIFY': <TokenType.QUALIFY: 373>, 'RANGE': <TokenType.RANGE: 376>, 'RECURSIVE': <TokenType.RECURSIVE: 377>, 'REGEXP': <TokenType.RLIKE: 385>, 'RENAME': <TokenType.RENAME: 379>, 'REPLACE': <TokenType.REPLACE: 380>, 'RETURNING': <TokenType.RETURNING: 381>, 'REFERENCES': <TokenType.REFERENCES: 383>, 'RIGHT': <TokenType.RIGHT: 384>, 'RLIKE': <TokenType.RLIKE: 385>, 'ROLLBACK': <TokenType.ROLLBACK: 387>, 'ROLLUP': <TokenType.ROLLUP: 388>, 'ROW': <TokenType.ROW: 389>, 'ROWS': <TokenType.ROWS: 390>, 'SCHEMA': <TokenType.SCHEMA: 83>, 'SELECT': <TokenType.SELECT: 392>, 'SEMI': <TokenType.SEMI: 393>, 'SESSION': <TokenType.SESSION: 59>, 'SESSION_USER': <TokenType.SESSION_USER: 61>, 'SET': <TokenType.SET: 397>, 'SETTINGS': <TokenType.SETTINGS: 398>, 'SHOW': <TokenType.SHOW: 399>, 'SIMILAR TO': <TokenType.SIMILAR_TO: 400>, 'SOME': <TokenType.SOME: 401>, 'SORT BY': <TokenType.SORT_BY: 402>, 'SQL SECURITY': <TokenType.SQL_SECURITY: 404>, 'STRAIGHT_JOIN': <TokenType.STRAIGHT_JOIN: 407>, 'TABLE': <TokenType.TABLE: 84>, 'TABLESAMPLE': <TokenType.TABLE_SAMPLE: 410>, 'TEMP': <TokenType.TEMPORARY: 412>, 'TEMPORARY': <TokenType.TEMPORARY: 412>, 'THEN': <TokenType.THEN: 414>, 'TRUE': <TokenType.TRUE: 415>, 'TRUNCATE': <TokenType.TRUNCATE: 416>, 'TRIGGER': <TokenType.TRIGGER: 417>, 'UNION': <TokenType.UNION: 421>, 'UNKNOWN': <TokenType.UNKNOWN: 216>, 'UNNEST': <TokenType.UNNEST: 422>, 'UNPIVOT': <TokenType.UNPIVOT: 423>, 'UPDATE': <TokenType.UPDATE: 424>, 'USE': <TokenType.USE: 425>, 'USING': <TokenType.USING: 426>, 'UUID': <TokenType.UUID: 172>, 'VIEW': <TokenType.VIEW: 429>, 'VOLATILE': <TokenType.VOLATILE: 431>, 'WHEN': <TokenType.WHEN: 433>, 'WHERE': <TokenType.WHERE: 434>, 'WINDOW': <TokenType.WINDOW: 435>, 'WITH': <TokenType.WITH: 436>, 'APPLY': <TokenType.APPLY: 225>, 'ARRAY': <TokenType.ARRAY: 226>, 'BIT': <TokenType.BIT: 98>, 'BOOL': <TokenType.BOOLEAN: 99>, 'BOOLEAN': <TokenType.BOOLEAN: 99>, 'BYTE': <TokenType.TINYINT: 100>, 'MEDIUMINT': <TokenType.MEDIUMINT: 104>, 'INT1': <TokenType.TINYINT: 100>, 'TINYINT': <TokenType.TINYINT: 100>, 'INT16': <TokenType.SMALLINT: 102>, 'SHORT': <TokenType.SMALLINT: 102>, 'SMALLINT': <TokenType.SMALLINT: 102>, 'HUGEINT': <TokenType.INT128: 111>, 'UHUGEINT': <TokenType.UINT128: 112>, 'INT2': <TokenType.SMALLINT: 102>, 'INTEGER': <TokenType.INT: 106>, 'INT': <TokenType.INT: 106>, 'INT4': <TokenType.INT: 106>, 'INT32': <TokenType.INT: 106>, 'INT64': <TokenType.BIGINT: 108>, 'INT128': <TokenType.INT128: 111>, 'INT256': <TokenType.INT256: 113>, 'LONG': <TokenType.BIGINT: 108>, 'BIGINT': <TokenType.BIGINT: 108>, 'INT8': <TokenType.TINYINT: 100>, 'UINT': <TokenType.UINT: 107>, 'UINT128': <TokenType.UINT128: 112>, 'UINT256': <TokenType.UINT256: 114>, 'DEC': <TokenType.DECIMAL: 118>, 'DECIMAL': <TokenType.DECIMAL: 118>, 'DECIMAL32': <TokenType.DECIMAL32: 119>, 'DECIMAL64': <TokenType.DECIMAL64: 120>, 'DECIMAL128': <TokenType.DECIMAL128: 121>, 'DECIMAL256': <TokenType.DECIMAL256: 122>, 'DECFLOAT': <TokenType.DECFLOAT: 123>, 'BIGDECIMAL': <TokenType.BIGDECIMAL: 125>, 'BIGNUMERIC': <TokenType.BIGDECIMAL: 125>, 'BIGNUM': <TokenType.BIGNUM: 110>, 'LIST': <TokenType.LIST: 324>, 'MAP': <TokenType.MAP: 327>, 'NULLABLE': <TokenType.NULLABLE: 175>, 'NUMBER': <TokenType.DECIMAL: 118>, 'NUMERIC': <TokenType.DECIMAL: 118>, 'FIXED': <TokenType.DECIMAL: 118>, 'REAL': <TokenType.FLOAT: 115>, 'FLOAT': <TokenType.FLOAT: 115>, 'FLOAT4': <TokenType.FLOAT: 115>, 'FLOAT8': <TokenType.DOUBLE: 116>, 'DOUBLE': <TokenType.DOUBLE: 116>, 'DOUBLE PRECISION': <TokenType.DOUBLE: 116>, 'JSON': <TokenType.JSON: 142>, 'JSONB': <TokenType.JSONB: 143>, 'CHAR': <TokenType.CHAR: 126>, 'CHARACTER': <TokenType.CHAR: 126>, 'CHAR VARYING': <TokenType.VARCHAR: 128>, 'CHARACTER VARYING': <TokenType.VARCHAR: 128>, 'NCHAR': <TokenType.NCHAR: 127>, 'VARCHAR': <TokenType.VARCHAR: 128>, 'VARCHAR2': <TokenType.VARCHAR: 128>, 'NVARCHAR': <TokenType.NVARCHAR: 129>, 'NVARCHAR2': <TokenType.NVARCHAR: 129>, 'BPCHAR': <TokenType.BPCHAR: 130>, 'STR': <TokenType.TEXT: 131>, 'STRING': <TokenType.TEXT: 131>, 'TEXT': <TokenType.TEXT: 131>, 'LONGTEXT': <TokenType.LONGTEXT: 133>, 'MEDIUMTEXT': <TokenType.MEDIUMTEXT: 132>, 'TINYTEXT': <TokenType.TINYTEXT: 138>, 'CLOB': <TokenType.TEXT: 131>, 'LONGVARCHAR': <TokenType.TEXT: 131>, 'BINARY': <TokenType.BINARY: 140>, 'BLOB': <TokenType.VARBINARY: 141>, 'LONGBLOB': <TokenType.LONGBLOB: 136>, 'MEDIUMBLOB': <TokenType.MEDIUMBLOB: 135>, 'TINYBLOB': <TokenType.TINYBLOB: 137>, 'BYTEA': <TokenType.VARBINARY: 141>, 'VARBINARY': <TokenType.VARBINARY: 141>, 'TIME': <TokenType.TIME: 144>, 'TIMETZ': <TokenType.TIMETZ: 145>, 'TIME_NS': <TokenType.TIME_NS: 146>, 'TIMESTAMP': <TokenType.TIMESTAMPTZ: 148>, 'TIMESTAMPTZ': <TokenType.TIMESTAMPTZ: 148>, 'TIMESTAMPLTZ': <TokenType.TIMESTAMPLTZ: 149>, 'TIMESTAMP_LTZ': <TokenType.TIMESTAMPLTZ: 149>, 'TIMESTAMPNTZ': <TokenType.TIMESTAMPNTZ: 150>, 'TIMESTAMP_NTZ': <TokenType.TIMESTAMPNTZ: 150>, 'DATE': <TokenType.DATE: 158>, 'DATETIME': <TokenType.TIMESTAMP: 147>, 'INT4RANGE': <TokenType.INT4RANGE: 160>, 'INT4MULTIRANGE': <TokenType.INT4MULTIRANGE: 161>, 'INT8RANGE': <TokenType.INT8RANGE: 162>, 'INT8MULTIRANGE': <TokenType.INT8MULTIRANGE: 163>, 'NUMRANGE': <TokenType.NUMRANGE: 164>, 'NUMMULTIRANGE': <TokenType.NUMMULTIRANGE: 165>, 'TSRANGE': <TokenType.TSRANGE: 166>, 'TSMULTIRANGE': <TokenType.TSMULTIRANGE: 167>, 'TSTZRANGE': <TokenType.TSTZRANGE: 168>, 'TSTZMULTIRANGE': <TokenType.TSTZMULTIRANGE: 169>, 'DATERANGE': <TokenType.DATERANGE: 170>, 'DATEMULTIRANGE': <TokenType.DATEMULTIRANGE: 171>, 'UNIQUE': <TokenType.UNIQUE: 437>, 'VECTOR': <TokenType.VECTOR: 217>, 'STRUCT': <TokenType.STRUCT: 408>, 'SEQUENCE': <TokenType.SEQUENCE: 395>, 'VARIANT': <TokenType.VARIANT: 199>, 'ALTER': <TokenType.ALTER: 221>, 'ANALYZE': <TokenType.ANALYZE: 444>, 'CALL': <TokenType.COMMAND: 239>, 'COMMENT': <TokenType.COMMENT: 240>, 'EXPLAIN': <TokenType.COMMAND: 239>, 'GRANT': <TokenType.GRANT: 293>, 'REVOKE': <TokenType.REVOKE: 382>, 'OPTIMIZE': <TokenType.COMMAND: 239>, 'PREPARE': <TokenType.COMMAND: 239>, 'VACUUM': <TokenType.COMMAND: 239>, 'USER-DEFINED': <TokenType.USERDEFINED: 194>, 'ANY TYPE': <TokenType.VARIANT: 199>, 'BEGIN TRANSACTION': <TokenType.BEGIN: 231>, 'BYTEINT': <TokenType.INT: 106>, 'BYTES': <TokenType.BINARY: 140>, 'CURRENT_DATETIME': <TokenType.CURRENT_DATETIME: 250>, 'DECLARE': <TokenType.DECLARE: 258>, 'ELSEIF': <TokenType.COMMAND: 239>, 'EXCEPTION': <TokenType.COMMAND: 239>, 'EXPORT': <TokenType.EXPORT: 446>, 'FLOAT64': <TokenType.DOUBLE: 116>, 'LOOP': <TokenType.COMMAND: 239>, 'MODEL': <TokenType.MODEL: 334>, 'RECORD': <TokenType.STRUCT: 408>, 'REPEAT': <TokenType.COMMAND: 239>, 'WHILE': <TokenType.COMMAND: 239>}
BYTE_STRING_ESCAPES: ClassVar[list[str]] = ['\\']