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 2017/07/06 23:00:38 UTC

[1/7] calcite git commit: [CALCITE-1873] In a "GROUP BY ordinal" query, validator gives invalid "Expression is not being grouped" error if column has alias

Repository: calcite
Updated Branches:
  refs/heads/master f47465236 -> 8cb189f72


[CALCITE-1873] In a "GROUP BY ordinal" query, validator gives invalid "Expression is not being grouped" error if column has alias

The solution is to ignore column aliases when validating a "GROUP BY
ordinal" query. Otherwise, you get an error like "Expression 'EMP.EMPNO'
is not being grouped" (see test case).

Close apache/calcite#490


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

Branch: refs/heads/master
Commit: d4ab1e508b47e4e168296ad701742e879f05c571
Parents: 47c8df9
Author: Gian Merlino <gi...@gmail.com>
Authored: Wed Jul 5 11:08:52 2017 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Thu Jul 6 11:24:37 2017 -0700

----------------------------------------------------------------------
 .../java/org/apache/calcite/sql/validate/SqlValidatorImpl.java | 2 +-
 .../test/java/org/apache/calcite/test/SqlValidatorTest.java    | 6 ++++++
 2 files changed, 7 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/d4ab1e50/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java
index 84a54cf..0c2f379 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java
@@ -5415,7 +5415,7 @@ public class SqlValidatorImpl implements SqlValidatorWithHints {
 
             // SQL ordinals are 1-based, but Sort's are 0-based
             int ordinal = intValue - 1;
-            return select.getSelectList().get(ordinal);
+            return SqlUtil.stripAs(select.getSelectList().get(ordinal));
           }
           break;
         }

http://git-wip-us.apache.org/repos/asf/calcite/blob/d4ab1e50/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
index 41acc82..ae1ee37 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
@@ -6304,6 +6304,12 @@ public class SqlValidatorTest extends SqlValidatorTestCase {
         + " group by 1,2")
         .tester(strict).fails("Expression 'DEPTNO' is not being grouped")
         .tester(lenient).sansCarets().ok();
+    sql("select ^empno^, count(*) from emp group by 1 order by 1")
+        .tester(strict).fails("Expression 'EMPNO' is not being grouped")
+        .tester(lenient).sansCarets().ok();
+    sql("select ^empno^ eno, count(*) from emp group by 1 order by 1")
+        .tester(strict).fails("Expression 'EMPNO' is not being grouped")
+        .tester(lenient).sansCarets().ok();
     sql("select count(*) from (select 1 from emp"
         + " group by substring(ename from 2 for 3))")
         .tester(strict).ok()


[2/7] calcite git commit: [CALCITE-1833] User-defined aggregate functions with more than one parameter (hzyuemeng1)

Posted by jh...@apache.org.
[CALCITE-1833] User-defined aggregate functions with more than one parameter (hzyuemeng1)

I don't like the fact that SqlUserDefinedAggregateFunction now has a
type factory field. I see why it is necessary - because the
SqlFunction.getParamTypes method does not take a type factory argument -
but we should consider changing it in future.

Close apache/calcite#481


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

Branch: refs/heads/master
Commit: 47c8df9ecad8aa0c8a65530dd89b94b3749f54a2
Parents: f474652
Author: hzyuemeng1 <hz...@corp.netease.com>
Authored: Tue Jun 20 09:51:57 2017 +0800
Committer: Julian Hyde <jh...@apache.org>
Committed: Thu Jul 6 11:24:37 2017 -0700

----------------------------------------------------------------------
 .../calcite/prepare/CalciteCatalogReader.java   |  2 +-
 .../sql/validate/SqlUserDefinedAggFunction.java | 36 ++++++++-
 .../java/org/apache/calcite/test/UdfTest.java   | 81 +++++++++++++++++--
 .../java/org/apache/calcite/util/Smalls.java    | 82 ++++++++++++++++++++
 4 files changed, 194 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/47c8df9e/core/src/main/java/org/apache/calcite/prepare/CalciteCatalogReader.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/prepare/CalciteCatalogReader.java b/core/src/main/java/org/apache/calcite/prepare/CalciteCatalogReader.java
