Jelajahi Sumber

Fixed #34873 -- Added QuerySet.explain() support for GENERIC_PLAN option on PostgreSQL 16+.

Mariusz Felisiak 1 tahun lalu
induk
melakukan
f9e9526800

+ 4 - 0
django/db/backends/postgresql/features.py

@@ -134,6 +134,10 @@ class DatabaseFeatures(BaseDatabaseFeatures):
     def is_postgresql_15(self):
         return self.connection.pg_version >= 150000
 
+    @cached_property
+    def is_postgresql_16(self):
+        return self.connection.pg_version >= 160000
+
     has_bit_xor = property(operator.attrgetter("is_postgresql_14"))
     supports_covering_spgist_indexes = property(operator.attrgetter("is_postgresql_14"))
     supports_unlimited_charfield = True

+ 1 - 0
django/db/backends/postgresql/operations.py

@@ -31,6 +31,7 @@ class DatabaseOperations(BaseDatabaseOperations):
             "ANALYZE",
             "BUFFERS",
             "COSTS",
+            "GENERIC_PLAN",
             "SETTINGS",
             "SUMMARY",
             "TIMING",

+ 4 - 0
docs/ref/models/querysets.txt

@@ -3076,6 +3076,10 @@ adverse effects on your database. For example, the ``ANALYZE`` flag supported
 by MariaDB, MySQL 8.0.18+, and PostgreSQL could result in changes to data if
 there are triggers or if a function is called, even for a ``SELECT`` query.
 
+.. versionchanged:: 5.1
+
+    Support for the ``generic_plan`` option on PostgreSQL 16+ was added.
+
 .. _field-lookups:
 
 ``Field`` lookups

+ 2 - 1
docs/releases/5.1.txt

@@ -168,7 +168,8 @@ Migrations
 Models
 ~~~~~~
 
-* ...
+* :meth:`.QuerySet.explain` now supports the ``generic_plan`` option on
+  PostgreSQL 16+.
 
 Requests and Responses
 ~~~~~~~~~~~~~~~~~~~~~~

+ 2 - 0
tests/queries/test_explain.py

@@ -85,6 +85,8 @@ class ExplainTests(TestCase):
             {"settings": True},
             {"analyze": True, "wal": True},
         ]
+        if connection.features.is_postgresql_16:
+            test_options.append({"generic_plan": True})
         for options in test_options:
             with self.subTest(**options), transaction.atomic():
                 with CaptureQueriesContext(connection) as captured_queries: