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

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'}
FORMAT_MAPPING: dict[str, str] = {'DD': '%d', 'MM': '%m', 'MON': '%b', 'MONTH': '%B', 'YYYY': '%Y', 'YY': '%y', 'HH': '%I', 'HH12': '%I', 'HH24': '%H', 'MI': '%M', 'SS': '%S', 'SSSSS': '%f', 'TZH': '%z'}

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] = {'_TABLE_SUFFIX', '_PARTITIONDATE', '_FILE_NAME', '_PARTITIONTIME', '_DBT_MAX_PARTITION'}

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.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <DType.TIME: 'TIME'>, <DType.DATE: 'DATE'>, <DType.TIMESTAMP: 'TIMESTAMP'>, <DType.NVARCHAR: 'NVARCHAR'>, <DType.DATETIME: 'DATETIME'>, <DType.TEXT: 'TEXT'>}, <DType.NCHAR: 'NCHAR'>: {<DType.VARCHAR: 'VARCHAR'>, <DType.NVARCHAR: 'NVARCHAR'>, <DType.TEXT: 'TEXT'>}, <DType.CHAR: 'CHAR'>: {<DType.VARCHAR: 'VARCHAR'>, <DType.NVARCHAR: 'NVARCHAR'>, <DType.NCHAR: 'NCHAR'>, <DType.TEXT: 'TEXT'>}, <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.DECFLOAT: 'DECFLOAT'>, <DType.FLOAT: 'FLOAT'>, <DType.BIGDECIMAL: 'BIGDECIMAL'>}, <DType.BIGINT: 'BIGINT'>: {<DType.DOUBLE: 'DOUBLE'>, <DType.DECFLOAT: 'DECFLOAT'>, <DType.DECIMAL: 'DECIMAL'>, <DType.FLOAT: 'FLOAT'>, <DType.BIGDECIMAL: 'BIGDECIMAL'>}, <DType.INT: 'INT'>: {<DType.BIGINT: 'BIGINT'>, <DType.DOUBLE: 'DOUBLE'>, <DType.DECFLOAT: 'DECFLOAT'>, <DType.DECIMAL: 'DECIMAL'>, <DType.FLOAT: 'FLOAT'>, <DType.BIGDECIMAL: 'BIGDECIMAL'>}, <DType.SMALLINT: 'SMALLINT'>: {<DType.BIGINT: 'BIGINT'>, <DType.INT: 'INT'>, <DType.DOUBLE: 'DOUBLE'>, <DType.DECFLOAT: 'DECFLOAT'>, <DType.DECIMAL: 'DECIMAL'>, <DType.FLOAT: 'FLOAT'>, <DType.BIGDECIMAL: 'BIGDECIMAL'>}, <DType.TINYINT: 'TINYINT'>: {<DType.INT: 'INT'>, <DType.DECFLOAT: 'DECFLOAT'>, <DType.DECIMAL: 'DECIMAL'>, <DType.BIGINT: 'BIGINT'>, <DType.SMALLINT: 'SMALLINT'>, <DType.DOUBLE: 'DOUBLE'>, <DType.FLOAT: 'FLOAT'>, <DType.BIGDECIMAL: 'BIGDECIMAL'>}, <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.DATETIME: 'DATETIME'>, <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.ArrayContains'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <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.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.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.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'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <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.core.ApproxDistinct'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.aggregate.CountIf'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.temporal.UnixMillis'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.temporal.UnixMicros'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.array.ArraySize'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.functions.Int64'>: {'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.math.IsInf'>: {'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.core.Between'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.string.StartsWith'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.aggregate.LogicalAnd'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.math.IsNan'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.core.Any'>: {'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.functions.Exists'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.string.EndsWith'>: {'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.TsOrDsToDate'>: {'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.StrToDate'>: {'returns': <DType.DATE: 'DATE'>}, <class 'sqlglot.expressions.temporal.DiToDate'>: {'returns': <DType.DATE: 'DATE'>}, <class 'sqlglot.expressions.temporal.TimeStrToDate'>: {'returns': <DType.DATE: 'DATE'>}, <class 'sqlglot.expressions.temporal.LastDay'>: {'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.CurrentDatetime'>: {'returns': <DType.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.temporal.DatetimeAdd'>: {'returns': <DType.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.aggregate.Avg'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.math.Log'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.math.Exp'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.math.Asinh'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Cbrt'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Tan'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.functions.Rand'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.StddevPop'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.SafeDivide'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.aggregate.ApproxQuantile'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.Kurtosis'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.Skewness'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Sin'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Cosh'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Asin'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Acos'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Pi'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Degrees'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Atan'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Cot'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.string.ToDouble'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Ln'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.math.Tanh'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Sinh'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.Variance'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.StddevSamp'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.VariancePop'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.Stddev'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.Quantile'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Round'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.math.Sqrt'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.math.Cos'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Acosh'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Radians'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Atanh'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.string.BitLength'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.DayOfWeek'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.Quarter'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.string.Length'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.temporal.DateToDi'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.string.Ascii'>: {'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.DayOfMonth'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.math.Ceil'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.Levenshtein'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.UnixDate'>: {'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.Unicode'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.DatetimeDiff'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.TsOrDiToDi'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.Hour'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.DayOfYear'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.string.StrPosition'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.JustifyInterval'>: {'returns': <DType.INTERVAL: 'INTERVAL'>}, <class 'sqlglot.expressions.datatypes.Interval'>: {'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.temporal.MakeInterval'>: {'returns': <DType.INTERVAL: 'INTERVAL'>}, <class 'sqlglot.expressions.json.ParseJSON'>: {'returns': <DType.JSON: 'JSON'>}, <class 'sqlglot.expressions.temporal.TimeSub'>: {'returns': <DType.TIME: 'TIME'>}, <class 'sqlglot.expressions.temporal.Time'>: {'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.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.StrToTime'>: {'returns': <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.temporal.UnixToTime'>: {'returns': <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.temporal.TimestampSub'>: {'returns': <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.temporal.TimestampAdd'>: {'returns': <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.temporal.TimeStrToTime'>: {'returns': <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.temporal.CurrentTimestamp'>: {'returns': <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.temporal.Day'>: {'returns': <DType.TINYINT: 'TINYINT'>}, <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.Week'>: {'returns': <DType.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.temporal.DayOfWeekIso'>: {'returns': <DType.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.query.RawString'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.array.ArrayToString'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Lower'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.Space'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.functions.SessionUser'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.functions.CurrentVersion'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.ToBase64'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.functions.CurrentUser'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Upper'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.Trim'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.GroupConcat'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.Concat'>: {'annotator': <function _annotate_concat>}, <class 'sqlglot.expressions.string.SHA2'>: {'returns': <DType.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.functions.CurrentSchema'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.temporal.TimeToStr'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.SHA'>: {'returns': <DType.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.temporal.Dayname'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.temporal.UnixToStr'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.MD5'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.temporal.Monthname'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Initcap'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.temporal.UnixToTimeStr'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.ToBase32'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.temporal.TsOrDsToDateStr'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.temporal.DateToDateStr'>: {'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.string.Translate'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.temporal.TimeToTimeStr'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Chr'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Substring'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.String'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.array.SortArray'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.FirstValue'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.array.ArraySlice'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.ArrayConcatAgg'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.LastValue'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.math.Abs'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.array.ArrayReverse'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.Filter'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.AnyValue'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.HavingMax'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.query.Window'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.query.Order'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.query.Limit'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.functions.Least'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.array.ArrayConcat'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.functions.Greatest'>: {'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.ArrayLast'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.array.ArrayFirst'>: {'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.Cast'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.functions.TryCast'>: {'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.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.query.Subquery'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.math.Floor'>: {'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.Right'>: {'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.RegexpReplace'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.Reverse'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.NthValue'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.Left'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.SafeFunc'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.ArgMin'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.temporal.TimestampTrunc'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.temporal.DatetimeTrunc'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.Lead'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.functions.NetFunc'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.Repeat'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.PercentileDisc'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.Replace'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.Ntile'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.string.FarmFingerprint'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.math.BitwiseXorAgg'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.functions.RangeBucket'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.math.BitwiseOrAgg'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.aggregate.RowNumber'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.math.BitwiseCount'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.aggregate.DenseRank'>: {'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.aggregate.Grouping'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.functions.LaxInt64'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.aggregate.Rank'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.string.MD5Digest'>: {'returns': <DType.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.string.Unhex'>: {'returns': <DType.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.query.ByteString'>: {'returns': <DType.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.string.SHA2Digest'>: {'returns': <DType.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.string.CodePointsToBytes'>: {'returns': <DType.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.string.SHA1Digest'>: {'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.EuclideanDistance'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.functions.LaxFloat64'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Csch'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Coth'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.CosineDistance'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Csc'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.PercentRank'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Sech'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.functions.Float64'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Sec'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.CumeDist'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Atan2'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.CovarSamp'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.CovarPop'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.json.JSONArrayAppend'>: {'returns': <DType.JSON: 'JSON'>}, <class 'sqlglot.expressions.json.JSONArrayInsert'>: {'returns': <DType.JSON: 'JSON'>}, <class 'sqlglot.expressions.json.JSONStripNulls'>: {'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.json.JSONArray'>: {'returns': <DType.JSON: 'JSON'>}, <class 'sqlglot.expressions.json.JSONObject'>: {'returns': <DType.JSON: 'JSON'>}, <class 'sqlglot.expressions.temporal.TimeFromParts'>: {'returns': <DType.TIME: 'TIME'>}, <class 'sqlglot.expressions.temporal.TsOrDsToTime'>: {'returns': <DType.TIME: 'TIME'>}, <class 'sqlglot.expressions.temporal.ParseTime'>: {'returns': <DType.TIME: 'TIME'>}, <class 'sqlglot.expressions.temporal.TimeTrunc'>: {'returns': <DType.TIME: 'TIME'>}, <class 'sqlglot.expressions.string.LowerHex'>: {'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.string.Soundex'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.json.JSONType'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.functions.Host'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.functions.Uuid'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Format'>: {'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.string.SafeConvertBytesToString'>: {'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.aggregate.PercentileCont'>: {'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.string.Split'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.ApproxQuantiles'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.json.JSONExtractArray'>: {'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.aggregate.Lag'>: {'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:
123    def normalize_identifier(self, expression: E) -> E:
124        if (
125            isinstance(expression, exp.Identifier)
126            and self.normalization_strategy is NormalizationStrategy.CASE_INSENSITIVE
127        ):
128            parent = expression.parent
129            while isinstance(parent, exp.Dot):
130                parent = parent.parent
131
132            # In BigQuery, CTEs are case-insensitive, but UDF and table names are case-sensitive
133            # by default. The following check uses a heuristic to detect tables based on whether
134            # they are qualified. This should generally be correct, because tables in BigQuery
135            # must be qualified with at least a dataset, unless @@dataset_id is set.
136            case_sensitive = (
137                isinstance(parent, exp.UserDefinedFunction)
138                or (
139                    isinstance(parent, exp.Table)
140                    and parent.db
141                    and (parent.meta.get("quoted_table") or not parent.meta.get("maybe_column"))
142                )
143                or expression.meta.get("is_table")
144            )
145            if not case_sensitive:
146                expression.set("this", expression.this.lower())
147
148            return t.cast(E, expression)
149
150        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}}, 'M': {'M': {0: True}, 'O': {'N': {0: True, 'T': {'H': {0: True}}}}, 'I': {0: True}}, 'Y': {'Y': {'Y': {'Y': {0: True}}, 0: True}}, 'H': {'H': {0: True, '1': {'2': {0: True}}, '2': {'4': {0: True}}}}, 'S': {'S': {0: True, 'S': {'S': {'S': {0: True}}}}}, 'T': {'Z': {'H': {0: True}}}}
INVERSE_TIME_TRIE: dict = {'%': {'m': {'/': {'%': {'d': {'/': {'%': {'y': {0: True}}}}}}}, 'S': {'.': {'%': {'f': {0: True}}}}, '-': {'d': {0: True}}, 'Y': {'-': {'%': {'m': {'-': {'%': {'d': {0: True}}}}}}}, 'H': {':': {'%': {'M': {':': {'%': {'S': {0: True, '.': {'%': {'f': {0: True}}}}}}}}}}, 'a': {' ': {'%': {'b': {' ': {'%': {'e': {' ': {'%': {'H': {':': {'%': {'M': {':': {'%': {'S': {' ': {'%': {'Y': {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'}
INVERSE_FORMAT_TRIE: dict = {'%': {'d': {0: True}, 'm': {0: True}, 'b': {0: True}, 'B': {0: True}, 'Y': {0: True}, 'y': {0: True}, 'I': {0: True}, 'H': {0: True}, 'M': {0: True}, 'S': {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] = {'DAYOFYEAR', 'H', 'MICROSEC', 'NSECONDS', 'S', 'MONTHS', 'DEC', 'EPOCH_SECOND', 'WEEKOFYEAR', 'CENTS', 'DW', 'QUARTERS', 'WEEKDAY_ISO', 'DECADE', 'NANOSEC', 'CENTURY', 'EPOCH', 'MSECS', 'M', 'DAYOFWEEK', 'WEEKDAY', 'CENTURIES', 'MILS', 'MI', 'DAYOFWEEKISO', 'MONTH', 'HOURS', 'DOW_ISO', 'WEEK_ISO', 'SEC', 'NSECOND', 'DAY', 'HH', 'MSEC', 'EPOCH_MICROSECONDS', 'CENT', 'DAYOFWEEK_ISO', 'YYY', 'YEAR', 'USECOND', 'C', 'EPOCH_SECONDS', 'YR', 'MIN', 'NSEC', 'WY', 'USECS', 'WEEKOFYEAR_ISO', 'DAY OF YEAR', 'YEARS', 'NANOSECOND', 'QTR', 'DOW', 'WEEKISO', 'EPOCH_MICROSECOND', 'DY', 'MILLISEC', 'MM', 'W', 'WEEK', 'SECONDS', 'NANOSECS', 'MILLISECON', 'SECOND', 'USECONDS', 'D', 'US', 'EPOCH_NANOSECONDS', 'Y', 'NS', 'EPOCH_NANOSECOND', 'YYYY', 'DW_ISO', 'DAYOFMONTH', 'QUARTER', 'MON', 'Q', 'MIL', 'MONS', 'WOY', 'WEEKOFYEARISO', 'MINUTE', 'YY', 'USEC', 'YRS', 'MILLISECONDS', 'MILLENNIUM', 'TIMEZONE_MINUTE', 'HR', 'HOUR', 'MICROSECONDS', 'EPOCH_MILLISECONDS', 'MILLISECOND', 'MILLISECS', 'MINS', 'MSECOND', 'WK', 'MSECONDS', 'DD', 'TIMEZONE_HOUR', 'TZM', 'MICROSECOND', 'MINUTES', 'DECS', 'QTRS', 'MS', 'TZH', 'MICROSECS', 'EPOCH_MILLISECOND', 'DECADES', 'HRS', 'DAY OF WEEK', 'SECS', 'DAYS', 'DOY', 'MILLENIA'}
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):
152    class JSONPathTokenizer(jsonpath.JSONPathTokenizer):
153        VAR_TOKENS = {
154            *jsonpath.JSONPathTokenizer.VAR_TOKENS,
155            TokenType.DASH,
156            TokenType.NUMBER,
157        }
VAR_TOKENS = {<TokenType.DASH: 9>, <TokenType.NUMBER: 76>, <TokenType.VAR: 87>}
BYTE_STRING_ESCAPES: ClassVar[list[str]] = ['\\']
class BigQuery.Tokenizer(sqlglot.tokens.Tokenizer):
159    class Tokenizer(tokens.Tokenizer):
160        QUOTES = ["'", '"', '"""', "'''"]
161        COMMENTS = ["--", "#", ("/*", "*/")]
162        IDENTIFIERS = ["`"]
163        STRING_ESCAPES = ["\\"]
164
165        HEX_STRINGS = [("0x", ""), ("0X", "")]
166
167        BYTE_STRINGS = [(prefix + q, q) for q in t.cast(list[str], QUOTES) for prefix in ("b", "B")]
168
169        RAW_STRINGS = [(prefix + q, q) for q in t.cast(list[str], QUOTES) for prefix in ("r", "R")]
170
171        NESTED_COMMENTS = False
172
173        KEYWORDS = {
174            **tokens.Tokenizer.KEYWORDS,
175            "ANY TYPE": TokenType.VARIANT,
176            "BEGIN": TokenType.COMMAND,
177            "BEGIN TRANSACTION": TokenType.BEGIN,
178            "BYTEINT": TokenType.INT,
179            "BYTES": TokenType.BINARY,
180            "CURRENT_DATETIME": TokenType.CURRENT_DATETIME,
181            "DATETIME": TokenType.TIMESTAMP,
182            "DECLARE": TokenType.DECLARE,
183            "ELSEIF": TokenType.COMMAND,
184            "EXCEPTION": TokenType.COMMAND,
185            "EXPORT": TokenType.EXPORT,
186            "FLOAT64": TokenType.DOUBLE,
187            "FOR SYSTEM TIME": TokenType.TIMESTAMP_SNAPSHOT,
188            "FOR SYSTEM_TIME": TokenType.TIMESTAMP_SNAPSHOT,
189            "LOOP": TokenType.COMMAND,
190            "MODEL": TokenType.MODEL,
191            "NOT DETERMINISTIC": TokenType.VOLATILE,
192            "RECORD": TokenType.STRUCT,
193            "REPEAT": TokenType.COMMAND,
194            "TIMESTAMP": TokenType.TIMESTAMPTZ,
195            "WHILE": TokenType.COMMAND,
196        }
197        KEYWORDS.pop("DIV")
198        KEYWORDS.pop("VALUES")
199        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: 71>, '{%+': <TokenType.BLOCK_START: 71>, '{%-': <TokenType.BLOCK_START: 71>, '%}': <TokenType.BLOCK_END: 72>, '+%}': <TokenType.BLOCK_END: 72>, '-%}': <TokenType.BLOCK_END: 72>, '{{+': <TokenType.BLOCK_START: 71>, '{{-': <TokenType.BLOCK_START: 71>, '+}}': <TokenType.BLOCK_END: 72>, '-}}': <TokenType.BLOCK_END: 72>, '&<': <TokenType.AMP_LT: 61>, '&>': <TokenType.AMP_GT: 62>, '==': <TokenType.EQ: 28>, '::': <TokenType.DCOLON: 14>, '?::': <TokenType.QDCOLON: 367>, '||': <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.DAMP: 60>, '??': <TokenType.DQMARK: 18>, '~~~': <TokenType.GLOB: 285>, '~~': <TokenType.LIKE: 316>, '~~*': <TokenType.ILIKE: 293>, '~*': <TokenType.IRLIKE: 305>, '-|-': <TokenType.ADJACENT: 63>, 'ALL': <TokenType.ALL: 218>, 'AND': <TokenType.AND: 34>, 'ANTI': <TokenType.ANTI: 219>, 'ANY': <TokenType.ANY: 220>, 'ASC': <TokenType.ASC: 223>, 'AS': <TokenType.ALIAS: 216>, 'ASOF': <TokenType.ASOF: 224>, 'AUTOINCREMENT': <TokenType.AUTO_INCREMENT: 226>, 'AUTO_INCREMENT': <TokenType.AUTO_INCREMENT: 226>, 'BEGIN': <TokenType.COMMAND: 235>, 'BETWEEN': <TokenType.BETWEEN: 228>, 'CACHE': <TokenType.CACHE: 230>, 'UNCACHE': <TokenType.UNCACHE: 411>, 'CASE': <TokenType.CASE: 231>, 'CHARACTER SET': <TokenType.CHARACTER_SET: 232>, 'CLUSTER BY': <TokenType.CLUSTER_BY: 233>, 'COLLATE': <TokenType.COLLATE: 234>, 'COLUMN': <TokenType.COLUMN: 79>, 'COMMIT': <TokenType.COMMIT: 237>, 'CONNECT BY': <TokenType.CONNECT_BY: 238>, 'CONSTRAINT': <TokenType.CONSTRAINT: 239>, 'COPY': <TokenType.COPY: 240>, 'CREATE': <TokenType.CREATE: 241>, 'CROSS': <TokenType.CROSS: 242>, 'CUBE': <TokenType.CUBE: 243>, 'CURRENT_DATE': <TokenType.CURRENT_DATE: 244>, 'CURRENT_SCHEMA': <TokenType.CURRENT_SCHEMA: 246>, 'CURRENT_TIME': <TokenType.CURRENT_TIME: 247>, 'CURRENT_TIMESTAMP': <TokenType.CURRENT_TIMESTAMP: 248>, 'CURRENT_USER': <TokenType.CURRENT_USER: 249>, 'CURRENT_CATALOG': <TokenType.CURRENT_CATALOG: 252>, 'DATABASE': <TokenType.DATABASE: 78>, 'DEFAULT': <TokenType.DEFAULT: 254>, 'DELETE': <TokenType.DELETE: 255>, 'DESC': <TokenType.DESC: 256>, 'DESCRIBE': <TokenType.DESCRIBE: 257>, 'DISTINCT': <TokenType.DISTINCT: 260>, 'DISTRIBUTE BY': <TokenType.DISTRIBUTE_BY: 261>, 'DROP': <TokenType.DROP: 263>, 'ELSE': <TokenType.ELSE: 264>, 'END': <TokenType.END: 265>, 'ENUM': <TokenType.ENUM: 203>, 'ESCAPE': <TokenType.ESCAPE: 266>, 'EXCEPT': <TokenType.EXCEPT: 267>, 'EXECUTE': <TokenType.EXECUTE: 268>, 'EXISTS': <TokenType.EXISTS: 269>, 'FALSE': <TokenType.FALSE: 270>, 'FETCH': <TokenType.FETCH: 271>, 'FILTER': <TokenType.FILTER: 274>, 'FILE': <TokenType.FILE: 272>, 'FIRST': <TokenType.FIRST: 276>, 'FULL': <TokenType.FULL: 282>, 'FUNCTION': <TokenType.FUNCTION: 283>, 'FOR': <TokenType.FOR: 277>, 'FOREIGN KEY': <TokenType.FOREIGN_KEY: 279>, 'FORMAT': <TokenType.FORMAT: 280>, 'FROM': <TokenType.FROM: 281>, 'GEOGRAPHY': <TokenType.GEOGRAPHY: 170>, 'GEOMETRY': <TokenType.GEOMETRY: 173>, 'GLOB': <TokenType.GLOB: 285>, 'GROUP BY': <TokenType.GROUP_BY: 288>, 'GROUPING SETS': <TokenType.GROUPING_SETS: 289>, 'HAVING': <TokenType.HAVING: 290>, 'ILIKE': <TokenType.ILIKE: 293>, 'IN': <TokenType.IN: 294>, 'INDEX': <TokenType.INDEX: 295>, 'INET': <TokenType.INET: 198>, 'INNER': <TokenType.INNER: 297>, 'INSERT': <TokenType.INSERT: 298>, 'INTERVAL': <TokenType.INTERVAL: 302>, 'INTERSECT': <TokenType.INTERSECT: 301>, 'INTO': <TokenType.INTO: 303>, 'IS': <TokenType.IS: 306>, 'ISNULL': <TokenType.ISNULL: 307>, 'JOIN': <TokenType.JOIN: 308>, 'KEEP': <TokenType.KEEP: 310>, 'KILL': <TokenType.KILL: 312>, 'LATERAL': <TokenType.LATERAL: 314>, 'LEFT': <TokenType.LEFT: 315>, 'LIKE': <TokenType.LIKE: 316>, 'LIMIT': <TokenType.LIMIT: 317>, 'LOAD': <TokenType.LOAD: 319>, 'LOCALTIME': <TokenType.LOCALTIME: 177>, 'LOCALTIMESTAMP': <TokenType.LOCALTIMESTAMP: 178>, 'LOCK': <TokenType.LOCK: 320>, 'MERGE': <TokenType.MERGE: 326>, 'NAMESPACE': <TokenType.NAMESPACE: 438>, 'NATURAL': <TokenType.NATURAL: 329>, 'NEXT': <TokenType.NEXT: 330>, 'NOT': <TokenType.NOT: 27>, 'NOTNULL': <TokenType.NOTNULL: 332>, 'NULL': <TokenType.NULL: 333>, 'OBJECT': <TokenType.OBJECT: 197>, 'OFFSET': <TokenType.OFFSET: 335>, 'ON': <TokenType.ON: 336>, 'OR': <TokenType.OR: 35>, 'XOR': <TokenType.XOR: 64>, 'ORDER BY': <TokenType.ORDER_BY: 339>, 'ORDINALITY': <TokenType.ORDINALITY: 342>, 'OUT': <TokenType.OUT: 343>, 'OUTER': <TokenType.OUTER: 345>, 'OVER': <TokenType.OVER: 346>, 'OVERLAPS': <TokenType.OVERLAPS: 347>, 'OVERWRITE': <TokenType.OVERWRITE: 348>, 'PARTITION': <TokenType.PARTITION: 350>, 'PARTITION BY': <TokenType.PARTITION_BY: 351>, 'PARTITIONED BY': <TokenType.PARTITION_BY: 351>, 'PARTITIONED_BY': <TokenType.PARTITION_BY: 351>, 'PERCENT': <TokenType.PERCENT: 352>, 'PIVOT': <TokenType.PIVOT: 353>, 'PRAGMA': <TokenType.PRAGMA: 358>, 'PRIMARY KEY': <TokenType.PRIMARY_KEY: 360>, 'PROCEDURE': <TokenType.PROCEDURE: 361>, 'OPERATOR': <TokenType.OPERATOR: 338>, 'QUALIFY': <TokenType.QUALIFY: 365>, 'RANGE': <TokenType.RANGE: 368>, 'RECURSIVE': <TokenType.RECURSIVE: 369>, 'REGEXP': <TokenType.RLIKE: 377>, 'RENAME': <TokenType.RENAME: 371>, 'REPLACE': <TokenType.REPLACE: 372>, 'RETURNING': <TokenType.RETURNING: 373>, 'REFERENCES': <TokenType.REFERENCES: 375>, 'RIGHT': <TokenType.RIGHT: 376>, 'RLIKE': <TokenType.RLIKE: 377>, 'ROLLBACK': <TokenType.ROLLBACK: 379>, 'ROLLUP': <TokenType.ROLLUP: 380>, 'ROW': <TokenType.ROW: 381>, 'ROWS': <TokenType.ROWS: 382>, 'SCHEMA': <TokenType.SCHEMA: 81>, 'SELECT': <TokenType.SELECT: 384>, 'SEMI': <TokenType.SEMI: 385>, 'SESSION': <TokenType.SESSION: 57>, 'SESSION_USER': <TokenType.SESSION_USER: 59>, 'SET': <TokenType.SET: 389>, 'SETTINGS': <TokenType.SETTINGS: 390>, 'SHOW': <TokenType.SHOW: 391>, 'SIMILAR TO': <TokenType.SIMILAR_TO: 392>, 'SOME': <TokenType.SOME: 393>, 'SORT BY': <TokenType.SORT_BY: 394>, 'SQL SECURITY': <TokenType.SQL_SECURITY: 396>, 'START WITH': <TokenType.START_WITH: 397>, 'STRAIGHT_JOIN': <TokenType.STRAIGHT_JOIN: 399>, 'TABLE': <TokenType.TABLE: 82>, 'TABLESAMPLE': <TokenType.TABLE_SAMPLE: 402>, 'TEMP': <TokenType.TEMPORARY: 404>, 'TEMPORARY': <TokenType.TEMPORARY: 404>, 'THEN': <TokenType.THEN: 406>, 'TRUE': <TokenType.TRUE: 407>, 'TRUNCATE': <TokenType.TRUNCATE: 408>, 'TRIGGER': <TokenType.TRIGGER: 409>, 'UNION': <TokenType.UNION: 412>, 'UNKNOWN': <TokenType.UNKNOWN: 212>, 'UNNEST': <TokenType.UNNEST: 413>, 'UNPIVOT': <TokenType.UNPIVOT: 414>, 'UPDATE': <TokenType.UPDATE: 415>, 'USE': <TokenType.USE: 416>, 'USING': <TokenType.USING: 417>, 'UUID': <TokenType.UUID: 169>, 'VIEW': <TokenType.VIEW: 420>, 'VOLATILE': <TokenType.VOLATILE: 422>, 'WHEN': <TokenType.WHEN: 424>, 'WHERE': <TokenType.WHERE: 425>, 'WINDOW': <TokenType.WINDOW: 426>, 'WITH': <TokenType.WITH: 427>, 'APPLY': <TokenType.APPLY: 221>, 'ARRAY': <TokenType.ARRAY: 222>, 'BIT': <TokenType.BIT: 95>, 'BOOL': <TokenType.BOOLEAN: 96>, 'BOOLEAN': <TokenType.BOOLEAN: 96>, 'BYTE': <TokenType.TINYINT: 97>, 'MEDIUMINT': <TokenType.MEDIUMINT: 101>, 'INT1': <TokenType.TINYINT: 97>, 'TINYINT': <TokenType.TINYINT: 97>, 'INT16': <TokenType.SMALLINT: 99>, 'SHORT': <TokenType.SMALLINT: 99>, 'SMALLINT': <TokenType.SMALLINT: 99>, 'HUGEINT': <TokenType.INT128: 108>, 'UHUGEINT': <TokenType.UINT128: 109>, 'INT2': <TokenType.SMALLINT: 99>, 'INTEGER': <TokenType.INT: 103>, 'INT': <TokenType.INT: 103>, 'INT4': <TokenType.INT: 103>, 'INT32': <TokenType.INT: 103>, 'INT64': <TokenType.BIGINT: 105>, 'INT128': <TokenType.INT128: 108>, 'INT256': <TokenType.INT256: 110>, 'LONG': <TokenType.BIGINT: 105>, 'BIGINT': <TokenType.BIGINT: 105>, 'INT8': <TokenType.TINYINT: 97>, 'UINT': <TokenType.UINT: 104>, 'UINT128': <TokenType.UINT128: 109>, 'UINT256': <TokenType.UINT256: 111>, 'DEC': <TokenType.DECIMAL: 115>, 'DECIMAL': <TokenType.DECIMAL: 115>, 'DECIMAL32': <TokenType.DECIMAL32: 116>, 'DECIMAL64': <TokenType.DECIMAL64: 117>, 'DECIMAL128': <TokenType.DECIMAL128: 118>, 'DECIMAL256': <TokenType.DECIMAL256: 119>, 'DECFLOAT': <TokenType.DECFLOAT: 120>, 'BIGDECIMAL': <TokenType.BIGDECIMAL: 122>, 'BIGNUMERIC': <TokenType.BIGDECIMAL: 122>, 'BIGNUM': <TokenType.BIGNUM: 107>, 'LIST': <TokenType.LIST: 318>, 'MAP': <TokenType.MAP: 321>, 'NULLABLE': <TokenType.NULLABLE: 172>, 'NUMBER': <TokenType.DECIMAL: 115>, 'NUMERIC': <TokenType.DECIMAL: 115>, 'FIXED': <TokenType.DECIMAL: 115>, 'REAL': <TokenType.FLOAT: 112>, 'FLOAT': <TokenType.FLOAT: 112>, 'FLOAT4': <TokenType.FLOAT: 112>, 'FLOAT8': <TokenType.DOUBLE: 113>, 'DOUBLE': <TokenType.DOUBLE: 113>, 'DOUBLE PRECISION': <TokenType.DOUBLE: 113>, 'JSON': <TokenType.JSON: 139>, 'JSONB': <TokenType.JSONB: 140>, 'CHAR': <TokenType.CHAR: 123>, 'CHARACTER': <TokenType.CHAR: 123>, 'CHAR VARYING': <TokenType.VARCHAR: 125>, 'CHARACTER VARYING': <TokenType.VARCHAR: 125>, 'NCHAR': <TokenType.NCHAR: 124>, 'VARCHAR': <TokenType.VARCHAR: 125>, 'VARCHAR2': <TokenType.VARCHAR: 125>, 'NVARCHAR': <TokenType.NVARCHAR: 126>, 'NVARCHAR2': <TokenType.NVARCHAR: 126>, 'BPCHAR': <TokenType.BPCHAR: 127>, 'STR': <TokenType.TEXT: 128>, 'STRING': <TokenType.TEXT: 128>, 'TEXT': <TokenType.TEXT: 128>, 'LONGTEXT': <TokenType.LONGTEXT: 130>, 'MEDIUMTEXT': <TokenType.MEDIUMTEXT: 129>, 'TINYTEXT': <TokenType.TINYTEXT: 135>, 'CLOB': <TokenType.TEXT: 128>, 'LONGVARCHAR': <TokenType.TEXT: 128>, 'BINARY': <TokenType.BINARY: 137>, 'BLOB': <TokenType.VARBINARY: 138>, 'LONGBLOB': <TokenType.LONGBLOB: 133>, 'MEDIUMBLOB': <TokenType.MEDIUMBLOB: 132>, 'TINYBLOB': <TokenType.TINYBLOB: 134>, 'BYTEA': <TokenType.VARBINARY: 138>, 'VARBINARY': <TokenType.VARBINARY: 138>, 'TIME': <TokenType.TIME: 141>, 'TIMETZ': <TokenType.TIMETZ: 142>, 'TIME_NS': <TokenType.TIME_NS: 143>, 'TIMESTAMP': <TokenType.TIMESTAMPTZ: 145>, 'TIMESTAMPTZ': <TokenType.TIMESTAMPTZ: 145>, 'TIMESTAMPLTZ': <TokenType.TIMESTAMPLTZ: 146>, 'TIMESTAMP_LTZ': <TokenType.TIMESTAMPLTZ: 146>, 'TIMESTAMPNTZ': <TokenType.TIMESTAMPNTZ: 147>, 'TIMESTAMP_NTZ': <TokenType.TIMESTAMPNTZ: 147>, 'DATE': <TokenType.DATE: 155>, 'DATETIME': <TokenType.TIMESTAMP: 144>, 'INT4RANGE': <TokenType.INT4RANGE: 157>, 'INT4MULTIRANGE': <TokenType.INT4MULTIRANGE: 158>, 'INT8RANGE': <TokenType.INT8RANGE: 159>, 'INT8MULTIRANGE': <TokenType.INT8MULTIRANGE: 160>, 'NUMRANGE': <TokenType.NUMRANGE: 161>, 'NUMMULTIRANGE': <TokenType.NUMMULTIRANGE: 162>, 'TSRANGE': <TokenType.TSRANGE: 163>, 'TSMULTIRANGE': <TokenType.TSMULTIRANGE: 164>, 'TSTZRANGE': <TokenType.TSTZRANGE: 165>, 'TSTZMULTIRANGE': <TokenType.TSTZMULTIRANGE: 166>, 'DATERANGE': <TokenType.DATERANGE: 167>, 'DATEMULTIRANGE': <TokenType.DATEMULTIRANGE: 168>, 'UNIQUE': <TokenType.UNIQUE: 428>, 'VECTOR': <TokenType.VECTOR: 213>, 'STRUCT': <TokenType.STRUCT: 400>, 'SEQUENCE': <TokenType.SEQUENCE: 387>, 'VARIANT': <TokenType.VARIANT: 196>, 'ALTER': <TokenType.ALTER: 217>, 'ANALYZE': <TokenType.ANALYZE: 437>, 'CALL': <TokenType.COMMAND: 235>, 'COMMENT': <TokenType.COMMENT: 236>, 'EXPLAIN': <TokenType.COMMAND: 235>, 'GRANT': <TokenType.GRANT: 287>, 'REVOKE': <TokenType.REVOKE: 374>, 'OPTIMIZE': <TokenType.COMMAND: 235>, 'PREPARE': <TokenType.COMMAND: 235>, 'VACUUM': <TokenType.COMMAND: 235>, 'USER-DEFINED': <TokenType.USERDEFINED: 191>, 'FOR VERSION': <TokenType.VERSION_SNAPSHOT: 432>, 'FOR TIMESTAMP': <TokenType.TIMESTAMP_SNAPSHOT: 433>, 'ANY TYPE': <TokenType.VARIANT: 196>, 'BEGIN TRANSACTION': <TokenType.BEGIN: 227>, 'BYTEINT': <TokenType.INT: 103>, 'BYTES': <TokenType.BINARY: 137>, 'CURRENT_DATETIME': <TokenType.CURRENT_DATETIME: 245>, 'DECLARE': <TokenType.DECLARE: 253>, 'ELSEIF': <TokenType.COMMAND: 235>, 'EXCEPTION': <TokenType.COMMAND: 235>, 'EXPORT': <TokenType.EXPORT: 439>, 'FLOAT64': <TokenType.DOUBLE: 113>, 'FOR SYSTEM TIME': <TokenType.TIMESTAMP_SNAPSHOT: 433>, 'FOR SYSTEM_TIME': <TokenType.TIMESTAMP_SNAPSHOT: 433>, 'LOOP': <TokenType.COMMAND: 235>, 'MODEL': <TokenType.MODEL: 328>, 'NOT DETERMINISTIC': <TokenType.VOLATILE: 422>, 'RECORD': <TokenType.STRUCT: 400>, 'REPEAT': <TokenType.COMMAND: 235>, 'WHILE': <TokenType.COMMAND: 235>}
BYTE_STRING_ESCAPES: ClassVar[list[str]] = ['\\']