Re: ctlib compute columns (was: "Fix affected rows after insert with prepared query" side effect)

John Kendall <[email protected]>
Newsgroups gmane.comp.db.tds.freetds
Message-ID <[email protected]>
> On May 12, 2016, at 11:30 PM, Frediano Ziglio <[email protected]> wrote:
> 
> It's always a good idea to open a new thread for a new topic!

yes

> 2016-05-11 21:47 GMT+01:00 John Kendall <[email protected]>:
>> 
>> On May 11, 2016, at 1:23 PM, Frediano Ziglio <[email protected]> wrote:
>> 
>>> 2016-05-11 6:07 GMT+01:00 John Kendall <[email protected]>:
>>>> 
>>>>> On May 10, 2016, at 3:34 PM, Frediano Ziglio <[email protected]> wrote:
>>>>> 
>>>>> 2016-05-10 22:31 GMT+01:00 John Kendall <[email protected]>:
>>>>>> It appears the patch for this ("fix ct-library rows count") has broken compute in ctlib:
>>>>>> 
>>>>>> 
>>>>>> select col=1 into #tbl insert #tbl values (2) select * from #tbl compute sum(col)
>>>>>> (1 row affected)
>>>>>> (1 row affected)
>>>>>> col
>>>>>> -----------
>>>>>>           1
>>>>>>           2
>>>>>>           2
>>>>>> 
>>>>>> (3 rows affected)
>>>>>> 
>>>>>> dblib (and ctlib RC1) does the expected:
>>>>>> 
>>>>>> select col=1 into #tbl insert #tbl values (2) select * from #tbl compute sum(col)
>>>>>> (1 row affected)
>>>>>> (1 row affected)
>>>>>> col
>>>>>> -----------
>>>>>>           1
>>>>>>           2
>>>>>> sum
>>>>>> ===========
>>>>>>           3
>>>>>> 
>>>>>> (3 rows affected)
>>>>>> 
>>>>>> 
>>>>>> Sorry to keep finding things!
>>>>>> 
>>>>>> John
>>>>>> 
>>>>>> 
>>>>> 
>>>>> Can you put some more detailed examples? Which program did you use?
>>>>> 
>>>>> Frediano
>>>> 
>>>> I'm using sqsh.
>>>> 
>>>> The compute clause should return an extra result line.  In the example I have given above, the table is a single column table with two rows with values 1 and 2.  Adding the compute sum clause to the select should return a compute result of 3, instead it is returns an extra copy of the last row.  My example is not a special case, no compute (sum, max, min, avg, etc) results seem to be returning from any queries with a compute clause.  I never saw this problem before RC4. Backing out the 'fix ct-library rows count' patch on ct.c makes it return the expected result.
>>>> 
>>>> John
>>>> 
>>> 
>>> 
>>> Just to be sure, can you test 1.0rc5 ?
>>> 
>> 
>> I already have.   And it looks good.  Thanks.
>> While I have your attention, and you are in that part of the code, I wonder if you might look into this:
>> 
>> http://lists.ibiblio.org/pipermail/freetds/2016q1/029725.html
>> 
>> I want to clarify what I'm asking you to look into.  That was a multi-topic thread.
>> The problem I am still interested in fixing is the ct_compute_info return values.
>> (The rest of that thread turned out to just be client differences.)
>> 
> 
> Patch looks good. Take a look at "compute operator" in include/freetds/tds.h.
> 
> Looks like for dblib constants are defined as protocol so no
> transformation is required however ctlib (and our headers!) contain
> different constants. Your patch is good however:
> - I would add a small function to do the conversion;
> - I would add support for additional mssql operators (I would collapse
> CNT_BIG into count and *U ones in no -U constants).

Aha! found them in include/freetds/proto.h.  Thanks.
Agree with your suggestions.  Not sure what to do with these, however:
 SYBAOPSTDEV
 SYBAOPSTDEVP
 SYBAOPVAR
 SYBAOPVARP
 SYBAOPCHECKSUM_AGG

I don't see an obvious mapping for them.

This works for me:

*** ct.c-orig	2016-05-11 12:49:42 -0700
--- ct.c	2016-05-13 01:46:33 -0700
***************
*** 57,62 ****
--- 57,63 ----
  int _ct_bind_data(CS_CONTEXT *ctx, TDSRESULTINFO * resinfo, TDSRESULTINFO *bindinfo, CS_INT offset);
  static void _ct_initialise_cmd(CS_COMMAND *cmd);
  static CS_RETCODE _ct_cancel_cleanup(CS_COMMAND * cmd);
+ static CS_INT _ct_map_compute_op(CS_INT comp_op);
  
  /* Added for CT_DIAG */
  /* Code changes starts here - CT_DIAG - 01 */
***************
*** 2655,2661 ****
  			int_val = 0;
  		} else {
  			curcol = resinfo->columns[colnum - 1];
! 			int_val = curcol->column_operator;
  		}
  		memcpy(buffer, &int_val, sizeof(CS_INT));
  		if (outlen)
--- 2656,2662 ----
  			int_val = 0;
  		} else {
  			curcol = resinfo->columns[colnum - 1];
! 			int_val = _ct_map_compute_op(curcol->column_operator);
  		}
  		memcpy(buffer, &int_val, sizeof(CS_INT));
  		if (outlen)
***************
*** 4630,4632 ****
--- 4631,4655 ----
  	return CS_SUCCEED;
  }
  
+ static CS_INT
+ _ct_map_compute_op(CS_INT comp_op)
+ {
+ 	switch (comp_op)
+ 	{
+ 		case SYBAOPCNT: 
+ 		case SYBAOPCNTU: 
+ 		case SYBAOPCNT_BIG:
+ 		        return CS_OP_COUNT; 
+ 		case SYBAOPSUM: 
+ 		case SYBAOPSUMU: 
+ 		        return CS_OP_SUM; 
+ 		case SYBAOPAVG: 
+ 		case SYBAOPAVGU: 
+ 		        return CS_OP_AVG; 
+ 		case SYBAOPMIN: 
+ 		        return CS_OP_MIN; 
+ 		case SYBAOPMAX: 
+ 		        return CS_OP_MAX; 
+         }
+ 	return comp_op;
+ }


John


> 
> Frediano
> _______________________________________________
> 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.