Repository: tobymao/sqlglot

Issue:
sqlglot.diff Bug for exp.Window Differences
The following statements are considered equal by `sqlglot.diff`.

However, one is `OVER`, while the other is `KEEP DENSE_RANK`, and thus these should not be considered semantically identical.

```
import sqlglot


parsed = sqlglot.parse_one(
    '''
        SELECT MAX(foo) OVER (
            ORDER BY bar
        )
        FROM baz
    ''',
    dialect='oracle'
)

parsed2 = sqlglot.parse_one(
    '''
        SELECT MAX(foo) KEEP (
            DENSE_RANK LAST
            ORDER BY bar
        )
        FROM baz
    ''',
    dialect='oracle'
)

diffs = sqlglot.diff(parsed, parsed2)

from sqlglot.diff import Keep

# This should fail but does not.
assert all(isinstance(diff, Keep) for diff in diffs)
```

Discussion:

Patch:
diff --git a/sqlglot/diff.py b/sqlglot/diff.py
index 5ebc682e..eaca8b8a 100644
--- a/sqlglot/diff.py
+++ b/sqlglot/diff.py
@@ -129,12 +129,14 @@ def diff(
 
 # The expression types for which Update edits are allowed.
 UPDATABLE_EXPRESSION_TYPES = (
+    exp.Alias,
     exp.Boolean,
+    exp.Column,
     exp.DataType,
+    exp.Lambda,
     exp.Literal,
     exp.Table,
-    exp.Column,
-    exp.Lambda,
+    exp.Window,
 )
 
 IGNORED_LEAF_EXPRESSION_TYPES = (exp.Identifier,)


Test patch:
diff --git a/tests/test_diff.py b/tests/test_diff.py
index f83c805a..a8345232 100644
--- a/tests/test_diff.py
+++ b/tests/test_diff.py
@@ -157,11 +157,20 @@ class TestDiff(unittest.TestCase):
         self._validate_delta_only(
             diff_delta_only(expr_src, expr_tgt),
             [
-                Remove(parse_one("ROW_NUMBER()")),  # the Anonymous node
-                Insert(parse_one("RANK()")),  # the Anonymous node
+                Remove(parse_one("ROW_NUMBER()")),
+                Insert(parse_one("RANK()")),
+                Update(source=expr_src.selects[0], target=expr_tgt.selects[0]),
             ],
         )
 
+        expr_src = parse_one("SELECT MAX(x) OVER (ORDER BY y) FROM z", "oracle")
+        expr_tgt = parse_one("SELECT MAX(x) KEEP (DENSE_RANK LAST ORDER BY y) FROM z", "oracle")
+
+        self._validate_delta_only(
+            diff_delta_only(expr_src, expr_tgt),
+            [Update(source=expr_src.selects[0], target=expr_tgt.selects[0])],
+        )
+
     def test_pre_matchings(self):
         expr_src = parse_one("SELECT 1")
         expr_tgt = parse_one("SELECT 1, 2, 3, 4")
@@ -202,5 +211,19 @@ class TestDiff(unittest.TestCase):
             ],
         )
 
+        expr_src = parse_one("SELECT 1 AS c1, 2 AS c2")
+        expr_tgt = parse_one("SELECT 2 AS c1, 3 AS c2")
+
+        self._validate_delta_only(
+            diff_delta_only(expr_src, expr_tgt),
+            [
+                Remove(expression=exp.alias_(1, "c1")),
+                Remove(expression=exp.Literal.number(1)),
+                Insert(expression=exp.alias_(3, "c2")),
+                Insert(expression=exp.Literal.number(3)),
+                Update(source=exp.alias_(2, "c2"), target=exp.alias_(2, "c1")),
+            ],
+        )
+
     def _validate_delta_only(self, actual_delta, expected_delta):
         self.assertEqual(set(actual_delta), set(expected_delta))