freetds AT lists.ibiblio.org
Subject: FreeTDS Development Group
List archive
Re: [freetds] SQLCancel() and error diagnostic: Expecting HY008 SQLSTATE
- From: Sebastien FLAESCH <sf AT 4js.com>
- To: FreeTDS Development Group <freetds AT lists.ibiblio.org>
- Subject: Re: [freetds] SQLCancel() and error diagnostic: Expecting HY008 SQLSTATE
- Date: Mon, 14 Jan 2008 10:31:50 +0100
Sorry little typo in original mail, on course the code examples are UNIX
specific, not WIN32.
See below.
Sorry, will take another coffee.
Seb
Sebastien FLAESCH wrote:
James K. Lowden wrote:
Frediano Ziglio wrote:
Also itWho catches the signal? I hope it's the application.
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
Yes:
static void sigint_handler(int s)
{
int rcode;
printf(">>>> SQLCancel() ...\n");
rcode = SQLCancel(m_hstmt1);
printf(">>>> ... SQLCancel done rcode = %d\n", rcode);
CHECK_RCODE(SQL_HANDLE_STMT,m_hstmt1,"SQLCancel failed");
signal(SIGINT, sigint_handler);
}
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.
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.
Actually this is what we do in our Genero VM. We just set a global variable
in the SIGINT handler, and check for it during the pseudo-code interpreter
loop...
However, our VM is a special case... As we interpret pseudo-code, we *can*
test for a interrupt flag variable between opcode interpretation.
But what about normal/simple TUI ODBC applications? I can't see any another
way as calling SQLCancel() from the signal handler... How would you implement
SQL interruption in a text-based SQL command interpreter?
From the ODBC programmer point of view, the steps are:
1) Call SQLExecute() ... wait for response.
2) Get a SIGINT signal... handler gets called and calls SQLCancel()
3) SQLExecute() should stop with SQL Error.
4) Application code must handle the error.
For sure GUI applications typically handle user interruption by catching
a special GUI event (click on cancel button), and can then call SQLCancel()
outside a signal handler flow... be this is about a non-GUI application.
- cancel token is sent, in_cancel get 1, current_statement is resetBy whom? It's too soon....
- select/poll stop with EINTR errorThe driver could steer here. We could add a property to the FreeTDS ODBC
- interrupt is call (which do nothing)
driver that would let the app tell the driver how to treat EINTR on reads.
Default behavior probably should be to return TDS_INT_CANCEL if sock_errno
== TDSSOCK_EINTR.
Writes are a different matter. There's no cancel packet to send. The
library should ignore the signal and let the application handle it.
I did not look at the code in detail, but you probably known that UNIX
system calls like read() or recv() can be interrupted (EINTR) and need
to be re-executed until all bytes have been processed...
Example of code we have (note this is a short version with WIN32 specific
... *without* the WIN32 specific code!!! It's UNIX only.
code - there are as you can imagine some differences when using MSVCRT):
static int uic_Reader_read(uic_Reader * r, char *dst, int size)
{
int n, rv = 0;
while(size) {
if ((n = recv(r->c->sockfd, dst, size, 0)) < 0) {
if (errno != EINTR) {
/* Handle TCP error */
}
return rv ? rv : -1;
} else {
if (n == 0) { /* EOF */
return rv;
}
rv += n;
size -= n;
dst += n;
}
}
return rv;
}
or:
static int my_write(int fd, const char *aSrc, int aSize)
{
int status = 0;
int size, n;
char *src;
status = 0;
src = (char *) aSrc;
size = aSize;
while (size) {
n = write(fd, src, size);
if (n == -1) {
if (errno == EINTR) {
n = 0;
} else {
status = errno;
break;
}
}
size -= n;
src += n;
}
return status;
}
- tds_select returns 0In sum, treat EINTR like an early timeout:
- tdserror(TDSETIME) is called
- odbc_errmsg_handler close connection cause current_statement is
NULL...
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. 3. Return control to the application with a timeout error.
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.
BTW this remembers me that Oracle's OCI client handle SIGINT signals in
the client driver... Is seems that Oracle registers a signal handler after
a connect. So to get the control back, we need to register again our
signal handler... (Oracle probably do that to take control and allow
interruption of SQL queries by default)...
This is to me unexpected: The application should handle signals such as
SIGINT, and do the DB client API calls (if available) to cancel a query.
This works for us with:
- Postgresql using PQcancel()
- DB2 CLI using SQLCancel()
- ANTS DS using SQLCancel()
- Informix using sqlbreak() on Unix, and callback method on MS Windows.
- Oracle using OCIBreak() (but need to register SIGINT handle after
connection)
Bye
Seb
HTH.
--jkl
_______________________________________________
FreeTDS mailing list
FreeTDS AT lists.ibiblio.org
http://lists.ibiblio.org/mailman/listinfo/freetds
_______________________________________________
FreeTDS mailing list
FreeTDS AT lists.ibiblio.org
http://lists.ibiblio.org/mailman/listinfo/freetds
-
Re: [freetds] Are LOBs supported? Two additional bytes are fetched for text column.
, (continued)
- Re: [freetds] Are LOBs supported? Two additional bytes are fetched for text column., Sebastien FLAESCH, 01/09/2008
- Re: [freetds] Are LOBs supported? Two additional bytes are fetched for text column., Frediano Ziglio, 01/10/2008
- Re: [freetds] Are LOBs supported? Two additional bytes arefetched for text column., ZIGLIO, Frediano, VF-IT, 01/10/2008
- Re: [freetds] Are LOBs supported? Two additional bytes arefetched for text column., Sebastien FLAESCH, 01/10/2008
- Re: [freetds] Are LOBs supported? Two additional bytes arefetched for text column., ZIGLIO, Frediano, VF-IT, 01/10/2008
- [freetds] SQLCancel() and error diagnostic: Expecting HY008 SQLSTATE, Sebastien FLAESCH, 01/09/2008
- Re: [freetds] SQLCancel() and error diagnostic: Expecting HY008 SQLSTATE, ZIGLIO, Frediano, VF-IT, 01/10/2008
- Re: [freetds] SQLCancel() and error diagnostic: Expecting HY008 SQLSTATE, Frediano Ziglio, 01/13/2008
- Re: [freetds] SQLCancel() and error diagnostic: Expecting HY008 SQLSTATE, James K. Lowden, 01/14/2008
- Re: [freetds] SQLCancel() and error diagnostic: Expecting HY008 SQLSTATE, Sebastien FLAESCH, 01/14/2008
- Re: [freetds] SQLCancel() and error diagnostic: Expecting HY008 SQLSTATE, Sebastien FLAESCH, 01/14/2008
- Re: [freetds] SQLCancel() and error diagnostic: Expecting HY008 SQLSTATE, James K. Lowden, 01/14/2008
- Re: [freetds] SQLCancel() and error diagnostic: Expecting HY008 SQLSTATE, Sebastien FLAESCH, 01/15/2008
- Re: [freetds] SQLCancel() and error diagnostic: Expecting HY008SQLSTATE, ZIGLIO, Frediano, VF-IT, 01/15/2008
- Re: [freetds] SQLCancel() and error diagnostic: Expecting HY008SQLSTATE, Sebastien FLAESCH, 01/15/2008
- Re: [freetds] SQLCancel() and error diagnostic: Expecting HY008SQLSTATE, Sebastien FLAESCH, 01/15/2008
- Re: [freetds] SQLCancel() and error diagnostic: Expecting HY008SQLSTATE, Sebastien FLAESCH, 01/15/2008
- Re: [freetds] SQLCancel() anderror diagnostic: Expecting HY008SQLSTATE, ZIGLIO, Frediano, VF-IT, 01/15/2008
- Re: [freetds] SQLCancel() anderror diagnostic: Expecting HY008SQLSTATE, Sebastien FLAESCH, 01/15/2008
- Re: [freetds] SQLCancel() anderror diagnostic: Expecting HY008SQLSTATE, ZIGLIO, Frediano, VF-IT, 01/16/2008
- Re: [freetds] SQLCancel() and error diagnostic: Expecting HY008 SQLSTATE, ZIGLIO, Frediano, VF-IT, 01/15/2008
Archive powered by MHonArc 2.6.24.