Skip to content

Commit 2f90c3f

Browse files
Fixed bug that caused "ORA-03137: malformed TTC packet from client
rejected" exception to be raised when attempting to call parse() on a scrollable cursor.
1 parent 5cd753e commit 2f90c3f

File tree

4 files changed

+51
-1
lines changed

4 files changed

+51
-1
lines changed

doc/src/release_notes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ Thick Mode Changes
2525
Common Changes
2626
++++++++++++++
2727

28+
#) Fixed bug that caused ``ORA-03137: malformed TTC packet from client
29+
rejected`` exception to be raised when attempting to call
30+
:meth:`Cursor.parse()` on a scrollable cursor.
31+
2832

2933
oracledb `3.4.0 <https://github.com/oracle/python-oracledb/compare/v3.3.0...v3.4.0>`__ (October 2025)
3034
-----------------------------------------------------------------------------------------------------

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ cdef class ExecuteMessage(MessageWithData):
8181
exec_flags |= TNS_EXEC_FLAGS_IMPLICIT_RESULTSET
8282
if not self.scroll_operation:
8383
options |= TNS_EXEC_OPTION_EXECUTE
84-
if cursor_impl.scrollable:
84+
if cursor_impl.scrollable and not self.parse_only:
8585
exec_flags |= TNS_EXEC_FLAGS_SCROLLABLE
8686
if stmt._cursor_id == 0 or stmt._is_ddl:
8787
options |= TNS_EXEC_OPTION_PARSE

tests/test_4200_cursor_scrollable.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,3 +223,26 @@ def test_4214(conn):
223223
(value,) = cursor.fetchone()
224224
assert value == 6.25
225225
assert cursor.rowcount == 5
226+
227+
228+
def test_4215(conn):
229+
"4215 - test parse() on a scrollable cursor"
230+
cursor = conn.cursor(scrollable=True)
231+
statement = """
232+
select 1 from dual
233+
union all
234+
select 2 from dual
235+
union all
236+
select 3 from dual
237+
union all
238+
select 4 from dual
239+
union all
240+
select 5 from dual
241+
"""
242+
cursor.parse(statement)
243+
cursor.execute(statement)
244+
(fetched_value,) = cursor.fetchone()
245+
assert fetched_value == 1
246+
cursor.scroll(mode="last")
247+
(fetched_value,) = cursor.fetchone()
248+
assert fetched_value == 5

tests/test_8600_cursor_scrollable_async.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,3 +226,26 @@ async def test_8614(async_conn):
226226
(value,) = await cursor.fetchone()
227227
assert value == 6.25
228228
assert cursor.rowcount == 5
229+
230+
231+
async def test_8615(async_conn):
232+
"8615 - test parse() on a scrollable cursor"
233+
cursor = async_conn.cursor(scrollable=True)
234+
statement = """
235+
select 1 from dual
236+
union all
237+
select 2 from dual
238+
union all
239+
select 3 from dual
240+
union all
241+
select 4 from dual
242+
union all
243+
select 5 from dual
244+
"""
245+
await cursor.parse(statement)
246+
await cursor.execute(statement)
247+
(fetched_value,) = await cursor.fetchone()
248+
assert fetched_value == 1
249+
await cursor.scroll(mode="last")
250+
(fetched_value,) = await cursor.fetchone()
251+
assert fetched_value == 5

0 commit comments

Comments
 (0)