Tim Bunce wrote:

> 
> Post a diff and I'll review it for you. The code you appended previously
> looks ok.

Attached is a diff for DBD::Oracle based on subversion this morning (the
diffs for oci8.c may be a little difficult to read due to the large
indentation of the surrounding code and there are some additional
changes to fix comments). It adds support for DiscardString and
StrictlyTyped bind_col attributes and  casting via sql_type_cast. Most
(all relevant) changes are conditional on a DBI with these features.

I have verified these changes work with Oracle 11 and DBD::Oracle from
subversion however, I note some lob tests were failing in DBD::Oracle
before my changes were applied.

There seem to be a large number of warnings compiling DBD::Oracle from
subversion but I've not touched any of them preferring to keep the patch
restricted to its purpose.

The issue with the SQL_DECIMAL return in sql_type_castsvpv still exists
(the NV_PRESERVES_UV issue) - I have not had time to look into this
properly as yet.

All comments appreciated.

Martin
-- 
Martin J. Evans
Easysoft Limited
http://www.easysoft.com
Index: oci8.c
===================================================================
--- oci8.c	(revision 13624)
+++ oci8.c	(working copy)
@@ -431,7 +431,7 @@
 	case OCI_ATTR_FSPRECISION OCI_ATTR_PDSCL:return "";*/
 	                                          /* fs prec for datetime data types */
 	case OCI_ATTR_PDPRC:				return "OCI_ATTR_PDPRC";                         /* packed decimal format
-	case OCI_ATTR_LFPRECISION OCI_ATTR_PDPRC: return "";
+                                                                                                            case OCI_ATTR_LFPRECISION OCI_ATTR_PDPRC: return ""; */
 	                                          /* fs prec for datetime data types */
 	case OCI_ATTR_PARAM_COUNT:			return "OCI_ATTR_PARAM_COUNT";       /* number of column in the select list */
 	case OCI_ATTR_ROWID:				return "OCI_ATTR_ROWID";                                     /* the rowid */
@@ -513,7 +513,7 @@
 	case OCI_ATTR_COL_COUNT:			return "OCI_ATTR_COL_COUNT";        /* columns of column array
 	                                                     processed so far.       */
 	case OCI_ATTR_STREAM_OFFSET:		return "OCI_ATTR_STREAM_OFFSET";  /* str off of last row processed
-	case OCI_ATTR_SHARED_HEAPALLO:				return "";    /* Shared Heap Allocation Size */
+                                                                                     case OCI_ATTR_SHARED_HEAPALLO:				return "";*/    /* Shared Heap Allocation Size */
 
 	case OCI_ATTR_SERVER_GROUP:			return "OCI_ATTR_SERVER_GROUP";    /* server group name */
 
@@ -686,7 +686,7 @@
 
 	/* Attr to allow setting of the stream version PRIOR to calling Prepare */
 	case OCI_ATTR_DIRPATH_STREAM_VERSION:	return "OCI_ATTR_DIRPATH_STREAM_VERSION";      /* version of the stream
-	case OCI_ATTR_RESERVED_11:				return "OCI_ATTR_RESERVED_11";                 /* reserved */
+                                                                                                  case OCI_ATTR_RESERVED_11:				return "OCI_ATTR_RESERVED_11";*/                 /* reserved */
 
 	case OCI_ATTR_RESERVED_12:			return "OCI_ATTR_RESERVED_12";                 /* reserved */
 	case OCI_ATTR_RESERVED_13:			return "OCI_ATTR_RESERVED_13";                 /* reserved */
@@ -2668,7 +2668,7 @@
 
 
 
-/*static int			/* --- Setup the row cache for this sth --- */
+static int			/* --- Setup the row cache for this sth --- */
 sth_set_row_cache(SV *h, imp_sth_t *imp_sth, int max_cache_rows, int num_fields, int has_longs)
 {
 	dTHX;
@@ -3742,10 +3742,38 @@
 						while(datalen && p[datalen - 1]==' ')
 							--datalen;
 					}
-					sv_setpvn(sv, p, (STRLEN)datalen);
-					if (CSFORM_IMPLIES_UTF8(fbh->csform) ){
-						SvUTF8_on(sv);
-					}
+                    sv_setpvn(sv, p, (STRLEN)datalen);
+#if DBISTATE_VERSION > 94
+                    /* DBIXS_REVISION > 13590 */
+                    /* If a bind type was specified we use DBI's sql_type_cast
+                       to cast it - currently only number types are handled */
+                    if (fbh->req_type != 0) {
+                        int sts;
+                        D_imp_xxh(sth);
+                        char errstr[256];
+
+                        sts = DBIc_DBISTATE(imp_sth)->sql_type_cast_svpv(
+                            aTHX_ sv, fbh->req_type, fbh->bind_flags, NULL);
+                        if (sts == 0) {
+                            sprintf(errstr,
+                                    "over/under flow converting column %d to type %ld",
+                                    i+1, fbh->req_type);
+                            oci_error(sth, imp_sth->errhp, OCI_ERROR, errstr);
+                            return Nullav;
+
+                        } else if (sts == -2) {
+                            sprintf(errstr,
+                                    "unsupported bind type %ld for column %d",
+                                    fbh->req_type, i+1);
+                            return Nullav;
+                        }
+                    } else
+#endif /* DBISTATE_VERSION > 94 */
+                    {
+                        if (CSFORM_IMPLIES_UTF8(fbh->csform) ){
+                            SvUTF8_on(sv);
+                        }
+                    }
 				}
 			}
 
