Skip to content

Commit

Permalink
sql: separate VDBE memory holding positive and negative ints
Browse files Browse the repository at this point in the history
As it was stated in the previous commit message, we are going to support
operations on unsigned values. Since unsigned and signed integers have
different memory representations, to provide correct results of
arithmetic operations we should be able to tell whether value is signed
or not.
This patch introduces new type of value placed in VDBE memory cell -
MEM_UInt. This flag means that value is integer and greater than zero,
hence can be fitted in range [0, 2^64 - 1]. Such approach would make
further replacing MEM_* flags with MP_ format types quite easy: during
decoding and encoding msgpack we assume that negative integers have
MP_INT type and positive - MP_UINT. We also add and refactor several
auxiliary helpers to operate on integers. Note that current changes
don't add ability to operate on unsigned integers - it is still
unavailable.

Needed for #3810
Needed for #4015
  • Loading branch information
Korablev77 committed Jul 5, 2019
1 parent dfe5912 commit 1fed024
Show file tree
Hide file tree
Showing 11 changed files with 375 additions and 264 deletions.
19 changes: 11 additions & 8 deletions src/box/execute.c
Expand Up @@ -139,17 +139,20 @@ sql_column_to_messagepack(struct sql_stmt *stmt, int i,
switch (type) {
case MP_INT: {
int64_t n = sql_column_int64(stmt, i);
if (n >= 0)
size = mp_sizeof_uint(n);
else
size = mp_sizeof_int(n);
size = mp_sizeof_int(n);
char *pos = (char *) region_alloc(region, size);
if (pos == NULL)
goto oom;
if (n >= 0)
mp_encode_uint(pos, n);
else
mp_encode_int(pos, n);
mp_encode_int(pos, n);
break;
}
case MP_UINT: {
uint64_t n = sql_column_int64(stmt, i);
size = mp_sizeof_uint(n);
char *pos = (char *) region_alloc(region, size);
if (pos == NULL)
goto oom;
mp_encode_uint(pos, n);
break;
}
case MP_DOUBLE: {
Expand Down
3 changes: 3 additions & 0 deletions src/box/lua/lua_sql.c
Expand Up @@ -60,6 +60,9 @@ lua_sql_call(sql_context *pCtx, int nVal, sql_value **apVal) {
case MP_INT:
luaL_pushint64(L, sql_value_int64(param));
break;
case MP_UINT:
luaL_pushuint64(L, sql_value_int64(param));
break;
case MP_DOUBLE:
lua_pushnumber(L, sql_value_double(param));
break;
Expand Down
14 changes: 10 additions & 4 deletions src/box/sql/func.c
Expand Up @@ -111,6 +111,7 @@ typeofFunc(sql_context * context, int NotUsed, sql_value ** argv)
UNUSED_PARAMETER(NotUsed);
switch (sql_value_type(argv[0])) {
case MP_INT:
case MP_UINT:
z = "integer";
break;
case MP_STR:
Expand Down Expand Up @@ -145,6 +146,7 @@ lengthFunc(sql_context * context, int argc, sql_value ** argv)
switch (sql_value_type(argv[0])) {
case MP_BIN:
case MP_INT:
case MP_UINT:
case MP_DOUBLE:{
sql_result_int(context,
sql_value_bytes(argv[0]));
Expand Down Expand Up @@ -177,6 +179,7 @@ absFunc(sql_context * context, int argc, sql_value ** argv)
assert(argc == 1);
UNUSED_PARAMETER(argc);
switch (sql_value_type(argv[0])) {
case MP_UINT:
case MP_INT:{
i64 iVal = sql_value_int64(argv[0]);
if (iVal < 0) {
Expand Down Expand Up @@ -1017,6 +1020,7 @@ quoteFunc(sql_context * context, int argc, sql_value ** argv)
SQL_TRANSIENT);
break;
}
case MP_UINT:
case MP_INT:{
sql_result_value(context, argv[0]);
break;
Expand Down Expand Up @@ -1419,7 +1423,8 @@ trim_func_two_args(struct sql_context *context, int argc, sql_value **argv)
return;

int input_str_sz = sql_value_bytes(argv[1]);
if (sql_value_type(argv[0]) == MP_INT) {
if (sql_value_type(argv[0]) == MP_INT ||
sql_value_type(argv[0]) == MP_UINT) {
uint8_t len_one = 1;
trim_procedure(context, sql_value_int(argv[0]),
(const unsigned char *) " ", &len_one, 1,
Expand Down Expand Up @@ -1450,7 +1455,8 @@ trim_func_three_args(struct sql_context *context, int argc, sql_value **argv)
assert(argc == 3);
(void) argc;

assert(sql_value_type(argv[0]) == MP_INT);
assert(sql_value_type(argv[0]) == MP_INT ||
sql_value_type(argv[0]) == MP_UINT);
const unsigned char *input_str, *trim_set;
if ((input_str = sql_value_text(argv[2])) == NULL ||
(trim_set = sql_value_text(argv[1])) == NULL)
Expand Down Expand Up @@ -1561,7 +1567,7 @@ sum_step(struct sql_context *context, int argc, sql_value **argv)
int type = sql_value_type(argv[0]);
if (type == MP_NIL || p == NULL)
return;
if (type != MP_DOUBLE && type != MP_INT) {
if (type != MP_DOUBLE && type != MP_INT && type != MP_UINT) {
if (mem_apply_numeric_type(argv[0]) != 0) {
diag_set(ClientError, ER_SQL_TYPE_MISMATCH,
sql_value_text(argv[0]), "number");
Expand All @@ -1571,7 +1577,7 @@ sum_step(struct sql_context *context, int argc, sql_value **argv)
type = sql_value_type(argv[0]);
}
p->cnt++;
if (type == MP_INT) {
if (type == MP_INT || type == MP_UINT) {
int64_t v = sql_value_int64(argv[0]);
p->rSum += v;
if ((p->approx | p->overflow) == 0 &&
Expand Down

0 comments on commit 1fed024

Please sign in to comment.