CC: | <dbi-dev [...] perl.org>, <bug-DBD-Oracle [...] rt.cpan.org> |
Subject: | RE: Bug in DBD::Oracle handling LOB columns and synonyms? |
Date: | Wed, 1 Oct 2008 15:42:51 +0200 |
To: | <scoles [...] pythian.com> |
From: | <mirko.kraft [...] ubs.com> |
Hi John,
the issue pops up again and I see there is a new Bug Id #38267 for the
same issue. Since I saw no reply to that last bug entry, I browsed
through 1.22 oci8.c code and found the following snippet in function
init_lob_refetch:
...
OCIAttrGet_log_stat(parmhp, OCI_DTYPE_PARAM,
&syn_schema, &syn_schema_len, OCI_ATTR_SCHEMA_NAME,
errhp, status);
OCIAttrGet_log_stat(parmhp, OCI_DTYPE_PARAM,
&syn_name, &syn_name_len, OCI_ATTR_OBJ_NAME, errhp,
status);
...
strcpy(new_tablename,syn_schema);
...
Second OCIAttrGet is obsolete. OCI_ATTR_OBJ_NAME is not defined for
synonym description and should be removed.
The strcpy will fail to produce correct results under certain
circumstances, because for OCI_ATTR_SCHEMA_NAME Oracle doesn't guarantee
a '\0' terminated string (see
http://download.oracle.com/docs/cd/B14117_01/appdev.101/b10779/oci06des.
htm#446652). So this should actually be
strncpy(new_tablename,syn_schema,syn_schema_len);
And I still have a problem with
char new_tablename[100];
being defined in the if-block, because the memory is referenced outside,
and due to current implementation may be overwritten. I still think this
chunk of memory has to be allocated on function block level. Just my
0.02$ ;-)
Having made all this changes, I'm now no longer experiencing any
problems with any kind of LOBs.
Thanks for looking into this,
Mirko
Show quoted text
-----Original Message-----
From: Kraft, Mirko
Sent: Mittwoch, 21. Mai 2008 12:26
To: 'scoles@pythian.com'
Cc: dbi-dev@perl.org; 'bug-DBD-Oracle@rt.cpan.org'
Subject: RE: Bug in DBD::Oracle handling LOB columns and synonyms?
Hi John,
the Web interface doesn't work for me, so I cc this to bug-DBD-Oracle
[at] rt.cpan.org which should also be ok.
I attached a diff -c on oci8.c from 1.21 which I think fixes the issue
(not tested currently, however):
*** oci8.c.ori Wed May 21 12:09:48 2008
--- oci8.c Wed May 21 12:16:08 2008
***************
*** 2811,2816 ****
--- 2811,2819 ----
lob_refetch_t *lr = NULL;
STRLEN tablename_len;
char *tablename;
+ #ifdef OCI_ATTR_OBJ_NAME /* not in 8.0.x */
+ char new_tablename[100];
+ #endif /* OCI_ATTR_OBJ_NAME */
switch (imp_sth->stmt_type) {
case OCI_STMT_UPDATE:
***************
*** 2834,2850 ****
OCIDescribeAny_log_stat(imp_sth->svchp, errhp, tablename,
strlen(tablename),
(ub1)OCI_OTYPE_NAME, (ub1)1, (ub1)OCI_PTYPE_SYN, dschp,
status);
if (status == OCI_SUCCESS) { /* There is a synonym, get the schema
*/
- char new_tablename[100];
char *syn_schema=NULL, *syn_name=NULL;
OCIAttrGet_log_stat(dschp, OCI_HTYPE_DESCRIBE,
&parmhp, 0, OCI_ATTR_PARAM, errhp,
status);
OCIAttrGet_log_stat(parmhp, OCI_DTYPE_PARAM,
! &syn_schema, 0, OCI_ATTR_SCHEMA_NAME, errhp,
status);
OCIAttrGet_log_stat(parmhp, OCI_DTYPE_PARAM,
! &syn_name, 0, OCI_ATTR_OBJ_NAME, errhp,
status);
! strcpy(new_tablename, syn_schema);
! strcat(new_tablename, ".");
! strcat(new_tablename, syn_name);
tablename=new_tablename;
if (DBIS->debug >= 3)
PerlIO_printf(DBILOGFP, " lob refetch synonym, schema=%s,
name=%s, new tablename=%s\n", syn_schema, syn_name, tablename);
--- 2837,2853 ----
OCIDescribeAny_log_stat(imp_sth->svchp, errhp, tablename,
strlen(tablename),
(ub1)OCI_OTYPE_NAME, (ub1)1, (ub1)OCI_PTYPE_SYN, dschp,
status);
if (status == OCI_SUCCESS) { /* There is a synonym, get the schema
*/
char *syn_schema=NULL, *syn_name=NULL;
+ ub4 syn_schema_len = 0, syn_name_len = 0;
OCIAttrGet_log_stat(dschp, OCI_HTYPE_DESCRIBE,
&parmhp, 0, OCI_ATTR_PARAM, errhp,
status);
OCIAttrGet_log_stat(parmhp, OCI_DTYPE_PARAM,
! &syn_schema, &syn_schema_len,
OCI_ATTR_SCHEMA_NAME, errhp, status);
OCIAttrGet_log_stat(parmhp, OCI_DTYPE_PARAM,
! &syn_name, &syn_name_len, OCI_ATTR_OBJ_NAME,
errhp, status);
! strncpy(new_tablename, syn_schema, syn_schema_len);
! strcat (new_tablename, ".");
! strncat(new_tablename, syn_name, syn_name_len);
tablename=new_tablename;
if (DBIS->debug >= 3)
PerlIO_printf(DBILOGFP, " lob refetch synonym, schema=%s,
name=%s, new tablename=%s\n", syn_schema, syn_name, tablename);
Thanks for looking into the issue,
Mirko
-----Original Message-----
From: scoles@pythian.com [mailto:scoles@pythian.com]
Sent: Dienstag, 20. Mai 2008 23:03
To: Kraft, Mirko
Cc: dbi-dev@perl.org
Subject: Re: Bug in DBD::Oracle handling LOB columns and synonyms?
Ok I will have a look at it and you are right the code does not look
quite
right.
Do you think you can raise a ticket for this at
http://rt.cpan.org/Public/Dist/Display.html?Status=Active&Name=DBD-Oracl
e
that way I can track it better.
You do not happen to know what the orginal starting line number was in
oci8?
cheers John SColes
> Hi *,
> I'm using DBD::Oracle (code checked onCPAN and verified in version
1.21)
> and encountered a problem (DB is Oracle 10gR2) related to LOBs and
> synonyms:
>
> Table TTHUMBNAIL (DOCUMENT_ID NUMBER(12), THUMBNAIL BLOB NOT NULL) is
> owned by user DMSSGADM. User DMSSGDP has a synonym TTHUMBNAIL on the
table
> and all necessary rights granted.
>
> When executing the following code
>
> $sthInsertTTHUMBNAIL = prepareStatement($dbh,
> 'INSERT ' .
> 'INTO tthumbnail ' .
> ' (document_id, ' .
> ' thumbnail) ' .
> 'VALUES
(document_id_seq.CURRVAL,
> ' .
> ' ?)');
> $sthInsertTTHUMBNAIL->bind_param(1, $thumbnail, { ora_type => ORA_BLOB
});
> $sthInsertTTHUMBNAIL->execute();
>
> I get the following error:
>
> ORA-04043: object DMSSGADMTTHUMBNAIL.TTHUMBNAIL does not exist (DBD
> SUCCESS: OCIDescribeAny(view)/LOB refetch)
>
> Currently I tracked down the error to the following place in oci8.c,
but
> since I got no compiler here, I can't verify further:
>
> 01 #ifdef OCI_ATTR_OBJ_NAME /* not in 8.0.x */
> 02 OCIDescribeAny_log_stat(imp_sth->svchp, errhp, tablename,
> strlen(tablename),
> 03 (ub1)OCI_OTYPE_NAME, (ub1)1, (ub1)OCI_PTYPE_SYN, dschp,
status);
> 04 if (status == OCI_SUCCESS) { /* There is a synonym, get the
schema
> */
> 05 char new_tablename[100];
> 06 char *syn_schema=NULL, *syn_name=NULL;
> 07 OCIAttrGet_log_stat(dschp, OCI_HTYPE_DESCRIBE,
> 08 &parmhp, 0, OCI_ATTR_PARAM, errhp,
status);
> 09 OCIAttrGet_log_stat(parmhp, OCI_DTYPE_PARAM,
> 10 &syn_schema, 0, OCI_ATTR_SCHEMA_NAME, errhp,
status);
> 11 OCIAttrGet_log_stat(parmhp, OCI_DTYPE_PARAM,
> 12 &syn_name, 0, OCI_ATTR_OBJ_NAME, errhp,
status);
> 13 strcpy(new_tablename, syn_schema);
> 14 strcat(new_tablename, ".");
> 15 strcat(new_tablename, syn_name);
> 16 tablenameew_tablename;
> 17 if (DBIS->debug >= 3)
> 18 PerlIO_printf(DBILOGFP, " lob refetch synonym, schema=%s,
> name=%s, new tablename=%s\n", syn_schema, syn_name, tablename);
> 19 }
> 20 #endif /* OCI_ATTR_OBJ_NAME */
>
> First, lines 05 & 16 constitute a very bad situation, since the
pointer
> refers to a stack variable that is freed when the block is closed :-(
So
> this buffer should be declared outside the block, anyway...
>
> And from what I know about OCIAttrGet, if you retrieve a text
attribute,
> you have to pass a pointer to receive the length of the string, as it
is
> not '\0' terminated! After that you would call something like
>
> strncpy(new_tablename, syn_schema, syn_schema_length);
> strcpy (new_tablename, ".");
> strncpy(new_tablename, syn_name, syn_name_length);
>
> I'm looking forward to hearing from you about the issue, since I'm
really
> stuck on the topic.
>
> Sincerely,
>
> Mirko Kraft
>
> UBS AG
> Global Wealth Management & Business Banking
> Information Technology
> eRMS - electronic Records Management Solutions
> Viaduktstr. 31-35, PO Box 4473, CH-4051 Basel
> Tel. +41-61-288 53 72
> Fax +41-61-288 71 91
> www.ubs.com
>
> Based on previous e-mail correspondence with you and/or an agreement
> reached with you, UBS considers itself authorized to contact you via
> unsecured e-mail.
> Warning:
> (a) E-mails can involve SUBSTANTIAL RISKS, e.g. lack of
confidentiality,
> potential manipulation of contents and/or sender's address, incorrect
> recipient (misdirection), viruses etc. UBS assumes no responsibility
for
> any loss or damage resulting from the use of e-mails. UBS recommends
in
> particular that you do NOT SEND ANY SENSITIVE INFORMATION, that you do
not
> include details of the previous message in any reply, and that you
enter
> e-mail address(es) manually every time you write an e-mail.
> (b) As a matter of principle, UBS does NOT accept any ORDERS,
revocations
> of orders or authorizations, blocking of credit cards, etc., sent by
> e-mail. Should such an e-mail nevertheless be received, UBS is not
obliged
> to act on or respond to the e-mail.
> Please notify UBS immediately if you received this e-mail by mistake
or if
> you do not wish to receive any further e-mail correspondence. If you
have
> received this e-mail by mistake, please completely delete it (and any
> attachments) and do not forward it or inform any other person of its
> contents.
>
>
>