Skip to content

Commit 3a9c365

Browse files
Internal change: further efforts to tighten code looking for the end of
a database request made to Oracle Database 23c.
1 parent e297ae9 commit 3a9c365

File tree

4 files changed

+37
-30
lines changed

4 files changed

+37
-30
lines changed

doc/src/release_notes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ oracledb 2.2.0 (TBD)
1717
Thin Mode Changes
1818
+++++++++++++++++
1919

20+
#) Internal change: further efforts to tighten code looking for the end of a
21+
database request made to Oracle Database 23c.
22+
2023
Thick Mode Changes
2124
++++++++++++++++++
2225

src/oracledb/impl/thin/messages.pyx

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,13 @@ cdef class Message:
4949
uint8_t function_code
5050
uint32_t call_status
5151
uint16_t end_to_end_seq_num
52+
bint end_of_response
5253
bint error_occurred
5354
bint flush_out_binds
5455
bint resend
5556
bint retry
5657
object warning
5758

58-
cdef bint _has_more_data(self, ReadBuffer buf):
59-
return buf.bytes_left() > 0 and not self.flush_out_binds
60-
6159
cdef int _initialize(self, BaseThinConnImpl conn_impl) except -1:
6260
"""
6361
Initializes the message to contain the connection and a place to store
@@ -117,7 +115,6 @@ cdef class Message:
117115
buf.read_ub4(&num_bytes) # oerrdd (logical rowid)
118116
if num_bytes > 0:
119117
buf.skip_raw_bytes_chunked()
120-
buf._in_request = False
121118

122119
# batch error codes
123120
buf.read_ub2(&num_errors) # batch error codes array
@@ -173,6 +170,9 @@ cdef class Message:
173170
info.pos = error_pos
174171
info.message = buf.read_str(CS_FORM_IMPLICIT).rstrip()
175172

173+
# an error message always marks the end of a response!
174+
self.end_of_response = True
175+
176176
cdef int _process_message(self, ReadBuffer buf,
177177
uint8_t message_type) except -1:
178178
if message_type == TNS_MSG_TYPE_ERROR:
@@ -187,7 +187,7 @@ cdef class Message:
187187
elif message_type == TNS_MSG_TYPE_SERVER_SIDE_PIGGYBACK:
188188
self._process_server_side_piggyback(buf)
189189
elif message_type == TNS_MSG_TYPE_END_OF_REQUEST:
190-
buf._in_request = False
190+
self.end_of_response = True
191191
else:
192192
errors._raise_err(errors.ERR_MESSAGE_TYPE_UNKNOWN,
193193
message_type=message_type,
@@ -301,10 +301,10 @@ cdef class Message:
301301

302302
cdef int process(self, ReadBuffer buf) except -1:
303303
cdef uint8_t message_type
304+
self.end_of_response = False
304305
self.flush_out_binds = False
305-
buf._in_request = True
306306
self._preprocess()
307-
while self._has_more_data(buf):
307+
while not self.end_of_response:
308308
buf.save_point()
309309
buf.read_ub1(&message_type)
310310
self._process_message(buf, message_type)
@@ -391,9 +391,6 @@ cdef class MessageWithData(Message):
391391
self.bit_vector = <const char_type*> self.bit_vector_buf.data.as_chars
392392
memcpy(<void*> self.bit_vector, ptr, num_bytes)
393393

394-
cdef bint _has_more_data(self, ReadBuffer buf):
395-
return buf._in_request and not self.flush_out_binds
396-
397394
cdef bint _is_duplicate_data(self, uint32_t column_num):
398395
"""
399396
Returns a boolean indicating if the given column contains data
@@ -848,6 +845,7 @@ cdef class MessageWithData(Message):
848845
self._process_row_data(buf)
849846
elif message_type == TNS_MSG_TYPE_FLUSH_OUT_BINDS:
850847
self.flush_out_binds = True
848+
self.end_of_response = True
851849
elif message_type == TNS_MSG_TYPE_DESCRIBE_INFO:
852850
buf.skip_raw_bytes_chunked()
853851
self._process_describe_info(buf, self.cursor, self.cursor_impl)
@@ -1929,6 +1927,7 @@ cdef class DataTypesMessage(Message):
19291927
buf.read_uint16(&conv_data_type)
19301928
if conv_data_type != 0:
19311929
buf.skip_raw_bytes(4)
1930+
self.end_of_response = True
19321931

19331932
cdef int _write_message(self, WriteBuffer buf) except -1:
19341933
cdef:
@@ -2225,9 +2224,6 @@ cdef class LobOpMessage(Message):
22252224
bint bool_flag
22262225
object data
22272226

