Skip to content

CLOB in/out parameters no longer work in 3.0.0 #468

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
doerwalter opened this issue Mar 12, 2025 · 4 comments
Closed

CLOB in/out parameters no longer work in 3.0.0 #468

doerwalter opened this issue Mar 12, 2025 · 4 comments
Labels
bug Something isn't working patch available

Comments

@doerwalter
Copy link

  1. What versions are you using?

The database is

Oracle Database 21c Express Edition Release 21.0.0.0.0

The script

import sys, platform, oracledb

print("platform.platform:", platform.platform())
print("sys.maxsize > 2**32:", sys.maxsize > 2**32)
print("platform.python_version:", platform.python_version())

print("oracledb.__version__:", oracledb.__version__)

reports

platform.platform: macOS-15.3.1-arm64-arm-64bit-Mach-O
sys.maxsize > 2**32: True
platform.python_version: 3.13.2
oracledb.__version__: 3.0.0
  1. Is it an error or a hang or a crash?

Code that worked with oracledb 2.5.1 now raises a

oracledb.exceptions.DatabaseError: ORA-22922: nonexistent LOB value
  1. What error(s) or behavior you are seeing?

I have the following procedure:

CREATE OR REPLACE procedure placeholders_replace(
	p_eq_body in out clob
)
as
begin
	null;
end;

And I try to call it with the following Python code:

#!python
import oracledb

db = oracledb.connect(f"user/owd@db")
c = db.cursor()

query = "begin PLACEHOLDERS_REPLACE(p_eq_body=>:p_eq_body); end;"

eq_body = c.var(oracledb.DB_TYPE_CLOB)

eq_body.setvalue(0, "foo")

c.execute(query, {"p_eq_body": eq_body})

print("eq_body", eq_body.getvalue(0))

This gives the following stack trace

eq_body Traceback (most recent call last):
  File "/Users/walter/x/oracledb_clob_bug.py", line 18, in <module>
    print("eq_body", eq_body.getvalue(0))
    ~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/walter/pyvenvs/default/lib/python3.13/site-packages/oracledb/lob.py", line 108, in __str__
    return self.read()
           ~~~~~~~~~^^
  File "/Users/walter/pyvenvs/default/lib/python3.13/site-packages/oracledb/lob.py", line 170, in read
    return self._impl.read(offset, amount)
           ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
  File "src/oracledb/impl/thin/lob.pyx", line 351, in oracledb.thin_impl.ThinLobImpl.read
  File "src/oracledb/impl/thin/lob.pyx", line 269, in oracledb.thin_impl.ThinLobImpl._process_message
  File "src/oracledb/impl/thin/protocol.pyx", line 447, in oracledb.thin_impl.Protocol._process_single_message
  File "src/oracledb/impl/thin/protocol.pyx", line 448, in oracledb.thin_impl.Protocol._process_single_message
  File "src/oracledb/impl/thin/protocol.pyx", line 440, in oracledb.thin_impl.Protocol._process_message
  File "src/oracledb/impl/thin/messages.pyx", line 103, in oracledb.thin_impl.Message._check_and_raise_exception
oracledb.exceptions.DatabaseError: ORA-22922: nonexistent LOB value
Help: https://docs.oracle.com/error-help/db/ora-22922/
  1. Does your application call init_oracle_client()?

No

  1. Include a runnable Python script that shows the problem.

See above

And if I change the procedure like that:

CREATE OR REPLACE procedure placeholders_replace(
	p_eq_body in out clob
)
as
begin
	p_eq_body := replace(p_eq_body, 'foo', 'bar');
end;

the Python code starts to work and outputs eq_body bar as expected.

Also with oracledb 2.5.1 the original procedure (with the null body) works.

@doerwalter doerwalter added the bug Something isn't working label Mar 12, 2025
@anthony-tuininga
Copy link
Member

I can replicate the issue. The problem is that with 3.0.0 the ability to close temporary LOBs was extended to all round trips and the temporary LOB that was created is mistakenly being added to the list of temporary LOBs to close. If you add another cursor.execute() call before calling eq_body.getvalue(0) you will see the problem in 2.5.1 as well.

@anthony-tuininga
Copy link
Member

I have pushed a patch that corrects this issue and have initated a build from which you can download pre-built development wheels once it completes. You can also build from source if you prefer. If you can test your scenario and confirm the patch works as expected, that would be appreciated!

@doerwalter
Copy link
Author

I've done the following in my checkout of python-oracledb:

git pull --recurse-submodules
python -m pip install build
python -m build
python -m pip install dist/oracledb-3.1.0b1-cp313-cp313-macosx_15_0_arm64.whl

With the resulting installed oracledb my test script outputs:

🐚 ~/checkouts/python-oracledb ❯ python oracledb-bug.py
eq_body foo

i.e. it works now.

@anthony-tuininga
Copy link
Member

This was included in python-oracledb 3.1.0 which was just released.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working patch available
Projects
None yet
Development

No branches or pull requests

2 participants