Skip to content

Commit 5c2aefb

Browse files
Raise meaningful error when maximum size of a direct path load is exceeded.
1 parent 1e93cf2 commit 5c2aefb

File tree

3 files changed

+13
-4
lines changed

3 files changed

+13
-4
lines changed

src/oracledb/errors.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ def _raise_not_supported(feature: str) -> None:
373373
ERR_INVALID_INTEGER = 4038
374374
ERR_CANNOT_CONVERT_TO_ARROW_FLOAT = 4039
375375
ERR_ARROW_FIXED_SIZE_BINARY_VIOLATED = 4040
376+
ERR_DPL_TOO_MUCH_DATA = 4041
376377

377378
# error numbers that result in InternalError
378379
ERR_MESSAGE_TYPE_UNKNOWN = 5000
@@ -650,6 +651,9 @@ def _raise_not_supported(feature: str) -> None:
650651
'the bind variable placeholder ":{name}" cannot be used both before '
651652
"and after the RETURNING clause in a DML RETURNING statement"
652653
),
654+
ERR_DPL_TOO_MUCH_DATA: (
655+
"the maximum size of a Direct Path load has been exceeded"
656+
),
653657
ERR_DUPLICATED_PARAMETER: (
654658
'"{deprecated_name}" and "{new_name}" cannot be specified together'
655659
),

src/oracledb/impl/thin/constants.pxi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,7 @@ cdef enum:
625625

626626
# other direct path load stream constants
627627
cdef enum:
628+
TNS_DPLS_MAX_MESSAGE_SIZE = 1_073_728_895
628629
TNS_DPLS_MAX_SHORT_LENGTH = 0xfa
629630
TNS_DPLS_MAX_PIECE_SIZE = 0xfff0
630631
TNS_DPLS_FAST_HEADER_SIZE = 4

src/oracledb/impl/thin/messages/direct_path_load_stream.pyx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ cdef class DirectPathPiece:
4040
bint is_split_with_next
4141
uint8_t flags
4242
uint8_t num_segments
43-
uint32_t length
43+
ssize_t length
4444
bytes data
4545

4646
cdef int finalize(self, PieceBuffer buf) except -1:
@@ -62,11 +62,11 @@ cdef class DirectPathPiece:
6262
self.flags |= TNS_DPLS_ROW_HEADER_FAST_ROW
6363
self.flags |= TNS_DPLS_ROW_HEADER_FAST_PIECE
6464

65-
cdef uint32_t header_length(self):
65+
cdef uint8_t header_length(self):
6666
"""
6767
Returns the length of the piece header.
6868
"""
69-
cdef uint32_t length = 2
69+
cdef uint8_t length = 2
7070
if self.is_fast_row():
7171
length += 2
7272
return length
@@ -101,10 +101,14 @@ cdef class PieceBuffer(Buffer):
101101
Finalizes the piece by adding the data in the buffer and calculating
102102
the piece length, then resetting the buffer.
103103
"""
104+
cdef uint64_t new_length
104105
self.current_piece.finalize(self)
105106
self.pieces.append(self.current_piece)
106-
self.total_piece_length += \
107+
new_length = (<uint64_t> self.total_piece_length) + \
107108
self.current_piece.length + self.current_piece.header_length()
109+
if new_length > TNS_DPLS_MAX_MESSAGE_SIZE:
110+
errors._raise_err(errors.ERR_DPL_TOO_MUCH_DATA)
111+
self.total_piece_length = <uint32_t> new_length
108112

109113
cdef int _write_more_data(self, ssize_t num_bytes_available,
110114
ssize_t num_bytes_wanted) except -1:

0 commit comments

Comments
 (0)