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

Stephane Magne smagne at atimi.com
Wed May 21 15:04:07 EDT 2008


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
>




More information about the FreeTDS mailing list