diff options
Diffstat (limited to 'sqlglot/dialects/bigquery.py')
-rw-r--r-- | sqlglot/dialects/bigquery.py | 61 |
1 files changed, 30 insertions, 31 deletions
diff --git a/sqlglot/dialects/bigquery.py b/sqlglot/dialects/bigquery.py index 701377b..1a88654 100644 --- a/sqlglot/dialects/bigquery.py +++ b/sqlglot/dialects/bigquery.py @@ -13,6 +13,7 @@ from sqlglot.dialects.dialect import ( max_or_greatest, min_or_least, no_ilike_sql, + parse_date_delta_with_interval, rename_func, timestrtotime_sql, ts_or_ds_to_date_sql, @@ -23,18 +24,6 @@ from sqlglot.tokens import TokenType E = t.TypeVar("E", bound=exp.Expression) -def _date_add(expression_class: t.Type[E]) -> t.Callable[[t.Sequence], E]: - def func(args): - interval = seq_get(args, 1) - return expression_class( - this=seq_get(args, 0), - expression=interval.this, - unit=interval.args.get("unit"), - ) - - return func - - def _date_add_sql( data_type: str, kind: str ) -> t.Callable[[generator.Generator, exp.Expression], str]: @@ -142,6 +131,7 @@ class BigQuery(Dialect): KEYWORDS = { **tokens.Tokenizer.KEYWORDS, + "ANY TYPE": TokenType.VARIANT, "BEGIN": TokenType.COMMAND, "BEGIN TRANSACTION": TokenType.BEGIN, "CURRENT_DATETIME": TokenType.CURRENT_DATETIME, @@ -155,14 +145,19 @@ class BigQuery(Dialect): KEYWORDS.pop("DIV") class Parser(parser.Parser): + PREFIXED_PIVOT_COLUMNS = True + + LOG_BASE_FIRST = False + LOG_DEFAULTS_TO_LN = True + FUNCTIONS = { **parser.Parser.FUNCTIONS, # type: ignore "DATE_TRUNC": lambda args: exp.DateTrunc( unit=exp.Literal.string(seq_get(args, 1).name), # type: ignore this=seq_get(args, 0), ), - "DATE_ADD": _date_add(exp.DateAdd), - "DATETIME_ADD": _date_add(exp.DatetimeAdd), + "DATE_ADD": parse_date_delta_with_interval(exp.DateAdd), + "DATETIME_ADD": parse_date_delta_with_interval(exp.DatetimeAdd), "DIV": lambda args: exp.IntDiv(this=seq_get(args, 0), expression=seq_get(args, 1)), "REGEXP_CONTAINS": exp.RegexpLike.from_arg_list, "REGEXP_EXTRACT": lambda args: exp.RegexpExtract( @@ -174,12 +169,12 @@ class BigQuery(Dialect): if re.compile(str(seq_get(args, 1))).groups == 1 else None, ), - "TIME_ADD": _date_add(exp.TimeAdd), - "TIMESTAMP_ADD": _date_add(exp.TimestampAdd), - "DATE_SUB": _date_add(exp.DateSub), - "DATETIME_SUB": _date_add(exp.DatetimeSub), - "TIME_SUB": _date_add(exp.TimeSub), - "TIMESTAMP_SUB": _date_add(exp.TimestampSub), + "TIME_ADD": parse_date_delta_with_interval(exp.TimeAdd), + "TIMESTAMP_ADD": parse_date_delta_with_interval(exp.TimestampAdd), + "DATE_SUB": parse_date_delta_with_interval(exp.DateSub), + "DATETIME_SUB": parse_date_delta_with_interval(exp.DatetimeSub), + "TIME_SUB": parse_date_delta_with_interval(exp.TimeSub), + "TIMESTAMP_SUB": parse_date_delta_with_interval(exp.TimestampSub), "PARSE_TIMESTAMP": lambda args: exp.StrToTime( this=seq_get(args, 1), format=seq_get(args, 0) ), @@ -209,14 +204,17 @@ class BigQuery(Dialect): PROPERTY_PARSERS = { **parser.Parser.PROPERTY_PARSERS, # type: ignore "NOT DETERMINISTIC": lambda self: self.expression( - exp.VolatilityProperty, this=exp.Literal.string("VOLATILE") + exp.StabilityProperty, this=exp.Literal.string("VOLATILE") ), } - LOG_BASE_FIRST = False - LOG_DEFAULTS_TO_LN = True - class Generator(generator.Generator): + EXPLICIT_UNION = True + INTERVAL_ALLOWS_PLURAL_FORM = False + JOIN_HINTS = False + TABLE_HINTS = False + LIMIT_FETCH = "LIMIT" + TRANSFORMS = { **generator.Generator.TRANSFORMS, # type: ignore **transforms.REMOVE_PRECISION_PARAMETERIZED_TYPES, # type: ignore @@ -236,9 +234,7 @@ class BigQuery(Dialect): exp.IntDiv: rename_func("DIV"), exp.Max: max_or_greatest, exp.Min: min_or_least, - exp.Select: transforms.preprocess( - [_unqualify_unnest], transforms.delegate("select_sql") - ), + exp.Select: transforms.preprocess([_unqualify_unnest]), exp.StrToTime: lambda self, e: f"PARSE_TIMESTAMP({self.format_time(e)}, {self.sql(e, 'this')})", exp.TimeAdd: _date_add_sql("TIME", "ADD"), exp.TimeSub: _date_add_sql("TIME", "SUB"), @@ -253,7 +249,7 @@ class BigQuery(Dialect): exp.ReturnsProperty: _returnsproperty_sql, exp.Create: _create_sql, exp.Trim: lambda self, e: self.func(f"TRIM", e.this, e.expression), - exp.VolatilityProperty: lambda self, e: f"DETERMINISTIC" + exp.StabilityProperty: lambda self, e: f"DETERMINISTIC" if e.name == "IMMUTABLE" else "NOT DETERMINISTIC", exp.RegexpLike: rename_func("REGEXP_CONTAINS"), @@ -261,6 +257,7 @@ class BigQuery(Dialect): TYPE_MAPPING = { **generator.Generator.TYPE_MAPPING, # type: ignore + exp.DataType.Type.BIGDECIMAL: "BIGNUMERIC", exp.DataType.Type.BIGINT: "INT64", exp.DataType.Type.BOOLEAN: "BOOL", exp.DataType.Type.CHAR: "STRING", @@ -272,17 +269,19 @@ class BigQuery(Dialect): exp.DataType.Type.NVARCHAR: "STRING", exp.DataType.Type.SMALLINT: "INT64", exp.DataType.Type.TEXT: "STRING", + exp.DataType.Type.TIMESTAMP: "DATETIME", + exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP", exp.DataType.Type.TINYINT: "INT64", exp.DataType.Type.VARCHAR: "STRING", + exp.DataType.Type.VARIANT: "ANY TYPE", } + PROPERTIES_LOCATION = { **generator.Generator.PROPERTIES_LOCATION, # type: ignore exp.PartitionedByProperty: exp.Properties.Location.POST_SCHEMA, + exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED, } - EXPLICIT_UNION = True - LIMIT_FETCH = "LIMIT" - def array_sql(self, expression: exp.Array) -> str: first_arg = seq_get(expression.expressions, 0) if isinstance(first_arg, exp.Subqueryable): |