diff options
Diffstat (limited to 'sqlglot/dialects')
-rw-r--r-- | sqlglot/dialects/databricks.py | 3 | ||||
-rw-r--r-- | sqlglot/dialects/duckdb.py | 7 | ||||
-rw-r--r-- | sqlglot/dialects/oracle.py | 24 | ||||
-rw-r--r-- | sqlglot/dialects/presto.py | 2 | ||||
-rw-r--r-- | sqlglot/dialects/redshift.py | 21 | ||||
-rw-r--r-- | sqlglot/dialects/spark.py | 3 | ||||
-rw-r--r-- | sqlglot/dialects/tsql.py | 7 |
7 files changed, 38 insertions, 29 deletions
diff --git a/sqlglot/dialects/databricks.py b/sqlglot/dialects/databricks.py index a044bc0..314a821 100644 --- a/sqlglot/dialects/databricks.py +++ b/sqlglot/dialects/databricks.py @@ -10,6 +10,7 @@ from sqlglot.tokens import TokenType class Databricks(Spark): class Parser(Spark.Parser): LOG_DEFAULTS_TO_LN = True + STRICT_CAST = True FUNCTIONS = { **Spark.Parser.FUNCTIONS, @@ -51,6 +52,8 @@ class Databricks(Spark): exp.ToChar: lambda self, e: self.function_fallback_sql(e), } + TRANSFORMS.pop(exp.TryCast) + def columndef_sql(self, expression: exp.ColumnDef, sep: str = " ") -> str: constraint = expression.find(exp.GeneratedAsIdentityColumnConstraint) kind = expression.args.get("kind") diff --git a/sqlglot/dialects/duckdb.py b/sqlglot/dialects/duckdb.py index 352f11a..5b94bcb 100644 --- a/sqlglot/dialects/duckdb.py +++ b/sqlglot/dialects/duckdb.py @@ -133,6 +133,10 @@ class DuckDB(Dialect): "UINTEGER": TokenType.UINT, "USMALLINT": TokenType.USMALLINT, "UTINYINT": TokenType.UTINYINT, + "TIMESTAMP_S": TokenType.TIMESTAMP_S, + "TIMESTAMP_MS": TokenType.TIMESTAMP_MS, + "TIMESTAMP_NS": TokenType.TIMESTAMP_NS, + "TIMESTAMP_US": TokenType.TIMESTAMP, } class Parser(parser.Parser): @@ -321,6 +325,9 @@ class DuckDB(Dialect): exp.DataType.Type.UINT: "UINTEGER", exp.DataType.Type.VARBINARY: "BLOB", exp.DataType.Type.VARCHAR: "TEXT", + exp.DataType.Type.TIMESTAMP_S: "TIMESTAMP_S", + exp.DataType.Type.TIMESTAMP_MS: "TIMESTAMP_MS", + exp.DataType.Type.TIMESTAMP_NS: "TIMESTAMP_NS", } STAR_MAPPING = {**generator.Generator.STAR_MAPPING, "except": "EXCLUDE"} diff --git a/sqlglot/dialects/oracle.py b/sqlglot/dialects/oracle.py index 6a007ab..6bdd8d6 100644 --- a/sqlglot/dialects/oracle.py +++ b/sqlglot/dialects/oracle.py @@ -82,7 +82,6 @@ class Oracle(Dialect): this=self._parse_format_json(self._parse_bitwise()), order=self._parse_order(), ), - "JSON_TABLE": lambda self: self._parse_json_table(), "XMLTABLE": _parse_xml_table, } @@ -96,29 +95,6 @@ class Oracle(Dialect): # Reference: https://stackoverflow.com/a/336455 DISTINCT_TOKENS = {TokenType.DISTINCT, TokenType.UNIQUE} - # Note: this is currently incomplete; it only implements the "JSON_value_column" part - def _parse_json_column_def(self) -> exp.JSONColumnDef: - this = self._parse_id_var() - kind = self._parse_types(allow_identifiers=False) - path = self._match_text_seq("PATH") and self._parse_string() - return self.expression(exp.JSONColumnDef, this=this, kind=kind, path=path) - - def _parse_json_table(self) -> exp.JSONTable: - this = self._parse_format_json(self._parse_bitwise()) - path = self._match(TokenType.COMMA) and self._parse_string() - error_handling = self._parse_on_handling("ERROR", "ERROR", "NULL") - empty_handling = self._parse_on_handling("EMPTY", "ERROR", "NULL") - self._match(TokenType.COLUMN) - expressions = self._parse_wrapped_csv(self._parse_json_column_def, optional=True) - - return exp.JSONTable( - this=this, - expressions=expressions, - path=path, - error_handling=error_handling, - empty_handling=empty_handling, - ) - def _parse_json_array(self, expr_type: t.Type[E], **kwargs) -> E: return self.expression( expr_type, diff --git a/sqlglot/dialects/presto.py b/sqlglot/dialects/presto.py index e5cfa1c..88525a2 100644 --- a/sqlglot/dialects/presto.py +++ b/sqlglot/dialects/presto.py @@ -34,7 +34,7 @@ def _approx_distinct_sql(self: Presto.Generator, expression: exp.ApproxDistinct) def _explode_to_unnest_sql(self: Presto.Generator, expression: exp.Lateral) -> str: - if isinstance(expression.this, (exp.Explode, exp.Posexplode)): + if isinstance(expression.this, exp.Explode): expression = expression.copy() return self.sql( exp.Join( diff --git a/sqlglot/dialects/redshift.py b/sqlglot/dialects/redshift.py index b70a8a1..04e78a5 100644 --- a/sqlglot/dialects/redshift.py +++ b/sqlglot/dialects/redshift.py @@ -58,6 +58,11 @@ class Redshift(Postgres): "STRTOL": exp.FromBase.from_arg_list, } + NO_PAREN_FUNCTION_PARSERS = { + **Postgres.Parser.NO_PAREN_FUNCTION_PARSERS, + "APPROXIMATE": lambda self: self._parse_approximate_count(), + } + def _parse_table( self, schema: bool = False, @@ -93,11 +98,22 @@ class Redshift(Postgres): return this - def _parse_convert(self, strict: bool) -> t.Optional[exp.Expression]: + def _parse_convert( + self, strict: bool, safe: t.Optional[bool] = None + ) -> t.Optional[exp.Expression]: to = self._parse_types() self._match(TokenType.COMMA) this = self._parse_bitwise() - return self.expression(exp.TryCast, this=this, to=to) + return self.expression(exp.TryCast, this=this, to=to, safe=safe) + + def _parse_approximate_count(self) -> t.Optional[exp.ApproxDistinct]: + index = self._index - 1 + func = self._parse_function() + + if isinstance(func, exp.Count) and isinstance(func.this, exp.Distinct): + return self.expression(exp.ApproxDistinct, this=seq_get(func.this.expressions, 0)) + self._retreat(index) + return None class Tokenizer(Postgres.Tokenizer): BIT_STRINGS = [] @@ -144,6 +160,7 @@ class Redshift(Postgres): **Postgres.Generator.TRANSFORMS, exp.Concat: concat_to_dpipe_sql, exp.ConcatWs: concat_ws_to_dpipe_sql, + exp.ApproxDistinct: lambda self, e: f"APPROXIMATE COUNT(DISTINCT {self.sql(e, 'this')})", exp.CurrentTimestamp: lambda self, e: "SYSDATE", exp.DateAdd: lambda self, e: self.func( "DATEADD", exp.var(e.text("unit") or "day"), e.expression, e.this diff --git a/sqlglot/dialects/spark.py b/sqlglot/dialects/spark.py index 2eaa2ae..8461920 100644 --- a/sqlglot/dialects/spark.py +++ b/sqlglot/dialects/spark.py @@ -76,6 +76,9 @@ class Spark(Spark2): exp.TimestampAdd: lambda self, e: self.func( "DATEADD", e.args.get("unit") or "DAY", e.expression, e.this ), + exp.TryCast: lambda self, e: self.trycast_sql(e) + if e.args.get("safe") + else self.cast_sql(e), } TRANSFORMS.pop(exp.AnyValue) TRANSFORMS.pop(exp.DateDiff) diff --git a/sqlglot/dialects/tsql.py b/sqlglot/dialects/tsql.py index d8bea6d..69adb45 100644 --- a/sqlglot/dialects/tsql.py +++ b/sqlglot/dialects/tsql.py @@ -477,7 +477,9 @@ class TSQL(Dialect): returns.set("table", table) return returns - def _parse_convert(self, strict: bool) -> t.Optional[exp.Expression]: + def _parse_convert( + self, strict: bool, safe: t.Optional[bool] = None + ) -> t.Optional[exp.Expression]: to = self._parse_types() self._match(TokenType.COMMA) this = self._parse_conjunction() @@ -513,12 +515,13 @@ class TSQL(Dialect): exp.Cast if strict else exp.TryCast, to=to, this=self.expression(exp.TimeToStr, this=this, format=format_norm), + safe=safe, ) elif to.this == DataType.Type.TEXT: return self.expression(exp.TimeToStr, this=this, format=format_norm) # Entails a simple cast without any format requirement - return self.expression(exp.Cast if strict else exp.TryCast, this=this, to=to) + return self.expression(exp.Cast if strict else exp.TryCast, this=this, to=to, safe=safe) def _parse_user_defined_function( self, kind: t.Optional[TokenType] = None |