alex-plekhanov commented on code in PR #11655: URL: https://github.com/apache/ignite/pull/11655#discussion_r1848472744
########## modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/FunctionsTest.java: ########## @@ -58,6 +60,165 @@ public void testQueryEngine() { assertQuery("SELECT QUERY_ENGINE()").returns(CalciteQueryEngineConfiguration.ENGINE_NAME).check(); } + /** */ + @Test + public void testBitwiseOperationsWithTable() { + try { + sql("CREATE TABLE TBL(i INT PRIMARY KEY, s SMALLINT, l BIGINT)"); + + for (int i = 0; i < 100; ++i) + sql("INSERT INTO TBL values (?, ?, ?)", i, i, i); + + sql("INSERT INTO TBL values (?, ?, ?)", Short.MAX_VALUE + 1, Short.MAX_VALUE, Short.MAX_VALUE); + + assertQuery("SELECT BITAND(i + 1, i + 1) FROM TBL WHERE i=0").returns(1).check(); + assertQuery("SELECT BITAND(s, s) FROM TBL WHERE i=1").returns((short)1).check(); + assertQuery("SELECT BITAND((SELECT l FROM TBL WHERE i=3), (SELECT l FROM TBL WHERE i=1))").returns(1L).check(); + assertQuery("SELECT BITOR((SELECT s FROM TBL WHERE i=?), (SELECT i FROM TBL WHERE i=?))").withParams(14, 1) + .returns(15).check(); + + assertQuery("SELECT BITAND((SELECT s FROM TBL WHERE s=3), (SELECT l FROM TBL WHERE i=1))").returns(1L).check(); + + assertQuery("SELECT BITXOR(1000::BIGINT, i) FROM TBL WHERE i=93").returns(949L).check(); + assertQuery("SELECT BITAND(?, i) FROM TBL WHERE i=73").withParams(new Object[]{null}).returns(73L).check(); + assertQuery("SELECT BITAND(l, ?) FROM TBL WHERE l=45").withParams(new Object[]{null}).returns(45L).check(); + assertQuery("SELECT BITAND(?, s) FROM TBL WHERE s=40").withParams(new Object[]{null}).returns(40L).check(); + + assertThrows("SELECT BITXOR(40000::SMALLINT, s) FROM TBL WHERE s=55", ArithmeticException.class, "overflow"); + + assertQuery("SELECT BITOR(i, s) FROM TBL WHERE l=?").withParams(Short.MAX_VALUE).returns(65535).check(); + assertQuery("SELECT BITOR(i, s) FROM TBL WHERE l=?").withParams(Short.MAX_VALUE).returns(65535).check(); Review Comment: The same check twice ########## modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/RexImpTable.java: ########## @@ -564,6 +568,10 @@ public class RexImpTable { // Operator IS_NOT_DISTINCT_FROM is removed by RexSimplify, but still possible in join conditions, so // implementation required. defineMethod(IS_NOT_DISTINCT_FROM, IgniteMethod.IS_NOT_DISTINCT_FROM.method(), NullPolicy.NONE); + + map.put(BITAND, new BitwiseImplementor(SqlKind.BIT_AND)); + map.put(BITOR, new BitwiseImplementor(SqlKind.BIT_OR)); + map.put(BITXOR, new BitwiseImplementor(SqlKind.BIT_XOR)); Review Comment: ``` defineMethod(BITAND, BuiltInMethod.BIT_AND.method, NullPolicy.ANY); defineMethod(BITOR, BuiltInMethod.BIT_OR.method, NullPolicy.ANY); defineMethod(BITXOR, BuiltInMethod.BIT_XOR.method, NullPolicy.ANY); ``` ########## modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/FunctionsTest.java: ########## @@ -58,6 +60,165 @@ public void testQueryEngine() { assertQuery("SELECT QUERY_ENGINE()").returns(CalciteQueryEngineConfiguration.ENGINE_NAME).check(); } + /** */ + @Test + public void testBitwiseOperationsWithTable() { + try { + sql("CREATE TABLE TBL(i INT PRIMARY KEY, s SMALLINT, l BIGINT)"); + + for (int i = 0; i < 100; ++i) + sql("INSERT INTO TBL values (?, ?, ?)", i, i, i); + + sql("INSERT INTO TBL values (?, ?, ?)", Short.MAX_VALUE + 1, Short.MAX_VALUE, Short.MAX_VALUE); + + assertQuery("SELECT BITAND(i + 1, i + 1) FROM TBL WHERE i=0").returns(1).check(); + assertQuery("SELECT BITAND(s, s) FROM TBL WHERE i=1").returns((short)1).check(); + assertQuery("SELECT BITAND((SELECT l FROM TBL WHERE i=3), (SELECT l FROM TBL WHERE i=1))").returns(1L).check(); + assertQuery("SELECT BITOR((SELECT s FROM TBL WHERE i=?), (SELECT i FROM TBL WHERE i=?))").withParams(14, 1) + .returns(15).check(); + + assertQuery("SELECT BITAND((SELECT s FROM TBL WHERE s=3), (SELECT l FROM TBL WHERE i=1))").returns(1L).check(); + + assertQuery("SELECT BITXOR(1000::BIGINT, i) FROM TBL WHERE i=93").returns(949L).check(); + assertQuery("SELECT BITAND(?, i) FROM TBL WHERE i=73").withParams(new Object[]{null}).returns(73L).check(); + assertQuery("SELECT BITAND(l, ?) FROM TBL WHERE l=45").withParams(new Object[]{null}).returns(45L).check(); + assertQuery("SELECT BITAND(?, s) FROM TBL WHERE s=40").withParams(new Object[]{null}).returns(40L).check(); Review Comment: `new Object[]{null}` -> `NULL_RESULT` ########## modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/FunctionsTest.java: ########## @@ -58,6 +60,165 @@ public void testQueryEngine() { assertQuery("SELECT QUERY_ENGINE()").returns(CalciteQueryEngineConfiguration.ENGINE_NAME).check(); } + /** */ + @Test + public void testBitwiseOperationsWithTable() { + try { + sql("CREATE TABLE TBL(i INT PRIMARY KEY, s SMALLINT, l BIGINT)"); + + for (int i = 0; i < 100; ++i) + sql("INSERT INTO TBL values (?, ?, ?)", i, i, i); + + sql("INSERT INTO TBL values (?, ?, ?)", Short.MAX_VALUE + 1, Short.MAX_VALUE, Short.MAX_VALUE); + + assertQuery("SELECT BITAND(i + 1, i + 1) FROM TBL WHERE i=0").returns(1).check(); + assertQuery("SELECT BITAND(s, s) FROM TBL WHERE i=1").returns((short)1).check(); + assertQuery("SELECT BITAND((SELECT l FROM TBL WHERE i=3), (SELECT l FROM TBL WHERE i=1))").returns(1L).check(); + assertQuery("SELECT BITOR((SELECT s FROM TBL WHERE i=?), (SELECT i FROM TBL WHERE i=?))").withParams(14, 1) + .returns(15).check(); + + assertQuery("SELECT BITAND((SELECT s FROM TBL WHERE s=3), (SELECT l FROM TBL WHERE i=1))").returns(1L).check(); + + assertQuery("SELECT BITXOR(1000::BIGINT, i) FROM TBL WHERE i=93").returns(949L).check(); + assertQuery("SELECT BITAND(?, i) FROM TBL WHERE i=73").withParams(new Object[]{null}).returns(73L).check(); + assertQuery("SELECT BITAND(l, ?) FROM TBL WHERE l=45").withParams(new Object[]{null}).returns(45L).check(); + assertQuery("SELECT BITAND(?, s) FROM TBL WHERE s=40").withParams(new Object[]{null}).returns(40L).check(); + + assertThrows("SELECT BITXOR(40000::SMALLINT, s) FROM TBL WHERE s=55", ArithmeticException.class, "overflow"); + + assertQuery("SELECT BITOR(i, s) FROM TBL WHERE l=?").withParams(Short.MAX_VALUE).returns(65535).check(); + assertQuery("SELECT BITOR(i, s) FROM TBL WHERE l=?").withParams(Short.MAX_VALUE).returns(65535).check(); + assertQuery("SELECT BITAND(i, s) FROM TBL WHERE l=?").withParams(Short.MAX_VALUE).returns(0).check(); + } + finally { + sql("DROP TABLE if EXISTS TBL"); + } + } + + /** */ + @Test + public void testBitwiseOperations() { + doTestBitwiseOperations(false); + + doTestBitwiseOperations(true); + } + + /** */ + private void doTestBitwiseOperations(boolean dynamic) { + for (List<Object> paramSet : bitwiseParams(dynamic)) { + assert paramSet.size() == 6; + + int idx = 0; + + String op = paramSet.get(idx++).toString(); + Object p1 = paramSet.get(idx++); + String cast1 = (String)paramSet.get(idx++); + Object p2 = paramSet.get(idx++); + String cast2 = (String)paramSet.get(idx++); + Object res = paramSet.get(idx); + + cast1 = cast1 == null ? "" : "::" + cast1; + cast2 = cast2 == null ? "" : "::" + cast2; + + log.info("Op: " + op + ", dynamic=" + dynamic + ", p1=" + p1 + ", p2=" + p2 + ", expected=" + res); + + if (dynamic) { + String sql = "SELECT BIT" + op + "(?" + cast1 + ", ?" + cast2 + ')'; + + if (res instanceof Exception) + assertThrows(sql, (Class<? extends Exception>)res.getClass(), ((Throwable)res).getMessage(), p1, p2); + else + assertQuery(sql).withParams(p1, p2).returns(res).check(); + } + else { + String sql = "SELECT BIT" + op + '(' + p1 + cast1 + ", " + p2 + cast2 + ')'; + + if (res instanceof Exception) + assertThrows(sql, (Class<? extends Exception>)res.getClass(), ((Throwable)res).getMessage()); + else + assertQuery(sql).returns(res).check(); + } + } + } + + /** Bitwise operation params: operation, param1, cast1, param2, cast2, result. */ + private Iterable<List<Object>> bitwiseParams(boolean dynamic) { + List<List<Object>> res = new ArrayList<>(100); + + // BITAND + res.add(F.asList("AND", 1, null, 1.0, null, new SqlValidatorException("Cannot apply 'BITAND' to arguments of type", null))); Review Comment: Line limit exceeded. Let's create an one instance of exception and use it for each case. ########## modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/IgniteMath.java: ########## @@ -418,4 +419,24 @@ private static double extendToRound(double x) { private static BigDecimal round(Number x) { return convertToBigDecimal(x).setScale(0, NUMERIC_ROUNDING_MODE); } + + /** */ + public static Number bitwise(SqlKind kind, Number v1, Number v2) { + if (v1 == null) + return v2; + + if (v2 == null) + return v1; Review Comment: bitand(null, 1) should be null (it's an usual rule for functions in sql) ########## modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/fun/IgniteOwnSqlOperatorTable.java: ########## @@ -123,6 +124,36 @@ public class IgniteOwnSqlOperatorTable extends ReflectiveSqlOperatorTable { OperandTypes.SAME_SAME, SqlFunctionCategory.SYSTEM); + /** Bitwise '&' of two values. */ + public static final SqlFunction BITAND = + new SqlFunction( + "BITAND", + SqlKind.OTHER_FUNCTION, + ReturnTypes.LEAST_RESTRICTIVE.andThen(SqlTypeTransforms.TO_NULLABLE), Review Comment: Why do we need TO_NULLABLE? LEAST_RESTRICTIVE of any nullable type will be nullable. And if both types is not nullable, than result is not nullable too. ########## modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/sql/fun/IgniteOwnSqlOperatorTable.java: ########## @@ -123,6 +124,36 @@ public class IgniteOwnSqlOperatorTable extends ReflectiveSqlOperatorTable { OperandTypes.SAME_SAME, SqlFunctionCategory.SYSTEM); + /** Bitwise '&' of two values. */ + public static final SqlFunction BITAND = + new SqlFunction( + "BITAND", + SqlKind.OTHER_FUNCTION, + ReturnTypes.LEAST_RESTRICTIVE.andThen(SqlTypeTransforms.TO_NULLABLE), + null, Review Comment: `InferTypes.RETURN_TYPE` - to convert nulls to integer ########## modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/FunctionsTest.java: ########## @@ -58,6 +60,165 @@ public void testQueryEngine() { assertQuery("SELECT QUERY_ENGINE()").returns(CalciteQueryEngineConfiguration.ENGINE_NAME).check(); } + /** */ + @Test + public void testBitwiseOperationsWithTable() { + try { + sql("CREATE TABLE TBL(i INT PRIMARY KEY, s SMALLINT, l BIGINT)"); + + for (int i = 0; i < 100; ++i) + sql("INSERT INTO TBL values (?, ?, ?)", i, i, i); + + sql("INSERT INTO TBL values (?, ?, ?)", Short.MAX_VALUE + 1, Short.MAX_VALUE, Short.MAX_VALUE); + + assertQuery("SELECT BITAND(i + 1, i + 1) FROM TBL WHERE i=0").returns(1).check(); + assertQuery("SELECT BITAND(s, s) FROM TBL WHERE i=1").returns((short)1).check(); + assertQuery("SELECT BITAND((SELECT l FROM TBL WHERE i=3), (SELECT l FROM TBL WHERE i=1))").returns(1L).check(); + assertQuery("SELECT BITOR((SELECT s FROM TBL WHERE i=?), (SELECT i FROM TBL WHERE i=?))").withParams(14, 1) + .returns(15).check(); + + assertQuery("SELECT BITAND((SELECT s FROM TBL WHERE s=3), (SELECT l FROM TBL WHERE i=1))").returns(1L).check(); + + assertQuery("SELECT BITXOR(1000::BIGINT, i) FROM TBL WHERE i=93").returns(949L).check(); + assertQuery("SELECT BITAND(?, i) FROM TBL WHERE i=73").withParams(new Object[]{null}).returns(73L).check(); + assertQuery("SELECT BITAND(l, ?) FROM TBL WHERE l=45").withParams(new Object[]{null}).returns(45L).check(); + assertQuery("SELECT BITAND(?, s) FROM TBL WHERE s=40").withParams(new Object[]{null}).returns(40L).check(); + + assertThrows("SELECT BITXOR(40000::SMALLINT, s) FROM TBL WHERE s=55", ArithmeticException.class, "overflow"); Review Comment: `40000::SMALLINT` gives ArithmeticException, so BITXOR check here is redundant -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: notifications-unsubscr...@ignite.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org