[Tarantool-patches] [PATCH v5 21/52] sql: introduce bitwise operations for MEM
Mergen Imeev
imeevma at tarantool.org
Tue Apr 13 23:49:39 MSK 2021
Thank you for the review! My answers below.
On Tue, Apr 13, 2021 at 01:31:39AM +0200, Vladislav Shpilevoy wrote:
> Hi! Thanks for the fixes!
>
> See 2 comments below.
>
> > diff --git a/src/box/sql/mem.c b/src/box/sql/mem.c
> > index eee72a7fe..aeb801c7c 100644
> > --- a/src/box/sql/mem.c
> > +++ b/src/box/sql/mem.c
> > @@ -624,6 +624,115 @@ mem_rem(const struct Mem *left, const struct Mem *right, struct Mem *result)
>
> <...>
>
> > +
> > +int
> > +mem_shift_right(const struct Mem *left, const struct Mem *right,
> > + struct Mem *result)
> > +{
> > + if (is_result_null(left, right, result, FIELD_TYPE_INTEGER))
> > + return 0;
> > + int64_t a;
> > + int64_t b;
> > + if (bitwise_prepare(left, right, &a, &b) != 0)
> > + return -1;
> > + if (b <= -64)
> > + result->u.i = 0;
> > + else if (b < 0)
> > + result->u.i = a << -b;
> > + else if (b > 64)
> > + result->u.i = a >= 0 ? 0 : -1;
> > + else
> > + result->u.i = a >> b;
>
> 1. Right shit has different meaning for negative and positive
> numbers. This code produces invalid output:
>
> tarantool> box.execute('SELECT 9223372036854775808 >> 3')
> ---
> - metadata:
> - name: COLUMN_1
> type: integer
> rows:
> - [-1152921504606846976]
> ...
>
> The number should have decreased, but it should not have changed
> its sign. It should be 1152921504606846976, positive. But I see
> the same bug exists on the master branch, even though it had
> special handling for negative numbers, which is also broken.
>
> Is there a ticket for that? Can you fix it right away?
>
There is one issue about these operations: #5364. I think these bugs shuld be
fixed in this issue.
> > + result->flags = result->u.i < 0 ? MEM_Int : MEM_UInt;
> > + return 0;
> > +}
> > +
> > +int
> > +mem_bit_not(const struct Mem *mem, struct Mem *result)
> > +{
> > + mem_clear(result);
> > + result->field_type = FIELD_TYPE_INTEGER;
> > + if ((mem->flags & MEM_Null) != 0)
> > + return 0;
> > + int64_t i;
> > + bool unused;
> > + if (sqlVdbeIntValue(mem, &i, &unused) != 0) {
> > + diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(mem),
> > + "integer");
> > + return -1;
> > + }
> > + result->u.i = ~i;
> > + result->flags = result->u.i < 0 ? MEM_Int : MEM_UInt;
>
> 2. What if the original value was positive, and the user also
> expected to get a positive result? For example, what if he did
> ~CAST(value AS UNSIGNED)? Or is it useless and I am expected to
> do CAST(~value as UNSIGNED)?
I believe there is no way to get unsigned value more that INT64_MAX. Casts also
won't work:
tarantool> box.execute('select ~1;')
---
- metadata:
- name: COLUMN_1
type: integer
rows:
- [-2]
...
tarantool> box.execute('select CAST(~1 AS UNSIGNED);')
---
- null
- 'Type mismatch: can not convert -2 to unsigned'
...
More information about the Tarantool-patches
mailing list