2228-
cdef bint _has_more_data(self, ReadBuffer buf):
2229-
return buf._in_request
2230-
22312227
cdef int _initialize_hook(self) except -1:
22322228
"""
22332229
Perform initialization.
@@ -2367,6 +2363,7 @@ cdef class ProtocolMessage(Message):
23672363
uint8_t message_type) except -1:
23682364
if message_type == TNS_MSG_TYPE_PROTOCOL:
23692365
self._process_protocol_info(buf)
2366+
self.end_of_response = True
23702367
else:
23712368
Message._process_message(self, buf, message_type)
23722369

@@ -2410,27 +2407,23 @@ cdef class FastAuthMessage(Message):
24102407
DataTypesMessage data_types_message
24112408
ProtocolMessage protocol_message
24122409
AuthMessage auth_message
2413-
bint renegotiate
2414-
2415-
cdef bint _has_more_data(self, ReadBuffer buf):
2416-
return buf._in_request
24172410

24182411
cdef int _process_message(self, ReadBuffer buf,
24192412
uint8_t message_type) except -1:
24202413
"""
24212414
Processes the messages returned from the server response.
24222415
"""
2423-
if message_type == TNS_MSG_TYPE_RENEGOTIATE:
2424-
self.renegotiate = True
2425-
elif message_type == TNS_MSG_TYPE_PROTOCOL:
2416+
if message_type == TNS_MSG_TYPE_PROTOCOL:
24262417
ProtocolMessage._process_message(self.protocol_message, buf,
24272418
message_type)
2419+
self.end_of_response = False
24282420
elif message_type == TNS_MSG_TYPE_DATA_TYPES:
24292421
DataTypesMessage._process_message(self.data_types_message, buf,
24302422
message_type)
2423+
self.end_of_response = False
24312424
else:
24322425
AuthMessage._process_message(self.auth_message, buf, message_type)
2433-
buf._in_request = False
2426+
self.end_of_response = True
24342427

24352428
cdef int _write_message(self, WriteBuffer buf) except -1:
24362429
"""

src/oracledb/impl/thin/packet.pyx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,12 @@ cdef class Packet:
6666
ptr = cpython.PyBytes_AS_STRING(self.buf)
6767
flags = unpack_uint16(<const char_type*> &ptr[PACKET_HEADER_SIZE],
6868
BYTE_ORDER_MSB)
69-
return flags & TNS_DATA_FLAGS_END_OF_REQUEST
69+
if flags & TNS_DATA_FLAGS_END_OF_REQUEST:
70+
return True
71+
if self.packet_size == PACKET_HEADER_SIZE + 3 \
72+
and ptr[PACKET_HEADER_SIZE + 2] == TNS_MSG_TYPE_END_OF_REQUEST:
73+
return True
74+
return False
7075

7176

7277
@cython.final
@@ -200,7 +205,7 @@ cdef class ReadBuffer(Buffer):
200205
Transport _transport
201206
list _saved_packets
202207
Capabilities _caps
203-
bint _in_request
208+
bint _check_request_boundary
204209
object _waiter
205210
object _loop
206211

@@ -340,8 +345,7 @@ cdef class ReadBuffer(Buffer):
340345
self._saved_packets.append(packet)
341346
notify_waiter[0] = \
342347
packet.packet_type != TNS_PACKET_TYPE_DATA \
343-
or not self._in_request \
344-
or not self._caps.supports_end_of_request \
348+
or not self._check_request_boundary \
345349
or packet.has_end_of_request()
346350

347351
cdef int _read_raw_bytes_and_length(self, const char_type **ptr,

src/oracledb/impl/thin/protocol.pyx

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ cdef class Protocol(BaseProtocol):
374374
try:
375375
self._read_buf.reset_packets()
376376
message.send(self._write_buf)
377-
self._receive_packet(message)
377+
self._receive_packet(message, check_request_boundary=True)
378378
message.process(self._read_buf)
379379
except socket.timeout:
380380
try:
@@ -440,12 +440,16 @@ cdef class Protocol(BaseProtocol):
440440
self._process_message(message)
441441
message.postprocess()
442442

443-
cdef int _receive_packet(self, Message message) except -1:
443+
cdef int _receive_packet(self, Message message,
444+
bint check_request_boundary=False) except -1:
444445
cdef:
445446
ReadBuffer buf = self._read_buf
446447
uint16_t refuse_message_len
447448
const char_type* ptr
449+
buf._check_request_boundary = \
450+
check_request_boundary and self._caps.supports_end_of_request
448451
buf.wait_for_packets_sync()
452+
buf._check_request_boundary = False
449453
if buf._current_packet.packet_type == TNS_PACKET_TYPE_MARKER:
450454
self._reset(message)
451455
elif buf._current_packet.packet_type == TNS_PACKET_TYPE_REFUSE:
@@ -784,7 +788,7 @@ cdef class BaseAsyncProtocol(BaseProtocol):
784788
"""
785789
self._read_buf.reset_packets()
786790
message.send(self._write_buf)
787-
await self._receive_packet(message)
791+
await self._receive_packet(message, check_request_boundary=True)
788792
while True:
789793
try:
790794
message.process(self._read_buf)
@@ -812,12 +816,16 @@ cdef class BaseAsyncProtocol(BaseProtocol):
812816
self._break_in_progress = False
813817
errors._raise_err(errors.ERR_CALL_TIMEOUT_EXCEEDED, timeout=timeout)
814818

815-
async def _receive_packet(self, Message message):
819+
async def _receive_packet(self, Message message,
820+
bint check_request_boundary=False):
816821
cdef:
817822
ReadBuffer buf = self._read_buf
818823
uint16_t refuse_message_len
819824
const char_type* ptr
825+
buf._check_request_boundary = \
826+
check_request_boundary and self._caps.supports_end_of_request
820827
await buf.wait_for_packets_async()
828+
buf._check_request_boundary = False
821829
if buf._current_packet.packet_type == TNS_PACKET_TYPE_MARKER:
822830
await self._reset()
823831
elif buf._current_packet.packet_type == TNS_PACKET_TYPE_REFUSE:
@@ -843,7 +851,6 @@ cdef class BaseAsyncProtocol(BaseProtocol):
843851
break
844852
await self._read_buf.wait_for_packets_async()
845853

846-
847854
# send reset marker and then read error packet; first skip as many
848855
# marker packets as may be sent by the server; if the server doesn't
849856
# handle out-of-band breaks properly, some quit immediately and others

0 commit comments

Comments
 (0)