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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.