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        "DD": "%d",
 77        "mm": "%m",
 78        "MM": "%m",
 79        "mon": "%b",
 80        "MON": "%b",
 81        "month": "%B",
 82        "MONTH": "%B",
 83        "yyyy": "%Y",
 84        "YYYY": "%Y",
 85        "yy": "%y",
 86        "YY": "%y",
 87        "HH": "%I",
 88        "HH12": "%I",
 89        "hh24": "%H",
 90        "HH24": "%H",
 91        "mi": "%M",
 92        "MI": "%M",
 93        "ss": "%S",
 94        "SS": "%S",
 95        "SSSSS": "%f",
 96        "tzh": "%z",
 97        "TZH": "%z",
 98    }
 99
100    # The _PARTITIONTIME and _PARTITIONDATE pseudo-columns are not returned by a SELECT * statement
101    # https://cloud.google.com/bigquery/docs/querying-partitioned-tables#query_an_ingestion-time_partitioned_table
102    # https://cloud.google.com/bigquery/docs/querying-wildcard-tables#scanning_a_range_of_tables_using_table_suffix
103    # https://cloud.google.com/bigquery/docs/query-cloud-storage-data#query_the_file_name_pseudo-column
104    PSEUDOCOLUMNS = {
105        "_PARTITIONTIME",
106        "_PARTITIONDATE",
107        "_TABLE_SUFFIX",
108        "_FILE_NAME",
109        "_DBT_MAX_PARTITION",
110    }
111
112    # All set operations require either a DISTINCT or ALL specifier
113    SET_OP_DISTINCT_BY_DEFAULT = dict.fromkeys((exp.Except, exp.Intersect, exp.Union), None)
114
115    # https://cloud.google.com/bigquery/docs/reference/standard-sql/navigation_functions#percentile_cont
116    COERCES_TO = {
117        **TypeAnnotator.COERCES_TO,
118        exp.DType.BIGDECIMAL: {exp.DType.DOUBLE},
119    }
120    COERCES_TO[exp.DType.DECIMAL] |= {exp.DType.BIGDECIMAL}
121    COERCES_TO[exp.DType.BIGINT] |= {exp.DType.BIGDECIMAL}
122    COERCES_TO[exp.DType.VARCHAR] |= {
123        exp.DType.DATE,
124        exp.DType.DATETIME,
125        exp.DType.TIME,
126        exp.DType.TIMESTAMP,
127        exp.DType.TIMESTAMPTZ,
128    }
129
130    EXPRESSION_METADATA = EXPRESSION_METADATA.copy()
131
132    def normalize_identifier(self, expression: E) -> E:
133        if (
134            isinstance(expression, exp.Identifier)
135            and self.normalization_strategy is NormalizationStrategy.CASE_INSENSITIVE
136        ):
137            parent = expression.parent
138            while isinstance(parent, exp.Dot):
139                parent = parent.parent
140
141            # In BigQuery, CTEs are case-insensitive, but UDF and table names are case-sensitive
142            # by default. The following check uses a heuristic to detect tables based on whether
143            # they are qualified. This should generally be correct, because tables in BigQuery
144            # must be qualified with at least a dataset, unless @@dataset_id is set.
145            case_sensitive = (
146                isinstance(parent, exp.UserDefinedFunction)
147                or (
148                    isinstance(parent, exp.Table)
149                    and parent.db
150                    and (parent.meta_get("quoted_table") or not parent.meta_get("maybe_column"))
151                )
152                or expression.meta_get("is_table")
153            )
154            if not case_sensitive:
155                expression.set("this", expression.this.lower())
156
157            return t.cast(E, expression)
158
159        return super().normalize_identifier(expression)
160
161    class JSONPathTokenizer(jsonpath.JSONPathTokenizer):
162        VAR_TOKENS = {
163            *jsonpath.JSONPathTokenizer.VAR_TOKENS,
164            TokenType.DASH,
165            TokenType.NUMBER,
166        }
167
168    class Tokenizer(tokens.Tokenizer):
169        QUOTES = ["'", '"', '"""', "'''"]
170        COMMENTS = ["--", "#", ("/*", "*/")]
171        IDENTIFIERS = ["`"]
172        STRING_ESCAPES = ["\\"]
173
174        HEX_STRINGS = [("0x", ""), ("0X", "")]
175
176        BYTE_STRINGS = [(prefix + q, q) for q in t.cast(list[str], QUOTES) for prefix in ("b", "B")]
177
178        RAW_STRINGS = [(prefix + q, q) for q in t.cast(list[str], QUOTES) for prefix in ("r", "R")]
179
180        NESTED_COMMENTS = False
181
182        KEYWORDS = {
183            **tokens.Tokenizer.KEYWORDS,
184            "ANY TYPE": TokenType.VARIANT,
185            "BEGIN": TokenType.COMMAND,
186            "BEGIN TRANSACTION": TokenType.BEGIN,
187            "BYTEINT": TokenType.INT,
188            "BYTES": TokenType.BINARY,
189            "CURRENT_DATETIME": TokenType.CURRENT_DATETIME,
190            "DATETIME": TokenType.TIMESTAMP,
191            "DECLARE": TokenType.DECLARE,
192            "ELSEIF": TokenType.COMMAND,
193            "EXCEPTION": TokenType.COMMAND,
194            "EXPORT": TokenType.EXPORT,
195            "FLOAT64": TokenType.DOUBLE,
196            "FOR SYSTEM TIME": TokenType.TIMESTAMP_SNAPSHOT,
197            "FOR SYSTEM_TIME": TokenType.TIMESTAMP_SNAPSHOT,
198            "LOOP": TokenType.COMMAND,
199            "MODEL": TokenType.MODEL,
200            "NOT DETERMINISTIC": TokenType.VOLATILE,
201            "RECORD": TokenType.STRUCT,
202            "REPEAT": TokenType.COMMAND,
203            "TIMESTAMP": TokenType.TIMESTAMPTZ,
204            "WHILE": TokenType.COMMAND,
205        }
206        KEYWORDS.pop("DIV")
207        KEYWORDS.pop("VALUES")
208        KEYWORDS.pop("/*+")
209
210    Parser = BigQueryParser
211
212    Generator = BigQueryGenerator
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        "DD": "%d",
 78        "mm": "%m",
 79        "MM": "%m",
 80        "mon": "%b",
 81        "MON": "%b",
 82        "month": "%B",
 83        "MONTH": "%B",
 84        "yyyy": "%Y",
 85        "YYYY": "%Y",
 86        "yy": "%y",
 87        "YY": "%y",
 88        "HH": "%I",
 89        "HH12": "%I",
 90        "hh24": "%H",
 91        "HH24": "%H",
 92        "mi": "%M",
 93        "MI": "%M",
 94        "ss": "%S",
 95        "SS": "%S",
 96        "SSSSS": "%f",
 97        "tzh": "%z",
 98        "TZH": "%z",
 99    }
100
101    # The _PARTITIONTIME and _PARTITIONDATE pseudo-columns are not returned by a SELECT * statement
102    # https://cloud.google.com/bigquery/docs/querying-partitioned-tables#query_an_ingestion-time_partitioned_table
103    # https://cloud.google.com/bigquery/docs/querying-wildcard-tables#scanning_a_range_of_tables_using_table_suffix
104    # https://cloud.google.com/bigquery/docs/query-cloud-storage-data#query_the_file_name_pseudo-column
105    PSEUDOCOLUMNS = {
106        "_PARTITIONTIME",
107        "_PARTITIONDATE",
108        "_TABLE_SUFFIX",
109        "_FILE_NAME",
110        "_DBT_MAX_PARTITION",
111    }
112
113    # All set operations require either a DISTINCT or ALL specifier
114    SET_OP_DISTINCT_BY_DEFAULT = dict.fromkeys((exp.Except, exp.Intersect, exp.Union), None)
115
116    # https://cloud.google.com/bigquery/docs/reference/standard-sql/navigation_functions#percentile_cont
117    COERCES_TO = {
118        **TypeAnnotator.COERCES_TO,
119        exp.DType.BIGDECIMAL: {exp.DType.DOUBLE},
120    }
121    COERCES_TO[exp.DType.DECIMAL] |= {exp.DType.BIGDECIMAL}
122    COERCES_TO[exp.DType.BIGINT] |= {exp.DType.BIGDECIMAL}
123    COERCES_TO[exp.DType.VARCHAR] |= {
124        exp.DType.DATE,
125        exp.DType.DATETIME,
126        exp.DType.TIME,
127        exp.DType.TIMESTAMP,
128        exp.DType.TIMESTAMPTZ,
129    }
130
131    EXPRESSION_METADATA = EXPRESSION_METADATA.copy()
132
133    def normalize_identifier(self, expression: E) -> E:
134        if (
135            isinstance(expression, exp.Identifier)
136            and self.normalization_strategy is NormalizationStrategy.CASE_INSENSITIVE
137        ):
138            parent = expression.parent
139            while isinstance(parent, exp.Dot):
140                parent = parent.parent
141
142            # In BigQuery, CTEs are case-insensitive, but UDF and table names are case-sensitive
143            # by default. The following check uses a heuristic to detect tables based on whether
144            # they are qualified. This should generally be correct, because tables in BigQuery
145            # must be qualified with at least a dataset, unless @@dataset_id is set.
146            case_sensitive = (
147                isinstance(parent, exp.UserDefinedFunction)
148                or (
149                    isinstance(parent, exp.Table)
150                    and parent.db
151                    and (parent.meta_get("quoted_table") or not parent.meta_get("maybe_column"))
152                )
153                or expression.meta_get("is_table")
154            )
155            if not case_sensitive:
156                expression.set("this", expression.this.lower())
157
158            return t.cast(E, expression)
159
160        return super().normalize_identifier(expression)
161
162    class JSONPathTokenizer(jsonpath.JSONPathTokenizer):
163        VAR_TOKENS = {
164            *jsonpath.JSONPathTokenizer.VAR_TOKENS,
165            TokenType.DASH,
166            TokenType.NUMBER,
167        }
168
169    class Tokenizer(tokens.Tokenizer):
170        QUOTES = ["'", '"', '"""', "'''"]
171        COMMENTS = ["--", "#", ("/*", "*/")]
172        IDENTIFIERS = ["`"]
173        STRING_ESCAPES = ["\\"]
174
175        HEX_STRINGS = [("0x", ""), ("0X", "")]
176
177        BYTE_STRINGS = [(prefix + q, q) for q in t.cast(list[str], QUOTES) for prefix in ("b", "B")]
178
179        RAW_STRINGS = [(prefix + q, q) for q in t.cast(list[str], QUOTES) for prefix in ("r", "R")]
180
181        NESTED_COMMENTS = False
182
183        KEYWORDS = {
184            **tokens.Tokenizer.KEYWORDS,
185            "ANY TYPE": TokenType.VARIANT,
186            "BEGIN": TokenType.COMMAND,
187            "BEGIN TRANSACTION": TokenType.BEGIN,
188            "BYTEINT": TokenType.INT,
189            "BYTES": TokenType.BINARY,
190            "CURRENT_DATETIME": TokenType.CURRENT_DATETIME,
191            "DATETIME": TokenType.TIMESTAMP,
192            "DECLARE": TokenType.DECLARE,
193            "ELSEIF": TokenType.COMMAND,
194            "EXCEPTION": TokenType.COMMAND,
195            "EXPORT": TokenType.EXPORT,
196            "FLOAT64": TokenType.DOUBLE,
197            "FOR SYSTEM TIME": TokenType.TIMESTAMP_SNAPSHOT,
198            "FOR SYSTEM_TIME": TokenType.TIMESTAMP_SNAPSHOT,
199            "LOOP": TokenType.COMMAND,
200            "MODEL": TokenType.MODEL,
201            "NOT DETERMINISTIC": TokenType.VOLATILE,
202            "RECORD": TokenType.STRUCT,
203            "REPEAT": TokenType.COMMAND,
204            "TIMESTAMP": TokenType.TIMESTAMPTZ,
205            "WHILE": TokenType.COMMAND,
206        }
207        KEYWORDS.pop("DIV")
208        KEYWORDS.pop("VALUES")
209        KEYWORDS.pop("/*+")
210
211    Parser = BigQueryParser
212
213    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', '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] = {'_FILE_NAME', '_PARTITIONTIME', '_TABLE_SUFFIX', '_PARTITIONDATE', '_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.TEXT: 'TEXT'>, <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <DType.TIME: 'TIME'>, <DType.DATETIME: 'DATETIME'>, <DType.NVARCHAR: 'NVARCHAR'>, <DType.DATE: 'DATE'>, <DType.TIMESTAMP: 'TIMESTAMP'>}, <DType.NCHAR: 'NCHAR'>: {<DType.TEXT: 'TEXT'>, <DType.NVARCHAR: 'NVARCHAR'>, <DType.VARCHAR: 'VARCHAR'>}, <DType.CHAR: 'CHAR'>: {<DType.TEXT: 'TEXT'>, <DType.NVARCHAR: 'NVARCHAR'>, <DType.VARCHAR: 'VARCHAR'>, <DType.NCHAR: 'NCHAR'>}, <DType.DECFLOAT: 'DECFLOAT'>: set(), <DType.DOUBLE: 'DOUBLE'>: {<DType.DECFLOAT: 'DECFLOAT'>}, <DType.FLOAT: 'FLOAT'>: {<DType.DECFLOAT: 'DECFLOAT'>, <DType.DOUBLE: 'DOUBLE'>}, <DType.BIGDECIMAL: 'BIGDECIMAL'>: {<DType.DOUBLE: 'DOUBLE'>}, <DType.DECIMAL: 'DECIMAL'>: {<DType.DECFLOAT: 'DECFLOAT'>, <DType.BIGDECIMAL: 'BIGDECIMAL'>, <DType.DOUBLE: 'DOUBLE'>, <DType.FLOAT: 'FLOAT'>}, <DType.BIGINT: 'BIGINT'>: {<DType.DECIMAL: 'DECIMAL'>, <DType.DECFLOAT: 'DECFLOAT'>, <DType.BIGDECIMAL: 'BIGDECIMAL'>, <DType.DOUBLE: 'DOUBLE'>, <DType.FLOAT: 'FLOAT'>}, <DType.INT: 'INT'>: {<DType.DECIMAL: 'DECIMAL'>, <DType.BIGINT: 'BIGINT'>, <DType.DECFLOAT: 'DECFLOAT'>, <DType.BIGDECIMAL: 'BIGDECIMAL'>, <DType.DOUBLE: 'DOUBLE'>, <DType.FLOAT: 'FLOAT'>}, <DType.SMALLINT: 'SMALLINT'>: {<DType.DECIMAL: 'DECIMAL'>, <DType.BIGINT: 'BIGINT'>, <DType.INT: 'INT'>, <DType.DECFLOAT: 'DECFLOAT'>, <DType.BIGDECIMAL: 'BIGDECIMAL'>, <DType.DOUBLE: 'DOUBLE'>, <DType.FLOAT: 'FLOAT'>}, <DType.TINYINT: 'TINYINT'>: {<DType.BIGDECIMAL: 'BIGDECIMAL'>, <DType.DECIMAL: 'DECIMAL'>, <DType.BIGINT: 'BIGINT'>, <DType.INT: 'INT'>, <DType.DECFLOAT: 'DECFLOAT'>, <DType.DOUBLE: 'DOUBLE'>, <DType.SMALLINT: 'SMALLINT'>, <DType.FLOAT: 'FLOAT'>}, <DType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>: set(), <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>: {<DType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>}, <DType.TIMESTAMP: 'TIMESTAMP'>: {<DType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <DType.DATETIME: 'DATETIME'>: {<DType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <DType.TIMESTAMP: 'TIMESTAMP'>, <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <DType.DATE: 'DATE'>: {<DType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <DType.TIMESTAMP: 'TIMESTAMP'>, <DType.DATETIME: 'DATETIME'>, <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>}}
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.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.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.aggregate.Ntile'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.aggregate.CountIf'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.aggregate.Rank'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.functions.Int64'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.array.ArraySize'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.temporal.UnixSeconds'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.aggregate.RowNumber'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.aggregate.DenseRank'>: {'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.core.ApproxDistinct'>: {'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.string.EndsWith'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.aggregate.LogicalAnd'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.core.Boolean'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.core.Between'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.string.Contains'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.core.Any'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.math.IsInf'>: {'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.functions.Exists'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.string.StartsWith'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.core.In'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.aggregate.LogicalOr'>: {'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.DateStrToDate'>: {'returns': <DType.DATE: 'DATE'>}, <class 'sqlglot.expressions.temporal.LastDay'>: {'returns': <DType.DATE: 'DATE'>}, <class 'sqlglot.expressions.temporal.StrToDate'>: {'returns': <DType.DATE: 'DATE'>}, <class 'sqlglot.expressions.temporal.DateFromParts'>: {'returns': <DType.DATE: 'DATE'>}, <class 'sqlglot.expressions.temporal.Date'>: {'returns': <DType.DATE: 'DATE'>}, <class 'sqlglot.expressions.temporal.DiToDate'>: {'returns': <DType.DATE: 'DATE'>}, <class 'sqlglot.expressions.temporal.CurrentDate'>: {'returns': <DType.DATE: 'DATE'>}, <class 'sqlglot.expressions.temporal.CurrentDatetime'>: {'returns': <DType.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.temporal.DatetimeSub'>: {'returns': <DType.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.temporal.DatetimeAdd'>: {'returns': <DType.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.temporal.Datetime'>: {'returns': <DType.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.math.Acos'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Pi'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Cot'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Ln'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.math.Cos'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Tan'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.Variance'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Sin'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.StddevSamp'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.ApproxQuantile'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Tanh'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.Kurtosis'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.Stddev'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Atanh'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Degrees'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.PercentRank'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.functions.Rand'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Asinh'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.PercentileCont'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.CumeDist'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Sqrt'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.math.Acosh'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.CovarPop'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.string.ToDouble'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Round'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.math.Exp'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.math.Log'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.math.Cbrt'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.Avg'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.math.Cosh'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Sinh'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.VariancePop'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.StddevPop'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.aggregate.Quantile'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Radians'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.SafeDivide'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.aggregate.Skewness'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Atan'>: {'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.temporal.TsOrDiToDi'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.TimeDiff'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.math.Ceil'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.temporal.TimestampDiff'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.math.Getbit'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.DatetimeDiff'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.DayOfMonth'>: {'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.BitLength'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.Quarter'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.string.StrPosition'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.string.Unicode'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.Hour'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.string.Ascii'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.UnixDate'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.temporal.DayOfYear'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.temporal.DayOfWeek'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.string.Levenshtein'>: {'returns': <DType.INT: 'INT'>}, <class 'sqlglot.expressions.math.Sign'>: {'annotator': <function <dictcomp>.<lambda>>}, <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.datatypes.Interval'>: {'returns': <DType.INTERVAL: 'INTERVAL'>}, <class 'sqlglot.expressions.temporal.JustifyDays'>: {'returns': <DType.INTERVAL: 'INTERVAL'>}, <class 'sqlglot.expressions.json.ParseJSON'>: {'returns': <DType.JSON: 'JSON'>}, <class 'sqlglot.expressions.temporal.TimeSub'>: {'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.Time'>: {'returns': <DType.TIME: 'TIME'>}, <class 'sqlglot.expressions.temporal.Localtime'>: {'returns': <DType.TIME: 'TIME'>}, <class 'sqlglot.expressions.temporal.TimestampLtzFromParts'>: {'returns': <DType.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>}, <class 'sqlglot.expressions.temporal.TimestampTzFromParts'>: {'returns': <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.temporal.CurrentTimestampLTZ'>: {'returns': <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.temporal.TimestampSub'>: {'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.TimestampAdd'>: {'returns': <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.temporal.CurrentTimestamp'>: {'returns': <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.temporal.TimeStrToTime'>: {'returns': <DType.TIMESTAMPTZ: 'TIMESTAMPTZ'>}, <class 'sqlglot.expressions.temporal.Week'>: {'returns': <DType.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.temporal.Year'>: {'returns': <DType.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.temporal.DayOfWeekIso'>: {'returns': <DType.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.temporal.YearOfWeekIso'>: {'returns': <DType.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.temporal.YearOfWeek'>: {'returns': <DType.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.temporal.Month'>: {'returns': <DType.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.temporal.Day'>: {'returns': <DType.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.temporal.WeekOfYear'>: {'returns': <DType.TINYINT: 'TINYINT'>}, <class 'sqlglot.expressions.temporal.DateToDateStr'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.functions.CurrentSchema'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.MD5'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.temporal.TimeToTimeStr'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.temporal.Monthname'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.ToBase64'>: {'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.array.ArrayToString'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.aggregate.GroupConcat'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.temporal.Dayname'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Concat'>: {'annotator': <function _annotate_concat>}, <class 'sqlglot.expressions.string.Lower'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.Chr'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.temporal.UnixToStr'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.String'>: {'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.Space'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Initcap'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Translate'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.functions.SessionUser'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.temporal.UnixToTimeStr'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.ConcatWs'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.functions.CurrentVersion'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Substring'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.functions.CurrentCatalog'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.temporal.TsOrDsToDateStr'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.query.RawString'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.functions.CurrentUser'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.SHA2'>: {'returns': <DType.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.string.SHA'>: {'returns': <DType.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.array.ArraySlice'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.array.ArrayReverse'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.AnyValue'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.query.Limit'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.Filter'>: {'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.HavingMax'>: {'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.query.Order'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.array.SortArray'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.ArrayConcatAgg'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.NthValue'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.functions.Greatest'>: {'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.aggregate.Max'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.array.ArrayConcat'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.functions.Least'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.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.DateTrunc'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.temporal.DateAdd'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.temporal.DateSub'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.functions.TryCast'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.functions.Cast'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.array.Map'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.array.VarMap'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.array.Array'>: {'annotator': <function _annotate_array>}, <class 'sqlglot.expressions.aggregate.ArrayAgg'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.core.Bracket'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.functions.Case'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.aggregate.Count'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.temporal.DateDiff'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.datatypes.DataType'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.core.Distinct'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.array.Explode'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.temporal.Extract'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.query.HexString'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.array.GenerateSeries'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.temporal.GenerateDateArray'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.temporal.GenerateTimestampArray'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.functions.If'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.aggregate.Lag'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.aggregate.Lead'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.core.Literal'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.core.Null'>: {'returns': <DType.NULL: 'NULL'>}, <class 'sqlglot.expressions.functions.Nullif'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.array.Struct'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.aggregate.Sum'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.temporal.Timestamp'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.array.ToMap'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.array.Unnest'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.core.WithinGroup'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.query.Subquery'>: {'annotator': <function <lambda>>}, <class 'sqlglot.expressions.math.Floor'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.Left'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.Reverse'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.functions.NetFunc'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.RegexpReplace'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.Repeat'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.ArgMin'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.core.SafeFunc'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.Replace'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.temporal.TimestampTrunc'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.Right'>: {'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.aggregate.ArgMax'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.aggregate.PercentileDisc'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.temporal.DatetimeTrunc'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.RegexpExtract'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.string.ByteLength'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.functions.RangeBucket'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.aggregate.Grouping'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.functions.LaxInt64'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.string.FarmFingerprint'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.math.BitwiseXorAgg'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.math.BitwiseOrAgg'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.math.BitwiseCount'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.math.BitwiseAndAgg'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.string.RegexpInstr'>: {'returns': <DType.BIGINT: 'BIGINT'>}, <class 'sqlglot.expressions.string.CodePointsToBytes'>: {'returns': <DType.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.string.MD5Digest'>: {'returns': <DType.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.string.SHA2Digest'>: {'returns': <DType.BINARY: 'BINARY'>}, <class 'sqlglot.expressions.query.ByteString'>: {'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.functions.LaxBool'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.json.JSONBool'>: {'returns': <DType.BOOLEAN: 'BOOLEAN'>}, <class 'sqlglot.expressions.temporal.ParseDatetime'>: {'returns': <DType.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.temporal.TimestampFromParts'>: {'returns': <DType.DATETIME: 'DATETIME'>}, <class 'sqlglot.expressions.math.Sech'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.CosineDistance'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Sec'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Atan2'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.Coth'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.functions.Float64'>: {'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.Csc'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.math.EuclideanDistance'>: {'returns': <DType.DOUBLE: 'DOUBLE'>}, <class 'sqlglot.expressions.json.JSONArray'>: {'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.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.TimeTrunc'>: {'returns': <DType.TIME: 'TIME'>}, <class 'sqlglot.expressions.temporal.TimeFromParts'>: {'returns': <DType.TIME: 'TIME'>}, <class 'sqlglot.expressions.temporal.ParseTime'>: {'returns': <DType.TIME: 'TIME'>}, <class 'sqlglot.expressions.temporal.TsOrDsToTime'>: {'returns': <DType.TIME: 'TIME'>}, <class 'sqlglot.expressions.string.LowerHex'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.SafeConvertBytesToString'>: {'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.functions.Host'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.functions.LaxString'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.json.JSONType'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.functions.Uuid'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Normalize'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.string.Format'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.functions.RegDomain'>: {'returns': <DType.VARCHAR: 'VARCHAR'>}, <class 'sqlglot.expressions.math.SafeSubtract'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.math.SafeMultiply'>: {'annotator': <function <dictcomp>.<lambda>>}, <class 'sqlglot.expressions.math.SafeAdd'>: {'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:
133    def normalize_identifier(self, expression: E) -> E:
134        if (
135            isinstance(expression, exp.Identifier)
136            and self.normalization_strategy is NormalizationStrategy.CASE_INSENSITIVE
137        ):
138            parent = expression.parent
139            while isinstance(parent, exp.Dot):
140                parent = parent.parent
141
142            # In BigQuery, CTEs are case-insensitive, but UDF and table names are case-sensitive
143            # by default. The following check uses a heuristic to detect tables based on whether
144            # they are qualified. This should generally be correct, because tables in BigQuery
145            # must be qualified with at least a dataset, unless @@dataset_id is set.
146            case_sensitive = (
147                isinstance(parent, exp.UserDefinedFunction)
148                or (
149                    isinstance(parent, exp.Table)
150                    and parent.db
151                    and (parent.meta_get("quoted_table") or not parent.meta_get("maybe_column"))
152                )
153                or expression.meta_get("is_table")
154            )
155            if not case_sensitive:
156                expression.set("this", expression.this.lower())
157
158            return t.cast(E, expression)
159
160        return super().normalize_identifier(expression)

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

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

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

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

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

SUPPORTS_COLUMN_JOIN_MARKS = False

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

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

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

STRINGS_SUPPORT_ESCAPED_SEQUENCES: bool = True

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

BYTE_STRINGS_SUPPORT_ESCAPED_SEQUENCES: bool = True

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

tokenizer_class = <class 'BigQuery.Tokenizer'>
jsonpath_tokenizer_class = <class 'BigQuery.JSONPathTokenizer'>
parser_class = <class 'sqlglot.parsers.bigquery.BigQueryParser'>
generator_class = <class 'sqlglot.generators.bigquery.BigQueryGenerator'>
TIME_TRIE: dict = {'%': {'x': {0: True}, 'D': {0: True}, 'E': {'6': {'S': {0: True}}}, 'e': {0: True}, 'F': {0: True}, 'T': {0: True}, 'c': {0: True}}}
FORMAT_TRIE: dict = {'d': {'d': {0: True}}, 'D': {'D': {0: True}}, 'm': {'m': {0: True}, 'o': {'n': {0: True, 't': {'h': {0: True}}}}, 'i': {0: True}}, 'M': {'M': {0: True}, 'O': {'N': {0: True, 'T': {'H': {0: True}}}}, 'I': {0: True}}, 'y': {'y': {'y': {'y': {0: True}}, 0: True}}, 'Y': {'Y': {'Y': {'Y': {0: True}}, 0: True}}, 'H': {'H': {0: True, '1': {'2': {0: True}}, '2': {'4': {0: True}}}}, 'h': {'h': {'2': {'4': {0: True}}}}, 's': {'s': {0: True}}, 'S': {'S': {0: True, 'S': {'S': {'S': {0: True}}}}}, 't': {'z': {'h': {0: True}}}, 'T': {'Z': {'H': {0: True}}}}
INVERSE_TIME_TRIE: dict = {'%': {'m': {'/': {'%': {'d': {'/': {'%': {'y': {0: True}}}}}}}, 'S': {'.': {'%': {'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] = {'HOURS', 'DOW', 'Q', 'MILLISECS', 'S', 'MILLISECON', 'DOW_ISO', 'QUARTERS', 'MIN', 'EPOCH_MICROSECONDS', 'EPOCH_MILLISECOND', 'TZH', 'WEEKOFYEAR_ISO', 'MILLISECONDS', 'CENTURY', 'US', 'MICROSECONDS', 'YEARS', 'USECONDS', 'DW_ISO', 'CENTS', 'DOY', 'HRS', 'QTRS', 'DECADES', 'USECS', 'W', 'DAY', 'DAYOFWEEK', 'HH', 'QUARTER', 'QTR', 'WEEKDAY_ISO', 'NS', 'YYYY', 'MSECS', 'C', 'USEC', 'NANOSEC', 'HR', 'EPOCH_NANOSECOND', 'YYY', 'WOY', 'TZM', 'DAY OF WEEK', 'MICROSEC', 'TIMEZONE_HOUR', 'DY', 'MINUTES', 'EPOCH', 'DAYOFMONTH', 'MIL', 'MONTHS', 'MILLENNIUM', 'YRS', 'MILS', 'DECADE', 'MM', 'MINUTE', 'MSECONDS', 'NSECONDS', 'MINS', 'MONTH', 'MSEC', 'MILLISEC', 'WEEKDAY', 'DEC', 'DD', 'MICROSECS', 'SECOND', 'WEEKISO', 'CENT', 'M', 'YR', 'DECS', 'WEEK_ISO', 'NSECOND', 'MILLENIA', 'D', 'DW', 'EPOCH_NANOSECONDS', 'HOUR', 'DAY OF YEAR', 'H', 'CENTURIES', 'MILLISECOND', 'DAYOFWEEKISO', 'WEEKOFYEARISO', 'EPOCH_MILLISECONDS', 'MS', 'EPOCH_SECONDS', 'EPOCH_MICROSECOND', 'NANOSECS', 'DAYS', 'WEEKOFYEAR', 'WY', 'YEAR', 'MI', 'SECONDS', 'YY', 'NANOSECOND', 'NSEC', 'USECOND', 'MON', 'EPOCH_SECOND', 'SEC', 'MSECOND', 'Y', 'MICROSECOND', 'DAYOFYEAR', 'SECS', 'WEEK', 'DAYOFWEEK_ISO', 'TIMEZONE_MINUTE', 'WK', 'MONS'}
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):
162    class JSONPathTokenizer(jsonpath.JSONPathTokenizer):
163        VAR_TOKENS = {
164            *jsonpath.JSONPathTokenizer.VAR_TOKENS,
165            TokenType.DASH,
166            TokenType.NUMBER,
167        }
VAR_TOKENS = {<TokenType.VAR: 88>, <TokenType.DASH: 9>, <TokenType.NUMBER: 77>}
BYTE_STRING_ESCAPES: ClassVar[list[str]] = ['\\']
class BigQuery.Tokenizer(sqlglot.tokens.Tokenizer):
169    class Tokenizer(tokens.Tokenizer):
170        QUOTES = ["'", '"', '"""', "'''"]
171        COMMENTS = ["--", "#", ("/*", "*/")]
172        IDENTIFIERS = ["`"]
173        STRING_ESCAPES = ["\\"]
174
175        HEX_STRINGS = [("0x", ""), ("0X", "")]
176
177        BYTE_STRINGS = [(prefix + q, q) for q in t.cast(list[str], QUOTES) for prefix in ("b", "B")]
178
179        RAW_STRINGS = [(prefix + q, q) for q in t.cast(list[str], QUOTES) for prefix in ("r", "R")]
180
181        NESTED_COMMENTS = False
182
183        KEYWORDS = {
184            **tokens.Tokenizer.KEYWORDS,
185            "ANY TYPE": TokenType.VARIANT,
186            "BEGIN": TokenType.COMMAND,
187            "BEGIN TRANSACTION": TokenType.BEGIN,
188            "BYTEINT": TokenType.INT,
189            "BYTES": TokenType.BINARY,
190            "CURRENT_DATETIME": TokenType.CURRENT_DATETIME,
191            "DATETIME": TokenType.TIMESTAMP,
192            "DECLARE": TokenType.DECLARE,
193            "ELSEIF": TokenType.COMMAND,
194            "EXCEPTION": TokenType.COMMAND,
195            "EXPORT": TokenType.EXPORT,
196            "FLOAT64": TokenType.DOUBLE,
197            "FOR SYSTEM TIME": TokenType.TIMESTAMP_SNAPSHOT,
198            "FOR SYSTEM_TIME": TokenType.TIMESTAMP_SNAPSHOT,
199            "LOOP": TokenType.COMMAND,
200            "MODEL": TokenType.MODEL,
201            "NOT DETERMINISTIC": TokenType.VOLATILE,
202            "RECORD": TokenType.STRUCT,
203            "REPEAT": TokenType.COMMAND,
204            "TIMESTAMP": TokenType.TIMESTAMPTZ,
205            "WHILE": TokenType.COMMAND,
206        }
207        KEYWORDS.pop("DIV")
208        KEYWORDS.pop("VALUES")
209        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: 72>, '{%+': <TokenType.BLOCK_START: 72>, '{%-': <TokenType.BLOCK_START: 72>, '%}': <TokenType.BLOCK_END: 73>, '+%}': <TokenType.BLOCK_END: 73>, '-%}': <TokenType.BLOCK_END: 73>, '{{+': <TokenType.BLOCK_START: 72>, '{{-': <TokenType.BLOCK_START: 72>, '+}}': <TokenType.BLOCK_END: 73>, '-}}': <TokenType.BLOCK_END: 73>, '&<': <TokenType.AMP_LT: 62>, '&>': <TokenType.AMP_GT: 63>, '==': <TokenType.EQ: 28>, '::': <TokenType.DCOLON: 14>, '?::': <TokenType.QDCOLON: 368>, '||': <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: 61>, '??': <TokenType.DQMARK: 18>, '~~~': <TokenType.GLOB: 286>, '~~': <TokenType.LIKE: 317>, '~~*': <TokenType.ILIKE: 294>, '~*': <TokenType.IRLIKE: 306>, '-|-': <TokenType.ADJACENT: 64>, 'ALL': <TokenType.ALL: 219>, 'AND': <TokenType.AND: 34>, 'ANTI': <TokenType.ANTI: 220>, 'ANY': <TokenType.ANY: 221>, 'ASC': <TokenType.ASC: 224>, 'AS': <TokenType.ALIAS: 217>, 'ASOF': <TokenType.ASOF: 225>, 'AUTOINCREMENT': <TokenType.AUTO_INCREMENT: 227>, 'AUTO_INCREMENT': <TokenType.AUTO_INCREMENT: 227>, 'BEGIN': <TokenType.COMMAND: 236>, 'BETWEEN': <TokenType.BETWEEN: 229>, 'CACHE': <TokenType.CACHE: 231>, 'UNCACHE': <TokenType.UNCACHE: 412>, 'CASE': <TokenType.CASE: 232>, 'CHARACTER SET': <TokenType.CHARACTER_SET: 233>, 'CLUSTER BY': <TokenType.CLUSTER_BY: 234>, 'COLLATE': <TokenType.COLLATE: 235>, 'COLUMN': <TokenType.COLUMN: 80>, 'COMMIT': <TokenType.COMMIT: 238>, 'CONNECT BY': <TokenType.CONNECT_BY: 239>, 'CONSTRAINT': <TokenType.CONSTRAINT: 240>, 'COPY': <TokenType.COPY: 241>, 'CREATE': <TokenType.CREATE: 242>, 'CROSS': <TokenType.CROSS: 243>, 'CUBE': <TokenType.CUBE: 244>, 'CURRENT_DATE': <TokenType.CURRENT_DATE: 245>, 'CURRENT_SCHEMA': <TokenType.CURRENT_SCHEMA: 247>, 'CURRENT_TIME': <TokenType.CURRENT_TIME: 248>, 'CURRENT_TIMESTAMP': <TokenType.CURRENT_TIMESTAMP: 249>, 'CURRENT_USER': <TokenType.CURRENT_USER: 250>, 'CURRENT_CATALOG': <TokenType.CURRENT_CATALOG: 253>, 'DATABASE': <TokenType.DATABASE: 79>, 'DEFAULT': <TokenType.DEFAULT: 255>, 'DELETE': <TokenType.DELETE: 256>, 'DESC': <TokenType.DESC: 257>, 'DESCRIBE': <TokenType.DESCRIBE: 258>, 'DISTINCT': <TokenType.DISTINCT: 261>, 'DISTRIBUTE BY': <TokenType.DISTRIBUTE_BY: 262>, 'DROP': <TokenType.DROP: 264>, 'ELSE': <TokenType.ELSE: 265>, 'END': <TokenType.END: 266>, 'ENUM': <TokenType.ENUM: 204>, 'ESCAPE': <TokenType.ESCAPE: 267>, 'EXCEPT': <TokenType.EXCEPT: 268>, 'EXECUTE': <TokenType.EXECUTE: 269>, 'EXISTS': <TokenType.EXISTS: 270>, 'FALSE': <TokenType.FALSE: 271>, 'FETCH': <TokenType.FETCH: 272>, 'FILTER': <TokenType.FILTER: 275>, 'FILE': <TokenType.FILE: 273>, 'FIRST': <TokenType.FIRST: 277>, 'FULL': <TokenType.FULL: 283>, 'FUNCTION': <TokenType.FUNCTION: 284>, 'FOR': <TokenType.FOR: 278>, 'FOREIGN KEY': <TokenType.FOREIGN_KEY: 280>, 'FORMAT': <TokenType.FORMAT: 281>, 'FROM': <TokenType.FROM: 282>, 'GEOGRAPHY': <TokenType.GEOGRAPHY: 171>, 'GEOMETRY': <TokenType.GEOMETRY: 174>, 'GLOB': <TokenType.GLOB: 286>, 'GROUP BY': <TokenType.GROUP_BY: 289>, 'GROUPING SETS': <TokenType.GROUPING_SETS: 290>, 'HAVING': <TokenType.HAVING: 291>, 'ILIKE': <TokenType.ILIKE: 294>, 'IN': <TokenType.IN: 295>, 'INDEX': <TokenType.INDEX: 296>, 'INET': <TokenType.INET: 199>, 'INNER': <TokenType.INNER: 298>, 'INSERT': <TokenType.INSERT: 299>, 'INTERVAL': <TokenType.INTERVAL: 303>, 'INTERSECT': <TokenType.INTERSECT: 302>, 'INTO': <TokenType.INTO: 304>, 'IS': <TokenType.IS: 307>, 'ISNULL': <TokenType.ISNULL: 308>, 'JOIN': <TokenType.JOIN: 309>, 'KEEP': <TokenType.KEEP: 311>, 'KILL': <TokenType.KILL: 313>, 'LATERAL': <TokenType.LATERAL: 315>, 'LEFT': <TokenType.LEFT: 316>, 'LIKE': <TokenType.LIKE: 317>, 'LIMIT': <TokenType.LIMIT: 318>, 'LOAD': <TokenType.LOAD: 320>, 'LOCALTIME': <TokenType.LOCALTIME: 178>, 'LOCALTIMESTAMP': <TokenType.LOCALTIMESTAMP: 179>, 'LOCK': <TokenType.LOCK: 321>, 'MERGE': <TokenType.MERGE: 327>, 'NAMESPACE': <TokenType.NAMESPACE: 439>, 'NATURAL': <TokenType.NATURAL: 330>, 'NEXT': <TokenType.NEXT: 331>, 'NOT': <TokenType.NOT: 27>, 'NOTNULL': <TokenType.NOTNULL: 333>, 'NULL': <TokenType.NULL: 334>, 'OBJECT': <TokenType.OBJECT: 198>, 'OFFSET': <TokenType.OFFSET: 336>, 'ON': <TokenType.ON: 337>, 'OR': <TokenType.OR: 35>, 'XOR': <TokenType.XOR: 65>, 'ORDER BY': <TokenType.ORDER_BY: 340>, 'ORDINALITY': <TokenType.ORDINALITY: 343>, 'OUT': <TokenType.OUT: 344>, 'OUTER': <TokenType.OUTER: 346>, 'OVER': <TokenType.OVER: 347>, 'OVERLAPS': <TokenType.OVERLAPS: 348>, 'OVERWRITE': <TokenType.OVERWRITE: 349>, 'PARTITION': <TokenType.PARTITION: 351>, 'PARTITION BY': <TokenType.PARTITION_BY: 352>, 'PARTITIONED BY': <TokenType.PARTITION_BY: 352>, 'PARTITIONED_BY': <TokenType.PARTITION_BY: 352>, 'PERCENT': <TokenType.PERCENT: 353>, 'PIVOT': <TokenType.PIVOT: 354>, 'PRAGMA': <TokenType.PRAGMA: 359>, 'PRIMARY KEY': <TokenType.PRIMARY_KEY: 361>, 'PROCEDURE': <TokenType.PROCEDURE: 362>, 'OPERATOR': <TokenType.OPERATOR: 339>, 'QUALIFY': <TokenType.QUALIFY: 366>, 'RANGE': <TokenType.RANGE: 369>, 'RECURSIVE': <TokenType.RECURSIVE: 370>, 'REGEXP': <TokenType.RLIKE: 378>, 'RENAME': <TokenType.RENAME: 372>, 'REPLACE': <TokenType.REPLACE: 373>, 'RETURNING': <TokenType.RETURNING: 374>, 'REFERENCES': <TokenType.REFERENCES: 376>, 'RIGHT': <TokenType.RIGHT: 377>, 'RLIKE': <TokenType.RLIKE: 378>, 'ROLLBACK': <TokenType.ROLLBACK: 380>, 'ROLLUP': <TokenType.ROLLUP: 381>, 'ROW': <TokenType.ROW: 382>, 'ROWS': <TokenType.ROWS: 383>, 'SCHEMA': <TokenType.SCHEMA: 82>, 'SELECT': <TokenType.SELECT: 385>, 'SEMI': <TokenType.SEMI: 386>, 'SESSION': <TokenType.SESSION: 58>, 'SESSION_USER': <TokenType.SESSION_USER: 60>, 'SET': <TokenType.SET: 390>, 'SETTINGS': <TokenType.SETTINGS: 391>, 'SHOW': <TokenType.SHOW: 392>, 'SIMILAR TO': <TokenType.SIMILAR_TO: 393>, 'SOME': <TokenType.SOME: 394>, 'SORT BY': <TokenType.SORT_BY: 395>, 'SQL SECURITY': <TokenType.SQL_SECURITY: 397>, 'START WITH': <TokenType.START_WITH: 398>, 'STRAIGHT_JOIN': <TokenType.STRAIGHT_JOIN: 400>, 'TABLE': <TokenType.TABLE: 83>, 'TABLESAMPLE': <TokenType.TABLE_SAMPLE: 403>, 'TEMP': <TokenType.TEMPORARY: 405>, 'TEMPORARY': <TokenType.TEMPORARY: 405>, 'THEN': <TokenType.THEN: 407>, 'TRUE': <TokenType.TRUE: 408>, 'TRUNCATE': <TokenType.TRUNCATE: 409>, 'TRIGGER': <TokenType.TRIGGER: 410>, 'UNION': <TokenType.UNION: 413>, 'UNKNOWN': <TokenType.UNKNOWN: 213>, 'UNNEST': <TokenType.UNNEST: 414>, 'UNPIVOT': <TokenType.UNPIVOT: 415>, 'UPDATE': <TokenType.UPDATE: 416>, 'USE': <TokenType.USE: 417>, 'USING': <TokenType.USING: 418>, 'UUID': <TokenType.UUID: 170>, 'VIEW': <TokenType.VIEW: 421>, 'VOLATILE': <TokenType.VOLATILE: 423>, 'WHEN': <TokenType.WHEN: 425>, 'WHERE': <TokenType.WHERE: 426>, 'WINDOW': <TokenType.WINDOW: 427>, 'WITH': <TokenType.WITH: 428>, 'APPLY': <TokenType.APPLY: 222>, 'ARRAY': <TokenType.ARRAY: 223>, 'BIT': <TokenType.BIT: 96>, 'BOOL': <TokenType.BOOLEAN: 97>, 'BOOLEAN': <TokenType.BOOLEAN: 97>, 'BYTE': <TokenType.TINYINT: 98>, 'MEDIUMINT': <TokenType.MEDIUMINT: 102>, 'INT1': <TokenType.TINYINT: 98>, 'TINYINT': <TokenType.TINYINT: 98>, 'INT16': <TokenType.SMALLINT: 100>, 'SHORT': <TokenType.SMALLINT: 100>, 'SMALLINT': <TokenType.SMALLINT: 100>, 'HUGEINT': <TokenType.INT128: 109>, 'UHUGEINT': <TokenType.UINT128: 110>, 'INT2': <TokenType.SMALLINT: 100>, 'INTEGER': <TokenType.INT: 104>, 'INT': <TokenType.INT: 104>, 'INT4': <TokenType.INT: 104>, 'INT32': <TokenType.INT: 104>, 'INT64': <TokenType.BIGINT: 106>, 'INT128': <TokenType.INT128: 109>, 'INT256': <TokenType.INT256: 111>, 'LONG': <TokenType.BIGINT: 106>, 'BIGINT': <TokenType.BIGINT: 106>, 'INT8': <TokenType.TINYINT: 98>, 'UINT': <TokenType.UINT: 105>, 'UINT128': <TokenType.UINT128: 110>, 'UINT256': <TokenType.UINT256: 112>, 'DEC': <TokenType.DECIMAL: 116>, 'DECIMAL': <TokenType.DECIMAL: 116>, 'DECIMAL32': <TokenType.DECIMAL32: 117>, 'DECIMAL64': <TokenType.DECIMAL64: 118>, 'DECIMAL128': <TokenType.DECIMAL128: 119>, 'DECIMAL256': <TokenType.DECIMAL256: 120>, 'DECFLOAT': <TokenType.DECFLOAT: 121>, 'BIGDECIMAL': <TokenType.BIGDECIMAL: 123>, 'BIGNUMERIC': <TokenType.BIGDECIMAL: 123>, 'BIGNUM': <TokenType.BIGNUM: 108>, 'LIST': <TokenType.LIST: 319>, 'MAP': <TokenType.MAP: 322>, 'NULLABLE': <TokenType.NULLABLE: 173>, 'NUMBER': <TokenType.DECIMAL: 116>, 'NUMERIC': <TokenType.DECIMAL: 116>, 'FIXED': <TokenType.DECIMAL: 116>, 'REAL': <TokenType.FLOAT: 113>, 'FLOAT': <TokenType.FLOAT: 113>, 'FLOAT4': <TokenType.FLOAT: 113>, 'FLOAT8': <TokenType.DOUBLE: 114>, 'DOUBLE': <TokenType.DOUBLE: 114>, 'DOUBLE PRECISION': <TokenType.DOUBLE: 114>, 'JSON': <TokenType.JSON: 140>, 'JSONB': <TokenType.JSONB: 141>, 'CHAR': <TokenType.CHAR: 124>, 'CHARACTER': <TokenType.CHAR: 124>, 'CHAR VARYING': <TokenType.VARCHAR: 126>, 'CHARACTER VARYING': <TokenType.VARCHAR: 126>, 'NCHAR': <TokenType.NCHAR: 125>, 'VARCHAR': <TokenType.VARCHAR: 126>, 'VARCHAR2': <TokenType.VARCHAR: 126>, 'NVARCHAR': <TokenType.NVARCHAR: 127>, 'NVARCHAR2': <TokenType.NVARCHAR: 127>, 'BPCHAR': <TokenType.BPCHAR: 128>, 'STR': <TokenType.TEXT: 129>, 'STRING': <TokenType.TEXT: 129>, 'TEXT': <TokenType.TEXT: 129>, 'LONGTEXT': <TokenType.LONGTEXT: 131>, 'MEDIUMTEXT': <TokenType.MEDIUMTEXT: 130>, 'TINYTEXT': <TokenType.TINYTEXT: 136>, 'CLOB': <TokenType.TEXT: 129>, 'LONGVARCHAR': <TokenType.TEXT: 129>, 'BINARY': <TokenType.BINARY: 138>, 'BLOB': <TokenType.VARBINARY: 139>, 'LONGBLOB': <TokenType.LONGBLOB: 134>, 'MEDIUMBLOB': <TokenType.MEDIUMBLOB: 133>, 'TINYBLOB': <TokenType.TINYBLOB: 135>, 'BYTEA': <TokenType.VARBINARY: 139>, 'VARBINARY': <TokenType.VARBINARY: 139>, 'TIME': <TokenType.TIME: 142>, 'TIMETZ': <TokenType.TIMETZ: 143>, 'TIME_NS': <TokenType.TIME_NS: 144>, 'TIMESTAMP': <TokenType.TIMESTAMPTZ: 146>, 'TIMESTAMPTZ': <TokenType.TIMESTAMPTZ: 146>, 'TIMESTAMPLTZ': <TokenType.TIMESTAMPLTZ: 147>, 'TIMESTAMP_LTZ': <TokenType.TIMESTAMPLTZ: 147>, 'TIMESTAMPNTZ': <TokenType.TIMESTAMPNTZ: 148>, 'TIMESTAMP_NTZ': <TokenType.TIMESTAMPNTZ: 148>, 'DATE': <TokenType.DATE: 156>, 'DATETIME': <TokenType.TIMESTAMP: 145>, 'INT4RANGE': <TokenType.INT4RANGE: 158>, 'INT4MULTIRANGE': <TokenType.INT4MULTIRANGE: 159>, 'INT8RANGE': <TokenType.INT8RANGE: 160>, 'INT8MULTIRANGE': <TokenType.INT8MULTIRANGE: 161>, 'NUMRANGE': <TokenType.NUMRANGE: 162>, 'NUMMULTIRANGE': <TokenType.NUMMULTIRANGE: 163>, 'TSRANGE': <TokenType.TSRANGE: 164>, 'TSMULTIRANGE': <TokenType.TSMULTIRANGE: 165>, 'TSTZRANGE': <TokenType.TSTZRANGE: 166>, 'TSTZMULTIRANGE': <TokenType.TSTZMULTIRANGE: 167>, 'DATERANGE': <TokenType.DATERANGE: 168>, 'DATEMULTIRANGE': <TokenType.DATEMULTIRANGE: 169>, 'UNIQUE': <TokenType.UNIQUE: 429>, 'VECTOR': <TokenType.VECTOR: 214>, 'STRUCT': <TokenType.STRUCT: 401>, 'SEQUENCE': <TokenType.SEQUENCE: 388>, 'VARIANT': <TokenType.VARIANT: 197>, 'ALTER': <TokenType.ALTER: 218>, 'ANALYZE': <TokenType.ANALYZE: 438>, 'CALL': <TokenType.COMMAND: 236>, 'COMMENT': <TokenType.COMMENT: 237>, 'EXPLAIN': <TokenType.COMMAND: 236>, 'GRANT': <TokenType.GRANT: 288>, 'REVOKE': <TokenType.REVOKE: 375>, 'OPTIMIZE': <TokenType.COMMAND: 236>, 'PREPARE': <TokenType.COMMAND: 236>, 'VACUUM': <TokenType.COMMAND: 236>, 'USER-DEFINED': <TokenType.USERDEFINED: 192>, 'FOR VERSION': <TokenType.VERSION_SNAPSHOT: 433>, 'FOR TIMESTAMP': <TokenType.TIMESTAMP_SNAPSHOT: 434>, 'ANY TYPE': <TokenType.VARIANT: 197>, 'BEGIN TRANSACTION': <TokenType.BEGIN: 228>, 'BYTEINT': <TokenType.INT: 104>, 'BYTES': <TokenType.BINARY: 138>, 'CURRENT_DATETIME': <TokenType.CURRENT_DATETIME: 246>, 'DECLARE': <TokenType.DECLARE: 254>, 'ELSEIF': <TokenType.COMMAND: 236>, 'EXCEPTION': <TokenType.COMMAND: 236>, 'EXPORT': <TokenType.EXPORT: 440>, 'FLOAT64': <TokenType.DOUBLE: 114>, 'FOR SYSTEM TIME': <TokenType.TIMESTAMP_SNAPSHOT: 434>, 'FOR SYSTEM_TIME': <TokenType.TIMESTAMP_SNAPSHOT: 434>, 'LOOP': <TokenType.COMMAND: 236>, 'MODEL': <TokenType.MODEL: 329>, 'NOT DETERMINISTIC': <TokenType.VOLATILE: 423>, 'RECORD': <TokenType.STRUCT: 401>, 'REPEAT': <TokenType.COMMAND: 236>, 'WHILE': <TokenType.COMMAND: 236>}
BYTE_STRING_ESCAPES: ClassVar[list[str]] = ['\\']