]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
add predicate into dialect_options
authorTobias Pfeiffer <tgp@preferred.jp>
Tue, 15 Nov 2022 07:14:05 +0000 (16:14 +0900)
committerTobias Pfeiffer <tgp@preferred.jp>
Tue, 15 Nov 2022 07:14:05 +0000 (16:14 +0900)
lib/sqlalchemy/dialects/sqlite/base.py
test/dialect/test_sqlite.py

index 99d84ae162da07ec876e2e1866d56f5f41e2fa65..cda8c7687ea4f971dbbdaa8cfa17490ec28cc815 100644 (file)
@@ -2643,6 +2643,20 @@ class SQLiteDialect(default.DefaultDialect):
         )
         indexes = []
 
+        # regular expression to extract the filter predicate of a partial index.
+        # this could fail to extract the predicate correctly on indexes created like
+        #   CREATE INDEX i ON t (col || ') where') WHERE col <> ''
+        # but as this function does not support expression-based indexes this case
+        # does not occur.
+        partial_pred_re = re.compile(r"\)\s+where\s+(.+)", re.IGNORECASE)
+
+        if schema:
+            schema_expr = "%s." % self.identifier_preparer.quote_identifier(
+                schema
+            )
+        else:
+            schema_expr = ""
+
         include_auto_indexes = kw.pop("include_auto_indexes", False)
         for row in pragma_indexes:
             # ignore implicit primary key index.
@@ -2653,10 +2667,25 @@ class SQLiteDialect(default.DefaultDialect):
                 continue
             indexes.append(
                 dict(
-                    name=row[1], column_names=[], unique=row[2], partial=row[4]
+                    name=row[1],
+                    column_names=[],
+                    unique=row[2],
+                    dialect_options={},
                 )
             )
 
+            # check partial indexes
+            if row[4]:
+                s = (
+                    "SELECT sql FROM %(schema)ssqlite_master "
+                    "WHERE name = ? "
+                    "AND type = 'index'" % {"schema": schema_expr}
+                )
+                rs = connection.exec_driver_sql(s, (row[1],))
+                index_sql = rs.scalar()
+                predicate = partial_pred_re.search(index_sql).group(1)
+                indexes[-1]["dialect_options"]["sqlite_where"] = predicate
+
         # loop thru unique indexes to get the column names.
         for idx in list(indexes):
             pragma_index = self._get_table_pragma(
@@ -2673,6 +2702,7 @@ class SQLiteDialect(default.DefaultDialect):
                     break
                 else:
                     idx["column_names"].append(row[2])
+
         indexes.sort(key=lambda d: d["name"] or "~")  # sort None as last
         if indexes:
             return indexes
index 1d88f49459a3790ec6484bedd4c4c1ebc2dd11d1..a5e24b382da13ad4a8b1ec40b44ce111a6183af3 100644 (file)
@@ -2282,7 +2282,7 @@ class ConstraintReflectionTest(fixtures.TestBase):
                     "unique": 1,
                     "name": "sqlite_autoindex_o_1",
                     "column_names": ["foo"],
-                    "partial": False,
+                    "dialect_options": {},
                 }
             ],
         )
@@ -2298,7 +2298,7 @@ class ConstraintReflectionTest(fixtures.TestBase):
                     "unique": 0,
                     "name": "ix_main_l_bar",
                     "column_names": ["bar"],
-                    "partial": False,
+                    "dialect_options": {},
                 }
             ],
         )
@@ -2323,13 +2323,13 @@ class ConstraintReflectionTest(fixtures.TestBase):
                         "unique": 1,
                         "name": "ix_no_partial",
                         "column_names": ["x"],
-                        "partial": False,
+                        "dialect_options": {},
                     },
                     {
                         "unique": 1,
                         "name": "ix_partial",
                         "column_names": ["x"],
-                        "partial": True,
+                        "dialect_options": {"sqlite_where": "y > 10"},
                     },
                 ],
             )