Repository: tobymao/sqlglot

Issue:
Support Positional Addition of columns for Databricks Delta
Databricks Delta format supports positional additions of columns using `AFTER <column>` or `FIRST` (last is default). 


Discussion:

Resolving patch:
diff --git a/sqlglot/expressions.py b/sqlglot/expressions.py
--- a/sqlglot/expressions.py
+++ b/sqlglot/expressions.py
@@ -948,12 +948,17 @@ def to_dot(self) -> Dot:
         return Dot.build(parts)
 
 
+class ColumnPosition(Expression):
+    arg_types = {"this": True, "position": True}
+
+
 class ColumnDef(Expression):
     arg_types = {
         "this": True,
         "kind": False,
         "constraints": False,
         "exists": False,
+        "position": False,
     }
 
 
diff --git a/sqlglot/generator.py b/sqlglot/generator.py
--- a/sqlglot/generator.py
+++ b/sqlglot/generator.py
@@ -466,6 +466,11 @@ def column_sql(self, expression: exp.Column) -> str:
             if part
         )
 
+    def columnposition_sql(self, expression: exp.ColumnPosition) -> str:
+        this = self.sql(expression, "this")
+        position = self.sql(expression, "position")
+        return f"{position} {this}"
+
     def columndef_sql(self, expression: exp.ColumnDef) -> str:
         column = self.sql(expression, "this")
         kind = self.sql(expression, "kind")
@@ -473,8 +478,10 @@ def columndef_sql(self, expression: exp.ColumnDef) -> str:
         exists = "IF NOT EXISTS " if expression.args.get("exists") else ""
         kind = f" {kind}" if kind else ""
         constraints = f" {constraints}" if constraints else ""
+        position = self.sql(expression, "position")
+        position = f" {position}" if position else ""
 
-        return f"{exists}{column}{kind}{constraints}"
+        return f"{exists}{column}{kind}{constraints}{position}"
 
     def columnconstraint_sql(self, expression: exp.ColumnConstraint) -> str:
         this = self.sql(expression, "this")
diff --git a/sqlglot/parser.py b/sqlglot/parser.py
--- a/sqlglot/parser.py
+++ b/sqlglot/parser.py
@@ -3860,6 +3860,14 @@ def _parse_add_column(self) -> t.Optional[exp.Expression]:
         if expression:
             expression.set("exists", exists_column)
 
+            # https://docs.databricks.com/delta/update-schema.html#explicitly-update-schema-to-add-columns
+            if self._match_texts(("FIRST", "AFTER")):
+                position = self._prev.text
+                column_position = self.expression(
+                    exp.ColumnPosition, this=self._parse_column(), position=position
+                )
+                expression.set("position", column_position)
+
         return expression
 
     def _parse_drop_column(self) -> t.Optional[exp.Expression]:


Test patch:
diff --git a/tests/fixtures/identity.sql b/tests/fixtures/identity.sql
--- a/tests/fixtures/identity.sql
+++ b/tests/fixtures/identity.sql
@@ -728,6 +728,8 @@ SELECT * INTO newevent FROM event
 SELECT * INTO TEMPORARY newevent FROM event
 SELECT * INTO UNLOGGED newevent FROM event
 ALTER TABLE integers ADD COLUMN k INT
+ALTER TABLE integers ADD COLUMN k INT FIRST m
+ALTER TABLE integers ADD COLUMN k INT AFTER m
 ALTER TABLE integers ADD COLUMN IF NOT EXISTS k INT
 ALTER TABLE IF EXISTS integers ADD COLUMN k INT
 ALTER TABLE integers ADD COLUMN l INT DEFAULT 10