[CALCITE-1867] Allow user-defined grouped window functions (Timo Walther)

Rename SqlGroupFunction to SqlGroupedWindowFunction.

Close apache/calcite#549


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

Branch: refs/heads/master
Commit: 814de2327d3255888a07e1940dbf7dd7bd340b19
Parents: 61f1258
Author: twalthr <[email protected]>
Authored: Tue Oct 17 11:30:10 2017 +0200
Committer: Julian Hyde <[email protected]>
Committed: Thu Nov 2 15:04:59 2017 -0700

----------------------------------------------------------------------
 .../calcite/sql/fun/SqlGroupFunction.java       |  99 ---------------
 .../sql/fun/SqlGroupedWindowFunction.java       | 124 +++++++++++++++++++
 .../calcite/sql/fun/SqlStdOperatorTable.java    |  42 +++----
 3 files changed, 145 insertions(+), 120 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/814de232/core/src/main/java/org/apache/calcite/sql/fun/SqlGroupFunction.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/calcite/sql/fun/SqlGroupFunction.java 
b/core/src/main/java/org/apache/calcite/sql/fun/SqlGroupFunction.java
deleted file mode 100644
index d44267a..0000000
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlGroupFunction.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.calcite.sql.fun;
-
-import org.apache.calcite.sql.SqlFunction;
-import org.apache.calcite.sql.SqlFunctionCategory;
-import org.apache.calcite.sql.SqlKind;
-import org.apache.calcite.sql.SqlOperatorBinding;
-import org.apache.calcite.sql.type.ReturnTypes;
-import org.apache.calcite.sql.type.SqlOperandTypeChecker;
-import org.apache.calcite.sql.validate.SqlMonotonicity;
-
-import com.google.common.collect.ImmutableList;
-
-import java.util.List;
-
-/**
- * SQL function that computes keys by which rows can be partitioned and
- * aggregated.
- *
- * <p>Grouped window functions always occur in the GROUP BY clause. They often
- * have auxiliary functions that access information about the group. For
- * example, {@code HOP} is a group function, and its auxiliary functions are
- * {@code HOP_START} and {@code HOP_END}. Here they are used in a streaming
- * query:
- *
- * <blockquote><pre>
- * SELECT STREAM HOP_START(rowtime, INTERVAL '1' HOUR),
- *   HOP_END(rowtime, INTERVAL '1' HOUR),
- *   MIN(unitPrice)
- * FROM Orders
- * GROUP BY HOP(rowtime, INTERVAL '1' HOUR), productId
- * </pre></blockquote>
- */
-class SqlGroupFunction extends SqlFunction {
-  /** The grouped function, if this an auxiliary function; null otherwise. */
-  final SqlGroupFunction groupFunction;
-
-  /** Creates a SqlGroupFunction.
-   *
-   * @param kind Kind; also determines function name
-   * @param groupFunction Group function, if this is an auxiliary;
-   *                      null, if this is a group function
-   * @param operandTypeChecker Operand type checker
-   */
-  SqlGroupFunction(SqlKind kind, SqlGroupFunction groupFunction,
-      SqlOperandTypeChecker operandTypeChecker) {
-    super(kind.name(), kind, ReturnTypes.ARG0, null,
-        operandTypeChecker, SqlFunctionCategory.SYSTEM);
-    this.groupFunction = groupFunction;
-    if (groupFunction != null) {
-      assert groupFunction.groupFunction == null;
-    }
-  }
-
-  /** Creates an auxiliary function from this grouped window function. */
-  SqlGroupFunction auxiliary(SqlKind kind) {
-    return new SqlGroupFunction(kind, this, getOperandTypeChecker());
-  }
-
-  /** Returns a list of this grouped window function's auxiliary functions. */
-  List<SqlGroupFunction> getAuxiliaryFunctions() {
-    return ImmutableList.of();
-  }
-
-  @Override public boolean isGroup() {
-    // Auxiliary functions are not group functions
-    return groupFunction == null;
-  }
-
-  @Override public boolean isGroupAuxiliary() {
-    return groupFunction != null;
-  }
-
-  @Override public SqlMonotonicity getMonotonicity(SqlOperatorBinding call) {
-    // Monotonic iff its first argument is, but not strict.
-    //
-    // Note: This strategy happens to works for all current group functions
-    // (HOP, TUMBLE, SESSION). When there are exceptions to this rule, we'll
-    // make the method abstract.
-    return call.getOperandMonotonicity(0).unstrict();
-  }
-}
-
-// End SqlGroupFunction.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/814de232/core/src/main/java/org/apache/calcite/sql/fun/SqlGroupedWindowFunction.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/calcite/sql/fun/SqlGroupedWindowFunction.java 
b/core/src/main/java/org/apache/calcite/sql/fun/SqlGroupedWindowFunction.java
new file mode 100644
index 0000000..8226e95
--- /dev/null
+++ 
b/core/src/main/java/org/apache/calcite/sql/fun/SqlGroupedWindowFunction.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.sql.fun;
+
+import org.apache.calcite.sql.SqlFunction;
+import org.apache.calcite.sql.SqlFunctionCategory;
+import org.apache.calcite.sql.SqlKind;
+import org.apache.calcite.sql.SqlOperatorBinding;
+import org.apache.calcite.sql.type.ReturnTypes;
+import org.apache.calcite.sql.type.SqlOperandTypeChecker;
+import org.apache.calcite.sql.validate.SqlMonotonicity;
+
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+
+/**
+ * SQL function that computes keys by which rows can be partitioned and
+ * aggregated.
+ *
+ * <p>Grouped window functions always occur in the GROUP BY clause. They often
+ * have auxiliary functions that access information about the group. For
+ * example, {@code HOP} is a group function, and its auxiliary functions are
+ * {@code HOP_START} and {@code HOP_END}. Here they are used in a streaming
+ * query:
+ *
+ * <blockquote><pre>
+ * SELECT STREAM HOP_START(rowtime, INTERVAL '1' HOUR),
+ *   HOP_END(rowtime, INTERVAL '1' HOUR),
+ *   MIN(unitPrice)
+ * FROM Orders
+ * GROUP BY HOP(rowtime, INTERVAL '1' HOUR), productId
+ * </pre></blockquote>
+ */
+public class SqlGroupedWindowFunction extends SqlFunction {
+  /** The grouped function, if this an auxiliary function; null otherwise. */
+  final SqlGroupedWindowFunction groupFunction;
+
+  /** Creates a SqlGroupedWindowFunction.
+   *
+   * @param name Function name
+   * @param kind Kind
+   * @param groupFunction Group function, if this is an auxiliary;
+   *                      null, if this is a group function
+   * @param operandTypeChecker Operand type checker
+   */
+  public SqlGroupedWindowFunction(String name, SqlKind kind, 
SqlGroupedWindowFunction groupFunction,
+      SqlOperandTypeChecker operandTypeChecker) {
+    super(name, kind, ReturnTypes.ARG0, null,
+        operandTypeChecker, SqlFunctionCategory.SYSTEM);
+    this.groupFunction = groupFunction;
+    if (groupFunction != null) {
+      assert groupFunction.groupFunction == null;
+    }
+  }
+
+  /** Creates a SqlGroupedWindowFunction.
+   *
+   * @param kind Kind; also determines function name
+   * @param groupFunction Group function, if this is an auxiliary;
+   *                      null, if this is a group function
+   * @param operandTypeChecker Operand type checker
+   */
+  public SqlGroupedWindowFunction(SqlKind kind, SqlGroupedWindowFunction 
groupFunction,
+      SqlOperandTypeChecker operandTypeChecker) {
+    this(kind.name(), kind, groupFunction, operandTypeChecker);
+  }
+
+  /** Creates an auxiliary function from this grouped window function.
+   *
+   * @param kind Kind; also determines function name
+   */
+  public SqlGroupedWindowFunction auxiliary(SqlKind kind) {
+    return auxiliary(kind.name(), kind);
+  }
+
+  /** Creates an auxiliary function from this grouped window function.
+   *
+   * @param name Function name
+   * @param kind Kind
+   */
+  public SqlGroupedWindowFunction auxiliary(String name, SqlKind kind) {
+    return new SqlGroupedWindowFunction(name, kind, this, 
getOperandTypeChecker());
+  }
+
+  /** Returns a list of this grouped window function's auxiliary functions. */
+  public List<SqlGroupedWindowFunction> getAuxiliaryFunctions() {
+    return ImmutableList.of();
+  }
+
+  @Override public boolean isGroup() {
+    // Auxiliary functions are not group functions
+    return groupFunction == null;
+  }
+
+  @Override public boolean isGroupAuxiliary() {
+    return groupFunction != null;
+  }
+
+  @Override public SqlMonotonicity getMonotonicity(SqlOperatorBinding call) {
+    // Monotonic iff its first argument is, but not strict.
+    //
+    // Note: This strategy happens to works for all current group functions
+    // (HOP, TUMBLE, SESSION). When there are exceptions to this rule, we'll
+    // make the method abstract.
+    return call.getOperandMonotonicity(0).unstrict();
+  }
+}
+
+// End SqlGroupedWindowFunction.java

