summaryrefslogtreecommitdiffstats
path: root/sqlglot/dialects
diff options
context:
space:
mode:
Diffstat (limited to 'sqlglot/dialects')
-rw-r--r--sqlglot/dialects/__init__.py1
-rw-r--r--sqlglot/dialects/dialect.py19
-rw-r--r--sqlglot/dialects/duckdb.py2
-rw-r--r--sqlglot/dialects/snowflake.py20
-rw-r--r--sqlglot/dialects/spark.py1
-rw-r--r--sqlglot/dialects/tsql.py38
6 files changed, 77 insertions, 4 deletions
diff --git a/sqlglot/dialects/__init__.py b/sqlglot/dialects/__init__.py
index f7d03ad..0f80723 100644
--- a/sqlglot/dialects/__init__.py
+++ b/sqlglot/dialects/__init__.py
@@ -14,3 +14,4 @@ from sqlglot.dialects.sqlite import SQLite
from sqlglot.dialects.starrocks import StarRocks
from sqlglot.dialects.tableau import Tableau
from sqlglot.dialects.trino import Trino
+from sqlglot.dialects.tsql import TSQL
diff --git a/sqlglot/dialects/dialect.py b/sqlglot/dialects/dialect.py
index f338c81..0120e71 100644
--- a/sqlglot/dialects/dialect.py
+++ b/sqlglot/dialects/dialect.py
@@ -27,6 +27,7 @@ class Dialects(str, Enum):
STARROCKS = "starrocks"
TABLEAU = "tableau"
TRINO = "trino"
+ TSQL = "tsql"
class _Dialect(type):
@@ -53,7 +54,6 @@ class _Dialect(type):
klass.parser_class = getattr(klass, "Parser", Parser)
klass.generator_class = getattr(klass, "Generator", Generator)
- klass.tokenizer = klass.tokenizer_class()
klass.quote_start, klass.quote_end = list(klass.tokenizer_class._QUOTES.items())[0]
klass.identifier_start, klass.identifier_end = list(klass.tokenizer_class._IDENTIFIERS.items())[0]
@@ -95,7 +95,6 @@ class Dialect(metaclass=_Dialect):
tokenizer_class = None
parser_class = None
generator_class = None
- tokenizer = None
@classmethod
def get_or_raise(cls, dialect):
@@ -138,6 +137,12 @@ class Dialect(metaclass=_Dialect):
def transpile(self, code, **opts):
return self.generate(self.parse(code), **opts)
+ @property
+ def tokenizer(self):
+ if not hasattr(self, "_tokenizer"):
+ self._tokenizer = self.tokenizer_class()
+ return self._tokenizer
+
def parser(self, **opts):
return self.parser_class(
**{
@@ -170,7 +175,15 @@ class Dialect(metaclass=_Dialect):
def rename_func(name):
- return lambda self, expression: f"{name}({csv(*[self.sql(e) for e in expression.args.values()])})"
+ def _rename(self, expression):
+ args = (
+ self.expressions(expression, flat=True)
+ if isinstance(expression, exp.Func) and expression.is_var_len_args
+ else csv(*[self.sql(e) for e in expression.args.values()])
+ )
+ return f"{name}({args})"
+
+ return _rename
def approx_count_distinct_sql(self, expression):
diff --git a/sqlglot/dialects/duckdb.py b/sqlglot/dialects/duckdb.py
index ff3a8b1..4ca9e84 100644
--- a/sqlglot/dialects/duckdb.py
+++ b/sqlglot/dialects/duckdb.py
@@ -108,7 +108,7 @@ class DuckDB(Dialect):
TRANSFORMS = {
**Generator.TRANSFORMS,
exp.ApproxDistinct: approx_count_distinct_sql,
- exp.Array: lambda self, e: f"LIST_VALUE({self.expressions(e, flat=True)})",
+ exp.Array: rename_func("LIST_VALUE"),
exp.ArraySize: rename_func("ARRAY_LENGTH"),
exp.ArraySort: _array_sort_sql,
exp.ArraySum: rename_func("LIST_SUM"),
diff --git a/sqlglot/dialects/snowflake.py b/sqlglot/dialects/snowflake.py
index 8d6ee78..b5d4f0a 100644
--- a/sqlglot/dialects/snowflake.py
+++ b/sqlglot/dialects/snowflake.py
@@ -106,6 +106,11 @@ class Snowflake(Dialect):
"TO_TIMESTAMP": _snowflake_to_timestamp,
}
+ FUNCTION_PARSERS = {
+ **Parser.FUNCTION_PARSERS,
+ "DATE_PART": lambda self: self._parse_extract(),
+ }
+
COLUMN_OPERATORS = {
**Parser.COLUMN_OPERATORS,
TokenType.COLON: lambda self, this, path: self.expression(
@@ -118,10 +123,20 @@ class Snowflake(Dialect):
class Tokenizer(Tokenizer):
QUOTES = ["'", "$$"]
ESCAPE = "\\"
+
+ SINGLE_TOKENS = {
+ **Tokenizer.SINGLE_TOKENS,
+ "$": TokenType.DOLLAR, # needed to break for quotes
+ }
+
KEYWORDS = {
**Tokenizer.KEYWORDS,
"QUALIFY": TokenType.QUALIFY,
"DOUBLE PRECISION": TokenType.DOUBLE,
+ "TIMESTAMP_LTZ": TokenType.TIMESTAMPLTZ,
+ "TIMESTAMP_NTZ": TokenType.TIMESTAMP,
+ "TIMESTAMP_TZ": TokenType.TIMESTAMPTZ,
+ "TIMESTAMPNTZ": TokenType.TIMESTAMP,
}
class Generator(Generator):
@@ -132,6 +147,11 @@ class Snowflake(Dialect):
exp.UnixToTime: _unix_to_time,
}
+ TYPE_MAPPING = {
+ **Generator.TYPE_MAPPING,
+ exp.DataType.Type.TIMESTAMP: "TIMESTAMPNTZ",
+ }
+
def except_op(self, expression):
if not expression.args.get("distinct", False):
self.unsupported("EXCEPT with All is not supported in Snowflake")
diff --git a/sqlglot/dialects/spark.py b/sqlglot/dialects/spark.py
index a331191..c051178 100644
--- a/sqlglot/dialects/spark.py
+++ b/sqlglot/dialects/spark.py
@@ -82,6 +82,7 @@ class Spark(Hive):
TRANSFORMS = {
**{k: v for k, v in Hive.Generator.TRANSFORMS.items() if k not in {exp.ArraySort}},
+ exp.FileFormatProperty: lambda self, e: f"USING {e.text('value').upper()}",
exp.ArraySum: lambda self, e: f"AGGREGATE({self.sql(e, 'this')}, 0, (acc, x) -> acc + x, acc -> acc)",
exp.BitwiseLeftShift: rename_func("SHIFTLEFT"),
exp.BitwiseRightShift: rename_func("SHIFTRIGHT"),
diff --git a/sqlglot/dialects/tsql.py b/sqlglot/dialects/tsql.py
new file mode 100644
index 0000000..68bb9bd
--- /dev/null
+++ b/sqlglot/dialects/tsql.py
@@ -0,0 +1,38 @@
+from sqlglot import exp
+from sqlglot.dialects.dialect import Dialect
+from sqlglot.generator import Generator
+from sqlglot.tokens import Tokenizer, TokenType
+
+
+class TSQL(Dialect):
+ null_ordering = "nulls_are_small"
+ time_format = "'yyyy-mm-dd hh:mm:ss'"
+
+ class Tokenizer(Tokenizer):
+ IDENTIFIERS = ['"', ("[", "]")]
+
+ KEYWORDS = {
+ **Tokenizer.KEYWORDS,
+ "BIT": TokenType.BOOLEAN,
+ "REAL": TokenType.FLOAT,
+ "NTEXT": TokenType.TEXT,
+ "SMALLDATETIME": TokenType.DATETIME,
+ "DATETIMEOFFSET": TokenType.TIMESTAMPTZ,
+ "TIME": TokenType.TIMESTAMP,
+ "VARBINARY": TokenType.BINARY,
+ "IMAGE": TokenType.IMAGE,
+ "MONEY": TokenType.MONEY,
+ "SMALLMONEY": TokenType.SMALLMONEY,
+ "ROWVERSION": TokenType.ROWVERSION,
+ "SQL_VARIANT": TokenType.SQL_VARIANT,
+ "UNIQUEIDENTIFIER": TokenType.UNIQUEIDENTIFIER,
+ "XML": TokenType.XML,
+ }
+
+ class Generator(Generator):
+ TYPE_MAPPING = {
+ **Generator.TYPE_MAPPING,
+ exp.DataType.Type.BOOLEAN: "BIT",
+ exp.DataType.Type.INT: "INTEGER",
+ exp.DataType.Type.DECIMAL: "NUMERIC",
+ }