Skip to Content.
Sympa Menu

freetds - Re: [freetds] Problem with FreeTDS validating SQL commands (actually a ct_cancel() error)

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: Stephane Magne <smagne AT atimi.com>
  • To: FreeTDS Development Group <freetds AT lists.ibiblio.org>
  • Subject: Re: [freetds] Problem with FreeTDS validating SQL commands (actually a ct_cancel() error)
  • Date: Wed, 21 May 2008 12:04:07 -0700

Hi James,

Yeah, I wasn't sure if my explanation was very clear at all yesterday ;)

I've attached the diff file, but I'll add an explanation in case it's not clear.


In ct.c, in the function ct_cancel(), I noticed a difference in the logic between the CS_CANCEL_ATTN case and the CS_CANCEL_ALL case.

Essentially, when the application passed the CS_CANCEL_ALL parameter, the command wouldn't be properly cancelled, but when I used the CS_CANCEL_ATTN parameter the cancel would work correctly.

Comparing the two, I noticed that the highlighted lines in the code below appeared in the CS_CANCEL_ATTN block, but didn't appear in the equivalent locations in the CS_CANCEL_ALL block. So I just added the two lines to the proper locations in the CS_CANCEL_ALL block of code and it cancelled the query properly.

if (type == CS_CANCEL_ATTN) {
if ((conn && cmd) || (!conn && !cmd)) {
return CS_FAIL;
}
if (cmd) {
tdsdump_log(TDS_DBG_FUNC, "CS_CANCEL_ATTN with cmd\n");
cmd_conn = cmd->con;
switch (cmd->command_state) {
case _CS_COMMAND_IDLE:
case _CS_COMMAND_READY:
tdsdump_log(TDS_DBG_FUNC, "ct_cancel() command
state READY/IDLE\n");
break;
case _CS_COMMAND_SENT:
tdsdump_log(TDS_DBG_FUNC, "ct_cancel() command state SENT results_state %d\n", cmd->results_state);
if (cmd->results_state != _CS_RES_NONE) {
tdsdump_log(TDS_DBG_FUNC, "ct_cancel()
sending a cancel \n");
tds_send_cancel(cmd_conn->tds_socket);

********* cmd->cancel_state =
_CS_CANCEL_PENDING;
}
break;
}
}
if (conn) {
tdsdump_log(TDS_DBG_FUNC, "CS_CANCEL_ATTN with connection\n");
for (cmds = conn->cmds; cmds != NULL; cmds = cmds->next) {
conn_cmd = cmds->cmd;
switch (conn_cmd->command_state) {
case _CS_COMMAND_IDLE:
case _CS_COMMAND_READY:
tdsdump_log(TDS_DBG_FUNC, "ct_cancel() command state READY/IDLE \n");
break;
case _CS_COMMAND_SENT:
tdsdump_log(TDS_DBG_FUNC, "ct_cancel()
command state SENT\n");
if (conn_cmd->results_state !=
_CS_RES_NONE) {
tdsdump_log(TDS_DBG_FUNC,
"ct_cancel() sending a cancel \n");

tds_send_cancel(conn->tds_socket);

********* conn_cmd->cancel_state =
_CS_CANCEL_PENDING;
}
break;
}
}
}


I hope that clears things up.

Stephane





On 20-May-08, at 7:24 PM, James K. Lowden wrote:

Stephane Magne wrote:
the case statement for CS_CANCEL_ALL, there is a
line of code missing.

In the case of _CS_COMMAND_SENT, the cancel_state isn't being set
properly.
So the final line of the case statement should be

case _CS_COMMAND_SENT:

Hi Stephane,

Cancelling is very tricky to get right, and I'm glad for your attention to
it in ct-lib, because we currently lack an expert. But I'm afraid neither
your reasoning nor your remedy is quite clear to me yet. :-(

Could you post the output of "diff -u" so I can see exactly what you mean
by "the final line", and explain again how the logic goes awry? I would
be much obliged.

Regards,

--jkl

_______________________________________________
FreeTDS mailing list
FreeTDS AT lists.ibiblio.org
http://lists.ibiblio.org/mailman/listinfo/freetds






Archive powered by MHonArc 2.6.24.

Top of Page