Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the DBD-Oracle CPAN distribution.

Report information
The Basics
Id: 4564
Status: resolved
Priority: 0/
Queue: DBD-Oracle

People
Owner: Nobody in particular
Requestors: J.Turner [...] mdl.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Date: Wed, 03 Dec 2003 15:55:49 -0800
From: Jay Turner <J.Turner [...] mdl.com>
To: bug-DBI [...] rt.cpan.org
Subject: Perl DBI bug handling CLOBs
Date: Fri, 28 Feb 2003 16:55:28 -0800 It has come to my attention that PERL DBI counts on OCILobGetLength returning BYTES. It returns CHARACTERS instead, which is the count of variable-width characters. For multi-byte character sets this results in errors such as: DBD::Oracle::st fetch failed: ORA-03130: the buffer for the next piece to be fetched is required (DBD ERROR: OCILobGetLength) at id rmsc01.pl line 294. The correct way to read CLOBs is 1) Query the LOB locator for the CSID and CSFRM (character set ID and form). A character set >= 800 is a mulitbyte character set and csfrm <> 0 is CLOB. 2) Pass the CSID and CSFRM to OCILobRead with AMT=0 and pass your buffer address and size. 3) Your callback routine must either be capable of completing the I/O by allocating additional buffers, or it must notify the caller of OCILobRead to free the lob locator, since an incomplete read jams the locator-you can't use it for anything else without finishing the read (attempts to reuse the locator will result in errors). Likewise, with OCILobWrite, you have to pass the CSID and CSFRM, with AMT=0 and the buffer size in bytes. The callback can just say it has zero bytes and set piece=OCI_LAST_PIECE. You cannot use the return value of OCILobGetLength as the size of the data that is being read. The actual size of the data is unknown for variable-width characters, and the buffer has to be big enough to accomplish the translation, so you can't just double or triple the return value from OCILobGetLength (I have seen that approach fail). You can simulate the effects of a foreign character set by $ export NLS_LANG=Japanese
Date: Thu, 4 Dec 2003 19:29:53 +0000
From: Tim Bunce <Tim.Bunce [...] pobox.com>
To: Jay Turner via RT <bug-DBI [...] rt.cpan.org>
CC: "AdminCc of cpan Ticket #4564": ;
Subject: Re: [cpan #4564] Perl DBI bug handling CLOBs
RT-Send-Cc:
Thanks. I'll take a look. The fastest way to get it fixed is to send me a patch. Tim. On Wed, Dec 03, 2003 at 06:56:07PM -0500, Jay Turner via RT wrote: Show quoted text
> > This message about DBI was sent to you by J.Turner@mdl.com <J.Turner@mdl.com> via rt.cpan.org > > Full context and any attached attachments can be found at: > <URL: https://rt.cpan.org/Ticket/Display.html?id=4564 > > > > Date: Fri, 28 Feb 2003 16:55:28 -0800 > > It has come to my attention that PERL DBI counts on OCILobGetLength > returning BYTES. It returns CHARACTERS instead, which is the count of > variable-width characters. For multi-byte character sets this results > in errors such as: > > DBD::Oracle::st fetch failed: ORA-03130: the buffer for the next piece > to be fetched is required (DBD ERROR: OCILobGetLength) at id rmsc01.pl > line 294. > > The correct way to read CLOBs is > > 1) Query the LOB locator for the CSID and CSFRM (character set ID and > form). A character set >= 800 is a mulitbyte character set and csfrm > <> 0 is CLOB. > > 2) Pass the CSID and CSFRM to OCILobRead with AMT=0 and pass your > buffer address and size. > > 3) Your callback routine must either be capable of completing the I/O > by allocating additional buffers, or it must notify the caller of > OCILobRead to free the lob locator, since an incomplete read jams the > locator-you can't use it for anything else without finishing the read > (attempts to reuse the locator will result in errors). > > Likewise, with OCILobWrite, you have to pass the CSID and CSFRM, with > AMT=0 and the buffer size in bytes. The callback can just say it has > zero bytes and set piece=OCI_LAST_PIECE. > > You cannot use the return value of OCILobGetLength as the size of the > data that is being read. The actual size of the data is unknown for > variable-width characters, and the buffer has to be big enough to > accomplish the translation, so you can't just double or triple the > return value from OCILobGetLength (I have seen that approach fail). > > You can simulate the effects of a foreign character set by > > $ export NLS_LANG=Japanese
I looked at the code and later version of Clobs seems to have fixed this up the way the reported stated