[freetds] SQLCancel() and error diagnostic: Expecting HY008 SQLSTATE

ZIGLIO, Frediano, VF-IT Frediano.Ziglio at vodafone.com
Mon Jan 14 04:05:58 EST 2008


> 
> Frediano Ziglio wrote:
> > Also it
> > seems that in some different systems signal are handled in 
> a slightly
> > different way. That is
> > - query is sent, state is set to TDS_READING
> > - select/poll stops
> > - signal is caught, SQLCancel is called
> 
> Who catches the signal?  I hope it's the application. 
> 
> I don't know the proper treatment of signals in an ODBC 
> application, but
> I'm pretty sure SQLCancel shouldn't be called in a signal 
> handler.  The
> handler doesn't have enough information to know whether 
> that's the right
> thing to do.  
> 


We correctly do not catches signals. Signals are a nightmare using
threads so I prefer not having to handle them. ODBC specification say
that there are 4 cancel types:
1- inline, call a statement and cancel data results, correctly supported
2- asyncronous, not still supported so no problem
3- cancel when sending long data (SQL_NEED_DATA). Never requested...
4- cancel from another thread
Cancellation on signal is not documented however:
- windows/dos does not have a signal handling working/used like *nix
systems
- ctlib specification require ct_cancel called in signal (supported, see
cancel test)

> I think all the signal handler can do is record the fact that 
> a signal was
> caught in a more-or-less global variable.  When the called function
> returns an error -- e.g. a timeout on reads -- the app can then decide
> whether or not to call SQLCancel.  
> 

As said I wouldn't handle signals in FreeTDS. The application can always
overwrite signals. Currently there is an exeption where our library
ignore SIGPIPE but only on system where send/write/recv/read do not
support ignoring signals (that is very old systems where probably thread
are not supported or rarely used). 

> > - cancel token is sent, in_cancel get 1, current_statement is reset
> 
> By whom?  It's too soon....
> 

By SQLCancel (tds_send_cancel send token and set in_cancel, SQLCancel
reset current statement)

> > - select/poll stop with EINTR error
> > - interrupt is call (which do nothing)
> 
> The driver could steer here.  We could add a property to the 
> FreeTDS ODBC
> driver that would let the app tell the driver how to treat 
> EINTR on reads.
>  

So, say continue on EINTR... yes seems ok. However int_handler is not
used only for interrupts... or to be correct is used mainly for dblib
1-second polling. Every 1 seconds a timeout is generated and handled by
dblib. I don't like dblib polling way (personally I hate polling, if I
know a query can take very long I prefer so not disturb system scheduler
every second!). 

> 
> Default behavior probably should be to return TDS_INT_CANCEL 
> if sock_errno
> == TDSSOCK_EINTR. 
> 

So close the connection ??

> Writes are a different matter.  There's no cancel packet to send.  The
> library should ignore the signal and let the application handle it.  
> 
> > - tds_select returns 0
> > - tdserror(TDSETIME) is called
> > - odbc_errmsg_handler close connection cause current_statement is
> > NULL...
> 
> In sum, treat EINTR like an early timeout: 
> 
> 1.  Don't catch the signal.  Let the app do it. 
> 2.  Let odbc_errmsg_handler return TDS_INT_TIMEOUT to tdserror(); let
> tdserror() send the cancel packet. 

Mmmm... however some implementations does not call tdserror so not
sending cancel packet on signal handler make wait undefinitely.

> 3.  Return control to the application with a timeout error. 
> 

In this case standard reply is HY008, statement cancelled.

> When control returns to the application, he'll have a failed call, a
> connection that's probably OK but might be dead, and evidence that a
> signal was caught.  
> 
> There's an expression in English, "to put two and two 
> together", meaning
> to come to the obvious conclusion.  The application puts two and two
> together, decides the signal caused the timeout, sees the state of the
> connection, and decides what to do.  
> 
> HTH.  
> 

Attached an output mixed with system trace and tds dump on a system that
get EINTR (I tested under 2 Linux systems... one returns EINTR while the
other seems to ignore them...).

freddy77
-------------- next part --------------
A non-text attachment was scrubbed...
Name: cancel.html.gz
Type: application/x-gzip
Size: 4368 bytes
Desc: cancel.html.gz
Url : http://lists.ibiblio.org/pipermail/freetds/attachments/20080114/fde3708e/attachment.bin 


More information about the FreeTDS mailing list