diff options
Diffstat (limited to 'sqlglot/dialects/bigquery.py')
-rw-r--r-- | sqlglot/dialects/bigquery.py | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/sqlglot/dialects/bigquery.py b/sqlglot/dialects/bigquery.py index 2166e65..52d4a88 100644 --- a/sqlglot/dialects/bigquery.py +++ b/sqlglot/dialects/bigquery.py @@ -4,6 +4,7 @@ import re import typing as t from sqlglot import exp, generator, parser, tokens, transforms +from sqlglot._typing import E from sqlglot.dialects.dialect import ( Dialect, datestrtodate_sql, @@ -106,6 +107,9 @@ def _unqualify_unnest(expression: exp.Expression) -> exp.Expression: class BigQuery(Dialect): UNNEST_COLUMN_ONLY = True + # https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#case_sensitivity + RESOLVES_IDENTIFIERS_AS_UPPERCASE = None + TIME_MAPPING = { "%D": "%m/%d/%y", } @@ -126,6 +130,20 @@ class BigQuery(Dialect): "TZH": "%z", } + @classmethod + def normalize_identifier(cls, expression: E) -> E: + # In BigQuery, CTEs aren't case-sensitive, but table names are (by default, at least). + # The following check is essentially a heuristic to detect tables based on whether or + # not they're qualified. + if ( + isinstance(expression, exp.Identifier) + and not (isinstance(expression.parent, exp.Table) and expression.parent.db) + and not expression.meta.get("is_table") + ): + expression.set("this", expression.this.lower()) + + return expression + class Tokenizer(tokens.Tokenizer): QUOTES = ["'", '"', '"""', "'''"] COMMENTS = ["--", "#", ("/*", "*/")] @@ -176,6 +194,7 @@ class BigQuery(Dialect): "DATETIME_ADD": parse_date_delta_with_interval(exp.DatetimeAdd), "DATETIME_SUB": parse_date_delta_with_interval(exp.DatetimeSub), "DIV": lambda args: exp.IntDiv(this=seq_get(args, 0), expression=seq_get(args, 1)), + "GENERATE_ARRAY": exp.GenerateSeries.from_arg_list, "PARSE_DATE": lambda args: format_time_lambda(exp.StrToDate, "bigquery")( [seq_get(args, 1), seq_get(args, 0)] ), @@ -201,6 +220,7 @@ class BigQuery(Dialect): "TIME_SUB": parse_date_delta_with_interval(exp.TimeSub), "TIMESTAMP_ADD": parse_date_delta_with_interval(exp.TimestampAdd), "TIMESTAMP_SUB": parse_date_delta_with_interval(exp.TimestampSub), + "TO_JSON_STRING": exp.JSONFormat.from_arg_list, } FUNCTION_PARSERS = { @@ -289,6 +309,8 @@ class BigQuery(Dialect): exp.DateDiff: lambda self, e: f"DATE_DIFF({self.sql(e, 'this')}, {self.sql(e, 'expression')}, {self.sql(e.args.get('unit', 'DAY'))})", exp.DateStrToDate: datestrtodate_sql, exp.DateTrunc: lambda self, e: self.func("DATE_TRUNC", e.this, e.text("unit")), + exp.JSONFormat: rename_func("TO_JSON_STRING"), + exp.GenerateSeries: rename_func("GENERATE_ARRAY"), exp.GroupConcat: rename_func("STRING_AGG"), exp.ILike: no_ilike_sql, exp.IntDiv: rename_func("DIV"), |