The DBD::DB2 driver does not handle warnings in a manner consistent with other DBD drivers. Specifically, if the trace level is lower than 3, warnings are ignored; if the trace level is 3 or above, warnings are treated like errors. The driver also directly manipulates the DBI internals instead of using DBIh_SET_ERR_CHAR.

I have asked IBM to fix this and have received an internal defect number for this (166025); however, the latest DBD::DB2 release (1.3) does not include this feature.

The attached patch shows an attempt to fix this. It works for me, but I'm not sure it is entirely correct; feedback from DBD::xxx authors and DBI experts would be welcome.

The patch basically removes the dependency on the trace level and rips out the direct manipulation of DBIc_err, errstr and state. It treats all SQL_SUCCESS_WITH_INFO cases as warnings - perhaps these should be reported as informational events instead.

I hope IBM gets around to including this (or an improved version) in the next DBD::DB2 release; in the meantime, other users of DBD::DB2 may benefit from this change.

Cheers,
  Hildo Biersma
*** dbdimp.c.orig       Tue Dec 30 10:03:29 2008
--- dbdimp.c    Tue Dec 30 12:28:15 2008
***************
*** 54,63 ****
      SQLINTEGER sqlcode;
      SQLCHAR sqlstate[6];
      SQLCHAR msgBuffer[SQL_MAX_MESSAGE_LENGTH+1];
!     char *msg = NULL;
      SQLRETURN rec;
  
- 
      if( SQL_SUCCESS == rc )
        return rc;
  
--- 54,62 ----
      SQLINTEGER sqlcode;
      SQLCHAR sqlstate[6];
      SQLCHAR msgBuffer[SQL_MAX_MESSAGE_LENGTH+1];
!     char *msg = NULL, *err = NULL;
      SQLRETURN rec;
  
      if( SQL_SUCCESS == rc )
        return rc;
  
***************
*** 80,88 ****
          }
      }
  
-     if( SQL_SUCCESS_WITH_INFO == rc && DBIS->debug < 3 )
-       return SQL_SUCCESS;
- 
      if( handle != SQL_NULL_HANDLE )
      {
        SQLRETURN rc;
--- 79,84 ----
***************
*** 112,125 ****
        msg = what ? what : "";
      }
  
!     sv_setiv(DBIc_ERR(imp_xxh), (IV)sqlcode);
!     sv_setpv(errstr, (char *)msg);
!     sv_setpv(state,(char *)sqlstate);
!     DBIh_EVENT2(h, ERROR_event, DBIc_ERR(imp_xxh), errstr);
!     if (DBIS->debug >= 2)
!       PerlIO_printf( DBILOGFP,
!                      "%s error %d recorded: %s\n",
!                      what, rc, SvPV(errstr,na) );
  
      return( rc == SQL_SUCCESS_WITH_INFO ? SQL_SUCCESS : rc );
  }
--- 108,120 ----
        msg = what ? what : "";
      }
  
!     /* Report error or warning the DBI way */
!     if (rc == SQL_SUCCESS_WITH_INFO) {
!       err = "0";              /* "0" = warning */
!     } else {
!       err = Nullch;
!     }
!     DBIh_SET_ERR_CHAR(h, imp_xxh, err, sqlcode, msg, sqlstate, Nullch);
  
      return( rc == SQL_SUCCESS_WITH_INFO ? SQL_SUCCESS : rc );
  }
***************
*** 141,149 ****
        return rc;
      }
  
-     if( SQL_SUCCESS_WITH_INFO == rc && DBIS->debug < 3 )
-       return SQL_SUCCESS;
- 
      if( SQL_ERROR == rc || SQL_SUCCESS_WITH_INFO == rc )
      {
        imp_sth_t *imp_sth;

Reply via email to