Closed mkmoisen closed 3 months ago
Thanks. I can replicate the issue. The source of the issue is your call to cursor.close()
which makes the cursor unusable. Removing that call resolves the issue. I will ensure that a better error message is raised!
Hi @anthony-tuininga
Thank you.
I just tried again in thick mode, please ignore my previous statement where I said it works without any issue. In thick mode it raises this error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/foo/python3.12/site-packages/oracledb/cursor.py", line 701, in execute
impl.execute(self)
File "src/oracledb/impl/thick/cursor.pyx", line 306, in oracledb.thick_impl.ThickCursorImpl.execute
File "src/oracledb/impl/thick/utils.pyx", line 456, in oracledb.thick_impl._raise_from_odpi
File "src/oracledb/impl/thick/utils.pyx", line 446, in oracledb.thick_impl._raise_from_info
oracledb.exceptions.DatabaseError: DPI-1002: invalid OCI handle
I suppose this would be a backwards breaking change, but a nicer error message here in thick mode would be nice, as well as a consistent error message between thick and thin mode.
Thanks!
I see that with thick mode it works if the exact statement is re-executed but fails with the invalid OCI handle
error when a different statement is executed. Why do you say that it is a backwards breaking change? What version had different behavior? And what was that behavior?
@anthony-tuininga
Sorry for the confusion, I mean if you change the error message to something more friendly such as "Please use a new cursor after closing it" instead of "invalid OCI handle" it would technically be a backwards breaking change.
Although I doubt anyone is writing a try/except that depends on this message.
Ah! That makes more sense. :-) I may be able to avoid the exception completely but I need to look closely at the code to see if that is possible.
This patch resolves the segfault:
diff --git a/src/oracledb/impl/thin/messages.pyx b/src/oracledb/impl/thin/messages.pyx
index 6679adc2..172b6008 100644
--- a/src/oracledb/impl/thin/messages.pyx
+++ b/src/oracledb/impl/thin/messages.pyx
@@ -1082,6 +1082,8 @@ cdef class MessageWithData(Message):
buf.write_binary_float(value)
elif ora_type_num == TNS_DATA_TYPE_CURSOR:
cursor_impl = value._impl
+ if cursor_impl is None:
+ errors._raise_err(errors.ERR_CURSOR_NOT_OPEN)
if cursor_impl._statement is None:
cursor_impl._statement = self.conn_impl._get_statement()
if cursor_impl._statement._cursor_id == 0:
To check this in thick mode requires considerably more effort. Avoiding the exception is not possible because in thick mode it is impossible to tell whether a PL/SQL bind variable is IN, IN/OUT or OUT -- so an exception should be thrown if the cursor that is bound has been closed.
I have pushed a patch that corrects this issue. If you are able to build from source you can verify that it works for you, too.
This was included in python-oracledb 2.4.0 which was just released.
Oracle 19
Also run Python and show the output of:
And:
-->
Crash
Segmentation Fault
Cut and paste text showing the command you ran. No screenshots.
Use a gist for long screen output and logs: see https://gist.github.com/
-->
This bug only occurs in thin mode.
I cannot replicate it in thick mode.
No segfault offcurs when I instead instantiate a new cursor_var:
In thick mode, it works as expected.