Skip to content

Commit e61f4f6

Browse files
ImeevMAkyukhin
authored andcommitted
sql: check left operand before right in arithmetic
Prior to this patch, the right operand was checked before the left. This can lead to some complications when arithmetic operations are added for the DATETIME and INTERVAL values. To avoid this, let's check the left operand before the right one. This will cause the description of the error to change, but nothing else. Needed for tarantool#6773 NO_DOC=Not documented feature.
1 parent 95b9c87 commit e61f4f6

File tree

5 files changed

+130
-45
lines changed

5 files changed

+130
-45
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
## feature/sql
2+
3+
* The left operand is now checked before the right operand in an arithmetic
4+
operation. (gh-6773).

src/box/sql/mem.c

+8-8
Original file line numberDiff line numberDiff line change
@@ -2009,7 +2009,7 @@ mem_add(const struct Mem *left, const struct Mem *right, struct Mem *result)
20092009
mem_set_null(result);
20102010
return 0;
20112011
}
2012-
if (check_types_numeric_arithmetic(right, left) != 0)
2012+
if (check_types_numeric_arithmetic(left, right) != 0)
20132013
return -1;
20142014
if (((left->type | right->type) & MEM_TYPE_DOUBLE) != 0) {
20152015
double a;
@@ -2051,7 +2051,7 @@ mem_sub(const struct Mem *left, const struct Mem *right, struct Mem *result)
20512051
mem_set_null(result);
20522052
return 0;
20532053
}
2054-
if (check_types_numeric_arithmetic(right, left) != 0)
2054+
if (check_types_numeric_arithmetic(left, right) != 0)
20552055
return -1;
20562056
if (((left->type | right->type) & MEM_TYPE_DOUBLE) != 0) {
20572057
double a;
@@ -2093,7 +2093,7 @@ mem_mul(const struct Mem *left, const struct Mem *right, struct Mem *result)
20932093
mem_set_null(result);
20942094
return 0;
20952095
}
2096-
if (check_types_numeric_arithmetic(right, left) != 0)
2096+
if (check_types_numeric_arithmetic(left, right) != 0)
20972097
return -1;
20982098
if (((left->type | right->type) & MEM_TYPE_DOUBLE) != 0) {
20992099
double a;
@@ -2135,7 +2135,7 @@ mem_div(const struct Mem *left, const struct Mem *right, struct Mem *result)
21352135
mem_set_null(result);
21362136
return 0;
21372137
}
2138-
if (check_types_numeric_arithmetic(right, left) != 0)
2138+
if (check_types_numeric_arithmetic(left, right) != 0)
21392139
return -1;
21402140
if (((left->type | right->type) & MEM_TYPE_DOUBLE) != 0) {
21412141
double a;
@@ -2193,13 +2193,13 @@ mem_rem(const struct Mem *left, const struct Mem *right, struct Mem *result)
21932193
mem_set_null(result);
21942194
return 0;
21952195
}
2196-
if (!mem_is_int(right) || mem_is_metatype(right)) {
2197-
diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(right),
2196+
if (!mem_is_int(left) || mem_is_metatype(left)) {
2197+
diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(left),
21982198
"integer");
21992199
return -1;
22002200
}
2201-
if (!mem_is_int(left) || mem_is_metatype(left)) {
2202-
diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(left),
2201+
if (!mem_is_int(right) || mem_is_metatype(right)) {
2202+
diag_set(ClientError, ER_SQL_TYPE_MISMATCH, mem_str(right),
22032203
"integer");
22042204
return -1;
22052205
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
local server = require('test.luatest_helpers.server')
2+
local t = require('luatest')
3+
local g = t.group()
4+
5+
g.before_all(function()
6+
g.server = server:new({alias = 'arithmetic_operands'})
7+
g.server:start()
8+
end)
9+
10+
g.after_all(function()
11+
g.server:stop()
12+
end)
13+
14+
g.test_add = function()
15+
g.server:exec(function()
16+
local t = require('luatest')
17+
local res = [[Type mismatch: can not convert string('1') to ]]..
18+
[[integer, decimal or double]]
19+
local _, err = box.execute([[SELECT '1' + '2';]])
20+
t.assert_equals(err.message, res)
21+
_, err = box.execute([[SELECT 1 + '2';]])
22+
res = [[Type mismatch: can not convert string('2') to integer, ]]..
23+
[[decimal or double]]
24+
t.assert_equals(err.message, res)
25+
end)
26+
end
27+
28+
g.test_sub = function()
29+
g.server:exec(function()
30+
local t = require('luatest')
31+
local res = [[Type mismatch: can not convert string('1') to ]]..
32+
[[integer, decimal or double]]
33+
local _, err = box.execute([[SELECT '1' - '2';]])
34+
t.assert_equals(err.message, res)
35+
_, err = box.execute([[SELECT 1 - '2';]])
36+
res = [[Type mismatch: can not convert string('2') to integer, ]]..
37+
[[decimal or double]]
38+
t.assert_equals(err.message, res)
39+
end)
40+
end
41+
42+
g.test_mul = function()
43+
g.server:exec(function()
44+
local t = require('luatest')
45+
local res = [[Type mismatch: can not convert string('1') to ]]..
46+
[[integer, decimal or double]]
47+
local _, err = box.execute([[SELECT '1' * '2';]])
48+
t.assert_equals(err.message, res)
49+
_, err = box.execute([[SELECT 1 * '2';]])
50+
res = [[Type mismatch: can not convert string('2') to integer, ]]..
51+
[[decimal or double]]
52+
t.assert_equals(err.message, res)
53+
end)
54+
end
55+
56+
g.test_div = function()
57+
g.server:exec(function()
58+
local t = require('luatest')
59+
local res = [[Type mismatch: can not convert string('1') to ]]..
60+
[[integer, decimal or double]]
61+
local _, err = box.execute([[SELECT '1' / '2';]])
62+
t.assert_equals(err.message, res)
63+
_, err = box.execute([[SELECT 1 / '2';]])
64+
res = [[Type mismatch: can not convert string('2') to integer, ]]..
65+
[[decimal or double]]
66+
t.assert_equals(err.message, res)
67+
end)
68+
end
69+
70+
g.test_rem = function()
71+
g.server:exec(function()
72+
local t = require('luatest')
73+
local res = [[Type mismatch: can not convert string('1') to integer]]
74+
local _, err = box.execute([[SELECT '1' % '2';]])
75+
t.assert_equals(err.message, res)
76+
_, err = box.execute([[SELECT 1 % '2';]])
77+
res = [[Type mismatch: can not convert string('2') to integer]]
78+
t.assert_equals(err.message, res)
79+
end)
80+
end

test/sql-tap/tkt-a8a0d2996a.test.lua

+2-1
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,8 @@ test:do_catchsql_test(
138138
SELECT '1.23e64'/'1.0000e+62';
139139
]], {
140140
-- <4.1>
141-
1, "Type mismatch: can not convert string('1.0000e+62') to integer, decimal or double"
141+
1, "Type mismatch: can not convert string('1.23e64') to integer, "..
142+
"decimal or double"
142143
-- </4.1>
143144
})
144145

0 commit comments

Comments
 (0)