🌐 AI搜索 & 代理 主页
Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Refs #36112 -- Added proper fallback regression test for Oracle last_…
…executed_query().
  • Loading branch information
VIZZARD-X committed Nov 27, 2025
commit 691979d86a85648ee2a6099f89076036dd148ee6
6 changes: 3 additions & 3 deletions django/db/backends/postgresql/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,11 +302,11 @@ def last_executed_query(self, cursor, sql, params):
try:
return self.compose_sql(sql, params)
except errors.DataError:
return None
return super().last_executed_query(cursor, sql, params)
else:
if cursor._query and cursor._query.query is not None:
return cursor._query.query.decode()
return None
return super().last_executed_query(cursor, sql, params)

else:

Expand All @@ -315,7 +315,7 @@ def last_executed_query(self, cursor, sql, params):
# The query attribute is a Psycopg extension to the DB API 2.0.
if cursor.query is not None:
return cursor.query.decode()
return None
return super().last_executed_query(cursor, sql, params)

if is_psycopg3:

Expand Down
32 changes: 0 additions & 32 deletions tests/backends/base/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

from django.db import DEFAULT_DB_ALIAS, connection, connections, transaction
from django.db.backends.base.base import BaseDatabaseWrapper
from django.db.backends.base.operations import BaseDatabaseOperations
from django.test import (
SimpleTestCase,
TestCase,
Expand Down Expand Up @@ -437,34 +436,3 @@ def test_multi_database_init_connection_state_called_once(self):
len(mocked_check_database_version_supported.mock_calls),
after_first_calls,
)


class DummyCursor:
def __init__(self, statement=None):
self.statement = statement


class DummyConnection:
vendor = "sqlite"
alias = "default"
features = MagicMock()
settings_dict = {}

def __init__(self):
self.ops = DummyBackendOperations(self)
self.queries_log = []


class DummyBackendOperations(BaseDatabaseOperations):
"""
Simulates a backend with the fallback behavior implemented in the patch:
- If cursor.statement is truthy, return it.
- If cursor.statement is None, fallback to the base implementation.
"""

def __init__(self, connection):
super().__init__(connection)

def last_executed_query(self, cursor, sql, params):
statement = getattr(cursor, "statement", None)
return statement or super().last_executed_query(cursor, sql, params)
21 changes: 21 additions & 0 deletions tests/backends/oracle/test_last_executed_query.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from django.db import connection
from django.test import TestCase
from django.test.utils import skipUnless


@skipUnless(connection.vendor == "oracle", "Oracle-specific tests")
class TestLastExecutedQueryFallback(TestCase):
def test_last_executed_query_fallback(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I'm aware, this test should pass for all database backends, so we can move it to the
tests.backends.base.test_operations.DatabaseOperationTests class.

# Use a real Oracle cursor and force an error
with connection.cursor() as cursor:
sql = "INVALID SQL"
params = []
try:
cursor.execute(sql, params)
except Exception:
pass

# The result MUST NOT be None and MUST fall back to the SQL string
result = connection.ops.last_executed_query(cursor, sql, params)
self.assertIsNotNone(result)
self.assertEqual(result, sql)
Comment on lines +20 to +21
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assertIsNotNone is redundant

Suggested change
self.assertIsNotNone(result)
self.assertEqual(result, sql)
self.assertEqual(result, sql)

21 changes: 21 additions & 0 deletions tests/backends/postgresql/test_last_executed_query.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from django.db import connection
from django.test import TestCase
from django.test.utils import skipUnless


@skipUnless(connection.vendor == "postgresql", "PostgreSQL-specific tests")
class TestLastExecutedQueryFallback(TestCase):
def test_last_executed_query_fallback(self):
# Use a real PostgreSQL cursor and force an error
with connection.cursor() as cursor:
sql = "INVALID SQL"
params = []
try:
cursor.execute(sql, params)
except Exception:
pass

# The result MUST NOT be None and MUST fall back to the SQL string
result = connection.ops.last_executed_query(cursor, sql, params)
self.assertIsNotNone(result)
self.assertEqual(result, sql)