sqlglot.dialects.bigquery
1from __future__ import annotations 2 3import typing as t 4 5 6from sqlglot.optimizer.annotate_types import TypeAnnotator 7 8from sqlglot import exp, jsonpath, tokens 9from sqlglot._typing import E 10from sqlglot.parsers.bigquery import BigQueryParser 11from sqlglot.generators.bigquery import BigQueryGenerator 12from sqlglot.dialects.dialect import ( 13 ASCII_LOWER, 14 Dialect, 15 NormalizationStrategy, 16) 17from sqlglot.tokens import TokenType 18from sqlglot.typing.bigquery import EXPRESSION_METADATA 19 20if t.TYPE_CHECKING: 21 from sqlglot.optimizer.annotate_types import TypeAnnotator 22 23 24class BigQuery(Dialect): 25 WEEK_OFFSET = -1 26 UNNEST_COLUMN_ONLY = True 27 SUPPORTS_USER_DEFINED_TYPES = False 28 LOG_BASE_FIRST = False 29 HEX_LOWERCASE = True 30 FORCE_EARLY_ALIAS_REF_EXPANSION = True 31 EXPAND_ONLY_GROUP_ALIAS_REF = True 32 PRESERVE_ORIGINAL_NAMES = True 33 HEX_STRING_IS_INTEGER_TYPE = True 34 BYTE_STRING_IS_BYTES_TYPE = True 35 UUID_IS_STRING_TYPE = True 36 ANNOTATE_ALL_SCOPES = True 37 PROJECTION_ALIASES_SHADOW_SOURCE_NAMES = True 38 TABLES_REFERENCEABLE_AS_COLUMNS = True 39 SUPPORTS_STRUCT_STAR_EXPANSION = True 40 EXCLUDES_PSEUDOCOLUMNS_FROM_STAR = True 41 QUERY_RESULTS_ARE_STRUCTS = True 42 JSON_EXTRACT_SCALAR_SCALAR_ONLY = True 43 JSON_PATH_SINGLE_DOT_IS_WILDCARD = True 44 LEAST_GREATEST_IGNORES_NULLS = False 45 DEFAULT_NULL_TYPE = exp.DType.BIGINT 46 PRIORITIZE_NON_LITERAL_TYPES = True 47 ALIAS_POST_VERSION = False 48 49 # https://docs.cloud.google.com/bigquery/docs/reference/standard-sql/string_functions#initcap 50 INITCAP_DEFAULT_DELIMITER_CHARS = ' \t\n\r\f\v\\[\\](){}/|<>!?@"^#$&~_,.:;*%+\\-' 51 52 # https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#case_sensitivity 53 NORMALIZATION_STRATEGY = NormalizationStrategy.CASE_INSENSITIVE 54 ASCII_ONLY_NORMALIZATION = True 55 56 # bigquery udfs are case sensitive 57 NORMALIZE_FUNCTIONS = False 58 59 # https://cloud.google.com/bigquery/docs/reference/standard-sql/format-elements#format_elements_date_time 60 TIME_MAPPING = { 61 "%x": "%m/%d/%y", 62 "%D": "%m/%d/%y", 63 "%E6S": "%S.%f", 64 "%e": "%-d", 65 "%F": "%Y-%m-%d", 66 "%T": "%H:%M:%S", 67 "%c": "%a %b %e %H:%M:%S %Y", 68 } 69 70 INVERSE_TIME_MAPPING = { 71 # Preserve %E6S instead of expanding to %T.%f - since both %E6S & %T.%f are semantically different in BigQuery 72 # %E6S is semantically different from %T.%f: %E6S works as a single atomic specifier for seconds with microseconds, while %T.%f expands incorrectly and fails to parse. 73 "%H:%M:%S.%f": "%H:%M:%E6S", 74 } 75 76 FORMAT_MAPPING = { 77 "dd": "%d", 78 "DD": "%d", 79 "mm": "%m", 80 "MM": "%m", 81 "mon": "%b", 82 "MON": "%b", 83 "month": "%B", 84 "MONTH": "%B", 85 "yyyy": "%Y", 86 "YYYY": "%Y", 87 "yy": "%y", 88 "YY": "%y", 89 "HH": "%I", 90 "HH12": "%I", 91 "hh24": "%H", 92 "HH24": "%H", 93 "mi": "%M", 94 "MI": "%M", 95 "ss": "%S", 96 "SS": "%S", 97 "SSSSS": "%f", 98 "tzh": "%z", 99 "TZH": "%z", 100 } 101 102 # The _PARTITIONTIME and _PARTITIONDATE pseudo-columns are not returned by a SELECT * statement 103 # https://cloud.google.com/bigquery/docs/querying-partitioned-tables#query_an_ingestion-time_partitioned_table 104 # https://cloud.google.com/bigquery/docs/querying-wildcard-tables#scanning_a_range_of_tables_using_table_suffix 105 # https://cloud.google.com/bigquery/docs/query-cloud-storage-data#query_the_file_name_pseudo-column 106 PSEUDOCOLUMNS = { 107 "_PARTITIONTIME", 108 "_PARTITIONDATE", 109 "_TABLE_SUFFIX", 110 "_FILE_NAME", 111 "_DBT_MAX_PARTITION", 112 } 113 114 # All set operations require either a DISTINCT or ALL specifier 115 SET_OP_DISTINCT_BY_DEFAULT = dict.fromkeys((exp.Except, exp.Intersect, exp.Union), None) 116 117 # https://cloud.google.com/bigquery/docs/reference/standard-sql/navigation_functions#percentile_cont 118 COERCES_TO = { 119 **TypeAnnotator.COERCES_TO, 120 exp.DType.BIGDECIMAL: {exp.DType.DOUBLE}, 121 } 122 COERCES_TO[exp.DType.DECIMAL] |= {exp.DType.BIGDECIMAL} 123 COERCES_TO[exp.DType.BIGINT] |= {exp.DType.BIGDECIMAL} 124 COERCES_TO[exp.DType.VARCHAR] |= { 125 exp.DType.DATE, 126 exp.DType.DATETIME, 127 exp.DType.TIME, 128 exp.DType.TIMESTAMP, 129 exp.DType.TIMESTAMPTZ, 130 } 131 132 EXPRESSION_METADATA = EXPRESSION_METADATA.copy() 133 134 def normalize_identifier(self, expression: E) -> E: 135 if ( 136 isinstance(expression, exp.Identifier) 137 and self.normalization_strategy is NormalizationStrategy.CASE_INSENSITIVE 138 ): 139 parent = expression.parent 140 while isinstance(parent, exp.Dot): 141 parent = parent.parent 142 143 # In BigQuery, CTEs are case-insensitive, but UDF and table names are case-sensitive 144 # by default. The following check uses a heuristic to detect tables based on whether 145 # they are qualified. This should generally be correct, because tables in BigQuery 146 # must be qualified with at least a dataset, unless @@dataset_id is set. 147 case_sensitive = ( 148 isinstance(parent, exp.UserDefinedFunction) 149 or ( 150 isinstance(parent, exp.Table) 151 and parent.db 152 and (parent.meta_get("quoted_table") or not parent.meta_get("maybe_column")) 153 ) 154 or expression.meta_get("is_table") 155 ) 156 if not case_sensitive: 157 expression.set("this", expression.this.translate(ASCII_LOWER)) 158 159 return t.cast(E, expression) 160 161 return super().normalize_identifier(expression) 162 163 class JSONPathTokenizer(jsonpath.JSONPathTokenizer): 164 VAR_TOKENS = { 165 *jsonpath.JSONPathTokenizer.VAR_TOKENS, 166 TokenType.DASH, 167 TokenType.NUMBER, 168 } 169 170 class Tokenizer(tokens.Tokenizer): 171 QUOTES = ["'", '"', '"""', "'''"] 172 COMMENTS = ["--", "#", ("/*", "*/")] 173 IDENTIFIERS = ["`"] 174 STRING_ESCAPES = ["\\"] 175 176 HEX_STRINGS = [("0x", ""), ("0X", "")] 177 178 BYTE_STRINGS = [(prefix + q, q) for q in t.cast(list[str], QUOTES) for prefix in ("b", "B")] 179 180 RAW_STRINGS = [(prefix + q, q) for q in t.cast(list[str], QUOTES) for prefix in ("r", "R")] 181 182 NESTED_COMMENTS = False 183 184 KEYWORDS = { 185 **tokens.Tokenizer.KEYWORDS, 186 "ANY TYPE": TokenType.VARIANT, 187 "BEGIN": TokenType.COMMAND, 188 "BEGIN TRANSACTION": TokenType.BEGIN, 189 "BYTEINT": TokenType.INT, 190 "BYTES": TokenType.BINARY, 191 "CURRENT_DATETIME": TokenType.CURRENT_DATETIME, 192 "DATETIME": TokenType.TIMESTAMP, 193 "DECLARE": TokenType.DECLARE, 194 "ELSEIF": TokenType.COMMAND, 195 "EXCEPTION": TokenType.COMMAND, 196 "EXPORT": TokenType.EXPORT, 197 "FLOAT64": TokenType.DOUBLE, 198 "LOOP": TokenType.COMMAND, 199 "MODEL": TokenType.MODEL, 200 "RECORD": TokenType.STRUCT, 201 "REPEAT": TokenType.COMMAND, 202 "TIMESTAMP": TokenType.TIMESTAMPTZ, 203 "WHILE": TokenType.COMMAND, 204 } 205 KEYWORDS.pop("DIV") 206 KEYWORDS.pop("VALUES") 207 KEYWORDS.pop("/*+") 208 209 Parser = BigQueryParser 210 211 Generator = BigQueryGenerator
25class BigQuery(Dialect): 26 WEEK_OFFSET = -1 27 UNNEST_COLUMN_ONLY = True 28 SUPPORTS_USER_DEFINED_TYPES = False 29 LOG_BASE_FIRST = False 30 HEX_LOWERCASE = True 31 FORCE_EARLY_ALIAS_REF_EXPANSION = True 32 EXPAND_ONLY_GROUP_ALIAS_REF = True 33 PRESERVE_ORIGINAL_NAMES = True 34 HEX_STRING_IS_INTEGER_TYPE = True 35 BYTE_STRING_IS_BYTES_TYPE = True 36 UUID_IS_STRING_TYPE = True 37 ANNOTATE_ALL_SCOPES = True 38 PROJECTION_ALIASES_SHADOW_SOURCE_NAMES = True 39 TABLES_REFERENCEABLE_AS_COLUMNS = True 40 SUPPORTS_STRUCT_STAR_EXPANSION = True 41 EXCLUDES_PSEUDOCOLUMNS_FROM_STAR = True 42 QUERY_RESULTS_ARE_STRUCTS = True 43 JSON_EXTRACT_SCALAR_SCALAR_ONLY = True 44 JSON_PATH_SINGLE_DOT_IS_WILDCARD = True 45 LEAST_GREATEST_IGNORES_NULLS = False 46 DEFAULT_NULL_TYPE = exp.DType.BIGINT 47 PRIORITIZE_NON_LITERAL_TYPES = True 48 ALIAS_POST_VERSION = False 49 50 # https://docs.cloud.google.com/bigquery/docs/reference/standard-sql/string_functions#initcap 51 INITCAP_DEFAULT_DELIMITER_CHARS = ' \t\n\r\f\v\\[\\](){}/|<>!?@"^#$&~_,.:;*%+\\-' 52 53 # https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#case_sensitivity 54 NORMALIZATION_STRATEGY = NormalizationStrategy.CASE_INSENSITIVE 55 ASCII_ONLY_NORMALIZATION = True 56 57 # bigquery udfs are case sensitive 58 NORMALIZE_FUNCTIONS = False 59 60 # https://cloud.google.com/bigquery/docs/reference/standard-sql/format-elements#format_elements_date_time 61 TIME_MAPPING = { 62 "%x": "%m/%d/%y", 63 "%D": "%m/%d/%y", 64 "%E6S": "%S.%f", 65 "%e": "%-d", 66 "%F": "%Y-%m-%d", 67 "%T": "%H:%M:%S", 68 "%c": "%a %b %e %H:%M:%S %Y", 69 } 70 71 INVERSE_TIME_MAPPING = { 72 # Preserve %E6S instead of expanding to %T.%f - since both %E6S & %T.%f are semantically different in BigQuery 73 # %E6S is semantically different from %T.%f: %E6S works as a single atomic specifier for seconds with microseconds, while %T.%f expands incorrectly and fails to parse. 74 "%H:%M:%S.%f": "%H:%M:%E6S", 75 } 76 77 FORMAT_MAPPING = { 78 "dd": "%d", 79 "DD": "%d", 80 "mm": "%m", 81 "MM": "%m", 82 "mon": "%b", 83 "MON": "%b", 84 "month": "%B", 85 "MONTH": "%B", 86 "yyyy": "%Y", 87 "YYYY": "%Y", 88 "yy": "%y", 89 "YY": "%y", 90 "HH": "%I", 91 "HH12": "%I", 92 "hh24": "%H", 93 "HH24": "%H", 94 "mi": "%M", 95 "MI": "%M", 96 "ss": "%S", 97 "SS": "%S", 98 "SSSSS": "%f", 99 "tzh": "%z", 100 "TZH": "%z", 101 } 102 103 # The _PARTITIONTIME and _PARTITIONDATE pseudo-columns are not returned by a SELECT * statement 104 # https://cloud.google.com/bigquery/docs/querying-partitioned-tables#query_an_ingestion-time_partitioned_table 105 # https://cloud.google.com/bigquery/docs/querying-wildcard-tables#scanning_a_range_of_tables_using_table_suffix 106 # https://cloud.google.com/bigquery/docs/query-cloud-storage-data#query_the_file_name_pseudo-column 107 PSEUDOCOLUMNS = { 108 "_PARTITIONTIME", 109 "_PARTITIONDATE", 110 "_TABLE_SUFFIX", 111 "_FILE_NAME", 112 "_DBT_MAX_PARTITION", 113 } 114 115 # All set operations require either a DISTINCT or ALL specifier 116 SET_OP_DISTINCT_BY_DEFAULT = dict.fromkeys((exp.Except, exp.Intersect, exp.Union), None) 117 118 # https://cloud.google.com/bigquery/docs/reference/standard-sql/navigation_functions#percentile_cont 119 COERCES_TO = { 120 **TypeAnnotator.COERCES_TO, 121 exp.DType.BIGDECIMAL: {exp.DType.DOUBLE}, 122 } 123 COERCES_TO[exp.DType.DECIMAL] |= {exp.DType.BIGDECIMAL} 124 COERCES_TO[exp.DType.BIGINT] |= {exp.DType.BIGDECIMAL} 125 COERCES_TO[exp.DType.VARCHAR] |= { 126 exp.DType.DATE, 127 exp.DType.DATETIME, 128 exp.DType.TIME, 129 exp.DType.TIMESTAMP, 130 exp.DType.TIMESTAMPTZ, 131 } 132 133 EXPRESSION_METADATA = EXPRESSION_METADATA.copy() 134 135 def normalize_identifier(self, expression: E) -> E: 136 if ( 137 isinstance(expression, exp.Identifier) 138 and self.normalization_strategy is NormalizationStrategy.CASE_INSENSITIVE 139 ): 140 parent = expression.parent 141 while isinstance(parent, exp.Dot): 142 parent = parent.parent 143 144 # In BigQuery, CTEs are case-insensitive, but UDF and table names are case-sensitive 145 # by default. The following check uses a heuristic to detect tables based on whether 146 # they are qualified. This should generally be correct, because tables in BigQuery 147 # must be qualified with at least a dataset, unless @@dataset_id is set. 148 case_sensitive = ( 149 isinstance(parent, exp.UserDefinedFunction) 150 or ( 151 isinstance(parent, exp.Table) 152 and parent.db 153 and (parent.meta_get("quoted_table") or not parent.meta_get("maybe_column")) 154 ) 155 or expression.meta_get("is_table") 156 ) 157 if not case_sensitive: 158 expression.set("this", expression.this.translate(ASCII_LOWER)) 159 160 return t.cast(E, expression) 161 162 return super().normalize_identifier(expression) 163 164 class JSONPathTokenizer(jsonpath.JSONPathTokenizer): 165 VAR_TOKENS = { 166 *jsonpath.JSONPathTokenizer.VAR_TOKENS, 167 TokenType.DASH, 168 TokenType.NUMBER, 169 } 170 171 class Tokenizer(tokens.Tokenizer): 172 QUOTES = ["'", '"', '"""', "'''"] 173 COMMENTS = ["--", "#", ("/*", "*/")] 174 IDENTIFIERS = ["`"] 175 STRING_ESCAPES = ["\\"] 176 177 HEX_STRINGS = [("0x", ""), ("0X", "")] 178 179 BYTE_STRINGS = [(prefix + q, q) for q in t.cast(list[str], QUOTES) for prefix in ("b", "B")] 180 181 RAW_STRINGS = [(prefix + q, q) for q in t.cast(list[str], QUOTES) for prefix in ("r", "R")] 182 183 NESTED_COMMENTS = False 184 185 KEYWORDS = { 186 **tokens.Tokenizer.KEYWORDS, 187 "ANY TYPE": TokenType.VARIANT, 188 "BEGIN": TokenType.COMMAND, 189 "BEGIN TRANSACTION": TokenType.BEGIN, 190 "BYTEINT": TokenType.INT, 191 "BYTES": TokenType.BINARY, 192 "CURRENT_DATETIME": TokenType.CURRENT_DATETIME, 193 "DATETIME": TokenType.TIMESTAMP, 194 "DECLARE": TokenType.DECLARE, 195 "ELSEIF": TokenType.COMMAND, 196 "EXCEPTION": TokenType.COMMAND, 197 "EXPORT": TokenType.EXPORT, 198 "FLOAT64": TokenType.DOUBLE, 199 "LOOP": TokenType.COMMAND, 200 "MODEL": TokenType.MODEL, 201 "RECORD": TokenType.STRUCT, 202 "REPEAT": TokenType.COMMAND, 203 "TIMESTAMP": TokenType.TIMESTAMPTZ, 204 "WHILE": TokenType.COMMAND, 205 } 206 KEYWORDS.pop("DIV") 207 KEYWORDS.pop("VALUES") 208 KEYWORDS.pop("/*+") 209 210 Parser = BigQueryParser 211 212 Generator = BigQueryGenerator
First day of the week in DATE_TRUNC(week). Defaults to 0 (Monday). -1 would be Sunday.
Whether the base comes first in the LOG function.
Possible values: True, False, None (two arguments are not supported by LOG)
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"
Whether alias reference expansion before qualification should only happen for the GROUP BY clause.
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
Whether hex strings such as x'CC' evaluate to integer or binary/blob type
Whether byte string literals (ex: BigQuery's b'...') are typed as BYTES/BINARY
Whether to annotate all scopes during optimization. Used by BigQuery for UNNEST support.
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.
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
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.
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.
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.
Whether JSON_EXTRACT_SCALAR returns null if a non-scalar value is selected.
Whether a single DOT in a JSON path (e.g. $.) is treated as a valid wildcard key.
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
The default type of NULL for producing the correct projection type.
For example, in BigQuery the default type of the NULL value is INT64.
Whether to prioritize non-literal types over literals during type annotation.
Whether the table alias comes after version (timestamp or iceberg snapshot).
Specifies the strategy according to which identifiers should be normalized.
Whether identifiers are only normalized with respect to ASCII characters, e.g. Ä and
ä are different identifiers in DuckDB, but the same identifier in Spark.
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.
Associates this dialect's time formats with their equivalent Python strftime formats.
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.
Columns that are auto-generated by the engine corresponding to this dialect.
For example, such columns may be excluded from SELECT * queries.
Whether a set operation uses DISTINCT by default. This is None when either DISTINCT or ALL
must be explicitly specified.
135 def normalize_identifier(self, expression: E) -> E: 136 if ( 137 isinstance(expression, exp.Identifier) 138 and self.normalization_strategy is NormalizationStrategy.CASE_INSENSITIVE 139 ): 140 parent = expression.parent 141 while isinstance(parent, exp.Dot): 142 parent = parent.parent 143 144 # In BigQuery, CTEs are case-insensitive, but UDF and table names are case-sensitive 145 # by default. The following check uses a heuristic to detect tables based on whether 146 # they are qualified. This should generally be correct, because tables in BigQuery 147 # must be qualified with at least a dataset, unless @@dataset_id is set. 148 case_sensitive = ( 149 isinstance(parent, exp.UserDefinedFunction) 150 or ( 151 isinstance(parent, exp.Table) 152 and parent.db 153 and (parent.meta_get("quoted_table") or not parent.meta_get("maybe_column")) 154 ) 155 or expression.meta_get("is_table") 156 ) 157 if not case_sensitive: 158 expression.set("this", expression.this.translate(ASCII_LOWER)) 159 160 return t.cast(E, expression) 161 162 return super().normalize_identifier(expression)
Transforms an identifier in a way that resembles how it'd be resolved by this dialect.
For example, an identifier like FoO would be resolved as foo in Postgres, because it
lowercases all unquoted identifiers. On the other hand, Snowflake uppercases them, so
it would resolve it as FOO. If it was quoted, it'd need to be treated as case-sensitive,
and so any normalization would be prohibited in order to avoid "breaking" the identifier.
There are also dialects like Spark, which are case-insensitive even when quotes are present, and dialects like MySQL, whose resolution rules match those employed by the underlying operating system, for example they may always be case-sensitive in Linux.
Finally, the normalization behavior of some engines can even be controlled through flags, like in Redshift's case, where users can explicitly set enable_case_sensitive_identifier.
SQLGlot aims to understand and handle all of these different behaviors gracefully, so that it can analyze queries in the optimizer and successfully capture their semantics.
Mapping of an escaped sequence (\n) to its unescaped version (
).
Whether string literals support escape sequences (e.g. \n). Set by the metaclass based on the tokenizer's STRING_ESCAPES.
Whether byte string literals support escape sequences. Set by the metaclass based on the tokenizer's BYTE_STRING_ESCAPES.
164 class JSONPathTokenizer(jsonpath.JSONPathTokenizer): 165 VAR_TOKENS = { 166 *jsonpath.JSONPathTokenizer.VAR_TOKENS, 167 TokenType.DASH, 168 TokenType.NUMBER, 169 }
Inherited Members
- sqlglot.tokens.Tokenizer
- Tokenizer
- BIT_STRINGS
- BYTE_STRINGS
- HEX_STRINGS
- RAW_STRINGS
- HEREDOC_STRINGS
- UNICODE_STRINGS
- IDENTIFIERS
- QUOTES
- VAR_SINGLE_TOKENS
- ESCAPE_FOLLOW_CHARS
- HEREDOC_TAG_IS_IDENTIFIER
- HEREDOC_STRING_ALTERNATIVE
- STRING_ESCAPES_ALLOWED_IN_RAW_STRINGS
- NESTED_COMMENTS
- HINT_START
- TOKENS_PRECEDING_HINT
- COMMANDS
- COMMAND_PREFIX_TOKENS
- NUMERIC_LITERALS
- COMMENTS
- dialect
- tokenize
- sql
- size
- tokens
171 class Tokenizer(tokens.Tokenizer): 172 QUOTES = ["'", '"', '"""', "'''"] 173 COMMENTS = ["--", "#", ("/*", "*/")] 174 IDENTIFIERS = ["`"] 175 STRING_ESCAPES = ["\\"] 176 177 HEX_STRINGS = [("0x", ""), ("0X", "")] 178 179 BYTE_STRINGS = [(prefix + q, q) for q in t.cast(list[str], QUOTES) for prefix in ("b", "B")] 180 181 RAW_STRINGS = [(prefix + q, q) for q in t.cast(list[str], QUOTES) for prefix in ("r", "R")] 182 183 NESTED_COMMENTS = False 184 185 KEYWORDS = { 186 **tokens.Tokenizer.KEYWORDS, 187 "ANY TYPE": TokenType.VARIANT, 188 "BEGIN": TokenType.COMMAND, 189 "BEGIN TRANSACTION": TokenType.BEGIN, 190 "BYTEINT": TokenType.INT, 191 "BYTES": TokenType.BINARY, 192 "CURRENT_DATETIME": TokenType.CURRENT_DATETIME, 193 "DATETIME": TokenType.TIMESTAMP, 194 "DECLARE": TokenType.DECLARE, 195 "ELSEIF": TokenType.COMMAND, 196 "EXCEPTION": TokenType.COMMAND, 197 "EXPORT": TokenType.EXPORT, 198 "FLOAT64": TokenType.DOUBLE, 199 "LOOP": TokenType.COMMAND, 200 "MODEL": TokenType.MODEL, 201 "RECORD": TokenType.STRUCT, 202 "REPEAT": TokenType.COMMAND, 203 "TIMESTAMP": TokenType.TIMESTAMPTZ, 204 "WHILE": TokenType.COMMAND, 205 } 206 KEYWORDS.pop("DIV") 207 KEYWORDS.pop("VALUES") 208 KEYWORDS.pop("/*+")
Inherited Members
- sqlglot.tokens.Tokenizer
- Tokenizer
- SINGLE_TOKENS
- BIT_STRINGS
- HEREDOC_STRINGS
- UNICODE_STRINGS
- VAR_SINGLE_TOKENS
- ESCAPE_FOLLOW_CHARS
- IDENTIFIER_ESCAPES
- HEREDOC_TAG_IS_IDENTIFIER
- HEREDOC_STRING_ALTERNATIVE
- STRING_ESCAPES_ALLOWED_IN_RAW_STRINGS
- HINT_START
- TOKENS_PRECEDING_HINT
- COMMANDS
- COMMAND_PREFIX_TOKENS
- NUMERIC_LITERALS
- NUMBERS_CAN_HAVE_DECIMALS
- dialect
- tokenize
- sql
- size
- tokens