Repository: tobymao/sqlglot

Issue:
Add support for Microsoft SQL Server Table Variables
Greetings - apologies for not testing properly with on my prior issue :(

I've followed your steps carefully here and I am getting an error with a sql server table variable

`>>> import sqlglot
>>> 
>>> sqlglot.__version__
'10.5.2'
>>> 
>>> sql = """
... SELECT Employee_ID, Department_ID FROM @MyTableVar;
... """
>>> 
>>> print(";\n".join(sqlglot.transpile(sql, read='tsql', pretty=True)))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/alan/trash/glot/.venv/lib/python3.9/site-packages/sqlglot/__init__.py", line 121, in transpile
    for expression in parse(sql, read, error_level=error_level)
  File "/Users/alan/trash/glot/.venv/lib/python3.9/site-packages/sqlglot/__init__.py", line 57, in parse
    return dialect.parse(sql, **opts)
  File "/Users/alan/trash/glot/.venv/lib/python3.9/site-packages/sqlglot/dialects/dialect.py", line 150, in parse
    return self.parser(**opts).parse(self.tokenizer.tokenize(sql), sql)
  File "/Users/alan/trash/glot/.venv/lib/python3.9/site-packages/sqlglot/parser.py", line 670, in parse
    return self._parse(
  File "/Users/alan/trash/glot/.venv/lib/python3.9/site-packages/sqlglot/parser.py", line 732, in _parse
    expressions.append(parse_method(self))
  File "/Users/alan/trash/glot/.venv/lib/python3.9/site-packages/sqlglot/parser.py", line 882, in _parse_statement
    expression = self._parse_set_operations(expression) if expression else self._parse_select()
  File "/Users/alan/trash/glot/.venv/lib/python3.9/site-packages/sqlglot/parser.py", line 1300, in _parse_select
    from_ = self._parse_from()
  File "/Users/alan/trash/glot/.venv/lib/python3.9/site-packages/sqlglot/parser.py", line 1447, in _parse_from
    exp.From, comments=self._prev_comments, expressions=self._parse_csv(self._parse_table)
  File "/Users/alan/trash/glot/.venv/lib/python3.9/site-packages/sqlglot/parser.py", line 2885, in _parse_csv
    parse_result = parse_method()
  File "/Users/alan/trash/glot/.venv/lib/python3.9/site-packages/sqlglot/parser.py", line 1598, in _parse_table
    self.raise_error(f"Expected table name but got {self._curr}")
  File "/Users/alan/trash/glot/.venv/lib/python3.9/site-packages/sqlglot/parser.py", line 778, in raise_error
    raise error
sqlglot.errors.ParseError: Expected table name but got <Token token_type: TokenType.PARAMETER, text: @, line: 2, col: 40, comments: []>. Line 2, Col: 40.
  
SELECT Employee_ID, Department_ID FROM @MyTableVar;

>>> `

More information on tsql table variables is available here...

https://learn.microsoft.com/en-us/sql/t-sql/data-types/table-transact-sql?view=sql-server-ver16

Discussion:

Patch:
diff --git a/sqlglot/dialects/tsql.py b/sqlglot/dialects/tsql.py
index 465f5348..a1a14c0b 100644
--- a/sqlglot/dialects/tsql.py
+++ b/sqlglot/dialects/tsql.py
@@ -288,7 +288,7 @@ class TSQL(Dialect):
         }
 
         # https://learn.microsoft.com/en-us/azure/synapse-analytics/sql-data-warehouse/sql-data-warehouse-tables-temporary#create-a-temporary-table
-        TABLE_PREFIX_TOKENS = {TokenType.HASH}
+        TABLE_PREFIX_TOKENS = {TokenType.HASH, TokenType.PARAMETER}
 
         def _parse_convert(self, strict):
             to = self._parse_types()


Test patch:
diff --git a/tests/dialects/test_tsql.py b/tests/dialects/test_tsql.py
index b74c05f7..2026a176 100644
--- a/tests/dialects/test_tsql.py
+++ b/tests/dialects/test_tsql.py
@@ -5,6 +5,11 @@ class TestTSQL(Validator):
     dialect = "tsql"
 
     def test_tsql(self):
+        self.validate_identity("SELECT Employee_ID, Department_ID FROM @MyTableVar")
+        self.validate_identity("INSERT INTO @TestTable VALUES (1, 'Value1', 12, 20)")
+        self.validate_identity(
+            "SELECT x FROM @MyTableVar AS m JOIN Employee ON m.EmployeeID = Employee.EmployeeID"
+        )
         self.validate_identity('SELECT "x"."y" FROM foo')
         self.validate_identity("SELECT * FROM #foo")
         self.validate_identity("SELECT * FROM ##foo")