summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2018-01-06 18:50:54 +0100
committerGitHub <noreply@github.com>2018-01-06 18:50:54 +0100
commit8f8a93a9ae49fa807348f9f456b6635c8ebc5d0c (patch)
tree5868485e67257c507395f1a9321cb9ddab25e313
parent777f216d555496798a1e65fd899b0f8a0349aeca (diff)
Fixed #28859 -- Made Oracle backend raise DatabaseError if "no data found" exception is hidden by the Oracle OCI library.
Thanks Tim Graham for the review and Jani Tiainen for the report.
-rw-r--r--django/db/backends/oracle/operations.py10
-rw-r--r--tests/backends/oracle/tests.py33
2 files changed, 42 insertions, 1 deletions
diff --git a/django/db/backends/oracle/operations.py b/django/db/backends/oracle/operations.py
index 1b0c6e9ed8..bea03e355e 100644
--- a/django/db/backends/oracle/operations.py
+++ b/django/db/backends/oracle/operations.py
@@ -5,6 +5,7 @@ import uuid
from django.conf import settings
from django.db.backends.base.operations import BaseDatabaseOperations
from django.db.backends.utils import strip_quotes, truncate_name
+from django.db.utils import DatabaseError
from django.utils import timezone
from django.utils.encoding import force_bytes
@@ -217,7 +218,14 @@ END;
return " DEFERRABLE INITIALLY DEFERRED"
def fetch_returned_insert_id(self, cursor):
- return int(cursor._insert_id_var.getvalue())
+ try:
+ return int(cursor._insert_id_var.getvalue())
+ except TypeError:
+ raise DatabaseError(
+ 'The database did not return a new row id. Probably "ORA-1403: '
+ 'no data found" was raised internally but was hidden by the '
+ 'Oracle OCI library (see https://code.djangoproject.com/ticket/28859).'
+ )
def field_cast_sql(self, db_type, internal_type):
if db_type and db_type.endswith('LOB'):
diff --git a/tests/backends/oracle/tests.py b/tests/backends/oracle/tests.py
index fd2435e5bb..02bcceabb4 100644
--- a/tests/backends/oracle/tests.py
+++ b/tests/backends/oracle/tests.py
@@ -2,6 +2,10 @@ import unittest
from django.db import connection
from django.db.models.fields import BooleanField, NullBooleanField
+from django.db.utils import DatabaseError
+from django.test import TransactionTestCase
+
+from ..models import Square
@unittest.skipUnless(connection.vendor == 'oracle', 'Oracle tests')
@@ -61,3 +65,32 @@ class Tests(unittest.TestCase):
with self.subTest(field=field):
field.set_attributes_from_name('is_nice')
self.assertIn('"IS_NICE" IN (0,1)', field.db_check(connection))
+
+
+@unittest.skipUnless(connection.vendor == 'oracle', 'Oracle tests')
+class HiddenNoDataFoundExceptionTest(TransactionTestCase):
+ available_apps = ['backends']
+
+ def test_hidden_no_data_found_exception(self):
+ # "ORA-1403: no data found" exception is hidden by Oracle OCI library
+ # when an INSERT statement is used with a RETURNING clause (see #28859).
+ with connection.cursor() as cursor:
+ # Create trigger that raises "ORA-1403: no data found".
+ cursor.execute("""
+ CREATE OR REPLACE TRIGGER "TRG_NO_DATA_FOUND"
+ AFTER INSERT ON "BACKENDS_SQUARE"
+ FOR EACH ROW
+ BEGIN
+ RAISE NO_DATA_FOUND;
+ END;
+ """)
+ try:
+ with self.assertRaisesMessage(DatabaseError, (
+ 'The database did not return a new row id. Probably "ORA-1403: '
+ 'no data found" was raised internally but was hidden by the '
+ 'Oracle OCI library (see https://code.djangoproject.com/ticket/28859).'
+ )):
+ Square.objects.create(root=2, square=4)
+ finally:
+ with connection.cursor() as cursor:
+ cursor.execute('DROP TRIGGER "TRG_NO_DATA_FOUND"')