Index: Changes
===================================================================
--- Changes	(revision 13624)
+++ Changes	(working copy)
@@ -13,6 +13,7 @@
   Fix for rt.cpan.org Ticket #=46246 fetching from nested cursor (returned from procedure) leads to application crash (abort) from John Scoles
   Fix for rt.cpan.org Ticket #=46016  LOBs bound with ora_field broken from RKITOVER
   Fix for bug in 58object.t when test run as externally identified user from Charles Jardine
+  Add support for the TYPE attribute on bind_col and the new DBI bind_col attributes StrictlyTyped and DiscardString from Martin J. Evans 
 
 =head1 Changes in DBD-Oracle 1.23(svn rev 12724)
   Fix from rt.cpan.org ticket #=44788 bool in_lite should be char in_literal 
Index: dbdimp.c
===================================================================
--- dbdimp.c	(revision 13624)
+++ dbdimp.c	(working copy)
@@ -871,7 +871,50 @@
 	return 1;
 }
 
+int dbd_st_bind_col(SV *sth, imp_sth_t *imp_sth, SV *col, SV *ref, IV type, SV *attribs) {
+    dTHX;
+    int field;
 
+    if (!SvIOK(col)) {
+        croak ("Invalid column number") ;
+    }
+
+    field = SvIV(col);
+
+    if ((field < 1) || (field > DBIc_NUM_FIELDS(imp_sth))) {
+        croak("cannot bind to non-existent field %d", field);
+    }
+
+    imp_sth->fbh[field-1].req_type = type;
+    imp_sth->fbh[field-1].bind_flags = 0; /* default to none */
+
+#if DBIXS_REVISION >= 13590
+    /* DBIXS 13590 added StrictlyTyped and DiscardString attributes */
+    if (attribs) {
+        HV *attr_hash;
+        SV **attr;
+
+        if (!SvROK(attribs)) {
+            croak ("attributes is not a reference");
+        } else if (SvTYPE(SvRV(attribs)) != SVt_PVHV) {
+            croak ("attributes not a hash reference");
+        }
+        attr_hash = (HV *)SvRV(attribs);
+
+        attr = hv_fetch(attr_hash, "StrictlyTyped", (U32)13, 0);
+        if (attr && SvTRUE(*attr)) {
+            imp_sth->fbh[field-1].bind_flags |= DBIstcf_STRICT;
+        }
+
+        attr = hv_fetch(attr_hash, "DiscardString", (U32)13, 0);
+        if (attr && SvTRUE(*attr)) {
+            imp_sth->fbh[field-1].bind_flags |= DBIstcf_DISCARD_STRING;
+        }
+    }
+#endif  /* DBIXS_REVISION >= 13590 */
+    return 1;
+}
+
 int
 dbd_db_disconnect(SV *dbh, imp_dbh_t *imp_dbh)
 {
Index: dbdimp.h
===================================================================
--- dbdimp.h	(revision 13624)
+++ dbdimp.h	(working copy)
@@ -113,7 +113,7 @@
 	int				fetch_offset;
 	int				fetch_position;
 	int 			prefetch_memory;	/* OCI_PREFETCH_MEMORY*/
-	int				prefetch_rows;		/* OCI_PREFETCH_ROWS
+    int				prefetch_rows;		/* OCI_PREFETCH_ROWS */
 	/* array fetch: state variables */
 	int				row_cache_off;
 	int 			rs_fetch_count;		/*fetch count*/
@@ -194,6 +194,9 @@
 	int			piece_lob;  /*use piecewise fetch for lobs*/
 	/* Our storage space for the field data as it's fetched	*/
 	sword		ftype;	/* external datatype we wish to get	*/
+        IV            req_type;                /* type passed to bind_col */
+        UV            bind_flags;               /* flags passed to bind_col */
+    
 	fb_ary_t	*fb_ary ;	/* field buffer array			*/
 	/* if this is an embedded object we use this */
 	fbh_obj_t	*obj;
@@ -376,6 +379,7 @@
 #define dbd_st_FETCH_attrib	ora_st_FETCH_attrib
 #define dbd_describe		ora_describe
 #define dbd_bind_ph			ora_bind_ph
+#define dbd_st_bind_col         ora_st_bind_col
 #include "ocitrace.h"
 
 /* end */
Index: Oracle.h
===================================================================
--- Oracle.h	(revision 13624)
+++ Oracle.h	(working copy)
@@ -67,6 +67,7 @@
 int	 dbd_db_do _((SV *sv, char *statement));
 int	 dbd_db_commit     _((SV *dbh, imp_dbh_t *imp_dbh));
 int	 dbd_db_rollback   _((SV *dbh, imp_dbh_t *imp_dbh));
+int dbd_st_bind_col(SV *sth, imp_sth_t *imp_sth, SV *col, SV *ref, IV type, SV *attribs);
 int	 dbd_db_disconnect _((SV *dbh, imp_dbh_t *imp_dbh));
 void dbd_db_destroy    _((SV *dbh, imp_dbh_t *imp_dbh));
 int	 dbd_db_STORE_attrib _((SV *dbh, imp_dbh_t *imp_dbh, SV *keysv, SV *valuesv));

Reply via email to