summaryrefslogtreecommitdiffstats
path: root/sqlglot/dialects/tsql.py
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2023-09-25 08:20:09 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2023-09-25 08:20:09 +0000
commit4554ab4c7d6b2bbbaa6f4d0b810bf477d1a505a6 (patch)
tree8f4f60a82ab9cd6dcd41397e4ecb2960c332b209 /sqlglot/dialects/tsql.py
parentReleasing debian version 18.5.1-1. (diff)
downloadsqlglot-4554ab4c7d6b2bbbaa6f4d0b810bf477d1a505a6.tar.xz
sqlglot-4554ab4c7d6b2bbbaa6f4d0b810bf477d1a505a6.zip
Merging upstream version 18.7.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sqlglot/dialects/tsql.py')
-rw-r--r--sqlglot/dialects/tsql.py38
1 files changed, 32 insertions, 6 deletions
diff --git a/sqlglot/dialects/tsql.py b/sqlglot/dialects/tsql.py
index 2299310..fa62e78 100644
--- a/sqlglot/dialects/tsql.py
+++ b/sqlglot/dialects/tsql.py
@@ -10,6 +10,7 @@ from sqlglot.dialects.dialect import (
any_value_to_max_sql,
max_or_greatest,
min_or_least,
+ move_insert_cte_sql,
parse_date_delta,
rename_func,
timestrtotime_sql,
@@ -206,6 +207,8 @@ class TSQL(Dialect):
RESOLVES_IDENTIFIERS_AS_UPPERCASE = None
NULL_ORDERING = "nulls_are_small"
TIME_FORMAT = "'yyyy-mm-dd hh:mm:ss'"
+ SUPPORTS_SEMI_ANTI_JOIN = False
+ LOG_BASE_FIRST = False
TIME_MAPPING = {
"year": "%Y",
@@ -345,6 +348,8 @@ class TSQL(Dialect):
}
class Parser(parser.Parser):
+ SET_REQUIRES_ASSIGNMENT_DELIMITER = False
+
FUNCTIONS = {
**parser.Parser.FUNCTIONS,
"CHARINDEX": lambda args: exp.StrPosition(
@@ -396,7 +401,6 @@ class TSQL(Dialect):
TokenType.END: lambda self: self._parse_command(),
}
- LOG_BASE_FIRST = False
LOG_DEFAULTS_TO_LN = True
CONCAT_NULL_OUTPUTS_STRING = True
@@ -609,11 +613,14 @@ class TSQL(Dialect):
exp.Extract: rename_func("DATEPART"),
exp.GroupConcat: _string_agg_sql,
exp.If: rename_func("IIF"),
+ exp.Insert: move_insert_cte_sql,
exp.Max: max_or_greatest,
exp.MD5: lambda self, e: self.func("HASHBYTES", exp.Literal.string("MD5"), e.this),
exp.Min: min_or_least,
exp.NumberToStr: _format_sql,
- exp.Select: transforms.preprocess([transforms.eliminate_distinct_on]),
+ exp.Select: transforms.preprocess(
+ [transforms.eliminate_distinct_on, transforms.eliminate_semi_and_anti_joins]
+ ),
exp.SHA: lambda self, e: self.func("HASHBYTES", exp.Literal.string("SHA1"), e.this),
exp.SHA2: lambda self, e: self.func(
"HASHBYTES",
@@ -632,6 +639,14 @@ class TSQL(Dialect):
exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED,
}
+ def setitem_sql(self, expression: exp.SetItem) -> str:
+ this = expression.this
+ if isinstance(this, exp.EQ) and not isinstance(this.left, exp.Parameter):
+ # T-SQL does not use '=' in SET command, except when the LHS is a variable.
+ return f"{self.sql(this.left)} {self.sql(this.right)}"
+
+ return super().setitem_sql(expression)
+
def boolean_sql(self, expression: exp.Boolean) -> str:
if type(expression.parent) in BIT_TYPES:
return "1" if expression.this else "0"
@@ -661,16 +676,27 @@ class TSQL(Dialect):
exists = expression.args.pop("exists", None)
sql = super().create_sql(expression)
+ table = expression.find(exp.Table)
+
+ if kind == "TABLE" and expression.expression:
+ sql = f"SELECT * INTO {self.sql(table)} FROM ({self.sql(expression.expression)}) AS temp"
+
if exists:
- table = expression.find(exp.Table)
identifier = self.sql(exp.Literal.string(exp.table_name(table) if table else ""))
+ sql = self.sql(exp.Literal.string(sql))
if kind == "SCHEMA":
- sql = f"""IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = {identifier}) EXEC('{sql}')"""
+ sql = f"""IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE schema_name = {identifier}) EXEC({sql})"""
elif kind == "TABLE":
- sql = f"""IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = {identifier}) EXEC('{sql}')"""
+ assert table
+ where = exp.and_(
+ exp.column("table_name").eq(table.name),
+ exp.column("table_schema").eq(table.db) if table.db else None,
+ exp.column("table_catalog").eq(table.catalog) if table.catalog else None,
+ )
+ sql = f"""IF NOT EXISTS (SELECT * FROM information_schema.tables WHERE {where}) EXEC({sql})"""
elif kind == "INDEX":
index = self.sql(exp.Literal.string(expression.this.text("this")))
- sql = f"""IF NOT EXISTS (SELECT * FROM sys.indexes WHERE object_id = object_id({identifier}) AND name = {index}) EXEC('{sql}')"""
+ sql = f"""IF NOT EXISTS (SELECT * FROM sys.indexes WHERE object_id = object_id({identifier}) AND name = {index}) EXEC({sql})"""
elif expression.args.get("replace"):
sql = sql.replace("CREATE OR REPLACE ", "CREATE OR ALTER ", 1)