Skip to content

Commit 0495841

Browse files
Raise error "DPY-2016: variable array size of %d is too small (should be
at least %d)" consistently when executemany() is called with an integer number of iterations that is too large for the existing bind variables.
1 parent d18544b commit 0495841

File tree

4 files changed

+40
-0
lines changed

4 files changed

+40
-0
lines changed

doc/src/release_notes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ Common Changes
6666
:data:`Cursor.arraysize`. Previously a variety of errors (``TypeError``,
6767
``OverflowError`` or ``ORA-03147: missing mandatory TTC field``) were
6868
raised.
69+
#) Error ``DPY-2016: variable array size of %d is too small (should be at
70+
least %d)`` is now raised when :meth:`Cursor.executemany()` is called with
71+
an integer number of iterations that is too large for the existing bind
72+
variables. Previously thin mode raised ``IndexError`` and thick mode raised
73+
``DPI-1018: array size of %d is too small``.
6974
#) Error ``DPY-1001: not connected to database`` is now raised when an attempt
7075
is made to perform an operation on a LOB using a closed connection.
7176
Previously Thin mode would raise an ``AttributeError`` exception and Thick

src/oracledb/base_impl.pxd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,7 @@ cdef class BaseCursorImpl:
509509
object params, uint32_t num_rows,
510510
uint32_t row_num,
511511
bint defer_type_assignment) except -1
512+
cdef int _check_binds(self, uint32_t num_execs) except -1
512513
cdef int _close(self, bint in_del) except -1
513514
cdef BaseVarImpl _create_fetch_var(self, object conn, object cursor,
514515
object type_handler, bint

src/oracledb/impl/base/cursor.pyx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,20 @@ cdef class BaseCursorImpl:
139139
return json.loads(value)
140140
return converter
141141

142+
cdef int _check_binds(self, uint32_t num_execs) except -1:
143+
"""
144+
Checks that all binds are capable of handling the number of executions
145+
provided.
146+
"""
147+
cdef BindVar bind_var
148+
for bind_var in self.bind_vars:
149+
if bind_var is None or bind_var.var_impl is None:
150+
continue
151+
if bind_var.var_impl.num_elements < num_execs:
152+
errors._raise_err(errors.ERR_INCORRECT_VAR_ARRAYSIZE,
153+
var_arraysize=bind_var.var_impl.num_elements,
154+
required_arraysize=num_execs)
155+
142156
cdef int _close(self, bint in_del) except -1:
143157
"""
144158
Internal method for closing the cursor.
@@ -411,6 +425,8 @@ cdef class BaseCursorImpl:
411425
self.set_input_sizes = False
412426
if isinstance(parameters, int):
413427
num_execs = parameters
428+
if self.bind_vars is not None:
429+
self._check_binds(num_execs)
414430
elif isinstance(parameters, list):
415431
num_execs = len(parameters)
416432
if parameters:

tests/test_4000_cursor_executemany.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,24 @@ def test_4026(self):
429429
(error_obj,) = cm.exception.args
430430
self.assertEqual(error_obj.offset, 3)
431431

432+
def test_4027(self):
433+
"4027 - test executemany with number of iterations too small"
434+
data = [[1], [2], [3]]
435+
self.cursor.execute("truncate table TestTempTable")
436+
self.cursor.executemany(
437+
"""
438+
declare
439+
t_Value number;
440+
begin
441+
t_Value := :1;
442+
end;
443+
""",
444+
data,
445+
)
446+
self.cursor.executemany(None, 2)
447+
with self.assertRaisesFullCode("DPY-2016"):
448+
self.cursor.executemany(None, 4)
449+
432450

433451
if __name__ == "__main__":
434452
test_env.run_test_cases()

0 commit comments

Comments
 (0)