Open horrendo opened 9 years ago
Thanks for a very thorough description of your issue and a script to reproduce. I have run it and it behaves the same here. I'm away for the next few days but I'll try and look at it when I get back. I'm terribly forgetful so by all means chase me if you hear nothing by end of Monday.
Martin
BTW, the problem is ORA 1406 - TRUNCATED as you correctly suggested. If you add {ora_verbose=>6} to the end of your connect call you can see the OCI calls and what happened.
Also,
Describe col #1 type=104((UNKNOWN SQL TYPECODE 104)) Described col 1: dbtype 104((UNKNOWN SQL TYPECODE 104)), scale 0, prec 20, nullok 0, name ROWID : dbsize 74, char_used 0, char_size 0, csid 0, csform 0(0), disize 20
ocidfn.h:#define SQLT_RDD 104
A quick hack that will fix it for rowid's less than 100 bytes. There is a better fix but more complicated.
diff --git a/oci8.c b/oci8.c
index 46a69e8..3a93a50 100644
--- a/oci8.c
+++ b/oci8.c
@@ -156,6 +156,7 @@ sql_typecode_name(int dbtype) {
case 97: return "CHARZ";
case 100: return "BINARY FLOAT oracle-endian";
case 101: return "BINARY DOUBLE oracle-endian";
+ case 104: return "ROWID";
case 106: return "MLSLABEL";
case 102: return "SQLT_CUR OCI 7 cursor variable";
case 112: return "SQLT_CLOB / long";
@@ -3662,7 +3663,7 @@ dbd_describe(SV *h, imp_sth_t *imp_sth)
case ORA_ROWID: /* ROWID */
case 104: /* ROWID Desc */
- fbh->disize = 20;
+ fbh->disize = 100;
fbh->prec = fbh->disize;
break;
case 108: /* some sort of embedded object */
That's awesome Martin. Thanks for such a quick response.
I've seen ROWID's from IOT's significantly longer than 100 bytes in some of my 'real life' tables. We don't use them a lot so it seems a shame to incur a large overhead for 'regular' ROWID's (which we do select a lot) just for a handful of these outlier cases.
Without knowing anything about the structure or logic of oci8.c, would it make sense to treat them as a separate case in dbd_describe rather than bundling them in with 'regular' ROWID's? That way we could make these type 104's something like 2000 and not affect 'regular' ROWID's.
No rush on this - we're not sweating on it.
Cheers,
Steve
Steve, that 100 is just a hack. Oracle does return the size of the rowid (it was 74 I think in your case) and that would be the better solution but more complicated. I was working on the get you going first then look at a longer term fix.
A simple workaround on the sql side - convert the rowid to a string by appending an empty string literal:
select rowid||'' from iot_table
Unlike 'regular' tables, the value returned by the pseudo column ROWID for IOT's is not of fixed length.
I have an IOT with a multi-column primary key. When I try to select rows from the table and include ROWID, I get the following error:
I'm not sure how to attach a test case so here's a simple self-contained perl script to reproduce the error:
My output (connecting to an Oracle 11.2.0.4 DB using the 12.1 instant client on RHEL6) is:
Thanks and regards,
Steve