http://git-wip-us.apache.org/repos/asf/calcite/blob/814de232/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java 
b/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java
index c8adf5e..aafc943 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java
@@ -2006,63 +2006,63 @@ public class SqlStdOperatorTable extends 
ReflectiveSqlOperatorTable {
       };
 
   /** The {@code TUMBLE} group function. */
-  public static final SqlGroupFunction TUMBLE =
-      new SqlGroupFunction(SqlKind.TUMBLE, null,
+  public static final SqlGroupedWindowFunction TUMBLE =
+      new SqlGroupedWindowFunction(SqlKind.TUMBLE, null,
           OperandTypes.or(OperandTypes.DATETIME_INTERVAL,
               OperandTypes.DATETIME_INTERVAL_TIME)) {
-        @Override List<SqlGroupFunction> getAuxiliaryFunctions() {
+        @Override public List<SqlGroupedWindowFunction> 
getAuxiliaryFunctions() {
           return ImmutableList.of(TUMBLE_START, TUMBLE_END);
         }
       };
 
   /** The {@code TUMBLE_START} auxiliary function of
    * the {@code TUMBLE} group function. */
-  public static final SqlGroupFunction TUMBLE_START =
+  public static final SqlGroupedWindowFunction TUMBLE_START =
       TUMBLE.auxiliary(SqlKind.TUMBLE_START);
 
   /** The {@code TUMBLE_END} auxiliary function of
    * the {@code TUMBLE} group function. */
-  public static final SqlGroupFunction TUMBLE_END =
+  public static final SqlGroupedWindowFunction TUMBLE_END =
       TUMBLE.auxiliary(SqlKind.TUMBLE_END);
 
   /** The {@code HOP} group function. */
-  public static final SqlGroupFunction HOP =
-      new SqlGroupFunction(SqlKind.HOP, null,
+  public static final SqlGroupedWindowFunction HOP =
+      new SqlGroupedWindowFunction(SqlKind.HOP, null,
           OperandTypes.or(OperandTypes.DATETIME_INTERVAL_INTERVAL,
               OperandTypes.DATETIME_INTERVAL_INTERVAL_TIME)) {
-        @Override List<SqlGroupFunction> getAuxiliaryFunctions() {
+        @Override public List<SqlGroupedWindowFunction> 
getAuxiliaryFunctions() {
           return ImmutableList.of(HOP_START, HOP_END);
         }
       };
 
   /** The {@code HOP_START} auxiliary function of
    * the {@code HOP} group function. */
-  public static final SqlGroupFunction HOP_START =
+  public static final SqlGroupedWindowFunction HOP_START =
       HOP.auxiliary(SqlKind.HOP_START);
 
   /** The {@code HOP_END} auxiliary function of
    * the {@code HOP} group function. */
-  public static final SqlGroupFunction HOP_END =
+  public static final SqlGroupedWindowFunction HOP_END =
       HOP.auxiliary(SqlKind.HOP_END);
 
   /** The {@code SESSION} group function. */
-  public static final SqlGroupFunction SESSION =
-      new SqlGroupFunction(SqlKind.SESSION, null,
+  public static final SqlGroupedWindowFunction SESSION =
+      new SqlGroupedWindowFunction(SqlKind.SESSION, null,
           OperandTypes.or(OperandTypes.DATETIME_INTERVAL,
               OperandTypes.DATETIME_INTERVAL_TIME)) {
-        @Override List<SqlGroupFunction> getAuxiliaryFunctions() {
+        @Override public List<SqlGroupedWindowFunction> 
getAuxiliaryFunctions() {
           return ImmutableList.of(SESSION_START, SESSION_END);
         }
       };
 
   /** The {@code SESSION_START} auxiliary function of
    * the {@code SESSION} group function. */
-  public static final SqlGroupFunction SESSION_START =
+  public static final SqlGroupedWindowFunction SESSION_START =
       SESSION.auxiliary(SqlKind.SESSION_START);
 
   /** The {@code SESSION_END} auxiliary function of
    * the {@code SESSION} group function. */
-  public static final SqlGroupFunction SESSION_END =
+  public static final SqlGroupedWindowFunction SESSION_END =
       SESSION.auxiliary(SqlKind.SESSION_END);
 
   /** {@code |} operator to create alternate patterns
@@ -2178,7 +2178,7 @@ public class SqlStdOperatorTable extends 
ReflectiveSqlOperatorTable {
 
   /** Returns the group function for which a given kind is an auxiliary
    * function, or null if it is not an auxiliary function. */
-  public static SqlGroupFunction auxiliaryToGroup(SqlKind kind) {
+  public static SqlGroupedWindowFunction auxiliaryToGroup(SqlKind kind) {
     switch (kind) {
     case TUMBLE_START:
     case TUMBLE_END:
@@ -2201,9 +2201,9 @@ public class SqlStdOperatorTable extends 
ReflectiveSqlOperatorTable {
    * to {@code TUMBLE(rowtime, INTERVAL '1' HOUR))}. */
   public static SqlCall convertAuxiliaryToGroupCall(SqlCall call) {
     final SqlOperator op = call.getOperator();
-    if (op instanceof SqlGroupFunction
+    if (op instanceof SqlGroupedWindowFunction
         && op.isGroupAuxiliary()) {
-      return copy(call, ((SqlGroupFunction) op).groupFunction);
+      return copy(call, ((SqlGroupedWindowFunction) op).groupFunction);
     }
     return null;
   }
@@ -2216,12 +2216,12 @@ public class SqlStdOperatorTable extends 
ReflectiveSqlOperatorTable {
   public static List<Pair<SqlNode, AuxiliaryConverter>> 
convertGroupToAuxiliaryCalls(
       SqlCall call) {
     final SqlOperator op = call.getOperator();
-    if (op instanceof SqlGroupFunction
+    if (op instanceof SqlGroupedWindowFunction
         && op.isGroup()) {
       ImmutableList.Builder<Pair<SqlNode, AuxiliaryConverter>> builder =
           ImmutableList.builder();
-      for (final SqlGroupFunction f
-          : ((SqlGroupFunction) op).getAuxiliaryFunctions()) {
+      for (final SqlGroupedWindowFunction f
+          : ((SqlGroupedWindowFunction) op).getAuxiliaryFunctions()) {
         builder.add(
             Pair.<SqlNode, AuxiliaryConverter>of(copy(call, f),
                 new AuxiliaryConverter.Impl(f)));

Reply via email to