I just ran into this problem...

A stored procedure call like "exec foo ..." was appearing to succeed but
returning no data.

It turned out that the ASE (15.0, which we've recently upgraded to) was
terminating the backend process (not sure why yet) but DBD::Sybase 1.08
wasn't noticing it.

Here's the trace:

    -> execute for DBD::Sybase::st (DBI::st=HASH(0x2a995b0360)~0x2a995b04b0)
    syb_alloc_cmd() -> CS_COMMAND 294e7e0 for CS_CONNECTION 294b8e0
    cmd_execute() -> ct_command() OK
    cmd_execute() -> ct_send() OK
    cmd_execute() -> set inUse flag
    servermsg_cb -> number=5702 severity=10 state=1 line=2 server=dev_barbie01 
text=ASE is terminating this process.
    st_next_result() -> ct_results(4047) == 1
    st_next_result() -> ct_results(4046) == 1
ct_results(4046) final retcode = -205
    st_next_result() -> lasterr = 0, lastsev = 0
    st_next_result() -> got CS_CMD_DONE: resetting ACTIVE, moreResults, 
dyn_execed, exec_done
    clear_sth_flags() -> resetting ACTIVE, moreResults, dyn_execed, exec_done
    clear_sth_flags() -> reset inUse flag
    <- execute= -1
    <- $DBI::err= undef
    <- $DBI::errstr= 'Server message number=5702 severity=10 state=1 line=2 
server=dev_barbie01 text=ASE is terminating this process.'   

Notice that although errstr contains the error message, err is undef.

The next time the connection was used it would fail with "Message String: 
ct_send(): network packet layer: internal Client Library error: State error: 
trying to write when connection is expecting a read."

I've appended a patch that seems to fix the problem, but I don't know if
it's doing the right thing in the best way. For example, I tried
adjusting the "severity > 10" to "severity >= 10" in the code below
but that caused some tests to fail.

Michael, any chance you could review this and get it (or a better fix)
released soonish?

Tim.


--- DBD-Sybase-1.08/dbdimp.c    2007-04-19 11:31:19.000000000 -0700
+++ DBD-Sybase-1.08.err5702/dbdimp.c    2008-06-12 09:06:04.000000000 -0700
@@ -498,11 +498,21 @@
 
     
     if(imp_dbh && srvmsg->msgnumber) {
-       if(srvmsg->severity > 10) {
+       /* error 5702 (severity=10 state=1 text=ASE is terminating this process)
+        * may be delivered only via servermsg_cb. If we don't deal with it here
+        * the command can appear to complete successfully. errstr will contain
+        * the error message but err will be false.
+        */
+       if(srvmsg->severity > 10 || srvmsg->msgnumber == 5702) {
            sv_setiv(DBIc_ERR(imp_dbh), (IV)srvmsg->msgnumber);
 
            imp_dbh->lasterr = srvmsg->msgnumber;
            imp_dbh->lastsev = srvmsg->severity;
+
+           if (srvmsg->msgnumber == 5702) {
+               ct_close(connection, CS_FORCE_CLOSE);
+               imp_dbh->isDead = 1;
+           }
        }
 
        if(SvOK(DBIc_ERRSTR(imp_dbh))) 

Reply via email to