nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: 3YOURMIND/django-migration-linter
Pull request #282 (2024-02-04 19:22:46)

Ignore IS NOT NULL statement.
Re-opened https://github.com/3YOURMIND/django-migration-linter/pull/273


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8383fd7..3b5ef18 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,8 @@
 ## 5.x.y
 
+Bug:
+- Don't detect 'IS NOT NULL' as backward incompatible changes (issue #263)
+
 Miscellaneous:
 
 - Migrated from `setup.py` and `setup.cfg` to `pyproject.toml`
diff --git a/src/django_migration_linter/sql_analyser/base.py b/src/django_migration_linter/sql_analyser/base.py
index 131652e..0dcd9b6 100644
--- a/src/django_migration_linter/sql_analyser/base.py
+++ b/src/django_migration_linter/sql_analyser/base.py
@@ -40,7 +40,7 @@ def has_not_null_column(sql_statements: list[str], **kwargs) -> bool:
             ends_with_default = False
     return (
         any(
-            re.search("(?<!DROP )NOT NULL", sql)
+            re.search("(?<!DROP )(?<!IS )NOT NULL", sql)
             and not (sql.startswith("CREATE TABLE") or sql.startswith("CREATE INDEX"))
             for sql in sql_statements
         )


Test patch:
diff --git a/tests/unit/test_sql_analyser.py b/tests/unit/test_sql_analyser.py
index b0a78aa..48daf0d 100644
--- a/tests/unit/test_sql_analyser.py
+++ b/tests/unit/test_sql_analyser.py
@@ -74,6 +74,12 @@ class MySqlAnalyserTestCase(SqlAnalyserTestCase):
         ]
         self.assertValidSql(sql)
 
+    def test_add_trigger(self):
+        sql = [
+            'CREATE OR REPLACE FUNCTION "public"._pgtrigger_should_ignore( trigger_name NAME ) RETURNS BOOLEAN AS $$ DECLARE _pgtrigger_ignore TEXT[]; _result BOOLEAN; BEGIN BEGIN SELECT INTO _pgtrigger_ignore CURRENT_SETTING(\'pgtrigger.ignore\'); EXCEPTION WHEN OTHERS THEN END; IF _pgtrigger_ignore IS NOT NULL THEN SELECT trigger_name = ANY(_pgtrigger_ignore) INTO _result; RETURN _result; ELSE RETURN FALSE; END IF; END; $$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION pgtrigger_update_field_5d480() RETURNS TRIGGER AS $$ BEGIN IF ("public"._pgtrigger_should_ignore(TG_NAME) IS TRUE) THEN IF (TG_OP = \'DELETE\') THEN RETURN OLD; ELSE RETURN NEW; END IF; END IF; NEW.field := 1; RETURN NEW; END; $$ LANGUAGE plpgsql; DROP TRIGGER IF EXISTS pgtrigger_update_field_5d480 ON "app_add_trigger_a"; CREATE TRIGGER pgtrigger_update_field_5d480 BEFORE UPDATE ON "app_add_trigger_a" FOR EACH ROW WHEN (OLD."field" IS NOT DISTINCT FROM NEW."field") EXECUTE PROCEDURE pgtrigger_update_field_5d480(); COMMENT ON TRIGGER pgtrigger_update_field_5d480 ON "app_add_trigger_a" IS \'8d42224131cefae42a0fa95e72ee29e16e2058ad\'; ; COMMIT;'
+        ]
+        self.assertValidSql(sql)
+
     def test_unique_together(self):
         sql = "ALTER TABLE `app_unique_together_a` ADD CONSTRAINT `app_unique_together_a_int_field_char_field_979ac7d8_uniq` UNIQUE (`int_field`, `char_field`);"
         self.assertBackwardIncompatibleSql(sql)