You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2018/02/16 21:51:15 UTC

[4/7] calcite git commit: [CALCITE-2180] Invalid code generated for negative of byte and short values

[CALCITE-2180] Invalid code generated for negative of byte and short values


Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/3c67a605
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/3c67a605
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/3c67a605

Branch: refs/heads/master
Commit: 3c67a605cb6d6613ea1696288254a90f621a2834
Parents: becb6df
Author: Julian Hyde <jh...@apache.org>
Authored: Thu Feb 15 12:25:14 2018 -0800
Committer: Julian Hyde <jh...@apache.org>
Committed: Fri Feb 16 10:18:02 2018 -0800

----------------------------------------------------------------------
 .../calcite/adapter/enumerable/RexImpTable.java | 12 +++++--
 core/src/test/resources/sql/misc.iq             | 36 ++++++++++++++++++++
 .../apache/calcite/linq4j/tree/Expressions.java | 10 ++++--
 .../calcite/linq4j/test/ExpressionTest.java     | 14 ++++++++
 4 files changed, 67 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/3c67a605/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
index 20d340e..a1a88ad 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
@@ -31,6 +31,7 @@ import org.apache.calcite.linq4j.tree.OptimizeShuttle;
 import org.apache.calcite.linq4j.tree.ParameterExpression;
 import org.apache.calcite.linq4j.tree.Primitive;
 import org.apache.calcite.linq4j.tree.Types;
+import org.apache.calcite.linq4j.tree.UnaryExpression;
 import org.apache.calcite.plan.RelOptTable;
 import org.apache.calcite.prepare.Prepare;
 import org.apache.calcite.rel.type.RelDataType;
@@ -1901,9 +1902,14 @@ public class RexImpTable {
         RexToLixTranslator translator,
         RexCall call,
         List<Expression> translatedOperands) {
-      return Expressions.makeUnary(
-          expressionType,
-          translatedOperands.get(0));
+      final Expression operand = translatedOperands.get(0);
+      final UnaryExpression e = Expressions.makeUnary(expressionType, operand);
+      if (e.type.equals(operand.type)) {
+        return e;
+      }
+      // Certain unary operators do not preserve type. For example, the "-"
+      // operator applied to a "byte" expression returns an "int".
+      return Expressions.convert_(e, operand.type);
     }
   }
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/3c67a605/core/src/test/resources/sql/misc.iq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/misc.iq b/core/src/test/resources/sql/misc.iq
index b9d64cd..ba2ebd6 100644
--- a/core/src/test/resources/sql/misc.iq
+++ b/core/src/test/resources/sql/misc.iq
@@ -1030,6 +1030,42 @@ Expression 'DEPTNO' is not being grouped
 
 !use scott
 
+# ORDER BY expression with SELECT DISTINCT
+select distinct deptno, job
+from "scott".emp
+order by substring(job from 2 for 1), -deptno;
++--------+-----------+
+| DEPTNO | JOB       |
++--------+-----------+
+|     30 | SALESMAN  |
+|     30 | MANAGER   |
+|     20 | MANAGER   |
+|     10 | MANAGER   |
+|     30 | CLERK     |
+|     20 | CLERK     |
+|     10 | CLERK     |
+|     20 | ANALYST   |
+|     10 | PRESIDENT |
++--------+-----------+
+(9 rows)
+
+!ok
+
+# [CALCITE-2180] Invalid code generated for negative of byte and short values
+select -deptno as d
+from "scott".dept;
++-----+
+| D   |
++-----+
+| -40 |
+| -30 |
+| -20 |
+| -10 |
++-----+
+(4 rows)
+
+!ok
+
 # [CALCITE-2099] Incorrect code generated for UNION
 select count(*) as c from "scott".emp group by deptno
 union

http://git-wip-us.apache.org/repos/asf/calcite/blob/3c67a605/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Expressions.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Expressions.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Expressions.java
index 6902cc4..5d7f83d 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Expressions.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Expressions.java
@@ -1605,8 +1605,14 @@ public abstract class Expressions {
    */
   public static UnaryExpression makeUnary(ExpressionType expressionType,
       Expression expression) {
-    return new UnaryExpression(expressionType, expression.getType(),
-        expression);
+    Type type = expression.getType();
+    switch (expressionType) {
+    case Negate:
+      if (type == byte.class || type == short.class) {
+        type = int.class;
+      }
+    }
+    return new UnaryExpression(expressionType, type, expression);
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/calcite/blob/3c67a605/linq4j/src/test/java/org/apache/calcite/linq4j/test/ExpressionTest.java
----------------------------------------------------------------------
diff --git a/linq4j/src/test/java/org/apache/calcite/linq4j/test/ExpressionTest.java b/linq4j/src/test/java/org/apache/calcite/linq4j/test/ExpressionTest.java
index 9d094b3..8f1756d 100644
--- a/linq4j/src/test/java/org/apache/calcite/linq4j/test/ExpressionTest.java
+++ b/linq4j/src/test/java/org/apache/calcite/linq4j/test/ExpressionTest.java
@@ -835,6 +835,20 @@ public class ExpressionTest {
             Expressions.constant(true),
             Expressions.constant(0),
             Expressions.constant(null)).getType());
+
+    // In Java, "-" applied to short and byte yield int.
+    assertEquals(double.class,
+        Expressions.negate(Expressions.constant((double) 1)).getType());
+    assertEquals(float.class,
+        Expressions.negate(Expressions.constant((float) 1)).getType());
+    assertEquals(long.class,
+        Expressions.negate(Expressions.constant((long) 1)).getType());
+    assertEquals(int.class,
+        Expressions.negate(Expressions.constant(1)).getType());
+    assertEquals(int.class,
+        Expressions.negate(Expressions.constant((short) 1)).getType());
+    assertEquals(int.class,
+        Expressions.negate(Expressions.constant((byte) 1)).getType());
   }
 
   @Test public void testCompile() throws NoSuchMethodException {