Re: Problem with FreeTDS validating SQL commands (actually a ct_cancel() error)
Stephane Magne <[email protected]>
| Newsgroups | gmane.comp.db.tds.freetds |
|---|---|
| Message-ID | <[email protected]> |
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
> [email protected]
> http://lists.ibiblio.org/mailman/listinfo/freetds
>
_______________________________________________
FreeTDS mailing list
[email protected]
http://lists.ibiblio.org/mailman/listinfo/freetds