Tim Bunce wrote:
>
> If you tell me which you'd like to see and why, and I like what you say,
> then your word will be my command (eventually:) !
>
> Better still (and faster still), send me a patch!
>
O.k. The patch is tested for OCI7 and OCI8 on WinNT 4.0, Borland 5.02.
The output for the test case now is:
TYPE PREC SCALE NAME
3 38 0 CINTEGER
8 126 0 CNUMBER
3 38 0 CNUMBER_38_0
3 11 2 CNUMBER_11_2
3 38 2 CNUMBER_XX_2
8 126 0 CFLOAT
8 11 0 CFLOAT_11
8 63 0 CREAL
8 126 0 CDOUBLE_PRECISION
9 0 0 CDATE
The patch includes the necessary changes to distinguish exact
and approximate numeric types.
There are still some options (see comments for SQL_NUMERIC and
SQL_INTEGER), but this would potentially break more code that
relies on SQL_DECIMAL and needs additional entries in the
type_info structure. Any opinions about that?
--------------------------------------------------------------------
diff -ubr ./DBD-Oracle-1.06-orig/dbdimp.c ./DBD-Oracle-1.06/dbdimp.c
--- ./DBD-Oracle-1.06-orig/dbdimp.c Sat Jul 15 00:52:12 2000
+++ ./DBD-Oracle-1.06/dbdimp.c Wed Mar 28 09:38:38 2001
@@ -29,7 +29,13 @@
static int set_sigint_handler = 0;
#endif
-static int ora2sql_type _((int oratype));
+typedef struct sql_fbh_st sql_fbh_t;
+struct sql_fbh_st {
+ int dbtype;
+ int prec;
+ int scale;
+};
+static sql_fbh_t ora2sql_type _((imp_fbh_t* fbh));
void ora_free_phs_contents _((phs_t *phs));
static void dump_env_to_trace();
@@ -1751,19 +1757,19 @@
AV *av = newAV();
retsv = newRV(sv_2mortal((SV*)av));
while(--i >= 0)
- av_store(av, i, newSViv(ora2sql_type(imp_sth->fbh[i].dbtype)));
+ av_store(av, i, newSViv(ora2sql_type(imp_sth->fbh+i).dbtype));
} else if (kl==5 && strEQ(key, "SCALE")) {
AV *av = newAV();
retsv = newRV(sv_2mortal((SV*)av));
while(--i >= 0)
- av_store(av, i, newSViv(imp_sth->fbh[i].scale));
+ av_store(av, i, newSViv(ora2sql_type(imp_sth->fbh+i).scale));
} else if (kl==9 && strEQ(key, "PRECISION")) {
AV *av = newAV();
retsv = newRV(sv_2mortal((SV*)av));
while(--i >= 0)
- av_store(av, i, newSViv(imp_sth->fbh[i].prec));
+ av_store(av, i, newSViv(ora2sql_type(imp_sth->fbh+i).prec));
#ifndef OCI_V8_SYNTAX
#ifdef XXXXX
@@ -1805,21 +1811,41 @@
/* --------------------------------------- */
-static int
-ora2sql_type(oratype)
- int oratype;
-{
- switch(oratype) { /* oracle Internal (not external) types */
- case SQLT_CHR: return SQL_VARCHAR;
- case SQLT_NUM: return SQL_DECIMAL;
- case SQLT_LNG: return SQL_LONGVARCHAR; /* long */
- case SQLT_DAT: return SQL_DATE;
- case SQLT_BIN: return SQL_BINARY; /* raw */
- case SQLT_LBI: return SQL_LONGVARBINARY; /* long raw */
- case SQLT_AFC: return SQL_CHAR; /* Ansi fixed char */
+static sql_fbh_t
+ora2sql_type(imp_fbh_t* fbh) {
+ sql_fbh_t sql_fbh;
+ sql_fbh.dbtype = fbh->dbtype;
+ sql_fbh.prec = fbh->prec;
+ sql_fbh.scale = fbh->scale;
+
+ switch(fbh->dbtype) { /* oracle Internal (not external) types */
+ case SQLT_NUM:
+ if (fbh->scale == -127) { /* FLOAT, REAL, DOUBLE_PRECISION */
+ sql_fbh.dbtype = SQL_DOUBLE;
+ sql_fbh.scale = 0; /* better: undef */
+ }
+ else if (fbh->scale == 0) {
+ if (fbh->prec == 0) { /* NUMBER */
+ sql_fbh.dbtype = SQL_DOUBLE;
+ sql_fbh.prec = 126;
+ }
+ else { /* INTEGER, NUMBER(p,0) */
+ sql_fbh.dbtype = SQL_DECIMAL; /* better: SQL_INTEGER */
+ }
}
- /* else map type into DBI reserved standard range */
- return -9000 - oratype;
+ else { /* NUMBER(p,s) */
+ sql_fbh.dbtype = SQL_DECIMAL; /* better: SQL_NUMERIC */
+ }
+ break;
+ case SQLT_CHR: sql_fbh.dbtype = SQL_VARCHAR; break;
+ case SQLT_LNG: sql_fbh.dbtype = SQL_LONGVARCHAR; break; /* long
*/
+ case SQLT_DAT: sql_fbh.dbtype = SQL_DATE; break;
+ case SQLT_BIN: sql_fbh.dbtype = SQL_BINARY; break; /* raw
*/
+ case SQLT_LBI: sql_fbh.dbtype = SQL_LONGVARBINARY; break; /* long
raw */
+ case SQLT_AFC: sql_fbh.dbtype = SQL_CHAR; break; /* Ansi
fixed char */
+ default: sql_fbh.dbtype = -9000 - fbh->dbtype; /* else
map type into DBI reserved standard range */
+ }
+ return sql_fbh;
}
static void
@@ -1827,7 +1853,9 @@
FILE *fp = DBILOGFP;
int i = 0;
char *p;
+#ifndef __BORLANDC__
extern char **environ;
+#endif
fprintf(fp, "Environment variables:\n");
do {
p = (char*)environ[i++];
diff -ubr ./DBD-Oracle-1.06-orig/oci7.c ./DBD-Oracle-1.06/oci7.c
--- ./DBD-Oracle-1.06-orig/oci7.c Wed May 03 00:24:40 2000
+++ ./DBD-Oracle-1.06/oci7.c Tue Mar 27 17:08:06 2001
@@ -240,9 +240,6 @@
fbh->dbsize *= 2;
fbh->disize *= 2;
}
- else if (fbh->dbtype == 2 && fbh->prec == 0) {
- fbh->prec = 38;
- }
else if ((fbh->dbtype == 1 || fbh->dbtype == 96) && fbh->prec == 0) {
fbh->prec = fbh->dbsize;
}
diff -ubr ./DBD-Oracle-1.06-orig/oci8.c ./DBD-Oracle-1.06/oci8.c
--- ./DBD-Oracle-1.06-orig/oci8.c Fri Jul 14 01:42:18 2000
+++ ./DBD-Oracle-1.06/oci8.c Tue Mar 27 17:07:53 2001
@@ -705,8 +705,6 @@
break;
case 2: /* NUMBER */
- if (!fbh->prec) /* is 0 for FLOATing point */
- fbh->prec = 38; /* max prec */
fbh->disize = 130+3; /* worst case! 1**-130 */
avg_width = 4; /* > approx +/- 1_000_000 ? */
break;
--------------------------------------------------------------------
Steffen