index 9ec3df4..921191a 100644
--- a/core/src/main/java/org/apache/calcite/prepare/CalciteCatalogReader.java
+++ b/core/src/main/java/org/apache/calcite/prepare/CalciteCatalogReader.java
@@ -329,7 +329,7 @@ public class CalciteCatalogReader implements Prepare.CatalogReader {
     } else if (function instanceof AggregateFunction) {
       return new SqlUserDefinedAggFunction(name,
           infer((AggregateFunction) function), InferTypes.explicit(argTypes),
-          typeChecker, (AggregateFunction) function, false, false);
+          typeChecker, (AggregateFunction) function, false, false, typeFactory);
     } else if (function instanceof TableMacro) {
       return new SqlUserDefinedTableMacro(name, ReturnTypes.CURSOR,
           InferTypes.explicit(argTypes), typeChecker, paramTypes,

http://git-wip-us.apache.org/repos/asf/calcite/blob/47c8df9e/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedAggFunction.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedAggFunction.java b/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedAggFunction.java
index da1f833..a8be50b 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedAggFunction.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlUserDefinedAggFunction.java
@@ -16,8 +16,10 @@
  */
 package org.apache.calcite.sql.validate;
 
+import org.apache.calcite.jdbc.JavaTypeFactoryImpl;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeFactory;
+import org.apache.calcite.rel.type.RelDataTypeFactoryImpl;
 import org.apache.calcite.schema.AggregateFunction;
 import org.apache.calcite.schema.FunctionParameter;
 import org.apache.calcite.sql.SqlAggFunction;
@@ -27,11 +29,13 @@ import org.apache.calcite.sql.SqlKind;
 import org.apache.calcite.sql.type.SqlOperandTypeChecker;
 import org.apache.calcite.sql.type.SqlOperandTypeInference;
 import org.apache.calcite.sql.type.SqlReturnTypeInference;
+import org.apache.calcite.sql.type.SqlTypeName;
 import org.apache.calcite.util.Util;
 
 import com.google.common.base.Function;
 import com.google.common.collect.Lists;
 
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -42,17 +46,47 @@ import java.util.List;
  */
 public class SqlUserDefinedAggFunction extends SqlAggFunction {
   public final AggregateFunction function;
+  public final RelDataTypeFactory typeFactory;
 
   /** Creates a SqlUserDefinedAggFunction. */
   public SqlUserDefinedAggFunction(SqlIdentifier opName,
       SqlReturnTypeInference returnTypeInference,
       SqlOperandTypeInference operandTypeInference,
       SqlOperandTypeChecker operandTypeChecker, AggregateFunction function,
-      boolean requiresOrder, boolean requiresOver) {
+      boolean requiresOrder, boolean requiresOver, RelDataTypeFactory typeFactory) {
     super(Util.last(opName.names), opName, SqlKind.OTHER_FUNCTION,
         returnTypeInference, operandTypeInference, operandTypeChecker,
         SqlFunctionCategory.USER_DEFINED_FUNCTION, requiresOrder, requiresOver);
     this.function = function;
+    this.typeFactory = typeFactory;
+  }
+
+  @Override public List<RelDataType> getParamTypes() {
+    List<RelDataType> argTypes = new ArrayList<>();
+    for (FunctionParameter o : function.getParameters()) {
+      final RelDataType type = o.getType(typeFactory);
+      argTypes.add(type);
+    }
+    return toSql(argTypes);
+  }
+
+  private List<RelDataType> toSql(List<RelDataType> types) {
+    return Lists.transform(types,
+        new com.google.common.base.Function<RelDataType, RelDataType>() {
+          public RelDataType apply(RelDataType type) {
+            return toSql(type);
+          }
+        });
+  }
+
+  private RelDataType toSql(RelDataType type) {
+    if (type instanceof RelDataTypeFactoryImpl.JavaType
+        && ((RelDataTypeFactoryImpl.JavaType) type).getJavaClass()
+        == Object.class) {
+      return typeFactory.createTypeWithNullability(
+          typeFactory.createSqlType(SqlTypeName.ANY), true);
+    }
+    return JavaTypeFactoryImpl.toSql(typeFactory, type);
   }
 
   @SuppressWarnings("deprecation")

http://git-wip-us.apache.org/repos/asf/calcite/blob/47c8df9e/core/src/test/java/org/apache/calcite/test/UdfTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/UdfTest.java b/core/src/test/java/org/apache/calcite/test/UdfTest.java
index 3297c27..3d0879f 100644
--- a/core/src/test/java/org/apache/calcite/test/UdfTest.java
+++ b/core/src/test/java/org/apache/calcite/test/UdfTest.java
@@ -463,8 +463,7 @@ public class UdfTest {
     with.query("select my_sum(\"deptno\") as p from EMPLOYEES\n")
         .returns("P=50\n");
     with.query("select my_sum(\"name\") as p from EMPLOYEES\n")
-        .throws_(
-            "Cannot apply 'MY_SUM' to arguments of type 'MY_SUM(<JAVATYPE(CLASS JAVA.LANG.STRING)>)'. Supported form(s): 'MY_SUM(<NUMERIC>)");
+        .throws_("No match found for function signature MY_SUM(<CHARACTER>)");
     with.query("select my_sum(\"deptno\", 1) as p from EMPLOYEES\n")
         .throws_(
             "No match found for function signature MY_SUM(<NUMERIC>, <NUMERIC>)");
@@ -481,6 +480,80 @@ public class UdfTest {
         .returnsUnordered("deptno=20; P=20", "deptno=10; P=30");
   }
 
+  /** Tests user-defined aggregate function. */
+  @Test public void testUserDefinedAggregateFunctionWithMultipleParameters() throws Exception {
+    final String empDept = JdbcTest.EmpDeptTableFactory.class.getName();
+    final String sum21 = Smalls.MyTwoParamsSumFunctionFilter1.class.getName();
+    final String sum22 = Smalls.MyTwoParamsSumFunctionFilter2.class.getName();
+    final String sum31 = Smalls.MyThreeParamsSumFunctionWithFilter1.class.getName();
+    final String sum32 = Smalls.MyThreeParamsSumFunctionWithFilter2.class.getName();
+    final CalciteAssert.AssertThat with = CalciteAssert.model("{\n"
+        + "  version: '1.0',\n"
+        + "   schemas: [\n"
+        + "     {\n"
+        + "       name: 'adhoc',\n"
+        + "       tables: [\n"
+        + "         {\n"
+        + "           name: 'EMPLOYEES',\n"
+        + "           type: 'custom',\n"
+        + "           factory: '" + empDept + "',\n"
+        + "           operand: {'foo': true, 'bar': 345}\n"
+        + "         }\n"
+        + "       ],\n"
+        + "       functions: [\n"
+        + "         {\n"
+        + "           name: 'MY_SUM2',\n"
+        + "           className: '" + sum21 + "'\n"
+        + "         },\n"
+        + "         {\n"
+        + "           name: 'MY_SUM2',\n"
+        + "           className: '" + sum22 + "'\n"
+        + "         },\n"
+        + "         {\n"
+        + "           name: 'MY_SUM3',\n"
+        + "           className: '" + sum31 + "'\n"
+        + "         },\n"
+        + "         {\n"
+        + "           name: 'MY_SUM3',\n"
+        + "           className: '" + sum32 + "'\n"
+        + "         }\n"
+        + "       ]\n"
+        + "     }\n"
+        + "   ]\n"
+        + "}")
+        .withDefaultSchema("adhoc");
+    with.withDefaultSchema(null)
+        .query(
+            "select \"adhoc\".my_sum3(\"deptno\",\"name\",'Eric') as p from \"adhoc\".EMPLOYEES\n")
+        .returns("P=20\n");
+    with.query("select \"adhoc\".my_sum3(\"empid\",\"deptno\",\"commission\") as p "
+        + "from \"adhoc\".EMPLOYEES\n")
+        .returns("P=330\n");
+    with.query("select \"adhoc\".my_sum3(\"empid\",\"deptno\",\"commission\"),\"name\" as p "
+        + "from \"adhoc\".EMPLOYEES\n")
+        .throws_("Expression 'name' is not being grouped");
+    with.query("select \"name\",\"adhoc\".my_sum3(\"empid\",\"deptno\",\"commission\") as p "
+        + "from \"adhoc\".EMPLOYEES\n"
+        + "group by \"name\"")
+        .returnsUnordered("name=Theodore; P=0",
+            "name=Eric; P=220",
+            "name=Bill; P=110",
+            "name=Sebastian; P=0");
+    with.query("select \"adhoc\".my_sum3(\"empid\",\"deptno\",\"salary\") as p "
+        + "from \"adhoc\".EMPLOYEES\n")
+        .throws_("No match found for function signature MY_SUM3(<NUMERIC>, "
+            + "<NUMERIC>, <APPROXIMATE_NUMERIC>)");
+    with.query("select \"adhoc\".my_sum3(\"empid\",\"deptno\",\"name\") as p "
+        + "from \"adhoc\".EMPLOYEES\n");
+    with.query("select \"adhoc\".my_sum2(\"commission\",250) as p "
+        + "from \"adhoc\".EMPLOYEES\n")
+        .returns("P=1500\n");
+    with.query("select \"adhoc\".my_sum2(\"name\",250) as p from \"adhoc\".EMPLOYEES\n")
+        .throws_("No match found for function signature MY_SUM2(<CHARACTER>, <NUMERIC>)");
+    with.query("select \"adhoc\".my_sum2(\"empid\",0.0) as p from \"adhoc\".EMPLOYEES\n")
+        .throws_("No match found for function signature MY_SUM2(<NUMERIC>, <NUMERIC>)");
+  }
+
   /** Test for
    * {@link org.apache.calcite.runtime.CalciteResource#firstParameterOfAdd(String)}. */
   @Test public void testUserDefinedAggregateFunction3() throws Exception {
@@ -531,9 +604,7 @@ public class UdfTest {
     with.query("select my_sum3(\"deptno\") as p from EMPLOYEES\n")
         .returns("P=50\n");
     with.query("select my_sum3(\"name\") as p from EMPLOYEES\n")
-        .throws_("Cannot apply 'MY_SUM3' to arguments of type "
-            + "'MY_SUM3(<JAVATYPE(CLASS JAVA.LANG.STRING)>)'. "
-            + "Supported form(s): 'MY_SUM3(<NUMERIC>)");
+        .throws_("No match found for function signature MY_SUM3(<CHARACTER>)");
     with.query("select my_sum3(\"deptno\", 1) as p from EMPLOYEES\n")
         .throws_("No match found for function signature "
             + "MY_SUM3(<NUMERIC>, <NUMERIC>)");

http://git-wip-us.apache.org/repos/asf/calcite/blob/47c8df9e/core/src/test/java/org/apache/calcite/util/Smalls.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/util/Smalls.java b/core/src/test/java/org/apache/calcite/util/Smalls.java
index c10d119..be5bd3e 100644
--- a/core/src/test/java/org/apache/calcite/util/Smalls.java
+++ b/core/src/test/java/org/apache/calcite/util/Smalls.java
@@ -553,6 +553,88 @@ public class Smalls {
     }
   }
 
+  /** Example of a user-defined aggregate function (UDAF). */
+  public static class MyTwoParamsSumFunctionFilter1 {
+    public MyTwoParamsSumFunctionFilter1() {
+    }
+    public int init() {
+      return 0;
+    }
+    public int add(int accumulator, int v1, int v2) {
+      if (v1 > v2) {
+        return accumulator + v1;
+      }
+      return accumulator;
+    }
+    public int merge(int accumulator0, int accumulator1) {
+      return accumulator0 + accumulator1;
+    }
+    public int result(int accumulator) {
+      return accumulator;
+    }
+  }
+
+  /** Example of a user-defined aggregate function (UDAF). */
+  public static class MyTwoParamsSumFunctionFilter2 {
+    public MyTwoParamsSumFunctionFilter2() {
+    }
+    public long init() {
+      return 0L;
+    }
+    public long add(long accumulator, int v1, String v2) {
+      if (v2.equals("Eric")) {
+        return accumulator + v1;
+      }
+      return accumulator;
+    }
+    public long merge(long accumulator0, long accumulator1) {
+      return accumulator0 + accumulator1;
+    }
+    public long result(long accumulator) {
+      return accumulator;
+    }
+  }
+
+  /** Example of a user-defined aggregate function (UDAF), whose methods are
+   * static. */
+  public static class MyThreeParamsSumFunctionWithFilter1 {
+    public static long init() {
+      return 0L;
+    }
+    public static long add(long accumulator, int v1, String v2, String v3) {
+      if (v2.equals(v3)) {
+        return accumulator + v1;
+      }
+      return accumulator;
+    }
+    public static long merge(long accumulator0, long accumulator1) {
+      return accumulator0 + accumulator1;
+    }
+    public static long result(long accumulator) {
+      return accumulator;
+    }
+  }
+
+  /** Example of a user-defined aggregate function (UDAF), whose methods are
+   * static. olny for validate to get exact function by calcite*/
+  public static class MyThreeParamsSumFunctionWithFilter2 {
+    public static long init() {
+      return 0L;
+    }
+    public static long add(long accumulator, int v1, int v2, int v3) {
+      if (v3 > 250) {
+        return accumulator + v1 + v2;
+      }
+      return accumulator;
+    }
+    public static long merge(long accumulator0, long accumulator1) {
+      return accumulator0 + accumulator1;
+    }
+    public static long result(long accumulator) {
+      return accumulator;
+    }
+  }
+
   /** User-defined function. */
   public static class SumFunctionBadIAdd {
     public long init() {


[3/7] calcite git commit: [CALCITE-1874] In Frameworks, make SqlToRelConverter configurable

Posted by jh...@apache.org.
[CALCITE-1874] In Frameworks, make SqlToRelConverter configurable

Close apache/calcite#492


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

Branch: refs/heads/master
Commit: 8e707d433f6f0e0ca9a35218fd8f92e555eb1b4d
Parents: d4ab1e5
Author: Gian Merlino <gi...@gmail.com>
Authored: Wed Jul 5 10:36:06 2017 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Thu Jul 6 11:24:38 2017 -0700

----------------------------------------------------------------------
 .../org/apache/calcite/prepare/PlannerImpl.java | 15 +++++++++++---
 .../apache/calcite/tools/FrameworkConfig.java   |  6 ++++++
 .../org/apache/calcite/tools/Frameworks.java    | 21 ++++++++++++++++++--
 3 files changed, 37 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/8e707d43/core/src/main/java/org/apache/calcite/prepare/PlannerImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/prepare/PlannerImpl.java b/core/src/main/java/org/apache/calcite/prepare/PlannerImpl.java
index 6cb3d39..09236a0 100644
--- a/core/src/main/java/org/apache/calcite/prepare/PlannerImpl.java
+++ b/core/src/main/java/org/apache/calcite/prepare/PlannerImpl.java
@@ -68,6 +68,7 @@ public class PlannerImpl implements Planner {
   private final ImmutableList<RelTraitDef> traitDefs;
 
   private final SqlParser.Config parserConfig;
+  private final SqlToRelConverter.Config sqlToRelConverterConfig;
   private final SqlRexConvertletTable convertletTable;
 
   private State state;
@@ -96,6 +97,7 @@ public class PlannerImpl implements Planner {
     this.operatorTable = config.getOperatorTable();
     this.programs = config.getPrograms();
     this.parserConfig = config.getParserConfig();
+    this.sqlToRelConverterConfig = config.getSqlToRelConverterConfig();
     this.state = State.STATE_0_CLOSED;
     this.traitDefs = config.getTraitDefs();
     this.convertletTable = config.getConvertletTable();
@@ -224,7 +226,10 @@ public class PlannerImpl implements Planner {
     final RexBuilder rexBuilder = createRexBuilder();
     final RelOptCluster cluster = RelOptCluster.create(planner, rexBuilder);
     final SqlToRelConverter.Config config = SqlToRelConverter.configBuilder()
-        .withTrimUnusedFields(false).withConvertTableAccess(false).build();
+        .withConfig(sqlToRelConverterConfig)
+        .withTrimUnusedFields(false)
+        .withConvertTableAccess(false)
+        .build();
     final SqlToRelConverter sqlToRelConverter =
         new SqlToRelConverter(new ViewExpanderImpl(), validator,
             createCatalogReader(), cluster, convertletTable, config);
@@ -260,8 +265,12 @@ public class PlannerImpl implements Planner {
 
       final RexBuilder rexBuilder = createRexBuilder();
       final RelOptCluster cluster = RelOptCluster.create(planner, rexBuilder);
-      final SqlToRelConverter.Config config = SqlToRelConverter.configBuilder()
-          .withTrimUnusedFields(false).withConvertTableAccess(false).build();
+      final SqlToRelConverter.Config config = SqlToRelConverter
+          .configBuilder()
+          .withConfig(sqlToRelConverterConfig)
+          .withTrimUnusedFields(false)
+          .withConvertTableAccess(false)
+          .build();
       final SqlToRelConverter sqlToRelConverter =
           new SqlToRelConverter(new ViewExpanderImpl(), validator,
               catalogReader, cluster, convertletTable, config);

http://git-wip-us.apache.org/repos/asf/calcite/blob/8e707d43/core/src/main/java/org/apache/calcite/tools/FrameworkConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/tools/FrameworkConfig.java b/core/src/main/java/org/apache/calcite/tools/FrameworkConfig.java
index 7921a80..94bb273 100644
--- a/core/src/main/java/org/apache/calcite/tools/FrameworkConfig.java
+++ b/core/src/main/java/org/apache/calcite/tools/FrameworkConfig.java
@@ -25,6 +25,7 @@ import org.apache.calcite.schema.SchemaPlus;
 import org.apache.calcite.sql.SqlOperatorTable;
 import org.apache.calcite.sql.parser.SqlParser;
 import org.apache.calcite.sql2rel.SqlRexConvertletTable;
+import org.apache.calcite.sql2rel.SqlToRelConverter;
 
 import com.google.common.collect.ImmutableList;
 
@@ -41,6 +42,11 @@ public interface FrameworkConfig {
   SqlParser.Config getParserConfig();
 
   /**
+   * The configuration of {@link SqlToRelConverter}.
+   */
+  SqlToRelConverter.Config getSqlToRelConverterConfig();
+
+  /**
    * Returns the default schema that should be checked before looking at the
    * root schema.  Returns null to only consult the root schema.
    */

http://git-wip-us.apache.org/repos/asf/calcite/blob/8e707d43/core/src/main/java/org/apache/calcite/tools/Frameworks.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/tools/Frameworks.java b/core/src/main/java/org/apache/calcite/tools/Frameworks.java
index 7aba625..6d29152 100644
--- a/core/src/main/java/org/apache/calcite/tools/Frameworks.java
+++ b/core/src/main/java/org/apache/calcite/tools/Frameworks.java
@@ -33,6 +33,7 @@ import org.apache.calcite.sql.SqlOperatorTable;
 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
 import org.apache.calcite.sql.parser.SqlParser;
 import org.apache.calcite.sql2rel.SqlRexConvertletTable;
+import org.apache.calcite.sql2rel.SqlToRelConverter;
 import org.apache.calcite.sql2rel.StandardConvertletTable;
 import org.apache.calcite.util.Util;
 
@@ -179,6 +180,8 @@ public class Frameworks {
     private ImmutableList<RelTraitDef> traitDefs;
     private SqlParser.Config parserConfig =
         SqlParser.Config.DEFAULT;
+    private SqlToRelConverter.Config sqlToRelConverterConfig =
+        SqlToRelConverter.Config.DEFAULT;
     private SchemaPlus defaultSchema;
     private RexExecutor executor;
     private RelOptCostFactory costFactory;
@@ -188,8 +191,8 @@ public class Frameworks {
 
     public FrameworkConfig build() {
       return new StdFrameworkConfig(context, convertletTable, operatorTable,
-          programs, traitDefs, parserConfig, defaultSchema, costFactory,
-          typeSystem, executor);
+          programs, traitDefs, parserConfig, sqlToRelConverterConfig,
+          defaultSchema, costFactory, typeSystem, executor);
     }
 
     public ConfigBuilder context(Context c) {
@@ -233,6 +236,13 @@ public class Frameworks {
       return this;
     }
 
+    public ConfigBuilder sqlToRelConverterConfig(
+        SqlToRelConverter.Config sqlToRelConverterConfig) {
+      this.sqlToRelConverterConfig =
+          Preconditions.checkNotNull(sqlToRelConverterConfig);
+      return this;
+    }
+
     public ConfigBuilder defaultSchema(SchemaPlus defaultSchema) {
       this.defaultSchema = defaultSchema;
       return this;
@@ -278,6 +288,7 @@ public class Frameworks {
     private final ImmutableList<Program> programs;
     private final ImmutableList<RelTraitDef> traitDefs;
     private final SqlParser.Config parserConfig;
+    private final SqlToRelConverter.Config sqlToRelConverterConfig;
     private final SchemaPlus defaultSchema;
     private final RelOptCostFactory costFactory;
     private final RelDataTypeSystem typeSystem;
@@ -289,6 +300,7 @@ public class Frameworks {
         ImmutableList<Program> programs,
         ImmutableList<RelTraitDef> traitDefs,
         SqlParser.Config parserConfig,
+        SqlToRelConverter.Config sqlToRelConverterConfig,
         SchemaPlus defaultSchema,
         RelOptCostFactory costFactory,
         RelDataTypeSystem typeSystem,
@@ -299,6 +311,7 @@ public class Frameworks {
       this.programs = programs;
       this.traitDefs = traitDefs;
       this.parserConfig = parserConfig;
+      this.sqlToRelConverterConfig = sqlToRelConverterConfig;
       this.defaultSchema = defaultSchema;
       this.costFactory = costFactory;
       this.typeSystem = typeSystem;
@@ -309,6 +322,10 @@ public class Frameworks {
       return parserConfig;
     }
 
+    public SqlToRelConverter.Config getSqlToRelConverterConfig() {
+      return sqlToRelConverterConfig;
+    }
+
     public SchemaPlus getDefaultSchema() {
       return defaultSchema;
     }


[4/7] calcite git commit: Cosmetic changes

Posted by jh...@apache.org.
Cosmetic changes


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

Branch: refs/heads/master
Commit: b199b9cd0d8959961a2469f3274f87ff0c8122ac
Parents: 8e707d4
Author: Julian Hyde <jh...@apache.org>
Authored: Thu Jul 6 12:13:46 2017 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Thu Jul 6 14:45:37 2017 -0700

----------------------------------------------------------------------
 .../calcite/rel/metadata/RelMetadataQuery.java  |  1 -
 .../calcite/rel/rules/DateRangeRules.java       |  1 +
 .../org/apache/calcite/sql/SqlCollation.java    |  2 +-
 .../calcite/sql/SqlIntervalQualifier.java       | 56 ++++++++++----------
 .../calcite/sql2rel/SqlToRelConverter.java      |  1 +
 .../calcite/test/JdbcFrontLinqBackTest.java     |  2 -
 .../concurrent/ConcurrentTestPluginCommand.java |  1 -
 7 files changed, 31 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/b199b9cd/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java
index ebd9e91..b50cd8d 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMetadataQuery.java
@@ -209,7 +209,6 @@ public class RelMetadataQuery {
    * statistic.
    *
    * @param rel the relational expression
-   * @return
    */
   public Multimap<Class<? extends RelNode>, RelNode> getNodeTypes(RelNode rel) {
     for (;;) {

http://git-wip-us.apache.org/repos/asf/calcite/blob/b199b9cd/core/src/main/java/org/apache/calcite/rel/rules/DateRangeRules.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/DateRangeRules.java b/core/src/main/java/org/apache/calcite/rel/rules/DateRangeRules.java
index 2a185a1..5b7cf95 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/DateRangeRules.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/DateRangeRules.java
@@ -232,6 +232,7 @@ public abstract class DateRangeRules {
                 (RexLiteral) op1);
           }
         }
+        // fall through
       default:
         calls.push(call);
         try {

http://git-wip-us.apache.org/repos/asf/calcite/blob/b199b9cd/core/src/main/java/org/apache/calcite/sql/SqlCollation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlCollation.java b/core/src/main/java/org/apache/calcite/sql/SqlCollation.java
index a3ac712..ef13ce9 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlCollation.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlCollation.java
@@ -145,7 +145,7 @@ public class SqlCollation implements Serializable {
    * @param col2 second operand for the dyadic operation
    * @return the resulting collation sequence
    *
-   * @throws org.apache.calcite.runtime.CalciteException
+   * @throws org.apache.calcite.runtime.CalciteException from
    *   {@link org.apache.calcite.runtime.CalciteResource#invalidCompare} or
    *   {@link org.apache.calcite.runtime.CalciteResource#differentCollations}
    *   if no collating sequence can be deduced

http://git-wip-us.apache.org/repos/asf/calcite/blob/b199b9cd/core/src/main/java/org/apache/calcite/sql/SqlIntervalQualifier.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlIntervalQualifier.java b/core/src/main/java/org/apache/calcite/sql/SqlIntervalQualifier.java
index 45e128f..fa1c45f 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlIntervalQualifier.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlIntervalQualifier.java
@@ -498,8 +498,8 @@ public class SqlIntervalQualifier extends SqlNode {
   /**
    * Validates an INTERVAL literal against a YEAR interval qualifier.
    *
-   * @throws org.apache.calcite.runtime.CalciteContextException
-   * if the interval value is illegal
+   * @throws org.apache.calcite.runtime.CalciteContextException if the interval
+   * value is illegal
    */
   private int[] evaluateIntervalLiteralAsYear(
       RelDataTypeSystem typeSystem, int sign,
@@ -533,8 +533,8 @@ public class SqlIntervalQualifier extends SqlNode {
   /**
    * Validates an INTERVAL literal against a YEAR TO MONTH interval qualifier.
    *
-   * @throws org.apache.calcite.runtime.CalciteContextException
-   * if the interval value is illegal
+   * @throws org.apache.calcite.runtime.CalciteContextException if the interval
+   * value is illegal
    */
   private int[] evaluateIntervalLiteralAsYearToMonth(
       RelDataTypeSystem typeSystem, int sign,
@@ -573,8 +573,8 @@ public class SqlIntervalQualifier extends SqlNode {
   /**
    * Validates an INTERVAL literal against a MONTH interval qualifier.
    *
-   * @throws org.apache.calcite.runtime.CalciteContextException
-   * if the interval value is illegal
+   * @throws org.apache.calcite.runtime.CalciteContextException if the interval
+   * value is illegal
    */
   private int[] evaluateIntervalLiteralAsMonth(
       RelDataTypeSystem typeSystem, int sign,
@@ -608,8 +608,8 @@ public class SqlIntervalQualifier extends SqlNode {
   /**
    * Validates an INTERVAL literal against a DAY interval qualifier.
    *
-   * @throws org.apache.calcite.runtime.CalciteContextException
-   * if the interval value is illegal
+   * @throws org.apache.calcite.runtime.CalciteContextException if the interval
+   * value is illegal
    */
   private int[] evaluateIntervalLiteralAsDay(
       RelDataTypeSystem typeSystem, int sign,
@@ -643,8 +643,8 @@ public class SqlIntervalQualifier extends SqlNode {
   /**
    * Validates an INTERVAL literal against a DAY TO HOUR interval qualifier.
    *
-   * @throws org.apache.calcite.runtime.CalciteContextException
-   * if the interval value is illegal
+   * @throws org.apache.calcite.runtime.CalciteContextException if the interval
+   * value is illegal
    */
   private int[] evaluateIntervalLiteralAsDayToHour(
       RelDataTypeSystem typeSystem, int sign,
@@ -683,8 +683,8 @@ public class SqlIntervalQualifier extends SqlNode {
   /**
    * Validates an INTERVAL literal against a DAY TO MINUTE interval qualifier.
    *
-   * @throws org.apache.calcite.runtime.CalciteContextException
-   * if the interval value is illegal
+   * @throws org.apache.calcite.runtime.CalciteContextException if the interval
+   * value is illegal
    */
   private int[] evaluateIntervalLiteralAsDayToMinute(
       RelDataTypeSystem typeSystem, int sign,
@@ -726,8 +726,8 @@ public class SqlIntervalQualifier extends SqlNode {
   /**
    * Validates an INTERVAL literal against a DAY TO SECOND interval qualifier.
    *
-   * @throws org.apache.calcite.runtime.CalciteContextException
-   * if the interval value is illegal
+   * @throws org.apache.calcite.runtime.CalciteContextException if the interval
+   * value is illegal
    */
   private int[] evaluateIntervalLiteralAsDayToSecond(
       RelDataTypeSystem typeSystem, int sign,
@@ -802,8 +802,8 @@ public class SqlIntervalQualifier extends SqlNode {
   /**
    * Validates an INTERVAL literal against an HOUR interval qualifier.
    *
-   * @throws org.apache.calcite.runtime.CalciteContextException
-   * if the interval value is illegal
+   * @throws org.apache.calcite.runtime.CalciteContextException if the interval
+   * value is illegal
    */
   private int[] evaluateIntervalLiteralAsHour(
       RelDataTypeSystem typeSystem, int sign,
@@ -838,8 +838,8 @@ public class SqlIntervalQualifier extends SqlNode {
    * Validates an INTERVAL literal against an HOUR TO MINUTE interval
    * qualifier.
    *
-   * @throws org.apache.calcite.runtime.CalciteContextException
-   * if the interval value is illegal
+   * @throws org.apache.calcite.runtime.CalciteContextException if the interval
+   * value is illegal
    */
   private int[] evaluateIntervalLiteralAsHourToMinute(
       RelDataTypeSystem typeSystem, int sign,
@@ -879,8 +879,8 @@ public class SqlIntervalQualifier extends SqlNode {
    * Validates an INTERVAL literal against an HOUR TO SECOND interval
    * qualifier.
    *
-   * @throws org.apache.calcite.runtime.CalciteContextException
-   * if the interval value is illegal
+   * @throws org.apache.calcite.runtime.CalciteContextException if the interval
+   * value is illegal
    */
   private int[] evaluateIntervalLiteralAsHourToSecond(
       RelDataTypeSystem typeSystem, int sign,
@@ -952,8 +952,8 @@ public class SqlIntervalQualifier extends SqlNode {
   /**
    * Validates an INTERVAL literal against an MINUTE interval qualifier.
    *
-   * @throws org.apache.calcite.runtime.CalciteContextException
-   * if the interval value is illegal
+   * @throws org.apache.calcite.runtime.CalciteContextException if the interval
+   * value is illegal
    */
   private int[] evaluateIntervalLiteralAsMinute(
       RelDataTypeSystem typeSystem, int sign,
@@ -988,8 +988,8 @@ public class SqlIntervalQualifier extends SqlNode {
    * Validates an INTERVAL literal against an MINUTE TO SECOND interval
    * qualifier.
    *
-   * @throws org.apache.calcite.runtime.CalciteContextException
-   * if the interval value is illegal
+   * @throws org.apache.calcite.runtime.CalciteContextException if the interval
+   * value is illegal
    */
   private int[] evaluateIntervalLiteralAsMinuteToSecond(
       RelDataTypeSystem typeSystem, int sign,
@@ -1057,8 +1057,8 @@ public class SqlIntervalQualifier extends SqlNode {
   /**
    * Validates an INTERVAL literal against an SECOND interval qualifier.
    *
-   * @throws org.apache.calcite.runtime.CalciteContextException
-   * if the interval value is illegal
+   * @throws org.apache.calcite.runtime.CalciteContextException if the interval
+   * value is illegal
    */
   private int[] evaluateIntervalLiteralAsSecond(
       RelDataTypeSystem typeSystem,
@@ -1124,8 +1124,8 @@ public class SqlIntervalQualifier extends SqlNode {
    *
    * @return field values, never null
    *
-   * @throws org.apache.calcite.runtime.CalciteContextException
-   * if the interval value is illegal
+   * @throws org.apache.calcite.runtime.CalciteContextException if the interval
+   * value is illegal
    */
   public int[] evaluateIntervalLiteral(String value, SqlParserPos pos,
       RelDataTypeSystem typeSystem) {

http://git-wip-us.apache.org/repos/asf/calcite/blob/b199b9cd/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
index 7f17cbb..4ba3875 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
@@ -4419,6 +4419,7 @@ public class SqlToRelConverter {
           throw new RuntimeException(kind
               + " is only supported if expand = false");
         }
+        // fall through
       case CURSOR:
       case IN:
       case NOT_IN:

http://git-wip-us.apache.org/repos/asf/calcite/blob/b199b9cd/core/src/test/java/org/apache/calcite/test/JdbcFrontLinqBackTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/JdbcFrontLinqBackTest.java b/core/src/test/java/org/apache/calcite/test/JdbcFrontLinqBackTest.java
index 73b1bb8..6546226 100644
--- a/core/src/test/java/org/apache/calcite/test/JdbcFrontLinqBackTest.java
+++ b/core/src/test/java/org/apache/calcite/test/JdbcFrontLinqBackTest.java
@@ -326,8 +326,6 @@ public class JdbcFrontLinqBackTest {
    * Method to be shared with {@code RemoteDriverTest}.
    *
    * @param initialData record to be presented in table
-   * @return java.sql.Connection
-   * @throws Exception
    */
   public static Connection makeConnection(
         final List<JdbcTest.Employee> initialData) throws Exception {

http://git-wip-us.apache.org/repos/asf/calcite/blob/b199b9cd/core/src/test/java/org/apache/calcite/test/concurrent/ConcurrentTestPluginCommand.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/concurrent/ConcurrentTestPluginCommand.java b/core/src/test/java/org/apache/calcite/test/concurrent/ConcurrentTestPluginCommand.java
index 37fb55b..2b4d1dd 100644
--- a/core/src/test/java/org/apache/calcite/test/concurrent/ConcurrentTestPluginCommand.java
+++ b/core/src/test/java/org/apache/calcite/test/concurrent/ConcurrentTestPluginCommand.java
@@ -53,7 +53,6 @@ public interface ConcurrentTestPluginCommand {
    * Implement this method to extend functionality of mtsql.
    *
    * @param testContext Exposed context for plugin to run in.
-   * @throws IOException
    */
   void execute(TestContext testContext) throws IOException;
 }


[7/7] calcite git commit: [CALCITE-1826] Generate dialect-specific SQL for FLOOR operator when in a GROUP BY (Chris Baynes)

Posted by jh...@apache.org.
[CALCITE-1826] Generate dialect-specific SQL for FLOOR operator when in a GROUP BY (Chris Baynes)

Close apache/calcite#489


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

Branch: refs/heads/master
Commit: 8cb189f727aafade53708d18bc7e51526da0bf38
Parents: c12e37d
Author: Chris Baynes <bi...@gmail.com>
Authored: Wed Jul 5 15:36:17 2017 +0200
Committer: Julian Hyde <jh...@apache.org>
Committed: Thu Jul 6 14:45:47 2017 -0700

----------------------------------------------------------------------
 .../calcite/sql/fun/SqlFloorFunction.java       | 29 ++++++++++++------
 .../rel/rel2sql/RelToSqlConverterTest.java      | 31 ++++++++++++++++++++
 2 files changed, 51 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/8cb189f7/core/src/main/java/org/apache/calcite/sql/fun/SqlFloorFunction.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlFloorFunction.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlFloorFunction.java
index 4038efb..5d751f7 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlFloorFunction.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlFloorFunction.java
@@ -88,19 +88,20 @@ public class SqlFloorFunction extends SqlMonotonicUnaryFunction {
     final SqlLiteral timeUnitNode = call.operand(1);
     final TimeUnitRange timeUnit = timeUnitNode.getValueAs(TimeUnitRange.class);
 
+    final SqlCall call2;
     switch (writer.getDialect().getDatabaseProduct()) {
     case ORACLE:
-      replaceTimeUnitOperand(call, timeUnit.name(), timeUnitNode.getParserPosition());
-      unparseDatetimeFunction(writer, call, "TRUNC", true);
+      call2 = replaceTimeUnitOperand(call, timeUnit.name(), timeUnitNode.getParserPosition());
+      unparseDatetimeFunction(writer, call2, "TRUNC", true);
       break;
     case HSQLDB:
-      String translatedLit = convertToHsqlDb(timeUnit);
-      replaceTimeUnitOperand(call, translatedLit, timeUnitNode.getParserPosition());
-      unparseDatetimeFunction(writer, call, "TRUNC", true);
+      final String translatedLit = convertToHsqlDb(timeUnit);
+      call2 = replaceTimeUnitOperand(call, translatedLit, timeUnitNode.getParserPosition());
+      unparseDatetimeFunction(writer, call2, "TRUNC", true);
       break;
     case POSTGRESQL:
-      replaceTimeUnitOperand(call, timeUnit.name(), timeUnitNode.getParserPosition());
-      unparseDatetimeFunction(writer, call, "DATE_TRUNC", false);
+      call2 = replaceTimeUnitOperand(call, timeUnit.name(), timeUnitNode.getParserPosition());
+      unparseDatetimeFunction(writer, call2, "DATE_TRUNC", false);
       break;
     case MSSQL:
       unparseDatetimeMssql(writer, call);
@@ -113,9 +114,19 @@ public class SqlFloorFunction extends SqlMonotonicUnaryFunction {
     }
   }
 
-  private void replaceTimeUnitOperand(SqlCall call, String literal, SqlParserPos pos) {
+  /**
+   * Copies a {@link SqlCall}, replacing the time unit operand with the given
+   * literal.
+   *
+   * @param call Call
+   * @param literal Literal to replace time unit with
+   * @param pos Parser position
+   * @return Modified call
+   */
+  private SqlCall replaceTimeUnitOperand(SqlCall call, String literal, SqlParserPos pos) {
     SqlLiteral literalNode = SqlLiteral.createCharString(literal, null, pos);
-    call.setOperand(1, literalNode);
+    return call.getOperator().createCall(call.getFunctionQuantifier(), pos,
+        call.getOperandList().get(0), literalNode);
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/calcite/blob/8cb189f7/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
index 1ca63d2..4b46e7a 100644
--- a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
+++ b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
@@ -754,6 +754,37 @@ public class RelToSqlConverterTest {
         .ok(expected);
   }
 
+  /** Test case for
+   * <a href="https://issues.apache.org/jira/browse/CALCITE-1826">[CALCITE-1826]
+   * JDBC dialect-specific FLOOR fails when in GROUP BY</a>. */
+  @Test public void testFloorWithGroupBy() {
+    final String query = "SELECT floor(\"hire_date\" TO MINUTE)\n"
+        + "FROM \"employee\"\n"
+        + "GROUP BY floor(\"hire_date\" TO MINUTE)";
+    final String expected = "SELECT TRUNC(hire_date, 'MI')\n"
+        + "FROM foodmart.employee\n"
+        + "GROUP BY TRUNC(hire_date, 'MI')";
+    final String expectedOracle = "SELECT TRUNC(\"hire_date\", 'MINUTE')\n"
+        + "FROM \"foodmart\".\"employee\"\n"
+        + "GROUP BY TRUNC(\"hire_date\", 'MINUTE')";
+    final String expectedPostgresql = "SELECT DATE_TRUNC('MINUTE', \"hire_date\")\n"
+        + "FROM \"foodmart\".\"employee\"\n"
+        + "GROUP BY DATE_TRUNC('MINUTE', \"hire_date\")";
+    final String expectedMysql = "SELECT"
+        + " DATE_FORMAT(`hire_date`, '%Y-%m-%d %k:%i:00')\n"
+        + "FROM `foodmart`.`employee`\n"
+        + "GROUP BY DATE_FORMAT(`hire_date`, '%Y-%m-%d %k:%i:00')";
+    sql(query)
+        .dialect(DatabaseProduct.HSQLDB.getDialect())
+        .ok(expected)
+        .dialect(DatabaseProduct.ORACLE.getDialect())
+        .ok(expectedOracle)
+        .dialect(DatabaseProduct.POSTGRESQL.getDialect())
+        .ok(expectedPostgresql)
+        .dialect(DatabaseProduct.MYSQL.getDialect())
+        .ok(expectedMysql);
+  }
+
   @Test public void testMatchRecognizePatternExpression() {
     String sql = "select *\n"
         + "  from \"product\" match_recognize\n"


[5/7] calcite git commit: [CALCITE-1842] Sort.computeSelfCost() calls makeCost() with arguments in wrong order (Junxian Wu)

Posted by jh...@apache.org.
[CALCITE-1842] Sort.computeSelfCost() calls makeCost() with arguments in wrong order (Junxian Wu)

Close apache/calcite#491


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

Branch: refs/heads/master
Commit: 48a20668647b5a5e86073ef0e9ce206669ad6867
Parents: b199b9c
Author: Junxian Wu <ru...@yahoo-inc.com>
Authored: Wed Jul 5 11:44:51 2017 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Thu Jul 6 14:45:47 2017 -0700

----------------------------------------------------------------------
 core/src/main/java/org/apache/calcite/rel/core/Sort.java     | 8 ++++----
 .../java/org/apache/calcite/test/JdbcFrontLinqBackTest.java  | 7 +++----
 2 files changed, 7 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/48a20668/core/src/main/java/org/apache/calcite/rel/core/Sort.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/core/Sort.java b/core/src/main/java/org/apache/calcite/rel/core/Sort.java
index 001fcd2..d9d49c5 100644
--- a/core/src/main/java/org/apache/calcite/rel/core/Sort.java
+++ b/core/src/main/java/org/apache/calcite/rel/core/Sort.java
@@ -133,10 +133,10 @@ public abstract class Sort extends SingleRel {
       RelMetadataQuery mq) {
     // Higher cost if rows are wider discourages pushing a project through a
     // sort.
-    double rowCount = mq.getRowCount(this);
-    double bytesPerRow = getRowType().getFieldCount() * 4;
-    return planner.getCostFactory().makeCost(
-        Util.nLogN(rowCount) * bytesPerRow, rowCount, 0);
+    final double rowCount = mq.getRowCount(this);
+    final double bytesPerRow = getRowType().getFieldCount() * 4;
+    final double cpu = Util.nLogN(rowCount) * bytesPerRow;
+    return planner.getCostFactory().makeCost(rowCount, cpu, 0);
   }
 
   @Override public List<RexNode> getChildExps() {

http://git-wip-us.apache.org/repos/asf/calcite/blob/48a20668/core/src/test/java/org/apache/calcite/test/JdbcFrontLinqBackTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/JdbcFrontLinqBackTest.java b/core/src/test/java/org/apache/calcite/test/JdbcFrontLinqBackTest.java
index 6546226..da6facc 100644
--- a/core/src/test/java/org/apache/calcite/test/JdbcFrontLinqBackTest.java
+++ b/core/src/test/java/org/apache/calcite/test/JdbcFrontLinqBackTest.java
@@ -106,10 +106,9 @@ public class JdbcFrontLinqBackTest {
             + "from \"hr\".\"emps\" as e\n"
             + "order by \"deptno\", \"name\" desc")
         .explainContains(""
-            + "EnumerableCalc(expr#0..1=[{inputs}], expr#2=[UPPER($t1)], UN=[$t2], deptno=[$t0], name=[$t1])\n"
-            + "  EnumerableSort(sort0=[$0], sort1=[$1], dir0=[ASC], dir1=[DESC])\n"
-            + "    EnumerableCalc(expr#0..4=[{inputs}], deptno=[$t1], name=[$t2])\n"
-            + "      EnumerableTableScan(table=[[hr, emps]])")
+            + "EnumerableCalc(expr#0..4=[{inputs}], expr#5=[UPPER($t2)], UN=[$t5], deptno=[$t1], name=[$t2])\n"
+            + "  EnumerableSort(sort0=[$1], sort1=[$2], dir0=[ASC], dir1=[DESC])\n"
+            + "    EnumerableTableScan(table=[[hr, emps]])")
         .returns("UN=THEODORE; deptno=10\n"
             + "UN=SEBASTIAN; deptno=10\n"
             + "UN=BILL; deptno=10\n"


[6/7] calcite git commit: Test case for [CALCITE-1799] "OR ... IN" sub-query conversion wrong

Posted by jh...@apache.org.
Test case for [CALCITE-1799] "OR ... IN" sub-query conversion wrong


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

Branch: refs/heads/master
Commit: c12e37d41a9d81b1303a345bad5067e1518d6c7d
Parents: 48a2066
Author: Julian Hyde <jh...@apache.org>
Authored: Thu Jul 6 12:13:07 2017 -0700
Committer: Julian Hyde <jh...@apache.org>
Committed: Thu Jul 6 14:45:47 2017 -0700

----------------------------------------------------------------------
 .../calcite/test/SqlToRelConverterTest.java     | 13 +++++++
 .../calcite/test/SqlToRelConverterTest.xml      | 18 ++++++++++
 .../calcite/adapter/csv/CsvStreamReader.java    |  4 +--
 .../org/apache/calcite/linq4j/Enumerator.java   | 36 ++++++++++----------
 4 files changed, 51 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/c12e37d4/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java b/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
index 29797c6..f7b730c 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
@@ -2005,6 +2005,19 @@ public class SqlToRelConverterTest extends SqlToRelTestBase {
 
   /**
    * Test case for
+   * <a href="https://issues.apache.org/jira/browse/CALCITE-1799">[CALCITE-1799]
+   * "OR .. IN" sub-query conversion wrong</a>.
+   *
+   * <p>The problem is only fixed if you have {@code expand = false}.
+   */
+  @Test public void testSubQueryOr() {
+    final String sql = "select * from emp where deptno = 10 or deptno in (\n"
+        + "    select dept.deptno from dept where deptno < 5)\n";
+    sql(sql).expand(false).ok();
+  }
+
+  /**
+   * Test case for
    * <a href="https://issues.apache.org/jira/browse/CALCITE-695">[CALCITE-695]
    * SqlSingleValueAggFunction is created when it may not be needed</a>.
    */

http://git-wip-us.apache.org/repos/asf/calcite/blob/c12e37d4/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
----------------------------------------------------------------------
diff --git a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
index 321b6a7..35cc58d 100644
--- a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
@@ -3664,6 +3664,24 @@ LogicalProject(EMPNO=[$0])
 ]]>
         </Resource>
     </TestCase>
+    <TestCase name="testSubQueryOr">
+        <Resource name="sql">
+            <![CDATA[select * from emp where deptno = 10 or deptno in (
+    select dept.deptno from dept where deptno < 5)
+]]>
+        </Resource>
+        <Resource name="plan">
+            <![CDATA[
+LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8])
+  LogicalFilter(condition=[OR(=($7, 10), IN($7, {
+LogicalProject(DEPTNO=[$0])
+  LogicalFilter(condition=[<($0, 5)])
+    LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+}))])
+    LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+        </Resource>
+    </TestCase>
     <TestCase name="testUpdateWhere">
         <Resource name="sql">
             <![CDATA[update emp set empno = empno + 1 where deptno = 10]]>

http://git-wip-us.apache.org/repos/asf/calcite/blob/c12e37d4/example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvStreamReader.java
----------------------------------------------------------------------
diff --git a/example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvStreamReader.java b/example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvStreamReader.java
index 9f24d4f..0478935 100644
--- a/example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvStreamReader.java
+++ b/example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvStreamReader.java
@@ -124,8 +124,8 @@ class CsvStreamReader extends CSVReader implements Closeable {
    * Reads the next line from the file.
    *
    * @return the next line from the file without trailing newline
-   * @throws IOException
-   *             if bad things happen during the read
+   *
+   * @throws IOException if bad things happen during the read
    */
   private String getNextLine() throws IOException {
     return contentQueue.poll();

http://git-wip-us.apache.org/repos/asf/calcite/blob/c12e37d4/linq4j/src/main/java/org/apache/calcite/linq4j/Enumerator.java
----------------------------------------------------------------------
diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/Enumerator.java b/linq4j/src/main/java/org/apache/calcite/linq4j/Enumerator.java
index 0bc2e01..46e08cb 100644
--- a/linq4j/src/main/java/org/apache/calcite/linq4j/Enumerator.java
+++ b/linq4j/src/main/java/org/apache/calcite/linq4j/Enumerator.java
@@ -22,7 +22,7 @@ package org.apache.calcite.linq4j;
  * <p>Analogous to LINQ's System.Collections.Enumerator. Unlike LINQ, if the
  * underlying collection has been modified it is only optional that an
  * implementation of the Enumerator interface detects it and throws a
- * {@link java.util.ConcurrentModificationException}.</p>
+ * {@link java.util.ConcurrentModificationException}.
  *
  * @param <T> Element type
  */
@@ -34,15 +34,15 @@ public interface Enumerator<T> extends AutoCloseable {
    * called, the {@link #moveNext} method must be called to advance the
    * enumerator to the first element of the collection before reading the
    * value of the {@code current} property; otherwise, {@code current} is
-   * undefined.</p>
+   * undefined.
    *
    * <p>This method also throws {@link java.util.NoSuchElementException} if
    * the last call to {@code moveNext} returned {@code false}, which indicates
-   * the end of the collection.</p>
+   * the end of the collection.
    *
    * <p>This method does not move the position of the enumerator, and
    * consecutive calls to {@code current} return the same object until either
-   * {@code moveNext} or {@code reset} is called.</p>
+   * {@code moveNext} or {@code reset} is called.
    *
    * <p>An enumerator remains valid as long as the collection remains
    * unchanged. If changes are made to the collection, such as adding,
@@ -55,13 +55,13 @@ public interface Enumerator<T> extends AutoCloseable {
    * invalidated.
    *
    * @return Current element
-   * @throws java.util.ConcurrentModificationException
-   *          if collection has
-   *          been modified
-   * @throws java.util.NoSuchElementException
-   *          if {@code moveToNext} has not
-   *          been called, has not been called since the most recent call to
-   *          {@code reset}, or returned false
+   *
+   * @throws java.util.ConcurrentModificationException if collection
+   *          has been modified
+   *
+   * @throws java.util.NoSuchElementException if {@code moveToNext}
+   *          has not been called, has not been called since the most
+   *          recent call to {@code reset}, or returned false
    */
   T current();
 
@@ -71,20 +71,20 @@ public interface Enumerator<T> extends AutoCloseable {
    * <p>After an enumerator is created or after the {@code reset} method is
    * called, an enumerator is positioned before the first element of the
    * collection, and the first call to the {@code moveNext} method moves the
-   * enumerator over the first element of the collection.</p>
+   * enumerator over the first element of the collection.
    *
    * <p>If {@code moveNext} passes the end of the collection, the enumerator
    * is positioned after the last element in the collection and
    * {@code moveNext} returns {@code false}. When the enumerator is at this
    * position, subsequent calls to {@code moveNext} also return {@code false}
-   * until {@code #reset} is called.</p>
+   * until {@code #reset} is called.
    *
    * <p>An enumerator remains valid as long as the collection remains
    * unchanged. If changes are made to the collection, such as adding,
    * modifying, or deleting elements, the enumerator is irrecoverably
    * invalidated. The next call to {@code moveNext} or {@link #reset} may,
    * at the discretion of the implementation, throw a
-   * {@link java.util.ConcurrentModificationException}.</p>
+   * {@link java.util.ConcurrentModificationException}.
    *
    * @return {@code true} if the enumerator was successfully advanced to the
    *         next element; {@code false} if the enumerator has passed the end of
@@ -101,10 +101,10 @@ public interface Enumerator<T> extends AutoCloseable {
    * modifying, or deleting elements, the enumerator is irrecoverably
    * invalidated. The next call to {@link #moveNext} or {@code reset} may,
    * at the discretion of the implementation, throw a
-   * {@link java.util.ConcurrentModificationException}.</p>
+   * {@link java.util.ConcurrentModificationException}.
    *
    * <p>This method is optional; it may throw
-   * {@link UnsupportedOperationException}.</p>
+   * {@link UnsupportedOperationException}.
    *
    * <h3>Notes to Implementers</h3>
    *
@@ -113,7 +113,7 @@ public interface Enumerator<T> extends AutoCloseable {
    * of the collection, before the first element. This invalidates the
    * enumerator if the collection has been modified since the enumerator was
    * created, which is consistent with {@link #moveNext()} and
-   * {@link #current()}.</p>
+   * {@link #current()}.
    */
   void reset();
 
@@ -121,7 +121,7 @@ public interface Enumerator<T> extends AutoCloseable {
    * Closes this enumerable and releases resources.
    *
    * <p>This method is idempotent. Calling it multiple times has the same effect
-   * as calling it once.</p>
+   * as calling it once.
    */
   void close();
 }