Repository: tobymao/sqlglot

Issue:
TSQL Dialect Yields Invalid Syntax when Creating Indexes and Replacing Data
Creating Indexes:
`>>> sqlglot.transpile('CREATE SCHEMA IF NOT EXISTS "sqlmesh_example"', 'mysql', 'tsql')`

`['CREATE SCHEMA IF NOT EXISTS "sqlmesh_example"']`

[Docs](https://learn.microsoft.com/en-us/sql/t-sql/statements/create-schema-transact-sql?view=sql-server-ver16)

Expected result: 
`IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE SCHEMA_NAME = 'sqlmesh_example') EXEC('CREATE SCHEMA "sqlmesh_example"')`

Replacing Data:
`>>> sqlglot.transpile("""INSERT INTO "test_table" ("a", "ds") REPLACE WHERE "ds" BETWEEN '2022-01-01' AND '2022-01-02' SELECT * FROM (SELECT CAST("a" AS INTEGER) AS "a", CAST("ds" AS TEXT) AS "ds" FROM (VALUES (1, '2022-01-01'), (2, '2022-01-02')) AS "test_table"("a", "ds")) AS "_subquery" WHERE "ds" BETWEEN '2022-01-01' AND '2022-01-02'""", 'mysql', 'tsql')`

`['INSERT INTO "test_table" (\'a\', \'ds\') REPLACE WHERE \'ds\' BETWEEN \'2022-01-01\' AND \'2022-01-02\' SELECT * FROM (SELECT CAST(\'a\' AS INTEGER) AS "a", 
CAST(\'ds\' AS TEXT) AS "ds" FROM (VALUES (1, \'2022-01-01\'), (2, \'2022-01-02\')) AS "test_table"("a", "ds")) AS "_subquery" WHERE \'ds\' BETWEEN \'2022-01-01\' AND \'2022-01-02\'']`

Not sure which would be the best SQL Server flavor but here are a few docs:
[Update/Delete/Insert](https://learn.microsoft.com/en-us/sql/odbc/reference/develop-app/update-delete-and-insert-statements?view=sql-server-ver16)
[Merge](https://learn.microsoft.com/en-us/sql/t-sql/statements/merge-transact-sql?view=sql-server-ver16)
[Switch Partition](https://learn.microsoft.com/en-us/sql/t-sql/statements/alter-table-transact-sql?view=sql-server-ver16#c-switch-partitions-between-tables)

Possible expected result: 
`DELETE FROM "test_table" WHERE "ds" BETWEEN '2022-01-01' AND '2022-01-02'`

`INSERT INTO "test_table" ("a", "ds") SELECT * FROM (SELECT CAST("a" AS INTEGER) AS "a", CAST("ds" AS TEXT) AS "ds" FROM (VALUES (1, '2022-01-01'), (2, '2022-01-02')) AS "test_table"("a", "ds")) AS "_subquery" WHERE "ds" BETWEEN '2022-01-01' AND '2022-01-02'`


Discussion:
I can look into this tomorrow.

Note: `EXEC` looks a bit [iffy](https://learn.microsoft.com/en-us/sql/relational-databases/security/sql-injection?view=sql-server-ver16#reviewing-code-for-sql-injection), though I'm not sure if it's the best / only tool to use in this context.
It definitely wasn't my favorite idea but was trying to maintain the if-exists functionality without just wrapping it in a try-catch and that was the first thing that came to mind. There's probably a couple ways to make it happen but CREATE SCHEMA needs to be the first statement in a query in sql server as well.

Resolving patch:
diff --git a/sqlglot/dialects/tsql.py b/sqlglot/dialects/tsql.py
--- a/sqlglot/dialects/tsql.py
+++ b/sqlglot/dialects/tsql.py
@@ -666,6 +666,16 @@ def createable_sql(self, expression: exp.Create, locations: t.DefaultDict) -> st
 
             return sql
 
+        def create_sql(self, expression: exp.Create) -> str:
+            kind = self.sql(expression, "kind").upper()
+            exists = expression.args.get("exists")
+
+            if exists and kind == "SCHEMA":
+                schema_name = self.sql(expression, "this")
+                return f"IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE SCHEMA_NAME = {schema_name}) EXEC('CREATE SCHEMA {schema_name}')"
+
+            return super().create_sql(expression)
+
         def offset_sql(self, expression: exp.Offset) -> str:
             return f"{super().offset_sql(expression)} ROWS"
 


Test patch:
diff --git a/tests/dialects/test_tsql.py b/tests/dialects/test_tsql.py
--- a/tests/dialects/test_tsql.py
+++ b/tests/dialects/test_tsql.py
@@ -410,6 +410,12 @@ def test_types_bin(self):
         )
 
     def test_ddl(self):
+        self.validate_all(
+            "IF NOT EXISTS (SELECT * FROM information_schema.schemata WHERE SCHEMA_NAME = foo) EXEC('CREATE SCHEMA foo')",
+            read={
+                "": "CREATE SCHEMA IF NOT EXISTS foo",
+            },
+        )
         self.validate_all(
             "CREATE TABLE #mytemp (a INTEGER, b CHAR(2), c TIME(4), d FLOAT(24))",
             write={