Skip to content

Commit 102b946

Browse files
Fixed bug when calling Cursor.executemany() with the "batcherrors"
parameter set to True multiple times with each call resulting in at least one batch error.
1 parent 08f2b7d commit 102b946

File tree

4 files changed

+36
-3
lines changed

4 files changed

+36
-3
lines changed

doc/src/release_notes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ Thin Mode Changes
3939
actual components being used. This is important for some configurations.
4040
#) Fixed bug resulting in an internal protocol error when handling database
4141
responses.
42+
#) Fixed bug when calling :meth:`Cursor.executemany()` with the `batcherrors`
43+
parameter set to `True` multiple times with each call resulting in at least
44+
one batch error.
4245

4346
Thick Mode Changes
4447
++++++++++++++++++

src/oracledb/impl/thin/constants.pxi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,7 @@ DEF TNS_ERR_INVALID_SERVICE_NAME = 12514
379379
DEF TNS_ERR_INVALID_SID = 12505
380380
DEF TNS_ERR_NO_DATA_FOUND = 1403
381381
DEF TNS_ERR_SESSION_SHUTDOWN = 12572
382+
DEF TNS_ERR_ARRAY_DML_ERRORS = 24381
382383

383384
# message types
384385
DEF TNS_MSG_TYPE_PROTOCOL = 1

src/oracledb/impl/thin/messages.pyx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,9 @@ cdef class MessageWithData(Message):
750750
self.error_info.num = 0
751751
cursor_impl._more_rows_to_fetch = False
752752
self.error_occurred = False
753+
elif self.error_info.num == TNS_ERR_ARRAY_DML_ERRORS:
754+
self.error_info.num = 0
755+
self.error_occurred = False
753756
elif self.error_info.num == TNS_ERR_VAR_NOT_IN_SELECT_LIST:
754757
conn_impl._add_cursor_to_close(cursor_impl._statement)
755758
cursor_impl._statement._cursor_id = 0
@@ -758,8 +761,6 @@ cdef class MessageWithData(Message):
758761
if exc_type is not exceptions.IntegrityError:
759762
conn_impl._add_cursor_to_close(cursor_impl._statement)
760763
cursor_impl._statement._cursor_id = 0
761-
if self.error_info.batcherrors is not None:
762-
self.error_occurred = False
763764

764765
cdef int _process_implicit_result(self, ReadBuffer buf) except -1:
765766
cdef:
@@ -1950,7 +1951,8 @@ cdef class ExecuteMessage(MessageWithData):
19501951
cdef:
19511952
Statement stmt = self.cursor_impl._statement
19521953
if stmt._cursor_id != 0 and not stmt._requires_full_execute \
1953-
and not self.parse_only and not stmt._is_ddl:
1954+
and not self.parse_only and not stmt._is_ddl \
1955+
and not self.batcherrors:
19541956
if stmt._is_query and not stmt._requires_define \
19551957
and self.cursor_impl.prefetchrows > 0:
19561958
self.function_code = TNS_FUNC_REEXECUTE_AND_FETCH

tests/test_3200_features_12_1.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,5 +512,32 @@ def test_3226_batch_error_no_errors(self):
512512
self.cursor.executemany(sql, rows, batcherrors=True)
513513
self.assertEqual(self.cursor.getbatcherrors(), [])
514514

515+
def test_3227_batch_error_multiple_execute(self):
516+
"3227 - test batcherrors mode with multiple executes"
517+
self.cursor.execute("truncate table TestArrayDML")
518+
rows_1 = [
519+
(1, "Value 1", 100),
520+
(2, "Value 2", 200),
521+
(2, "Value 2", 200)
522+
]
523+
rows_2 = [
524+
(3, "Value 3", 300),
525+
(3, "Value 3", 300),
526+
(4, "Value 4", 400)
527+
]
528+
sql = """
529+
insert into TestArrayDML (IntCol, StringCol, IntCol2)
530+
values (:1, :2, :3)"""
531+
self.cursor.executemany(sql, rows_1, batcherrors=True)
532+
expected_errors = [(2, "ORA-00001")]
533+
actual_errors = [(e.offset, e.full_code) \
534+
for e in self.cursor.getbatcherrors()]
535+
self.assertEqual(actual_errors, expected_errors)
536+
self.cursor.executemany(sql, rows_2, batcherrors=True)
537+
expected_errors = [(1, "ORA-00001")]
538+
actual_errors = [(e.offset, e.full_code) \
539+
for e in self.cursor.getbatcherrors()]
540+
self.assertEqual(actual_errors, expected_errors)
541+
515542
if __name__ == "__main__":
516543
test_env.run_test_cases()

0 commit comments

Comments
 (0)