Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IGNITE-23192 Sql. Arithmetic operations failed with "out of range" exception #4422

Open
wants to merge 27 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ public async Task TestCustomDecimalScale()
await using var resultSet = await Client.Sql.ExecuteAsync(null, "select cast((10 / ?) as decimal(20, 5))", 3m);
IIgniteTuple res = await resultSet.SingleAsync();

Assert.AreEqual(3.33333m, res[0]);
Assert.AreEqual(3.3m, res[0]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's should be either 3.00000 or 3.33333, but not 3.3

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will be fixed soon

}

[Test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ void testExecuteAsyncDdlDml() {
assertEquals(10, rows.size());
assertEquals("hello 1", rows.get(1).stringValue(0));
assertEquals(1, rows.get(1).intValue(1));
assertEquals(2, rows.get(1).intValue(2));
assertEquals(2, rows.get(1).longValue(2));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
assertEquals(2, rows.get(1).longValue(2));
assertEquals(2L, rows.get(1).longValue(2));

?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


// Update data.
AsyncResultSet updateRes = sql
Expand Down Expand Up @@ -300,7 +300,7 @@ void testExecuteDdlDml() {
assertEquals(10, rows.size());
assertEquals("hello 1", rows.get(1).stringValue(0));
assertEquals(1, rows.get(1).intValue(1));
assertEquals(2, rows.get(1).intValue(2));
assertEquals(2L, rows.get(1).longValue(2));

// Update data.
ResultSet updateRes = sql.execute(null, "UPDATE testExecuteDdlDml SET VAL='upd' WHERE ID < 5");
Expand Down Expand Up @@ -398,18 +398,18 @@ void testResultSetMapping(boolean useStatement) {
@ValueSource(booleans = {true, false})
void testResultSetMappingAsync(boolean useStatement) {
IgniteSql sql = client().sql();
String query = "select 1 as num, concat('hello ', ?) as str";
String query = "select 1 + ? as num, concat('hello ', ?) as str";
korlov42 marked this conversation as resolved.
Show resolved Hide resolved

AsyncResultSet<Pojo> resultSet = useStatement
? sql.executeAsync(null, Mapper.of(Pojo.class), client().sql().statementBuilder().query(query).build(), "world").join()
: sql.executeAsync(null, Mapper.of(Pojo.class), query, "world").join();
? sql.executeAsync(null, Mapper.of(Pojo.class), client().sql().statementBuilder().query(query).build(), 10, "world").join()
: sql.executeAsync(null, Mapper.of(Pojo.class), query, 10, "world").join();

assertTrue(resultSet.hasRowSet());
assertEquals(1, resultSet.currentPageSize());

Pojo row = resultSet.currentPage().iterator().next();

assertEquals(1, row.num);
assertEquals(11L, row.num);
assertEquals("hello world", row.str);
}

Expand Down Expand Up @@ -522,7 +522,7 @@ public void testExecuteScriptFail() {
}

private static class Pojo {
public int num;
public long num;

public String str;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public void testCorrelatesAssignedBeforeAccess() {

assertQuery("SELECT " + DISABLED_JOIN_RULES + " t0.v, (SELECT t0.v + t1.v FROM test_tbl t1) AS j FROM test_tbl t0")
.matches(containsSubPlan("CorrelatedNestedLoopJoin"))
.returns(1, 2)
.returns(1, 2L)
.check();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ public class ItDataTypesTest extends BaseSqlIntegrationTest {

private static final String NUMERIC_FORMAT_ERROR = "neither a decimal digit number";

private static final Object EMPTY_PARAM = new Object();

/**
* Drops all created tables.
*/
Expand Down Expand Up @@ -606,64 +604,51 @@ public void testDecimalCastsFromNumeric(RelDataType inputType, Object input,
@ParameterizedTest(name = "{1} {2}")
@MethodSource("decimalOverflows")
public void testCalcOpOverflow(SqlTypeName type, String expr, Object param) {
if (param == EMPTY_PARAM) {
assertThrowsSqlException(RUNTIME_ERR, type.getName() + " out of range", () -> sql(expr));
} else {
assertThrowsSqlException(RUNTIME_ERR, type.getName() + " out of range", () -> sql(expr, param));
}
assertThrowsSqlException(RUNTIME_ERR, type.getName() + " out of range", () -> sql(expr, param));
}

private static Stream<Arguments> decimalOverflows() {
return Stream.of(
// BIGINT
arguments(SqlTypeName.BIGINT, "SELECT 9223372036854775807 + 1", EMPTY_PARAM),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you decide to remove such cases? It looks as valid testcases

arguments(SqlTypeName.BIGINT, "SELECT 9223372036854775807 * 2", EMPTY_PARAM),
arguments(SqlTypeName.BIGINT, "SELECT -9223372036854775808 - 1", EMPTY_PARAM),
arguments(SqlTypeName.BIGINT, "SELECT -(-9223372036854775807 - 1)", EMPTY_PARAM),
arguments(SqlTypeName.BIGINT, "SELECT -CAST(-9223372036854775808 AS BIGINT)", EMPTY_PARAM),
arguments(SqlTypeName.BIGINT, "SELECT -(?)", -9223372036854775808L),
arguments(SqlTypeName.BIGINT, "SELECT -9223372036854775808/-1", EMPTY_PARAM),
arguments(SqlTypeName.BIGINT, "SELECT -CAST(? AS BIGINT)", -9223372036854775808L),

// INTEGER
arguments(SqlTypeName.INTEGER, "SELECT 2147483647 + 1", EMPTY_PARAM),
arguments(SqlTypeName.INTEGER, "SELECT CAST(CAST(2147483648 AS BIGINT) AS INTEGER)", EMPTY_PARAM),
arguments(SqlTypeName.INTEGER, "SELECT 2147483647 * 2", EMPTY_PARAM),
arguments(SqlTypeName.INTEGER, "SELECT -2147483648 - 1", EMPTY_PARAM),
arguments(SqlTypeName.INTEGER, "SELECT -(-2147483647 - 1)", EMPTY_PARAM),
arguments(SqlTypeName.INTEGER, "SELECT -CAST(-2147483648 AS INTEGER)", EMPTY_PARAM),
arguments(SqlTypeName.INTEGER, "SELECT -(?)", -2147483648),
arguments(SqlTypeName.INTEGER, "SELECT -2147483648/-1", EMPTY_PARAM),
arguments(SqlTypeName.INTEGER, "select CAST(9223372036854775807.5 + 9223372036854775807.5 AS INTEGER)",
EMPTY_PARAM),
arguments(SqlTypeName.INTEGER, "SELECT -CAST(? AS INTEGER)", -2147483648),

// SMALLINT
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does it make sense to have similar test cases for all 4 types ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

derived type for SMALLINT and TINYINT tests without explicit casting is INTEGER so - no overflow will raised here

arguments(SqlTypeName.SMALLINT, "SELECT 32000::SMALLINT + 1000::SMALLINT", EMPTY_PARAM),
arguments(SqlTypeName.SMALLINT, "select CAST(9223372036854775807.5 + 9223372036854775807.5 AS SMALLINT)",
EMPTY_PARAM),
arguments(SqlTypeName.SMALLINT, "SELECT CAST(CAST(33000 AS BIGINT) AS SMALLINT)", EMPTY_PARAM),
arguments(SqlTypeName.SMALLINT, "SELECT CAST(CAST(33000 AS FLOAT) AS SMALLINT)", EMPTY_PARAM),
arguments(SqlTypeName.SMALLINT, "SELECT CAST(CAST(33000 + 1 AS FLOAT) AS SMALLINT)", EMPTY_PARAM),
arguments(SqlTypeName.SMALLINT, "SELECT 17000::SMALLINT * 2::SMALLINT", EMPTY_PARAM),
arguments(SqlTypeName.SMALLINT, "SELECT -32000::SMALLINT - 1000::SMALLINT", EMPTY_PARAM),
arguments(SqlTypeName.SMALLINT, "SELECT -(-32767::SMALLINT - 1::SMALLINT)", EMPTY_PARAM),
arguments(SqlTypeName.SMALLINT, "SELECT -CAST(-32768 AS SMALLINT)", EMPTY_PARAM),
arguments(SqlTypeName.SMALLINT, "SELECT -CAST(? AS SMALLINT)", -32768),
arguments(SqlTypeName.SMALLINT, "SELECT CAST (-32768 AS SMALLINT)/-1::SMALLINT", EMPTY_PARAM),

// TINYINT
arguments(SqlTypeName.TINYINT, "SELECT 2::TINYINT + 127::TINYINT", EMPTY_PARAM),
arguments(SqlTypeName.TINYINT, "select CAST(9223372036854775807.5 + 9223372036854775807.5 AS TINYINT)",
EMPTY_PARAM),
arguments(SqlTypeName.TINYINT, "SELECT CAST(CAST(200 AS BIGINT) AS TINYINT)", EMPTY_PARAM),
arguments(SqlTypeName.TINYINT, "SELECT CAST(CAST(200 AS FLOAT) AS TINYINT)", EMPTY_PARAM),
arguments(SqlTypeName.TINYINT, "SELECT CAST(CAST(200 + 1 AS FLOAT) AS TINYINT)", EMPTY_PARAM),
arguments(SqlTypeName.TINYINT, "SELECT 2::TINYINT * 127::TINYINT", EMPTY_PARAM),
arguments(SqlTypeName.TINYINT, "SELECT -2::TINYINT - 127::TINYINT", EMPTY_PARAM),
arguments(SqlTypeName.TINYINT, "SELECT -(-127::TINYINT - 1::TINYINT)", EMPTY_PARAM),
arguments(SqlTypeName.TINYINT, "SELECT -CAST(-128 AS TINYINT)", EMPTY_PARAM),
arguments(SqlTypeName.TINYINT, "SELECT -CAST(? AS TINYINT)", -128),
arguments(SqlTypeName.TINYINT, "SELECT CAST(-128 AS TINYINT)/-1::TINYINT", EMPTY_PARAM),
arguments(SqlTypeName.TINYINT, "SELECT CAST(CAST(200 + 1 AS FLOAT) AS TINYINT)", EMPTY_PARAM)
arguments(SqlTypeName.TINYINT, "SELECT -CAST(? AS TINYINT)", -128)
);
}

@ParameterizedTest
@MethodSource("decimalOpTypeExtension")
public void testCalcOpDynParamOverflow(String expr, String expect, Object param) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why did you name this test 'overflow' when no overflow is expected?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

assertEquals(sql(expr, param).get(0).get(0).toString(), expect);
}

private static Stream<Arguments> decimalOpTypeExtension() {
return Stream.of(
// TODO: https://issues.apache.org/jira/browse/IGNITE-23232
// arguments("SELECT -9223372036854775808::BIGINT/-1::BIGINT", "9223372036854775808"),
// arguments("SELECT -?::BIGINT/-1::BIGINT", "9223372036854775808", "9223372036854775808"),
// arguments("SELECT -2147483648::INTEGER/-1::INTEGER", "2147483648")/*,
// arguments("SELECT -32768::SMALLINT/-1::SMALLINT", "32768"),
// arguments("SELECT -128::TINYINT/-1::TINYINT", "128")

arguments("SELECT CAST(-? AS BIGINT)/-1", "9223372036854775808", "9223372036854775808"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the test doesn't fail with overflow?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i not understand why it need to fail ? Overflow need to operate with type, i didn`t see ant type here, did i miss smth ?

arguments("SELECT CAST(-? AS INTEGER)/-1", "2147483648", "2147483648"),
arguments("SELECT CAST(-? AS SMALLINT)/-1", "32768", "32768"),
arguments("SELECT CAST(-? AS TINYINT)/-1", "128", "128"),

arguments("SELECT CAST(-? AS BIGINT) * -1", "9223372036854775808", "9223372036854775808"),
arguments("SELECT CAST(-? AS INTEGER) * -1", "2147483648", "2147483648"),
arguments("SELECT CAST(-? AS SMALLINT) * -1", "32768", "32768"),
arguments("SELECT CAST(-? AS TINYINT) * -1", "128", "128")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does it make sense to add test cases not only with cast from string?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

other tests are moved into "cast_to_integer.test"

);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ public void testDynamicParameters() {
assertQuery("SELECT SQRT(?)").withParams(4d).returns(2d).check();
assertQuery("SELECT ?").withParams("asd").returns("asd").check();
assertQuery("SELECT ? % ?").withParams(11, 10).returns(1).check();
assertQuery("SELECT ? + ?, LOWER(?) ").withParams(2, 2, "TeSt").returns(4, "test").check();
assertQuery("SELECT LOWER(?), ? + ? ").withParams("TeSt", 2, 2).returns("test", 4).check();
assertQuery("SELECT ? + ?, LOWER(?) ").withParams(2, 2, "TeSt").returns(4L, "test").check();
assertQuery("SELECT LOWER(?), ? + ? ").withParams("TeSt", 2, 2).returns("test", 4L).check();
assertQuery("SELECT (? + 1)::INTEGER").withParams(1).returns(2).check();

createAndPopulateTable();
Expand Down Expand Up @@ -160,7 +160,7 @@ public void testNestedCase() {
/** Need to test the same query with different type of parameters to cover case with check right plans cache work. **/
@Test
public void testWithDifferentParametersTypes() {
assertQuery("SELECT ? + ?, LOWER(?) ").withParams(2, 2, "TeSt").returns(4, "test").check();
assertQuery("SELECT ? + ?, LOWER(?) ").withParams(2, 2, "TeSt").returns(4L, "test").check();
assertQuery("SELECT ? + ?, LOWER(?) ").withParams(2.2, 2.2, "TeSt").returns(4.4, "test").check();

assertQuery("SELECT COALESCE(?, ?)").withParams(null, null).returns(null).check();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ public void testIntervalResult() {

// Interval range overflow
assertThrowsSqlException(Sql.RUNTIME_ERR, "INTEGER out of range", () -> sql("SELECT INTERVAL 5000000 MONTHS * 1000"));
assertThrowsSqlException(Sql.RUNTIME_ERR, "BIGINT out of range", () -> sql("SELECT DATE '2021-01-01' + INTERVAL 999999999999 DAY"));
assertThrowsSqlException(Sql.RUNTIME_ERR, "INTEGER out of range", () -> sql("SELECT DATE '2021-01-01' + INTERVAL -999999999 YEAR"));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,10 @@ public void testComparison() {

@Test
public void testArithmetic() {
assertExpression("1 + 2").returns(3).check();
assertExpression("2 - 1").returns(1).check();
assertExpression("2 * 3").returns(6).check();
assertExpression("3 / 2 ").returns(1).check();
assertExpression("1 + 2").returns(3L).check();
assertExpression("2 - 1").returns(1L).check();
assertExpression("2 * 3").returns(6L).check();
assertExpression("3 / 2 ").returns(1L).check();
assertExpression("-(1)").returns(-1).check();
assertExpression("+(1)").returns(1).check();
assertExpression("3 % 2").returns(1).check();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ void lookupBySimpleKeyWithProjection() {
assertQuery("SELECT id, val * 10 FROM simple_key WHERE id = ?")
.matches(containsSubPlan("KeyValueGet"))
.withParams(key)
.returns(key, key * 10)
.returns(key, key * 10L)
.check();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,13 @@ SELECT a, val FROM test
11 A
2 B

skipif ignite3
# https://issues.apache.org/jira/browse/IGNITE-23183
statement ok
UPDATE test SET a = (SELECT a + 1 FROM test WHERE val = 'A')

skipif ignite3
# https://issues.apache.org/jira/browse/IGNITE-23183
query IT rowsort
SELECT a, val FROM test
----
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,140 @@ SELECT * FROM strings ORDER BY cast(a AS INTEGER)
4
13
NULL

statement ok
CREATE TABLE t8(id int, i TINYINT);

statement ok
CREATE TABLE t16(id int, i SMALLINT);

statement ok
CREATE TABLE t32(id int, i INTEGER);

statement ok
CREATE TABLE t64(id int, i BIGINT);

statement ok
INSERT INTO t8 VALUES(1, -128);

statement ok
INSERT INTO t16 VALUES(1, -32768);

statement ok
INSERT INTO t32 VALUES(1, -2147483648);

statement ok
INSERT INTO t64 VALUES(1, -9223372036854775808);

#Multiply

statement ok
INSERT INTO t16 VALUES(2, (SELECT i*i FROM t8 WHERE id=1));

query T
SELECT i FROM t16 WHERE id=2;
----
16384

statement ok
INSERT INTO t16 VALUES(21, (SELECT i*i*id::BIGINT FROM t8 WHERE id=1));

query T
SELECT i FROM t16 WHERE id=21;
----
16384

statement ok
INSERT INTO t32 VALUES(2, (SELECT i*i FROM t16 WHERE id=1));

query T
SELECT i FROM t32 WHERE id=2;
----
1073741824

statement ok
INSERT INTO t64 VALUES(2, (SELECT i*i FROM t32 WHERE id=1));

query T
SELECT i FROM t64 WHERE id=2;
----
4611686018427387904

#Divide

statement ok
INSERT INTO t16 VALUES(3, (SELECT i/-1 FROM t8 WHERE id=1));

query T
SELECT i FROM t16 WHERE id=3;
----
128

statement ok
INSERT INTO t32 VALUES(3, (SELECT i/-1 FROM t16 WHERE id=1));

query T
SELECT i FROM t32 WHERE id=3;
----
32768

statement ok
INSERT INTO t64 VALUES(3, (SELECT i/-1 FROM t32 WHERE id=1));

query T
SELECT i FROM t64 WHERE id=3;
----
2147483648

#Add

statement ok
INSERT INTO t16 VALUES(4, (SELECT i+i FROM t8 WHERE id=1));

query T
SELECT i FROM t16 WHERE id=4;
----
-256

statement ok
INSERT INTO t32 VALUES(4, (SELECT i+i FROM t16 WHERE id=1));

query T
SELECT i FROM t32 WHERE id=4;
----
-65536

statement ok
INSERT INTO t64 VALUES(4, (SELECT i+i FROM t32 WHERE id=1));

query T
SELECT i FROM t64 WHERE id=4;
----
-4294967296

#Subtract

statement ok
INSERT INTO t16 VALUES(5, (SELECT i-1 FROM t8 WHERE id=1));

query T
SELECT i FROM t16 WHERE id=5;
----
-129

statement ok
INSERT INTO t32 VALUES(5, (SELECT i-1 FROM t16 WHERE id=1));

query T
SELECT i FROM t32 WHERE id=5;
----
-32769

statement ok
INSERT INTO t64 VALUES(5, (SELECT i-1 FROM t32 WHERE id=1));

query T
SELECT i FROM t64 WHERE id=5;
----
-2147483649

Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ statement error
SELECT a-10 AS k FROM test UNION SELECT a-10 AS l FROM test ORDER BY l

# ORDER BY on alias in right-most query but related just to the subquery.
query I
query I rowsort
SELECT a-10 AS k FROM test UNION (SELECT a-10 AS l FROM test ORDER BY l)
----
1
Expand Down
Loading