]> git.ipfire.org Git - thirdparty/sqlalchemy/alembic.git/commitdiff
dont compare server defaults if user FN returns non-None
authorMike Bayer <mike_mp@zzzcomputing.com>
Mon, 5 Jan 2026 19:07:38 +0000 (14:07 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 5 Jan 2026 19:07:38 +0000 (14:07 -0500)
fixed regression caused by e532a7e39cb6b0e91fbe045778f3
where we started continuing default server default comparison
even if user defined function returned False.

Fixes: #1777
Change-Id: I99fe8a10bc58a83aae1f1fae48b3b151a4db64c6

alembic/autogenerate/compare/server_defaults.py
tests/test_autogen_diffs.py

index e48f4c8edd1ea046fd7e26fb9cb51b86f03647fe..1e09e8e21ae5250dd21c49993274bad3e26c820c 100644 (file)
@@ -227,6 +227,11 @@ def _user_compare_server_default(
             cname,
         )
         return PriorityDispatchResult.STOP
+    elif is_diff is False:
+        # if user compare server_default returns False and not None,
+        # it means "dont do any more server_default comparison"
+        return PriorityDispatchResult.STOP
+
     return PriorityDispatchResult.CONTINUE
 
 
index ee99fc319b195f8f64e661d23e9adaaee4d780ea..c7dd8a3cd93561485a8dc3c09194bf73de127451 100644 (file)
@@ -884,6 +884,63 @@ class CompareServerDefaultTest(TestBase):
 
         assert not diff
 
+    @testing.combinations(
+        (False, "different", False),
+        (True, "original", True),
+        (None, "different", True),
+        id_="naa",
+        argnames="return_value,new_default,expect_diff",
+    )
+    def test_user_compare_server_default_return_values(
+        self, return_value, new_default, expect_diff, connection, metadata
+    ):
+        """Test user compare_server_default callable return values.
+
+        This is a regression test for #1777 where the plugin refactoring
+        broke the handling of False return values from user-defined
+        compare_server_default callables.
+
+        - False: stop comparison, no diff detected
+        - True: diff detected regardless of actual difference
+        - None: continue to default comparison logic
+        """
+
+        def my_compare_server_default(
+            context,
+            inspected_col,
+            metadata_col,
+            inspected_default,
+            metadata_default,
+            rendered_metadata_default,
+        ):
+            return return_value
+
+        t1 = Table(
+            "t1",
+            metadata,
+            Column("x", VARCHAR(30), server_default=text("'original'")),
+        )
+        t1.create(connection)
+
+        new_metadata = MetaData()
+        Table(
+            "t1",
+            new_metadata,
+            Column("x", VARCHAR(30), server_default=text(f"'{new_default}'")),
+        )
+
+        mc = MigrationContext.configure(
+            connection,
+            opts={"compare_server_default": my_compare_server_default},
+        )
+
+        diff = api.compare_metadata(mc, new_metadata)
+        if expect_diff:
+            eq_(len(diff), 1)
+            eq_(diff[0][0][0], "modify_default")
+        else:
+            assert not diff
+
 
 class CompareMetadataToInspectorTest(TestBase):
     __backend__ = True