]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Update SQLite unique constraint parser to handle tabs 11759/head
authorJohn A Stevenson <jostev@bgs.ac.uk>
Mon, 19 Aug 2024 16:59:36 +0000 (17:59 +0100)
committerJohn A Stevenson <jostev@bgs.ac.uk>
Mon, 26 Aug 2024 14:47:20 +0000 (15:47 +0100)
Fixes: #11746
Sometimes the whitespace between fields in a column definition in SQLite
can be tabs instead of spaces, particularly between the column name and
the type definition.  This commit updates the regular expression used to
detect UNIQUE constraints so that it handles this situation.

lib/sqlalchemy/dialects/sqlite/base.py
test/dialect/test_sqlite.py

index a678e10940c448de07de3cbc871bd62556478da1..cf8f16966bae64f6aaef9c41aec50e719ed796eb 100644 (file)
@@ -2588,8 +2588,8 @@ class SQLiteDialect(default.DefaultDialect):
                 return
             UNIQUE_PATTERN = r'(?:CONSTRAINT "?(.+?)"? +)?UNIQUE *\((.+?)\)'
             INLINE_UNIQUE_PATTERN = (
-                r'(?:(".+?")|(?:[\[`])?([a-z0-9_]+)(?:[\]`])?) '
-                r"+[a-z0-9_ ]+? +UNIQUE"
+                r'(?:(".+?")|(?:[\[`])?([a-z0-9_]+)(?:[\]`])?)[\t ]'
+                r"+[a-z0-9_ ]+?[\t ]+UNIQUE"
             )
 
             for match in re.finditer(UNIQUE_PATTERN, table_data, re.I):
index b137c0579f4674809d3a11b6d2f75502bec63ee1..8afa80053034568e474ddca2d3201d8d2aa57ee1 100644 (file)
@@ -2503,17 +2503,27 @@ class ConstraintReflectionTest(fixtures.TestBase):
         argnames="colname,expected",
     )
     @testing.combinations(
-        "uq", "uq_inline", "pk", "ix", argnames="constraint_type"
+        "uq",
+        "uq_inline",
+        "uq_inline_tab_before",  # tab before column params
+        "uq_inline_tab_within",  # tab within column params
+        "pk",
+        "ix",
+        argnames="constraint_type",
     )
     def test_constraint_cols(
         self, colname, expected, constraint_type, connection, metadata
     ):
-        if constraint_type == "uq_inline":
+        if constraint_type.startswith("uq_inline"):
+            inline_create_sql = {
+                "uq_inline": "CREATE TABLE t (%s INTEGER UNIQUE)",
+                "uq_inline_tab_before": "CREATE TABLE t (%s\tINTEGER UNIQUE)",
+                "uq_inline_tab_within": "CREATE TABLE t (%s INTEGER\tUNIQUE)",
+            }
+
             t = Table("t", metadata, Column(colname, Integer))
             connection.exec_driver_sql(
-                """
-            CREATE TABLE t (%s INTEGER UNIQUE)
-            """
+                inline_create_sql[constraint_type]
                 % connection.dialect.identifier_preparer.quote(colname)
             )
         else:
@@ -2531,7 +2541,12 @@ class ConstraintReflectionTest(fixtures.TestBase):
 
             t.create(connection)
 
-        if constraint_type in ("uq", "uq_inline"):
+        if constraint_type in (
+            "uq",
+            "uq_inline",
+            "uq_inline_tab_before",
+            "uq_inline_tab_within",
+        ):
             const = inspect(connection).get_unique_constraints("t")[0]
             eq_(const["column_names"], [expected])
         elif constraint_type == "pk":