[Tarantool-discussions] Rules for comparing numbers using Tarantool indexes in SQL.
Mergen Imeev
imeevma at tarantool.org
Tue Mar 10 16:23:39 MSK 2020
Hi all,
I would like to discuss comparison between numbers using an index
in SQL. I admit that I was wrong when I said that we can compare
numbers without any explicit conversion.
To achieve the same result as if we would not use any index, I
propose the following rules.
Column names in the tables below:
opcode - original operation ('>' == GT, etc.);
conditions - additional conditions on the value of the variable;
iter - iterator that will be used to search in Tarantool;
value - value that will be used to search in Tarantool;
is_none - flag, is_none == true if tuples will not be found.
I) Field type of index part == UNSIGNED:
1) mp_type of value == MP_INT:
All values with mp_type == MP_INT are less than 0 by definition.
| opcode | conditions | iter | value | is_none |
--------------------------------------------------------
| GE/GT | - | GE | 0 | No |
| LE/LT/EQ | - | - | - | Yes |
2) mp_type of value == MP_DOUBLE:
| opcode | conditions | iter | value | is_none |
-------------------------------------------------------------
| GE/GT | d < 0 | GE | 0 | No |
| LE/LT/EQ | d < 0 | - | - | Yes |
| GE/GT/EQ | d > UINT64_MAX | - | - | Yes |
| LE/LT | d > UINT64_MAX | LE | UINT64_MAX | No |
In the next table we assert that d >= 0 and d <= UINT64_MAX.
| opcode | conditions | iter | value | is_none |
----------------------------------------------------------
| GT | - | GT | (int)d | No |
| GE | d == (int)d | GE | (int)d | No |
| GE | d != (int)d | GT | (int)d | No |
| EQ | d == (int)d | EQ | (int)d | No |
| EQ | d != (int)d | - | - | Yes |
| LT | d == (int)d | LT | (int)d | No |
| LT | d != (int)d | LE | (int)d | No |
| LE | - | LE | (int)d | No |
II) Field type of index part == INTEGER:
In this case the only possible mp_type of value is MP_DOUBLE.
| opcode | conditions | iter | value | is_none |
-------------------------------------------------------------
| GE/GT | d < INT64_MIN | GE | INT64_MIN | No |
| LE/LT/EQ | d < INT64_MIN | - | - | Yes |
| GE/GT/EQ | d > UINT64_MAX | - | - | Yes |
| LE/LT | d > UINT64_MAX | LE | UINT64_MAX | No |
In the next table we assert that d >= INT64_MIN and
d < 0. In case d >= 0 and d <= UINT64_MAX we may use table for
UNSIGNED.
| opcode | conditions | iter | value | is_none |
---------------------------------------------------------
| GT | d == (int)d | GT | (int)d | No |
| GT | d != (int)d | GE | (int)d | No |
| GE | - | GE | (int)d | No |
| EQ | d == (int)d | EQ | (int)d | No |
| EQ | d != (int)d | - | - | Yes |
| LT | - | LT | (int)d | No |
| LE | d == (int)d | LE | (int)d | No |
| LE | d != (int)d | LT | (int)d | No |
III) Field type of index part == DOUBLE:
In this case, the rules are the same for MP_INT and MP_UINT. In
addition, we exclude the case when the value is less than 2^53 and
more than -2^53, since we can simply convert it to DOUBLE without
precision loss.
In the table below, we assert that the value is INTEGER which is
greater than 2^53 or less than -2^53.
| opcode | conditions | iter | value | is_none |
------------------------------------------------------------
| GT | (double)i > i | GE | (double)i | No |
| GT | (double)i <= i | GT | (double)i | No |
| GE | (double)i >= i | GE | (double)i | No |
| GE | (double)i < i | GT | (double)i | No |
| EQ | (double)i == i | EQ | (double)i | No |
| EQ | (double)i != i | - | - | Yes |
| LT | (double)i < i | LE | (double)i | No |
| LT | (double)i >= i | LT | (double)i | No |
| LE | (double)i <= i | LE | (double)i | No |
| LE | (double)i > i | LT | (double)i | No |
More information about the Tarantool-discussions
mailing list