[tarantool-patches] Re: [PATCH 4/6] sql: make built-in functions operate on unsigned values
n.pettik
korablev at tarantool.org
Mon Jul 1 17:21:40 MSK 2019
>> diff --git a/src/box/sql/func.c b/src/box/sql/func.c
>> index 457c9b92b..365f8f9d2 100644
>> --- a/src/box/sql/func.c
>> +++ b/src/box/sql/func.c
>> @@ -645,21 +638,13 @@ ICU_CASE_CONVERT(Upper);
>> static void
>> randomFunc(sql_context * context, int NotUsed, sql_value ** NotUsed2)
>> {
>> - sql_int64 r;
>> + int64_t r;
>> UNUSED_PARAMETER2(NotUsed, NotUsed2);
>> sql_randomness(sizeof(r), &r);
>> - if (r < 0) {
>> - /* We need to prevent a random number of 0x8000000000000000
>> - * (or -9223372036854775808) since when you do abs() of that
>> - * number of you get the same value back again. To do this
>> - * in a way that is testable, mask the sign bit off of negative
>> - * values, resulting in a positive value. Then take the
>> - * 2s complement of that positive value. The end result can
>> - * therefore be no less than -9223372036854775807.
>> - */
>> - r = -(r & LARGEST_INT64);
>> - }
>> - sql_result_int64(context, r);
>> + if (r < 0)
>> + sql_result_int(context, r);
>> + else
>> + sql_result_uint(context, r);
>
> 1. To avoid such mess I propose you the same as for mem_set_int - make
> several functions:
What kind of mess do you mean? Here we have two functions:
one sets unsigned result, another one - signed. Pretty straight
approach, isn’t it? What is more, this is the only place where
branching is required.
> /* Return an int64 value, sign is detected inside. */
> sql_result_i64(int64_t value);
>
> /* Return a uint64 value. */
> sql_result_u64(uint64_t value);
>
> /* Return an integer value with explicit sign. */
> sql_result_int(int64_t value, bool is_negative);
>
>> diff --git a/src/box/sql/sqlInt.h b/src/box/sql/sqlInt.h
>> index c0e2ab699..4697e3003 100644
>> --- a/src/box/sql/sqlInt.h
>> +++ b/src/box/sql/sqlInt.h
>> @@ -455,6 +455,9 @@ sql_column_subtype(struct sql_stmt *stmt, int i);
>> sql_int64
>> sql_value_int64(sql_value *);
>>
>> +uint64_t
>> +sql_value_uint64(sql_value *val);
>> +
>> const unsigned char *
>> sql_value_text(sql_value *);
>>
>> @@ -496,13 +499,13 @@ void
>> sql_result_error_code(sql_context *, int);
>>
>> void
>> -sql_result_int(sql_context *, int);
>> +sql_result_int(sql_context *, int64_t);
>>
>> void
>> -sql_result_bool(struct sql_context *ctx, bool value);
>> +sql_result_uint(sql_context *ctx, int64_t u_val);
>
> 2. Why result_uint takes int instead of uint?
Because mem_set_int() accepts int64 and to avoid
extra casts to uint (since almost al used values are singed).
> 3. Please, move 'result_uint' above 'result_int' to
> avoid messing diff with 'result_bool’.
… Ok, done.
>> diff --git a/src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h
>> index abed46486..0c86ed0f3 100644
>> --- a/src/box/sql/vdbeInt.h
>> +++ b/src/box/sql/vdbeInt.h
>> @@ -501,7 +501,7 @@ void sqlVdbeMemShallowCopy(Mem *, const Mem *, int);
>> void sqlVdbeMemMove(Mem *, Mem *);
>> int sqlVdbeMemNulTerminate(Mem *);
>> int sqlVdbeMemSetStr(Mem *, const char *, int, u8, void (*)(void *));
>> -void sqlVdbeMemSetInt64(Mem *, i64);
>> +void sqlVdbeMemSetInt64(Mem *, i64, bool is_neg);
>
> 4. That function does not exist. And looks like its existence has
> ceased not in this commit, but in one of the previous ones. Please,
> drop.
Removed in previous patch.
>> diff --git a/src/box/sql/vdbeapi.c b/src/box/sql/vdbeapi.c
>> index 393782c23..752efeecb 100644
>> --- a/src/box/sql/vdbeapi.c
>> +++ b/src/box/sql/vdbeapi.c
>> @@ -239,6 +239,16 @@ sql_value_int64(sql_value * pVal)
>> return i;
>> }
>>
>> +uint64_t
>> +sql_value_uint64(sql_value *val)
>> +{
>> + int64_t i = 0;
>> + bool is_neg;
>> + sqlVdbeIntValue((struct Mem *) val, &i, &is_neg);
>> + assert(!is_neg);
>
> 5. Why did not you add a similar assertion to sql_value_int64()?
Because it can accept both signed and unsigned values.
>> diff --git a/test/sql-tap/fkey2.test.lua b/test/sql-tap/fkey2.test.lua
>> index 54e5059b3..8e786edec 100755
>> --- a/test/sql-tap/fkey2.test.lua
>> +++ b/test/sql-tap/fkey2.test.lua
>> @@ -320,10 +320,10 @@ test:do_execsql_test(
>> CREATE TABLE j(j INT PRIMARY KEY REFERENCES i);
>> INSERT INTO i VALUES(35);
>> INSERT INTO j VALUES(35);
>> - SELECT j, typeof(j) FROM j;
>> + SELECT j FROM j;
>> ]], {
>> -- <fkey2-2.1>
>> - 35, "integer"
>> + 35
>
> 6. Why did you drop 'typeof' instead of having it
> fixed?
Because typeof() function will be fixed: it should return
type of column, not type of particular value. To avoid
abusing test files, I decided to drop it (since it is going
to change again soon).
>> diff --git a/test/sql-tap/func.test.lua b/test/sql-tap/func.test.lua
>> index 314c528ab..9cf9c2f67 100755
>> --- a/test/sql-tap/func.test.lua
>> +++ b/test/sql-tap/func.test.lua
>> @@ -1742,10 +1742,20 @@ test:do_catchsql_test(
>> SELECT abs(-9223372036854775807-1);
>> ]], {
>> -- <func-18.32>
>> - 1, "Failed to execute SQL statement: integer overflow"
>> + 0, {9223372036854775808LL}
>> -- </func-18.32>
>> })
>>
>> +test:do_catchsql_test(
>> + "func-18.33",
>> + [[
>> + SELECT abs(-9223372036854775807-1);
>> + ]], {
>> + -- <func-18.32>
>> + 0, {9223372036854775808LL}
>> + -- </func-18.32>
>> +})
>
> 7. But this test is exactly the same as the previous one. Why
> do you need it?
Probably I wanted to do this:
diff --git a/test/sql-tap/func.test.lua b/test/sql-tap/func.test.lua
index 4d96f2fed..3ff623e82 100755
--- a/test/sql-tap/func.test.lua
+++ b/test/sql-tap/func.test.lua
@@ -1749,10 +1749,10 @@ test:do_catchsql_test(
test:do_catchsql_test(
"func-18.33",
[[
- SELECT abs(-9223372036854775807-1);
+ SELECT abs(-9223372036854775807-2);
]], {
-- <func-18.32>
- 0, {9223372036854775808LL}
+ 1, "Failed to execute SQL statement: integer is overflowed"
-- </func-18.32>
})
>
> Consider my review fixes here and on the branch in a
> separate commit.
Applied.
More information about the Tarantool-patches
mailing list