[Tarantool-patches] [PATCH v5 19/52] sql: introduce arithmetic operations for MEM

Vladislav Shpilevoy v.shpilevoy at tarantool.org
Thu Apr 15 02:10:42 MSK 2021


Thanks for the fixes!

>>> diff --git a/src/box/sql/mem.c b/src/box/sql/mem.c
>>> index 2d76ef88d..859e337aa 100644
>>> --- a/src/box/sql/mem.c
>>> +++ b/src/box/sql/mem.c
>>> @@ -390,6 +390,240 @@ mem_concat(struct Mem *a, struct Mem *b, struct Mem *result)
>>> +
>>> +static int
>>> +get_number(const struct Mem *mem, struct sql_num *number)
>>> +{
>>> + if ((mem->flags & MEM_Real) != 0) {
>>> +   number->d = mem->u.r;
>>> +   number->type = MEM_Real;
>>> +   return 0;
>>> + }
>>> + if ((mem->flags & MEM_Int) != 0) {
>>> +   number->i = mem->u.i;
>>> +   number->type = MEM_Int;
>>> +   number->is_neg = true;
>>> +   return 0;
>>> + }
>>> + if ((mem->flags & MEM_UInt) != 0) {
>>> +   number->u = mem->u.u;
>>> +   number->type = MEM_UInt;
>>> +   number->is_neg = false;
>>> +   return 0;
>>> + }
>>> + if ((mem->flags & (MEM_Str | MEM_Blob)) == 0)
>>> +   return -1;
>>> + if ((mem->flags & MEM_Subtype) != 0)
>>> +   return -1;
>>> + if (sql_atoi64(mem->z, &number->i, &number->is_neg, mem->n) == 0) {
>>> +   number->type = number->is_neg ? MEM_Int : MEM_UInt;
>>> +   /*
>>> +    * The next line should be removed along with the is_neg field
>>> +    * of struct sql_num. The integer type tells us about the sign.
>>> +    * However, if it is removed, the behavior of arithmetic
>>> +    * operations will change.
>>> +    */
>>> +   number->is_neg = (mem->flags & MEM_Int) != 0;
>>
>> I don't understand that. How is it possible it mismatches the
>> value returned from sql_atoi64()? And why isn't it just 'false' then?
>> Because a few lines above you already checked (mem->flags & MEM_Int) != 0
>> and it was false.
>>
> Not exactly right. For example:
> 
> tarantool> box.execute([[SELECT '-5' + 2;]])
> ---
> - metadata:
>   - name: COLUMN_1
>     type: integer
>   rows:
>   - [18446744073709551613]
> ...
> 
> As you see, this is wrong. This is due to the fact, that MEM of type string do
> not have MEM_Int set. Even though this is wrong, it is expected behaviour. I
> created an issue for this: #5756. Since I didn't want to change this behaviour,
> I added is_neg field to struct sql_num. This is clearly a hack and should be
> fixed.

But that does not answer the second part of my question - why can't
I set it to false here always?

====================
@@ -286,7 +286,7 @@ get_number(const struct Mem *mem, struct sql_num *number)
 		 * However, if it is removed, the behavior of arithmetic
 		 * operations will change.
 		 */
-		number->is_neg = (mem->flags & MEM_Int) != 0;
+		number->is_neg = false;
 		return 0;
 	}
====================

Because (mem->flags & MEM_Int) == 0, otherwise it would return earlier above.

Also 'is_neg' is not used at all now in all places where get_number() is called.
At least in this commit. I would propose to add it in the commit which needs it
or remove it then now.


More information about the Tarantool-patches mailing list